Das Schneider CPC Systembuch

Die Abteilungen des Betriebssystems

Die Basic-Vektoren

Nach den Kernel-Routinen im Überblick: MAIN FIRMWARE JUMPBLOCKMAIN FIRMWARE JUMPBLOCK folgt noch das MAIN FIRMWARE JUMPBLOCK: MACHINE PACK
Die Firmware des Schneider CPC: MACHINE PACK
Machine Pack
mit einigen hardware-nahen Routinen etc. und der Vektor JUMPER: BD37: JUMP RESTOREJUMP RESTORE. Damit ist Die Sprungleisten: Der Main Firmware Jumpblockder 'main firmware jumpblock' eigentlich zuende. Darüber folgen aber noch weitere Vektoren, die nur nicht mehr zum Betriebssystem gezählt werden: Die Abteilungen des Betriebssystems: Die Basic-Vektoren
Überblick: Die Basic-Vektoren
Die Firmware des Schneider CPC: Die Basic-Vektoren
Die Basic-Vektoren
.

Da sie aber so nützliche Dinge wie die Fließkomma-Arithmetik und einen Vektor zum Zeileneditor beinhalten, wird man auf sie wohl kaum verzichten wollen. Auch diese Vektoren werden mit jedem System-Reset und jedem Aufruf von JUMPER: BD37: JUMP RESTOREJump Restore im RAM eingerichtet. Dass sie nicht zum Betriebssystem gehören, hat aber einen ganz entscheidenden Nebeneffekt: Diese Vektoren haben keine von Amstrad garantierte Lage im RAM.

Arithmetik-Vektoren

Blieb man bis hierhin vor Kompatibilitäts-Problemen weitgehend verschont, so hat man sie jetzt satt und reichlich. Alle Basic-Vektoren liegen bei allen drei CPC's an einer anderen Stelle! Das liegt zum Einen daran, dass Die Abteilungen des Betriebssystems: Die Basic-Vektoren
Überblick: Die Basic-Vektoren
Die Firmware des Schneider CPC: Die Basic-Vektoren
die Basic-Vektoren
direkt an Die Sprungleisten: Der Main Firmware Jumpblockden 'main firmware jumpblock' angefügt wurden, und dieser bei allen drei CPC's um einige Vektoren verlängert wurde (Hauptsächlich Grafik-Vektoren und Garbage Collection: ... beim CPC 464beim CPC 6128 der RAM-Select-Vektor).

Zum Anderen hatte man den Arithmetik-Teil Garbage Collection: ... beim CPC 464beim CPC 664/6128 erheblich gestrafft: Einige der Fließkomma-Vektoren fielen heraus und die Integer-Rechenroutinen, die Garbage Collection: ... beim CPC 464beim CPC 464 noch im unteren Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM lagen, wurden Garbage Collection: ... beim CPC 664 und 6128beim CPC 664 und 6128 in's Basic-ROM integriert. Diese Vektoren wurden damit auch überfluessig. Ansich war das nur zu befürworten, werden Rechnungen mit Integerzahlen so doch noch schneller. Nur passionierte Assembler-Programmierer stehen jetzt etwas alleine gelassen da. Hier muss man die Rechenroutinen jetzt selbst via LOW KERNEL JUMPBLOCK: 0018 - RST 3: LOW FAR CALLRST_3 aufrufen.

Wer nur für den eigenen Gebrauch programmiert, hat es noch am leichtesten. Er muss sich eben an die im AnhangAnhang für seinen Computer angegebenen Adressen Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: Halthalten. Garbage Collection: ... beim CPC 664 und 6128Beim CPC 664 und 6128 muss man für Integer-Rechnungen die entsprechenden Routinen im Basic-ROM mit einem ROM-Konfiguration: RestartsRestart direkt aufrufen.

