1 extra cycle added when OUTing to VDP (on some cases)

Page 1/3
| 2 | 3

By Overflow

Resident (57)

Overflow's picture

08-12-2014, 10:22

Hello guys.

Since a few weeks, I'm trying things on msx.
And I'm lacking much knowledge about msx.
So here am I!

Let's see this with an example: OUT(#99),A takes 12 cycles.
But when tested on some machines, it takes 13 cycles.
Some machines are:
- a real MSX turbo R, booted @50Hz and z80 forced
- MSX turbo R on emulators
- MSX2+ on BlueMSX... but on openMSX it's still 12 cycles!? WTF?
- my remote friend also managed to get 12 cycles on his real MSX turbo R!?!?

I remember some thread I can't find back.
Does it deal with "slowing down" hardware which can get an overclocked cpu?
(I mean: that extra cycle may be there to slow down access to the vdp (I try to guess))
Anyway: on which cases do we have such extra time lost when outing to the vdp?
Is there a way to disable it (when forcing the z80 at is original speed)?

Thanks for reading!
Oliverflow

Login or register to post comments

By Overflow

Resident (57)

Overflow's picture

08-12-2014, 16:04

Hi again,

Since this morning, I found this: "waitstate generator".

http://www.msx.org/wiki/Compatibility_testing
V9958 has a built-in waitstate generator that can be enabled by software
bit 2 "WTE" of the V9958's R#25

doc V9958
When the CPU accesses the VRAM, accesses to all ports on V9958
is held in the WAIT state until access to the VRAM of V9958 is completed.

http://www.msx.org/forum/msx-talk/hardware/does-enabling-wai...
(...) so there is one cycle of cpu clk

Finally, I'm going to test this (z80 enabled, neither R800 nor overclocking z80):
VDP(25)=VDP(25)and251

Am I right? dunno!

By Grauw

Enlighted (8084)

Grauw's picture

08-12-2014, 16:41

Hi Overflow, welcome.

The V9958 wait state generator is not used on most computers. Only some CIEL turbo circuit I think actually uses it. Panasonic FS-A1 WSX, ST and GT all implement the throttling in the engine, and only when turbo mode is enabled I think (but maybe it’s always active).

Are you sure it takes 13 cycles? How do you measure it?

By Overflow

Resident (57)

Overflow's picture

08-12-2014, 22:27

I'm back!

