title 'Character I/O handler for z80 chip based system'

; Character I/O for the Modular CP/M 3 BIOS
; MARC Version 1.0
; 04.02.90
; Bildschirmsteuerung mit Abfrage auf Adresse 07H
; BIT   7    6   543210
; Bed. /ZAR /BAR 000000

	maclib Z80	; define Z80 op codes
	maclib ports	; define port addresses
	maclib modebaud	; define mode bits and baud equates


TEST	EQU	TRUE


	; limitations:

	;		baud rates 19200,7200,3600,1800 and 134
	;			are approximations.

	;		9600 is the maximum baud rate that is likely
	;			to work.

	;		baud rates 50, 75, and 110 are not supported


	public ?cinit,?ci,?co,?cist,?cost
	public @ctbl
	public csfabr,csrafr,csctrr,stfabr
	public staon,staoff
	public t100ms
	public zeisat,flosta

	extrn @date,@sec,@hour,@cbnk
	extrn ?bnksl
	extrn tasini,tasabf,tab
	extrn tasmer
	extrn ivctc3,ivcent
	extrn motoff,motcot

max$devices	equ 6

;**************************************************************
; Programm
;**************************************************************

	dseg
;	cseg

?cinit:

IF	NOT TEST
	mov a,c ! cpi max$devices ! jz cent$init ; init parallel printer
	rnc				; invalid device
	mov l,c ! mvi h,0		; make 16 bits from device number
	push h				; save device in stack
	dad h ! dad h ! dad h		; *8 
	lxi d,@ctbl+7 ! dad d ! mov l,m	; get baud rate
	mov a,l ! cpi baud$600		; see if baud > 300
	mvi a,44h ! jnc hi$speed	; if >= 600, use *16 mode
	mvi a,0C4h			;    else, use *64 mode
hi$speed:
	sta sio$reg$4	
	mvi h,0 ! lxi d,speed$table ! dad d	; point to counter entry
	mov a,m ! sta speed		; get and save ctc count
	pop h				; recover 
	lxi d,data$ports ! dad d	; point at SIO port address
	mov a,m ! inr a ! sta sio$port	; get and save port
	lxi d,baud$ports-data$ports ! dad d	; offset to baud rate port
	mov a,m ! sta ctc$port		; get and save
	lxi h,serial$init$tbl
	jmp stream$out

cent$init:
	lxi h,pio$init$tbl

stream$out:
	mov a,m ! ora a ! rz
	mov b,a ! inx h ! mov c,m ! inx h
	outir
	jmp stream$out
ENDIF

	call	tasini		; Tastatur Initialisieren

;**************** Initialisieren CRT-Steuerung ***************

	di
	mvi a,07h

IF	NOT LOADER
	sta csfabr
ENDIF
	out csfab
	rlc
	rlc
	rlc
	rlc
IF	NOT LOADER
	sta cscurf
	sta csrafr
ENDIF
	out csraf
	xra a
if	not loader
	sta csctrr
endif
	out csctr

IF NOT LOADER

	LXI	H,IVCTC3
	MOV	A,H		; INITIALISIERUNG INTERRUPT
	STAI
	IM2
	MVI	C,LSTCTC	; DRUCKERINITIALISIERUNG
	MVI	B,2
	LXI	H,LSTTAB
	OUTIR
	MVI	C,LSTCRT
	MVI	B,9
	OUTIR
;______________________________________________________________
; INITIALISIEREN DES UHRINTERRUPTES / ABFRAGE DER TASTATUR
;______________________________________________________________

	mvi	a,10		; 10 * 100 ms
	STA	t100ms		; UHRPUFFER FREIMACHEN

	call	staon

	LXI	H,TASTP		; FREIMACHEN TASTATURPUFFER
	MVI	B,TASTPE-TASTP+1
