mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
o errors
- renamed GopherError to FormattedError - reading files now handled by ioutil.ReadAll(), rather than os.Read()
This commit is contained in:
parent
5a223794d4
commit
6d597c5035
27 changed files with 96 additions and 123 deletions
|
@ -106,7 +106,7 @@ func (bp *breakpoints) clear() {
|
|||
|
||||
func (bp *breakpoints) drop(num int) error {
|
||||
if len(bp.breaks)-1 < num {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Errorf("breakpoint #%d is not defined", num))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Errorf("breakpoint #%d is not defined", num))
|
||||
}
|
||||
|
||||
h := bp.breaks[:num]
|
||||
|
@ -214,7 +214,7 @@ func (bp *breakpoints) parseBreakpoint(tokens *input.Tokens) error {
|
|||
|
||||
// make sure we've not left a previous target dangling without a value
|
||||
if !resolvedTarget {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Errorf("need a value to break on (%s)", tgt.Label()))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Errorf("need a value to break on (%s)", tgt.Label()))
|
||||
}
|
||||
|
||||
// possibly switch composition mode
|
||||
|
@ -238,7 +238,7 @@ func (bp *breakpoints) parseBreakpoint(tokens *input.Tokens) error {
|
|||
}
|
||||
|
||||
if !resolvedTarget {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Errorf("need a value to break on (%s)", tgt.Label()))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Errorf("need a value to break on (%s)", tgt.Label()))
|
||||
}
|
||||
|
||||
// don't add breakpoints that already exist
|
||||
|
@ -262,7 +262,7 @@ func (bp *breakpoints) parseBreakpoint(tokens *input.Tokens) error {
|
|||
|
||||
// fail on first error
|
||||
if duplicate {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Errorf("breakpoint already exists (%s)", nb))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Errorf("breakpoint already exists (%s)", nb))
|
||||
}
|
||||
|
||||
bp.breaks = append(bp.breaks, nb)
|
||||
|
|
|
@ -182,7 +182,7 @@ func (dbg *Debugger) parseCommand(userInput string) (bool, error) {
|
|||
// many cases to ignore the "success" flag when calling tokens.item()
|
||||
if err := DebuggerCommands.ValidateInput(tokens); err != nil {
|
||||
switch err := err.(type) {
|
||||
case errors.GopherError:
|
||||
case errors.FormattedError:
|
||||
switch err.Errno {
|
||||
case errors.InputEmpty:
|
||||
// user pressed return
|
||||
|
@ -253,7 +253,7 @@ func (dbg *Debugger) parseCommand(userInput string) (bool, error) {
|
|||
table, symbol, address, err := dbg.disasm.Symtable.SearchSymbol(symbol, symbols.UnspecifiedSymTable)
|
||||
if err != nil {
|
||||
switch err := err.(type) {
|
||||
case errors.GopherError:
|
||||
case errors.FormattedError:
|
||||
if err.Errno == errors.SymbolUnknown {
|
||||
dbg.print(ui.Feedback, "%s -> not found", symbol)
|
||||
return false, nil
|
||||
|
|
|
@ -455,7 +455,7 @@ func (dbg *Debugger) inputLoop(mainLoop bool) error {
|
|||
|
||||
if err != nil {
|
||||
switch err := err.(type) {
|
||||
case errors.GopherError:
|
||||
case errors.FormattedError:
|
||||
// do not exit input loop when error is a gopher error
|
||||
// set lastStepError instead and allow emulation to
|
||||
// halt
|
||||
|
|
|
@ -15,7 +15,7 @@ func (options Commands) ValidateInput(newInput *Tokens) error {
|
|||
|
||||
// if tokens is empty then return
|
||||
if len(tokens) == 0 {
|
||||
return errors.NewGopherError(errors.InputEmpty)
|
||||
return errors.NewFormattedError(errors.InputEmpty)
|
||||
}
|
||||
|
||||
tokens[0] = strings.ToUpper(tokens[0])
|
||||
|
@ -23,29 +23,29 @@ func (options Commands) ValidateInput(newInput *Tokens) error {
|
|||
// basic check for whether command is recognised
|
||||
var ok bool
|
||||
if args, ok = options[tokens[0]]; !ok {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Sprintf("%s is not a debugging command", tokens[0]))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Sprintf("%s is not a debugging command", tokens[0]))
|
||||
}
|
||||
|
||||
// too *many* arguments have been supplied
|
||||
if len(tokens)-1 > args.maximumLen() {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Sprintf("too many arguments for %s", tokens[0]))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Sprintf("too many arguments for %s", tokens[0]))
|
||||
}
|
||||
|
||||
// too *few* arguments have been supplied
|
||||
if len(tokens)-1 < args.requiredLen() {
|
||||
switch args[len(tokens)-1].typ {
|
||||
case argKeyword:
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Sprintf("keyword required for %s", tokens[0]))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Sprintf("keyword required for %s", tokens[0]))
|
||||
case argFile:
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Sprintf("filename required for %s", tokens[0]))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Sprintf("filename required for %s", tokens[0]))
|
||||
case argValue:
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Sprintf("numeric argument required for %s", tokens[0]))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Sprintf("numeric argument required for %s", tokens[0]))
|
||||
case argString:
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Sprintf("string argument required for %s", tokens[0]))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Sprintf("string argument required for %s", tokens[0]))
|
||||
default:
|
||||
// TODO: argument types can be OR'd together. breakdown these types
|
||||
// to give more useful information
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Sprintf("too few arguments for %s", tokens[0]))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Sprintf("too few arguments for %s", tokens[0]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ func (mem memoryDebug) mapAddress(address interface{}, cpuPerspective bool) (uin
|
|||
}
|
||||
|
||||
if !mapped {
|
||||
return 0, errors.NewGopherError(errors.UnrecognisedAddress, address)
|
||||
return 0, errors.NewFormattedError(errors.UnrecognisedAddress, address)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"gopher2600/debugger/ui"
|
||||
"gopher2600/errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
@ -13,28 +14,15 @@ func (dbg *Debugger) loadScript(scriptfile string) ([]string, error) {
|
|||
// open script and defer closing
|
||||
sf, err := os.Open(scriptfile)
|
||||
if err != nil {
|
||||
return nil, errors.NewGopherError(errors.ScriptFileCannotOpen, err)
|
||||
return nil, errors.NewFormattedError(errors.ScriptFileCannotOpen, err)
|
||||
}
|
||||
defer func() {
|
||||
_ = sf.Close()
|
||||
}()
|
||||
|
||||
// get file info
|
||||
sfi, err := sf.Stat()
|
||||
buffer, err := ioutil.ReadAll(sf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// allocate enough memory for new cartridge
|
||||
buffer := make([]uint8, sfi.Size())
|
||||
|
||||
// read script file
|
||||
n, err := sf.Read(buffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != len(buffer) {
|
||||
return nil, errors.NewGopherError(errors.ScriptFileError, errors.FileTruncated)
|
||||
return nil, errors.NewFormattedError(errors.ScriptFileError, err)
|
||||
}
|
||||
|
||||
// convert buffer to an array of lines
|
||||
|
@ -68,13 +56,13 @@ func (dbg *Debugger) RunScript(scriptfile string, silent bool) error {
|
|||
}
|
||||
next, err := dbg.parseInput(lines[i])
|
||||
if err != nil {
|
||||
return errors.NewGopherError(errors.ScriptFileError, err)
|
||||
return errors.NewFormattedError(errors.ScriptFileError, err)
|
||||
}
|
||||
if next {
|
||||
// make sure run state is still sane
|
||||
dbg.runUntilHalt = false
|
||||
|
||||
return errors.NewGopherError(errors.ScriptRunError, strings.ToUpper(lines[i]), scriptfile, i)
|
||||
return errors.NewFormattedError(errors.ScriptRunError, strings.ToUpper(lines[i]), scriptfile, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,10 +149,10 @@ func parseTarget(dbg *Debugger, tokens *input.Tokens) (target, error) {
|
|||
},
|
||||
}
|
||||
default:
|
||||
err = errors.NewGopherError(errors.InvalidTarget, fmt.Sprintf("%s/%s", keyword, subkey))
|
||||
err = errors.NewFormattedError(errors.InvalidTarget, fmt.Sprintf("%s/%s", keyword, subkey))
|
||||
}
|
||||
} else {
|
||||
err = errors.NewGopherError(errors.InvalidTarget, keyword)
|
||||
err = errors.NewFormattedError(errors.InvalidTarget, keyword)
|
||||
}
|
||||
|
||||
// cartridge
|
||||
|
@ -170,14 +170,14 @@ func parseTarget(dbg *Debugger, tokens *input.Tokens) (target, error) {
|
|||
},
|
||||
}
|
||||
default:
|
||||
err = errors.NewGopherError(errors.InvalidTarget, fmt.Sprintf("%s/%s", keyword, subkey))
|
||||
err = errors.NewFormattedError(errors.InvalidTarget, fmt.Sprintf("%s/%s", keyword, subkey))
|
||||
}
|
||||
} else {
|
||||
err = errors.NewGopherError(errors.InvalidTarget, keyword)
|
||||
err = errors.NewFormattedError(errors.InvalidTarget, keyword)
|
||||
}
|
||||
|
||||
default:
|
||||
err = errors.NewGopherError(errors.InvalidTarget, keyword)
|
||||
err = errors.NewFormattedError(errors.InvalidTarget, keyword)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ func (tr *traps) clear() {
|
|||
|
||||
func (tr *traps) drop(num int) error {
|
||||
if len(tr.traps)-1 < num {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Errorf("trap #%d is not defined", num))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Errorf("trap #%d is not defined", num))
|
||||
}
|
||||
|
||||
h := tr.traps[:num]
|
||||
|
|
|
@ -72,7 +72,7 @@ func (wtc *watches) clear() {
|
|||
|
||||
func (wtc *watches) drop(num int) error {
|
||||
if len(wtc.watches)-1 < num {
|
||||
return errors.NewGopherError(errors.CommandError, fmt.Errorf("watch #%d is not defined", num))
|
||||
return errors.NewFormattedError(errors.CommandError, fmt.Errorf("watch #%d is not defined", num))
|
||||
}
|
||||
|
||||
h := wtc.watches[:num]
|
||||
|
|
|
@ -17,7 +17,7 @@ func (dsm *Disassembly) parseLoop(mc *cpu.CPU) error {
|
|||
// filter out some errors
|
||||
if err != nil {
|
||||
switch err := err.(type) {
|
||||
case errors.GopherError:
|
||||
case errors.FormattedError:
|
||||
switch err.Errno {
|
||||
case errors.ProgramCounterCycled:
|
||||
return nil
|
||||
|
|
|
@ -47,7 +47,7 @@ const (
|
|||
|
||||
// GUI
|
||||
UnknownGUIRequest
|
||||
SDLTV
|
||||
SDL
|
||||
|
||||
// Peripherals
|
||||
NoControllersFound
|
||||
|
|
|
@ -5,23 +5,24 @@ import "fmt"
|
|||
// Errno is used specified the specific error
|
||||
type Errno int
|
||||
|
||||
// Values is the type used to specify arguments for a GopherError
|
||||
// Values is the type used to specify arguments for FormattedErrors
|
||||
type Values []interface{}
|
||||
|
||||
// GopherError is the error type used by Gopher2600
|
||||
type GopherError struct {
|
||||
// FormattedError provides a convenient way of providing arguments to a
|
||||
// predefined error
|
||||
type FormattedError struct {
|
||||
Errno Errno
|
||||
Values Values
|
||||
}
|
||||
|
||||
// NewGopherError is used to create a Gopher2600 specific error
|
||||
func NewGopherError(errno Errno, values ...interface{}) GopherError {
|
||||
ge := new(GopherError)
|
||||
// NewFormattedError is used to create a new instance of a FormattedError
|
||||
func NewFormattedError(errno Errno, values ...interface{}) FormattedError {
|
||||
ge := new(FormattedError)
|
||||
ge.Errno = errno
|
||||
ge.Values = values
|
||||
return *ge
|
||||
}
|
||||
|
||||
func (er GopherError) Error() string {
|
||||
func (er FormattedError) Error() string {
|
||||
return fmt.Sprintf(messages[er.Errno], er.Values...)
|
||||
}
|
||||
|
|
|
@ -46,14 +46,8 @@ var messages = map[Errno]string{
|
|||
|
||||
// GUI
|
||||
UnknownGUIRequest: "GUI does not support %v request",
|
||||
SDLTV: "SDLTV: %s",
|
||||
SDL: "SDL: %s",
|
||||
|
||||
// Peripherals
|
||||
NoControllersFound: "no controllers found",
|
||||
}
|
||||
|
||||
// more error strings -- these are strings that are used as arguments to error
|
||||
// string messages
|
||||
const (
|
||||
FileTruncated string = "file truncated"
|
||||
)
|
||||
|
|
|
@ -121,7 +121,7 @@ func main() {
|
|||
dsm, err := disassembly.NewDisassembly(modeFlags.Arg(0))
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case errors.GopherError:
|
||||
case errors.FormattedError:
|
||||
// print what disassembly output we do have
|
||||
if dsm != nil {
|
||||
dsm.Dump(os.Stdout)
|
||||
|
|
|
@ -21,7 +21,7 @@ func (tv *GUI) GetMetaState(request gui.MetaStateReq) (interface{}, error) {
|
|||
case gui.ReqLastMouseScanline:
|
||||
return tv.crit.lastMouseScanline, nil
|
||||
default:
|
||||
return nil, errors.NewGopherError(errors.UnknownGUIRequest, request)
|
||||
return nil, errors.NewFormattedError(errors.UnknownGUIRequest, request)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ func (tv *GUI) RegisterCallback(request gui.CallbackReq, channel chan func(), ca
|
|||
tv.onMouseButtonRight.channel = channel
|
||||
tv.onMouseButtonRight.function = callback
|
||||
default:
|
||||
return errors.NewGopherError(errors.UnknownGUIRequest, request)
|
||||
return errors.NewFormattedError(errors.UnknownGUIRequest, request)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -120,7 +120,7 @@ func (tv *GUI) SetFeature(request gui.FeatureReq, args ...interface{}) error {
|
|||
}
|
||||
|
||||
default:
|
||||
return errors.NewGopherError(errors.UnknownGUIRequest, request)
|
||||
return errors.NewFormattedError(errors.UnknownGUIRequest, request)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -67,7 +67,7 @@ func (overlay *systemStateOverlay) setPixel(attr monitor.SystemState) error {
|
|||
|
||||
// label required...
|
||||
if attr.Label == "" {
|
||||
errors.NewGopherError(errors.CannotRecordState, "recording of system state requires a label")
|
||||
errors.NewFormattedError(errors.CannotRecordState, "recording of system state requires a label")
|
||||
}
|
||||
|
||||
// ... however, if a group has been supplied, use that to assign color
|
||||
|
|
|
@ -104,7 +104,7 @@ func (mc *CPU) IsExecuting() bool {
|
|||
func (mc *CPU) Reset() error {
|
||||
// sanity check
|
||||
if mc.IsExecuting() {
|
||||
return errors.NewGopherError(errors.InvalidOperationMidInstruction, "reset")
|
||||
return errors.NewFormattedError(errors.InvalidOperationMidInstruction, "reset")
|
||||
}
|
||||
|
||||
mc.PC.Load(0)
|
||||
|
@ -127,7 +127,7 @@ func (mc *CPU) Reset() error {
|
|||
func (mc *CPU) LoadPCIndirect(indirectAddress uint16) error {
|
||||
// sanity check
|
||||
if mc.IsExecuting() {
|
||||
return errors.NewGopherError(errors.InvalidOperationMidInstruction, "load PC")
|
||||
return errors.NewFormattedError(errors.InvalidOperationMidInstruction, "load PC")
|
||||
}
|
||||
|
||||
// because we call this LoadPC() outside of the CPU's ExecuteInstruction()
|
||||
|
@ -151,7 +151,7 @@ func (mc *CPU) LoadPCIndirect(indirectAddress uint16) error {
|
|||
func (mc *CPU) LoadPC(directAddress uint16) error {
|
||||
// sanity check
|
||||
if mc.IsExecuting() {
|
||||
return errors.NewGopherError(errors.InvalidOperationMidInstruction, "load PC")
|
||||
return errors.NewFormattedError(errors.InvalidOperationMidInstruction, "load PC")
|
||||
}
|
||||
|
||||
// because we call this LoadPC() outside of the CPU's ExecuteInstruction()
|
||||
|
@ -175,7 +175,7 @@ func (mc *CPU) write8Bit(address uint16, value uint8) error {
|
|||
|
||||
if err != nil {
|
||||
switch err := err.(type) {
|
||||
case errors.GopherError:
|
||||
case errors.FormattedError:
|
||||
// don't worry about unwritable addresses (unless strict addressing
|
||||
// is on)
|
||||
if mc.StrictAddressing || err.Errno != errors.UnwritableAddress {
|
||||
|
@ -195,7 +195,7 @@ func (mc *CPU) read8Bit(address uint16) (uint8, error) {
|
|||
|
||||
if err != nil {
|
||||
switch err := err.(type) {
|
||||
case errors.GopherError:
|
||||
case errors.FormattedError:
|
||||
// don't worry about unreadable addresses (unless strict addressing
|
||||
// is on)
|
||||
if mc.StrictAddressing || err.Errno != errors.UnreadableAddress {
|
||||
|
@ -237,7 +237,7 @@ func (mc *CPU) read8BitPC() (uint8, error) {
|
|||
}
|
||||
carry, _ := mc.PC.Add(1, false)
|
||||
if carry {
|
||||
return 0, errors.NewGopherError(errors.ProgramCounterCycled, nil)
|
||||
return 0, errors.NewFormattedError(errors.ProgramCounterCycled, nil)
|
||||
}
|
||||
return op, nil
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ func (mc *CPU) read16BitPC() (uint16, error) {
|
|||
// the next instruction but I don't believe this has any side-effects
|
||||
carry, _ := mc.PC.Add(2, false)
|
||||
if carry {
|
||||
return 0, errors.NewGopherError(errors.ProgramCounterCycled, nil)
|
||||
return 0, errors.NewFormattedError(errors.ProgramCounterCycled, nil)
|
||||
}
|
||||
|
||||
return val, nil
|
||||
|
@ -362,10 +362,10 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func(*result.Instruction)) (*res
|
|||
// has wandered into data memory - most likely to occur during
|
||||
// disassembly.
|
||||
if (operator>>4)%2 == 1 {
|
||||
return nil, errors.NewGopherError(errors.InvalidOpcode, fmt.Sprintf("%02x", operator))
|
||||
return nil, errors.NewFormattedError(errors.InvalidOpcode, fmt.Sprintf("%02x", operator))
|
||||
}
|
||||
|
||||
return nil, errors.NewGopherError(errors.UnimplementedInstruction, operator, mc.PC.ToUint16()-1)
|
||||
return nil, errors.NewFormattedError(errors.UnimplementedInstruction, operator, mc.PC.ToUint16()-1)
|
||||
}
|
||||
result.Defn = defn
|
||||
|
||||
|
|
|
@ -46,14 +46,14 @@ func (mem *mockMem) Clear() {
|
|||
|
||||
func (mem mockMem) Read(address uint16) (uint8, error) {
|
||||
if address&0xff00 == 0xff00 {
|
||||
return 0, errors.NewGopherError(errors.UnreadableAddress, address)
|
||||
return 0, errors.NewFormattedError(errors.UnreadableAddress, address)
|
||||
}
|
||||
return mem.internal[address], nil
|
||||
}
|
||||
|
||||
func (mem *mockMem) Write(address uint16, data uint8) error {
|
||||
if address&0xff00 == 0xff00 {
|
||||
return errors.NewGopherError(errors.UnwritableAddress, address)
|
||||
return errors.NewFormattedError(errors.UnwritableAddress, address)
|
||||
}
|
||||
mem.internal[address] = data
|
||||
return nil
|
||||
|
@ -539,7 +539,7 @@ func testStrictAddressing(t *testing.T, mc *cpu.CPU, mem *mockMem) {
|
|||
origin = mem.putInstructions(origin, 0x8d, 0x00, 0xff)
|
||||
_, err := mc.ExecuteInstruction(func(*result.Instruction) {})
|
||||
if err != nil {
|
||||
if err.(errors.GopherError).Errno == errors.UnwritableAddress {
|
||||
if err.(errors.FormattedError).Errno == errors.UnwritableAddress {
|
||||
t.Fatalf("recieved an UnwritableAddress error when we shouldn't")
|
||||
}
|
||||
t.Fatalf("error during CPU step (%v)\n", err)
|
||||
|
@ -552,7 +552,7 @@ func testStrictAddressing(t *testing.T, mc *cpu.CPU, mem *mockMem) {
|
|||
if err == nil {
|
||||
t.Fatalf("not recieved an UnwritableAddress error when we should")
|
||||
}
|
||||
if err.(errors.GopherError).Errno == errors.UnwritableAddress {
|
||||
if err.(errors.FormattedError).Errno == errors.UnwritableAddress {
|
||||
// this is okay
|
||||
} else {
|
||||
t.Fatalf("error during CPU step (%v)\n", err)
|
||||
|
@ -563,7 +563,7 @@ func testStrictAddressing(t *testing.T, mc *cpu.CPU, mem *mockMem) {
|
|||
origin = mem.putInstructions(origin, 0xad, 0x00, 0xff)
|
||||
_, err = mc.ExecuteInstruction(func(*result.Instruction) {})
|
||||
if err != nil {
|
||||
if err.(errors.GopherError).Errno == errors.UnreadableAddress {
|
||||
if err.(errors.FormattedError).Errno == errors.UnreadableAddress {
|
||||
t.Fatalf("recieved an UnreadableAddress we shouldn't")
|
||||
}
|
||||
t.Fatalf("error during CPU step (%v)\n", err)
|
||||
|
@ -576,7 +576,7 @@ func testStrictAddressing(t *testing.T, mc *cpu.CPU, mem *mockMem) {
|
|||
if err == nil {
|
||||
t.Fatalf("not recieved an UnreadableAddress error when we should")
|
||||
}
|
||||
if err.(errors.GopherError).Errno == errors.UnreadableAddress {
|
||||
if err.(errors.FormattedError).Errno == errors.UnreadableAddress {
|
||||
// this is okay
|
||||
} else {
|
||||
t.Fatalf("error during CPU step (%v)\n", err)
|
||||
|
|
|
@ -86,7 +86,7 @@ func (cart *Cartridge) Clear() {
|
|||
// Implementation of CPUBus.Read
|
||||
func (cart Cartridge) Read(address uint16) (uint8, error) {
|
||||
if len(cart.memory) == 0 {
|
||||
return 0, errors.NewGopherError(errors.CartridgeMissing)
|
||||
return 0, errors.NewFormattedError(errors.CartridgeMissing)
|
||||
}
|
||||
return cart.readHook(cart.origin | address ^ cart.origin)
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func (cart *Cartridge) readBanks(file io.ReadSeeker, numBanks int) error {
|
|||
return err
|
||||
}
|
||||
if n != 4096 {
|
||||
return errors.NewGopherError(errors.CartridgeFileError, errors.FileTruncated)
|
||||
return errors.NewFormattedError(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ func (cart *Cartridge) readBanks(file io.ReadSeeker, numBanks int) error {
|
|||
func (cart *Cartridge) Attach(filename string) error {
|
||||
cf, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return errors.NewGopherError(errors.CartridgeFileError, err)
|
||||
return errors.NewFormattedError(errors.CartridgeFileError, err)
|
||||
}
|
||||
defer func() {
|
||||
_ = cf.Close()
|
||||
|
@ -148,11 +148,11 @@ func (cart *Cartridge) Attach(filename string) error {
|
|||
|
||||
// set default read hooks
|
||||
cart.readHook = func(addr uint16) (uint8, error) {
|
||||
return 0, errors.NewGopherError(errors.UnreadableAddress, addr)
|
||||
return 0, errors.NewFormattedError(errors.UnreadableAddress, addr)
|
||||
}
|
||||
|
||||
cart.writeHook = func(addr uint16, data uint8) error {
|
||||
return errors.NewGopherError(errors.UnwritableAddress, addr)
|
||||
return errors.NewFormattedError(errors.UnwritableAddress, addr)
|
||||
}
|
||||
|
||||
// how cartridges are mapped into the 4k space can differs dramatically.
|
||||
|
@ -227,7 +227,7 @@ func (cart *Cartridge) Attach(filename string) error {
|
|||
} else if addr == 0x0ff9 {
|
||||
cart.Bank = 1
|
||||
} else {
|
||||
return errors.NewGopherError(errors.UnwritableAddress, addr)
|
||||
return errors.NewFormattedError(errors.UnwritableAddress, addr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ func (cart *Cartridge) Attach(filename string) error {
|
|||
// o Montezuma's Revenge
|
||||
|
||||
case 12288:
|
||||
return errors.NewGopherError(errors.CartridgeUnsupported, "12288 bytes not yet supported")
|
||||
return errors.NewFormattedError(errors.CartridgeUnsupported, "12288 bytes not yet supported")
|
||||
|
||||
case 16384:
|
||||
cart.readBanks(cf, 4)
|
||||
|
@ -278,7 +278,7 @@ func (cart *Cartridge) Attach(filename string) error {
|
|||
} else if addr == 0x0ff9 {
|
||||
cart.Bank = 3
|
||||
} else {
|
||||
return errors.NewGopherError(errors.UnwritableAddress, addr)
|
||||
return errors.NewFormattedError(errors.UnwritableAddress, addr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ func (cart *Cartridge) Attach(filename string) error {
|
|||
} else if addr == 0x0ffb {
|
||||
cart.Bank = 7
|
||||
} else {
|
||||
return errors.NewGopherError(errors.UnwritableAddress, addr)
|
||||
return errors.NewFormattedError(errors.UnwritableAddress, addr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -344,11 +344,11 @@ func (cart *Cartridge) Attach(filename string) error {
|
|||
cart.addCartridgeRAM()
|
||||
|
||||
case 65536:
|
||||
return errors.NewGopherError(errors.CartridgeUnsupported, "65536 bytes not yet supported")
|
||||
return errors.NewFormattedError(errors.CartridgeUnsupported, "65536 bytes not yet supported")
|
||||
|
||||
default:
|
||||
cart.Eject()
|
||||
return errors.NewGopherError(errors.CartridgeUnsupported, fmt.Sprintf("unrecognised cartridge size (%d bytes)", cfi.Size()))
|
||||
return errors.NewFormattedError(errors.CartridgeUnsupported, fmt.Sprintf("unrecognised cartridge size (%d bytes)", cfi.Size()))
|
||||
}
|
||||
|
||||
// note name of cartridge
|
||||
|
@ -407,7 +407,7 @@ func (cart *Cartridge) addCartridgeRAM() bool {
|
|||
// BankSwitch changes the current bank number
|
||||
func (cart *Cartridge) BankSwitch(bank int) error {
|
||||
if bank > cart.NumBanks {
|
||||
return errors.NewGopherError(errors.CartridgeNoSuchBank, bank, cart.NumBanks)
|
||||
return errors.NewFormattedError(errors.CartridgeNoSuchBank, bank, cart.NumBanks)
|
||||
}
|
||||
cart.Bank = bank
|
||||
return nil
|
||||
|
@ -429,7 +429,7 @@ func (cart *Cartridge) Eject() {
|
|||
// Peek is the implementation of Memory.Area.Peek
|
||||
func (cart Cartridge) Peek(address uint16) (uint8, uint16, string, string, error) {
|
||||
if len(cart.memory) == 0 {
|
||||
return 0, 0, "", "", errors.NewGopherError(errors.CartridgeMissing)
|
||||
return 0, 0, "", "", errors.NewFormattedError(errors.CartridgeMissing)
|
||||
}
|
||||
return cart.memory[cart.Bank][cart.origin|address^cart.origin], address, cart.Label(), "", nil
|
||||
}
|
||||
|
@ -438,5 +438,5 @@ func (cart Cartridge) Peek(address uint16) (uint8, uint16, string, string, error
|
|||
func (cart Cartridge) Poke(address uint16, value uint8) error {
|
||||
// if we want to poke cartridge memory we need to account for different
|
||||
// cartridge sizes.
|
||||
return errors.NewGopherError(errors.UnPokeableAddress, address)
|
||||
return errors.NewFormattedError(errors.UnPokeableAddress, address)
|
||||
}
|
||||
|
|
|
@ -63,12 +63,12 @@ func (area ChipMemory) Memtop() uint16 {
|
|||
func (area ChipMemory) Peek(address uint16) (uint8, uint16, string, string, error) {
|
||||
sym := vcssymbols.ReadSymbols[address]
|
||||
if sym == "" {
|
||||
return 0, 0, "", "", errors.NewGopherError(errors.UnreadableAddress, address)
|
||||
return 0, 0, "", "", errors.NewFormattedError(errors.UnreadableAddress, address)
|
||||
}
|
||||
return area.memory[address-area.origin], address, area.Label(), sym, nil
|
||||
}
|
||||
|
||||
// Poke is the implementation of Memory.Area.Poke
|
||||
func (area ChipMemory) Poke(address uint16, value uint8) error {
|
||||
return errors.NewGopherError(errors.UnPokeableAddress, address)
|
||||
return errors.NewFormattedError(errors.UnPokeableAddress, address)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ func (area *ChipMemory) Read(address uint16) (uint8, error) {
|
|||
|
||||
sym := vcssymbols.ReadSymbols[address]
|
||||
if sym == "" {
|
||||
return 0, errors.NewGopherError(errors.UnreadableAddress, address)
|
||||
return 0, errors.NewFormattedError(errors.UnreadableAddress, address)
|
||||
}
|
||||
|
||||
return area.memory[area.origin|address^area.origin], nil
|
||||
|
@ -26,12 +26,12 @@ func (area *ChipMemory) Write(address uint16, data uint8) error {
|
|||
|
||||
// check that the last write to this memory area has been serviced
|
||||
if area.writeSignal {
|
||||
return errors.NewGopherError(errors.UnservicedChipWrite, vcssymbols.WriteSymbols[area.lastWriteAddress])
|
||||
return errors.NewFormattedError(errors.UnservicedChipWrite, vcssymbols.WriteSymbols[area.lastWriteAddress])
|
||||
}
|
||||
|
||||
sym := vcssymbols.WriteSymbols[address]
|
||||
if sym == "" {
|
||||
return errors.NewGopherError(errors.UnwritableAddress, address)
|
||||
return errors.NewFormattedError(errors.UnwritableAddress, address)
|
||||
}
|
||||
|
||||
// note address of write
|
||||
|
|
|
@ -33,7 +33,7 @@ func NewStick(tia memory.PeriphBus, riot memory.PeriphBus, panel *Panel) *Stick
|
|||
// system assigned index: typically increments on each new controller added.
|
||||
stick.device = joysticks.Connect(1)
|
||||
if stick.device == nil {
|
||||
stick.err = errors.NewGopherError(errors.NoControllersFound, nil)
|
||||
stick.err = errors.NewFormattedError(errors.NoControllersFound, nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -203,10 +203,10 @@ func addCartridge(cartridgeFile string, tvMode string, numOfFrames int, allowUpd
|
|||
if allowUpdate == false {
|
||||
if existEntry, ok := db.entries[entry.key]; ok {
|
||||
if existEntry.cartridgeFile == entry.cartridgeFile {
|
||||
return errors.NewGopherError(errors.RegressionEntryExists, entry)
|
||||
return errors.NewFormattedError(errors.RegressionEntryExists, entry)
|
||||
}
|
||||
|
||||
return errors.NewGopherError(errors.RegressionEntryCollision, entry.cartridgeFile, existEntry.cartridgeFile)
|
||||
return errors.NewFormattedError(errors.RegressionEntryCollision, entry.cartridgeFile, existEntry.cartridgeFile)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ func RegressDeleteCartridge(cartridgeFile string) error {
|
|||
}
|
||||
|
||||
if _, ok := db.entries[key]; ok == false {
|
||||
return errors.NewGopherError(errors.RegressionEntryDoesNotExist, cartridgeFile)
|
||||
return errors.NewFormattedError(errors.RegressionEntryDoesNotExist, cartridgeFile)
|
||||
}
|
||||
|
||||
delete(db.entries, key)
|
||||
|
@ -262,7 +262,7 @@ func RegressRunTests(output io.Writer, failOnError bool) (int, int, error) {
|
|||
|
||||
if err != nil || entry.digest != digest {
|
||||
if err == nil {
|
||||
err = errors.NewGopherError(errors.RegressionEntryFail, entry)
|
||||
err = errors.NewFormattedError(errors.RegressionEntryFail, entry)
|
||||
}
|
||||
|
||||
numFail++
|
||||
|
|
|
@ -46,5 +46,5 @@ func (sym *Table) SearchSymbol(symbol string, table TableType) (TableType, strin
|
|||
}
|
||||
}
|
||||
|
||||
return UnspecifiedSymTable, symbol, 0, errors.NewGopherError(errors.SymbolUnknown, symbol)
|
||||
return UnspecifiedSymTable, symbol, 0, errors.NewFormattedError(errors.SymbolUnknown, symbol)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/hardware/memory/vcssymbols"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
@ -69,26 +70,15 @@ func ReadSymbolsFile(cartridgeFilename string) (*Table, error) {
|
|||
if cartridgeFilename == "" {
|
||||
return table, nil
|
||||
}
|
||||
return table, errors.NewGopherError(errors.SymbolsFileCannotOpen, cartridgeFilename)
|
||||
return nil, errors.NewFormattedError(errors.SymbolsFileCannotOpen, cartridgeFilename)
|
||||
}
|
||||
defer func() {
|
||||
_ = sf.Close()
|
||||
}()
|
||||
|
||||
// get file info of symbols file
|
||||
sfi, err := sf.Stat()
|
||||
sym, err := ioutil.ReadAll(sf)
|
||||
if err != nil {
|
||||
return table, errors.NewGopherError(errors.SymbolsFileError, err)
|
||||
}
|
||||
|
||||
// read symbols file and split into lines
|
||||
sym := make([]byte, sfi.Size())
|
||||
n, err := sf.Read(sym)
|
||||
if err != nil {
|
||||
return table, errors.NewGopherError(errors.SymbolsFileError, err)
|
||||
}
|
||||
if n != len(sym) {
|
||||
return table, errors.NewGopherError(errors.SymbolsFileError, errors.FileTruncated)
|
||||
return nil, errors.NewFormattedError(errors.SymbolsFileError, err)
|
||||
}
|
||||
lines := strings.Split(string(sym), "\n")
|
||||
|
||||
|
|
|
@ -273,7 +273,7 @@ func (tv *HeadlessTV) SystemStateRecord(monitor.SystemState) error {
|
|||
func (tv *HeadlessTV) GetState(request StateReq) (interface{}, error) {
|
||||
switch request {
|
||||
default:
|
||||
return nil, errors.NewGopherError(errors.UnknownTVRequest, request)
|
||||
return nil, errors.NewFormattedError(errors.UnknownTVRequest, request)
|
||||
case ReqFramenum:
|
||||
return tv.frameNum, nil
|
||||
case ReqScanline:
|
||||
|
|
|
@ -84,14 +84,14 @@ func (tv *ImageTV) setPixel(x, y int32, red, green, blue byte, vblank bool) erro
|
|||
// <group/<label>_<framenum>.png
|
||||
func (tv *ImageTV) SystemStateRecord(state monitor.SystemState) error {
|
||||
if state.Label == "" || state.Group == "" {
|
||||
return errors.NewGopherError(errors.ImageTV, "SystemStateRecord requires a Label and Group")
|
||||
return errors.NewFormattedError(errors.ImageTV, "SystemStateRecord requires a Label and Group")
|
||||
}
|
||||
return tv.save(filepath.Join(state.Group, state.Label))
|
||||
}
|
||||
|
||||
func (tv *ImageTV) save(fileNameBase string) error {
|
||||
if tv.lastImage == nil {
|
||||
return errors.NewGopherError(errors.ImageTV, "no data to save")
|
||||
return errors.NewFormattedError(errors.ImageTV, "no data to save")
|
||||
}
|
||||
|
||||
// prepare filename for image
|
||||
|
@ -100,22 +100,22 @@ func (tv *ImageTV) save(fileNameBase string) error {
|
|||
f, err := os.Open(imageName)
|
||||
if f != nil {
|
||||
f.Close()
|
||||
return errors.NewGopherError(errors.ImageTV, fmt.Errorf("image file (%s) already exists", imageName))
|
||||
return errors.NewFormattedError(errors.ImageTV, fmt.Errorf("image file (%s) already exists", imageName))
|
||||
}
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return errors.NewGopherError(errors.ImageTV, err)
|
||||
return errors.NewFormattedError(errors.ImageTV, err)
|
||||
}
|
||||
|
||||
f, err = os.Create(imageName)
|
||||
if err != nil {
|
||||
return errors.NewGopherError(errors.ImageTV, err)
|
||||
return errors.NewFormattedError(errors.ImageTV, err)
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
err = png.Encode(f, tv.lastImage)
|
||||
if err != nil {
|
||||
return errors.NewGopherError(errors.ImageTV, err)
|
||||
return errors.NewFormattedError(errors.ImageTV, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Add table
Reference in a new issue