honeylisp/ssc/iigs/graphics.fnl
Jeremy Penner d2ff69258f implement draw-object & pei slamming
asm: allow computed addresses, not just immediate mode values
map llissp source to assembly
2021-09-10 22:55:47 -04:00

49 lines
2.2 KiB
Fennel

; IIgs graphical architecture:
; PREMISE: All small-scale bitmapped graphics are encoded as code that pushes the graphics onto the stack,
; which has been aligned to the appropriate place to draw said graphics.
; Jump tables are stored in the main code segment so that eg. tiles can be easily calculated by index, and
; so we don't have to explicitly pass longs to a regular function.
(import-macros {:sss ! : compile} :ssc.macros)
(local lume (require :lib.lume))
(local {: countiter} (require :lib.util))
#(compile $1
(global word draw-object-saved-stack 0)
(fn draw-object (screen object)
(asm (sei) ; disable interrupts
(lda object) (sta [{:abs #(+ ($1:lookup-addr :draw-object-current-object-jump) 1)}])
(tsc) (sta draw-object-saved-stack)
(lda screen) (tcs)
(lda :0xc068) (ora 0x30) (sta :0xc068) ; set altzp
draw-object-current-object-jump
(jmp draw-object)
draw-object-finished (export draw-object-finished)
(lda :0xc068) (and 0xffcf) (sta :0xc068) ; clear altzp
(lda draw-object-saved-stack) (tcs)
(cli))) ; enable interrupts
(form drawfn [(fn [ssc name ...]
(assert (not (ssc:defining?)) "drawfn must be defined at top level")
(set ssc.locals nil) ; locals cannot be used
(local asm (ssc:expr-poly (lume.concat [:do ...] [[:asm [:jmp :draw-object-finished]]])))
(set ssc.locals [])
(ssc:expr-poly [:form name (fn [ssc] (assert (= ssc.locals nil) (.. name " must be called from a drawfn")) [:jmp name])])
(ssc:expr-poly [:getter name [:ref name]])
(ssc.org:append name asm))])
(drawfn pei-slam-tile
(asm (tdc) (tax) ; store direct page register in X
(tsc) (sec) (sbc 255) (tcd)
[(lume.concat [:block] (icollect [_ (countiter 16)]
[(! block (pei (:d0xfe)) (pei (:d0xfc)) (pei (:d0xfa)) (pei (:d0xf8))
(tsc) (sbc 152) (tcs) (sbc 255) (tcd))]))]
(txa) (tcd))) ; restore direct page register
(drawfn pei-slam-scanline
(asm (tdc) (tax) ; store direct page register in X
(tsc) (sec) (sbc 255) (tcd)
[(lume.concat [:block] (icollect [offset (countiter 0xfe (- 0x100 160) -2)] [:pei [(.. :d offset)]]))]
(txa) (tcd))) ; restore direct page register
)