What I'm talking about is explained there:
http://www.msx.org/forum/msx-talk/hardware/vdp-speed-curious...
Briefly: yes, on MSX2+ and MSX turbo R when z80 enabled at its original speed,
OUTs take "a bit" more time than on MSX1 or MSX2.
I did not write "a bit" but exactly one extra cycle on each OUT.
Measurement thru openMSX confirms 13 cycles for OUT(#99),A
See below, if needed, for détails.

That said, my remote friend was able to boot/configurate his Panasonic FS A1-WSX
to then behave like a standard MSX: getting 12 cycles on OUT(#99),A
My question: technically speaking, how? any idea?
I now understand that the V9958 wait state generator is not used there.
So? that extra wait cycle is generated by the MSX-engine, isn't it?
I still haven't found much about them (T9769B or T9769C),
I'm OK with port #40 and #41 to overclock the z80 on Panasonic msx2+,
but is there any other port (or any other mean) to enable/disable that extra-cycle on OUT?

----

I like to count cycle, so I count them thru openMSX.
I wrote my own command:
t0 to reset cycles counter,
dt to see how many cycles since the reset.

Prereq:
variable old_time 0

New commands:

proc t0 {} {
	set machineid [machine]
	set err [catch {set mtime [${machineid}::machine_info time]}]
	if {$err} {
		return ""
	}
	set cpu [get_active_cpu]
	set cycle_freq [expr {[machine_info ${cpu}_freq]}]
	set t [expr {$mtime * $cycle_freq}]
	set dt "t="
	append dt [format "%18s" [expr {$t -$::old_time}]]
	append dt "\n                              | "
	set ::old_time $t
	return $dt
}
proc dt {} {
	set machineid [machine]
	set err [catch {set mtime [${machineid}::machine_info time]}]
	if {$err} {
		return ""
	}
	set cpu [get_active_cpu]
	set cycle_period [expr {1.0 / [machine_info ${cpu}_freq]}]
	set t [expr {$mtime / $cycle_period}]
	set dt ""
	append dt "t=     "
	append dt [format "%20s" [expr {$t -$::old_time}]]
	append dt "\n                               | "
	return $dt
}

By Grauw

Enlighted (8084)

Grauw's picture

08-12-2014, 23:49

Z80 user manual says OUT is 11 cycles, however the MSX-ENGINE adds extra M1 waits for instructions, as described here and on page 30 of the Z80 user manual. With this included it should be 12 cycles.

It does also say on page 14 of the Z80 user manual that an extra wait cycle is added by the Z80 to in/out instructions, however as far as I know (studying the timing diagram) this should be included in the 11 cycles quoted by the manual, which you also found on the real MSX. Maybe turboR adds another one, or you miscalculated the timing?

I know just the other day I did a experiment (rom link) with PSG generating a pulse wave with duty cycle. In that experiment the MSX has to output volume changes in sync with the PSG, and the timing only worked correctly when I assumed 12 cycles for out instructions (tested on Yamaha CX5MII). Just a single cycle offset and it starts modulating audibly.

Though, running it on openMSX, there is some slight modulation present, so it seems that openMSX is off by a fraction of a cycle. Note that even if I deduct or add a cycle, it never becomes stable. Could be a little openMSX bug in PSG timing, or Z80 timing.

By sd_snatcher

Prophet (3014)

sd_snatcher's picture

09-12-2014, 21:51

It isn't advisable for user software to change the V9958 built-in waitstate settings. From the wiki article:

Quote:

For the bit-0, the issue is that the V9958 has a built-in waitstate generator that can be enabled by software. But this is a specific feature that must be implemented on a per-machine basis. Enabling it by yourself can cause problems on some machines that doesn't have the necessary circuit, and disabling it on machines that have the circuitry will also cause problems on turbo mode.

One characteristic of the MSX standard is that you cant count on a given VDP I/O speed. Different machines will have different speeds, depending on their design. The MSX wasn't designed for "running against the raster" style of programming.

By hit9918

Prophet (2853)

hit9918's picture

10-12-2014, 03:45

@sd_snatcher, a nice dream but it doesn't work.
tell for how many Mhz shall I code the VDP delay. ok let's be safe and do it for the hypothetical nice 28Mhz.
meanwhile users machines crawl.

the standards are
the 3.57mhz z80 M1 standard
the 9918 standard
the 9938 standard
Smile

I hope those 2+ dont do the 13 cycles thing in 3.57mhz mode.

By hit9918

Prophet (2853)

hit9918's picture

10-12-2014, 23:04

e.g. hblank is so late that I get the first effect on the left pixels of display area, horrors. Together with jitter it is 50 pixels into the screen.
Need timed cpu wait to ge to the right side to do something outside display area.
And every turbo is a new unknown thing asking special code for it...

I first sync on hblank and then afterwards check whether there actualy is a line interrupt. Then between interrupt and hblank fits quite some code, i.e. app code can have quite some DI zone without messing the line interrupt.
I got realtime OS things in mind Smile

I added some IN 0x99 and the TR with slow VDP brake ends up taking roughly same time for the whole code as z80.
At that point I wondered whether VDP acess was made so slow that the average line interrupt code still works LOL!
And then one can set one VDP register and then one is back into display area.
It needs much ado but one can have tidy splits.

By sd_snatcher

Prophet (3014)

sd_snatcher's picture

11-12-2014, 00:06

hit9918 wrote:

@sd_snatcher, a nice dream but it doesn't work.
tell for how many Mhz shall I code the VDP delay. ok let's be safe and do it for the hypothetical nice 28Mhz.
meanwhile users machines crawl.

If the idea is not to overrun the VDP, then you should code with 3.57MHz in mind. Faster machines always must include some form of speed throttling (waitstates, lower clock, and/or so on) to make sure that no data will be lost.

But a completely different idea is to code taking for granted that the OUT will take time equivalent to 12 cycles of 3.57MHz, for example to change a certain part of the screen while it's being drawn to achieve a certain timed effect. This is the "racing against the raster" kind of programming that is very usual on C64 and ZX-Spectrum, but that will not work reliably on MSX because the machine just wasn't designed for this.

Quote:

I hope those 2+ dont do the 13 cycles thing in 3.57mhz mode.

That's the point, Panasonic and Sanyo ones will do, as it was proven in this thread.

Sony MSX2+ machines, OTOH, will show VRAM corruption in many situations if you access the VRAM too fast. As a proof, just run SimCity on one of them and you see what I mean.

By Grauw

Enlighted (8084)

Grauw's picture

11-12-2014, 09:42

sd_snatcher wrote:
Quote:

I hope those 2+ dont do the 13 cycles thing in 3.57mhz mode.

That's the point, Panasonic and Sanyo ones will do, as it was proven in this thread.

Could you point to the specific post? I’m curious.

Note btw that in my experiment I mentioned above, I was not outputting to the VDP.

By hit9918

Prophet (2853)

hit9918's picture

11-12-2014, 15:33

I wonder what it is about. An OUT with 1 cycle more, at 5.4Mhz it still is much too fast for VDP.

Page 1/3
| 2 | 3