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:
Actually, the second char set is quite similar to implement:
Setting the second char set is as simple as adding another copy routine:
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!
Previous Step Next Step
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!
Previous Step Next Step
Attached Files
-
step57.zip (81.27K)
downloads: 44
Create a custom theme




