;       SCCSID = @(#)putc.asm	6.2 91/01/14
SCCSID      equ     "@(#)putc.asm	6.2 91/01/14"
;
;	IBM/Microsoft Confidential
;
;	Copyright (c) IBM Corporation 1987, 1990
;	Copyright (c) Microsoft Corporation 1987, 1990
;
;	All Rights Reserved

;***    PUTC.ASM - com2 output of a single byte

ifdef MEDIUM_MODEL
.MODEL MEDIUM, PASCAL
else
.MODEL SMALL, PASCAL
endif

.286P

ifdef MEDIUM_MODEL
.CODE _TEXT
else
.CODE
endif


;**     Most of this stuff is ripped off from kernel debugger

COM1_PORT       equ     03f8H
COM2_PORT       equ     02f8H

COM_DAT         equ     00H
COM_IEN         equ     01H             ; interrupt enable
COM_IER         equ     02H             ; interrupt ID
COM_LCR         equ     03H             ; line control registers
COM_MCR         equ     04H             ; modem control register
COM_LSR         equ     05H             ; line status register
COM_MSR         equ     06H             ; modem status regiser
COM_DLL         equ     00H             ; divisor latch least sig
COM_DLM         equ     01H             ; divisor latch most sig


IODelay Macro
	local a
	jmp a
a:
endm

ifdef MEDIUM_MODEL
PollC   PROC    FAR
else
PollC   PROC
endif

		mov     dx, ds:PortAdr
		add     dx, COM_LSR

		in      al,dx                   ; get input status
		IODelay

		and     al,1                    ; is there a char in RECV buffer?
		jz      plc1                    ; no, go return empty

		mov     dx, ds:PortAdr
		add     dx, COM_DAT

		in      al,dx                   ; suck char out of buffer
		IODelay

		and     al,07fh                 ; strip off stupid parity crap
plc1:   ret
PollC   ENDP


;**     PUTC - output a single char to COM2 handling ^S

ifdef MEDIUM_MODEL
PUTC    PROC    FAR     chData:WORD
else
PUTC    PROC            chData:WORD
endif

;       See if ^S

		call    PollC               ; is there a char at input
		jz      pc2                 ; no, go output our char
		cmp     al,'S' - 'A' + 1    ; is it ^S?
		jnz     pc2                 ; no, go output our char

;       Saw ^S.  Wait for and eat next char.

pc1:    call    PollC               ; look for next char
		jz      pc1                 ; no char, go look again
		cmp     al,'S' - 'A' + 1    ; is it ^S again?
		jz      pc1                 ; yes, go look for something else

pc2:    mov     dx, ds:PortAdr
		add     dx, COM_LSR
		in      al,dx
		IODelay
		test    al,020h
		jz      pc2

;       ready.  crank it out!

		mov     dx, ds:PortAdr
		add     dx, COM_DAT
		mov     ax,chData
		out     dx,al
		IODelay
		ret    

PUTC    endp


;       ComInit - looks at a global to determine which port to use
;                 and sets up a variable to use later that contains
;                 the address of desired port


ifdef MEDIUM_MODEL
ComInit PROC    FAR Port:word
else
ComInit PROC        Port:word
endif

		cmp     Port, 1                 ; test the global       
		jz      cini1                   ; jump if com1
		mov     ds:PortAdr, COM2_PORT   ; desired port is com2
		ret
cini1:  mov     ds:PortAdr, COM1_PORT   ; desired port is com1
		ret     
ComInit ENDP     

.DATA
PUBLIC PortAdr
PortAdr DW COM2_PORT            ; actual adr of which port to
								; use: com2=02f8H, com1=03f8H
end
