SIO-INTERRUPTS

 

Die SIO benutzt drei IRQ-Interrupts,um über den seriellen Bus mit den Geräten zu kommunizieren. Die Interruts sind:

 

IRQ       Speicherstelle,      Funktion

          Länge

 

VSERIR    ($020A,2)            Serielle Ausgabe abgeschlossen

VSEROR    ($020C,2)            Serielle Ausgabe benötigt

VSEROC    ($020E,2)            ‹bertragung beendet

 

 

Die gesamte Programmausführung wird gestoppt, wenn die SIO den

seriellen BUS für die Datenübertragung benutzt. Für diese Ausgabe übergibt die SIO ein Byte an das "serielle Ausgabe-Schieberegister" im POKEY-Chip (SEROUT), welches dann auf den seriellen Bus gesendet wird. Danach wird in eine Warteschleife gesprungen, bis ein IRQ (VSEROR) vom POKEY-Chip empfangen wird und der SIO mitteilt, daß SEROUT für ein anderes Byte frei ist. Der IRQ bewirkt einen Sprung zur SIO-Routine für das Laden von SEROUT mit einem Byte. Diese Schleife wird solange ausgeführt, bis alle in der DCB-Länge festgelegten Bytes gesendet wurden. VSEROR ist ein IRQ, der anzeigt, daß die ‹bertragung von Bytes über den Bus abgeschlossen ist.

 

Die SIO-Operation für die Eingabe läuft ähnlich ab. Der POKEY-Chip informiert die SIO, daß ein Byte im seriellen Eingabe-Schieberegister empfangen wurde (SERIN), indem ein IRQ (VSERIN) erzeugt wird. Die SIO speichert das Byte in einem Puffer und geht daraufhin in eine Endlosschleife, die durch den nächsten IRQ d.h. das nächste Byte unterbrochen wird.

 

Wie man aus den oberen Absätzen ersehen kann, verliert die SIO einige Zeit, während auf das Signal vom POKEY-Chip gewartet wird. Da die Vektoren für die 3 SIO-IRQ-Service-Routinen RAM-Vektoren sind, können sie auch durch andere Handler benutzt werden, um die I/O-Operationen des Systems zu verbessern.

 

Dieses ist genau der Punkt, der dem 850-Modul ermöglicht, einen eigenständigen I/O durchzuführen. Der Handler des 850-Moduls überschreibt die SIO-IRQ-Vektoren mit den moduleigenen IRQ-Routinen. Dieses geschieht beim eigenständigen I/O, wodurch der 850-Modul-Handler dann Kommandos über den Bus senden kann. Der Modul-Handler gestattet dann, daß ein Programm weiterläuft, während das 850-Modul ein I/O-Kommando ausführt.

 

 

INTERRUPTS

Einführung

 

Im vorangegangenen Abschnitt wurde gezeigt, wie die SIO Interrupts zum Koordinieren von Datenübertragungen über den seriellen Bus benutzt. Der Computer besitzt außerdem noch andere Interrupt-Arten, die ein Programm um leistungsstarke Möglichkeiten erweitern können. Es gibt 2 verschiedene Interrupt-Typen: den maskierbaren Interrupt (IRQ) und den nicht-maskierbaren Interrupt (NMI). Die Interrupts das ATARI ¥TM¥ Personal Computers sind:

 

Name (Vektor)             Typ  Funktion                  Benutzt

                                                         von**

DISPLAY LIEST

     (VDLIST)             NMI  Graphik-Timing            B

SYSTEM RESET

     (keinen)             NMI  System-Initials.          C

VERTIKAL BLANK

     (VVBLKI,VVBLKD)      NMI  Graphik-Display           C,B

SERIELLE AUSGABE BEENDET

     (VSERIN)             IRQ  Ser. Eingabe              C

SERIELLE EINGABE ABGESCHLOSSEN

     (VSEROR)             IRQ  Ser. Eingabe              C

SERIELLE AUSGABE ABGESCHLOSSEN

     (VSEROC)             IRQ  Ser. Ausgabe              C

POKEY-TIMER 1

     (VTIMR1)             IRQ  Hardware-Timer            B

POKEY-TIMER 2

     (VTIMR2)             IRQ  Hardware-Timer            B

*POKEY-TIMER 4

     (VTIMR4)             IRQ  Hardware-Timer            B

TASTATUR

     (VKEYBD)             IRQ  Tastendruck               C

BREAK-TASTE

     (keinen)             IRQ  (BREAK)-Tastendruck       C

SERIELLER BUS ABLAUF

     (VPRCED)             IRQ  Geräte-Ablauf             N

