joeylib2/examples/spacetaxi/stMarshalIigs.s

354 lines
6 KiB
ArmAsm

; stMarshalIigs.s - Space Taxi's stSimMarshal for the Apple IIgs.
;
; GAS syntax for the llvm-mos w65816 toolchain (see src/iigs/peislam.s
; for the conventions). The C version copies eight sprites' shadow
; registers into the displayed frame through far pointers, which the
; w65816 backend turns into ~5000 cycles of pointer re-materialisation
; per tick (5% of a ride frame). This is the same copy as straight-line
; [dp],y moves: ~700 cycles.
;
; void stSimMarshalIigs(const StMarshalArgsT *args)
; args (A = low word, X = bank) points at { spr, frame, multi }:
; +0 const StSpriteT *spr (32-bit: low word, bank word)
; +4 StFrameT *frame
; +8 uint8_t multi
; StSpriteT (6 bytes): col, msb, row, enable, ptr, color.
; StFrameT: x[8] (u16, +0), y[8] (+16), ptr[8] (+24), color[8] (+32),
; enableMask (+40), multiMask (+41).
; stSim.c checks these layouts at compile time.
;
; Every store runs with M=16 and writes two bytes: the byte after each
; single-byte field gets a junk high byte that the NEXT store repairs,
; so the blocks run in order x, y, ptr, color and finish with the
; enable/multi word. The last colour store's junk lands on enableMask,
; which the final word overwrites.
;
; Direct-page $E0-$EF are the compiler's own per-function scratch
; (re-set before every use, never live across a call); $C0 is left alone.
.section .text.stSimMarshalIigs,"ax"
.globl stSimMarshalIigs
stSimMarshalIigs:
php
rep #0x30
.a16
.i16
sta 0xe0 ; args low
txa
sta 0xe2 ; args bank
ldy #0
lda [0xe0],y
sta 0xe4 ; spr low
ldy #2
lda [0xe0],y
sta 0xe6 ; spr bank
ldy #4
lda [0xe0],y
sta 0xe8 ; frame low
ldy #6
lda [0xe0],y
sta 0xea ; frame bank
ldy #8
lda [0xe0],y
and #0xff
sta 0xec ; multi
stz 0xee ; enable mask accumulator
; sprite 0: x = (msb ? 0x100 : 0) | col; enable bit
ldy #0
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX0clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX0st
mX0clr:
lda 0xf0
and #0x00ff
mX0st:
ldy #0
sta [0xe8],y
ldy #3
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE0off
lda 0xee
ora #1
sta 0xee
mE0off:
; sprite 1: x = (msb ? 0x100 : 0) | col; enable bit
ldy #6
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX1clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX1st
mX1clr:
lda 0xf0
and #0x00ff
mX1st:
ldy #2
sta [0xe8],y
ldy #9
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE1off
lda 0xee
ora #2
sta 0xee
mE1off:
; sprite 2: x = (msb ? 0x100 : 0) | col; enable bit
ldy #12
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX2clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX2st
mX2clr:
lda 0xf0
and #0x00ff
mX2st:
ldy #4
sta [0xe8],y
ldy #15
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE2off
lda 0xee
ora #4
sta 0xee
mE2off:
; sprite 3: x = (msb ? 0x100 : 0) | col; enable bit
ldy #18
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX3clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX3st
mX3clr:
lda 0xf0
and #0x00ff
mX3st:
ldy #6
sta [0xe8],y
ldy #21
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE3off
lda 0xee
ora #8
sta 0xee
mE3off:
; sprite 4: x = (msb ? 0x100 : 0) | col; enable bit
ldy #24
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX4clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX4st
mX4clr:
lda 0xf0
and #0x00ff
mX4st:
ldy #8
sta [0xe8],y
ldy #27
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE4off
lda 0xee
ora #16
sta 0xee
mE4off:
; sprite 5: x = (msb ? 0x100 : 0) | col; enable bit
ldy #30
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX5clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX5st
mX5clr:
lda 0xf0
and #0x00ff
mX5st:
ldy #10
sta [0xe8],y
ldy #33
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE5off
lda 0xee
ora #32
sta 0xee
mE5off:
; sprite 6: x = (msb ? 0x100 : 0) | col; enable bit
ldy #36
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX6clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX6st
mX6clr:
lda 0xf0
and #0x00ff
mX6st:
ldy #12
sta [0xe8],y
ldy #39
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE6off
lda 0xee
ora #64
sta 0xee
mE6off:
; sprite 7: x = (msb ? 0x100 : 0) | col; enable bit
ldy #42
lda [0xe4],y ; col | msb<<8
sta 0xf0
and #0xff00
beq mX7clr
lda 0xf0
and #0x00ff
ora #0x0100
bra mX7st
mX7clr:
lda 0xf0
and #0x00ff
mX7st:
ldy #14
sta [0xe8],y
ldy #45
lda [0xe4],y ; enable | ptr<<8
and #0xff
beq mE7off
lda 0xee
ora #128
sta 0xee
mE7off:
; y[] block (16-bit stores; the junk high byte is repaired by the next store)
ldy #2
lda [0xe4],y
ldy #16
sta [0xe8],y
ldy #8
lda [0xe4],y
ldy #17
sta [0xe8],y
ldy #14
lda [0xe4],y
ldy #18
sta [0xe8],y
ldy #20
lda [0xe4],y
ldy #19
sta [0xe8],y
ldy #26
lda [0xe4],y
ldy #20
sta [0xe8],y
ldy #32
lda [0xe4],y
ldy #21
sta [0xe8],y
ldy #38
lda [0xe4],y
ldy #22
sta [0xe8],y
ldy #44
lda [0xe4],y
ldy #23
sta [0xe8],y
; ptr[] block (16-bit stores; the junk high byte is repaired by the next store)
ldy #4
lda [0xe4],y
ldy #24
sta [0xe8],y
ldy #10
lda [0xe4],y
ldy #25
sta [0xe8],y
ldy #16
lda [0xe4],y
ldy #26
sta [0xe8],y
ldy #22
lda [0xe4],y
ldy #27
sta [0xe8],y
ldy #28
lda [0xe4],y
ldy #28
sta [0xe8],y
ldy #34
lda [0xe4],y
ldy #29
sta [0xe8],y
ldy #40
lda [0xe4],y
ldy #30
sta [0xe8],y
ldy #46
lda [0xe4],y
ldy #31
sta [0xe8],y
; color[] block (16-bit stores; the junk high byte is repaired by the next store)
ldy #5
lda [0xe4],y
ldy #32
sta [0xe8],y
ldy #11
lda [0xe4],y
ldy #33
sta [0xe8],y
ldy #17
lda [0xe4],y
ldy #34
sta [0xe8],y
ldy #23
lda [0xe4],y
ldy #35
sta [0xe8],y
ldy #29
lda [0xe4],y
ldy #36
sta [0xe8],y
ldy #35
lda [0xe4],y
ldy #37
sta [0xe8],y
ldy #41
lda [0xe4],y
ldy #38
sta [0xe8],y
ldy #47
lda [0xe4],y
ldy #39
sta [0xe8],y
; enableMask | multiMask<<8
lda 0xec
xba
and #0xff00
ora 0xee
ldy #40
sta [0xe8],y
plp
rtl