
; Kermit system dependent module for Heath/Zenith Z100

	public	term
	include msdefs.h


BIOS_SEG SEGMENT AT 40H		; Define segment where BIOS really is
	ORG	4*3
BIOS_PRINT	LABEL FAR       ; Printer output
	ORG	6*3
BIOS_AUXOUT	LABEL FAR	; AUX output routine
	ORG	26*3
BIOS_AUXFUNC	LABEL FAR	; AUX: function
	ORG	27*3
BIOS_CONFUNC	LABEL FAR	; CON: function
BIOS_SEG ENDS

; Function codes for BIOS_xxxFUNC
CHR_WRITE	EQU	0	; Write character
CHR_READ	EQU	1	; Read character
CHR_STATUS	EQU	2	; Get status
  CHR_SFGS	EQU	0	; Get status subfunction
  CHR_SFGC	EQU	1	; Get config subfunction
CHR_CONTROL	EQU	3	; Control function
  CHR_CFSU	EQU	0	; Set new configuration parameters
  CHR_CFCI	EQU	1	; Clear input buffer

; Scan code definitions used for translating back to Heath ESC sequences
entscan	equ	08dh		; enter key scan code
f0scan	equ	096h		; F0 key
f1scan	equ	097h		; F1 key
f2scan	equ	098h		; F2 key
f3scan	equ	099h		; F3 key
f4scan	equ	09ah		; F4 key
f5scan	equ	09bh		; F5 key
f6scan	equ	09ch		; F6 key
f7scan	equ	09dh		; F7 key
f8scan	equ	09eh		; F8 key
f9scan	equ	09fh		; F9 key
f10scn	equ	0a0h		; F10 key
f11scn	equ	0a1h		; F11 key
f12scn	equ	0a2h		; F12 key
homscan	equ	0a9h		; Home key
upscan	equ	0a5h		; Up arrow
dnscan	equ	0a6h		; Down arrow
rtscan	equ	0a7h		; Right arrow
lfscan	equ	0a8h		; Left arrow
kpminus	equ	0adh		; keypad minus
kpdot	equ	0aeh		; keypad period
kp0	equ	0b0h		; keypad 0
kp1	equ	0b1h		; keypad 1
kp2	equ	0b2h		; keypad 2
kp3	equ	0b3h		; keypad 3
kp4	equ	0b4h		; keypad 4
kp5	equ	0b5h		; keypad 5
kp6	equ	0b6h		; keypad 6
kp7	equ	0b7h		; keypad 7
kp8	equ	0b8h		; keypad 8
kp9	equ	0b9h		; keypad 9
sentscn	equ	0cdh		; shifted enter key
sf0scan	equ	0d6h		; shifted F0 key
sf1scan	equ	0d7h		; shifted F1 key
sf2scan	equ	0d8h		; shifted F2 key
sf3scan	equ	0d9h		; shifted F3 key
sf4scan	equ	0dah		; shifted F4 key
sf5scan	equ	0dbh		; shifted F5 key
sf6scan	equ	0dch		; shifted F6 key
sf7scan	equ	0ddh		; shifted F7 key
sf8scan	equ	0deh		; shifted F8 key
sf9scan	equ	0dfh		; shifted F9 key
sf10scn	equ	0e0h		; shifted F10 key
sf11scn	equ	0e1h		; shifted F11 key
sf12scn	equ	0e2h		; shifted F12 key
shomscn	equ	0e9h		; shifted Home key
supscan	equ	0e5h		; shifted Up arrow
sdnscan	equ	0e6h		; shifted Down arrow
srtscan	equ	0e7h		; shifted Right arrow
slfscan	equ	0e8h		; shifted Left arrow
skpmins	equ	0edh		; shifted keypad minus
skpdot	equ	0eeh		; shifted keypad period
skp0	equ	0f0h		; shifted keypad 0
skp1	equ	0f1h		; shifted keypad 1
skp2	equ	0f2h		; shifted keypad 2
skp3	equ	0f3h		; shifted keypad 3
skp4	equ	0f4h		; shifted keypad 4
skp5	equ	0f5h		; shifted keypad 5
skp6	equ	0f6h		; shifted keypad 6
skp7	equ	0f7h		; shifted keypad 7
skp8	equ	0f8h		; shifted keypad 8
skp9	equ	0f9h		; shifted keypad 9

; Miscellaneous scan codes used for functions
prscan	equ	f12scn		; print-screen scan code (F12)...
brkscan	equ	0aah		; Break key


