I'm new to these forums, but I've been messing around with 6502 assembly for decades...
A few years ago, I got the crazy idea to try porting the Commodore 64 KERNAL and BASIC ROMs to the NES, since their CPUs are mostly the same. But I gave up when things got complicated with the PPU. Then a couple weeks ago, I saw that someone ported it to the Atari 1200XL, so I decided I'd give it another shot. This time, I was able to make a (mostly) working system.
Here are some videos of it in action:
- Booting up, running BASIC, and showing tab stop and scrolling support: https://www.youtube.com/watch?v=G2APi8KVKGc
- Running a benchmark maze generator program: https://www.youtube.com/watch?v=ETx8FjbXT_0
- Running a benchmark that calls a machine language subroutine: https://www.youtube.com/watch?v=CrPb3mq1qwM
- Writing to the APU to play a C major scale: https://www.youtube.com/watch?v=KKzs_-WQxlI
UPDATE: I've published the code and a prebuilt ROM on GitHub. Check it out here: https://github.com/calcwatch/nes64
I went with the MMC5 mapper so that I could use ExRAM for the text screen, and not worry as much about reading/writing bytes in the PPU. The KERNAL an BASIC ROM are 8 kB each, so I put them in the last two banks ($C000-$FFFF), and filled the other banks with PRG RAM ($6000-$BFFF). The first byte of OS RAM is reserved, and the rest is available to BASIC. Hence the "24,575 bytes free" in the splash screen: $C000 - $6001 = $5FFF = 24,575.
The CHR ROM just contains the default all-caps character set from the C64.
I disabled all the mapper's interrupts except for the raster one, which the OS uses for keyboard scans, etc.
Because it's using the MMC5, it gets an 8-bit-to-16-bit multiplier for free. I tested it, and it works, but I can't find a practical use for it. (Not that this project has any practically uses! )
The original code comes from a heavily annotated disassembly I found on github. I needed to make some minor changes to get it assembled with ca65, mostly adding colons after labels. To free up space for new code, I removed pieces related to datacassettes, modems, RS232 devices and color RAM.
Caveats / Future Work
FCEUX only seems to support the shift key for letters. E.g., "shift+A" works, but "shift+1" doesn't register as a keypress. So there's no way to type "!", or most other symbols you'd need for BASIC. However, control key combos work, so I made the keyboard code act as if control were the same as shift.
The C64 text screen is 40 columns by 25 rows. I changed it to 32x30, which is fine for emulators, but I realize it's outside what TVs would display. (Family BASIC's text screen is just 28x24.) Shrinking it further would require substantial code changes to ignore the screen RAM bytes before and after each screen line.
So that's all I have now. I hope you enjoyed the writeup! I still can't believe that it works at all.