add and use lzss decompressor, baku variant
This commit is contained in:
parent
0b3e476863
commit
7c9a47bfaa
6 changed files with 287 additions and 16 deletions
18
kernel.asm
18
kernel.asm
|
@ -100,15 +100,15 @@ Drive64Done:
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
|
||||||
// try out an interrupt:
|
// // try out an interrupt:
|
||||||
//sw r0, 0(r0)
|
// //sw r0, 0(r0)
|
||||||
mfc0 t1, CP0_Status
|
// mfc0 t1, CP0_Status
|
||||||
ori t1, 2
|
// ori t1, 2
|
||||||
mtc0 t1, CP0_Status
|
// mtc0 t1, CP0_Status
|
||||||
la t0, WipeRegisters
|
// la t0, WipeRegisters
|
||||||
mtc0 t0, CP0_EPC
|
// mtc0 t0, CP0_EPC
|
||||||
j InterruptHandler
|
// j InterruptHandler
|
||||||
nop
|
// nop
|
||||||
|
|
||||||
WipeRegisters:
|
WipeRegisters:
|
||||||
// load up most registers with a dummy value for debugging
|
// load up most registers with a dummy value for debugging
|
||||||
|
|
2
lz.asm
2
lz.asm
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
LZInit:
|
LZInit:
|
||||||
la a0, LZ+4 // A0 = Source Address
|
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
|
lbu t0, -1(a0) // T0 = HI Data Length Byte
|
||||||
sll t0, 8
|
sll t0, 8
|
||||||
|
|
134
lzss.baku.asm
Normal file
134
lzss.baku.asm
Normal 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
123
lzss.baku.unsafe.asm
Normal 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
|
26
main.asm
26
main.asm
|
@ -27,17 +27,29 @@ Main:
|
||||||
lui t0, K_BASE
|
lui t0, K_BASE
|
||||||
|
|
||||||
lui s0, BLAH_BASE
|
lui s0, BLAH_BASE
|
||||||
|
|
||||||
mfc0 t0, CP0_Count
|
|
||||||
mfc0 t1, CP0_Status+0
|
mfc0 t1, CP0_Status+0
|
||||||
sw t0, BLAH_COUNTS+0(s0)
|
|
||||||
sw t1, 8(s0)
|
sw t1, 8(s0)
|
||||||
|
|
||||||
// decompress our picture
|
nop; nop; nop; nop
|
||||||
include "lz.asm"
|
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
|
mfc0 t0, CP0_Count
|
||||||
|
nop; nop; nop; nop
|
||||||
|
|
||||||
|
lw t1, BLAH_COUNTS+0(s0)
|
||||||
sw t0, BLAH_COUNTS+8(s0)
|
sw t0, BLAH_COUNTS+8(s0)
|
||||||
|
subu t1, t0, t1
|
||||||
|
sw t1, BLAH_COUNTS+0xC(s0)
|
||||||
|
|
||||||
lui a0, BLAH_BASE
|
lui a0, BLAH_BASE
|
||||||
lli a1, 0x20
|
lli a1, 0x20
|
||||||
|
@ -150,8 +162,10 @@ PushRSPTask:
|
||||||
jr ra
|
jr ra
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
include "lzss.baku.unsafe.asm"
|
||||||
|
|
||||||
align(16); insert F3DZEX_BOOT, "bin/F3DZEX2.boot.bin"
|
align(16); insert F3DZEX_BOOT, "bin/F3DZEX2.boot.bin"
|
||||||
align(16); insert F3DZEX_DMEM, "bin/F3DZEX2.data.bin"
|
align(16); insert F3DZEX_DMEM, "bin/F3DZEX2.data.bin"
|
||||||
align(16); insert F3DZEX_IMEM, "bin/F3DZEX2.bin"
|
align(16); insert F3DZEX_IMEM, "bin/F3DZEX2.bin"
|
||||||
align(16); insert FONT, "res/dwarf.1bpp"
|
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
BIN
res/Image.baku.lzss
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue