; this is a simple terminal emulator for the TurboDOS
; it uses T-34 thru t-36 COM IO

; on z80 emulator-
;  CON  is (TTY)Generic DEV0
;  COM 0 is (SerA)Generic DEV14


;Assemble with AS8080
	z80

BDOS	equ	005h
TDOS	equ	050h

ORAW	equ	4
IRAW	equ	3

DIO	equ	6
PrtStr	equ	9
GetSTS	equ	11

ComSts	equ	34
ComIN	equ	35
ComOUT	equ	36
ComMst	equ	40

CR	equ	0x0d
LF	equ	0x0a
TILDE	equ	0x7e

	org	0x100
Entry	jmp	start

OpenMsg	db	"Terminal Program (V 2.0) for TurboDOS - ",cr,lf
	db	"  Connects CONSOLE via COM0 on DEV0 to COM14 on DEV14",cr,lf
	db	"  Type a Tilde to Exit",cr,lf,'$',0
NotTDOSMsg	db	cr,lf,"  NOT TDOS - Exiting...",cr,lf,'$',0

Qnext	db	0
Qstart	db	0
Qcount	db	0

OldStack	dw	0

Start:
	sspd	OldStack

	lxi	de,OpenMsg
	mvi	c,PrtStr
	call	BDOS

; test for TODS
	lda	050h	; assume a jmp at 50 for TDOS 
			;(might be there for CPM too, if TDOS run before)
	cmpi	0c3h
	jnz	NotTDOS	

TxLoop:
; input from console

	mvi	c,11	;con stat
	call	BDOS
	ana	a
	jrz	conNOch

	mvi	c,IRAW
	call	BDOS		;A=char or 0x00

	cmpi	TILDE		;escape is TILDE
	jrz	Exit
	
	mov	c,a
	call	Qput
	cz	Qoverflow
	
conNOch:

	call	Qempty
	jrz	next2


; check COM 14 for OK to send CTS

	mvi	c,ComMst
	mvi	d,14
	call	TDOS
	
	ani	080h

	jz	Next2

OUTit:
	Call	Qget	

; output to com 14 (sera = dev14)

	mov	e,c
	mvi	c,ComOut	;tdos com channel out
	mvi	d,14		;channel 14 (dev14=sera)
	call	TDOS
	
Next2:
; check in status of Com 0

	mvi	c,ComSts	;com status
	mvi	d,14		;channel 14
	call	TDOS
	cmpi	0		;char?
	jrz	TxLoop		;no char

; input from com 0

	mvi	c,ComIN		;com input
	mvi	d,14		; channel 14
	call	TDOS

; out to console

	mov	e,a
	mvi	c,ORAW
	call	BDOS		;A=char or 0x00
	jmpr	TxLoop


Exit:
	lspd	OldStack
	ret

Qoverflow:
	ret

NotTDOS:
	lxi	d,NotTDOSMsg
	mvi	c,PrtStr
	call	bdos
	jmp	exit

;	returns z=1 a=0 if emtpy
Qempty:
	lda	Qcount
	ana	a
	ret

;	returns z=1  a=255 if full
Qfull:
	lda	Qcount
	cmpi	255
	ret

; put c into queue
Qput:
	call 	Qfull
	rz

	lda	Qcount
	inr	a
	sta	Qcount

	lda	Qnext

	push	hl
	lxi	h,Queue
	mov	l,a
	mov	m,c
	pop	hl

	inr	a
	sta	Qnext

	ret

;return next in queue in c
Qget:
	call	Qempty
	rz
	
	push	hl
	lxi	h,Queue

	lda	Qstart

	mov	l,a
	mov	c,m
	pop	hl
	
	inr	a
	sta	Qstart

	lda	Qcount
	dcr	a
	sta	Qcount

	ret

Qclear:
	mvi	a,0
	sta	Qcount
	sta	Qstart
	sta	Qnext
	ret

NPAGE:	macro
	rept	256-low($)
	db	0
	endm
	endm

	dw	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	NPAGE

Stack:

QUEUE: 	
	NPAGE
	end	entry