modfrm	struc				; format of mode line
	db	'Esc chr: '
m_echr	db	2 dup (?)
	db	', Speed: '
m_baud	db	4 dup (?)
	db	', Parity: '
m_par	db	4 dup (?)
	db	', Echo: '
m_echo	db	3 dup (?)
	db	', Prn: '
m_prs	db	3 dup (?)
	db	', Type '
m_hlp	db	2 dup (?)
	db	'? for Help$'
modfrm	ends

datas 	segment	public 'datas'
waste	db	100h dup(?)		; assembler problem???

flags1	db	0			; internal flags
prtscr	equ	80h			; print screen pressed flag

; Key translations - F12 is printscreen
ckeys	db	brkscan,prscan,upscan,dnscan,lfscan,rtscan,homscan
	db	entscan,f0scan,f1scan,f2scan,f3scan,f4scan,f5scan,f6scan
	db	f7scan,f8scan,f9scan,f10scn,f11scn,kpminus
	db	kpdot,kp0,kp1,kp2,kp3,kp4,kp5,kp6,kp7,kp8,kp9
	db	supscan,sdnscan,slfscan,srtscan,shomscn
	db	sentscn,sf0scan,sf1scan,sf2scan,sf3scan,sf4scan,sf5scan,sf6scan
	db	sf7scan,sf8scan,sf9scan,sf10scn,sf11scn,skpmins
	db	skpdot,skp0,skp1,skp2,skp3,skp4,skp5,skp6,skp7,skp8,skp9
lckeys	equ	$-ckeys
;ckacts must parallel ckeys above...
ckacts	dw	trnbrk,trnprs,trnupw,trndnw,trnlfw,trnrgw,trnhom,trnkpn
	dw	trnf0,trnf1,trnf2,trnf3,trnf4,trnf5,trnf6,trnf7,trnf8,trnf9
	dw	trnf10,trnf11,trnkpn,trnkpn,trnkpn,trnkpn,trnkpn
	dw	trnkpn,trnkpn,trnkpn,trnkpn,trnkpn,trnkpn,trnkpn
	dw	trnupw,trndnw,trnlfw,trnrgw,trnhom,trnkps
	dw	trnsf0,trnsf1,trnsf2,trnsf3,trnsf4,trnsf5,trnsf6,trnsf7
	dw	trnsf8,trnsf9,trnsf10,trnsf11,trnkps,trnkps
	dw	trnkps,trnskp1,trnskp2,trnskp3,trnskp4,trnskp5,trnskp6
	dw	trnskp7,trnskp8,trnskp9

enascan	db	ESC,'y?$'	; Enable scan codes
disscan	db	ESC,'x?$'	; Disable scan codes
uptrn	db	esc,'A'
dntrn	db	esc,'B'
rgtrn	db	esc,'C'
lftrn	db	esc,'D'
enttrn	db	cr		; enter key translation
homtrn	db	ESC,'H'		; home key translation
dottrn	db	'.'		; keypad . translation
mintrn	db	'-'		; keypad - translation
kp0trn	db	'0'		; keypad 0 translation
kp1trn	db	'1'		; keypad 1 translation
kp2trn	db	'2'		; keypad 2 translation
kp3trn	db	'3'		; keypad 3 translation
kp4trn	db	'4'		; keypad 4 translation
kp5trn	db	'5'		; keypad 5 translation
kp6trn	db	'6'		; keypad 6 translation
kp7trn	db	'7'		; keypad 7 translation
kp8trn	db	'8'		; keypad 8 translation
kp9trn	db	'9'		; keypad 9 translation
senttrn	db	cr		; shifted enter key translation
shomtrn	db	ESC,'H'		; home key translation
sdottrn	db	'.'		; shifted keypad . translation
smintrn	db	'-'		; shifted keypad - translation
skp0trn	db	'0'		; shifted keypad 0 translation
skp1trn	db	ESC,'L'		; shifted keypad 1 translation
skp2trn	db	ESC,'B'		; shifted keypad 2 translation
skp3trn	db	ESC,'M'		; shifted keypad 3 translation
skp4trn	db	ESC,'D'		; shifted keypad 4 translation
skp5trn	db	ESC,'H'		; shifted keypad 5 translation
skp6trn	db	ESC,'C'		; shifted keypad 6 translation
skp7trn	db	ESC,'@'		; shifted keypad 7 translation
skp8trn	db	ESC,'A'		; shifted keypad 8 translation
skp9trn	db	ESC,'N'		; shifted keypad 9 translation
f0trn	db	ESC,'J'		; F0 translation
f1trn	db	ESC,'S'		; F1 translation
f2trn	db	ESC,'T'		; F2 translation
f3trn	db	ESC,'U'		; F3 translation
f4trn	db	ESC,'V'		; F4 translation
f5trn	db	ESC,'W'		; F5 translation
f6trn	db	ESC,'P'		; F6 translation
f7trn	db	ESC,'Q'		; F7 translation
f8trn	db	ESC,'R'		; F8 translation
f9trn	db	ESC,'0I'	; F9 translation
f10trn	db	ESC,'0J'	; F10 translation
f11trn	db	ESC,'0K'	; F11 translation
f12trn	db	ESC,'0L'	; F12 translation
sf0trn	db	ESC,'E'		; shifted F0 translation
sf1trn	db	ESC,'1A'	; shifted F1 translation
sf2trn	db	ESC,'1B'	; shifted F2 translation
sf3trn	db	ESC,'1C'	; shifted F3 translation
sf4trn	db	ESC,'1D'	; shifted F4 translation
sf5trn	db	ESC,'1E'	; shifted F5 translation
sf6trn	db	ESC,'1F'	; shifted F6 translation
sf7trn	db	ESC,'1G'	; shifted F7 translation
sf8trn	db	ESC,'1H'	; shifted F8 translation
sf9trn	db	ESC,'1I'	; shifted F9 translation
sf10trn	db	ESC,'1J'	; shifted F10 translation
sf11trn	db	ESC,'1K'	; shifted F11 translation
sf12trn	db	ESC,'1L'	; shifted F12 translation


