Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - SMS VDP Tester

Reply to topic Goto page Previous  1, 2
Author Message
  • Joined: 12 Apr 2005
  • Posts: 391
  • Location: London, United Kingdom
Reply with quote
Post Posted: Mon Aug 17, 2009 2:52 pm
PoorAussie wrote
In most Z80 emulators when an IO occurs you are looking at the cycles executed PRIOR to the IO instruction being executed. In reality it's a few cycles later than that when the write/read actually happens. The other issue on top of that is then when the receiving device "accepts the write/read".

I'll try swapping the order over in my code then, if only to be consistent with other emulators. :-)
Quote
Also if you are using a MAME Z80 or something along these lines there are a few timing errors in it, and also issues with IRQs taking much longer than they should. You should make sure the prefix instructions return instead of executing in large blocks. I still don't think it's possible to pass all of Flubbas test without a cycle accurate Z80 emulator though?

I wrote the Z80 emulator myself, and any "repeating" instruction (LDIR, OTIR, HALT etc) shunts PC back to its original position and returns after each execution rather than repeating, so that shouldn't be an issue. There have been timing errors in the past (there are some popular documents that claim that a failed JP c takes 1 clock cycle!) so I wouldn't rule those out.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Thu Aug 20, 2009 9:03 am
Quote
I still don't think it's possible to pass all of Flubbas test without a cycle accurate Z80 emulator though?


About that, I don't think a complete cycle-accurate Z80 core is necessary for SMS emulation since all hardware devices that need to synchronize with the Z80 (VDP, PSG and I/O chip) and therefore need to handle Z80 accesses at the cycle level, are all mapped to I/O memory. This would limit cycle accuracy to the few INx/OUTx instructions, right ?

And since interrupts can only be accepted between instructions, it should be perfectly accurate to handle them at the instruction level, as long as you trigger IRQ at the correct cycle.

The MAME core for example, is already doing that (checking IRQ before each instruction) and is also adjusting the Z80 cycle count BEFORE actually having executed the instruction: with that in mind, all that you need to modify are the INI/IND/INIR/INDR instructions, by only adding the last M-Cycle AFTER the I/O port has been read.


Quote

Also if you are using a MAME Z80 or something along these lines there are a few timing errors in it, and also issues with IRQs taking much longer than they should.


Could you please elaborate a bit more about these errors ? I know that, in the last version, 2 instructions timings have been fixed ($26 and $2E with $DD or $FD prefix) and the IM0 handling has been modified (now 0xFF is always read from the bus). Did you catched other errors ?

Quote

You should make sure the prefix instructions return instead of executing in large blocks


you are only talking about block transfer(LDIR,CPIR) and I/O (INIR,OTIR,...) instructions, right ?
Because, according to the documentation, interrupts cannot be accepted during instruction execution, including the prefixed one ($DD $DD $DD $26 ... for example, can not be interrupted).
  View user's profile Send private message
  • Joined: 26 Aug 2008
  • Posts: 292
  • Location: Australia
Reply with quote
Post Posted: Thu Aug 20, 2009 9:32 am
Eke wrote
About that, I don't think a complete cycle-accurate Z80 core is necessary for SMS emulation since all hardware devices that need to synchronize with the Z80 (VDP, PSG and I/O chip) and therefore need to handle Z80 accesses at the cycle level, are all mapped to I/O memory. This would limit cycle accuracy to the few INx/OUTx instructions, right ?

And since interrupts can only be accepted between instructions, it should be perfectly accurate to handle them at the instruction level, as long as you trigger IRQ at the correct cycle.


Kinda. :) For some reason a few months ago I had my interrupt reading code at the first cycle of each instruction but it actually happens on the last cycle of the instruction. It was making Flubbas VDP test read a bit incorrect for the interrupts.

So in theory a game could exploit this weakness in an instruction accurate only emulator, since they read the interrupt on the first cycle usually. How necessary is it "with the currenty software library"? Hard to say.

For the SMS, complete cycle accuracy isn't exactly going to bring that much enjoyment, as you said you could concentrate on the in/out and that would do make most of the leap for the SMS when it comes to accuracy (for existing devices anyhow).

BUSREQ and things of this nature require a lot more accuracy, which in theory SMS cartridges could use.

Eke wrote
The MAME core for example, is already doing that (checking IRQ before each instruction) and is also adjusting the Z80 cycle count BEFORE actually having executed the instruction: with that in mind, all that you need to modify are the INI/IND/INIR/INDR instructions, by only adding the last M-Cycle AFTER the I/O port has been read.

Could you please elaborate a bit more about these errors ? I know that, in the last version, 2 instructions timings have been fixed ($26 and $2E with $DD or $FD prefix) and the IM0 handling has been modified (now 0xFF is always read from the bus). Did you catched other errors ?


It was a while ago I looked at MAME, a friend of mine wrote a cycle Z80 emulator and reported those fixes to MAME (after I pointed them out, he has an affinity with MAME I do not share). There are other timing issues as I remember more than 2, I would have to look at the MAME Z80 again to find them and I can't really be bothered to do it. If you check the Z80 manual, and all the undocumented instruction documents, and then understand how the Z80 works at the cycle level you should be able to find them.

Eke wrote
you are only talking about block transfer(LDIR,CPIR) and I/O (INIR,OTIR,...) instructions, right ?
Because, according to the documentation, interrupts cannot be accepted during instruction execution, including the prefixed one ($DD $DD $DD $26 ... for example, can not be interrupted).


It's one thing I need to test at some time the interrupt relationship with the prefix instructions. I would tend to believe that they would be read as "separate instructions" which simply set flags for the Z80 upon further execution. You could verify this with the M1 pin I guess. Where did you read that they could not be interrupted?
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Thu Aug 20, 2009 10:35 am
Quote

Kinda. :) For some reason a few months ago I had my interrupt reading code at the first cycle of each instruction but it actually happens on the last cycle of the instruction. It was making Flubbas VDP test read a bit incorrect for the interrupts.


hmm, I see what you mean.. can't this be corrected by simply checking for interrupts AFTER instruction execution ? Also,since interrupts on the SMS occurs at very predictable time, you could synchronize your CPU execution with the VDP by making interrupt occurence (first VINT then HINT, or is it the contrary ?) as the first "event" of line execution...

However, it still leave the problem of interrupts being triggered after a VDP register write but I have no idea what the timing should be in that case (does the VDP triggers IRQ line *immediately* ? I know one mega drive game that requires one 68k instruction latency between the moment interrupt is enabled through teh VDP register and the moment the VDP is triggering the IRQ6 line)

Quote

For the SMS, complete cycle accuracy isn't exactly going to bring that much enjoyment, as you said you could concentrate on the in/out and that would do make most of the leap for the SMS when it comes to accuracy (for existing devices anyhow).

BUSREQ and things of this nature require a lot more accuracy, which in theory SMS cartridges could use.


yeah, but then comes the use of emulating something that could only be used by hardware that does not even exist.

for a mega drive emulator though, it would be necessary

Quote

It was a while ago I looked at MAME, a friend of mine wrote a cycle Z80 emulator and reported those fixes to MAME (after I pointed them out, he has an affinity with MAME I do not share). There are other timing issues as I remember more than 2, I would have to look at the MAME Z80 again to find them and I can't really be bothered to do it. If you check the Z80 manual, and all the undocumented instruction documents, and then understand how the Z80 works at the cycle level you should be able to find them.

yeah, I've started doing that... the Z80 instruction decoding and execution process is quite logical when you start thinking about it (just that variable Wait States are sometime automatically added for some instructions without apparent logic but some consistance between instructions of the same type).

anyway, about the MAME core, so far timings are correct and it's also pretty accurate regarding flags (they even recently added proper emulation of some BIT undocumented instructions, with the use of a MEMPTR register), which is not so surprising considering the amount and quality of work which has been put so far in this project.


