Jump to content
IGNORED

Testing the new Stella TIA core


stephena

Recommended Posts

Now that I've laid it all out and explained it, I'm no longer sure what FrameTiming is for :-D

 

I will look through the code again and see if it's specifically needed. I now realize that it's not really needed for the Alt-l display, since if something says PAL and is running at 60Hz, it is obviously PAL60. I need to think about this a little further. My main concern is that we have all the functionality there to override the auto-detection, since it doesn't always work.

Link to comment
Share on other sites

In all cases, we have all the info we need. Is this more or less confusing than what others have in mind??

 

That's precisely what I had in mind (possible with other identifier names, but I am unsure about those myself). To rephrase it in my words and add a bit of lore about the new TIA core:

 

FrameTiming

==========

The quantities that define what parts of a frame are displayed (a frame basically is the period between two VSYNC cycles) are visible frame height ("height") and visible frame start ("ystart"), These can be autodetected or set (either manually or via ROM property). In case of autodetection, the selected FrameTiming (aka currently TVMode) defines a baseline from which autodetect starts (if this is wrong, autodetect might go funky in edge cases). FrameTiming itself can either be preset or autodetected from the total number of scanlines per frame (the stuff between two VSYNC cycles) when the console starts up. Basically, FrameTiming is something that parameterizes a simulated, very flexible TV set and usually is autodetected. It has no relevance outside the question "which scanlines are shown on screen".

 

ConsoleTiming

===========

This defines the TIA flavor and oscillator frequency used in the console --- either a PAL, NTSC or SECAM model. It is used to select the palette and the oscillator frequency. It cannot be autodetected, but it can be changed at runtime.

 

PAL50/60 and friends

===========

Those represent a specific frame layout on a specific console type. A game written for PAL60 should run on a PAL console and will generate a NTSCish frame layout. They all amount to selecting a specific combination of ConsoleTiming and FrameTiming (and the latter will usually be autodetected fine, just as an ordinary TV set will usually adapt to the signal within a tolerance window and display it).

 

Does that make sense? Actually, after writing all this, I think I would prefer to use FrameLayout instead of FrameTiming :P

 

EDIT: I think this also answers you question about the signifcance of FrameTiming: it defines a baseline for the frame detection algorithm. If ystart and height are set, it is irrelavant.

 

ANOTHER EDIT: I forgot another, very important use for FrameTiming: if ConsoleTiming is not specified, the autodetected value of FrameTiming is used to set it :)

Edited by DirtyHairy
  • Like 1
Link to comment
Share on other sites

If I get you right, then providing a FrameTiming/TVMode is (only?) a required hint for autodetection, correct? Wouldn't for such edge cases the settings for YStart and Height be sufficient?

 

Also, what happens to ROMs which are somewhat in between (~285 scanlines)? Those would either fall into 50 or 60Hz, right? Which both are not exactly correct. Again, YStart and Height should solve the problem more precisely, no?

Link to comment
Share on other sites

I will also add that part of the complexity here is that the semantics of Display.Format has changed from old Stella to new, as well as ystart/height (which can now be auto-detected, and before it couldn't be). To his credit, DirtyHairy mentioned that we'd need to come back to this and refactor at some point, since some of the meanings have changed and made things more confusing. So it's not just that the TIA is being improved; several old assumptions are no longer valid/required either. We are, after all, porting the TIA class from a completely different emulator :)

  • Like 5
Link to comment
Share on other sites

 

Wouldn't that require vertical rescaling and resizing?

Stella already resizes the window (in the horizontal direction) depending on the FrameTiming. The amount of rescaling (in percentage) can be changed in the "Video Settings" menu or using the "-tia.aspectn"/"-tia.aspectp" options from the command line. If you select the "Fullscreen Fill" option and switch to fullscreen mode, the display fills the screen while keeping the aspect ratio.

post-10599-0-98958900-1489608561_thumb.png

Link to comment
Share on other sites

If I get you right, then providing a FrameTiming/TVMode is (only?) a required hint for autodetection, correct? Wouldn't for such edge cases the settings for YStart and Height be sufficient?

 

Almost. There are three aspects to TVMode (I refer to the quantities currently used by the code in this post ;) )

 

