Can this be done to wait VSYNC?

Page 1/2
| 2

By DarkSchneider

Paladin (965)

DarkSchneider's picture

11-04-2014, 11:36

The idea is to do something like:

loop
  ... Do the work here ...

  ei ; for safety, maybe something did DI
  halt ; wait for interrupt (VDP)
  jp loop

I have tested it on a simple program and it works, so if the loop period is shorter than V-preiod is fine. The question is what will happen if loop period is longer than v-period.

Login or register to post comments

By Manuel

Ascended (19270)

Manuel's picture

11-04-2014, 11:40

Why don't you just put your work on the ISR then?

By DarkSchneider

Paladin (965)

DarkSchneider's picture

11-04-2014, 11:57

I think you means the famous "hook", am I right?

Because PC inheritance, many people (including me) are used to use this method (i.e. OpenGL in C++) so I'd want to know if on MSX ASM can be translated in a similar way.

By snout

Ascended (15187)

snout's picture

11-04-2014, 13:33

It can and AFAIK there's nothing wrong with it. Think we did that in No Pressure as well...

By NYYRIKKI

Enlighted (6016)

NYYRIKKI's picture

11-04-2014, 14:02

This is ok as long as you don't have other interrupt sources than VDP... (Ie. MSX tR MIDI or MSX-Audio sample interrupts)
If loop period is longer than v-period you will get half speed (as default ISR will handle the pending interrupts anyway)

By DarkSchneider

Paladin (965)

DarkSchneider's picture

11-04-2014, 15:36

Then that is OK as it is the desired behaviour. No intention to use MSX tR MIDI or MSX-Audio samples at this moment. They generate interrupts even if they are not used? And in affirmative case, there is a way to disable then? (I mean MSX tR MIDI or MSX-Audio sample interrupts only).

By hit9918

Prophet (2927)

hit9918's picture

11-04-2014, 15:39

I think it is common practice that an expansion should not make interrupts when it was never used.
But you could check whether the bios timer value has increased by one. That only happens on vblank interrupt.

Such game loop is solid with game slowdowns. In an interrupt server, when the game takes longer than a frame, bios does nasty things. bios does enable interrupts early. the thing ends up in stack overflow.

I advice to put music still into interrupt server: then music doesnt slow down even when the game slows down.

By hit9918

Prophet (2927)

hit9918's picture

11-04-2014, 15:44

Trying to disable expansions interrupts is not so good way.
Because the MSX has dozens expansions the coder doesnt know.
Just checking for bios timer value to change, that should do it.

By DarkSchneider

Paladin (965)

DarkSchneider's picture

11-04-2014, 17:54

Sorry I don't know what is that bios timer (noob yet Big smile )

Could I read the VDP status register S#0? In this way:

loop
  ... Do the work here ...

wait_vblank
  ei ; for safety, maybe something did DI
  halt ; wait for interrupt (VDP)
  if(S#0 bit 7 is 0) GOTO wait_vblank ; interrupt other than vblank, then wait again (this part in pseudo-BASIC sorry)
  jp loop

Question, how can I read S#0 on MSX1? I got it, only needed

  in a,(#99)

By DarkSchneider

Paladin (965)

DarkSchneider's picture

11-04-2014, 18:07

Ok the previous doesn't work, it seems that the halt reads S#0 so if you want to read later it is gone. At this moment I have 2 methods to wait VSYNC:

Method #1

loop
  ... Do the work here ...

  ei ; for safety, maybe something did DI
  halt ; wait for interrupt (VDP)
  jp loop

Method #2

loop
  ... Do the work here ...

wait_vblank
  di ; if I set EI it runs slow ??
  in a,(#99) ; read S#0
  and #80 ; flag F
  jr z,wait_vblank ; if 0, go to wait_vblank
  jp loop

I don't understand well why I have to disable interrupts in method #2.

In the other hand, tested method #1 on BlueMSX in TurboR mode with MIDI and MSX-Audio and seems to work fine (at least on BlueMSX). So I think that really they don't generate interrupts if not used, so they are not a problem in my case.

By hit9918

Prophet (2927)

hit9918's picture

11-04-2014, 21:24

the bios interrupt server does in 99, it does consume the VDP event, that is why you had issues with some versions

further on MSX1 real machine, reading IN 99 outside interrupt code sometime misses the event.
because VDP wanted to update the same time as IN 99 did clear the event.
so then only an IN 99 in the interrupt code is reliable, because it reliably is done after the event.

in the end maybe best for what you want is this:
poke to 0xFD9A hook a jump to your interrupt code. then:

int:
	in a,(0x99)	;consuming event, bios thinks that no VDP interrupt happened
	and 128
	ret z

	ld hl,(mytimer)
	inc hl
	ld (mytimer),hl
	
	call music player
	ret

the wait in gameloop:

	ei
	ld de,(mytimer)
waitvbl:
	ld hl,(mytimer)
	and a
	sbc hl,de
	jp z,waitvbl

this way some bios services no more work like ascii keyboard functions.
and bios timer variable not incremented, so have your own.

to keep bios services, poke the jump to int: to 0xFD9F hook.
and remove the IN 99 / AND / RET Z instruction, because with that hook, bios handles it.

Page 1/2
| 2