|
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 PACKMachine 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-VektorenDie 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.
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-Vektorendie 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: BasicBasic 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-Vektorendie 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 INSTRUCTIONE,(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: BytesBytes 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 Z80CPU 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 Vssvs. 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
;
; -------------------------------
;
Die Grafik-VDU: CircleCIRCLE: 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 INSTRUCTIONE,(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
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: BytesBytes 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: BasicBasic 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: BasicBasic 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 Vssvs. 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: EditorEDITOR: EQU #BD3A ; CPC 464: &KEY MANAGER: BD3A: KM SET LOCKS Editor: BD3A / BD5B / BD5E: EDITBD3A / 664: &KERNEL: BD5B: KL RAM SELECT Editor: BD3A / BD5B / BD5E: EDIT Operationen: BD5B / 349A / 349A: FLO SUBBD5B / 6128: &Editor: BD3A / BD5B / BD5E: EDIT Operationen: BD5E / BD7F / BD82: FLO SUB* Sonstiges: BD3D / BD5E / BD61: FLO MOVEBD5E
; ; 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 INTERRUPTB,0 ; BC := Länge des Datentypen: StringsString
INC HL
LD LOW KERNEL JUMPBLOCK: 000E: LOW PCBC INSTRUCTION LOW KERNEL JUMPBLOCK: 001E: LOW PCHL INSTRUCTIONE,(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: BytesByte 0,
LD HL,BUFFER ; Zeiger auf den Puffer nach HL laden
Maschinencode über HIMEM: CALLCALL Die Basic-Vektoren: Editor Die Basic-Vektoren: EditorEDITOR ; 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 INSTRUCTIONE
INC HL
LD (HL),D ; und die String-Adresse (= Puffer-Adresse).
RET
;
BUFFER: DEFS 256
| |