Got decompression working, yay\!

This commit is contained in:
Martin Haye 2017-01-06 17:49:51 -08:00
parent bf179182b0
commit 845239c2cf
5 changed files with 109 additions and 43 deletions

View File

@ -1249,10 +1249,10 @@ class A2PackPartitions
} }
// If we saved at least 10 bytes, take the compressed version. // If we saved at least 10 bytes, take the compressed version.
if (false && (uncompressedLen - compressedLen) >= 10) { if ((uncompressedLen - compressedLen) >= 10) {
if (debugCompression) if (debugCompression)
println String.format(" Compress. rawLen=\$%x compLen=\$%x", uncompressedLen, compressedLen) println String.format(" Compress. rawLen=\$%x compLen=\$%x", uncompressedLen, compressedLen)
compressionSavings += (uncompressedLen - compressedLen) - 2 compressionSavings += (uncompressedLen - compressedLen) - 2 // -2 for storing compressed len
return [data:compressedData, len:compressedLen, return [data:compressedData, len:compressedLen,
compressed:true, uncompressedLen:uncompressedLen] compressed:true, uncompressedLen:uncompressedLen]
} }

View File

@ -15,11 +15,11 @@
* = $DF00 * = $DF00
tmp = $2 ; len 2 tmp = $2 ; len 2
pTmp = $4 ; len 2 pTmp = $6 ; len 2 ; not at $4, to preserve memmgr's pTmp
bits = $6 ; len 1 bits = $8 ; len 1
pSrc = $C ; len 2 pDst = $C ; len 2 ; opposite order from memmgr,
pDst = $E ; len 2 pSrc = $E ; len 2 ; so it can avoid swapping
pEnd = $10 ; len 2 pEnd = $10 ; len 2
cout = $FDED cout = $FDED

View File

@ -22,12 +22,8 @@ DEBUG = 0
* = $2000 * = $2000
tmp = $2 ; len 2 pDst = $C ; len 2 ; opposite order from memmgr,
pTmp = $4 ; len 2 pSrc = $E ; len 2 ; so it can avoid swapping
bits = $6 ; len 1
pSrc = $C ; len 2
pDst = $E ; len 2
pEnd = $10 ; len 2 pEnd = $10 ; len 2
pData = $80 ; len 2 pData = $80 ; len 2

View File

