c64: added a couple of routines that calculate the correct memory locations for video ram and sprite pointers etc. based on current VIC-II memory setup.

the examples with sprites, now use it.
This commit is contained in:
Irmen de Jong 2023-09-08 21:27:38 +02:00
parent dd2463a440
commit b500a0d477
7 changed files with 49 additions and 14 deletions

View File

@ -10,15 +10,16 @@ graphics {
const uword WIDTH = 320
const ubyte HEIGHT = 200
const uword BITMAP_ADDRESS = $6000 ; MUST BE IN REGULAR RAM if you are not messing with ROM/RAM banking.
const uword CHARS_ADDRESS = $5c00 ; must be in same vic bank as the bitmap
const uword BITMAP_ADDRESS = $6000 ; MUST BE IN REGULAR RAM if you are not messing with ROM/RAM banking. (and $2000-aligned)
; note: this constant is also used in a asm multiplication table below!
const uword CHARS_ADDRESS = $5c00 ; must be in same vic memory bank as the bitmap.
sub enable_bitmap_mode() {
; enable bitmap screen, erase it and set colors to black/white.
clear_screen(1, 0)
c64.SCROLY = %00111011 ; enable bitmap graphics mode
c64.SCROLX = %00001000 ; 40 column mode, no scrolling, multicolor bitmap off
c64.VMCSB = (lsb(CHARS_ADDRESS >> 6) & $F0) | (((BITMAP_ADDRESS & $3fff) / $0800) << 1) ; set bitmap address
c64.VMCSB = (lsb(CHARS_ADDRESS >> 6) & $F0) | (lsb((BITMAP_ADDRESS & $3fff) / $0800) << 1) ; set bitmap address
c64.CIA2DDRA |= %11
c64.CIA2PRA = lsb(BITMAP_ADDRESS >> 14) ^ 3 ; set VIC bank.
}

View File

@ -136,7 +136,8 @@ c64 {
%option no_symbol_prefixing
; the default locations of the 8 sprite pointers (store address of sprite / 64)
; (depending on the VIC bank and screen ram address selection these can be shifted around though)
; (depending on the VIC bank and screen ram address selection these can be shifted around though,
; see the two routines after this for a dynamic way of determining the correct memory location)
&ubyte SPRPTR0 = 2040
&ubyte SPRPTR1 = 2041
&ubyte SPRPTR2 = 2042
@ -285,6 +286,39 @@ c64 {
; ---- end of SID registers ----
sub get_vic_memory_base() -> uword {
; one of the 4 possible banks. $0000/$4000/$8000/$c000.
c64.CIA2DDRA |= %11
return ((c64.CIA2PRA & 3) ^ 3) as uword << 14
}
sub get_char_matrix_ptr() -> uword {
; Usually the character screen matrix is at 1024-2039 (see above)
; However the vic memory configuration can be altered and this moves these registers with it.
; So this routine determines it dynamically from the VIC memory setup.
uword chars_matrix_offset = (c64.VMCSB & $f0) as uword << 6
return get_vic_memory_base() + chars_matrix_offset
}
sub get_bitmap_ptr() -> uword {
return get_vic_memory_base() + ((c64.VMCSB & %00001000) as uword << 10)
}
sub get_sprite_addr_ptrs() -> uword {
; Usually the sprite address pointers are at addresses 2040-2047 (see above)
; However the vic memory configuration can be altered and this moves these registers with it.
; So this routine determines it dynamically from the VIC memory setup.
return get_char_matrix_ptr() + 1016
}
sub set_sprite_ptr(ubyte sprite_num, uword sprite_data_address) {
; Sets the sprite data pointer to the given address.
; Because it takes some time to calculate things based on the vic memory setup,
; its only suitable if you're not continuously changing the data address.
; Otherwise store the correct sprite data pointer location somewhere yourself and reuse it.
@(get_sprite_addr_ptrs() + sprite_num) = lsb(sprite_data_address / 64)
}
}
sys {

View File

@ -15,7 +15,7 @@ main {
ubyte perform_scroll = false
sub start() {
c64.SPRPTR[0] = $0f00 / 64
c64.set_sprite_ptr(0, $0f00) ; alternatively, set directly: c64.SPRPTR[0] = $0f00 / 64
c64.SPENA = 1
c64.SP0COL = 14
c64.SPXY[0] = 80

View File

@ -171,6 +171,7 @@ main {
c64.SPXYW[i] = mkword(sy, sx)
; because we want speed, we don't use the dynamic c64.set_sprite_ptr() here
if(zc < 30*128)
c64.SPRPTR[i] = $2000/64 +1 ; large ball
else

View File

@ -40,7 +40,7 @@ main {
ubyte @zp i
for i in 0 to 7 {
c64.SPRPTR[i] = $0a00 / 64
c64.set_sprite_ptr(i, $0a00) ; alternatively, set directly: c64.SPRPTR[i] = $0a00 / 64
c64.SPXY[i*2] = 50+25*i
c64.SPXY[i*2+1] = math.rnd()
}

View File

@ -30,19 +30,18 @@ turtle {
float angle
bool pendown
const uword SPRITE_MEMORY = $5800
sub init() {
xpos = 160.0
ypos = 100.0
angle = 0.0
pendown = true
const uword SPRITE_MEMORY = $5800
const uword SPRITE_ADDR_POINTERS = (graphics.CHARS_ADDRESS & $fc00) + 1016 ; no longer the default location 2040!
sys.memcopy(&turtlesprite, SPRITE_MEMORY, len(turtlesprite))
@(SPRITE_ADDR_POINTERS) = (SPRITE_MEMORY & $3fff) / 64
c64.SPENA = 1
c64.SP0COL = 5
sys.memcopy(&turtlesprite, SPRITE_MEMORY, len(turtlesprite)) ; copy the sprite pixel data
c64.set_sprite_ptr(0, SPRITE_MEMORY) ; use dynamic setter because of changed vic memory layout
c64.SPENA = 1 ; sprites on
c64.SP0COL = 5 ; green sprite
update_turtle_sprite()
}

View File

@ -35,7 +35,7 @@ main {
sub start() {
ubyte i
for i in 0 to 7 {
c64.SPRPTR[i] = $0a00/64
c64.set_sprite_ptr(i, $0a00) ; alternatively, set directly: c64.SPRPTR[i] = $0a00 / 64
}
c64.SPENA = 255 ; enable all sprites
sys.set_rasterirq(&irq.irqhandler, 230, true) ; enable animation