Skip to content

Commit

Permalink
Enable {bin2sna,snapmod,tap2sna,trace}.py to POKE 128K RAM banks
Browse files Browse the repository at this point in the history
  • Loading branch information
skoolkid committed Dec 18, 2023
1 parent 1c4c228 commit 73e6b7b
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 48 deletions.
4 changes: 2 additions & 2 deletions skoolkit/bin2sna.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ def main(args):
help="Specify the RAM bank (N=0-7) mapped to 49152 (0xC000) in the main input file. This option creates a 128K snapshot.")
group.add_argument('-p', '--stack', dest='stack', metavar='STACK', type=integer,
help="Set the stack pointer (default: ORG).")
group.add_argument('-P', '--poke', dest='pokes', metavar='a[-b[-c]],[^+]v', action='append', default=[],
help="POKE N,v for N in {a, a+c, a+2c..., b}. "
group.add_argument('-P', '--poke', dest='pokes', metavar='[p:]a[-b[-c]],[^+]v', action='append', default=[],
help="POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}. "
"Prefix 'v' with '^' to perform an XOR operation, or '+' to perform an ADD operation. "
"This option may be used multiple times.")
group.add_argument('-r', '--reg', dest='reg', metavar='name=value', action='append', default=[],
Expand Down
4 changes: 2 additions & 2 deletions skoolkit/snapmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def main(args):
group = parser.add_argument_group('Options')
group.add_argument('-m', '--move', dest='moves', metavar='src,size,dest', action='append', default=[],
help='Move a block of bytes of the given size from src to dest. This option may be used multiple times.')
group.add_argument('-p', '--poke', dest='pokes', metavar='a[-b[-c]],[^+]v', action='append', default=[],
help="POKE N,v for N in {a, a+c, a+2c..., b}. "
group.add_argument('-p', '--poke', dest='pokes', metavar='[p:]a[-b[-c]],[^+]v', action='append', default=[],
help="POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}. "
"Prefix 'v' with '^' to perform an XOR operation, or '+' to perform an ADD operation. "
"This option may be used multiple times.")
group.add_argument('-r', '--reg', dest='reg', metavar='name=value', action='append', default=[],
Expand Down
18 changes: 16 additions & 2 deletions skoolkit/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,14 @@ def poke(snapshot, param_str):
addr, val = param_str.split(',', 1)
except ValueError:
raise SkoolKitError("Value missing in poke spec: {}".format(param_str))
if ':' in addr:
page, addr = addr.split(':', 1)
try:
page = get_int_param(page)
except ValueError:
raise SkoolKitError(f'Invalid page number in poke spec: {param_str}')
else:
page = None
try:
if val.startswith('^'):
value = get_int_param(val[1:], True)
Expand All @@ -637,8 +645,14 @@ def poke(snapshot, param_str):
except ValueError:
raise SkoolKitError('Invalid address range in poke spec: {}'.format(param_str))
addr1, addr2, step = values + [values[0], 1][len(values) - 1:]
for a in range(addr1, addr2 + 1, step):
snapshot[a] = poke_f(snapshot[a])
if page is None:
for a in range(addr1, addr2 + 1, step):
snapshot[a] = poke_f(snapshot[a])
elif hasattr(snapshot, 'banks'):
bank = snapshot.banks[page % 8]
if bank:
for a in range(addr1, addr2 + 1, step):
bank[a % 0x4000] = poke_f(bank[a % 0x4000])

# API (SnapshotReader)
class SnapshotError(SkoolKitError):
Expand Down
7 changes: 4 additions & 3 deletions skoolkit/tap2sna.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ def _print_ram_help():
Usage: --ram call=[/path/to/moduledir:]module.function
--ram load=[+]block[+],start[,length,step,offset,inc]
--ram move=src,size,dest
--ram poke=a[-b[-c]],[^+]v
--ram poke=[p:]a[-b[-c]],[^+]v
--ram sysvars
Load data from a tape block, move a block of bytes from one location to
Expand Down Expand Up @@ -844,10 +844,11 @@ def _print_ram_help():
--ram move=32512,256,32768 # Move 32512-32767 to 32768-33023
--ram poke=a[-b[-c]],[^+]v
--ram poke=[p:]a[-b[-c]],[^+]v
Do POKE N,v for N in {a, a+c, a+2c..., b}.
Do POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}.
p - the RAM bank to POKE (0-7; 128K only)
a - the first address to POKE
b - the last address to POKE (optional; default=a)
c - step (optional; default=1)
Expand Down
4 changes: 2 additions & 2 deletions skoolkit/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ def main(args):
help="Don't execute interrupt routines.")
group.add_argument('-o', '--org', metavar='ADDR', type=integer,
help='Specify the origin address of a binary (raw memory) file (default: 65536 - length).')
group.add_argument('-p', '--poke', dest='pokes', metavar='a[-b[-c]],[^+]v', action='append', default=[],
help="POKE N,v for N in {a, a+c, a+2c..., b}. "
group.add_argument('-p', '--poke', dest='pokes', metavar='[p:]a[-b[-c]],[^+]v', action='append', default=[],
help="POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}. "
"Prefix 'v' with '^' to perform an XOR operation, or '+' to perform an ADD operation. "
"This option may be used multiple times.")
group.add_argument('-r', '--reg', metavar='name=value', action='append', default=[],
Expand Down
3 changes: 3 additions & 0 deletions sphinx/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Changelog
``--page`` and ``--bank`` options, or by providing a 128K input file)
* Added support to :ref:`bin2tap.py` for writing 128K TAP files (by using the
``--7ffd``, ``--banks`` and ``--loader`` options)
* Added support to :ref:`bin2sna.py`, :ref:`snapmod.py`, :ref:`tap2sna.py` and
:ref:`trace.py` for modifying 128K RAM banks (via the ``--poke`` and
``--ram poke`` options)
* Added the :ref:`BANK` macro (for switching the RAM bank that is mapped to
49152-65535)
* Added the :ref:`asm-bank` directive (for specifying the RAM bank that is
Expand Down
40 changes: 23 additions & 17 deletions sphinx/source/commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ Run `bin2sna.py` with no arguments to see the list of available options::
snapshot.
-p STACK, --stack STACK
Set the stack pointer (default: ORG).
-P a[-b[-c]],[^+]v, --poke a[-b[-c]],[^+]v
POKE N,v for N in {a, a+c, a+2c..., b}. Prefix 'v'
with '^' to perform an XOR operation, or '+' to
perform an ADD operation. This option may be used
multiple times.
-P [p:]a[-b[-c]],[^+]v, --poke [p:]a[-b[-c]],[^+]v
POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}.
Prefix 'v' with '^' to perform an XOR operation, or
'+' to perform an ADD operation. This option may be
used multiple times.
-r name=value, --reg name=value
Set the value of a register. Do '--reg help' for more
information. This option may be used multiple times.
Expand All @@ -63,7 +63,8 @@ Run `bin2sna.py` with no arguments to see the list of available options::
| Version | Changes |
+=========+===================================================================+
| 9.1 | Added the ``--bank`` and ``--page`` options and support for |
| | writing 128K snapshots |
| | writing 128K snapshots; the ``--poke`` option can modify specific |
| | RAM banks |
+---------+-------------------------------------------------------------------+
| 9.0 | Added support for writing SZX snapshots; added the ``fe`` |
| | hardware state attribute |
Expand Down Expand Up @@ -1287,11 +1288,11 @@ To list the options supported by `snapmod.py`, run it with no arguments::
-m src,size,dest, --move src,size,dest
Move a block of bytes of the given size from src to
dest. This option may be used multiple times.
-p a[-b[-c]],[^+]v, --poke a[-b[-c]],[^+]v
POKE N,v for N in {a, a+c, a+2c..., b}. Prefix 'v'
with '^' to perform an XOR operation, or '+' to
perform an ADD operation. This option may be used
multiple times.
-p [p:]a[-b[-c]],[^+]v, --poke [p:]a[-b[-c]],[^+]v
POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}.
Prefix 'v' with '^' to perform an XOR operation, or
'+' to perform an ADD operation. This option may be
used multiple times.
-r name=value, --reg name=value
Set the value of a register. Do '--reg help' for more
information. This option may be used multiple times.
Expand All @@ -1304,7 +1305,8 @@ To list the options supported by `snapmod.py`, run it with no arguments::
+---------+-------------------------------------------------------------------+
| Version | Changes |
+=========+===================================================================+
| 9.1 | Added support for modifying SZX snapshots and 128K snapshots |
| 9.1 | Added support for modifying SZX snapshots and 128K snapshots; the |
| | ``--poke`` option can modify specific RAM banks |
+---------+-------------------------------------------------------------------+
| 8.10 | Added the ``issue2`` hardware state attribute |
+---------+-------------------------------------------------------------------+
Expand Down Expand Up @@ -1668,6 +1670,8 @@ Configuration parameters may also be set on the command line by using the
+---------+-------------------------------------------------------------------+
| Version | Changes |
+=========+===================================================================+
| 9.1 | The ``--ram poke`` option can modify specific RAM banks |
+---------+-------------------------------------------------------------------+
| 9.0 | A simulated LOAD is performed by default; an existing snapshot |
| | will be overwritten by default; added the ``load``, ``machine``, |
| | ``polarity`` and ``in-flags`` simulated LOAD configuration |
Expand Down Expand Up @@ -1806,11 +1810,11 @@ To list the options supported by `trace.py`, run it with no arguments::
-n, --no-interrupts Don't execute interrupt routines.
-o ADDR, --org ADDR Specify the origin address of a binary (raw memory)
file (default: 65536 - length).
-p a[-b[-c]],[^+]v, --poke a[-b[-c]],[^+]v
POKE N,v for N in {a, a+c, a+2c..., b}. Prefix 'v'
with '^' to perform an XOR operation, or '+' to
perform an ADD operation. This option may be used
multiple times.
-p [p:]a[-b[-c]],[^+]v, --poke [p:]a[-b[-c]],[^+]v
POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}.
Prefix 'v' with '^' to perform an XOR operation, or
'+' to perform an ADD operation. This option may be
used multiple times.
-r name=value, --reg name=value
Set the value of a register. Do '--reg help' for more
information. This option may be used multiple times.
Expand Down Expand Up @@ -1894,6 +1898,8 @@ Configuration parameters may also be set on the command line by using the
+---------+-------------------------------------------------------------------+
| Version | Changes |
+=========+===================================================================+
| 9.1 | The ``--poke`` option can modify specific RAM banks |
+---------+-------------------------------------------------------------------+
| 9.0 | Configuration is read from `skoolkit.ini` if present; added the |
| | ``--ini``, ``--no-interrupts`` and ``--show-config`` options; |
| | interrupt routines are executed by default; added support for |
Expand Down
10 changes: 5 additions & 5 deletions sphinx/source/man/bin2sna.py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ OPTIONS
default value is `ORG`. `STACK` must be a decimal number, or a hexadecimal
number prefixed by '0x'.

-P, --poke `a[-b[-c]],[^+]v`
POKE N,v for N in {a, a+c, a+2c..., b}. Prefix 'v' with '^' to perform an
XOR operation, or '+' to perform an ADD operation. This option may be used
multiple times. 'a', 'b', 'c' and 'v' must each be a decimal number, or a
hexadecimal number prefixed by '0x'.
-P, --poke `[p:]a[-b[-c]],[^+]v`
POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}. Prefix 'v' with '^' to
perform an XOR operation, or '+' to perform an ADD operation. This option may
be used multiple times. 'a', 'b', 'c' and 'v' must each be a decimal number,
or a hexadecimal number prefixed by '0x'.

