;	CE50.MAC

;	- waehlt den USER-Drucker im IOBYTE (Adr.03),
;	- initialisiert die Centronics-Schnittstelle (Ports 24/26 bzw. 25/27)
;	  fuer die Druckausgabe auf der Typenradschreibmaschine Brother CE50,
;	- synchronisiert die CE50,
;	- initialisiert die CE50, indem sie die fuer ASCII-Ausgabe noetige 
;	  Umcodierung der Tastatur ausgeschaltet. Fuer normalen Schreib-
;	  betrieb ist die CE50 deshalb aus- und wieder anzuschalten.
;	- patcht die Treiberroutine CELIST in die User Patch Area.
;	  CELIST gibt das Zeichen in Reg. C "serialisiert" ueber den Parallel-
;	  Port aus (8 Bits, hoechstwertiges Bit zuerst). Esc (1B Hex) ver-
;	  hindert die Umcodierung des naechsten Zeichens und kann deshalb
;	  zur Einleitung eines Steuerbytes verwendet werden.
;	  CELIST veraendert lediglich den Akku.
;	- patcht die Status-Abfrage der CE50 in die User Patch Area.

;	02.03.1986

	.Z80
	ENTRY CE50

;-------------- Konstanten und Variablen

	IOBYTE	EQU 3		;ADRESSE DES IOBYTES
	BDOS	EQU 5		;EINSPRUNG INS BDOS
	USRLST	EQU 0DAE6H	;ANFANG DES USER PATCH

	PIOAD	EQU 24H		;PIO-A DATA PORT
	CONT	EQU 24H		;BEDIENT CE-STEUERSIGNALE (UND EINGABEDATEN)
	PIOAC	EQU 26H		;PIO-A CONTROL PORT
	PIOBD	EQU 25H		;PIO-B DATA PORT
	DATA	EQU 25H		;BEDIENT CE-AUSGABEDATEN
	PIOBC	EQU 27H		;PIO-B CONTROL PORT

	;Bitpositionen
	SI	EQU 0		;BIT0 DATENBIT
	SCK	EQU 0		;BIT0 CE-TAKT
	READY	EQU 1		;BIT1 RECHNER EMPFANGSBEREIT
	KBACK	EQU 4		;BIT4 CE EMPFANGSBEREIT
	KBRQ	EQU 5		;BIT5 CE AUSGABEBEREIT

;********** INITIALISIERUNGSPROGRAMM *******************

CE50:	LD A,(IOBYTE)		;LIST-AUSGABE UEBER
	AND 0FH			;BENUTZER-TREIBER
	LD (IOBYTE),A

;-------------- Initialisierung des Ausgabe-Ports

	LD A,11001111B		;PIO-A IM BIT-MODE
	OUT (PIOAC),A
	LD A,00111100B		;MIT A0,A1,A6,A7=AUS, A2-A5=EIN
	OUT (PIOAC),A
	LD A,00001111B		;PIO-B IM OUTPUT-MODE
	OUT (PIOBC),A
	LD A,00000111B		;KEINE INTERUPTS
	OUT (PIOAC),A		;FUER PORT A
	OUT (PIOBC),A		;BZW. PORT B

;--------------- Synchronisierung der CE50 
;	Ausgabe von NOP (0FFH) bis KBACK=1

	LD A,2			;READY=1 SETZEN
	OUT (CONT),A
	IN A,(CONT)
	BIT KBRQ,A		;KBRQ=1, D.H. CE NICHT
	JR NZ,FEHLER		;EINGESCHALTET?

	LD C,16			;MAX.2 BYTES, 16 TAKTE

CESYNC:	LD A,1			;DATENBIT SETZEN
	OUT (DATA),A
	XOR A			;TAKT-IMPULS GENERIEREN
	OUT (CONT),A		;LOG.0
	INC A
	OUT (CONT),A		;LOG.1
	LD B,32			;100 MIKROSEC WARTEN
	DJNZ $
	IN A,(CONT)
	BIT KBACK,A		;WENN KBACK=1, DANN SYNCHRON
	JR NZ,SYNCHR
	DEC C			;ANDERNFALLS WEITER VERSUCHEN
	JR NZ,CESYNC		;BZW. ERFOLGLOS ABBRECHEN