Werden umfangreichere Berechnungen mit Integer-Zahlen durchgeführt, kann man auch mit den Vektoren HIGH KERNEL JUMPBLOCK: B900: HI KL U ROM ENABLEHI KL U ROM ENABLE und HIGH KERNEL JUMPBLOCK: B903: HI KL U ROM DISABLEHI KL U ROM DISABLE für die Dauer der Integer-Operationen das Basic-ROM ständig einblenden, und dann die entsprechenden Routinen mit einfachen CALL-Befehlen aufrufen:

; Integer-Berechnungen Garbage Collection: ... beim CPC 464beim CPC 664/6128
;
       ...
       Maschinencode über HIMEM: CALLCALL #B900   ; HIGH KERNEL JUMPBLOCK: B900:  HI KL U ROM ENABLEHI KL U ROM ENABLE
       ...
       ...          ; Hier Berechnungen
       ...
       Maschinencode über HIMEM: CALLCALL #B903   ; HIGH KERNEL JUMPBLOCK: B903:  HI KL U ROM DISABLEHI KL U ROM DISABLE
       ...

Bei dieser Methode muss nur immer sicher sein, dass im obersten Adress-Viertel auch wirklich das Basic-ROM selektiert ist. Normalerweise (bei der Programmierung von Utilities für Einleitung: BASIC
Anhang: Basic
Basic
o. AE.) wird das aber immer der Fall sein.

Entsprechend können übrigens auch CPC-464-Routinen mit dem unteren Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM verfahren. Mit den Vektoren HIGH KERNEL JUMPBLOCK: B906: HI KL L ROM ENABLEHI KL L ROM ENABLE und -DISABLE (&BC06 und &BC09) kann man das untere Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM einblenden. Wenn man sich dann die Adressen der Routinen einmal aus den Vektoren herausklaubt, kann man sie immer direkt aufrufen und auch hier die ewige Bank-Schalterei umgehen.

Wer aber Programme schreibt, die nachher auch auf den 'kompatiblen' Geschwistern laufen sollen, der kommt nicht umhin, entweder drei verschiedene Versionen zu schreiben, oder zuallererst zu Erklärung der Anschlussbelegung: Testtesten, welche Version er jeweils vorliegen hat. Dazu kann man den Vektor &HIGH KERNEL JUMPBLOCK: B915: HI KL PROBE ROMB915 HI KL PROBE ROM benutzen und dann vielleicht eine eigene Sprungleiste entsprechend initialisieren.

Bis auf diese Probleme sind Die Abteilungen des Betriebssystems: Die Basic-Vektoren
Überblick: Die Basic-Vektoren
Die Firmware des Schneider CPC: Die Basic-Vektoren
die Basic-Vektoren
aber eine feine Sache. Wer in Assembler mit Fließkomma-Zahlen rechnen will, muss sich hier nicht mehr selbst damit 'rumschlagen. Man kann die einzelnen Vektoren wieder als Module auffassen, von denen man nur die Schnittstellen-Beschreibung zu kennen braucht: Eingabe -Die Fließkomma-Routinen: FunktionenFunktion - Ausgabe.

Das folgende Beispiel demonstriert eine Fließkomma-Multiplikation in Assembler:

; FLO-Multiplikation
; ------------------
;
       ORG  40000    ; Basic und Maschinencode: ParameterParameter von einem Basic-Aufruf übernehmen:
       LD   L,(IX+0) ; HL = zweiter Basic und Maschinencode: ParameterParameter
       LD   H,(IX+1)
       LD   LOW KERNEL JUMPBLOCK: 000E:  LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
