In general: code like you want. If everything works within the framework noone cares. If it doesn't you could make Spider cry, who is good friends with Jesus, so it's like you make Jesus cry. Oh and of course: every time you deliver code that doesn't work with the framework A KITTEN DIES!
Do *not* use 'SEI' !!!
There may be certain situations where you might think you need SEI. In those cases be assured: You are wrong. You will never ever need to use SEI when coding within the framework.
As the framework uses the famous loader by Krill, doing VIC bank switching the usual way will break the loader. The "Krill-Safe" method for changing the VIC bank is:
; $dd00 = %xxxxxx11 -> bank0: $0000-$3fff ; $dd00 = %xxxxxx10 -> bank1: $4000-$7fff ; $dd00 = %xxxxxx01 -> bank2: $8000-$bfff ; $dd00 = %xxxxxx00 -> bank3: $c000-$ffff lda #%000000xx ; <- your desired VIC bank value, see above sta $dd00
A little hint: if you don't know your final memory layout and vic bank setup when starting your part you could setup the vic bank, video memory and charset like so:
vicbank = $4000 charset = vicbank+$0000 vidmem0 = vicbank+$0800 sprite_data = vicbank+$0c00 sprite_base = <((sprite_data-vicbank)/$40) lda #<!(vicbank/$4000) & 3 sta $dd00 lda # <(((vidmem0-vicbank)/$400) << 4)+ <(((charset-vicbank)/$800) << 1) sta $d018
Then you usually only have to change the value of the 'vicbank' label/symbol (and eventually the offset values) later.
↑ back to top ↑At the time of writing there is no safe way to create real random numbers within the framework. You obviously can't use SID, as there's a tune playing, but you also can't use the CIA because the framwork does a CIA timer setup for 63 cycle counting at init.
Consider the use of pseudo-random numbers or even a random-table instead. In many cases this will be "random enough". In a demo you usually want the exact same behaviour anyway everytime it is executed.
$0000 - $0001 | as usual | FRAMEWORK/PARTS |
---|---|---|
$0002 - $0004 | zeropage for irq save/restore A,X,Y | FRAMEWORK/PARTS |
$0005 - $00DF | zeropage free for use in parts | PARTS |
$00E0 - $00FF | zeropage used by framework | FRAMEWORK |
$0100 - $01FF | stack | FRAMEWORK/PARTS |
$0200 - $02FF | framework code | FRAMEWORK |
$0300 - $03FF | framework irq | FRAMEWORK |
$0400 - $07FF | free for use in parts (at runtime) | FRAMEWORK INIT/PARTS |
$0800 - $0BFF | krill loader resident | FRAMEWORK |
$0C00 - $1FFD | space for music | FRAMEWORK |
$1FFE - $1FFF | lo/hi pointer to part startaddress | PARTS |
$2000 - $FFF7 | free for use in parts (at runtime)* | PARTS |
$FFF8 - $FFFF | vectors | FRAMEWORK/PARTS |
* $D000-$FFF7 is free to use at runtime, but uncrunched code and data should fit into memory between $1FFE - $CFFF, as loading into I/O - Kernal area is not activated.
↑ back to top ↑fw_irq_lo | lo-byte of your first irq in the frame |
---|---|
fw_irq_hi | hi-byte of your first irq in the frame |
fw_d011_value | $d011 value that is set at the end of the framework irq |
fw_d012_value | $d012 value that is set at the end of the framework irq |
fw_color_d020 | value of $d020 to be set at line $000 by framework irq |
fw_color_d021 | value of $d021 to be set at line $000 by framework irq |
fw_global_ct fw_global_ct+1 fw_global_ct+2 |
continuous 24 bit counter ( READONLY!!!! ) |
fw_preserve_screen | if set to 1 the framework will keep the current values of $d011, $d016, $d018 while loading the next part. i.e. for keeping a PETSCII on the screen make sure that fw_d011_value is setup correctly!!! |
fw_irq fw_irq_addr |
framework irq |
---|---|
fw_wait_irq | waits until framework irq is over (at least 1 frame) |
In order to use the framework you have to at least include the symbols/labels from frameworksymbols.inc and put the entry point of your code into addresses $1ffe/$1fff (lo/hi).
Of course you usually also want to be able to test your part standalone. Therefore include the framework-noloader.prg at $0400 if the RELEASE variable is 0.
Usually Spider will deliver the soundtrack not only as a whole, but also split into snippets to be found in src/framework/music/. So if you want to sync your part to a specific music section, just include the SID file you want.
ATTENTION: the framework-noloader.prg is already build with the whole tune, so acme will give you a warning that you overwrite memory. Therefore it's also important to include the SID file afterwards.
!source "../../bin/framework/frameworksymbols.inc" !if RELEASE = 0 { *= $0400 !bin "../../bin/framework/framework-noloader.prg",,2 *= fw_music_init !bin "../framework/music/TUNESNIPPET.sid",,$7e } *= $1ffe !byte <code_start !byte >code_start↑ back to top ↑
As there is already a raster-irq running when your code starts you must not setup your IRQ in the usual way. Instead you have to write the values you need into the framework registers.
fw_irq_lo is the pendant to $fffe, fw_irq_hi the pendant to $ffff and fw_d011_value/fw_d012_value of course are the values for $d011/$d012.
ATTENTION: Be aware that after this setup your IRQ fires the first time in the next frame, no matter what value for $d012 you have given. So if you want to have a synced mainloop afterwards, better jsr fw_wait_irq again.
jsr fw_wait_irq lda #<MYIRQ sta fw_irq_lo lda #>MYIRQ sta fw_irq_hi lda #MYIRQ_RASTERLINE sta fw_d012_value lda #MY_D011_VALUE sta fw_d011_value↑ back to top ↑
If you don't need any IRQ and all your routines will fit into one frame and want to to a part in the oldskewl 'rasterpolling' way, you can easily do that.
But there are a few things you should be aware of:
Here's an example how a 'typical' rasterpolling mainloop could look like:
mainloop: jsr fw_wait_irq ; <- RASTER around $011-$01A here ; .. some code in the top border .. lda #$32 cmp $d012 beq *-3 ; <- RASTER around the beginning of the screen here ; .. some code in the screen .. lda #$fe cmp $d012 beq *-3 ; <- RASTER around the end of the screen here ; .. some code in the lower border .. ; !IMPORTANT! be sure lower border code is done *before* RASTER wraps to $000 jmp mainloop↑ back to top ↑