Skip to content

Latest commit

 

History

History
158 lines (118 loc) · 7.67 KB

c64.md

File metadata and controls

158 lines (118 loc) · 7.67 KB

c64

The Commodore 64.

Commodore 64 Monopole Digiloi

Status

  • Only text mode
  • Simple BASIC programs work
  • Inputs hacked in, needs work
  • No sprites
  • No I/O
  • No audio

Run

retro-cs -s c64

Controls

  • Control-C: STOP key

ROMs

The ROMs used from this emulator were taken from the VICE source code in the data/C64 directory. The correct SHA1 checksums are listed below.

Place these files in ~/rcs/data/c64

79015323128650c742a3694c9429aa91f355905e  basic
adc7c31e18c7c7413d54802ef2f4193da14711aa  chargen
1d503e56df85a62fee696e7618dc5b4e781df1bb  kernal

Viewers

rcs-viewer c64:chars
rcs-viewer c64:colors

Testing Programs

c1b6f3323509a981f157c55320a97ecba8b7991a  monopole.prg
db84a42bbd0de88b29a40567b465bae399f9d8d0  digiloi64.prg

Development Notes

These are my notes from the development work on the C64 emulator. I hope that these notes are useful for those who wish to write their own emulator.

Memory

I have some thoughts on memory.

The Commodore 64 uses a banked memory scheme and I implemented that from the beginning but completely forgot to wire it up. It actually isn't that important until much later on.

I assumed that writes to a region of memory that had ROM banked in were ignored. This is not correct. Writes will go to the RAM that is being hidden underneath the ROM. I haven't encountered this so far with the Commodore 64, but I did see it in the initialization routine for the Commodore 128. The code looks similar to this:

lda $e000,x
sta $e000,x

It does this to copy certain kernal routines that need to be available even if the ROM is banked out. It looks strange to see a load/store operation to the same address but it makes sense once you know what is going on.

CPU

See the notes on the 6502 series processor.

The Commodore 64 actually has a 6510 processor but the differences between the two have no impact on this software implementation.

First Light

The main loop started out endlessly executing CPU instructions. I loaded in the ROMs, started up the emulator, and took a look at what was in video RAM:

$0400  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$0410  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$0420  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
...

Cleared out with blank spaces, but no text. The emulator was stuck in a loop at this location:

$ff5e:  ad 12 d0  lda $d012
$ff61:  d0 fb     bne $ff5e

This register value contains the current raster scan line and the code is waiting for this value to go to zero. Since nothing was implemented yet to change this value, I added code to the main loop to stuff this value with zero on each iteration. Restarting the emulator got the desired result:

$0400  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$0410  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$0420  20 20 20 20 20 20 20 20  20 20 20 20 2a 2a 2a 2a              ****
$0430  20 03 0f 0d 0d 0f 04 0f  12 05 20 36 34 20 02 01   COMMODORE 64 BA
$0440  13 09 03 20 16 32 20 2a  2a 2a 2a 20 20 20 20 20  SIC V2 ****
$0450  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$0460  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$0470  20 20 20 20 20 20 20 20  20 36 34 0b 20 12 01 0d           64K RAM
$0480  20 13 19 13 14 05 0d 20  20 33 38 39 31 31 20 02   SYSTEM  38911 B
$0490  01 13 09 03 20 02 19 14  05 13 20 06 12 05 05 20  ASIC BYTES FREE
$04a0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$04b0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$04c0  20 20 20 20 20 20 20 20  12 05 01 04 19 2e 20 20          READY.
$04d0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$04e0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
$04f0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20

Except for the first time when the system reported that 0 bytes were free. That was a bug in the sdc implementation.

Video

Tile sheet from the chargen ROM:

C64 chargen

For implementing text mode:

  • Draw the border
  • Draw the background
  • Draw the characters

The characters are drawn to the texture by copying from the tile sheet and setting a color modification.

Timing now became sort of important. The simple strategy used in Pac-Man of running 20,000 CPU instructions between VBLANKs worked here too. I put in the interrupt requests at this point too but I kept commenting it out since I was having problems. It would have been better to worry about them later as it is possible to get to a cursor-less READY prompt without them. Once I had the interrupts fixed, the emulator booted up properly.

Keyboard

I first checked to see if I could directly insert key presses to the keyboard buffer at $c6 and update the buffer counter in $277. That worked so I went for that method to start. I just mapped the "simple" characters for now to be able to type. The fancy symbols and color directives can come later.

I then typed in the following program to see if it worked:

10 PRINT "HELLO WORLD"
20 GOTO 10
RUN

It did, but I forgot to map the STOP key so I wasn't able to stop the loop. I then botched the stop key by mapping it to Control-C but didn't handle the key release properly. I was confused for a bit when the program would run the first time but then would immediately say "BREAK" when trying to run it again.

PRG load

Now I went looking for a nice simple BASIC program that I could load in for testing. I came across a game that I remembered from my youth called Monopole. It is a two player game of Monopoly with no AI. You have to actually have another person around to play.

I loaded it up and it crashed right away. There are some pointers in zero page memory that need to be updated after a BASIC program is loaded. They are the pointer to variable storage at $2d and the pointer to array storage at $2f. They needed to be updated to the first byte after the program and then everything worked as expected.

The next program I tried is a new release called Digiloi which I saw on the 8-Bit Guy. All graphics are using PETSCII characters and there are no sprites used at all. This game does change the memory bank so this was a good time to test out that code. After fixing some small bugs with the memory handling, it booted up fine. I added in some joystick mappings and was able play. There is no audio yet but this has a kicking soundtrack that will be great for testing a SID implementation later.

To Be Continued

More to come later.

References