ourarg	termarg	<>
modbuf	modfrm	<>			; mode line buffer

; some static data for mode line
unkbaud	db	'Unk '			; must be 4 chars...
baudn	db	'45.5'
	db	'  50'
	db	'  75'
	db	' 110'
	db	' 135'
	db	' 150'
	db	' 300'
	db	' 600'
	db	'1200'
	db	'1800'
	db	'2000'
	db	'2400'
	db	'4800'
	db	'9600'
	db	' 19K'
	db	' 38K'

baudnsiz  equ	16			; # of baud rates known (tbl size / 4)
parnams	db	'Even'
	db	'Mark'
	db	'None'
	db	'Odd '			; must be 4 chars
	db	'Spc '
offmsg	db	'Off'
onmsg	db	'On '
lclmsg	db	'Lcl'
remmsg	db	'Rem'

datas	ends

code	segment	public
	extrn	prtchr:near,outchr:near,putmod:near,clrmod:near,sendbr:near
	assume	cs:code,ds:datas

; This is from the dumb terminal emulator routine in MSXGEN.ASM.
; Had to use bios calls because DOS calls were losing chars.
term	proc	near
	mov 	si,ax		; this is source
	mov 	di,offset ourarg ; place to store arguments
	mov 	ax,ds
	push	es		; save caller's extra segment address
	mov 	es,ax		; address destination segment
	mov 	cx,size termarg
	rep 	movsb		; copy into our arg blk
	and	flags1,not (prtscr)	; print screen mode disabled

	test	ourarg.flgs,emheath ; Are we to use Heath sequences?
	jnz	chkmod		; no, do something else
	mov	ah,prstr
	mov	dx,offset enascan ; enable scan codes
	int	dos 

chkmod:	call 	clrmod		; clear mode line
	test 	ourarg.flgs,modoff ; is mode line disabled?
	jnz	term1		; yes, skip it
	call 	modlin		; turn on mode line

term1:	call 	portchr		; char at port?
	 jnc	term3		; no, keep going
	call	outtty		; print on terminal

term3:	mov 	ah,chr_status
	mov 	al,chr_sfgs	; get number of characters
	call 	bios_confunc	; check console
	cmp 	bl,0
	jz 	term1		; no character, go on
	mov 	ah,chr_read
	call 	bios_confunc	; read it
	cmp 	al,ourarg.escc	; escape char?
	je 	term4		; yes, exit
	push 	ax		; save char
	mov 	ah,al
	call	trnout		; translate if nec., output to port
	pop 	ax
	jmp 	term1		; else echo and keep going

term4:	call	clrmod
	mov	ah,prstr
	mov	dx,offset disscan ; disable scan code generation
	int	dos
	pop	es
	ret

term	endp

; returns with carry on if a character is available

portchr	proc	near
	call	prtchr			; character at port?
	 jmp	short portc1		; yes, go handle
	nop				; skip return is stupid
	clc				; no carry -> no character
	ret
