; 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