help with vdp and out commands timing

Door mzoran

Supporter (13)

afbeelding van mzoran

27-05-2019, 22:10

Hello everyone,
I have rediscovered love for my old MSX 1 and have decided to write a simple game which is coming along slowly.
The emulator of choice for development is openMSX and the target machine MSX 1 with 16k RAM. But I wasn't paying attention and was just running an emulator with a MSX 2 machine thinking everything is the same. Finally trying with MSX 1 I got strange display problems which turned out to be slowness of the VDP and my consecutive use of OUTI statements.
This was sorted out by using the recommended MSX1 routine from
http://map.grauw.nl/articles/vdp_tut.php
This is fine for filling up VRAM but I started working with sprites and needed something to set the position, color and pattern. For test I wrote this code
LD HL, (GRPATR)
CALL VRAM_POS
LD A, 175
OUT (&98), A
LD A, 120
OUT (&98), A
LD A, 0
OUT (&98), A
LD A, 13
OUT (&98), A
This works on MSX2 but not on MSX1. I tried adding a bunch if NOPs to make it work but no luck.
Can anyone please give me a version that will work on MSX1 ?
Thanks

Aangemeld of registreer om reacties te plaatsen

Van Grauw

Ascended (8515)

afbeelding van Grauw

27-05-2019, 23:12

You need to either write during VBlank period (no write speed restriction), or have 29 cycles betweeen each OUT. OUT (n),A is 12 cycles, LD A,n is 8 cycles (see timing Z80 + M1 column). That means you still need 9 more cycles. 2 additional NOPs (10 cycles total) between each OUT should be sufficient.

mzoran wrote:

This works on MSX2 but not on MSX1. I tried adding a bunch if NOPs to make it work but no luck.

Can you decribe exactly what goes wrong?

Van thegeps

Champion (278)

afbeelding van thegeps

27-05-2019, 23:12

your code is too fast. I think you want to send your SAT values to VRAM, right? well you have to set a table in RAM with all the values you need, in the same order as the SAT in VRAM is: 4 bytes for each sprite, so 128 bytes in total. Then you have to load this table address in hl and OUTI your data. Now I'll show you how:

ramsat: equ address of your choice

xor a
out (99h),a
ld a,91 ;1bh or 64
out (99h),a
ld hl,ramsat ;put ramsat address in hl
ld b,128 ;in b the number of bytes to move
to_sat_loop:
outi
jp nz,to_sat_loop

this copy all 128 bytes of your own sat in RAM to the sat in VRAM at the right speed (29 cycles)
in fact outi 18 cycles
jp nz 11 cycles

Van mzoran

Supporter (13)

afbeelding van mzoran

28-05-2019, 07:36

Can you decribe exactly what goes wrong?
well...the sprite is not shown
and I tried with 10 NOPs after each OUT
is there a way to view VDP memory in openMSX ?
I am using MSX debugger which can show only registers

Van mzoran

Supporter (13)

afbeelding van mzoran

28-05-2019, 07:37

thanks, but I am trying to avoid copying from RAM if not needed
a simple OUT for x & y should be working the same on MSX1 and MSX2

Van Grauw

Ascended (8515)

afbeelding van Grauw

28-05-2019, 11:50

It sounds to me like the problem you’re currently having is not related to timing.

The openMSX debugger has various functions to inspect the VDP… Check the View / VDP menu, also you can add a debuggable viewer for the video RAM. And you can “peek” and “poke” in the console.

Indeed carefully check whether everything is set up correctly. E.g. what is VRAM_POS, there is no BIOS routine with that name, is it your own or did you give the BIOS entry a different name? If it’s your own, what does it look like? What screen mode are you in, and how did you select the screen mode?

Van thegeps

Champion (278)

afbeelding van thegeps

28-05-2019, 12:26

Are you writing at the right address? On MSX1 SAT start at 1b00h. But why avoid copying from RAM. It's rivht if you have to use only few sprites, but if you have to use a lot is better update their data in RAM and then move them all to VRAM at once. In this way you can also revert the SAT to avoid 5th sprite limit...

Van mzoran

Supporter (13)

afbeelding van mzoran

28-05-2019, 14:20

Thank you for that. I found the problem using vpeek and vdpreg commands in openmsx console.
I enabled screen2 using a call to CHGMOD assuming that addresses in VRAM will be correctly stored in GRPATR and GRPPAT. I was surprised to find out that GRPPAT did not match the value set in VDP register 6.
Why was this address not correctly initialized by BIOS and why is that working in MSX 2?

Van mzoran

Supporter (13)

afbeelding van mzoran

28-05-2019, 20:08

Nevermind.... I was using control register 14 for VRAM positioning on a MSX1 - it worked but would set R6 to 0 Smile