#23001 - f(DarkAngel) - Fri Jul 02, 2004 3:46 pm
Has anyone got huffman encoding work in VBA (1.7.2)? I've been implementing a huffman encoder and it never works correctly on VBA, i can't be sure since i don't have equipment to test it on real hardware either.
Both Cowbite and GBATek says the 5th byte is treeSize/2-1 but VBA bios.cpp tries to get the original value by (treeSize<<1)+1 instead of (treeSize+1)<<1.
Here's the original code from VBA 1.7.2
If GBATek and Cowbite are correct, this seems to be a bug and i'm going to post a bug-report to sf tracker.
_________________
death scream...
Both Cowbite and GBATek says the 5th byte is treeSize/2-1 but VBA bios.cpp tries to get the original value by (treeSize<<1)+1 instead of (treeSize+1)<<1.
Here's the original code from VBA 1.7.2
Code: |
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // Copyright (C) 1999-2003 Forgotten // Copyright (C) 2004 Forgotten and the VBA development team // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or(at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void BIOS_HuffUnComp() { #ifdef DEV_VERSION if(systemVerbose & VERBOSE_SWI) { log("HuffUnComp: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, reg[1].I, VCOUNT); } #endif u32 source = reg[0].I; u32 dest = reg[1].I; u32 header = CPUReadMemory(source); source += 4; if(((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) return; u8 treeSize = CPUReadByte(source++); u32 treeStart = source; source += (treeSize<<1) + 1; int len = header >> 8; u32 mask = 0x80000000; u32 data = CPUReadMemory(source); source += 4; int pos = 0; u8 rootNode = CPUReadByte(treeStart); u8 currentNode = rootNode; bool writeData = false; int byteShift = 0; int byteCount = 0; u32 writeValue = 0; if((header & 0x0F) == 8) { while(len > 0) { // take left if(pos == 0) pos++; else pos += (((currentNode & 0x3F)+1)<<1); if(data & mask) { // right if(currentNode & 0x40) writeData = true; currentNode = CPUReadByte(treeStart+pos+1); } else { // left if(currentNode & 0x80) writeData = true; currentNode = CPUReadByte(treeStart+pos); } if(writeData) { writeValue |= (currentNode << byteShift); byteCount++; byteShift += 8; pos = 0; currentNode = rootNode; writeData = false; if(byteCount == 4) { byteCount = 0; byteShift = 0; CPUWriteMemory(dest, writeValue); writeValue = 0; dest += 4; len -= 4; } } mask >>= 1; if(mask == 0) { mask = 0x80000000; data = CPUReadMemory(source); source += 4; } } } else { int halfLen = 0; int value = 0; while(len > 0) { // take left if(pos == 0) pos++; else pos += (((currentNode & 0x3F)+1)<<1); if((data & mask)) { // right if(currentNode & 0x40) writeData = true; currentNode = CPUReadByte(treeStart+pos+1); } else { // left if(currentNode & 0x80) writeData = true; currentNode = CPUReadByte(treeStart+pos); } if(writeData) { if(halfLen == 0) value |= currentNode; else value |= (currentNode<<4); halfLen += 4; if(halfLen == 8) { writeValue |= (value << byteShift); byteCount++; byteShift += 8; halfLen = 0; value = 0; if(byteCount == 4) { byteCount = 0; byteShift = 0; CPUWriteMemory(dest, writeValue); dest += 4; writeValue = 0; len -= 4; } } pos = 0; currentNode = rootNode; writeData = false; } mask >>= 1; if(mask == 0) { mask = 0x80000000; data = CPUReadMemory(source); source += 4; } } } } |
If GBATek and Cowbite are correct, this seems to be a bug and i'm going to post a bug-report to sf tracker.
_________________
death scream...