,(IX+2) ; DE = erster Basic und Maschinencode: ParameterParameter LD D,(IX+3) Maschinencode über HIMEM: CALLCALL #BD61 ; CPC 464: #BD61 / 664: #BD82 / 6128: #BD85 RET ; FLO(HL) := FLO(HL) * FLO(DE)     100 ' Basic-Aufruf dazu: 110 ' 120 DIM dummy%(8000),Operationen: BD5B / 349A / 349A: FLO SUBa!(2) 120 Operationen: BD5B / 349A / 349A: FLO SUBa!(1)=12345.6 130 Operationen: BD5B / 349A / 349A: FLO SUBa!(2)=98765.4 140 ' 150 Maschinencode über HIMEM: CALLCALL 40000,@Operationen: BD5B / 349A / 349A: FLO SUBa!(1),@Operationen: BD5B / 349A / 349A: FLO SUBa!(2) 160 ' 170 PRINT Operationen: BD5B / 349A / 349A: FLO SUBa!(2)

Damit nicht beim ersten Versuch ein Phantasie-Ergebnis herauskommt, sollte man wirklich wie in diesem Beispiel gezeigt vorgehen:

Mit dummy%(8000) wird ein Datenspeicherung und Datenstrukturen: ArraysArray definiert, der etwas über 16000 Datentypen: Bytes
Datenbreite: Bytes
Bytes
lang ist. Das nachfolgend definierte Feld Operationen: BD5B / 349A / 349A: FLO SUBa!(2) wird über dummy%() angelegt und liegt deshalb im zentralen RAM.

Da Die Basic-Vektoren: Die Fließkomma-Routinendie Fließkomma-Routinen im unteren Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM untergebracht sind, können sie nicht auf Unterprogramme: VariablenVariablen im untersten RAM-Viertel zugreifen. Übergibt man eine Adresse unterhalb von &4000 so wird der entsprechende Wert aus dem Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM gelesen, hinterher das Ergebnis aber an dieser Stelle in's RAM geschrieben (Schreibzugriffe der Die ICs im Überblick: Die CPU Z80
Das Innenleben der CPC-Rechner: Die CPU Z80
Die Anschlussbelegungen der wichtigsten ICs im CPC: Die CPU Z80
CPU
gehen ja immer an's RAM!). So würde zwar die Zielvariable verändert, ein sinnvolles Ergebnis kaeme aber nicht heraus.

Mit dem Aufruf in Zeile 150 werden dem Assembler-Programm die Adressen der beiden Feld-Elemente Operationen: BD5B / 349A / 349A: FLO SUBa!(1) und Operationen: BD5B / 349A / 349A: FLO SUBa!(2) übergeben. Diese werden im Assembler-Programm zunächst nach DE und HL geladen und dann die Multiplikations-Routine aufgerufen. Diese legt das Ergebnis zum Schluss wieder in der durch HL adressierten Unterprogramme: VariablenVariablen ab, was in diesem Beispiel Operationen: BD5B / 349A / 349A: FLO SUBa!(2) ist.

Allgemein wird aber ein Maschinencode-Programm, das Fließkomma-Zahlen übernimmt, diese zuerst einmal in reservierte Bereiche im zentralen RAM kopieren, damit die Rechenroutinen auch ganz sicher darauf zugreifen können.

Das folgende Beispiel greift den Kreis-Algorithmus aus dem Kapitel zur Grafik-VDU auf:

200 n%=1+PI*SQR(r)
210 ORIGIN xm,ym
220 dx!=0:dy!=r:MOVE dx!,dy!
230 sinus!=SIN(2*PI/n%)
240 cosin!=COS(2*PI/n%)
250 '
260 FOR n%=1 TO n%
270    z!=dx!*cosin!-dy!*sinus!
280   dy!=dy!*cosin!+dx!*sinus!
290   dx!=z!
300   DRAW dx!,dy!
310 NEXT:RETURN

Das entsprechende Assembler-Programm ist für den CPC 464 geschrieben. Benutzer eines CPC 664 oder 6128 müssen sich die entsprechenden Adressen aus den Tabellen im AnhangAnhang herausklauben.

An diesem Beispiel sieht man aber auch, zu welchen Längenwundern in Assembler geschriebene Rechen-Routinen neigen. Anhand der Programmiertechnik: KommentareKommentare ist es aber hoffentlich leicht zu verfolgen, welcher Wert sich wann in welchem Speicher befindet.

