• entries
  • comments
  • views

A c64 game - Step 2

Sign in to follow this  


And onwards we stumble!

In the first part we prepared everything for the VIC, now we set up our modified charset. Note that I used a selfmade tool (similar to CharPad), which is included (Windows binary). The file J.CHR contains the charset and is included into the source as binary. The memory layout of the game expects the modified charset at $f000. Since the C64 can't load files to locations after $C000 we have to copy the charset to the target memory at $f000. To be able to properly write at those addresses we need to switch off the ROM overlay.

The current step should display "HELLO". The rest of the screen depends on the current memory setup of your emulator/C64


First code piece we add is the copy routine. Interrupts are blocked because we turn off the kernal ROM. If we didn't the IRQ code would jump in the middle of uninitialised RAM, likely resulting in a crash. The RAM/ROM layout is influenced by memory address $1.

          ;copy charset to target
          ;block interrupts
          ;since we turn ROMs off this would result in crashes if we did not
          ;save old configuration
          lda $1
          sta PARAM1
          ;only RAM
          ;to copy under the IO rom
          lda #%00110000
          sta $1
          ;take source address from CHARSET
          LDA #<CHARSET
          LDA #>CHARSET
          STA ZEROPAGE_POINTER_1 + 1
          ;now copy
          jsr CopyCharSet
          ;restore ROMs
          lda PARAM1
          sta $1


The actual copy routine. Note that we only copy 254 characters. The last two characters are omitted to not overwrite the default IRQ vectors residing at $fffb. Since we deal with a 8 bit machine there is an extra loop taking care of the high bytes of our addresses. At the end of the copy routine we include the binary charset data.

!zone CopyCharSet
          ;set target address ($F000)
          lda #$00
          sta ZEROPAGE_POINTER_2
          lda #$F0
          sta ZEROPAGE_POINTER_2 + 1
          ldx #$00
          ldy #$00
          lda #0
          sta PARAM2
          lda (ZEROPAGE_POINTER_1),Y
          sta (ZEROPAGE_POINTER_2),Y
          cpx #$8
          bne .NextLine
          cpy #$00
          bne .PageBoundaryNotReached
          ;we reached the next 256 bytes, inc high byte
          inc ZEROPAGE_POINTER_1 + 1
          inc ZEROPAGE_POINTER_2 + 1
          ;only copy 254 chars to keep irq vectors intact
          inc PARAM2
          lda PARAM2
          cmp #254
          beq .CopyCharsetDone
          ldx #$00
          jmp .NextLine
!binary "j.chr"


To display HELLO on the screen we simple poke the character codes on the screen and also set the characters colors to white.

;test charset
          lda #'H'
          sta SCREEN_CHAR
          lda #'E'
          sta SCREEN_CHAR + 1
          lda #'L'
          sta SCREEN_CHAR + 2
          sta SCREEN_CHAR + 3
          lda #'O'
          sta SCREEN_CHAR + 4
          lda #1
          sta SCREEN_COLOR
          sta SCREEN_COLOR + 1
          sta SCREEN_COLOR + 2
          sta SCREEN_COLOR + 3
          sta SCREEN_COLOR + 4


The charset of the C64 is using 8 bytes per character. This totals at 256 characters a 8 bytes = 2048 bytes. A custom character set can be positioned almost everywhere in RAM (at 2048 interval steps).

In hires text mode every bit corresponds to a pixel. In multicolor text mode pixels are doubling width, so two bits make up one pixel. In multicolor mode two colors are shared by all multi-color characters, one is the background color and one is the current char color.

The memory layout looks like this (nicked from www.c64-wiki.de):

$FFFF = 65535 ?????????????????????????????????
              ?---------------?|||||||||||||||? ||| = read by PEEK
              ?---------------?|||||||||||||||? --- = written to by POKE
              ?---------------?|||||||||||||||? +++ = read and write
              ?---------------?||| KERNAL- |||? other = not reachable from BASIC
              ?---------------?|||  ROM    |||?
$E000 = 57344 ?????????????????????????????????????????????????
              ?               ?               ?+++++++++++++++?
              ?               ?    CHAR ROM   ?+++++ I/O +++++?
              ?               ?               ?+++++++++++++++?
$D000 = 53248 ?????????????????????????????????????????????????
$C000 = 49152 ?????????????????????????????????
              ?---------------?||| BASIC- ||||?
              ?---------------?|||  ROM   ||||?
$A000 = 40960 ?????????????????????????????????
              ?+++ BASIC- ++++?
              ?+++  RAM   ++++?
              .               .
              ?+++ BASIC- ++++?
              ?+++  RAM   ++++?
$800 = 2048   ?+++++++++++++++?-?
$400 = 1024   ?+++++++++++++++?-?Default Screen Address
$0000         ?????????????????-?Zeropage and Enhanced Zeropage


Previous Step 1b Next Step 3

Sign in to follow this  


Recommended Comments

Glad you like it :)

It does support multicolor, but with the restrictions of the real machine. You need to a) check multicolor for every char and b) have a char color >= 8.

The C64 allowed both multicolor and hires color chars at the same time, albeit only a char color in the first 8 colors.

Share this comment

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now