SC1:	MVI	M,0
	INX	H
	DJNZ	SC1

	call	staoff

	LXI	H,TIMINT	; EINSTELLEN INT-TABELLE KANAL 2
	SHLD	IVCTC3
	LXI	H,IVCTC3
	MOV	A,L		; INT-VEKTOR CTC LADEN
	OUT	CTC1

	mvi	a,05h		; Kanal 2 Erzeugung Takt 1 ms
	out	ctc1k2		; fuer Kanal 3
	mvi	a,250		; fuer 4 MHz
				; 250 * 250ns * 16
	out	ctc1k2
	mvi	a,0cdh		; Kanal 3 Zaehler Interrupt
	out	ctc1k3		; aller 100 ms
	mvi	a,100
	out	ctc1k3

; Initialisieren der CENTRONICS - Schnittstelle

	mvi a,4fh ! out cenpac ! out cenpbc
	xra a ! out cenpbd
	dcr a ! out cenpbc ! dcr a ! out cenpbc ! lda timcen
	lxi h,cenint ! shld ivcent
	lxi h,ivcent ! mov a,l ! out cenpac
	mvi a,83h ! out cenpac ! in cenpad

	ei
ENDIF

	RET

;**************************************************************
; INITIALISIERUNGSTABELLE FUER DRUCKER
;**************************************************************

LSTTAB:	DB	5		; CTC
	DB	1
	DB	0		; SIO
	DB	19H		; REG. 1
	DB	0		; KEIN INTERRUPT
	DB	3		; REG. 3
	DB	0C1H		; 8 BIT EMPFANGEN
	DB	4		; REG. 4
	DB	45H		; VT=16, 1 STOPBIT, UNGER. PAR.
	DB	5		; REG. 5
;	DB	68H		; 8 BIT SENDEN
	db	0e8h

	cseg

?ci:		; character input

IF	NOT TEST
	mov a,b ! cpi 6 ! jnc null$input ; can't read from centronics
ci1:
	call ?cist ! jz ci1		; wait for character ready
	dcr c ! inp a			; get data
	ani 7Fh				; mask parity
	ret
ENDIF

IF	TEST
	MOV A,B ! CPI 1 ! JNC NULL$INPUT
;**************************************************************
; CONSOLEINGABE
;**************************************************************
;CONIN:	CALL	CONST
;	ORA	A
;	JRZ	CONIN
;	IN	TASTE
;	RET

CONIN:
	sspd consp		; Stackrettung
	lxi sp,constk
	LHLD	TABMER
	MOV	A,H
	ORA	L
	JRNZ	NEXZEI
CONIN1:	LDA	TASMER
	ORA	A
	JRZ	CONIN1
	LXI	D,TASTP
	LXI	H,TASTP+1
;	LXI	B,TASTPE-TASTP
;zt1a:	in	bstast
;	ani	40h
;	jrz	zt1a
;zt2a:	in	bstast	
;	ani	40h
;	jrnz	zt2a

	di

	call	staon

	mvi	c,bstast
cona1a:	db	0edh,070h	; INF -Befehl
	jp	cona1a
cona1b:	db	0edh,070h	; INF -Befehl
	jm	cona1b

	ldax	d
	push	psw

	mvi	b,tastpe-tastp
cona2a:	db	0edh,070h	; INF -Befehl
	jp	cona2a
cona2b:	db	0edh,070h	; INF -Befehl
	jm	cona2b
	ldi
	inr c
	djnz	cona2a

;	LDIR

cona3a:	db	0edh,070h	; INF -Befehl
	jp	cona3a
cona3b:	db	0edh,070h	; INF -Befehl
	jm	cona3b

	LDA	TASTP
	STA	TASMER
	XRA	A

	call	staanz

;	stax	d

	call	staoff

	pop	psw
	ei
	LXI	H,TAB
	MOV	B,A
SUCH:	MOV	A,M
	ORA	A
	JRZ	NOTFOU
	INX	H
	CMP	B
	JRZ	SUCHE
WEIT:	INX	H
	MOV	A,M
	ORA	A
	JRNZ	WEIT
	INX	H
	JR	SUCH
SUCHE:
NEXZEI:	MOV	B,M
	INX	H
	MOV	A,M
	ORA	A
	JRNZ	MEHRZE
NOTFOU:	LXI	H,0
MEHRZE:	SHLD	TABMER
	MOV	A,B
	CPI	80H
	jrc	econin
	XRA	A
