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