FEHLER:	LD DE,ERRMSG		;MELDUNG UND ABBRUCH
	JP MELDG
ERRMSG:	DB 'CE50 nicht bereit'
	DB 0DH,0AH
	DB '$'
OKMSG:	DB 'CE50 synchronisiert und initialisiert'
	DB 0DH,0AH
	DB '$'

SYNCHR:	LD HL,PATCH		;BEI ERFOLG:
	LD DE,USRLST		;INIT-, TREIBER- UND
	LD BC,PATCHE-PATCH	;STATUSROUTINE PATCHEN
	LDIR

;	CE50 auf ASCII umschalten (Sequenz 0F00 Hex)

	LD C,0FCH
	CALL CEPRNT
	LD C,0
	CALL CEPRNT

	LD DE,OKMSG
MELDG:	LD C,9
	CALL BDOS

EXIT:	RET			;PROGRAMM ENDE

;************** FOLGEN DIE ZU RELOZIERENDEN TREIBERROUTINEN**************

PATCH	EQU $

	.PHASE USRLST

;	Relative Spruenge zu den User-Routinen

ILP:	RET		;KEINE INITIALISIERUNG
	NOP
LIP:	JR CELIST	;ZEICHENAUSGABE
LSP:	JR CESTAT	;STATUSABFRAGE

ESCFLG:	DB 0		;ESC SEQUENZ FLAG

;	Ausgabe eines Zeichens
CELIST:			;Zeichen in C fuer CE50 umcodieren
	LD A,(ESCFLG)	;ESC SEQUENZ AKTIV?
	OR A
	JR Z,CELIS1
	XOR A		;JA, FLAG LOESCHEN UND
	LD (ESCFLG),A
	JR CEPRNT	;ZEICHEN SO AUSGEBEN

CELIS1:	LD A,C
	CP 1BH		;ZEICHEN = ESC?
	JR NZ,CELIS2
	LD A,0FFH	;JA, FLAG SETZEN
	LD (ESCFLG),A
	RET		;UND FERTIG.

CELIS2:	CP 80H
	JR NC,CODNOP	;KEIN ASCII, ALSO NOP
	CP 20H
	JR Z,CODSPC	;SPACE
	JR NC,CODEX	;SO DRUCKBAR
	CP 08		;STEUERZEICHEN
	JR Z,CODBSP	;BACKSPACE
	CP 0AH
	JR Z,CODLF	;LINEFEED
	CP 0DH
	JR Z,CODCR	;CARRIAGE RETURN
CODNOP:	LD C,0FFH	;NOP SUBSTITUIEREN
	JR CODEX
CODSPC:	LD C,0		;CE-CODE FUER SPACE
	JR CODEX
CODBSP:	LD C,3		;FUER BACKSPACE
	JR CODEX
CODLF:	LD C,2		;FUER CR/LF
	JR CODEX
CODCR:	LD C,14H	;FUER CR
CODEX:	

CEPRNT:	CALL CESTAT	;STATUS DER CE ABFRAGEN
	OR A
	JR Z,CEPRNT	;A=0, D.H. NICHT BEREIT

;	Ausgabe des Zeichens in Register C ueber die PIO

CEPIO:	PUSH BC		;RETTEN DER REGISTER
	LD B,8		;BITZAEHLER
CEPIO1:	XOR A
	RL C		;CY=AUSGABEBIT
	JR NC,CEPIO2
	INC A
CEPIO2: OUT (DATA),A	;DATENBIT SETZEN
	XOR A		;TAKT-IMPULS GENERIEREN
	OUT (CONT),A	;LOG.0
	INC A
	OUT (CONT),A	;LOG.1
	DJNZ CEPIO1	;NAECHSTES BIT
	POP BC
	RET

;	CE50-Status abfragen; Akku=FF, falls bereit, sonst =0

CESTAT:	IN A,(CONT)
	BIT KBACK,A
	LD A,0FFH
	RET NZ
	CPL
	RET

	.DEPHASE
PATCHE	EQU $

	END
