mirror of
https://github.com/mnaberez/py65.git
synced 2024-09-27 09:55:23 +00:00
Added a new interactive assembly mode to the monitor.
This commit is contained in:
parent
b122a60ddf
commit
5dd6e9f95a
@ -19,6 +19,12 @@ Next Release
|
|||||||
- Applied patch from Ed Spittles to change the CMP algorithm so that
|
- Applied patch from Ed Spittles to change the CMP algorithm so that
|
||||||
it no longer fails Rob Finch's test suite. Closes #8.
|
it no longer fails Rob Finch's test suite. Closes #8.
|
||||||
|
|
||||||
|
- Added a new interactive assembly mode to the monitor. Entering the
|
||||||
|
the assemble command with a statement such as "a c000 lda #0" works
|
||||||
|
as before. Entering "a c000" will start the interactive assembler
|
||||||
|
at that address. Entering "a" alone will start it at the current
|
||||||
|
program counter.
|
||||||
|
|
||||||
0.6 (2009-08-11)
|
0.6 (2009-08-11)
|
||||||
|
|
||||||
- Added monitor shortcut "a" for "assemble".
|
- Added monitor shortcut "a" for "assemble".
|
||||||
|
@ -11,6 +11,7 @@ from py65.devices.mpu65c02 import MPU as CMOS65C02
|
|||||||
from py65.disassembler import Disassembler
|
from py65.disassembler import Disassembler
|
||||||
from py65.assembler import Assembler
|
from py65.assembler import Assembler
|
||||||
from py65.utils.addressing import AddressParser
|
from py65.utils.addressing import AddressParser
|
||||||
|
from py65.utils.console import getch
|
||||||
from py65.utils.console import getch_noblock
|
from py65.utils.console import getch_noblock
|
||||||
from py65.utils.conversions import itoa
|
from py65.utils.conversions import itoa
|
||||||
from py65.memory import ObservableMemory
|
from py65.memory import ObservableMemory
|
||||||
@ -83,6 +84,9 @@ class Monitor(cmd.Cmd):
|
|||||||
if (not quoted) and (line[pos] == ';'):
|
if (not quoted) and (line[pos] == ';'):
|
||||||
line = line[:pos]
|
line = line[:pos]
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if line == 'a':
|
||||||
|
line = 'assemble'
|
||||||
|
|
||||||
return line
|
return line
|
||||||
|
|
||||||
@ -169,7 +173,7 @@ class Monitor(cmd.Cmd):
|
|||||||
def do_assemble(self, args):
|
def do_assemble(self, args):
|
||||||
split = args.split(None, 1)
|
split = args.split(None, 1)
|
||||||
if len(split) != 2:
|
if len(split) != 2:
|
||||||
return self.help_assemble()
|
return self._interactive_assemble(args)
|
||||||
|
|
||||||
start, statement = split
|
start, statement = split
|
||||||
try:
|
try:
|
||||||
@ -190,6 +194,65 @@ class Monitor(cmd.Cmd):
|
|||||||
self._output("assemble <address> <statement>")
|
self._output("assemble <address> <statement>")
|
||||||
self._output("Assemble a statement at the address.")
|
self._output("Assemble a statement at the address.")
|
||||||
|
|
||||||
|
def _interactive_assemble(self, args):
|
||||||
|
if args == '':
|
||||||
|
start = self._mpu.pc
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
start = self._address_parser.number(args)
|
||||||
|
except KeyError:
|
||||||
|
self._output("Bad label: %s" % start)
|
||||||
|
return
|
||||||
|
|
||||||
|
assembling = True
|
||||||
|
|
||||||
|
while assembling:
|
||||||
|
collecting_line = True
|
||||||
|
line = ''
|
||||||
|
prompt = "\r$%04x " % (start)
|
||||||
|
|
||||||
|
self.stdout.write(prompt)
|
||||||
|
|
||||||
|
while collecting_line:
|
||||||
|
char = getch(self.stdin)
|
||||||
|
if char in ("\n", "\r"):
|
||||||
|
break
|
||||||
|
elif ord(char) in (0x7f, 0x08): # backspace
|
||||||
|
if len(line) > 0:
|
||||||
|
line = line[:-1]
|
||||||
|
self.stdout.write("\r%s\r%s%s" % \
|
||||||
|
(' ' * (len(prompt+line) +5), prompt, line))
|
||||||
|
elif ord(char) == 0x1b: # escape
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
line += char
|
||||||
|
self.stdout.write(char)
|
||||||
|
|
||||||
|
if not line:
|
||||||
|
self.stdout.write("\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
bytes = self._assembler.assemble(line)
|
||||||
|
if bytes is None:
|
||||||
|
self._output("Assemble failed: %s\n" % line)
|
||||||
|
return
|
||||||
|
|
||||||
|
end = start + len(bytes)
|
||||||
|
self._mpu.memory[start:end] = bytes
|
||||||
|
|
||||||
|
bytes, disasm = self._disassembler.instruction_at(start)
|
||||||
|
|
||||||
|
mem = ''
|
||||||
|
for byte in self._mpu.memory[start:start+bytes]:
|
||||||
|
mem += '%02x ' % byte
|
||||||
|
|
||||||
|
self.stdout.write("\r" + (' ' * (len(prompt+line) + 5) ))
|
||||||
|
line = "\r$%04x %-10s%s\n" % (start, mem, disasm)
|
||||||
|
self.stdout.write(line)
|
||||||
|
|
||||||
|
start += bytes
|
||||||
|
|
||||||
|
|
||||||
def do_disassemble(self, args):
|
def do_disassemble(self, args):
|
||||||
start, end = self._address_parser.range(args)
|
start, end = self._address_parser.range(args)
|
||||||
if start == end:
|
if start == end:
|
||||||
|
@ -9,14 +9,6 @@ class MonitorTests(unittest.TestCase):
|
|||||||
|
|
||||||
# assemble
|
# assemble
|
||||||
|
|
||||||
def test_do_assemble_shows_help_for_invalid_args(self):
|
|
||||||
stdout = StringIO()
|
|
||||||
mon = Monitor(stdout=stdout)
|
|
||||||
mon.do_assemble('c000')
|
|
||||||
|
|
||||||
out = stdout.getvalue()
|
|
||||||
self.assertTrue(out.startswith("assemble <address>"))
|
|
||||||
|
|
||||||
def test_do_assemble_assembles_valid_statement(self):
|
def test_do_assemble_assembles_valid_statement(self):
|
||||||
stdout = StringIO()
|
stdout = StringIO()
|
||||||
mon = Monitor(stdout=stdout)
|
mon = Monitor(stdout=stdout)
|
||||||
|
Loading…
Reference in New Issue
Block a user