Jump to content
IGNORED

Requesting help in improving TIA emulation in Stella


stephena

Recommended Posts

I'm requesting help with completing the final remaining bugs in the TIA emulation in Stella. First of all, a little background and the reason I'm asking for help. I've been working on the project for many years (over a decade, in fact), and while I've made improvements to the TIA emulation, I've reached my level of understanding of the code. I can easily understand what the code is doing, just not always why. And without the why, I have no hope of making further improvements.

 

This request was prompted by my situation as described in another thread. Basically, I'm on the verge of burnout in this area, and would like to finally complete this part of the emulation so I can move on to other parts of the code. The alternative from my POV is to walk away from the project entirely before I burn out completely. Please help me avoid that path.

 

Anyway, I suspect this will be a long, ongoing thread, and that I will have to add info to it quite often, as I'm very familiar with the codebase and probably not many other people really are. So, where to begin?

 

 

Current issues with the TIA emulation

 

The biggest issue is changes to NUSIZx registers after drawing has already began. The core needs to track when drawing started, and then when NUSIZx is changed, update what is drawn from that point on (keeping in mind that sometimes the NUSIZx write will change the output and sometimes it won't; it depends on the timing).

 

There are related issues with RESPx, and I suspect for very similar reasons.

 

 

How can the code be viewed

 

The ideal way (and what I personally request) is to download the code from the Stella repository, set up a compile environment, and compile/run/test it. The repo (latest version) is located at https://stella.svn.sourceforge.net, and can be checked out at https://stella.svn.s...stella/trunk.

 

The relevant files are TIA.hxx, TIA.cxx, TIATables.hxx, and TIATables.cxx.

 

 

How does the current TIA emulation work

 

The TIA code makes extensive use of tables, where (as much as possible) conditions are precomputed once, upon TIA creation. These tables essentially create 'masks' that define, for the given conditions, how the graphics should be drawn. For example, take the following example of the BALL mask for the current conditions:

 

myBLMask = &TIATables::BLMask[myPOSBL & 0x03] [(myCTRLPF & 0x30) >> 4] [160 - (myPOSBL & 0xFC)];

 

This looks complicated, but is basically determining how the ball will look given the current position (myPOSBL) and playfield control register (myCTRLPF). Since the behaviour of the ball is deterministic based on position and playfield register, the state can be precomputed. Another example of setting the player0 mask:

 

myP0Mask = &TIATables::PxMask[myPOSP0 & 0x03] [mySuppressP0][myNUSIZ0 & 0x07] [160 - (myPOSP0 & 0xFC)];

 

Here, the player0 object state is a combination of 3 things: current position, suppression, and NUSIZx. Suppression in this sense is (I believe) whether the first copy of the player should be suppressed. Since this depends on other factors, it must be decided at runtime. In fact, I believe this is part of the issue; the mySuppressP0 and mySuppressP1 booleans aren't being updated when they should. I suspect this because of the following comment on line 1151:

 

// See if we're at the end of a scanline
if(myClocksToEndOfScanLine == 228)
{
// TODO - 01-21-99: These should be reset right after the first copy
// of the player has passed. However, for now we'll just reset at the
// end of the scanline since the other way would be too slow.
mySuppressP0 = mySuppressP1 = 0;
}

Similarly, the following is from the update of NUSIZ0:

 

case NUSIZ0: // Number-size of player-missle 0
{
// TODO - 08-11-2009: determine correct delay instead of always
// using '8' in TIATables::PokeDelay
updateFrame(clock + ;

myNUSIZ0 = value;
mySuppressP0 = 0;
break;
}

 

The '8' in this case seems to be a delay that corresponds with the majority of ROMs. However, it doesn't work for all of them. If I play with the number, some of the ROMs that don't display correctly suddenly start working. While this doesn't definitely confirm that this is the issue, it lends to the conclusion that this shouldn't be a hard-coded value, and instead should be calculated at runtime based on current state.

 

Anyway, that's probably enough info for now. I would like someone knowledgeable in C/C++ to look at the TIA.cxx class and help me understand what's going on. The class is 2000+ lines of code, but I think the issues are localized to perhaps 100 lines or so. And I can point them all out. But before I do that, I welcome feedback/questions, etc.

 

Thanks in advance for any help you can provide.

 

EDIT: I've added more detailed instructions for checking out code, compiling it, etc on the Stella Development webpage.

  • Like 3
Link to comment
Share on other sites

I forgot to mention, some problem ROMs and the issues they exhibit:

 

32_20120625.bin Too much text is drawn to the left

36char.bin Text is fully drawn when it shouldn't be

barber.a26 Double-bars should start immediately from the left; there shouldn't be a single bar at all (fixed, due to typo in HMOVE functionality)

bumperbash.a26 Part of right flipper (player 1) is present when it shouldn't be. Also, part of missile0 on the left isn't extended

koolaid.a26 Collisions are constantly triggered because player0 and player1 overlap (positioning issue) (fixed, due to typo in HMOVE functionality)

meltdown.a26 Rightmost columns aren't stretched properly; I believe this is an NUSIZx change after drawing has already started

polepos.a26 'Zero' character in upper-left is mangled; while this is a missile, I believe a hardcoded delay used with updateFrame() is causing it (using smaller values fixes the issue)

yt.a26 Duplicate dice in upper-left corner, due to either invalid suppression or perhaps a late HMOVE

 

The next few may be due to other issues, and haven't been fully researched:

 

atext.bin Several obvious issues, such as vertical blank space; seems to be related to player positioning

test.bin Different from a real console

  • Like 3
Link to comment
Share on other sites

Also forgot to mention that I don't think the TIA tables/masks are the issue here. Granted, they make for some quasi-complicated to read code, but once you get past that initial hurdle, I think it's pretty easy to follow. I believe the main issue is of timing, in that player suppression isn't being turned on (or off) at the right time. It seems to be done only at the end of a scanline, which works in the majority of cases, but not always. Furthermore, writes to NUSIZx seem to be coded according the to Stella developers guide, and not to the actual hardware (IOW, no allowance is made for 'invalid' writes when drawing has already started).

  • Like 1
Link to comment
Share on other sites

I started testing the ROMs <32k with z26. All except Meltdown seem to be correct (Todo: verify with real hardware). I will repeat that using MESS and maybe other non-Stella based emulators where source code is available.

 

My hope is, that their solutions (only the general ones, not the special ROM based tweaks) can be used to fix some of Stella's problems.

  • Like 1
Link to comment
Share on other sites

I think we can remove barber.a26 from the list. It displays on my hardware (PAL Darth Vader) like Stella does (and not like z26 does). Can someone confirm this with NTSC hardware?

 

Also I cannot see any difference for test.bin. What should be different?

  • Like 1
Link to comment
Share on other sites

The following is a snapshot of barber2.a26, which is simply barber.a26 with the colours changed to make it easier to see: post-1512-0-43429600-1361559896_thumb.jpg

 

Note that the double bars start from the left, and there are 3 pairs. In current Stella, there's a single bar, then 3 pairs of double bars. It looks like either missile0 or missile1 is shifted too far. Again, this might be from updateFrame() using too large (hardcoded) values.

 

The following is from test.bin: post-1512-0-76604100-1361560058_thumb.jpg

 

I still need to make sure this differs in Stella. Perhaps it's already been fixed.

 

The final one is atext.bin: post-1512-0-86645800-1361560064_thumb.jpg

 

The differences are obvious.

 

We can probably concentrate on the first group of ROMs and ignore atext/test for now, as they don't work in any emulator.

Link to comment
Share on other sites

Similarly, the following is from the update of NUSIZ0:

 

case NUSIZ0: // Number-size of player-missle 0
{
// TODO - 08-11-2009: determine correct delay instead of always
// using '8' in TIATables::PokeDelay
updateFrame(clock + ;

myNUSIZ0 = value;
mySuppressP0 = 0;
break;
}

 

The '8' in this case seems to be a delay that corresponds with the majority of ROMs. However, it doesn't work for all of them. If I play with the number, some of the ROMs that don't display correctly suddenly start working. While this doesn't definitely confirm that this is the issue, it lends to the conclusion that this shouldn't be a hard-coded value, and instead should be calculated at runtime based on current state.

I checked the code in MESS (which seems to work nicely) and it is much more complicated here

WRITE8_MEMBER( tia_video_device::NUSIZ0_w )
{
..int curr_x = current_x();

../* Check if relevant bits have changed */
..if ( ( data & 7 ) != ( NUSIZ0 & 7 ) ) {
....int i;
..../* Check if we are (about to start) drawing a copy of the player 0 graphics */
....for ( i = 0; i < PLAYER_GFX_SLOTS; i++ ) {
......if ( p0gfx.start_pixel[i] < 8 ) {
........int min_x = p0gfx.start_drawing[i];
........int size = ( 8 - p0gfx.start_pixel[i] ) * p0gfx.size[i];
........if ( curr_x >= ( min_x - 5 ) % 160 && curr_x < ( min_x + size ) % 160 ) {
..........if ( curr_x >= min_x % 160 || p0gfx.start_pixel[i] != 0 ) {
............/* This copy has started drawing */
............if ( p0gfx.size[i] == 1 && nusiz[data & 7][1] > 1 ) {
..............int delay = 1 + ( ( p0gfx.start_pixel[i] + ( curr_x - p0gfx.start_drawing[i] ) ) & 1 );
..............update_bitmap( curr_x + delay, current_y() );
..............p0gfx.start_pixel[i] += ( curr_x + delay - p0gfx.start_drawing[i] );
..............if ( p0gfx.start_pixel[i] > 8 )
................p0gfx.start_pixel[i] = 8;
..............p0gfx.start_drawing[i] = curr_x + delay;
............} else if ( p0gfx.size[1] > 1 && nusiz[data & 7][1] == 1 ) {
..............int delay = ( curr_x - p0gfx.start_drawing[i] ) & ( p0gfx.size[i] - 1 );
..............if ( delay ) {
................delay = p0gfx.size[i] - delay;
..............}
..............update_bitmap( curr_x + delay, current_y() );
..............p0gfx.start_pixel[i] += ( curr_x - p0gfx.start_drawing[i] ) / p0gfx.size[i];
..............p0gfx.start_drawing[i] = curr_x + delay;
............} else {
..............p0gfx.start_pixel[i] += ( curr_x - p0gfx.start_drawing[i] ) / p0gfx.size[i];
..............p0gfx.start_drawing[i] = curr_x;
............}
............p0gfx.size[i] = nusiz[data & 7][1];
..........} else {
............/* This copy was just about to start drawing (meltdown) */
............/* Adjust for 1 clock delay between zoomed and non-zoomed sprites */
............if ( p0gfx.size[i] == 1 && nusiz[data & 7][1] > 1 ) {
............../* Check for hardware oddity */
..............if ( p0gfx.start_drawing[i] - curr_x == 2 ) {
................p0gfx.start_drawing[i]--;
..............} else {
................p0gfx.start_drawing[i]++;
..............}
............} else if ( p0gfx.size[i] > 1 && nusiz[data & 7][1] == 1 ) {
..............p0gfx.start_drawing[i]--;
............}
............p0gfx.size[i] = nusiz[data & 7][1];
..........}
........} else {
........../* We are passed the copy or the copy still needs to be done. Mark
............ it as done/invalid, the data will be reset in the next loop. */
..........p0gfx.start_pixel[i] = 8;
........}
......}
....}
..../* Apply NUSIZ updates to not yet drawn copies */
....for ( i = ( startP0 ? 0 : 1 ); i < nusiz[data & 7][0]; i++ ) {
......int j;
....../* Find an unused p0gfx entry */
......for ( j = 0; j < PLAYER_GFX_SLOTS; j++ ) {
........if ( p0gfx.start_pixel[j] == 8 )
..........break;
......}
......p0gfx.size[j] = nusiz[data & 7][1];
......p0gfx.start_drawing[j] = ( horzP0 + (p0gfx.size[j] > 1 ? 1 : 0)
..................+ i * 8 * ( nusiz[data & 7][2] + p0gfx.size[j] ) ) % 160;
......if ( curr_x < p0gfx.start_drawing[j] % 160 ) {
........p0gfx.start_pixel[j] = 0;
......}
....}
....NUSIZx_changed = 1;
..}
..NUSIZ0 = data;
}

Had to use dots to keep the formatting, this forum software really sucks when trying to indent code. The code is in TIA.c. The large upper part loop seems to care for changes while players are already drawn (e.g. in Meltdown), the much smaller lower part loop seems to handle the delay in other cases.

 

Overall it seems that the delay value should be depending on the existing value of NUSIZx. Quad and double wide players reduce the delay.

 

I also looked at z26's code, which also reacts to NUSIZx.

Edited by Thomas Jentzsch
Link to comment
Share on other sites

Had to use dots to keep the formatting, this forum software really sucks when trying to indent code.

 

At this time, the only way to keep indenting in code boxes when editing posts is to have the editor toggled to the plain version (where the bar above the text box is faded and none of the buttons work). Note: You have to be switched to plain mode before editing your post.

Link to comment
Share on other sites

I checked the code in MESS (which seems to work nicely) and it is much more complicated here

 

Overall it seems that the delay value should be depending on the existing value of NUSIZx. Quad and double wide players reduce the delay.

 

I also looked at z26's code, which also reacts to NUSIZx.

 

Yes, I'd already looked at that code, and the z26 code too. That's partly where I got the idea that they delays should be calculated at runtime instead of being hardcoded. Perhaps I should have mentioned that :)

 

Also, some of the complexity in how MESS does it is actually already taken care of in the tables/masks in Stella. So I suspect that what needs to be added to Stella won't be as complicated as what's in MESS. Also, I can't just take that code from MESS, as it's not GPL-compatible.

Link to comment
Share on other sites

At the moment I am trying to setup MinGW to be able to compile Stella. But since I am new to it, I fail at the first step (running ./configure as requested by make). So how do I start this??? :?( (I used the installer and included MSYS, but somehow this cannot be found, unlike g++)

 

Is there are noob documentation somewhere? (why is setting up this still not automatized or at least self explaining? :x)

 

Also, is there an integrated, lightweight IDE (like Free Pascal) for C/C++?

Link to comment
Share on other sites

At the moment I am trying to setup MinGW to be able to compile Stella. But since I am new to it, I fail at the first step (running ./configure as requested by make). So how do I start this??? :?( (I used the installer and included MSYS, but somehow this cannot be found, unlike g++)

 

I actually had to stop using MinGW/Msys some years back, since it just became too much work to get the environment set up. I use Visual Studio 2010 now, which works great once it's actually downloaded and set up.

 

Is there are noob documentation somewhere? (why is setting up this still not automatized or at least self explaining? :x)

 

Don't get too upset. I will personally get you a copy of Visual Studio 2010 if it means you'll be working on Stella :)

 

Give me a little time, and I will download Visual Studio 2010 Express (the free version) and test installing in a VM, then document how to set it up for Stella. This is a small price to pay for the one (and currently only) person to step forward and offer their help.

 

What version of Windows are you using, and is it 32 or 64-bit? I will duplicate your environment and install VS2010, then explain exactly what you need to do to continue. I agree that having to set up/maintain build environments is a PITA, particularly when you just want to get in and start coding. I do that across Windows XP/Vista/7/8 for 32/64-bit, OSX PPC and Intel, and Linux 32/64-bit. Welcome to my world :)

Link to comment
Share on other sites

That's very kind of you. I had hoped command line would work for me, but somehow MinGW/MSYS and I are not compatible. All the documentation I am reading seems to be misleading (Mount? There is no mount.exe! Blue MSYS Icon? Nope!... :x). I want to concentrate my efforts into coding, not some complicated environment setup! Who are those people who in the year 2013(!) with IDEs like Eclipse and VS around for years still think people should HAVE TO use command line tools?

 

...I better stop now... relax Thomas...

 

If you setup a VS project that I can use out of the box, that would definitely save me a lot of nerves. But I cannot promise that my result will be worth it. :) I am using Windows 7, 64-bit.

 

BTW: Do I have to study law to know which code I am allowed to use and how? :ponder: GPL means "public something" for me, I never cared for details. Boooring! :)

Link to comment
Share on other sites

Well, I would recommend Eclipse, but it's the IDE; you'd still need to download and install the compiler separately, which brings you right back where you are now. VS2010, while being proprietary software and a large download (2+ GB) at least comes with everything you need, and is basically point and click. And I know it works, so I'll stick with that for now.

 

Stella already contains a VS project, ready to open in Visual Studio. We just need to get the actual environment installed on your system.

 

As for the licensing, yes, unfortunately, the MAME/MESS source code isn't GPL compatible. You're free to look at it and adapt it, but not to take the entire thing verbatim and just drop it into Stella. Or in their words, you can use the ideas, not the code.

 

Anyway, I'll look at getting this working. It may take a few hours, and since it's 7:30PM here, maybe the rest of the night. So I'll get a setup document done for tomorrow. Maybe some time for you to relax :) Believe me, there's a reason I've been starting to get burned out on all this stuff over the years. Don't let it happen to you before you even start coding.

Link to comment
Share on other sites

So I need VS2010, not VS2012? Also, if there already is a VS project in Stella, what do you still have to do?

 

I suggested 2010 because (a) that's what I'm using, and (b) the VS project in Stella was created with 2010. It's likely that it would work with 2012 too, but I haven't tested it, and I didn't want to force that testing on you.

 

As for what I was going to do; I am installing VS 2010 Express and making sure that the included VS project file works with it (there may be some differences between the full 2010 version I use, and the Express version which is free to download). Again, I could push that testing to you, but you seem upset enough as it is :)

 

BTW: I am working with Eclipse in my daily work. :)

 

If you'd prefer to use Eclipse, I can research setting up C++ and Stella with that instead. It will take a little longer, but if you're more familiar with it, that's fine by me. It really doesn't matter to me what build environment we use, as long as we can get past the installation issues and move to the coding.

 

EDIT: I will research the Eclipse option instead, as others may want to join in, and Eclipse is probably more familiar to most people.

Link to comment
Share on other sites

If you'd prefer to use Eclipse, I can research setting up C++ and Stella with that instead. It will take a little longer, but if you're more familiar with it, that's fine by me. It really doesn't matter to me what build environment we use, as long as we can get past the installation issues and move to the coding.

No Problem. I did a project (Win8 App) with VS last year. It sucked compared to Eclipse, but I got used to it. So anything that works will do.

Link to comment
Share on other sites

BTW: Did you try to contact the developers of z26 or the a2600 emulation of MESS? They might be able (and willing) to help too.

 

I thought I was speaking to one of the developer of z26? The only other ones I know of are Eckhard and John, both of which aren't involved anymore, I think. And also Brian Watson, who helped greatly with the initial debugger support in Stella, but has been MIA for years.

 

