Jump to content

Open Club  ·  76 members

StellaRT
IGNORED

Community-Built Unnamed 1970's Video Game Console-Compatible System (WIP)


Recommended Posts

14 minutes ago, batari said:

But if you don't want to dump the cart, at least you could cache known ROM data if you knew it was ROM, and would not need to fetch from ROM every single cycle. That could provide the speed boost you need and allow for more time for when you really have to interact with the cart.

But couldn't a hotspot theoretically be hit on any cycle causing the active ROM to change? And if it is a solution that is agnostic to the cart format, then there's no way to know that the cached ROM is still valid? 

56 minutes ago, Karl G said:

But couldn't a hotspot theoretically be hit on any cycle causing the active ROM to change? And if it is a solution that is agnostic to the cart format, then there's no way to know that the cached ROM is still valid? 

The emulator would need to know what bankswitch type it is running for true caching to work. If it is not aware, it can always revert to processing every cycle.

 

Even such, if you are not aware of the bankswitch type, there may still be some tricks that can help this along to gain enough extra performance.

 

Basically, speculative processing. You can cache values at known locations, then instead of waiting for the bus, begin performing (non-permanent) operations on the value. Then read the bus. If the value matches the cache then you are ahead of the game. If values do not match, abandon the work that has been done and process with the new value.

 

  • Like 1
6 hours ago, batari said:

But if you don't want to dump the cart, at least you could cache known ROM data if you knew it was ROM, and would not need to fetch from ROM every single cycle. That could provide the speed boost you need and allow for more time for when you really have to interact with the cart.

This technique wouldn't work for the newer ELF ROMs. In these ROMs, the data returned is potentially completely dynamic. i.e. the byte returned for a given cartridge address can be different on every access.

  • Like 1

For further discussion, we have just created a new club.

Everybody can join!

 

Please try to stay on topic or create new topics where required.

  • Like 3
  • Thanks 3
18 hours ago, Kroko said:

>>Do you mean indexed reads and writes, which have a dummy access to the non-indexed addresses?

Not only indexed reads. All instructions that take longer than one cycle (like JSR, RTS etc.) have some exact sequence of how they put which data to the address and databus during the cycles they are executed. So you need to exactly put to the bus the same data that would be put to the bus in each single cycle of a multi cycle instruction. Because some cartridges monitor the sequence of what happens from cycle to cycle and rely on seeing on the bus exactly what the 6502 puts there in each cycle during a multi cycle instruction. I am not 100% sure, but some cartridges implement delays based on signal changes on the data or address bus, so you would need to do the data change at least roughly at the time this hardware expects the change. I feel this is all a fun challenge :)

As @Thomas Jentzsch says, the bus transitions should be all correctly emulated by Stella at this point. This is definitely a requirement for some carts. Supercharger (for example) is especially finicky as it waits precisely five transitions between scheduling data (by accessing $F0XX) and writing it (by accessing the destination address).

On 9/13/2023 at 12:49 AM, r_type2600 said:

How about "Stellactic" or "Stellaxy" or "Stellaga" - sure would be fitting this project's impact 🙂

Stellantis!

 

Oh, wait... :D

  • Haha 1
1 hour ago, DirtyHairy said:

As @Thomas Jentzsch says, the bus transitions should be all correctly emulated by Stella at this point. This is definitely a requirement for some carts. Supercharger (for example) is especially finicky as it waits precisely five transitions between scheduling data (by accessing $F0XX) and writing it (by accessing the destination address).

Thats already a very good start. But if I remember correctly, the way Stella emulates the bankswitching logic inside the cartridges is not always what was actually happening on the real cartridge. Take RobotTank and Decathlon for example where the bankswitching logic inside the cart is detecting "by looking at the bus" were the jump came from and therefore finds out where it is supposed to return to. As far as I was able to figure out, this monitoring of the bus is complicated and involves strict timing. But Stella on the other hand (at least when I last looked and the FE bankswitching code) just makes its life easy because it knows where it jumps to and has to return to without analysing the address and databus. So the banking works, but its kind of cheating :)
But now, in case you want to ensure the FE based cartridges will be working, you just need to get the stuff 100% correct that is happening, because otherwise a real cart will not work. And just because you see a working RobotTank on the emulator does not mean, that the bus timing is actually correctly emulated. But I feel we might find out soon enough.

  • Thanks 1
2 minutes ago, bent_pin said:

Maybe @Albert could move this thread to the StellaXYZ group? Assuming OP is ok with that.

