
#name decomp
#type &ffc
#base 0

; This file should be compiled with ExtAsm

struct v {

  .sizeof
}

macro getbyte
{
  LDRB R0,[R11],#1
}
macro putbyte
{
  STRB R0,[R10,#1]!
}


;init conditions
;R0 points to the file to be decomped
;exits with R1 = size of decompressed file
;           R2 = address to return to after allocation

.init
LDR R1,[R0]
BIC R1,R1,#&FFFF<<16
LDR R2,idcode
CMP R1,R2
BNE nothmr
LDR R1,[R0,#4]
MOV R2,PC
MOV PC,R14

;entry conditions
;R0 = address of file to decomp
;R1 = address of space for decomped file
.entry
STMFD R13!,{R10-R11,R14}
MOV R11,R0
MOV R10,R1
LDR R0,[R11]
BIC R0,R0,#&FFFF<<16
LDR R1,idcode
CMP R1,R0
BNE nothmr2
LDR R9,[R11,#4]
ADD R9,R10,R9; R9 is the end limit marker
MOV R8,#0
SUB R10,R10,#1; align for putbyte
SUB R9,R9,#1  ; likewise
ADD R11,R11,#8; skip header
.loop1
getbyte
CMP R0,#&10
BLT type1
CMP R0,#&20
BLT type2
CMP R0,#&40
BLT type3
CMP R0,#&80
BLT type4
;drops through
.type5
CMP R0,#&FF
BEQ overrunerr
MOV R1,R0
getbyte
AND R2,R1,#&78
MOV R2,R2,LSR #3
ADD R2,R2,#2
AND R3,R1,#&7
ADD R3,R0,R3,LSL #8
SUB R3,R10,R3
.loop7
LDRB R0,[R3],#1
putbyte
SUBS R2,R2,#1
BGT loop7
.typeins
CMP R10,R9
BLT loop1
BLNE inconserr
getbyte
CMP R0,#&FF
BNE underrunerr
.decompend
LDMFD R13!,{R10-R11,PC}

.type1     ;&00-&0F
MOV R1,R0
CMP R1,#15
ADDNE R1,R1,#2
MOVEQ R1,#256
getbyte
.loop2
putbyte
SUBS R1,R1,#1
BGT loop2
B typeins

.type2     ;&10-&1F
MOV R1,R0
AND R1,R1,#&F
ADD R1,R1,#1
.loop3
getbyte
putbyte
SUBS R1,R1,#1
BGT loop3
B typeins

.type3     ;&20-&3F
MOV R1,R0
getbyte
AND R2,R1,#&1C
MOV R2,R2,LSR #2
ADD R2,R2,#2
AND R3,R1,#&3
ADD R3,R0,R3,LSL #8
SUB R3,R10,R3
.loop5
LDRB R0,[R3],#-1
putbyte
SUBS R2,R2,#1
BGT loop5
B typeins

.type4      ;&40-&7F
MOV R1,R0
getbyte
AND R2,R1,#&38
MOV R2,R2,LSR #3
ADD R2,R2,#2
AND R4,R1,#&06
MOV R4,R4,LSR #1
CMP R4,#2
ADDGE R4,R4,#1

AND R3,R1,#&1
ADD R3,R0,R3,LSL #8
SUB R5,R10,R3

MOV R1,#1
MOV R4,R1,LSL R4

MOV R3,#0
.loop6
LDRB R0,[R5,R3,ASR #2]
putbyte
ADD R3,R3,R4
SUBS R2,R2,#1
BGT loop6
B typeins

.nothmr
ADR R0,nothmrtext
MOV R1,#0
ADR R2,traperr
ORR R14,R14,#1<<28
MOVS PC,R14

.nothmr2
ADR R0,nothmr2text
SWI OS_GenerateError

.traperr
ADR R0,traperrtext
SWI OS_GenerateError

.overrunerr
ADR R0,overrunerrtext
ADD R0,R0,#4
SWI OS_Write0
SWI OS_NewLine
B decompend
SWI OS_GenerateError

.underrunerr
ADR R0,underrunerrtext
ADD R0,R0,#4
SWI OS_Write0
SWI OS_NewLine
B decompend
SWI OS_GenerateError

.inconserr
STMFD R13!,{R14}
ADR R0,inconserrtext
ADD R0,R0,#4
SWI OS_Write0
SWI OS_NewLine
LDMFD R13!,{PC}

.nothmrtext
DCD &666
DCB "Decomp : Not a hammer file",0
ALIGN
.nothmr2text
DCD &666
DCB "Decomp : R0 corrupted during space allocation",0
ALIGN
.traperrtext
DCD &666
DCB "Decomp : Your error trapping is not working",0
ALIGN
.overrunerrtext
DCD &666
DCB "Decomp : Overrun - bad hammer file",0
ALIGN
.underrunerrtext
DCD &666
DCB "Decomp : Underrun - bad hammer file",0
ALIGN
.inconserrtext
DCD &666
DCB "Decomp : File length inconsistent with header",0
ALIGN
.idcode
DCB "Hm",0,0
.spec
DCB "Decomp 0.01",0
ALIGN
