File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)1		public  serini, serrst, clrbuf, outchr, coms, vts, dodel, ctlu
****
2)1	; MS-DOS Kermit system-dependent module for the Wang PC
2)	; Jeff Damens, CUCCA
2)		public  serini, serrst, clrbuf, outchr, coms, vts, dodel, ctlu
**************
1)1	        include msdefs.h
1)	false   equ     0
****
2)1	        include mssdef.h
2)	false   equ     0
**************
1)1	rs      equ     1fh             ;extended code prefix for wang      
1)	scnwrds	equ	2047			; number of words in wang screen area
1)	wngscrn	equ	0F000h			; starting address of wang screen area
1)	datas   segment public 'datas'
1)	        extrn   drives:byte, flags:byte, trans:byte
1)		extrn	portval:word, port1:byte, port2:byte, swchar:byte
1)	machnam	db	'Wang PC$'
1)	curini	db	0		; [gaw@prc]
1)	cursav	db	esc,'[s','$'	; [gaw@prc]
1)	curres	db	esc,'[u','$'	; [gaw@prc]
1)	scrsav	dw	scnwrds DUP(?)
1)	portin	db	0
1)	crlf    db      cr,lf,'$'
1)	noimp	db	cr,lf,'Command not implemented.$'
1)	xofsnt	db	0		; Say if we sent an XOFF.
1)	xofrcv	db	0		; Say if we received an XOFF.
1)	invseq	db	esc,'[7m$'	; Reverse video on.
****
2)1	datas   segment public 'datas'
2)	        extrn   drives:byte, flags:byte, trans:byte
2)		extrn	portval:word, port1:byte, port2:byte
2)	portin	db	0
2)	crlf    db      cr,lf,'$'
2)	machnam	db	'FIELD TEST Wang$'
2)	noimp	db	cr,lf,'Command not implemented.$'
2)	shkmsg	db	'Not implemented.'
2)	shklen	equ	$-shkmsg
2)	xofsnt	db	0		; Say if we sent an XOFF.
2)	xofrcv	db	0		; Say if we received an XOFF.
2)	setktab	db	0
2)	setkhlp	db	0
2)	invseq	db	esc,'[7m$'	; Reverse video on.
**************
1)1	argadr	dw	?		; address of arg blk
1)	uptrn	db	esc,'A'
1)	dntrn	db	esc,'B'
1)	rgtrn	db	esc,'C'
1)	lftrn	db	esc,'D'
1)	; key redefinitions
1)	ktrntab	dw	?			; address of translation table
1)	krpltab	dw	?			; address of replacement table
1)	tmptab	db	0eh,3bh			; scan code for bs, f1
1)	ktlen	dw	?
1)	setktab	db	12
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)		mkeyw	'BACKSPACE',0eh
1)		mkeyw	'F1',3bh
1)		mkeyw	'F2',3ch
1)		mkeyw	'F3',3dh
1)		mkeyw	'F4',3eh
1)		mkeyw	'F5',3fh
1)		mkeyw	'F6',40h
1)		mkeyw	'F7',41h
1)		mkeyw	'F8',42h
1)		mkeyw	'F9',43h
1)		mkeyw	'F10',44h
1)		mkeyw	'SCAN',-1
1)	setkhlp	db	cr,lf,'Keyname: backspace, f1, ... f10, or "SCAN" follwed by '
1)		db	'decimal scan code$'
1)	rbtrn	db	7fH		; rubout
1)	shkbuf	db	300 dup (?)	; room for definition
1)	shkmsg	db	'  Scan code: '
1)	shkmln	equ	$-shkmsg
1)	shkms1	db	cr,lf,'  Definition: '
1)	shkm1ln	equ	$-shkms1
1)	; Entries for choosing communications port. [19b]
****
2)1	; Entries for choosing communications port. [19b]
**************
1)1	; put the number in ax into the buffer pointed to by di.  Di is updated
1)	nout	proc	near
1)		push	dx		; save registers
1)		push	bx
1)		push	ax
1)		mov	dx,0		; high order is always 0.
1)		mov	bx,10
1)		div	bx		; divide to get digit
1)		push	dx		; save remainder digit
1)		or	ax,ax		; test quotient
1)		jz	nout1		; zero, no more of number
1)		call	nout		; else call for rest of number
1)	nout1:	pop	ax		; get digit back
1)		add	al,'0'		; make printable
1)		stosb			; drop it off
1)		pop	ax		; restore all registers
1)		pop	bx
1)		pop	dx
1)		ret			; and return
1)	nout	endp
1)	;NOUT	PROC	NEAR
1)	;        cbw                     ; extend to word
1)	;        div     byte ptr ten    ; divide by 10
1)	;        or      al,al           ; any quotient?
1)	;        jz      nout1           ; no, forget this
1)	;        push    ax              ; save current result
1)	;        call    nout            ; output high order
1)	;        pop     ax              ; restore
1)	;nout1:  mov     al,ah           ; get digit
1)	;        add     al,'0'          ; make printable
1)	;        stosb
1)	;        ret                     ; put in buffer and return
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)	;NOUT    endp
1)	; Perform a delete.
****
2)1	NOUT	PROC	NEAR
2)	        cbw                     ; extend to word
2)	        div     byte ptr ten    ; divide by 10
2)	        or      al,al           ; any quotient?
2)	        jz      nout1           ; no, forget this
2)	        push    ax              ; save current result
2)	        call    nout            ; output high order
2)	        pop     ax              ; restore
2)	nout1:  mov     al,ah           ; get digit
2)	        add     al,'0'          ; make printable
2)	        stosb
2)	        ret                     ; put in buffer and return
2)	NOUT    endp
2)	; Perform a delete.
**************
1)1	lclini:
1)		mov	flags.vtflg,0	; turn off terminal emulation [gaw@prc]
1)		mov trans.escchr,ctrla	; Use Control-A as escape char.
1)		mov swchar,'/'
1)		ret
1)	;*********** SHOWKEY added 12/11/84 --shotton **************
1)	; show the definition of a key.  The terminal argument block (which contains
1)	; the address and length of the definition tables) is passed in ax.
1)	; Returns a string to print in AX, length of same in CX.
1)	; Returns normally.
1)	showkey	proc	near
1)		push	es
1)		push	ax		; save the ptr
1)		mov	bx,ds
1)		mov	es,bx		; address data segment
1)		cld
1)	showk1:
1)		mov	dl,0ffh		; wait for input but don't echo
1)		mov	ah,coninq
1)		int	dos
1)	;	or	al,al		; extended code?
1)	        cmp     al,rs		;wang prefix for extended code
1)		mov	ah,0
1)		jnz	noalt		; no, skip getting 2nd char
1)		mov	dl,0ffh		; get 2nd char
1)		mov	ah,coninq
1)		int	dos
1)		mov	ah,08h		; fake, alt key in ah
1)	;	xor	ah,ah
1)	;	call	prtchr		; read a char
1)	;	nop
1)	;	nop
1)	;	nop
1)	;	or	ax,ax		; get one?
1)	;	jz	showk1		; nope, wait
1)	;	push	ax		; save the character
1)	;	call	gss		; get shift state
1)	;	pop	bx
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)	;	mov	ah,al		; shift state to ah
1)	;	mov	al,bh		; scan code to al
1)	noalt:
1)		push	ax		; remember scan code
1)		mov	di,offset shkbuf
1)		mov	si,offset shkmsg
1)		mov	cx,shkmln
1)		rep	movsb		; copy in initial message
1)		call	nout		; write out scan code
1)		mov	si,offset shkms1
1)		mov	cx,shkm1ln	; second message
1)		rep	movsb
1)		pop	ax		; get scan code back
1)		pop	bx		; and terminal arg block
1)		mov	cx,[bx].klen	; and length
1)		jcxz	showk2		; no table, not defined
1)		push	di		; remember output ptr
1)		mov	di,[bx].ktab	; get key table
1)		repne	scasw		; search for a definition for this
1)		mov	si,di		; remember result ptr
1)		pop	di		; get output ptr back
1)		jne	showk2		; not defined, forget it
1)		sub	si,[bx].ktab	; compute offset from beginning
1)		sub	si,2		; minus 2 for pre-increment
1)		add	si,[bx].krpl	; get index into replacement table
1)		mov	si,[si]		; pick up replacement
1)		mov	cl,[si]		; get length
1)		mov	ch,0
1)		inc	si
1)		rep	movsb		; copy into buffer
1)	showk2:	mov	ax,offset shkbuf ; this is buffer
1)		mov	cx,di
1)		sub	cx,ax		; length
1)		pop	es
1)		ret			; and return
1)	showkey	endp
1)	;     Common initialization for using serial port.
****
2)1	lclini: mov trans.escchr,ctrla	; Use Control-A as escape char.
2)		ret
2)	showkey:
2)		mov ax,offset shkmsg
2)		mov cx,shklen
2)		ret
2)	;     Common initialization for using serial port.
**************
1)1	; send the character in al out to the serial port
1)	; handle echoing also...
1)	outprt	proc	near
1)		test	flags,lclecho		; echoing?
1)		jz	outpr1			; no, forget it
1)		push	ax			; save char
1)		mov dl,al
1)		and dl,7fh		; mask off parity for terminal
1)		mov ah,dconio
1)		int dos			; write	out the	character
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)		pop	ax			; restore
1)	outpr1:	mov	ah,al			; this is where outchr expects it
1)		call	outchr			; output to the port
1)		 nop
1)		 nop
1)		 nop				; skip returns...
1)		ret
1)	outprt	endp
1)	argini	proc	near			; read passed arguments
1)		mov	bx,argadr		; base of argument block
1)		mov	al,[bx].flgs		; get flags
1)		and	al,capt+emheath+havtt+trnctl+lclecho  ; +modoff
1)		mov	flags,al		; mask for allowable and save
1)	;	and	flags1,not (prtscr)	; these are allowable
1)						; (others remain).
1)		mov	al,[bx].prt
1)	;	cmp	al,portno		; using same port?
1)	;	je	argin1			; yes, go on
1)	;	and	flags1,not inited	; else re-init stuff
1)	argin1:
1)	;	mov	portno,al		; update port number
1)	;	mov	ax,[bx].captr
1)	;	mov	captrtn,ax		; buffer capture routine
1)	;	mov	ax,[bx].belld
1)	;	mov	beldiv,ax		; bell divisor
1)		mov	ax,[bx].klen
1)		mov	ktlen,ax		; length of key redef tbl
1)		mov	ax,[bx].ktab
1)		mov	ktrntab,ax		; save key translation table
1)		mov	ax,[bx].krpl
1)		mov	krpltab,ax
1)	;	mov	al,[bx].escc
1)	;	mov	esc_ch,al
1)		ret				; that's it
1)	argini	endp
1)	term	proc	near
1)		push	ax
1)		push	es
1)		mov si,ax		; this is source
1)		mov di,offset ourarg	; place	to store arguments
1)		mov ax,ds
1)		mov es,ax		; address destination segment
1)		mov cx,size termarg
1)		rep movsb		; copy into our	arg blk
1)		pop	es
1)		pop	ax
1)		mov	argadr,ax		; save argument ptr
1)		push	es			; save caller's extra segment address
1)		mov	ax,seg datas
1)		mov	es,ax
1)		call	argini			; init options from arg address
1)		cmp	curini,0		; have we been in here before[gaw@prc]
1)		je	term1			; if not skip restoring cursor[gaw@prc]
1)		call	restscr			; restore screen
1)		cmp	flags.vtflg,0		; are we in emulation mode[gaw@prc]
1)		jne	term1			; if we are skip restoring cursor[gaw@prc]
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)		mov	ah,prstr		; send '<esc>[u' to ansi.sys[gaw@prc]
1)		mov	dx,offset curres	; [gaw@prc]
1)		int	dos			; [gaw@prc]
1)	term1:
1)		call prtchr
1)		jmp short term2		; have a char...
1)		nop
1)		nop
1)		jmp short term3		; no char, go on
1)	term2:	push ax
1)		mov dl,al
1)		and dl,7fh		; mask off parity for terminal
1)		mov ah,dconio
1)		int dos			; write	out the	character
1)		pop ax
1)		test ourarg.flgs,capt	; capturing output?
1)		jz term3		; no, forget it
1)		call ourarg.captr	; else call the	routine
1)	term3:
1)		mov ah,dconio
1)		mov dl,0ffh
1)		int dos
1)		jz term1		; no character,	go on
1)		cmp al,ourarg.escc	; escape char?
1)		je term4		; yes, exit
1)	;	or	al,al		; extended code?
1)		cmp	al,rs		; wang extended code
1)		mov	bl,0
1)		jnz	no2nd		; no, skip getting 2nd char
1)		mov	dl,0ffh		; get 2nd char
1)		mov	ah,coninq
1)		int	dos
1)		mov	ah,al		; duplicate char in ah for "call turnout"
1)		mov	bl,08h		; fake, alt key in bl for "call turnout"
1)	no2nd:
1)		call	trnout		; translate if necessary
1)	;	push ax			; save char
1)	;	mov ah,al
1)	;;	or ah,80H		; ?? turn on hi bit so DOS doesn't interfere
1)	;	call outchr		; output the character
1)	;	nop
1)	;	nop
1)	;	nop
1)	;	pop ax
1)	;	test ourarg.flgs,lclecho ; echoing?
1)	;	jz term1		; no, continue loop
1)	;
1)	;	mov dl,al
1)	;	mov ah,dconio
1)	;	int dos
1)		jmp term1		; else echo and	keep going
1)	term4:
1)		cmp	flags.vtflg,0		; are we in emulation mode[gaw@prc]
1)		jne	term5			; if we are skip saving cursor[gaw@prc]
1)		mov	ah,prstr		; send '<esc>[s' to ansi.sys[gaw@prc]
1)		mov	dx,offset cursav	; [gaw@prc]
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)		int	dos			; [gaw@prc]
1)		mov	byte ptr curini,1	; now we've saved the cursor[gaw@prc]
1)	term5:					; [gaw@prc]
1)		call	savescr			; save screen [gaw@prc]
1)		mov	al,flags
1)		mov	bx,argadr
1)		mov	[bx].flgs,al		; update flags in arg block
1)		pop	es			; restore segment register
1)		ret				; and return to caller
1)	term	endp
1)	savescr	proc near
1)		push	es
1)		call	getvid			; dx = addr of video write option reg
1)		mov	al,1			; enable memory mapped access
1)		out	dx,al
1)		push	ds			; move ds base address to es
1)		pop	es
1)		mov	di,offset scrsav	; point to start of screen save area
1)		push	ds
1)		mov	ax,wngscrn		; point to base page with ds
1)		mov	ds,ax
1)		mov	si,0			; point to screen memory area
1)		mov	cx,scnwrds		; setup word count
1)		rep	movsw			; transfer image to save area
1)		call	getvid			; dx = addr of video write option reg
1)		xor	ax,ax			; disable memory mapped access
1)		out	dx,al
1)		pop	ds			; restore registers and return
1)		pop	es
1)		ret
1)	savescr	endp
1)	restscr	proc near
1)		push	es
1)		call	getvid			; dx = addr of video write option reg
1)		mov	al,1			; enable memory mapped access
1)		out	dx,al
1)		mov	ax,wngscrn		; point to base page with es
1)		mov	es,ax
1)		mov	di,0			; point to screen memory area
1)		mov	si,offset scrsav	; point to start of screen save area
1)		mov	cx,scnwrds		; setup word count
1)		rep	movsw			; transfer image to screen
1)		call	getvid			; dx = addr of video write option reg
1)		xor	ax,ax			; disable memory mapped access
1)		out	dx,al
1)		pop	es			; restore register and return
1)		ret
1)	restscr	endp
1)	getvid	proc near
1)		mov	ax,1			; get pointer to system config. table
1)		int	88h
1)		mov	bx,es:[bx+0Ah]		; get pointer to screen info table
1)		mov	dl,es:[bx]		; get 'state' from screen info table
1)		and	dx,000fh		; setup nibble for screen activation
1)		xchg	dh,dl
1)		or	dx,1010h		; base of video controller i/o ports
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)		ret
1)	getvid	endp
1)	; translate the scan code in ah according to the translate table
1)	; given in ktrntab/krpltab, output to port.  If no translation,
1)	; use ascii char in al. (should probably include shift state
1)	; somewhere).  Shift state is in bl.
1)	trnout	proc	near
1)	;	cmp	ah,4eh			;*** plus key thing?
1)	;	je	trnmod			; yes, go toggle mode line
1)	trnou1:
1)		test	flags,havtt		; translate table given?
1)		jz	trnou3			; no, just output character
1)		push	ax			; save original value
1)		mov	al,ah			; put scan code into ah
1)		mov	ah,bl			; shift state into top half.
1)		mov	di,ktrntab		; pick up translate tbl
1)		mov	cx,ktlen		; length of tbl
1)		repne	scasw			; look for our key
1)		pop	ax			; recover character
1)		jne	trnou3			; not found, forget it
1)		sub	di,ktrntab		; get index into tbl
1)		sub	di,2			; (minus 2 for pre-increment)
1)		mov	bx,krpltab		; get replacement table
1)		mov	si,[bx][di]		; and addr of replacement
1)		mov	cl,[si]			; get first byte (length)
1)		xor	ch,ch			; clear high-order byte
1)		inc	si			; point to translation string
1)	trnou2:	lodsb				; get a byte
1)		push	si
1)		push	cx			; save important registers
1)		call	outprt			; send to port
1)		pop	cx
1)		pop	si
1)		loop	trnou2			; send all chars
1)		ret				; and return
1)	trnou3:
1)	;	cmp	al,0			; is it a special code?
1)	;	jne	trnou4			; no, don't do this
1)	;	mov	al,ah			; get scan code
1)	;	mov	cx,lckeys		; length of table
1)	;	mov	di,offset ckeys		; table address
1)	;	repne	scasb
1)	;	mov	al,0			; ascii code was 0...
1)	;	jne	trnou4			; not found, keep going
1)	;	sub	di,offset ckeys+1	; get table offset
1)	;	shl	di,1			; shift for word offset
1)	;	jmp	ckacts[di]		; jump to appropriate routine
1)	;trnou4:
1)		call	outprt			; just output single char
1)		ret				; and return
1)	;trnmod:	test	flags,modoff		; mode line already off?
1)	;	jnz	trnm1			; yes, go turn on
1)	;	call	clrmod			; no, clear mode line here
1)	;	or	flags,modoff		; turn on flag
1)	;	ret				; and return
1)	;trnm1:	call	modlin			; turn on mode line
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

