MZ-700 demos

Is there such a thing as an MZ demoscene?
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

The cycles I gave are in CPU cycles so yeah 82-83 is indeed close to BLNK with 80 cycles.
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

@Sdw

I read the source and can explain the trick it uses:

1) wait for vertical blanking to be gone
2) wait for first horizontal blanking to be gone
3) push 8 bytes in VRAM <--- first PUSH will wait until BLNK=1
4) run some cycles through several instructions according the number of cycles you select
5) push the last two bytes. <--- that's the key! the result in the screen will be different there if too much spent cycles inside the BLNK period.
6) invert the bit of the next bytes to push in VRAM
7) goto 1) eight times to draw 8 lignes with alternate vertical lines if cycles is enough

Now, even corrected with my numbers gotten from my logic analyzer, I got a weird limit : it works until I reach 91. It shouldn't as I set to 80.

There is definitely something fishy about the way to handle that stuff...
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

Oh I know! it accepts one PUSH while the genuine MZ-700 won't accept it! Emulator CPU is not blocked upon the right PUSH but on the next PUSH so you get an extra 11 cycles (PUSH costs 11 cycles) to transform a 80 into 91 limit. Gosh!
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

Genuine MZ-700:

Code: Select all

  Wait for BLANK==1 ---> First PUSH is blocked and so it and the rest are countable in the 80 cycles (what my logic analyzer gives me)
    |
    v
[PUSH:11][PUSH:11][PUSH:11][PUSH:11][...:n-44][PUSH:11]
PAL EmuZ-700:

Code: Select all

  Wait for BLANK==1 ---> First PUSH is executed and then set /BUSREQ to 0 because it tries to access VRAM whan BLANK==0
    |
    |      Second PUSH is now blocked and so it and the rest are countable in the 80 cycles
    |        |
    v        v
[PUSH:11][PUSH:11][PUSH:11][PUSH:11][...:n-44][PUSH:11]
Now why the genuine MZ-700 can accept 83 cycles while the logical analyzer says the BLANK is 80 cycles? In fact when you execute a PUSH, you have 4 cycles in fetching the opcode which is not blocked by the /WAIT state. So I think we have up to 83 as 80 + 4 - 1.
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

@Sdw

I believe the way how the emulators are emulating Z80 and their /WAIT states is the main issue here. They handle them inside the instruction as if those /WAIT states are known in advance (it is true that when you want to access ROM in MZ-700, we know we should add 1 extra cycle due to an inserted /WAIT state). But the interpreter cannot handle an unknown amount of /WAIT states when inside the MEMR/W step of an instruction.

To handle it correctly, we need to know how many cycles remain until reaching BLANK==1 to give it as the amount of /WAIT states inside the MEMR/W step of the instruction.
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

@Sdw

As you said 82 cycles was the max working I had a doubt. So I tried `wt` on my genuine MZ-700.

83 is the max working (phew!)
IMG_20200712_190021.jpg
Higher than 83 shows a permanent disruption.
IMG_20200712_190021.jpg
So that confirms my equation: N cycles are working if N - 4 < 80. For NTSC, it should be N - 4 < 60.

Now let's compute for a PAL genuine MZ-700:

21000000 / (312 x 83 x 50) ~= 16.2ms

Now let's compute for a PAL EmuZ-700 (`wt` gives me 91 as the highest accepted value):

21000000 / (312 x 91 x 50) ~= 14.8ms (I rather got 13ms on my chronometer)

On PAL EmuZ-700:
Now temporaly removing 11 (PUSH INSN) - 4 (PUSH OPCODE FETCH) cycles in BLNK period to mimic the genuine MZ-700 when executing wt.
-> it does behaves the same as genuine MZ-700 with `wt`.

But if I want to test with `emutest`, I must handle LDIR instead of PUSH so now removing 21 (LDIR INSN) - 4 (LDIR OPCODE FETCH) when executing `emutest`.
-> Bingo! 16ms!
Attachments
IMG_20200712_190010.jpg
Sdw
Posts: 12
Joined: Wed Jul 08, 2020 10:27 am

Re: MZ-700 demos

Post by Sdw »

It's interesting that you machine is stable at 83 cycles, I get stable no-bug at 82, but flickering bugs at 83 already.

Anyway, what I gather from your investigations is that:

1) Emulator had wrong number of free cycles from the begining (91 vs 82/83)
2) Even with corrected number of cycles, it will not work properly, since Z80 is emulated at an instruction level, and the locks can happen on individual T-states within the instruction. You have verified this by hardcoding a static decrease in the number of available VRAM-cycles that corresponded to the test program you wanted to run.

If haven't looked at the source code yet, but how is the Z80-emulation vs. VRAM-locks handled? Perhaps some kind of look-ahead could be added, instead of checking "are we in a VRAM-locked state" before running the instruction, do a "will the number of cycles this instruction takes put us in VRAM-locked state".
Maybe I'm just rambling, I probably should check that source first! :)
Attachments
Unstable @ 83
Unstable @ 83
IMG_20200713_145853.jpg (193.41 KiB) Viewed 2263 times
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

@Sdw

1) The registered free cycles is 80 which is correct if compared with the logic analyzer. We get 91 free cycles IF the locking instruction is a PUSH, it would be 101 cycles with LDIR I think. Those higher free cycles are due to the way how /BUSREQ works under emulator instead of using /WAIT states which cannot be handled properly through the emulator anyway. So let's say you're correct.

2) Correct. The real lock does happen on individual T-states - specifically the one envolving a memory access. The emulator handles it in instruction level through /BUSREQ as it cannot do through /WAIT states which are always handled in instruction level by the emulator with a known value.

I tried several changes:

A) Try to fetch the number of cycles it needs to allow the locked instruction to execute. Failure so far but I will retry as I think I have more insights now. It means you need to know how many cycles the current instruction executes plus the remaining cycles until the BLANK event (look-ahead) minus 3 cycles due to opcode fetching which is not locking.

B) Try to adjust the free cycles when executing a locking instruction which set /BUSREQ=0 when accessing VRAM by adding the instruction cycles minus 3 to make the same thing as in 2) but dynamically. Failure so far as I think the adjustement is done too late because the BLANK event is already handled (it runs several instructions until the end of the event so the count is comuted BEFORE the dynamical adjustement).

It's quite demotivating up to now.
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

@Sdw

Have you a way to check with other screens? I believe your CRT is a little pricky to accept the MZ-700 video timing. My assumption is as long as you are not trying messing on raster line level, you won't see any flickering. Remember I got my cycles from MZ-700 video timings through a logic analyzer under no display constraint, which is quite a strong assertion of what they should be. What a CRT can accept is another issue.
hlide
Posts: 508
Joined: Thu Jan 25, 2018 9:31 pm

Re: MZ-700 demos

Post by hlide »

Oh I just realized the case where you execute a code in VRAM. There is a memory fetch in the opcode fetch so any instruction will be locked pretty much instantaneously. That makes the changes harder if possible.
Post Reply