// Run runs the commandLoop. // The loop waits for commands sent to sms.command channel. func (l *commandLoop) Run() { for { select { case <-l.pause: l.pause <- 0 case <-l.terminate: l.terminate <- 0 case _cmd := <-l.emulatorLoop.sms.command: switch cmd := _cmd.(type) { case cmdRenderFrame: l.displayLoop.Display() <- l.emulatorLoop.sms.frame() case cmdLoadRom: l.emulatorLoop.sms.loadRom(cmd.fileName) case cmdJoypadEvent: l.emulatorLoop.sms.joypad(cmd.value, cmd.event) case cmdPauseEmulation: l.emulatorLoop.pauseEmulation <- 0 <-l.emulatorLoop.pauseEmulation cmd.paused <- l.emulatorLoop.sms.paused case cmdShowCurrentInstruction: prevAddr := z80.PreviousInstruction(l.emulatorLoop.sms.memory, l.emulatorLoop.sms.cpu.PC()) res, address, shift := z80.Disassemble(l.emulatorLoop.sms.memory, prevAddr, 0) if res != "shift " { application.Logf("0x%04x %s\n", l.emulatorLoop.sms.cpu.PC(), res) } res, address, shift = z80.Disassemble(l.emulatorLoop.sms.memory, l.emulatorLoop.sms.cpu.PC(), 0) if res != "shift " { application.Logf("0x%04x %s\n", l.emulatorLoop.sms.cpu.PC(), res) } for i := 0; i < 20; i++ { oldAddress := address res, address, shift = z80.Disassemble(l.emulatorLoop.sms.memory, address, shift) if res != "shift " { application.Logf("0x%04x %s\n", oldAddress, res) } // address++ } } } } }
// Disassemble the instruction at the given pc and return the address, // machine language, and instruction. Return the PC of the following // instruction in nextPc. func (vm *vm) disasm(pc uint16) (line string, nextPc uint16) { var asm string shift := 0 // Disassemble the instruction. for { asm, nextPc, shift = z80.Disassemble(vm, pc, shift) // Keep going as long as shift != 0. This is for extended instructions like 0xCB. if shift == 0 { break } } // Address. line = fmt.Sprintf("%04X ", pc) // Machine language. for addr := pc; addr < pc+4; addr++ { if addr < nextPc { line += fmt.Sprintf("%02X ", vm.memory[addr]) } else { line += fmt.Sprint(" ") } } // Instruction. line += asm return }