HBlank Timings

For anything related to VDP (plane, color, sprite, tiles)

Moderators: BigEvilCorporation, Mask of Destiny

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Thu Feb 12, 2009 11:04 am

Snake -> That's exactely what i've done.
Each components are in their own class.
I have a class Genesis wich contains a class for 68k, a class for Z80, VDP, PSG ...
The class Genesis doesn't car how each component work.

Each component are implemented an class interface called "Component".
The only thing a component call do is executing events.
Each components are communicating with his controller, and can ask to him to add event.

So for the VDP we have the class VDP and the Class VDPController.
The Genesis implements all the controller VDPController, PSGController, 68KController ....

At start of each frame, The VDP ask his controller (Class Genesis) to add an event in 3416 cycles (Vdp Clock) called VDP_EVENT_HBLANK. The class Genesis convert the number of cycle into system cycle (also 3416 because clock not divided) and add to his queue.
When processor have executed 3416 system cycles, the class Genesis take the event and send it to the owner component (VDP in that case).

My main loop is unique :-)

So the only thing the Genesis do is take event, send to the component at the good moment and executing processors.

With this solution the code is very clear and we can have very good timings (instruction by instruction).

My emulator isn't as fast as other but code is easy to read and with a solid object model.

All the data are typped in a header and all memory access (READ_WORD, READ_BYTE ...) too.
All Genesis emulation is in a kernel wich is system independant.
All you have to do to use the kernel in a system is redefine some macros in the system.h header file and that's all you can use class Genesis in your software.

that's was for presentation of my work.

PS : Sorry for my bad english :-)

Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake » Thu Feb 12, 2009 11:23 am

Interesting :)

I'll think about this some more at a later stage, it'd be handy because I'm constantly reusing components in different projects, and this would just make it easier. But I also must do this with an extremely minimal overhead, or it defeats the object.

notaz
Very interested
Posts: 193
Joined: Mon Feb 04, 2008 11:58 pm
Location: Lithuania

Post by notaz » Thu Feb 12, 2009 11:39 am

Interesting :)
Yeah, looking forward to see the code.

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Thu Feb 12, 2009 12:37 pm

Eke wrote:
Do delay between Hint and Hblank start is also 36 cycles?
no, I made Hblank, Vcounter jump and Hint starts at the same time, even if it's probably not *exactly* what happen on the real thing but it's easier and does not seem to break anything

more precisely, there is two things to handle with HBLANK: the HBLANK flag which is polled by some games and some register writes during HBLANK period which can affect the current line (which has already been drawn by the emulator)

Does your HCounter table in genesis plus start at Hint?
correct, Hcounter table starts at 0x85 in H32 mode and 0xA5 in H40 mode
again, not sure if this is completely accurate but it works
In the emulator i actually write, if i execute 36 cycles of 68k between Hint and Line rendering, I have glitch (Lotus -> write values to CRAM in start of H-Int function and landstalker -> one line is clipping)
it's because Hint processing takes some time (at least 44 cycles to start the processing) so the cycles executed during Hint routine should be executed AFTER the line rendering, because at that time, the VDP has already latched those values and the CRAM/VSRAM/whatever changes will only occur on the next line


at least, this is what happen with Lotus games, not sure about Landtstalker, I never had any problems with this one, I just know that it requires proper DMA operation somewhere


so, I do NOT execute 36 cycles between Hint triggering and line rendering but instead, I ADJUST the events timing regarding of Hint occurences, do you see the difference ?
So, if i understand, the VDP trigger Hint at the same time that HBlank start but the processor need 44 cycles to start processing?
So :
- The line rendering (ideally) is made at HBlankStart +36 cycles
- The first instruction of HInt processus is made at HBlankStart + 44 cycles, when the line has already been rendered?

Does a 68k processor already need 44 cycles (44*7 = 308 system cycles) to start an interrupt processus or the reason is something else?

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Thu Feb 12, 2009 1:03 pm

So, if i understand, the VDP trigger Hint at the same time that HBlank start but the processor need 44 cycles to start processing?
So :
- The line rendering (ideally) is made at HBlankStart +36 cycles
- The first instruction of HInt processus is made at HBlankStart + 44 cycles, when the line has already been rendered?
yes, it's exactly what I did
but as I said, I can not say for sure this is perfectly correct