Quote
Where did you read that they could not be interrupted?


from Sean Young's famous document (chapter 5.5):


Quote
And yes, for all instructions, including the prefixed ones, interrupts are never accepted during an instruction. Only after the tested instruction. Remember that block instructions simply re-execute themselves (by decreasing the PC with 2) so an interrupt is accepted after each iteration.

Another predictable test is this: at the \insert instruction to test" insert a large sequence of EI instructions. Of course, during execution of the EI instructions, no interrupts are accepted.

But now for the interesting stuff. ED or CB make up instructions, so interrupts are accepted after them. But DD and FD are prefixes, which only slightly affects the next opcode. If you test a large sequence of DDs or FDs, the same happens as with the EI instruction: no interrupts are accepted during the execution of these sequences.

This makes sense, if you think of DD and FD as a prefix which set the \use IX instead of HL" or \use IY instead of HL" °ag. If an interrupt was accepted after DD or FD, this flag information would be lost, and:
DD 21 00 00 LD IX,0
could be interpreted as a simple LD HL,0 if the interrupt was after the last DD.
Which never happens, so the implementation is correct. Although I haven't tested this, as I imagine the same holds for NMI interrupts.
  View user's profile Send private message
  • Joined: 26 Aug 2008
  • Posts: 292
  • Location: Australia
Reply with quote
Post Posted: Thu Aug 20, 2009 1:30 pm
Eke wrote
hmm, I see what you mean.. can't this be corrected by simply checking for interrupts AFTER instruction execution ? Also,since interrupts on the SMS occurs at very predictable time, you could synchronize your CPU execution with the VDP by making interrupt occurence (first VINT then HINT, or is it the contrary ?) as the first "event" of line execution...


The cpu samples the interrupt pin on the rising edge of the last cycle (ie before it executes last cycle). So sampling the interrupt pin after an instruction is one cycle late.

Eke wrote
yeah, but then comes the use of emulating something that could only be used by hardware that does not even exist.


Yep but then what is the point of going half way between a MAME Z80 and something like RC? MEKA "runs" all the existing SMS games with its core... ;)

One thing I didn't want to do for my own reasons, is to have to come back later and rewrite the CPU emulator, so the cycle accurate 6502 and Z80 I did are made to be used in any project, whether emulated or real. And I want to do genesis later and any addon SMS hardware people design.

Eke wrote
anyway, about the MAME core, so far timings are correct and it's also pretty accurate regarding flags (they even recently added proper emulation of some BIT undocumented instructions, with the use of a MEMPTR register), which is not so surprising considering the amount and quality of work which has been put so far in this project.


Oh so they've fixed all their issues? Good to hear. ;)

Quote
But now for the interesting stuff. ED or CB make up instructions, so interrupts are accepted after them. But DD and FD are prefixes, which only slightly affects the next opcode. If you test a large sequence of DDs or FDs, the same happens as with the EI instruction: no interrupts are accepted during the execution of these sequences.


I'd like to test it personally to verify because you never know for sure until you try yourself. It's also important for me to know the exact output of each of the Z80 pins for my goals and no one has documented this. I'd like to at one stage be able to use RC as a replacement for a real Z80.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Thu Aug 20, 2009 1:49 pm
Quote
The cpu samples the interrupt pin on the rising edge of the last cycle (ie before it executes last cycle). So sampling the interrupt pin after an instruction is one cycle late.


yes, I understand what you mean: you mean that in the case where the IRQ is triggered just after the last cycle, it is not supposed to be accepted until the NEXT instruction but here, it would be taken immediately, the result being one instruction less when exception processing starts.

But what I wanted to say was that since we knew that interrupts are triggered exactly each 342 cycles and that interrupts are only accepted between instructions, you could perfectly do something as simple as this on each line:

1) if required, VDP assert IRQ line
2) run 342 cycles (check for interrupts before each instruction)

Or would you mind explaining me what errors this could introduce ?


I mean, I know it's not perfectly accurate but anywxay, there is no way for you to know where the VDP exactly is (which line and which HCount) when the Z80 end its RESET process and starts executing instructions so even a cycle-accurate Z80 emulator is worthless as long as you didn't accurately initialized the synchronization, right ?
  View user's profile Send private message
  • Joined: 26 Aug 2008
  • Posts: 292
  • Location: Australia
Reply with quote
Post Posted: Thu Aug 20, 2009 2:15 pm
Eke wrote
yes, I understand what you mean: you mean that in the case where the IRQ is triggered just after the last cycle,


Or *during* the last cycle. The VDP runs 3 cycles per one Z80. If the VDP misses the rising edge of the last cycle then one more instruction should execute before IRQ. If you are sampling a cycle late it means you will take interrupts earlier than you should.

Eke wrote
it is not supposed to be accepted until the NEXT instruction but here, it would be taken immediately, the result being one instruction less when exception processing starts.


Right.

Eke wrote
But what I wanted to say was that since we knew that interrupts are triggered exactly each 342 cycles and that interrupts are only accepted between instructions, you could perfectly do something as simple as this on each line:


VDP runs at 684 cycles per scanline. You would need to perfectly count the cycles needed and then work out when you get close to the end whether or not you should take the interrupt, etc.

There are plenty of ways to optimize the need for a true cycle accurate core, I've done plenty of them. It is quite fun really, caching writes, catching up devices, plenty of different ways to optimize. Thing is though what is the point of doing all this? That tiny bit of speed you gain is offset by ungainly code and complication that will drive you insane after you put it away for a month.

Take a look at BlueMSX for an example, I haven't tested my VDP core against it for speed, but my codebase is 5 times smaller. If you take away the parts that have nothing to do with the SMS, it's only 3 times smaller. but my core also emulates the SMS VDP which it doesn't, so it's an interesting thing to wonder about.

An old NES emulator I worked on had cached writes and things of this nature to simulate cycle accuracy fairly well, but thankfully I don't have to touch that era again. ;)


Eke wrote
I mean, I know it's not perfectly accurate but anywxay, there is no way for you to know where the VDP exactly is (which line and which HCount) when the Z80 end its RESET process and starts executing instructions so even a cycle-accurate Z80 emulator is worthless as long as you didn't accurately initialized the synchronization, right ?


The BIOS takes away some of the "startup" issues since software can't really get an idea about what is before it thanks to the BIOS. It's one of those things we have to find out though, the startup synchronization in regards to the VDP. In regards to clock sync though, you just have to align the master clock to the devices correctly, it's fairly straight forward for the SMS since the devices all run off integer ratios unlike other systems.

In RetroCopy I have the VDP executed for 2 cycles before the first cycle of the Z80 and third of the VDP. It may be a bit different than this. You have to be careful to make sure when devices are running on the same "cycle" together that they can't see each others output either until the end.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Tue Aug 25, 2009 10:34 am
I finally managed to pass all test successfully with SMS Plus. The few changes required are listed below (no cycle accurate Z80 emulation though , cycle count is updated before processing the instruction).

The only thing that was *really* required was somehow limited cycle-accurate VDP execution, i.e each time you are writing a VDP register and reading the VDP status or VC registers, you have to check if the current cycle count did not moved to the next line...

If the current cycle count indicates we are already on the next line, I parse sprites and render the line immediately before updating the register (this makes xscroll latched correclty) or reading the status flag (this updates INT and OVR flags at the correct HC). A flag is obviously set to prevent rendering the same line twice.

Same goes for VC register, the current line is deducted from the current cycle count (z80_get_elapsed_cycles()/CYCLES_PER_LINE) instead of using the incrementing line counter.

About the COL flag, it is, as usual, set during the line rendering function (done once at the beginning of each line) but additional information provides the line and the HC value ((xpos >> 1) + 0x06) on which it occured. When the VDP status is read, the current HC and lines value are compared to return the real-time status of this flag.

