mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-26 05:30:18 +00:00
A8 system off example and some minor refactor
This commit is contained in:
parent
88e74906b6
commit
e8a50dc610
@ -82,10 +82,12 @@ how to create a program made of multiple files loaded on demand
|
|||||||
|
|
||||||
* [Rainbow example](a8/rainbow.mfk) – simple scrolling rasterbars
|
* [Rainbow example](a8/rainbow.mfk) – simple scrolling rasterbars
|
||||||
|
|
||||||
* [DLI example](a8/dli-example.mfk) – simple display list and display list interrupt example
|
* [DLI example](a8/dli_example.mfk) – simple display list and display list interrupt example
|
||||||
|
|
||||||
* [Scroll example](a8/endless_scroll.mfk) – simple horizontal scroll example
|
* [Scroll example](a8/endless_scroll.mfk) – simple horizontal scroll example
|
||||||
|
|
||||||
|
* [System Off example](a8/systemoff_example.mfk) – Programming example with ROM off
|
||||||
|
|
||||||
## Game Boy examples
|
## Game Boy examples
|
||||||
|
|
||||||
* [GB test example](gb/gbtest.mfk) – a partial port of the NES example, with a rudimentary experimental text output implementation
|
* [GB test example](gb/gbtest.mfk) – a partial port of the NES example, with a rudimentary experimental text output implementation
|
||||||
|
129
examples/a8/systemoff_example.mfk
Normal file
129
examples/a8/systemoff_example.mfk
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// ================================================
|
||||||
|
//
|
||||||
|
// antic_nmien = $40
|
||||||
|
//
|
||||||
|
// %01000000 $40 VBI
|
||||||
|
// %10000000 $80 DLI
|
||||||
|
// %11000000 $c0 VBI + DLI
|
||||||
|
//
|
||||||
|
// ================================================
|
||||||
|
//
|
||||||
|
// pia_portb = $fe
|
||||||
|
//
|
||||||
|
// PORTB_BASIC_OFF + PORTB_SELFTEST_OFF + %01111100
|
||||||
|
//
|
||||||
|
// PORTB_SELFTEST_OFF = %10000000; portb bit value to turn Self-Test off
|
||||||
|
// PORTB_BASIC_OFF = %00000010; portb bit value to turn Basic off
|
||||||
|
// PORTB_SYSTEM_ON = %00000001; portb bit value to turn System on
|
||||||
|
//
|
||||||
|
// ================================================
|
||||||
|
|
||||||
|
byte nmien = $c0
|
||||||
|
|
||||||
|
byte rti @ $15 // default routine for VBI & DLI
|
||||||
|
word vbivec @ $10 // vector for VBI
|
||||||
|
word vdslst @ $16 // vector for DLI
|
||||||
|
|
||||||
|
// simple display list; LMS = $e000
|
||||||
|
const array(byte) dl align(32) = [
|
||||||
|
$70,$70,$70,
|
||||||
|
$42,$00,$e0,2,2,$f0,2,2,2,$f0,2,2,2,
|
||||||
|
$41,@word[dl.addr]
|
||||||
|
]
|
||||||
|
|
||||||
|
// init procedure
|
||||||
|
void system_off(){
|
||||||
|
asm { sei } // turn off IRQ
|
||||||
|
antic_nmien = 0 // turn off ANTIC
|
||||||
|
pia_portb = $fe // turn off ROM
|
||||||
|
rti = $40 // set RTI opcode
|
||||||
|
vbivec = rti.addr // set address for VBI routine
|
||||||
|
vdslst = rti.addr // set address for DLI routine
|
||||||
|
os_NMIVEC = nmi.addr // set address for custom NMI handler
|
||||||
|
antic_nmien = nmien
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom NMI handler
|
||||||
|
asm void nmi(){
|
||||||
|
bit antic_nmist // test nmist
|
||||||
|
bpl .vblclock // if 7-bit not set handle VBI
|
||||||
|
jmp (vdslst) // indirect jump to DLI routine
|
||||||
|
.vblclock: // RTCLOK maintainer
|
||||||
|
inc os_RTCLOK.b2
|
||||||
|
bne .tickend
|
||||||
|
inc os_RTCLOK.b1
|
||||||
|
bne .tickend
|
||||||
|
inc os_RTCLOK.b0
|
||||||
|
.tickend:
|
||||||
|
jmp (vbivec) // indirect jump to VBI routine
|
||||||
|
}
|
||||||
|
|
||||||
|
// example dli
|
||||||
|
interrupt asm void dli_first(){
|
||||||
|
pha
|
||||||
|
lda #$2a
|
||||||
|
sta gtia_colpf2
|
||||||
|
sta antic_wsync
|
||||||
|
lda #<dli_second.addr
|
||||||
|
sta vdslst.lo
|
||||||
|
lda #>dli_second.addr
|
||||||
|
sta vdslst.hi
|
||||||
|
pla
|
||||||
|
rti
|
||||||
|
}
|
||||||
|
|
||||||
|
// example dli
|
||||||
|
interrupt asm void dli_second(){
|
||||||
|
pha
|
||||||
|
lda #$de
|
||||||
|
sta gtia_colpf2
|
||||||
|
sta antic_wsync
|
||||||
|
lda #<dli_first.addr
|
||||||
|
sta vdslst.lo
|
||||||
|
lda #>dli_first.addr
|
||||||
|
sta vdslst.hi
|
||||||
|
pla
|
||||||
|
rti
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for VBLANK
|
||||||
|
asm void pause() {
|
||||||
|
lda os_RTCLOK.b2
|
||||||
|
.rt_check:
|
||||||
|
cmp os_RTCLOK.b2
|
||||||
|
beq .rt_check
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait 0-255 frames
|
||||||
|
noinline asm void wait(byte register(a) f) {
|
||||||
|
clc
|
||||||
|
adc os_RTCLOK.b2
|
||||||
|
.rt_check:
|
||||||
|
cmp os_RTCLOK.b2
|
||||||
|
bne .rt_check
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
// example vbi
|
||||||
|
interrupt void vbi(){
|
||||||
|
gtia_colpf2 = os_RTCLOK.b2
|
||||||
|
}
|
||||||
|
|
||||||
|
// main procdure
|
||||||
|
void main(){
|
||||||
|
system_off(); // turn off OS
|
||||||
|
|
||||||
|
wait(100) // waint 2 sec on PAL for fun
|
||||||
|
antic_dlist = dl.addr // set custom displaylist
|
||||||
|
wait(100 ) // waint 2 sec on PAL for the lulz
|
||||||
|
vbivec = vbi.addr // set custom VBI
|
||||||
|
wait(100) // waint 2 sec on PAL because we can
|
||||||
|
vdslst = dli_first.addr // set custom DLI
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
wait(100)
|
||||||
|
nmien ^= %10000000 // toggle DLI
|
||||||
|
antic_nmien = nmien
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user