* It is the result of the initial autodetection at startup (which subsequently determines PAL50/60 and friends): the emulation runs for 60 or so frames during which the value is detected, then it resets with the value fixed. The set of possible results of autodetection is precisely the value set of TVMode --- there is no more information that the TIA can determine. This is unchanged from Stella 4 (apart from the actual detection algorithm), but there the result was directly mapped to PAL50 or NTSC60 in the old code. So regardless of how we call it and how we represent it, this quantitiy exists and has meaning.

 

* It determines frame height (unless configured manually or via ROM properties). My previous statement was a bit misleading here: it is ystart which is autodetected, not height.

 

* It is a paramter that stabilizes ystart autodetection. Part of the confusion that there are two autodetected quantities, and they are autodetected at different points in the emulation lifecycle: TVmode is detected during startup, before anything is actually displayed, while ystart is detected during the first few visible frames. In many cases TVMode does not influence the detected ystart value, but we have seen enought fragile cases where it is relevant. From what I have seen, I think that leaving it out will leave too many loose ends for autodetection to work reliably.

 

Also, what happens to ROMs which are somewhat in between (~285 scanlines)? Those would either fall into 50 or 60Hz, right? Which both are not exactly correct. Again, YStart and Height should solve the problem more precisely, no?

 

We both have seen such cases. Some are treated correctly, some fail initial autodetection (and need PAL50/60, NTSC50/60 or SECAM50/60 specified), some fail ystart autodetection (requiring ystart and possibly specified), and some fail both. We basically try to guess from the video signal what console the game was intented to run on, and if the signal is bad, autodetection becomes unreliable. There is no way to autodetect all ROMs correctly, and changing names won't help, either ;-)

 

Regardless of how we call it, the information represented by TVMode will always be there, and not using it in autodetection would be waste. It is only truly irrelevant if all paramters (ystart, height and ConsoleTiming, now using the new term, are specified). The same holds true for PAL50/60 and friends, but I think ConsoleTiming offers less possibility for misunderstandings while representing the same information.

Edited by DirtyHairy
  • Like 4
Link to comment
Share on other sites

Based on alex_79's info, I've updated the timer routine to this:

void Thumbulator::updateTimer(uInt32 cycles, uInt8 type)
{
  const double NTSC = 70.0 / 1.193182;  //58.6664323021;
  const double PAL  = 70.0 / 1.182298;  //59.2061068702;
  const double SECAM = 70.0 / 1.187500;
  double increment;
 
  if (T1TCR & 1) // bit 0 controls timer on/off
  {
    if (type == 0)
      increment = cycles * NTSC;
    else if (type == 1)
      increment = cycles * PAL;
    else //if (type == 2)
      increment = cycles * SECAM;
    T1TC += uInt32(increment);
  }
}

 

and obtained these timer results for NTSC:

post-3056-0-25767000-1489615682_thumb.png

 

SECAM:

post-3056-0-64382500-1489615690_thumb.png

 

and PAL:

post-3056-0-48304000-1489615702_thumb.png

 

Those values fall in line with the samples done so far so I changed the autodetect routine in Draconian to this:

void SplashVerticalBlank()
{
    MODE++;
    
    if (MODE == 0x81)
    {
        T1TC = 0;           // make sure timer starts at 0
        T1TCR = 1;          // turn on timer
    }
    else if (MODE == 0x82)
    {
        T1TCR = 0;          // turn off timer
        
        if (T1TC < (0x11e8ff + 0x11d329)/2)
            MM_TV_TYPE = NTSC;
        else if (T1TC > (0x11fd2b + 0x11e8ff)/2)
            MM_TV_TYPE = PAL;
        else
            MM_TV_TYPE = SECAM;
        
    }
    else // if (MODE == (0x80 + 60))   // 1 second delay for testing splash screen line count
    {
        // eventually this will be the time the AtariAge splash screen is displayed
        MODE = 1;   // menu
    }
}

 

ROM:

draconian_20170315.bin

  • Like 1