The first event of the line is Horizontal interrupt and HC table starts at 0xF4.

Updated sourcecode should be available here soon for anyone interested ;-)
  View user's profile Send private message
  • Joined: 28 Sep 1999
  • Posts: 1200
Reply with quote
Post Posted: Tue Aug 25, 2009 3:18 pm
Eke wrote
I finally managed to pass all test successfully with SMS Plus.


Wow, I can't thank you enough for continuing development on SMS Plus and making it so accurate. This is thrilling news to me. :)
  View user's profile Send private message Visit poster's website
  • Joined: 26 Aug 2008
  • Posts: 292
  • Location: Australia
Reply with quote
Post Posted: Wed Aug 26, 2009 12:54 am
Nice work EKE, did you compare speed before and after the changes? Would be interesting to know.

Flubbas VDP test is a little loose with some of the timing stuff, I hope to make a new test soon once I get my dev system setup. Just to verify things and also something emulator authors can use to improve their emus. Anyhow, good work. :)
  View user's profile Send private message Visit poster's website
  • Joined: 21 Jul 2005
  • Posts: 412
  • Location: GBG
Reply with quote
Post Posted: Wed Aug 26, 2009 7:09 am
My SMS emu on the GBA clears all test (except all the sprite COL/OVR tests), so it doesn't have to be cpu taxing in any way.
@PoorAussie. Which tests are "a bit loose" now? I'm going to add some more things to the test right now so it would be nice to fix those tests as well.
  View user's profile Send private message Visit poster's website
  • Joined: 26 Aug 2008
  • Posts: 292
  • Location: Australia
Reply with quote
Post Posted: Fri Aug 28, 2009 12:58 am
FluBBa wrote
@PoorAussie. Which tests are "a bit loose" now? I'm going to add some more things to the test right now so it would be nice to fix those tests as well.


Pretty much all of the timing ones, I've got about 4-8 VDP cycles difference in a lot of them before it breaks anything (this is with your previous test, I haven't used your newest one yet because you said you haven't verified it). I have to come up with ways to accurately get the timing information though in my own program, as you would know it's quite difficult. There are also other things to do with memory timing that your test doesn't cover that I want to do.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Wed Oct 21, 2009 8:08 am
PoorAussie wrote

Or *during* the last cycle. The VDP runs 3 cycles per one Z80. If the VDP misses the rising edge of the last cycle then one more instruction should execute before IRQ. If you are sampling a cycle late it means you will take interrupts earlier than you should.


I figured a simple and fast way to handle this... since interrupts are separated by a constant number of cycles (228 Z-Cycles or 684 M-Cycles), it's easy to check the current Z80 cycle count when interrupt is supposed to happen (at the start of the line for example). If it's exactly multiple of 228, it means the interrupts is triggered AFTER the instruction IRQ detection point and you have to execute one more single instruction before triggering interrupt... if it's 228+n (n>0), interrupt can be triggered immediately.


for (i=0;i<lines_per_frame;i++)
{
  /* check if Hint should be triggered on this line */
  if (xxxx)
  {
     if (count_z80%Z80_CYCLES_PER_LINE == 0)
        z80_execute(1);

     ....

     z80_set_interrupt();
   
 }


Same thing can be done for Vint, knowing the exact cycle where it occurs.

Quote
There are plenty of ways to optimize the need for a true cycle accurate core, I've done plenty of them. It is quite fun really, caching writes, catching up devices, plenty of different ways to optimize. Thing is though what is the point of doing all this? That tiny bit of speed you gain is offset by ungainly code and complication that will drive you insane after you put it away for a month.


Well, this is still way faster and more optimized than emulating Z80 and/or VDP with cycle granularity and does not add so much code complexity honestly... without losing any accuracy ;-)

And this is exactly my point: you can do a lot of things through different ways when you emulate something, but there is not a "better" or "more accurate" method as long as no program could tell the difference if you did things correctly (at least on a SMS).

Anyway, at the end, the only thing that should matter is the pleasure you have to code something in the way you like it, with complete understanding of what you are doing.

Some people would always prefer to limit themselves to what is really necessary and enjoy finding optimized way of doing things (and that doesn't mean necessarily sacrifying accuracy ou using infamous hacks), some others would always prefer to have full control on what they are emulating, at the lowest level possible, as near as the hardware as possible. Both approaches, which are sometime not so opposed, should be respected and not minimized because it's generally a motivated choice, not a matter of competence...
Btw, on that matter, I'd say the biggest challenge is not emulating hardware at the lowest timing level but to actually figure exactly what the hardware is doing and how it is doing it... thanks to charles,marat, MAME devs and all those generous contributers and opensource developpers, this makes the whole job damn easier by now :)

Quote

In regards to clock sync though, you just have to align the master clock to the devices correctly, it's fairly straight forward for the SMS since the devices all run off integer ratios unlike other systems.


well, that's not exactly true. Even when using Mclock as a base, there can be a shift between those 2 devices depending on when Z80 start its execution, for example, if it starts at Mcyc+(3*n)+1 or Mcyc+(3*n)+2, with Zclk=Mclk/3
To be exactly accurate, this should be taken in account (but again, I don't think this matters much since everything get synchronized with interrupt sooner or later)


Charles MacDonald wrote
Wow, I can't thank you enough for continuing development on SMS Plus and making it so accurate. This is thrilling news to me. :)


my pleasure :)
  View user's profile Send private message
  • Joined: 26 Aug 2008
  • Posts: 292
  • Location: Australia
Reply with quote
Post Posted: Wed Oct 21, 2009 12:55 pm
Eke wrote
Well, this is still way faster and more optimized than emulating Z80 and/or VDP with cycle granularity and does not add so much code complexity honestly... without losing any accuracy ;-)

And this is exactly my point: you can do a lot of things through different ways when you emulate something, but there is not a "better" or "more accurate" method as long as no program could tell the difference if you did things correctly (at least on a SMS).


I agree that if the SMS software can't tell the difference then in accuracy it doesn't matter how it's achieved at all. The means is irrelevant to the end. That said, I didn't want to design a Z80/VDP combo that was SMS only, and the Z80 SMSPLUS uses is inaccurate for busreq's and will need a complete rewrite to support it. SMS software can use busreq's (none does yet, though I will code a game which uses it eventually for DMA).

I have been criticized for calling this level of accuracy "perfect", because to me it is all that matters. If software is unable to detect a real system or emulator using every single possible method then it's perfection as far as I'm concerned. I actually go a step beyond this even just for my own reasons because I like developing software that is like real hardware. Nothing is going to intercept the VDP accessing it's VRAM for instance on the SMS but RetroCopy is right in there to do something with it if something did.

