package stfw import ( "encoding/binary" //"fmt" "os" ) type Record struct { Addr uint32 Data []byte Sum uint8 ComputedSum uint8 Good bool } func ReadRecord(f *os.File) (*Record, error) { r := struct { Data [36]byte Sum uint8 }{} err := binary.Read(f, binary.BigEndian, &r) if err != nil { return nil, err } var t uint8 for _, b := range r.Data { t += uint8(b) } t = ^t record := &Record{ Addr: uint32(r.Data[0])<<24 | uint32(r.Data[1])<<16 | uint32(r.Data[2])<<8 | uint32(r.Data[3]), Data: r.Data[4:], Sum: r.Sum, ComputedSum: t, Good: r.Sum == t, } return record, nil } func WriteRecord(f *os.File, rec *Record) error { r := struct { Data [36]byte Sum uint8 }{} r.Data[0] = byte(rec.Addr >> 24) r.Data[1] = byte(rec.Addr >> 16) r.Data[2] = byte(rec.Addr >> 8) r.Data[3] = byte(rec.Addr) copy(r.Data[4:], rec.Data[:]) for _, b := range r.Data { r.Sum += uint8(b) } r.Sum = ^r.Sum err := binary.Write(f, binary.BigEndian, r) if err != nil { return err } return nil } func SplitBin(mem []byte) ([]byte, []byte) { low := make([]byte, len(mem)>>1) high := make([]byte, len(mem)>>1) for i := 0; i < len(mem); i += 2 { low[i/2] = mem[i] high[i/2] = mem[i+1] } return low, high } func MergeBin(low []byte, high []byte) []byte { mem := make([]byte, len(low)*2) for i := 0; i < len(low); i++ { mem[i*2] = low[i] mem[i*2+1] = high[i] } return mem } type MemoryMode int func (m MemoryMode) physAddr(addr int) int { switch m { case MemoryModeCombinedLow: return addr * 2 case MemoryModeCombinedHigh: return addr*2 + 1 } return addr } const ( MemoryModeLinear MemoryMode = iota MemoryModeCombinedLow MemoryModeCombinedHigh ) func GetChecksum(mem []byte, mm MemoryMode) uint16 { return uint16(mem[mm.physAddr(0xfffe)])*256 + uint16(mem[mm.physAddr(0xffff)]) } func GetChecksums(mem []byte) (uint16, uint16) { return GetChecksum(mem, MemoryModeCombinedLow), GetChecksum(mem, MemoryModeCombinedHigh) } func CalcChecksum(mem []byte, mm MemoryMode, start int) uint16 { var cs uint16 for i := 0; i <= 0xFFFB; i++ { cs = addx(uint16(mem[mm.physAddr(i)]), cs) } cs = ^cs return cs } func CalcChecksums(mem []byte, start int) (uint16, uint16) { return CalcChecksum(mem, MemoryModeCombinedLow, start), CalcChecksum(mem, MemoryModeCombinedHigh, start) } func UpdateChecksum(mem []byte, mm MemoryMode, cs uint16) { mem[mm.physAddr(0xfffe)] = byte(cs >> 8) mem[mm.physAddr(0xffff)] = byte(cs) } var xFlag bool func addx(x, y uint16) uint16 { if x+y < y { xFlag = true return x + y } if xFlag { xFlag = false return x + y + 1 } return x + y }