Dicky's Diamonds/Laderoutine

Aus C64-Wiki
Zur Navigation springenZur Suche springen

<< 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