Commit graph

204 commits

Author SHA1 Message Date
Daniel Prilik
a5477dace3 quickfix for paperboy + README update 2018-05-29 17:03:38 -07:00
Daniel Prilik
d6e704a9f9 cleaned up mapper->cycle() args, and implemented nmi timing hack
I'm still not happy about having to pass a reference of the PPU to
mappers, since i'd much rather be faithful to the actual HW.
Alas, until I rewrite the PPU's sprite handling routines to be
cycle-accurate, I can't snoop PPU A12 in the mapper for timing.
Damn you MMC3!

Unrelated to that, I've gone ahead and implemented a (togglable!)
NMI timing hack. Some games were failing to boot at all, and it
seems to be due to my CPU not being subinstruction-cycle accurate.
I checked, and fogleman/nes had the same issue, so I wholesale
copied the hack from him. Seems to get Bad Dudes and Solomon's Key
up and running :)
2018-05-29 16:29:20 -07:00
Daniel Prilik
f11df3bc53 MMC3 works!
As usual, the best way to solve a problem is to not think about it
for a few days, and glance at the code again later.

Just like MMC1, the root of the issue was mishandling of RAM R/W
bits. I'm a real dingus.
2018-05-29 14:30:31 -07:00
Daniel Prilik
d7d25d7783 first try at MMC3 implementation - broken IRQ
The code is sloppy, and it doesn't work. Not entirely sure why...
2018-05-25 10:45:38 -07:00
Daniel Prilik
8a93ba24e5 cleanup movies + reorg memory management
1) Movie Cleanup

- Movie recording and playback are now well-defined classes.
- Infrastructure is in place to enable lazy-loading from a fm2 file
(if need be).
- File I/O is not handled in main anymore AT ALL

2) Reorg Memory Management

I changed the ROM class to be a zero-allocation wrapper around
existing memory, essentially just there to bound check raw ROM, and
to wrap it in a Memory interface.

I also reintroduced the Cartridge class, since in hindsight,
deleting it completely was overkill, and that it's actually a
useful memory-management construct. It owns both the ROM_File and
the Mapper, and frees them automatically.
The only real difference between the new Cartridge class and the
old one is that now, instead of being the entire class being
passed to the nes subsystem, one simply uses a getter to retrieve
the Mapper, (the important bit) to pass that to the NES.
2018-05-24 13:50:38 -07:00
Daniel Prilik
4751db118d mapper cleanup and major reorg - part II
I shuffled A LOT of files and functions around.

Two big things in this change:

1) There is no more Cartridge class.

I wrote that class when I was just starting out with ANESE, and
before I had a good idea of how NES hardware operates. As it turned
out, the Cartridge class essentially just mirrored the Mapepr
interface! The only real functionality it brought to the table was
routing the raw ROM data through into thte ROM_File class, which
would parse the ROM data.

I restructured all that.

File parsing shouldn't be under the /nes directory, since the nes
couldn't care less if the ROM file is iNES, NES2.0, or whatever
other formats there are. All the NES cares bout is that there is a
ROM_File struct with good data in it.
So, I moved the specifics of file-format parsing out of /nes, and
put them under /ui/fs/parse_rom.h.

I've changed all the interfaces that used Cartridge to just use
Mapper, and pushed the construction and ownership of the ROM_File
struct to main() for now. Which leads to number 2...

2) Main doesn't have any filesystem code anymore.

Yep, i've moved all the code required to read roms (and general
files) into /ui/fs/load_rom.h, so all main() has to do is pass the
path to a ROM / file, and it gets back a fully validated ROM_File
struct, or filled data pointers!

The code could still use some work, reorganizing the freestanding
functions into classes / namespaces, but this is a big step-up
from just having it all cluttering up main()

----

So yeah. Not much on the emulation front today, mostly just
improving code-quality.

