
;This is the Oddball version of Blitz.

#name Blitz
#type &ffa
#base 0

#set Service_Error		= &06
#set Service_PreModeChange	= &4D
#set Service_PreReset		= &45


struct v {
  .tickerctr	DCD 0
  .prevctr	DCD 0
  .waitcall	DCD 0
  .workspace	DCD 0
  .sizeof
}

DCD 0
DCD init
DCD final
DCD 0 ;service
DCD title
DCD help
DCD commandtable
DCD &49640
DCD swicode
DCD switab
DCD 0
.title
DCB "Blitz",0
.help
DCB "Blitz		1.01 (01 Dec 1994) - OddBall",0
ALIGN
.commandtable
DCB "Blitz",0
ALIGN
DCD 0
DCD 0
DCD 0
DCD blitzhelp

DCD 0; *** END Marker ***
.blitzhelp
DCB 27,0,"This particular Blitz decompresses files in Hammer format and provides a timed waiting facility.",10,13
DCB " A.Southgate 1994",0
ALIGN

.switab
DCB "Blitz",0
DCB "Wait",0
DCB "Time",0
DCB "SetTime",0
DCB "WaitCall",0
DCB "Spare1",0
DCB "HammerOp",0
DCB 0 ;*** END MARKER ***
ALIGN
.swicode
LDR R12,[R12]
CMP R11,#0
BEQ waitswi
CMP R11,#1
BEQ timeswi
CMP R11,#2
BEQ settimeswi
CMP R11,#5
BEQ hammeropswi
B unknownswierr
LDMFD R13!,{PC}

.claimticker
STMFD R13!,{R14}
MOV R0,#&1C
ADR R1,ticker
MOV R2,R12
SWI OS_Claim
LDMFD R13!,{PC}

.releaseticker
STMFD R13!,{R14}
MOV R0,#&1C
ADR R1,ticker
MOV R2,R12
SWI OS_Release
LDMFD R13!,{PC}

