mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-27 11:30:19 +00:00
Merge pull request #66 from zbyti/master
Atari 800 System Off example, some minor refactor and more examples
This commit is contained in:
commit
fe094af912
@ -82,10 +82,14 @@ how to create a program made of multiple files loaded on demand
|
||||
|
||||
* [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
|
||||
|
||||
* [System Off example](a8/systemoff_example.mfk) – Programming example with ROM off
|
||||
|
||||
* [GR.8 Chessboard Benchmark](a8/gr8_chessboard_benchmark.mfk) – Chessboard drawing benchmark in GR.0
|
||||
|
||||
## Game Boy examples
|
||||
|
||||
* [GB test example](gb/gbtest.mfk) – a partial port of the NES example, with a rudimentary experimental text output implementation
|
||||
|
@ -4,7 +4,7 @@ const word dliAddr = $3100
|
||||
const array(byte) dl @ dlAddr = [
|
||||
$70,$70,$70,
|
||||
$42,$00,$40,2,2,2,2,$f0,2,2,2,2,
|
||||
$41,lo(dlAddr),hi(dlAddr)
|
||||
$41,@word[dlAddr]
|
||||
]
|
||||
|
||||
volatile word SDLST @ $230
|
@ -3,22 +3,20 @@ const word lms1Addr = $4000
|
||||
const word lms2Addr = $4060
|
||||
const word lms3Addr = $40c0
|
||||
|
||||
volatile word SDLST @ $230
|
||||
|
||||
array(byte) dl @ dlAddr = [
|
||||
$70,$70,$70,
|
||||
$52,lo(lms1Addr),hi(lms1Addr),
|
||||
$52,lo(lms2Addr),hi(lms2Addr),
|
||||
$52,lo(lms3Addr),hi(lms3Addr),
|
||||
$52, @word[lms1Addr],
|
||||
$52, @word[lms2Addr],
|
||||
$52, @word[lms3Addr],
|
||||
$41,lo(dlAddr),hi(dlAddr)
|
||||
]
|
||||
|
||||
noinline asm void wait(byte register(a) f) {
|
||||
clc
|
||||
adc os_RTCLOK+2
|
||||
rt_check:
|
||||
cmp os_RTCLOK+2
|
||||
bne rt_check
|
||||
adc os_RTCLOK.b2
|
||||
.rt_check:
|
||||
cmp os_RTCLOK.b2
|
||||
bne .rt_check
|
||||
rts
|
||||
}
|
||||
|
||||
@ -33,7 +31,7 @@ void main() {
|
||||
screeni = lms1Addr
|
||||
|
||||
wait(1)
|
||||
SDLST = dl.addr
|
||||
os_SDLST = dl.addr
|
||||
|
||||
while true {
|
||||
if hscroli == $b {
|
||||
|
109
examples/a8/gr8_chessboard_benchmark.mfk
Normal file
109
examples/a8/gr8_chessboard_benchmark.mfk
Normal file
@ -0,0 +1,109 @@
|
||||
const word lmsAddr1 = $8400
|
||||
const word lmsAddr2 = $6010
|
||||
|
||||
byte i@$e0, j@$e2, k@$e4, count@$e6
|
||||
pointer screen@$e8
|
||||
|
||||
const array(byte) dl align(256) = [
|
||||
$70,$70,$70,
|
||||
$4f,@word[lmsAddr2],
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,
|
||||
$4f,0,lmsAddr2.hi + $10,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,
|
||||
$0f,
|
||||
$41,@word[dl.addr]
|
||||
]
|
||||
|
||||
const array(byte) dlPrint align(16) = [
|
||||
$70,$70,$70,
|
||||
$42,@word[lmsAddr1],
|
||||
$41,@word[dlPrint.addr]
|
||||
]
|
||||
|
||||
asm void pause() {
|
||||
LDA os_RTCLOK.b2
|
||||
.rt_check:
|
||||
CMP os_RTCLOK.b2
|
||||
BEQ .rt_check
|
||||
RTS
|
||||
}
|
||||
|
||||
//print HEX value
|
||||
void printScore() {
|
||||
array(byte) tmp[2]
|
||||
byte iter
|
||||
|
||||
screen = lmsAddr1
|
||||
os_SDLST = dlPrint.addr
|
||||
|
||||
tmp[0] = count >> 4
|
||||
tmp[1] = count & %00001111
|
||||
|
||||
for iter:tmp {
|
||||
if tmp[iter] < 10 {
|
||||
screen[iter] = tmp[iter] + $10
|
||||
} else {
|
||||
screen[iter] = tmp[iter] + $17
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawBoard() {
|
||||
screen = lmsAddr2
|
||||
os_SDLST = dl.addr
|
||||
|
||||
for i,7,downto,0 {
|
||||
for j,23,downto,0 {
|
||||
for k,3,downto,0 {
|
||||
screen[0] = 255
|
||||
screen[1] = 255
|
||||
screen[2] = 255
|
||||
screen += 6
|
||||
}
|
||||
screen += 16
|
||||
}
|
||||
if (i & 1) != 0 {
|
||||
screen += 3
|
||||
} else {
|
||||
screen -= 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
count = 0
|
||||
|
||||
pause()
|
||||
os_RTCLOK.b2 = 0
|
||||
|
||||
while os_RTCLOK.b2 < 150 {
|
||||
drawBoard()
|
||||
count += 1
|
||||
}
|
||||
|
||||
printScore()
|
||||
|
||||
while (true){}
|
||||
}
|
122
examples/a8/systemoff_example.mfk
Normal file
122
examples/a8/systemoff_example.mfk
Normal file
@ -0,0 +1,122 @@
|
||||
// ================================================
|
||||
//
|
||||
// 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 void dli_second(){
|
||||
gtia_colpf2 = $de
|
||||
antic_wsync = $de
|
||||
vdslst = dli_first.addr
|
||||
}
|
||||
|
||||
// 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 procedure
|
||||
void main(){
|
||||
system_off() // turn off OS
|
||||
|
||||
wait(100) // waint 2 sec on PAL for fun
|
||||
antic_dlist = dl.addr // set custom display list
|
||||
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