INCLUDE "tios.h" ;------------------------------------------------------------------------ XDEF _library XDEF pk92lib@0000 XDEF pk92lib@0001 ;------------------------------------------------------------------------ ;------------------------------------------------------------------------ ; ReadValue ;------------------------------------------------------------------------ ; Parameters: ; a0.l = *Src (++) ; d0.b = Bit (+x) ; d1.b = Byte (= *Src++) ; d2.b = BitsperGroup ; Return: ; d3.l = Value ; Temporary: ; d4.w = GroupShift ; d5.w = Group ; d6.b = GroupBit/ValueEnd ; d7.w = Break ;------------------------------------------------------------------------ ReadValue: clr.l d3 ;Value = GroupShift = 0 clr.w d4 \ReadValueLp: ;-------------Read Group ----------------- clr.w d5 ;Group = 0 st.b d6 ;GroupBit = -1 \ReadGroupLp: addq.b #1, d6 btst d0, d1 ;Bit set in Byte? beq \BitClr bset d6, d5 ;set GroupBit in Group \BitClr: addq.b #1, d0 ;Bit++; bclr #3, d0 ;Bit == 8 ? beq \NoNewByte move.b (a0)+, d1 ;Byte = *Src++; \NoNewByte: cmp.b d2, d6 ; GroupBit < BitsperGroup ? blt \ReadGroupLp ;-------------End Read Group --------------- ; ------ Add Group ------ bclr d6, d5 ;Break = ... seq d7 addq.w #1, d5 lsl.w d4, d5 ;Group <<= GroupShift add.w d5, d3 ;Value += Group add.w d2, d4 ;GroupShift += BitsperGroup tst.b d7 beq \ReadValueLp ;while (!Break) subq.w #1, d3 ;Value -= 1; rts ;------------------------------------------------------------------------ ; ExtrPart ;------------------------------------------------------------------------ ; Parameters: ; a0 = *Src (destroyed) ; a1 = *Dest (destroyed) ; a2 = *TransTbl (fst elm.: DiffChrs) ; d0.l = _Length (destroyed) ; Temp: ; a3 = *Rep ; d0.b = Bit ; d1.b = Byte ; Local: ; -4(a7) = Length ; all other Regs destroyed ; Return: ; d0.b = 0 OK / FF Error ;------------------------------------------------------------------------ ExtrPart: link a6, #-4 ;Initialize Local Var move.l d0, -4(a6) ;Length = _Length move.b (a0)+, d1 ;Byte = *Src++ clr.b d0 ;Bit = 0 \ExtrLoop: ;ReadValue3_1 () moveq.b #3, d2 ;BitsPerGroup = 3 bsr ReadValue clr.w d2 ;DiffChrs.w = 0 move.b (a2), d2 addq.w #1, d2 cmp.w d2, d3 ;Value < DiffChrs ? beq \RLE bhi \LZBC bra \BitCoded ;------------------- RLE -------------------- \RLE: ;ReadValue1_1 () move.b #1, d2 ;BitsPerGroup = 1 bsr ReadValue move.b -1(a1), d2 ;d2 = Dest[I-1] addq.l #1, d3 ;Value += 1; (Value+2 Reps) sub.l d3, -4(a6) \RLELp: move.b d2, (a1)+ ;*Dest++ = d2 dbra d3, \RLELp bra \ExtrLpCond ;------------------ LZBC -------------------- \LZBC: sub.w d2, d3 ;Value -= DiffChrs neg.l d3 lea -1(a1, d3.l), a3 ;Rep = Dest + Value - 1 ;ReadValue1_1 () moveq.b #1, d2 ;BitsPerGroup = 1 bsr ReadValue addq.l #1, d3 ;Value+=1 (Value+2 Reps) sub.l d3, -4(a6) \LZBCLp: move.b (a3)+, (a1)+ ;*Dest++ = *Rep++ dbra d3, \LZBCLp ;while (--Value != -1) bra \ExtrLpCond ;----------------- Bitwise ------------------ \BitCoded: move.b 1(a2, d3.w), (a1)+ ;*Dest++ = TransTbl[Value] \ExtrLpCond: subq.l #1, -4(a6) ;Length-- tst.l -4(a6) bmi \Error bne \ExtrLoop ;while (Length != 0) unlk a6 ;Remove locals clr.b d0 ;d0 = 0h (OK) rts \Error: unlk a6 ;Remove locals st d0 ;d0 = FFh (Error) rts ;************************************************************************ ;* Extract * ;*----------------------------------------------------------------------* ;* Extracts Packer92-packed archive, given its address * ;* Parameters: * ;* a0 = pointer to archives' begin * ;* for normal and divided archives: d0.w = number of file * ;* Return: * ;* d0.b = 0 OK / FF ERROR * ;* a1 = pointer to uncompressed file * ;* d1.w = handle of uncompressed file * ;* d2.l = Length of uncompressed file * ;* All Registers are stored, and restored * ;************************************************************************ pk92lib@0000: movem.l d3-d7/a0/a2-a6, -(a7) clr.l d1 ;d1.l = 0 !!! (is used later) lsl.w #1, d0 ;FileNum *= 2 (is used later) ;-------------- Archive Type? -------------------- move.b (a0)+, d7 cmpi.b #'s', d7 beq \SolidArc cmpi.b #'n', d7 beq \NormalArc cmpi.b #'d', d7 beq \DividedArc bra \Error \SolidArc: addq.l #1, a0 ;Dummy \SolArcInit: clr.l d0 move.w (a0)+, d0 ;Length bsr \GetDestMem ;GetDestMem () | d0/a0/a1 ok movea.l a0, a2 ;a2 = *TransTbl clr.w d1 move.b (a0), d1 lea 2(a0,d1.w), a0 ;a0 = *Src bsr ExtrPart bra \UncpEnd \NormalArc: move.b (a0)+, d1 ;get TransT (d1.l was 0) lsl.w #1, d1 lea 0(a0, d1.w), a2 ;a2 = *Trans ;a0 = *Src (lsl.w #1, d0 was allready done) ;adda.w 0(a0, d0.w), a0 ;this is the old version ;subq.l #2, a0 ;high word of d1 is still cleared! move.w 0(a0, d0.w), d1 ;newer version, now archives > 32K work lea -2(a0, d1.l), a0 clr.l d0 ;get Len move.w (a0)+, d0 bsr \GetDestMem ;get Dest bsr ExtrPart ;Extract bra \UncpEnd \DividedArc: subq.l #1, a0 ;(lsl.w #1, d0 was allready done) ;adda.w 2(a0, d0.w), a0 ;this is the older version ;newer version, now archives > 32 work move.w 2(a0, d0.w), d1 ;(d1.l was 0) adda.l d1, a0 bra \SolArcInit ;same as SolArcInit... \Error: st d0 \UncpEnd: lea PtrUncp(PC), a0 movea.l (a0)+, a1 move.w (a0)+, d1 move.l (a0), d2 movem.l (a7)+, d3-d7/a0/a2-a6 rts \GetDestMem: ;-------- d0.l = Len; a1 = *Dest ;-------- d0/a0/a2 stored; HandleUncp, PtrUncp, FileLen set ; create_handle(long size) movem.l d0/a0/a2, -(a7) move.l d0, FileLen move.l d0, -(a7) ;HandleUncp = create_handle (Length) jsr tios::HeapAlloc addq.l #4, a7 move.w d0, HandleUncp tst.l d0 beq \NotEnoughMem tios::DEREF d0, a1 move.l a1, PtrUncp movem.l (a7)+, d0/a0/a2 rts \NotEnoughMem: movem.l (a7)+, d0/a0/a2 move.l #\Error, (a7) rts ;************************************************************************ ;* FreeMem * ;*----------------------------------------------------------------------* ;* Destroys the handle, which was used by the last uncompression. * ;* Note: FreeMem saves all registers. * ;* Parameters: nothing * ;* Return: nothing * ;************************************************************************ pk92lib@0001: movem.l d0-d7/a0-a6, -(a7) lea HandleUncp(PC), a0 tst.w (a0) beq \NoHandle ; dispose_handle(int *handle) pea (a0) jsr tios::HeapFreeIndir addq.w #4, a7 \NoHandle: movem.l (a7)+, d0-d7/a0-a6 rts PtrUncp: dc.l 0 HandleUncp: dc.w 0 FileLen: dc.l 0 ;------------------------------------------------------------------------ _library: dc.b "pk92lib", 0 ;------------------------------------------------------------------------ ;************************************************************************ ;************************************************************************ ;************************************************************************ END