econin:
	lspd	consp
	ret

TABMER:	DW	0

ENDIF

null$input:
	mvi a,1Ah			; return a ctl-Z for no device
	ret

?cist:		; character input status

IF	NOT	TEST
	mov a,b ! cpi 6 ! jnc null$status ; can't read from centronics
	mov l,b ! mvi h,0		; make device number 16 bits
	lxi d,data$ports ! dad d	; make pointer to port address
	mov c,m ! inr c			; get SIO status port
	inp a				; read from status port
	ani 1			; isolate RxRdy
	rz				; return with zero
	ori 0FFh
	ret
ENDIF
IF	TEST
	MOV A,B ! CPI 1 ! JNC NULL$STATUS
;**************************************************************
; CONSOLSTATUS
;**************************************************************

;CONST:	IN	TASTST
;	CMA
;	BIT	3,A
;	MVI	A,0
;	RZ
;	MVI	A,0FFH
;	RET

CONST:
	LHLD	TABMER
	MOV	A,H
	ORA	L
	JRNZ	CONST1
	LDA	TASMER
	ORA	A
	RZ			; KEINE TASTE
CONST1:	MVI	A,0FFH		; TASTE DA
	RET

ENDIF

null$status:
	xra a ! ret


?co:		; character output

IF	NOT TEST
	mov a,b ! cpi 6 ! jz centronics$out
	jnc null$output
	mov a,c ! push psw		; save character from <C>
	push b				; save device number
co$spin:
	call ?cost ! jz co$spin		; wait for TxEmpty
	pop h ! mov l,h ! mvi h,0	; get device number in <HL>
	lxi d,data$ports ! dad d	; make address of port address
	mov c,m				; get port address
	pop psw ! outp a		; send data
ENDIF

IF	TEST
	MOV A,B ! CPI 1 ! JZ LIST
	CPI 0 ! JNZ NULL$OUTPUT
;**************************************************************
; CONSOLAUSGABE
;**************************************************************

CONOUT:
	sspd	consp
	lxi	sp,constk
	push	psw
	lhld	curs
	di
	xra a ! sta timcur
	lda cscurf ! sta cscuri
	push b
	mvi	c,bstast
rescu1:	db	0edh,070h	; INF -Befehl
	jp	rescu1
rescu2:	db	0edh,070h	; INF -Befehl
	jm	rescu2
	mov	a,m		; reset Cursor
	mov	m,a
	pop b

;	lda curmer ; ani 4
;	JRZ	NOCLR		; --> Cursor war nicht gesetzt
;	push h
;	lxi h,timcur ; mov a,m ; ani 1 ; mvi m,0
;	pop h
;	jrz noclr
;	push	b		; Zeichen retten
;	call	invcur
;	pop	b
;noclr:
	ei
	lda	farmer
	ora	a
	jnz	faraus
	LDA	ESCMER		; WAR ESC-FOLGE ?
	ORA	A
	JRZ	NOESC		; -> NEIN
	DCR	A
	STA	ESCMER
	JRZ	ESC2		; -> 2.BYTE DER ESC-FOLGE
	LXI	H,0f800h		; BEHANDLUNG 1.BYTE DER ESC-FO.
	MOV	A,C		; ALS ZEILENANGABE
	ANI	7FH
	ORA	A
	JRZ	SETCUR
	CPI	18H
	JRC	ESC11
	LXI	H,0f800h
	JR	SETCUR
ESC11:
	MOV	B,A
	LXI	D,0050H
ESC12:
	DAD	D
	DJNZ	ESC12
	JR	SETCUR
ESC2:
	MOV	A,C		; BEHANDLUNG 2.BYTE DER ESC-FO.
	ANI	7FH		; ALS SPALTENANGABE
	CPI	50H
	LXI	D,004FH
	JRNC	ESC22
	MOV	E,A
ESC22:
	DAD	D
	JR	SETCUR
NOESC:
	MOV	A,C		; AUSWERTUNG STEUERZEICHEN
	cpi	0c0h
	jrc	nospez
	cpi	0e0h
	jrnc	nospez
	ani	1fh
	jr	zeiums1
