I am currently testing out some stuff in assembly with C64Studio and Vice and I noticed something with odd sprites.

My code starts at $1000 and my sprites at $2000 but when I try to lower the first sprite's address, I only get random stuff.
I tried to put the sprite at $1FC0 with #$7F as the pointer and $1080 with #$42.
But when I go up (like $2040/#$81 and $3000/#$C0), it works perfectly.

Here is the code I used:

    * = $1000

PRA  = $dc00 ; CIA#1 (Port Register A)
DDRA = $dc02 ; CIA#1 (Data Direction Register A)

PRB  = $dc01 ; CIA#1 (Port Register B)
DDRB = $dc03 ; CIA#1 (Data Direction Register B)

    lda #%11111111
    sta DDRA
    lda #%00000000
    sta DDRB
    lda #%011111111
    sta PRA

    jsr screen_clear
    lda #$FE ; light purple
    sta $D020 ;Frame
    lda #$F6 ; purple
    sta $D021 ;Center

    lda #$80 ;-> $2000
    sta $07F8 ;1(8) -> 8(F)

    lda #%00000001
    sta $D015

    lda #$95
    sta $D000
    sta $D001

    lda PRB
    and #%00010000
    bne main

    lda #$20
    sta $0400,x
    sta $0500,x 
    sta $0600,x 
    sta $06e8,x 
    lda #$00
    sta $d800,x
    sta $d900,x
    sta $da00,x
    sta $dae8,x
    bne screen_clear

* = $2000
!byte $c0,$00,$03,$81,$00,$01,$01,$3e
!byte $00,$01,$3e,$00,$01,$22,$00,$01
!byte $36,$00,$01,$3e,$00,$01,$71,$c0
!byte $03,$f7,$c0,$03,$f6,$c0,$03,$b4
!byte $40,$03,$b6,$c0,$01,$36,$c0,$00
!byte $3b,$80,$00,$21,$00,$00,$22,$00
!byte $00,$22,$00,$00,$22,$00,$00,$22
!byte $00,$80,$00,$01,$c0,$00,$03,$01

And these are the kind of sprites I get: (L:$2000/#$80 R:$1FC0/#$7F)
enter image description here

Is there some kind of limitation to where the sprites can be in memory or am I missing something else ?

  • 3
    I came here to say that this is an example of a well written question; you've explained exactly what you wanted, what went wrong and gave an example Commented Sep 4, 2017 at 10:14

1 Answer 1


Yes, there is a limitation. Due to incomplete address decoding, the VIC sees the bitmap font ROM between $1000 and $1FFF and $9000-$9FFF.

Here is the end of the font ROM (the C64/chargen file in VICE)

0FC0: 00 00 00 FF │ FF FF FF FF │ FF FF FF FF │ FF 00 00 00
0FD0: FE FC F9 93 │ 87 8F 9F FF │ FF FF FF FF │ 0F 0F 0F 0F
0FE0: F0 F0 F0 F0 │ FF FF FF FF │ E7 E7 E7 07 │ 07 FF FF FF    
0FF0: 0F 0F 0F 0F │ FF FF FF FF │ 0F 0F 0F 0F │ F0 F0 F0 F0

One can recognize the pattern of the garbage sprite on the right. It starts with 3 00 bytes, the first line of the sprite is transparent, followed by 10 FF bytes, that's 3-1/3 lines of white pixels, followed by 3 00 bytes etc.

The VIC chip has a view of the system memory that's quite different from that of the CPU. It can only address 16 kbytes of memory, and there is a banking mechanism, the two missing address bits are supplemented by GPIO pins of a CIA. Because the screen memory is at $0400, bank 0 is active, the VIC can access memory only between $0000 and $3FFF. The 4 kbytes of the font ROM must be mapped somewhere in this area, and the designers decided to place it from $1000 to $1FFF. If you try to relocate the screen from $0400 to $1000 (move your program out of the way first), then it'd show only garbage too, interpreting font bitmap patterns as character codes.

This mapping is present in banks 0 and 2, but not in banks 1 and 3. Switching to bank 2, memory between $9000-$9FFF will not be usable for screen or sprite data either. However, if you set VIC bank 1 ($4000-$7FFF) or bank 3 ($C000-$FFFF), then you can put the screen and sprite memory anywhere in the 16k bank, but then you have to install font data somewhere in RAM too, because the VIC can't access the font ROM at all.

The latter case is quite useful if you want to have a text screen with custom characters. Map in RAM for the processor at $D000 (with interrupts disabled), install custom font and sprite data there, then you can turn back I/O. RAM between $D000-$DFFF is too painful to use for anything else.

  • I wasn't expecting something like that, I'm surprised that the c64 wiki doesn't mention it on the "Memory Map" and/or "VIC" pages.
    – Azias
    Commented Sep 6, 2017 at 0:18
  • 1
    It's there, you're right, it should be better linked. Commented Sep 6, 2017 at 9:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .