The assign registers command (r) somehow repeats the current instruction when the command is used.
some examples:
(C:$e5cf) break 1000
BREAK: 1 C:$1000 (Stop on exec)
(C:$e5cf) break e147
BREAK: 2 C:$e147 (Stop on exec)
.C:1000 EE 20 D0 INC $D020
.C:1003 60 RTS
here, INC $D020 is executed twice when using the assign registers command:
#1 (Stop on exec 1000) 16/$010, 17/$11
.C:1000 EE 20 D0 INC $D020 - A:00 X:00 Y:00 SP:f7 ..-..... 13150889
(C:$1000) r a = ff
(C:$1000) x
#1 (Stop on exec 1000) 16/$010, 23/$17
.C:1000 EE 20 D0 INC $D020 - A:FF X:00 Y:00 SP:f7 ..-..... 13150895
(C:$1000) x
#2 (Stop on exec e147) 16/$010, 35/$23
.C:e147 08 PHP - A:FF X:00 Y:00 SP:f9 ..-...Z. 13150907
(C:$e147) chis 4
.C:e144 6C 14 00 JMP ($0014) A:00 X:00 Y:00 SP:f7 ..-..... 13150884
.C:1000 EE 20 D0 INC $D020 A:ff X:00 Y:00 SP:f7 ..-..... 13150889
.C:1000 EE 20 D0 INC $D020 A:ff X:00 Y:00 SP:f7 ..-..... 13150895
.C:1003 60 RTS A:ff X:00 Y:00 SP:f7 ..-...Z. 13150901
(C:$e147)
.C:1000 E8 INX
.C:1001 8E 20 D0 STX $D020
.C:1004 60 RTS
here, INX is executed twice, but x remains unchanged the first time:
#1 (Stop on exec 1000) 268/$10c, 16/$10
.C:1000 E8 INX - A:00 X:00 Y:00 SP:f7 ..-..... 11672908
(C:$1000) r a = ff
(C:$1000) x
#1 (Stop on exec 1000) 268/$10c, 18/$12
.C:1000 E8 INX - A:FF X:00 Y:00 SP:f7 ..-..... 11672910
(C:$1000) x
#2 (Stop on exec e147) 268/$10c, 30/$1e
.C:e147 08 PHP - A:FF X:01 Y:00 SP:f9 ..-..... 11672922
(C:$e147) chis 5
.C:e144 6C 14 00 JMP ($0014) A:00 X:00 Y:00 SP:f7 ..-..... 11672903
.C:1000 E8 INX A:ff X:00 Y:00 SP:f7 ..-..... 11672908
.C:1000 E8 INX A:ff X:00 Y:00 SP:f7 ..-..... 11672910
.C:1001 8E 20 D0 STX $D020 A:ff X:01 Y:00 SP:f7 ..-..... 11672912
.C:1004 60 RTS A:ff X:01 Y:00 SP:f7 ..-..... 11672916
(C:$e147)
setting PC to new address, or using goto command (g) does this:
#1 (Stop on exec 1000) 167/$0a7, 36/$24
.C:1000 EE 20 D0 INC $D020 - A:00 X:00 Y:00 SP:f7 ..-..... 10506861
(C:$1000) r pc = 1003
(C:$1000) x
#2 (Stop on exec e147) 167/$0a7, 48/$30
.C:e147 08 PHP - A:00 X:00 Y:00 SP:f9 ..-..... 10506873
(C:$e147) chis 3
.C:e144 6C 14 00 JMP ($0014) A:00 X:00 Y:00 SP:f7 ..-..... 10506856
.C:1003 60 RTS A:00 X:00 Y:00 SP:f7 ..-..... 10506861
.C:1003 60 RTS A:00 X:00 Y:00 SP:f7 ..-..... 10506867
(C:$e147)
so it seems the instruction at the current (or new) address is "executed" two times (looking at the cpu history) but it is actually only really executed the second time, when this instruction is one that changes one of the registers or the PC.
also see this bug, looks like it describes the same issues:
https://sourceforge.net/p/vice-emu/bugs/2024/
This may just be a bug in the chis feature. But yeah, its weird
OK first experiment shows:
- the problem exists in both GTK and SDL version, so this isn't some weird issue related to threading (THANK GOD)
the history is wrong, but the instruction is not actually executed twice (GOOD!)It IS executed twice. Bummer
Last edit: gpz 2024-05-02
doesnt even need a breakpoint apparently, just "enter monitor":
enter monitor, r a=ff, z ... last instruction will be "executed" (but not really =P)
so somehow the order of events (enter monitor, modify registers, continue) screws it up
... and it also happens in xscpu64, which doesn't have a chis implementation at all.
it seems to be a very old bug, and it seems NOT to be related to "cpu history". i could reproduce the first example even in the 1.9 release (which doesn't have cpu history at all)
wth, noone noticed this, ever? :D
Last edit: gpz 2024-05-02
Just so it wont get forgotten and maybe someone else can pick it up... the problem is likely related to how the registers are "exported" and "imported" before entering/after leaving the monitor. Unfortunately this is really non trivial and very old code, which is seriously lacking comments (of course, in good VICE tradition), so its hard to track down.
It would help if we could come up with a test/example that reproduces the problem only by entering/exiting the monitor and does not involve breakpoints
Also the instruction IS actually executed twice, which is really fatal and a big problem :(
I was just about to write a ticket on this (split out from #2024).
This instruction-duplication can also be reproducted without "r", but with "g XXXX" and a breakpoint. For example:
and
If you type
m 0400
, you can see that address $0400 contains $22 instead of $21If you type
cpuhistory
, you can also see that it's duplicated in the CPU-historyEDIT: It seems like you just have to SET a breakpoint, you don't have to actually break at it, for this to happen. If you instead of
break exec c003
write some random address likebreak exec 4000
, the instruction-duplication still happens afterg c000
.But if you between
break exec 4000
andg c000
exit the monitor and enter it again, it doesn't happen. So it looks a bit like a breakpoint has to have been made (or touched or something) in the current monitor-session..?Last edit: Algorithmix 2024-05-02
Found this:
- set a break point (does not even have to be enabled)
- execute any 'r' command
and then do a reset immediately (from the monitor)
this will now make Vice lock up(?) (until you reset again).
note that you can enter the monitor and you'll see that the program is still running!
If you can build yourself, please try this horrible patch:
It seems to remove some of the problem at least (perhaps all?) - but i don't know what it might break.
i did try ist. and indeed it looks this "horrible hack" fixes the 3 initial posted probs, plus the other two as well. the 5 cases:
break 1000
break e147
a 1000
INC $D020
RTS
sys 4096
r a = ff
chis 4
break 1000
break e147
a 1000
INX
STX $D020
RTS
sys 4096
r a = ff
chis 5
break 1000
break e147
a 1000
INC $D020
RTS
sys 4096
r pc = 1003
chis 5
break 1000
r a = ff
reset
a c000
inc $0400
jmp $c003
break exec c003
g c000
m 0400
chis 2
seem to work as expected.
BUT i am a complete n00b when it comes to stuff like this, i only followed the instructions.
attached a pic of the last case.
Last edit: Querino 2024-05-03
cool, that is encouraging at least :) I still have not understood why
is still required after inserting the other EXPORT_REGISTERS() invocations, which is why i did not yet commit. Will look at this a bit closer then :)
i have comitted a more sane version of that patch in r45151 - please test, not only if the problem is solved, but also if everything related to R and G commands, and entering/exiting the monitor, still works as before :)
So, as a first step to get these things under control i knocked up the beginning of a test bench for the monitor: https://sourceforge.net/p/vice-emu/code/HEAD/tree/testprogs/Monitor/testbench/
Refer to the included readme for details, how to add tests etc. Obviously more tests would be good, so feel free to provide some :)
As for this ticket:
- some tests are missing, some of the cases Querino posted need to be added
- if all those pass (on trunk) then this ticket can probably be closed?