REM >A.SSAVEAS
REM Source code for SSAVE
REM 2byte screen compactor
REM by Greg Cook 20/Jun/1999
REM Optimally compresses files using
REM first-past-the-post to choose
REM C or R blocks.
 
IFPAGE<&1B00THENSTOP
rbcptr=0
rbiaschar1=ASC("R")
rbiaschar2=ASC("r")
sofn=2
code=&1900
osArgs=&FFDA
osBput=&FFD4
osByte=&FFF4
osFind=&FFCE
argBlock=&80
s=&80
t=&82
u=&84
v=&86
z=&88
channel=&89
flag=&8A
FOR pass=0TO3STEP3
P%=code
[OPT pass
LDY #0
STY flag
LDA #1
LDX #argBlock
JSR osArgs
LDY #rbcptr
LDA (argBlock),Y
CMP #rbiaschar1
BEQ setrbias
CMP #rbiaschar2
BNE clearrbias
.setrbias
LDY #&80
STY flag
.clearrbias
LDA argBlock
CLC
ADC #sofn MOD 256 
TAX
LDA argBlock+1
ADC #sofn DIV 256
TAY
LDA #128
JSR osFind
STA channel
LDA #132
JSR osByte
STX s
STY s+1
STX t
STY t+1
STX u
STY u+1
LDY #2
STY z
.loop
BIT u+1
BMI eos
JSR find
LDA v
SEC
SBC u
TAY
LDA v+1
SBC u+1
BNE repeat
TYA
LDY v
STY u
LDY v+1
STY u+1
CLC
ADC z
BCS repeat
SEC
SBC #3
BCC copy
STA z
BEQ ontheline
BMI repeat
CMP #2
BEQ woodwork
BPL repeat
BMI loop
.eos
JSR flush
LDY channel
LDA #0
JMP osFind
.woodwork
BIT flag
BPL loop
.repeat
JSR flush
LDY #2
STY z
BNE loop
.ontheline
BIT flag
BMI loop
.copy
LDY v
STY t
LDY v+1
STY t+1
LDY #0
STY z
BEQ loop
.flush
LDA t
SEC
SBC s
TAY
LDA t+1
SBC s+1
BNE chain
CPY #0
BEQ flushrep
.chain
PHA
TYA
LDY channel
JSR osBput
PLA
JSR osBput
.fLoop
LDY #0
LDA (s),Y
LDY channel
JSR osBput
INC s
BNE fNoCarry
INC s+1
.fNoCarry
LDY s
CPY t
BNE fLoop
LDY s+1
CPY t+1
BNE fLoop
.flushrep
LDY v
STY t
LDY v+1
STY t+1
LDY s
STY u
LDY s+1
STY u+1
.rLoop
JSR find
LDA v
SEC
SBC u
TAY
LDA v+1
SBC u+1
BNE somerep
CPY #0
BEQ visu
.somerep
PHA
TYA
LDY channel
JSR osBput
PLA
ORA #&80
JSR osBput
LDY #0
LDA (u),Y
LDY channel
JSR osBput
LDY v
STY u
LDY v+1
STY u+1
.visu
LDY v
CPY t
BNE rLoop
LDY v+1
CPY t+1
BNE rLoop
STY s+1
LDY v
STY s
RTS
.find
LDY #0
LDA u
STA v
LDA u+1
STA v+1
BPL fndLoop
RTS
.fndLoop
INC v
BNE fndNoCarry
INC v+1
BMI stuffit
.fndNoCarry
LDA (u),Y
CMP (v),Y
BEQ fndLoop
.stuffit
RTS
]
NEXT
OSCLI "SAVE SSAVE "+STR$~(code)+" "+STR$~(P%)