(i'm also just procrastinating having to implement MMC3 lol)
2018-05-22 17:45:08 -07:00
Daniel Prilik
5e2ade82b9 mapper cleanup and reorg - part I
i've also had a chance to experiment a bit with ANESE, and I've
realized that I probably won't get supreme cycle-accuracy working.

My CPU emulator is instruction-level cycle accurate, but there are
some tests, games, and demos out there that rely on sub-instruction
level timings.

fixing these issues would involve a substantial rewrite of the CPU
core, which is something that I doubt i'll get around to. I'd
rather just push forward with implementing some more mappers,
cleaning up the code and UI, and taking a stab at a proper
home-grown APU implementation.
2018-05-22 15:42:07 -07:00
Daniel Prilik
f27a1b5796 fix broken bg colors in Bubble Bobble 2018-05-22 13:18:42 -07:00
Daniel
afaa20aba9 quickfix to movie recording 2018-05-21 21:59:41 -07:00
Daniel Prilik
33c174c9fe added rudimentary fm2 movie playback
It's one of those little featues that is nice to have. I'll record
myself playing some games, and i'll be able to see how various
changes I make alter the timings.

also, maybe i'll get to the point where I can actually run propper
TAS movies on ANESE. that'd be pretty rad.

----

I also moved speedup out from the nes core, since movies would need
a lot more fancy logic if I had kept the functionality contained in
nes.cc. The only reason the nes is still notified of the speed
change is so Blaarg's APU can adjust itself.
2018-05-21 18:51:53 -07:00
Daniel Prilik
7c9bbd619a fixed mapper 7
attention to detail strikes again! in blindly copying and pasting
the read function from another mapper, I totally didn't change the
fact that mapper 7 is one-big bank vs. 2 smaller ones.
yep. i'm a dingus.

ah well, c'est la vie. Battletoads works now!
2018-05-21 12:54:58 -07:00
Daniel
a3d35ecbfe janky step-through capability + mapper fixes / tweaks 2018-05-20 12:53:46 -07:00
Daniel
338cb9895a fixed windows builds 2018-05-20 11:42:25 -07:00
Daniel Prilik
36929b7a07 misc cleanup and refactor
you know, I just realized that MMC1 and Mapper 7 don't seem to be
passing the mapper tests...
MMC1 is incorrectly attributed to Mapper 2, and Mapper 7 doesn't
even work!

I've gotta investigate...
2018-05-18 17:42:09 -07:00
Daniel Prilik
6f5595a36d FIXED THE PPU
HAHA SUCK IT, I DID IT! THE PPU WORKS (well enough)

You know what it was? I completely overlooked handling 8x16 sized
sprites when fetching data! After I put that in, BAM, things began
working!

I'm sure the PPU isn't perfect (by any means), but games look good
now! HOORAY!

I can move onto implementing more mappers!

WOOOO! YES! WHAT A DAY!!!
2018-05-17 19:15:14 -07:00
Daniel Prilik
fe25c33146 running though test-roms, trying to narrow down issues
well, I don't think the issue is with DMA anymore. I've greatly
simplified the DMA class, and the implementation is so basic that I
doubt there is a issue with it (or at least one that I can see)

I also ran through a bunch of test roms, even implementing mapper 7
to get one working (oamtest3, which sucks by the way). Although I
could not fix the gfx issues, I did stumble across some minor bugs
that I fixed up:
- I realized that I was failing the CPU dummy_reads/dummy_write
tests, and while I did go ahead and fix dummy_writes, I was too
 lazy to look into fixing dummy_reads.
- I noticed that adresses 0x4018 - 0x401F in my CPU_MMU were being
handled wrong, being assigned to the Cartridge, instead of being
their own special thing. I've rectified that issue by simply having
them return 0x00 for now, at least until / if I implement the wierd
CPU / APU test functionality they are responsible for.

My methodology for narrowing down issues has been to run the test
roms in various emulators, and seeing if they pass / fail it. If
they fail the test, and so do I, that means that the innacuracy
that test is looking for shouldn't be affecting the garbled-gfx
issues i've been having. On the other hand, if they pass tests and
I don't, i'd try to fix the issue and see if that got my problems
to go away.

No luck yet with the gfx thing though...

That said, I think i've narrowed down the gfx issue to the Sprite
implementation. It never was written that well, and although it
works for some games, clearly it's breaking for many others.

Instead of debugging that mess, I'll probably just completely
reimplement the Sprite code in the PPU. Fun!
2018-05-17 10:26:30 -07:00
Daniel Prilik
41a5ae8cb6 more granular speed-adjust, some cleanup in main.cc and CMakeLists
I'm just procrastinating debugging the PPU.
2018-05-16 13:19:07 -07:00
Daniel Prilik
0eb82ac726 implemented mappers 2 and 3, started on 4
so, MMC3 == Mapper 4. that kind of tripped me up a bit, but that's
a minor thing

So yeah, MMC3 is a tricky boi, and it's probably going to require
some restructuring / new wiring. I'll tackle that later.

In the meantime, I got mappers 2 and 3 working! They are really
simple mappers: 2 has a single swappable PRG ROM, and 3 has a
single swappable CHR ROM. ezpz implementations.
Mappers 2 and 3 got some quality games "working," such as Mega
Man 1, Contra, and Arkanoid! "working" is in quotes because i'm
still seeing glitchy graphics, namely in Contra.

By the looks of it, the glitchy graphics are similar to those in
some MMC1 games i've messed abou with, which indicates to me that
odds are the root of the problem lies somewhere with my PPU
implementation.

My gut is telling me it might be something to do with DMA timings,
but that may very well be completely wrong...

All in all, i'm pretty happy with this commit. I can stop stressing
over my MMC1 implementation, and instead get _really_ stressed over
my PPU implementaion!

weeeeeeeeee
2018-05-15 17:59:36 -07:00
Daniel Prilik
f2be7c3f72 fixed MMC1 enough to boot Zelda!
You know what the issue was?
The ram enable flag in the MMC1 control register enables access to
SRAM when it is set to 0.
Let me repeat that: 0 == enabled. 1 == disabled.

WHY WOULD ANY SANE PERSON DO THAT GOD DAMMIT WHY AAAAAGGHHHHH!

...

Sorry about that, it's just shit like that which really pisses me
off.

Well, regarless, now that i've put that fix in, Zelda actually
boots. Albeit with garbled graphics.

And other MMC1 games also still have the garbled-graphics issue,
which I still can't seem to fix...

As usual, i'm scared to say it but the issues probably lie within
the PPU. That said, I think i'm done with hammering on MMC1 for now
and instead I think i'll shift gears and see if I can get MMC3 up
and running. If graphical issue still remain with MMC3, then odds
are the issues are with the PPU, and not with MMC1.

weeeeeeeeeee I looooove emulator developmenttttt
2018-05-15 15:18:37 -07:00
Daniel Prilik
92d14e0486 hammering on MMC1, trying to get Zelda working
It's been a while...

Once the semester started, I stopped working on my sideprojects,
as I had built a brand spanking new Gaming PC, and PUBG entered my
life.

Well, it's coop now, and I don't have a fancy gaming PC.
Might as well finish what I started here.

I always felt bad that ANESE was broken, and couldn't play all the
major titles. Yeah, SMB1 and Donkey Kong are great, but what about
Zelda? What about SMB2 and SMB3? Kirby?

So yeah. Hopefully I can get those working, and go on to bigger and
better things!

-----

Now, I don't know for sure, but I _think_ i've mostly fixed my MMC1
implementation. It passes the MMC1 mapper tests.

That means that things are broken for other reasons...
...
...

the PPU probably.

Ugh, this is going to suck.
2018-05-11 15:46:48 -07:00
Daniel Prilik
3895b69412 added mapper tests 2018-05-11 15:46:37 -07:00
Daniel Prilik
cfe1d2b94d Mapper 1 Support
So, lots of early assumptions proved to be wrong.
This meant that there was a bunch of code that had to be rewritten.

1) iNES format stores ROMs in 16k / 8k chunks, but that does _not_
   mean that all mappers bank along those lines!

