mirror of
https://github.com/mnaberez/py65.git
synced 2024-11-16 18:05:47 +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
|
||||
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)
|
||||
|
||||
- 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.assembler import Assembler
|
||||
from py65.utils.addressing import AddressParser
|
||||
from py65.utils.console import getch
|
||||
from py65.utils.console import getch_noblock
|
||||
from py65.utils.conversions import itoa
|
||||
from py65.memory import ObservableMemory
|
||||
@ -83,6 +84,9 @@ class Monitor(cmd.Cmd):
|
||||
if (not quoted) and (line[pos] == ';'):
|
||||
line = line[:pos]
|
||||
break
|
||||
|
||||
if line == 'a':
|
||||
line = 'assemble'
|
||||
|
||||
return line
|
||||
|
||||
@ -169,7 +173,7 @@ class Monitor(cmd.Cmd):
|
||||
def do_assemble(self, args):
|
||||
split = args.split(None, 1)
|
||||
if len(split) != 2:
|
||||
return self.help_assemble()
|
||||
return self._interactive_assemble(args)
|
||||
|
||||
start, statement = split
|
||||
try:
|
||||
@ -190,6 +194,65 @@ class Monitor(cmd.Cmd):
|
||||
self._output("assemble <address> <statement>")
|
||||
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):
|
||||
start, end = self._address_parser.range(args)
|
||||
if start == end:
|
||||
|
@ -9,14 +9,6 @@ class MonitorTests(unittest.TestCase):
|
||||
|
||||
# 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):
|
||||
stdout = StringIO()
|
||||
mon = Monitor(stdout=stdout)
|
||||
|
Loading…
Reference in New Issue
Block a user