Save'n'Pack von Christian Dombacher ----------------------------------------
Die Effekte werden immer besser, noch mehr Sprites und Farben schillern auf dem Bildschirm. Die Kehrseite der Me- daille ist der Speicheraufwand. Bisher wurde dieses Problem dadurch gelöst (oder umgangen), daß man die Note im Speicher gepackt und dann auf Disk abge- speichert hat. Da der Speicherinhalt dadurch unverwendbar geworden ist, kann danach nur noch ein Reset durchgeführt werden. Die Idee, die hinter dem >>Sa- ve'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 di- rekt 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 wel- ches Byte beim Entpacken dupliziert wer- den muß. Anderenfalls wird das Origi- nalbyte ausgegeben. Verwendet wird die Routine folgenderma- ßen: Zunächst müssen die Filenamenpara- meter (über $FFBD) gesetzt werden. Dann wird die Endadresse des zu packenden Speicherbereichs in >>END<< abgespei- chert, danach wird die Anfangsadresse ins X- und Y-Register geladen und die Routine aufgerufen. Es sind also nicht mehr Parameter als bei der normalen Sa- ve-Routine nötig. Dies ermöglicht ein leichtes Einbauen in vorhandene Program- me. Der Inhalt des Prozessorstatusregi- sters und der Programmeinsprung im De- packerteil müssen beim Abtippen festge- legt werden (Im Kommentar steht >>Enter Value !<<). Die Decrunchroutine liegt in der Zeropage, ihr könnt also Speicherbe- reiche 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 = $5C
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 die- sem Sinne, mögen Eure Programme schrump- fen.
(cd)