mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
299 lines
11 KiB
Plaintext
299 lines
11 KiB
Plaintext
;
|
|
; 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 arenÕt any more words, just think about a last byte
|
|
moveq #0, d2 ; and make sure we donÕt 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
|