z80 emulation in fuse "emulates" active /M1 only on first byte of instruction. because of that it is not possible to return to BASIC from NMI routine in T-BIOS firmware for divide (divide memory is not unmapped on return)
T-BIOS uses for return from NMI routine RETN at address 0x1FF7. 0x1FF7 is not in unmapping area, but second byte of RETN is at 0x1FF8 which is unmapping point. RETN is prefixed instruction and on real z80 for prefixed instructions is /M1 active not just on fetch of first byte of instruction (prefix), but also on fetch of second byte (main code of instruction).
How to reproduce:
1) download&unzip T-BIOS: https://divide.speccy.cz/files/tbios14.zip
2) start fuse
3) enable divide and disable write protect
4) enter usr0 mode (if using 128k machine)
5) load tbiosv14.tap, let flash it to divide
6) enable write protect
7) reset spectrum
8) press NMI: spectrum freezes
(if you want to play more with T-BIOS, here is example of content for dithvide and divideo players implemented in T-BIOS: https://divide.speccy.cz/files/divIDE-DithvIDE-Divideo-examples.zip , in the package is also info.txt with list of controls)
To confirm information found on internet (http://www.primrosebank.net/computers/z80/z80_special_reset.htm , part "(Nov 22, 2016) Anonymous", regarding double prefixed instructions and /M1) I've designed and prototyped small device, which counts /M1 activated by z80. If you are curious here is schematic:
https://sindik.at/~ub880d/images/article_13/M1hunter_lite.png
It counts /M1 when executing code in range 0x8000-0x80FF, so put your test instructions there and put RET at 0x8100 (/M1 of that RET won't be included in the result), then reset counters by pressing microswitch and then run your test program.
--
Attached patch will fix this issue for divide and divmmc (though T-BIOS is for divide only), but I'm not really happy with it, because it would need to be fixed for more devices (every device which uses /M1 of cpu, or at least those for which is possible to use custom rom) and that might mean all CHECKS needs to be listed 5times. Maybe all early/late CHECKS should be moved to new 2 routines (one for early mappings and second for late mappings) and then call them from all 5 places instead.
I've made second patch, which should work for every device
This patch works as I wrote at the end of the ticket description just with a small change. Instead of having 2 functions I've put it to one with parameter describing which part should run.
small modification of previous patch, I forgot that from "evenm1" check should be possible to exit execution loop and with previous patch it would only exit from "evenm1" check and execution will continue.
Hi ub880d,
There are a few commented out lines in your patched code - do you need to make any more changes?
Phil/Sergio: do you see any issues or particular tests that should be run for this one?
hi,
if you are ok with the patch (the way how the issue is fixed) then i would maybe leave there just one comment, which is describing purpose of the return value.
so to remove:
+//static libspectrum_byte opcode2 = 0x00;
+// libspectrum_byte opcode2 = 0x00;
+// opcode_delay:
+// run_opcode:
leave in code:
+ return 1; //to exit execution loop in z80_do_opcodes()
do you want me to create new patch or it is enough to describe it like this?
I don't feel super comfortable with changing the z80 core which is why I am asking for other opinions on the patch as I'd hate the work to go to waste :)
Sorry, I'm not familiar enough with Z80 to propose anything specific. RZX tests might help, but don't stress peripherals.
It seems there is something wrong with fuse_prefixed_instructions_mappings2.patch. I've tested over 5000 RZX files from RZX Archive and I got 92% of unexpected failures, e.g., try to play Arithmetic Tutor. The program works well from tape, though.
Hi,
thanks for the test. Now I've found there is also break of the execution loop in case of rzx end of frame. Here is changed patch (also with comments we discussed earlier removed). To me with this patch, Arithmetic Tutor works.
Thanks. I've tested fuse_prefixed_instructions_mappings3.patch over 2000 RZXs and everything is back to normal.