Files
vt1200/dwt/visual/blink2.asm
T

120 lines
3.1 KiB
NASM

; blinkpc.asm -- resident blink that draws AFTER the stock display handler.
;
; Hook: the firmware's DI RAM trampoline at bit 00000DB0h
; (RLONG(0xFFFFFEA0) = 00000DB0h, stub `JA 3F714530h`).
;
; entry saves the interrupt's saved PC, replaces it with ret_hook, then
; tail-jumps to the stock handler 3F714530h;
; ret_hook runs when the stock handler `reti`s, draws the box, and returns
; to the original PC with `rets 2` (the 2 skips the temporary a0
; slot and keeps the interrupted stack balanced).
;
; Drawing after the handler matters: a draw before it is wiped by the handler's
; own screen work (measured: blink.asm counter runs, no box in any frame).
;
; Box: framebuffer (256,400), 64x64, white Terminal Manager body.
; State toggles every 0014h invocations (~20 frames at ~1 DI/frame idle).
;
; Linked at bit 01840000h by dwt/visual/build.sh.
.text
_start: ; install, called by rdebug `jump`
pushst
dint
setf 32, 0, 0
movi entry, a0, L
move a0, @00000F40h, 0
setf 16, 0, 0
movi 0C080h, a0, L
move a0, @00000F30h, 0
sub a0, a0
move a0, @01840E00h, 0 ; counter
move a0, @01840E10h, 0 ; state (0 = black)
movi 0Ah, a0, L
move a0, @01840E30h, 0 ; skip the first 10 DI entries
popst
rets
; ---- entry: point the interrupt's return at ret_hook, run stock handler ---
entry:
move a0, @01840E60h, 1 ; save interrupted a0
setf 16, 0, 0
move @01840E30h, a0, 0 ; settle counter
cmpi 0, a0
jreq active
dec a0
move a0, @01840E30h, 0
setf 32, 0, 1
move @01840E60h, a0, 1
jauc 3F714530h ; still settling: stock handler only
active:
setf 32, 0, 1
move *sp(020h), a0, 1 ; saved PC (SP -> ST, +20h -> PC)
move a0, @01840E20h, 1 ; orig_pc
movi ret_hook, a0, L
move a0, *sp(020h), 1
move @01840E60h, a0, 1
jauc 3F714530h ; stock OS display handler
; ---- ret_hook: after the stock handler, draw, then resume -----------------
ret_hook:
dint ; first instruction: close the reti->hook race
mmtm sp, a0,a1,a2,a3,a4,a5 ; field-independent A-reg save
getst a0
setf 32, 0, 1
move a0, @01840E40h, 1 ; interrupted ST
setf 16, 0, 0
setf 32, 0, 1
move @01840E00h, a0, 0
inc a0
move a0, @01840E00h, 0
cmpi 0014h, a0
jrne draw
sub a0, a0
move a0, @01840E00h, 0
move @01840E10h, a1, 0
cmpi 0, a1
jrne was_white
movk 1, a1
jruc set_state
was_white:
sub a1, a1
set_state:
move a1, @01840E10h, 0
draw:
move @01840E10h, a1, 0
cmpi 0, a1
jrne pat_white
sub a2, a2
jruc pat_ready
pat_white:
movi 0FFFFh, a2, L
pat_ready:
movi 04064100h, a3, L
movi 64, a4, L
movi 4, a5, L
drow:
move a5, a1
dword:
move a2, *a3+, 0
dsjs a1, dword
addi 03C0h, a3
dsjs a4, drow
; restore the A registers (field 1 is still 32)
mmfm sp, a0,a1,a2,a3,a4,a5
; leave with [ST][orig_pc] and the temporary a0 slot skipped by rets 2
setf 32, 0, 1
mmtm sp, a0 ; a0 slot at S-20h
move @01840E20h, a0, 1 ; orig_pc
move a0, -*sp, 1 ; orig_pc at S-40h
move *sp(020h), a0, 1 ; restore a0 from S-20h
move @01840E40h, a0, 1 ; interrupted ST (temporarily in a0)
move a0, -*sp, 1 ; ST at S-60h
move *sp(040h), a0, 1 ; restore a0 from S-20h
popst ; restore interrupted ST/IE
rets 2 ; pop orig_pc, skip the a0 slot
.end