Das Schneider CPC Systembuch

Die Abteilungen des Betriebssystems

Amsdos

der 'MERGE-Fehler'

Es ist unter Die Abteilungen des Betriebssystems: AmsdosAmsdos jedoch nicht möglich, zeichenweise geschriebene Dateien en Die Speicherkonfiguration im Schneider CPC: Blockblock zu laden!

Und versucht man, en Die Speicherkonfiguration im Schneider CPC: Blockblock geschriebene Dateien zeichenweise zu lesen, so gibt es Schwierigkeiten:

Das Zeichen 26 wird, wie das beim zeichenweisen Lesen einer Datei üblich ist, als EOF interpretiert. Dieser Code kann aber auch rein zufällig in der Datei vorkommen, vor allem, wenn sie eben keinen 'normalen' ASCII-Text enthält. Man kann dieses Zeichen aber auch ganz bewusst in eine Datei schreiben, z.LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL
LOW KERNEL JUMPBLOCK: 001B: LOW KL FAR PCHL
LOW KERNEL JUMPBLOCK: 003B: LOW EXT INTERRUPT
B
. unter Einleitung: BASIC
Anhang: Basic
Basic
in eine OPENOUT-Datei: PRINT#9,CHR$(26). Wird dieses Zeichen später eingelesen, so wird es als sogenanntes 'weiches' EOF (soft end) interpretiert, auch wenn danach noch 10 kByte Text folgen sollten!

Trotzdem kann man bei einer Datei mit Amsdos: HeaderHeader erkennen, dass ein CHR 26 kein EOF ist, weil im Amsdos: HeaderHeader ja steht, wieviele Datentypen: Bytes
Datenbreite: Bytes
Bytes
die Datei umfasst. Bei einer ASCII-Datei dagegen könnte man nur dann ein EOF trotz gelesenem Zeichen 26 sicher ausschließen, wenn das Zeichen in einem anderen als dem letzten Datenspeicherung und Datenstrukturen: RecordsRecord gefunden wurde.

Soll ein Basic-Programm zu einem bereits bestehenden in den Speicher gemischt, also 'gemerget' werden, so muss der Basic-Interpreter das neue Programm zeichenweise einlesen, auch wenn es, wie üblich, en Die Speicherkonfiguration im Schneider CPC: Blockblock gespeichert wurde. Damit ist der kritische Fall da:

Wird jetzt das Zeichen 26 eingelesen, was sehr häufig vorkommen kann (nicht nur bei der Zeilennummer 26), so meldet Die Abteilungen des Betriebssystems: AmsdosAmsdos mitten in einer Basic-Zeile ein EOF und der Basic-Interpreter weiß sich in seiner Not nicht anders zu helfen, als das gesamte Programm zu löschen.

Der einfachste Trick ist, Programme, die später 'gemerget' werden sollen, als ASCII-Datei zu speichern:

 SAVE "progname",Operationen: BD5B / 349A / 349A:  FLO SUBa

Der von Schneider publizierte Trick besteht in einem Patch des Vektors CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR: Hier wird die Meldung "soft end" = CY=0, Z=0 und Operationen: BD5B / 349A / 349A: FLO SUBA=26 in "alles o.k." = CY=1 und Operationen: BD5B / 349A / 349A: FLO SUBA=26 umgewandelt. Damit klappt dann das Mergen von normalen Basic-Programmen.

Aber oh weh! Damit ist man bei Schneider voll über's Ziel hinausgeschossen, denn jetzt wird u. Operationen: BD5B / 349A / 349A: FLO SUBA. beim Mergen von ASCII-Programmdateien das Zeichen 26 nicht mehr als EOF erkannt, und Einleitung: BASIC
Anhang: Basic
Basic
meldet nun mit schöner Regelmäßigkeit "Direct Befehls-Elemente: Commandscommand found". Auch INPUT und LINE INPUT aus OPENIN-Dateien schießen jetzt über das Datei-Ende hinaus, weil CHR 26 nicht mehr als File-Ende erkannt wird. Statt dessen lesen sie schön brav weiter, bis mit dem Record-Ende das sogenannte 'hard end' erreicht ist.

Trotzdem ist es sicher oft sinnvoll, diesen Vektor zu patchen. Das folgende Assembler-Programm vermeidet die Schwäche des Schneider-Patches, indem nur bei Header-Dateien der Vektor CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR gepatcht wird. Dateien ohne Amsdos: HeaderHeader werden nicht gepatcht und liefern deshalb beim CHR 26 auch weiterhin ein 'soft end'.

Dieses Beispiel zeigt auch, wie umständlich man die Amsdos-Vektoren patchen muss, weil diese nicht relocatibel sind.

Da die beiden RSX-Kommandos |DISC und |DISC.IN die betroffenen Vektoren wieder in den Original-Amsdos-Zustand versetzen, dürfen sie nicht benutzt werden! Man kann aber selbst zwei RSX-Kommandos mit diesen Namen zu definieren (die dann Priorität über die 'aelteren' Definitionen erlangen), die erst die Original-Routinen aufrufen, und danach den Patch sofort wieder restaurieren.

