Delete partial save state implementation
This commit is contained in:
parent
20c9a842d5
commit
a3f69bc01d
|
@ -148,9 +148,7 @@ Line:
|
|||
- F5: Toggle speed between real and fastest
|
||||
- Ctrl-F5: Show current speed in Mhz
|
||||
- F6: Toggle between NTSC color TV and green phosphor monochrome monitor
|
||||
- Ctrl-F6: Show the video mode and a split screen with the views for NTSC color TV, page 1, page 2 and extra info.
|
||||
- F7: Save current state to disk (incomplete)
|
||||
- F8: Restore state from disk (incomplete)
|
||||
- F7: Show the video mode and a split screen with the views for NTSC color TV, page 1, page 2 and extra info.
|
||||
- F10: Cycle character generator code pages. Only if the character generator ROM has more than one 2Kb page.
|
||||
- F11: Toggle on and off the trace to console of the CPU execution
|
||||
- F12: Save a screen snapshot to a file `snapshot.png`
|
||||
|
|
116
apple2.go
116
apple2.go
|
@ -1,11 +1,7 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/ivanizag/apple2/core6502"
|
||||
|
@ -127,10 +123,6 @@ const (
|
|||
CommandShowSpeed
|
||||
// CommandToggleColor toggles between NTSC color TV and Green phospor monitor
|
||||
CommandToggleColor
|
||||
// CommandSaveState stores the state to file
|
||||
CommandSaveState
|
||||
// CommandLoadState reload the last state
|
||||
CommandLoadState
|
||||
// CommandDumpDebugInfo dumps usefull info
|
||||
CommandDumpDebugInfo
|
||||
// CommandNextCharGenPage cycles the CharGen page if several
|
||||
|
@ -164,18 +156,6 @@ func (a *Apple2) executeCommand(command int) {
|
|||
a.showSpeed = !a.showSpeed
|
||||
case CommandToggleColor:
|
||||
a.isColor = !a.isColor
|
||||
case CommandSaveState:
|
||||
fmt.Println("Saving state")
|
||||
err := a.save("apple2.state")
|
||||
if err != nil {
|
||||
fmt.Printf("Error loadind state: %v.", err)
|
||||
}
|
||||
case CommandLoadState:
|
||||
fmt.Println("Loading state")
|
||||
err := a.load("apple2.state")
|
||||
if err != nil {
|
||||
fmt.Printf("Error loadind state: %v.", err)
|
||||
}
|
||||
case CommandDumpDebugInfo:
|
||||
a.dumpDebugInfo()
|
||||
case CommandNextCharGenPage:
|
||||
|
@ -207,102 +187,6 @@ func (a *Apple2) executionTrace() {
|
|||
}
|
||||
}
|
||||
|
||||
type persistent interface {
|
||||
save(io.Writer) error
|
||||
load(io.Reader) error
|
||||
}
|
||||
|
||||
func (a *Apple2) save(filename string) error {
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
w := bufio.NewWriter(f)
|
||||
defer w.Flush()
|
||||
|
||||
err = a.cpu.Save(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.mmu.save(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.io.save(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, a.isColor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, a.fastMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, a.fastRequestsCounter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, c := range a.cards {
|
||||
if c != nil {
|
||||
err = c.save(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Apple2) load(filename string) error {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
r := bufio.NewReader(f)
|
||||
|
||||
err = a.cpu.Load(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.mmu.load(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.io.load(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &a.isColor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &a.fastMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &a.fastRequestsCounter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, c := range a.cards {
|
||||
if c != nil {
|
||||
err = c.load(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Apple2) dumpDebugInfo() {
|
||||
// See "Apple II Monitors Peeled"
|
||||
pageZeroSymbols := map[int]string{
|
||||
|
|
|
@ -107,15 +107,9 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
|
|||
k.a.SendCommand(apple2.CommandToggleSpeed)
|
||||
}
|
||||
case sdl.K_F6:
|
||||
if ctrl {
|
||||
k.showPages = !k.showPages
|
||||
} else {
|
||||
k.a.SendCommand(apple2.CommandToggleColor)
|
||||
}
|
||||
k.a.SendCommand(apple2.CommandToggleColor)
|
||||
case sdl.K_F7:
|
||||
k.a.SendCommand(apple2.CommandSaveState)
|
||||
case sdl.K_F8:
|
||||
k.a.SendCommand(apple2.CommandLoadState)
|
||||
k.showPages = !k.showPages
|
||||
case sdl.K_F9:
|
||||
k.a.SendCommand(apple2.CommandDumpDebugInfo)
|
||||
case sdl.K_F10:
|
||||
|
|
15
cardBase.go
15
cardBase.go
|
@ -1,13 +1,8 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type card interface {
|
||||
loadRom(data []uint8)
|
||||
assign(a *Apple2, slot int)
|
||||
persistent
|
||||
}
|
||||
|
||||
type cardBase struct {
|
||||
|
@ -76,13 +71,3 @@ func (c *cardBase) addCardSoftSwitchW(address uint8, ss softSwitchW, name string
|
|||
c._ssw[address] = ss
|
||||
c._sswName[address] = name
|
||||
}
|
||||
|
||||
func (c *cardBase) save(w io.Writer) error {
|
||||
// Empty
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *cardBase) load(r io.Reader) error {
|
||||
// Empty
|
||||
return nil
|
||||
}
|
||||
|
|
90
cardDisk2.go
90
cardDisk2.go
|
@ -1,9 +1,7 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -248,91 +246,3 @@ func moveStep(phases uint8, prevStep int) int {
|
|||
func (d *cardDisk2Drive) insertDiskette(dt diskette) {
|
||||
d.diskette = dt
|
||||
}
|
||||
|
||||
func (c *cardDisk2) save(w io.Writer) error {
|
||||
err := binary.Write(w, binary.BigEndian, c.selected)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.dataLatch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.q6)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.q7)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.drive[0].save(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.drive[1].save(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.cardBase.save(w)
|
||||
}
|
||||
|
||||
func (c *cardDisk2) load(r io.Reader) error {
|
||||
err := binary.Read(r, binary.BigEndian, &c.selected)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.dataLatch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.q6)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.q7)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.drive[0].load(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.drive[1].load(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.cardBase.load(r)
|
||||
}
|
||||
|
||||
func (d *cardDisk2Drive) save(w io.Writer) error {
|
||||
err := binary.Write(w, binary.BigEndian, d.power)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, d.phases)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, d.tracksStep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *cardDisk2Drive) load(r io.Reader) error {
|
||||
err := binary.Read(r, binary.BigEndian, &d.power)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &d.phases)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &d.tracksStep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
/*
|
||||
Language card with 16 extra kb for the Apple ][ and ][+
|
||||
Manual: http://www.applelogic.org/files/LANGCARDMAN.pdf
|
||||
|
@ -104,36 +99,3 @@ func (c *cardLanguage) ssAction(ss uint8) {
|
|||
func (c *cardLanguage) applyState() {
|
||||
c.a.mmu.setLanguageRAM(c.readState, c.writeState == lcWriteEnabled, c.altBank)
|
||||
}
|
||||
|
||||
func (c *cardLanguage) save(w io.Writer) error {
|
||||
err := binary.Write(w, binary.BigEndian, c.readState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.writeState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.altBank)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.cardBase.save(w)
|
||||
}
|
||||
|
||||
func (c *cardLanguage) load(r io.Reader) error {
|
||||
err := binary.Read(r, binary.BigEndian, &c.readState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.writeState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.altBank)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.applyState()
|
||||
return c.cardBase.load(r)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
RAM card with 128Kb. It's like 8 language cards.
|
||||
|
||||
http://www.applelogic.org/files/SATURN128MAN.pdf
|
||||
|
||||
See:
|
||||
http://www.applelogic.org/files/SATURN128MAN.pdf
|
||||
*/
|
||||
|
||||
type cardSaturn struct {
|
||||
|
@ -117,48 +111,3 @@ func (c *cardSaturn) applyState() {
|
|||
c.a.mmu.setLanguageRAMActiveBlock(c.activeBlock)
|
||||
c.a.mmu.setLanguageRAM(c.readState, c.writeState == lcWriteEnabled, c.altBank)
|
||||
}
|
||||
|
||||
func (c *cardSaturn) save(w io.Writer) error {
|
||||
for i := 0; i < saturnBlocks; i++ {
|
||||
err := binary.Write(w, binary.BigEndian, c.readState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.writeState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.altBank)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, c.activeBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return c.cardBase.save(w)
|
||||
}
|
||||
|
||||
func (c *cardSaturn) load(r io.Reader) error {
|
||||
for i := 0; i < saturnBlocks; i++ {
|
||||
err := binary.Read(r, binary.BigEndian, &c.readState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.writeState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.altBank)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.activeBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.applyState()
|
||||
}
|
||||
return c.cardBase.load(r)
|
||||
}
|
||||
|
|
10
ioC0Page.go
10
ioC0Page.go
|
@ -1,9 +1,7 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type ioC0Page struct {
|
||||
|
@ -63,14 +61,6 @@ func (p *ioC0Page) setPanicNotImplemented(value bool) {
|
|||
p.panicNotImplemented = value
|
||||
}
|
||||
|
||||
func (p *ioC0Page) save(w io.Writer) error {
|
||||
return binary.Write(w, binary.BigEndian, p.softSwitchesData)
|
||||
}
|
||||
|
||||
func (p *ioC0Page) load(r io.Reader) error {
|
||||
return binary.Read(r, binary.BigEndian, &p.softSwitchesData)
|
||||
}
|
||||
|
||||
func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR, name string) {
|
||||
p.addSoftSwitchR(address, ss, name)
|
||||
p.addSoftSwitchW(address, func(p *ioC0Page, _ uint8) {
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
// See https://fabiensanglard.net/fd_proxy/prince_of_persia/Inside%20the%20Apple%20IIe.pdf
|
||||
// See https://i.stack.imgur.com/yn21s.gif
|
||||
|
||||
|
@ -269,30 +264,3 @@ func (mmu *memoryManager) setExtendedRAMActiveBlock(block uint8) {
|
|||
}
|
||||
mmu.extendedRAMBlock = block
|
||||
}
|
||||
|
||||
// TODO: complete save and load
|
||||
func (mmu *memoryManager) save(w io.Writer) error {
|
||||
err := mmu.physicalMainRAM.save(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, mmu.activeSlot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) load(r io.Reader) error {
|
||||
err := mmu.physicalMainRAM.load(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &mmu.activeSlot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// mmu.activateCardRomExtra(mmu.activeSlot)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package apple2
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
type memoryRange struct {
|
||||
base uint16
|
||||
data []uint8
|
||||
|
@ -28,27 +23,3 @@ func (m *memoryRange) poke(address uint16, value uint8) {
|
|||
func (m *memoryRange) subRange(a, b uint16) []uint8 {
|
||||
return m.data[a-m.base : b-m.base]
|
||||
}
|
||||
|
||||
func (m *memoryRange) save(w io.Writer) error {
|
||||
err := binary.Write(w, binary.BigEndian, m.base)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, m.data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *memoryRange) load(r io.Reader) error {
|
||||
err := binary.Read(r, binary.BigEndian, &m.base)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &m.data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue