|
ForumsSega Master System / Mark III / Game GearSG-1000 / SC-3000 / SF-7000 / OMV |
Home - Forums - Games - Scans - Maps - Cheats - Credits Music - Videos - Development - Hacks - Translations - Homebrew |
Goto page 1, 2 Next |
Author | Message |
---|---|
|
SMS VDP Tester
Posted: Tue Dec 11, 2007 12:37 am Last edited by FluBBa on Wed Nov 04, 2009 12:07 pm; edited 3 times in total |
I've been putting together a VDP test program, I tried to think of all possible way to mess with the address/registers/latch/buffer that could be logicaly verified. I haven't found any SMS emulator (for Windows) that handles everything right (not even Charles SMSPlus, though I followed his doc which is correct compared to a real SMS).
I've successfully run the SMS test on a PAL SMS1 @50 & 60Hz and on a PAL SMS2 (@50Hz), I've also run the MD test on a PAL MD1 with a PBC. http://ndsretro.com/download/SMSVDTST.zip If someone could run the test on a GG in SMS mode that would be great. Edit: Updated with 10 new tests. Edit2: Added some more tests, including accurate timing for interrupts and VINT flag, lots of sprite tests. Edit3: Fixed up the timing for HInt and VInt. |
|
|
Posted: Tue Dec 11, 2007 1:27 am |
Thanks, that's great. I have to find out what's going wrong in my emu. I wonder though why Test 15 is writing to the Test 14 variable at one point. But I don't understand Test 15 at the moment, so maybe it's correct :) | |
|
Posted: Tue Dec 11, 2007 9:44 am |
Thanks for pointing it out, I've uploaded a fixed version now. | |
|
Posted: Tue Dec 11, 2007 5:03 pm |
very useful program, thanks
Test #9 and #10 were the only ones that were not supported by the version of smsplus I used... now it is fixed, thanks to your program ;) Do any games use this "buffer" feature ? |
|
|
Posted: Tue Dec 11, 2007 6:18 pm |
Great stuff FluBBA!
Can anyone run the test on a Game Gear ? |
|
|
Posted: Tue Dec 11, 2007 6:30 pm |
Excellent work, I was thinking of trying to finish my SMS emulator and releasing it last night so this has provided more incentive to do so. :-)
I have a GG-PRO, but the DreamWriter software is hard-coded to use legacy port addresses and modern PCs don't tend to have legacy ports, resulting in PCI-based parallel ports with non-legacy addresses (mine's at 0xCCD8). I'll have to see if I can dig out an old PC running with the software. :-\ |
|
|
Posted: Tue Dec 11, 2007 6:41 pm |
Not likely, though I'm in the process of writing some test programs for the Sega 8bit systems and I'm just trying to be thorough (sp?). I don't think there is a need for todays emulators to not be accurate, is there? So I'm just doing this to help out emulator authors and a bit of documenting. |
|
|
Posted: Tue Dec 11, 2007 8:58 pm |
Great effort! I've tried and it seems that Emukon get less errors. Kega fail, Meka fail... this confirm me that actually there're no accurated emulators on the net obviously always remembering that writing an emulator is often free and difficult. |
|
|
Posted: Tue Dec 11, 2007 10:16 pm |
I am pretty sure that a Game Gear (either in GG mode, either in both GG/SMS mode, less likely) has differences.
MEKA has code to cope with Game Gear (eg: Bart vs Space Mutants, AX Battler are using some of those features as far as I remember), probably other emulators doing the same, emulating a pseudo VDP in-between SMS and GG. Hence some "fails". I might be wrong because this is only out of memory. Of course it should be fixed and VDP emulation mode switched accordingly. But I'm curious to see results of a Game Gear in SMS mode and in GG mode. |
|
|
Game Gear results
Posted: Thu Dec 13, 2007 11:19 am
|
I ran it on a Game Gear in SMS mode and Game Gear mode, and it passes all tests in both instances (of course, in Game Gear mode the palette is incorrect and the display is cropped, so you have to switch back to SMS mode to view the results once the test has run).
No apologies made for the terrible photo quality. :-) |
|
|
Posted: Thu Dec 13, 2007 11:31 am |
I stand corrected.
(Now hopefully the software can also be corrected) |
|
|
Posted: Thu Dec 13, 2007 9:31 pm |
Thanks benryves for testing it on the GG. =)
I have a couple of more ideas for tests, though most of them can only verified visually and not logically. |
|
Simon82_
|
Posted: Fri Dec 14, 2007 8:12 am |
Excellent that it run flawless on a real gg so it's true that emulators has got problems. You should make it a sort of "benchmark" including some "graphical example" of each test.. :) |
|
|
Posted: Fri Dec 14, 2007 8:28 am |
I wrote one a while back for testing access speeds, where you have to look for display corruption to figure out whether you've exceeded the limit. Although now I come to think of it, that could be detected logically (write fast, read back at a safe speed and compare or checksum - or even write slow/read fast to test the other way). | |
|
Posted: Mon Dec 17, 2007 7:44 am |
Great test!
I gave it a quick try on mess and it passed all tests without any modifications to the code :) |
|
Simon82_
|
Posted: Mon Dec 17, 2007 10:32 am |
Interesting considering that every other emulator got problems.. |
|
|
Posted: Mon Dec 17, 2007 11:22 am |
mess appears to use a real bios, the others AFAIK are emulated. | |
|
Posted: Mon Dec 17, 2007 8:45 pm |
this has nothing to do with bios, MESS is simply a well maintaned "community" emulator, focused on accurracy
from the changelog:
;) |
|
|
Posted: Mon Feb 11, 2008 5:39 pm |
Updated with 10 new tests. | |
|
Posted: Sat Feb 23, 2008 8:15 pm |
I'm trying to get my VDP implementation to pass the tests. There's one I fail, but do not understand what it's trying to check for - "VDP Register mirrors". What does this mean? :-) | |
|
Posted: Sat Feb 23, 2008 10:13 pm Last edited by FluBBa on Sun Feb 24, 2008 9:36 am; edited 1 time in total |
The 2 most significant bits of the second byte you write to the VDP CTRL port desides what function you want to use (read, write, register & palette).
When writing to the registers some of the other 6 bits have meaning, depending on the VDP version (TMS9918, SMS/GG, MD) from 3 to 5 bits, the other ones are ignored. So for the SMS you should only check the 4 least significant bits. I hope that explains it well. =) |
|
|
Posted: Sat Feb 23, 2008 10:49 pm |
Cheers for the quick reply!
As far as I'm aware, this means that when the second byte is written to the control port, you should mask it with 0x0F and use this as the register index. I'm doing this, yet fail the test. Here's the relevant snippet from my code... /// <summary>
/// Write a byte of data to the <see cref="VideoDisplayProcessor"/> control port. /// </summary> /// <param name="data">The data to write to the port.</param> public void WriteControl(byte data) { if (this.waitingForSecond) { this.accessMode = (DataAccessMode)(data >> 6); this.address = (ushort)((this.address & 0x00FF) + (data << 8)); switch (this.accessMode) { case DataAccessMode.VideoRamReadWrite: // 0 this.readBuffer = this.vram[this.address & 0x3FFF]; ++this.address; break; case DataAccessMode.RegisterWrite: // 2 this.registers[data & 0x0F] = (byte)(address & 0xFF); this.UpdateIrq(); break; } this.waitingForSecond = false; } else { this.address = (ushort)((this.address & 0xFF00) + data); this.waitingForSecond = true; } } I have a myriad other VDP bugs (for example, I have no horizontal counter emulation at all!) so it might be something completely unrelated. Thank you for this very useful tool! It's helped me greatly so far. :-) |
|
|
Posted: Sun Feb 24, 2008 9:43 am |
I think that test was timing dependant before, I've uploaded a new version again.
The test works by enabling and disabling the line interrupt (through register $00, $10, $20 & $30) so that must be working as well. I think it was just timing problem before your code looks ok, test it again. |
|
|
Posted: Sun Feb 24, 2008 3:48 pm |
I'm still failing the test here. I do have some line-interrupt timing problems (which may or may not be CPU-related) in certain games, though, so I'll try and sort those out first!
Edit: Paul Baker pointed out the bug in my interrupt code, so the test now passes. Sorry for that! |
|
|
Posted: Wed Feb 27, 2008 5:50 pm |
thanks for taking the time doing this ;)
hum, I only failed at the test checking correct "HCOUNTER values" :strangely, I use the table from SMS Plus, which have the following values (342 pixel entries):0x00-0xe9,0x94-0xff From your readme:
I don't understand, this makes more than 342 pixels ? |
|
|
Posted: Wed Feb 27, 2008 9:28 pm |
The values should be between 0xE9 -> 0xFF & 0x00 -> 0x93 (or how ever you want to count).
Every third value is repeated once. On my 2 SMS they are like this: 0x00, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06... Though on my MD I don get a definitive sequence, it repeates both 0x00, 0x01 & 0x02 depending on how it feels when I turn it on. I will try to fix up the test later to account for this. |
|
Guest
|
Posted: Thu Feb 28, 2008 4:31 am |
Isn't the horizontal counter only used for the light gun and nothing else ? | |
|
Posted: Thu Feb 28, 2008 7:31 am |
Nope, I'm using it right now in my test program as you can see :P | |
|
Posted: Thu Feb 28, 2008 10:26 am |
thanks, this was definitely a mistake in the table I used, I fixed this (it was even described in GG docs and it's the same for genesis in h32 mode) About the repetitive value,doesn't it depend on read timings ? btw, I always thought that hc latch could only work with external peripheral driving TH, that is when TH is set to input only (on the genesis for example, it seems that you can not trigger INT2 by setting TH to output and writing 0 then 1 into TH bit) |
|
|
Posted: Thu Feb 28, 2008 12:25 pm |
It depends on the syncronisation between the VDP clock and the CPU clock.
I don't know how the MD acts in MD mode as I don't have a flashcart for the MD, the HCount latch works just fine in SMS mode (except that the repeating values are not the same all the time). |
|
|
Posted: Thu Mar 27, 2008 4:19 pm |
Added 2 new test for line interrupt and vblank interrupt, plus some very preliminary mode5 palette test. | |
|
Posted: Sat Apr 05, 2008 7:06 pm |
I don't quite follow how you measure the HCount values, especially the offsets (eg your "0xE9 -> 0xFF & 0x00 -> 0x93" statement - why do you start at $E9?)
When the H counter is latched, my current logic simply takes the number of CPU cycles that have executed since the start of the current scanline, multiplies by 342 then divides by 228. This fails the test! I've attached two screenshots - the first is generated when I take the main SMS test, the second when I take the HCount timing test. I haven't found any emulators that pass the test, so have nothing to compare them against! This is the last test I'm failing, so am naturally quite eager to correct my bugs! |
|
|
Posted: Sat Apr 05, 2008 9:07 pm |
Are you sure you're not dividing first and then multiply? (use paranthesis)
Even if you had the wrong numbers in your calculation you shouldn't end up with the same number 13 times =) 0xE9 is -23, that's ~46 vdp clocks before the screen starts, 0 is on pixel 0. You also can use SMSAdvance on Visualboy Advance to see what the values should be. |
|
|
Posted: Sat Apr 05, 2008 10:21 pm |
Yes, the exact code is as follows: /// <summary>
(I did forget to mention that I divided the number of pixels drawn by two).
/// Latches the value of the horizontal counter. /// </summary> public void LatchHorizontalCounter() { int ExecutedCycles = this.Emulator.TotalExecutedCycles - this.CpuCyclesAtStartOfScanline; int PixelsDrawn = (ExecutedCycles * 342) / this.CpuCyclesPerScanline; this.HorizontalCounter = (byte)(PixelsDrawn / 2); } I'm not quite sure how your test works, so I'm also not quite sure where I'm going wrong. If I rig LatchHorizontalCounter to simply increment HorizontalCounter by one (or any other number) each time it's called, the test results show a smoothly incrementing value to reflect that (however, for such a test to work, you'd need to poll the counter in < 1 CPU cycle, which isn't going to happen). If I just return ExecutedCycles directly (a value which changes wildly each call) I get similar results to the previous screenshots - long runs of identical numbers. Could it be because scanlines aren't exactly 228 clock cycles long? On average they are, but some are a little longer (and some a little shorter) as not all sequences of instructions will fit into the 228 clock cycle designation. Thank you very much for your patience, but I'm absolutely stumped here! EDIT: My assumption - that scanlines aren't exactly 228 cycles long - seems to be vaguely correct. Rather than use the total number of CPU cycles that have been executed to calculate the offset from the start of the current scanline, I use a secondary counter that increments in fixed 228 increments and calculate the pixel offset based on that. I still get the wrong values, but at least they're only out in so far as they increment in the sequence 0, 0, 1, 2, 3, 3, 4, 5, 6, 6, ... |
|
|
Posted: Sun Apr 06, 2008 10:06 am |
My calculation is something like this:
HCount = (590 - (scanLineCycle*3))/4; Where scanLineCount should be between 0 & 227 (228 cycles). |
|
|
Posted: Wed May 14, 2008 12:39 pm |
Nice utility. The latest mobile version of JavaGear I have in the works passes the first screen of tests no problem.
Obviously on a mobile based emulator there is still a need to ensure speed is pretty good, and not to add unnecessary complexity. With the line interrupt test (last test screen 2), it currently fails as both frame int and line int are set simultaneously, at the very last stage of the test. Can anyone recommend a lightweight way of implementing the correct behaviour? |
|
|
Posted: Wed May 14, 2008 7:53 pm |
I guess you haven't worked with a 16MHz ARM machine ;) If you are talking about the HCounter I don't think you should put too much effort into that. The frame interrupt is taken at the begining of line 0xC1 (193), the line interrupt happens between line 0x00 and 0xC0 (0 to 192) (Bock take note). |
|
|
Posted: Wed May 14, 2008 9:44 pm |
Trust me - the performance you get out of some Java phones when emulating a CPU, is probably the equivalent of a 16Mhz ARM processor running asm emulation. :)
Thanks for the clarification on the frame interrupt. I was setting the frame interrupt flag on line 192 and then actually allowing the interrupt to be triggered from line 193. Correcting this to the way you describe fixed the text. |
|
|
Posted: Tue May 20, 2008 9:45 am |
from the WIKI:
your test is waiting for HC to change on a TH 0->1 transition. Emulating the contrary (like described in Wiki and docs) makes the test failed so, who is right ? |
|
|
Posted: Tue May 20, 2008 10:13 am |
The wiki may be wrong. I didn't confirm the details on hardware, just based on my own understanding of how things work and the official docs. | |
|
Posted: Tue May 20, 2008 12:04 pm |
As said before, the tests have been run succesfully on my 3 hardware configurations, I suppose there can be differences (maybe the Japanese SMS?). | |
|
Posted: Thu Feb 26, 2009 9:36 pm |
Updated the VDP tester, lots of timing and sprite tests. | |
Simon82_
|
Posted: Fri Feb 27, 2009 12:58 pm |
I cannot find an emulator that run it flawless... |
|
|
Posted: Wed Aug 12, 2009 11:03 pm |
Would you mind explaining what "VCounter chg time" and the straight column are testing for? | |
|
Posted: Wed Aug 12, 2009 11:50 pm |
"VCounter chg time" measures/tests at what (HCount) time the scanline register (VCounter) changes.
The straight column tests at what (HCount) time HScroll value is latched. |
|
|
Posted: Thu Aug 13, 2009 12:43 am |
Thanks. :-)
When latching HCount, I calculate the value based on the total number of CPU cycles executed since the beginning of the scanline, divided by the number of cycles per scanline, multiplied by 342, then divided by 2. Does this sound right? One problem I am aware of is that I count the total number of CPU cycles executed before outputting a value to a port, when in reality there should be a number of clock cycles before and after the output. I fudge the HCount values by subtracting eight before dividing by two, but in reality there would be a number of cycles before and after the output - how is that usually measured (do you have a reference)? Edit: Sorry about that, I forgot that .zip files can contain other files (in this case, documentation) when it came to SMS ROMs :-$ I should learn to read first! |
|
|
Posted: Thu Aug 13, 2009 11:36 pm |
Some comments on the version posted on the 26th February 2009, running on a real Game Gear in SMS mode:
Somewhat interestingly the errors match up identically with the errors in my emulator, and I was hoping to fix these by comparing my results to the ones from the hardware - so you could say I passed with flying colours. :-) |
|
|
Posted: Fri Aug 14, 2009 9:05 am |
Do you get consistent repeating numbers for the HCount values?
You wrote that it had repeating numbers for 2A & 2D, on a SMS it should have repeating numbers for 26, 29, 2C and so on. Can you see that pattern matches for all numbers on the GG or is it hard to see on the blurry screen ? ;) Also I would like to know the patterns/numbers for when the scanline wraps (eg ~93 - ~E9). Hopefully I can get hold of a GG and MasterGear adapter so I can test all of the stuff myself but that might be a while before it happens. |
|
|
Posted: Fri Aug 14, 2009 10:28 am |
The wrap occurs at 93->E0, but you'll have to wait for me to modify the program to use a clearer font and white-on-black before I can start trying to search for patterns in the HCount values. It's very difficult to read the results on the Game Gear screen, yes. ;-) | |
|
Posted: Mon Aug 17, 2009 2:39 pm |
You must also remember that a scanline isn't exactly broken up how most people think of it. The exact relationship of the cycle count (and even when latching occurs) isn't quite known yet. Sega documentation states the first visible area of the screen is drawn at hlatch of $08. I hope to verify this in a month or two. The way Flubba (and lightguns) latches the count also might be delayed by a few cycles, it's hard to verify that though.
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". 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? |
|
Goto page 1, 2 Next |