Skip to content

Commit

Permalink
[#18] Use events to save snapshots.
Browse files Browse the repository at this point in the history
  • Loading branch information
kosarev committed Feb 20, 2021
1 parent 29fec80 commit 4d0c26a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 18 deletions.
5 changes: 5 additions & 0 deletions zx/_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ class QuantumRun(DeviceEvent):
pass


class SaveSnapshot(DeviceEvent):
def __init__(self, filename):
self.filename = filename


class ScreenUpdated(DeviceEvent):
def __init__(self, pixels):
self.pixels = pixels
Expand Down
5 changes: 2 additions & 3 deletions zx/_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from ._device import LoadFile
from ._device import PauseStateUpdated
from ._device import QuantumRun
from ._device import SaveSnapshot
from ._device import ScreenUpdated
from ._device import TapeStateUpdated
from ._device import ToggleEmulationPause
Expand All @@ -30,7 +31,6 @@
from ._time import get_elapsed_time
from ._time import get_timestamp
from ._utils import div_ceil
from ._z80snapshot import Z80SnapshotFormat
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk # nopep8

Expand Down Expand Up @@ -322,8 +322,7 @@ def _save_snapshot(self, devices):
dialog.set_do_overwrite_confirmation(True)
if dialog.run() == Gtk.ResponseType.OK:
try:
self.xmachine._save_snapshot_file(Z80SnapshotFormat,
dialog.get_filename())
devices.notify(SaveSnapshot(dialog.get_filename()))
except USER_ERRORS as e:
self._error_box('File error', verbalize_error(e))

Expand Down
40 changes: 37 additions & 3 deletions zx/_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
from ._device import KeyStroke
from ._device import LoadFile
from ._device import PauseStateUpdated
from ._device import SaveSnapshot
from ._device import ToggleEmulationPause
from ._device import ToggleTapePause
from ._emulatorbase import _Spectrum48Base
from ._except import EmulationExit
from ._keyboard import KEYS
from ._rom import get_rom_image
from ._utils import make16
from ._z80snapshot import Z80SnapshotFormat


class RunEvents(enum.IntFlag):
Expand Down Expand Up @@ -134,6 +136,14 @@ def af(self):
def af(self, value):
self.__af[:] = _split16(value)

@property
def a(self):
return self.__af[1]

@property
def f(self):
return self.__af[0]

@property
def ix(self):
return _make16(*self.__ix)
Expand Down Expand Up @@ -182,6 +192,14 @@ def alt_af(self):
def alt_af(self, value):
self.__alt_af[:] = _split16(value)

@property
def alt_a(self):
return self.__alt_af[1]

@property
def alt_f(self):
return self.__alt_af[0]

@property
def pc(self):
return _make16(*self.__pc)
Expand All @@ -202,6 +220,14 @@ def sp(self, value):
def ir(self):
return _make16(*self.__ir)

@property
def i(self):
return self.__ir[1]

@property
def r(self):
return self.__ir[0]

@ir.setter
def ir(self, value):
self.__ir[:] = _split16(value)
Expand Down Expand Up @@ -328,10 +354,15 @@ def ticks_since_int(self):
def ticks_since_int(self, ticks):
self.__ticks_since_int[:] = _split32(ticks)

''' TODO
def get_border_color(self):
return self.get('border_color')
@property
def border_color(self):
return self.__border_color[0]

@border_color.setter
def border_color(self, value):
self.__border_color[0] = value

''' TODO
def set_border_color(self, color):
self.set('border_color', color)
Expand All @@ -348,6 +379,7 @@ def install_snapshot(self, snapshot):
for addr, block in value:
self.write(addr, block)
else:
# print(field)
setattr(self, field, value)


Expand Down Expand Up @@ -440,6 +472,8 @@ def on_event(self, event, devices, result):
self._handle_key_stroke(key, event.pressed)
elif isinstance(event, LoadFile):
self._load_file(event.filename)
elif isinstance(event, SaveSnapshot):
self._save_snapshot_file(Z80SnapshotFormat, event.filename)
elif isinstance(event, ToggleEmulationPause):
self.paused ^= True
elif isinstance(event, ToggleTapePause):
Expand Down
24 changes: 12 additions & 12 deletions zx/_z80snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,22 +236,22 @@ def make_snapshot(self, state):
# the middle of IX- and IY-prefixed instructions, so
# such situations need some additional processing.
# TODO: Check for similar problems with other state attributes.
assert state.get_iregp_kind() == 'hl'
assert state.iregp_kind == 'hl'

flags1 = 0
flags2 = 0

# Bit 7 of the stored R value is not signigicant and
# shall be taken from bit 0 of flags1.
r = state.get_r_reg()
r = state.r
flags1 |= (r & 0x80) >> 7
r &= 0x7f

border_color = state.get_border_color()
border_color = state.border_color
assert 0 <= border_color <= 7
flags1 |= border_color << 1

int_mode = state.get_int_mode()
int_mode = state.int_mode
assert int_mode in [0, 1, 2] # TODO
flags2 |= int_mode

Expand All @@ -260,14 +260,14 @@ def make_snapshot(self, state):
writer = BinaryWriter()
writer.write(
self._PRIMARY_HEADER,
a=state.get_a(), f=state.get_f(), bc=state.get_bc(),
hl=state.get_hl(), pc=state.get_pc(), sp=state.get_sp(),
i=state.get_i(), r=r, flags1=flags1, de=state.get_de(),
alt_bc=state.get_alt_bc(), alt_de=state.get_alt_de(),
alt_hl=state.get_alt_hl(),
alt_a=state.get_alt_a(), alt_f=state.get_alt_f(),
iy=state.get_iy(), ix=state.get_ix(),
iff1=state.get_iff1(), iff2=state.get_iff2(), flags2=flags2)
a=state.a, f=state.f, bc=state.bc,
hl=state.hl, pc=state.pc, sp=state.sp,
i=state.i, r=r, flags1=flags1, de=state.de,
alt_bc=state.alt_bc, alt_de=state.alt_de,
alt_hl=state.alt_hl,
alt_a=state.alt_a, alt_f=state.alt_f,
iy=state.iy, ix=state.ix,
iff1=state.iff1, iff2=state.iff2, flags2=flags2)

# Write memory snapshot.
writer.write_block(state.read(0x4000, size=48 * 1024))
Expand Down

0 comments on commit 4d0c26a

Please sign in to comment.