rsync68 - ing
Transcription
rsync68 - ing
RSYNC68 ======================================================== Realtime - Monitor 68xxx Version 1.1 Realtime - Kern 10/99 ======================================================== Benutzerhandbuch Programmierunterlagen ======================================================== Ing.-Büro Heiner Jaap Soltaustraße 5 21029 Hamburg Tel.: 040/7241152 E-Mail: hj@ing-jaap.de www.ing-jaap.de ======================================================== Inhaltsverzeichnis 1 1.1 Einleitung Systemübersicht 4 6 2. Der RSYNC68-Monitor 8 3. 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 Kommandos des RSYNC68-Monitors B BREAK-POINT setzen D Disassembler E Adreßbereich ansehen G USER-Programm starten L Interne Listen ausgeben M Speicherinhalt anzeigen und ändern R USER-Register des Prozessors anzeigen S S-Record laden T TRACE ein- oder ausschalten W WATCH-Memory X Alle BREAK-POINTS löschen Z BREAK-POINT-Liste anzeigen ^A USER-Adreßregister anzeigen und ändern ^D USER-Datenregister anzeigen und ändern ^O Lade-Offset anzeigen und ändern ^P USER-PC anzeigen und ändern ^S USER-Statusregister anzeigen und ändern 12 14 16 17 17 18 26 27 27 27 28 29 29 29 29 30 30 31 4. 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 Monitor-Funktionsaufrufe Kaltstart des gesamten Systems Warmstart des gesamten Systems 8Bit-Zeicheneingabe ohne Echo 7Bit-Zeicheneingabe mit Echo Eingabeport testen 8Bit-Zeichenausgabe Stringausgabe Ausgabe von CR/LF Ausgabe von CR/LF und eines Strings Debug-Aufruf des Monitors 32 33 33 34 34 34 35 35 35 36 36 5. 5.1 5.2 Das REALTIME-SYSTEM Das Multitask-System Die Interruptverwaltung 37 38 40 6. 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 Realtime-Funktionsausfufe Erzeugen einer ISB-/IOB-Eintragung Realtime-Modus setzen IOC-Adresse holen Anmeldung einer neuen Task Status einer Task ändern Event an eine Task senden Event lesen Eventstatus löschen 42 42 47 48 49 51 53 53 54 7. 7.1 7.2 System-Funktionsaufrufe Speicherinitialisierung Speicherbereich holen 55 56 56 -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 2 7.3 7.4 7.5 7.6 7.7 Speicherbereich zurückgeben Zeichen einlesen Zeichen ausgeben Puffer löschen PIPE-Puffer erzeugen 56 57 58 58 59 8. 8.1 Einzelne Funktionsaufrufe TRAP 15 Taskwechsel erzwingen 60 60 -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 3 1 Einleitung Der Realtime-Monitor/-Kern RSYNC68 ist zum Einsatz auf CPU-Karten mit den Prozessoren 68xxx geeignet. Er beinhaltet alle wichtigen Funktionen und Debug-Kommandos, die für ein romorientiertes Real-Time- und Multitasksystem benötigt werden. In diesen Unterlagen ist die Implementierung für das 68302/SYSTEM K2 beschrieben. Der Monitor Nach einem Systemstart werden vom Monitor alle nötigen Initialisierungen vorgenommen: - Bus-RESET-Signal, auch nach einem Warmstart. - Ermitteln des RAM-Speicherbereichs. - Initialisierung aller Listen und Variablen. - Öffnen des Monitorports (stdio). - Starten eines USER-Programms im ROM. Mit dem Monitor können einfache Kommandos eingegeben werden. So können Programme auf unterster Ebene bearbeitet und geprüft werden: - Speicherinhalte ansehen und ändern S-Records laden Break-Point-Verwaltung Programme starten und testen Zugriff auf CPU-Register Disassmbler Außerdem hält der Monitor für Anwenderprogramme eine Reihe von hilfreichen Funktionen mit I/OOperationen und zur Systemverwaltung bereit. Der Realtime- und Multitask-Kern Das Realtime-System ist zwar selbständig, arbeitet aber eng mit dem Monitor zusammen. Somit lassen sich Realtime- und Multitaskfunktionen vom Monitor aus testen. Die Kommunikation mit Anwenderprogrammen geschieht über Funktionsaufrufe. Sie werden unterschieden in Realtime/, System-/ und einzelne Funktionsaufrufe. Zu den aufrufbaren Realtime-Funktionen gehören zum Beispiel diejenigen, mit denen Interruptquellen und Tasks eingerichtet, sowie verwaltet werden können. Solche zur Speicher- und Pufferverwaltung sind den System-Funktionen untergeordnet. Diese Funktionen werden über eine TRAP, einer Funktionsnummer und gegebenenfalls Parametern aufgerufen. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 4 Die einzelne Funktionen sind jeweils einer eigenen TRAP zugeordnet und damit schneller. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 5 1.1 Systemübersicht Der Adreßbereich von $0000 0000 bis $001f ffff (2MByte ROM) ist für RSYNC und Anwenderprogramme reserviert. RSYNC muß fest ab der Adresse $0 im System installiert sein. Von dort ab sind 32kByte reserviert. Ein Benutzerprogramm kann demnach an der Adresse $8000 beginnen. Es wird nach Systemstart vom Monitor automatisch gesucht und gestartet (ROM-Systeme). Der Adreßbereich von $0020 0000 bis $002f ffff (1MByte) ist als RAM-Bereich reserviert. RSYNC ermittelt den durchgehenden Speicherbereich von der Adresse $0020 0000 an und initialisiert ihn. Die ersten 64KByte werden von RSYNC benutzt. Ein Benutzerprogramm kann den RAM-Bereich ab Adresse $0021 0000 benutzen. Die Adressen $ffff 8000 bis $ffff 8fff werden vom internen Dual Port Ram des 68302 belegt. Auf der Adresse $ffff c000 wird die externe Watch Dog auf der CPU-Karte angesprochen. Der I/O-Bereich liegt in den Adressen von $ffff e000 bis $ffff ffff. Wenn eine Adresse zwischen $0030 0000 bis $00ff 7fff angesprochen wird, kommt es zum BUS-ERROR Abbruch. $0000 0000 - $001F FFFF $0000 0000 - $0000 7FFF ab $0000 8000 ROM-Bereich - RSYNC - USER-Programm $0020 0000 - $0020 FFFF $0020 0000 - $0020 FFFF RAM-Bereich - RSYNC-Variablen, Listen ab $0021 0000 - Anwenderprogamm (Test) - Anwendervariablen ab höchster Adresse abwärts - Main-Stack $0030 0000 - 00FF 7FFF BUS-ERROR $FFFF 8000 - FFFF 8FFF Internes ProzessorRAM $FFFF C000 Watchdog $FFFF E000 - FFFF FFFF BUS I/O-Bereich -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 6 Von RSYNC werden drei Interruptebenen, IRQ1, IRQ4, IRQ6 und der NMI (IRQ7) bedient. Der NMI wird vom System selbst nicht verwendet. Er ist nur zu Testzwecken gedacht und löst einen Sprung in die Kommandoebene des Monitors aus. Alle weiteren Interruptaktivitäten bleiben so lange gesperrt, bis ein Rücksprung in das unterbrochene Programm stattfindet (G-Kommando). Zur NMI-Eingabe gibt es eine zweipolige Stiftleiste auf der Prozessorkarte, deren Kontake auch einfach nur geschlossen werden können. Eine Entprellung des Signals ist jedoch nicht vorgesehen. Sie muß von der externen Ansteuerschaltung vorgenommen werden. Mit Hilfe der Interrupts IRQ6 und IRQ4 werden dem System Eingabeanforderungen und andere Real-Time Ereignisse mitgeteilt. Die höchste Priorität haben dabei Interrupts von der IRQ-Leitung des I/OBusses (IRQ6). Ihre Wichtigkeit innerhalb dieser Ebene wird durch die Reihenfolge ihrer Anmeldung beim System festgelegt (RSYNC_IRS_CREATE). Die Prioritäten der internen Interrupts (IRQ4) sind im Prozessor festgelegt (MC68302 User's Manual). Die Multitaskverwaltung wird programmierbar durch einen Timer (68302-WATCH-DOG) gesteuert, der den niederwertigsten Interrupt (IRQ1) auslöst. IRQ6: IRQ4: IRQ1: IRQ (I/O) auf dem BUS, Autovektor. Interne CPU-Interrupts (I/O). Multitask-Timer. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 7 2. Der RSYNC68-Monitor Der Monitor ist der Kern des RSYNC68-Betriebssystems. Er wird nach einem Power-Up Reset aufgerufen und initialisiert die Grundfunktionen des Systems. Er ermittelt die Größe des Arbeitsspeichers, und durchsucht den ROM-Bereich nach einem lauffähigen Programm, das, falls es vorhanden ist, nach der Initialisierung gestartet wird. Wenn kein Programm gefunden wurde, meldet sich der Monitor über die Standardschnitstelle (stdio). Über sie kann jetzt zum Beispiel ein Anwenderprogramm im S-Record-Format in das RAM geladen und gestartet, sowie alle anderen Monitorkommandos eingegeben werden. Der Monitor und alle Anwenderprogramme laufen auf der Main-Ebene im Single-Task-Betrieb. Das Realtime- und Multitasksystem ist dabei noch nicht aktiv, da es erst vom Anwenderprogramm gestartet werden muß. Aus einem laufenden Programm heraus kann der Monitor mit dem OP-Code $4AFC (TRAP #4: Illegaler Befehl, BREAK-POINT) aufgerufen werden. Fals das Realtime-System aktiv ist, arbeitet es ungehindert weiter. Auch in diesem Zustand lassen sich alle Monitorkommandos aufrufen. Ein Anwenderprogramm kann so auf unterster Ebene geprüft werden. Der eingebaute Disasembler erleichtert dabei die Orientierung bei allen TRACE- und DEBUG-Operationen. Der Monitor verwendet zur Ein- und Ausgabe den Standardkanal stdio. Damit es nicht zu undurchschaubaren I/O-Operationen kommt, sollte der Monitor nur von einer Task zur gleichen Zeit aufgerufen werden. Außerdem sollten in keiner anderen Task I/O-Operationen aktiv sein, die über stdio laufen. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 8 Damit RSYNC ein Anwenderprogramm im ROM (ab Adr.$8000) erkennen und richtig starten kann, muß es eine Kennung und ein Startprogramm besitzen, das die Initialisierung durchführt. Das folgende Beispiel muß an die jeweilige Entwicklungsumgebung angepaßt werden. ****************************************************************** * * * START68 * START-UP-Modul fuer RSYNC68 (C) Heiner Jaap, Fileanlagedatum: 09.09.1997 * * * * * Dieses Modul muss am Anfang eines Programms stehen, * * das mit dem Betriebssystem RSYNC arbeitet * * * ****************************************************************** include sys68.sys far data far code xref _main xref __H0_org,__H0_end,__H1_org,__H1_end,__H2_org,__H2_end xdef .begin * Konstantenvereinbarung * --------------------------------------------------------------- USERPROG equ $4e724e72 ; Kennung des USER-Programms im PROM dseg * Variablenvereinbarungen * --------------------------------------------------------------xref __ttyback,__ttybreak __ttyback ds.b 1 ; 1 Zeichen Unget-Platz fuer stdin __ttybreak ds.b 1 ; wenn <> 0, dann BREAK-Char bei putc() cseg * Vorbereitung des USER-Programms * ---------------------------------------------------------------.begin: bra START dc.w * USER-Programmkennung jump 0 USERPROG muss auf Langwort beginnen USER-Programmkennung fuer automatischen Start aus dem ROM dc.l USERPROG 1. Kennungswort dc.l USERPROG 2. Kennungswort dc.l START Startadresse des Programms -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 9 dc.l START USERPROG 3. Kennungswort clr d0 move.b d0,__ttyback Kein Unget-Char vom stdio move.b d0,__ttybreak BREAK-Eingabe nicht aktiv -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 10 * Initialisierte Daten kopieren move.l #__H1_org+32766,a5 move.l #__H1_end,d0 sub.l #__H1_org,d0 Laenge des beq NOINI Keine initialisierten Daten lsr.l #1,d0 Wortanzahl move.l #__H0_end,a0 Quelle * initialisierten Datensegments INICOP * #__H1_org,a1 Ziel move (a0)+,(a1)+ kopieren dbra d0,INICOP BSS berechnen und initialisieren NOINI BSSINI * move.l move.l #__H2_end,d0 sub.l #__H2_org,d0 BSS Laenge beq NOBSS Kein BSS lsr.l #1,d0 Wortanzahl move.l #__H2_org,a0 BSS Anfang clr (a0)+ BSS auf NULL setzen dbra d0,BSSINI __H2_end an RSYNC zur Speicherinitialiserung fuer MALLOC NOBSS move.l #__H2_end,d0 move #RSYNC_SYS_MEMINIT,d1 trap #2 * User-Programm aufrufen und beenden * --------------------------------------------------------------bsr * _main USER-Programm aufrufen Nach dem Programmende, Sprung zum Monitor-Warmstart move #RSYNC_MONI,d1 trap #0 end Der Linker stellt Angaben über die Programm- und Datenbereiche zur Verfügung: __H0_org: __H0_end: __H1_org: ten. __H1_end: __H2_org: Daten. __H2_end: Daten. Anfangsadresse des Programmcodes. Endadresse des Programmcodes. Anfangsadresse der initialisierte DaEndadresse der initialisierten Daten. Anfangsadresse nicht initialisierter Endardesse der nicht initialisierter -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 11 3. Kommandos des RSYNC68-Monitors Wenn sich der Monitor mit der Eingabeanforderung (>> ) gemeldet hat, können Kommandos eingegeben werden. Die Kommandonamen bestehen aus einem Buchstaben oder einem Steuerzeichen (CTRL.+Buchstabe). Die Steuerzeichen werden im folgenden Text durch ein vor dem dazugehörigen Kommandobuchstaben stehenden Aufwärtspfeil (^) gekennzeichnet. Zum Beispiel bedeutet ^E, daß die Taste Control und die Taste E gleichzeitig gedrückt sein müssen. Nach der Eingabe eines ungültiges Kommando gibt der Monitor ein Fragezeichen (?) aus und meldet sich in der nächsten Zeile wieder mit der Eingabeanforderung. Ist das Kommando richtig und werden keine weiteren Parameter benötigt, wird es sofort ausgeführt, sonst erst nach der fehlerfreien Parametereingabe. Bei der Buchstabeneingabe wird vom Monitor kein Unterschied zwischen Groß- und Kleinschreibung gemacht. 'E' ist gleichbedeutend mit 'e'. Angaben zur Syntax: Sind Parameter in der Form <PARAMETER> angeben, dann müssen sie unbedingt eingegeben werden, um das Kommando zu vervollständigen. Die Schreibweise [PARAMETER] bedeutet, daß der Parameter eingegeben werden kann, aber nicht unbedingt eingegeben werden muß. X,y oder z als Parameterwert bedeuten eine Hexziffer oder Hexzahl. (0...9,A...F). Besteht eine Hexzahl aus sechs Stellen, dann wird nach der Eingabe der ersten beiden Stellen vom System ein SPACE ausgegeben, damit die Zahl leichter lesbar ist. Bei einer achstelligen Hexzahl wird das SPACE hinter den ersten vier Stellen eingefügt. Eine Dezimalziffer oder Zahl wird durch den Buchstaben n dargestellt, ein beliebiges ASCII-Zeichen durch den Buchstaben c. Das Zeichen | in einer Parameterliste bedeutet, daß einer der Parameter ausgewählt werden kann oder muß. Sind bei der Syntaxangabe Zeichen zwischen runden Klammern geschrieben, dann handelt es sich dabei um eine Ausgabe des Monitors. Beispiel: ( - ) bedeutet, daß der Monitor an dieser Stelle ein SPACE, gefolgt von einem Minuszeichen und einem weiteren SPACE ausgibt. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 12 Die Eingabe CARIAGE RETURN wird als CR abgekürzt. Dieses Zeichen wird in der Regel mit Hilfe der RETURN-Taste erzeugt. Die sechstelligen Adresseneingaben mit dem Wert $Fx xxxx werden intern auf die achtstelligen Adressen $FFFx xxxx erweitert. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 13 3.1 B BREAK-POINT setzen Syntax: B <xxxxxx> Stößt der Prozessor bei der Abarbeitung eines USER-Programms auf einen BREAK-POINT (OP-CODE: ILLEGAL $4AFC), dann erfolgt ein Sprung zum Monitor. Auf dem Terminal wird die Meldung "BREAKPOINT", der PC-Adresse des BREAK-POINTs und der Inhalt aller Prozessorregister ausgegeben. Nach der Registerausgabe wird der BREAK POINT gelöscht und der ursprüngliche Code wieder eingesetzt. Der PC seht auf der Adresse des BREAK POINTs und der Programmcode an dieser Stelle wird disassembliert ausgegeben. Danach meldet sich der Monitor mit der Eingabeanforderung. Durch das G-Kommando kann mit der Programmabarbeitung fortgefahren werden. Es lassen sich an dieser Stelle aber auch alle anderen Monitorkommandos aufrufen. Ist der BREAK-POINT direkt als Befehl im Programm eingegeben, kann er nicht durch einen "ursprünglichen Code" ersetzt werden. Als Meldung vor dem Registerausdruck wird in diesem Fall "BREAK-CODE" ausgegeben und die PC-Adresse des nächsten Befehls. Ein BREAK-POINT muß immer im RAM auf die Adresse gesetzt werden, an der ein Prozessorbefehl beginnt. Einige Adreßangaben werden schon bei der Kommandoeingabe überprüft. Wird dabei ein Fehler festgestellt, dann wird der BREAK-POINT nicht angenommen. Der Monitor gibt dann hinter der eingegebenen Adresse ein ? aus. Fehlt das Fragezeichen, dann ist der BREAK-POINT ins RAM geschrieben und in die BREAK-POINT-Liste eingetragen. Bei folgenden Fehleingaben wird kein BREAK-POINT gesetzt und das ? nach der Adresse ausgegeben: 1. Als BREAK-POINT-Adresse ist keine einwandfreie sechsstellige Hexzahl eingegeben worden. 2. Die Adresse liegt nicht im USER-RAM-Bereich des Systems (siehe Systemübersicht). 3. Der BREAK-POINT konnte nicht eingesetzt werden (z.B. RAM-Fehler). -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 14 4. Der BREAK-POINT sollte auf eine ungerade Adresse gesetzt werden. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 15 3.2 D Disassembler Syntax: D <CR>|<xxxxxx> Der Disassembler übersetzt den Maschinencode im ROM oder RAM in die leicht lesbare Assemblerschreibweise. Da er auch bei jedem BREAK-POINT oder BREAK-CODE, sowie im TRACE-Modus nach jedem Befehl aufgerufen wird, kann ein Programmablauf leichter verfolgt werden. Dies erleichtert besonders das Testen von Programmen, die mit einem Linker gebunden wurden. Für das Kommando sind zwei Eingabeformen möglich: D <CR> Der Befehl, auf dem der PC des Anwenderprogrammes gerade steht, wird disassembliert ausgeben. D <xxxxxx> Der Code wird von der Adresse xx xxxx an fortlaufend disassembliert und vorweg mit der momentanen Adresse zeilenweise ausgegeben. Der Disassembler kann durch Betätigung der SPACETaste am Ende einer Zeile angehalten werden. In diesem Zustand kann das Kommando durch die Eingabe von CR abgebrochen werden. Durch jede andere Eingabe wird die Ausgabe fortgesetzt. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 16 3.3 E Adreßbereich ansehen Syntax: E <xxxxxx> ( - ) <yyyyyy> Mit diesem Kommando ist es möglich, den Inhalt eines Speicherbereichs von xxxxxx bis yyyyyy in HEX und ASCII anzusehen. Die Anfangs- und die Endadresse wird dabei jeweils auf die vorhergehende oder nachfolgende Zeilengrenze (16 Adressen pro Zeile) gesetzt. Die Ausgabe erfolgt in der Form: xxxx xxxx - yy yy yy......yy yy yy nnnnnnnnnnnnnnnn Dabei ist xxxx xxxx die erste Speicheradresse der ausgebenen Zeile. yy ist der jeweilige Inhalt (Byte) dieser und der nächsten 15 Adressen in HEX-Darstellung. Danach wird der Inhalt der gleichen Adressen nochmals ausgegeben, diesmal jedoch in ASCII (c). Für ein nicht druckbares Zeichen wird an der entsprechenden Stelle ein PUNKT (.) angezeigt. Die laufende Ausgabe kann durch Betätigung der SPACE-Taste am Ende einer Zeile angehalten werden. In diesem Zustand kann das Kommando durch die Eingabe von CR abgebrochen werden. Durch jede andere Eingabe wird die Ausgabe fortgesetzt. Mit diesem Kommando kann bis auf dem BUS-ERRORBereich jeder Adreßbereich angesehen werden. Wird dieser Adreßbereich erreicht, dann wird das Kommando abgebrochen. 3.4 G USER-Programm starten Syntax: G Mit diesem Kommando kann ein USER-Programm gestartet oder dessen Bearbeitung nach beispielsweise einem BREAK-POINT wieder aufgenommen werden. Das USER-Programm läuft von der Adresse an, auf die der Programmzähler (siehe Kommando ^P) steht. Nach einem Kalt- oder Warmstart des Monitors wird der Programmzähler immer auf die Warmstartadresse des Monitors gesetzt. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 17 3.5 L Interne Listen ausgeben Syntax: L <I>|<V>|<M>|<T> RSYNC legt zur internen Verwaltung Listen an, wie beispielsweise zur Task- oder Speicherverwaltung. Diese Listen können durch das L-Kommando eingesehen werden. Die Auswahl der gewünschten Liste geschieht nach der Kommandoeingabe durch einen weiteren Buchstaben. Vorher werden vom Monitor alle auszuwählenden Listen angezeigt. Die Listenausgabe kann am Ende eines Listeneintrages durch Betätigung der SPACE-Taste angehalten werden. Danach kann die Ausgabe durch RETURN abgebrochen oder durch jede andere Eingabe fortgesetzt werden. Folgende Listen können angesehen werden: I: V: M: T: Interrupt-Server Liste (ISB, IOB) Interne Interrupt-Server Liste (IOB) Memory-Allocation-Liste Task-Liste (TCB) -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 18 I: Interrupt-Server-Liste In dieser Liste sind alle Interruptquellen, deren Adresse im BUS I/O-Bereich liegt, aufgeführt. (Siehe RSYNC_IRS_CREATE). Bei einem I/O-Interrupt wird die zugehörige Interruptquelle vom Anfang dieser Liste aus gesucht. Format der Listenausgabe: INTERRUPT-SERVER-LISTE ISB-/IOB-Eintragungen: N -------------------------------------------------------- Die Liste beginnt mit der Listenbezeichnung und der Anzahl (N) der in der Liste vorhandenen Einträge (dezimal). In den folgenden Zeilen folgen blockweise Informationen zu den jeweiligen Einträgen: Nr. ISB-Adr. Intr.-Adr. Buffer-Adr. Write-Adr. IOB-SYNCTASK IOB-Adr. IRS-/IOB-Name Port-Adr. Len BUFFFLAGS COUNT Read-Adr. IOB-TASKINFO Nr.: Listennummer Die Einträge in dieser Liste sind in der Reihenfolge fortlaufend numeriert, wie sie beim Auftreten eines Interrupts durchsucht werden. ISB-Adr. (HEX) Adresse des zugehörigen ISBs. IOB-Adr. (HEX) Adresse des zugehörigen IOBs. IRS-/IOB-Name Name dieser Blöcke, wie er mit mit dem Funktionsaufruf RSYNC_IRS_CREATE übergeben wurde. Intr.-Adr. (HEX) Adresse der Interruptquelle. Unter dieser Adresse wird das Interrupt-Bit vom zugeordneten Portbaustein gelesen. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 19 Port-Adr. (HEX) Port-Basisadresse für die I/O-Treiber. Buffer-Adr. (HEX) Anfangsadresse des Eingabepuffers, in dem die vom Lese-Treiber geschriebenen Daten (Bytes) geschrieben werden. Len (HEX) Tiefe des Eingangspuffers. Maximalanzahl der Zeichen, die er aufnehmen kann. BUFFFLAGS (HEX) Interne Flags zur Verwaltung des Eingangspuffers, der I/O- und interner Funktionen. COUNT Momentane Zeichenanzahl (Bytes) im Eingangspuffer. Write-Adr. (HEX) Adresse, an die das nächste Zeichen (Byte) in den Eingangspuffer geschrieben wird. Read-Adr. (HEX) Adresse, von der das nächste Zeichen (Byte) aus dem Eingangspuffer gelesen wird. IOB-SYNCTASK (HEX) Adresse tuellen Adresse NE TASK der SYNCHRONEN TASK, die nach einer evenZeicheneingabe aufgerufen wird. Wenn die den Wert NULL besitzt, ist keine SYNCHROdefiniert. IOB-TASKINFO (HEX) Parameter, der an die SYNCHRONE TASK übergeben wird. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 20 V: Interne Interrupt-Server-Liste In dieser Liste sind alle Interruptquellen, die mit einem Vektor im Prozessor definiert und vom Benutzerprogramm angemeldet sind, aufgeführt. Format der Listenausgabe: Interne INTERRUPT-SERVER-LISTE -------------------------------------------------------- Diese Liste ist grundsätzlich wie die INTERRUPTSERVER-Liste aufgebaut. Anstelle der Listennummer und der ISB-Adresse beginnt jeder Block mit der internen Interruptquellenbezeichnung (z.B. 68302_SCC3). Dann folgen die weiteren Informationen zu den jeweiligen Einträgen. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 21 M: Memory-Allocation-Liste Ein USER-Programm kann vom System über den Malloc-Aufruf Speicherplatz anfordern und ihn durch den Free-Aufruf zurückgeben. Das setzt natürlich voraus, daß der Systemspeicher initialisiert wurde. Das geschieht in der Regel durch das Startmodul START68, das am Anfang eines jeden USER-Programms stehen muß. Format der Listenausgabe: MEMORY-ALLOCATION-LISTE xxxx - yyyy - zzzz -------------------------------------------------------- In der ersten Zeile der Liste wird an erster Stelle die Anfangsadresse (xxxx xxxx) des zu verwaltenen Speicherbereichs ausgegeben. Danach folgt die Adresse (yyyy yyyy), von der ein neuer Speicherblock angefordert werden wird, falls nicht ein gelöschter Bereich zur Verfügung steht. Zum Schluß folgt die höchste Adresse (zzzz zzzz), die für den frei zu verwaltener Speicherbereich benutzt werden darf. Ist für diese Adresse NULL angegeben, dann ist der Speicherbereich nicht eingegrenzt. Das bedeutet in der Praxis, daß vom Malloc-Aufruf keine Bereichsprüfung vorgenommen wird und ein Stack überschrieben werden kann. Falls für die beiden Adressen xxxx xxxx und yyyy yyyy NULL angezeigt wird, ist die Speicherverwaltung noch nicht initialisiert. Speicher kann dann nicht angefordert werden. In den folgenden Zeilen werden Angaben zu den einzelnen reservierten Blöcken gemacht: xxxx xxxx - yyyy yyyy [TASK] zzzz zzzz xxxx xxxx: Adresse (Hex) Anfang des zum zugewiesenen Speicherbereichs vorangestellten Steuerblocks. yyyy yyyy: Adresse (HEX) Anfang des zugewiesenen Speicherbereichs. Von dieser Adresse aus kann der Speicher benutzt werden. Sie wird vom MALLOC-Aufruf zurückgegeben und muß beim FREE-Aufruf wieder übergeben werden. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 22 [TASK]: Tasknummer Diese Dezimalzahl zeigt die Nummer der Task, die diesen Speicherbereich reserviert hat. Es gibt zwei Sonderformen: [free] bedeutet, daß dieser Bereich frei ist und bei der nächsten Möglichkeit wieder zugewiesen wird. Wenn der Speicher von der Main-Task (Task 0) angefordert wurde, erscheint die Angabe [main]. Wenn es möglich ist, erscheint hinter der TaskNummer auch noch der Verwendungszweck des Speicherbereichs: /Input /Stack Eingabepuffer (ISB/IOB) Stack der Task zzzz zzzz: Bereichslänge (HEX) Diese Hexzahl gibt die Länge des reservierten, beschreibbaren Speicherbereich in Bytes an. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 23 T: Task-Liste In der Task-Liste werden Angaben über alle angemeldeten Tasks gemacht. Format der Listenausgabe: TASK-LISTE TCB-Eintragungen: N -------------------------------------------------------- Die Liste beginnt mit der Listenbezeichnung und der Anzahl (N) der angemeldeten Tasks(dezimal). In den folgenden Zeilen folgen Informationen zum jeweiligen Task Control Block (TCB): Nr. TCB-Adr. NEXT-TCB-Adr. Task-Adr. Temp.-Stack Temp.-PC Task-Nr. Task-Parameter Stack-Bottom TASK-Name Status Event Stack-Len Nr. Fortlaufende Ausgabenummer. TCB-Adr. (HEX) Adresse des angezeigten TCBs. Task-Nr. Interne Taskverwaltungsnummer. Die Main-Task, die der Monitor automatisch erzeugt, besitzt die Nummer 0. TASK-Name Name der Task, der bei der Task-Anmeldung übergeben wurde. Der Name der Main-Task "main" wird automatisch vergeben. NEXT-TCB-Adr. (HEX) Adresse des nächsten, in der Task-Liste eingetragenen TCBs, deren Task auf gleicher Ebene die Laufberechtigung erhält. Status -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 24 Mit dem Status der Task wird angezeigt, auf welcher Ebene der Laufberechtigung sie sich befindet. READY: Die Task ist laufbereit und bekommt normal Rechenzeit zugewiesen. WAIT: Die Task bekommt im Moment keine Rechenzeit zugewiesen und wartet auf einen EVENT. Nachdem ein EVENT eingetroffen ist, bekommt sie so lange bevorzugt Rechenzeit, wie der EVENT-Status besteht. DORMANT: Die Task stillgelegt. Ihr wird keine Rechenzeit zugewiesen, ist aber weiterhin angemeldet und kann in den READY- oder WAIT-Zustand versetzt werden. Task-Adr. (HEX) Anfangsadresse des Programmcodes der Task. Task-Parameter (HEX) Parameter, der an die Task bei deren Neustart übergeben wird. Event (HEX) Datum (Byte) im Event-Register der Task. Temp.-Stack (HEX) Momentaner Stack-Pointer der Task. Stack-Bottom (HEX) Unterste reservierte Stack-Adresse der Task. Stack-Len (HEX) Anzahl des reservierten Speicherplatzes (Bytes) für die Task. Temp.-PC (HEX) Momentane Programmadresse der Task. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 25 3.6 M Speicherinhalt anzeigen und ändern Syntax: M <xxxxxx> Soll der Inhalt einer Speicheradresse nicht nur angesehen, sondern auch geändert werden, dann kann dieses Kommando benutzt werden. Bis auf den BUS-ERROR-Bereich kann der Inhalt jeder Adresse angesehen und gegebenenfalls geändert werden. Nach gültiger Kommandoeingabe erfolgt zeilenweise die Anzeige der Adresse, und durch einen Bindestrich getrennt, deren Hexinhalt. Jetzt gibt es verschiedene Eingabemöglichkeiten: 1. Ein CR beendet das Kommando, ohne den Inhalt der angezeigten Adresse zu ändern. 2. Mit dem Zeichen ^ wird der Inhalt der vorhergehenden Adresse angezeigt. Kein Speicherinhalt wird geändert. 3. Durch die Eingabe beliebiger Zeichen, die keine gültige Hexzahl (xx) darstellen, wird der Inhalt der nächsten Adresse angezeigt, ohne einen Inhalt zu ändern. 4. Wird eine gültige Hexzahl eingegeben, dann wird sie in die angezeigte Adresse geschrieben und der Inhalt der nächsten Adresse wird angezeigt. Kann der neue Inhalt nicht fehlerfrei zurückgelesen werden (zB. ROM, PORT), erfolgt eine Fragezeichenausgabe. Danach wird die nächste Adresse aufgerufen. Wenn auf Adressen geschrieben werden soll, bei deren Zugriff ein internes Register inkrementiert oder dekrementiert wird ist darauf zu achten, daß vor dem Schreiben schon ein Lesevorgang auf die angezeigte Adresse durchgeführt wurde. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 26 3.7 R USER-Register des Prozessors anzeigen Syntax: R Wenn ein USER-Programm mit dem G-Kommando neu gestartet oder fortgeführt wird, dann werden die USER-Registerinhalte für PC, SR, D0,...D7 und A0,...A7 in den Prozessor geladen. Der Inhalt dieser Register kann mit dem R-Kommando angesehen werden. 3.8 S S-Record laden Syntax: S S-Records werden über den Monitorport geladen. Dabei wird jedes empfangene Zeichen geechot. Zu allen Ladeadressen wird der Offset, der durch das O-Kommando geändert werden kann, addiert. Im Normalfall hat dieser den Wert NULL. Der Ladevorgang wird beendet, wenn das Zeichen ^A im Datenstrom erscheint, oder wenn ein Fehler festgestellt wurde. Folgende S1: Code S2: Code S3: Code 3.9 Records werden berücksichtigt: mit 16Bit-Adresse. mit 24Bit-Adresse. mit 32Bit-Adresse. T TRACE ein- oder ausschalten Syntax: T <+|-> Diese Kommando schaltet das Trace-Flag (Bit 15 im SR) für das USER-Programm ein (+) oder aus (-). Eine andere Eingabe als + oder - ändert das Flag nicht. Wenn das Trace-Flag gesetzt ist, erfolgt bei der Abarbeitung des USER-Programms nach jedem Befehl ein Registerausdruck und ein Sprung zur Kommandoeingabe des Monitors. Nach dem Registerausdruck wird der nächste Befehl disassembliert und ausgegeben. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 27 3.10 W WATCH-Memory Syntax: W <CR>|<+>|<yyyyyy>|<X> Mit diesem Kommando kann der Inhalt von maximal vier Adressen (Byte) auf Änderungen hin beobachtet werden. Sobald es eine Änderung gibt, werden die neuen Adreßinhalte ausgegeben. Auf diese Weise können Daten überprüft werden, ohne daß das Realtime-Verhalten geändert wird, da die Task, in welcher der Monitoraufruf stattfand, ganz normal an der Verteilung der Rechenzeit teilnimmt. Für das Kommando sind vier Eingabeformen möglich: W <CR> Der momentane Inhalt der vier Adressen wird in einer Reihe angezeigt. Eine NULL als Adresse bedeutet, daß diese WATCH-Adresse noch frei ist. W <+> Der Inhalt der vier Adressen wird wie bekannt angezeigt. Dann wird laufend auf eine Änderung hin geprüft. Sobald sich der Inhalt wenigsten einer der definierten Adressen (<>NULL) geändert hat, wird eine neue Ausgabe vorgenommen. Dieser Modus wird durch eine beliebige Zeicheneingabe beendet. Da eine Überprüfung nur vorgenommen werden kann, wenn die Task, die den Monitor aufgerufen hat Rechenzeit bekommt, ist es möglich, daß nicht alle Änderungen festgestellt wurden. Das hängt von der Änderungsrate und der zeitlichen Belastung des Systems ab. W <yyyyyy> Die Hexzahl yy yyyy ist die Adresse, die als nächste in die Watch-Liste eingetragen wird. W <X> Mit diesem Parameter wird die gesamte Liste gelöscht, so daß neue Eintragungen vorgenommen werden können. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 28 3.11 X Alle BREAK-POINTS löschen Syntax: X Alle gesetzten BREAK-POINTS, die noch in der BREAK-POINT-Liste eingetragen sind, werden durch dieses Kommando gelöscht. Dabei wird der ursprüngliche Code zurückgeschrieben. 3.12 Z BREAK-POINT-Liste anzeigen Syntax: Z Mit diesem Kommando kann die BREAK-POINT-Liste angezeigt werden. Zu jedem BREAK-POINT wird zeilenweise die BREAK-POINT-Adresse und nach einem Bindestrich folgend der ursprüngliche Code ausgegeben, falls die Liste nicht leer ist. 3.13 ^A USER-Adreßregister anzeigen und ändern Syntax: ^A <0,...,6> Dieses Kommando zeigt den Inhalt des ausgewählten Adreßregisters an. Wird nach der Ausgabe eine achtstellige Hexzahl eingegeben, ändert sich der Registerinhalt entsprechend. Alle anderen Eingaben verändern den Registerinhalt nicht. Das Register A7 kann nicht angesprochen werden, da es als Stack-Pointer reserviert ist. Damit ist es mit diesem Kommando nicht möglich, den Stack-Pointer versehentlich zu ändern. 3.14 ^D USER-Datenregister anzeigen und ändern Syntax: ^D <0,...,7> Der Inhalt aller Datenregister D0 bis D7 kann mit diesem Kommando angezeigt und geändert werden. Der Ablauf entspricht dem des Kommandos ^A für die Adreßregister. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 29 3.15 ^O Lade-Offset anzeigen und ändern Syntax: ^O Der Monitor kann Programme im Format der Motorola-S-Records laden. Mit dem O-Kommando kann ein Offset zur Lade-Adresse eingegeben werden. Voraussetzung ist dabei, daß der geladene Code verschiebbar ist. Nach der Kommandoeingabe wird der momentane Offset ausgegeben. Danach kann eine sechsstellige Hexzahl als neuer Offset eingegeben werden. Jede andere Eingabe verändert den momentanen Offset nicht. Bei einem Kaltstart des Monitors bekommt der Offset den Wert NULL. 3.16 ^P USER-PC anzeigen und ändern Syntax: ^P Nach der Eingabe des ^P-Kommandos wird der Inhalt des PROGRAM-COUNTERs angezeigt, mit dem nach einem G-Kommando das USER-PROGRAMM aufgerufen wird. Durch die Eingabe einer gültigen sechstelligen Hexzahl kann der PC geändert werden. Falls keine gültige Hexzahl eingegeben wird, bleibt der PC unverändert und ohne weiteren Angaben erscheint in der nächsten Zeile weiter die Eingabeanforderung des Monitors. Falls nach der Eingabe einer Hexzahl ein ? erscheint, konnte der PC nicht auf die neue Adresse gesetzt werden. Das geschieht wenn: 1. Die Adresse außerhalb des ROM- oder des USERRAM-Bereichs liegt. 2. Der PC sollte auf eine ungerade Adresse gesetzt werden. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 30 3.17 ^S USER-Statusregister anzeigen und ändern Syntax: ^S Der Inhalt des Statusregisters wird hexadezimal und symbolisch angezeigt. Geändert werden kann er jedoch nur durch die vollständige Eingabe einer neuen vierstelligen Hexzahl. Bedeutung der Bits im Statusregister T . S . . I2 I1 I0 . . . X N Z V C T: S: I(2,1,0): X N Z V C CPU ist in der Trace-Betriebsart CPU arbeitet im Supervisor-Modus Interrupt-Maske (0 bis 7) Extended-Flag Negativ-Flag Zero-Flag Overflow-Flag Carry-Flag Bei der symbolischen Ausgabe werden alle gesetzten Flags an der Stellen, an der sie im Statusregister angeordnet sind, durch ihre Kurzbezeichnung angezeigt. Ist ein Flag nicht gesetzt, wird ein Punkt (.) ausgegeben. Die Interrupt-Maske wird direkt als Zahlenwert i7,...,i0 dargestellt. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 31 4. Monitor-Funktionsaufrufe Funktionsaufrufe an den Monitor werden über TRAP #0 vorgenommen. Vorher muß die den Aufruf entsprechende Funktionsnummer in das Register D1.w geladen werden. Parameter an die Funktion werden in den Registern D0.x und A0.x übergeben. Rückgabeparameter befinden sich in D0.x und dem CCR. Die Datengröße, Byte, Wort oder Langwort, hängt von der jeweiligen Funktion ab. Die Funktionsaufrufe verändern die Prozessorregister D1-D7 und A0-A7 nicht. Monitorfunktionen können von jeder Task aus aufgerufen werden. Allgemein sollten sie jedoch nur von einer Task zur Zeit benutzt werden, da zum Beispiel alle I/O-Operationen über einen Port (stdio) gehen. Beispiel: Ausgabe von CR/LF und eines Strings lea move trap TEXT,A0 #RSYNC_PSTRNG,d1 #0 Anfang des Text-Strings Funktionsnummer Monitoraufruf . . RSYNC_PSTRNG TEXT equ dc.b 8 "Test-Text",0 Übersicht der Monitorfunktionen Label RSYNC_START RSYNC_MONI RSYNC_INCH RSYNC_INCHE RSYNC_INCHEK RSYNC_OUTCH RSYNC_PDATA RSYNC_PCRLF RSYNC_PSTRNG RSYNC_DEBUG Nummer 0 1 2 3 4 5 6 7 8 9 Bezeichnung Kaltstart des gesamten Systems Warmstart des gesamten Systems Zeicheneingabe ohne Echo (8Bit) Zeicheneingabe mit Echo (7Bit) Test, ob Zeichen im Eingabe-Port Zeichenausgabe String-Ausgabe Ausgabe von CR/LF Ausgabe von CR/LF und String DEBUG-Aufruf des Monitiors Die Funktionsaufrufe sind in der Datei SYS68.SYS definiert. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 32 4.1 Kaltstart des gesamten Systems TRAP #0 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter : 0 RSYNC_START Keine Keine Beschreibung Dieser Funktionsaufruf startet das gesamte System neu wie nach dem Einschalten. Nach dem Kaltstart gehen alle Monitor-I/O-Operationen über den Default-Monitorport. Außerdem werden alle Systemvariabel neu initialisiert. Der Inhalt des USERSpeicherbereichs wird jedoch nicht verändert. Falls ein USER-Programm im EPROM-gefunden wird, wird es automatisch aufgerufen. Ist das nicht der Fall, wird, falls ein Disk- oder Plattencontroller vorhanden ist, der Kommandointerpreter gestartet, sonst der RSYNC-Monitor. Der Kaltstart wird auch automatisch nach einem Fehlerabbruch aufgerufen: - 4.2 Watch Dog Bus-Error Adress-Error Illegal Intruction ZERO DIVIDE Warmstart des gesamten Systems TRAP #0 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter : 1 RSYNC_MONI Keine Keine Beschreibung Nach einem Warmstart wird der Monitorport nicht geändert. Alle Systemvariablen werden neu initialisiert. Das Realtime-System wird gestopt und soweit wie möglich werden alle ISB-Interruptquelle abgeschaltet. Alle Break-Points werden zurückgesetzt. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 33 4.3 8Bit-Zeicheneingabe ohne Echo TRAP #0 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter (D0.b): 2 RSYNC_INCH Keine Eingelesenes Zeichen Beschreibung Diese Funktion ließt ein 8Bit breites Zeichen (Byte) vom aktuellen Monitorport (stdio) ein. Es erfolgt keine Echoausgabe. 4.4 7Bit-Zeicheneingabe mit Echo TRAP #0 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter (D0.b): 3 RSYNC_INCHE Keine Eingelesenes Zeichen Beschreibung Mit dieser Funktion wird das vom Monitorport (stdio) eingelesene Zeichen auf den Ausgabeport des Monitors zurückgeschrieben (Echo). Außerdem wird das MS-Bit (Bit 7) des Zeichens auf Null gesetzt. 4.5 Eingabeport testen TRAP #0 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter (CCR): 4 RSYNC_INCHEK Keine Z-Flag Beschreibung Wenn getestet werden soll, ob im Monitorport (stdio) ein Zeichen eingetroffen ist, das mit einer Zeicheneingabefunktion abgeholt werden kann, kann diese Funktion benutzt werden. Sie meldet den Status des Port durch den Zustand des Z-Flags im CCR. Z=0: Zeichen im Port (bne) Z=1: Kein Zeichen im Port (beq) -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 34 4.6 8Bit-Zeichenausgabe TRAP #0 Funktionsnummer (D1.w): Aufrufparameter (D0.b): chen Rückgabeparameter : 5 RSYNC_OUTCH Auszugebenes ZeiKeine Beschreibung Diese Funktion gibt ein 8Bit breites Zeichen über den Monitorport (stdio) aus. 4.7 Stringausgabe TRAP #0 Funktionsnummer Aufrufparameter Rückgabeparameter (D1.w): (A0.l): 6 : RSYNC_PDATA Adresse des Strings Keine Beschreibung Der String wird byteweise über den Monitorport (stdio) ausgegeben. Das Stringende muß durch ein NULL-Byte ($00) gekennzeichnet sein. 4.8 Ausgabe von CR/LF TRAP #0 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter : 7 RSYNC_PCRLF Keine Keine Beschreibung Durch den Aufruf dieser Funktion wird ein Zeilenvorschub (CR/LF/0/0/0) über den Monitorport (stdio) ausgegeben. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 35 4.9 Ausgabe von CR/LF und eines Strings TRAP #0 Funktionsnummer Aufrufparameter (D1.w): (A0.l): Rückgabeparameter 8 : RSYNC_PSTRNG Adresse des Strings Keine Beschreibung Vor der Ausgabe des Strings wird ein Zeilenvorschub über den Monitorport (stdio) ausgegeben. Diese Funktion ein verkürzter Aufruf der oft benötigten Kombination RSYNC_PCRLF und RSYNC_PDATA. 4.10 Debug-Aufruf des Monitors TRAP #0 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter : 9 RSYNC_DEBUG Keine Keine Beschreibung Zum Prüfen eines Programmes kann der Monitor durch einen BREAK-POINT-Befehl (ILLEGAL $4AFC) aufgerufen werden. Hierbei bleiben alle Interrupts frei und das Realtime-System arbeitet weiter. Sollen die Interrupts jedoch gesperrt, das Realtime-System also angehalten werden, dann muß mit dieser Funktion in den Monitor gesprungen werden. Wenn der Monitor von einem Benutzerprogramm aus über eine dieser beiden Möglichkeiten aufgerufen wird, arbeitet er praktisch als Programmteil in der aufrufenden Task. Der Rücksprung erfolgt durch die Eingabe des G-Kommandos. Da der Monitor alle Ein- und Ausgaben über den gleichen Port (stdio) vornimmt, sollte er nur von einer Task aus aufgrufen werden. Außerdem müssen alle weiteren Ein- und Ausgaben über diese Schnittstelle vermieden werden. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 36 5. Das REALTIME-SYSTEM Das Realtime-System besteht aus zwei Hauptblökken: Dem Multitasksystem und der Interruptverwaltung. Das Multitasksystem verteilt Rechenzeit an die Tasks entsprechend ihres Zustandes (Status). Die Interruptverwaltung bearbeitet alle Unterbrechungsanforderungen, ließt Zeichen von den Eingabeeinheiten und startet die eventuell dazugehörige SYNCHRONE TASK. Nach dem Start des Monitors ist das REALTIME-SYSTEM noch nicht aktiviert. Es muß im USER-Programm mit der Funktion RSYNC_REAL_MODE gestartet, kann aber auch wieder angehalten werden. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 37 5.1 Das Multitask-System Das System kann bis zu 32 Tasks verwaltet. Die Main-Task mit der Nummer NULL wird vom System selbst erzeugt. Sie ist immer vorhanden. Der Monitor und das von ihm aufgerufene Programm gehören dieser Task an. Die weiteren 31 Tasks können frei definiert werden. Eine Task ist ein Unterprogramm, das quasi unabhängig und parallel zu anderen Unterprogrammen läuft. Es ist normalerweise als Endlosschleife aufgebaut, kann aber auch mit einem RTS-Befehl beendet werden. In diesem Fall geht die Task in den DORMAT-Zustand über und kann erneut in den RUN-Zustand versetzt werden. Das dazugehöhrige Unterprogramm wird dann erneut von Anfang an aufgerufen. Der für die Task vereinbarte Parameter (32Bit) kann dem Stack [4(sp)] oberhalb der Rücksprungadresse der Task-SBR entnommen werden. * * TASK1 Beispiel fuer ein Task -------------------------------------------------far code far data cseg Code-Segment move.l suba 4(sp),d0 #VARIABLEN,sp Task Parameter laden Stack-Variablenbereich LOOP ... ... bra rts Programm-Code der Task LOOP Task ohne Ende RTS sollte niefehlen Jede neue Task muß im System angemeldet und gestartet werden. Das muß mit dem Funktionsaufrufen RSYNC_TASK_CREATE und RSYNC_TASK_SET_STATUS geschehen. Eine Task kann sich in einem der Zuständen DORMANT, READY, WAIT und RUNNING befinden. Im DORMANT-Zustand ist eine Task zwar laufbereit, aber zur Zeit suspendiert. Das bedeutet, daß sie bei der Verteilung der Rechenzeit nicht berücksichtigt wird. Jede neu angemeldetet Task und jede mit einem RTS-Befehl (RETURN) beendete Task wird in diesen Zustand gebracht. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 38 Im READY-Zustand nimmt eine Task an der allgemeinen Verteilung der Rechenzeit teil. In der Regel bekommt eine Task nach der anderen die ihr zustehende Zeitscheibe. Diese Zeitzuteilung ist jedoch mit Einschränkungen zu sehen, denn jede Interrupt-Anforderung und jede SYNCHRONE TASK verbraucht Zeit von der gerade laufenden Task. Außerdem kann eine Task von sich aus ihre Zeit abgeben, wenn sie nicht benötigt wird. Eine Task im WAIT-Zustand nimmt an der Verteilung der Rechenzeit nicht direkt teil. Sie wartet auf ein Ereignis (EVENT). Ein Ereignis ist eine beliebige Zahl von 1,..,255, das von einer anderen Task übermittelt wurde. Empfing eine Task einen EVENT, dann bekommt sie beim nächsten Task-Wechsel sofort Rechenzeit zugeteilt. Alle Tasks, die sich im WAIT-Zustand befinden, erhalten so lange bevorzugt Rechenzeit, wie ihr EVENT-Status aktiv ist. Damit dann die normalen, sich im READY-Zustand befindlichen Tasks nicht total lahmgelegt werden, teilt die Taskverwaltung ihen in regelmäßigen Abstanden eine Zeitscheibe zu. Eine Task, die gerade arbeitet, befindet sich im Zustand RUNNING. Dieser Zustand wird beendet, wenn die zugeteilt Zeit abgelaufen ist, die Task selbst ihre Arbeit beendet oder unterbricht, oder wenn Systemanforderungen mit höherer Priorität, wie beispielsweise I/O-Anforderungen, vorliegen. Wurde die Task durch eine andere Anforderung nur unterbrochen und ist ihre Zeitscheibe noch nicht abgelaufen, bleibt sie nach einer Unterbrechung weiterhin im RUNNING-Zustand. Da eine Task endlos (LOOP) oder nach jeden Start nur einmal (RTS) laufen kann, von sich aus einen Taskwechsel erzwingen oder in den WAIT-Zustand gehen und bevorzugt Rechenzeit zugewiesen bekommen kann, sind Anwenderprogramme mit unterschiedlichem Multitaskverhalten möglich. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 39 5.2 Die Interruptverwaltung Die Interruptverwaltung besitzt die höchste Priorität im System, damit allen Eingabeanforderungen unverzüglich nachgekommen werden kann. Liegt ein Interrupt vom I/O-Bus her vor, muß die Interruptquelle gesucht werden. Dazu werden der Reihe nach alle Interruptadressen (Interrupt-Server-Liste) gelesen und deren Inhalt mit der Interruptmaske verundet. Ist das Ergebnis ungleich NULL, wird die Interruptquelle als gefunden angenommen und die Port-Lesefunktion aufgerufen. Falls ein Eingabepuffer vereinbart ist, dieser Puffer noch nicht gefüllt ist und die Lesefunktion nicht den ERROR-Wert (1) in D0.w liefert, wird das Byte aus D0.b in den Puffer geschrieben. Danach wird, falls definiert, immer die SYNCHRONE TASK aufgerufen. Für den Fall, daß schon wenigstens eine SYNCHRONE TASK aktiv ist, wir diese für den Start vorgemerkt. Die Suche der Interruptquellen und der Aufruf der SYNCHRONEN TASKs wird wird vom Anfang der Interrupt-Server-Liste vorgenommen. Sie wird in der Reihenfolge aufgebaut, wie die Quellen eingetragen (RSYNC_IRS_CREATE) worden sind. Interruptquellen mit der höchsten Anforderungsfrequenz sollten in der Regel am Anfang der Liste stehen. Die Bearbeitung der Interrupts vom BUS-I/O haben im System die höchste Priorität. Danach werden alle SYNCHRONEN TASKs ausgeführt. Eine SYNCHRONE TASK wird immer innerhalb der gerade laufende Task aufgerufen. Sie verbraucht deren Stack und Zeit. Während der kurzen Zeit, da die Interruptquelle gesucht wird, der Port-Lesetreiber und Zeichensicherung aktiv ist, werden keine weiteren Interrupts angenommen. Diese Zeit liegt mit 16MHzTaktfrequenz bei ca. 10µs. Aus diesem Grunde sollen die Treiber so kurz wie möglich sein. Während der Zeit, da eine SYNCHRONE TASK läuft, werden weitere Interrupts bearbeitet. Die internen Interruptquellen der CPU besitzen eine niedrigere Priorität, sind aber vektorisiert. Sie müssen deshalb nicht aus einer Liste heraus gesucht werden. Bis auf diesen Unterschied laufen alle anderen Funktionen (Port-Lesetreiber, SYNCHRONE TASK) gleich ab. Die internen Interruptquellen sind innerhalb des 68302 priorisiert: -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 40 PB11 PB10 SCC1 SDMA IDMA SCC2 TIMER1 SCC3 PB9 TIMER2 SCP TIMER3 SMC1 SMC2 PB8 höchste Priorität niedrigste Priorität -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 41 6. Realtime-Funktionsausfufe Funktionsaufrufe an das Real-Time-System werden über TRAP #1 vorgenommen. Vorher muß die dem Aufruf entsprechende Funktionsnummer in das Register D1.w geladen werden. Parameter an die Funktion werden in den Registern D0.x und A0.x übergeben. Rückgabeparameter befinden sich in D0.x und dem CCR. Die Datengröße, Byte, Wort oder Langwort, hängt von der jeweiligen Funktion ab. Die Funktionsaufrufe verändern die Prozessorregister D1-D7 und A0-A7 nicht. Realtime-Funktionsaufrufe sind aus einer SYNCHRONEN TASK heraus nicht möglich. Beispiel: Erzeugen ISB-/IOB-Eintragung lea move trap IRSDATA,A0 #RSYNC_IRS_CREATE,D1 #1 Übergabedaten Funktionsnummer REALTIME-System-Aufruf . . RSYNC_IRS_CREATE IRSDATA equ ... ... 0 Übergabedatenstruktur Übersicht der Funktionen des REALTIME-Systems Label Nummer RSYNC_IRS_CREATE 0 RSYNC_REAL_MODE RSYNC_GET_IOCONTROL RSYNC_TASK_CREATE RSYNC_TASK_SET_STATUS RSYNC_EVENT_SEND RSYNC_EVENT_READ RSYNC_EVENT_CLEAR 1 2 3 4 5 6 7 Bezeichnung ISB-/IOB-Eintragung er zeugen Realtime-Modus setzen IOC-Adresse holen Neue Task anmelden Status einer Task ändern Event an eine Task senden Event lesen Eventstatus löschen Die Funktionsaufrufe sind in der Datei SYS68.SYS definiert. 6.1 Erzeugen einer ISB-/IOB-Eintragung TRAP #1 -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 42 Funktionsnummer Aufrufparameter (D1.w): (A0.l): Rückgabeparameter (D0.l): 0 RSYNC_IRS_CREATEAdr. der IRSDEFStruktur NULL -> Fehler <>NULL -> IOB-Zeiger Beschreibung Wenn dem Realtime-System eine neue Interruptquelle (BUS-Leitung INT1) und eventuell auch eine dazugehörige SYNCHRONE TASK mitgeteilt werden soll, so muß das mit dieser Funktion geschehen. Dazu werden die entsprechenden Daten in eine IRSDEFStruktur geschrieben, deren Adresse vorm Funktionsaufruf in das Register A0.l geladen werden muß. Ist in der Verwaltungsliste des InterruptServers noch Platz, werden die benötigten Steuerblöcke (ISB, IOB) erzeugt. Die ermittelte IOBAdresse wird im Register D0.l zurückgegeben. Falls die Verwaltungsliste voll ist oder ein anderer Fehlerzustand festgestellt wird (zB. kein Platz für den Eingabepuffer), wird in D0.l der Wert NULL zurückgegeben. Ist ein IOB-Block erzeugt worden, dann kann mit der Funktion RSYNC_GET_IOCONTROL die Adresse des dazugehörigen IOCONTROL-Blocks ermittelt werden, die für I/O-Systemaufrufe RSYNC_SYS_IN und RSYNC_SYS_OUT benötigt wird. IOCONTROL-Blocks werden vom Interrupt-Server so initialisiert, daß die Funktion RSYNC_SYS_IN aus den Eingabepuffer ließt, und die Funktion RSYNC_SYS_OUT auf den Port schreibt. Definition der Struktur IRSDEF IRSDEF_INTRADR IRSDEF_INTRMASK IRSDEF_INIBYTE IRSDEF_BUFFLEN IRSDEF_PORTADR IRSDEF_WRITE IRSDEF_READ IRSDEF_INI IRSDEF_RESET IRSDEF_SYNCTASK IRSDEF_TASKINFO IRSDEF_NAME ds.w ds.b ds.b ds.w ds.w ds.l ds.l ds.l ds.l ds.l ds.l ds.l 1 1 1 1 1 1 1 1 1 1 1 1 Adresse der Interruptquelle Interruptmaske Zusatz zur Initialisierung Pufferlänge Portadresse Port-Schreibfunktion Port-Lesefunktion Port-Initialisierungsfunktion Port-RESET-Funktion Adresse der SYNCHRONEN TASK Parameter für die synch. Task Zeiger zum IOB-Namen Initialisierungwerte, die mit der Struktur IRSDEF übergeben werden müssen. IRSDEF_INTRADR -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 43 Diese Adresse benutzt der Interruptserver, um den Port zu finden, der einen Interrupt erzeugt hat. Das bedeutet, daß von dieser Adresse die Interruptflags des benutzten Bausteins gelesen werden. Die Adresse ist 16Bit breit, denn alle Ports, die vom Interruptserver überwacht werden sollen, müssen in den oberen 32KByte des Adreßbereichs (I/OBereich) liegen. Bei Aufruf eines internen Interrupts des Prozessors ist dieser Wert undefiniert. IRSDEF_INTRMASK Das hier angegebene Byte wird mit dem von der Interruptadresse (IRSDEF_INTRADR) gelesenem Byte durch UND verknüpft, um die Interruptflags des Ports zu testen. Die Verknüpfung muß einen Wert ungleich NULL ergeben, falls der Portbaustein einen Interrupt ausgelöst hat. Bei Aufruf eines internen Interrupts des Prozessors ist dieser Wert undefiniert. IRSDEF_INIBYTE Das hier übergebene Byte wird zur Portinitialisierung an die Initialisierungsfunktion, deren Adresse in IRSDEF_INI steht, im Register D0.b übergeben. Es kann beispielsweise zur BaudrateEinstellung benutzt werden. Die endgültige Bedeutung ist durch die Initialisierungsfunktion festgelegt. Bei Aufruf eines internen Interrupts des Prozessors ist dieser Wert undefiniert. IRSDEF_BUFFLEN Wenn vom Port ein Byte fehlerfrei gelesen wurde, wird es in den Eingabepuffer geschrieben. Der Eingabepuffer kann eine Tiefe von 0,...,32767 Byte haben. Er wird als Ringpuffer verwaltet. IRSDEF_PORTADR Bei einer Interruptquelle im I/O-Bereich wird die Port-Basisadresse übergeben. Soll eine interne Interruptquelle des Prozessors verwendet werden, dann wird hier die entsprechende Interruptnummer eingesetzt. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 44 Für die internen Interruptquellen sind folgende Portadressen vereinbart: IRSDEF_68302_PB8 IRSDEF_68302_PB9 IRSDEF_68302_PB10 IRSDEF_68302_PB11 IRSDEF_68302_SMC1 IRSDEF_68302_SMC2 IRSDEF_68302_SCP IRSDEF_68302_TIMER1 IRSDEF_68302_TIMER2 IRSDEF_68302_SCC1 IRSDEF_68302_SCC2 IRSDEF_68302_SCC3 IRSDEF_68302_IDMA IRSDEF_68302_SDMA equ equ equ equ equ equ equ equ equ equ equ equ equ equ 16 17 18 19 20 21 22 23 24 25 26 27 28 29 IRSDEF_WRITE Adresse des Port-Treibers, mit dem ein Byte über den Port ausgegeben wird. Beim Aufruf dieses Unterprogrammes befindet sich die Portadresse in A0.l und das Ausgabezeichen in D0.b. Ist kein Schreibtreiber vorhanden, muß für diese Adresse eine NULL eingetragen werden. IRSDEF_READ Adresse des Port-Treibers, der den Interruptzustand des Ports abschaltet, und mit dem ein Byte vom Port gelesen wird. Die Portadresse erhält der Treiber in A0.l. Das gelesene Byte muß im Register D0.w zurückgegeben werden. Dabei muß das MSB im Register D0.w muß auf NULL gesetzt werden und das N-Flag darf nicht gesetzt sein. Tritt beim Lesen jedoch ein Fehler auf, muß der ERROR-Code (-1, $FFFF) in D0.w stehen, und das N-Flag muß gesetzt sein. Das Byte in D0.b wird dann nicht in den Eingabepuffer geschrieben. Wird keine Lesefunktion benötigt, muß diese Adresse auf einen Pseudo-Lesetreiber zeigen, der wenigstens den Interruptzustand abschaltet. IRSDEF_INI Adresse des Treibers, der den Port initialisiert. Auch diesem Treiber wird die Portadresse in A0.l übergeben. Außerdem steht der Wert aus IRSDEF_INIBYTE in D0.b. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 45 Ist kein Initialisierungstreiber vorhanden, muß für diese Adresse eine NULL eingetragen werden. IRSDEF_RESET Dieser Treiber wird aufgerufen, um den InterruptModus des Ports abzugeschalten. Die Adresse des Ports wird ihr in A0.l übergeben. Wenn es keinen Reset-Treiber gibt, muß diese Strukturvariable mit NULL initialisiert werden. IRSDEF_SYNCTASK Nachdem ein Zeichen vom Port gelesen wurde, kann eine SYNCHRONE TASK gestartet, oder, falls bereits eine läuft, vorgemerkt werden. Eine SYNCHRONE TASK wird auch aufgerufen, wenn die Lesefunktion den ERROR-Code zurückgibt. Gibt es keine SYNCHRONE TASK, dann muß diese Srukturvariable mit NULL initialisiert sein. Eine SYNCHRONE TASK ist ein Unterprogramm, das nicht in einer Endlosschleife laufen darf. So lange eine SYNCHRONE TASK aktiv ist, werden zwar weiterhin alle Interrupts bearbeitet, die mit der Funktion RSYNC_IRS_CREATE angemeldet wurden, ein normaler Taskwechsel findet aber nicht statt. Eine SYNCHRONE TASK wird nie von einer anderen Task unterbrochen. Sie verbraucht die Rechenzeit der gerade laufenden Task. Von einer SYNCHRONEN TASK aus sind nicht alle Systemaufrufe erlaubt. IRSDEF_TASKINFO Dieser Parameter wird der SYNCHRONEN TASK im Register D0.l und im Stack unter der Adresse 4(SP) übergeben. Die Bedeutung und des Datentyps muß in der Task festgelegt werden. IRSDEF_NAME Dieser Zeiger kann auf einen Text-String (abgeschlossen mit NULL) zeigen, dessen ersten sieben Zeichen als Name an den Interrupt-Server übergeben werden. Soll kein Name eingetragen werden, muß diese Strukturvariable mit NULL initialisiert sein oder auf einen NULL-String zeigen. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 46 6.2 Realtime-Modus setzen TRAP #1 Funktionsnummer (D1.w): Aufrufparameter (D0.b): Rückgabeparameter : 1 RSYNC_REAL_MODE Modusnummer Keine Beschreibung Mit dieser Funktion wird die Interrupt-Maske im SR des Prozessors entsprechend der gewünschten Arbeitsweise des Realtime-Systems gesetzt. Dazu sind in der Datei SYS68.SYS folgende zwei Modi definiert: RSYNC_MODE_STOP Prioritätsebene 7 In diesem Modus ist das Realtime-System abgeschaltet. Vom Prozessor werden keine Interrupts angenommen. RSYNC_MODE_RUN Prioritätsebene 0 Wenn dieser Modus gesetzt ist, dann ist das Realtime-System eingeschaltet. Übersicht der Prioritätsebenen Int1-Server und synch. Tasks: höchste Priorität (5) INT4-Sever und synch. Tasks: ... (3) Multitask-System : niedrichste Priorität (0) -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 47 6.3 IOC-Adresse holen TRAP #1 Funktionsnummer (D1.w): Aufrufparameter (A0.l): Rückgabeparameter (D0.l): 2 RSYNC_GET_IOCONTROL IOB-Zeiger NULL -> Fehler <>NULL -> Adr. IOCONTROL Beschreibung Der von der Funktion RSYNC_IRS_CREATE übergebene Zeiger kann nicht direkt dazu benutzt werden, Zeichen aus dem Eingabepuffer zu lesen oder auf den Port zu schreiben. Dazu muß der IOCONTROLZeiger benutzt werden, mit dem die entsprechenden I/O-Funktionen aufgerufen werden. Weitere Erklärungen stehen in der Beschreibung der System-Funktionsaufrufe RSYNC_SYS_IN und RSYNC_SYS_OUT. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 48 6.4 Anmeldung einer neuen Task TRAP #1 Funktionsnummer Aufrufparameter (D1.w): (A0.l): Rückgabeparameter (D0.l): 3 RSYNC_TASK_CREATE Adr. der TCBDEFStruktur NULL -> Fehler <>NULL -> TCB-Zeiger Beschreibung Wenn eine neue Task angemeldet werden soll, müssen alle nötigen Angaben in eine TCBDEF-Struktur geschrieben werden. Die Adresse dieser Struktur wird dann in A0.l an den Funktionsaufruf übergeben. Maximal können dem System bis zu 32 Tasks bekannt sein. Dabei wird bereits eine Task, die MainTask, bei der Systeminitialisierung automatisch angelegt. Die Task-Verwaltung ist dann jedoch noch nicht aktiv. Sie muß gesondert durch die Funktion "RSYNC_REAL_MODE" (Realtime-Modus setzen) gestartet werden. Eine neue Task darf in jedem Modus der Task-Verwaltung angemeldet werden. Ist die neue Task in die Taskverwaltungsliste eingetragen worden, gibt die Funktion einen Zeiger auf die TCB-Struktur der neuen Task zurück, der für weitere Task-Funktionsaufrufe gebraucht wird. Konnte die Anforderung nicht erfüllt werden, ist der Rückgabewert in D0.l gleich NULL. Eine Neue Task wird in den DORMANT-Status gesetzt. Sie ist damit bereit zu laufen, wird aber von der Task-Verwaltung nicht berücksichtigt. Dazu muß sie erst in den Status READY oder WAIT gesetzt werden. (Siehe Funktion RSYNC_TASK_SET_STATUS). Definition der Struktur TCBDEF TCBDEF_TASKPNTR ds.l 1 TCBDEF_PARA TCBDEF_STACK TCBDEF_NAME ds.l 1 ds.l 1 ds.l 1 Adresse der Task-Funktion Parameter an die Task Stack für die Task Zeiger zum Task-Namen -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 49 Beschreibung der Struktur TCBDEF TCBDEF_TASKPNTR Anfangsadresse eines Unterprogrammes, das als eigenständige Task laufen soll. Normalerweise läuft dieses Unterprogramm als Endlosschleife. Es kann aber auch durch einen RTS-Befehl beendet werden. Nach der Beendigung wird es von der Task-Verwaltung neu initialisiert und wieder in den DORMANTZustand gesetzt. TCBDEF_PARA Dieses Langwort wird der Task als Parameter auf dem Stack übergeben. Es steht direkt über der Rücksprungadresse der Task [4(SP)]. TCBDEF_STACK Für eine Task muß die Tiefe des Stacks, das ihr zur Verfügung stehen soll, angegeben werden. Diese Angabe erfolgt in "Anzahl der Bytes" in diesem Langwort. Falls eine ungerade Byteanzahl angefordert wird, erhöht sich die Anzahl um Eins auf die nächste Wortgrenze. Für jede Task wird vom System eine Mindesanzahl von 1024 Byte reserviert. TCBDEF_NAME Jede Task sollte einen Namen bekommen, über den sie identifiziert werden kann, wenn ihr TCB-Zeiger nicht bekannt ist. Dieser Name kann bis zu sieben Zeichen lang sein. Der Zeiger auf diesen Namen muß in diesem Langwort übergeben werden. Bei der Taskinitialisierung wird der Taskname in die Taskverwaltungsstruktur kopiert. Soll kein Name eingetragen werden, muß TCBDEF_NAME NULL sein oder auf einen NULL-String zeigen. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 50 6.5 Status einer Task ändern TRAP #1 Funktionsnummer (D1.w): Aufrufparameter (A0.l): (D0.b): Rückgabeparameter (D0.l): 4 RSYNC_TASK_ SET_STATUS Adresse der TCBStruktur Neuer Status der Task ERROR (-1) -> Fehler sonst Neuer Status Beschreibung Mit dieser Funktion kann der Zustand einer Task geändert, bzw. die Task gelöscht werden (KILL). Der Status der Main-Task kann jedoch nicht geändert werden. Eine Task kann in folgende Zustände versetzt werden: DORMANT (Label: TASK_STATUS_DORMANT) Die Task ist der Task-Verwaltung bekannt und laufbereit, bekommt aber keine Rechenzeit. Das bedeutet, daß sie nicht mit aufgerufen wird. In diesen Status wird eine Task immer bei der Initialisierung gesetzt. Sie kann jederzeit, wenn sie nicht gebraucht wird, wieder in den DORMANTZustand gebracht werden. READY (Label: TASK_STATUS_READY) Eine Task in diesem Zustand bekommt Rechenzeit, und zwar dann, wenn sie die höchste momentane Priorität erreicht hat. Hat sie die höchste Priorität nicht erreicht, dann wird ihre momentane Priorität bei dem Task-Wechsel im System um Eins erhöht. Nach ihrem Aufruf wird ihre momentane Priorität wieder auf ihre Grundpriorität eingestellt. WAIT (Label: TASK_STATUS_WAIT) Eine Task in diesem Zustand bekommt so lange keine Rechenzeit, wie sie keinen EVENT empfangen hat. Ist das jedoch der Fall, wird sie beim nächsten Taskwechsel sofort aufgerufen oder an das Ende der Warteliste gesetzt. In die Warteliste wird sie geschrieben, wenn wenigsten schon eine weitere Task auf einen EVENT gewartet hat. Die Task erhält so lange bevorzugt Rechenzeit, wie ihr Eventstatus nicht gelöscht ist. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 51 KILL (Label: TASK_STATUS_KILL) Durch diese Statusangabe wird eine Task gelöscht und aus der Task-Verwaltungsliste entfernt. Neben diesen hier aufgeführten Zuständen gibt es noch den internen Zustand RUNNING, in dem sich eine Task dann befindet, wenn sie gerade aktiv ist. Die Label sind in der Datei SYS68.SYS vereinbart. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 52 6.6 Event an eine Task senden TRAP #1 Funktionsnummer Aufrufparameter (D1.w): (A0.l): 5 (D0.b): Rückgabeparameter (D0.l): RSYNC_EVENT_SEND Adresse der TCBStruktur Event ERROR (-1) -> Fehler sonst NULL Beschreibung Als Event kann an eine Task eine Zahl von 1 bis 255 gesendet werden. Sie wird mit einer eventuell bestehenden Eintragung im Event-Register bitweise mit ODER verknüft. Wartet eine Task auf einen Event (WAIT), wird sie nach dem Empfang des Events intern in den Eventstatus gesetzt und ihr wird bei jedem Taskwechsel bevorzugt Rechenzeit zugeteilt. Wenn der Event bei der Empfangstask eingetragen werden konnte, gibt der Aufruf den Wert NULL zurück, sonst ERROR. Ein Event kann nicht eingetragen werden, wenn die Empfangstask gleichzeit die aufrufende Task (Sendetask) ist. 6.7 Event lesen TRAP #1 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter (D0.l): 6 RSYNC_EVENT_READ keine Event Beschreibung Diese Funktion ließt das Eventregister der aufrufende Task und setzt es danach auf Null. Gelesen wird ein Wert von 0 bis 255. Dabei bedeutet der Wert NULL, daß das Eventregister bereits gelesen und kein neuer Event empfangen wurde. Da der Eventstatus beim Lesen nicht gelöscht wird, bekommt die Task, falls sie sich im WAIT-Zustand befindet, weiterhin bevorzugt Rechenzeit. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 53 6.8 Eventstatus löschen TRAP #1 Funktionsnummer (D1.w): Aufrufparameter : Rückgabeparameter (D0.l): 7 RSYNC_EVENT_CLEAR keine keine Beschreibung Durch diese Funktion wird der Eventstatus der aufrufenden Task gelöscht. Befindet sich die Task im WAIT-Zustand, wird ihr beim nächsten Taskwechsel keine weitere Rechenzeit zugeteilt. Der Eventstatus kann nicht gelöscht werden, wenn noch ein Event im Eventregister eingetragen ist. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 54 7. System-Funktionsaufrufe Allgemeine System-Funktionsaufrufe werden über TRAP #2 vorgenommen. Vorher muß die den Aufruf entsprechende Funktionsnummer in das Register D1.w geladen werden. Parameter an die Funktion werden in den Registern D0.x und A0.x übergeben. Rückgabeparameter befinden sich in D0.x und dem CCR. Die Datengröße, Byte, Wort oder Langwort, hängt von der jeweiligen Funktion ab. Die Funktionsaufrufe verändern die Prozessorregister D1-D7 und A0-A7 nicht. Beispiel: Reservieren von Speicherbereich move.l #ANZAHL,D0 move #RSYNC_SYS_MALLOC,d1 trap #2 Zu reservierende Bytes Systemaufruf . . RSYNC_SYS_MALLOC ANZAHL equ equ 1 nn Übersicht der Systemfunktionen Label Nummer RSYNC_SYS_MEMINIT RSYNC_SYS_MALLOC RSYNC_SYS_FREE 0 1 2 RSYNC_SYS_IN RSYNC_SYS_OUT RSYNC_SYS_BUFFCLR RSYNC_SYS_PIPECREATE 3 4 5 6 Bezeichnung Speicherinitialisierung Speicherbereich holen Speicherbereich zurückgeben Byte einlesen Byte ausgeben Pufferinhalt löschen PIPE-Puffer erzeugen Gelesenes Zeichen zurückgeben Die Funktionsaufrufe sind in der Datei SYS68.SYS definiert. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 55 7.1 Speicherinitialisierung TRAP #2 Funktionsnummer Aufrufparameter (D1.w): (D0.l): Rückgabeparameter Beschreibung 0 : RSYNC_SYS_MEMINIT Anfang des USERSpeichers Keine Bevor mit dem Funktionsaufruf RSYNC_SYS_MALLOC Speicher vom System angefordert werden kann, muß dem System die Anfangsadresse des zur Verfügung stehen Speicherbereichs mitgeteilt werden. Diese Funktion wird vom Startmodul START68 aufgerufen. Der Bereichsanfang wird dabei auf den Anfang des uninitialisierten Datenbereichs gesetzt. Ein USER-Programm sollte diesen Funktionsaufruf normalerweise nicht benutzen. 7.2 Speicherbereich holen TRAP #2 Funktionsnummer Aufrufparameter (D1.w): (D0.l): 1 Rückgabeparameter (D0.l): RSYNC_SYS_MALLOC Benötigte Speichertiefe NULL -> Fehler <>NULL -> Speicheranfang Beschreibung Mit diesem Funktionsaufruf kann Speicher vom System angefordert werden. Dazu muß die Anzahl der benötigten Bytes in D0.l eingetragen sein. Falls diese Zahl ungerade ist, wird sie automatisch um Eins erhöht, da Speicherblöcke immer auf einer geraden Adresse beginnen müssen. Ist der angeforderte Speicherbereich vorhanden, dann wird die Adresse des ersten zu benutzen Bytes zurückgegeben, sonst NULL. 7.3 Speicherbereich zurückgeben TRAP #2 Funktionsnummer Aufrufparameter Rückgabeparameter (D1.w): (D0.l): : 2 RSYNC_SYS_FREE Adr. des Speicheranfangs Keine Beschreibung -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 56 Angeforderte Speicher kann mit dieser Funktion an das System zurückgegeben werden. Dazu muß die vorher von der Funktion RSYNC_SYS_MALLOC gelieferte Adresse in D0.l geladen werden. Ein anderer Wert kann zu einem undefinierten Systemzustand führen. 7.4 Zeichen einlesen TRAP #2 Funktionsnummer (D1.w): Aufrufparameter (A0.l): Rückgabeparameter (D0.l): 3 RSYNC_SYS_IN IOCONTROL-Zeiger ERROR (-1) -> Fehler sonst Eingabezeichen Beschreibung Mit dieser Funktion wird ein Zeichen (Byte) über einen IOCONTROL-oder FILE-Steuerblock eingelesen. Je nachdem, wie dieser Steuerblock initialisiert ist, wird entweder aus dem Puffer oder direkt vom Port mit Hilfe der im Steuerblock eingetragenen READ-Funktion gelesen. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 57 7.5 Zeichen ausgeben TRAP #2 Funktionsnummer Aufrufparameter (D1.w): (A0.l): (D0.b): Rückgabeparameter (D0.l): 4 RSYNC_SYS_OUT IOCONTROL-Zeiger Ausgabezeichen ERROR (-1) -> Fehler sonst Ausgabezeichen Beschreibung Mit dieser Funktion wird ein Zeichen (Byte) über einen IOCONTROL- oder FILE-Steuerblock ausgegeben. Je nachdem, wie dieser Steuerblock initialisiert ist, wird entweder in den Puffer oder direkt zum Port mit Hilfe der im Steuerblock eingetragenen WRITE-Funktion geschrieben. Verlief die Ausgabe erfolgreich, dann liefert die Funktion das gleiche Zeichen zurück, sonst den ERROR-Code -1. 7.6 Puffer löschen TRAP #2 Funktionsnummer (D0.w): Aufrufparameter (A0.l): Rückgabeparameter (D0.l): 5 RSYNC_SYS_BUFFCLR IOCONTROL-ZeigerKeine Beschreibung Mit dieser Funktion wird der Inhalt des Puffers, dessen IOCONTROL-Zeigers übergeben wird, gelöscht. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 58 7.7 PIPE-Puffer erzeugen TRAP #2 Funktionsnummer (D0.w): Aufrufparameter (Do.l): Rückgabeparameter (D0.l): 6 RSYNC_SYS_PIPECREATE Puffertiefe NULL -> Fehler <> NULL -> IOCONTROLZeiger Dieser Aufruf wird von einer SYNCHRONEN TASK aus nicht ausgeführt. Beschreibung Datenübertragungen von einer Task zur anderen können über Pipes durchgeführt werden. Dazu muß ein Puffer angelegt werden, in den die eine Task byteweise schreiben kann und aus dem die andere lesen kann. Dieser Puffer kann eine maximale Länge von 32kByte besitzen. Dieser Aufruf gibt, wenn er erfolgreich war, einen IOCONTROL-Zeiger zurück, sonst NULL. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 59 8. Einzelne Funktionsaufrufe Über reservierte TRAPs können einzelne, besondere Funktionen schnell ohne großen Verwaltungsaufwand im System aufgerufen werden. 8.1 TRAP 15 Taskwechsel erzwingen Assemblerbefehl: TRAP #15 Dieser Aufruf wird von einer SYNCHRONEN TASK aus nicht ausgeführt. Mit diesem Befehl führt das System einen Taskwechsel durch. Dieser Wechsel kann auch erzwungen werden, wenn der Realtime-Modus auf STOP gesetzt ist. -----------------------------------------------------------------(C)Heiner Jaap RSYNC68 Seite 60