As for the MESS a2600 guy, that's Wilbert Pol, who's actually mentioned in TIA.cxx. He gave permission to use certain parts of the code he personally added, but the tia.c file itself belongs to the MAME project, and under their license. I don't suspect they'd be interested, since from their POV they've already completed their work.

 

I just found a link for setting up Eclipse with C++, including first installing MinGW/MSys. I will try it out, and if it works, I'll create an Eclipse project for Stella. http://www.banym.de/eclipse/install-eclipse-cdt-on-windows-7

Link to comment
Share on other sites

I just found a link for setting up Eclipse with C++, including first installing MinGW/MSys. I will try it out, and if it works, I'll create an Eclipse project for Stella. http://www.banym.de/...dt-on-windows-7

That looks easy enough for me. I will give it a try tomorrow.

 

BTW: I have VS2012 Express for Windows Desktop on my computer already (had forgotten that).

Edited by Thomas Jentzsch
Link to comment
Share on other sites

Downloaded the latest source, but couldn't build it due to that X11 include issue I ran into before.

 

Edit: I have Parallels, I might be able to install an older OS X release to work on Stella. I've only got 25GB free on my drive though so I'll need to either need to clean up the drive, or get a new one. Might be a good excuse to bump up my Momentus XT to the next size, which also has twice the SSD space than the one I have now :ponder:

