1
0
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:
Mike Naberezny 2009-08-18 23:12:55 -07:00
parent b122a60ddf
commit 5dd6e9f95a
3 changed files with 70 additions and 9 deletions

View File

@ -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".

View File

@ -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:

View File

@ -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)