add and use lzss decompressor, baku variant

This commit is contained in:
Connor Olding 2018-08-19 00:22:24 +02:00
parent 0b3e476863
commit 7c9a47bfaa
6 changed files with 287 additions and 16 deletions

View file

@ -100,15 +100,15 @@ Drive64Done:
nop
nop
// try out an interrupt:
//sw r0, 0(r0)
mfc0 t1, CP0_Status
ori t1, 2
mtc0 t1, CP0_Status
la t0, WipeRegisters
mtc0 t0, CP0_EPC
j InterruptHandler
nop
// // try out an interrupt:
// //sw r0, 0(r0)
// mfc0 t1, CP0_Status
// ori t1, 2
// mtc0 t1, CP0_Status
// la t0, WipeRegisters
// mtc0 t0, CP0_EPC
// j InterruptHandler
// nop
WipeRegisters:
// load up most registers with a dummy value for debugging

2
lz.asm
View file

@ -3,7 +3,7 @@
LZInit:
la a0, LZ+4 // A0 = Source Address
lui a1, 0xA010 // A1 = Destination Address (DRAM Start Offset)
lui a1, 0x8010 // A1 = Destination Address (DRAM Start Offset)
lbu t0, -1(a0) // T0 = HI Data Length Byte
sll t0, 8

134
lzss.baku.asm Normal file
View file

@ -0,0 +1,134 @@
LzDecomp:
// a0: pointer to compressed data (must be RDRAM, cart is unsupported)
// a1: compressed size
// a2: output pointer
// a3: maximum uncompressed size
// v0: error code (0 is OK)
// t0: current pointer for reading
// t1: end pointer (exclusive)
// t2: current pointer for writing
// t3: end pointer (exclusive)
// t4: current code, shifted as necessary
// t5: 1 means raw, 0 means copy
// t6: either raw byte or part of copy command
// t7: current pseudo-position
// t8: match length
// t9: match position
beqz a1, LzExit // nothing to decompress? nothing to do!
nop
blez a3, LzNoSpace
nop
or t0, a0, r0
addu t1, a0, a1
or t2, a2, r0
addu t3, a2, a3
lli t7, 0x3BE
LzNextCode:
// READ
lbu t4, 0(t0)
addiu t0, 1
ori t4, t4, 0x100 // add end marker
andi t5, t4, 1
LzReadCode:
beq t2, t3, LzReiterate
nop
// READ
beq t0, t1, LzBadEnd
nop
lbu t6, 0(t0)
addiu t0, 1
beqz t5, LzCopy
nop
LzRaw:
// WRITE
beq t2, t3, LzNoSpace
addiu t7, 1
andi t7, t7, 0x3FF
sb t6, 0(t2)
addiu t2, 1
// SHIFT
srl t4, 1
xori at, t4, 1
bnez at, LzReadCode // branch if t4 != 1
andi t5, t4, 1
b LzReiterate
nop
LzCopy:
// READ
beq t0, t1, LzBadEnd
nop
lbu t8, 0(t0)
addiu t0, 1
// extract match position
sll t9, t8, 2
andi t9, 0x0300
or t9, t6
// extract and prepare match length
andi t8, 0x003F
addiu t8, 3
// prepare absolute match position
subu t9, t7, t9
subiu t9, 1
andi t9, 0x03FF
addiu t9, 1
subu t9, t2, t9
// pre-emptively move psuedo-position ahead (don't need it for the loop)
addu t7, t8
andi t7, t7, 0x3FF
LzCopyLoop:
// repurposing t6: byte being copied
slt at, t9, a2
bnez at,+ // don't copy bytes before the output pointer
lli t6, 0 // use nulls instead
lbu t6, 0(t9)
+
// WRITE
beq t2, t3, LzNoSpace
subiu t8, 1
sb t6, 0(t2)
addiu t2, 1
bnez t8, LzCopyLoop
addiu t9, 1
// SHIFT
srl t4, 1
xori at, t4, 1
bnez at, LzReadCode // branch if t4 != 1
andi t5, t4, 1
LzReiterate:
bne t0, t1, LzNextCode
nop
LzExit:
jr ra
lli v0, 0
LzNoSpace:
jr ra
lli v0, 1
LzBadEnd: // aka Unexpected End Of File
jr ra
lli v0, 2

123
lzss.baku.unsafe.asm Normal file
View file

