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