Edited by SpiceWare
Link to comment
Share on other sites

That looks easy enough for me. I will give it a try tomorrow.

 

BTW: I have VS2012 Express for Windows Desktop on my computer already (had forgotten that).

 

If you already have VS2012 installed, I'd appreciate it if you'd try the Stella VS project file first, located in src/win32. At this point, you're closer to a solution than I am, since you've used VS before. OTOH, I haven't really used Eclipse before, and setting it up and creating a Stella project for it could take me quite some time. I'm willing to invest the time if necessary, but please let me know if it's a good use of my time or not.

Link to comment
Share on other sites

Downloaded the latest source, but couldn't build it due to that X11 include issue I ran into before.

 

Edit: I have Parallels, I might be able to install an older OS X release to work on Stella. I've only got 25GB free on my drive though so I'll need to either need to clean up the drive, or get a new one. Might be a good excuse to bump up my Momentus XT to the next size, which also has twice the SSD space than the one I have now :ponder:

 

Yes, Xcode 3 is required. It doesn't work with Xcode 4, because SDL hasn't been ported to it yet (I really need to look into that). However, you shouldn't need to install an old version of OSX just to get the old compiler. I have Xcode 3 (and 4) installed in OSX 10.8, and it works fine. They install to completely different locations, so they shouldn't conflict. I still have the Xcode 3.2.6 DMG here, although it's ~4GB ...

Link to comment
Share on other sites

BTW: I have VS2012 Express for Windows Desktop on my computer already (had forgotten that).

 

I just downloaded and installed this exact version of VS in Windows 7/64, and it works great. So that makes thing so much easier. From there, you need to do a few other things:

 

EDITED: There's now a specific page for this; the Stella Development webpage.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...