.ticker
STMFD R13!,{R0}
LDR R0,[R12,#v.tickerctr]
ADD R0,R0,#1
STR R0,[R12,#v.tickerctr]
LDR R0,[R12,#v.waitcall]
CMP R0,#0
LDMFD R13!,{R0}
BNE dowaitcall
MOVS PC,R14

.dowaitcall
STMFD R13!,{R0-R1,R14}
MOV R0,PC
ORR R1,R0,#3
TEQP R1,#0  ;switch to SVC
MOV R0,R0
STMFD R13!,{R0-R12,R14}
LDR R1,[R12,#v.waitcall]
MOV R0,#0
STR R0,[R12,#v.waitcall]
LDR R12,[R12,#v.workspace]
MOV R14,PC
MOV PC,R1
LDMFD R13!,{R0-R12,R14}
TEQP R0,#0  ;switch back to whatever
MOV R0,R0
LDMFD R13!,{R0-R1,PC}

.timeswi
STMFD R13!,{R1,R14}
LDR R0,[R12,#v.prevctr]
LDR R1,[R12,#v.tickerctr]
SUB R0,R1,R0
LDMFD R13!,{R1,PC}

.settimeswi
STMFD R13!,{R1,R14}
LDR R1,[R12,#v.tickerctr]
SUB R1,R1,R0
STR R1,[R12,#v.prevctr]
LDMFD R13!,{R1,PC}

.waitswi
STMFD R13!,{R2,R14}
LDR R1,[R12,#v.prevctr]
ADD R1,R1,R0
LDR R0,[R12,#v.tickerctr]
SUB R2,R1,R0
CMP R0,R1
ADDGE R1,R0,#1
MOV R3,#1<<24
.waitloop
SUBS R3,R3,#1
BLT toolong
LDR R0,[R12,#v.tickerctr]
CMP R0,R1
BLT waitloop
LDR R1,[R12,#v.prevctr]
STR R0,[R12,#v.prevctr]
SUB R0,R0,R1
MOV R1,R2
LDMFD R13!,{R2,PC}

.toolong
LDMFD R13!,{R2,R14}
B toolongerr

.waitcall
STR R0,[R12,#v.waitcall]
STR R1,[R12,#v.workspace]
MOV PC,R14

.removewaitcall
STMFD R13!,{R14}
MOV R0,#0
STR R0,[R12,#v.waitcall]
LDMFD R13!,{PC}



.hammeropswi
;on entry
;R0 = op type (0-size, 1-load, 2-ofs size, 3-ofs load)
;R1=filename
;R2=pathname
;R4=offset (if 2 or 3)
;on exit
;R0 corrupted
;R1,R2 preserved
;R3 = file length or 0 if not a hammer file
TST R0,#4
BNE hammerfind
TST R0,#1
BNE hammerload

.hammersize
STMFD R13!,{R1-R2,R4-R7,R14}
MOV R7,R1
BL openfile
LDMVSFD R13!,{R1-R2,R4-R7,PC}
MOV R3,#0
BL getword
LDMCSFD R13!,{R1-R2,R4-R7,R14}
BCS fileerr
MOV R1,R0
BL getword
LDMCSFD R13!,{R1-R2,R4-R7,R14}
BCS fileerr
BL closefile
BIC R1,R1,#&FFFF<<16
LDR R2,hamidcode
CMP R1,R2
MOV R3,R0
MOVNE R3,#0
LDMFD R13!,{R1-R2,R4-R7,PC}  ;drops through via R3
.hamidcode
DCB "Hm",0,0

;HammerOp 6
;R0=6
;R1=filename
;R2=pathname
;R4=offset into file
;returns
;R1,R2 as above
;R4 offset to file in question
;can be passed to HammerOp 2

.hammerfind
STMFD R13!,{R1-R2,R5-R7,R14}
BL openfile
LDMVSFD R13!,{R1-R2,R5-R7,PC}
BL getword
LDMCSFD R13!,{R1-R2,R5-R7,R14}
BCS fileerr
BL closefile
MOV R4,R0
LDMFD R13!,{R1-R2,R5-R7,PC}

.hammerload
;R0=1 or 3
;R1=filename
;R2=pathname
;R3=load address
;R4=offset (if 3)

STMFD R13!,{R3-R11,R14}
MOV R10,R3
BL openfile
LDMVSFD R13!,{R3-R11,PC}
BL getword
MOV R7,R0
BL getword
ADD R0,R0,#3
BIC R0,R0,#3
MOV R9,R0
MOV R8,R0  ;used as a constant
ADD R9,R10,R9; R9 is the end limit marker
TST R7,#1<<24
MOV R7,R10
MOVEQ R7,#0
SUB R10,R10,#1; align for putbyte
SUB R9,R9,#1  ; likewise
.loop1
BL 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
BL 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
MOV R0,R3
BL translate
LDRB R0,[R0]
BL putbyte
ADD R3,R3,#1
SUBS R2,R2,#1
BGT loop7
.typeins
CMP R10,R9
BLT loop1
BLNE inconserr
BL getbyte
CMP R0,#&FF
LDMNEFD R13!,{R3-R11,R14}
BNE underrunerr
.decompend
BL closefile
MOV R2,#&FFF
.typeerr
LDMFD R13!,{R3-R11,PC}


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

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

.type3     ;&20-&3F
MOV R1,R0
BL getbyte
BVS typeerr
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
MOV R0,R3
BL translate
LDRB R0,[R0]
BL putbyte
SUB R3,R3,#1
SUBS R2,R2,#1
BGT loop5
B typeins

.type4      ;&40-&7F
MOV R1,R0
BL getbyte
BVS typeerr
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
ADD R0,R5,R3,ASR #2
BL translate
LDRB R0,[R0]
BL putbyte
ADD R3,R3,R4
SUBS R2,R2,#1
BGT loop6
B typeins

.getbyte
STMFD R13!,{R1,R14}
MOV R1,R6
SWI XOS_BGet
LDMFD R13!,{R1,R14}
BCS overrunerr
MOV PC,R14

.putbyte
STMFD R13!,{R0,R14}
ADD R10,R10,#1
MOV R0,R10
BL translate
MOV R1,R0
LDMFD R13!,{R0,R14}
STRB R0,[R1]
MOV PC,R14

.translate
CMP R7,#0
MOVEQ PC,R14
SUB R0,R0,R7
MOV R1,R0,LSL #2
SUBS R0,R0,R8,LSR #2
ADDPL R1,R1,#1
SUBPL R1,R1,R8
SUBS R0,R0,R8,LSR #2
ADDPL R1,R1,#1
SUBPL R1,R1,R8
SUBS R0,R0,R8,LSR #2
ADDPL R1,R1,#1
SUBPL R1,R1,R8
MOV R0,R1
ADD R0,R0,R7
MOV PC,R14

.getword
STMFD R13!,{R1-R2,R14}
MOV R2,#0
MOV R1,R6
SWI XOS_BGet
ORRCC R2,R2,R0
SWICC XOS_BGet
ORRCC R2,R2,R0,LSL #8
SWICC XOS_BGet
ORRCC R2,R2,R0,LSL #16
SWICC XOS_BGet
ORRCC R0,R2,R0,LSL #24

LDMFD R13!,{R1-R2,R14}
BCS overrunerr
MOV PC,R14

.openfile
STMFD R13!,{R1-R4,R14}
MOV R3,R0
MOV R0,#&4C
CMP R2,#0
ORRNE R0,R0,#2
SWI XOS_Find
MOV R6,R0
MOVVS R6,#0
LDMVSFD R13!,{R1-R4,PC}
TST R3,#2
LDMEQFD R13!,{R1-R4,PC}
MOV R0,#1
MOV R1,R6
MOV R2,R4
SWI OS_Args
LDMFD R13!,{R1-R4,PC}


.closefile
STMFD R13!,{R0-R1,R14}
MOV R0,#0
MOV R1,R6
CMP R6,#0
SWINE XOS_Find
MOV R6,#0
LDMFD R13!,{R0-R1,PC}^


.init
STMFD R13!,{R7-R11,R14}
MOV R0,#6
MOV R3,#v.sizeof
SWI XOS_Module
LDMVSFD R13!,{R7-R11,R14}
BVS initerr
STR R2,[R12]
LDR R12,[R12]
MOV R0,#0
STR R0,[R12,#v.tickerctr]
STR R0,[R12,#v.prevctr]
STR R0,[R12,#v.waitcall]
BL claimticker
LDMFD R13!,{R7-R11,PC}

.final
STMFD R13!,{R7-R11,R14}
LDR R12,[R12]
BL releaseticker
MOV R0,#7
MOV R2,R12
SWI XOS_Module
LDMFD R13!,{R7-R11,PC}

.err
ORR R14,R14,#1<<28
MOVS PC,R14

.fileerr
STMFD R13!,{R0,R14}
BL closefile
LDMFD R13!,{R0,R14}
ADR R0,fileerrtext
B err
.inconserr
STMFD R13!,{R14}
SWI OS_WriteS
DCB "Blitz : Hammer file length inconsistency",0
ALIGN
LDMFD R13!,{PC}
.underrunerr

ADR R0,underrunerrtext
B err
.overrunerr
ADR R0,overrunerrtext
B err
.initerr
ADR R0,initerrtext
B err
.unknownswierr
ADR R0,unknownswitext
B err
.toolongerr
ADR R0,toolongtext
B err

.initerrtext
DCD &80c980
DCB "Blitz : Failed to initialise",0
ALIGN
.unknownswitext
DCD &80C981
DCB "Blitz : Unknown SWI",0
ALIGN
.toolongtext
DCD &80C982
DCB "Blitz : Excessive timer wait.",0
ALIGN
.underrunerrtext
DCD &80C983
DCB "Blitz : Hammer file underrun",0
ALIGN
.overrunerrtext
DCD &80C984
DCB "Blitz : Hammer file overrun",0
.fileerrtext
DCD &80C985
DCB "Blitz : File error",0
ALIGN