nospez:
	CPI	7FH
	jrnc	crtcrtl
	CPI	20H
	JRC	CRTCRTL
CRTZEI:
	mov	b,a
	lda	zeisat
	ora	a
	jrz	noums
	mov	a,b
	cpi	7eh
	jrz	zeiums
	ani	0dfh
	cpi	5bh
	jrc	noums
	cpi	5eh
	jrnc	noums
zeiums:
	ani	1fh
	bit	5,b
	jrnz	zeiums1
	sui	3
zeiums1:
	mov	b,a
noums:
eizeium:
	mvi	c,0ffh
	mvi	a,0ffh
	sta	eizeium+1
	lda	invmer
	ora	b	
	ana	c
	call	zeidar		; Zeichen darstellen
	CALL	CRTCRI
;
SETCUR:
	lda	curmer
	bit 2,a
	di
	jrz noset
	sta	timcur
noset:
	SHLD	CURS		; Cursorposition merken
	POP	PSW
	lspd	consp
	ei
	RET
;
CRTCRTL:			; STEUERZEICHEN AUSWERTEN
	lxi	d,setcur
	push	d
	cpi	7fh
	jz	crtdch
	CPI	0DH
	JZ	CRTCR
	CPI	0AH
	JZ	CRTLF
	CPI	15H
	JZ	CRTCRI
	CPI	08H
	JZ	CRTCLE
	CPI	0CH
	JZ	CRTFF
	CPI	01H
	JZ	CRTHOM
	CPI	14H
	JZ	CRTDRB
	CPI	18H
	JZ	CRTDZE
	CPI	16H
	JZ	CRTDCZ
	CPI	1AH
	JZ	CRTCHO
	CPI	1BH
	JZ	CRTESC
	cpi	82h
	jz	curson
	cpi	83h
	jz	cursof
	cpi	86h
	jz	cublkon
	cpi	87h
	jz	cublkof
	cpi	84h
	jz	inveof
;	jz	inveon
	cpi	85h
	jz	inveon
;	jz	inveof
	cpi	8fh
	jz	farein
	cpi	0f0h
	jz	ascii
	cpi	0f1h
	jz	ascii
	cpi	0f2h
	jz	german
	cpi	0f3h
	jz	german
	cpi	08eh
	jz	eizeis
	cpi	7
	jz	bell
	ret

CRTDCH:	mvi	a,' '		; DEL
	call	zeidar
CRTCLE:	DCX	H		; BACKSPACE
	MOV	A,H
	CPI	0f7H
	RNZ
	INX	H
	RET
CRTFF:	LXI	H,0ff7fh	; FORM FEED
	LXI	D,0f800H
	call	cltbab
CRTHOM:	LXI	H,0f800h		; HOME POSITION
	RET
CRTLF:	LXI	D,0050H		; LINE FEED
	DAD	D
	MOV	A,H
	CPI	0ffH
	RNZ
	MOV	A,L
	CPI	80H
	RC
	DSBC	DE		; SBC HL,DE
	JR	CRTPO1
CRTCRI:	INX	H		; NAECHSTE KURSORPOSITION
	MOV	A,H		; WENN NOETIG BILD ROLLEN
	CPI	0ffH
	RNZ
	MOV	A,L
	CPI	80H
	RC
	LXI	H,0ff30H
CRTPO1:	PUSH	H
	lxi h,0f850h ! lxi d,0f800h
	mvi	b,4
crtpoa:	push	b
	lxi	b,460
zt1d:	in bstast ! ani 40h
	jrz	zt1d
zt2d:	ei
	nop
	di
	in bstast ! ani 40h
	jrnz zt2d
	lda csctrr ! ori 2 ! out csctr
	LDIR
	ani 0fdh ! out csctr
	ei
	pop	b
	djnz	crtpoa
	lxi h,0ff7fh ! lxi d,0ff30h	; letzte Zeile loeschen
	call	cltbab
	POP	H
	RET
CRTCR:	MOV	B,H		; CARRIAGE RETURN
	MOV	C,L
	LXI	H,0ff80H
	LXI	D,0050H
	ORA	A
