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