Thomas Jentzsch Posted March 15, 2017 Share Posted March 15, 2017 Wouldn't that require vertical rescaling and resizing? Yup. Maybe this could be done when TV-effects are enabled. 1 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted March 15, 2017 Share Posted March 15, 2017 So what is FrameTiming used for? Besides the size of the emulator window? Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 15, 2017 Author Share Posted March 15, 2017 Now that I've laid it all out and explained it, I'm no longer sure what FrameTiming is for 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. Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted March 15, 2017 Share Posted March 15, 2017 (edited) 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 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 March 15, 2017 by DirtyHairy 1 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted March 15, 2017 Share Posted March 15, 2017 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? Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 15, 2017 Author Share Posted March 15, 2017 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 5 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted March 15, 2017 Share Posted March 15, 2017 I completely understand that this is a complex matter. The 2600 is somewhat special, because AFAIK its about the only console which generates its own video signal. So the problems to solve are sometimes pretty unique. 3 Quote Link to comment Share on other sites More sharing options...
alex_79 Posted March 15, 2017 Share Posted March 15, 2017 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. Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted March 15, 2017 Share Posted March 15, 2017 (edited) 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 March 15, 2017 by DirtyHairy 4 Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 15, 2017 Author Share Posted March 15, 2017 The question of resizing and rescaling is separate from this (ie, it can be done afterwards, now that the video supports hardware rendering). Lets worry about one thing at a time 3 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted March 15, 2017 Share Posted March 15, 2017 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: SECAM: and PAL: 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 1 Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 15, 2017 Author Share Posted March 15, 2017 Hurry up and get that pull request ready; I want to see this in action Also, I'd make those 'const' be 'constexpr', to guarantee that they're done at compile-time. Quote Link to comment Share on other sites More sharing options...
R.Cade Posted March 15, 2017 Share Posted March 15, 2017 (edited) 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 March 15, 2017 by R.Cade Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 15, 2017 Author Share Posted March 15, 2017 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 ). 2 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted March 15, 2017 Share Posted March 15, 2017 Hurry up and get that pull request ready; I want to see this in action 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! Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted March 15, 2017 Share Posted March 15, 2017 I've a few other things to finish, namely audio support. Just go ahead, fork it on Github and start committing, then we can satisfy our curiosity now ...just kidding, take your time, but I am looking forward to trying this stuff out, too Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 15, 2017 Author Share Posted March 15, 2017 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). Quote Link to comment Share on other sites More sharing options...
alex_79 Posted March 16, 2017 Share Posted March 16, 2017 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! 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 16, 2017 Share Posted March 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted March 16, 2017 Share Posted March 16, 2017 Just go ahead, fork it on Github and start committing, then we can satisfy our curiosity now 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! Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted March 16, 2017 Share Posted March 16, 2017 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): I removed the "F6SC" from its entry in DefProps.hxx and it was detected as F6, so didn't run correctly: Made the change ThomH suggested and it's now auto detected correctly: 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; } Quote Link to comment Share on other sites More sharing options...
ThomH Posted March 16, 2017 Share Posted March 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 16, 2017 Author Share Posted March 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 17, 2017 Author Share Posted March 17, 2017 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; } 1 Quote Link to comment Share on other sites More sharing options...
+stephena Posted March 18, 2017 Author Share Posted March 18, 2017 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 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.