{
 "chunk": "boot_c64cart_8000_8000",
 "unit": "boot/c64cart_8000",
 "routines": [
  {"addr": "8009",
   "name": "cartColdStart",
   "summary": "Cold/warm start entry of the CBM80 pseudo-cartridge that the C128 boot sector copies to $8000 before GO64. Re-implements the parts of the C64 KERNAL reset that are skipped when a cartridge is present (IOINIT, clear $0002-$0101/$0200-$03FF, MEMTOP=$A000, MEMSTR=$0800, HIBASE=$0400, RESTOR, CINT), sets border/background to blue (6) and blanks the screen (VIC_CTRL1 bit 4 cleared), opens the drive command channel via $0B45, sends drive command index 2 = \"I\" via $0B55, closes lfn 15, then SETNAM \"0:EA\" and falls into cartLoadEaFile. It never returns; execution continues at $02B8 (eaLoadGame).",
   "inputs": "None (entered from the KERNAL reset via the $8000 cold-start vector). Relies on the C128 boot sector code still being present at $0B45/$0B55 (it is: the KERNAL reset skips RAMTAS when CBM80 is found and this routine only clears $0002-$0101 and $0200-$03FF).",
   "outputs": "Zero page $02-$FF and $0100/$0101, $0200-$03FF cleared; $0282=$08, $0288=$04; MEMTOP=$A000; KERNAL vectors restored; screen editor initialised; VIC_BORDER=VIC_BG0=6; display blanked; drive initialised; stack pointer = $F0; A=0 (LOAD, not verify) on entry to cartLoadEaFile. Does not return.",
   "confidence": "high"},
  {"addr": "800F",
   "name": "clearLowRamLoop",
   "summary": "Loop body inside cartColdStart: with A=0 and Y=0..255 it stores to $0002+Y (absolute-indexed, so $0002-$0101), $0200+Y and $0300+Y. Equivalent to the RAMTAS clear but leaves $00/$01 (CPU port) untouched. Not a callable routine, just the loop label.",
   "inputs": "A=0, Y=0",
   "outputs": "$0002-$0101, $0200-$03FF zeroed; Y=0 on exit",
   "confidence": "high"},
  {"addr": "8065",
   "name": "cartLoadEaFile",
   "summary": "Tail of cartColdStart (reached by JMP over the embedded \"0:EA\" filename): JSR KERNAL_LOAD then JMP $02B8. The LOAD uses the SETLFS left by $0B45 (lfn 15, device 8, secondary 15), so the file \"ea\" is loaded to its own address $02A8-$030B; control then goes straight to eaLoadGame at $02B8 rather than through the BASIC vector hijack used on the plain C64 path. The carry/error result of LOAD is ignored.",
   "inputs": "A=0 (load), filename set by SETNAM (4 bytes at $8061), logical file parameters from $0B45",
   "outputs": "$02A8-$030B loaded from disk; jumps to $02B8, never returns",
   "confidence": "high"}
 ],
 "variables": [
  {"addr": "0282", "scope": "abs", "name": "kernalMemStrHi", "meaning": "KERNAL MEMSTR high byte (start of BASIC/user memory); the cartridge stores $08 so low memory starts at $0800 exactly as on a normal C64 reset.", "confidence": "high"},
  {"addr": "0288", "scope": "abs", "name": "kernalHiBase", "meaning": "KERNAL HIBASE (page of the text screen); the cartridge stores $04 so CINT uses the default screen at $0400.", "confidence": "high"},
  {"addr": "0B45", "scope": "abs", "name": "c128OpenCommandChannel", "meaning": "Routine left in RAM by the C128 boot sector (boot/c128boot_T1S0.s): SETNAM length 0, SETLFS 15,8,15, OPEN. Called from the cartridge at $8043; its SETLFS settings are also what the later KERNAL_LOAD at $8065 uses.", "confidence": "high"},
  {"addr": "0B55", "scope": "abs", "name": "c128SendDriveCommand", "meaning": "Routine left in RAM by the C128 boot sector: A = index into the pointer table at $0B75 (0=\"U0>M0\", 1=\"U0>H0\", 2=\"I\"), sends the zero-terminated string on lfn 15 via CHKOUT/CIOUT/CLRCHN. The cartridge calls it with A=2 to initialise the drive.", "confidence": "high"}
 ],
 "dataBlocks": [
  {"addr": "8000", "length": 9, "type": "addrTable", "name": "cartHeader", "description": "Standard C64 cartridge header: cold-start vector $8009, warm-start vector $8009, signature \"CBM80\" ($C3 $C2 $CD $38 $30). Found by the KERNAL reset code, which then jumps to $8009."},
  {"addr": "8061", "length": 4, "type": "text", "name": "eaFileNameCart", "description": "Filename \"0:EA\" passed to SETNAM (X=$61, Y=$80, length 4) at $8050-$8056; plain PETSCII, no terminator (length-counted). Sits in the middle of the code and is skipped by the JMP at $805E."},
  {"addr": "806B", "length": 12, "type": "unknown", "name": "cartTailFiller", "description": "Never referenced: $00 followed by the byte pattern 8E 72 17 8E 73 17 8E 70 17 8E 71, i.e. fragments of STX $1772 / STX $1773 / STX $1770 / STX $1771. These are the last bytes ($F4-$FF) of track 1 sector 0 and look like leftovers from the mastering buffer (compare the assembler-source fragments on track 1 sector 16)."}
 ],
 "misclassified": [],
 "insights": [
  "This image is only live on the C128 boot path: C128 boot sector (track 1 sector 0, at $0B00) copies its bytes $89-$FF to $8000, switches a 1571 to 1541 mode, then GO64. The C64 KERNAL reset finds CBM80 at $8004, skips RAMTAS and jumps to $8009.",
  "Because RAMTAS is skipped, the C128 boot sector's helper routines at $0B45 (open command channel 15,8,15) and $0B55 (send drive command string) survive in RAM and are reused by the cartridge code; the cartridge's own clear loop deliberately stops at $03FF. $0B45/$0B55 in the game's main program ($0B4F loadCommTailBuild1 etc.) are unrelated code that only exists after the fast loader has run.",
  "The LOAD at $8065 relies on the secondary address 15 set by $0B45 (nonzero -> load to the file's own address), so 'ea' lands at $02A8-$030B. The cartridge then JMPs directly to $02B8 (eaLoadGame), which SETLFS 8,1 / loads 'load' to $9800-$C3FF / JSR $C000 / JMP $0800. The BASIC-vector hijack in 'ea' ($0300-$030B = $02B8) is only needed on the plain C64 LOAD\"EA\",8,1 path.",
  "The cartridge mimics the standard power-on memory configuration without entering BASIC: MEMTOP $A000, MEMSTR $0800 ($0282), HIBASE $0400 ($0288), RESTOR + CINT. Screen is blanked (DEN bit cleared) with blue border/background; the $C000 boot loader later unblanks it for the title picture.",
  "Stack pointer is forced to $F0 before the LOAD (the reset code would have used $FF; $F0 leaves room below for nothing in particular, most likely copied from EA's generic cartridge template).",
  "At run time $8000-$87FF is overwritten by overlay variants A/B; the XREF entry L_806A (branch target from $8065 in game/ovl_6F00_B) belongs to the overlay, not to this cartridge image.",
  "No zero-page variables of the game are used; the only zero-page access is the wholesale clear of $0002-$0101."
 ]
}
