The export report is authoritative for the exact binary being used. Rebuilding the player can move addresses; Python reads the bundled layout JSON instead of assuming a fixed sample-data address. capacity uses the same layout.
| Resource | Current layout / use |
|---|---|
| PRG load address | $0801; two-byte file header is not loaded as data |
| BASIC entry | SYS 2064, machine-code entry $0810 |
| Bundled player and information text | $0801–$0E17, 1,559 loaded bytes |
| Packed audio | Starts $0E18; final address must be below $D000 |
| Maximum packed audio | 49,640 bytes, 99,280 samples, 24.820 seconds at 4 kHz |
| Zero page | $F7–$FC, saved/restored around playback |
| Hardware stack | $0100–$01FF; normal 6502 stack use |
| Screen | $0400–$07E7 (1000 bytes); copy also initializes the last 24 screen-page bytes |
| Color RAM | $D800–$DBE7 (1000 color nybbles); last 24 bytes also initialized |
| IRQ/NMI vectors under KERNAL ROM | $FFFE–$FFFF / $FFFA–$FFFB |
The screen buffer is additional C64 memory use, outside the PRG's loaded byte count. The 1024-byte text template is already included in the player's 1,559 bytes. Color RAM is separate hardware RAM. No audio is placed in the I/O area.
The old builder allowed a 40,000-byte file while leaving BASIC ROM mapped over part of the sample range. The new player banks ROMs out during playback, allowing RAM through $CFFF to be read correctly. Standalone playback owns the machine while active; it is not a music-player IRQ designed to coexist with arbitrary running C64 software.
--format cart is the flash-streaming path. It is distinct from makecart, which wraps an existing RAM-sized PRG.
| Resource | Streaming layout |
|---|---|
| Physical flash | 64 banks × 16 KiB = 1 MiB |
| Bank 0 ROML | The 1,614-byte RAM player, copied to $0801–$0E4E at startup |
| Bank 0 ROMH | Native Ultimax boot at $E000; reset/NMI/IRQ vectors at chip offsets $1FFA–$1FFF |
| EasyAPI | Bank 0 ROMH offsets $1800–$1AFF, real 768-byte AM/M29F040 driver |
| Cartridge name | Bank 0 ROMH offsets $1B00–$1B17; ef-nAmE: plus 16-byte PETSCII name |
| Reserved metadata region | Bank 0 ROMH $1800–$1BFF; boot/data must not overlap it |
| Packed audio | Banks 1–63, ROML then ROMH in each bank |
| Available audio | 63 × 16,384 = 1,032,192 bytes, after reserving all of bank 0 |
| CPU windows | ROML $8000–$9FFF, ROMH $A000–$BFFF in 16 KiB mode |
| Zero page during stream | $F6–$FC, including a 24-bit byte counter |
| Startup scratch | $F0–$F4; EasyFlash RAM $DF00–$DFFF contains the boot trampoline |
| NMI handling during ROM reads | $0318–$0319, plus the RAM NMI vector when ROM is hidden |
Raw EasyFlash images are bank-major and interleaved: bank 0 ROML, bank 0 ROMH, bank 1 ROML, bank 1 ROMH, etc. Erased space is $FF. cartconv can omit completely erased CHIP packets, so CRT file size is not the amount of audio space available.
The boot code sets CPU port $01 before DDR $00, quiesces interrupts, copies a trampoline to EasyFlash RAM, hides cartridge ROM and initializes the KERNAL. A held key bypasses playback. The small streaming player is copied to main RAM; the audio stays in flash. The player exposes cartridge ROM briefly while reading each packed byte and returns to RAM interrupt vectors immediately afterwards. It switches banks only when the pointer crosses $BFFF. Its count includes every audio byte, including $00; an odd final padding nibble is never emitted.
A PRG-wrapper cartridge from makecart stores the existing PRG in ROML banks starting at 1, copies that whole PRG into RAM, then hides the cartridge. It does not increase the wrapped PRG's sample capacity. Both cart types reserve the same boot/EasyAPI/name areas and are validated as native EasyFlash CRTs. CRT generation writes an image file, not physical flash.
The EasyAPI source and binary are attributed in third_party/easyapi. ACME is only needed to rebuild that third-party driver; 64tass is only needed to rebuild our templates. Neither is needed when exporting with the bundled binaries.
| Registers | Purpose |
|---|---|
$01 |
6510 banking: RAM vectors during playback; brief ROM-visible reads in streaming mode |
$DC04/$DC05 |
CIA1 Timer A latch for the chosen sample rate |
$DC0D/$DC0E |
CIA1 interrupt mask/acknowledge and Timer A control |
$DD0D/$DD0E |
Quiesce CIA2 interrupts/timer during playback |
$D400–$D418 |
Clear/configure SID; one volume sample per timer tick at $D418 |
$D404/$D40B/$D412 |
8580 profile: $19 = triangle + TEST + GATE |
$D406/$D40D/$D414 |
8580 profile: full sustain; AD registers remain zero |
$D011/$D016/$D018/$D021 |
Screen enable, mode, character/screen pointers and black background |
$D01A/$D019 |
Disable/acknowledge VIC interrupts while the player owns playback |
$DD00 |
VIC bank for the information display |
$DE00 |
EasyFlash bank selection, bits 0–5 only |
$DE02 |
EasyFlash mode/LED: $86 for startup copying, $87 for streaming, $04 to hide ROM |
$D020 |
Untouched by the player; normal KERNAL boot can initialize the border before a cart starts |
The player pauses the KERNAL keyboard/jiffy IRQ. It does not chain the entire KERNAL IRQ at sample frequency. Normal PRG completion restores the saved CPU banking, zero page and display registers, resets I/O through the KERNAL, clears the information screen and returns to the caller. Cartridge completion proceeds to a clean KERNAL/BASIC reset. Looping programs require reset to stop.
For packed four-bit mono samples:
packed bytes = ceil(sample count / 2)
duration = sample count / sample rate
maximum duration = available packed bytes × 2 / sample rate
| Rate | Bytes/second | RAM PRG capacity | Streaming cart capacity |
|---|---|---|---|
| 1000 Hz | 500 | 99.280 s / 1:39.280 | 2064.384 s / 34:24.384 |
| 2000 Hz | 1000 | 49.640 s / 0:49.640 | 1032.192 s / 17:12.192 |
| 4000 Hz | 2000 | 24.820 s / 0:24.820 | 516.096 s / 8:36.096 |
| 8000 Hz | 4000 | 12.410 s / 0:12.410, screen off | Not supported by the streaming player |
These are nominal durations, not input-file byte sizes. Compressed MP3/FLAC size says little about the packed duration. Stereo is downmixed. Trimming can change the processed sample count. PAL/NTSC output reports include actual timer rate; PRG timing reports also include actual playback duration for both clocks.
The mapper, startup and metadata conventions follow the EasyFlash Programmer's Reference and the current c64-3d-toolkit cartridge implementation. SID control bits follow the MOS SID datasheet transcription. Emulator validation is evidence of software behavior; physical C64/EasyFlash validation remains separate.