There are defined ways how a cartridge is recognized in a C64 or C128 system . But what defines a MEGA65 cartridge and how is it started? The Slot 0 core needs to know and also the ROM has probably to do something.
We decided to go both the C64 and C128 way: a MEGA65 cartridge has the bytes $4D $36, $34 at $8007. This spells “m65” (the C128 has “cbm” at that location, while the C64 can have “CBM80” at $8004).
With M65 carts, EXROM/GAME lines are both high. The system does not map any cart memory to bank 0. The M65 ROM handles auto-start by reading cart memory directly from $400xxxx.
Like the C128 $8000 (in cartridge space) has the coldstart and warmstart code:
* = $8000 cartVectors: jmp coldStart // cold-start vector jmp warmStart // warm-start vector cartFlags: .byte %00000001 // flags, bit 0 = 1 to auto-start cartMagic: .byte $4D,$36,$35 // "m65" string
Cartridge Startup
If the ROM sees the identifier at $4008007, and bit 0 of $4008006 is 1, the ROM uses DMA to copy 8 KB from $4008000 to $8000 and executes a JMP $8000. This executes the coldStart routine of the cartridge. Everything else is up to the cartridge.
A simple cart storing a program less than 8 KB in size can just run from 0.8000.
A cart larger than 8 KB in size will need a bootstrap routine to set up memory as desired. All cartridge hardware lines are available at 400.xxxx, so the actual bootstrap code will depend on the cartridge hardware platform.
EasyFlash 1 can store up to 1 megabyte, making 16 KB visible at a time in two 8 KB chunks at 400.8000 (ROML) and 400.E000 (ROMH). Only EF bank 0 ROML is DMA’d to 0.8000 during cart start-up. The cart’s bootstrap code can write to the 400.DE00 EasyFlash bank register to select one of 64 banks to replace ROML and ROMH. This does not change 0.8000 automatically: the cart’s bootstrap needs to decide how to access and install cart data read from 400.xxxx.
Gmod2 can store up to 512 KB, making 16 KB visible at a time in one 16 KB chunk at 400.8000. Only the first 8 KB is DMA’d to 0.8000 during cart start-up.
Custom hardware must serve a DMA’able bootstrap program at $8000-9FFF.
CRT files and EasyProg
Someone writing software intended to be installed on an EasyFlash 1CR cart is likely to distribute that software as a file that an end user can install on their own EF1CR hardware. For C64/C128 carts, software is distributed as a CRT file, which can also be run in the VICE emulator. The end user uses EasySplit and EasyProg to write the CRT to the EF1CR using their C64.
We don’t yet have comparable tools for MEGA65 carts, but it’s worth discussing the appropriate format extensions while we’re figuring out the rest of it.
RFC: Use a CRT signature of:
MEGA65 CARTRIDGE
Other format changes might be justified if this is added to the CRT standard by the VICE team, e.g. incrementing the format version bytes.
We would define these cartridge types, similar to the C64 and C128 cartridge types:
generic
16KiB ROML at $8000-BFFF, 16 KiB ROMH at $C000-$FFFF, non-banking
One or two CHIP packets, one for each of ROML and ROMH
See C128 generic for reference
EasyFlash
8KiB ROML at $8000, 8KiB ROMH at $E000, with banking
See EasyFlash for reference
Gmod2
16KiB banks, always mapped to ROML at $8000-BFFF
See Gmod2-128 for reference
A fork of EasyProg would be required to recognize the CRT signature and install the
M65
cart header described above.A fork of bin2efcrt would be useful for developers. The change to the CRT signature would be straightforward.
I have not yet tested EasyProg from GO64 mode. It works well with the C64 core. Ideally we’d have a new version of EasyProg that runs in MEGA65 mode and can read full CRT files off the SD card, but that’ll be a big project.
External References
World of Jani: Making a C64 Cartridge and Making a C128 Cartridge
Test Cartridge download
ROM implementation issue: MEGA65 cart support #62
bin2efcrt program