portc1:	and	al,7fh			; we don't worry about parity here
	stc				; have a character
	ret
portchr	endp

; put the character in al to the screen
outtty	proc	near
	mov 	ah,chr_write
	call 	bios_confunc
	test 	ourarg.flgs,capt ; capturing output?
	jz 	outtt1		; no, forget it
	call 	ourarg.captr	; else call the routine

outtt1:	test	flags1,prtscr	; print screen?
	jz	outtt2		; no, try something else
	call	bios_print

outtt2:	ret
outtty	endp

; send the character in al out to the serial port
; handle echoing also...
outprt	proc	near
	test	ourarg.flgs,lclecho	; echoing?
	jz	outpr1			; no, forget it
	push	ax			; save char
	call	outtty			; print it
	pop	ax			; restore
outpr1:	mov	ah,al			; this is where outchr expects it
	call	outchr			; output to the port
	 nop
	 nop
	 nop				; skip returns...
	ret
outprt	endp

modlin	proc	near			; turn on mode line
	mov	al,ourarg.escc
	mov	modbuf.m_echr,' '	; first char is initial space
	mov	modbuf.m_hlp,' '	; goes here too.
	cmp	al,32			; printable?
	jnb	modl1			; yes, keep going
	add	al,40h			; made printable
	mov	modbuf.m_echr,'^'	; note control char
	mov	modbuf.m_hlp,'^'
modl1:	mov	modbuf.m_echr+1,al	; fill in character
	mov	modbuf.m_hlp+1,al
	mov	al,ourarg.baudb		; get baud bits
	mov	si,offset unkbaud	; assume unknown baud
	cmp	al,baudnsiz		; too big?
	jnb	modl2			; yes, use default
	mov	cl,2			; each is 4 bytes long
	shl	al,cl
	mov	ah,0
	add	ax,offset baudn
	mov	si,ax
modl2:	mov	cx,size m_baud		; length of baud space
	mov	di,offset modbuf.m_baud
	rep	movsb			; copy in baud rate
	mov	al,ourarg.parity	; get parity code
	mov	cl,2			; each is 4 bytes long...
	shl	al,cl
	mov	ah,0
	add	ax,offset parnams	; names of parity settings
	mov	si,ax
	mov	cx,4			; each is 4 long
	mov	di,offset modbuf.m_par
	rep	movsb
	mov	si,offset remmsg	; assume remote echoing
	test	ourarg.flgs,lclecho	; echoing?
	jz	modl4			; no, keep going
	mov	si,offset lclmsg
modl4:	mov	cx,3			; size of on/off
	mov	di,offset modbuf.m_echo
	rep	movsb
;	mov	al,'1'
;	cmp	portno,1		; port 1?
;	je	modl5			; yes, keep going
;	mov	al,'2'
;modl5:	mov	modbuf.m_prt,al		; fill in port number
;	mov	cx,size modfrm		; this is size of mode line
;	mov	si,offset modbuf	; mode line image
	mov	si,offset offmsg	; assume printer off
	test	flags1,prtscr		; print screen enabled?
	jz	modl5			; no, keep going
	mov	si,offset onmsg
modl5:	mov	cx,3
	mov	di,offset modbuf.m_prs
	rep	movsb
	mov	dx,offset modbuf
	call	putmod
	ret				; and return
modlin	endp

; translate the scan code in ah according to the translate table
; given in ktrntab/krpltab, output to port.  If no translation,
; use ascii char in al. (should probably include shift state
; somewhere).  Shift state is in bl.
trnout	proc	near
	test	ourarg.flgs,havtt	; translate table given?
	jz	trnou3			; no, just output character
	cmp	ourarg.klen,0		; did they say we have one 
	je	trnou3			; but we really don't?
	push	ax			; save original value
	xor	ah,ah			; Zero top half
	mov	di,ourarg.ktab
	mov	cx,ourarg.klen
	repne	scasw			; look for our key
	pop	ax			; recover character
	jne	trnou3			; not found, forget it
	sub	di,ourarg.ktab
	sub	di,2			; (minus 2 for pre-increment)
	mov	bx,ourarg.krpl
	mov	si,[bx][di]		; and addr of replacement
	mov	cl,[si]			; get first byte (length)
	xor	ch,ch			; clear high-order byte
	inc	si			; point to translation string
trnou2:	lodsb				; get a byte
	push	si
	push	cx			; save important registers
	call	outprt			; send to port
	pop	cx
	pop	si
	loop	trnou2			; send all chars
	ret				; and return
