potentially wrong memptr value during otir/otdr
Opened this issue · 7 comments
reading the logic here, it appears the routine dealing with otir sets memptr to bc+1
https://github.com/hoglet67/Z80Decoder/blob/master/src/em_z80.c#L2342-L2345
however according to visual z80 this is only the case when b == 0; otherwise memptr should contain the value PC+1 (arguably this is only observable when looking at a single intermediate state, rather than the state of when the loop returns to the calling z80 code).
i haven't actually been able to verify this is indeed what happens when running your code, as #1 prevents me from doing so.
I'm just trying to understand this issue...
Here's an example that shows OTIR running: Visual Z80
What I see is that during the execution of OTIR (21 cycles), memptr (wz) takes two different values:
- cycle 14: WZ := BC + 1
- cycle 18: WZ := PC (the address after the ED prefix)
Currently the Z80 decoder always sets WZ to BC + 1.
However, I think it's impossible to ever observe the intermediate value. Even if you interrupt the OTIR instruction (with either NMI or INT) then WZ is updated with the address of the interrupt handler.
If it's impossible to observe this behaviour, then I don't think this will ever cause a modelling failure in Z80 Decoder.
I've thought of a way to observe this value....
Using IM 0, putting opcode E9 [ JP (HL) ] on the bus during the Int Ack cycle.
Here's an example of this: Visual Z80
At the end of this test, WZ has the value 000B which is the second byte of the OUTI instruction.
So I will fix this in the Z80 Decoder.
I expect this behaviour (WZ := PC + 1 when the block instruction does not terminate) is common to all of the block instructions.
Using IM 0, putting opcode E9 [ JP (HL) ] on the bus during the Int Ack cycle.
nice find!
i've observed the issue in the z80 core i'm hacking on (
rofl0r/generator@b194608 )
when running it side-by-side with @floooh's cycle-stepped z80 and comparing the register values after every single instruction executed.
Here's a trace that flags a failure due to this issue:
???? : 00 : NOP : 19/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=???? IR=???? IFF=?? IM=?
???? : 00 : NOP : 4/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=???? IR=???? IFF=?? IM=?
???? : C3 04 00 : JP 0004h : 10/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=?? IM=?
0004 : ED 46 : IM 0 : 8/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=?? IM=0
0006 : FB : EI : 4/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=11 IM=0
0007 : 21 20 00 : LD HL,0020h : 10/ 0 : A=?? F=???????? BC=???? DE=???? HL=0020 IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=11 IM=0
000A : 01 01 FF : LD BC,FF01h : 10/ 0 : A=?? F=???????? BC=FF01 DE=???? HL=0020 IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=11 IM=0
000D : ED B3 : OTIR : 23/ 0 : A=?? F=S V BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
000D : E9 : JP (HL) : 4/ 0 : A=?? F=S V BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
0021 : CB 46 : BIT 0,(HL) : 12/ 0 : A=?? F= YHX BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
0023 : 00 : NOP : 4/ 0 : A=?? F= YHX BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
0024 : F5 : PUSH AF : 11/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0 : fail
0025 : 00 : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
0026 : 00 : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
0027 : 76 : HALT : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
0028 : : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
0028 : : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=FE02 IR=???? IFF=11 IM=0
And here's it after this issue is fixed:
???? : 00 : NOP : 19/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=???? IR=???? IFF=?? IM=?
???? : 00 : NOP : 4/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=???? IR=???? IFF=?? IM=?
???? : C3 04 00 : JP 0004h : 10/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=?? IM=?
0004 : ED 46 : IM 0 : 8/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=?? IM=0
0006 : FB : EI : 4/ 0 : A=?? F=???????? BC=???? DE=???? HL=???? IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=11 IM=0
0007 : 21 20 00 : LD HL,0020h : 10/ 0 : A=?? F=???????? BC=???? DE=???? HL=0020 IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=11 IM=0
000A : 01 01 FF : LD BC,FF01h : 10/ 0 : A=?? F=???????? BC=FF01 DE=???? HL=0020 IX=???? IY=???? SP=???? : WZ=0004 IR=???? IFF=11 IM=0
000D : ED B3 : OTIR : 23/ 0 : A=?? F=S V BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
000D : E9 : JP (HL) : 4/ 0 : A=?? F=S V BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0021 : CB 46 : BIT 0,(HL) : 12/ 0 : A=?? F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0023 : 00 : NOP : 4/ 0 : A=?? F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0024 : F5 : PUSH AF : 11/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0025 : 00 : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0026 : 00 : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0027 : 76 : HALT : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0028 : : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
0028 : : NOP : 4/ 0 : A=55 F= H BC=FE01 DE=???? HL=0021 IX=???? IY=???? SP=???? : WZ=000E IR=???? IFF=11 IM=0
The JP (HL) a 000D is actually a IM0 interrupt with E9 put on the bus.
More work is needed to properly handle IM0 interrupts where the opcode is something other than RST. I've created a seperate issue for this (#3).
This trace was generated from the z80otir test case in Perfect Z80:
https://github.com/hoglet67/perfect6502/blob/Z80/z80otir.c
This trace was generated from the z80otir test case in Perfect Z80:
https://github.com/hoglet67/perfect6502/blob/Z80/z80otir.c
thanks for this useful hint. i'm currently using this as an example to trace an inir test program, though the trace produced with -t is binary. which program do you use to transfer the trace into a readable output like you pasted above ?
The Z80 Decoder (in this very repository!)
oh haha thanks :)
trying to figure out why it seems visualz80 doesn't modify F at all after first iteration of inir
http://www.visual6502.org/JSSim/expert-z80.html?a=0&d=31000401FFFFC5F1017F03210002EDB27600&graphics=false&logmore=a,f,bc,hl,wz&steps=200