Skip to content

Commit

Permalink
c64: added a couple of routines that calculate the correct memory loc…
Browse files Browse the repository at this point in the history
…ations for video ram and sprite pointers etc. based on current VIC-II memory setup.

the examples with sprites, now use it.
  • Loading branch information
irmen committed Sep 8, 2023
1 parent dd2463a commit b500a0d
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 14 deletions.
7 changes: 4 additions & 3 deletions compiler/res/prog8lib/c64/graphics.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
Expand Down
36 changes: 35 additions & 1 deletion compiler/res/prog8lib/c64/syslib.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion examples/c64/balloonflight.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/c64/cube3d-sprites.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion examples/c64/sprites.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
13 changes: 6 additions & 7 deletions examples/c64/turtle-gfx.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
2 changes: 1 addition & 1 deletion examples/c64/wizzine.p8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit b500a0d

Please sign in to comment.