-r, --reg `name=value`
Set the value of a register. Do ``--reg help`` for more information, or see
Expand Down
10 changes: 5 additions & 5 deletions sphinx/source/man/snapmod.py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ OPTIONS
be used multiple times. 'src', 'size' and 'dest' must each be a decimal
number, or a hexadecimal number prefixed by '0x'.

-p, --poke `a[-b[-c]],[^+]v`
POKE N,v for N in {a, a+c, a+2c..., b}. Prefix 'v' with '^' to perform an
XOR operation, or '+' to perform an ADD operation. This option may be used
multiple times. 'a', 'b', 'c' and 'v' must each be a decimal number, or a
hexadecimal number prefixed by '0x'.
-p, --poke `[p:]a[-b[-c]],[^+]v`
POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}. Prefix 'v' with '^' to
perform an XOR operation, or '+' to perform an ADD operation. This option may
be used multiple times. 'a', 'b', 'c' and 'v' must each be a decimal number,
or a hexadecimal number prefixed by '0x'.

-r, --reg `name=value`
Set the value of a register. Do ``--reg help`` for more information, or see
Expand Down
7 changes: 5 additions & 2 deletions sphinx/source/man/tap2sna.py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,12 @@ The ``--ram`` option can be used to POKE values into the snapshot before saving
it.

