// LoadImage loads an e8 image into the machine. func (m *Machine) LoadImage(r io.ReadSeeker) error { secs, err := e8.Read(r) if err != nil { return err } return m.LoadSections(secs) }
// DumpImage disassembles an image. func DumpImage(r io.ReadSeeker, out io.Writer) error { secs, err := e8.Read(r) if err != nil { return err } for _, sec := range secs { switch sec.Type { case e8.Code: fmt.Fprintln(out, "[code section]") lines := Dasm(sec.Bytes, sec.Addr) for _, line := range lines { fmt.Fprintln(out, line) } case e8.Data: fmt.Fprintf(out, "[data of %d bytes at %08x]\n", sec.Size, sec.Addr, ) lines := Dasm(sec.Bytes, sec.Addr) for _, line := range lines { fmt.Fprintln(out, line) } case e8.Zeros: fmt.Fprintf(out, "[zeros of %d bytes at %08x]\n", sec.Size, sec.Addr, ) case e8.Debug: fmt.Fprintf(out, "[debug of %d bytes]\n", sec.Size) } } return nil }
func main() { flag.Parse() args := flag.Args() if len(args) != 1 { log.Fatal("need exactly one input file\n") } fname := args[0] if *doDasm { f, err := os.Open(fname) defer f.Close() err = dasm8.DumpImage(f, os.Stdout) if err != nil { log.Fatal(err) } } else if *printDebug { f, err := os.Open(fname) defer f.Close() secs, err := e8.Read(f) if err != nil { log.Fatal(err) } for _, sec := range secs { if sec.Type != e8.Debug { continue } tab, err := debug8.UnmarshalTable(sec.Bytes) if err != nil { log.Fatal(err) } tab.PrintTo(os.Stdout) } } else { bs, err := ioutil.ReadFile(fname) if err != nil { log.Fatal(err) } n, e := run(bs) fmt.Printf("(%d cycles)\n", n) if e != nil { if !arch8.IsHalt(e) { fmt.Println(e) } } else { fmt.Println("(end of time)") } } }
func run(bs []byte) (int, error) { // create a single core machine m := arch8.NewMachine(uint32(*memSize), 1) secs, err := e8.Read(bytes.NewReader(bs)) if err != nil { return 0, err } if err := m.LoadSections(secs); err != nil { return 0, err } if *bootArg > math.MaxUint32 { log.Fatalf("boot arg(%d) is too large", *bootArg) } if err := m.WriteWord(arch8.AddrBootArg, uint32(*bootArg)); err != nil { return 0, err } if *romRoot != "" { m.MountROM(*romRoot) } if *randSeed != 0 { m.RandSeed(*randSeed) } ret, exp := m.Run(*ncycle) if *printStatus { m.PrintCoreStatus() } if !arch8.IsHalt(exp) { fmt.Println(exp) err := arch8.FprintStack(os.Stdout, m, exp) if err != nil { log.Fatal(err) } } if exp == nil { return ret, nil } return ret, exp }
func run(bs []byte) (int, error) { if *bootArg > math.MaxUint32 { log.Fatalf("boot arg(%d) is too large", *bootArg) } // create a single core machine m := arch8.NewMachine(&arch8.Config{ MemSize: uint32(*memSize), ROM: *romRoot, RandSeed: *randSeed, BootArg: uint32(*bootArg), }) secs, err := e8.Read(bytes.NewReader(bs)) if err != nil { return 0, err } if err := m.LoadSections(secs); err != nil { return 0, err } ret, exp := m.Run(*ncycle) if *printStatus { m.PrintCoreStatus() } if !arch8.IsHalt(exp) { fmt.Println(exp) err := arch8.FprintStack(os.Stdout, m, exp) if err != nil { log.Fatal(err) } } if exp == nil { return ret, nil } return ret, exp }