SERIELLER BUS INTERRUPT

     (VINTER)             IRQ  Geräte-Interrupt          N

* Dieser IRQ wird im augenblicklichen im Computer vorhandenen OS nicht vektorisiert.

 

** B=Benutzer; C=Computer; N=Nicht benutzt

 

 

Ist der Leser nicht mit Interrupts vertraut, dann sei er auf Abschnitt 6 des OS-Manuals verwiesen, der Information zu diesem Thema enthält. Das Arbeiten mit Interrupts kann kompliziert sein. Wird z.B. der Tastatur-IRQ-Interrupt ausgeschaltet, dann ignoriert der Computer sämtliche Tastendrücke mit Ausnahme der (BREAK)-Taste. Obwohl dieses manchmal von Nutzen sein kann, macht es die Fehlersuche in einem Programm ein wenig schwierig.

 

 

DER IRQ-INTERRUPT-HANDLER

 

Das OS besitzt einen IRQ-Interrupt-Handler, der die verschiedenen IRQs bearbeitet. Dieser Handler hat RAM-Vektoren für alle IRQs, ausgenommen den (BREAK)-Tasten-IRQ. Die IRQ-Vektoren werden während des Einschaltens bzw. beim SYSTEM-RESET auf ihre Werte gesetzt. Die Speicherstellen der IRQ-RAM-Vektoren werden in Abbildung 8.9b gezeigt.

 

Die IRQ-Vektoren sind:

 

 

VIMIRQ Direkter IRQ-Vaktor. Alle IRQs laufen über diese Speicherstelle. VIMIRQ zeigt normalerweise auf den IRQ-Handler. Dem Benutzer ist es aber möglich, diesen Vektor zu ändern, um eigene Routinen für die Interrupts abarbeiten zu lassen.

 

VSEROR IRQ-Vektor POKEYs zur Beendigung der seriellen Ausgabe (siehe Abschnitt 8.2).

 

VSERIN IRQ-Vaktor POKEYs zur Beendigung der seriellen Ausgabe (siehe Abschnitt 8.2).

 

VSEROC IRG-Vaktor POCKEYs zum Abschluss der seriellen Ausgabe (siehe Abschnitt 8.2).

 

VTIMR1 Timer 1-Vektor POKEYs (siehe Abschnitt 8.7 für  Information über die POKEY-Timer).

 

VTIMR2 Timer 2-Vektor POKEYs.

 

VTIMR4 Timer 4-Vektor POKEYs.

 

VKEYBD Tastatur-IRQ-Vektor. Das Drücken einer Taste, ausgenommen der (BREAK)-Taste, verursacht diesen IRQ. Der VKEYBD-Vektor kann zum Vorarbeiten des Tastencodes benutzt werden, bevor er durch das OS in ATASCII-Code umgewandelt wird. Dieser Vektor zeigt normalerweise auf die Tastatur-Routine des OS.

 

VPRECD IRQ-Vektor für den Peripherie-Ablauf. Diese Signalleitung ist über den seriellen Bus für Peripherie-Geräte zugänglich. Dieser IRQ wird zur Zeit noch nicht benutzt und zeigt daher normalerweise auf einen RTI-Befehl.

 

VINTER IRQ-Vektor für Peripherie-Interrupt. Diese Signalleitung ist über den seriellen Bus für den Computer zugänglich. VINTER zeigt normalerweise auf ein RTI-Kommando.

 

VBREAK IRQ-Vektor für 6502-BRK-Anweisungen. Immer, wenn ein $00 Opcode (softwaremäßige BREAK-Anweisung) ausgeführt wird, taucht dieser Interrupt auf. Dieser Vektor kann zum Setzen von Unterbrechungs-Punkten innerhalb eines Maschinensprache-Debuggers benutzt werden. VBREAK zeigt normalerweise auf einen RTI-Befehl.

 

 

Die IRQs werden gemeinsam durch die 6502-Instruktion CLI bzw. SEI ein- oder ausgeschaltet. Weiterhin haben die IRQS eigene Ein/Ausschalt-Bits. Ein Abschnitt des Hardware-Manuals führt die IRQs sowie die Ein/Ausschalt-Bits auf.

 

Das Register IRQEN enthält die meisten der E/A-Bits für die IRGs und ist ein Nur-Schreib-Register. Das OS besitzt eine für den Benutzer zugängliche Schattenadresse. Diese Adresse ist POKMSK und wird während des Vertical-Blanks geschrieben.

 

 

BENUTZEN DER IRQS

 