|
| ``--ram poke=A[-B[-C]],[^+]V``
| ``--ram poke=[P:]A[-B[-C]],[^+]V``
This does ``POKE N,V`` for ``N`` in ``{A, A+C, A+2C..., B}``, where:
This does ``POKE N,V`` in RAM bank ``P`` for ``N`` in ``{A, A+C, A+2C..., B}``,
where:

``P`` is the RAM bank to POKE (0-7; 128K only)

``A`` is the first address to POKE

Expand Down
10 changes: 5 additions & 5 deletions sphinx/source/man/trace.py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ OPTIONS
address is 65536 minus the length of the file. `ORG` must be a decimal
number, or a hexadecimal number prefixed by '0x'.

-p, --poke `a[-b[-c]],[^+]v`
POKE N,v for N in {a, a+c, a+2c..., b}. Prefix 'v' with '^' to perform an
XOR operation, or '+' to perform an ADD operation. This option may be used
multiple times. 'a', 'b', 'c' and 'v' must each be a decimal number, or a
hexadecimal number prefixed by '0x'.
-p, --poke `[p:]a[-b[-c]],[^+]v`
POKE N,v in RAM bank p for N in {a, a+c, a+2c..., b}. Prefix 'v' with '^' to
perform an XOR operation, or '+' to perform an ADD operation. This option may
be used multiple times. 'a', 'b', 'c' and 'v' must each be a decimal number,
or a hexadecimal number prefixed by '0x'.

