;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; JAGUAR Multimedia Entertainment System Source Code ;;; ;;; COPYRIGHT (c)1994 Atari Computer Corporation ;;; UNAUTHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION, ;;; PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR ;;; THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED. ;;; ALL RIGHTS RESERVED. ;;; ;;; Module: delzjag.s ;;; GPU Code to Un-LZSS a Block of Memory ;;; ;;; History: 09/20/94 - Created (SDS) ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .include "jaguar.inc" ;;; Exposed Globals .globl _dlzstart .globl _dlzend .globl delzss .globl lzinbuf .globl lzoutbuf .globl lzworkbuf ;;; Equates INDEX_BIT_COUNT .equ 13 LENGTH_BIT_COUNT .equ 4 BREAK_EVEN .equ ((1+INDEX_BIT_COUNT+LENGTH_BIT_COUNT)/9) .68000 .phrase _dlzstart: .gpu .org G_RAM+$100 ;;; Register Equates lzinbufptr .equr r0 lzoutbufptr .equr r1 lzworkbufptr .equr r2 currentpos .equr r3 ch .equr r4 addr .equr r5 temp .equr r6 matchlen .equr r7 matchpos .equr r8 mask .equr r9 rack .equr r10 bufmask .equr r11 bigmask .equr r12 startmask .equr r13 rbigloop .equr r14 mreg .equr r15 preg .equr r16 inner .equr r17 compressed .equr r18 done .equr r19 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; INPUT_BITS destreg,num_bits MACRO INPUT_BITS destreg, num_bits moveq #1,bigmask ; bigmask = 1 << (bit_count - 1) moveq #0,\destreg shlq #\num_bits-1,bigmask movei #.m\~,mreg movei #.p\~,preg .m\~: cmpq #0,bigmask ; If bigmask == 0 we're done jump EQ,(preg) ; (1 wait) nop cmp startmask,mask ; (1 wait) jr NE,.n\~ nop load (lzinbufptr),rack ; Load new input byte addq #4,lzinbufptr .n\~: move rack,temp ; if( rack & mask ) destreg |= bigmask and mask,temp ; (1 wait) jr EQ,.o\~ ; (1 wait) nop or bigmask,\destreg .o\~: shrq #1,bigmask ; bigmask >>= 1 shrq #1,mask ; mask >>= 1 jump NE,(mreg) ; (1 wait ) nop move startmask,mask jump T,(mreg) nop .p\~: ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; This is our routine entry point (instructions are interleaved for speed) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; delzss: movei #lzinbuf,addr ; Address of variables movei #$80000000,mask ; Mask to shift movei #cstream,compressed load (addr),lzinbufptr addq #4,addr ; Next long variable movei #$1FFF,bufmask ; Mask for 8k buffer load (addr),lzoutbufptr addq #4,addr ; Next long buffer load (addr),lzworkbufptr movei #bigloop,rbigloop ; Put in register for quick access move mask,startmask ; Copy for later compares movei #getchs,inner moveq #1,currentpos ; Current position in window movei #alldone,done bigloop: cmp startmask,mask ; Is mask $80? jr NE,noreread nop load (lzinbufptr),rack ; Get a new byte addq #4,lzinbufptr noreread: move rack,temp ; Make a copy and mask,temp ; Isolate bit (1 wait) shrq #1,mask ; mask >>= 1 jr NE,havemask ; (1 wait) nop move startmask,mask ; If mask == 0, mask = $80 havemask: cmpq #0,temp ; Do final test to set ZERO flag jump EQ,(compressed) ; If 0, get compressed stream nop INPUT_BITS ch,8 storeb ch,(lzoutbufptr) ; store byte addq #1,lzoutbufptr ; go to next buffer pos and bufmask,currentpos ; force range of 0-8191 move lzworkbufptr,addr ; get address of window add currentpos,addr ; add offset (1 wait) addq #1,currentpos ; increment window pointer storeb ch,(addr) ; update window jump T,(rbigloop) nop cstream: INPUT_BITS matchpos,13 ; Get Index into Window cmpq #0,matchpos ; END_OF_STREAM??? jump EQ,(done) ; (1 wait) nop INPUT_BITS matchlen,4 ; Get Length of Match addq #BREAK_EVEN,matchlen getchs: and bufmask,matchpos move lzworkbufptr,addr ; Get Window Address + Offset and bufmask,currentpos ; Range check currentpos add matchpos,addr ; ^ avoids 1 wait loadb (addr),ch ; Load a byte from window or ch,ch ; (1 wait on purpose) storeb ch,(lzoutbufptr) ; Store it to our buffer addq #1,lzoutbufptr move lzworkbufptr,temp ; Store byte in window add currentpos,temp ; @ currentpos (1 wait) addq #1,currentpos ; Update Window Position storeb ch,(temp) ; Update Buffer addq #1,matchpos ; Increment window read addr subq #1,matchlen ; Decrement loop counter jump PL,(inner) ; ->getchs (1 wait) nop jump T,(rbigloop) nop ;;; Ok, we're done... now leave. alldone: moveq #0,temp movei #G_CTRL,addr store temp,(addr) nop .long lzinbuf: .dc.l 0 ; Pointer to Compressed Data lzoutbuf: .dc.l 0 ; Pointer of Destination Buffer lzworkbuf: .dc.l 0 ; Pointer to 8k LZSS Window .68000 _dlzend: .end