Viele Programme erfordern eine "gesicherte" Tastatur. Der Benutzer kann also jede Tasten-Kombination drücken, wobei nur die zulässigen akzeptiert und die anderen ignoriert werden. Der Benutzer kann eine Reihe von IRQs verwenden, um diese Sicherung zu erreichen. Das Beispiel in Abbildung 8.8 benutzt den VKEYBD-IRQ-Vektor, um die Kontroll-Taste (CTRL) abzuschalten, d.h. unwirksam zu machen. Die Routine maskiert außerdem die (BREAK)-Taste, indem der VIMIRQ-Vektor geändert und der (BREAK)-Tasten-Interrupt ignoriert wird.

 

 

DER NMI-HANDLER

 

Das OS besitzt einen NMI-Handler zum Bearbeiten der nicht-maskierbaren Interrupts. Im Gegensatz zu den IRQs können die NMIs nicht "maskiert" werden, d.h. sie können nicht über den 6502 ausgeschaltet werden. Alle NMIs ausgenommen des SYSTEM-RESET-Interrupts, können über den ANTIC-Prozessor ausgeschaltet werden.

 

Zwei NMIs, der Display-List-Interrupt und der Vertical-Blank-Interrupt VBLANK) , besitzen RAM-Vektoren, die vom Programmierer benutzt werden können. Die Vektoren sind:

 

 

     Name                      Vektor

     SYSTEM-RESET              keinen

     DISPLAY-LIST-INTERRUPT    VDSLST($0200)

     VERTICAL-BLANK:

          IMMEDIATE            VVBLKI($0222)

          DEFERRED             VVBLKD($0224)

 

 

Der SYSTEM-RESET-NMI besitzt keinen RAM-Vektor. Ein SYSTEM-RESET resultiert immer in einem Sprung zur Warmstart-Routine des Monitors (siehe Abschnitt 8.5). Der DLI- und der VBLANK-Interrupt werden in Kapitel 5 bzw. in Anhang I besprochen.

 

0000           10 POKMSK = $0010

D209           20 KBCODE = $D209

0208           30 VKEYBD = $0208

D20E           40 IRQEN  = $D20E

D20E           50 IRQST  = $D20E

0216           60 VMIRQ  = $0216

0000           70       *= $0600

0600 78        80 START  SEI            IRQs abschalten

0601 AD 16 02 90        LDA VMIRG      IRQ-Vektor durch

0604 8D 4D 06  0100      STA NBRK+1     einen vom Benutzer

0607 AD 17 02  0110      LDA VMIRQ+1    ersetzen. Alle IRQs

060A 8D 4E 06  0120      STA NBRK+2     gehen dann zu NBRK.

060D A9 45     0130      LDA #IRQ&255

060F 8D 16 02  0140      STA VIMRQ

0612 A9 06     0150      LDA #IRQ/256

0614 8D 17 02  0160      STA VIMRQ+l

0617 58        0170      CLI            IRQs einschalten

0618 AD 08 02  0180      LDA VKEYBD     Tastatur-IRQ zeigt

061C 8D 43 06  0210      STA JUMP+1     nach REP.

061F AD 09 02  0220      LDA VKEYBD+1

0622 8D 44 06  0230      STA JUMP+2

0625 A9 39     0240      LDA #REP&255   Tastatur-IRQ-Vektor

0627 8D 08 02  0250      STA VKEYBD     niederwertiges Byte

062A A9 06     0260      LDA #REP/256   des Vektors

062C 8D 09 02  0270      STA VKEYBD+1

062F 60        0280      RTS

               0290     *= $0639

0639 AD 09 02  0300 REP  LDA KBCODE     Hierher laufen alle

063C 29 80     0310      AND #$80       Tastatur-IRQs. CTRL-

063E F0 02     0320      BEQ JUMP       Taste sedrueckt? Nein,

0640 68        0330      PLA            dann springe.. andern-

0641 40        0340      RTI            falls CTRL ignorieren.

0642 4C 42 06  0350 JUMP JMP JUMP       Dieses ruft den alten

0645 48        0360 IRQ  PHA            Tasten-IRQ.

0646 AD 0E D2  0380      LDA IRQST      <BREAK>?

0649 10 04     0390      BPL BREAK      Ja-, BREAK-IRQ

064B 68        0400      PLA            Andernfalls alter IRG

064C 4C 4C 06  0410 NBRK JMP NBRK       Alten IRQ-Vektor auf-

064F A9 7F     0430 BREAK LDA #$7F       rufen.

0651 8D 0E D2  0440      STA IRQST      <BREAK> nicht zeigen

0654 A5 10     0450      LDA POKMSK

0656 8D 0E D2  0460      STA IRQEN

0659 68        0462      PLA