-r, --reg `name=value`
Set the value of a register before execution begins. Do ``--reg help`` for
Expand Down
21 changes: 21 additions & 0 deletions tests/test_bin2sna.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,26 @@ def test_option_P_128k(self):
exp_state = ['7ffd=7']
self._check_write_snapshot(args, exp_ram, exp_state)

@patch.object(bin2sna, 'write_snapshot', mock_write_snapshot)
def test_option_P_with_page_number(self):
exp_ram = [[0] * 0x4000 for i in range(8)]
args = ['--page 5']
for page, addr, value in (
(0, 0, 255),
(1, 16384, 254),
(2, 32768, 253),
(3, 49152, 252),
(4, 65535, 251),
(5, 49151, 250),
(6, 32767, 249),
(7, 16383, 248),
):
exp_ram[page][addr % 0x4000] = value
args.append(f'-P {page}:{addr},{value}')
args.append(self.write_bin_file([0], suffix='.bin'))
exp_state = ['7ffd=5']
self._check_write_snapshot(' '.join(args), exp_ram, exp_state)

@patch.object(bin2sna, 'write_snapshot', mock_write_snapshot)
def test_option_P_with_128k_input_file(self):
exp_ram = []
Expand All @@ -400,6 +420,7 @@ def test_option_P_with_128k_input_file(self):
def test_option_P_invalid_values(self):
self._test_bad_spec('-P 1', 'Value missing in poke spec: 1')
self._test_bad_spec('-P q', 'Value missing in poke spec: q')
self._test_bad_spec('-P p:1,0', 'Invalid page number in poke spec: p:1,0')
self._test_bad_spec('-P 1,x', 'Invalid value in poke spec: 1,x')
self._test_bad_spec('-P x,1', 'Invalid address range in poke spec: x,1')
self._test_bad_spec('-P 1-y,1', 'Invalid address range in poke spec: 1-y,1')
Expand Down
42 changes: 42 additions & 0 deletions tests/test_snapmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,27 @@ def test_option_p_z80v3_128k(self):
options.append(f'--poke {addr},{value}')
self._test_z80_128k(' '.join(options), header, exp_header, ram, exp_ram, 3)