;   |Die Grafik-VDU: CircleCIRCLE,xm,ym,r[,f]         Erklärung zu den Anschlüssen: Vcc und Vss
Erklärung zu den Anschluss-Bezeichnungen: Vcc und Vss
vs
. 4.6.86 (c) G.Woigk ; ------------------- ---------- ----------- ; ORG #6000 JP KREIS ; ; HIER: Einbindung als Maschinencode über HIMEM: RSXRSX & Relocalisation ; DEGRAD: EQU #BD73 ; Operationen: BD5B / 349A / 349A: FLO SUBA=0 => RADIANT Angaben für CPC 464!! FLOMOV: EQU #BD3D ; FLO(HL) := FLO(DE) ---------------------- FLOPI: EQU #BD76 ; FLO(HL) := PI FLOSIN: EQU #BD88 ; FLO(HL) := SIN(FLO) FLOCOS: EQU #BD8B ; FLO(HL) := COS(FLO) FLOSQR: EQU #BD79 ; FLO(HL) := SQR(FLO) FLOADD: EQU #BD58 ; FLO(HL) := FLO(HL) + FLO(DE) FLOMUL: EQU #BD61 ; FLO(HL) := FLO(HL) * FLO(DE) FLODIV: EQU #BD64 ; FLO(HL) := FLO(HL) / FLO(DE) FLOSUB: EQU #BD5B ; FLO(HL) := FLO(HL) - FLO(DE) INTFLO: EQU #BD40 ; FLO(DE) := HL,Operationen: BD5B / 349A / 349A: FLO SUBA=VZ FLOINT: EQU #BD46 ; HL,Operationen: BD5B / 349A / 349A: FLO SUBA=VZ := FLO(HL) INTVZW: EQU #BDC7 ; HL := -1 * HL ; SETPEN: EQU #BBDE ; SETZE GRAFIK-FARBSTIFT SETORG: EQU #BBC9 ; SETZE GRAFIK-ORIGIN GETORG: EQU #BBCC ; ERFRAGE GRAFIK-ORIGIN PLOTR: EQU #BBED ; PLOTTE EINEN PUNKT Adressierungsarten der Z80: RelativRELATIV DRAW: EQU #BBF6 ; ZIEHE LINIE Adressierungsarten der Z80: AbsolutABSOLUT MOVE: EQU #BBC0 ; SETZE GRAFIK-CURSOR Adressierungsarten der Z80: AbsolutABSOLUT ; SINUS: DEFS 5 ; Speicher für SIN(PI*2/n) COSIN: DEFS 5 ; Speicher für COS(PI*2/n) XPOS: DEFS 5 ; Speicher für X-Koord. des Kreisbogen YPOS: DEFS 5 ; Speicher für Y-Koord. des Kreisbogen ZW1: DEFS 5 ; Zwischenspeicher Nr. 1 ZW2: DEFS 5 ; Zwischenspeicher Nr. 2 Real: NullNULL: DEFB 0,0,0,0,0 ; Konstante: 0 ; ; ------------------------------- ; KREIS: CP 5 RET NC ; Zuviele Arg. CP 3 RET C JR Z,K1 ; LD Operationen: BD5B / 349A / 349A: FLO SUBA,(IX) ; 4. Par. = Farb-Angabe INC IX INC IX Maschinencode über HIMEM: CALLCALL SETPEN ; Grafikfarbe setzen ; K1: Maschinencode über HIMEM: CALLCALL GETORG ; Rette ORIGIN PUSH HL PUSH DE Maschinencode über HIMEM: CALLCALL Die Grafik-VDU: CircleCIRCLE ; DO THE JOB POP DE POP HL JP SETORG ; Restaurieren & RET ; ; ------------------------------- ; CIRCLE: XOR Operationen: BD5B / 349A / 349A: FLO SUBA Maschinencode über HIMEM: CALLCALL DEGRAD ; Winkelmass auf radiant einstellen ; LD D,(IX+5) LD LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
,(IX+4) ; 1.Basic und Maschinencode: ParameterParameter: XM LD H,(IX+3) LD L,(IX+2) ; 2.Basic und Maschinencode: ParameterParameter: YM Maschinencode über HIMEM: CALLCALL SETORG ; Kreismittelpunkt setzen ; LD H,(IX+1) LD L,(IX+0) ; 3.Basic und Maschinencode: ParameterParameter: Radius Datenbreite: Bits
Port B - Input: &F5xx: Bit 0:
Port B - Input: &F5xx: Bit 4:
Port B - Input: &F5xx: Bit 5:
Port B - Input: &F5xx: Bit 6:
Port B - Input: &F5xx: Bit 7:
Port C - Output: &F6xx: Bit 4:
Port C - Output: &F6xx: Bit 5:
BIT
7,H RET NZ ; Der Linien-Algorithmus: Fehler 3FEHLER: Neg. Radius PUSH HL LD DE,0 Maschinencode über HIMEM: CALLCALL MOVE ; Startpunkt der Kreislinie: (0,R) ; LD HL,XPOS ; (HL) = XPOS LD DE,Real: NullNULL ; (DE) = Real: NullNULL Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = XPOS := Real: NullNULL POP HL ; HL = RADIUS = R XOR Operationen: BD5B / 349A / 349A: FLO SUBA ; VORZEICHEN := POS. LD DE,YPOS ; (DE) = YPOS Maschinencode über HIMEM: CALLCALL INTFLO ; (HL) = YPOS := R ; EX DE,HL ; (DE) = YPOS = R LD HL,ZW1 ; (HL) = ZW1 Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = ZW1 := R Maschinencode über HIMEM: CALLCALL FLOSQR ; (HL) = ZW1 := SQR(R) LD HL,ZW2 ; (HL) = ZW2 Maschinencode über HIMEM: CALLCALL FLOPI ; (HL) = ZW2 := PI EX DE,HL ; (DE) = ZW2 = PI LD HL,ZW1 ; (HL) = ZW1 = SQR(R) Maschinencode über HIMEM: CALLCALL FLOMUL ; (HL) = ZW1 := PI*SQR(R) Maschinencode über HIMEM: CALLCALL FLOINT ; HL := ROUND(PI*SQR(R)) INC HL ; HL := 1+ROUND(PI*SQR(R)) ; ; ***** HL = L = ECKENZAHL N ***** ; PUSH HL ; N = Schleifenvariable für später ; LD DE,ZW1 ; (DE) = ZW1 Maschinencode über HIMEM: CALLCALL INTFLO ; (HL) = ZW1 := N LD HL,ZW2 ; (HL) = ZW2 = PI LD DE,ZW2 ; (DE) = ZW2 = PI Maschinencode über HIMEM: CALLCALL FLOADD ; (HL) = ZW2 := 2*PI LD DE,ZW1 ; (DE) = ZW1 = N Maschinencode über HIMEM: CALLCALL FLODIV ; (HL) = ZW2 := 2*PI/N EX DE,HL ; (DE) = ZW2 = 2*PI/N LD HL,SINUS ; (HL) = SINUS Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = SINUS := 2*PI/N LD HL,COSIN ; (HL) = COSIN Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = COSIN := 2*PI/N Maschinencode über HIMEM: CALLCALL FLOCOS ; (HL) = COSIN := COS(2*PI/N) LD HL,SINUS ; (HL) = SINUS = 2*PI/N Maschinencode über HIMEM: CALLCALL FLOSIN ; (HL) = SINUS := SIN(2*PI/N) ; ; SCHLEIFE UEBER N STRECKENZUEGE ; LOOP: LD HL,0 LD DE,0 Maschinencode über HIMEM: CALLCALL PLOTR ; Ersten Punkt der Linie doppelt setzen falls XOR-Modus ; LD DE,XPOS LD HL,ZW1 Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = ZW1 := XA ( = ALTES Die verwendeten Abkürzungen bedeuten: x:X ) LD DE,COSIN ; (DE) = COS Maschinencode über HIMEM: CALLCALL FLOMUL ; (HL) = ZW1 := XA*COS LD HL,ZW2 LD DE,YPOS Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = ZW2 := YA ( = ALTES Y ) LD DE,SINUS ; (DE) = SIN Maschinencode über HIMEM: CALLCALL FLOMUL ; (HL) = ZW2 := YA*SIN EX DE,HL ; (DE) = ZW2 := YA*SIN LD HL,ZW1 ; (HL) = ZW1 = XA*COS Maschinencode über HIMEM: CALLCALL FLOSUB ; (HL) = ZW1 := XA*COS-YA*SIN = XN ; LD DE,YPOS LD HL,ZW2 Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = ZW2 := YA LD DE,COSIN ; (DE) = COS Maschinencode über HIMEM: CALLCALL FLOMUL ; (HL) = ZW2 := YA*COS EX DE,HL ; (DE) = ZW2 = YA*COS LD HL,YPOS ; (HL) = YPOS Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = YPOS :=YA*COS LD HL,ZW2 LD DE,XPOS Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = ZW2 := XA LD DE,SINUS ; (DE) = SIN Maschinencode über HIMEM: CALLCALL FLOMUL ; (HL) = ZW2 := XA*SIN EX DE,HL ; (DE) = ZW2 := XA*SIN LD HL,YPOS ; (HL) = YPOS Maschinencode über HIMEM: CALLCALL FLOADD ; (HL) = YPOS := YA*COS+XA*SIN = YN ; Maschinencode über HIMEM: CALLCALL FLOINT ; HL := YN & Operationen: BD5B / 349A / 349A: FLO SUBA:=VZ JR NC,OVFLOW ; YN zu groß ? Datenbreite: Bits
Port B - Input: &F5xx: Bit 0:
Port B - Input: &F5xx: Bit 4:
Port B - Input: &F5xx: Bit 5:
Port B - Input: &F5xx: Bit 6:
Port B - Input: &F5xx: Bit 7:
Port C - Output: &F6xx: Bit 4:
Port C - Output: &F6xx: Bit 5:
BIT
7,H JR NZ,OVFLOW RLA Maschinencode über HIMEM: CALLCALL C,INTVZW ; NEG. => HL := -HL PUSH HL ; YN Retten LD DE,ZW1 ; (DE) = ZW1 = XN LD HL,XPOS ; (HL) = XPOS Maschinencode über HIMEM: CALLCALL FLOMOV ; (HL) = XPOS := XN ; Maschinencode über HIMEM: CALLCALL FLOINT ; HL := XN POP DE ; DE := YN JR NC,OVFLOW ; XN zu groß ? Datenbreite: Bits
Port B - Input: &F5xx: Bit 0:
Port B - Input: &F5xx: Bit 4:
Port B - Input: &F5xx: Bit 5:
Port B - Input: &F5xx: Bit 6:
Port B - Input: &F5xx: Bit 7:
Port C - Output: &F6xx: Bit 4:
Port C - Output: &F6xx: Bit 5:
BIT
7,H JR NZ,OVFLOW RLA Maschinencode über HIMEM: CALLCALL C,INTVZW ; Neg. => HL := -HL EX DE,HL Maschinencode über HIMEM: CALLCALL DRAW ; Zeichne Linie ; POP BC ; C=Schleifenvariable N DEC C PUSH BC JP NZ,LOOP ; Noch eine Linie ; OVFLOW: POP BC ; Abbruch bei Überschreitung des Integer-Formats RET

