home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ANews 1
/
AnewsCD01.iso
/
Indispensables
/
Compression
/
xfd
/
Developer
/
Sources
/
ASM
/
TUC.a
< prev
next >
Wrap
Text File
|
1999-08-03
|
20KB
|
958 lines
********************************************************
** XFD external decruncher for TUC 1.16 **
** © 1998 by Georg Hörmann **
********************************************************
**
** 1.0 - Initial release.
** 1.1 - Added support for data files.
** - Added support for address files.
**
OUTPUT "LIBS:xfd/TUC"
SECTION TUC,CODE
INCDIR "dh0:Include_Asm"
INCLUDE "dh0:xfd/xfdmaster.i"
F_TUC moveq #-1,d0
rts
dc.l XFDF_ID
dc.w 1
dc.w 0
dc.l 0,0
dc.l S_TUC
dc.b "$VER: xfd_TUC_1.16 1.1 (13.12.98) © 1998 Georg Hörmann",0
cnop 0,4
********************************************************
*
* Reloc files will always be restored to their original
* appearance.
*
* Address files will be treated as follows:
* a. If more than 1 hunk, a reloc file will be created.
* The first hunk gets the MEM_TYPE of the decrunch
* address.
* b. If 1 hunk with reloc information, same as a.
* c. If 1 hunk without reloc information, it could be
* a relocated image and therefore gets a small
* header in front that copies it to the decrunch
* address. Only such files support the "Rückwärts"
* option.
*
S_TUC dc.l S_TUCData
dc.w 2
dc.w 36
dc.l N_TUC
dc.w XFDPFF_RELOC
dc.w 0
dc.l RB_TUC
dc.l DB_TUC
dc.l 0
dc.l 0
dc.w 0
dc.w 0
dc.l $1c8+4+12
N_TUC dc.b 'TUC 1.16',0
even
;-------------------------------------------------
RB_TUC cmp.l #$3f3,(a0)
bne.s .Exit
move.l 8(a0),d1
lsl.w #2,d1
lea 20+4(a0,d1.w),a0
cmp.l #$55,(a0)+ ;header length
bne.s .Exit
cmp.l #$7e001e1d,$36-$2c(a0)
bne.s .Exit
cmp.l #$48471e1d,$3a-$2c(a0)
bne.s .Exit
cmp.l #$49f50000,$4c-$2c(a0)
bne.s .Exit
cmp.l #$bd834846,$5a-$2c(a0)
bne.s .Exit
moveq #1,d0
rts
.Exit moveq #0,d0
rts
;-------------------------------------------------
TUC_BSS SET xfdBufferInfo_SIZE
TUC_CrunchedData SET xfdBufferInfo_SIZE+4
TUC_CountSize SET xfdBufferInfo_SIZE+8
TUC_CountStruct SET xfdBufferInfo_SIZE+12
TUC_EorValue SET xfdBufferInfo_SIZE+16
TUC_Mode SET xfdBufferInfo_SIZE+20 ;1=reloc, 0=addr, -1=image
TUC_Back SET xfdBufferInfo_SIZE+21
TUC_JmpAddr SET xfdBufferInfo_SIZE+22
TUC_DecAddr SET xfdBufferInfo_SIZE+26
TUC_SIZE SET xfdBufferInfo_SIZE+30
DB_TUC movem.l d2-d7/a2-a6,-(a7)
sub.w #TUC_SIZE,a7
move.l a7,a5
move.l a0,-(a7) ;bufferinfo
move.l a5,a1
moveq #xfdBufferInfo_SIZE-1,d1
.CopyBI1 move.b (a0)+,(a1)+
dbf d1,.CopyBI1
* get some addresses and sizes
move.l xfdbi_SourceBuffer(a5),a0
move.l 8(a0),d1
move.l d1,d0
lsl.l #2,d0
lea 20(a0,d0.w),a0 ;start of code hunk
move.l $40-$24(a0),d0
eor.l #"rich",d0
move.l d0,TUC_EorValue(a5)
move.l $160-$24(a0),TUC_JmpAddr(a5)
sf TUC_Mode(a5)
cmp.w #$2094,$158-$24(a0) ;only used by reloc mode
bne.s .Mode_Ok
move.b #1,TUC_Mode(a5) ;reloc
.Mode_Ok sf TUC_Back(a5)
cmp.w #$4480,$110-$24(a0) ;forward mode
beq.s .Back_Ok
st TUC_Back(a5)
.Back_Ok move.l 4(a0),d0
lsl.l #2,d0
lea 8+24(a0,d0.l),a0 ;end of code+reloc hunk
move.l a0,TUC_BSS(a5)
move.l d1,d0
subq.w #2,d0 ;amount of bss hunks
mulu #12,d0
lea 8(a0,d0.l),a0 ;start of crunched data
move.l a0,TUC_CrunchedData(a5)
moveq #0,d0
move.b 1(a0),d0 ;amount hunks
move.l d0,d7 ;amount of hunks
moveq #1,d2
add.w d0,d2
lsl.l #2,d2
move.l d2,TUC_CountSize(a5)
mulu d0,d2 ;length of CountStructs
addq.l #4,d2 ;for length
move.l d2,d0
move.l #$10001,d1
move.l 4.w,a6
jsr -198(a6)
move.w #XFDERR_NOMEMORY,xfdbi_Error(a5)
tst.l d0
beq .Exit
move.l d0,a0
move.l d2,(a0)+
move.l a0,TUC_CountStruct(a5)
move.l d7,-(a7)
bsr TUC_Count
move.l (a7)+,d7
move.w #XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
tst.w d0
beq .ExitFree
* calculate length of final file
move.l TUC_CountStruct(a5),a3
moveq #20,d0 ;3f3,0,x,0,x-1
move.l d7,d1
lsl.l #4,d1
add.l d1,d0 ;header,3e9/a/b,len,3f2
move.w d7,d3
.CalcNext move.l (a3),d1 ;is BSS ??
beq.s .SkipReloc
add.l d1,d0 ;hunklen
move.w d7,d2
moveq #0,d4
moveq #0,d5 ;3ec flag
.TestNextReloc move.l 4(a3,d4.w),d1
beq.s .NoReloc
tst.w d5
bne.s .Skip3ec
addq.l #8,d0 ;3ec, 0 am ende
moveq #1,d5
.Skip3ec addq.l #8,d0 ;x,hunk #
lsl.l #2,d1
add.l d1,d0 ;offsets
.NoReloc addq.w #4,d4
subq.w #1,d2
bne.s .TestNextReloc
.SkipReloc add.l TUC_CountSize(a5),a3
subq.w #1,d3
bne.s .CalcNext
tst.b TUC_Mode(a5) ;reloc, mode=1
beq.s .Test_Addr
move.l TUC_DecAddr(a5),d1 ;really reloc or just no JmpAddr?
beq.s .Mode_Ok2
move.l d1,TUC_JmpAddr(a5)
sf TUC_Mode(a5)
.Test_Addr cmp.w #1,d7 ;more than 1 hunk, mode=0
bne.s .Mode_Ok2
move.l TUC_CountStruct(a5),a0
tst.l 4(a0) ;one hunk, but with relocs, mode=0
bne.s .Mode_Ok2
st TUC_Mode(a5) ;image, mode=-1
add.l #TUCAddr_End-TUCAddr_Start,d0
.Mode_Ok2 move.l d0,xfdbi_TargetBufSaveLen(a5)
move.l d0,xfdbi_TargetBufLen(a5)
move.l xfdbi_TargetBufMemType(a5),d1
move.l 4.w,a6
jsr -198(a6)
move.w #XFDERR_NOMEMORY,xfdbi_Error(a5)
move.l d0,xfdbi_TargetBuffer(a5)
beq .ExitFree
* prepare allocated buffer
move.l d0,a1
move.l #$3f3,(a1)+
clr.l (a1)+
move.l d7,(a1)+
clr.l (a1)+
move.l d7,d0
subq.l #1,d0
move.l d0,(a1)+
move.l TUC_CountStruct(a5),a3
move.l xfdbi_SourceBuffer(a5),a0
add.w #20+4,a0
move.w d7,d0
cmp.b #1,TUC_Mode(a5) ;if reloc, just copy header
beq.s .CopyHunkHeader
move.l (a3),d1 ;else, use coded hunklen
tst.b TUC_Mode(a5)
beq.s .NoImage
add.l #TUCAddr_End-TUCAddr_Start,d1
.NoImage lsr.l #2,d1
tst.b TUC_Mode(a5) ;get MEM_TYPE
bmi.s .NoMemType
movem.l d0/d1/a0/a1,-(a7)
move.l TUC_DecAddr(a5),a1
jsr -534(a6) ;typeofmem
move.l d0,d2
movem.l (a7)+,d0/d1/a0/a1
beq.s .NoMemType
and.w #$0002,d2
beq.s .NoMemType
or.l #$40000000,d1
.NoMemType move.l d1,(a1)+
bra.s .SkipHunkHeader
.CopyHunkHeader move.l (a0)+,(a1)+
.SkipHunkHeader subq.w #1,d0
bne.s .CopyHunkHeader
move.l TUC_BSS(a5),a2
addq.w #4,a2
moveq #0,d6 ;flag for bss
move.w d7,d0
.PrepareHunks tst.l (a3)
beq .BSS
move.l #$3e9,(a1)+
cmp.b #1,TUC_Mode(a5)
beq.s .UseBSS
tst.w d6
bne.s .UseBSS
move.l (a3),d1
tst.b TUC_Mode(a5)
beq.s .NoImage2
add.l #TUCAddr_End-TUCAddr_Start,d1
.NoImage2 lsr.l #2,d1
subq.w #8,a2 ;correct add at end
moveq #1,d6
bra.s .SkipBSS
.UseBSS move.l (a2)+,d1
.SkipBSS move.l d1,(a1)+
tst.b TUC_Mode(a5) ;copy address header
bge.s .NoImage3
moveq #(TUCAddr_End-TUCAddr_Start)/4,d2
sub.l d2,d1
lea TUCAddr_Start(pc),a0
.CopyAddr move.l (a0)+,(a1)+
subq.l #1,d2
bne.s .CopyAddr
move.l TUC_DecAddr(a5),TUCAddr_DecAddr+2-TUCAddr_End(a1)
move.l TUC_JmpAddr(a5),TUCAddr_JmpAddr+2-TUCAddr_End(a1)
move.l (a3),TUCAddr_DataLen+2-TUCAddr_End(a1)
.NoImage3 move.l a1,(a3) ;save pointer to hunk
lsl.l #2,d1
add.l d1,a1 ;skip code/data
move.w d7,d1
moveq #0,d2
moveq #0,d3 ;flag
.PrepareReloc move.l 4(a3,d2.w),d4
beq.s .NoReloc_1
tst.w d3
bne.s .Skip3ec_1
move.l #$3ec,(a1)+
moveq #1,d3
.Skip3ec_1 move.l d4,(a1)+ ;x hunks
lsr.w #2,d2
move.l d2,(a1)+ ;hunk #
lsl.w #2,d2
move.l a1,4(a3,d2.w) ;save pointer for decrunching
lsl.l #2,d4
add.l d4,a1 ;skip offsets
.NoReloc_1 addq.w #4,d2
subq.w #1,d1
bne.s .PrepareReloc
tst.w d3
beq.s .NextHunk
clr.l (a1)+
bra.s .NextHunk
.BSS move.l #$3eb,(a1)+
move.l (a2)+,(a1)+
clr.l (a3) ;no pointer needed
.NextHunk move.l #$3f2,(a1)+
addq.w #8,a2
add.l TUC_CountSize(a5),a3
subq.w #1,d0
bne .PrepareHunks
bsr TUC_Decrunch
tst.b TUC_Mode(a5)
bge.s .Ok
tst.b TUC_Back(a5)
beq.s .Ok
move.l xfdbi_TargetBuffer(a5),a0
add.w #20+4+8+(TUCAddr_End-TUCAddr_Start),a0
move.l TUCAddr_DataLen+2-TUCAddr_End(a0),d0
lea (a0,d0.l),a1
lsr.l #1,d0
.Switch move.b (a0),d1
move.b -(a1),(a0)+
move.b d1,(a1)
subq.l #1,d0
bne.s .Switch
.Ok moveq #1,d0
.ExitFree move.l d0,-(a7)
move.l TUC_CountStruct(a5),a1
move.l -(a1),d0
move.l 4.w,a6
jsr -210(a6)
move.l (a7)+,d0
.Exit move.l (a7)+,a1 ;bufferinfo
moveq #xfdBufferInfo_SIZE-1,d1
.CopyBI2 move.b (a5)+,(a1)+
dbf d1,.CopyBI2
add.w #TUC_SIZE,a7
movem.l (a7)+,d2-d7/a2-a6
rts
cnop 0,4
TUCAddr_Start movem.l d0/d1/a0/a1/a6,-(a7)
TUCAddr_DecAddr lea $12345678,a1
TUCAddr_DataLen move.l #$12345678,d0
move.l 4.w,a6
jsr -204(a6)
tst.l d0
bne.s .Ok
add.w #20,a7
rts
.Ok lea TUCAddr_End(pc),a0
move.l TUCAddr_DecAddr+2(pc),a1
move.l TUCAddr_DataLen+2(pc),d0
jsr -624(a6)
movem.l (a7)+,d0/d1/a0/a1/a6
TUCAddr_JmpAddr jmp $12345678
cnop 0,4
TUCAddr_End
;-------------------------------------------------
*
* CountStruct:
*
* ULONG HunkLen ]
* ULONG Relocs to Hunk 0 ] (n+1)*4
* ... ]
* ULONG Relocs to Hunk n-1 ]
*
* This structure is needed for every crunched hunk !
*
TUC_Count move.l TUC_CrunchedData(a5),a0
moveq #0,d7
move.b (a0)+,d7 ;bits needed for highest hunk #
swap d7
move.b (a0)+,d7 ;amount hunks
;a0: table of hunk len bits
move.w d7,d0
addq.w #1,d0
and.w #$fe,d0
lea (a0,d0.w),a2 ;hunk table
move.l (a2),TUC_DecAddr(a5)
move.w d7,d0
asl.w #2,d0
lea 20(a2,d0.w),a2 ;data begin first hunk
move.l TUC_EorValue(a5),d3
move.l TUC_CountStruct(a5),a3
moveq #0,d6 ;hunk count
.lbC00003A moveq #0,d5
move.w (a2)+,d0 ;info table length
beq .lbC0000FE
move.l a2,a6 ;info table
lea (a2,d0.w),a2
move.w d6,d0
moveq #0,d1
move.b (a0,d0.w),d1 ;bit width of hunk length
bsr TUC_GetBits
move.l d0,d4 ;hunk length
move.l d0,(a3)
.lbC000062 moveq #0,d0
.lbC000064 asl.l #1,d5 ;get value from info table
bne.s .lbC000072
move.l (a2)+,d5
eor.l d3,d5
move.b #$10,ccr
roxl.l #1,d5
.lbC000072 bcc.s .lbC000076
addq.w #2,d0
.lbC000076 move.w (a6,d0.w),d0 ;loop until negative
bpl.s .lbC000064
not.w d0
cmp.w #$100,d0 ;less than $100 -> data byte
bcs.s .lbC0000F0
bne.s .lbC0000A6 ;more than $100 -> crunched
* reloc info
move.l d7,d1
swap d1 ;bits needed for hunk #
bsr.s TUC_GetBits ;d0: hunk number
move.w d0,d1
lsl.w #2,d1
addq.l #1,4(a3,d1.w) ;count reloc to hunk x
moveq #0,d1
move.b (a0,d0.w),d1 ;bits of hunk length
bsr.s TUC_GetBits
subq.l #4,d4
bra.s .lbC0000F2
* crunched
.lbC0000A6 cmp.w #$110,d0 ;$101-$110
bhi.s .lbC0000C6
sub.w #$101,d0
move.w d0,d1 ;value 0-$f
bsr.s TUC_GetBits
sub.l d0,d4
moveq #7,d1
bsr.s TUC_GetBits
subq.l #2,d4
bra.s .lbC0000F2
.lbC0000C6 move.w d0,d2 ;$111-$1ff
move.w d0,d1
and.w #15,d1
bsr.s TUC_GetBits
addq.w #3,d0 ;length of string
sub.l d0,d4
move.w d2,d1
lsr.w #4,d1
and.w #15,d1
addq.w #2,d1
bsr.s TUC_GetBits
* copy uncrunched byte
.lbC0000F0 subq.l #1,d4
.lbC0000F2 bmi.s .Error
bne.s .lbC000062
.lbC0000FE add.l TUC_CountSize(a5),a3
addq.w #1,d6
cmp.w d7,d6 ;last hunk ??
bcs .lbC00003A
moveq #1,d0
rts
.Error moveq #0,d0
rts
TUC_GetBits moveq #0,d0
.lbC00013A asl.l #1,d5
bne.s .lbC000148
move.l (a2)+,d5
eor.l d3,d5
move.b #$10,ccr
roxl.l #1,d5
.lbC000148 roxl.l #1,d0
dbra d1,.lbC00013A
rts
;-------------------------------------------------
TUC_Decrunch move.l TUC_CrunchedData(a5),a0
move.l TUC_CountStruct(a5),a3
moveq #0,d7
move.b (a0)+,d7 ;bits needed for highest hunk #
swap d7
move.b (a0)+,d7 ;amount hunks
* a0: table of hunk lengths (bits to calculate hunk length)
move.w d7,d0
addq.w #1,d0
and.w #$fe,d0
lea (a0,d0.w),a2 ;hunk table
move.w d7,d0
asl.w #2,d0
lea 20(a2,d0.w),a2 ;data begin first hunk
move.l TUC_EorValue(a5),d3
moveq #0,d6 ;hunk count
.lbC00003A moveq #0,d5
move.l (a3),a1 ;pointer to hunk
move.w (a2)+,d0 ;info table length
beq .lbC0000FE
move.l a2,a6 ;info table
lea (a2,d0.w),a2
move.w d6,d0
moveq #0,d1
move.b (a0,d0.w),d1 ;bit width of hunk length
bsr.s TUC_GetBits
move.l d0,d4 ;hunk length
add.l a1,d4 ;end of hunk
.lbC000062 moveq #0,d0
.lbC000064 asl.l #1,d5 ;get value from info table
bne.s .lbC000072
move.l (a2)+,d5
eor.l d3,d5
move.b #$10,ccr
roxl.l #1,d5
.lbC000072 bcc.s .lbC000076
addq.w #2,d0
.lbC000076 move.w (a6,d0.w),d0 ;loop until negative
bpl.s .lbC000064
not.w d0
cmp.w #$100,d0 ;less than $100 -> data byte
bcs.s .lbC0000F0
bne.s .lbC0000A6 ;more than $100 -> crunched
* reloc info
move.l d7,d1
swap d1 ;bits needed for hunk #
bsr TUC_GetBits
moveq #0,d1
move.b (a0,d0.w),d1 ;bits of hunk length
move.w d0,d2 ;d2: hunk number
bsr TUC_GetBits
move.l d5,-(a7)
lsl.w #2,d2
move.l 4(a3,d2.w),a4 ;current reloc pointer
move.l (a3),d5
neg.l d5
add.l a1,d5 ;offset
move.l d5,(a4)+
move.l a4,4(a3,d2.w) ;save back pointer
move.l d0,(a1)+ ;save longword
move.l (a7)+,d5
bra.s .lbC0000F2
* crunched
.lbC0000A6 cmp.w #$110,d0 ;$101-$110
bhi.s .lbC0000C6
sub.w #$101,d0
move.w d0,d1 ;value 0-$f
bsr TUC_GetBits
move.w d0,d2 ;amount of same bytes
moveq #7,d1
bsr TUC_GetBits
.lbC0000BE move.b d0,(a1)+ ;copy same bytes
dbra d2,.lbC0000BE
bra.s .lbC0000F0
.lbC0000C6 move.w d0,d2 ;$111-$1ff
move.w d0,d1
and.w #15,d1
bsr TUC_GetBits
addq.w #3,d0 ;length of string
move.w d2,d1
move.w d0,d2
lsr.w #4,d1
and.w #15,d1
addq.w #2,d1
bsr TUC_GetBits
neg.l d0 ;offset
.lbC0000E6 move.b (a1,d0.l),(a1)+
dbra d2,.lbC0000E6
bra.s .lbC0000F2
* copy uncrunched byte
.lbC0000F0 move.b d0,(a1)+
.lbC0000F2 cmp.l d4,a1 ;end of hunk ??
bne .lbC000062
.lbC0000FE add.l TUC_CountSize(a5),a3
addq.w #1,d6
cmp.w d7,d6 ;last hunk ??
bcs .lbC00003A
rts
**********************************************************
*
* Data files must have the following format:
*
* - Only one "hunk" (starting with $0001)
* - Address of the "hunk" must be "TUC!" (that's the ID)
* - No reloc information (bitcode $100)
*
* The "Rückwärts" option cannot be recognized in any way,
* you have to switch bytes by hand if such a file appears.
*
S_TUCData dc.l 0
dc.w 2
dc.w 38
dc.l N_TUCData
dc.w XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
dc.w 0
dc.l RB_TUCData
dc.l DB_TUCData
dc.l SD_TUCData
dc.l VD_TUCData
dc.w 0
dc.w 0
dc.l $1c+2+2+4
N_TUCData dc.b 'TUC 1.16 Data',0
even
;-------------------------------------------------
RB_TUCData bsr.s RB_TUCDataID
beq.s .Out
cmp.w #$0001,(a0) ;only data with 1 "hunk"
bne.s .Exit
move.w $1c(a0),d0 ;info table length
beq.s .Out
movem.l d3/d5/a2,-(a7)
lea $1e(a0,d0.w),a2
moveq #0,d1
move.b 2(a0),d1 ;bit width of hunk length
moveq #0,d5
move.l 8(a0),d3 ;calculate EOR value
eor.l #"M.F.",d3
neg.l d3
swap d3
ror.l #8,d3
bsr TUC_GetBits
movem.l (a7)+,d3/d5/a2
move.l d0,xfdrr_MinTargetLen(a1)
move.l d0,xfdrr_FinalTargetLen(a1)
moveq #1,d0
rts
.Exit moveq #0,d0
.Out rts
RB_TUCDataID cmp.l #"TUC!",4(a0)
bne.s .Exit
cmp.l #"TUC ",$c(a0)
bne.s .Exit
cmp.l #" M.F",$10(a0)
bne.s .Exit
cmp.l #"ried",$14(a0)
bne.s .Exit
cmp.l #"rich",$18(a0)
bne.s .Exit
moveq #1,d0
rts
.Exit moveq #0,d0
rts
;-------------------------------------------------
SD_TUCData cmp.w #$0001,(a0) ;only data with 1 "hunk"
bne.s .Exit
cmp.l #$1e,d0 ;length to scan
blt.s .Exit
bsr.s RB_TUCDataID
beq.s .Out
tst.w $1c(a0) ;info table length
beq.s .Exit
rts
.Exit moveq #0,d0
.Out rts
;-------------------------------------------------
VD_TUCData moveq #0,d1
move.w $1c(a0),d1
add.w #$1e,d1 ;start of packed data
sub.l d1,d0
cmp.l #4,d0 ;at least one longword
blt.s .Exit
movem.l d2-d7/a2/a6,-(a7)
move.l d0,d6 ;bytes still there
move.l 8(a0),d3 ;calculate EOR value
eor.l #"M.F.",d3
neg.l d3
swap d3
ror.l #8,d3
bsr.s TUCData_GetLen
move.l a2,d0
sub.l a0,d0
movem.l (a7)+,d2-d7/a2/a6
tst.w d1
beq.s .Exit
rts
.Exit moveq #0,d0
rts
TUCData_GetLen moveq #0,d7
move.b 2(a0),d7 ;bit width of data
lea $1c(a0),a2 ;data table
moveq #0,d5
move.w (a2)+,d0 ;info table length
move.l a2,a6 ;info table
lea (a2,d0.w),a2
move.w d7,d1 ;bit width of hunk length
bsr.s .GetBitsD6
move.l d0,d4 ;hunk length
.lbC000062 moveq #0,d0
.lbC000064 asl.l #1,d5 ;get value from info table
bne.s .lbC000072
move.l (a2)+,d5
subq.l #4,d6
bmi.s .Error
eor.l d3,d5
move.b #$10,ccr
roxl.l #1,d5
.lbC000072 bcc.s .lbC000076
addq.w #2,d0
.lbC000076 move.w (a6,d0.w),d0 ;loop until negative
bpl.s .lbC000064
not.w d0
cmp.w #$100,d0 ;less than $100 -> data byte
bcs.s .lbC0000F0
bne.s .lbC0000A6 ;more than $100 -> crunched
* reloc info
.Error moveq #0,d1 ;error
rts
* crunched
.lbC0000A6 cmp.w #$110,d0 ;$101-$110
bhi.s .lbC0000C6
sub.w #$101,d0
move.w d0,d1 ;value 0-$f
bsr.s .GetBitsD6
sub.l d0,d4
moveq #7,d1
bsr.s .GetBitsD6
subq.l #2,d4
bra.s .lbC0000F2
.lbC0000C6 move.w d0,d2 ;$111-$1ff
move.w d0,d1
and.w #15,d1
bsr.s .GetBitsD6
addq.w #3,d0 ;length of string
sub.l d0,d4
move.w d2,d1
lsr.w #4,d1
and.w #15,d1
addq.w #2,d1
bsr.s .GetBitsD6
* copy uncrunched byte
.lbC0000F0 subq.l #1,d4
.lbC0000F2 bgt.s .lbC000062
bmi.s .Error
moveq #1,d1
rts
.GetBitsD6 moveq #0,d0
.lbC00013A asl.l #1,d5
bne.s .lbC000148
move.l (a2)+,d5
subq.l #4,d6
bge.s .Ok
addq.w #4,a7
bra.s .Error
.Ok eor.l d3,d5
move.b #$10,ccr
roxl.l #1,d5
.lbC000148 roxl.l #1,d0
dbra d1,.lbC00013A
rts
;-------------------------------------------------
DB_TUCData movem.l d2-d7/a2-a6,-(a7)
move.l a0,a5
move.l xfdbi_MinTargetLen(a5),d0
move.l d0,xfdbi_TargetBufSaveLen(a5)
move.l d0,xfdbi_TargetBufLen(a5)
move.w xfdbi_Flags(a5),d1
and.w #XFDFF_USERTARGET,d1
beq.s .Alloc
move.l xfdbi_UserTargetBuf(a5),d0
bra.s .UserTarget
.Alloc move.l xfdbi_TargetBufMemType(a5),d1
move.l 4.w,a6
jsr -198(a6)
.UserTarget move.w #XFDERR_NOMEMORY,xfdbi_Error(a5)
move.l d0,xfdbi_TargetBuffer(a5)
beq.s .Exit
move.l d0,a1
move.l xfdbi_SourceBuffer(a5),a0
move.l 8(a0),d3 ;calculate EOR value
eor.l #"M.F.",d3
neg.l d3
swap d3
ror.l #8,d3
bsr.s TUCData_Decr
tst.w d0
bne.s .Exit
.Free move.w xfdbi_Flags(a5),d1
and.w #XFDFF_USERTARGET,d1
bne.s .UserTarget2
move.l xfdbi_TargetBuffer(a5),a1
move.l xfdbi_TargetBufLen(a5),d0
move.l 4.w,a6
jsr -210(a6)
.UserTarget2 move.w #XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
moveq #0,d0
.Exit movem.l (a7)+,d2-d7/a2-a6
rts
TUCData_Decr moveq #0,d7
move.b 2(a0),d7 ;bit width of data
lea $1c(a0),a2 ;data table
moveq #0,d5
move.w (a2)+,d0 ;info table length
move.l a2,a6 ;info table
lea (a2,d0.w),a2
move.w d7,d1 ;bit width of hunk length
bsr TUC_GetBits
move.l d0,d4 ;hunk length
add.l a1,d4 ;end of hunk
.lbC000062 moveq #0,d0
.lbC000064 asl.l #1,d5 ;get value from info table
bne.s .lbC000072
move.l (a2)+,d5
eor.l d3,d5
move.b #$10,ccr
roxl.l #1,d5
.lbC000072 bcc.s .lbC000076
addq.w #2,d0
.lbC000076 move.w (a6,d0.w),d0 ;loop until negative
bpl.s .lbC000064
not.w d0
cmp.w #$100,d0 ;less than $100 -> data byte
bcs.s .lbC0000F0
bne.s .lbC0000A6 ;more than $100 -> crunched
* reloc info
.Error moveq #0,d0 ;error
rts
* crunched
.lbC0000A6 cmp.w #$110,d0 ;$101-$110
bhi.s .lbC0000C6
sub.w #$101,d0
move.w d0,d1 ;value 0-$f
bsr TUC_GetBits
move.w d0,d2 ;amount of same bytes
moveq #7,d1
bsr TUC_GetBits
.lbC0000BE move.b d0,(a1)+ ;copy same bytes
cmp.l d4,a1
beq.s .Error
dbra d2,.lbC0000BE
bra.s .lbC0000F0
.lbC0000C6 move.w d0,d2 ;$111-$1ff
move.w d0,d1
and.w #15,d1
bsr TUC_GetBits
addq.w #3,d0 ;length of string
move.w d2,d1
move.w d0,d2
lsr.w #4,d1
and.w #15,d1
addq.w #2,d1
bsr TUC_GetBits
neg.l d0 ;offset
.lbC0000E6 move.b (a1,d0.l),(a1)+
cmp.l d4,a1
dbeq d2,.lbC0000E6
tst.w d2
ble.s .lbC0000F2
bra.s .Error
* copy uncrunched byte
.lbC0000F0 move.b d0,(a1)+
.lbC0000F2 cmp.l d4,a1 ;end of hunk ??
bne .lbC000062
moveq #1,d0
rts
END