Link to comment
Share on other sites

Out of curiosity, why spend all the effort to detect the ROM at all? I should be able to choose which console (PAL, NTSC, SECAM, PAL60) I want to emulate, and any cartridge I insert will play would look the way it should on that machine.

 

Want to see how PAL Pitfall! plays on my NTSC 7800? OK, choose that config and see...

NTSC Donkey Kong on SECAM 2600 Junior... OK.

 

You're spending time emulating something that doesn't exist... A multi-format console. :)

Instead, make it so you can choose different versions of the TIA, etc.

(Unless you can already do this, in which case- ignore me).

Edited by R.Cade
Link to comment
Share on other sites

Stella has to emulate every known type of console, so in that sense, yes, it is trying to be a multi-format console. There's no other way to do it if we want to be able to play every ROM out there.

 

Also, the typical end-user wants to just double-click on a ROM and have it display correctly. They often don't know (or care) about NTSC, PAL, etc. So while you may be content to manually select the console type, etc, it is best to auto-detect as much as possible, and to have the end-user do as little as possible (which is what they often will do :evil: ).

  • Like 2
Link to comment
Share on other sites

Hurry up and get that pull request ready; I want to see this in action :grin:

:lol:

 

I've a few other things to finish, namely audio support. The 3-voice routines sound incorrect, and packed sample support has yet to be implemented. However, working on the ARM Timer helped me figure out how mySystem->cycle() works (specifically that it gets reset to 0 all the time :!: ) which might help with the audio. I believe batari wrote the audio routines for Stella's DPC+ support, and they'd never made sense to me before without that bit of knowledge.

 

I also suspect it'd be better to set type just once, and set a double variable to the appropriate value at that time instead of passing and deciphering it every time the ARM routines are run.

 

Also, I'd make those 'const' be 'constexpr', to guarantee that they're done at compile-time.

Done!
Link to comment
Share on other sites

I've a few other things to finish, namely audio support. The 3-voice routines sound incorrect, and packed sample support has yet to be implemented. However, working on the ARM Timer helped me figure out how mySystem->cycle() works (specifically that it gets reset to 0 all the time :!: ) which might help with the audio. I believe batari wrote the audio routines for Stella's DPC+ support, and they'd never made sense to me before without that bit of knowledge.

 

Yes, I really have no idea how those routines work either, which is why the Chetiry bankswitch scheme (and ROM) doesn't have any music output yet.

 

 

I also suspect it'd be better to set type just once, and set a double variable to the appropriate value at that time instead of passing and deciphering it every time the ARM routines are run.

 

Yes, I meant to mention that one too. It only ever needs to be set once, and thereafter only if the type manually changes (with Ctrl-f).

Link to comment
Share on other sites

Those values fall in line with the samples done so far so I changed the autodetect routine in Draconian to this:

[...]

I soldered the missing TV-TYPE switch on the SECAM console and managed to get a (lousy) color picture on the LCD TV.

The Autodetection seems to work just fine!

post-10599-0-48512100-1489662836_thumb.jpg

  • Like 1
Link to comment
Share on other sites

The main engine of a traditional VCS is the three-chip chipset. That's what Stella emulates. The main engine of the portable flashback console is a SoC + emulator. Quite distant from the three original chips. I don't necessarily believe an emulator should be emulating an emulator.

 

I do believe that Stella should properly emulate power-up states of original internal hardware and external cartridge hardware where possible; whether it be randomized, or zero'd, or whatever.

 

Keatah,

I Agree. There are a couple more protos that don't run in Stella but run on all real Atari's, including the flashback portable. Javatari and Harmony/encore both match real hardware performance here but Stella does not.

 

I can't change the code without breaking compatibility with all Atari consoles, but I can work around the bug to support Stella as a platform thus the release versions of the unworking proto's do work on Stella.

 

This similar SuperCharger bug was patched in the Harmony firmware but not in Stella despite an example with real hardware.

 