this is more probably something like:
HSYNC<-->start of Hblank <-->VDP fetches infos for the line <-->HINT start processing-->VDP starts rendering the line (end of HBLANK)
with some unknown delays between those events

you have to take border (left & right) periods in consideration also

maybe one of our two former genesis programmer here could tell us what timings they were told to use to do fast display modifications during HBLANK ;-)

Does a 68k processor already need 44 cycles (44*7 = 308 system cycles) to start an interrupt processus or the reason is something else?
it's specified like that in the 68k programmer manual, I guess it includes the time necessary to update 68k registers, fetch the interrupt vector address, update the PC, jump to new PC, etc... all 68k internal operations are tied to the clock.

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Thu Feb 12, 2009 1:22 pm

Yes, VDP render line at end of HBLank but in my emulator I must execute my rendering function at HBlankStart + 36 cycles (ideally)?

So I will have that config :
HBlankStart : Trigger HInt
HBlankStart + 36 cycles : render line

Between this event, i can execute 36 cycles of 68k.
IF first instruction of interrupt processus is executed during this 36 cycles, this is a 68k core bug that i must correct because between the moment the H-Int is take by 68k core and the moment of the first interrupt instruction, there must be this delay ...

Then
HBlankStart + 44 cycles : 68 execute first interrupt opcode

In that way I would have no gltch in Lotus for example.

Do you understand?

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Thu Feb 12, 2009 1:29 pm

yes,

I found easier to play with line durations in cycle instead of modifying the 68k core (they usually starts executing instructions as soon as you call the "execute" function, adding interrupt processing cycles at the end)

your approach is better though and gave me some ideas, thanks ;-)

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Thu Feb 12, 2009 1:37 pm

If the delay comes from 68k i think it's better to implement this delay in 68 core?
What kind of idea my approach gave you? ;-)
I will do test tonight and post my results ;-)

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Fri Feb 13, 2009 8:26 am

The first tests i made are ok.
I have a glitch on road rash (the first line at the top of the road).
I searched on the forum and the reason is that border is modified during the line, wich take effect immediately.
the VDP fetch datas on start of the line but I notice 2 access wich take effect on the current line :
- Display ON/OFF
- Border color modify (needs to remap colors but not redraw line !!!)

Are there other access in that case?

If the display is turned off during active scan, the start off the line is drawn and the end is blanking?

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Fri Feb 13, 2009 9:38 am

What kind of idea my approach gave you?
some improved event system and better way to handle interrupt latency, I realised that I've already quite modified the original musashi core interface so there is no reason not to continue ;-)
Are there other access in that case?

If the display is turned off during active scan, the start off the line is drawn and the end is blanking?
not sure about that, but it's possible (see how Kega emulates Sonic 2 vs-mode, especially the end of the separation bar... the display is sometime enabled later in the line... I do not remember the original game doing this however, only some white CRAM dots on the last line)

in genesis plus, I made this possible only during hblank period (including borders)

again, this would require real testing ;-)

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Fri Feb 13, 2009 9:56 am

I notice that in Kega the start of the first line sepration bar is flickering.
Does it happen on real hardware? What's the reason? Display Off some cycle after active line?

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Fri Feb 13, 2009 10:06 am

There's quite a bit of flicker on real HW, but on last line of the separation bar. I don't recall flickering on 1st line... I need to pay more attention.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Fri Feb 13, 2009 10:23 am

mickagame wrote:I notice that in Kega the start of the first line sepration bar is flickering.
Does it happen on real hardware? What's the reason? Display Off some cycle after active line?
on my PAL mega drive 2, I didn't get any blue bar flickering as far as I remember (I used this game quite intensively for aspect ratio comparison with the emulator); only some white dots flickering

what the game does is shutoff the display for a few lines to increase DMA capacity. The CPU is frozen during DMA so the display will be reenabled once it is finish, this is how you get this blue separation bar.

I think that I remember the game was reading the HBLANK flag in the Hint routine to wait before re-enabling display after DMA is finish.

same goes for the start of the DMA which is triggered once the game has disabled the display, on the required line

