; ---------------------------------------------------------------- one block ; \1 = right-shift needed to bring this block's 2 mode bits to bits 1-0. BLOCK macro move.b (a1),d0 ifne \1 lsr.b #\1,d0 endc and.w #3,d0 beq .sk\@ ; 00 SKIP -- the median block subq.w #1,d0 beq .v1\@ ; 01 V1 subq.w #1,d0 bne .rw\@ ; 11 RAW, else 10 V4 ; -- V4: four 2x2 codewords, sub-block order TL TR BL BR (vq_hybrid.paint) moveq #0,d0 move.b (a0)+,d0 lsl.w #3,d0 movem.l (a3,d0.w),d0-d1 move.l d0,(a4) move.l d1,1024(a4) moveq #0,d0 move.b (a0)+,d0 lsl.w #3,d0 movem.l (a3,d0.w),d0-d1 move.l d0,4(a4) move.l d1,1028(a4) moveq #0,d0 move.b (a0)+,d0 lsl.w #3,d0 movem.l (a3,d0.w),d0-d1 move.l d0,2048(a4) move.l d1,3072(a4) moveq #0,d0 move.b (a0)+,d0 lsl.w #3,d0 movem.l (a3,d0.w),d0-d1 move.l d0,2052(a4) move.l d1,3076(a4) bra .sk\@ ; -- V1: one 4x4 codeword, 32 bytes, straight out of the expanded codebook .v1\@: moveq #0,d0 move.b (a0)+,d0 lsl.w #5,d0 movem.l (a2,d0.w),d0-d7 ; EA is resolved before the load movem.l d0-d1,(a4) movem.l d2-d3,1024(a4) movem.l d4-d5,2048(a4) movem.l d6-d7,3072(a4) bra .sk\@ ; -- RAW: 16 literal palette indices. Two indices are assembled into one long ; via swap, so each pair of pixels costs one write instead of two; the high ; byte of each word is left as zero because the hardware discards it anyway. .rw\@: RAWPAIR 0 RAWPAIR 4 RAWPAIR 1024 RAWPAIR 1028 RAWPAIR 2048 RAWPAIR 2052 RAWPAIR 3072 RAWPAIR 3076 .sk\@: addq.l #8,a4 endm RAWPAIR macro moveq #0,d0 move.b (a0)+,d0 swap d0 move.b (a0)+,d0 move.l d0,\1(a4) endm ; ------------------------------------------------------- the span section ; in: a0 = span section, a1 = mode header (preserved across the call) ; out: a0 = one past the section, i.e. the block payload ; ; This is tools/bench/blit.s v7 verbatim, and deliberately so: the 66.0 clocks ; per span + 9.143 per coarse pixel + 9.978 per fine pixel of FINDINGS 40 were ; measured on exactly this instruction sequence, over thirteen span lengths, and ; a "tidier" rewrite here would silently invalidate every span figure in ; FINDINGS 39/40 and in tools/analysis/14_dmac_chain.py. ; ; The fine chain is entered by FALLING OUT of the coarse one, so a span with no ; coarse units enters at v7cx with d0 already reloaded -- which is why the ; coarse displacement for c=0 is SPCN*SPCU, one past the last coarse unit, ; rather than a special case. paint_spans: move.w (a0)+,d7 ; spans in this frame subq.w #1,d7 bmi spnone ; a frame may legitimately have none (the ; chain is far past a short branch) move.l a1,-(sp) ; a1 is a payload register below spspan: move.l (a0)+,a2 ; absolute GVRAM destination move.w (a0)+,d0 ; (SPCN - coarse) * SPCU jmp spch(pc,d0.w) spch: movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 movem.l (a0)+,d0-d6/a1/a3-a6 movem.l d0-d6/a1/a3-a6,(a2) lea 48(a2),a2 spcx: move.w (a0)+,d0 ; (SPFN - fine) * SPFU, from mid-stream jmp spfh(pc,d0.w) spfh: move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ move.l (a0)+,(a2)+ dbra d7,spspan move.l (sp)+,a1 spnone: rts ; ------------------------------------------------------------- one frame ; in: a0 = payload, a1 = packed mode header ; out: a0 = one past the last payload byte consumed decode_frame: lea CB1,a2 lea CB4,a3 lea DST0,a6 rowloop: move.l a6,a4 lea ROWLEN(a6),a5 byteloop: tst.b (a1) ; four SKIPs in one test beq allskip BLOCK 6 BLOCK 4 BLOCK 2 BLOCK 0 addq.l #1,a1 cmpa.l a5,a4 bne byteloop bra rowdone allskip: addq.l #1,a1 lea 32(a4),a4 cmpa.l a5,a4 bne byteloop rowdone: lea BROW(a6),a6 cmpa.l #DSTE,a6 bne rowloop rts