Dicky's Diamonds/Laderoutine
<< zurück zu Dicky's Diamonds
Dicky's_Diamonds/Laderoutine: Der folgende Abschnitt stellt die disassemblierte Kassetten-Laderoutine des Spiels Dicky's Diamonds dar. Sie findet vollständig im Headerblock des ersten Programmteils Platz.
Programmheader[Bearbeiten | Quelltext bearbeiten]
Das folgende Listing zeigt den Inhalt des Datassetten-Headerblocks, der dem ersten Programmteil von "Dicky's Diamonds" vorangestellt ist. Der Programmteil selbst besteht nur aus den beiden Datenbytes $43 $03, die an Adresse $029F geladen werden und dort den Interruptvektor überschreiben, der später nach dem Ende des Ladevorgangs wieder aktiviert wird. Diese beiden Datenbytes bilden einen Sprungvektor zum Label "P_AA" der nachfolgenden Laderoutine, über den dann beim ersten Interrupt nach dem Ende des Kassettenzugriffs die Laderoutine ausgeführt wird.
ORG $033C
DB $03 ; Code für "Absolut zu ladendes Programm"
DW $029F ; Startadresse des ersten Programmteils
DW $02A1 ; Endadresse+1 des ersten Programmteils
DB $93 ; PETSCII-Code für "Bildschirm löschen"
DB $1F ; PETSCII-Code für "Zeichenfarbe Dunkelblau"
P_AA: SEI ; IRQs verbieten
LDA #$31 ; Ursprünglichen IRQ-Vektor (Low-Byte)
STA $0314 ; wiederherstellen
LDA #$EA ; Ursprünglichen IRQ-Vektor (High-Byte)
STA $0315 ; wiederherstellen
CLI ; IRQs wieder zulassen
JSR $FD02 ; Prüft auf Modul-Kennung "CBM80" an Adresse $8004
SEC ; Kennzeichen für "Ladefehler"
BEQ $03BD ; Sprung, falls Modul-Kennung gefunden
LDA #$81 ; Einsprungadresse für Rückkehr aus Interruptroutine (Low-Byte)
STA $0316 ; als BRK-Vektor setzen (Low-Byte)
STA $0318 ; und als NMI-Vektor setzen (Low-Byte)
LDA #$EA ; Einsprungadresse für Rückkehr aus Interruptroutine (High-Byte)
STA $0317 ; als BRK-Vektor setzen (High-Byte)
STA $0319 ; und als NMI-Vektor setzen (High-Byte)
LDA #$00 ; Basisadresse Kernal-ROM (Low-Byte)
STA *$FB ; als Zeiger setzen (Low-Byte)
LDA #$E0 ; Basisadresse Kernal-ROM (High-Byte)
STA *$FC ; als Zeiger setzen (High-Byte)
LDY #$00 ; Index für nachfolgende Lese-/Schreibzugriffe
AA00: LDA ($FB),Y ; Kernal-ROM lesen
STA ($FB),Y ; und in darunterliegendes RAM kopieren
INY ; Lese-/Schreibindex erhöhen
BNE AA00 ; Rücksprung falls kein Überlauf
INC *$FC ; High-Byte des Zeigers erhöhen
BNE AA00 ; Rücksprung falls Ende des Kernals noch nicht erreicht
LDA #$2F ; Standardwert für Datenrichtungsregister des CPU-Ports
STA *$00 ; in Datenrichtungsregister des CPU-Ports schreiben
LDA #$35 ; Wert für "alle ROMs ausblenden, nur RAM und I/O einblenden"
STA *$01 ; in Datenregister des CPU-Ports schreiben
LDA #$02 ; Reset-Vektor
STA $FFFC ; auf Adresse $0802 umbiegen (Low-Byte)
LDA #$08 ; Reset-Vektor
STA $FFFD ; auf Adresse $0802 umbiegen (High-Byte)
LDA #$00 ; Programmmodus
JSR $FF90 ; setzen (unterdrückt Fehlermeldungen)
LDA #$00 ; Bandpuffer
STA *$B2 ; nach Adresse $C100 verlegen (Low-Byte)
LDA #$C1 ; Bandpuffer
STA *$B3 ; nach Adresse $C100 verlegen (High-Byte)
; Zwei weitere Programmteile nachladen
LDA #$01 ; Logische Dateinummer=1
TAX ; Geräteadresse=1
TAY ; Sekundäradresse=1
JSR $FFBA ; Dateiparameter setzen
LDA #$00 ; Länge des Dateinamens=0
JSR $FFBD ; Dateinamenparameter setzen
LDA #$00 ; Load-/Verify-Flag auf "LOAD"
JSR $FFD5 ; Ersten Programmteil laden
BCS AA01 ; Sprung falls Ladefehler
LDA #$01 ; Logische Gerätenummer=1
TAX ; Geräteadresse=1
TAY ; Sekundäradresse=1
JSR $FFBA ; Dateiparameter setzen
LDA #$00 ; Länge des Dateinamens=0
JSR $FFBD ; Dateinamenparamter setzen
LDA #$00 ; Load-/Verify-Flag auf "LOAD"
JSR $FFD5 ; Zweiten Programmteil laden
AA01: BCS AA04 ; Sprung falls Ladefehler
; Programmcode entschlüsseln
LDY #$00 ; Index für nachfolgende Lese-/Schreibzugriffe
STY *$FB ; Zeiger setzen (Low-Byte)
LDA #$04 ; Hauptspeicher ab Adresse $0400 entschlüsseln
STA *$FC ; Zeiger setzen (High-Byte)
LDX #$02 ; Index für nachfolgende Entschlüsselung
AA02: LDA $0200,X ; Schlüssel holen
EOR ($FB),Y ; mit Programmbyte im Hauptspeicher XOR-verknüpfen
STA ($FB),Y ; und zurückschreiben
DEX ; X-Register auf nächstes Byte des Schlüssels richten
BPL AA03 ; Sprung falls kein Unterlauf
LDX #$02 ; sonst X-Register wieder auf erstes Byte des Schlüssels richten
AA03: INY ; Lese-/Schreibindex erhöhen
BNE AA02 ; Rücksprung falls kein Überlauf
INC *$FC ; High-Byte des Zeigers erhöhen
BPL AA02 ; Rücksprung, falls noch nicht bis $7FFF entschlüsselt
SEI ; IRQs verbieten
JSR $FF8A ; I/O initialisieren
CLI ; IRQs wieder erlauben
JMP $0802 ; Sprung zur Startadresse des Programms
; Speicher löschen und Reset ausführen
AA04: LDY #$00 ; Index für nachfolgende Schreibzugriffe
STY *$FB ; Zeiger setzen (Low-Byte)
LDA #$04 ; Hauptspeicher ab Adresse $0400 löschen
STA *$FC ; Zeiger setzen (High-Byte)
AA05: STA ($FB),Y ; Hauptspeicher mit Wert $04 überschreiben
INY ; Schreibindex erhöhen
BNE AA05 ; Rücksprung falls kein Überlauf
INC *$FC ; High-Byte des Zeigers erhöhen
BPL AA05 ; Rücksprung, falls noch nicht bis $7FFF überschrieben
LDA #$37 ; I/O und alle ROMs in Adressraum einblenden
STA *$01 ; Datenregister des CPU-Ports beschreiben
JMP ($FFFC) ; Reset auslösen