izapple2/command.go

107 lines
2.4 KiB
Go

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)
}