@ -27,8 +27,8 @@
; Constants ; Constants
MAX_SEGS = 96 MAX_SEGS = 96
DEBUG = 1 DEBUG = 0
SANITY_CHECK = 1 ; also prints out request data SANITY_CHECK = 0 ; also prints out request data
; Zero page temporary variables ; Zero page temporary variables
tmp = $2 ; len 2 tmp = $2 ; len 2
@ -37,10 +37,10 @@ reqLen = $6 ; len 2
resType = $8 ; len 1 resType = $8 ; len 1
resNum = $9 ; len 1 resNum = $9 ; len 1
isAuxCmd = $A ; len 1 isAuxCmd = $A ; len 1
isCompressed = $B ; len 1 unused____0B = $B ; len 1
pSrc = $C ; len 2 pSrc = $C ; len 2
pDst = $E ; len 2 pDst = $E ; len 2
ucLen = $10 ; len 2 pEnd = $10 ; len 2
; Mapping of ProRWTS register names to mem mgr registers: ; Mapping of ProRWTS register names to mem mgr registers:
; "status" -> tmp+1 ; "status" -> tmp+1
@ -97,9 +97,9 @@ relocate:
cpx #$40 ; skip our own unrelocated code $4000.4FFF cpx #$40 ; skip our own unrelocated code $4000.4FFF
bne + bne +
ldx #$60 ldx #$60
+ cpx #$C0 ; skip IO space $C000.CFFF + cpx #$C0 ; skip IO space $C000.CFFF, our future home $D000.DEFF, and decomp $DF00.DFFF
bne + bne +
ldx #$D0 ldx #$E0
+ cpx #$F6 ; skip ProRWTS $F600.FEFF, and ROM vecs $FF00.FFFF + cpx #$F6 ; skip ProRWTS $F600.FEFF, and ROM vecs $FF00.FFFF
bne .clr1 bne .clr1
@ -207,11 +207,11 @@ init: !zone
; 0: main $0000 -> 4, active + locked ; 0: main $0000 -> 4, active + locked
; 1: aux $0000 -> 2, active + locked ; 1: aux $0000 -> 2, active + locked
; 2: aux $0200 -> 3, inactive ; 2: aux $0200 -> 3, inactive
; 3: aux $C000 -> 0, active + locked ; 3: aux $BFFD -> 0, active + locked
; 4: main $0xxx -> 5, inactive (xxx = end of mem mgr low mem portion) ; 4: main $0xxx -> 5, inactive (xxx = end of mem mgr low mem portion)
; 5: main $4000 -> 6, active + locked ; 5: main $4000 -> 6, active + locked
; 6: main $6000 -> 7, inactive ; 6: main $6000 -> 7, inactive
; 7: main $BF00 -> 8, active + locked ; 7: main $BFFD -> 8, active + locked
; 8: main $E000 -> 9, inactive ; 8: main $E000 -> 9, inactive
; 9: main $FFFA -> 0, active + locked ; 9: main $FFFA -> 0, active + locked
; First, the flags ; First, the flags
@ -242,10 +242,9 @@ init: !zone
; Then the addresses ; Then the addresses
lda #2 lda #2
sta tSegAdrHi+2 sta tSegAdrHi+2
ldy #$C0 lda #$BF
sty tSegAdrHi+3 sta tSegAdrHi+3
dey sta tSegAdrHi+7
sty tSegAdrHi+7
lda #<lastLoMem lda #<lastLoMem
sta tSegAdrLo+4 sta tSegAdrLo+4
lda #>lastLoMem lda #>lastLoMem
@ -258,6 +257,9 @@ init: !zone
sta tSegAdrHi+8 sta tSegAdrHi+8
lda #$FA lda #$FA
sta tSegAdrLo+9 sta tSegAdrLo+9
lda #$FD
sta tSegAdrLo+3
sta tSegAdrLo+7
lda #$FF lda #$FF
sta tSegAdrHi+9 sta tSegAdrHi+9
; Finally, form a long list of the remaining unused segments. ; Finally, form a long list of the remaining unused segments.
@ -2072,8 +2074,8 @@ disk_queueLoad: !zone
lda (pTmp),y ; and hi byte lda (pTmp),y ; and hi byte
+ stx reqLen ; save the uncompressed length + stx reqLen ; save the uncompressed length
sta reqLen+1 ; both bytes sta reqLen+1 ; both bytes
!if DEBUG { +prStr : !text "uclen=",0 : +prWord reqLen : +crout } !if DEBUG { +prStr : !text "ucLen=",0 : +prWord reqLen : +crout }
; Load the bytecode of the main (first) bytecode module at the highest possible point ; Load the bytecode of the gamelib (first) bytecode module at the highest possible point
; (to reduce fragmentation of the rest of aux mem) ; (to reduce fragmentation of the rest of aux mem)
lda resType lda resType
cmp #RES_TYPE_BYTECODE cmp #RES_TYPE_BYTECODE
@ -2081,11 +2083,12 @@ disk_queueLoad: !zone
lda resNum lda resNum
cmp #1 cmp #1
bne + bne +
lda #0 ; Take $BFFD - size. Why $BFFD and not $C000? Because decomp temporarily overwrites 3-byte "unnderlap" after.
lda #$FD
sec sec
sbc reqLen sbc reqLen
sta targetAddr sta targetAddr
lda #$C0 lda #$BF
sbc reqLen+1 sbc reqLen+1
sta targetAddr+1 sta targetAddr+1
+ jsr shared_alloc ; reserve memory for this resource (main or aux as appropriate) + jsr shared_alloc ; reserve memory for this resource (main or aux as appropriate)
@ -2210,30 +2213,29 @@ disk_finishLoad: !zone
ldy .ysave ldy .ysave
lda (pTmp),y ; grab resource length on disk lda (pTmp),y ; grab resource length on disk
sta reqLen ; save for reading sta reqLen ; save for reading
sta ucLen sta pEnd
iny iny
lda (pTmp),y ; hi byte too lda (pTmp),y ; hi byte too
sta isCompressed ; save flag php ; save hi bit (isCompressed) for later check
and #$7F ; mask off the flag to get the real (on-disk) length and #$7F ; mask off the flag to get the real (on-disk) length
sta reqLen+1 sta reqLen+1
bit isCompressed ; retrieve flag iny ; if compressed, we also have the uncomp len avail next
bpl + ; if uncompressed, we also have the ucLen now
iny ; is compressed
lda (pTmp),y ; fetch uncomp length lda (pTmp),y ; fetch uncomp length
sta ucLen ; and save it sta pEnd ; and save it
iny iny
lda (pTmp),y ; hi byte of uncomp len lda (pTmp),y ; hi byte of uncomp len
+ sta ucLen+1 ; save uncomp len hi byte sta pEnd+1 ; save uncomp len hi byte
jsr scanForResource ; find the segment number allocated to this resource jsr scanForResource ; find the segment number allocated to this resource
beq .addrErr ; it better have been allocated beq .addrErr ; it better have been allocated
lda tSegAdrLo,x ; grab the address lda tSegAdrLo,x ; grab the address
sta pDst ; and save it to the dest point for copy or decompress ldy tSegAdrHi,x ; hi byte too
lda tSegAdrHi,x ; hi byte too sta pDst ; and save it for later
sta pDst+1 sty pDst+1
!if DEBUG { jsr .debug2 } !if DEBUG { jsr .debug2 }
lda #cmdread plp ; retrieve isCompressed flag
bmi .readAndDecomp ; if so, go do read/decompress thing
lda #cmdread ; else, just read.
jsr readAndAdj jsr readAndAdj
;jsr lz4Decompress ; decompress (or copy if uncompressed)
.resume ldy .ysave .resume ldy .ysave
.next lda (pTmp),y ; lo byte of length .next lda (pTmp),y ; lo byte of length
clc clc
@ -2255,6 +2257,60 @@ disk_finishLoad: !zone
+ jmp .scan ; back for more + jmp .scan ; back for more
.addrErr: .addrErr:
jmp invalParam jmp invalParam
.readAndDecomp:
; Calculate end of uncompressed data, and start of compressed data.
; We overlap the compressed and uncompressed as much as possible, e.g.:
; DDDDDDDDDDDDDD
; SSSSSSSSSsss ; sss is the 3-byte 'underlap'
sta pSrc
sty pSrc+1
clc
adc pEnd
sta pEnd ; reuse pEnd for end ptr
tax
tya
adc pEnd+1
sta pEnd+1
tay
txa
adc #3 ; this is the max "underlap" required for decompressing overlapped buffers
bcc +
iny
+ sec
sbc reqLen ; then back up by the compressed size
sta pDst ; and load the compressed data there
tya
sbc reqLen+1
sta pDst+1
; save the 3 byte underlap bytes because we're going to read over them
ldy #2
ldx isAuxCmd
sta clrAuxRd,x ; from aux mem if appropriate
- lda (pEnd),y
pha
dey
bpl -
sta clrAuxRd
; Now read the raw (compressed) data
lda #cmdread
jsr readAndAdj
!if DEBUG { jsr .debug3 }
; Stuff was read to into pDst. Now that becomes the source. Decompressor is set up
; to decompress *from* our pDst to our pSrc. Its labels are swapped.
ldx isAuxCmd
sta clrAuxRd,x ; switch to r/w aux mem if appropriate
sta clrAuxWr,x
jsr lx47Decomp ; remaining work is for the dedicated decompressor
; restore the underlap bytes
ldy #0
- pla
sta (pEnd),y
iny
cpy #3
bne -
sta clrAuxRd
sta clrAuxWr
jmp .resume ; always taken
.ysave: !byte 0 .ysave: !byte 0
.nFixups: !byte 0 .nFixups: !byte 0
@ -2281,6 +2337,15 @@ disk_finishLoad: !zone
+prWord pDst +prWord pDst
+crout +crout
rts rts
.debug3:+prStr : !text "decomp ",0
+prStr : !text "src=",0
+prWord pDst
+prStr : !text "dst=",0
+prWord pSrc
+prStr : !text "end=",0
+prWord pEnd
+crout
rts
} ; end DEBUG } ; end DEBUG
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
@ -2821,8 +2886,13 @@ tSegAdrHi !fill MAX_SEGS
tableEnd = * tableEnd = *
; Be careful not to grow past the size of the LC bank ; Be careful not to grow past the size of the LC bank
!if tableEnd > $DFFF { !ifdef PASS2 {
!error "Memory manager grew too large." !warn "mmgr spare: ", lx47Decomp - tableEnd
!if tableEnd >= lx47Decomp {
!error "Memory manager grew too large."
}
} else { ;PASS2
!set PASS2=1
} }
} ; end of !pseudopc $D000 } ; end of !pseudopc $D000

View File

@ -71,7 +71,7 @@
; 0000.01FF 6502 zero page and stack ; 0000.01FF 6502 zero page and stack
; 0200.2xxx expander (if 3D map is running) ; 0200.2xxx expander (if 3D map is running)
; 3000.9xxx (free) ; 3000.9xxx (free)
; Axxx.BFFF gameloop PLASMA code ; Axxx.BFFF gameloop PLASMA code (loaded as high as possible)
; C000.CFFF I/O ; C000.CFFF I/O
; D000.DFFF bank 1: ProRWTS runtime (Note: D900.DFFF free) ; D000.DFFF bank 1: ProRWTS runtime (Note: D900.DFFF free)
; bank 2: part of expander ; bank 2: part of expander