Save'n'Pack
von Christian Dombacher
Die Effekte werden immer besser, noch
mehr Sprites und Farben schillern auf
dem Bildschirm. Die Kehrseite der Medaille ist der Speicheraufwand. Bisher
wurde dieses Problem dadurch gelöst
( oder umgangen), daß man die Note im
Speicher gepackt und dann auf Disk abgespeichert hat. Da der Speicherinhalt
dadurch unverwendbar geworden ist, kann
danach nur noch ein Reset durchgeführt
werden. Die Idee, die hinter dem >> Save' n' Pack-System<< steht, ist eigentlich
ganz einfach. Mit Hilfe eines Equal-Char- Packers und einer leicht geänderten
Save-Routine kann man vom Speicher direkt auf Disk packen. Zuerst wird mit
dem Scanner ein Codebyte gesucht, das im
zu packenden Speicherbereich möglichst
selten vorkommt. Bevor die eigentliche
Arbeit beginnt, wird der Entpacker über den Bus ausgegeben. Befinden sich nun
mehr als drei gleiche Bytes im Speicher, so wird eine spezielle Bytekombination
abgespeichert, die angibt, wie oft welches Byte beim Entpacken dupliziert werden muß. Anderenfalls wird das Originalbyte ausgegeben.
Verwendet wird die Routine folgendermaßen: Zunächst müssen die Filenamenparameter ( über $ FFBD) gesetzt werden. Dann
wird die Endadresse des zu packenden
Speicherbereichs in >> END<< abgespeichert, danach wird die Anfangsadresse
ins Xund Y-Register geladen und die
Routine aufgerufen. Es sind also nicht
mehr Parameter als bei der normalen Save- Routine nötig. Dies ermöglicht ein
leichtes Einbauen in vorhandene Programme. Der Inhalt des Prozessorstatusregisters und der Programmeinsprung im Depackerteil müssen beim Abtippen festgelegt werden ( Im Kommentar steht >> Enter
Value !<<) . Die Decrunchroutine liegt in der Zeropage, ihr könnt also Speicherbereiche von $0100-$ FFFF mit dem Save' n'- Pack-System in Angriff nehmen.
;--------------------------
;- Save'n'Pack by the sir -
;- Assembler: Startool -
;--------------------------
BUF = $CE00 ;define labels
INITI5 = $FFBD
I1 = $AC
I2 = $AE
I5 = $BB
BY = $02
WORK = $03
END = $F8
;--- Cruncher & Scanner ---
CRUNCH STX ANFL+1
STY ANFH+1
LDA #$08 ;Drive
STA $BA
LDA #$61
STA $B9
JSR $F3D5 ;Open
LDA $BA
JSR $ED0C ;Send Driveaddr
LDA $B9
JSR $EDB9 ;Send Sekaddr
LDA #$01 ;Startaddress
JSR $EDDD ;Low
LDA #$08
JSR $EDDD ;High
JSR SSCAN ;Scan Memory
LDY #$00
CR5 LDA DEPACK,Y ;Depacker Out
JSR $EDDD
INY
CPY #<PACK-DEPACK
BNE CR5
JSR CR0 ;Packen
JSR STOSEQ ;Last Sequence
JMP $F63F ;Close
CR0 LDX ANFL+1
LDY ANFH+1
STX I2
STY I2+1
LDX #$01 ;X=Lencounter
JSR GETBYT ;Get First Byte
STA BY
CR2 JSR GETBYT ;Equal ?
CMP BY
BNE CR1
INX ;Count + 1
BNE CR2 ;Count < 255
DEX ;Overflow
CR1 PHA
JSR STOSEQ ;Store Sequence
LDX #$01 ;Len = 1
PLA
CMP BY ;Overflow ?
BEQ CR2
STA BY ;New Value
JSR CHKEND ;End ?
BCC CR2
RTS
STOSEQ LDA BY
CMP DC0 ;Byte=Code
BEQ CR3 ;-> Store Seq
CPX #$04 ;Len > 3 ?
BCS CR3 ;-> Store Seq
CR4 JSR $EDDD ;Byte Out
DEX ;Len times
BNE CR4
RTS
CR3 LDA DC0 ;Codebyte Out
JSR $EDDD
TXA ;Len Out
JSR $EDDD
LDA BY ;Byte Out
JMP $EDDD
SSCAN LDX ANFL+1
LDY ANFH+1
STX I2
STY I2+1
LDY #$00 ;Clear Buffer
TYA
SC6 STA BUF,Y
STA BUF+$0100,Y
INY
BNE SC6
JSR SC0 ;Count Bytes
LDY #$FF ;Search Minimum
STY I1
STY I1+1
INY
SC4 TYA ;Pos of Number
ASL
STA I5
LDA #>BUF
ADC #$00
STA I5+1
STY WORK
LDY #$00
LDA (I5),Y ;(I5) < I1 ?
PHA
CMP I1
INY
LDA (I5),Y
TAX
SBC I1+1
PLA
LDY WORK
BCS SC3 ;(I5) > I1
STA I1 ;Set New I1
STX I1+1
STY DC0 ;Set Codebyte
SC3 INY
BNE SC4
RTS
SC0 LDY #$00
SC1 JSR GETBYT ;Byte from Mem
ASL ;Pos of Number
STA I5
LDA #>BUF
ADC #$00
STA I5+1
LDA (I5),Y ;(I5) + 1
CLC
ADC #$01
STA (I5),Y
INY
LDA (I5),Y
ADC #$00
STA (I5),Y
DEY
JSR CHKEND
BCC SC1
RTS
GETBYT LDA (I2),Y ;Byte from Mem
INC I2
BNE GB1
INC I2+1
RTS
CHKEND LDA I2 ;End ?
CMP END
LDA I2+1
SBC END+1
RTS
;--- Decruncher ---
DEPACK .BYTE $0E,$08,$C8,$07,$9E
.TEXT "2062 TS"
.BYTE $00,$00,$00
ZPPOS =$5 C
SEI
INC $01
LDY #$32 ;Trans Depacker
DC3 LDA DC0-1-K,Y
STA ZPPOS-1,Y
DEY
BNE DC3
STY $AC ;Trans Proggie
STY $AD
DC1 DEC $AD
DEC $AF
DC2 DEY
LDA ($AE),Y
STA ($AC),Y
TYA
BNE DC2
LDA $AF
CMP #$07
BNE DC1
LDA $AE ;Set Addrs
EOR #$FF
CLC
ADC #<PACK+1-K
STA $AC
BCC ANFL
INC $AD
ANFL LDX #$01 ;Start
ANFH LDY #$08
STX $AE
STY $AF
LDY #$00
JMP ZPPOS+1
DC0 .BYTE $99 ;Codebyte
DC7 JSR DC8-C ;Get Byte
CMP ZPPOS ;= Codebyte ?
BNE DC4
JSR DC8-C ;Get Len
TAX
JSR DC8-C ;Get Byte
.BYTE $2C ;Skip 2 Bytes
DC4 LDX #$01
DC6 STA ($AE),Y ;Store Byte/Seq
INC $AE
BNE DC5
INC $AF
DC5 DEX
BNE DC6
LDA $AD
BNE DC7
LDA #$37 ;Enter Value !
STA $01
CLI
JMP $FFFF ;Enter Value !
DC8 LDA ($AC),Y ;Get Byte
INC $AC
BNE DC9
INC $AD
DC9 RTS
PACK . BYTE $00 ; Dummy
C = DC0- ZPPOS ; Correction K = DEPACK-$0801
So, das war' s. Natürlich findet ihr den
Sourcecode ( im Startool-Format) und den
ausführbaren Code auf Disk vor. In diesem Sinne, mögen Eure Programme schrumpfen.
(cd)