CIO-AUFRUF
ÜBER BASIC
Die
meisten CIO-Funktionen (OPEN, CLOSE usw.) sind durch BASIC-Befehle aufrufbar. Ein
Teil CIO-Funktionen allerdings läßt sich vom BASIC-Interpreter nicht ansprechen.
So besitzt der Interpreter nicht die Fähigkeit, I/0 mit mehr als einem Byte
durchzuführen (GETCHARACTER und PUTCHARACTER), außer als Record.
Die
Möglichkeit einen ganzen Puffer von Zeichen auf einmal ein- und auszugeben ist
sehr elegant. So könnte eine Assembler-Routine z.B. direkt von einer Disk-Datei
in den Speicher geladen werden. Bei einem BASIC-Programm wird die Assembler-Routine
normalerweise über einen String eingelesen und dann mit der USR(ADR($))-Funktion
aufgerufen. Da die Adresse eines BASIC-Strings sich während der Programmänderung
verschieben kann, muß die Routine unabhängig von Speicherstellen sein.
Dieses Bedeutet, daß Speicherzugriffe innerhalb des Strings nicht arbeiten.
Die
Unterroutine in Abbildung 8.6 umgeht die Benutzung von Strings. So muß die
Assembler-Routine nicht unbedingt unabhängig von Speicherstellen sein. Die Kontrolldaten
werden in einem IOCB gesetzt, d.h. das Assembler-Programm wird direkt in die Speicherstellen
gelesen, wo es ursprünglich assembliert wurde. Die BASIC-Unterroutine in Abbildung
8.6 kann auch dazu benutzt werden, Daten direkt vom Speicher auszugeben, wobei der
Benutzer die Speicherstelle und die Pufferlänge festlegt.
DIE
GERÄTE-HANDLER
Die
Geräte-Handler können in zwei Gruppen aufgeteilt werden: die residenten
und die nicht-residenten Handler. Die residenten Handler befinden sich im OS-ROM
und können durch die CIO aufgerufen werden, sofern sie einen Eintrag in HATABS
besitzen. Die residenten Handler sind:
(E:) Bildschirm-Editor
(S:) Screen (Bildschirm)
(K:) Keyboard (Tastatur)
(P:) Printer (Drucker)
(C:) Cassettenstation
30
REM Dieses Programm laedt PAGE 6 von der Datei "D:TEST"
100
DIM FILE$(20),CIO$(7)
101
CIO$="hhh*LVd": REM "*" & "D" invers eingeben
105
REM CIO$ = PLA,PLA,PLA,TAX,JMP $E456 (=CIOV)
110
FILE$="D:TEST":REM Dateiname
120
CMD=7:STADR=1536:GOSUB 30000
130
IF ERROR<>1 THEN ? "FEHLER -";ERROR;"in Zeile";
140
? PEEK(186)+PEEK(187)*256,PEEK(195)
200
END
300
REM - CIOVORBEREITUNG
310
REM
30000
REM Routine von M. Ekberg fuer ATARI 3.9.1980
30001
REM
30002
REM Diese Routine laedt oder sichert Dateien von
30003
REM BASIC, indem ein IOCB gesetzt und CIO direkt
30004
REM aufgerufen wird.
30005
REM
30006
REM Eingang CMD=7 bedeutet: laden
30007
REM - CMD=11
bedeutet: sichern
30008
REM - STADR=
Die Adresse zum Laden o. Sichern
30009
REM - BYTES=
Die Anzahl der Bytes
30010
REM - IOCB=
Der zu benutzende IOCB
30011
REM - FILE$=
Ausgabe-Dateiname
30012
REM
30013
REM Abschluss mit ERROR=1 bedeutet erfolgreiche
30014
REM Ausfuehrung
30015
REM ERROR<>l bedeutet: Fehlerzustand
30016
REM
30017
REM
30018
REM *** IOCB-FESTLEGUNGEN ***
30019
REM
30024
IOCBX=IOCB*16:ICCOM=834+IOCBX:ICSTA=835+IOCBX
30026
ICBAL=836+IOCBX:ICBAH=837+IOCBX
30028
ICBLL=840+IOCBX:ICBLH=841+IOCBX
30030
AUX1=4:IF CMD=11 THEN AUX1=8
30035
TRAP 30900:OPEN #IOCB,AUX1,0,FILE$:IOCBX=IOCB*16
30040
TEMP=STADR:GOSUB 30500
30090
POKE ICBAL,LOW:POKE ICBAH,HIGH
30100
TEMP=BYTES:GOSUB 30500
30130
POKE ICBLL,LOW:POKE ICBLH,HIGH
30140
POKE ICCOM,CMD:ERROR=USR(ADR(CIO$),IOBX)
30150
ERROR=PEEK(ICSTA):RETURN
30200
REM
30300
REM *** Diese Routine errechnet hoeher und
30305
REM *** niederwertiges Byte einer 16-Bit-Zahl
30400
REM
30500
HIGH=INT(TEMP/256):LOW=INT(TEMP-HIGH*256):RETURN
30550
REM
30600
REM *** Hierher wird bei Fehler gesprungen
30900
ERROR=PEEK(195)
30920
CLOSE #IOCB:RETURN
Abbildung
8.6
Direkter
CIO-Aufruf über BASIC
Die
nicht-residenten Handler befinden sich nicht im OS-ROM. Sie können dem OS beim
Einschalten oder SYSTEM-RESET hinzugefügt werden. Dieses kann aber auch während
der Programmausführung geschehen (siehe Abbildung 8.5).
Die
Geräte-Handler benutzen I/O-Kontrolldaten, die über die CIO zum ZIOCB gebracht
werden. Die Daten im ZIOCB werden beim Ausführen von I/O-Funktionen, wie z.B.
OPEN, CLOSE, PUT oder SET verwendet. Nicht alle Geräte-Handler sprechen auf
alle I/O-Kommandos an (das PUT-Kommando zur Tastatur würde eine Fehler-146 (Funktion
nicht implemetiert) -Meldung erzeugen). Abschnitt 5 des OS-Benutzer-Manuals enthält
eine Liste der von den einzelnen Handlern ausführbaren I/O-Funktionen.
SERIELLE
I/O-SYSTEM-ROUTINE - SIO
SIO
und die Geräte-Handler
Die
SIO bearbeitet die Kommunikation zwischen den seriellen Geräte-Handler im Computer
und den Devices des seriellen Busses. Dieses geschieht über den Device-Kontrollblock
(DCB). Die SIO benutzt die I/0-Kontrolldaten im DCB zum Senden und Empfangen von
Daten über den seriellen Bus. Die Aufrufsequenz sieht wie folgt aus:
; der DCB wurde zur Durchführung der
; Operation erstellt.
JSR SIOV ; Systemvektor zur SIO
BMI ERROR ; gesetztes N-BIT zeigt Fehler
bei der
; Ausführung der I/O-Operation
Der
DCB enthält Kontrollinformationen für die SIO und muß vor deren Aufruf
aufgestellt werden. Abbildung 8.3 zeigt die Inhalte des DCBs für einige I/O-Operationen.
Es
ist erforderlich, die Struktur des DCBs zu verstehen, um Kommandos an die SIO senden
zu können. Abbildung 8.7 zeigt eine einfache Assembler-Routine, um eine Zeile
(durch Erstellen eines DCBs und Aufrufen der SIO) über den Drucker ausgeben
zu lassen.
0000
05
*= $3000 Beliebiger Startpunkt
10 ; Diese Routine druckt eine Zeile auf dem
15 ; Drucker, indem die SIO aufgerufen wird.
E459
20 SIOV
= $E459 SIO-Vektor
009B
30 CR
= $9B EOL
0040
40 PRNTID =
$40 Drucker-ID f.ser.
Bus
004E
50 MODE
= $4E Normaler
Modus
001C
60 PTIMOT =
$001C Timeout-Speicherstelle
0300
70 DDEVIC =
$300 Geraete-ID f.ser. Bus
0301
80 DUNIT
= $301 Nummer d.ser.
Einheit
0302
90 DCOMND =
$302 SIO-Kommando
0303
0100 DSTATS = $303
SIO-Datenrichtung
0304
0110 DBUFLO = $304
Niederw.Adr.d.Puffers
0305
0120 DBUFHI = $305
Hoeherw.Adr.d.Puffers
0306
0130 DTIMLO = $306
SIO-Timeout
0307
0140 DTIMHI = $307
0308
0150 DBYTLO = $308
Pufferlaenge
0309
0160 DBYTHI = $309
030A
0170 DAUX1 =
$30A Hilfsbyte:Druckermodus
030B
0180 DAUX2 =
$30B Hilfsbyte:nicht
benutzt
0190 ;
3000 42 45 49
0200 MESS .BYTE
"BEISPIEL12",CR
3001 53 50 49
3005 45 4C 31
3009 32 9B
0210 ;
300B A9 40
0220 LDA #PRNTID
Setzen des Bus IDs
300D 8D 00 03
0230 STA DDEVIC
3010 A9 01
0240 LDA #1
Setzen d.Einheits-Nr.
3012 8D 01 03
0250 STA DUNIT
3015 A9 4E
0260 LDA #MODE
Norm. Drucker-Modus
3017 8D 0A 03
0270 STA DAUX1
301A A9 01
0275 LDA #1
301C 8D 0B 03
0280 STA DAUX2
Nichtbenutzt
301F 8D 07 03
0290 STA DTIMHI
Timeout nach 256 Sek.
3022 A5 1C
0300 LDA PTIMOT
Setzen des SIO-Time-
3024 8D 06 03
0310 STA DTIMLO
outs fuer Drucker
3027 A9 00
0320 LDA #MESS&255
3029 8D 04 03
0330 STA DBUFLO
MESS als Puffer
302C A9 30
0340 LDA #MESS/256
setzen
302E 8D 05 03
0350 STA DBUFHI
3031 A9 80
0360 LDA #$80
Setzen der SIO-Daten-
3033 8D 03 03
0370 STA DSTATS
richtung f. Peripherie
3036 A9 57
0380 LDA #¥W
SIO-Kommando schreiben
3038 8D 02 03
0390 STA DCOMND
303B 20 59 E4
0410 JSR SIOV
SIO aufrufen
303E 30 01
0420 BMI ERROR
3040 00
0420 GOOD BRK
3041 00
0440 ERROR BRK
Abbildung
8.7.
Aufrufen
der SIO zum Drucken einer Zeile auf dem Drucker