From 3d5790e23004ae65708fc4255fdd77526f66e41e Mon Sep 17 00:00:00 2001 From: Zorchenhimer Date: Sun, 29 Sep 2024 15:00:44 -0400 Subject: [PATCH] Some cleanup an the decode code Added a bunch of comments and clarified some variables in the decoding logic. --- rom/decoder.go | 24 +++++++++++++++--------- rom/export.go | 14 +++++++++----- rom/packets.go | 9 +++++---- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/rom/decoder.go b/rom/decoder.go index 13028b7..615e937 100644 --- a/rom/decoder.go +++ b/rom/decoder.go @@ -10,17 +10,18 @@ import ( // Returns packet, next state, and error (if any) type decodeFunction func(page *Page, data []byte, startIdx int) (Packet, int, error) -// map of states. each state is a map of types +// Map of states. Each state is a map of types var definedPackets = map[int]map[byte]decodeFunction{ - 0: map[byte]decodeFunction{ + + 0: map[byte]decodeFunction{ // state 3 in firmware.org 0x01: decodeHeader, }, - 1: map[byte]decodeFunction{ + 1: map[byte]decodeFunction{ // state 1 in firmware.org 0x00: decodeMarkDataEnd, }, - 2: map[byte]decodeFunction{ + 2: map[byte]decodeFunction{ // state 2 in firmware.org 0x02: decodeSetWorkRamLoad, 0x03: decodeMarkDataStart, 0x04: decodeMarkDataStart, @@ -45,18 +46,19 @@ func (page *Page) decode(data []byte) error { return nil } + stateArg := data[idx+1] var packet Packet - if page.state == 1 && data[idx+1] != 0x00 { + if page.state == 1 && stateArg != 0x00 { // stateArg is length here? // bulk data packet, page.state, err = decodeBulkData(page, data, idx) if err != nil { return err } } else { - df, ok := definedPackets[page.state][data[idx+1]] + df, ok := definedPackets[page.state][stateArg] if !ok { return fmt.Errorf("State %d packet with type %02X isn't implemented", - page.state, data[idx+1]) + page.state, stateArg) } packet, page.state, err = df(page, data, idx) if err != nil { @@ -149,7 +151,7 @@ func decodeMarkDataStart(page *Page, data []byte, idx int) (Packet, int, error) func decodeMarkDataEnd(page *Page, data []byte, idx int) (Packet, int, error) { packet := &packetMarkDataEnd{ Type: data[idx+2], - Reset: (data[idx+2]&0xF0 == 0xF0), + Reset: (data[idx+2]&0xF0 == 0xF0), // what is this? checksum: data[idx+3], address: page.DataOffset + idx, } @@ -195,6 +197,9 @@ func decodeSetWorkRamLoad(page *Page, data []byte, idx int) (Packet, int, error) } func decodeBulkData(page *Page, data []byte, idx int) (Packet, int, error) { + // idx+1: length of data + // idx+2: data start + if data[idx+1] == 0 { return nil, 0, fmt.Errorf("Bulk data packet has a length of zero at offset %08X", page.DataOffset+idx) @@ -206,8 +211,9 @@ func decodeBulkData(page *Page, data []byte, idx int) (Packet, int, error) { datalen := int(data[idx+1]) packet.Data = data[idx+2 : idx+2+datalen] - packet.checksum = data[idx+len(packet.Data)+2] + packet.checksum = data[idx+2+len(packet.Data)] + // checksum includes the packet ID and data length values checksum := calcChecksum(data[idx : idx+int(data[idx+1])+2]) if checksum != packet.checksum { data := []string{} diff --git a/rom/export.go b/rom/export.go index 339ed67..01c0c85 100644 --- a/rom/export.go +++ b/rom/export.go @@ -13,6 +13,10 @@ func (sb *StudyBox) Export(directory string) error { Audio: directory + "/audio" + sb.Audio.ext(), } + // A "Page" here does not correspond to the entered "Page" number on the + // title screen. These are really segments. The "Page" that is entered on + // the title screen is stored in the header of a segment. Multiple + // segments can have the same "Page" number. for pidx, page := range sb.Data.Pages { jp := jsonPage{ AudioOffsetLeadIn: page.AudioOffsetLeadIn, @@ -20,7 +24,7 @@ func (sb *StudyBox) Export(directory string) error { Data: []jsonData{}, } - file, err := os.Create(fmt.Sprintf("%s/page%02d_0000.txt", directory, pidx)) + file, err := os.Create(fmt.Sprintf("%s/segment-%02d_packet-0000.txt", directory, pidx)) if err != nil { return err } @@ -74,13 +78,13 @@ func (sb *StudyBox) Export(directory string) error { switch jData.Type { case "pattern": - jData.File = fmt.Sprintf("%s/page%02d_%04d_chrData.chr", directory, pidx, dataStartId) + jData.File = fmt.Sprintf("%s/segment-%02d_packet-%04d_chrData.chr", directory, pidx, dataStartId) case "nametable": - jData.File = fmt.Sprintf("%s/page%02d_%04d_ntData.dat", directory, pidx, dataStartId) + jData.File = fmt.Sprintf("%s/segment-%02d_packet-%04d_ntData.dat", directory, pidx, dataStartId) case "script": - jData.File = fmt.Sprintf("%s/page%02d_%04d_scriptData.dat", directory, pidx, dataStartId) + jData.File = fmt.Sprintf("%s/segment-%02d_packet-%04d_scriptData.dat", directory, pidx, dataStartId) //script, err := DissassembleScript(scriptData) //if err != nil { @@ -118,7 +122,7 @@ func (sb *StudyBox) Export(directory string) error { rawData = append(rawData, p.Data...) default: - return fmt.Errorf("Encountered an unknown packet: %s page: %d", p.Asm(), pidx) + return fmt.Errorf("Encountered an unknown packet: %s segment: %d", p.Asm(), pidx) } } diff --git a/rom/packets.go b/rom/packets.go index f518f58..85597b0 100644 --- a/rom/packets.go +++ b/rom/packets.go @@ -26,7 +26,7 @@ func (ph *packetHeader) RawBytes() []byte { } func (ph *packetHeader) Asm() string { - return fmt.Sprintf("header %d ; Checksum: %02X", ph.PageNumber, ph.Checksum) + return fmt.Sprintf("header %d [Page %d] ; Checksum: %02X", ph.PageNumber, ph.PageNumber+1, ph.Checksum) } func (ph *packetHeader) Address() int { @@ -81,7 +81,7 @@ func newPacketWorkRamLoad(bank, addressHigh uint8) *packetWorkRamLoad { } func (p *packetWorkRamLoad) Asm() string { - return fmt.Sprintf("work_ram_load $%02X $%02X ; Checksum %02X", + return fmt.Sprintf("work_ram_load bank:$%02X addr:$%02X00 ; Checksum %02X", p.bankId, p.loadAddressHigh, p.checksum) } @@ -192,7 +192,7 @@ func (p *packetMarkDataStart) Address() int { type packetMarkDataEnd struct { //Arg uint8 - Reset bool + Reset bool // what does this mean? what is special about the value 0xF0? Type uint8 address int @@ -251,7 +251,8 @@ func (p *packetMarkDataEnd) Asm() string { for _, b := range p.RawBytes() { s = append(s, fmt.Sprintf("%02X", b)) } - return fmt.Sprintf("mark_datatype_end %s ; %s Checksum: %02X", tstr, strings.Join(s, " "), p.checksum) + return fmt.Sprintf("mark_datatype_end %s ; %s Checksum: %02X", + tstr, strings.Join(s, " "), p.checksum) } func (p *packetMarkDataEnd) Address() int {