package izapple2 import "fmt" const ( // CommandToggleSpeed toggles cpu speed between full speed and actual Apple II speed CommandToggleSpeed = iota + 1 // CommandShowSpeed toggles printinf the current freq in Mhz CommandShowSpeed // CommandDumpDebugInfo dumps useful info CommandDumpDebugInfo // CommandNextCharGenPage cycles the CharGen page if several CommandNextCharGenPage // CommandToggleCPUTrace toggle tracing of CPU execution CommandToggleCPUTrace // CommandKill stops the cpu execution loop CommandKill // CommandReset executes a 6502 reset CommandReset // CommandPauseUnpause allows the Pause button to freeze the emulator for a coffee break CommandPauseUnpause // CommandPause pauses the emulator CommandPause // CommandStart restarts the emulator CommandStart // CommandComplex for commands that use a struct with parameters CommandComplex ) type command interface { getId() int } type commandSimple struct { id int } type commandLoadDisk struct { drive int path string } func (c *commandSimple) getId() int { return c.id } func (c *commandLoadDisk) getId() int { return CommandComplex } func (a *Apple2) queueCommand(c command) { a.commandChannel <- c } // SendCommand enqueues a command to the emulator thread func (a *Apple2) SendCommand(commandId int) { var c commandSimple c.id = commandId a.queueCommand(&c) } func (a *Apple2) SendLoadDisk(drive int, path string) { var c commandLoadDisk c.drive = drive c.path = path a.queueCommand(&c) } func (a *Apple2) executeCommand(command command) { switch command.getId() { case CommandToggleSpeed: if a.cycleDurationNs == 0 { //fmt.Println("Slow") a.cycleDurationNs = 1000.0 / CPUClockMhz } else { //fmt.Println("Fast") a.cycleDurationNs = 0 } case CommandShowSpeed: a.showSpeed = !a.showSpeed case CommandDumpDebugInfo: a.dumpDebugInfo() case CommandNextCharGenPage: a.cg.nextPage() fmt.Printf("Chargen page %v\n", a.cg.page) case CommandToggleCPUTrace: a.cpu.SetTrace(!a.cpu.GetTrace()) case CommandReset: a.reset() case CommandComplex: switch t := command.(type) { case *commandLoadDisk: err := a.changeDisk(t.drive, t.path) if err != nil { fmt.Printf("Could no load file %v\n%v\n", t.path, err) } } } } func (a *Apple2) changeDisk(unit int, path string) error { if unit < len(a.removableMediaDrives) { return a.removableMediaDrives[unit].insertDiskette(path) } return fmt.Errorf("unit %v not defined", unit) }