supermario/base/SuperMarioProj.1994-02-09/Patches/GreggyBitsDefProc.a
2019-06-29 23:17:50 +08:00

299 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: GreggyBitsDefProc.a
;
; Contains: Decompress defProc for GreggyBits decompression "'dcmp'(2)"
;
; Written by: Greg Marriott
;
; Copyright: © 1990-1991 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <6> 12/18/91 pvh Remove '040 cache flushing from here and move to
; DeCompressorPatch.a where it will do more good for mankind.
; <5> 12/10/91 pvh Added cache flushing for '040s at end of decompression. This
; appears to clear up boot problems on the Quadras.
; <4> 1/30/91 gbm sab, #38: Change the name of one of the decompressor header
; files (because Sheila said it was okay)
; <3> 12/14/90 dba & sab: make a small optimization to the decompressor
; <2> 9/4/90 gbm add new calling interface for new defProcs (like this one)
; <1> 9/3/90 gbm first checked in
; 9/3/90 gbm Newly checked in today
;
; To Do:
;
LOAD 'StandardEqu.d'
include 'DecompressorPatchEqu.a'
IF &TYPE('forCompressor')='UNDEFINED' THEN
forCompressor: SET 0
ENDIF
;
; First, we have the offset table for the three entry points used by the decompress patch
;
EntryPointTable proc
import PrepareForDecompression, WordForByte, CleanUpAfterDecompression
dc.w PrepareForDecompression-EntryPointTable
dc.w WordForByte-EntryPointTable
dc.w CleanUpAfterDecompression-EntryPointTable
endproc
;---------------------------------------------------------------------------------
;
; RECORD PrepareForDecompressionFrame
;
; Stack frame template for PrepareForDecompression routine
;
;---------------------------------------------------------------------------------
PrepareForDecompressionFrame RECORD {A6Link},DECR
StartParams EQU *
header DS.L 1 ; extended header for this resource
ParamSize EQU StartParams-*
Return DS.L 1
A6Link DS.L 1
; locals go here
ENDRSize
;---------------------------------------------------------------------------------
;
; PROCEDURE PrepareForDecompression( header : Ptr ); {ptr to an extended resource header}
;
; This is the routine called by the decompress patch to tell us to get ready
; for decompression. This is where we allocate extra storage, etc...
; But, this defproc doesn't NEED any extra storage, so we don't do anything.
;
;---------------------------------------------------------------------------------
PrepareForDecompression Proc Export
With PrepareForDecompressionFrame
; I guess we can just leave...
movem.l D4/A6, BootTmp8 ; this is very important
move.l (sp)+, a0 ; get return address
add.l #ParamSize, sp ; pop parameters
jmp (a0) ; return to caller
EndWith
EndProc
;---------------------------------------------------------------------------------
;
; RECORD CleanUpAfterDecompressionFrame
;
; Stack frame template for CleanUpAfterDecompression routine
;
;---------------------------------------------------------------------------------
CleanUpAfterDecompressionFrame RECORD {A6Link},DECR
StartParams EQU *
header DS.L 1 ; extended header for this resource
ParamSize EQU StartParams-*
Return DS.L 1
A6Link DS.L 1
; locals go here
ENDRSize
;---------------------------------------------------------------------------------
;
; PROCEDURE CleanUpAfterDecompression( header : Ptr ); {ptr to an extended resource header}
;
; This is the routine called by the decompress patch to tell us to clean up
; after decompression. This is where we deallocate extra storage, etc...
; But, this defproc doesn't NEED any extra storage, so we don't do anything.
;
;---------------------------------------------------------------------------------
CleanUpAfterDecompression Proc Export
With CleanUpAfterDecompressionFrame
; I guess we can just leave...
move.l BootTmp8, A0 ; this is just as important
add.l BootTmp8+4, A0
move.l (sp)+, a0 ; get return address
add.l #ParamSize, sp ; pop parameters
jmp (a0) ; return to caller
EndWith
EndProc
;---------------------------------------------------------------------------------
;
; RECORD WordForByteFrame
;
; Stack frame template for WordForByte routine
;
;---------------------------------------------------------------------------------
WordForByteFrame RECORD {A6Link},DECR
StartParams EQU *
source DS.L 1 ; get compressed data here,
destination DS.L 1 ; and put it here
header DS.L 1 ; extended header for this resource
ParamSize EQU StartParams-*
Return DS.L 1
A6Link DS.L 1
; locals go here
ENDRSize
;
; Register equates I COULD have used in decompression
;
;
;scratch EQU d0
;numberOfWords EQU d1
;numberOfRuns EQU d1
;wordsInLastRun EQU d2
;runBitMap EQU d3
;runCount EQU d4
;extraByteFlag EQU d5
;source EQU a0
;byteTable EQU a1
;destination EQU a2
;extendedHeader EQU a3
;endOfSource EQU a4
;---------------------------------------------------------------------------------
;
; PROCEDURE WordForByte( source, destination, extHeader : Ptr ); (not MemoryMgr blocks, just addresses)
;
; This function takes data and decompresses it. The data is moved from source to
; destination, decompressing bytes into words. If a dynamic byte table is included
; in the data, it is copied into the table buffer (contained herein) before decompression.
; A pointer to the extended header is also provided, so that various flags and whatnot will
; be available to the decompress routine.
;
;---------------------------------------------------------------------------------
WordForByte Proc Export
With WordForByteFrame, ExtendedResource
link a6, #WordForByteFrame.SIZE
movem.l a0-a4/d0-d5, -(SP)
move.l header(a6), a3 ; flags and shit be here...
move.l source(a6), a0
move.l destination(a6), a2
@testForTable
btst #byteTableSaved, compressFlags(a3)
beq.s @noByteTableSaved
moveq #0, d0
move.b byteTableSize(a3), d0 ; get the size, in words, of the byte table
addq.w #1, d0 ; adjust it to "real" numbers (not zero based)
add.w d0, d0 ; make it bytes
lea DynamicTable, a1 ; point to the start of our storage
move.w d0, d1 ; save size a sec...
_BlockMove ; copy the table
adda.w d1, a0 ; move source pointer past table data
bra.s @testForOddLength
@noByteTableSaved
lea StaticTable, a1 ; point to the start of the static table
@testForOddLength
move.l actualSize(a3), d1 ; get the real size, and figure out the special cases
lsr.l #1, d1 ; but first, turn data length into number of words of uncompressed data
scs d5 ; indicate no extra byte is there
@testForBitMap
btst #bitmappedData, compressFlags(a3)
bne.s DoBitMappedData
DoNonBitMappedData
move.l a0, a4
add.l d1, a4 ; point a4 past last byte of source data
@again
moveq #0, d0
move.b (a0)+, d0 ; get byte
add.w d0, d0 ; turn it into an index
move.w (a1, d0.w), (a2)+ ; move word to destination
cmp.l a0, a4
bhi.s @again ; not at end, do it again
DoDanglingByte
tst.b d5 ; is there one more byte to move?
beq.s AllDone ; no, leave
move.b (a0), (a2) ; yes, move it and leave
bra.s AllDone
DoBitMappedData
move.l d1, d2 ; get number of uncompressed words we should do
andi.l #$7, d2 ; MOD 8 - d2 now has the number of words in the last run
lsr.l #3, d1 ; DIV 8 - d1 now has the number of 8 word runs to decompress
bra.s @endOfRun
@do8 ; if we're making this routine for the compressor
IF forCompressor THEN ; to do its reality check, then make sure
cmp.l a0, a2 ; the source and dest pointers never cross...
bls.s @pointersOK ; if they do, just leave, because the comparison
bra AllDone ; routine will show that this decompressed
@pointersOK ; resource doesn't match the original...
ENDIF
moveq #8-1, d4 ; otherwise, load up for another run
move.b (a0)+, d3 ; get bitmap
beq.s @fast8 ; if the bitmap's empty, all 16 words are uncompressed
@doNextDatum
add.b d3, d3 ; shift map over one
bcs.s @doCompressed ; bit was set, so do it the hard way
move.b (a0)+, (a2)+ ; bit wasn't set, so do it the easy way
move.b (a0)+, (a2)+ ; bit wasn't set, so do it the easy way, part II
dbra d4, @doNextDatum ; loop around
@endOfRun
subq.l #1, d1 ; subtract one from run count (we may go past -1 because of last run)
bpl.s @do8 ; and go do another batch of 16
bra.s @doLastRun ; when we fall below zero, bail out
@fast8
move.b (a0)+, (a2)+
move.b (a0)+, (a2)+
dbra d4, @fast8
bra.s @endOfRun
@doCompressed
moveq #0, d0
move.b (a0)+, d0 ; get compressed datum
add.w d0, d0 ; make it an index into byte table
move.w (a1, d0.w), (a2)+ ; move word from table to destination
@lastEntry
dbra d4, @doNextDatum ; loop around
bra.s @endOfRun ; branch to end, prepare another run
@doLastRun
move.w d2, d4 ; load up number of words to move
beq.s DoDanglingByte ; there arent any more words, just think about a last byte
moveq #0, d2 ; and make sure we dont do this again...
move.b (a0)+, d3 ; get mask for this run
bra.s @lastEntry ; enter through bottom of dbra, 'cause the count is 1 based
AllDone
; I guess we can just leave...
movem.l (sp)+, a0-a4/d0-d5
unlk a6
move.l (sp)+, a0 ; get return address
add.l #ParamSize, sp ; pop parameters
jmp (a0) ; return to caller
StaticTable
DC.W $0000, $0008, $4EBA, $206E, $4E75, $000C, $0004, $7000, $0010, $0002, $486E, $FFFC, $6000, $0001, $48E7, $2F2E
DC.W $4E56, $0006, $4E5E, $2F00, $6100, $FFF8, $2F0B, $FFFF, $0014, $000A, $0018, $205F, $000E, $2050, $3F3C, $FFF4
DC.W $4CEE, $302E, $6700, $4CDF, $266E, $0012, $001C, $4267, $FFF0, $303C, $2F0C, $0003, $4ED0, $0020, $7001, $0016
DC.W $2D40, $48C0, $2078, $7200, $588F, $6600, $4FEF, $42A7, $6706, $FFFA, $558F, $286E, $3F00, $FFFE, $2F3C, $6704
DC.W $598F, $206B, $0024, $201F, $41FA, $81E1, $6604, $6708, $001A, $4EB9, $508F, $202E, $0007, $4EB0, $FFF2, $3D40
DC.W $001E, $2068, $6606, $FFF6, $4EF9, $0800, $0C40, $3D7C, $FFEC, $0005, $203C, $FFE8, $DEFC, $4A2E, $0030, $0028
DC.W $2F08, $200B, $6002, $426E, $2D48, $2053, $2040, $1800, $6004, $41EE, $2F28, $2F01, $670A, $4840, $2007, $6608
DC.W $0118, $2F07, $3028, $3F2E, $302B, $226E, $2F2B, $002C, $670C, $225F, $6006, $00FF, $3007, $FFEE, $5340, $0040
DC.W $FFE4, $4A40, $660A, $000F, $4EAD, $70FF, $22D8, $486B, $0022, $204B, $670E, $4AAE, $4E90, $FFE0, $FFC0, $002A
DC.W $2740, $6702, $51C8, $02B6, $487A, $2278, $B06E, $FFE6, $0009, $322E, $3E00, $4841, $FFEA, $43EE, $4E71, $7400
DC.W $2F2C, $206C, $003C, $0026, $0050, $1880, $301F, $2200, $660C, $FFDA, $0038, $6602, $302C, $200C, $2D6E, $4240
DC.W $FFE2, $A9F0, $FF00, $377C, $E580, $FFDC, $4868, $594F, $0034, $3E1F, $6008, $2F06, $FFDE, $600A, $7002, $0032
DC.W $FFCC, $0080, $2251, $101F, $317C, $A029, $FFD8, $5240, $0100, $6710, $A023, $FFCE, $FFD4, $2006, $4878, $002E
DC.W $504F, $43FA, $6712, $7600, $41E8, $4A6E, $20D9, $005A, $7FFF, $51CA, $005C, $2E00, $0240, $48C7, $6714, $0C80
DC.W $2E9F, $FFD6, $8000, $1000, $4842, $4A6B, $FFD2, $0048, $4A47, $4ED1, $206F, $0041, $600C, $2A78, $422E, $3200
DC.W $6574, $6716, $0044, $486D, $2008, $486C, $0B7C, $2640, $0400, $0068, $206D, $000D, $2A40, $000B, $003E, $0220
DynamicTable
DCB.W 256, 0
EndProc
End