Closed jmdyck closed 1 year ago
Hi @jmdyck, sorry for the delay. To answer your questions:
(1) The disassembling function you call is an internal one (note the leading underscore). c28c9687 has intentionally overridden on_format_char()
to prepend the format character to help the disassembler (_disasm.py
) figure the types of operands. The disassembler itself is still in development, but should be capable enough for what your script does. The just-submitted 96c8ced exposes the _Z80InstrBuilder
class, which we can use for that and which is supposed to become part of the public z80
interface:
import z80
m = z80.Z80Machine()
b = z80._Z80InstrBuilder()
image = b'\x00\xdd\x21\xf5\x04\x00'
m.set_memory_block(0, image)
# for i in range(5):
while m.pc < len(image):
print('-' * 35)
print(f"m.pc = {m.pc:04X}")
# (instr_asm, instr_nbytes) = m._disasm(image[m.pc: m.pc+4])
instr = b.build_instr(m.pc, image[m.pc:m.pc+4])
instr_asm = str(instr)
instr_nbytes = instr.size
addr_of_next_instr = m.pc + instr_nbytes
instr_byte_string = ' '.join(
f"{byte:02X}"
for byte in image[m.pc: addr_of_next_instr]
)
print(f"instr is next {instr_nbytes} bytes (so following instr starts at {addr_of_next_instr:04X})")
print(f"{instr_byte_string:12} = {instr_asm}")
print('')
m.ticks_to_stop = 1
m.run()
(2) This is as expected. Every time the emulator runs into an IX/IY prefix, the instruction decoder changes its internal state respectively so it knows next time there's going be a prefixed instruction and then the emulator returns control. So the prefix bytes are treated very much like separate instructions. This is necessary, because otherwise the emulator would just never return control once it's given an image completely filled with prefix bytes. So if you want to step by full instructions, the instruction-running loop should be something like the following (requires 5e921cf):
while True:
m.ticks_to_stop = 1
m.run()
# Only stop at the end of a full instruction.
if m.index_rp_kind is z80.HL:
break
(3) No documentation for the disasm and actually any APIs yet, sorry. So far the focus was on figuring out the right interfaces, and this is still in progress, so I guess just asking is the way to go for now. (And I aim to respond sooner.)
Here's the script I ran:
And here's the output I got:
So: (1) At the line
DD 21 F5 04 = ld Pix, W0x04f5
, I would have expected the disasm string to beld ix, 0x04f5
. Instead, the format charactersP
andW
are included along with their expansions. Looking at the code inon_format_char
, I can't even figure out how this is possible. (2) Given that the instruction at address 1 is 4 bytes long, I would have expected the next value of m.pc to be 5. Instead, it's only 2. (But the one after that is 5, so the machine isn't just stepping through the image one byte at a time.) (3) Am I mis-using the Python API? I couldn't find any documentation.(I fetched the z80 code today, so it's presumably up-to-date.)