CRTCR1:	DSBC	DE		; SBC HL,DE
	PUSH	H
	DSBC	BC		; SBC HL,BC
	POP	H
	RZ
	JRNC	CRTCR1
	RET
CRTESC:	MVI	A,02H		; BEHANDLUNG ESC-FOLGE
	STA	ESCMER		; BEGINNEN
	RET
CRTDRB:	XCHG			; LOESCHEN AB CURSOR BIS
	LXI	H,0ff7FH		; BILDENDE
crtdr0:	call	cltbab
	LHLD	CURS
	RET
CRTDZE:	CALL	CRTCR		; LOESCHEN KURSORZEILE UND
				; SETZEN KURSOR AN ZEILEN-
				; ANFANG
CRTDCZ:				; LOESCHEN AB KURSORPOSITION    
                               	; BIS ZEILENENDE		
	push h ! call crtcr
	LXI D,0050H ! DAD D ! pop d ! ORA A
	jr crtdr0
CRTCHO:				; KURSOR EINE ZEILE HOCH
	LXI D,0050H
	DSBC DE
	mvi a,0f7h ! cmp h ! rc
	LHLD CURS ! RET
curson:
	lda curmer
	ori 4
	jr curend
cursof:
	lda curmer
	ani 0fbh
	jr curend
cublkon:
	lda curmer
	ori 2
	jr curend
cublkof:
	lda curmer
	ani 0fdh
curend:
	sta curmer ! ret
inveof:
	xra a ! sta invmer ! ret
inveon:
	mvi a,80h ! sta invmer ! ret
ascii:
	xra a
german:
	sta zeisat ! ret
eizeis:
	mvi a,1fh ! sta eizeium+1 ! ret
farein:
	mvi a,2 ! sta farmer ! ret
faraus:
	dcr a ! sta farmer
	jrz far2
	mov a,c ! sta csfabr ! out 40h
	rrc ! rrc ! rrc ! rrc ! sta cscurf ! sta cscuri
	jmp setcur
far2:
	mov a,c ! sta csrafr ! out 41h
	jmp setcur
bell:
	mvi a,5 ! out 58h
	mvi a,80h ! out 58h
	lxi b,4000h
bell1:	dcx b ! mov a,b ! ora c
	jrnz bell1
	mvi a,3 ! out 58h
	ret

; Direkte Bildschirmzugriffe

; Cursor invertieren

invcur:
	lda cscuri ! out 40h
	mvi	c,bstast
zx1a:	db	0edh,070h	; INF -Befehl
	jp	zx1a
zx2a:	db	0edh,070h	; INF -Befehl
	jm	zx2a
	mov	a,m
;	xri	80h		; Invertieren Cursordarstellung
	mov	m,a
	lda csfabr ! out 40h
	lda cscuri ! rlc ! rlc ! rlc ! rlc ! sta cscuri
	ret

; Zeichen in Bildschirmpuffer bringen

zeidar:	mvi	c,bstast
zx1b:	db	0edh,070h	; INF-Befehl
	jp	zx1b
zx2b:	db	0edh,070h	; INF-Befehl
	jm	zx2b
	mov	m,a		; ZEICHEN AUF BILDSCHIRM
	ret

; Bildschirmabschnitt loeschen
; DE - erste Adresse
; HL - letzte Adresse

cltbab:
	DSBC	DE		; SBC HL,DE
	jrz	cltba6
	mvi	a,1
	lxi	b,460
cltba1:	ora	a
	dsbc	bc
	jrc	cltba2
	inr	a
	jr	cltba1
cltba2:	dad	b
	push	psw
	mov b,h ! mov c,l
	mov h,d ! mov l,e ! inx d
	jr	cltba4
cltba3:	push	b
	lxi	b,460
cltba4:	in	bstast
	ani	40h
	jrz	cltba4
cltba5:	ei
	nop
	di
	in	bstast	
	ani	40h
	jrnz	cltba5
	mvi	m,' '
	LDIR
	ei
	pop	b
	djnz	cltba3
cltba6:	ret