And the Atari portable is real hardware too; this console gets extra points for being an official Atari, and in this instance, for getting CBS RAM initialization correct - If someone could prove that 1983 CBS RAM technology utilized static RAM or a button battery in the cart (it doesn't) we would have two official console models to support.

Link to comment
Share on other sites

Just go ahead, fork it on Github and start committing, then we can satisfy our curiosity now :evil:

Something else I still need to figure out - I've not yet signed up for, nor learned how to use Github.

 

Yes, I really have no idea how those routines work either, which is why the Chetiry bankswitch scheme (and ROM) doesn't have any music output yet.

I'll have to take a look once I figure it out for BUS and CDF. Do we have any info on it?

 

 

I soldered the missing TV-TYPE switch on the SECAM console and managed to get a (lousy) color picture on the LCD TV.

The Autodetection seems to work just fine!

Sweet!

Link to comment
Share on other sites

ThomH made a suggestion in the openemu problem?.. topic about Superchip detection:

 

 


 

Quick tip on the RAM test though, as it could help you to eliminate the special case you mentioned for Dig Dug: I initially had more or less exactly that but found it failed on the Dig Dug here on Atari Age. I switched to "if the first 128 bytes are a mirror of the second". That works correctly for all ROM images here, including Dig Dug. No false positives, no false negatives. My working theory is that somebody read the cartridge without physical disassembly in ascending address order, the first 128 bytes getting whatever happened to be on the bus of whatever device they constructed, but then getting the same values reported back because the read ports come after the write ports and the write ports also captured whatever was on the bus.
If you considered that as a strategy but discounted it for some reason, the warning would be appreciated.

 

I ran the version of Dig Dug I have and it's the one with the hardcoded type (no asterisk):
post-3056-0-31483900-1489682089_thumb.png
I removed the "F6SC" from its entry in DefProps.hxx and it was detected as F6, so didn't run correctly:
post-3056-0-23749300-1489682137_thumb.png post-3056-0-36330400-1489682298_thumb.png
Made the change ThomH suggested and it's now auto detected correctly:
post-3056-0-18015700-1489682162_thumb.png post-3056-0-38905800-1489682365_thumb.png
The change:
bool Cartridge::isProbablySC(const uInt8* image, uInt32 size)
{
  // We assume a Superchip cart repeats the first 128 bytes for the second
  // 128 bytes in the RAM area, which is the first 256 bytes of each 4K bank
  uInt32 banks = size / 4096;
  for(uInt32 i = 0; i < banks; ++i)
  {
    for(uInt32 j = 0; j < 128; ++j)
    {
      if(image[i*4096+j] != image[i*4096+j + 128])
        return false;
    }
  }
  return true;
}
Link to comment
Share on other sites

If it's any help further to comment, I have a unit test for my detection routines that runs through every ROM available on AtariAge and compares results against a hand-collated list; this test doesn't throw up any false positives or false negatives amongst that set.

Link to comment
Share on other sites

I'll go ahead and make this change. And the analysis is correct; the original dumper for this ROM wasn't as advanced as other ones, and didn't take the read (or write, I forget) port into account. I remember reading about this somewhere, but again, I forget where it was.

 

I've also done tests on the approx. 6000 ROMs I have, and this change didn't break anything.

Link to comment
Share on other sites

OK, this is now implemented in Stella, in a little more efficient manner:

bool Cartridge::isProbablySC(const uInt8* image, uInt32 size)
{
  // We assume a Superchip cart repeats the first 128 bytes for the second
  // 128 bytes in the RAM area, which is the first 256 bytes of each 4K bank
  while(size)
  {
    if(memcmp(image, image + 128, 128) != 0)
      return false;

    image += 4096;
    size  -= 4096;
  }
  return true;
}

  • Like 1
Link to comment
Share on other sites

Spice, there is now functionality exposed to query whether the console is ntsc, pal, or secam. This is available through the method call: mySystem->tia().consoleTiming(). This returns ConsoleTiming::ntsc, ConsoleTiming::pal or ConsoleTiming::secam, which you can tie into your updateTimer() call (which should now accept a ConsoleTiming parameter instead of a uInt8 parameter).

 

I'm unable to test this since you haven't committed to git yet; hint-hint :evil:

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...