JetSetIlly / Gopher2600

Gopher2600 is an emulator for the Atari 2600 games console
GNU General Public License v3.0
239 stars 20 forks source link

args not passed to elf_main #29

Open ZacharyScolaro opened 3 months ago

ZacharyScolaro commented 3 months ago

When loading an elf rom the elf_main() function should be passed an array of uint32_t that specifies the system type, clock rate, and feature flags.

See UCA firmware for an example here: https://github.com/Al-Nafuur/United-Carts-of-Atari/blob/main/source/STM32firmware/PlusCart/Src/cartridge_emulation_ELF.c

uint32_t mainArgs[MP_COUNT] =
{
    0, // MP_SYSTEM_TYPE (TBD below)        0  - Should be set based on TV
    SystemCoreClock, // MP_CLOCK_HZ         1 - Should be set based on arm CPU clock
    FF_MULTI_CART, // MP_FEARTURE_FLAGS     2 - Use this flag to indicate that the game should support exiting 
};

// For MP_SYSTEM_TYPE

define ST_NTSC_2600 0

define ST_PAL_2600 1

define ST_PAL60_2600 2

// For MP_FEATURE_FLAGS

define FF_MULTI_CART 1 // Indicates elf is loaded by multicart and should allow exiting (return from main() function)

JetSetIlly commented 3 months ago

Yes. The mechanism is in place but the values aren't being set correctly. What you should be seeing at the moment is

System Type = 0 ARM Clock = 0xdeadbeef Flags = 0

Question about the System Type field: What are you intending to do with this information in the ELF code? I'm asking because I'm not entirely convinced you need the PAL60 option.

I'm sure we agree that PAL60 is the same as PAL except that the display is 60Hz rather than 50Hz. However, the frequency of the display is something that would be 'decided' by the ELF code. ie. it's not information the hardware or emulation can reliably provide before the ELF code is run.

There is something called PAL-M which is very nearly the PAL standard in that it produces PAL colour but at the intended frequency of 60Hz. Is that what you meant? Maybe I'm just being overly fussy with the naming but I've been down this rabbit hole a lot :-)

For references, Gopher2600 supports the following clock speeds:

// clock speeds taken from
// http://www.taswegian.com/WoodgrainWizard/tiki-index.php?page=Clock-Speeds
const (
    ntscClock  = 1.193182
    palClock   = 1.182298
    palMClock  = 1.191870
    secamClock = 1.187500
)

Gopher2600 will assume the NTSC clock unless (a) explicitely instructed or (b) the TV display indicates that the ROM is outputting a PAL-50 signal. As far as I know, it's impossible to reliably discern the other specifications just from the ROM program.

ZacharyScolaro commented 3 months ago

I think for Gopher it can be limited to NTSC and PAL60. PAL50 would only be relevant on the UCA carts where there could be systems that require 50Hz.

The elf game can adjust its color palette based on which TV standard the loader indicates.

The Flags can be kept at 0 until you add support for exiting from elf games back to the ROM selection screen. If that's supported, Flags can be set to 1 to indicate exit is available.

JetSetIlly commented 3 months ago

I've pushed a change that set the ARM clock speed correctly and sets the System Type https://github.com/JetSetIlly/Gopher2600/commit/d7c71fd49ad7c44a02dc5a0f72eae62f637e10a7

I don't think we agree on the PAL60 issue. As far as I'm concerned, there's no such thing as PAL60. There's PAL running at 60Hz but the only information that can be provided in that situation is that the machine is PAL. Whether the display is running at 60Hz is something the ROM decides, not the hardware.

As such, in this change the System Type is set to either NTSC or PAL. If the emulated VCS is either a SECAM or PAL-M machine, the System Type will be set to NTSC.

JetSetIlly commented 3 months ago

Thinking this over some more, I think the only way the system type argument can work in hardware is if the multicart has a way for the user to of specify the system. So the user will be able to say that "this is a PAL system with a TV that can display 60Hz". Or "This is a SECAM system". Etc.

I can emulate that capability in the preferences window. Maybe have a section in the PlusCart tab: "System Type for ELF ROMs". System in this context being the combination of the console and the TV.

I don't see how the information can be supplied to the ELF ROM otherwise. Unless you have other thoughts on this.

ZacharyScolaro commented 3 months ago

Indeed, the UCA family of carts have a setting in the menu system that lets you choose the TV type. That is what is passed in those carts. Generally, it's much easier to support both NTSC and PAL if they both run at 60HZ because 50HZ would change the timing of audio and physics without some extra code to compensate. So, given the option between 50HZ and 60HZ the cart would do 60HZ. That was my reasoning behind PAL60 being the default for PAL TV mode. As you pointed out though, it's ultimately up to the cart. So far, my games will only output 60HZ regardless. Only the palette will change depending on TV mode.

I've pushed a change that set the ARM clock speed correctly and sets the System Type d7c71fd I think this commit solves the issue. Having the ability to choose between PAL50 and PAL60 would be nice for development purposes if anyone should decide to support both, but that's going to be a pretty rare use case.

ale-79 commented 3 months ago

This concept of passing the preferred TV type to a game was actually part of the AtariVox/Savekey specs, altough it is rarely used AFAIK: Byte 8 of the eeprom, right after the "ATARIVOX" signature, is supposed to store the TV Mode: bit 7 is the palette (0=NTSC, 1=PAL), while bit 6 is the framerate (0=60Hz, 1=50Hz).

The unfinished homebrew "Man goes down" read this byte and uses its value as the default TV mode. By pressing the SELECT switch when starting the game, it is possible to change the TV mode between NTSC, PAL and PAL60, and the result is written back to the eeprom, so it is remembered the next time you play the cart (as long as you have the AtariVox/Savekey plugged in, of course).

I'm not aware of any other game that uses that feature.

JetSetIlly commented 3 months ago

Indeed, the UCA family of carts have a setting in the menu system that lets you choose the TV type. That is what is passed in those carts.

I didn't know that! But I now realise that the cartridges must have such a system already. I understand what you need and I'll make the changes.

JetSetIlly commented 3 months ago

This concept of passing the preferred TV type to a game was actually part of the AtariVox/Savekey specs, altough it is rarely used AFAIK: Byte 8 of the eeprom, right after the "ATARIVOX" signature, is supposed to store the TV Mode: bit 7 is the palette (0=NTSC, 1=PAL), while bit 6 is the framerate (0=60Hz, 1=50Hz).

That's really interesting! I'll add that information to the savekey code

JetSetIlly commented 3 months ago

I've pushed the changes to allow PAL60 to be selected and forwarded to the ELF binary.

I've not added the "System Type for ELF ROMs" tab like I suggested. However, changing the TV spec on the command line works as expected. Example:

gopher2600 -tv PAL60 raycaster.elf

You can also use the filename to specify the TV system:

gopher2600 raycaster_PAL60.elf

In both cases the ELF args are set appropriately but that'll be revealed in testing.

I've also improved the TV selection combobox in the debugger. This won't affect the ELF arg memory currently (the arg memory is set on cartridge "insertion" and not afterwards) but I suppose it could be made to be kept up to date as options are changed.

The real change behind this combo box is the TV image updating immediately, even if the emulation is paused.

image