Jump to content
  • 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

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!