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)