I rewrote the entire ROM File parsing logic, and instead of chunking
the raw ROM into banks at the iNES parsing stage, it is done on a
mapper-per-mapper basis

2) Cartridges are _not_ just dumb data storage devices, and can have
   cycle-dependant logic!

To be fair, I knew I would have to cross this bridge someday. I had
to expand the Cartridge / Mapper interfaces to expose more of the
NES's. This is in both directions: Giving the Cartridge acess to the
NES's cycling logic, and also giving the NES a direct way to get
mirror modes from the cartridge (dynamically)

I was hoping that getting Mapper 1 working would also get Zelda
working, but alas, it's crasahing for some reason! As usual, I
suspect it's some shitty timings, and I can confirm, I am failing
a bunch of the NMI timing tests...

I _really_ don't want to go back into the hellhole that is the PPU,
but gosh darnit, I wanna play Zelda!

But hey, at least Megaman II works now :D

PS: I've been working on this commit for probably, oh, 8h total?
Not all at once mind you, it's been over the span of several days.
Now that i'm back in Toronto, i've been a bit busy, what with the
holidays, and old friends, and Wolfenstein II / DOOM taking up my
time.
2017-12-27 16:34:48 -05:00
Daniel Prilik
dfd561600e >tfw you fix windows and break osx 2017-12-20 10:15:03 -05:00
Daniel Prilik
8ad770c589 fix windows build 2017-12-20 00:19:30 -05:00
Daniel Prilik
73883fb814
remove file that broke pulling on windows 2017-12-20 00:05:08 -05:00
Daniel Prilik
edb40e42e7 APU courtesy of Blargg's 💯 nes_snd_emu library
I started looking into how to make the APU, and boy, let me tell
ya, it's going to be a massive undertaking.