1)	;	and	flags,not modoff	; clear flag
1)	;	ret				; and return
1)	;
1)	;trnbrk:	mov	ah,dconio
1)	;	mov	dl,0ffH
1)	;	int	dos			; read the bogus ^C DOS gets.
1)	;	call	sendbr
1)	;	ret
1)	;trnprs:	xor	flags1,prtscr		; flip the flag
1)	;	and	flags,not modoff	; turn on mode line
1)	;	mov	si,offset prton
1)	;	mov	cx,prtnlen
1)	;	test	flags1,prtscr		; did it go on?
1)	;	jnz	trnpr1			; yes, say so
1)	;	mov	si,offset prtoff
1)	;	mov	cx,prtflen
1)	;trnpr1:	call	modwrt			; write into mode line
1)	;	ret				; and return
1)	; common entry for arrow keys
1)	trnarr:	mov	cx,2			; length is always 2
1)		jmp	trnou2			; go send definition
1)	trnupw:	mov	si,offset uptrn
1)		jmp	trnarr
1)	trndnw:	mov	si,offset dntrn
1)		jmp	trnarr
1)	trnlfw:	mov	si,offset lftrn
1)		jmp	trnarr
1)	trnrgw:	mov	si,offset rgtrn
1)		jmp	trnarr
1)	trnout	endp
1)	code	ends
1)	        end
****
2)1	term    proc    near
2)	        mov si,ax               ; this is source
2)	        mov di,offset ourarg    ; place to store arguments
2)	        mov ax,ds
2)	        mov es,ax               ; address destination segment
2)	        mov cx,size termarg
2)	        rep movsb               ; copy into our arg blk
2)	term1:  call prtchr
2)	        jmp short term2         ; have a char...
2)	        nop
2)	        nop
2)	        jmp short term3         ; no char, go on
2)	term2:	and al,7fh
2)		push ax
2)	        mov dl,al
2)		mov ah,dconio
2)	        int dos                 ; write out the character
2)	        pop ax
2)	        test ourarg.flgs,capt   ; capturing output?
2)	        jz term3                ; no, forget it
2)	        call ourarg.captr       ; else call the routine
2)	term3:  mov ah,dconio
2)	        mov dl,0ffh
File 1)	MSXWNG.ASM.1,27-Jan-86 17:41:26
File 2)	PB:<KERMIT>MSXWNG.ASM.2, 6-Jan-86 15:23:36

2)	        int dos
2)		or al,al
2)	        jz term1                ; no character, go on
2)	        cmp al,ourarg.escc      ; escape char?
2)	        je term4                ; yes, exit
2)	        push ax                 ; save char
2)	        mov ah,al
2)	        call outchr             ; output the character
2)	        nop
2)	        nop
2)	        nop
2)	        pop ax
2)	        test ourarg.flgs,lclecho ; echoing?
2)	        jz term1                ; no, continue loop
2)	        mov dl,al
2)	        mov ah,dconio
2)	        int dos
2)	        jmp term1               ; else echo and keep going
2)	term4:	ret
2)	term    endp
2)	code	ends
2)	        end
**************
