mamedev / mame

MAME
https://www.mamedev.org/
Other
7.96k stars 1.98k forks source link

LR35902 exposes memory accesses that don’t actually go via the bus #10334

Open cuavas opened 2 years ago

cuavas commented 2 years ago

While working on the Game Boy cartridges, I encountered an annoying issue with the LR35902 core. In reality, memory accesses for certain internal peripherals, including HRAM and the bootstrap ROM, are not exposed on the bus. However, the MAME CPU core does these accesses via the program address space.

This means that cartridges can’t use address space taps for things like monitoring ROM accesses for defeating the logo check, as they’ll incorrectly see bootstrap ROM accesses as program space accesses at low addresses. (Various unlicensed cartridges, including Rocket Games and Sachen, depend on the fact that A15 remains high when the CPU is reading its internal bootstrap ROM at addresses 0x0000-0x00FF.)

It also means that cartridges need to be careful about changing handlers in the address space to ensure they don’t stomp on the view that the root system driver device uses to switch the bootstrap in.

For some reason, accesses to some internal peripherals are visible externally. For example the Game Boy Pocket (MGB) CPU has integrated VRAM, but VRAM accesses are still visible externally.

I have no idea how one would go about addressing this without substantially complicating the CPU core and/or hurting performance.

galibert commented 2 years ago

Perhaps you can have an address space for bootstrap and one for afterwards, and change the specific as needed? The cost is in fact rather low, and you'll be full speed once the switch is done.

OG.

On Tue, Sep 13, 2022 at 9:47 PM Vas Crabb @.***> wrote:

While working on the Game Boy cartridges, I encountered an annoying issue with the LR35902 core. In reality, memory accesses for certain internal peripherals, including HRAM and the bootstrap ROM, are not exposed on the bus. However, the MAME CPU core does these accesses via the program address space.

This means that cartridges can’t use address space taps for things like monitoring ROM accesses for defeating the logo check, as they’ll incorrectly see bootstrap ROM accesses as program space accesses at low addresses. (Various unlicensed cartridges, including Rocket Games and Sachen, depend on the fact that A15 remains high when the CPU is reading its internal bootstrap ROM at addresses 0x0000-0x00FF.)

It also means that cartridges need to be careful about changing handlers in the address space to ensure they don’t stomp on the view that the root system driver device uses to switch the bootstrap in.

For some reason, accesses to some internal peripherals are visible externally. For example the Game Boy Pocket (MGB) CPU has integrated VRAM, but VRAM accesses are still visible externally.

I have no idea how one would go about addressing this without substantially complicating the CPU core and/or hurting performance.

— Reply to this email directly, view it on GitHub https://github.com/mamedev/mame/issues/10334, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACGSF4LL77IPZYSVIZPRYJLV6DK5BANCNFSM6AAAAAAQLYHBW4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

cuavas commented 2 years ago

I thought about this a bit more.

VRAM is always on a separate bus to the main system bus. CPU and PPU VRAM accesses are visible on this bus, even on CPUs with internal VRAM. In practice, there’s nothing besides RAM connected to the VRAM bus, and it’s just brought out to test points on the PCB when the VRAM in internal. It might still be useful to have it exposed as an address space so debugger watchpoints and Lua script taps can be used on VRAM.

As far as i know, accesses to everything from 0xfe00 to 0xffff, as well as the bootstrap ROM, are not exposed on the system bus.

Maybe it would be better to separate the external address space from the AS_PROGRAM space, and put trampolines in the AS_PROGRAM space that send reads/writes to 0x0000-0xfdff to the external address space. A view for the bootstrap could be installed over the top, so bootstrap accesses wouldn’t go through the trampoline. Then things like cartridges on the external address space would only see external accesses, and views/taps at low addresses would work properly.

I know trampolines are a bit of a dirty word, but I’m not sure if there’s a better way of doing it.