Undoubtedly a fun undertaking, but still...

Since it's a personal goal to get Super Mario Bros 2 running
before new years (after all, that game has won
game-of-the-year i don't even know _how_ many years in a row),
i've decided to just use Blargg's venerable `nes_snd_emu` library
for now.

It took some wrestling, it it's in, and it works!

Almost.

I still don't know why enabling the Frame IRQ kills most games, but
i'll look into that!

Welp, on to bigger and better things!
Namely: MMC1, which will give me Zelda and... Super Mario Bros 2!
2017-12-20 00:00:56 -05:00
Daniel Prilik
1893508fec misc cleanup + some apu tests 2017-12-19 16:14:50 -05:00
Daniel Prilik
46a1454cf6 sprite cutoff fix 2017-12-18 22:48:03 -05:00
Daniel Prilik
c0e9556e1d add support for zipped roms
golly, i sure do hate cmake.
why does c++ package management have to be so bloody hard?
2017-12-18 22:26:56 -05:00
Daniel Prilik
0538ae0517 add fast-forward mode 2017-12-18 13:52:36 -08:00
Daniel Prilik
8c8177dc29 sprite 0 hit - MARIO WORKS HOLY SHIT
HOLY SHIT THE DAY THAT I'VE BEEN WORKING TOWARDS FINALLY CAME!

SUPAH.
MAHRIO.
BROS.
1.
WORKS!

Now, mind you, it's not flawless.

There are some issues I still need to work out, but nevertheless,
IT BLOODY RUNS!

I have a suspicion that it's relying on more accurate timings,
since right now, movement is pretty jank, and the time is ticking
far too quickly...

I'll look into the Frame IRQ now, hopefully that will be the last
piece of the puzzle :)

...

I'M SO HAPPY!

...

PS: I'm writing this from a plane as I fly home from vancouver.
It's pretty rad that I got this working on a plane :D
2017-12-17 13:40:41 -08:00
Daniel Prilik
baa01f12e9 BACKGROUND RENDERING PROPERLY! DONKEY KONG WORKS!
It happened! IT FINALLY HAPPENED!
I reimplemented how background pixels are rendered, and by golly,
IT SEEMS TO WORK! And you know what that means... DONKEY KONG
FUCKING WORKS. YES!

This is a _huge_ win for me, and i'm super stoked.

Up next, i'm going to look into redoing sprite rendering properly,
and getting the sprite-0 hit working. Hopefully, that will get SMB1
booting (unless it also needs the Frame IRQ implemented...)

WOOT!
2017-12-16 20:20:22 -08:00
Daniel Prilik
d83fce06f3 minor controller fix 2017-12-16 17:30:27 -08:00
Daniel Prilik
2222f959f0 fix mapper detect + better error msgs 2017-12-15 16:33:55 -08:00
Daniel Prilik
cd6c1aefe3 fix nametable corruption
golly, aren't I a idiot.
I forgot to add an if statement that prevented nametable fetches
from occuring during vblank, thereby causing the ppu to keep
updating the v register even during vblank (i.e: while the CPU was
doing writes too)