; Verbesserter CHAIN-MERGE / MERGE-Patch    Erklärung zu den Anschlüssen: Vcc und Vss
Erklärung zu den Anschluss-Bezeichnungen: Vcc und Vss
vs
. 25/26.5.86 (c) G.Woigk ; -------------------------------------- -------------- ----------- ; ORG 40000 ; INCHAR: EQU #BC80 ; CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR OPENIN: EQU #BC77 ; CASSETTE MANAGER: BC77: CAS IN OPENCAS in OPEN ; ; Hier: Relocater einbinden. ; INIT: LD HL,OPENIN ; Erstelle eine Kopie (1) des Vektors LD DE,KOPIE1 ; CASSETTE MANAGER: BC77: CAS IN OPENCAS IN OPEN. LD BC,3 LDIR ; LD HL,INCHAR ; Erstelle eine Kopie (2) des Vektors LD BC,3 ; CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR. LDIR ; ; Hier evtl. noch eigene |DISC- und |DISC.IN-Befehle definieren. ; INIT1: LD HL,OPEN ; Patche den Vektor CASSETTE MANAGER: BC77: CAS IN OPENCAS IN OPEN LD (OPENIN+1),HL ; mit Sprung zur eigenen Routine OPEN. LD HL,OPENIN LD (HL),195 ; Opcode für 'JP'. RET ; KOPIE1: DEFS 3 ; Platz für Original von CASSETTE MANAGER: BC77: CAS IN OPENCAS IN OPEN. KOPIE2: DEFS 3 ; Platz für Original von CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR. ; ; Ersatz-Routine für CASSETTE MANAGER: BC77: CAS IN OPENCAS IN OPEN ; OPEN: PUSH HL LD HL,(KOPIE1) ; Restauriere Vektor LD (OPENIN),HL ; CASSETTE MANAGER: BC77: CAS IN OPENCAS IN OPEN. LD Operationen: BD5B / 349A / 349A: FLO SUBA,(KOPIE1+2) LD (OPENIN+2),Operationen: BD5B / 349A / 349A: FLO SUBA POP HL ; Maschinencode über HIMEM: CALLCALL OPENIN ; Rufe normale Die Fließkomma-Routinen: FunktionenFunktion auf. ; PUSH HL PUSH AF Maschinencode über HIMEM: CALLCALL INIT1 ; und richte Patch wieder ein. ; LD Operationen: BD5B / 349A / 349A: FLO SUBA,LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL
LOW KERNEL JUMPBLOCK: 001B: LOW KL FAR PCHL
LOW KERNEL JUMPBLOCK: 003B: LOW EXT INTERRUPT
B
; logische Datei-Länge = 0 ?? OR C Maschinencode über HIMEM: CALLCALL NZ,OPEN1 ; Nein -> Datei hat Amsdos: HeaderHeader. Patche CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR Maschinencode über HIMEM: CALLCALL Z,OPEN2 ; Ja -> Datei hat keinen Amsdos: HeaderHeader. Soft EOF darf POP AF ; nicht abgefangen werden. --> CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR POP HL ; restaurieren. RET ; ; Patche CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR. (Nur HL benutzt wg. INCHR) ; OPEN1: LD HL,INCHAR ; Opcode 'JP' in Vektor poken LD (HL),195 LD HL,INCHR ; und Sprungadresse dahinter. LD (INCHAR+1),HL RET ; ; Versetze CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR in den Originalzustand: ; OPEN2: LD HL,(KOPIE2) ; Vektor aus Kopie2 LD (INCHAR),HL ; an seine Position LD Operationen: BD5B / 349A / 349A: FLO SUBA,(KOPIE2+2) ; im BCD1: KL LOG EXT: 1. JumpblockJumpblock LD (INCHAR+2),Operationen: BD5B / 349A / 349A: FLO SUBA ; zurückkopieren. RET ; ; Eigene Routine für CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR ; INCHR: PUSH HL Maschinencode über HIMEM: CALLCALL OPEN2 ; CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR restaurieren Maschinencode über HIMEM: CALLCALL INCHAR ; CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR aufrufen Maschinencode über HIMEM: CALLCALL OPEN1 ; CASSETTE MANAGER: BC80: CAS IN CHARCAS IN CHAR wieder patchen POP HL ; RET C ; CY=1 -> alles o.k. RET Z ; Der Linien-Algorithmus: Fehler 3Fehler mit Z=1 -> kein 14/15/26-Der Linien-Algorithmus: Fehler 3Fehler CP 26 ; Der Linien-Algorithmus: Fehler 3Fehler 26 = Soft EOF? CCF RET NC ; Der Linien-Algorithmus: Fehler 3Fehler < 26: Dann zurück mit CY=0 und Z=0 CP 27 RET C ; Der Linien-Algorithmus: Fehler 3Fehler = 26: Dann zurück mit CY=1 und Z=0 CP 26 RET ; Der Linien-Algorithmus: Fehler 3Fehler > 26: Dann zurück mit CY=0 und Z=0

Valid HTML   Valid CSS