Hi Dave,
I've sort of done this...
There was already a stringhiz() function which terminates at top-bit-set or 0x00. It didn't have an associated stringhiz_hook() function so I've added one.
However, that doesn't do quite what I think you want here. stringhiz() returns the address of the first byte after the string, and it *doesn't* include the terminator in the string. This meant that using stringhiz_hook for print_string disassembles the 0x00 terminator as BRK.
Edit: This is in fact probably exactly what you wanted, now I look at the code better. Anyway, I'll leave the following here as it's perhaps useful background material for anyone wanting to write their own hook functions, and I think the change I've made to add an optional argument to stringhiz() isn't bad.
I've made stringhiz() take an optional argument include_terminator_fn which is a function which is called with the terminator byte; if that function returns True, the terminator is included in the string (and therefore the return address points one past it), otherwise it isn't (and the return address points to the terminator).
Given this variant, you can write in TOSDOS-S3.py:
Code: Select all
def RENAMEME(target, addr):
return stringhiz(addr + 3, include_terminator_fn=lambda c: c == 0)
hook_subroutine(0xf009, "print_string", RENAMEME)
I think this does what you want, if it doesn't please let me know. I am happy to include RENAMEME in the standard commands/functions in commands.py if you can suggest a good name for it.
If you think it's clearer, you can also just write it out yourself explicitly in TOSDOS-S3.py:
Code: Select all
def print_string_hook(target, addr):
addr += 3
start = addr
while True:
if disassembly.is_classified(addr):
break
if memory[addr] == 0:
addr += 1
break
if memory[addr] & 0x80 == 0x80:
break
addr += 1
string(start, addr - start)
return addr
hook_subroutine(0xf009, "print_string", print_string_hook)
That's longer but maybe less confusing than using a standard function which you still need to wrap in a hook and pass a custom (if trivial) lambda function.
All these changes have been pushed to the "assembly" branch.
Edit: Nothing to do with py8dis, but as the System 3 code at &F000 itself shows, NOP has top-bit-set so you can use it as a harmless terminator and then you don't need to recognise 0x00 as a special case. But I suppose 0x00 is a more traditional terminator and if this is a standard function for the platform it's probably nice to recognise it.