New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MEGA65 cart support #62
Comments
Cartridge ROM is at $400.XXXX. So a standard ROMLO cartridge can be found at $400.8000. A M65 cartridge has the bytes $4D $36, $34 ("M65") at $400.8007. This is like a C128 cartridge. I use
to copy and excute ROMLO of my testcartidge. Current idea is that the ROM does MAP $8000-$9FFF and then JMP $8000 to execute the cartridge coldstart. Cartridge files are on discord, github does not allow the 7z |
Optional: slot 0 currently does not care about EXROM/GAME. If they are low in any combination, but M65 is found at 8007, the ROM should assume that this is a MEGA65 cartridge and exit C64 mode, initialize MEGA65 mode and than map & start. Resources: |
The current start-up sequence checks for The new version will leave the C64 side of start-up intact, because a M65 cart will not register as a C64 cart and start-up will pass through to the M65 kernel. M65 start will check for For now I'll assume:
Let me know what you think! I'll prepare this change and send you a test ROM. I'll also try to prepare an EF1 cart with the test cart data. |
@lydon42 @ki-bo Check my thinking: To map $8000-$9FFF to $400.8000, I need to set the MAPHI offset to $400.0000. All upper 16-bit addresses must use the same offset, so with this MAP the upper 8 KB segments either refer to cart ROM or bank 0 RAM. M65 kernel ROM—including hardware vectors—is mapped in with MAP, and so cannot be mapped to 16-bit addresses at the same time as cart ROM. Previously we've had D030 override MAP so bit 7 could preserve kernel in E000-FFFF. However, I understand that we're changing this: MEGA65/mega65-core#712 Therefore, a M65 cartridge cannot coexist in lower memory addresses with kernel ROM, must set the FFFx hardware vectors, and therefore must be 32 KB (or at least electronically return values for the hardware vectors) and have all 32 KB of $8000-$FFFF mapped to $400.8000-$400.FFFF. If a cart wants to use the kernel, it has to manage memory on its own, either by copying kernel code to bank 0 or by copying its own code to bank 0, and setting the MAP register. Am I thinking about this correctly? Is it just expected that a typical cart will have a start-up routine that DMAs itself into bank 0? Does this influence any of our other decisions regarding memory management? |
I think you are correct. How about mirroring the kernel ROM behind the cart ROM so it could be made available with the same offset? |
First some thoughts:
So the other plausible way to do it would be to not MAP $8000, but to do the DMA copy. Or a core based solution would be the ability to fake EXROM/GAME to force the mapping. |
Sorry, I may have overlooked an obvious solution: leave MAP disabled for E000-FFFF, and use D030 mapping for ROME. This already has to happen with ROMC, where the boot code lives. ROMC does the MAP'ing, so it cannot be MAP'ed and survive the process. (As the manual cautions, doing a megabyte MAP disables MAP'ing partway through the process, so the code doing the MAP'ing must not depend on MAP to stay in memory.) The M65 default (non-cart) boot state has D030 bit 7 (ROME) clear, and MAPHI B300 = +3.0000 for %1011 ($8000-BFFF, $E000-FFFF). Maybe it's sufficient for cart boot to set ROME, set MAPHI to +400.0000 for %0011 ($8000-BFFF), then let the cart boot code figure out what else it needs to do—including possibly setting MAP again to make more hardware addresses visible in the 16-bit address space. (I don't know why the M65 kernel uses MAP and not ROME to map itself to E000-FFFF. Maybe there's a reason I'm not thinking of. It's very late in my timezone rn. :) ) |
This sounds like a solution to me... In my mind a big cartridge (say Showdown 65 as a cart) would have a loader stub in $8000, which will copy itself downward into RAM, and then begin to map different cartridge pages (in that case using EF1CR registers to set EXROM/GAME to map 16K into $8000-BFFF) and DMA them into memory banks and/or attic RAM, replacing the loader that would do this from disk. |
But shouldn't we assume $D030.7 mapping C64 Kernal? That's what the C65 is doing. And this is the reason it is not used but MAP instead for mapping the Kernal at $E000. |
If that is what the C65 is doing, then this is what we should do! |
Interesting! It's not what the MEGA65 has been doing as far back as 920287. Just after boot, PEEK($D030) returns $64 and MAPHI is B300. We've also been giving D030 priority over MAP in the core until the recent proposed core change, dunno if that has anything to do with it. Since the very beginning of our own source repo (version 920108, January 2021), |
Hmm, ROM 910828 also boots with D030 set to $64 and MAPHI B300 MAPLO E300. Does |
I think this is ROM dependent. Starting up an old Commodore ROM should give you the C65 value for D030. $64 basically means to enable only ROMC mapping. The other bit in the upper nibble just switches the char rom. And I think this bit is actually ignored at the moment in the M65 core. So, no difference between $2x and $6x. |
It makes sense to only map $2Cxxx via $D030 in C65 or M65 mode, as all other mapping bits of $D030 will also map in $2xxxx blocks. Getting $3xxxx ROM area mapped needs MAP functionality. |
The limitation of having only two offsets for mapping are already present in the regular MAP function (when not mapping beyond the 1MB limit). You have one offset for all addresses up to $7FFF and a second offset for the upper 32kb range. But you can decide for each 8k block whether the offset gets applied or not. Offsets can have a granularity of 256 bytes. The MB mapping just extends the value range of the offset parameter to also reach address space >1MB. |
@ki-bo We've documented D030 as accessing ROM8, ROMA, and ROME from 3.xxxx, and ROMC and CROM9 from 2.xxxx. Is that inaccurate? Is it an inaccuracy in our implementation (doesn't match C65) or our documentation? As mentioned, Commodore ROM 910828 sets D030 to $64. I concur that this leaves ROME unset, which is why I concluded that ROME is brought in by MAP. Are you seeing something different on a C65? I had thought you were suggesting that a C65 brings in ROM E000-FFFF via D030 and not via MAP. |
Our implementation does not match what a real C65 is doing. You can read the difference in mapping in this issue: $D030 is a VIC-III register controlling access to a specific 32kb address range in ROM. The reason why C65 Kernal is banked in via MAP and not via $D030 is that it is not possible to do it that way with a real VIC-III chip. Because of this, it is easy to correct now on M65 as most software is not yet relying on $D030 flags. |
OK, got it. I overlooked that part of the memory mapping proposal. With the proposal in place, D030 can never map M65 ROM data. (It can and must init D030 to pull in ROMC from the C64 kernel before the reset vector is called by the hardware.) To get cart data accessible at 8000-9FFF and M65 ROM at E000-FFFF, we either 1) DMA one and MAP the other, 2) DMA both, or 3) somehow make them both visible at the same offset so they can both be MAP'd. #3 sounds like more trouble than it's worth, and #2 seems unnecessary. DMA'ing the cart addresses makes more sense than DMA'ing the kernel ROM. It's more consistent with non-cart behavior, and doesn't meaningfully rule out any fancy expansion port possibilities (e.g. dynamic values). The cart just needs to reliably serve its header and bootstrap routine to DMA, both during cold boot and during warm boot (RunStop-Restore). I'll proceed this way. Thanks both! Let me know if you think of anything else. |
Actually, on a real C65, I wouldn't be surprised if $D030 is not initialized in HW during reset, essentially doing no mapping at all, not even ROMC nor ROME. Instead, probably register $01 is initialized in HW to map in C64 Kernal, in order to provide reset vector and the reset routine. |
Correct, I meant the C64 kernel sets D030 in its reset vector routine, which starts at $E4B8. It sets D030 then jumps to $C800 in the M65 ROM. 👍 |
@dansanderson With the latest beta ROM and core from 2023-11-23, I'm able to boot lydon's test cartridge using my Ultimate II+, so this appears to be implemented. What's left to do for this task? |
The MEGA65 ROM part of the proposed MEGA65 cartridge auto-boot protocol is complete. I made a note to figure out whether the cartridge warm boot vector gets called in a way that's consistent with expectations (Run-Stop/Restore? I don't actually know), but other than that, it supports the one test cart. I left this open mostly because I wanted to make a project out of doing more substantial test cartridges, as a sort of stress test for the protocol design before we committed to it. I got sidetracked trying to port EasyProg to MEGA65, then I got distracted with other things. (It's possible to just use EasyProg from the C64 core for making MEGA65 test carts, I just thought it would be cool. :) I didn't get far.) I also wanted to stress test my proposed extension to the CRT file format, as a potential input for EasyProg, Xemu, and maybe someday a CRT file loader built into the Freezer. I wrote the CRT file spec extension into the proposal on the wiki but I don't really have a way to verify it without building out more of the tool chain. I'll close this issue. We can open new ones for any other ROM changes that might be needed. |
This issue is to track the ROM side of implementing a new standard for MEGA65 cartridges. The next core will have the plumbing for implementing physical cartridges with a MEGA65 ID, so a cart can contain a MEGA65 program and start the MEGA65 core (vs. C64 carts starting the C64 core). The MEGA65 ROM needs the ability to detect a connected cartridge and the MEGA65 ID, and automatically start the program from the MEGA65 boot state.
There should be existing code that detects C64 carts and activates the MEGA65 C64 mode. We should retain this for when the MEGA65 is configured to start the MEGA65 core for C64 cartridges (the default behavior when no C64 core is installed, and configurable by the user with the new core in slot 0).
@lydon42 please describe the MEGA65 cart spec that you've decided on to this ticket. Also please attach your test cart image. (I have EF1 hardware I can put it on.) ty!
The text was updated successfully, but these errors were encountered: