Wenn der Atari ST mit der Gabi anbandelt (Teil 2)

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:

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.

Erläuterung: Der linke Rand wird auf die Position gesetzt, auf der gerade der Druckschlitten steht.

Erläuterung: Die Schreibwalze wird um eine halbe Grundzeile zurückgedreht, wodurch ein Hochstellen der Zeichen auf dem Papier erfolgt.

Erläuterung: Die Schreibwalze wird um eine halbe Grundzeile vorgedreht, wodurch ein Tiefstellen der Zeichen auf dem Papier erfolgt.

Erläuterung: Die Schreibwalze wird entsprechend dem eingestellten Zeilenabstand eine Zeile zurückbewegt.

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.

Erläuterung: Alle nachfolgenden Zeichen werden wieder ohne Fettdruck abgedruckt.

Erläuterung: Bei allen nachfolgenden Zeichen wird zusätzlich zum Zeichenabdruck auch ein Unterstreichstrich abgedruckt.

Erläuterung: Alle nachfolgenden Zeichen werden wiederohne Unterstreichen abgedruckt.

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

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


Wilfried Keller
Aus: ST-Computer 08 / 1988, Seite 139

Links

Copyright-Bestimmungen: siehe Über diese Seite