It can be moved into the club (first time I've even checked that!), although many people may not then be able to find it, as Clubs are a bit more off the beaten path.  

 

 ..Al

4 minutes ago, Albert said:

It can be moved into the club (first time I've even checked that!), although many people may not then be able to find it, as Clubs are a bit more off the beaten path.  

 

 ..Al

Totally up to you and OP. Thanks for the quick reply.

3 minutes ago, Thomas Jentzsch said:

Would copy and locking this one work?

Well, I can move it and leave a temporary link available in this forum (which will point to the new location of the thread), and that goes away after 30 days or so.  It would enable people to find the thread in its new location.  Also, there's no way for me to make a copy of a thread as far as I'm aware. 

 

Screenshot 2023-09-14 at 12.13.59 PM.png

 

 ..Al

  • Like 2
Just now, Albert said:

Well, I can move it and leave a temporary link available in this forum (which will point to the new location of the thread), and that goes away after 30 days or so.  It would enable people to find the thread in its new location.  Also, there's no way for me to make a copy of a thread as far as I'm aware. 

That would be fine, IMO.

  • Like 1
20 minutes ago, Kroko said:

But Stella on the other hand (at least when I last looked and the FE bankswitching code) just makes its life easy because it knows where it jumps to and has to return to without analysing the address and databus. So the banking works, but its kind of cheating :)

Hm, probably this goes over my head, but AFAIK the code analyzes the address.

Spoiler
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeFE::checkSwitchBank(uInt16 address, uInt8 value)
{
  if(myLastAccessWasFE)
  {
    bank((value & 0x20) ? 0 : 1);
    myLastAccessWasFE = false; // was: address == 0x01FE;
    return true;
  }
  myLastAccessWasFE = address == 0x01FE;
  return false;
}

 

Maybe you can explain for dummies? :) 

12 hours ago, JetSetIlly said:

This technique wouldn't work for the newer ELF ROMs. In these ROMs, the data returned is potentially completely dynamic. i.e. the byte returned for a given cartridge address can be different on every access.

I didn't say everything would work, but games that do work can take advantage of the speedup from caching (if emulation speed turns out to be a problem.)

56 minutes ago, Thomas Jentzsch said:

Hm, probably this goes over my head, but AFAIK the code analyzes the address.

  Reveal hidden contents
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeFE::checkSwitchBank(uInt16 address, uInt8 value)
{
  if(myLastAccessWasFE)
  {
    bank((value & 0x20) ? 0 : 1);
    myLastAccessWasFE = false; // was: address == 0x01FE;
    return true;
  }
  myLastAccessWasFE = address == 0x01FE;
  return false;
}

 

Maybe you can explain for dummies? :) 

Well we need somebody who understands the hardware and the emulator, maybe batari can help here. He also had it working on the Harmony. I never managed to get to run both Decatlon and RobotTank ... the other one was always failing when the first one worked. So I didn't fully understand the secret :)

Shortly read through the corresponding patent and schematic of what is most likely on the cartridge. I really doubt that that few lines of code from Stella are very close to what happens on the cartridge and what the cartridge is therefore expecting to get to see on the bus when the rom is run by the emulator: (look at page 4 of the patent and what is expected when on the bus)

imgf0001.png

EP0116455A2.pdf

Edited by Kroko
  • Like 1

Hm, it checks access the address bus to match 0x1FE (top of stack) and, one cycle later, switches banks (up to 8 ) depending on the data bus (bits 13..15). That's what I understand.

 

And the Stella code does indeed work different. It can only switch between two banks, because it only checks A13.

Edited by Thomas Jentzsch

We don't necessarily need to understand how this works, but i feel .... however it works ... it is heavily relying on bus timing and I am not 100% convinced the bus timing has ever been validated on the level that is required to get all bankswitching modes working. So this will be fun to figure out ...

2 hours ago, Kroko said:

Well we need somebody who understands the hardware and the emulator, maybe batari can help here. He also had it working on the Harmony. I never managed to get to run both Decatlon and RobotTank ... the other one was always failing when the first one worked. So I didn't fully understand the secret :)

Hm, I just checked the UnoCart source, it does the same as Stella --- watch for an access to 0x01FE, grab bit 5 and use that to select the bank. I also tested Decathlon and RobotTank, both work on the Uno. We'll find out soon enough, but I really think that this is all there is. I also remember that there was a discussion about that scheme and the related patent in 2600 dev forum a few years ago, and as a result we rewrote the implementation in Stella to its current form --- previously, it was a hack that relied on telling reads from writes iirc.

  • Like 1
7 minutes ago, DirtyHairy said:

Hm, I just checked the UnoCart source, it does the same as Stella --- watch for an access to 0x01FE, grab bit 5 and use that to select the bank. I also tested Decathlon and RobotTank, both work on the Uno. We'll find out soon enough, but I really think that this is all there is. I also remember that there was a discussion about that scheme and the related patent in 2600 dev forum a few years ago, and as a result we rewrote the implementation in Stella to its current form --- previously, it was a hack that relied on telling reads from writes iirc.

Cool! Sometimes things are easier than you would expect :D

45 minutes ago, DirtyHairy said:

Hm, I just checked the UnoCart source, it does the same as Stella --- watch for an access to 0x01FE, grab bit 5 and use that to select the bank. I also tested Decathlon and RobotTank, both work on the Uno. We'll find out soon enough, but I really think that this is all there is. I also remember that there was a discussion about that scheme and the related patent in 2600 dev forum a few years ago, and as a result we rewrote the implementation in Stella to its current form --- previously, it was a hack that relied on telling reads from writes iirc.

The explanation is at the top of the header file: https://github.com/stella-emu/stella/blob/master/src/emucore/CartFE.hxx

  • Like 1
  • Recently Browsing   0 members

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