GideonZ / 1541ultimate

Official GIT archive of 1541 ultimate II sources
GNU General Public License v3.0
181 stars 46 forks source link

Question: bank switching vs IO access #437

Open ithinu opened 2 weeks ago

ithinu commented 2 weeks ago

One of the issues with SID emulation is that UII cannot distinguish between RAM and I/O access. What prevents it from tracing writes to the memory location 0x0001 in order to determine the current bank switch mode? Is there a hardware limitation?

GideonZ commented 2 weeks ago

Yes. Writes to $0000 and $0001 do not appear on the cartridge bus.

ithinu commented 2 weeks ago

Would such a workaround make sense? The cartridge could detect a write of a 64-bit signature at a certain address, with the signature itself being unique enough. Depending on its value, the signature would enable or disable an access to a specific I/O device in the cartridge, such as the emulated SID or UII's command interface.

GideonZ commented 2 weeks ago

What would this 64-bit signature look like, and who is responsible for adding that to existing code? How would you ensure backwards compatibility with existing code?

ithinu commented 2 weeks ago

What would this 64-bit signature look like?

For example, it could start with 0xACCE (indicating access) followed by "UII" and then by an 8-bit value encoding a 7-bit device identifier and a 1-bit enable/disable flag.

Who is responsible for adding that to existing code?

We might rely on the adoption of UII. For instance, in the case of the real C64, many, if not most emulated SIDs are provided by UII, which might prompt some C64 devs. In the case of unmaintained software, a simple patch would do (changing SYS xxxx to point to the write, followed by a jump to xxxx).

How would you ensure backward compatibility with existing code?

It might improve on the current situation. If a device is enabled in the UII configuration, it would always be present in the address space, and its specific signature writes would be ignored, so nothing changes. But if the device is disabled, it would only be activated (until the next reset) by C64 software that explicitly knows how to handle it.

In the less likely case that a C64 software wants to use an emulated device but the user doesn't want to allow it, three configuration options OFF, AUTO, ON could be provided.

markusC64 commented 2 weeks ago

Yes. Writes to $0000 and $0001 do not appear on the cartridge bus.

More specific: Writes to those addresses appear on the bus as follows: Adress bus is set as usual. Data bus however is in tristate and latches last data from VIC. This combination indeed allows to write arbitrary data to memory locations 0 and 1.

Source: https://codebase64.org/doku.php?id=base:ram_beneath_00_and_01

Perhaps this fact might be used somehow. You can detect that I/O mapping might have changed due to a write to adress $01. But you don't know the new mapping.

But what if you assume that after a write to $01 I/O is enabled until proven otherwise? If you map RAM to the I/O Area, you can safely access $DExx. The cartridge sees that adress and can see that IO1 isn't active so its proven that I/O is disabled.

Inserting such a read is more simple than your suggestion.

GideonZ commented 2 weeks ago

@ithinu I honestly don't see the point in doing it like this. If you make U2 specific software, you could easily use another mechanism, like UCI to set some kind of mode, or, when it needs to be fast, specify an IO register to write the copy of $01 to.

@markusC64 Yes, the vic value is indeed visible on the bus. It is unfortunate that it cannot be used.

The best solution would be to have a 6502 running in parallel with the 6510. At least part of it. As long as A, X and Y can be known, the value to be written is also known when considering the write opcode.

markusC64 commented 2 weeks ago

The best solution would be to have a 6502 running in parallel with the 6510. At least part of it. As long as A, X and Y can be known, the value to be written is also known when considering the write opcode.

I know how to break that. Connect the U2 to a C128 in C64 mode. And enable 2 Mhz mode that is available in C64 mode, too. Not talking about C128 mode, of cause. Because it is obvious what happens....

ithinu commented 2 weeks ago

GideonZ it would be helpful to have the mechanism in question implemented in any simple way you'd choose.

That said,

if you make U2 specific software you could easily use another mechanism, like UCI to set some kind of mode

the problem to solve concerns C64 cartridges in general. A developer working on a different cartridge might want to reuse your solution for compatibility. Similarly, a user might want to modify their SID player as discussed above. Two reasons for keeping the solution on the C64 side very simple and not specific to UII - maybe just a dozen lines of assembly code that do nothing if there is no cartridge. Of course, having this functionality in UCI is better than nothing.

or, when it needs to be fast, specify an IO register to write the copy of $01 to.

An "unprotected" IO register somewhere may have the same problems as the SID emulation.

ithinu commented 2 weeks ago

I know how to break that. Connect the U2 to a C128 in C64 mode. And enable 2 Mhz mode that is available in C64 mode, too. Not talking about C128 mode, of cause. Because it is obvious what happens....

And in response, Gideon will start to supply his customers with a custom PLA which transmits impulses in Morse code over the power supply line directly to his cartridge.