mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
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:
parent
dd2463a440
commit
b500a0d477
@ -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.
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user