mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
returns a CoProcState value rather than a boolean value updated prompt building and debugger reflection overlays to work with new type and values commentary introduces the idea that coprocessor state is about VCS synchronisation ELF will call ExecutionStart() and ExecutionEnd() as appropriate for the change of state. this needs work because the meaning of "Execution" in context of StrongARM type synchronisation is unclear
87 lines
3 KiB
Go
87 lines
3 KiB
Go
// This file is part of Gopher2600.
|
|
//
|
|
// Gopher2600 is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Gopher2600 is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package debugger
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/jetsetilly/gopher2600/debugger/terminal"
|
|
"github.com/jetsetilly/gopher2600/disassembly"
|
|
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
|
|
)
|
|
|
|
func (dbg *Debugger) buildPrompt() terminal.Prompt {
|
|
content := strings.Builder{}
|
|
|
|
// to keep things simple for now, only the idle coprocessor state will
|
|
// result in a detailed 6507 prompt. the other states are better served
|
|
// (for now) by a descriptive prompt without any disassembly
|
|
//
|
|
// TODO: better prompts for non-idle coprocessor states
|
|
switch dbg.vcs.Mem.Cart.CoProcState() {
|
|
case mapper.CoProcNOPFeed:
|
|
content.WriteString(fmt.Sprintf("$%04x (NOP feed)", dbg.vcs.CPU.PC.Address()))
|
|
case mapper.CoProcStrongARMFeed:
|
|
content.WriteString(fmt.Sprintf("$%04x (StrongARM feed)", dbg.vcs.CPU.PC.Address()))
|
|
case mapper.CoProcParallel:
|
|
content.WriteString(fmt.Sprintf("$%04x (parallel)", dbg.vcs.CPU.PC.Address()))
|
|
case mapper.CoProcIdle:
|
|
var e *disassembly.Entry
|
|
|
|
// decide which address value to use
|
|
if dbg.vcs.CPU.LastResult.Final || dbg.vcs.CPU.HasReset() {
|
|
e = dbg.Disasm.GetEntryByAddress(dbg.vcs.CPU.PC.Address())
|
|
} else {
|
|
// if we're in the middle of an instruction then use the addresss in
|
|
// lastResult. in these instances we want the prompt to report the
|
|
// instruction that the CPU is working on, not the next one to be
|
|
// stepped into.
|
|
e = dbg.liveDisasmEntry
|
|
}
|
|
|
|
// build prompt based on how confident we are of the contents of the
|
|
// disassembly entry. starting with the condition of no disassembly at all
|
|
if e == nil {
|
|
content.WriteString(fmt.Sprintf("$%04x", dbg.vcs.CPU.PC.Address()))
|
|
} else if e.Level == disassembly.EntryLevelUnmappable {
|
|
content.WriteString(e.Address)
|
|
} else {
|
|
// this is the ideal path. the address is in the disassembly and we've
|
|
// decoded it already
|
|
content.WriteString(fmt.Sprintf("%s %s", e.Address, e.Operator))
|
|
|
|
if e.Operand.String() != "" {
|
|
content.WriteString(fmt.Sprintf(" %s", e.Operand))
|
|
}
|
|
}
|
|
}
|
|
|
|
p := terminal.Prompt{
|
|
Content: content.String(),
|
|
Recording: dbg.scriptScribe.IsActive(),
|
|
CPURdy: dbg.vcs.CPU.RdyFlg,
|
|
}
|
|
|
|
// LastResult final is false on CPU reset so we must check for that also
|
|
if dbg.vcs.CPU.LastResult.Final || dbg.vcs.CPU.HasReset() {
|
|
p.Type = terminal.PromptTypeCPUStep
|
|
} else {
|
|
p.Type = terminal.PromptTypeVideoStep
|
|
}
|
|
|
|
return p
|
|
}
|