Der Editor

Die letzte, sehr nützliche Abteilung im Betriebssystem, die unverständlicherweise auch nur einen Vektor im Basic-Jumpblock zugestanden bekam, ist der Zeileneditor.

Hiermit können Text-Eingaben mit einer Hoechstlänge von 255 Zeichen neu eingegeben oder auch verändert, editiert werden. Jeder, der Eingaben in Assembler-Programmen entgegennehmen will, braucht sich die Routinen hierfür nicht selbst zu programmieren, sondern kann den Zeileneditor aufrufen. Dabei muss er im HL-Register einen Zeiger auf den Textpuffer übergeben, der immer 256 Datentypen: Bytes
Datenbreite: Bytes
Bytes
lang sein muss. Der zu editierende Text muss dabei immer mit einem Nullbyte abgeschlossen sein.

Im AnhangAnhang ist Die Basic-Vektoren: Der Editorder Editor genau beschrieben. Deshalb folgt an dieser Stelle nur noch ein Anwendungsbeispiel:

Eine Die Fließkomma-Routinen: FunktionenFunktion, die man in Einleitung: BASIC
Anhang: Basic
Basic
vermisst, ist ein Befehl, mit dem man Datentypen: StringsStrings nicht nur komplett neu eingeben, sondern auch bestehende Datentypen: StringsStrings editieren kann. Dafür ist dieses Beispiel gedacht.