065A 40        0464      RTI            Ruecksprung, Wie ohne

065B           0470     *= $02E2         BREAK.

02E2 00 06     0480      .WORD START

 

 

Abbildung 8.8:

"Sicherung" der Tastatur

 

 

DIE SYSTEM-VEKTOREN

 

Das OS besitzt zwei Arten von Vektoren: ROM- und RAM-Vektoren. ROM-Vektoren sind Speicherstellen, die JMP-Befehle enthalten, welche auf System-Routinen zeigen. Die RAM-Vektoren enthalten 2-Byte-Adressen zu System-Routinen, zu Handler-Einsprung- zeigern (siehe CIO-Abschnitt 8.2) oder zu Initialisierungs-Routinen.

 

Sowohl die RAM- und ROM-Vektoren werden sich in neuen Versionen des Operating-Systems nicht ändern. Dieses gilt aber nicht für ihre Inhalte, d.h. ein Programm, das auf dem jetzigen und allen zukünftigen Systemen laufen soll, muß auf die Vektoren, anstatt auf die in ihnen befindlichen Adressen zeigen. Die Vektoren, ihre Inhalte und eine kurze Beschreibung ihrer Funktion findet sich in den Abbildungen 8.9a und 8.9b.

 

 

ROM-Vektoren

 

Name      Speicher- Funktion

          stelle

DISKIV    $E450     Initialisierung des Disk-Handlers

DSKINV    $E453     Vektor für Disketten-Handler

CIOV      $E456     Vektor für zentrale I/0-Routine

SIOV      $E459     Vektor für die serielle I/O-Routine

SETVBV    $E45C     Routinen-Vektor z.Setzen d. System-Timer

SYSVBV    $E45F     Berechnungen d.Systems f.d. Vert.Blank

XITVBV    $E462     Berechnungen z.Ausgang a.d. Vert.Blank

SIOINV    $E465     Initialisierung des seriellen I/Os.

SENDEV    $E468     Einschaltroutine z.Senden ü.d.ser.Bus.

INTINV    $E46B     Interrupt-Handler-Routine.

CIOINV    $E46E     Initialisierung des zentralen I/0s.

BLKBDV    $E471     Blackboard-Modus (MEMOPAD)-Vektor.

WARMSV    $E474     Warmstart-Einsprungpunkt (SYSTEM-RESET).

COLDSV    $E477     Kaltstart-Einsprungpunkt (Einschalten).

RBLOKV    $E47A     Routine zum Block-Einlegen von Cassette.

CSOPOV    $E47D     Bereitmachen für Eingabe (Cassette).

 

 

Ein Beispiel für die Verwendung eines ROM-Vektors wäre:

 

JSR CIOV

 

 

Abbildung 8.9a:

ROM-Vektoren

 

Name   Stelle  Inhalt Funktionen

VDSLST $0200   $E7B3  Display-List-Vektor (NMI)

VPRCED $0202   $E7B3  IRG-Vektor Proceed-Leitung-z.Z.unbenutzt

VINTER $0204   $E7B3  IRG-Vektor Interrupt-Leitung-z.Z.unben.

VBREAK $0206   $E7B3  IRG-Vektor So+tware-BREAK

VKEYBD $0208   $FFBE  IRG-Vektor Tastatur.

VSERIN $020A   $EB11  IRG-Vektor serielle Eingabe beendet.

VSEROR $020C   $EA90  IRG-Vektor serielle Ausgabe beendet.

VSEROC $020E   $EAD1  IRQ-Vektor ser. Ausgabe abgeschlossen

VTIMR1 $0210   $E7B3  IRQ-Vektor POKEY-Timer 1

VTIMR2 $0212   $E7B3  IRG-Vektor POKEY-Timer 2

VTIMR4 $0214   $E7B3  IRG-Vektor POKEY-Timer 4.

VIMIRQ $0216   $E6F6  Direkter IRD-Vektor zum IRG-Handler.

VVBLKI $0222   $E7D1  Immediate NMI-Vektor Vertical-Blank.

VVBLKD $0224   $E93E  De+erred NMI-Vektor Vertical-Blank.

CDTMA1 $0226   $xxxx  JSR-Adresse für System-Timer 1.

CDTMA2 $0228   $xxxx  JSR-Adresse für System-Timer 2.

CASINI $0002   $xxxx  Initialisierung des Cassetten-BOOTs.

DOSINI $000C   $xxxx  Initialisierung des Disketten-BOOTs.

RUNVEC $02E0   $xxxx  DUP-File Run-Vektor

INIVEC $02E2   $xxxx  DUP-File Initialis.-Vektor.

