Ich befürchte, dass dir das meiste hiervon vorerst nix nützen wird, weil es RAM bezogen ist, und damit nur von Nutzen, wenn du in den ASM-Code des 5A22 (~= 65816) eintauchen willst. Fürs erste ist wohl nur aller Kram nützlich, der nicht mit 7E oder 7F anfängt.
Also, ich habe mal ein wenig im Handbuch des 65816 nachgeschlagen, und da steht zum COP-Befehl folgendes (das muss jetzt keiner wirklich lesen):
Execution of COP causes a software interrupt, similarly to BRK, but through the separate COP vector. Alternatively, COP may be trapped by a co-processor, such as a floating point or graphics processor, to call a co-processor function. COP is unaffected by the i interrupt disable flag.
COP is much like BRK, with the program counter value pushed on the stack being incremented by two; this lets you follow the co-processor instruction with a signature byte to indicate to the co-processor or coprocessor handling routine which operation to execute. Unlike the BRK instruction, 65816 assemblers require you to follow the COP instruction with such a signature byte. Signature bytes in the range $80-$FF are reserved by the Western Design Center for implementation of co-processor control; signatures in the range $00-$7F are available for use with software-implemented COP handlers.
6502 Emulation Mode (65802/65816, e=1): The program counter is incremented by two and pushed onto the stack; the status register is pushed onto the stack; the interrupt disable flag is set; and the program counter is loaded from the emulation mode co-processor vector at $FFF4-FFF5. The d decimal flag is cleared after a COP is executed.
65802/65816 Native Mode (e = 0): The program counter bank register is pushed onto the stack; the program counter is incremented by two and pushed onto the stack; the status register is pushed onto the stack; the interrupt disable flag is set; the program bank register is cleared to zero; and the program counter is loaded from the native mode co-processor vector at $00FFE4-00FFE5. The d decimal flag is reset to 0 after a COP is executed.
Folglich ist das nur eine alternative Art und Weise, einen Software-Break herbeizuführen. Gerade mal im SNES-Header geguckt: Die ROM hat folgende Vektoren:
Emulation Mode - RESET (natürlich): $8000
Native Mode - COP: $8007
Native Mode - BRK: $800F
Native Mode - NMI: $800B
Liegen alle ziemlich dicht beieinander, was?
Also gucken wir mal in den Code ab $8000:
78 18 FB 5C 14 80 80 5C 6D 84 80 5C F8 82 80 5C 13 80 80 40 D8 C2 30 A9 00 00 5B A9 FF 01 1B E2
RESET: ; $8000
SEI
CLC
XCE ; (Enable Native Mode)
JMP $808014 ; Jump
COP: ; $8007
JMP $80846D ; Jump
BRK: ; $800B
JMP $8082F8 ; Jump
NMI: ; $800F
JMP $808013 ; Jump
;808014 [Spielbeginn]
Gut, also, das hat mich jetzt nicht weitergebracht. $(80)846D fängt an mit:
C2 20 9B A3 04 85 0C A3 02 3A 85 0A A7 0A E6 0A 29 FF 00 0A AA 7C 85 84 4E 86 89 86 A0 86 B7 86
REP #$20
TXY
LDA #$04,s
STA $0C
LDA #$02,s
DEC A
STA $0A
LDA [$0A]
...
Hah, kuhl. Jetzt weiß ich, wie die das machen:
Da oben im Auszug aus dem 65816-Handbuch steht ja, dass der COP-Befehl immer einen Argument-Byte hat. Der Kram, den ich da oben mehr schlecht als recht per Hand disassembled habe, macht folgendes:
Der COP-Befehl schmeißt sich die Adresse, wo er herkommt, auf den Stack, damit er nach Beendigung seines Handlers dahin zurückspringen kann. Der Kram daoben zieht Daten vom Stack und nutzt die als Adresse, um einen Datenbyte zu laden. Logischerweise lädt sich das Ding so den Argumentbyte. Folglich sind die COP-Befehle, die nicht zwangsweise ihrem Namen gemäß etwas mit einem COProzessor zutun haben (siehe Handbuch), auch nur eine bestimmte Art und Weise, einen Handler aus einer Liste von Handlern zu laden.
Das kann man sich ja mal beizeiten angucken, aber evtl. schließt das zumindest einige weiße Flecken in deiner ROM-Map.
