• Advertisement
  • entries
  • comments
  • views

A C64 Game - Step 57

Sign in to follow this  


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 # sta ZEROPAGE_POINTER_1
          lda #>LEVEL_BORDER_DATA
          sta ZEROPAGE_POINTER_1 + 1
          jsr .BuildLevel

          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


          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 + 1

          ;now copy
          jsr CopyCharSet2

;copies charset from ZEROPAGE_POINTER_1 to ZEROPAGE_POINTER_2
!zone 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
          lda (ZEROPAGE_POINTER_1),Y
          sta (ZEROPAGE_POINTER_2),Y
          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
          ;only copy 254 chars to keep irq vectors intact
          inc PARAM2
          lda PARAM2
          cmp #254
          beq .CopyCharsetDone
          ldx #$00
          jmp .NextLine

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

Sign in to follow this  

1 Comment

Recommended Comments

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

  • Advertisement