now, the last critical bug is actually just nailing the background
rendering, since once that's in place, all that'll be left to do is
add proper Sprite 0 detection, and a rudimentary APU Frame IRQ, and
BAM, most games should "just work" TM

hurrah! looks like this project will play Super Mario Bros before
the new year after all!
2017-12-15 15:55:47 -08:00
Daniel Prilik
14d278e5d2 ui and build improvements
added some 3rd party libs today! man, cmake is pretty complicated,
so it took a while to figure out, but hey, it seems to be working,
so that's good!

I added two libraries:
- `tinyfiledialogs` to handle opening a file-select window (that
  varies per platform) in the case that no rom is specified on the
  commandline.
- `args` handles parsing and validation of commandline arguments.
  As I start to add more and more flags, it's probably a good idea
  to set up a more extensible framework to configure ANESE

Oh, and FYI, this is all me procrastinating working on the PPU.

weeeeeeee!! isn't emulation fun?!
2017-12-14 16:17:51 -08:00
Daniel Prilik
36aa4e222c fix major PPU bug
goddamit. i misread the spec.
i didn't set the vbl flag if i didn't generate a vbl.

goddamit.

this fixes quite a few issues.

afaik, the major issue with ANESE right now is that the NMI is not
set properly. hopefully, i can hammer out the proper timing soon.
2017-12-13 19:31:08 -08:00
Daniel Prilik
61f45d68f6 rudimentary controller support (neat!) 2017-12-13 17:57:23 -08:00
Daniel Prilik
466fa9d0eb very minor logo tweak 2017-12-13 14:09:43 -08:00
Daniel Prilik
c47461cdc0 add logo + windows exe icon 2017-12-13 13:58:39 -08:00
Daniel Prilik
8b7c5f525e switch msvc to use Release config
yeah, i'm a bit of a dummy. I was building ANESE in _Debug_ config
with MSVC, and wondering why it was so bloody slow. Well, no shit
it's slow, it's not even being optimized!

I've set all the flags properly now, and have killed the windows
clang portion of the cmake script. Clang is a massive pain in the
ass to set up on windows with visual studio, so finally getting
MSVC to run ANESE properly is awesome.
2017-12-13 11:35:56 -08:00
Daniel
cabc5d5054 fixed a very silly mistake 2017-12-12 23:10:35 -08:00
Daniel Prilik
c586bc9e11 dma fix + small tweaks 2017-12-12 16:57:57 -08:00
Daniel Prilik
5c19d78761 more tests 2017-12-12 16:56:26 -08:00
Daniel Prilik
85849956c1 more misc edits + timing fixes?
nah, i didn't spend all day on these. I went skating, and i'm just
commiting these changes from earlier. Fun!
2017-12-10 21:32:04 -08:00
Daniel Prilik
283ecf7fb6 slightly better shortcuts 2017-12-10 13:34:53 -08:00
Daniel Prilik
d7c60781b2 implement joypad interface + standard controller
basically i'm just procrastinating, since getting the PPU working is
a _real_ grind
2017-12-10 13:17:32 -08:00
Daniel Prilik
ec1e89408c i want to die 2017-12-09 22:52:08 -08:00
Daniel Prilik
fd43f2bc13 add apu foundations 2017-12-09 20:54:14 -08:00
Daniel Prilik
d90a452ad0 trying random stuff to get things working
let's start with the good:

- well, graphics are a *bit* less janky now, since I fixed the bgr
fetch timings a bit. so that's nice.
- I found out that I forgot to emulate a instruction (CLI). (darn
NESTEST didn't ever test that one!)

and, well, that's it. shit's still fucked yo.

as a hail mary, i'm going to look into emulating some basic APU
stuff, hoping that it will magically make the timings align.

also, i'm starting to get a sneaking suspicion that my fancy
operator overloading and template magic shenanigans are breaking
things in very subtle ways. that fucking terrifies me. it's going
to be a massive shitshow to debug if that is the case.

anyhoo, that's where i'm at right now. time to get some dinner :)
2017-12-09 17:33:10 -08:00