def test_option_p_z80v3_with_page_number(self):
pokes = (
(0, 0x0000, 0xFF),
(1, 0x4000, 0xFE),
(2, 0x8000, 0xFD),
(3, 0xC000, 0xFC),
(4, 0x3FFF, 0xFB),
(5, 0x7FFF, 0xFA),
(6, 0xBFFF, 0xF9),
(7, 0xFFFF, 0xF8),
)
header = self._get_header(3, True)
exp_header = header[:]
ram = [0] * 0x20000
exp_ram = ram[:]
options = []
for bank, addr, value in pokes:
exp_ram[(bank * 0x4000) + (addr % 0x4000)] = value
options.append(f'--poke {bank}:{addr},{value}')
self._test_z80_128k(' '.join(options), header, exp_header, ram, exp_ram, 3)

def test_option_p_szx_16k(self):
option = '-p 16384,255'
exp_block_diffs = None
Expand Down Expand Up @@ -372,6 +393,26 @@ def test_option_p_szx_128k(self):
options.append(f'--poke {addr},{value}')
self._test_szx(' '.join(options), exp_block_diffs, exp_ram_diffs, 128, ch7ffd=3)

def test_option_p_szx_with_page_number(self):
pokes = (
(0, 0x0000, 0xFF),
(1, 0x4000, 0xFE),
(2, 0x8000, 0xFD),
(3, 0xC000, 0xFC),
(4, 0x3FFF, 0xFB),
(5, 0x7FFF, 0xFA),
(6, 0xBFFF, 0xF9),
(7, 0xFFFF, 0xF8),
)
exp_block_diffs = None
exp_ram_diffs = {}
options = []
for bank, addr, value in pokes:
exp_ram_diffs[bank] = [0] * 0x4000
exp_ram_diffs[bank][addr % 0x4000] = value
options.append(f'--poke {bank}:{addr},{value}')
self._test_szx(' '.join(options), exp_block_diffs, exp_ram_diffs, 128)

def test_option_poke_multiple(self):
pokes = ((24576, 1), (32768, 34), (49152, 205))
header = list(range(30))
Expand Down Expand Up @@ -413,6 +454,7 @@ def test_option_p_invalid_values(self):
infile = self.write_z80_file([1] * 30, [0] * 49152, 1)
self._test_bad_spec('-p 1', infile, 'Value missing in poke spec: 1')
self._test_bad_spec('-p q', infile, 'Value missing in poke spec: q')
self._test_bad_spec('-p p:1,x', infile, 'Invalid page number in poke spec: p:1,x')
self._test_bad_spec('-p 1,x', infile, 'Invalid value in poke spec: 1,x')
self._test_bad_spec('-p x,1', infile, 'Invalid address range in poke spec: x,1')
self._test_bad_spec('-p 1-y,1', infile, 'Invalid address range in poke spec: 1-y,1')
Expand Down
Loading

0 comments on commit 73e6b7b

Please sign in to comment.