Der dem Aufruf als Basic und Maschinencode: ParameterParameter übergebene Datentypen: StringsString wird zunächst in den 256-Byte-Puffer kopiert und dann der Zeileneditor aufgerufen. Dieser funktioniert jetzt ganz normal, wie auch bei LINE INPUT. Jenachdem, ob der Anwender die Eingabe mit [ENTER] oder [ESC] abschließt, ist beim Rücksprung das CY-Flag gesetzt (o.k.) oder auch nicht.

Wenn man die Eingabe mit [ESC] abbricht, wird der String-Descriptor nicht auf den neuen Datentypen: StringsString eingestellt, der Datentypen: StringsString bleibt also unverändert. Wird die Eingabe aber mit [ENTER] abgeschlossen, so wird der Descriptor auf den Datentypen: StringsString im Puffer eingestellt. Dieser muss danach noch in den Memory Pool transferiert werden. Das folgende Beispiel zeigt, wie ein Aufruf von Einleitung: BASIC
Anhang: Basic
Basic
aus aussehen müsste:

 100 KEY DEF 66,0,140                     ' Break-Taste so umdefinieren, dass
 110 KEY 140,CHR$(252)+CHR$(&EF)+CHR$(27) ' ein Break erkennbar wird.
 120 Maschinencode über HIMEM: CALLCALL &KEY MANAGER: BB48: KM DISARM BREAKBB48                           ' ON BREAK CONT
 ... ...
 ... ...
