A C64 Game - Step 2


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
sei

;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
sta ZEROPAGE_POINTER_1
lda #>CHARSET
sta ZEROPAGE_POINTER_1 + 1

;now copy
jsr CopyCharSet

;restore ROMs
lda PARAM1
sta $1
cli



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
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
.NextLine
lda (ZEROPAGE_POINTER_1),Y
sta (ZEROPAGE_POINTER_2),Y
inx
iny
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

.PageBoundaryNotReached
;only copy 254 chars to keep irq vectors intact
inc PARAM2
lda PARAM2
cmp #254
beq .CopyCharsetDone
ldx #$00
jmp .NextLine

.CopyCharsetDone
rts

CHARSET
!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



Clarifications:

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




step2.zip