HATABS $031A   "P"   Drucker-Geräte I.D.

       $031B   $E430  Adr. d. Drucker Einsprungpunkt-Tafel.

       $031D   "C"    Cassetten-Geräte I/D.

       $031E   $E440   Adr. d. Cassetten Einsprungpunkt-Tafel.

       $0320   "E"    Display-Editor I.D.

       $0321   $E400  Adr. d. Dis.Edit.Einsprungpunkt-Ta+el.

       $0323   "S"    Bildschirm-Handler I.D.

       $0324   $E410  Adr. d.B-Handler Einsprungpunkt-Tafel.

       $0326   "K"    Tastatur-Handler I.D.

       $0327   $E420  Adr. d. Tast.-Handleinsprungpunkt-Ta+el.

       $0329   "x"    Unbenutzter HATABS-Eintrag   1

       $032B   "x"            ..        ..        2

       $032E   "x"            ..        ..        3

       $0331   "x"            ..        ..        4

       $0234   "x"            ..        ..        5

       $0237   "x"            ..        ..        6

       $032A   "x"            ..        ..        7

       $034D   "x"            ..        ..        8

       $0340   "x"            ..        ..        9

 

 

 

 

Ein "X" zeigt einen sich ändernden Inhalt an.

Ein Beispiel für die Benutzung eines RAM-Vektors wäre:

 

JSR CALL

CALL JMP (DOSINI)

 

Abbildung 8.9b:

 RAM-Vektoren

 

 

               0010 ; seschrieben von MiChaei Ekbers

 

0600           0030 START     = $600

000C           0040 DOSINI    = $0C

02E7           0050 MEMLO     = $2E7

3000           0060 NEWMEM    = $3000 Dieser Wert legt die

               0065 ; Groesse fest.

               0070 ; Diese Routine sichert Speicherplatz

               0080 ; fuer Assembler-Routinen, indem der

               0090 ; MEMLO-Zeiger gesetzt wird. Sie laeuft

               0100 ; als AUTORUN.SYS-File. Sie setzt

               0110 ; ausserdem MEMLO bei <SYSTEM-RESET>

               0120 ; zurueck. MEMLO wird auf den Wert von

               0130 ; NEWMEM sesetzt.

               0135 ;

               0140 ; Dieser Teil ist Permanent, d.h. muss

               0150 ; resident sein. Der DOS-InitVektor

               0160 ; wurde geaendert und in die Speicher-

               0170 ; stelle INITDOS+1 & 2 gebracht. Das

               0180 ; DOS wird initialisiert, worauf

               0190 ; gleiches mit MEMLO geschieht. INITDOS

               0191 ; wird bei <SYSTEM-RESET> ausgefuehrt.

0000           0200           *= START

               0210 INITDOS

0600 20 0D 06  0220           JSR CYNTHIA    ;DOS INITLIST

0603 A9 00     0230           LDA #NEWMEM&255 ;ausfuehren

0605 8D E7 02  0240           STA MEMLO

0608 A9 30     0250           LDA #NEWMEM/256

060A 8D E8 02  0260           STA MEMLO+1

               0270 CYNTHIA

060D 60        0280           RTS

               0290 ; Dieser Teil wird nur beim Einschalten

               0300 ; ausgefuehrt und kann danach geloescht

               0310 ; werden. Diese Routine speichert die

               0320 ; Inhalte von DOSINI in einem JSR bei

               0330 ; der Speicherstelle INITDOS+1. Danach

               0340 ; wird der Wert von DOSINI ersetzt;

               0350 ; der neue ist die Speicherstelle

               0360 ; INITDOS.

               0390 JACKIE

060E A5 0C     0400           LDA DOSINI     ;DOSINI sichern

0610 8D 01 06  0410           STA INITDOS+l

0613 A5 0D     0420           LDA DOSINI+1

0615 8D 03 06  0430           STA INITDOS+2

0618 A9 00     0440           LDA #INITDOS&255 ;DOSINI setzen

061A 85 0C     0450           STA DOSINI

061C A9 06     0460           LDA #INITDOS/256

06lE 85 0D     0470           STA DOSINI+1

0620 A5 00     0480           LDA NEWMEM&255 ;MEMLO setzen

0622 8D E7 02  0490           STA MEMLO

0625 A9 30     0500           LDA #NEWMEM/256

0627 8D E8 02  0510           STA MEMLO+1

062A 60        0520           RTS

062B           0530           *= $2E2

02E2 0E 06     0540           .WORD JACKIE ;RUN-Adresse setzen

 

 

Abbildung 8.10: MEMLO-ƒnderer