CURS:	DW	0f800h
ESCMER:	db	0
farmer:	db	0
curmer:	db	0
curblk: db	0
invmer:	db	0
timcur:	db	0
zeisat:	db	0
cscurf:	db	0
cscuri:	db	0
csfabr:	db	0
csrafr:	db	0
csctrr:	db	0
stfabr:	db	07h

constak:
	ds	32
constk:
consp:	ds	2

flosta:
	LXI	D,floanz
	mvi	b,9
	di
	call	staon
flost1:	mov a,m ! call staanz ! inx h
	djnz	flost1
	call	staoff
	ei
	ret

ENDIF

null$output:
	ret

IF	NOT TEST
centronics$out:
	in p$centstat ! ani 20h ! jnz centronics$out
	mov a,c ! out p$centdata	; give printer data
	in p$centstat ! ori 1 ! out p$centstat	; set strobe
	ani 7Eh ! out p$centstat		; clear strobe
	ret
ENDIF

?cost:		; character output status
IF	NOT TEST
	mov a,b ! cpi 6 ! jz cent$stat
	jnc null$status
	mov l,b ! mvi h,0
	lxi d,data$ports ! dad d
	mov c,m ! inr c 
	inp a				; get input status
	ani 4 ! rz			; test transmitter empty

ENDIF				; IMMER READY SIMULIEREN

	ori 0FFh ! ret			; return true if ready

IF	NOT TEST
cent$stat:
	in p$centstat ! cma
	ani 20h ! rz
	ori 0FFh ! ret	

baud$ports:		; CTC ports by physical device number
	db	p$baud$con1,p$baud$lpt1,p$baud$con2,p$baud$con34
	db	p$baud$con34,p$baud$lpt2

data$ports:		; serial base ports by physical device number
	db	p$crt$data,p$lpt$data,p$con2data,p$con3data
	db	p$con4data,p$lpt2data
ENDIF

@CTBL:	DB 'TASTE '
	DB MB$INPUT
	DB BAUD$NONE
	DB 'BAB   '
	DB MB$INPUT
	DB BAUD$NONE
	DB 0		; TABENDE

IF	NOT TEST
@ctbl	db 'CRT   '	; device 0, CRT port 0
	db mb$in$out+mb$serial+mb$softbaud
	db baud$9600
	db 'LPT   '	; device 1, LPT port 0
	db mb$in$out+mb$serial+mb$softbaud+mb$xonxoff
	db baud$9600
	db 'CRT1  '	; device 2, CRT port 1
	db mb$in$out+mb$serial+mb$softbaud
	db baud$9600
	db 'CRT2  '	; device 3, CRT port 2
	db mb$in$out+mb$serial+mb$softbaud
	db baud$9600
	db 'CRT3  '	; device 4, CRT port 3
	db mb$in$out+mb$serial+mb$softbaud
	db baud$9600
	db 'VAX   '	; device 5, LPT port 1 used for VAX interface
	db mb$in$out+mb$serial+mb$softbaud
	db baud$9600
	db 'CEN   '	; device 6, Centronics parallel printer
	db mb$output
	db baud$none
	db 0			; table terminator


speed$table	db	0,255,255,255,233,208,104,208,104,69,52,35,26,17,13,7

serial$init$tbl
		db 2		; two bytes to CTC
ctc$port	ds 1		; port address of CTC
		db 47h		; CTC mode byte
speed		ds 1		; baud multiplier
		db 7		; 7 bytes to SIO
sio$port	ds 1		; port address of SIO
		db 18h,3,0E1h,4
sio$reg$4	ds 1
		db 5,0EAh 	
		db 0		; terminator

pio$init$tbl	db	2,p$zpio$2b,0Fh,07h
		db	3,p$zpio$2a,0CFh,0F8h,07h
		db 0
ENDIF


;**************************************************************
; INTERRUPTROUTINE UHRZEIT
;**************************************************************

TIMINT:	SSPD RETTSP
	LXI SP,TIMSTE
	PUSH PSW ! PUSH H ! PUSH B

; erst Test, ob Zeichen von Centronics

	lda timcen ! ora a
	jrnz tim100
	call cenout

; 100-ms ZAEHLER

