Some cleanup an the decode code
Added a bunch of comments and clarified some variables in the decoding logic.
This commit is contained in:
parent
928a8e2faf
commit
3d5790e230
|
@ -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{}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue