; 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 3F7146D0h`). ; ; entry saves the interrupt's saved PC, replaces it with ret_hook, then ; tail-jumps to the stock handler 3F7146D0h; ; 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, @00000DC0h, 0 setf 16, 0, 0 movi 0C080h, a0, L move a0, @00000DB0h, 0 sub a0, a0 move a0, @01840800h, 0 ; counter move a0, @01840810h, 0 ; state (0 = black) popst rets ; ---- entry: point the interrupt's return at ret_hook, run stock handler --- entry: move a0, @01840860h, 1 ; save interrupted a0 setf 32, 0, 1 move *sp(020h), a0, 1 ; saved PC (SP -> ST, +20h -> PC) move a0, @01840820h, 1 ; orig_pc movi ret_hook, a0, L move a0, *sp(020h), 1 move @01840860h, a0, 1 jauc 3F7146D0h ; stock OS display handler ; ---- ret_hook: after the stock handler, draw, then resume ----------------- ret_hook: mmtm sp, a0,a1,a2,a3,a4,a5 ; field-independent A-reg save getst a0 setf 32, 0, 1 move a0, @01840840h, 1 ; interrupted ST dint setf 16, 0, 0 setf 32, 0, 1 move @01840800h, a0, 0 inc a0 move a0, @01840800h, 0 cmpi 0014h, a0 jrne draw sub a0, a0 move a0, @01840800h, 0 move @01840810h, a1, 0 cmpi 0, a1 jrne was_white movk 1, a1 jruc set_state was_white: sub a1, a1 set_state: move a1, @01840810h, 0 draw: move @01840810h, 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 @01840820h, a0, 1 ; orig_pc move a0, -*sp, 1 ; orig_pc at S-40h move *sp(020h), a0, 1 ; restore a0 from S-20h move @01840840h, 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