Promote Joypad Test Cartridge (U) from _wip to top-level project

Moves Joypad Test Cartridge (U) from _wip/ to Joypad Test Cartridge (U)/ with full ROM build:
- Adds header.s, chr.s, linker.cfg (HEADER+PRG+CHR segments)
- Updates Makefile to build and verify reconstructed.nes vs rom.nes
- Adds rom.nes copy + copilot/rom.nes symlink per repo convention
- Verified byte-identical build

Pass 1 complete: full code/data classification (~3.5% code / ~96.5% data)
Pass 2 complete: routine headers for all labels, semantic naming for key
routines (Reset, NmiHandler, VramWrite, PpuScrollLatch, VramPtrWrite,
RetAddrUpdate, etc.), zero-page aliases in locals.inc

Root OVERVIEW.md updated:
- Removes Joypad Test Cartridge from _wip skeleton table (22 -> 21 skeletons)
- Adds Joypad Test Cartridge as #14 in numbered inventory (BYTE-IDENTICAL, Pass 2)
- Updates summary count from 13 to 14 projects
This commit is contained in:
tmerritt committed 2026-10-16 19:01:42 -04:00
1 parent c79a52e354
commit b43b4a149d
24 files changed
+1963 -87

No files matched your search

@@ -0,0 +1,25 @@
CA65 ?= ca65
LD65 ?= ld65
all: reconstructed.nes verify
prg.o: prg.s symbols.inc locals.inc
$(CA65) -g -o $@ $<
header.o: header.s
$(CA65) -g -o $@ $<
chr.o: chr.s
$(CA65) -g -o $@ $<
reconstructed.nes: header.o prg.o chr.o linker.cfg
$(LD65) -C linker.cfg -m reconstructed.map -Ln reconstructed.lbl -o $@ header.o prg.o chr.o
verify: reconstructed.nes
cmp reconstructed.nes rom.nes
@echo "Byte-identical ROM verified."
clean:
rm -f *.o reconstructed.nes reconstructed.map reconstructed.lbl
.PHONY: all verify clean
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
.segment "CHR"
.incbin "chr.bin"
Binary file not shown.
@@ -0,0 +1,2 @@
.segment "HEADER"
.incbin "header.bin"
@@ -0,0 +1,10 @@
MEMORY {
HEADER: start = $0000, size = $0010, fill = yes;
PRG: start = $C000, size = $4000, file = %O, fill = yes;
CHR: start = $0000, size = $2000, file = %O, fill = yes;
}
SEGMENTS {
HEADER: load = HEADER, type = ro;
PRG: load = PRG, type = ro;
CHR: load = CHR, type = ro;
}
@@ -0,0 +1,46 @@
; Joypad Test Cartridge (U) zero-page aliases - Pass 2
; Semantic names for addresses with observed usage patterns; ZpXX names for
; addresses whose role is not yet uniquely determined.
VramPtrLo = $00 ; VRAM write pointer low byte (indirect, used by VramWriteLoop/VramWrite)
VramPtrHi = $01 ; VRAM write pointer high byte (indirect)
VramLen = $02 ; VRAM write data length counter
PpuScrollX = $03 ; PPU horizontal scroll value (latched to $2005)
Zp04 = $04 ; Temporary zero-page storage
RetAddrTempLo = $05 ; Return address temp low byte (used by RetAddrUpdate)
RetAddrTempHi = $06 ; Return address temp high byte (used by RetAddrUpdate)
Zp0D = $0D ; Temporary zero-page storage
PpuMaskShadow = $0E ; PPUMASK shadow register (bits cleared for sprite/bg)
PpuScrollY = $0EC ; PPU vertical scroll value (latched to $2005)
PpuScrollX_Init = $0ED ; PPU horizontal scroll value written during init
PpuMaskValue = $0EE ; PPUMASK value written during init (also shadow)
PpuCtrlShadow = $EF ; PPUCTRL shadow register (NMI bit cleared via and #$7F)
VramToggleFlag = $CF ; Flag toggled each frame (asl/rol at $C095-$C09D)
NmiFlagByte = $E0 ; Flag cleared during NMI ($CD0F)
; Controller / button state (indexed by button number via $4E,X)
JoyBtnStateBase = $4E ; Base address for indexed button states ($4E,X)
JoyBtnState_P1_A = $4E ; Player 1 button A state/timer
JoyBtnState_P1_B = $4F ; Player 1 button B state/timer
JoyBtnState_P1_Select = $50 ; Player 1 select state/timer (if used)
JoyBtnState_P1_Start = $51 ; Player 1 start state/timer
JoyBtnState_P1_Up = $52 ; Player 1 up state/timer
FrameCounterLo = $53 ; Frame counter low byte (incremented each frame)
FrameCounterHi = $54 ; Frame counter high byte
JoyBtnTimer_P1_Down = $55 ; Player 1 down button timer
JoyBtnTimer_P1_Left = $56 ; Player 1 left button timer
JoyBtnTimer_P1_Right = $57 ; Player 1 right button timer
JoyBtnTimer_P1_Start2 = $5C ; Player 1 start timer (second instance)
JoyBtnTimer_P1_A2 = $61 ; Player 1 button A timer (second instance)
JoyBtnTimer_P2_Down = $5E ; Player 2 down button timer
JoyBtnTimer_P2_Left = $59 ; Player 2 left button timer
JoyBtnTimer_P2_Right = $64 ; Player 2 right button timer
JoyBtnTimer_P2_A = $5F ; Player 2 button A timer
JoyBtnTimer_P2_B = $5A ; Player 2 button B timer
; Generic zero-page aliases (role not yet uniquely determined)
Zp60 = $60 ; Temporary zero-page storage
Zp65 = $65 ; Temporary zero-page storage
Zp66 = $66 ; Temporary zero-page storage
Zp68 = $68 ; Temporary zero-page storage
Zp69 = $69 ; Temporary zero-page storage
Binary file not shown.
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,35 @@
al 00CE89 .Label_CE89
al 00CE6E .Label_CE6E
al 00CE5F .Label_CE5F
al 00CE8A .Label_CE8A
al 00CE4F .VramBurstWrite
al 00CE3C .PpuScrollLatch
al 00CE33 .Label_CE33
al 00CE39 .Label_CE39
al 00CE16 .Label_CE16
al 00CE12 .Label_CE12
al 00CDEE .VramWrite
al 00CDC8 .RetAddrUpdate
al 00CDB1 .Label_CDB1
al 00CDA3 .Label_CDA3
al 00CD99 .VramPtrTableRead
al 00CD8D .Label_CD8D
al 00CD74 .Label_CD74
al 00CD71 .Label_CD71
al 00CD6E .Label_CD6E
al 00CD69 .Label_CD69
al 00CD5C .Label_CD5C
al 00CD45 .VramWriteLoop
al 00CD3F .VramPtrWrite
al 00CD2F .PpuMaskSetup
al 00CD24 .OamDmaSetup
al 00CD17 .PpuCtrlSetup
al 00CD0A .NmiContinue
al 00CCF7 .NmiHandler
al 00C178 .Label_C178
al 00C174 .ClearOAM_Routine
al 00C05D .ClearRAM2_Loop
al 00C013 .ClearRAM1_Loop
al 00C00A .WaitVblank3
al 00C005 .WaitVblank2
al 00C000 .Reset
@@ -0,0 +1,32 @@
Modules list:
-------------
header.o:
HEADER Offs=000000 Size=000010 Align=00001 Fill=0000
prg.o:
PRG Offs=000000 Size=004000 Align=00001 Fill=0000
chr.o:
CHR Offs=000000 Size=002000 Align=00001 Fill=0000
Segment list:
-------------
Name Start End Size Align
----------------------------------------------------
CHR 000000 001FFF 002000 00001
HEADER 000000 00000F 000010 00001
PRG 00C000 00FFFF 004000 00001
Exports list by name:
---------------------
Exports list by value:
----------------------
Imports list:
-------------
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
../rom.nes
@@ -0,0 +1,108 @@
; =============================================================================
; Nintendo Entertainment System hardware symbols
; =============================================================================
; -----------------------------------------------------------------------------
; PPU registers
; -----------------------------------------------------------------------------
PPUCTRL = $2000
PPUMASK = $2001
PPUSTATUS = $2002
OAMADDR = $2003
OAMDATA = $2004
PPUSCROLL = $2005
PPUADDR = $2006
PPUDATA = $2007
OAMDMA = $4014
; -----------------------------------------------------------------------------
; Controller ports
;
; $4016:
; Write: controller strobe
; Read: controller port 1
;
; $4017:
; Read: controller port 2
; Write: APU frame counter
; -----------------------------------------------------------------------------
JOY1 = $4016
JOY2 = $4017
; -----------------------------------------------------------------------------
; APU pulse channel 1
; -----------------------------------------------------------------------------
APUPULSE1CTRL = $4000
APUPULSE1SWEEP = $4001
APUPULSE1TIMERLO = $4002
APUPULSE1TIMERHI = $4003
; -----------------------------------------------------------------------------
; APU pulse channel 2
; -----------------------------------------------------------------------------
APUPULSE2CTRL = $4004
APUPULSE2SWEEP = $4005
APUPULSE2TIMERLO = $4006
APUPULSE2TIMERHI = $4007
; -----------------------------------------------------------------------------
; APU triangle channel
; -----------------------------------------------------------------------------
APUTRIANGLECTRL = $4008
APUTRIANGLETIMERLO = $400A
APUTRIANGLETIMERHI = $400B
; -----------------------------------------------------------------------------
; APU noise channel
; -----------------------------------------------------------------------------
APUNOISECTRL = $400C
APUNOISEPERIOD = $400E
APUNOISELENGTH = $400F
; -----------------------------------------------------------------------------
; APU DMC channel
; -----------------------------------------------------------------------------
APUDMCCTRL = $4010
APUDMCDIRECT = $4011
APUDMCADDR = $4012
APUDMCLENGTH = $4013
; -----------------------------------------------------------------------------
; APU status and frame counter
;
; $4015:
; Write: enable or disable the five APU channels
; Read: channel and interrupt status
;
; $4017:
; Write: APU frame-counter mode and IRQ inhibit
; Read: controller port 2
; -----------------------------------------------------------------------------
APUSTATUS = $4015
APUFRAMECOUNTER = $4017
; -----------------------------------------------------------------------------
; Controller masks
; -----------------------------------------------------------------------------
PAD_RIGHT = $01
PAD_LEFT = $02
PAD_DOWN = $04
PAD_UP = $08
PAD_START = $10
PAD_SELECT = $20
PAD_B = $40
PAD_A = $80
PAD_HORIZONTAL = PAD_LEFT | PAD_RIGHT
PAD_VERTICAL = PAD_UP | PAD_DOWN
PAD_DPAD = PAD_HORIZONTAL | PAD_VERTICAL