Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

z80/z80dasm.cpp: Switched *R (LDIR, OTIR, etc) debugger flag to STEP_OVER #13451

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

holub
Copy link
Contributor

@holub holub commented Mar 7, 2025

STEP_COND on repeatable instructions doesn't allow to skip execution with F10
STEP_OVER is more reasonable for this instructions as allowed to take advantage from F10/F11

Per my understanding that should close match expectation:
static constexpr u32 STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards

@cuavas
Copy link
Member

cuavas commented Mar 12, 2025

I think at some point in the past, at least djnz did have the “step over” – it apparently changed in c759722. @ajrhacker and @galibert can you explain how the flags are supposed to be used for instructions like this? Is it supposed to be possible to skip over these things when they use the STEP_COND flag?

@cuavas
Copy link
Member

cuavas commented Mar 12, 2025

Is the gni debugger command on a looping instruction supposed to run until the instruction falls through?

@holub
Copy link
Contributor Author

holub commented Mar 12, 2025

The problem with djnz it can used either as loop with back reference or as "conditional jp" and jump forward.

@ajrhacker
Copy link
Contributor

gni is precisely equivalent to go X, where X is the address of the next instruction in the disassembly, and works regardless of what the instruction does. You can also do gni N, though I set an arbitrary limit on N because it has to look up each instruction successively.

The over command works sort of like gni when it encounters an instruction flagged with STEP_OVER, and does ordinary stepping otherwise. There's some tricky logic to handle delay slots (which Z80 doesn't have) and conditional calls (which the Z80 does have). It's a bit over-complicated, but MAME has had it for a while longer than gni.

There are a few calling conventions which neither gni nor over can handle properly. One is where the subroutine call instruction is followed by an arbitrary number of inline operands. Another is subroutines with multiple returns.

As for the Z80 instructions in question:

DJNZ is now treated as the conditional branch instruction it is. It doesn't really make sense to flag it STEP_OVER, given that it doesn't necessarily form a closed loop.

LDIR, INIR, OTIR, etc. are executed by the Z80 much like a combination of their seldom-used single-shot counterparts (LDI, INI, OUTI) with a DJNZ back to the instruction itself (the conditional timing penalties are similar). STEP_OVER would work more reliably for these instructions, though it's still not logically correct since they don't perform subroutine calls.

One idea I've entertained is adding a live branch predictor for MAME CPU cores to implement through device_disasm_interface. It would take the address of a conditional instruction, preferably that of the current program counter or something very close to it, and predict if a branch would be taken or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants