CA65 ?= ca65 LD65 ?= ld65 PYTHON ?= python3 TOOLS ?= ../../_tools all: reconstructed.nes verify prg.o: prg.s symbols.inc locals.inc $(CA65) -g -o $@ $< header.o: header.s header.bin $(CA65) -g -o $@ $< chr.o: chr.s chr.bin $(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 rom.nes cmp reconstructed.nes rom.nes @echo "Byte-identical ROM verified." # Regenerate prg.s and locals.inc from prg.bin, then re-apply the naming. # Every --table/--extra-seed flag below is a documented classification # decision, not a convenience; see the provenance block at the head of prg.s. # # --table 0xC3A6:9,0xCCD5:8 the two queued-event dispatchers, whose # 16-bit vector tables hold the handler # addresses the engine jumps to # --extra-seed the sixteen targets of the four `jmp` # trampoline tables the tracer cannot see # ($C01E, $C02A, $C042, $C054), the $C800 # boot mainline, and six further code starts # found by inspection regen: pass1 pass2 pass3 pass1: $(PYTHON) $(TOOLS)/nesdis.py --prg prg.bin --base 0xC000 --project "Pyramid (U)" \ --out prg.s --locals locals.inc --auto-seed \ --table "0xC3A6:9,0xCCD5:8" \ --extra-seed "0xC800,0xC1C9,0xC1D0,0xC1D7,0xC1EF,0xC205,0xC201,0xC225,0xC23A,0xC294,0xC34A,0xC43E,0xC585,0xC5AB,0xC614,0xC662,0xC6A3,0xD79D,0xD7D7,0xD7EB,0xDF89,0xF942,0xFF74" cat zp_aliases.inc >> locals.inc # Pass 2: the routine and branch-target names, then the zero-page aliases # at the sites where their role is proven. pass2: pass1 $(PYTHON) $(TOOLS)/apply_pass2_map.py . routinemap.tsv --write $(PYTHON) $(TOOLS)/apply_zp_aliases.py . \ --alias ScriptPtrLo=Zp02 --alias ScriptPtrHi=Zp03 --alias CommandListFlag=Zp04 \ --alias VramPosHi=Zp05 --alias VramPosLo=Zp06 --alias FrameCounter=Zp0A \ --alias FrameCounterHi=Zp0B --alias DrawCounter=Zp0C \ --alias SoundTickScriptLo=Zp27 --alias SoundTickScriptHi=Zp28 \ --alias SoundPlayer1ScriptLo=Zp29 --alias SoundPlayer1ScriptHi=Zp2A \ --alias SoundPlayer2ScriptLo=Zp2B --alias SoundPlayer2ScriptHi=Zp2C \ --alias SoundPlayer3ScriptLo=Zp2D --alias SoundPlayer3ScriptHi=Zp2E \ --alias Player1Input=Zp3D --alias Player2Input=Zp3E \ --alias SpriteX=Zp43 --alias SpriteY=Zp44 \ --alias DeltaLo=Zp4D --alias DeltaMid=Zp4E --alias DeltaHi=Zp4F \ --alias DeltaWrapCount=Zp50 \ --at-ind 'ScriptPtrLo@C3A3' --at-ind 'ScriptPtrLo@CCCA' --write # Pass 3: name the data blocks, apply the hardware register names, and put # the audit comments back in their canonical column. pass3: pass2 $(PYTHON) $(TOOLS)/name_data_region.py . $$(awk -F'\t' '!/^#/ && NF>1 {printf "%s=%s ", $$1, $$2}' data_region_names.tsv) --write $(PYTHON) $(TOOLS)/apply_symbols.py . --write $(PYTHON) $(TOOLS)/align_audit_comments.py . --write clean: rm -f *.o reconstructed.nes reconstructed_prg.bin reconstructed.map reconstructed.lbl .PHONY: all verify clean regen pass1 pass2 pass3