tim100:
	lxi h,timcur
	bit 2,m
	res 2,m
	jrnz blktes
cur1:
	bit 1,m
	jrz noblk
	lda t100ms ! ani 1	;7  3
	jrnz noblk
blktes:
	mvi a,1 ! xra m ! mov m,a
	lhld curs ! call invcur
noblk:
	lxi h,t100ms
	dcr m
	JNZ TIMEND
;	mvi m,20
	mvi m,10

	lda motcot ! ora a
	jrz secun
	dcr a ! sta motcot ! cz motoff

; SEKUNDEN
secun:
	LXI H,@SEC
	MOV A,M ! ora a ! INR A ! DAA ! MOV M,A ! SUI 60H
	JRNZ TIMOUT
	MOV M,A

; MINUTEN

	DCX H ! MOV A,M ! INR A ! DAA ! MOV M,A ! SUI 60H
	JRNZ TIMOUT
	MOV M,A

; STUNDEN

	DCX H ! MOV A,M ! INR A ! DAA ! MOV M,A ! SUI 24H
	JRNZ TIMOUT
	MOV M,A

; DATUM

	LHLD @DATE ! INX H ! SHLD @DATE

; ZEIT AUSGEBEN AUF BSE

TIMOUT:
	call staon ! PUSH D ! LXI D,0ffbdh ! LXI H,@HOUR
	MVI B,2
NEXZEO:	CALL BYTOUT
	MVI A,':'
	call staanz ! INX H
	DJNZ NEXZEO
	call bytout ! POP D
	jr timen2

timend:
	call staon
TIMEN2:	CALL TASABF

;______________________________________________________________
; ENDE TASTATURABFRAGE / UHREINSTELLUNG
;______________________________________________________________

	call staoff
timen3:
	POP B ! POP H ! POP PSW
	LSPD RETTSP
	EI
	RETI

;______________________________________________________________

BYTOUT:	MOV A,M
	RRC ! RRC ! RRC ! RRC
	CALL BYTOU1
	MOV A,M
BYTOU1:	ANI 0FH ! ADI '0'
staanz:
	mvi	c,bstast
zx1f:	db	0edh,070h	; INF-Befehl
	jp	zx1f
zx2f:	db	0edh,070h	; INF-Befehl
	jm	zx2f

	STAX D ! INX D
	RET

;______________________________________________________________

TIMST:	DS	20H		; STACK FUER TIMINT
TIMSTE:
RETTSP:	DW	0		; STACKPOINTER MERKEN

;______________________________________________________________

t100ms:	DB	0

timcen: db 0ffh

;**************************************************************
; CENTRONICS-INTERFACE
;**************************************************************

cenint:
	sspd censtack
	lxi sp,censtack
	push h
	lxi h,cenout1
	xthl
	ei
	reti

cenout:
	sspd censtack
	lxi sp,censtack
cenout1:
	push psw
	call listst
	sta timcen ! ora a
	jrz cenend
	in cenpad ! out lstdat
cenend:
	pop psw
	lspd censtack
	ret

	ds 16
censtack:
	ds 2

;**************************************************************

LIST:
	CALL	LISTST
	ORA	A
	JZ	LIST		; LIST NOT READY
	MOV	A,C
	ANI	7FH		; MASKIEREN ALS 7 BIT AUSGABE
	OUT	LSTDAT
	RET

;**************************************************************
; DRUCKERSTATUS
;**************************************************************

LISTST:
	MVI A,10H ! OUT LSTCRT
	IN LSTCRT ! CMA
	BIT 5,A			; CTS FREI ?
	JRNZ LISTS1		; NEIN
	BIT 2,A			; SENDER FREI ?
LISTS1:	MVI A,0
	RNZ			; LIST NOT READY
	DCR A
	RET			; LIST READY


;**************************************************************
; Einschalten Statuszeile
;**************************************************************

staon:
	lda stfabr ! out csfab
	xra a ! out csctr
	ret

;**************************************************************
; Ausschalten Statuszeile
;**************************************************************

staoff:
	lda csfabr ! out csfab
	lda csctrr ! out csctr
	ret

	end