Eke wrote
Some people would always prefer to limit themselves to what is really necessary and enjoy finding optimized way of doing things (and that doesn't mean necessarily sacrifying accuracy ou using infamous hacks), some others would always prefer to have full control on what they are emulating, at the lowest level possible, as near as the hardware as possible. Both approaches, which are sometime not so opposed, should be respected and not minimized because it's generally a motivated choice, not a matter of competence...


Certainly. While I'm targeting not wanting to touch my cores again, writing them once and having them work until the end of time at cycle accuracy there will be cores which can be faster if they take certain knowledge about a system and optimize for it. Like the fact no existing SMS games use BUSREQ. Or the fact that a system has very regular interrupts or whatever. I'm completely for people doing that because it gives people with lesser computers the opportunity to use it at minimal sacrifice really. MEKA which is probably my favourite emulator is a perfect example of having near perfect compatibility at a very low cost, MEKA also did something different with it's interface compared to near everything else, it's obvious a lot of love was put into it which I respect.

BTW my Z80 emulator is "only" about 2-2.5 times slower than the MAME one, I used a technique I haven't seen in any other emulator that I talked about in another post. Most of the cost of cycle emulating the SMS comes with the VDP. My I7 is currently doing about 106 million emulated cycles per cycle per SMS core, at about 30 host cycles to one emulated cycle. This is enough to emulate 5 SMS's at cycle accuracy with high quality audio filtering and FM chip.

http://www.retrocopy.com/blog/52/emulator-benchmark.aspx

My original non cycle accurate (but high compat) SMS emulator I had in earlier versions of RetroCopy was getting about 2000FPS (3.2GHz core2), at cycle accuracy the same system is getting about 300FPS. So it's quite a bit slower overall.

Eke wrote
Btw, on that matter, I'd say the biggest challenge is not emulating hardware at the lowest timing level but to actually figure exactly what the hardware is doing and how it is doing it... thanks to charles,marat, MAME devs and all those generous contributers and opensource developpers, this makes the whole job damn easier by now :)


Yep, though it usually ends up being a question of access. There are plenty of talented guys on the internet who can code up wonderful things and crack lots of puzzles, but not all of them have access to logic analyzers and arcade boards.

Eke wrote
well, that's not exactly true. Even when using Mclock as a base, there can be a shift between those 2 devices depending on when Z80 start its execution, for example, if it starts at Mcyc+(3*n)+1 or Mcyc+(3*n)+2, with Zclk=Mclk/3
To be exactly accurate, this should be taken in account (but again, I don't think this matters much since everything get synchronized with interrupt sooner or later)


I meant the fact that all the devices run off integer ratios compared to each other. Other systems aren't so lucky. (Z80=PSG=FM=3VDP).

But yes it's an interesting thing to ponder about when it comes to how things start. Since there are some unknowns like the fact that the R register is different boot to boot on a real system by the time it gets to the game. I think it does matter though, RetroCopy can emulate it whatever it is but at the moment they do start at the same clock.
  View user's profile Send private message Visit poster's website
  • Joined: 21 Jul 2005
  • Posts: 412
  • Location: GBG
Reply with quote
Post Posted: Wed Nov 04, 2009 12:21 pm
I've tightened up the HInt & VInt HCount tests and tested it on my SMS1.
I thought I would write a test to find the background NameTable latch time but it looks like it's not latched at all and you can switch nametable mid-scanline.
  View user's profile Send private message Visit poster's website
  • Joined: 27 Oct 2009
  • Posts: 138
Reply with quote
Post Posted: Tue Nov 10, 2009 4:53 am
Thanks for the new test Flubba. I'm still interested in the sprite collisions happening in the border regions. Does your SMS1 have the original VDP or the second revision?
  View user's profile Send private message Visit poster's website
  • Joined: 21 Jul 2005
  • Posts: 412
  • Location: GBG
Reply with quote
Post Posted: Tue Nov 10, 2009 1:42 pm
In what way do you want to test it?
I already test collision in the side and top/bottom borders...
My SMS1 has the first VDP and my SMS2 has the newer VDP, problem is that I have hard time showing the RF signal from my SMS2...
  View user's profile Send private message Visit poster's website
  • Joined: 27 Oct 2009
  • Posts: 138
Reply with quote
Post Posted: Wed Nov 11, 2009 5:30 am
FluBBa wrote
In what way do you want to test it?
I already test collision in the side and top/bottom borders...
My SMS1 has the first VDP and my SMS2 has the newer VDP, problem is that I have hard time showing the RF signal from my SMS2...


Well it's just interesting that sprite processing still happens in the border region. However the VDP must still process sprites during lines 0-191 even when the display is off because if it doesn't the first line of active display after enabling display again won't have sprites on it due to the "process sprites for next line" feature. So maybe they just have a "active display" which means draw and display tiles/sprites and an "off display" which means process sprites and memory.

From my tests though it looks like the sprite processing changes from the active display way of doing things to something else. Due to the 36 MCLK gap in active sprite processing where there are no CPU windows. This would break the 16 Z80 cycle "Sega limit" (when you add the VDP delay) for offscreen writes.

Have you ever checked where 'display off' is latched? I always thought it would be HC=0 but maybe it's HC=F4ish.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Wed Nov 11, 2009 12:46 pm
Quote
So maybe they just have a "active display" which means draw and display tiles/sprites and an "off display" which means process sprites and memory.


Most likely, what happen is that the display status only affects the output of the priority controller (background color is always picked but sprite collision is still checked as long as sprites are processed).

Sprites processing is more probaly timed with line events (Ypos during active line, Xpos/Name during HBlank), not with hdisplay status (hblank != display off or vblank), and controlled by the current vertical counter value.

Interestingly, on the Genesis, it has been noticed that forcing the display off during HBLANK will have effects on sprite processing (i.e some sprites data are going to be masked on the upcoming line) which would indicate that forcing the display OFF would also stop sprite processing, contrary to the blanked border areas (which seems obvious since you usually do that for "full" access to the CPU).

It might be interesting, on the SMS, to disable manually the display on line 192 and see if sprite collision still happen in the bottom/top border.


Quote
Have you ever checked where 'display off' is latched? I always thought it would be HC=0 but maybe it's HC=F4ish.


Are you sure it can't not be switched anytime during the line ?
On the Genesis VDP at least (i know it could be quite different but who knows), you can switch display off/on midline so the "display off" bit is apparently checked periodically during the line.
  View user's profile Send private message
  • Joined: 27 Oct 2009
  • Posts: 138
Reply with quote
Post Posted: Wed Nov 11, 2009 1:24 pm
Eke wrote
Interestingly, on the Genesis, it has been noticed that forcing the display off during HBLANK will have effects on sprite processing (i.e some sprites data are going to be masked on the upcoming line) which would indicate that forcing the display OFF would also stop sprite processing, contrary to the blanked border areas (which seems obvious since you usually do that for "full" access to the CPU).

It might be interesting, on the SMS, to disable manually the display on line 192 and see if sprite collision still happen in the bottom/top border.

Are you sure it can't not be switched anytime during the line ?
On the Genesis VDP at least (i know it could be quite different but who knows), you can switch display off/on midline so the "display off" bit is apparently checked periodically during the line.


I'm fairly sure the display switch is latched rather than instant. I've emulated both and with it emulated as non latched the games which use it (impossible mission, cool spot, etc) don't display correctly or are otherwise glitchy. I don't remember those glitches on the real game.

So if it is latched it also means that it probably has a "table" if you want to call it that, of things to do for the line. I believe when it switches to the "off" table it must still do sprite processing in it, this simplifies things somewhat, line 312 or 261 can process sprites for line 0, sprites are still processed for the next line if it's toggled on/off for different lines, etc.

On the other hand if sprite processing was tweaked over the TMS, maybe an access window(s) was conveniently placed to not break the 16 Z80 cycle "limit". This way you could think of sprite processing as a layer which was always on regardless.

I know Charles has mentioned that you can disable the display in the horizontal border regions but I think this is more related to the Genesis than the SMS. You're not going to gain much on the SMS by doing it, the Z80/port simply can't feed much to it in that time frame.

I do find it weird though that collisions are set during the border regions. Possibly since the VDP is outputting border color and display is set to "on", the sprite display hardware is still being used but not shown. Is there a limit to where these are set? Flubba says "border region" but I would guess that applies to the full range of possible sprite Y values.
  View user's profile Send private message Visit poster's website
  • Joined: 27 Oct 2009
  • Posts: 138
Reply with quote
Post Posted: Wed Nov 18, 2009 3:35 pm
FluBBa wrote
I've tightened up the HInt & VInt HCount tests and tested it on my SMS1.
I thought I would write a test to find the background NameTable latch time but it looks like it's not latched at all and you can switch nametable mid-scanline.


Flubba does your emulator pass your test? I've noticed Fantastic Dizzy doesn't like sprite collisions to be set in the offscreen region, just wondering if you have tried running that game with that effect emulated.
  View user's profile Send private message Visit poster's website
  • Joined: 21 Jul 2005
  • Posts: 412
  • Location: GBG
Reply with quote
Post Posted: Wed Nov 18, 2009 5:43 pm
My emulator doesn't even attempt to do real sprite collision, so, no it doesn't pass many of the sprite tests.
Offscreen, is that in the top/bottom or the sideborders?
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Wed Nov 18, 2009 7:12 pm
My current version of SMS Plus passes all Flubba's tests (incl. sprites collision ones) and does not have any problem with that game.

However, I remember that having the sprite collision flag being set a little too early (or too late) in the line would produce some line flickering in the top status bar (also when the PAUSE button is pressed), this is very likely some inaccuracies with your pixel rendering/collision timing.
  View user's profile Send private message
  • Joined: 27 Oct 2009
  • Posts: 138
Reply with quote
Post Posted: Thu Nov 19, 2009 1:32 am
Eke wrote
My current version of SMS Plus passes all Flubba's tests (incl. sprites collision ones) and does not have any problem with that game.


Do you do sprite collision testing on every line of display? I noticed if you don't do any lines over 255 (256-311) Flubbas test still passes and the game now works, it seems a collision just before line 0 trips it up, but...

Eke wrote
However, I remember that having the sprite collision flag being set a little too early (or too late) in the line would produce some line flickering in the top status bar (also when the PAUSE button is pressed), this is very likely some inaccuracies with your pixel rendering/collision timing.


I am getting a little flicker on the second last line of the status bar so maybe you're right. It is wanting the "display off" to be latched about 30 MCLKs later than I currently do on some lines, it wants to turn off display for 2 lines to change the palette, on some frames it misses the right spot which is why the flicker occurs.

BTW does your smsplus pass the latest test from Flubba?
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Thu Nov 19, 2009 9:01 am
Quote
Do you do sprite collision testing on every line of display? I noticed if you don't do any lines over 255 (256-311) Flubbas test still passes and the game now works, it seems a collision just before line 0 trips it up, but...


I do sprite rendering (and collision test) on every line of active display, including vertical borders, that's 240 lines for NTSC and 288 lines for PAL (it should be 243 and 294 to be accurate but the Wii hardware limitations made it simpler to use those values and it doesn't really mattter anyway).
You are right that a collision occurs the line before 0 and the sprite collision flag is indeed used to switch the display OFF for a few lines. If your timings are not exactly what they are supposed to be, you indeed get line flickering (but I'm pretty sure that midline display switching is authorized so switching the display OFF anywhere during the HBLANK period should not be noticable).

Quote

BTW does your smsplus pass the latest test from Flubba?

yes it does ;-)

EDIT: actually it doesn't in PAL mode, I forgot to test that case: the offscreen sprite collision test indeed fails .
I guess it's because my border area is smaller than expected and the collision is programmed on a line outside the area I used. I should probably fix that by using more accurate overscan ranges and see if Fantastic Dizzy is affected ...
  View user's profile Send private message
  • Joined: 27 Oct 2009
  • Posts: 138
Reply with quote
Post Posted: Thu Nov 19, 2009 10:40 am
Eke wrote
EDIT: actually it doesn't in PAL mode, I forgot to test that case: the offscreen sprite collision test indeed fails .
I guess it's because my border area is smaller than expected and the collision is programmed on a line outside the area I used. I should probably fix that by using more accurate overscan ranges and see if Fantastic Dizzy is affected ...


Well it's funny, mine passes but has visible flaws in Fantastic Dizzy. :)

If "display off" isn't latched then the glitch in my emulator would be very hard to spot. But since there isn't any evidence it isn't latched I'm assuming it is.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Thu Nov 19, 2009 2:25 pm
As expected, after fixing the overscan area height to match real hardware, the emulator now passes all tests in both (NTSC & PAL) modes...

and Fantastic Dizzy is still fine (in PAL mode as well), even with Display Blanking bit being latched (in SMS Plus, it is latched when the line is rendered, i.e at the start of a line, when Hint occurs and also when other registers, like HSCROLL, are latched)
  View user's profile Send private message
  • Joined: 06 Feb 2009
  • Posts: 110
  • Location: Toulouse, France
Reply with quote
Post Posted: Wed Aug 11, 2010 12:27 pm
I have run the VDP Test program on my 60hz-switched PAL MD2 without PBC (using Everdrive flash card that has SMS compatibility) and got the following tests sometime (not always) failing:

HCounter correct: Error
VINT Flag Hcount: Error
Spr ovr correct HC: Error

The Hcounter values seemed correct though, with any third value repeated two times but Hcount timing test is sometime out of bound regarding VBLANK value ($81 mostly)

I also tested Z80 registers initial value but it appears they are all initialized by the OS program of the flash card so it's irrelevant (I will try to get a compiled version that does not touch Z80). IR value is $0009 as expected (reset at $00 + first instructions execution, got the same R value on emulators), while it seems to be $001D with PBC and $0019 with SMS without BIOS (according to that thread), as if Z80 had been running a few more instructions.

After soft reset (Mega Drive RESET button), IR value is always $0009 and other registers keep the value they had when reset was occuring.

My MD2 mainboard is VA0, with discrete QFP Z80 chip (can't tell the brand).
  View user's profile Send private message
  • Joined: 05 Jan 2006
  • Posts: 417
  • Location: USA
Reply with quote
Post Posted: Thu Jun 11, 2015 5:43 am
Enik requested infos from a Game Gear running this VDP Test. Here it is:



Running a 2 ASIC VA0 Game Gear with Viletim's GGTV board (with an upgraded CXA2075 encoder).

-Segasonicfan
  View user's profile Send private message Visit poster's website
  • Joined: 29 Apr 2007
  • Posts: 27
Reply with quote
Post Posted: Thu Jun 11, 2015 9:50 pm
Thank you Segasonicfan!

So, comparing with the previous test performed by benryves, there are two differences:

HCounter correct: Ok
Line IRQ HCount: Error

Does anyone know the hardware version of his Game Gear? Also, Segasonicfan's test showed out of bound HCount value for VBlank: $82

Edit: To answer my own question, according to his posts, benryves has/had two UK Game Gears, with BIOS, that have date stamps for 1993. He posted pictures of one unit that reveal it is the 1 ASIC version, what I think also applies to the other unit.
  View user's profile Send private message
  • Joined: 05 Jan 2006
  • Posts: 417
  • Location: USA
Reply with quote
Post Posted: Sun Jun 14, 2015 7:41 pm
Quote
Does anyone know the hardware version of his Game Gear?


That's a VA1 Game Gear. The 315-5535 was the since ASIC version that was released right after the VA0 which had 2 separate ASICS.

I have modded them both for TV out in the past with pics here:
http://www.freewebs.com/vgmods/gamegearmodifications.htm

-Segasonicfan
  View user's profile Send private message Visit poster's website
  • Joined: 07 Nov 2016
  • Posts: 11
Reply with quote
Post Posted: Sat Jul 20, 2019 9:53 pm
Since the first results of FluBBa's VDP Tester were posted and showed errors when ran on Game Gear units, I've been wondering what would be the correct results for that handheld system. So, last year I bought two Game Gear units, a 1 ASIC version and a 2 ASIC version, and verified which SMS VDP tests failed. I figured out what values where returned by the GG units and, based on the SMS tests, created new GG versions of those tests for the two GG units. I submitted changes to MAME to support Game Gear-specific timings, that were released in version 0.200. I planned to release the changes for the VDP Tester ROM here, but they were not clean yet. I became busy with other things for a long time, but now finally took the time to clean up, revise and release the changes.

What gave me more work was the weird HClocks registered for the tests in the readme file, that I needed to understand to add the timings for the GG units. I figure out that, instead VDP clocks, the HClocks were in fact Z80 clock counts relative to HCount 0x00. Due to this discovery, my diff file changes "HClock" to "ZClock" for the test values.
I built a ZClock->HCount table to found what should be the values:

Quote

ZClock 0 offset -31 HCount 0xE9 Pixel 0 offset -47
ZClock 1 offset -30 HCount 0xEA Pixel 2 offset -45
ZClock 2 offset -29 HCount 0xEA Pixel 3 offset -44
ZClock 3 offset -28 HCount 0xEB Pixel 5 offset -42
ZClock 4 offset -27 HCount 0xEC Pixel 6 offset -41
ZClock 5 offset -26 HCount 0xED Pixel 8 offset -39
ZClock 6 offset -25 HCount 0xED Pixel 9 offset -38
ZClock 7 offset -24 HCount 0xEE Pixel 11 offset -36
ZClock 8 offset -23 HCount 0xEF Pixel 12 offset -35
ZClock 9 offset -22 HCount 0xF0 Pixel 14 offset -33
ZClock 10 offset -21 HCount 0xF0 Pixel 15 offset -32
ZClock 11 offset -20 HCount 0xF1 Pixel 17 offset -30
ZClock 12 offset -19 HCount 0xF2 Pixel 18 offset -29
ZClock 13 offset -18 HCount 0xF3 Pixel 20 offset -27
ZClock 14 offset -17 HCount 0xF3 Pixel 21 offset -26
ZClock 15 offset -16 HCount 0xF4 Pixel 23 offset -24
ZClock 16 offset -15 HCount 0xF5 Pixel 24 offset -23
ZClock 17 offset -14 HCount 0xF6 Pixel 26 offset -21
ZClock 18 offset -13 HCount 0xF6 Pixel 27 offset -20
ZClock 19 offset -12 HCount 0xF7 Pixel 29 offset -18
ZClock 20 offset -11 HCount 0xF8 Pixel 30 offset -17
ZClock 21 offset -10 HCount 0xF9 Pixel 32 offset -15
ZClock 22 offset -9 HCount 0xF9 Pixel 33 offset -14
ZClock 23 offset -8 HCount 0xFA Pixel 35 offset -12
ZClock 24 offset -7 HCount 0xFB Pixel 36 offset -11
ZClock 25 offset -6 HCount 0xFC Pixel 38 offset -9
ZClock 26 offset -5 HCount 0xFC Pixel 39 offset -8
ZClock 27 offset -4 HCount 0xFD Pixel 41 offset -6
ZClock 28 offset -3 HCount 0xFE Pixel 42 offset -5
ZClock 29 offset -2 HCount 0xFF Pixel 44 offset -3
ZClock 30 offset -1 HCount 0xFF Pixel 45 offset -2
ZClock 31 offset 0 HCount 0x00 Pixel 47 offset 0
ZClock 32 offset 1 HCount 0x00 Pixel 48 offset 1
ZClock 33 offset 2 HCount 0x01 Pixel 50 offset 3
ZClock 34 offset 3 HCount 0x02 Pixel 51 offset 4
ZClock 35 offset 4 HCount 0x03 Pixel 53 offset 6
ZClock 36 offset 5 HCount 0x03 Pixel 54 offset 7
ZClock 37 offset 6 HCount 0x04 Pixel 56 offset 9
ZClock 38 offset 7 HCount 0x05 Pixel 57 offset 10
ZClock 39 offset 8 HCount 0x06 Pixel 59 offset 12
ZClock 40 offset 9 HCount 0x06 Pixel 60 offset 13
ZClock 41 offset 10 HCount 0x07 Pixel 62 offset 15
ZClock 42 offset 11 HCount 0x08 Pixel 63 offset 16
ZClock 43 offset 12 HCount 0x09 Pixel 65 offset 18
ZClock 44 offset 13 HCount 0x09 Pixel 66 offset 19
ZClock 45 offset 14 HCount 0x0A Pixel 68 offset 21
ZClock 46 offset 15 HCount 0x0B Pixel 69 offset 22
ZClock 47 offset 16 HCount 0x0C Pixel 71 offset 24
ZClock 48 offset 17 HCount 0x0C Pixel 72 offset 25
ZClock 49 offset 18 HCount 0x0D Pixel 74 offset 27
ZClock 50 offset 19 HCount 0x0E Pixel 75 offset 28
ZClock 51 offset 20 HCount 0x0F Pixel 77 offset 30
ZClock 52 offset 21 HCount 0x0F Pixel 78 offset 31
ZClock 53 offset 22 HCount 0x10 Pixel 80 offset 33
ZClock 54 offset 23 HCount 0x11 Pixel 81 offset 34
ZClock 55 offset 24 HCount 0x12 Pixel 83 offset 36
ZClock 56 offset 25 HCount 0x12 Pixel 84 offset 37
ZClock 57 offset 26 HCount 0x13 Pixel 86 offset 39
ZClock 58 offset 27 HCount 0x14 Pixel 87 offset 40
ZClock 59 offset 28 HCount 0x15 Pixel 89 offset 42
ZClock 60 offset 29 HCount 0x15 Pixel 90 offset 43
ZClock 61 offset 30 HCount 0x16 Pixel 92 offset 45
ZClock 62 offset 31 HCount 0x17 Pixel 93 offset 46
ZClock 63 offset 32 HCount 0x18 Pixel 95 offset 48
ZClock 64 offset 33 HCount 0x18 Pixel 96 offset 49
ZClock 65 offset 34 HCount 0x19 Pixel 98 offset 51
ZClock 66 offset 35 HCount 0x1A Pixel 99 offset 52
ZClock 67 offset 36 HCount 0x1B Pixel 101 offset 54
ZClock 68 offset 37 HCount 0x1B Pixel 102 offset 55
ZClock 69 offset 38 HCount 0x1C Pixel 104 offset 57
ZClock 70 offset 39 HCount 0x1D Pixel 105 offset 58
ZClock 71 offset 40 HCount 0x1E Pixel 107 offset 60
ZClock 72 offset 41 HCount 0x1E Pixel 108 offset 61
ZClock 73 offset 42 HCount 0x1F Pixel 110 offset 63
ZClock 74 offset 43 HCount 0x20 Pixel 111 offset 64
ZClock 75 offset 44 HCount 0x21 Pixel 113 offset 66
ZClock 76 offset 45 HCount 0x21 Pixel 114 offset 67
ZClock 77 offset 46 HCount 0x22 Pixel 116 offset 69
ZClock 78 offset 47 HCount 0x23 Pixel 117 offset 70
ZClock 79 offset 48 HCount 0x24 Pixel 119 offset 72
ZClock 80 offset 49 HCount 0x24 Pixel 120 offset 73
ZClock 81 offset 50 HCount 0x25 Pixel 122 offset 75
ZClock 82 offset 51 HCount 0x26 Pixel 123 offset 76
ZClock 83 offset 52 HCount 0x27 Pixel 125 offset 78
ZClock 84 offset 53 HCount 0x27 Pixel 126 offset 79
ZClock 85 offset 54 HCount 0x28 Pixel 128 offset 81
ZClock 86 offset 55 HCount 0x29 Pixel 129 offset 82
ZClock 87 offset 56 HCount 0x2A Pixel 131 offset 84
ZClock 88 offset 57 HCount 0x2A Pixel 132 offset 85
ZClock 89 offset 58 HCount 0x2B Pixel 134 offset 87
ZClock 90 offset 59 HCount 0x2C Pixel 135 offset 88
ZClock 91 offset 60 HCount 0x2D Pixel 137 offset 90
ZClock 92 offset 61 HCount 0x2D Pixel 138 offset 91
ZClock 93 offset 62 HCount 0x2E Pixel 140 offset 93
ZClock 94 offset 63 HCount 0x2F Pixel 141 offset 94
ZClock 95 offset 64 HCount 0x30 Pixel 143 offset 96
ZClock 96 offset 65 HCount 0x30 Pixel 144 offset 97
ZClock 97 offset 66 HCount 0x31 Pixel 146 offset 99
ZClock 98 offset 67 HCount 0x32 Pixel 147 offset 100
ZClock 99 offset 68 HCount 0x33 Pixel 149 offset 102
ZClock 100 offset 69 HCount 0x33 Pixel 150 offset 103
ZClock 101 offset 70 HCount 0x34 Pixel 152 offset 105
ZClock 102 offset 71 HCount 0x35 Pixel 153 offset 106
ZClock 103 offset 72 HCount 0x36 Pixel 155 offset 108
ZClock 104 offset 73 HCount 0x36 Pixel 156 offset 109
ZClock 105 offset 74 HCount 0x37 Pixel 158 offset 111
ZClock 106 offset 75 HCount 0x38 Pixel 159 offset 112
ZClock 107 offset 76 HCount 0x39 Pixel 161 offset 114
ZClock 108 offset 77 HCount 0x39 Pixel 162 offset 115
ZClock 109 offset 78 HCount 0x3A Pixel 164 offset 117
ZClock 110 offset 79 HCount 0x3B Pixel 165 offset 118
ZClock 111 offset 80 HCount 0x3C Pixel 167 offset 120
ZClock 112 offset 81 HCount 0x3C Pixel 168 offset 121
ZClock 113 offset 82 HCount 0x3D Pixel 170 offset 123
ZClock 114 offset 83 HCount 0x3E Pixel 171 offset 124
ZClock 115 offset 84 HCount 0x3F Pixel 173 offset 126
ZClock 116 offset 85 HCount 0x3F Pixel 174 offset 127
ZClock 117 offset 86 HCount 0x40 Pixel 176 offset 129
ZClock 118 offset 87 HCount 0x41 Pixel 177 offset 130
ZClock 119 offset 88 HCount 0x42 Pixel 179 offset 132
ZClock 120 offset 89 HCount 0x42 Pixel 180 offset 133
ZClock 121 offset 90 HCount 0x43 Pixel 182 offset 135
ZClock 122 offset 91 HCount 0x44 Pixel 183 offset 136
ZClock 123 offset 92 HCount 0x45 Pixel 185 offset 138
ZClock 124 offset 93 HCount 0x45 Pixel 186 offset 139
ZClock 125 offset 94 HCount 0x46 Pixel 188 offset 141
ZClock 126 offset 95 HCount 0x47 Pixel 189 offset 142
ZClock 127 offset 96 HCount 0x48 Pixel 191 offset 144
ZClock 128 offset 97 HCount 0x48 Pixel 192 offset 145
ZClock 129 offset 98 HCount 0x49 Pixel 194 offset 147
ZClock 130 offset 99 HCount 0x4A Pixel 195 offset 148
ZClock 131 offset 100 HCount 0x4B Pixel 197 offset 150
ZClock 132 offset 101 HCount 0x4B Pixel 198 offset 151
ZClock 133 offset 102 HCount 0x4C Pixel 200 offset 153
ZClock 134 offset 103 HCount 0x4D Pixel 201 offset 154
ZClock 135 offset 104 HCount 0x4E Pixel 203 offset 156
ZClock 136 offset 105 HCount 0x4E Pixel 204 offset 157
ZClock 137 offset 106 HCount 0x4F Pixel 206 offset 159
ZClock 138 offset 107 HCount 0x50 Pixel 207 offset 160
ZClock 139 offset 108 HCount 0x51 Pixel 209 offset 162
ZClock 140 offset 109 HCount 0x51 Pixel 210 offset 163
ZClock 141 offset 110 HCount 0x52 Pixel 212 offset 165
ZClock 142 offset 111 HCount 0x53 Pixel 213 offset 166
ZClock 143 offset 112 HCount 0x54 Pixel 215 offset 168
ZClock 144 offset 113 HCount 0x54 Pixel 216 offset 169
ZClock 145 offset 114 HCount 0x55 Pixel 218 offset 171
ZClock 146 offset 115 HCount 0x56 Pixel 219 offset 172
ZClock 147 offset 116 HCount 0x57 Pixel 221 offset 174
ZClock 148 offset 117 HCount 0x57 Pixel 222 offset 175
ZClock 149 offset 118 HCount 0x58 Pixel 224 offset 177
ZClock 150 offset 119 HCount 0x59 Pixel 225 offset 178
ZClock 151 offset 120 HCount 0x5A Pixel 227 offset 180
ZClock 152 offset 121 HCount 0x5A Pixel 228 offset 181
ZClock 153 offset 122 HCount 0x5B Pixel 230 offset 183
ZClock 154 offset 123 HCount 0x5C Pixel 231 offset 184
ZClock 155 offset 124 HCount 0x5D Pixel 233 offset 186
ZClock 156 offset 125 HCount 0x5D Pixel 234 offset 187
ZClock 157 offset 126 HCount 0x5E Pixel 236 offset 189
ZClock 158 offset 127 HCount 0x5F Pixel 237 offset 190
ZClock 159 offset 128 HCount 0x60 Pixel 239 offset 192
ZClock 160 offset 129 HCount 0x60 Pixel 240 offset 193
ZClock 161 offset 130 HCount 0x61 Pixel 242 offset 195
ZClock 162 offset 131 HCount 0x62 Pixel 243 offset 196
ZClock 163 offset 132 HCount 0x63 Pixel 245 offset 198
ZClock 164 offset 133 HCount 0x63 Pixel 246 offset 199
ZClock 165 offset 134 HCount 0x64 Pixel 248 offset 201
ZClock 166 offset 135 HCount 0x65 Pixel 249 offset 202
ZClock 167 offset 136 HCount 0x66 Pixel 251 offset 204
ZClock 168 offset 137 HCount 0x66 Pixel 252 offset 205
ZClock 169 offset 138 HCount 0x67 Pixel 254 offset 207
ZClock 170 offset 139 HCount 0x68 Pixel 255 offset 208
ZClock 171 offset 140 HCount 0x69 Pixel 257 offset 210
ZClock 172 offset 141 HCount 0x69 Pixel 258 offset 211
ZClock 173 offset 142 HCount 0x6A Pixel 260 offset 213
ZClock 174 offset 143 HCount 0x6B Pixel 261 offset 214
ZClock 175 offset 144 HCount 0x6C Pixel 263 offset 216
ZClock 176 offset 145 HCount 0x6C Pixel 264 offset 217
ZClock 177 offset 146 HCount 0x6D Pixel 266 offset 219
ZClock 178 offset 147 HCount 0x6E Pixel 267 offset 220
ZClock 179 offset 148 HCount 0x6F Pixel 269 offset 222
ZClock 180 offset 149 HCount 0x6F Pixel 270 offset 223
ZClock 181 offset 150 HCount 0x70 Pixel 272 offset 225
ZClock 182 offset 151 HCount 0x71 Pixel 273 offset 226
ZClock 183 offset 152 HCount 0x72 Pixel 275 offset 228
ZClock 184 offset 153 HCount 0x72 Pixel 276 offset 229
ZClock 185 offset 154 HCount 0x73 Pixel 278 offset 231
ZClock 186 offset 155 HCount 0x74 Pixel 279 offset 232
ZClock 187 offset 156 HCount 0x75 Pixel 281 offset 234
ZClock 188 offset 157 HCount 0x75 Pixel 282 offset 235
ZClock 189 offset 158 HCount 0x76 Pixel 284 offset 237
ZClock 190 offset 159 HCount 0x77 Pixel 285 offset 238
ZClock 191 offset 160 HCount 0x78 Pixel 287 offset 240
ZClock 192 offset 161 HCount 0x78 Pixel 288 offset 241
ZClock 193 offset 162 HCount 0x79 Pixel 290 offset 243
ZClock 194 offset 163 HCount 0x7A Pixel 291 offset 244
ZClock 195 offset 164 HCount 0x7B Pixel 293 offset 246
ZClock 196 offset 165 HCount 0x7B Pixel 294 offset 247
ZClock 197 offset 166 HCount 0x7C Pixel 296 offset 249
ZClock 198 offset 167 HCount 0x7D Pixel 297 offset 250
ZClock 199 offset 168 HCount 0x7E Pixel 299 offset 252
ZClock 200 offset 169 HCount 0x7E Pixel 300 offset 253
ZClock 201 offset 170 HCount 0x7F Pixel 302 offset 255
ZClock 202 offset 171 HCount 0x80 Pixel 303 offset 256
ZClock 203 offset 172 HCount 0x81 Pixel 305 offset 258
ZClock 204 offset 173 HCount 0x81 Pixel 306 offset 259
ZClock 205 offset 174 HCount 0x82 Pixel 308 offset 261
ZClock 206 offset 175 HCount 0x83 Pixel 309 offset 262
ZClock 207 offset 176 HCount 0x84 Pixel 311 offset 264
ZClock 208 offset 177 HCount 0x84 Pixel 312 offset 265
ZClock 209 offset 178 HCount 0x85 Pixel 314 offset 267
ZClock 210 offset 179 HCount 0x86 Pixel 315 offset 268
ZClock 211 offset 180 HCount 0x87 Pixel 317 offset 270
ZClock 212 offset 181 HCount 0x87 Pixel 318 offset 271
ZClock 213 offset 182 HCount 0x88 Pixel 320 offset 273
ZClock 214 offset 183 HCount 0x89 Pixel 321 offset 274
ZClock 215 offset 184 HCount 0x8A Pixel 323 offset 276
ZClock 216 offset 185 HCount 0x8A Pixel 324 offset 277
ZClock 217 offset 186 HCount 0x8B Pixel 326 offset 279
ZClock 218 offset 187 HCount 0x8C Pixel 327 offset 280
ZClock 219 offset 188 HCount 0x8D Pixel 329 offset 282
ZClock 220 offset 189 HCount 0x8D Pixel 330 offset 283
ZClock 221 offset 190 HCount 0x8E Pixel 332 offset 285
ZClock 222 offset 191 HCount 0x8F Pixel 333 offset 286
ZClock 223 offset 192 HCount 0x90 Pixel 335 offset 288
ZClock 224 offset 193 HCount 0x90 Pixel 336 offset 289
ZClock 225 offset 194 HCount 0x91 Pixel 338 offset 291
ZClock 226 offset 195 HCount 0x92 Pixel 339 offset 292
ZClock 227 offset 196 HCount 0x93 Pixel 341 offset 294


The table was created using this code:


#include <stdio.h>

int main(void)
{
        for (unsigned int c = 0; c < 228; c++)
        {
                unsigned int pix = ((c * 3) + 1) / 2;
                int offsetcyc = c - 31;
                int offsetpix = pix - 47;
                printf("ZClock %3d offset %3d HCount 0x%02X Pixel %3d offset %3d\n", c, offsetcyc, (offsetpix / 2) & 0xff, pix, offsetpix);
        }
        return 0;
}


I found the GG-specific values based on the cycle count differences from the original SMS tests.

I was not able to figure out what should be the ZClock and HCount values for VINT and HINT tests, because the values returned by the GG units didn't followed the same pattern as the SMS values and the tests don't read them soon after the interrupt occurs.

- Frame IRQ HCount:

RunTest32         - first value 0x82, second value 0x84
RunTest32_GG2ASIC - first value 0x85, second value 0x84
RunTest32_GG1ASIC - first value 0x83, second value 0x83


- Line IRQ HCount:

RunTest34         - first value 0x88, second value 0x8A
RunTest34_GG2ASIC - first value 0x8B, second value 0x8A
RunTest34_GG1ASIC - first value 0x89, second value 0x89


For these tests I could copy the Mega Drive values registered by FluBBa, because the MD tests for VINT and HINT pass on the GG units, but they are slightly different, so I decided leave them unregistered.
SMSVDPTest-SMS-1.31-GG_Tests_diff.zip (5.72 KB)
Changes to the VDP Tester to add GG tests

  View user's profile Send private message
  • Joined: 07 Nov 2016
  • Posts: 11
Reply with quote
Post Posted: Sat Jul 20, 2019 10:03 pm
Here is a compiled SMS ROM with the changes applied. It runs on Game Gear using the SMS compatibility mode.

There are two Game Gear options, one for the 2 ASIC (older) version and one for the 1 ASIC version. I also forgot to mention that the HCount values showed in the end of the Game Gear tests are more GG-friendly.
VDPTEST_GG.zip (7.71 KB)
Compiled SMS ROM test.

  View user's profile Send private message
  • Joined: 05 Jan 2006
  • Posts: 417
  • Location: USA
Reply with quote
Post Posted: Sun Jul 21, 2019 12:26 am
Great work! l can do the video testing for ya sometime. I got a working 2 ASIC video out unit.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Nov 2016
  • Posts: 11
Reply with quote
Post Posted: Sun Jul 28, 2019 8:30 pm
segasonicfan wrote
Great work! l can do the video testing for ya sometime. I got a working 2 ASIC video out unit.


Thanks for the offer, segasonicfan, but I just need feedback of the results of more Game Gears running the two new test options that my patch added. Photo or video would be necessary only if none of the two new options finished with all tests passed.

The video you took for me in the past was necessary because benryves's GG failed the "HCounter correct" test and the HCount table at the final screen of the tests was unreadable on its original LCD display, a problem that your Game Gear didn't have with the TV out mod you did. With my 1 ASIC GG the "HCounter correct" also occurred, but I discovered that turning the GG off and on again (eventually needed to repeat a few times) would correct the problem (my patch adds a note about this behaviour).

After add specific GG timings to MAME, I haven't tested many games, just discovered that a one-line glitch was fixed on two scenes in the opening story of the Japanese game Madou Monogatari I - 3-Tsu no Madoukyuu. I added a ZIP file to this post with snapshots of the glitch that was solved.

  View user's profile Send private message
  • Joined: 04 Oct 2015
  • Posts: 17
Reply with quote
Post Posted: Mon Sep 05, 2022 11:26 pm
enik2 wrote
Here is a compiled SMS ROM with the changes applied. It runs on Game Gear using the SMS compatibility mode.


I tested this ROM with the Tectoy SMS3 Compact that has the 315-5681 VDP coupled with the 315-5680 I/O chip and it passed all tests of the "GG 2 ASIC version".

It fails on a many tests of the "SMS" and "GG1 ASIC" versions.
  View user's profile Send private message Visit poster's website
  • Joined: 21 Jul 2005
  • Posts: 412
  • Location: GBG
Reply with quote
Post Posted: Wed Sep 07, 2022 7:19 am
I've put up the source code on Github if anyone wants to fork and keep working on it. I'll also be willing to take PRs if time permits.
https://github.com/FluBBaOfWard/SmsVdpTest
  View user's profile Send private message Visit poster's website
  • Joined: 06 Mar 2022
  • Posts: 697
  • Location: London, UK
Reply with quote
Post Posted: Wed Sep 07, 2022 8:02 am
Amazing, thanks for sharing the code for this project, it's so useful.
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2



Back to the top of this page

Back to SMS Power!