In der heutigen Ausgabe wollen wir uns weiter mit der Verbindung von ATARI ST und TA-Gabriele 9009 bzw. kompatiblen Schreibmaschinen beschÀftigen. Doch bevor wir uns in das Reich der Bits und Bytes begeben, möchte ich die Aufgabenstellung definieren:
Gesucht wird ein Programm, das im Auto-Ordner mitgebootet wird und sich resistent im Speicher hĂ€lt. Dieses Programm âverbiegtâ die Druckerausgabe auf eine Routine, die die spezielle Aussteuerung der Schreibmaschine entsprechend der in der letzten Ausgabe aufgefĂŒhrten Befehlssequenzen realisiert.
AuĂerdem installiert es eine Interruptroutine, die dafĂŒr sorgt, daĂ die Schreibmaschine ĂŒber die entsprechenden Tasten von der Schreibmaschinentastatur aus zwischen den BetriebszustĂ€nden ONLINE und OFFLINE umgeschalten werden kann.
Das Programm sorgt auch fĂŒr die Verwaltung der Druckschlittenposition und fĂŒr die Realisierung einiger spezieller Funktionen.
Alle diese nachfolgend aufgelisteten Funktionen werden durch Codes bzw. Sequenzen gesteuert, die vollkompatibel zur Original-Interfacebox von TA sind. Dadurch ist es möglich, einen entsprechenden Druckertreiber mitzuverwenden. Es ist durch Ănderungen im Programm aber auch möglich, eine Anpassung an beispielweise EPSON-Sequenzen zu erreichen.
ASCII-Code-Befehle
Folgende Steuerzeichen innerhalb des ASCII-Codes werden von der Druckroutine erkannt und realisiert:
- 08H : Backspace: Der Druckschlitten wird um eine Schreibteilung nach links bewegt.
- 0AH : Linefeed: Dieser Code löst das Weiterschalten der Schreibmaschine um eine Zeile aus.
- 0CH : Form Feed: Dieser Befehl fĂŒhrt ĂŒblicherweise dazu, daĂ das Papier zum Anfang der nĂ€chsten Seite transportiert wird (Endlospapier). Da die Schreibmaschine allerdings nur Einzelblattverarbeitung erlaubt, wurde die Funktion im Programm so realisiert, daĂ die Schreibmaschine beim Auftreten des Befehls in den OFFLINE-Modus geschaltet wird. Sie wartet dann, bis ein neues Blatt eingespannt und ĂŒber die ONLINE-Taste auf der Schreibmaschinentastatur das Weiterdrucken veranlaĂt wurde.
- 0DH : Carriage Return: Der Druckschlitten wird zum linken Rand zurĂŒckbewegt.
- 1BH: ESCAPE: Erstes Byte einer folgenden Befehlssequenz.
- 20H: Space: Leerzeichen entsprechend der eingestellten Schreibteilung. Um eine Geschwindigkeits-Optimierung bei mehreren aufeinanderfolgenden Leerzeichen zu erreichen, werden diese nicht einzeln ausgefĂŒhrt, sondern zu einer schnelleren direkten Bewegung zusammengefaĂt.
Andere Kontrollbytes. die im Bereich der ASCII-Codes bis 20H (z.B. DCI/3 oder HT) liegen, werden ĂŒblicherweise nicht benutzt und deshalb von unserem Programm einfach unterdrĂŒckt.
ESCAPE-Sequenzen
Unter ESC-Sequenz versteht man eine Reihenfolge von Steuerbefehlen, die mit einem ESC-Zeichen (=1BH) beginnen und druckerspezifische Funktionen (z.B. VerĂ€nderung der Schreibteilung) steuern. Leider sind diese Sequenzen fĂŒr die verschiedenen Drucker nicht standardisiert. Unser Programm richtet sich nach den von der Original-Interfacebox vorgegebenen ESC-Sequenzen. Allerdings wurde nur eine Untermenge der von der IFD1 vorgegebenen Sequenzen realisiert, jedoch genĂŒgen diese, um eine leistungsfĂ€hige FunktionalitĂ€t zu erreichen.
- ESC 9 (= 1BH + 39H): Linken Rand setzen
ErlÀuterung: Der linke Rand wird auf die Position gesetzt, auf der gerade der Druckschlitten steht.
- ESC D (= 1BH + 44H): Hochstellen
ErlĂ€uterung: Die Schreibwalze wird um eine halbe Grundzeile zurĂŒckgedreht, wodurch ein Hochstellen der Zeichen auf dem Papier erfolgt.
- ESC U (= 1BH + 55H): Tiefstellen
ErlÀuterung: Die Schreibwalze wird um eine halbe Grundzeile vorgedreht, wodurch ein Tiefstellen der Zeichen auf dem Papier erfolgt.
- ESC LF (= 1BH + 0AH): Linefeed rĂŒckwĂ€rts
ErlĂ€uterung: Die Schreibwalze wird entsprechend dem eingestellten Zeilenabstand eine Zeile zurĂŒckbewegt.
- ESC W (= 1BH + 57H): Fettschrift einschalten
ErlĂ€uterung: Alle anschlieĂenden Zeichen werden in Fettdruck dargestellt. Dies erfolgt dadurch, daĂ jedes Zeichen zweimal abgeschlagen und zwischen den AnschlĂ€gen eine minimale Horizontalbewegung (1/120â) ausgefĂŒhrt.
- ESC & (= 1BH + 26H): Fettschrift ausschalten
ErlÀuterung: Alle nachfolgenden Zeichen werden wieder ohne Fettdruck abgedruckt.
- ESC E(= 1BH + 45H): Unterstreichen einschalten
ErlÀuterung: Bei allen nachfolgenden Zeichen wird zusÀtzlich zum Zeichenabdruck auch ein Unterstreichstrich abgedruckt.
- ESC R(= 1BH + 52H): Unterstreichen ausschalten
ErlÀuterung: Alle nachfolgenden Zeichen werden wiederohne Unterstreichen abgedruckt.
- ESC US x (= 1BH + 0BH + x): Schreibteilung setzen auf x-Schritte
ErlĂ€uterung: Die Schreibteilung wird auf 12(12 Zeichen pro Zoll) vorbesetzt. Mit dieser Sequenz ist es möglich, die Schreibteilung im Bereich von 1/120" bis 255/120â-Schritten einzustellen.
Die Sequenzdefinition der Interface-Box sagt aus unerklĂ€rlichen GrĂŒnden, daĂ als Schrittzahl (x + 1) ĂŒbergeben werden muĂ.
Nachfolgend ist die Zuordnung der Schrittzahlen zu den gebrĂ€uchlichsten Schreibteilungen aufgefĂŒhrt:
Schreibteilung Schrittzahl X
10 13
12 11
15 9
6 23
- ESC RS x(= 1BH + 1EH + x): Zeilenabstand setzen auf (x + 1) Schritte ErlĂ€uterung: Der Zeilenabstand ist auf die genormte Grundzeile von 1/6â voreingestellt. Durch die Sequenz ist es möglich, den Zeilenabstand zwischen 1/96â und 255/96" einzustellen. FĂŒr die Grundzeile st als x beispielsweise der Wert 17 einzusetzen.
Absichtlich nicht realisiert wurden die ESC-Sequenzen fĂŒr bidirektionalen Druck (Druck links - rechts - links usw.), da die Schreibmaschine Gabriele 9009 zwar prinzipiell von rechts nach links drucken kann, jedoch aus internen GrĂŒnden nach jedem Schritt nach links eine seltsame RĂŒttelbewegung ausfĂŒhrt Damit wird der durch den bidirektionellen Druck gewonnene Zeitvorteil mehr als aufgebraucht.
Nicht verwirklicht wurde auch die Funktion Proportionaldruck. Proportionaldruck bedeutet, daĂ jedem Zeichen ein spezifischer Horizontalabstand zugeordnet ist; der Abstand zwischen âiâ ist somit viel schmaler als zwischen âMâ. Wir haben auf die Realisierung der Funktion verzichtet, da diese nur in Zusammenarbeit mit speziellen TypenrĂ€dern ansprechende Ergebnisse bringt und andererseits groĂen Aufwand im Programm sowie in entsprechenden Treibern bedeutet hĂ€tte.
Das nachfolgende aufgelistete Programm wurde inAssembler erstellt, um möglichst âmaschinennah" arbeiten zu können. Die enthaltenen Kommentare sollten genĂŒgen, die verschiedenen Programmabschnitte nachvollziehbar zu machen. Es wird somit auch möglich sein, bei Bedarf kleinere Modifikationen einzubringen.
Da der ATARI ST ĂŒber die serielle Schnittstelle wĂ€hrend des Hochlaufs oft Undefiniertes aussendet, ist es sinnvoll, die angeschlossene Schreibmaschine erst nach abgeschlossenem Boot-Vorgang einzuschalten. Denn empfĂ€ngt die Schreibmaschine Zeichen, mit denen sie nichts anfangen kann, ignoriert sie diese nicht immer, sondern stĂŒrzt manchmal auch ab, was nur durch erneutes Aus-/ Einschalten der Schreibmaschine behoben werden kann.
Bevor man mit dem Drucken beginnen kann, muà man die Schreibmaschine durch BetÀtigen der ONL-Taste (oder entsprechende Tastenkombination) auf ONLINE schalten.
Obwohl die serielle Verbindung physika-Hsch ĂŒber die V.24-Schnittstelle erfolgt,ist als logische Schnittstelle die voreingestellte Parallelschnittstelle zu verwenden. FĂŒr WORDPLUS-Benutzer habe ich noch einen kleinen Treiber erstellt. der die vorgenannten ESC-Sequenzen beim Ausdrucken automatisch ansteuert.
Eine Code-Umsetzung der Schreibzeichen ist nicht erforderlich, da unser "IFD-EMULATOR" schon alle druckfÀhigen Zeichen ansteuert.
*****************************************************************
* *
* Nachbildung der INTERFACEBOX IFD1 durch Software im ST *
* (Einsatz des deutschen Typenrades Grp. 01) *
* *
* Diese Datei enthĂ€lt Tabellen bezĂŒglich der CODE SEQUENZEN und *
* des Zeichensatzes. Dadurch ist es möglich, die verschiedenen *
* Funktionen und den Zeichensatz anzupassen. *
* *
*****************************************************************
*
* Name of printer
* ===============
*
IFD 1 - Emulator
*
* Miscellaneous configurable variables
* ====================================
*
* 1: printer type, 0=dot matrix, 1=daisy wheel
* Note if printer type is 0 the following 4 variables are never used.
* 2: unit width of one character
* 3: unit height of one line
* 4: Approximate middle of carriage after formfeed
* 5: Carriage shift for bold overstrike
*
0,0,0,0, 0,0
*
* Printer characteristics
* =======================
*
* This table specifies the printer command sequences.
* If the top bit of a code is set, then this indicates the position
* of a parameter passed to the printer. The code whose top bit is set
* in this table is added to the parameter passed before being sent to the
* printer. It is not used in all command sequences, only in those where
* the printer requires a variable value such as the length of a vertical
* tab.
*
* 0 * Character width
1, D, A * Linefeed WITH return
* 2 * Forward print
* 3 * Reverse print
* 4 * Vertical tab to line
* 5 * Absolute horizontal tab
6 * Draft bold on
7 * Draft bold off
8, 1B, 57 * Near Letter Quality (NLQ) bold on
9, 1B, 26 * NLQ bold off
A * Draft italic on
B * Draft italic off
C * NLQ italic on
D * NLQ italic off
E * Draft light on
F * Draft light off
* 10, 1B, 78, 0 * NLQ light on
* 11, 1B, 78, 1 * NLQ light off
12, 1B, 44 * Draft superscript on
13, 1B, 55 * Draft superscript off
14, 1B, 44 * NLQ superscript on
15, 1B, 55 * NLQ superscript off
16, 1B, 55 * Draft subscript on
17, 1B, 44 * Draft subscript off
18, 1B, 55 * NLQ subscript on
19, 1B, 44 * NLQ subscript off
1A
1B * Draft underline off
1C, 1B, 45 * NLQ underline on
1D, 1B, 52 * NLQ underline off
1E, 0C,0D * Formfeed
1F, 12 * Horizontal Initialisation
20,0D * Termination: printer reset
21,0D * Termination: printer reset
22,08 * Backspace
23,13 * Carriage Return
* 24 * Form length in lines
* 25 * Set line feed to N units
* 26 * Start graphics (mode 0)
* 27 * Reserved
28,1B,1F,0D * Draft Pica (10 cpi)
29,1B,IF,0D * NLQ Pica (10 cpi)
2A,1B,IF,0B * Draft Elite (12 cpi)
2B,1B,1F,0B * NQL Elite (12 cpi)
2C,1B,1F,9 * Draft Condensed (15 cpi)
2D,1B,1F,9 * NQL Condensed (15 cpi)
2E,1B,1F,15 * Draft Expanded (6 cpi)
2F,1B,1F,15 * NQL Expanded (6 cpi)
* 30 * Black ink
* 31 * Magenta ink
* 32 * Cyan ink
* 33 * Yellow ink
0 * NULL termination byte
*
* Translation Table
* =================
*
* Diese Tabelle ĂŒbersetzt einfache ATARI Eingangscodes in vielfache
* Druckercodes, dies ermöglicht den Entwurf eines erweiterten Zeichen-
* satzes usw. .
*
* Da der Zeichensatz schon vom Steuerprogramm verwirklicht wird, ist es
* hier nicht nötig, nochmals eine Ăbersetzung durchzufĂŒhren.
Abb. 1: Tabelle der CODE-SEQUENZEN
*******************************************************
* IFD 1 - EMULATOR fĂŒr ATARI ST *
* *
* Diese Routine verbiegt d.Druckerausgabe a.ein Kon- *
* vertierprogramm, das d.ASCII-Code i.f. die Schreib- *
* maschine Gabriele 9009 verstÀnd1.Steuerbefehle um- *
* setzt. Die Kommunikation m.d.Schreibmaschine erfolgt*
* o.Spooler-Pufferung ĂŒ.d.serielle V.24-Verbindung. *
*******************************************************
move.b #16,zeile
move.b #10,teilung
move.l 4(sp),a0 ; Groesse des Programms
move.l #$100,d6 ; berechnen
add.l 12(a0),d6
add.l 20(a0),d6
add.l 28(a0),d6
move.l d6,-(sp) ; Ergebnis auf Stack Zwischenlagern
clr.l -(sp) ; In SUPER-Modus schalten
move.w #$20,-(sp)
trap #1
add.l #6,sp
move.l d0,-(sp) ; Alten Stack merken
move.l #trap13,-(sp) ; TRAP13 "verbiegen"
move #45,-(sp)
move #5,-(sp)
trap #13
addq.l #8,sp
move.l d0,tr_save ; alte Sprungadresse merken
move.l #em_int,-(sp) ; Interruptroutine installieren,
move.w #12,-(sp) ; die ausgelöst wird, wenn von der SM ein
move #13,-(sp) ; Zeichen empfangen wurde
trap #14 ; -> Offline - Online
addq.l #8,sp
bsr init ; Intialisierungsroutine
move.l (sp)+,d1 ; In USER-Modus zurueckschalten
move.l d0,-(sp)
move.w #$20,-(sp)
trap #1
addq.l #6,sp
move.l (sp)+,d6 ; Programmgroesse zurĂŒckholen
clr -(sp) ; Programm im Speicher halten
move.l d6,-(sp)
move #$31,-(sp)
trap #1
trap13: move.l sp,a2 ; neue Trap 13-Routine
btst #5,(sp) ; jetzt abprĂŒfen, ob
bne super ; Druckerangesprochen ist
move.l usp,a2
subq #6,a2
super: cmp #3,6(a2)
bne normal ; wenn nicht â> alte Routine
cmp #0, 8(a2)
bne normal
movem.l d1-d7/a0-a6,-(sp)
move.l $4a2,a1
move (sp)+,-(a1)
move.l (sp)+,-(a1)
move.l a1,$4a2 ; Drucker ist gemeint auszu-
move 10(a2),d1 ; gebendes Zeichen nach d1
move #$2700,sr
cmp.w #0,esc_flag ; Folgebyte in ESC-Sequenz?
bne esc_folg ; Ja â> verzweigen
cmp.b #$20,d1 ; Druckbares Zeichen?
bls so_zei ; Nein â> verzweigen
cmp.w #0,step_li ; Sind noch Leerschritte nachzuholen?
bne spa_nach ; Ja â> verzweigen
drck: lea zei_satz,a2 ; Adresse f.Tabelle nach a1
and.1 #$FFFF,d1
sub.w #$21,d1 ; Offset von ASCII-Code subtrahieren
lsl.w #1,d1 ; Rest mit 2 multiplizieren
add.l d1,a2 ; Als Offset zu Tabellenzeiger addieren
cmp.w #0,son_flag ; Ist eine Sonderfunktion eingeschaltet ?
bne so_druck ; Ja â> verzweigen
narma: move.b (a2)+,d1 ; Typenrad-Code aus Tabelle
bsr print ; holen und an SM senden
move.b (a2),d1 ; Abschlag-Code aus Tabelle
bsr print ; holen und an SM senden
gedr: move.b teilung,d0
and.w #$FF,d0
add.w d1,spalte ; Spaltenzaehler inkrem,
moveq #-1,d0 ; kein Fehler aufgetreten
bra exit ; Aussprung
spa_nach: ; Umwandeln von vorher nicht ausgedruckten
move.l d1,-(sp) ; Leerschritten in Direktbewegung
move.w step_li,d1 ; Anzahl der auszufĂŒhrenden Leerschritte
lsr #8,d1
bset #7,d1 ; Befehl fĂŒr SM bilden
bset #6,d1
bclr #5,d1
bclr #4,d1
bsr print
move.w step_li,d1 ; High_byte fĂŒr direkte Bewegung
bsr print
move.w #0,step_li ; Low_byte fĂŒr direkte Bewegung
move.l (sp)+,d1
bra drck ; zurĂŒck â> normal drucken
so_druck:
move.l a2,a4
btst #1,son_flag ; unterstreichen eingeschaltet?
beq fett ; Nein â> Weiter mit Fettdruck-Abfrage
move.b #$33,d1 ; Typenradcode fĂŒr bsr print
move.b #$10,d1 ; Abschlagscode und Totzeichenkennung
bsr print
fett: btst #2,son_flag ; fett eingeschaltet?
beq narma ; Nein â> Normal weiter
move.b (a2)+,d1 ; Typenradcode aus Tabelle holen
bsr print
move.b (a2),d1 ; Abschlagscode aus Tabelle holen
bclr #7,d1 ; Horizontalbewegung unterdrĂŒcken
bsr print
move.b #$83,d1 ; Mikrostep (1/120") ausfĂŒhren
bsr print
move.b #1,d1
bsr print
move.b (a2),d1 ; War es wirklich ein druckbares Zeichen
cmp.b #0,d1
beq gedr ; Nein â> Aussprung
sub.l #1,a2 ; Ja â> Zeichen nochmal drucken
bra narma
esc_folg:
cmp.w #1,esc_flag
bne esc_3byt ; 3. oder 4. Byte einer ESC-Folge
move.w #0,esc_flag
cmp.b #$39,d1 ; Linken Rand setzen?
beq li_rand ; Ja â> verzweigen
cmp.b #$44,d1 ; Hochstellen?
beq hochst ; Ja â> verzweigen
cmp.b #$55,d1 ; Tiefstellen?
beq tiefst ; Ja â> verzweigen
cmp.b #$0A,d1 ; ZeilenrĂŒckschritt?
beq lf_back ; Ja â> verzweigen
cmp.b #$45,d1 ; Unterstreichen ein?
beq unt_ein ; Ja â> verzweigen
cmp.b #$52,d1 ; Unterstreichen aus?
beq unt_aus ; Ja â> verzweigen
cmp.b #$57,d1 ; Fettdruck ein?
beq fett_ein ; Ja â> verzweigen
cmp.b #$26,d1 ; Fettdruck aus?
beq fett_aus ; Ja â> verzweigen
cmp.b #$1F,d1 ; HMI setzen?
beq hmi1 ; Ja â> verzweigen
cmp.b #$05,d1 ; VMI setzen?
beq vmi1 ; Ja â> verzweigen
bra exit ; andere ESC-Sequenzen kenn ich nicht!!!
esc_3byt:
cmp.w #2,esc_flag ; HMI-Sequenz?
bne vmi2 ; Nein â> verzweigen
subq.b #1,d1 ; HMI = N-1
move.b d1,teilung ; Neue Teilung merken
move.b #$80,d4 ; Neue Teilung an SM schicken
bsr senden
move.b teilung,d4
bsr senden
move.w #0,esc_flag ; Flag löschen
bra exit
vmi2: cmp.w #3,esc_flag ; VMI-Sequenz?
move.w #0,esc_flag ; Flag löschen
bne exit ; Nein â> dann unbekannt
subq.l #1,d1 ; VMI = N-l
move.b d1,zeile ; Neue Schrittzahl fĂŒr LF merken
bra exit
li_rand: move.w #0,spalte ; SpaltenzÀhler auf Null setzen
bra exit
hochst: move.w #$f0,d1 ; Vertikale Bewegung um 8/96"
bsr print ; = 0,5 Grundzeilen zurĂŒck
move.w #8 ,d1
bsr print
bra exit
tiefst: move.w #$D0,d1 ; Vertikale Bewegung um 8/96"
bsr print ; = 0,5 Grundzeilen vorwÀrts
move.w #8,d1
bsr print
bra exit
lf_back: move.w #$f0,d1 ; Vert.Bewegung u.normalerweis«
bsr print ; 16/96" = 1 Grundzeile zurĂŒck
move.b zeile,d1
bsr print
bra exit
unt_ein: bset #1,son_flag ; Bit 1 fĂŒr Unterstreichen setzen
bra exit
unt_aus: bclr #1,son_flag ; Bit 1 fĂŒr Unterstreichen löschen
bra exit
fett_ein: bset #2,son_flag ; Bit 2 fĂŒr Fettschrift setzen
move.b #$80,d1 ; Horizontalschritt auf Teilung-1
bsr print ; Teilung-1 anpassen
move.b teilung,d1
subq.b #1,d1
bsr print
bra exit
fett_aus: bclr #2,son_flag ; Bit 2 fĂŒr Fettschrift löschen
move.b #$80,d1 ; Horizontalschritt auf
bsr print ; eingestellte Teilung
move.b teilung,d1 ; anpassen
bsr print
bra exit
hmi1: move.w #2,esc_flag ; Flag fĂŒr HMI-Sequenz setzen
bra exit
vmi1: move.w #3,esc_flag ; Flag fĂŒr VMI-Sequenz setzen
bra exit
; Abfrage nach Sonderzeichen
so_zei: cmp.b #$20,d1 ; ASCII-Code = 32
beq space ; Ja â> Leerschritt
cmp.b #13,d1 ; ASCII-Code = 13
beq cr ; Ja â> Carriage Return
cmp.b #10,d1 ; ASCII-Code = 10
beq lf ; Ja â> Linefeed
cmp.b #$1B,d1 ; ASCII-Code = 27
beq esc ; Ja â> ESC-Zeichen â> Flag setzen
cmp.b #8,d1 ; ASCII-Code = 8
beq backsp ; Ja â> Backspace
cmp.b #12,d1 ; ASCII-Code = 12
beq formfeed ; JA â> Formfeed
bra exit ; Andere Sonderzeichen kenn ich nicht
esc: move.w #1,esc_flag / Flag fĂŒr erstes Byte aus Sequenz setzen
bra exit
space:
move.b teilung,d1 ; Leerschritt nicht direkt ausfĂŒhren,
and.l #$FF,d1 ; sondern fĂŒr spĂ€ter zusammenfassen
add.w d1,step_li ; und in "step_li" merken
add.w d1,spalte
bra exit
backsp: move.w #$84,d1 ; Leerschritt nach links â> direkt ausfĂŒhren
bsr print ; direkt ausfĂŒhren
move.b teilung,d1
and.w #$ff,d1
sub.w d1,spalte
move.w #0,d1
bsr print
bra exit
cr: move.w spalte, d0 ; Carriage-Return ausfĂŒhren, dabei auch
; noch nicht ausgefĂŒhrte Leerschritte
sub.w step_li,d0 ; berĂŒcksichtigen
move.w # 0,step_li
or.w #$e000,d0
move.w d1,d1
lsr #8,d1
move.w d1,-(sp)
bsr print
move.w (sp)+,d1
and.w #$FF,d1
bsr print
move.w #0,spalte ; SpaltenzĂ€hler zurĂŒcksetzen
bra exit
lf: move.w #$D0,d1 ; Linefeed ausfĂŒhren, Anzah]
bsr print ; der Schritte steht in #zei1
move.b zeile,d1
bsr print
bra exit
formfeed:
move.b #$a3,d1
bsr print
move.b #0,d1
bsr print
wait: bsr lesen
cmp.b #1,d5
bne wait
move.b #$a2,d1
bsr print
move.b #0,d1
bsr print
bra exit
exit :
move.w onl_flag,d0
cmp.w #1,d0
bne probl
moveq #-1,d0
bra exit1
probl: moveq #0,d0
exitl: move.l $4a2,a1
move.l (a1)+,-(sp)
move (a1)+,-(sp)
move.l a1,$4a2
movem.l (sp)+,d1-d7/a0-a6
move #$2300,sr
rte
normal:
cmp #8,6(a2)
bne norml
cmp #0,8(a2)
bne norm1
moveq #-1,d0
move.w onl_flag,d2
cmp.w #1,d2
bne probl1
movea.l #$fffa01,a3
move.b (a3),d2
btst #2,d2
beq platz
probll: moveq #0,d0
platz: rte
norm1: move.l tr_save,a0
jmp (a0)
print: move.b d1,d4
bsr senden
rts
; ****************************************************
em_int: ; Interrupt-routine, die von
move #$2700,sr ; der SM ausgelöst wird
MOVEM.L D0-D6/A0-A3,-(SP)
bsr lesen ; Empfangenes Zeichen lesen
cmp.b #1,d5 ; Wurde die Online-TastegedrĂŒckt?
bne nionline ; Nein â> weitere Abfrage
move.w onl_flag,d5 ; Ist die SM schon ONLINE?
cmp.w #1,d5
beq ni_line ; Ja â> nichts machen
bsr online ; Nein â> Online schalten
move.w #1,onl_flag ; Flag setzen
bra fertig
nionline:
cmp.b #2,d5 ; Wurde die OFFLINE-Taste gedrĂŒckt'
bne ni_line ; Nein â> nichts machen
move.w onl_flag,d5 ; Ist SM noch OFFLINE?
cmp.w #0,d5
beq ni_line ; Ja â> nichts machen
bsr offline ; Nein â> Offline schalten
bsr offline
move.w #0,onl_flag ; Flag zurĂŒcksetzen
bra fertig
ni_line:
move.b #0,d4 ; zwei "dummy-Zeichen" senden
bsr senden
move.b #0,d4
bsr delay2
bsr senden
bsr delay2
fertig:
move.l #$FFFA0F,a0 ; Interrupt-Service-Bit löschen
bclr #4,(a0)
movem.l (sp)+,d0-d6/a0-a3
move #$2300,sr
rte
online:
MOVEM.L D0-D7/A0-A4,-(SP)
bsr raus
bsr delay2
lea onl_tab,a1
move.l #tab_end-onl_tab-1,d0
loop9:
move.b (a1)+,d4
bsr senden
bsr delay1
move.b #0,d4
bsr senden
bsr delay2
bsr raus
dbra d1,loop9
movem.l (sp)+,d1-d7/aO-a4
bsr delay2
move.b #$82,d4
bsr senden
bsr delay1
move.b #$lF,d4
bsr senden
bsr delay2
move.b #$80,d4
bsr senden
bsr delay1
move.b teilung,d4
bsr senden
bsr delay2
move.w #0,spalte
move.w #0,esc_flag
move.w #0,son_flag
rts
**************************************************
offline:
lea offl_tab, a1
move.w #tab_end2-offl_tab-1,d0
move.w #0,d6
loop1: move.b (a1)+,d4
bsr senden
bsr delay2
dbra d1,loop1
rts
**************************************************
senden:
movea.l #$fffa01,a3
move.b (a3),d7
btst #2,d7
bne senden
send1:
movea.l #$fffa2f,a3
move.b d4,(a3)
send2:
movea.l #$fffa01,a3
move.b (a3),d7
btst #2,d7
beq send2
rts
lesen:
move.w #100,d6
les1: sub #1,d6
cmp.w #0,d6
beq raus
movea.l #$fffa2b,a3
move.b (a3),d5
and.w #$80,d5
cmp.b #0,d5
beq les1
raus:
movea.l #$FFFa2F,a3
move.b (a3),d5
and.l #$FF,d5
rts
delay1:
move.l d0,-(sp)
move.l #$3fff,d0
loop2:
dbra d1,loop2
move.l (sp)+,d0 rts
delay2:
move.l d0,-(sp)
move.l #$ffff,d0
loop3:
move.l d1,d1
move.l d1,d1
dbra d1,loop3
move.l (sp)+,d0
rts
init:
move.w #-1,-(sp)
move.w #-1,-(sp)
move.w #-1,-(sp)
move.w #-1,-(sp)
move.w #2,-(sp)
move.w #2,-(sp)
move.w #15,-(sp)
trap #14
add.l #14,sp
move.w #1,-(sp)
move.w #26,-(sp)
trap #14
addq.l #4,sp
move.w #10,-(sp)
move.w #26,-(sp)
trap #14
addq.l #4,sp
move.w #9,-(sp)
move.w #26,-(sp)
trap #14
addq.l #4,sp
move.w #11,-(sp)
move.w #26,-(sp)
trap #14
addq.l #4,sp
rts
move.w #2,-(sp)
move.w #26,-(sp)
trap #14
addq.l #4,sp
.data
onl_tab:
dc.b $A1, $A4, $A2, 0
tab_end:
move.w d1,d1
offl_tab:
dc.b $A3,0,$A0,0
tab_end2:
move.w d0,d0
onl_flag: dc.w 0
zei_satz:
dc.b $3E,$92 ; !
dc.b $2B,$90
dc.b $4C,$99 ; #
dc.b $27,$97 ; $
dc.b $43,$97 ; %
dc.b $22,$99 ; &
dc.b $0E,$8C
dc.b $3A, $92 ; (
dc.b $31,$92 ; )
dc.b $29,$92 ; *
dc.b $0F,$90 ; +
dc.b $02,$8E
dc.b $03,$8E
dc.b $01,$8C
dc.b $3C,$92 ; /
dc.b $19,$94 ; 0
dc.b $10,$94 ; 1
dc.b $11,$94 ; 2
dc.b $12, $94 ; 3
dc.b $13,$94 ; 4
dc.b $14,$94 ; 5
dc.b $15,$94 ; 6
dc.b $16,$92 ; 7
dc.b $17,$97 ; 8
dc.b $18,$94 ; 9
dc.b $36,$90
dc.b $35, $90
dc.b $4A,$92 ; <
dc.b $34,$92
dc.b $0D,$92 ; >
dc.b $2D,$94 ; ?
dc.b $40,$99 ; §
dc.b $24,$99 ; A
dc.b $1C,$99 ; B
dc.b $2A,$97 ; C
dc.b $2C,$99 ; D
dc.b $1A,$97 ; E
dc.b $1D,$94 ; F
dc.b $45,$99 ; G
dc.b $39,$97 ; H
dc.b $2F,$92 ; I
dc.b $42, $94 ; J
dc.b $3B,$97 ; K
dc.b $26,$94 ; L
dc.b $37,$99 ; M
dc.b $2E,$99 ; N
dc.b $3D,$99 ; O
dc.b $1E,$99 ; P
dc.b $41,$99 ; Q
dc.b $28,$99 ; R
dc.b $1F,$97 ; S
dc.b $25,$94 ; T
dc.b $30,$99 ; U
dc.b $21,$94 ; V
dc.b $32,$99 ; W
dc.b $3F,$94 ; X
dc.b $23,$94 ; Y
dc.b $20,$97 ; Z
dc.b $3A,$92 ; ( fĂŒr [
dc.b $29,$92 ; ; fĂŒr \
dc.b $31,$92 ; ) fĂŒr ]
dc.b $0C,$8C
dc.b $33,$90
dc.b $48,$8C
dc.b $5E,$94 ; a
dc.b $62,$97 ; b
dc.b $58,$92 ; c
dc.b $60,$97 ; d
dc.b $5D,$94 ; e
dc.b $0B,$92 ; f
dc.b $59,$97 ; g
dc.b $57,$94 ; h
dc.b $5F,$92 ; i
dc.b $07,$92 ; j
dc.b $55,$94 ; k
dc.b $05,$92 ; 1
dc.b $06,$97 ; m
dc.b $5A,$94 ; n
dc.b $63,$94 ; o
dc.b $56,$97 ; p
dc.b $4F,$97 ; q
dc.b $5B,$92 ; r
dc.b $5C,$94 ; s
dc.b $4D,$92 ; t
dc.b $61,$94 ; u
dc.b $04,$92 ; v
dc.b $08,$94 ; w
dc.b $4E,$92 ; x
dc.b $54,$94 ; y
dc.b $64,$92 ; z
dc.b $3A,$92 ; (
dc.b $2F,$92 ; I
dc.b $31,$92 ; )
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $51, $97 ; ĂŒ
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $53,$97 ; À
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $4b,$99 ; Ă
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $52,$97 ; ö
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $49,$99 ; Ă
dc.b $47,$99 ; O
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $1B,$99 ; pfund
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $50,$97
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $50,$97 ; P
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
dc.b $83,0 ; nicht auf TR vorhanden
buffer= 0
len= 4
head= 6
tail= 8
.bss
step_li: ds.w 1
step_re: ds.w 1
spalte: ds.w 1
esc_flag: ds.w 1
son_flag: ds.w 1
tr_save: ds.1 1
zeile: ds.b 1
teilung: ds.b 1
end
Listing : Der IFD-Emulators fĂŒr TA Gabriele 9009 in Assembler