1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-03-24 13:35:24 +00:00

LZ4 decompressor

This commit is contained in:
David Schmenk 2018-04-19 06:59:39 -07:00
parent 430b70f931
commit 6cf47da936
3 changed files with 168 additions and 1 deletions

View File

@ -36,6 +36,7 @@ SNDSEQ = rel/apple/SNDSEQ\#FE1000
PLAYSEQ = rel/apple/PLAYSEQ\#FE1000
SANITY = rel/SANITY\#FE1000
RPNCALC = rel/RPNCALC\#FE1000
LZ4DECOMP = rel/LZ4DECOMP\#FE1000
UTHERNET2 = rel/apple/UTHERNET2\#FE1000
UTHERNET = rel/apple/UTHERNET\#FE1000
ETHERIP = rel/ETHERIP\#FE1000
@ -81,7 +82,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4DECOMP) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
-rm vmsrc/plvmzp.inc
c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64)
@ -255,6 +256,10 @@ $(SANITY): samplesrc/sanity.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/sanity.pla > samplesrc/sanity.a
acme --setpc 4094 -o $(SANITY) samplesrc/sanity.a
$(LZ4DECOMP): samplesrc/lz4.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/lz4.pla > samplesrc/lz4.a
acme --setpc 4094 -o $(LZ4DECOMP) samplesrc/lz4.a
$(RPNCALC): samplesrc/rpncalc.pla libsrc/fpu.pla inc/fpu.plh libsrc/fpstr.pla inc/fpstr.plh inc/conio.plh $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < samplesrc/rpncalc.pla > samplesrc/rpncalc.a
acme --setpc 4094 -o $(RPNCALC) samplesrc/rpncalc.a

View File

@ -47,6 +47,7 @@ rm -rf prodos/demos
mkdir prodos/demos
cp rel/apple/DGRTEST#FE1000 prodos/demos/DGRTEST.REL
cp rel/RPNCALC#FE1000 prodos/demos/RPNCALC.REL
cp rel/LZ4DECOMP#FE1000 prodos/demos/LZ4DECOMP.REL
cp rel/ROD#FE1000 prodos/demos/ROD.REL
mkdir prodos/demos/rogue

161
src/samplesrc/lz4.pla Normal file
View File

@ -0,0 +1,161 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/fileio.plh"
struc t_header
word magic[2]
byte FLG
byte BD
end
word arg
byte ref
def dump(addr, len)#0
while len
putc(^addr == $0A ?? $0D :: ^addr)
addr++
len--
loop
end
def lz4Decomp(seq, seqend)#2
word buff, data, len, offset, fill
byte token
buff = heapalloc(heapavail - 256)
data = buff
if not buff
return NULL, 0
fin
while seq < seqend
//puts("LZ4 sequence @ $"); puth(seq); putln
token = ^seq
seq++
len = token >> 4
if len
//
// Literal sequence
//
if len == 15
while ^seq == 255
len = len + 255
seq++
loop
len = len + ^seq
seq++
fin
//puts("Literals @ $"); puth(seq); puts(", len $"); puth(len); putln; getc
dump(seq, len)
memcpy(data, seq, len)
data = data + len
seq = seq + len
fin
//
// Match sequence
//
offset = *seq
seq = seq + 2
len = (token & $0F) + 4
if len == 19 // $0F + 4
while ^seq == 255
len = len + 255
seq++
loop
len = len + ^seq
seq++
fin
//puts("Match offset $"); puth(offset); puts(" @ $"); puth(data - offset); puts(", len $"); puth(len); putln; getc
while len > offset
memcpy(data, data - offset, offset)
dump(data, offset)
data = data + offset
len = len - offset
loop
memcpy(data, data - offset, len)
dump(data, len)
data = data + len
loop
return buff, data - buff
end
def lz4ReadBlock(flags)#2
word size[2], block, data, len
fileio:read(ref, @size, 4)
if size[1] & $7FFF
return NULL, 0
fin
block = heapalloc(size[0])
if block
fileio:read(ref, block, size[0])
else
return NULL, 0
fin
if size[1] & $8000
//
// Uncompressed block
//
data = block
//puts("Uncompressed data @ $"); puth(data); putln
else
//
// Decompress block
//
//puts("Compressed block @ $"); puth(block); putln
data, len = lz4Decomp(block, block + size[0])
//puts("Uncompressed data @ $"); puth(data); putln
if data
memcpy(block, data, len)
data = block
fin
heaprelease(block + len)
fin
if flags & $10 // Block Checksum
fileio:read(ref, @size, 4)
fin
return data, len
end
def lz4ReadFrame#0
word data, len
byte header[t_header], opt
fileio:read(ref, @header, t_header)
if header:magic[1] <> $184D or header:magic[0] <> $2204
puts("Not LZ4 file.\n")
return
fin
if header.FLG & $C0 <> $40
puts("Wrong LZ4 version.\n")
return
fin
if header.BD & $70 <> $40
puts("Not 64K block size.\n")
return
fin
opt = 1
if header.FLG & $08 // Content Size
opt = opt + 8
fin
if header.FLG & $01 // Dictionary ID
opt = opt + 4
fin
fileio:read(ref, heapmark, opt) // Read rest of header and throw away
repeat
data, len = lz4ReadBlock(header.FLG)
until not data
if header.FLG & $04 // Content Checksun
fileio:read(ref, heapmark, 4)
fin
end
arg = argNext(argFirst)
if ^arg
ref = fileio:open(arg)
if ref
lz4ReadFrame
fileio:close(ref)
else
puts("File not found.\n")
fin
fin
done