@ -0,0 +1,123 @@
LzDecomp:
// a0: pointer to compressed data (must be RDRAM, cart is unsupported)
// a1: compressed size
// a2: output pointer
// a3: maximum uncompressed size
// v0: error code (0 is OK)
// t0: current pointer for reading
// t1: end pointer (exclusive)
// t2: current pointer for writing
// t3: end pointer (exclusive)
// t4: current code, shifted as necessary
// t5: 1 means raw, 0 means copy
// t6: either raw byte or part of copy command
// t7: current pseudo-position
// t8: match length
// t9: match position
beqz a1, LzExit // nothing to decompress? nothing to do!
lli v0, 0
blez a3, LzExit
lli v0, 1
or t0, a0, r0
addu t1, a0, a1
or t2, a2, r0
addu t3, a2, a3
lli t7, 0x3BE
LzNextCode:
// READ
lbu t4, 0(t0)
addiu t0, 1
ori t4, t4, 0x100 // add end marker
andi t5, t4, 1
LzReadCode:
beq t2, t3, LzExit
lli v0, 0
// READ
lbu t6, 0(t0)
addiu t0, 1
beqz t5, LzCopy
nop
LzRaw:
// WRITE
addiu t7, 1
andi t7, t7, 0x3FF
sb t6, 0(t2)
addiu t2, 1
// SHIFT
srl t4, 1
xori at, t4, 1
bnez at, LzReadCode // branch if t4 != 1
andi t5, t4, 1
// reiterate
bne t0, t1, LzNextCode
nop
b LzExit
lli v0, 0
LzCopy:
// READ
lbu t8, 0(t0)
addiu t0, 1
// extract match position
sll t9, t8, 2
andi t9, 0x0300
or t9, t6
// extract and prepare match length
andi t8, 0x003F
addiu t8, 3
// prepare absolute match position
subu t9, t7, t9
subiu t9, 1
andi t9, 0x03FF
addiu t9, 1
subu t9, t2, t9
// pre-emptively move psuedo-position ahead (don't need it for the loop)
addu t7, t8
andi t7, t7, 0x3FF
LzCopyLoop:
// repurposing t6: byte being copied
lbu t6, 0(t9)
// WRITE
subiu t8, 1
sb t6, 0(t2)
addiu t2, 1
bnez t8, LzCopyLoop
addiu t9, 1
// SHIFT
srl t4, 1
xori at, t4, 1
bnez at, LzReadCode // branch if t4 != 1
andi t5, t4, 1
// reiterate
bne t0, t1, LzNextCode
nop
b LzExit
lli v0, 0
LzExit:
jr ra
nop

View file

@ -27,17 +27,29 @@ Main:
lui t0, K_BASE
lui s0, BLAH_BASE
mfc0 t0, CP0_Count
mfc0 t1, CP0_Status+0
sw t0, BLAH_COUNTS+0(s0)
sw t1, 8(s0)
// decompress our picture
include "lz.asm"
nop; nop; nop; nop
mfc0 t0, CP0_Count
sw t0, BLAH_COUNTS+0(s0)
// decompress our picture
la a0, LZ_BAKU + 4
lw a3, -4(a0) // load uncompressed size from the file itself
li a1, LZ_BAKU.size - 4
li a2, VIDEO_BUFFER | 0x80000000
jal LzDecomp
nop
// TODO: flush cache on video buffer
mfc0 t0, CP0_Count
nop; nop; nop; nop
lw t1, BLAH_COUNTS+0(s0)
sw t0, BLAH_COUNTS+8(s0)
subu t1, t0, t1
sw t1, BLAH_COUNTS+0xC(s0)
lui a0, BLAH_BASE
lli a1, 0x20
@ -150,8 +162,10 @@ PushRSPTask:
jr ra
nop
include "lzss.baku.unsafe.asm"
align(16); insert F3DZEX_BOOT, "bin/F3DZEX2.boot.bin"
align(16); insert F3DZEX_DMEM, "bin/F3DZEX2.data.bin"
align(16); insert F3DZEX_IMEM, "bin/F3DZEX2.bin"
align(16); insert FONT, "res/dwarf.1bpp"
align(16); insert LZ, "res/Image.lz"
align(16); insert LZ_BAKU, "res/Image.baku.lzss"

BIN
res/Image.baku.lzss Normal file

Binary file not shown.