all of this was handled (display OFF -> DMA -> display ON) is handled in the Hint routine

So this game requires very accurate DMA and Hint/Hblank timings to be displayed exactly like real hardware but, theorically, the DMA operation should be constant in time and the display enabled/disabled in constant intervals...

EDIT:
here's the disassembled Hint :

Code: Select all

 loc_F6E:                                ; CODE XREF: HInt+24j
ROM:00000F6E                 move.w  (VDP_Control).l,d0
ROM:00000F74                 andi.w  #4,d0
ROM:00000F78                 beq.s   loc_F6E
ROM:00000F7A                 move.w  ($FFFFF60C).w,d0
ROM:00000F7E                 andi.b  #$BF,d0
ROM:00000F82                 move.w  d0,(VDP_Control).l
ROM:00000F88                 move.w  #$8228,(VDP_Control).l
ROM:00000F90                 move.l  #$40000010,(VDP_Control).l
ROM:00000F9A                 move.l  ($FFFFEEEC).w,(VDP_Data).l
ROM:00000FA2                 move.w  #$100,(Z80BusReq).l ; D8 ( W)   0: BUSREQ CANCEL
ROM:00000FA2                                         ;           1: BUSREQ REQUEST
ROM:00000FA2                                         ;    ( R)   0: CPU FUNCTION STOP ACCESSIBLE
ROM:00000FA2                                         ;           1: FUNCTIONING
ROM:00000FAA
ROM:00000FAA loc_FAA:                                ; CODE XREF: HInt+5Ej
ROM:00000FAA                 btst    #0,(Z80BusReq).l ; D8 ( W)   0: BUSREQ CANCEL
ROM:00000FAA                                         ;           1: BUSREQ REQUEST
ROM:00000FAA                                         ;    ( R)   0: CPU FUNCTION STOP ACCESSIBLE
ROM:00000FAA                                         ;           1: FUNCTIONING
ROM:00000FB2                 bne.s   loc_FAA
ROM:00000FB4                 lea     (VDP_Control).l,a5
ROM:00000FBA                 move.l  #$94019340,(a5)
ROM:00000FC0                 move.l  #$96EE9580,(a5)
ROM:00000FC6                 move.w  #$977F,(a5)
ROM:00000FCA                 move.w  #$7800,(a5)
ROM:00000FCE                 move.w  #$83,($FFFFF640).w ; 'â'
ROM:00000FD4                 move.w  ($FFFFF640).w,(a5)
ROM:00000FD8                 move.w  #0,(Z80BusReq).l ; D8 ( W)   0: BUSREQ CANCEL
ROM:00000FD8                                         ;           1: BUSREQ REQUEST
ROM:00000FD8                                         ;    ( R)   0: CPU FUNCTION STOP ACCESSIBLE
ROM:00000FD8                                         ;           1: FUNCTIONING
ROM:00000FE0
ROM:00000FE0 loc_FE0:                                ; CODE XREF: HInt+96j
ROM:00000FE0                 move.w  (VDP_Control).l,d0
ROM:00000FE6                 andi.w  #4,d0
ROM:00000FEA                 beq.s   loc_FE0
ROM:00000FEC                 move.w  ($FFFFF60C).w,d0
ROM:00000FF0                 ori.b   #$40,d0 ; '@'
ROM:00000FF4                 move.w  d0,(VDP_Control).l
ROM:00000FFA                 move.l  (sp)+,d0
ROM:00000FFC                 movea.l (sp)+,a5
ROM:00000FFE
ROM:00000FFE locret_FFE:                             ; CODE XREF: HInt+4j
ROM:00000FFE                 rte


you can see the game first wait for Hblank flag to be set then disabled the display ($FFFFF60C holds VDP register #1 value)
then it programs and triggers a DMA operation
once CPU is released,it wait for the HBlank flag to be set then enable the display again

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Fri Feb 13, 2009 10:53 am

Thank you for all this infos, that's very precious :-)

what do you use to disassemble the rom?

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Fri Feb 13, 2009 1:22 pm

IDA pro and Kaneda's plugin (check on the website, tools section)
any 68k disassembler should be enough however to check specific stuff

Post Reply