mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
o cartridgeloader
- moved from memory package
This commit is contained in:
parent
11d9676ba9
commit
28d7352b52
23 changed files with 161 additions and 126 deletions
81
cartridgeloader/loader.go
Normal file
81
cartridgeloader/loader.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package cartridgeloader
|
||||
|
||||
import (
|
||||
"gopher2600/errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Loader is used to specify the cartridge to use when Attach()ing to
|
||||
// the VCS. it also permits the called to specify the format of the cartridge
|
||||
// (if necessary. fingerprinting is pretty good)
|
||||
type Loader struct {
|
||||
Filename string
|
||||
|
||||
// empty string or "AUTO" indicates automatic fingerprinting
|
||||
Format string
|
||||
|
||||
// expected hash of the loaded cartridge. empty string indicates that the
|
||||
// hash is unknown and need not be validated
|
||||
Hash string
|
||||
|
||||
data []byte
|
||||
}
|
||||
|
||||
// ShortName returns a shortened version of the CartridgeLoader filename
|
||||
func (cl Loader) ShortName() string {
|
||||
shortCartName := path.Base(cl.Filename)
|
||||
shortCartName = strings.TrimSuffix(shortCartName, path.Ext(cl.Filename))
|
||||
return shortCartName
|
||||
}
|
||||
|
||||
// Load the cartridge
|
||||
func (cl Loader) Load() ([]byte, error) {
|
||||
if len(cl.data) > 0 {
|
||||
return cl.data, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if strings.HasPrefix(cl.Filename, "http://") {
|
||||
var resp *http.Response
|
||||
|
||||
resp, err = http.Get(cl.Filename)
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.CartridgeLoader, cl.Filename)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
size := resp.ContentLength
|
||||
|
||||
cl.data = make([]byte, size)
|
||||
_, err = resp.Body.Read(cl.data)
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.CartridgeLoader, cl.Filename)
|
||||
}
|
||||
} else {
|
||||
var f *os.File
|
||||
f, err = os.Open(cl.Filename)
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.CartridgeLoader, cl.Filename)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// get file info
|
||||
cfi, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.CartridgeLoader, cl.Filename)
|
||||
}
|
||||
size := cfi.Size()
|
||||
|
||||
cl.data = make([]byte, size)
|
||||
_, err = f.Read(cl.data)
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.CartridgeLoader, cl.Filename)
|
||||
}
|
||||
}
|
||||
|
||||
return cl.data, nil
|
||||
}
|
|
@ -2,6 +2,7 @@ package debugger
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/debugger/commandline"
|
||||
"gopher2600/debugger/console"
|
||||
"gopher2600/debugger/script"
|
||||
|
@ -9,7 +10,6 @@ import (
|
|||
"gopher2600/gui"
|
||||
"gopher2600/hardware/cpu/register"
|
||||
"gopher2600/hardware/cpu/result"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/hardware/memory/addresses"
|
||||
"gopher2600/hardware/peripherals"
|
||||
"gopher2600/symbols"
|
||||
|
@ -274,7 +274,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool)
|
|||
|
||||
case cmdInsert:
|
||||
cart, _ := tokens.Get()
|
||||
err := dbg.loadCartridge(memory.CartridgeLoader{Filename: cart})
|
||||
err := dbg.loadCartridge(cartridgeloader.Loader{Filename: cart})
|
||||
if err != nil {
|
||||
return doNothing, err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package debugger
|
||||
|
||||
import (
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/debugger/commandline"
|
||||
"gopher2600/debugger/console"
|
||||
"gopher2600/debugger/reflection"
|
||||
|
@ -11,7 +12,6 @@ import (
|
|||
"gopher2600/gui/sdldebug"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/cpu/definitions"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/screendigest"
|
||||
"gopher2600/setup"
|
||||
"gopher2600/symbols"
|
||||
|
@ -190,7 +190,7 @@ func NewDebugger(tvType string) (*Debugger, error) {
|
|||
|
||||
// Start the main debugger sequence. starting the debugger is a distinct
|
||||
// operation to creating the debugger.
|
||||
func (dbg *Debugger) Start(cons console.UserInterface, initScript string, cartload memory.CartridgeLoader) error {
|
||||
func (dbg *Debugger) Start(cons console.UserInterface, initScript string, cartload cartridgeloader.Loader) error {
|
||||
// prepare user interface
|
||||
if cons == nil {
|
||||
dbg.console = new(console.PlainTerminal)
|
||||
|
@ -247,7 +247,7 @@ func (dbg *Debugger) Start(cons console.UserInterface, initScript string, cartlo
|
|||
//
|
||||
// this is the glue that hold the cartridge and disassembly packages
|
||||
// together
|
||||
func (dbg *Debugger) loadCartridge(cartload memory.CartridgeLoader) error {
|
||||
func (dbg *Debugger) loadCartridge(cartload cartridgeloader.Loader) error {
|
||||
err := setup.AttachCartridge(dbg.vcs, cartload)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -2,6 +2,7 @@ package disassembly
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/hardware/cpu"
|
||||
"gopher2600/hardware/memory"
|
||||
|
@ -63,7 +64,7 @@ func (dsm *Disassembly) Dump(output io.Writer) {
|
|||
// FromCartrige initialises a new partial emulation and returns a
|
||||
// disassembly from the supplied cartridge filename. - useful for one-shot
|
||||
// disassemblies, like the gopher2600 "disasm" mode
|
||||
func FromCartrige(cartload memory.CartridgeLoader) (*Disassembly, error) {
|
||||
func FromCartrige(cartload cartridgeloader.Loader) (*Disassembly, error) {
|
||||
// ignore errors caused by loading of symbols table - we always get a
|
||||
// standard symbols table even in the event of an error
|
||||
symtable, _ := symbols.ReadSymbolsFile(cartload.Filename)
|
||||
|
|
|
@ -71,6 +71,9 @@ const (
|
|||
SymbolsFileError
|
||||
SymbolUnknown
|
||||
|
||||
// cartridgeloader
|
||||
CartridgeLoader
|
||||
|
||||
// vcs
|
||||
VCSError
|
||||
|
||||
|
@ -90,8 +93,6 @@ const (
|
|||
UnrecognisedAddress
|
||||
|
||||
// cartridges
|
||||
CartridgeFileError
|
||||
CartridgeFileUnavailable
|
||||
CartridgeError
|
||||
CartridgeEjected
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ var messages = map[Errno]string{
|
|||
SymbolsFileUnavailable: "symbols error: no symbols file for %s",
|
||||
SymbolUnknown: "symbols error: unrecognised symbol (%s)",
|
||||
|
||||
// cartridgeloader
|
||||
CartridgeLoader: "cartridge loading error: %s",
|
||||
|
||||
// vcs
|
||||
VCSError: "vcs error: %s",
|
||||
|
||||
|
@ -77,10 +80,8 @@ var messages = map[Errno]string{
|
|||
UnrecognisedAddress: "memory error: address unrecognised (%v)",
|
||||
|
||||
// cartridges
|
||||
CartridgeFileError: "cartridge error: %s",
|
||||
CartridgeFileUnavailable: "cartridge error: cannot open cartridge file (%s)",
|
||||
CartridgeError: "cartridge error: %s",
|
||||
CartridgeEjected: "cartridge error: no cartridge attached",
|
||||
CartridgeError: "cartridge error: %s",
|
||||
CartridgeEjected: "cartridge error: no cartridge attached",
|
||||
|
||||
// peripherals
|
||||
PeriphHardwareUnavailable: "peripheral error: controller hardware unavailable (%s)",
|
||||
|
|
|
@ -3,11 +3,11 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/debugger"
|
||||
"gopher2600/debugger/colorterm"
|
||||
"gopher2600/debugger/console"
|
||||
"gopher2600/disassembly"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/magicflags"
|
||||
"gopher2600/performance"
|
||||
"gopher2600/playmode"
|
||||
|
@ -94,7 +94,7 @@ func play(mf *magicflags.MagicFlags) bool {
|
|||
}
|
||||
fallthrough
|
||||
case 1:
|
||||
cartload := memory.CartridgeLoader{
|
||||
cartload := cartridgeloader.Loader{
|
||||
Filename: mf.SubModeFlags.Arg(0),
|
||||
Format: *cartFormat,
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ func debug(mf *magicflags.MagicFlags) bool {
|
|||
fallthrough
|
||||
case 1:
|
||||
runner := func() error {
|
||||
cartload := memory.CartridgeLoader{
|
||||
cartload := cartridgeloader.Loader{
|
||||
Filename: mf.SubModeFlags.Arg(0),
|
||||
Format: *cartFormat,
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ func disasm(mf *magicflags.MagicFlags) bool {
|
|||
fmt.Println("* 2600 cartridge required")
|
||||
return false
|
||||
case 1:
|
||||
cartload := memory.CartridgeLoader{
|
||||
cartload := cartridgeloader.Loader{
|
||||
Filename: mf.SubModeFlags.Arg(0),
|
||||
Format: *cartFormat,
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ func perform(mf *magicflags.MagicFlags) bool {
|
|||
fmt.Println("* 2600 cartridge required")
|
||||
return false
|
||||
case 1:
|
||||
cartload := memory.CartridgeLoader{
|
||||
cartload := cartridgeloader.Loader{
|
||||
Filename: mf.SubModeFlags.Arg(0),
|
||||
Format: *cartFormat,
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ func regressAdd(mf *magicflags.MagicFlags) bool {
|
|||
Notes: *notes,
|
||||
}
|
||||
} else {
|
||||
cartload := memory.CartridgeLoader{
|
||||
cartload := cartridgeloader.Loader{
|
||||
Filename: mf.SubModeFlags.Arg(0),
|
||||
Format: *cartFormat,
|
||||
}
|
||||
|
|
|
@ -3,34 +3,11 @@ package memory
|
|||
import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CartridgeLoader is used to specify the cartridge to use when Attach()ing to
|
||||
// the VCS. it also permits the called to specify the format of the cartridge
|
||||
// (if necessary. fingerprinting is pretty good)
|
||||
type CartridgeLoader struct {
|
||||
Filename string
|
||||
|
||||
// empty string or "AUTO" indicates automatic fingerprinting
|
||||
Format string
|
||||
|
||||
// expected hash of the loaded cartridge. empty string indicates that the
|
||||
// hash is unknown and need not be validated
|
||||
Hash string
|
||||
}
|
||||
|
||||
// ShortName returns a shortened version of the CartridgeLoader filename
|
||||
func (cl CartridgeLoader) ShortName() string {
|
||||
shortCartName := path.Base(cl.Filename)
|
||||
shortCartName = strings.TrimSuffix(shortCartName, path.Ext(cl.Filename))
|
||||
return shortCartName
|
||||
}
|
||||
|
||||
// cartMapper implementations hold the actual data from the loaded ROM and
|
||||
// keeps track of which banks are mapped to individual addresses. for
|
||||
// convenience, functions with an address argument recieve that address
|
||||
|
@ -210,10 +187,10 @@ func (cart *Cartridge) fingerprint(data []byte) error {
|
|||
}
|
||||
|
||||
case 65536:
|
||||
return errors.New(errors.CartridgeFileError, "65536 bytes not yet supported")
|
||||
return errors.New(errors.CartridgeError, "65536 bytes not yet supported")
|
||||
|
||||
default:
|
||||
return errors.New(errors.CartridgeFileError, fmt.Sprintf("unrecognised cartridge size (%d bytes)", len(data)))
|
||||
return errors.New(errors.CartridgeError, fmt.Sprintf("unrecognised cartridge size (%d bytes)", len(data)))
|
||||
}
|
||||
|
||||
// if cartridge mapper implements the optionalSuperChip interface then try
|
||||
|
@ -226,46 +203,10 @@ func (cart *Cartridge) fingerprint(data []byte) error {
|
|||
}
|
||||
|
||||
// Attach loads the bytes from a cartridge (represented by 'filename')
|
||||
func (cart *Cartridge) Attach(cartload CartridgeLoader) error {
|
||||
var err error
|
||||
var data []byte
|
||||
|
||||
if strings.HasPrefix(cartload.Filename, "http://") {
|
||||
var resp *http.Response
|
||||
|
||||
resp, err = http.Get(cartload.Filename)
|
||||
if err != nil {
|
||||
return errors.New(errors.CartridgeFileUnavailable, cartload.Filename)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
size := resp.ContentLength
|
||||
|
||||
data = make([]byte, size)
|
||||
_, err = resp.Body.Read(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
var f *os.File
|
||||
f, err = os.Open(cartload.Filename)
|
||||
if err != nil {
|
||||
return errors.New(errors.CartridgeFileUnavailable, cartload.Filename)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// get file info
|
||||
cfi, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
size := cfi.Size()
|
||||
|
||||
data = make([]byte, size)
|
||||
_, err = f.Read(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
|
||||
data, err := cartload.Load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// note name of cartridge
|
||||
|
|
|
@ -172,7 +172,7 @@ func newAtari4k(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, 1)
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
cart.banks[0] = make([]uint8, bankSize)
|
||||
|
@ -220,7 +220,7 @@ func newAtari2k(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, 1)
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
cart.banks[0] = make([]uint8, bankSize)
|
||||
|
@ -266,7 +266,7 @@ func newAtari8k(data []uint8) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, cart.numBanks())
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
for k := 0; k < cart.numBanks(); k++ {
|
||||
|
@ -333,7 +333,7 @@ func newAtari16k(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, cart.numBanks())
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
for k := 0; k < cart.numBanks(); k++ {
|
||||
|
@ -408,7 +408,7 @@ func newAtari32k(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, cart.numBanks())
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
for k := 0; k < cart.numBanks(); k++ {
|
||||
|
|
|
@ -27,7 +27,7 @@ func newCBS(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, cart.numBanks())
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
for k := 0; k < cart.numBanks(); k++ {
|
||||
|
|
|
@ -75,7 +75,7 @@ func newMnetwork(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, cart.numBanks())
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
for k := 0; k < cart.numBanks(); k++ {
|
||||
|
|
|
@ -59,7 +59,7 @@ func newparkerBros(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, cart.numBanks())
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
for k := 0; k < cart.numBanks(); k++ {
|
||||
|
|
|
@ -57,7 +57,7 @@ func newTigervision(data []byte) (cartMapper, error) {
|
|||
cart.banks = make([][]uint8, cart.numBanks())
|
||||
|
||||
if len(data) != bankSize*cart.numBanks() {
|
||||
return nil, errors.New(errors.CartridgeFileError, "not enough bytes in the cartridge file")
|
||||
return nil, errors.New(errors.CartridgeError, "not enough bytes in the cartridge file")
|
||||
}
|
||||
|
||||
for k := 0; k < cart.numBanks(); k++ {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package hardware
|
||||
|
||||
import (
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/hardware/cpu"
|
||||
"gopher2600/hardware/memory"
|
||||
|
@ -69,7 +70,7 @@ func NewVCS(tv television.Television) (*VCS, error) {
|
|||
// memory. While this function can be called directly it is advised that the
|
||||
// equivalent function call in the setup package is used. that function in turn
|
||||
// calls this function in this package
|
||||
func (vcs *VCS) AttachCartridge(cartload memory.CartridgeLoader) error {
|
||||
func (vcs *VCS) AttachCartridge(cartload cartridgeloader.Loader) error {
|
||||
if cartload.Filename == "" {
|
||||
vcs.Mem.Cart.Eject()
|
||||
} else {
|
||||
|
|
|
@ -2,11 +2,11 @@ package performance
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/gui"
|
||||
"gopher2600/gui/sdlplay"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/setup"
|
||||
"gopher2600/television"
|
||||
"io"
|
||||
|
@ -14,7 +14,7 @@ import (
|
|||
)
|
||||
|
||||
// Check is a very rough and ready calculation of the emulator's performance
|
||||
func Check(output io.Writer, profile bool, display bool, tvType string, scaling float32, runTime string, cartload memory.CartridgeLoader) error {
|
||||
func Check(output io.Writer, profile bool, display bool, tvType string, scaling float32, runTime string, cartload cartridgeloader.Loader) error {
|
||||
var ftv television.Television
|
||||
var err error
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@ package playmode
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/gui"
|
||||
"gopher2600/gui/sdlplay"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/recorder"
|
||||
"gopher2600/setup"
|
||||
"os"
|
||||
|
@ -14,14 +14,14 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func uniqueFilename(cartload memory.CartridgeLoader) string {
|
||||
func uniqueFilename(cartload cartridgeloader.Loader) string {
|
||||
n := time.Now()
|
||||
timestamp := fmt.Sprintf("%04d%02d%02d_%02d%02d%02d", n.Year(), n.Month(), n.Day(), n.Hour(), n.Minute(), n.Second())
|
||||
return fmt.Sprintf("recording_%s_%s", cartload.ShortName(), timestamp)
|
||||
}
|
||||
|
||||
// Play sets the emulation running - without any debugging features
|
||||
func Play(tvType string, scaling float32, stable bool, transcript string, newRecording bool, cartload memory.CartridgeLoader) error {
|
||||
func Play(tvType string, scaling float32, stable bool, transcript string, newRecording bool, cartload cartridgeloader.Loader) error {
|
||||
if recorder.IsPlaybackFile(cartload.Filename) {
|
||||
return errors.New(errors.PlayError, "specified cartridge is a playback file. use -recording flag")
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ package recorder
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/hardware/peripherals"
|
||||
"gopher2600/screendigest"
|
||||
"gopher2600/television"
|
||||
|
@ -35,7 +35,7 @@ type playbackSequence struct {
|
|||
type Playback struct {
|
||||
transcript string
|
||||
|
||||
CartLoad memory.CartridgeLoader
|
||||
CartLoad cartridgeloader.Loader
|
||||
TVtype string
|
||||
|
||||
sequences []*playbackSequence
|
||||
|
|
|
@ -3,10 +3,10 @@ package regression
|
|||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/database"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/performance/limiter"
|
||||
"gopher2600/screendigest"
|
||||
"gopher2600/setup"
|
||||
|
@ -35,7 +35,7 @@ const (
|
|||
// regression tests pass if the screen digest after N frames matches the stored
|
||||
// value.
|
||||
type FrameRegression struct {
|
||||
CartLoad memory.CartridgeLoader
|
||||
CartLoad cartridgeloader.Loader
|
||||
TVtype string
|
||||
NumFrames int
|
||||
State bool
|
||||
|
|
|
@ -2,14 +2,14 @@ package regression
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/cartridgeloader"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// create a unique filename from a CatridgeLoader instance
|
||||
|
||||
func uniqueFilename(cartload memory.CartridgeLoader) string {
|
||||
func uniqueFilename(cartload cartridgeloader.Loader) string {
|
||||
n := time.Now()
|
||||
timestamp := fmt.Sprintf("%04d%02d%02d_%02d%02d%02d", n.Year(), n.Month(), n.Day(), n.Hour(), n.Minute(), n.Second())
|
||||
newScript := fmt.Sprintf("%s_%s", cartload.ShortName(), timestamp)
|
||||
|
|
|
@ -16,11 +16,13 @@ import (
|
|||
// cryptographic task.
|
||||
type SHA1 struct {
|
||||
television.Television
|
||||
digest [sha1.Size]byte
|
||||
frameData []byte
|
||||
frameNum int
|
||||
digest [sha1.Size]byte
|
||||
pixels []byte
|
||||
frameNum int
|
||||
}
|
||||
|
||||
const pixelDepth = 3
|
||||
|
||||
// NewSHA1 initialises a new instance of DigestTV. For convenience, the
|
||||
// television argument can be nil, in which case an instance of
|
||||
// StellaTelevision will be created.
|
||||
|
@ -71,7 +73,14 @@ func (dig *SHA1) ResetDigest() {
|
|||
|
||||
// Resize implements television.Television interface
|
||||
func (dig *SHA1) Resize(_, _ int) error {
|
||||
dig.frameData = make([]byte, len(dig.digest)+((television.ClocksPerScanline+1)*(dig.GetSpec().ScanlinesTotal+1)*3))
|
||||
// length of pixels array contains enough room for the previous frames
|
||||
// digest value
|
||||
l := len(dig.digest)
|
||||
|
||||
// alloscate enough pixels for entire frame
|
||||
l += ((television.ClocksPerScanline + 1) * (dig.GetSpec().ScanlinesTotal + 1) * pixelDepth)
|
||||
|
||||
dig.pixels = make([]byte, l)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -79,11 +88,11 @@ func (dig *SHA1) Resize(_, _ int) error {
|
|||
func (dig *SHA1) NewFrame(frameNum int) error {
|
||||
// chain fingerprints by copying the value of the last fingerprint
|
||||
// to the head of the screen data
|
||||
n := copy(dig.frameData, dig.digest[:])
|
||||
n := copy(dig.pixels, dig.digest[:])
|
||||
if n != len(dig.digest) {
|
||||
return errors.New(errors.ScreenDigest, fmt.Sprintf("unexpected amount of data copied"))
|
||||
return errors.New(errors.ScreenDigest, fmt.Sprintf("digest error during new frame"))
|
||||
}
|
||||
dig.digest = sha1.Sum(dig.frameData)
|
||||
dig.digest = sha1.Sum(dig.pixels)
|
||||
dig.frameNum = frameNum
|
||||
return nil
|
||||
}
|
||||
|
@ -96,17 +105,17 @@ func (dig *SHA1) NewScanline(scanline int) error {
|
|||
// SetPixel implements television.Renderer interface
|
||||
func (dig *SHA1) SetPixel(x, y int, red, green, blue byte, vblank bool) error {
|
||||
// preserve the first few bytes for a chained fingerprint
|
||||
offset := television.ClocksPerScanline * y * 3
|
||||
offset += x * 3
|
||||
i := len(dig.digest)
|
||||
i += television.ClocksPerScanline * y * pixelDepth
|
||||
i += x * pixelDepth
|
||||
|
||||
if offset >= len(dig.frameData) {
|
||||
return errors.New(errors.ScreenDigest, fmt.Sprintf("the coordinates (%d, %d) passed to SetPixel will cause an invalid access of the frameData array", x, y))
|
||||
if i <= len(dig.pixels)-pixelDepth {
|
||||
// setting every pixel regardless of vblank value
|
||||
dig.pixels[i] = red
|
||||
dig.pixels[i+1] = green
|
||||
dig.pixels[i+2] = blue
|
||||
}
|
||||
|
||||
dig.frameData[offset] = red
|
||||
dig.frameData[offset+1] = green
|
||||
dig.frameData[offset+2] = blue
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package setup
|
||||
|
||||
import (
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/database"
|
||||
"gopher2600/errors"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/memory"
|
||||
)
|
||||
|
||||
// the location of the setupDB file
|
||||
|
@ -31,7 +31,7 @@ func initDBSession(db *database.Session) error {
|
|||
}
|
||||
|
||||
// AttachCartridge to the VCS and apply setup information from the setupDB
|
||||
func AttachCartridge(vcs *hardware.VCS, cartload memory.CartridgeLoader) error {
|
||||
func AttachCartridge(vcs *hardware.VCS, cartload cartridgeloader.Loader) error {
|
||||
err := vcs.AttachCartridge(cartload)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -2,10 +2,10 @@ package main_test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/gui"
|
||||
"gopher2600/gui/sdldebug"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/memory"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -27,7 +27,7 @@ func BenchmarkSDL(b *testing.B) {
|
|||
panic(fmt.Errorf("error preparing VCS: %s", err))
|
||||
}
|
||||
|
||||
err = vcs.AttachCartridge(memory.CartridgeLoader{Filename: "../roms/ROMs/Pitfall.bin"})
|
||||
err = vcs.AttachCartridge(cartridgeloader.Loader{Filename: "../roms/ROMs/Pitfall.bin"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"gopher2600/cartridgeloader"
|
||||
"gopher2600/hardware"
|
||||
"gopher2600/hardware/memory"
|
||||
"gopher2600/hardware/peripherals"
|
||||
"gopher2600/setup"
|
||||
"syscall/js"
|
||||
|
@ -22,7 +22,7 @@ func main() {
|
|||
}
|
||||
|
||||
// load cartridge
|
||||
cartload := memory.CartridgeLoader{
|
||||
cartload := cartridgeloader.Loader{
|
||||
Filename: "http://localhost:8080/Pitfall.bin",
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue