renamed errors package to 'curated'

to differentiate with the now existing errors package in the standard
library.
This commit is contained in:
JetSetIlly 2020-09-28 18:03:31 +01:00
parent 2d5cae17f5
commit 7fc48dcd65
92 changed files with 676 additions and 623 deletions

View file

@ -25,7 +25,7 @@ import (
"path"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
)
@ -174,7 +174,7 @@ func (cl *Loader) Load() error {
url, err := url.Parse(cl.Filename)
if err != nil {
return errors.Errorf("cartridgeloader: %v", err)
return curated.Errorf("cartridgeloader: %v", err)
}
switch url.Scheme {
@ -183,13 +183,13 @@ func (cl *Loader) Load() error {
case "https":
resp, err := http.Get(cl.Filename)
if err != nil {
return errors.Errorf("cartridgeloader: %v", err)
return curated.Errorf("cartridgeloader: %v", err)
}
defer resp.Body.Close()
cl.Data, err = ioutil.ReadAll(resp.Body)
if err != nil {
return errors.Errorf("cartridgeloader: %v", err)
return curated.Errorf("cartridgeloader: %v", err)
}
case "file":
@ -198,7 +198,7 @@ func (cl *Loader) Load() error {
case "":
f, err := os.Open(cl.Filename)
if err != nil {
return errors.Errorf("cartridgeloader: %v", err)
return curated.Errorf("cartridgeloader: %v", err)
}
defer f.Close()
@ -206,18 +206,18 @@ func (cl *Loader) Load() error {
// windows version (when running under wine) does not handle that
cfi, err := os.Stat(cl.Filename)
if err != nil {
return errors.Errorf("cartridgeloader: %v", err)
return curated.Errorf("cartridgeloader: %v", err)
}
size := cfi.Size()
cl.Data = make([]byte, size)
_, err = f.Read(cl.Data)
if err != nil {
return errors.Errorf("cartridgeloader: %v", err)
return curated.Errorf("cartridgeloader: %v", err)
}
default:
return errors.Errorf("cartridgeloader: %v", fmt.Sprintf("unsupported URL scheme (%s)", url.Scheme))
return curated.Errorf("cartridgeloader: %v", fmt.Sprintf("unsupported URL scheme (%s)", url.Scheme))
}
// generate hash
@ -225,7 +225,7 @@ func (cl *Loader) Load() error {
// check for hash consistency
if cl.Hash != "" && cl.Hash != hash {
return errors.Errorf("cartridgeloader: %v", "unexpected hash value")
return curated.Errorf("cartridgeloader: %v", "unexpected hash value")
}
// not generated hash

112
curated/doc.go Normal file
View file

@ -0,0 +1,112 @@
// 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 curated is a helper package for the plain Go language error type.
// Curated errors implement the error interface and external to the package are
// stored as an instance of that interface.
//
// Curated errors are created with the Errorf() function. This is similar to
// the Errorf() function in the fmt package, it takes a formatting pattern and
// placeholder values and returns an error.
//
// The Is() function can be used to check whether an error was created by the
// (Errorf() function) with the specified pattern. For example:
//
// a := 10
// e := curated.Errorf("error: value = %d", a)
//
// if curated.Is(e, "error: value = %d") {
// fmt.Println("true")
// }
//
// The Has() function is similar but checks if a pattern occurs somewhere in
// the error chain. The value of the variable 'a' in this example does not
// matter.
//
// a := 10
// e := curated.Errorf("error: value = %d", a)
// f := curated.Errorf("fatal: %v", e)
//
// if curated.Has(f, "error: value = %d") {
// fmt.Println("true")
// }
//
// if curated.Is(f, "error: value = %d") {
// fmt.Println("true")
// }
//
// Note that in this example, the call to Is() fails will not print 'true'
// because error f does not match that pattern - it is wrapped inside the
// pattern "fatal: %v".
//
// The IsAny() function simply answers whether the error was created by
// Errorf() or not. Or put another way, it returns true if the error is
// 'curated' and false if the error is 'uncurated'. We could alternatively
// think of the difference as being 'expected' and 'unexpected' depending on
// how we choose to handle the result of the function call.
//
// The Error() function implementation for curated errors ensures that the
// error chain is normalised. Specifically, that the chain does not contain
// duplicate adjacent parts. The practical advantage of this is that it
// alleviates the problem of when and how to wrap curated. For example:
//
// func main() {
// err := A()
// if err != nil {
// fmt.Println(err)
// }
// }
//
// func A() error {
// err := B()
// if err != nil {
// return curated.Errorf("error: %v", err)
// }
// return nil
// }
//
// func B() error {
// err := C()
// if err != nil {
// return curated.Errorf("error: %v", err)
// }
// return nil
// }
//
// func C() error {
// return curated.Errorf("not yet implemented")
// }
//
// This will result in the main() function printing an error message. Using the
// curated Error() function, the message will be:
//
// debugger error: not yet implemented
//
// and not:
//
// error: error: not yet implemented
//
// For the purposes of this package we think of chains as being composed of
// parts separted by the sub-string ': ' as suggestedf on p239 of "The Go
// Programming Language" (Donovan, Kernighan). For example:
//
// part 1: part 2: part 3
//
// There is no special provision for sentinal errors in the curated package but
// they are achievable in practice through the use of the Is() and Has()
// functions. For clarity the sentinal pattern should be stored as a const
// string, suitably named and commented. A Sentinal type may be introduced in
// the future.
package curated

View file

@ -13,7 +13,7 @@
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
package errors
package curated
import (
"fmt"
@ -21,30 +21,36 @@ import (
)
// Values is the type used to specify arguments for FormattedErrors
type Values []interface{}
type values []interface{}
// curated erorrs allow code to specify a predefined error and not worry too
// much about the message behind that error and how the message will be
// formatted on output.
// curated is an implementation of the go language error interface
type curated struct {
message string
values Values
pattern string
values values
}
// Errorf creates a new curated error
func Errorf(message string, values ...interface{}) error {
// Errorf creates a new curated error.
//
// Note that unlike the Errorf() function in the fmt package the first argument
// is named "pattern" not "format". This is because we use the pattern string
// in the Is() and Has() functions, in which 'pattern' seems a better name.
func Errorf(pattern string, values ...interface{}) error {
// note that we're not actually formatting the error here, despite the
// function name. we instead store the arguments. formatting takes place in
// the Error() function
return curated{
message: message,
pattern: pattern,
values: values,
}
}
// Error returns the normalised error message. Normalisation being the removal
// of duplicate adjacent error messsage parts.
// of duplicate adjacent error messsage parts in the error message chains. It
// doesn't affect letter-case or white space.
//
// Implements the go language error interface.
func (er curated) Error() string {
s := fmt.Errorf(er.message, er.values...).Error()
s := fmt.Errorf(er.pattern, er.values...).Error()
// de-duplicate error message parts
p := strings.SplitN(s, ": ", 3)
@ -55,20 +61,7 @@ func (er curated) Error() string {
return strings.Join(p, ": ")
}
// Head returns the leading part of the message.
//
// Similar to Is() but returns the string rather than a boolean. Useful for
// switches.
//
// If err is a plain error then the return of Error() is returned
func Head(err error) string {
if er, ok := err.(curated); ok {
return er.message
}
return err.Error()
}
// IsAny checks if error is being curated by this package
// IsAny checks if error is specifically of the curated type
func IsAny(err error) bool {
if err == nil {
return false
@ -77,23 +70,26 @@ func IsAny(err error) bool {
if _, ok := err.(curated); ok {
return true
}
return false
}
// Is checks if error has a specific head
func Is(err error, head string) bool {
// Is checks if error is a curated error with a specific pattern
func Is(err error, pattern string) bool {
if err == nil {
return false
}
if er, ok := err.(curated); ok {
return er.message == head
return er.pattern == pattern
}
return false
}
// Has checks if the message string appears somewhere in the error
func Has(err error, msg string) bool {
// Is checks if error is a curated error with a specific pattern somewhere in
// the chain
func Has(err error, pattern string) bool {
if err == nil {
return false
}
@ -102,13 +98,13 @@ func Has(err error, msg string) bool {
return false
}
if Is(err, msg) {
if Is(err, pattern) {
return true
}
for i := range err.(curated).values {
if e, ok := err.(curated).values[i].(curated); ok {
if Has(e, msg) {
if Has(e, pattern) {
return true
}
}

View file

@ -13,13 +13,13 @@
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
package errors_test
package curated_test
import (
"fmt"
"testing"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/test"
)
@ -28,42 +28,55 @@ const testErrorB = "test error B: %s"
func TestDuplicateErrors(t *testing.T) {
e := errors.Errorf(testError, "foo")
e := curated.Errorf(testError, "foo")
test.Equate(t, e.Error(), "test error: foo")
// packing errors of the same type next to each other causes
// one of them to be dropped
f := errors.Errorf(testError, e)
f := curated.Errorf(testError, e)
test.Equate(t, f.Error(), "test error: foo")
}
func TestIs(t *testing.T) {
e := errors.Errorf(testError, "foo")
test.ExpectedSuccess(t, errors.Is(e, testError))
e := curated.Errorf(testError, "foo")
test.ExpectedSuccess(t, curated.Is(e, testError))
// Has() should fail because we haven't included testErrorB anywhere in the error
test.ExpectedFailure(t, errors.Has(e, testErrorB))
test.ExpectedFailure(t, curated.Has(e, testErrorB))
// packing errors of the same type next to each other causes
// one of them to be dropped
f := errors.Errorf(testErrorB, e)
test.ExpectedFailure(t, errors.Is(f, testError))
test.ExpectedSuccess(t, errors.Is(f, testErrorB))
test.ExpectedSuccess(t, errors.Has(f, testError))
test.ExpectedSuccess(t, errors.Has(f, testErrorB))
f := curated.Errorf(testErrorB, e)
test.ExpectedFailure(t, curated.Is(f, testError))
test.ExpectedSuccess(t, curated.Is(f, testErrorB))
test.ExpectedSuccess(t, curated.Has(f, testError))
test.ExpectedSuccess(t, curated.Has(f, testErrorB))
// IsAny should return true for these errors also
test.ExpectedSuccess(t, errors.IsAny(e))
test.ExpectedSuccess(t, errors.IsAny(f))
test.ExpectedSuccess(t, curated.IsAny(e))
test.ExpectedSuccess(t, curated.IsAny(f))
}
func TestPlainErrors(t *testing.T) {
// test plain errors that haven't been formatted with our errors package
e := fmt.Errorf("plain test error")
test.ExpectedFailure(t, errors.IsAny(e))
test.ExpectedFailure(t, curated.IsAny(e))
const testError = "test error: %s"
test.ExpectedFailure(t, errors.Has(e, testError))
test.ExpectedFailure(t, curated.Has(e, testError))
}
func TestWrapping(t *testing.T) {
a := 10
e := curated.Errorf("error: value = %d", a)
f := curated.Errorf("fatal: %v", e)
test.ExpectedSuccess(t, curated.Has(f, "error: value = %d"))
test.ExpectedFailure(t, curated.Is(f, "error: value = %d"))
test.ExpectedSuccess(t, curated.Has(f, "fatal: %v"))
test.ExpectedSuccess(t, curated.Is(f, "fatal: %v"))
test.Equate(t, f.Error(), "fatal: error: value = 10")
}

View file

@ -20,7 +20,7 @@ import (
"io"
"sort"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// arbitrary maximum number of entries
@ -101,7 +101,7 @@ func (db *Session) Add(ent Entry) error {
}
if key == maxEntries {
return errors.Errorf("database: maximum entries exceeded (max %d)", maxEntries)
return curated.Errorf("database: maximum entries exceeded (max %d)", maxEntries)
}
db.entries[key] = ent
@ -114,11 +114,11 @@ func (db *Session) Add(ent Entry) error {
func (db *Session) Delete(key int) error {
ent, ok := db.entries[key]
if !ok {
return errors.Errorf("database: key not available (%s)", key)
return curated.Errorf("database: key not available (%s)", key)
}
if err := ent.CleanUp(); err != nil {
return errors.Errorf("database: %v", err)
return curated.Errorf("database: %v", err)
}
delete(db.entries, key)

View file

@ -18,7 +18,7 @@ package database
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Deserialiser extracts/converts fields from a SerialisedEntry
@ -50,7 +50,7 @@ type Entry interface {
func (db *Session) RegisterEntryType(id string, des Deserialiser) error {
if _, ok := db.entryTypes[id]; ok {
msg := fmt.Sprintf("trying to register a duplicate entry ID [%s]", id)
return errors.Errorf("database: %v", msg)
return curated.Errorf("database: %v", msg)
}
db.entryTypes[id] = des
return nil

View file

@ -15,7 +15,7 @@
package database
import "github.com/jetsetilly/gopher2600/errors"
import "github.com/jetsetilly/gopher2600/curated"
// SelectAll entries in the database. onSelect can be nil.
//
@ -80,7 +80,7 @@ func (db Session) SelectKeys(onSelect func(Entry) (bool, error), keys ...int) (E
}
if entry == nil {
return nil, errors.Errorf("database: select empty")
return nil, curated.Errorf("database: select empty")
}
return entry, nil

View file

@ -22,7 +22,7 @@ import (
"strconv"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Sentinal error returned when requested database is not available
@ -81,9 +81,9 @@ func StartSession(path string, activity Activity, init func(*Session) error) (*S
if err != nil {
switch err.(type) {
case *os.PathError:
return nil, errors.Errorf(NotAvailable, path)
return nil, curated.Errorf(NotAvailable, path)
}
return nil, errors.Errorf("databas: %v", err)
return nil, curated.Errorf("databas: %v", err)
}
// closing of db.dbfile requires a call to endSession()
@ -106,7 +106,7 @@ func (db *Session) EndSession(commitChanges bool) error {
// write entries to database
if commitChanges {
if db.activity == ActivityReading {
return errors.Errorf("database: cannot commit to a read-only database")
return curated.Errorf("database: cannot commit to a read-only database")
}
err := db.dbfile.Truncate(0)
@ -168,7 +168,7 @@ func (db *Session) readDBFile() error {
buffer, err := ioutil.ReadAll(db.dbfile)
if err != nil {
return errors.Errorf("database: %v", err)
return curated.Errorf("database: %v", err)
}
// split entries
@ -185,23 +185,23 @@ func (db *Session) readDBFile() error {
key, err := strconv.Atoi(fields[leaderFieldKey])
if err != nil {
return errors.Errorf("invalid key (%s) [line %d]", fields[leaderFieldKey], i+1)
return curated.Errorf("invalid key (%s) [line %d]", fields[leaderFieldKey], i+1)
}
if _, ok := db.entries[key]; ok {
return errors.Errorf("duplicate key (%s) [line %d]", key, i+1)
return curated.Errorf("duplicate key (%s) [line %d]", key, i+1)
}
var ent Entry
deserialise, ok := db.entryTypes[fields[leaderFieldID]]
if !ok {
return errors.Errorf("unrecognised entry type (%s) [line %d]", fields[leaderFieldID], i+1)
return curated.Errorf("unrecognised entry type (%s) [line %d]", fields[leaderFieldID], i+1)
}
ent, err = deserialise(strings.Split(fields[numLeaderFields], ","))
if err != nil {
return errors.Errorf("%v [line %d]", err, i+1)
return curated.Errorf("%v [line %d]", err, i+1)
}
db.entries[key] = ent

View file

@ -27,7 +27,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
"github.com/jetsetilly/gopher2600/disassembly"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
)
@ -164,12 +164,12 @@ func newBreakpoints(dbg *Debugger) (*breakpoints, error) {
bp.checkPcBreak, err = parseTarget(bp.dbg, commandline.TokeniseInput("PC"))
if err != nil {
return nil, errors.Errorf("breakpoint: this should not have failed: %v", err)
return nil, curated.Errorf("breakpoint: this should not have failed: %v", err)
}
bp.checkBankBreak, err = parseTarget(bp.dbg, commandline.TokeniseInput("BANK"))
if err != nil {
return nil, errors.Errorf("breakpoint: this should not have failed: %v", err)
return nil, curated.Errorf("breakpoint: this should not have failed: %v", err)
}
return bp, err
@ -183,7 +183,7 @@ func (bp *breakpoints) clear() {
// drop a specific breakpoint by position in list
func (bp *breakpoints) drop(num int) error {
if len(bp.breaks)-1 < num {
return errors.Errorf("breakpoint #%d is not defined", num)
return curated.Errorf("breakpoint #%d is not defined", num)
}
h := bp.breaks[:num]
@ -253,7 +253,7 @@ func (bp *breakpoints) parseCommand(tokens *commandline.Tokens) error {
// something appropriate
tgt, err := parseTarget(bp.dbg, commandline.TokeniseInput("PC"))
if err != nil {
return errors.Errorf("breakpoint: this should not have failed: %v", err)
return curated.Errorf("breakpoint: this should not have failed: %v", err)
}
// resolvedTarget keeps track of whether we have specified a target but not
@ -298,10 +298,10 @@ func (bp *breakpoints) parseCommand(tokens *commandline.Tokens) error {
case "false":
val = false
default:
err = errors.Errorf("invalid value (%s) for target (%s)", tok, tgt.Label)
err = curated.Errorf("invalid value (%s) for target (%s)", tok, tgt.Label)
}
default:
return errors.Errorf("unsupported value type (%T) for target (%s)", tgt.TargetValue(), tgt.Label())
return curated.Errorf("unsupported value type (%T) for target (%s)", tgt.TargetValue(), tgt.Label())
}
if err == nil {
@ -326,7 +326,7 @@ func (bp *breakpoints) parseCommand(tokens *commandline.Tokens) error {
} else {
// make sure we've not left a previous target dangling without a value
if !resolvedTarget {
return errors.Errorf("%v", err)
return curated.Errorf("%v", err)
}
// possibly switch composition mode
@ -344,7 +344,7 @@ func (bp *breakpoints) parseCommand(tokens *commandline.Tokens) error {
tokens.Unget()
tgt, err = parseTarget(bp.dbg, tokens)
if err != nil {
return errors.Errorf("%v", err)
return curated.Errorf("%v", err)
}
resolvedTarget = false
@ -355,7 +355,7 @@ func (bp *breakpoints) parseCommand(tokens *commandline.Tokens) error {
}
if !resolvedTarget {
return errors.Errorf("need a value (%T) to break on (%s)", tgt.TargetValue(), tgt.Label)
return curated.Errorf("need a value (%T) to break on (%s)", tgt.TargetValue(), tgt.Label)
}
for _, nb := range newBreaks {
@ -373,7 +373,7 @@ func (bp *breakpoints) parseCommand(tokens *commandline.Tokens) error {
}
if i := bp.checkBreaker(nb); i != noBreakEqualivalent {
return errors.Errorf("already exists (%s)", bp.breaks[i])
return curated.Errorf("already exists (%s)", bp.breaks[i])
}
bp.breaks = append(bp.breaks, nb)
}

View file

@ -28,7 +28,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
"github.com/jetsetilly/gopher2600/disassembly"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/hardware/cpu/registers"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/plusrom"
@ -107,7 +107,7 @@ func (dbg *Debugger) tokeniseCommand(cmd string, scribe bool, echo bool) (*comma
// fail when the tokens DO match the scriptUnsafe template (ie. when
// there is no err from the validate function)
if err == nil {
return nil, errors.Errorf("'%s' is unsafe to use in scripts", tokens.String())
return nil, curated.Errorf("'%s' is unsafe to use in scripts", tokens.String())
}
// record command if it auto is false (is not a result of an "auto" command
@ -141,7 +141,7 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) (bool, error) {
switch command {
default:
return false, errors.Errorf("%s is not yet implemented", command)
return false, curated.Errorf("%s is not yet implemented", command)
case cmdHelp:
keyword, ok := tokens.Get()
@ -202,7 +202,7 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) (bool, error) {
tokens.Unget()
err := dbg.stepTraps.parseCommand(tokens)
if err != nil {
return false, errors.Errorf("unknown step mode (%s)", mode)
return false, curated.Errorf("unknown step mode (%s)", mode)
}
dbg.runUntilHalt = true
}
@ -1008,12 +1008,12 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) (bool, error) {
case "SCALE":
scl, ok := tokens.Get()
if !ok {
return false, errors.Errorf("value required for %s %s", cmdDisplay, action)
return false, curated.Errorf("value required for %s %s", cmdDisplay, action)
}
scale, err := strconv.ParseFloat(scl, 32)
if err != nil {
return false, errors.Errorf("%s %s value not valid (%s)", cmdDisplay, action, scl)
return false, curated.Errorf("%s %s value not valid (%s)", cmdDisplay, action, scl)
}
err = dbg.scr.ReqFeature(gui.ReqSetScale, float32(scale))
@ -1060,8 +1060,8 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) (bool, error) {
}
if err != nil {
if errors.Is(err, gui.UnsupportedGuiFeature) {
return false, errors.Errorf("display does not support feature %s", action)
if curated.Is(err, gui.UnsupportedGuiFeature) {
return false, curated.Errorf("display does not support feature %s", action)
}
return false, err
}
@ -1283,25 +1283,25 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) (bool, error) {
case cmdBreak:
err := dbg.breakpoints.parseCommand(tokens)
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
case cmdTrap:
err := dbg.traps.parseCommand(tokens)
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
case cmdWatch:
err := dbg.watches.parseCommand(tokens)
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
case cmdTrace:
err := dbg.traces.parseCommand(tokens)
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
case cmdList:
@ -1331,7 +1331,7 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) (bool, error) {
s, _ := tokens.Get()
num, err := strconv.Atoi(s)
if err != nil {
return false, errors.Errorf("drop attribute must be a number (%s)", s)
return false, curated.Errorf("drop attribute must be a number (%s)", s)
}
drop = strings.ToUpper(drop)
@ -1403,21 +1403,21 @@ func (dbg *Debugger) processTokens(tokens *commandline.Tokens) (bool, error) {
case "LOAD":
err := dbg.Prefs.load()
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
err = dbg.Disasm.Prefs.Load()
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
case "SAVE":
err := dbg.Prefs.save()
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
err = dbg.Disasm.Prefs.Save()
if err != nil {
return false, errors.Errorf("%v", err)
return false, curated.Errorf("%v", err)
}
}

View file

@ -25,7 +25,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
"github.com/jetsetilly/gopher2600/disassembly"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/cpu/execution"
@ -161,21 +161,21 @@ func NewDebugger(tv television.Television, scr gui.GUI, term terminal.Terminal,
// create a new VCS instance
dbg.VCS, err = hardware.NewVCS(dbg.tv)
if err != nil {
return nil, errors.Errorf("debugger: %v", err)
return nil, curated.Errorf("debugger: %v", err)
}
// replace player 1 port with savekey
if useSavekey {
err = dbg.VCS.RIOT.Ports.AttachPlayer(ports.Player1ID, savekey.NewSaveKey)
if err != nil {
return nil, errors.Errorf("debugger: %v", err)
return nil, curated.Errorf("debugger: %v", err)
}
}
// create a new disassembly instance
dbg.Disasm, err = disassembly.NewDisassembly()
if err != nil {
return nil, errors.Errorf("debugger: %v", err)
return nil, curated.Errorf("debugger: %v", err)
}
// set up debugging interface to memory. note that we're reaching deep into
@ -199,7 +199,7 @@ func NewDebugger(tv television.Television, scr gui.GUI, term terminal.Terminal,
// set up breakpoints/traps
dbg.breakpoints, err = newBreakpoints(dbg)
if err != nil {
return nil, errors.Errorf("debugger: %v", err)
return nil, curated.Errorf("debugger: %v", err)
}
dbg.traps = newTraps(dbg)
dbg.watches = newWatches(dbg)
@ -230,7 +230,7 @@ func NewDebugger(tv television.Television, scr gui.GUI, term terminal.Terminal,
// connect gui
err = scr.ReqFeature(gui.ReqSetEventChan, dbg.events.GuiEvents)
if err != nil {
return nil, errors.Errorf("debugger: %v", err)
return nil, curated.Errorf("debugger: %v", err)
}
// allocate memory for user input
@ -245,7 +245,7 @@ func NewDebugger(tv television.Television, scr gui.GUI, term terminal.Terminal,
// setup preferences and load from disk
dbg.Prefs, err = newPreferences(dbg)
if err != nil {
return nil, errors.Errorf("debugger: %v", err)
return nil, curated.Errorf("debugger: %v", err)
}
return dbg, nil
@ -256,13 +256,13 @@ func (dbg *Debugger) Start(initScript string, cartload cartridgeloader.Loader) e
// prepare user interface
err := dbg.term.Initialise()
if err != nil {
return errors.Errorf("debugger: %v", err)
return curated.Errorf("debugger: %v", err)
}
defer dbg.term.CleanUp()
err = dbg.loadCartridge(cartload)
if err != nil {
return errors.Errorf("debugger: %v", err)
return curated.Errorf("debugger: %v", err)
}
dbg.running = true
@ -275,7 +275,7 @@ func (dbg *Debugger) Start(initScript string, cartload cartridgeloader.Loader) e
err = dbg.inputLoop(scr, false)
if err != nil {
dbg.term.Silence(false)
return errors.Errorf("debugger: %v", err)
return curated.Errorf("debugger: %v", err)
}
dbg.term.Silence(false)
@ -293,7 +293,7 @@ func (dbg *Debugger) Start(initScript string, cartload cartridgeloader.Loader) e
// debugging session is to be terminated
err = dbg.inputLoop(dbg.term, false)
if err != nil {
return errors.Errorf("debugger: %v", err)
return curated.Errorf("debugger: %v", err)
}
return nil
@ -327,12 +327,12 @@ func (dbg *Debugger) loadCartridge(cartload cartridgeloader.Loader) error {
err := dbg.scr.ReqFeature(gui.ReqChangingCartridge, true)
if err != nil {
return errors.Errorf("debugger: %v", err)
return curated.Errorf("debugger: %v", err)
}
defer dbg.scr.ReqFeature(gui.ReqChangingCartridge, false)
err = setup.AttachCartridge(dbg.VCS, cartload)
if err != nil && !errors.Has(err, cartridge.Ejected) {
if err != nil && !curated.Has(err, cartridge.Ejected) {
return err
}

View file

@ -19,7 +19,7 @@ import (
"fmt"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/logger"
"github.com/jetsetilly/gopher2600/playmode"
@ -31,7 +31,7 @@ func (dbg *Debugger) guiEventHandler(ev gui.Event) error {
switch ev := ev.(type) {
case gui.EventQuit:
dbg.running = false
return errors.Errorf(terminal.UserInterrupt)
return curated.Errorf(terminal.UserInterrupt)
case gui.EventKeyboard:
var handled bool

View file

@ -19,10 +19,10 @@ import (
"fmt"
"io"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/debugger/script"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/disassembly"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/hardware/cpu/instructions"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/supercharger"
@ -199,13 +199,13 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, videoCycle bool) error {
// following block interprets the error carefully and proceeds
// appropriately
if err != nil {
if !errors.IsAny(err) {
if !curated.IsAny(err) {
// if the error originated from outside of gopher2600 then
// it is probably serious or unexpected
switch err {
case io.EOF:
// treat EOF events the same as UserInterrupt events
err = errors.Errorf(terminal.UserInterrupt)
// treat EOF errors the same as terminal.UserAbort
err = curated.Errorf(terminal.UserAbort)
default:
// the error is probably serious. exit input loop with err
return err
@ -213,29 +213,28 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, videoCycle bool) error {
}
// we now know the we have an project specific error
switch errors.Head(err) {
// user interrupts are triggered by the user (in a terminal
// environment, usually by pressing ctrl-c)
case terminal.UserInterrupt:
if curated.Is(err, terminal.UserInterrupt) {
// user interrupts are triggered by the user (in a terminal
// environment, usually by pressing ctrl-c)
dbg.handleInterrupt(inputter, inputLen)
// like UserInterrupt but with no confirmation stage
case terminal.UserAbort:
} else if curated.Is(err, terminal.UserAbort) {
// like UserInterrupt but with no confirmation stage
dbg.running = false
// a script that is being run will usually end with a ScriptEnd
// error. in these instances we can say simply say so (using
// the error message) with a feedback style (not an error
// style)
case script.ScriptEnd:
} else if curated.Is(err, script.ScriptEnd) {
// a script that is being run will usually end with a ScriptEnd
// error. in these instances we can say simply say so (using
// the error message) with a feedback style (not an error
// style)
if !videoCycle {
dbg.printLine(terminal.StyleFeedback, err.Error())
}
return nil
// all other errors are passed upwards to the calling function
default:
} else {
// all other errors are passed upwards to the calling function
return err
}
}
@ -337,7 +336,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, videoCycle bool) error {
} else {
// exit input loop if error is a plain error
if !errors.IsAny(stepErr) {
if !curated.IsAny(stepErr) {
return stepErr
}
@ -417,7 +416,7 @@ func (dbg *Debugger) handleInterrupt(inputter terminal.Input, inputLen int) {
if err != nil {
// another UserInterrupt has occurred. we treat
// UserInterrupt as thought 'y' was pressed
if errors.Is(err, terminal.UserInterrupt) {
if curated.Is(err, terminal.UserInterrupt) {
confirm[0] = 'y'
} else {
dbg.printLine(terminal.StyleError, err.Error())

View file

@ -20,7 +20,7 @@ import (
"strconv"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
@ -150,7 +150,7 @@ const (
func (dbgmem memoryDebug) peek(address interface{}) (*addressInfo, error) {
ai := dbgmem.mapAddress(address, true)
if ai == nil {
return nil, errors.Errorf(peekError, address)
return nil, curated.Errorf(peekError, address)
}
area := dbgmem.mem.GetArea(ai.area)
@ -158,8 +158,8 @@ func (dbgmem memoryDebug) peek(address interface{}) (*addressInfo, error) {
var err error
ai.data, err = area.Peek(ai.mappedAddress)
if err != nil {
if errors.Is(err, bus.AddressError) {
return nil, errors.Errorf(peekError, address)
if curated.Is(err, bus.AddressError) {
return nil, curated.Errorf(peekError, address)
}
return nil, err
}
@ -174,15 +174,15 @@ func (dbgmem memoryDebug) peek(address interface{}) (*addressInfo, error) {
func (dbgmem memoryDebug) poke(address interface{}, data uint8) (*addressInfo, error) {
ai := dbgmem.mapAddress(address, false)
if ai == nil {
return nil, errors.Errorf(pokeError, address)
return nil, curated.Errorf(pokeError, address)
}
area := dbgmem.mem.GetArea(ai.area)
err := area.Poke(ai.mappedAddress, data)
if err != nil {
if errors.Is(err, bus.AddressError) {
return nil, errors.Errorf(pokeError, address)
if curated.Is(err, bus.AddressError) {
return nil, curated.Errorf(pokeError, address)
}
return nil, err
}

View file

@ -16,7 +16,7 @@
package debugger
import (
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/paths"
"github.com/jetsetilly/gopher2600/prefs"
)
@ -62,7 +62,7 @@ func newPreferences(dbg *Debugger) (*Preferences, error) {
err = p.dsk.Load(true)
if err != nil {
// ignore missing prefs file errors
if !errors.Is(err, prefs.NoPrefsFile) {
if !curated.Is(err, prefs.NoPrefsFile) {
return nil, err
}
}

View file

@ -21,7 +21,7 @@ import (
"strings"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
const commentLine = "#"
@ -45,7 +45,7 @@ func RescribeScript(scriptfile string) (*Rescribe, error) {
// open script and defer closing
f, err := os.Open(scriptfile)
if err != nil {
return nil, errors.Errorf("script: file not available: %v", err)
return nil, curated.Errorf("script: file not available: %v", err)
}
defer func() {
_ = f.Close()
@ -53,7 +53,7 @@ func RescribeScript(scriptfile string) (*Rescribe, error) {
buffer, err := ioutil.ReadAll(f)
if err != nil {
return nil, errors.Errorf("script: %v", err)
return nil, curated.Errorf("script: %v", err)
}
scr := &Rescribe{scriptFile: scriptfile}
@ -91,7 +91,7 @@ const (
// TermRead implements the terminal.Input interface
func (scr *Rescribe) TermRead(buffer []byte, _ terminal.Prompt, _ *terminal.ReadEvents) (int, error) {
if scr.lineCt > len(scr.lines)-1 {
return -1, errors.Errorf(ScriptEnd, scr.scriptFile)
return -1, curated.Errorf(ScriptEnd, scr.scriptFile)
}
n := len(scr.lines[scr.lineCt]) + 1

View file

@ -20,7 +20,7 @@ import (
"io"
"os"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Scribe can be used again after a start()/end() cycle. isWriting()
@ -46,7 +46,7 @@ func (scr Scribe) IsActive() bool {
// StartSession a new script
func (scr *Scribe) StartSession(scriptfile string) error {
if scr.IsActive() {
return errors.Errorf("script scribe already active")
return curated.Errorf("script scribe already active")
}
scr.scriptfile = scriptfile
@ -55,10 +55,10 @@ func (scr *Scribe) StartSession(scriptfile string) error {
if os.IsNotExist(err) {
scr.file, err = os.Create(scriptfile)
if err != nil {
return errors.Errorf("cannot create new script file")
return curated.Errorf("cannot create new script file")
}
} else {
return errors.Errorf("file already exists")
return curated.Errorf("file already exists")
}
return nil
@ -86,7 +86,7 @@ func (scr *Scribe) EndSession() error {
errb := scr.file.Close()
if errb != nil {
return errors.Errorf("script: scripe: %v", errb)
return curated.Errorf("script: scripe: %v", errb)
}
return err
@ -146,20 +146,20 @@ func (scr *Scribe) Commit() error {
if scr.inputLine != "" {
n, err := io.WriteString(scr.file, scr.inputLine)
if err != nil {
return errors.Errorf("script: scribe: %v", err)
return curated.Errorf("script: scribe: %v", err)
}
if n != len(scr.inputLine) {
return errors.Errorf("script: scribe output truncated")
return curated.Errorf("script: scribe output truncated")
}
}
if scr.outputLine != "" {
n, err := io.WriteString(scr.file, scr.outputLine)
if err != nil {
return errors.Errorf("script: scribe: %v", err)
return curated.Errorf("script: scribe: %v", err)
}
if n != len(scr.outputLine) {
return errors.Errorf("script: scribe output truncated")
return curated.Errorf("script: scribe output truncated")
}
}

View file

@ -20,7 +20,7 @@ import (
"strings"
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/television"
)
@ -215,14 +215,14 @@ func parseTarget(dbg *Debugger, tokens *commandline.Tokens) (*target, error) {
}
default:
return nil, errors.Errorf("invalid target: %s %s", keyword, subkey)
return nil, curated.Errorf("invalid target: %s %s", keyword, subkey)
}
} else {
return nil, errors.Errorf("invalid target: %s", keyword)
return nil, curated.Errorf("invalid target: %s", keyword)
}
default:
return nil, errors.Errorf("invalid target: %s", keyword)
return nil, curated.Errorf("invalid target: %s", keyword)
}
}

View file

@ -24,7 +24,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/debugger/terminal/colorterm/easyterm"
"github.com/jetsetilly/gopher2600/debugger/terminal/colorterm/easyterm/ansi"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// #cursor #keys #tab #completion
@ -103,7 +103,7 @@ func (ct *ColorTerminal) TermRead(input []byte, prompt terminal.Prompt, events *
// just return the UserInterrupt error and not worry about clearing
// the input line. see easyterm.KeyInterrupt for what happens
// normally.
return 0, errors.Errorf(terminal.UserInterrupt)
return 0, curated.Errorf(terminal.UserInterrupt)
case ev := <-events.GuiEvents:
// handle functions that are passsed on over interruptChannel. these can
@ -136,7 +136,7 @@ func (ct *ColorTerminal) TermRead(input []byte, prompt terminal.Prompt, events *
} else {
// there is no input so return UserInterrupt error
ct.EasyTerm.TermPrint("\r\n")
return 0, errors.Errorf(terminal.UserInterrupt)
return 0, curated.Errorf(terminal.UserInterrupt)
}
case easyterm.KeySuspend:

View file

@ -19,7 +19,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Commands is the root of the node tree
@ -69,7 +69,7 @@ func (cmds Commands) String() string {
func (cmds *Commands) AddHelp(helpCommand string, helps map[string]string) error {
// if help command exists then there is nothing to do
if _, ok := cmds.Index[helpCommand]; ok {
return errors.Errorf("%s: already defined", helpCommand)
return curated.Errorf("%s: already defined", helpCommand)
}
// keep reference to helps
@ -109,7 +109,7 @@ func (cmds *Commands) AddHelp(helpCommand string, helps map[string]string) error
// parse the constructed definition
p, d, err := parseDefinition(defn.String(), "")
if err != nil {
return errors.Errorf("%s: %s (char %d)", helpCommand, err, d)
return curated.Errorf("%s: %s (char %d)", helpCommand, err, d)
}
// add parsed definition to list of commands

View file

@ -32,7 +32,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// ParseCommandTemplate turns a string representation of a command template
@ -75,12 +75,12 @@ func ParseCommandTemplate(template []string) (*Commands, error) {
// parse the definition for this command
p, d, err := parseDefinition(defn, "")
if err != nil {
return nil, errors.Errorf("parser: %v", fmt.Errorf("%s [line %d, col %d]", err, t, d))
return nil, curated.Errorf("parser: %v", fmt.Errorf("%s [line %d, col %d]", err, t, d))
}
// check that parsing was complete
if d < len(defn)-1 {
return nil, errors.Errorf("parser: %v", fmt.Errorf("outstanding characters in definition [line %d, col %d]", t, d))
return nil, curated.Errorf("parser: %v", fmt.Errorf("outstanding characters in definition [line %d, col %d]", t, d))
}
// add to list of commands (order doesn't matter at this stage)

View file

@ -20,7 +20,7 @@ import (
"strconv"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Validate input string against command defintions
@ -52,10 +52,10 @@ func (cmds Commands) ValidateTokens(tokens *Tokens) error {
// special handling for help command
if cmd == cmds.helpCommand {
return errors.Errorf("no help for %s", strings.ToUpper(arg))
return curated.Errorf("no help for %s", strings.ToUpper(arg))
}
return errors.Errorf("unrecognised argument (%s) for %s", arg, cmd)
return curated.Errorf("unrecognised argument (%s) for %s", arg, cmd)
}
return nil
@ -76,7 +76,7 @@ func (n *node) validate(tokens *Tokens, speculative bool) error {
if !ok {
// we treat arguments in the root-group as though they are required
if n.typ == nodeRequired || n.typ == nodeRoot {
return errors.Errorf("%s required", n.nodeVerbose())
return curated.Errorf("%s required", n.nodeVerbose())
}
return nil
}
@ -213,7 +213,7 @@ func (n *node) validate(tokens *Tokens, speculative bool) error {
}
if !match {
err := errors.Errorf("unrecognised argument (%s)", tok)
err := curated.Errorf("unrecognised argument (%s)", tok)
// there's still no match but the speculative flag means we were half
// expecting it. return error without further consideration

View file

@ -23,7 +23,7 @@ import (
"os"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// PlainTerminal is the default, most basic terminal interface. It keeps the
@ -94,7 +94,7 @@ func (pt PlainTerminal) TermRead(input []byte, prompt terminal.Prompt, events *t
// error to the debugging loop
select {
case <-events.IntEvents:
return 0, errors.Errorf(terminal.UserInterrupt)
return 0, curated.Errorf(terminal.UserInterrupt)
default:
}

View file

@ -20,7 +20,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory"
)
@ -59,7 +59,7 @@ func (trc *traces) clear() {
// drop a specific tracer by a position in the list
func (trc *traces) drop(num int) error {
if len(trc.traces)-1 < num {
return errors.Errorf("trace #%d is not defined", num)
return curated.Errorf("trace #%d is not defined", num)
}
h := trc.traces[:num]
@ -132,7 +132,7 @@ func (trc *traces) parseCommand(tokens *commandline.Tokens) error {
if ai == nil {
ai = trc.dbg.dbgmem.mapAddress(a, false)
if ai == nil {
return errors.Errorf("invalid trace address: %s", a)
return curated.Errorf("invalid trace address: %s", a)
}
}
@ -141,7 +141,7 @@ func (trc *traces) parseCommand(tokens *commandline.Tokens) error {
// check to see if trace already exists
for _, t := range trc.traces {
if t.ai.address == nt.ai.address {
return errors.Errorf("already being traced (%s)", t)
return curated.Errorf("already being traced (%s)", t)
}
}

View file

@ -25,7 +25,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
type traps struct {
@ -57,7 +57,7 @@ func (tr *traps) clear() {
// drop the numbered trap from the list
func (tr *traps) drop(num int) error {
if len(tr.traps)-1 < num {
return errors.Errorf("trap #%d is not defined", num)
return curated.Errorf("trap #%d is not defined", num)
}
h := tr.traps[:num]

View file

@ -22,7 +22,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/debugger/terminal/commandline"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory"
)
@ -78,7 +78,7 @@ func (wtc *watches) clear() {
// drop a specific watcher by a position in the list
func (wtc *watches) drop(num int) error {
if len(wtc.watches)-1 < num {
return errors.Errorf("watch #%d is not defined", num)
return curated.Errorf("watch #%d is not defined", num)
}
h := wtc.watches[:num]
@ -216,7 +216,7 @@ func (wtc *watches) parseCommand(tokens *commandline.Tokens) error {
// mapping of the address was unsucessful
if ai == nil {
return errors.Errorf("invalid watch address: %s", a)
return curated.Errorf("invalid watch address: %s", a)
}
// get value if possible
@ -226,7 +226,7 @@ func (wtc *watches) parseCommand(tokens *commandline.Tokens) error {
if useVal {
val, err = strconv.ParseUint(v, 0, 8)
if err != nil {
return errors.Errorf("invalid watch value (%s)", a)
return curated.Errorf("invalid watch value (%s)", a)
}
}
@ -252,7 +252,7 @@ func (wtc *watches) parseCommand(tokens *commandline.Tokens) error {
w.ai.read == nw.ai.read &&
w.matchValue == nw.matchValue && w.value == nw.value {
return errors.Errorf("already being watched (%s)", w)
return curated.Errorf("already being watched (%s)", w)
}
}

View file

@ -19,7 +19,7 @@ import (
"crypto/sha1"
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/television"
)
@ -89,7 +89,7 @@ func (dig *Audio) flushAudio() error {
dig.digest = sha1.Sum(dig.buffer)
n := copy(dig.buffer, dig.digest[:])
if n != len(dig.digest) {
return errors.Errorf("digest: audio: %v", fmt.Sprintf("digest error while flushing audio stream"))
return curated.Errorf("digest: audio: %v", fmt.Sprintf("digest error while flushing audio stream"))
}
dig.bufferCt = audioBufferStart
return nil

View file

@ -19,7 +19,7 @@ import (
"crypto/sha1"
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/television"
)
@ -99,7 +99,7 @@ func (dig *Video) NewFrame(frameNum int, _ bool) error {
// to the head of the video data
n := copy(dig.pixels, dig.digest[:])
if n != len(dig.digest) {
return errors.Errorf("digest: video: %v", fmt.Sprintf("digest error during new frame"))
return curated.Errorf("digest: video: %v", fmt.Sprintf("digest error during new frame"))
}
dig.digest = sha1.Sum(dig.pixels)
dig.frameNum = frameNum

View file

@ -16,7 +16,7 @@
package disassembly
import (
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/cpu"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
@ -261,7 +261,7 @@ func (dsm *Disassembly) decode(mc *cpu.CPU, mem *disasmMemory) error {
mc.PC.Load(address)
err := mc.ExecuteInstruction(nil)
unimplementedInstruction := errors.Is(err, cpu.UnimplementedInstruction)
unimplementedInstruction := curated.Is(err, cpu.UnimplementedInstruction)
// filter out the predictable errors
if err != nil && !unimplementedInstruction {
@ -297,12 +297,12 @@ func (dsm *Disassembly) decode(mc *cpu.CPU, mem *disasmMemory) error {
// sanity checks
if bankCt != dsm.cart.NumBanks() {
return errors.Errorf("disassembly: number of banks in disassembly is different to NumBanks()")
return curated.Errorf("disassembly: number of banks in disassembly is different to NumBanks()")
}
for b := range dsm.disasm {
for _, a := range dsm.disasm[b] {
if a == nil {
return errors.Errorf("disassembly: not every address has been decoded")
return curated.Errorf("disassembly: not every address has been decoded")
}
}
}

View file

@ -19,7 +19,7 @@ import (
"sync"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/cpu"
"github.com/jetsetilly/gopher2600/hardware/cpu/execution"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge"
@ -71,8 +71,8 @@ func NewDisassembly() (*Disassembly, error) {
dsm.Prefs, err = newPreferences(dsm)
if err != nil {
if !errors.Is(err, prefs.NoPrefsFile) {
return nil, errors.Errorf("disassembly: %v", err)
if !curated.Is(err, prefs.NoPrefsFile) {
return nil, curated.Errorf("disassembly: %v", err)
}
}
@ -96,12 +96,12 @@ func FromCartridge(cartload cartridgeloader.Loader) (*Disassembly, error) {
err = cart.Attach(cartload)
if err != nil {
return nil, errors.Errorf("disassembly: %v", err)
return nil, curated.Errorf("disassembly: %v", err)
}
err = dsm.FromMemory(cart, symtable)
if err != nil {
return nil, errors.Errorf("disassembly: %v", err)
return nil, curated.Errorf("disassembly: %v", err)
}
return dsm, nil
@ -165,7 +165,7 @@ func (dsm *Disassembly) fromMemory(startAddress ...uint16) error {
// create a new NoFlowControl CPU to help disassemble memory
mc, err := cpu.NewCPU(mem)
if err != nil {
return errors.Errorf("disassembly: %v", err)
return curated.Errorf("disassembly: %v", err)
}
mc.NoFlowControl = true
@ -178,7 +178,7 @@ func (dsm *Disassembly) fromMemory(startAddress ...uint16) error {
// disassemble cartridge binary
err = dsm.disassemble(mc, mem, startAddress...)
if err != nil {
return errors.Errorf("disassembly: %v", err)
return curated.Errorf("disassembly: %v", err)
}
return nil
@ -229,7 +229,7 @@ func (dsm *Disassembly) UpdateEntry(bank banks.Details, result execution.Result,
var err error
dsm.disasm[bank.Number][idx], err = dsm.formatResult(bank, result, EntryLevelExecuted)
if err != nil {
return nil, errors.Errorf("disassembly: %v", err)
return nil, curated.Errorf("disassembly: %v", err)
}
} else if e.Level < EntryLevelExecuted || e.UpdateActualOnExecute {

View file

@ -16,7 +16,7 @@
package disassembly
import (
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// IterateCart faciliates traversal over all the banks in a cartridge.
@ -95,7 +95,7 @@ func (dsm *Disassembly) NewBankIteration(minLevel EntryLevel, bank int) (*Iterat
// banks than the current cartridge at the exact moment an illegal bank is
// being drawn by the sdlimgui disassembly window.
if bank >= len(dsm.disasm) {
return nil, 0, errors.Errorf("no bank %d in disasm", bank)
return nil, 0, curated.Errorf("no bank %d in disasm", bank)
}
bitr := &IterateBank{
@ -108,7 +108,7 @@ func (dsm *Disassembly) NewBankIteration(minLevel EntryLevel, bank int) (*Iterat
count := 0
for _, a := range dsm.disasm[bank] {
if a == nil {
return nil, 0, errors.Errorf("disassembly not complete")
return nil, 0, curated.Errorf("disassembly not complete")
}
if a.Level >= minLevel {

View file

@ -19,7 +19,7 @@ import (
"fmt"
"io"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// WriteAttr controls what is printed by the Write*() functions
@ -44,7 +44,7 @@ func (dsm *Disassembly) Write(output io.Writer, attr WriteAttr) error {
// WriteBank writes the disassembly of the selected bank to io.Writer
func (dsm *Disassembly) WriteBank(output io.Writer, attr WriteAttr, bank int) error {
if bank < 0 || bank > len(dsm.disasm)-1 {
return errors.Errorf("disassembly: no such bank (%d)", bank)
return curated.Errorf("disassembly: no such bank (%d)", bank)
}
output.Write([]byte(fmt.Sprintf("--- bank %d ---\n", bank)))

View file

@ -1,67 +0,0 @@
// 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 errors is a helper package for the plain Go language error type. We
// think of these errors as curated errors. External to this package, curated
// errors are referenced as plain errors (ie. they implement the error
// interface).
//
// Internally, errors are thought of as being composed of parts, as described
// by The Go Programming Language (Donovan, Kernighan): "When the error is
// ultimately handled by the program's main function, it should provide a clear
// causal chain from the root of the problem to the overal failure".
//
// The Error() function implementation for curated errors ensures that this
// chain is normalised. Specifically, that the chain does not contain duplicate
// adjacent parts. The practical advantage of this is that it alleviates the
// problem of when and how to wrap errors. For example:
//
// func main() {
// err := A()
// if err != nil {
// fmt.Println(err)
// }
// }
//
// func A() error {
// err := B()
// if err != nil {
// return errors.Errorf("debugger error: %v", err)
// }
// return nil
// }
//
// func B() error {
// err := C()
// if err != nil {
// return errors.Errorf("debugger error: %v", err)
// }
// return nil
// }
//
// func C() error {
// return errors.Errorf("not yet implemented")
// }
//
// This will result in the main() function printing an error message. Using the
// curated Error() function, the message will be:
//
// debugger error: not yet implemented
//
// and not:
//
// debugger error: debugger error: not yet implemented
//
package errors

View file

@ -18,7 +18,7 @@ package sdldebug
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/veandco/go-sdl2/sdl"
@ -117,7 +117,7 @@ func (scr *SdlDebug) serviceFeatureRequests(request featureRequest) {
// gui doesn't need to know when the cartridge is being changed
default:
err = errors.Errorf(gui.UnsupportedGuiFeature, request.request)
err = curated.Errorf(gui.UnsupportedGuiFeature, request.request)
}
scr.featureErr <- err

View file

@ -18,7 +18,7 @@ package sdldebug
import (
"io"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/reflection"
"github.com/jetsetilly/gopher2600/television"
@ -115,7 +115,7 @@ func NewSdlDebug(tv television.Television, scale float32) (*SdlDebug, error) {
// set up sdl
err = sdl.Init(sdl.INIT_EVERYTHING)
if err != nil {
return nil, errors.Errorf("sdldebug: %v", err)
return nil, curated.Errorf("sdldebug: %v", err)
}
setupService()
@ -126,14 +126,14 @@ func NewSdlDebug(tv television.Television, scale float32) (*SdlDebug, error) {
0, 0,
uint32(sdl.WINDOW_HIDDEN))
if err != nil {
return nil, errors.Errorf("sdldebug: %v", err)
return nil, curated.Errorf("sdldebug: %v", err)
}
// sdl renderer. we set the scaling amount in the setWindow function later
// once we know what the tv specification is
scr.renderer, err = sdl.CreateRenderer(scr.window, -1, uint32(sdl.RENDERER_ACCELERATED))
if err != nil {
return nil, errors.Errorf("sdldebug: %v", err)
return nil, curated.Errorf("sdldebug: %v", err)
}
// register ourselves as a television.Renderer
@ -143,13 +143,13 @@ func NewSdlDebug(tv television.Television, scale float32) (*SdlDebug, error) {
spec, _ := scr.GetSpec()
err = scr.resize(spec.ScanlineTop, spec.ScanlinesVisible)
if err != nil {
return nil, errors.Errorf("sdldebug: %v", err)
return nil, curated.Errorf("sdldebug: %v", err)
}
// set window scaling to default value
err = scr.setWindow(scale)
if err != nil {
return nil, errors.Errorf("sdldebug: %v", err)
return nil, curated.Errorf("sdldebug: %v", err)
}
// note that we've elected not to show the window on startup
@ -260,12 +260,12 @@ func (scr *SdlDebug) resize(topScanline, numScanlines int) error {
scr.textures, err = newTextures(scr.renderer, television.HorizClksScanline, spec.ScanlinesTotal)
if err != nil {
return errors.Errorf("sdldebug: %v", err)
return curated.Errorf("sdldebug: %v", err)
}
scr.overlay, err = newOverlay(scr.renderer, television.HorizClksScanline, spec.ScanlinesTotal)
if err != nil {
return errors.Errorf("sdldebug: %v", err)
return curated.Errorf("sdldebug: %v", err)
}
// setWindow dimensions. see commentary for Resize() function in

View file

@ -17,7 +17,7 @@ package sdlimgui
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/paths"
"github.com/jetsetilly/gopher2600/prefs"
)
@ -91,7 +91,7 @@ func (img *SdlImgui) initPrefs(group prefGroup) error {
err = img.prefs.Load(true)
if err != nil {
// ignore missing prefs file errors
if !errors.Is(err, prefs.NoPrefsFile) {
if !curated.Is(err, prefs.NoPrefsFile) {
return err
}
}

View file

@ -17,7 +17,7 @@ package sdlimgui
import (
"github.com/jetsetilly/gopher2600/debugger"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/hardware"
)
@ -110,12 +110,12 @@ func (img *SdlImgui) serviceFeatureRequests(request featureRequest) {
img.plusROMFirstInstallation = request.args[0].(*gui.PlusROMFirstInstallation)
default:
err = errors.Errorf(gui.UnsupportedGuiFeature, request.request)
err = curated.Errorf(gui.UnsupportedGuiFeature, request.request)
}
if err == nil {
img.featureErr <- nil
} else {
img.featureErr <- errors.Errorf("sdlimgui: %v", err)
img.featureErr <- curated.Errorf("sdlimgui: %v", err)
}
}

View file

@ -19,7 +19,7 @@ import (
"io"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/gui/sdlaudio"
"github.com/jetsetilly/gopher2600/gui/sdlimgui/lazyvalues"
@ -115,17 +115,17 @@ func NewSdlImgui(tv television.Television, playmode bool) (*SdlImgui, error) {
img.plt, err = newPlatform(img)
if err != nil {
return nil, errors.Errorf("sdlimgui: %v", err)
return nil, curated.Errorf("sdlimgui: %v", err)
}
img.glsl, err = newGlsl(img.io, img)
if err != nil {
return nil, errors.Errorf("sdlimgui: %v", err)
return nil, curated.Errorf("sdlimgui: %v", err)
}
iniPath, err := paths.ResourcePath("", imguiIniFile)
if err != nil {
return nil, errors.Errorf("sdlimgui: %v", err)
return nil, curated.Errorf("sdlimgui: %v", err)
}
img.io.SetIniFilename(iniPath)
@ -138,7 +138,7 @@ func NewSdlImgui(tv television.Television, playmode bool) (*SdlImgui, error) {
img.wm, err = newWindowManager(img)
if err != nil {
return nil, errors.Errorf("sdlimgui: %v", err)
return nil, curated.Errorf("sdlimgui: %v", err)
}
// connect pixel renderer to television and texture renderer to pixel renderer
@ -150,7 +150,7 @@ func NewSdlImgui(tv television.Television, playmode bool) (*SdlImgui, error) {
// implementation in winAudio which visualises the sound
img.audio, err = sdlaudio.NewAudio()
if err != nil {
return nil, errors.Errorf("sdlimgui: %v", err)
return nil, curated.Errorf("sdlimgui: %v", err)
}
tv.AddAudioMixer(img.audio)

View file

@ -19,7 +19,7 @@ import (
"strings"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
type term struct {
@ -134,7 +134,7 @@ func (trm *term) TermRead(buffer []byte, prompt terminal.Prompt, events *termina
ev()
case _ = <-events.IntEvents:
return 0, errors.Errorf(terminal.UserAbort)
return 0, curated.Errorf(terminal.UserAbort)
}
}
}

View file

@ -20,7 +20,7 @@ import (
"log"
"math/rand"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/cpu/execution"
"github.com/jetsetilly/gopher2600/hardware/cpu/instructions"
"github.com/jetsetilly/gopher2600/hardware/cpu/registers"
@ -146,14 +146,14 @@ func (mc CPU) HasReset() bool {
// LoadPCIndirect loads the contents of indirectAddress into the PC
func (mc *CPU) LoadPCIndirect(indirectAddress uint16) error {
if !mc.LastResult.Final && !mc.Interrupted {
return errors.Errorf("cpu: load PC indirect invalid mid-instruction")
return curated.Errorf("cpu: load PC indirect invalid mid-instruction")
}
// read 16 bit address from specified indirect address
lo, err := mc.mem.Read(indirectAddress)
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()
@ -161,7 +161,7 @@ func (mc *CPU) LoadPCIndirect(indirectAddress uint16) error {
hi, err := mc.mem.Read(indirectAddress + 1)
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()
@ -175,7 +175,7 @@ func (mc *CPU) LoadPCIndirect(indirectAddress uint16) error {
// LoadPC loads the contents of directAddress into the PC
func (mc *CPU) LoadPC(directAddress uint16) error {
if !mc.LastResult.Final && !mc.Interrupted {
return errors.Errorf("cpu: load PC invalid mid-instruction")
return curated.Errorf("cpu: load PC invalid mid-instruction")
}
mc.PC.Load(directAddress)
@ -191,7 +191,7 @@ func (mc *CPU) read8Bit(address uint16) (uint8, error) {
val, err := mc.mem.Read(address)
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return 0, err
}
mc.LastResult.Error = err.Error()
@ -214,7 +214,7 @@ func (mc *CPU) read8BitZeroPage(address uint8) (uint8, error) {
val, err := mc.mem.(bus.CPUBusZeroPage).ReadZeroPage(address)
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return 0, err
}
mc.LastResult.Error = err.Error()
@ -238,7 +238,7 @@ func (mc *CPU) write8Bit(address uint16, value uint8) error {
if err != nil {
// don't worry about unwritable addresses (unless strict addressing
// is on)
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()
@ -254,7 +254,7 @@ func (mc *CPU) write8Bit(address uint16, value uint8) error {
func (mc *CPU) read16Bit(address uint16) (uint16, error) {
lo, err := mc.mem.Read(address)
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return 0, err
}
mc.LastResult.Error = err.Error()
@ -268,7 +268,7 @@ func (mc *CPU) read16Bit(address uint16) (uint16, error) {
hi, err := mc.mem.Read(address + 1)
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return 0, err
}
mc.LastResult.Error = err.Error()
@ -296,7 +296,7 @@ func (mc *CPU) read8BitPC(f func(val uint8) error) error {
v, err := mc.mem.Read(mc.PC.Address())
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()
@ -339,7 +339,7 @@ func (mc *CPU) read8BitPC(f func(val uint8) error) error {
func (mc *CPU) read16BitPC() error {
lo, err := mc.mem.Read(mc.PC.Address())
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()
@ -364,7 +364,7 @@ func (mc *CPU) read16BitPC() error {
hi, err := mc.mem.Read(mc.PC.Address())
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()
@ -488,7 +488,7 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func() error) error {
// a previous call to ExecuteInstruction() has not yet completed. it is
// impossible to begin a new instruction
if !mc.LastResult.Final && !mc.Interrupted {
return errors.Errorf("cpu: starting a new instruction is invalid mid-instruction")
return curated.Errorf("cpu: starting a new instruction is invalid mid-instruction")
}
// reset Interrupted flag
@ -524,7 +524,7 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func() error) error {
// !!TODO: remove this once all opcodes are defined/implemented
if defn == nil {
return errors.Errorf(UnimplementedInstruction, val, mc.PC.Address()-1)
return curated.Errorf(UnimplementedInstruction, val, mc.PC.Address()-1)
}
mc.LastResult.Defn = defn
@ -687,7 +687,7 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func() error) error {
lo, err = mc.mem.Read(indirectAddress)
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()
@ -696,7 +696,7 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func() error) error {
// +1 cycle
err = mc.endCycle()
if err != nil {
if !errors.Is(err, bus.AddressError) {
if !curated.Is(err, bus.AddressError) {
return err
}
mc.LastResult.Error = err.Error()

View file

@ -19,7 +19,7 @@ import (
"fmt"
"testing"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/cpu"
rtest "github.com/jetsetilly/gopher2600/hardware/cpu/registers/test"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
@ -63,7 +63,7 @@ func (mem *mockMem) Clear() {
func (mem mockMem) Read(address uint16) (uint8, error) {
if address&0xff00 == 0xff00 {
return 0, errors.Errorf(bus.AddressError, address)
return 0, curated.Errorf(bus.AddressError, address)
}
return mem.internal[address], nil
}
@ -74,7 +74,7 @@ func (mem mockMem) ReadZeroPage(address uint8) (uint8, error) {
func (mem *mockMem) Write(address uint16, data uint8) error {
if address&0xff00 == 0xff00 {
return errors.Errorf(bus.AddressError, address)
return curated.Errorf(bus.AddressError, address)
}
mem.internal[address] = data
return nil

View file

@ -16,31 +16,31 @@
package execution
import (
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// IsValid checks whether the instance of Result contains information
// consistent with the instruction definition.
func (result Result) IsValid() error {
if !result.Final {
return errors.Errorf("cpu: execution not finalised (bad opcode?)")
return curated.Errorf("cpu: execution not finalised (bad opcode?)")
}
// is PageFault valid given content of Defn
if !result.Defn.PageSensitive && result.PageFault {
return errors.Errorf("cpu: unexpected page fault")
return curated.Errorf("cpu: unexpected page fault")
}
// byte count
if result.ByteCount != result.Defn.Bytes {
return errors.Errorf("cpu: unexpected number of bytes read during decode (%d instead of %d)", result.ByteCount, result.Defn.Bytes)
return curated.Errorf("cpu: unexpected number of bytes read during decode (%d instead of %d)", result.ByteCount, result.Defn.Bytes)
}
// if a bug has been triggered, don't perform the number of cycles check
if result.CPUBug == "" {
if result.Defn.IsBranch() {
if result.ActualCycles != result.Defn.Cycles && result.ActualCycles != result.Defn.Cycles+1 && result.ActualCycles != result.Defn.Cycles+2 {
return errors.Errorf("cpu: number of cycles wrong for opcode %#02x [%s] (%d instead of %d, %d or %d)",
return curated.Errorf("cpu: number of cycles wrong for opcode %#02x [%s] (%d instead of %d, %d or %d)",
result.Defn.OpCode,
result.Defn.Mnemonic,
result.ActualCycles,
@ -51,7 +51,7 @@ func (result Result) IsValid() error {
} else {
if result.Defn.PageSensitive {
if result.PageFault && result.ActualCycles != result.Defn.Cycles && result.ActualCycles != result.Defn.Cycles+1 {
return errors.Errorf("cpu: number of cycles wrong for opcode %#02x [%s] (%d instead of %d, %d)",
return curated.Errorf("cpu: number of cycles wrong for opcode %#02x [%s] (%d instead of %d, %d)",
result.Defn.OpCode,
result.Defn.Mnemonic,
result.ActualCycles,
@ -60,7 +60,7 @@ func (result Result) IsValid() error {
}
} else {
if result.ActualCycles != result.Defn.Cycles {
return errors.Errorf("cpu: number of cycles wrong for opcode %#02x [%s] (%d instead of %d)",
return curated.Errorf("cpu: number of cycles wrong for opcode %#02x [%s] (%d instead of %d)",
result.Defn.OpCode,
result.Defn.Mnemonic,
result.ActualCycles,

View file

@ -19,7 +19,7 @@ import (
"fmt"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/harmony"
@ -144,7 +144,7 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
if cartload.Mapping == "" || cartload.Mapping == "AUTO" {
err := cart.fingerprint(cartload)
if err != nil {
return errors.Errorf("cartridge: %v", err)
return curated.Errorf("cartridge: %v", err)
}
// in addition to the regular fingerprint we also check to see if this
@ -159,12 +159,12 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
// if the error is a NotAPlusROM error then log the false
// positive and return a success, keeping the main cartridge
// mapper intact
if errors.Is(err, plusrom.NotAPlusROM) {
if curated.Is(err, plusrom.NotAPlusROM) {
logger.Log("cartridge", err.Error())
return nil
}
return errors.Errorf("cartridge: %v", err)
return curated.Errorf("cartridge: %v", err)
}
// we've wrapped the main cartridge mapper inside the PlusROM
@ -234,13 +234,13 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
}
if err != nil {
return errors.Errorf("cartridge: %v", err)
return curated.Errorf("cartridge: %v", err)
}
if addSuperchip {
if superchip, ok := cart.mapper.(mapper.OptionalSuperchip); ok {
if !superchip.AddSuperchip() {
return errors.Errorf("cartridge: error adding superchip")
return curated.Errorf("cartridge: error adding superchip")
}
}
}

View file

@ -17,7 +17,7 @@ package cartridge
import (
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/harmony"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/supercharger"
@ -232,7 +232,7 @@ func (cart *Cartridge) fingerprint(cartload cartridgeloader.Loader) error {
}
case 65536:
return errors.Errorf("cartridge: 65536 bytes not yet supported")
return curated.Errorf("cartridge: 65536 bytes not yet supported")
case 131072:
cart.mapper, err = fingerprint128k(cartload.Data)(cartload.Data)
@ -241,7 +241,7 @@ func (cart *Cartridge) fingerprint(cartload cartridgeloader.Loader) error {
}
default:
return errors.Errorf("cartridge: unrecognised size (%d bytes)", len(cartload.Data))
return curated.Errorf("cartridge: unrecognised size (%d bytes)", len(cartload.Data))
}
// if cartridge mapper implements the optionalSuperChip interface then try

View file

@ -18,7 +18,7 @@ package harmony
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -76,7 +76,7 @@ func NewDPCplus(data []byte) (mapper.CartMapper, error) {
// size check
if bankLen <= 0 || bankLen%cart.bankSize != 0 {
return nil, errors.Errorf("cartridge", fmt.Errorf("%s: wrong number of bytes in cartridge data", cart.mappingID))
return nil, curated.Errorf("cartridge", fmt.Errorf("%s: wrong number of bytes in cartridge data", cart.mappingID))
}
// partition
@ -152,7 +152,7 @@ func (cart *dpcPlus) Read(addr uint16, passive bool) (uint8, error) {
}
if addr > 0x0027 {
return 0, errors.Errorf(bus.AddressError, addr)
return 0, curated.Errorf(bus.AddressError, addr)
}
switch addr {
@ -277,7 +277,7 @@ func (cart *dpcPlus) Write(addr uint16, data uint8, passive bool, poke bool) err
}
if addr < 0x0028 || addr > 0x007f {
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
switch addr {
@ -554,7 +554,7 @@ func (cart *dpcPlus) Write(addr uint16, data uint8, passive bool, poke bool) err
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// bankswitch on hotspot access
@ -591,7 +591,7 @@ func (cart dpcPlus) GetBank(addr uint16) banks.Details {
func (cart *dpcPlus) Patch(offset int, data uint8) error {
if offset >= cart.fileSize {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
if offset >= cart.freqOffset {

View file

@ -18,7 +18,7 @@ package harmony
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
)
@ -53,24 +53,24 @@ func (cart *dpcPlus) PutStatic(label string, addr uint16, data uint8) error {
switch label {
case "ARM":
if int(addr) >= len(cart.static.Arm) {
return errors.Errorf("harmony: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
return curated.Errorf("harmony: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
}
cart.static.Arm[addr] = data
case "Data":
if int(addr) >= len(cart.static.Data) {
return errors.Errorf("harmony: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
return curated.Errorf("harmony: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
}
cart.static.Data[addr] = data
case "Freq":
if int(addr) >= len(cart.static.Freq) {
return errors.Errorf("harmony: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
return curated.Errorf("harmony: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
}
cart.static.Freq[addr] = data
default:
return errors.Errorf("harmony: static: %v", fmt.Errorf("unknown static area (%s)", label))
return curated.Errorf("harmony: static: %v", fmt.Errorf("unknown static area (%s)", label))
}
return nil

View file

@ -19,7 +19,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -63,7 +63,7 @@ func new3e(data []byte) (mapper.CartMapper, error) {
const ramSize = 1024
if len(data)%cart.bankSize != 0 {
return nil, errors.Errorf("%s: wrong number bytes in the cartridge data", cart.mappingID)
return nil, curated.Errorf("%s: wrong number bytes in the cartridge data", cart.mappingID)
}
numBanks := len(data) / cart.bankSize
@ -159,7 +159,7 @@ func (cart *m3e) Write(addr uint16, data uint8, passive bool, poke bool) error {
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// NumBanks implements the mapper.CartMapper interface
@ -178,7 +178,7 @@ func (cart *m3e) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *m3e) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize

View file

@ -19,7 +19,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -65,7 +65,7 @@ func new3ePlus(data []byte) (mapper.CartMapper, error) {
const ramSize = 512
if len(data)%cart.bankSize != 0 {
return nil, errors.Errorf("%s: wrong number bytes in the cartridge file", cart.mappingID)
return nil, curated.Errorf("%s: wrong number bytes in the cartridge file", cart.mappingID)
}
numBanks := len(data) / cart.bankSize
@ -175,7 +175,7 @@ func (cart *m3ePlus) Write(addr uint16, data uint8, passive bool, poke bool) err
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// NumBanks implements the mapper.CartMapper interface
@ -205,7 +205,7 @@ func (cart *m3ePlus) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *m3ePlus) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize

View file

@ -18,7 +18,7 @@ package cartridge
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -146,7 +146,7 @@ func (cart *atari) Write(addr uint16, data uint8, passive bool, poke bool) error
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
func (cart *atari) addSuperchip() bool {
@ -181,7 +181,7 @@ func (cart *atari) addSuperchip() bool {
// Patch implements the mapper.CartMapper interface
func (cart *atari) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize
@ -257,7 +257,7 @@ func newAtari4k(data []byte) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, 1)
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
}
cart.banks[0] = make([]uint8, cart.bankSize)
@ -307,7 +307,7 @@ func newAtari2k(data []byte) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, 1)
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
}
cart.banks[0] = make([]uint8, cart.bankSize)
@ -355,7 +355,7 @@ func newAtari8k(data []uint8) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, cart.NumBanks())
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
}
for k := 0; k < cart.NumBanks(); k++ {
@ -431,7 +431,7 @@ func newAtari16k(data []byte) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, cart.NumBanks())
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
}
for k := 0; k < cart.NumBanks(); k++ {
@ -511,7 +511,7 @@ func newAtari32k(data []byte) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, cart.NumBanks())
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge file", cart.mappingID)
}
for k := 0; k < cart.NumBanks(); k++ {

View file

@ -18,7 +18,7 @@ package cartridge
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -49,7 +49,7 @@ func newCBS(data []byte) (mapper.CartMapper, error) {
}
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
}
cart.banks = make([][]uint8, cart.NumBanks())
@ -109,7 +109,7 @@ func (cart *cbs) Write(addr uint16, data uint8, passive bool, poke bool) error {
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// bankswitch on hotspot access
@ -145,7 +145,7 @@ func (cart cbs) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *cbs) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize

View file

@ -18,7 +18,7 @@ package cartridge
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -49,7 +49,7 @@ func newDF(data []byte) (mapper.CartMapper, error) {
}
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
}
cart.banks = make([][]uint8, cart.NumBanks())
@ -110,7 +110,7 @@ func (cart *df) Write(addr uint16, data uint8, passive bool, poke bool) error {
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// bankswitch on hotspot access
@ -207,7 +207,7 @@ func (cart df) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *df) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize

View file

@ -20,7 +20,7 @@ import (
"strconv"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -136,7 +136,7 @@ func newDPC(data []byte) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, cart.NumBanks())
if len(data) < cart.bankSize*cart.NumBanks()+staticSize {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
}
for k := 0; k < cart.NumBanks(); k++ {
@ -341,7 +341,7 @@ func (cart *dpc) Write(addr uint16, data uint8, passive bool, poke bool) error {
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// bank switch on hotspot access
@ -373,7 +373,7 @@ func (cart dpc) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *dpc) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks)+len(cart.static.Gfx) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
staticStart := cart.NumBanks() * cart.bankSize
@ -495,11 +495,11 @@ func (cart dpc) GetStatic() []bus.CartStatic {
func (cart *dpc) PutStatic(label string, addr uint16, data uint8) error {
if label == "Gfx" {
if int(addr) >= len(cart.static.Gfx) {
return errors.Errorf("dpc: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
return curated.Errorf("dpc: static: %v", fmt.Errorf("address too high (%#04x) for %s area", addr, label))
}
cart.static.Gfx[addr] = data
} else {
return errors.Errorf("dpc: static: %v", fmt.Errorf("unknown static area (%s)", label))
return curated.Errorf("dpc: static: %v", fmt.Errorf("unknown static area (%s)", label))
}
return nil

View file

@ -16,7 +16,7 @@
package cartridge
import (
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
)
@ -53,12 +53,12 @@ func (cart *ejected) Initialise() {
// Read implements the cartMapper interface
func (cart *ejected) Read(_ uint16, _ bool) (uint8, error) {
return 0, errors.Errorf(Ejected)
return 0, curated.Errorf(Ejected)
}
// Write implements the cartMapper interface
func (cart *ejected) Write(_ uint16, _ uint8, _, _ bool) error {
return errors.Errorf(Ejected)
return curated.Errorf(Ejected)
}
// NumBanks implements the cartMapper interface
@ -73,7 +73,7 @@ func (cart ejected) GetBank(_ uint16) banks.Details {
// Patch implements the cartMapper interface
func (cart *ejected) Patch(_ int, _ uint8) error {
return errors.Errorf(Ejected)
return curated.Errorf(Ejected)
}
// Listen implements the cartMapper interface

View file

@ -19,7 +19,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -107,7 +107,7 @@ func newMnetwork(data []byte) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, cart.NumBanks())
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
}
for k := 0; k < cart.NumBanks(); k++ {
@ -185,7 +185,7 @@ func (cart *mnetwork) Read(addr uint16, passive bool) (uint8, error) {
data = cart.banks[cart.NumBanks()-1][addr&0x07ff]
}
} else {
return 0, errors.Errorf(bus.AddressError, addr)
return 0, curated.Errorf(bus.AddressError, addr)
}
return data, nil
@ -212,7 +212,7 @@ func (cart *mnetwork) Write(addr uint16, data uint8, passive bool, poke bool) er
return nil
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// bankswitch on hotspot access
@ -298,7 +298,7 @@ func (cart *mnetwork) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *mnetwork) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize

View file

@ -18,7 +18,7 @@ package cartridge
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -64,7 +64,7 @@ func newParkerBros(data []byte) (mapper.CartMapper, error) {
cart.banks = make([][]uint8, cart.NumBanks())
if len(data) != cart.bankSize*cart.NumBanks() {
return nil, errors.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
return nil, curated.Errorf("%s: wrong number of bytes in the cartridge data", cart.mappingID)
}
for k := 0; k < cart.NumBanks(); k++ {
@ -129,7 +129,7 @@ func (cart *parkerBros) Write(addr uint16, data uint8, passive bool, poke bool)
cart.hotspot(addr, passive)
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// bankswitch on hotspot access
@ -225,7 +225,7 @@ func (cart parkerBros) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *parkerBros) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize

View file

@ -18,7 +18,7 @@ package cartridge
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -67,7 +67,7 @@ func newTigervision(data []byte) (mapper.CartMapper, error) {
}
if len(data)%cart.bankSize != 0 {
return nil, errors.Errorf("%s: wrong number bytes in the cartridge data", cart.mappingID)
return nil, curated.Errorf("%s: wrong number bytes in the cartridge data", cart.mappingID)
}
numBanks := len(data) / cart.bankSize
@ -121,7 +121,7 @@ func (cart *tigervision) Write(addr uint16, data uint8, _ bool, poke bool) error
cart.banks[cart.segment[1]][addr&0x07ff] = data
}
}
return errors.Errorf(bus.AddressError, addr)
return curated.Errorf(bus.AddressError, addr)
}
// NumBanks implements the mapper.CartMapper interface
@ -140,7 +140,7 @@ func (cart *tigervision) GetBank(addr uint16) banks.Details {
// Patch implements the mapper.CartMapper interface
func (cart *tigervision) Patch(offset int, data uint8) error {
if offset >= cart.bankSize*len(cart.banks) {
return errors.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
return curated.Errorf("%s: patch offset too high (%v)", cart.ID(), offset)
}
bank := int(offset) / cart.bankSize

View file

@ -19,7 +19,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -43,7 +43,7 @@ func NewPlusROM(child mapper.CartMapper, onLoaded func(cart mapper.CartMapper) e
cart.Prefs, err = newPreferences()
if err != nil {
return nil, errors.Errorf("plusrom: %s", err)
return nil, curated.Errorf("plusrom: %s", err)
}
cart.net = newNetwork(cart.Prefs)
@ -71,7 +71,7 @@ func NewPlusROM(child mapper.CartMapper, onLoaded func(cart mapper.CartMapper) e
b := int((a & 0xf000) >> 12)
if b == 0 || b > cart.NumBanks() {
return nil, errors.Errorf(NotAPlusROM, "invlid NMI vector")
return nil, curated.Errorf(NotAPlusROM, "invlid NMI vector")
}
// normalise indirect address so it's suitable for indexing bank data
@ -115,7 +115,7 @@ func NewPlusROM(child mapper.CartMapper, onLoaded func(cart mapper.CartMapper) e
// fail if host or path is not valid
hostValid, pathValid := cart.SetAddrInfo(host.String(), path.String())
if !hostValid || !pathValid {
return nil, errors.Errorf(NotAPlusROM, "invalid host/path")
return nil, curated.Errorf(NotAPlusROM, "invalid host/path")
}
// log success
@ -125,7 +125,7 @@ func NewPlusROM(child mapper.CartMapper, onLoaded func(cart mapper.CartMapper) e
if onLoaded != nil {
err := onLoaded(cart)
if err != nil {
return nil, errors.Errorf("plusrom %s:", err)
return nil, curated.Errorf("plusrom %s:", err)
}
}

View file

@ -21,7 +21,7 @@ import (
"strings"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/banks"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -75,7 +75,7 @@ func NewSupercharger(cartload cartridgeloader.Loader) (mapper.CartMapper, error)
cart.tape, err = NewFastLoad(cart, cartload)
}
if err != nil {
return nil, errors.Errorf("supercharger: %v", err)
return nil, curated.Errorf("supercharger: %v", err)
}
// allocate ram
@ -86,7 +86,7 @@ func NewSupercharger(cartload cartridgeloader.Loader) (mapper.CartMapper, error)
// load bios and activate
cart.bios, err = loadBIOS(path.Dir(cartload.Filename))
if err != nil {
return nil, errors.Errorf("supercharger: %v", err)
return nil, curated.Errorf("supercharger: %v", err)
}
// prepare onLoaded function
@ -179,14 +179,14 @@ func (cart *Supercharger) Read(fullAddr uint16, passive bool) (uint8, error) {
if fullAddr == 0xfa1a {
err := cart.onLoaded(cart)
if err != nil {
return 0, errors.Errorf("supercharger: %v", err)
return 0, curated.Errorf("supercharger: %v", err)
}
}
return cart.bios[addr&0x07ff], nil
}
return 0, errors.Errorf("supercharger: ROM is powered off")
return 0, curated.Errorf("supercharger: ROM is powered off")
}
if !passive && cart.registers.Delay == 1 {
@ -266,7 +266,7 @@ func (cart Supercharger) GetBank(addr uint16) banks.Details {
// Patch implements the cartMapper interface
func (cart *Supercharger) Patch(_ int, _ uint8) error {
return errors.Errorf("%s: not patchable")
return curated.Errorf("%s: not patchable")
}
// Listen implements the cartMapper interface

View file

@ -18,7 +18,7 @@ package memory
import (
"math/rand"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge"
@ -223,7 +223,7 @@ func (mem VCSMemory) Peek(address uint16) (uint8, error) {
if area, ok := mem.GetArea(ar).(bus.DebugBus); ok {
return area.Peek(ma)
}
return 0, errors.Errorf(bus.AddressError, address)
return 0, curated.Errorf(bus.AddressError, address)
}
// Poke implements the DebugBus interface
@ -232,5 +232,5 @@ func (mem VCSMemory) Poke(address uint16, data uint8) error {
if area, ok := mem.GetArea(ar).(bus.DebugBus); ok {
return area.(bus.DebugBus).Poke(ma, data)
}
return errors.Errorf(bus.AddressError, address)
return curated.Errorf(bus.AddressError, address)
}

View file

@ -18,7 +18,7 @@ package vcs
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
)
@ -55,7 +55,7 @@ type ChipMemory struct {
func (area ChipMemory) Peek(address uint16) (uint8, error) {
sym := addresses.Read[address]
if sym == "" {
return 0, errors.Errorf(bus.AddressError, address)
return 0, curated.Errorf(bus.AddressError, address)
}
return area.memory[address^area.origin], nil
}
@ -95,7 +95,7 @@ func (area *ChipMemory) Read(address uint16) (uint8, error) {
// do not allow reads from memory that do not have symbol name
if _, ok := addresses.ReadSymbols[address]; !ok {
return 0, errors.Errorf(bus.AddressError, address)
return 0, curated.Errorf(bus.AddressError, address)
}
return area.memory[address^area.origin], nil
@ -111,7 +111,7 @@ func (area *ChipMemory) Write(address uint16, data uint8) error {
// do not allow writes to memory that do not have symbol name
if _, ok := addresses.WriteSymbols[address]; !ok {
return errors.Errorf(bus.AddressError, address)
return curated.Errorf(bus.AddressError, address)
}
// signal the chips that their chip memory has been written to

View file

@ -16,7 +16,7 @@
package controllers
import (
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
)
@ -99,7 +99,7 @@ func (aut *Auto) HandleEvent(event ports.Event, data ports.EventData) error {
err := aut.controller.HandleEvent(event, data)
// if error was because of an unhandled event then return without error
if err != nil && errors.Is(err, UnhandledEvent) {
if err != nil && curated.Is(err, UnhandledEvent) {
return nil
}

View file

@ -18,7 +18,7 @@ package controllers
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
@ -69,7 +69,7 @@ func (key *Keyboard) Name() string {
func (key *Keyboard) HandleEvent(event ports.Event, data ports.EventData) error {
switch event {
default:
return errors.Errorf(UnhandledEvent, key.Name(), event)
return curated.Errorf(UnhandledEvent, key.Name(), event)
case ports.NoEvent:
@ -79,7 +79,7 @@ func (key *Keyboard) HandleEvent(event ports.Event, data ports.EventData) error
k != '4' && k != '5' && k != '6' &&
k != '7' && k != '8' && k != '9' &&
k != '*' && k != '0' && k != '#' {
return errors.Errorf("keyboard: unrecognised rune (%v)", k)
return curated.Errorf("keyboard: unrecognised rune (%v)", k)
}
// note key for use by readKeyboard()

View file

@ -18,7 +18,7 @@ package controllers
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
@ -94,7 +94,7 @@ func (pdl *Paddle) Name() string {
func (pdl *Paddle) HandleEvent(event ports.Event, data ports.EventData) error {
switch event {
default:
return errors.Errorf(UnhandledEvent, pdl.Name(), event)
return curated.Errorf(UnhandledEvent, pdl.Name(), event)
case ports.NoEvent:

View file

@ -18,7 +18,7 @@ package controllers
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
@ -82,7 +82,7 @@ func (stk *Stick) Name() string {
func (stk *Stick) HandleEvent(event ports.Event, data ports.EventData) error {
switch event {
default:
return errors.Errorf(UnhandledEvent, stk.Name(), event)
return curated.Errorf(UnhandledEvent, stk.Name(), event)
case ports.NoEvent:

View file

@ -18,7 +18,7 @@ package ports
import (
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
)
@ -165,7 +165,7 @@ func (pan *Panel) HandleEvent(event Event, value EventData) error {
pan.p1pro = !pan.p1pro
case PanelPowerOff:
return errors.Errorf(PowerOff)
return curated.Errorf(PowerOff)
}

View file

@ -19,7 +19,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/bus"
)
@ -271,7 +271,7 @@ func (p *Ports) HandleEvent(id PortID, ev Event, d EventData) error {
}
if err != nil {
return errors.Errorf("ports: %v", err)
return curated.Errorf("ports: %v", err)
}
// record event with the EventRecorder

View file

@ -18,7 +18,7 @@ package polycounter
import (
"fmt"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Polycounter counts from 0 to Limit. can be used to index a polycounter
@ -54,7 +54,7 @@ func New(numBits int) (*Polycounter, error) {
// sanity check that the table has looped correctly
if pcnt.table[len(pcnt.table)-1] != pcnt.table[0] {
return nil, errors.Errorf("polycounter: %v", fmt.Errorf("error creating %d bit polycounter", numBits))
return nil, curated.Errorf("polycounter: %v", fmt.Errorf("error creating %d bit polycounter", numBits))
}
// force the final value to be the invalid polycounter value. this is only
@ -104,5 +104,5 @@ func (pcnt *Polycounter) Match(pattern string) (int, error) {
return i, nil
}
}
return 0, errors.Errorf("polycounter: %v", fmt.Errorf("could not find pattern (%s) in %d bit lookup table", pattern, pcnt.numBits))
return 0, curated.Errorf("polycounter: %v", fmt.Errorf("could not find pattern (%s) in %d bit lookup table", pattern, pcnt.numBits))
}

View file

@ -16,7 +16,7 @@
package hiscore
import (
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/paths"
"github.com/jetsetilly/gopher2600/prefs"
)
@ -39,7 +39,7 @@ func newPreferences() (*Preferences, error) {
// save server using the prefs package
pth, err := paths.ResourcePath("", prefs.DefaultPrefsFile)
if err != nil {
return nil, errors.Errorf("hiscore: %v", err)
return nil, curated.Errorf("hiscore: %v", err)
}
p.dsk, err = prefs.NewDisk(pth)
@ -48,7 +48,7 @@ func newPreferences() (*Preferences, error) {
err = p.dsk.Load(true)
if err != nil {
return p, errors.Errorf("hiscore: %v", err)
return p, curated.Errorf("hiscore: %v", err)
}
return p, nil

View file

@ -23,7 +23,7 @@ import (
"net/http"
"time"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Session represents a gaming session with the hi-score server. A session is
@ -43,7 +43,7 @@ func NewSession() (*Session, error) {
sess.Prefs, err = newPreferences()
if err != nil {
return nil, errors.Errorf("hiscore: %v", err)
return nil, curated.Errorf("hiscore: %v", err)
}
return sess, nil
@ -55,7 +55,7 @@ func (sess *Session) StartSession(name string, hash string) error {
jsonValue, _ := json.Marshal(values)
statusCode, response, err := sess.post("/HiScore/rest/game/", jsonValue)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
switch statusCode {
@ -65,12 +65,12 @@ func (sess *Session) StartSession(name string, hash string) error {
// game is new and has been added to the database
default:
err = fmt.Errorf("register game: unexpected response from HiScore server [%d: %s]", statusCode, response)
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
err = json.Unmarshal(response, &sess.id)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
return nil
@ -83,7 +83,7 @@ func (sess *Session) EndSession(playTime time.Duration) error {
jsonValue, _ := json.Marshal(values)
statusCode, response, err := sess.post("/HiScore/rest/play/", jsonValue)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
switch statusCode {
@ -91,7 +91,7 @@ func (sess *Session) EndSession(playTime time.Duration) error {
// hiscore has been posted
default:
err = fmt.Errorf("register hiscore: unexpected response from HiScore server [%d: %s]", statusCode, response)
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
return nil

View file

@ -24,7 +24,7 @@ import (
"net/url"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// SetServer to use for hiscore storage
@ -32,7 +32,7 @@ func SetServer(input io.Reader, output io.Writer, server string) error {
// get reference to hiscore preferences
prefs, err := newPreferences()
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
// server has not been provided so prompt for it
@ -42,7 +42,7 @@ func SetServer(input io.Reader, output io.Writer, server string) error {
b = make([]byte, 255)
_, err := input.Read(b)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
server = string(b)
}
@ -53,13 +53,13 @@ func SetServer(input io.Reader, output io.Writer, server string) error {
// parse entered url
url, err := url.Parse(server)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
// error on path, but allow a single slash (by removing it)
if url.Path != "" {
if url.Path != "/" {
return errors.Errorf("hiscore: %v", "do not include path in server setting")
return curated.Errorf("hiscore: %v", "do not include path in server setting")
}
}
@ -82,12 +82,12 @@ func Login(input io.Reader, output io.Writer, username string) error {
// get reference to hiscore preferences
prefs, err := newPreferences()
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
// we can't login unless highscore server has been specified
if prefs.Server.Get() == "" {
return errors.Errorf("hiscore: %v", "no highscore server available")
return curated.Errorf("hiscore: %v", "no highscore server available")
}
// prompt for username if it has not been supplied
@ -97,7 +97,7 @@ func Login(input io.Reader, output io.Writer, username string) error {
b = make([]byte, 255)
_, err := input.Read(b)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
username = strings.Split(string(b), "\n")[0]
}
@ -111,7 +111,7 @@ func Login(input io.Reader, output io.Writer, username string) error {
b = make([]byte, 255)
_, err = input.Read(b)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
password := strings.Split(string(b), "\n")[0]
@ -120,20 +120,20 @@ func Login(input io.Reader, output io.Writer, username string) error {
data := url.Values{"username": {username}, "password": {password}}
resp, err := cl.PostForm(fmt.Sprintf("%s/rest-auth/login/", prefs.Server), data)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
// get response
response, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
// unmarshal response
var key map[string]string
err = json.Unmarshal(response, &key)
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
// update authentication key and save changes
@ -146,7 +146,7 @@ func Logoff() error {
// get reference to hiscore preferences
prefs, err := newPreferences()
if err != nil {
return errors.Errorf("hiscore: %v", err)
return curated.Errorf("hiscore: %v", err)
}
// blank authentication key and save changes

View file

@ -20,7 +20,7 @@ import (
"io"
"github.com/jetsetilly/gopher2600/disassembly"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/cpu/instructions"
"github.com/jetsetilly/gopher2600/hardware/memory/addresses"
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
@ -38,7 +38,7 @@ func Lint(dsm *disassembly.Disassembly, output io.Writer) error {
// create a new iteration for the bank
bitr, _, err := dsm.NewBankIteration(disassembly.EntryLevelBlessed, b)
if err != nil {
return errors.Errorf("linter: %v", err)
return curated.Errorf("linter: %v", err)
}
// iterate through disassembled bank

View file

@ -24,7 +24,7 @@ import (
"strings"
"unicode"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge"
"github.com/jetsetilly/gopher2600/paths"
)
@ -42,16 +42,16 @@ func CartridgeMemory(mem *cartridge.Cartridge, patchFile string) (bool, error) {
p, err := paths.ResourcePath(patchPath, patchFile)
if err != nil {
return false, errors.Errorf("patch: %v", err)
return false, curated.Errorf("patch: %v", err)
}
f, err := os.Open(p)
if err != nil {
switch err.(type) {
case *os.PathError:
return false, errors.Errorf("patch: %v", fmt.Sprintf("patch file not found (%s)", p))
return false, curated.Errorf("patch: %v", fmt.Sprintf("patch file not found (%s)", p))
}
return false, errors.Errorf("patch: %v", err)
return false, curated.Errorf("patch: %v", err)
}
defer f.Close()
@ -118,7 +118,7 @@ func CartridgeMemory(mem *cartridge.Cartridge, patchFile string) (bool, error) {
// patch memory
err = mem.Patch(int(offset), uint8(v))
if err != nil {
return patched, errors.Errorf("patch: %v", err)
return patched, curated.Errorf("patch: %v", err)
}
patched = true

View file

@ -23,7 +23,7 @@ import (
"time"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/setup"
"github.com/jetsetilly/gopher2600/television"
@ -36,25 +36,25 @@ func Check(output io.Writer, profile bool, tv television.Television, runTime str
// create vcs using the tv created above
vcs, err := hardware.NewVCS(tv)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
// attach cartridge to te vcs
err = setup.AttachCartridge(vcs, cartload)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
// parse supplied duration
duration, err := time.ParseDuration(runTime)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
// get starting frame number (should be 0)
startFrame, err := tv.GetState(television.ReqFramenum)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
// run for specified period of time
@ -99,7 +99,7 @@ func Check(output io.Writer, profile bool, tv television.Television, runTime str
}
})
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
return nil
}
@ -112,13 +112,13 @@ func Check(output io.Writer, profile bool, tv television.Television, runTime str
err = runner()
}
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
// get ending frame number
endFrame, err := vcs.TV.GetState(television.ReqFramenum)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
// calculate performance

View file

@ -20,7 +20,7 @@ import (
"runtime"
"runtime/pprof"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// ProfileCPU runs supplied function "through" the pprof CPU profiler
@ -28,11 +28,11 @@ func ProfileCPU(outFile string, run func() error) error {
// write cpu profile
f, err := os.Create(outFile)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
err = pprof.StartCPUProfile(f)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
defer pprof.StopCPUProfile()
@ -43,12 +43,12 @@ func ProfileCPU(outFile string, run func() error) error {
func ProfileMem(outFile string) error {
f, err := os.Create(outFile)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
runtime.GC()
err = pprof.WriteHeapProfile(f)
if err != nil {
return errors.Errorf("performance; %v", err)
return curated.Errorf("performance; %v", err)
}
f.Close()

View file

@ -22,7 +22,7 @@ import (
"time"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -59,7 +59,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
// do not allow this if a new recording has been requested
if newRecording {
return errors.Errorf("playmode: %v", "cannot make a new recording using a playback file")
return curated.Errorf("playmode: %v", "cannot make a new recording using a playback file")
}
recording = cartload.Filename
@ -89,7 +89,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
vcs, err := hardware.NewVCS(tv)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
scr.ReqFeature(gui.ReqAddVCS, vcs)
@ -97,7 +97,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
if useSavekey {
err = vcs.RIOT.Ports.AttachPlayer(ports.Player1ID, savekey.NewSaveKey)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
}
@ -116,7 +116,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
// prepare new recording
rec, err := recorder.NewRecorder(recording, vcs)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
// making sure we end the recording gracefully when we leave the function
@ -128,7 +128,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
// setup because we want to catch any setup events in the recording
err = setup.AttachCartridge(vcs, cartload)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
} else if recording != "" {
@ -145,7 +145,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
// will be applied that way
err = vcs.AttachCartridge(plb.CartLoad)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
// the following will fail if the recording was made with different tv
@ -154,7 +154,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
// another television implementation.
err = plb.AttachToVCS(vcs)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
} else {
@ -163,7 +163,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
err = setup.AttachCartridge(vcs, cartload)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
// apply patch if requested. note that this will be in addition to any
@ -171,7 +171,7 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
if patchFile != "" {
_, err := patch.CartridgeMemory(vcs.Mem.Cart, patchFile)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
}
}
@ -186,20 +186,20 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
// connect gui
err = scr.ReqFeature(gui.ReqSetEventChan, pl.guiChan)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
// request television visibility
err = scr.ReqFeature(gui.ReqSetVisibility, true)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
// if a waitForEmulationStart channel has been created then halt the
// goroutine until we recieve a non-error signal
if waitForEmulationStart != nil {
if err := <-waitForEmulationStart; err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
}
@ -217,12 +217,12 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
if hiscoreServer {
sess, err = hiscore.NewSession()
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
err = sess.StartSession(cartload.ShortName(), vcs.Mem.Cart.Hash)
if err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
}
@ -238,17 +238,17 @@ func Play(tv television.Television, scr gui.GUI, newRecording bool, cartload car
// send to high score server
if hiscoreServer {
if err := sess.EndSession(playTime); err != nil {
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
}
if err != nil {
if errors.Has(err, ports.PowerOff) {
if curated.Has(err, ports.PowerOff) {
// PowerOff is okay and is to be expected. swallow the error
// message and return as normal
return nil
}
return errors.Errorf("playmode: %v", err)
return curated.Errorf("playmode: %v", err)
}
return nil

View file

@ -23,7 +23,7 @@ import (
"strings"
"unicode"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// DefaultPrefsFile is the default filename of the global preferences file
@ -83,7 +83,7 @@ func NewDisk(path string) (*Disk, error) {
func (dsk *Disk) Add(key string, p pref) error {
for _, r := range key {
if !(r == '.' || unicode.IsLetter(r)) {
return errors.Errorf("prefs: %v", fmt.Errorf("illegal character [%c] in key string [%s]", r, key))
return curated.Errorf("prefs: %v", fmt.Errorf("illegal character [%c] in key string [%s]", r, key))
}
}
@ -104,7 +104,7 @@ func (dsk *Disk) Save() error {
// load *all* existing entries to temporary entryMap
_, err := load(dsk.path, &entries, false)
if err != nil {
if !errors.Is(err, NoPrefsFile) {
if !curated.Is(err, NoPrefsFile) {
return err
}
}
@ -118,7 +118,7 @@ func (dsk *Disk) Save() error {
// create a new prefs file
f, err := os.Create(dsk.path)
if err != nil {
return errors.Errorf("prefs: %v", err)
return curated.Errorf("prefs: %v", err)
}
defer f.Close()
@ -128,19 +128,19 @@ func (dsk *Disk) Save() error {
// add warning label
n, err = fmt.Fprintf(f, fmt.Sprintf("%s\n", WarningBoilerPlate))
if err != nil {
return errors.Errorf("prefs: %v", err)
return curated.Errorf("prefs: %v", err)
}
if n != len(WarningBoilerPlate)+1 {
return errors.Errorf("prefs: %v", "incorrect number of characters writtent to file")
return curated.Errorf("prefs: %v", "incorrect number of characters writtent to file")
}
// write entries (combination of old and live entries) to disk
n, err = fmt.Fprintf(f, entries.String())
if err != nil {
return errors.Errorf("prefs: %v", err)
return curated.Errorf("prefs: %v", err)
}
if n != len(entries.String()) {
return errors.Errorf("prefs: %v", "incorrect number of characters writtent to file")
return curated.Errorf("prefs: %v", "incorrect number of characters writtent to file")
}
return nil
@ -182,9 +182,9 @@ func load(path string, entries *entryMap, limit bool) (int, error) {
if err != nil {
switch err.(type) {
case *os.PathError:
return numLoaded, errors.Errorf(NoPrefsFile, path)
return numLoaded, curated.Errorf(NoPrefsFile, path)
}
return numLoaded, errors.Errorf("prefs: %v", err)
return numLoaded, curated.Errorf("prefs: %v", err)
}
defer f.Close()
@ -194,7 +194,7 @@ func load(path string, entries *entryMap, limit bool) (int, error) {
// check validity of file by checking the first line
scanner.Scan()
if scanner.Text() != WarningBoilerPlate {
return 0, errors.Errorf("prefs: %v", fmt.Errorf("not a valid prefs file (%s)", path))
return 0, curated.Errorf("prefs: %v", fmt.Errorf("not a valid prefs file (%s)", path))
}
// key and value strings
@ -218,7 +218,7 @@ func load(path string, entries *entryMap, limit bool) (int, error) {
if p, ok := (*entries)[k]; ok {
err = p.Set(v)
if err != nil {
return numLoaded, errors.Errorf("prefs: %v", err)
return numLoaded, curated.Errorf("prefs: %v", err)
}
numLoaded++
} else if !limit {
@ -226,7 +226,7 @@ func load(path string, entries *entryMap, limit bool) (int, error) {
var dummy String
err = dummy.Set(v)
if err != nil {
return numLoaded, errors.Errorf("prefs: %v", err)
return numLoaded, curated.Errorf("prefs: %v", err)
}
(*entries)[k] = &dummy
}

View file

@ -20,7 +20,7 @@ import (
"strconv"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Value represents the actual Go preference value
@ -59,7 +59,7 @@ func (p *Bool) Set(v Value) error {
p.value = false
}
default:
return errors.Errorf("prefs: %v", fmt.Errorf("cannot convert %T to prefs.Bool", v))
return curated.Errorf("prefs: %v", fmt.Errorf("cannot convert %T to prefs.Bool", v))
}
if p.callback != nil {
@ -149,10 +149,10 @@ func (p *Int) Set(v Value) error {
var err error
p.value, err = strconv.Atoi(v)
if err != nil {
return errors.Errorf("prefs: %v", fmt.Errorf("cannot convert %T to prefs.Int", v))
return curated.Errorf("prefs: %v", fmt.Errorf("cannot convert %T to prefs.Int", v))
}
default:
return errors.Errorf("prefs: %v", fmt.Errorf("cannot convert %T to prefs.Int", v))
return curated.Errorf("prefs: %v", fmt.Errorf("cannot convert %T to prefs.Int", v))
}
if p.callback != nil {

View file

@ -21,7 +21,7 @@ import (
"os"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
const (
@ -74,12 +74,12 @@ func (rec *Recorder) writeHeader() error {
if err != nil {
rec.output.Close()
return errors.Errorf("recorder: %v", err)
return curated.Errorf("recorder: %v", err)
}
if n != len(line) {
rec.output.Close()
return errors.Errorf("recorder: output truncated")
return curated.Errorf("recorder: output truncated")
}
return nil
@ -87,7 +87,7 @@ func (rec *Recorder) writeHeader() error {
func (plb *Playback) readHeader(lines []string) error {
if lines[lineMagicString] != magicString {
return errors.Errorf("playback: not a valid transcript (%s)", plb.transcript)
return curated.Errorf("playback: not a valid transcript (%s)", plb.transcript)
}
// read header

View file

@ -23,8 +23,8 @@ import (
"strings"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/digest"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
"github.com/jetsetilly/gopher2600/television"
@ -74,7 +74,7 @@ func (plb Playback) String() string {
func (plb Playback) EndFrame() (bool, error) {
currFrame, err := plb.digest.GetState(television.ReqFramenum)
if err != nil {
return false, errors.Errorf("playback: %v", err)
return false, curated.Errorf("playback: %v", err)
}
if currFrame > plb.endFrame {
@ -96,15 +96,15 @@ func NewPlayback(transcript string) (*Playback, error) {
tf, err := os.Open(transcript)
if err != nil {
return nil, errors.Errorf("playback: %v", err)
return nil, curated.Errorf("playback: %v", err)
}
buffer, err := ioutil.ReadAll(tf)
if err != nil {
return nil, errors.Errorf("playback: %v", err)
return nil, curated.Errorf("playback: %v", err)
}
err = tf.Close()
if err != nil {
return nil, errors.Errorf("playback: %v", err)
return nil, curated.Errorf("playback: %v", err)
}
// convert file contents to an array of lines
@ -123,13 +123,13 @@ func NewPlayback(transcript string) (*Playback, error) {
// ignore lines that don't have enough fields
if len(toks) != numFields {
return nil, errors.Errorf("playback: expected %d fields at line %d", numFields, i+1)
return nil, curated.Errorf("playback: expected %d fields at line %d", numFields, i+1)
}
// add a new playbackSequence for the id if it doesn't exist
n, err := strconv.Atoi(toks[fieldID])
if err != nil {
return nil, errors.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldID+1], fieldSep)))
return nil, curated.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldID+1], fieldSep)))
}
// create a new entry and convert tokens accordingly
@ -168,7 +168,7 @@ func NewPlayback(transcript string) (*Playback, error) {
entry.frame, err = strconv.Atoi(toks[fieldFrame])
if err != nil {
return nil, errors.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldFrame+1], fieldSep)))
return nil, curated.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldFrame+1], fieldSep)))
}
// assuming that frames are listed in order in the file. update
@ -177,12 +177,12 @@ func NewPlayback(transcript string) (*Playback, error) {
entry.scanline, err = strconv.Atoi(toks[fieldScanline])
if err != nil {
return nil, errors.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldScanline+1], fieldSep)))
return nil, curated.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldScanline+1], fieldSep)))
}
entry.horizpos, err = strconv.Atoi(toks[fieldHorizPos])
if err != nil {
return nil, errors.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldHorizPos+1], fieldSep)))
return nil, curated.Errorf("playback: %s line %d, col %d", err, i+1, len(strings.Join(toks[:fieldHorizPos+1], fieldSep)))
}
entry.hash = toks[fieldHash]
@ -226,7 +226,7 @@ func parseEventData(value string) ports.EventData {
func (plb *Playback) AttachToVCS(vcs *hardware.VCS) error {
// check we're working with correct information
if vcs == nil || vcs.TV == nil {
return errors.Errorf("playback: no playback hardware available")
return curated.Errorf("playback: no playback hardware available")
}
plb.vcs = vcs
@ -234,14 +234,14 @@ func (plb *Playback) AttachToVCS(vcs *hardware.VCS) error {
// specification. some combinations may work but there's no compelling
// reason to figure that out just now.
if plb.vcs.TV.SpecIDOnCreation() != plb.TVSpec {
return errors.Errorf("playback: recording was made with the %s TV spec. trying to playback with a TV spec of %s.", plb.TVSpec, vcs.TV.SpecIDOnCreation())
return curated.Errorf("playback: recording was made with the %s TV spec. trying to playback with a TV spec of %s.", plb.TVSpec, vcs.TV.SpecIDOnCreation())
}
var err error
plb.digest, err = digest.NewVideo(plb.vcs.TV)
if err != nil {
return errors.Errorf("playback: %v", err)
return curated.Errorf("playback: %v", err)
}
// attach playback to all vcs ports
@ -266,15 +266,15 @@ func (plb *Playback) GetPlayback() (ports.PortID, ports.Event, ports.EventData,
// get current state of the television
frame, err := plb.vcs.TV.GetState(television.ReqFramenum)
if err != nil {
return ports.NoPortID, ports.NoEvent, nil, errors.Errorf("playback: %v", err)
return ports.NoPortID, ports.NoEvent, nil, curated.Errorf("playback: %v", err)
}
scanline, err := plb.vcs.TV.GetState(television.ReqScanline)
if err != nil {
return ports.NoPortID, ports.NoEvent, nil, errors.Errorf("playback: %v", err)
return ports.NoPortID, ports.NoEvent, nil, curated.Errorf("playback: %v", err)
}
horizpos, err := plb.vcs.TV.GetState(television.ReqHorizPos)
if err != nil {
return ports.NoPortID, ports.NoEvent, nil, errors.Errorf("playback: %v", err)
return ports.NoPortID, ports.NoEvent, nil, curated.Errorf("playback: %v", err)
}
// compare current state with the recording
@ -282,7 +282,7 @@ func (plb *Playback) GetPlayback() (ports.PortID, ports.Event, ports.EventData,
if frame == entry.frame && scanline == entry.scanline && horizpos == entry.horizpos {
plb.seqCt++
if entry.hash != plb.digest.Hash() {
return ports.NoPortID, ports.NoEvent, nil, errors.Errorf(PlaybackHashError, entry.line)
return ports.NoPortID, ports.NoEvent, nil, curated.Errorf(PlaybackHashError, entry.line)
}
return entry.portID, entry.event, entry.value, nil
}

View file

@ -21,7 +21,7 @@ import (
"os"
"github.com/jetsetilly/gopher2600/digest"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
"github.com/jetsetilly/gopher2600/television"
@ -48,7 +48,7 @@ func NewRecorder(transcript string, vcs *hardware.VCS) (*Recorder, error) {
// check we're working with correct information
if vcs == nil || vcs.TV == nil {
return nil, errors.Errorf("recorder: hardware is not suitable for recording")
return nil, curated.Errorf("recorder: hardware is not suitable for recording")
}
rec := &Recorder{vcs: vcs}
@ -59,7 +59,7 @@ func NewRecorder(transcript string, vcs *hardware.VCS) (*Recorder, error) {
// video digester for playback verification
rec.digest, err = digest.NewVideo(vcs.TV)
if err != nil {
return nil, errors.Errorf("recorder: %v", err)
return nil, curated.Errorf("recorder: %v", err)
}
// open file
@ -67,10 +67,10 @@ func NewRecorder(transcript string, vcs *hardware.VCS) (*Recorder, error) {
if os.IsNotExist(err) {
rec.output, err = os.Create(transcript)
if err != nil {
return nil, errors.Errorf("recorder: can't create file")
return nil, curated.Errorf("recorder: can't create file")
}
} else {
return nil, errors.Errorf("recorder: file already exists")
return nil, curated.Errorf("recorder: file already exists")
}
// delay writing of header until the first call to transcribe. we're
@ -90,12 +90,12 @@ func (rec *Recorder) End() error {
// write the power off event to the transcript
err := rec.RecordEvent(ports.PanelID, ports.PanelPowerOff, nil)
if err != nil {
return errors.Errorf("recorder: %v", err)
return curated.Errorf("recorder: %v", err)
}
err = rec.output.Close()
if err != nil {
return errors.Errorf("recorder: %v", err)
return curated.Errorf("recorder: %v", err)
}
return nil
@ -109,7 +109,7 @@ func (rec *Recorder) RecordEvent(id ports.PortID, event ports.Event, value ports
if !rec.headerWritten {
err = rec.writeHeader()
if err != nil {
return errors.Errorf("recorder: %v", err)
return curated.Errorf("recorder: %v", err)
}
rec.headerWritten = true
}
@ -121,11 +121,11 @@ func (rec *Recorder) RecordEvent(id ports.PortID, event ports.Event, value ports
// sanity checks
if rec.output == nil {
return errors.Errorf("recorder: recording file is not open")
return curated.Errorf("recorder: recording file is not open")
}
if rec.vcs == nil || rec.vcs.TV == nil {
return errors.Errorf("recorder: hardware is not suitable for recording")
return curated.Errorf("recorder: hardware is not suitable for recording")
}
// create line and write to file
@ -159,10 +159,10 @@ func (rec *Recorder) RecordEvent(id ports.PortID, event ports.Event, value ports
n, err := io.WriteString(rec.output, line)
if err != nil {
return errors.Errorf("recorder: %v", err)
return curated.Errorf("recorder: %v", err)
}
if n != len(line) {
return errors.Errorf("recorder: output truncated")
return curated.Errorf("recorder: output truncated")
}
return nil

View file

@ -25,7 +25,7 @@ import (
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/logger"
"github.com/jetsetilly/gopher2600/setup"
@ -60,10 +60,10 @@ func deserialiseLogEntry(fields database.SerialisedEntry) (database.Entry, error
// basic sanity check
if len(fields) > numLogFields {
return nil, errors.Errorf("log: too many fields")
return nil, curated.Errorf("log: too many fields")
}
if len(fields) < numLogFields {
return nil, errors.Errorf("log: too few fields")
return nil, curated.Errorf("log: too few fields")
}
// string fields need no conversion
@ -79,7 +79,7 @@ func deserialiseLogEntry(fields database.SerialisedEntry) (database.Entry, error
reg.NumFrames, err = strconv.Atoi(fields[logFieldNumFrames])
if err != nil {
msg := fmt.Sprintf("invalid numFrames field [%s]", fields[logFieldNumFrames])
return nil, errors.Errorf("log: %v", msg)
return nil, curated.Errorf("log: %v", msg)
}
return reg, nil
@ -126,19 +126,19 @@ func (reg *LogRegression) regress(newRegression bool, output io.Writer, msg stri
// create headless television. we'll use this to initialise the digester
tv, err := television.NewTelevision(reg.TVtype)
if err != nil {
return false, "", errors.Errorf("log: %v", err)
return false, "", curated.Errorf("log: %v", err)
}
defer tv.End()
// create VCS and attach cartridge
vcs, err := hardware.NewVCS(tv)
if err != nil {
return false, "", errors.Errorf("log: %v", err)
return false, "", curated.Errorf("log: %v", err)
}
err = setup.AttachCartridge(vcs, reg.CartLoad)
if err != nil {
return false, "", errors.Errorf("log: %v", err)
return false, "", curated.Errorf("log: %v", err)
}
// display ticker for progress meter
@ -163,7 +163,7 @@ func (reg *LogRegression) regress(newRegression bool, output io.Writer, msg stri
})
if err != nil {
return false, "", errors.Errorf("log: %v", err)
return false, "", curated.Errorf("log: %v", err)
}
// get hash of log output

View file

@ -25,7 +25,7 @@ import (
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/digest"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
"github.com/jetsetilly/gopher2600/recorder"
@ -54,10 +54,10 @@ func deserialisePlaybackEntry(fields database.SerialisedEntry) (database.Entry,
// basic sanity check
if len(fields) > numPlaybackFields {
return nil, errors.Errorf("playback: too many fields")
return nil, curated.Errorf("playback: too many fields")
}
if len(fields) < numPlaybackFields {
return nil, errors.Errorf("playback: too few fields")
return nil, curated.Errorf("playback: too few fields")
}
// string fields need no conversion
@ -106,28 +106,28 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
plb, err := recorder.NewPlayback(reg.Script)
if err != nil {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
tv, err := television.NewTelevision(plb.TVSpec)
if err != nil {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
defer tv.End()
_, err = digest.NewVideo(tv)
if err != nil {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
vcs, err := hardware.NewVCS(tv)
if err != nil {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
err = plb.AttachToVCS(vcs)
if err != nil {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
// not using setup.AttachCartridge. if the playback was recorded with setup
@ -135,7 +135,7 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
// will be applied that way
err = vcs.AttachCartridge(plb.CartLoad)
if err != nil {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
// prepare ticker for progress meter
@ -146,10 +146,10 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
err = vcs.Run(func() (bool, error) {
hasEnded, err := plb.EndFrame()
if err != nil {
return false, errors.Errorf("playback: %v", err)
return false, curated.Errorf("playback: %v", err)
}
if hasEnded {
return false, errors.Errorf("playback: ended unexpectedly")
return false, curated.Errorf("playback: ended unexpectedly")
}
// display progress meter every 1 second
@ -162,9 +162,9 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
})
if err != nil {
if errors.Has(err, ports.PowerOff) {
if curated.Has(err, ports.PowerOff) {
// PowerOff is okay and is to be expected
} else if errors.Has(err, recorder.PlaybackHashError) {
} else if curated.Has(err, recorder.PlaybackHashError) {
// PlaybackHashError means that a screen digest somewhere in the
// playback script did not work. filter error and return false to
// indicate failure
@ -174,7 +174,7 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
failm := fmt.Sprintf("%v: at fr=%d, sl=%d, hp=%d", err, fr, sl, hp)
return false, failm, nil
} else {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
}
@ -184,7 +184,7 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
// create a unique filename
newScript, err := uniqueFilename("playback", plb.CartLoad)
if err != nil {
return false, "", errors.Errorf("playback: %v", err)
return false, "", curated.Errorf("playback: %v", err)
}
// check that the filename is unique
@ -192,28 +192,28 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
// no need to bother with returned error. nf tells us everything we
// need
if nf != nil {
return false, "", errors.Errorf("playback: script already exists (%s)", newScript)
return false, "", curated.Errorf("playback: script already exists (%s)", newScript)
}
nf.Close()
// create new file
nf, err = os.Create(newScript)
if err != nil {
return false, "", errors.Errorf("playback: while copying playback script: %v", err)
return false, "", curated.Errorf("playback: while copying playback script: %v", err)
}
defer nf.Close()
// open old file
of, err := os.Open(reg.Script)
if err != nil {
return false, "", errors.Errorf("playback: while copying playback script: %v", err)
return false, "", curated.Errorf("playback: while copying playback script: %v", err)
}
defer of.Close()
// copy old file to new file
_, err = io.Copy(nf, of)
if err != nil {
return false, "", errors.Errorf("playback: while copying playback script: %v", err)
return false, "", curated.Errorf("playback: while copying playback script: %v", err)
}
// update script name in regression type

View file

@ -24,7 +24,7 @@ import (
"time"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/paths"
)
@ -69,7 +69,7 @@ func initDBSession(db *database.Session) error {
// make sure regression script directory exists
// if err := os.MkdirAll(paths.ResourcePath(regressionScripts), 0755); err != nil {
// msg := fmt.Sprintf("regression script directory: %s", err)
// return errors.Errorf("regression: %v", msg)
// return curated.Errorf("regression: %v", msg)
// }
return nil
@ -83,7 +83,7 @@ func RegressList(output io.Writer) error {
dbPth, err := paths.ResourcePath("", regressionDBFile)
if err != nil {
return errors.Errorf("regression: %v", err)
return curated.Errorf("regression: %v", err)
}
db, err := database.StartSession(dbPth, database.ActivityReading, initDBSession)
@ -108,7 +108,7 @@ func RegressAdd(output io.Writer, reg Regressor) error {
dbPth, err := paths.ResourcePath("", regressionDBFile)
if err != nil {
return errors.Errorf("regression: %v", err)
return curated.Errorf("regression: %v", err)
}
db, err := database.StartSession(dbPth, database.ActivityCreating, initDBSession)
@ -137,12 +137,12 @@ func RegressDelete(output io.Writer, confirmation io.Reader, key string) error {
v, err := strconv.Atoi(key)
if err != nil {
return errors.Errorf("regression: invalid key [%s]", key)
return curated.Errorf("regression: invalid key [%s]", key)
}
dbPth, err := paths.ResourcePath("", regressionDBFile)
if err != nil {
return errors.Errorf("regression: %v", err)
return curated.Errorf("regression: %v", err)
}
db, err := database.StartSession(dbPth, database.ActivityModifying, initDBSession)
@ -153,7 +153,7 @@ func RegressDelete(output io.Writer, confirmation io.Reader, key string) error {
ent, err := db.SelectKeys(nil, v)
if err != nil {
return errors.Errorf("regression: %v", err)
return curated.Errorf("regression: %v", err)
}
output.Write([]byte(fmt.Sprintf("%s\ndelete? (y/n): ", ent)))
@ -191,12 +191,12 @@ func RegressRunTests(output io.Writer, verbose bool, failOnError bool, filterKey
dbPth, err := paths.ResourcePath("", regressionDBFile)
if err != nil {
return errors.Errorf("regression: %v", err)
return curated.Errorf("regression: %v", err)
}
db, err := database.StartSession(dbPth, database.ActivityReading, initDBSession)
if err != nil {
return errors.Errorf("regression: %v", err)
return curated.Errorf("regression: %v", err)
}
defer db.EndSession(false)
@ -205,7 +205,7 @@ func RegressRunTests(output io.Writer, verbose bool, failOnError bool, filterKey
for k := range filterKeys {
v, err := strconv.Atoi(filterKeys[k])
if err != nil {
return errors.Errorf("regression: invalid key [%s]", filterKeys[k])
return curated.Errorf("regression: invalid key [%s]", filterKeys[k])
}
keysV = append(keysV, v)
}

View file

@ -27,7 +27,7 @@ import (
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/digest"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/setup"
"github.com/jetsetilly/gopher2600/television"
@ -67,10 +67,10 @@ func deserialiseVideoEntry(fields database.SerialisedEntry) (database.Entry, err
// basic sanity check
if len(fields) > numVideoFields {
return nil, errors.Errorf("video: too many fields")
return nil, curated.Errorf("video: too many fields")
}
if len(fields) < numVideoFields {
return nil, errors.Errorf("video: too few fields")
return nil, curated.Errorf("video: too few fields")
}
// string fields need no conversion
@ -85,7 +85,7 @@ func deserialiseVideoEntry(fields database.SerialisedEntry) (database.Entry, err
// convert number of frames field
reg.NumFrames, err = strconv.Atoi(fields[videoFieldNumFrames])
if err != nil {
return nil, errors.Errorf("video: invalid numFrames field [%s]", fields[videoFieldNumFrames])
return nil, curated.Errorf("video: invalid numFrames field [%s]", fields[videoFieldNumFrames])
}
// handle state field
@ -101,7 +101,7 @@ func deserialiseVideoEntry(fields database.SerialisedEntry) (database.Entry, err
case "CPU":
reg.State = StateCPU
default:
return nil, errors.Errorf("video: invalid state field [%s]", fields[videoFieldState])
return nil, curated.Errorf("video: invalid state field [%s]", fields[videoFieldState])
}
// state options
@ -110,7 +110,7 @@ func deserialiseVideoEntry(fields database.SerialisedEntry) (database.Entry, err
// and state file field
if fields[videoFieldStateFile] != "" {
if reg.State == StateNone {
return nil, errors.Errorf("video: invalid state file field: no state type specifier")
return nil, curated.Errorf("video: invalid state file field: no state type specifier")
}
reg.stateFile = fields[videoFieldStateFile]
}
@ -182,24 +182,24 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
// create headless television. we'll use this to initialise the digester
tv, err := television.NewTelevision(reg.TVtype)
if err != nil {
return false, "", errors.Errorf("video: %v", err)
return false, "", curated.Errorf("video: %v", err)
}
defer tv.End()
dig, err := digest.NewVideo(tv)
if err != nil {
return false, "", errors.Errorf("video: %v", err)
return false, "", curated.Errorf("video: %v", err)
}
// create VCS and attach cartridge
vcs, err := hardware.NewVCS(tv)
if err != nil {
return false, "", errors.Errorf("video: %v", err)
return false, "", curated.Errorf("video: %v", err)
}
err = setup.AttachCartridge(vcs, reg.CartLoad)
if err != nil {
return false, "", errors.Errorf("video: %v", err)
return false, "", curated.Errorf("video: %v", err)
}
// list of state information. we'll either save this in the event of
@ -250,7 +250,7 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
})
if err != nil {
return false, "", errors.Errorf("video: %v", err)
return false, "", curated.Errorf("video: %v", err)
}
if newRegression {
@ -260,7 +260,7 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
// create a unique filename
reg.stateFile, err = uniqueFilename("state", reg.CartLoad)
if err != nil {
return false, "", errors.Errorf("video: %v", err)
return false, "", curated.Errorf("video: %v", err)
}
// check that the filename is unique
@ -269,21 +269,21 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
// no need to bother with returned error. nf tells us everything we
// need
if nf != nil {
return false, "", errors.Errorf("video: state recording file already exists (%s)", reg.stateFile)
return false, "", curated.Errorf("video: state recording file already exists (%s)", reg.stateFile)
}
nf.Close()
// create new file
nf, err = os.Create(reg.stateFile)
if err != nil {
return false, "", errors.Errorf("video: error creating state recording file: %v", err)
return false, "", curated.Errorf("video: error creating state recording file: %v", err)
}
defer nf.Close()
for i := range state {
s := fmt.Sprintf("%s\n", state[i])
if n, err := nf.WriteString(s); err != nil || len(s) != n {
return false, "", errors.Errorf("video: error writing state recording file: %v", err)
return false, "", curated.Errorf("video: error writing state recording file: %v", err)
}
}
}
@ -298,7 +298,7 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
if reg.State != StateNone {
nf, err := os.Open(reg.stateFile)
if err != nil {
return false, "", errors.Errorf("video: old state recording file not present (%s)", reg.stateFile)
return false, "", curated.Errorf("video: old state recording file not present (%s)", reg.stateFile)
}
defer nf.Close()

View file

@ -18,7 +18,7 @@ package regression
import (
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// Indicates the State recording method to use
@ -48,7 +48,7 @@ func NewStateType(state string) (StateType, error) {
case "CPU":
return StateCPU, nil
}
return StateNone, errors.Errorf("regression: video: unrecognised state type [%s]", state)
return StateNone, curated.Errorf("regression: video: unrecognised state type [%s]", state)
}
func (t StateType) String() string {

View file

@ -20,7 +20,7 @@ import (
"strconv"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
)
@ -52,10 +52,10 @@ func deserialisePanelSetupEntry(fields database.SerialisedEntry) (database.Entry
// basic sanity check
if len(fields) > numPanelSetupFields {
return nil, errors.Errorf("panel: too many fields in panel entry")
return nil, curated.Errorf("panel: too many fields in panel entry")
}
if len(fields) < numPanelSetupFields {
return nil, errors.Errorf("panel: too few fields in panel entry")
return nil, curated.Errorf("panel: too few fields in panel entry")
}
var err error
@ -63,15 +63,15 @@ func deserialisePanelSetupEntry(fields database.SerialisedEntry) (database.Entry
set.cartHash = fields[panelSetupFieldCartHash]
if set.p0, err = strconv.ParseBool(fields[panelSetupFieldP0]); err != nil {
return nil, errors.Errorf("panel: invalid player 0 setting")
return nil, curated.Errorf("panel: invalid player 0 setting")
}
if set.p1, err = strconv.ParseBool(fields[panelSetupFieldP1]); err != nil {
return nil, errors.Errorf("panel: invalid player 1 setting")
return nil, curated.Errorf("panel: invalid player 1 setting")
}
if set.col, err = strconv.ParseBool(fields[panelSetupFieldCol]); err != nil {
return nil, errors.Errorf("panel: invalid color setting")
return nil, curated.Errorf("panel: invalid color setting")
}
set.notes = fields[panelSetupFieldNotes]

View file

@ -19,7 +19,7 @@ import (
"fmt"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/patch"
)
@ -46,10 +46,10 @@ func deserialisePatchEntry(fields database.SerialisedEntry) (database.Entry, err
// basic sanity check
if len(fields) > numPatchFields {
return nil, errors.Errorf("patch: too many fields in patch entry")
return nil, curated.Errorf("patch: too many fields in patch entry")
}
if len(fields) < numPatchFields {
return nil, errors.Errorf("patch: too few fields in patch entry")
return nil, curated.Errorf("patch: too few fields in patch entry")
}
set.cartHash = fields[patchFieldCartHash]
@ -94,7 +94,7 @@ func (set Patch) matchCartHash(hash string) bool {
func (set Patch) apply(vcs *hardware.VCS) error {
_, err := patch.CartridgeMemory(vcs.Mem.Cart, set.patchFile)
if err != nil {
return errors.Errorf("patch: %v", err)
return curated.Errorf("patch: %v", err)
}
return nil
}

View file

@ -20,7 +20,7 @@ import (
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/paths"
)
@ -70,16 +70,16 @@ func AttachCartridge(vcs *hardware.VCS, cartload cartridgeloader.Loader) error {
dbPth, err := paths.ResourcePath("", setupDBFile)
if err != nil {
return errors.Errorf("setup: %v", err)
return curated.Errorf("setup: %v", err)
}
db, err := database.StartSession(dbPth, database.ActivityReading, initDBSession)
if err != nil {
if errors.Is(err, database.NotAvailable) {
if curated.Is(err, database.NotAvailable) {
// silently ignore absence of setup database
return nil
}
return errors.Errorf("setup: %v", err)
return curated.Errorf("setup: %v", err)
}
defer db.EndSession(false)
@ -102,7 +102,7 @@ func AttachCartridge(vcs *hardware.VCS, cartload cartridgeloader.Loader) error {
_, err = db.SelectAll(onSelect)
if err != nil {
return errors.Errorf("setup: %v", err)
return curated.Errorf("setup: %v", err)
}
return nil

View file

@ -19,7 +19,7 @@ import (
"fmt"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/hardware"
)
@ -45,10 +45,10 @@ func deserialiseTelevisionEntry(fields database.SerialisedEntry) (database.Entry
// basic sanity check
if len(fields) > numtelevisionFields {
return nil, errors.Errorf("television: too many fields in television entry")
return nil, curated.Errorf("television: too many fields in television entry")
}
if len(fields) < numtelevisionFields {
return nil, errors.Errorf("television: too few fields in television entry")
return nil, curated.Errorf("television: too few fields in television entry")
}
set.cartHash = fields[televisionFieldCartHash]

View file

@ -24,7 +24,7 @@ import (
"strings"
"unicode"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// ReadSymbolsFile initialises a symbols table from the symbols file for the
@ -68,7 +68,7 @@ func ReadSymbolsFile(cartridgeFilename string) (*Table, error) {
sf, err := os.Open(symFilename)
if err != nil {
return tbl, errors.Errorf("symbols: file not available (%s)", cartridgeFilename)
return tbl, curated.Errorf("symbols: file not available (%s)", cartridgeFilename)
}
defer func() {
_ = sf.Close()
@ -76,7 +76,7 @@ func ReadSymbolsFile(cartridgeFilename string) (*Table, error) {
sym, err := ioutil.ReadAll(sf)
if err != nil {
return nil, errors.Errorf("symbols: processing error: %v", err)
return nil, curated.Errorf("symbols: processing error: %v", err)
}
lines := strings.Split(string(sym), "\n")

View file

@ -30,7 +30,7 @@ import (
"fmt"
"strings"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
)
// the number of additional lines over the NTSC spec that is allowed before the
@ -326,7 +326,7 @@ func (tv *television) GetState(request StateReq) (int, error) {
case ReqHorizPos:
return tv.horizPos - HorizClksHBlank, nil
default:
return 0, errors.Errorf("television: unhandled tv state request (%v)", request)
return 0, curated.Errorf("television: unhandled tv state request (%v)", request)
}
}
@ -343,7 +343,7 @@ func (tv *television) SetSpec(spec string) error {
tv.spec = SpecNTSC
tv.auto = true
default:
return errors.Errorf("television: unsupported spec (%s)", spec)
return curated.Errorf("television: unsupported spec (%s)", spec)
}
tv.top = tv.spec.ScanlineTop

View file

@ -19,7 +19,7 @@ package wavwriter
import (
"os"
"github.com/jetsetilly/gopher2600/errors"
"github.com/jetsetilly/gopher2600/curated"
tiaAudio "github.com/jetsetilly/gopher2600/hardware/tia/audio"
"github.com/go-audio/audio"
@ -53,7 +53,7 @@ func (aw *WavWriter) SetAudio(audioData uint8) error {
func (aw *WavWriter) EndMixing() error {
f, err := os.Create(aw.filename)
if err != nil {
return errors.Errorf("wavwriter: %v", err)
return curated.Errorf("wavwriter: %v", err)
}
defer f.Close()
@ -61,7 +61,7 @@ func (aw *WavWriter) EndMixing() error {
enc := wav.NewEncoder(f, tiaAudio.SampleFreq, 8, 1, 1)
if enc == nil {
return errors.Errorf("wavwriter: %v", "bad parameters for wav encoding")
return curated.Errorf("wavwriter: %v", "bad parameters for wav encoding")
}
defer enc.Close()
@ -77,7 +77,7 @@ func (aw *WavWriter) EndMixing() error {
err = enc.Write(buf.AsIntBuffer())
if err != nil {
return errors.Errorf("wavwriter: %v", err)
return curated.Errorf("wavwriter: %v", err)
}
return nil