1000 Operationen: BD5B / 349A / 349A:  FLO SUBa$="default.dat"                     ' Vorgabewert in Operationen: BD5B / 349A / 349A:  FLO SUBa$
1010 PRINT "Welche Datei laden? >>> ";    ' Dialogtext
1020 |Editor: BD3A / BD5B / BD5E:  EDITEDIT,@Operationen: BD5B / 349A / 349A:  FLO SUBa$                            ' Operationen: BD5B / 349A / 349A:  FLO SUBa$ editieren
1025 IF INKEY$=CHR$(27) THEN 1010         ' Breaks abfangen
1030 Operationen: BD5B / 349A / 349A:  FLO SUBa$=Operationen: BD5B / 349A / 349A:  FLO SUBa$+""                             ' Operationen: BD5B / 349A / 349A:  FLO SUBa$ in den Memory Pool bringen
.... ...
 
 
; String-Editor   Erklärung zu den Anschlüssen: Vcc und Vss
Erklärung zu den Anschluss-Bezeichnungen: Vcc und Vss
vs
. 10.6.86 (c) by G.Woigk ; ------------- ----------- -------------- ; ; AUFRUF mit: |Editor: BD3A / BD5B / BD5E: EDITEDIT,@Operationen: BD5B / 349A / 349A: FLO SUBA$ ; ----------- --------- ; ORG 40000 ; Die Basic-Vektoren: Editor
Die Basic-Vektoren: Editor
EDITOR
: EQU #BD3A ; CPC 464: &KEY MANAGER: BD3A: KM SET LOCKS
Editor: BD3A / BD5B / BD5E: EDIT
BD3A
/ 664: &KERNEL: BD5B: KL RAM SELECT
Editor: BD3A / BD5B / BD5E: EDIT
Operationen: BD5B / 349A / 349A: FLO SUB
BD5B
/ 6128: &Editor: BD3A / BD5B / BD5E: EDIT
Operationen: BD5E / BD7F / BD82: FLO SUB*
Sonstiges: BD3D / BD5E / BD61: FLO MOVE
BD5E
; ; Basic-Vektor zum Zeileneditor ; ; ********************************* ; Hier Relozierung und ; Einbindung als Maschinencode über HIMEM: RSXRSX einfügen. ; ********************************* ; Editor: BD3A / BD5B / BD5E: EDITEDIT: DEC Operationen: BD5B / 349A / 349A: FLO SUBA ; Erklärung der Anschlussbelegung: TestTeste auf einen Basic und Maschinencode: ParameterParameter RET NZ ; Parameter-Error ; ; STRING-LAENGE UND -ADRESSE BESTIMMEN ; LD L,(IX+0) ; Adresse des String-Descriptors LD H,(IX+1) ; nach HL holen PUSH HL ; und auf den Stack retten. ; LD C,(HL) LD LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL
LOW KERNEL JUMPBLOCK: 001B: LOW KL FAR PCHL
LOW KERNEL JUMPBLOCK: 003B: LOW EXT INTERRUPT
B
,0 ; BC := Länge des Datentypen: StringsString INC HL LD LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
,(HL) INC HL LD D,(HL) ; DE := Adresse des Datentypen: StringsString ; ; Datentypen: StringsSTRING IN DEN PUFFER KOPIEREN ; EX DE,HL ; HL = LDIR-Quelle := Adresse des Datentypen: StringsStrings LD DE,BUFFER ; DE = LDIR-Ziel := Adresse des 256-Byte-Buffer XOR Operationen: BD5B / 349A / 349A: FLO SUBA CP C ; Länge = 0 ? Dann kein LDIR !! JR Z,P2 LDIR ; Datentypen: StringsString in den Puffer kopieren. ; ; EDITIEREN DES Datentypen: StringsSTRINGS ; P2: LD (DE),Operationen: BD5B / 349A / 349A: FLO SUBA ; String-Abschlussmarke setzen: Datentypen: Bytes
Datenbreite: Bytes
Byte
0, LD HL,BUFFER ; Zeiger auf den Puffer nach HL laden Maschinencode über HIMEM: CALLCALL Die Basic-Vektoren: Editor
Die Basic-Vektoren: Editor
EDITOR
; und den Zeileneditor aufrufen. POP HL RET NC ; Falls BREAK: Datentypen: StringsString nicht ändern. PUSH HL ; ; NEUE STRINGLAENGE BERECHNEN ; LD HL,BUFFER ; HL zeigt auf den neuen $ XOR Operationen: BD5B / 349A / 349A: FLO SUBA LD BC,101H CPIR ; Suche die String-Endmarke. SUB C ; Operationen: BD5B / 349A / 349A: FLO SUBA := String-Länge ; ; STRING-DESCRIPTOR AUF DEN NEUEN STAND BRINGEN ; P3: POP HL ; HL := Adresse des String-Descriptors LD DE,BUFFER LD (HL),Operationen: BD5B / 349A / 349A: FLO SUBA ; String-Länge in den Descriptor eintragen INC HL LD (HL),LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION
LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTION
E
INC HL LD (HL),D ; und die String-Adresse (= Puffer-Adresse). RET ; BUFFER: DEFS 256

Valid HTML   Valid CSS