trnou3:	xor	ah,ah			; get scan code
	mov	cx,lckeys		; length of table
	mov	di,offset ckeys		; table address
	repne	scasb
;	mov	al,0			; ascii code was 0...
	jne	trnou4			; not found, keep going
	sub	di,offset ckeys+1	; get table offset
	shl	di,1			; shift for word offset
	jmp	ckacts[di]		; jump to appropriate routine
trnou4:	call	outprt			; just output single char
	ret				; and return

;trnmod:	test	flags,modoff		; mode line already off?
;	jnz	trnm1			; yes, go turn on
;	call	clrmod			; no, clear mode line here
;	or	flags,modoff		; turn on flag
;	ret				; and return
;trnm1:	call	modlin			; turn on mode line
;	and	flags,not modoff	; clear flag
;	ret				; and return

trnbrk:
	call	sendbr
	ret

trnprs:	xor	flags1,prtscr		; flip the flag
	and	ourarg.flgs,not modoff	; turn on mode line
	call	modlin			; write into mode line
	ret				; and return

trn1ch:	mov	cx,1			; length is always 1
	jmp	trnou2

; common entry for arrow keys
trn2ch:	mov	cx,2			; length is always 2
	jmp	trnou2			; go send definition

trn3ch:	mov	cx,3			; length is always 3
	jmp	trnou2

trnupw:	mov	si,offset uptrn
	jmp	trn2ch

trndnw:	mov	si,offset dntrn
	jmp	trn2ch

trnlfw:	mov	si,offset lftrn
	jmp	trn2ch

trnrgw:	mov	si,offset rgtrn
	jmp	trn2ch

trnhom:	mov	si,offset homtrn
	jmp	trn2ch

trnent:	mov	si,offset enttrn
	jmp	trn1ch

trnf0:	mov	si,offset f0trn
	jmp	trn2ch

trnf1:	mov	si,offset f1trn
	jmp	trn2ch

trnf2:	mov	si,offset f2trn
	jmp	trn2ch

trnf3:	mov	si,offset f3trn
	jmp	trn2ch

trnf4:	mov	si,offset f4trn
	jmp	trn2ch

trnf5:	mov	si,offset f5trn
	jmp	trn2ch

trnf6:	mov	si,offset f6trn
	jmp	trn2ch

trnf7:	mov	si,offset f7trn
	jmp	trn2ch

trnf8:	mov	si,offset f8trn
	jmp	trn2ch

trnf9:	mov	si,offset f9trn
	jmp	trn3ch

trnf10:	mov	si,offset f10trn
	jmp	trn3ch

trnf11:	mov	si,offset f11trn
	jmp	trn3ch

trnkpn:	and	al,07fh			; strip high bits
	jmp	trnou4			; now output it

trnkps:	and	al,03fh			; strip high bits (special case)
	jmp	trnou4

trnsf0:	mov	si,offset sf0trn
	jmp	trn2ch

trnsf1:	mov	si,offset sf1trn
	jmp	trn3ch

trnsf2:	mov	si,offset sf2trn
	jmp	trn3ch

trnsf3:	mov	si,offset sf3trn
	jmp	trn3ch

trnsf4:	mov	si,offset sf4trn
	jmp	trn3ch

trnsf5:	mov	si,offset sf5trn
	jmp	trn3ch

trnsf6:	mov	si,offset sf6trn
	jmp	trn3ch

trnsf7:	mov	si,offset sf7trn
	jmp	trn3ch

trnsf8:	mov	si,offset sf8trn
	jmp	trn3ch

trnsf9:	mov	si,offset sf9trn
	jmp	trn3ch

trnsf10: mov	si,offset sf10trn
	jmp	trn3ch

trnsf11: mov	si,offset sf11trn
	jmp	trn3ch

trnskp1: mov	si,offset skp1trn
	jmp	trn2ch

trnskp2: mov	si,offset skp2trn
	jmp	trn2ch

trnskp3: mov	si,offset skp3trn
	jmp	trn2ch

trnskp4: mov	si,offset skp4trn
	jmp	trn2ch

trnskp5: mov	si,offset skp5trn
	jmp	trn2ch

trnskp6: mov	si,offset skp6trn
	jmp	trn2ch

trnskp7: mov	si,offset skp7trn
	jmp	trn2ch

trnskp8: mov	si,offset skp8trn
	jmp	trn2ch

trnskp9: mov	si,offset skp9trn
	jmp	trn2ch

trnout	endp

code	ends 
	end

