A C64 Game - Step 57


This is a technically more sophisticated step. We'll add the possibility of a borderless level, and also a second charset.



Especially the latter requires a thorough planning of where to put things in memory. Remember, the VIC (the C64s graphic chip) can only see a 16K range at once. This means, all visible characters, sprite and screen memory must reside inside one 16K bank.

The new memory layout looks like this:

;screen back color $BC00 to $BFFF
;charset2 $C000 to $C800
;screen back char $C800 to $CBFF
;screen $CC00 to $CFFF
;sprites $D000 to $F7FF
;charset $F800 to $FFFF



Once that's down (and fits) the code changes are rather simple. A new byte is added per screen to allow for 8 flags. Bit 0 means no border, bit 1 means second charset.

Implementing borderless is easy, check the bit, and it set, skip the level border drawing:

          lda LEVEL_CONFIG
and #$01
bne .SkipBorder
;draw level border
lda #<‍LEVEL_BORDER_DATA
sta ZEROPAGE_POINTER_1
lda #>LEVEL_BORDER_DATA
sta ZEROPAGE_POINTER_1 + 1
jsr .BuildLevel

.SkipBorder
sta VIC_MEMORY_CONTROL



Actually, the second char set is quite similar to implement:

          ;.. snip
lda LEVEL_CONFIG
and #$02
beq .SetCharSet1

;set charset 2
lda #$30
-
sta VIC_MEMORY_CONTROL
jsr DisplayLevelNumber

rts

.SetCharSet1
lda #$3e
jmp -



Setting the second char set is as simple as adding another copy routine:

          ;take source address from CHARSET 2
lda #<‍CHARSET_2
sta ZEROPAGE_POINTER_1
lda #>CHARSET_2
sta ZEROPAGE_POINTER_1 + 1

;now copy
jsr CopyCharSet2

;------------------------------------------------------------
;copies charset from ZEROPAGE_POINTER_1 to ZEROPAGE_POINTER_2
;------------------------------------------------------------
!zone CopyCharSet2
CopyCharSet2
;set target address ($F000)
lda #$00
sta ZEROPAGE_POINTER_2
lda #$C0
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 #$08
bne .NextLine
cpy #$00
bne .PageBoundaryNotReached

;we have 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



The last one is a subtle change, due to the border not always used the ClearPlayScreen routine is adjusted to clear one more line.

Have fun!


step57.zip