{ File: [Iris]<WMicro>DLion>RS232CMisc.asm
Modification History:

Dennis Grundler:  1-Sep-84 17:13:02 Add copyright notice.
Michael Thatcher:  3-Jan-84 15:04:21  Add Async Flow Control
Dennis Grundler:  1-Dec-83 18:22:25  More on fix for DTR/RTS glitch.
Dennis Grundler:  9-Oct-83 11:02:36  Added Siemens 9750 support.
Dennis Grundler: 12-Jul-83 23:44:37  Do naked notify after simple command (improve performance).
Dennis Grundler:  1-Jul-83 13:33:14 .Put in fix for DTR/RTS glitch on SetParameters
Dennis Grundler: 30-Jun-83 11:12:50 meet IBM specs.
Dennis Grundler: 26-Jun-83 17:03:12 to incorporate changes made by Amy Fasnacht : 10-Jun-83 15:42:21: Add GetTaskStartAddress stuff for fixing CTS naked notify. Also incorporate changes made by Allen TSang and Tommy Chang: 17-May-83  9:11:09 Initialization of SIO for RS232C
Chuck Fay :  9-Jan-83 19:04:18: Fix send break command.
Jim Frandeen : October 15, 1982  10:36 AM: Test for Voice command.  
Jim Frandeen : September 8, 1982  4:56 PM: Change handling of abort.
Jim Frandeen : August 5, 1982  10:36 AM: new IO Page format
Created by Jim Frandeen : March 25, 1982  1:53 PM
}

{ 	Copyright (C) 1982, 1983, 1984 by Xerox Corporation.  All rights reserved.}


	Get "SysDefs"			
	Get "CommonDefs"
	Get "RS232CDefs"

	IMP	AsyncRS232CInterrupt	;From Rs232CInterrupts
	IMP	AbortGetFlag		;From RS232CGet
	IMP	AbortPutFlag		;From RS232CPut
	IMP	AsyncGetLoop		;From RS232CGet
	IMP	AsynchronousDivisor	;From SIOSubs
	IMP	BEL1			;From BisyncInterrupts
	IMP	BEL6			;From BisyncInput
	IMP	BisyncGetLoop		;From RS232CGet
	IMP	BisyncRS232CInterrupt	;From Rs232CInterrupts
	IMP	BisyncTimerTable	;From SIOSubs
	IMP	Copy			;From CPSubs
	IMP	DisableRST		;From Common
	IMP	DisableRxCRC1		;From BisyncInput
	IMP	DisableRxCRC2		;From BisyncInput
	IMP	DisableRxCRC3		;From BisyncInput
	IMP	DisableTxCRC1		;From BisyncInterrupts
	IMP	DoNakedNotify		;From Common
	IMP	EnableRST		;From Common
	IMP	EnableRxCRC1		;From BisyncInput
	IMP	EnableRxCRC2		;From BisyncInput
	IMP	EnableRxCRC3		;From BisyncInput
	IMP	EnableRxCRC4		;From BisyncInput
	IMP	EnableTxCRC1		;From BisyncInterrupts
	IMP	EndOfBisyncFrame	;From BisyncInput
	IMP	ENQ1			;From BisyncInterrupts
	IMP	ENQ2			;From BisyncInterrupts
	IMP	ENQ4			;From BisyncInterrupts
	IMP	ENQ6			;From BisyncInput
	IMP	ENQ9			;From BisyncInput
	IMP	ENQ10			;From BisyncInput
	IMP	ENQ11			;From BisyncInput
	IMP	ENQ12			;From BisyncInterrupts
	IMP	EnterHuntMode1		;From BisyncInput
	IMP	EnterHuntMode2		;From BisyncInput
	IMP	EOT1			;From BisyncInterrupts
	IMP	EOT6			;From BisyncInput
	IMP	EOTEndFrameSwitch	;From BisyncInput
	IMP	EOT3270			;From BisyncInput
	IMP	ETB2			;From BisyncInterrupts
	IMP	ETB4			;From BisyncInterrupts
	IMP	ETB5			;From BisyncInterrupts
	IMP	ETB6			;From BisyncInterrupts
	IMP	ETB7			;From BisyncInput
	IMP	ETB8			;From BisyncInput
	IMP	ETB9			;From BisyncInput
	IMP	ETB10			;From BisyncInput
	IMP	ETB11			;From BisyncInput
	IMP	ETB12			;From BisyncInterrupts
	IMP	FCState			;From RS232CInterrupts
	IMP	FlowControlFlag		;From RS232CInterrupts
	IMP	GetModeSwitch		;From RS232CGet
	IMP	GetTaskResumeAddress	;From RS232CGet
	IMP	GetTaskStartAddress	;From RS232CGet		CTS fix.
	IMP	GetTaskQuiet		;From RS232CGet
	IMP	HLPlus2A		;From SIOSubs
	IMP	LastBufferFlag		;From RS232CInterrupts
	IMP	NAK1			;From BisyncInterrupts
	IMP	NAK6			;From BisyncInput
	IMP	OverflowFlag		;From RS232CInterrupts
	IMP	OneSecondTimerLow	;From BisyncInterrupts
	IMP	OneSecondTimerHigh	;From BisyncInterrupts
	IMP	PortBusyFlag		;From CPSubs
	IMP	PrevAsyncDCD		;From RS232CInterrupts
	IMP	PrevCTS			;From RS232CInterrupts
	IMP	PrevBisyncDCD		;From RS232CInterrupts
	IMP	PrevSdlcDCD		;From BisyncInterrupts
	IMP	PutAsyncMode		;From RS232CPut
	IMP	PutBisyncMode		;From RS232CPut
	IMP	PutSdlcMode		;From RS232CPut
	IMP	PutModeSwitch		;From RS232CPut
	IMP	PutTaskResumeAddress	;From RS232CPut
	IMP	PutTaskQuiet		;From RS232CPut
	IMP	ReadCPBuffer		;From CPSubs
	IMP	ResetChannels		;From SIOSubs
	IMP	RS232CGetFlag		;From BookKeepingTask
	IMP	RS232CInterruptSwitch	;From Common
	IMP	RS232CPutFlag		;From BookKeepingTask
	IMP	RS232CMiscFlag		;From BookKeepingTask
	IMP	RS232CMiscCommand	;From BookKeepingTask
	IMP	RxFIFO
	IMP	RxFifoEnd
	IMP	RxInitBiSyncInput	;From BisyncInput
	IMP	SdlcGetLoop		;From RS232CGet
	IMP	SdlcRS232CInterrupt	;From Rs232CInterrupts
	IMP	SetAsyncTimer		;From RS232CSubs
	IMP	SetBaudRate		;From SIOSubs
	IMP	SetRS366		;From SIOSubs
	IMP	StartGetTask		;From RS232CGet
	IMP	StartPutTask		;From RS232CPut
	IMP	SYN1			;From BisyncInterrupts
	IMP	SYN2			;From BisyncInterrupts
	IMP	SYN3			;From BisyncInterrupts
	IMP	SYN4			;From BisyncInterrupts
	IMP	SYN5			;From BisyncInterrupts
	IMP	SYN6			;From BisyncInterrupts
	IMP	SYN7			;From BisyncInput
	IMP	SYN8			;From BisyncInput
	IMP	SYN9			;From BisyncInput
	IMP	SYN10			;From BisyncInput
	IMP	SYN11			;From BisyncInput
	IMP	SYN12			;From BisyncInterrupts
	IMP	SYN13			;From BisyncInput  6/30/83
	IMP	SYN14			;From BisyncInput  6/30/83
	IMP	SynchronousDivisor	;From SIOSubs
	IMP	TestStatusChange	;From RS232CGet		CTS fix.
	IMP	TxInitBiSyncInterrupts
	{IMP	VoiceCommandTask}	;From VoiceTask
	IMP	WriteCPBuffer		;From CPSubs
	IMP	XoffChar
	IMP	XoffReceivedFlag
	IMP	XonChar
	IMP	ZeroCommand		;From Common

	EXP	CurrentCharLengthMask	;Parameter
	EXP	CurrentCorrespondent
	EXP	CurrentRS366Status	;Parameter
	EXP	CurrentSyncCharacter	;Parameter
	EXP	CurrentSyncCount	;Parameter
	EXP	RS232CMiscTask		;Parameter
	EXP	RS232CMode		;Parameter
	EXP	RS232CTaskWakeMask
	EXP	RxWR1			;Parameter
	EXP	RxWR3			;Parameter
	EXP	RxWR4			;Parameter
	EXP	TxWR1			;Parameter
	EXP	TxWR4			;Parameter
	EXP	TxWR5			;Parameter
	{EXP	VoiceSwitch}
;
{  Commented out until we can get Voice to work with the rest of Domino.
	DB	opJMP
VoiceSwitch:
	DW	RS232CMiscTask		;Set by StopVoiceBox
;	DW	VoiceCommandTask		Set by first voice command
}

RS232CMiscTask:
	LDA	PortBusyFlag
	ORA	A
	JNZ	MiscYield

	DB	opJMP
MiscTaskResumeAddress:
	DW	CheckMiscFlag
;	JMP	WaitForGetAbort
;	JMP	WaitForPutAbort

CheckMiscFlag:
{RS232CMiscFlag is the same word as VoiceCommand. For RS232C commands, the high order bit is set. For voice commands, the high order bit is zero.}
	LDA	RS232CMiscFlag
	ORA	A
	JZ	MiscYield		
	JM	MiscCommand

{Continue if this is the first voice command. From now until we get a StopVoiceBox, we will skip RS232CMiscTask, RS232CGet, and RS232CPut.}
{
	LXI	H,VoiceCommandTask
	SHLD	VoiceSwitch
	PCHL			;Jump to VoiceCommandTask
}	JMP	MiscYield	;Temporarily Yield until voice works.

MiscCommand:
	LXI	H,ReadMiscCSB
	CALL	ReadCPBuffer

{The Misc Task implements the following commands. The command numbers are defined in IOPInterfaceDefs.mesa.}

	LDA	RS232CMiscCommand	 
	ORA	A
	JZ	DoOn		;Zero is On command
	CPI	1
	JZ	DoOff
	CPI	2
	JZ	DoBreakOn
	CPI	3
	JZ	DoBreakOff
	CPI	4
	JZ	DoAbortInput
	CPI	5
	JZ	DoAbortOutput
	CPI	6
	JZ	DoSetRS366Status
	CPI	7
	JZ	DoGetStatus
	CPI	8
	JZ	DoMajorSetParameters
	CPI	14
	JZ	DoMinorSetParameters
	CPI	15
	JZ	DoSetChannelResetFlag		{1 Jul 83}
	{BREAK}			;treat all other commands as a Nop or break for debugging

{Continue if IOP Command is invalid.}
	JMP	ResetMiscTaskFlag
;
CurrentCorrespondent:
	DB	0

RS232CMiscCSB:
RS232CParameter4:
	DS	2		;1402C
RS232CParameter3:
	DS	1		;1402D low
RS232CParameter3Hi:
	DS	1		;1402D  high
RS232CParameter2:
	DS	1		;1402E
RS232CParameter2Hi:
	DS	1		;1402E high
RS232CParameter1:
	DS	1		;1402F low
RS232CParameter1Hi:
	DS	1		;1402F high
RS232CTaskWakeMask:
	DS	2		;14030
RS232CParameterFlowControl:
	DS	2
RS232CParameterXOn:
	DS	2
RS232CParameterXoff:
	DS	2

RS232CParameter:
	DS	1		;14036 low
RS232CParameterHi:
	DS	1		;14036 high


RS232CDeviceStatus:
	DS	1		;14035 low
RS232CDeviceStatusHi:
	DS	1		;14035 high


CurrentParameters:
; Channel A is the Rx Channel on the Z80 SIO chip
RxWR1: DB	0
RxWR3: DB	0
RxWR4: DB	0
RxWR5: DB	0

; Channel B is the Rx Channel on the Z80 SIO chip
TxWR1: DB	0
TxWR4: DB	0
TxWR5: DB	0

CurrentCode:
	DB	0		;0 = Ascii, 1 = Ebcdic

{The following characters will be replaced by the Ebcdic or Ascii values, depending on the code used.}
BEL:	DB	0
ENQ:	DB	0
EOT:	DB	0
ETB:	DB	0
NAK:	DB	0
SYN:	DB	0
CurrentRS366Status:
	DB	0		; RS366 Test Status Storage (LocalTim+SIOLpEn)
CurrentParametersSize EQU CurrentRS366Status-RxWR1+1


SdlcDefaultParameters:
{	Default Values for Sdlc mode. These will be moved into CurrentParameters above.}

{RxWR1:}	DB	IntOnAllRxCharacters+ExternalIntEnable	
{RxWR3:}	DB	RxCRCEnable	
{RxWR4:}	DB	X1ClockMode+SdlcMode
{RxWR5:}	DB	0

{TxWR1:}	DB	StatusAffectsVector+ExternalIntEnable+TxIntEnable
{TxWR4:}	DB	X1ClockMode+SdlcMode
{TxWR5:}	DB	TxCRCEnable+TxEnable	

{Code:}	DB	0		
{BEL:}	DB	0
{ENQ:}	DB	0
{EOT:}	DB	0
{ETB:}	DB	0
{NAK:}	DB	0
{SYN:}	DB	0
{Rs366Status:}	DB	0	


AsyncDefaultParameters:
{	Default Values for Async mode. These will be moved into CurrentParameters above.}

{RxWR1:}	DB	IntOnAllRxCharacters+ExternalIntEnable
{RxWR3:}	DB	0
{RxWR4:}	DB	X16ClockMode
{RxWR5:}	DB	0

{TxWR1:}	DB	StatusAffectsVector+ExternalIntEnable+TxIntEnable
{TxWR4:}	DB	X16ClockMode
{TxWR5:}	DB	TxEnable

{Code:}	DB	0
{BEL:}	DB	0
{ENQ:}	DB	0
{EOT:}	DB	0
{ETB:}	DB	0
{NAK:}	DB	0
{SYN:}	DB	0
{RS366Status:}	DB	LocalTim


BisyncDefaultParameters:
{Default values for Bisync mode. These will be moved into CurrentParameters above.}

{RxWR1:}	DB	IntOnAllRxCharacters+ExternalIntEnable
{RxWR3:}	DB	0
{RxWR4:}	DB	X1ClockMode+SyncCharacter16Bits
{RxWR5:}	DB	BisyncCRC

{TxWR1:}	DB	StatusAffectsVector+ExternalIntEnable+TxIntEnable
{TxWR4:}	DB	X1ClockMode+SyncCharacter16Bits
{TxWR5:}	DB	TxEnable+BisyncCRC		

{Code:}	DB	Ebicdic
{BEL:}	DB	EbcdicBELL
{ENQ:}	DB	EbcdicENQ
{EOT:}	DB	EbcdicEOT
{ETB:}	DB	EbcdicETB
{NAK:}	DB	EbcdicNAK
{SYN:}	DB	EbcdicSYN
{RS366Status:}	DB	0
;
{ Other Parameters}

RS232CMode:
	DB	0		; current mode (0=Sdlc, 1=Bisync, 2=Async)

CurrentCorrespondents:
	DB	0
	  {0 = xerox800
	  1 = xerox850
	  2 = system6
	  3 = cmcII
	  4 = ttyHost
	  5 = oisSystemElement
	  6 = ibm3270Host
	  7 = ibm2770Host
	  8 = ibm6670Host
	  9 = ibm6670
	  10 = xerox860
	  11 = oisSystemElementBSC
	  12 = siemens9750} 

CurrentSyncCount:
	DB	0		;Set from RS232CParameter2
CurrentSyncCharacter:
	DB	0		;Set from RS232CParameter3		 
CurrentBaudRate:
	DB	0		;Set from RS232CParameter1
		{0 = 50 Baud
		1 = 75 Baud
		2 = 110 Baud
		3 = 134.5 Baud
		4 = 150 Baud
		5 = 300 Baud
		6 = 600 Baud
		7 = 1200 Baud
		8 = 2400 Baud
		9 = 3600 Baud
		10 = 4800 Baud
		11 = 7200 Baud
		12 = 9600 Baud
		13 = 19200 Baud
		14 = 48000 Baud
		15 = 56000 Baud}

{CurrentCharLengthMask will be replaced by one of the entries from the table below.}
CurrentCharLengthMask:
	DB	0FFH		; character length mask

CurrentCharLengthMaskTable:
	DB	01FH		; 5 bits
	DB	03FH		; 6 bits
	DB	07FH		; 7 bits
	DB	0FFH		; 8 bits

{This character length table is set up for WR3.}
CharLengthTable:
	DB	0		; 0=Character Length 5 of SIO Command
	DB	80H		; 80H=Character Length 6 of SIO Command
	DB	40H		; 40H=Character Length 7 of SIO Command
	DB	0C0H		; 0C0H=Character Length 8 of SIO Command

AsciiCodeTable:
{Code:}	DB	Ascii
{BEL:}	DB	AsciiBELL
{ENQ:}	DB	AsciiENQ
{EOT:}	DB	AsciiEOT
{ETB:}	DB	AsciiETB
{NAK:}	DB	AsciiNAK
{SYN:}	DB	AsciiSYN
AsciiCodeTableSize  EQU 7

ReadMiscCSB:
	DW	RS232CMiscCSBLoc	; CP Buffer Pointer Low
	DW	CPIOPageHi	; CP Buffer Pointer Hi
	DW	RS232CMiscCSBSize	; CP Buffer Count in bytes
	DW	RS232CMiscCSB	; Pointer to IOP Buffer

ZeroMiscFlag:
	DW	RS232CMiscFlagLoc	; CP Buffer Pointer Low
	DW	CPIOPageHi	; CP Buffer Pointer Hi
	DW	2		; CP Buffer Count in bytes
	DW	ZeroCommand	; Pointer to IOP Buffer

SendDeviceStatus:
	; to transfer RS232C Device Status to CP IOPage
	DW	RS232CDeviceStatusLoc	; CP Buffer Pointer Low
	DW	CPIOPageHi	; CP Buffer Pointer Hi
	DW	RS232CDeviceStatusSize	; CP Buffer Count in bytes
	DW	RS232CDeviceStatus	; Pointer to IOP Buffer

SendParameter:
	; to transfer RS232C Parameter Outcome to IOPage
	DW	RS232CParameterLoc	; CP Buffer Pointer Low
	DW	CPIOPageHi	; CP Buffer Pointer Hi
	DW	RS232CParameterSize	; CP Buffer Count in bytes
	DW	RS232CParameter	; Pointer to IOP Buffer
;
{ Local subroutines}

CopyParameters:
{Copy default parameters into CurrentParameters. On entry, DE points to default parameters, and HL points to the address to be used for RS232C interrupts. Set up the interrupt table address first.}
	SHLD	RS232CInterruptSwitch
	XCHG			;HL ← address of parameters
	LXI	D,CurrentParameters
	MVI	A,CurrentParametersSize	
	JMP	Copy		;Copy and RET

CheckResetRingHeard:
{If ResetRingHeard bit is set, reset the RingHeardLatch.}
	LDA	RS232CParameter2Hi	; Reset Ring Hard, if required
	ANI	CPRRHMask
	RZ	
	XRA	A
	STA	RingHeardLatch
	RET

UpdateTxWR5:
{This procedure is called whenever WR5 changes. We update the value of WR5 with and without CRCEnable for the Bisync interrupt routine.}
	STA	TxWR5	;Update WR5
	STA	DisableTxCRC1
	ORI	TxCRCEnable
	STA	EnableTxCRC1
	RET
;
DoOn:
	MVI	A,Rst65DisableMsk
	CALL	EnableRST	

{Initialize state of Clear To Send and Data Carrier Detect so we will know if they change.}
	XRA	A
	STA	PrevAsyncDCD
	STA	PrevCTS
	STA	PrevBisyncDCD
	STA	PrevSdlcDCD

{Calculate End of Buffer Address and store it for future use}
	LXI	D,RxFIFO		;calculate end of RxFifo
	LXI	H,RxFifoSize
	DAD	D
	SHLD	RxFifoEnd

DoSetChannelResetFlag:		{1 Jul 83}
	JMP	ResetMiscTaskFlag


DoAbortInput:
	STA	AbortGetFlag
	CALL	SetChannelResetFlag
	LXI	H,WaitForGetAbort
	JMP	SaveMiscResumeAddressAndYield

WaitForGetAbort:
	LDA	AbortGetFlag		; the last thing it does is reset the abort flag
	ORA	A
	JNZ	MiscYield		; if not stopped, keep waiting
	STA	OverflowFlag		;Reset the overflow flag.
	JMP	RestoreMiscResumeAddress	; if so, quit now.


{Break key handling -- a break is defined to be holding the serial data transmit line low for 190 milliseconds or more.  To send a break, you have to tell the SIO chip to hold the transmit line low, wait for 190 milliseconds or more, and then tell the SIO chip to stop holding the line low.  The SIO chip will hold the transmit line low if you turn on the "Send Break" bit in write register 5.  It stops holding it low when you turn off the bit.  The waiting is done in the Dandelion RS232C head.}

DoBreakOff:
	LXI	H,TxCont+8000H		;HL points to TxCont register
	LDA	TxWR5
	DI
	MVI	M,PointToWR5		;Send address of WR5		
	MOV	M,A			;Send turn break off command
	EI
	JMP	ResetMiscTaskFlag

DoBreakOn:
	LXI	H,TxCont+8000H		;HL points to TxCont register
	LDA	TxWR5
	ORI	SendBreak
	DI
	MVI	M,PointToWR5		;Send address of WR5		
	MOV	M,A			;Send turn break on command
	EI
{Now abort any puts in progress -- fall through to DoAbortOutput}


DoAbortOutput:
	STA	AbortPutFlag
	LXI	H,WaitForPutAbort
	JMP	SaveMiscResumeAddressAndYield

WaitForPutAbort:
	LDA	AbortPutFlag
	ORA	A		; the last thing it does is reset the abort flag
	JNZ	MiscYield	; if not stopped, keep waiting
RestoreMiscResumeAddress:
	LXI	H,CheckMiscFlag
	SHLD	MiscTaskResumeAddress
	JMP	ResetMiscTaskFlag	; if so, quit now.


DoOff:
	MVI	A,Rst65DisableMsk
	CALL	DisableRST		; Disable Rst 6.5 interrupt
	CALL	ResetChannels	
	LXI	H,GetTaskQuiet
	SHLD	GetTaskStartAddress	; Fix for CTS
	LXI	H,PutTaskQuiet
	SHLD	GetTaskResumeAddress
	JMP	ResetMiscTaskFlag	
;
DoMajorSetParameters:
{Set CurrentParameters depending on RS232CParameter2Hi:

	 (mask 3):
		0 => Sdlc
		1 => Bisync
		2 => Async
}
{Set the mode.}
	LDA	RS232CParameter2Hi	
	ANI	CPLineTypeMask
	STA	RS232CMode
	JZ	SetSdlcParameters	;Zero is Sdlc mode
	CPI	CPBisyncMode
	JZ	SetBisyncParameters

SetAsyncParameters:
{Set up the Async timer.}

	LHLD	RS232CParameter4	; get user-supplied timeout value
	MVI	A,1		; Set timer not running
	CALL	SetAsyncTimer
	LXI	H, PutAsyncMode
	SHLD	PutModeSwitch	; Set JMP instruction
	LXI	H,AsyncGetLoop
	SHLD	GetModeSwitch
	LXI	H,AsyncRS232CInterrupt
	LXI	D,AsyncDefaultParameters	
	CALL	CopyParameters
	
{GEt Flow control flag and characters}
	LDA	RS232CParameterFlowControl
	STA	FlowControlFlag
	LDA	RS232CParameterXOn
	STA	XonChar
	LDA	RS232CParameterXoff
	STA	XoffChar
	XRA	A			;Initialize Flags to False
	STA	XoffReceivedFlag
	STA	LastBufferFlag
	STA	FCState

{In Async mode, check for one or two Stop bits and set up WR4 depending on RS232CParameter2Hi:

	 (mask 4):
		0 => 1 Stop bit
		1 => 2 Stop bits}
	MVI	D,StopBits1		
	LDA	RS232CParameter2Hi
	ANI	CPStopBitsMask	
	JZ	SetStopBits
	MVI	D,StopBits2
SetStopBits:
	LDA	TxWR4		
	ORA	D
	STA	TxWR4
	LDA	RxWR4
	ORA	D
	STA	RxWR4
	LXI	H,AsynchronousDivisor
	JMP	SetBaud	

SetBisyncParameters:
	LXI	H, PutBisyncMode
	SHLD	PutModeSwitch	; Set JMP instruction
	LXI	H,BisyncGetLoop
	SHLD	GetModeSwitch
	LXI	H,BisyncRS232CInterrupt
	LXI	D,BisyncDefaultParameters
	JMP	CommonSynchParamaters	 

SetSdlcParameters:
	LXI	H,PutSdlcMode
	SHLD	PutModeSwitch	; Set JMP instruction
	LXI	H,SdlcGetLoop	
	SHLD	GetModeSwitch
	LXI	H,SdlcRS232CInterrupt
	LXI	D,SdlcDefaultParameters	

CommonSynchParamaters:
	CALL	CopyParameters
	LXI	H,SynchronousDivisor

SetBaud:
{Set the baud rate. HL points to Divisor table.}
	LDA	RS232CParameter1Hi	; Set Baud Rate
	ANI	CPLineSpeedMask	; Async:x16, Sync or Sdlc:x1
	STA	CurrentBaudRate
	CALL	SetBaudRate		

SetSyncCharacter:
	LDA	RS232CParameter3
	STA	CurrentSyncCharacter

{If ResetRingHeard bit is set, reset the RingHeardLatch.}
	CALL	CheckResetRingHeard

{Set up the parity parameters in WR4 depending on RS232CParameter2 (mask 0E0):

	0 => no parity
	20H (1) => odd parity
	40H (2) => even parity
	60H (3) => one parity (no parity specified, but add "1" bit)
	80H (4) => zero parity (no parity specified, but add "0" bit)
Set up B to contain the bits to OR into WR4.}

	MVI	D,0		; Assume no parity
	LDA	RS232CParameter2
	ANI	CPParityMask
	JZ	SetParity	;zero => no parity
	CPI	CPOneParity
	JZ	SetParity
	CPI	CPZeroParity
	JZ	SetParity
	MVI	D,ParityOdd	;if parity is specified
	CPI	CPOddParity	
	JZ	SetParity
	MVI	D,ParityEven	

SetParity:
	LDA	RxWR4
	ORA	D
	STA	RxWR4
	LDA	TxWR4
	ORA	D
	STA	TxWR4

{Set the character length depending on the character length  (mask 18):

	0 => char length = 5	0
	8H (1) => char length = 6	80
	10H (2) => char length = 7	40
	18H (3) => char length = 8	C0}

	LDA	RS232CParameter2	; Charcter Length Check
	ANI	CPCharLMask	;A ← LLxxx
	RRC			;A ← LLxx
	RRC			;A ← LLx
	RRC			;A ← LL

{Pick up the character length code that we will use to set WR3, and set up WR3.}
	MOV	E,A		;DE ← character length code * 2
	MVI	D,0
	LXI	H,CharLengthTable
	DAD	D		;HL ← CharLengthTable + length code
	LDA	RxWR3	; Set Character Length
	ORA	M
	STA	RxWR3

{The character length code for WR5 is the character length code for WR3 shifted right one position. Set up WR5.}
	ANI	Rx8BitsPerCharacter	;A ← character length for WR3
	RRC			;A ← character length for WR5
	MOV	H,A
	LDA	TxWR5
	ORA	H
	STA	TxWR5

{Set up the character length mask.}
	LXI	H,CurrentCharLengthMaskTable
	DAD	D		;HL ← CurrentCharLengthMaskTable + length code
	MOV	A,M
	STA	CurrentCharLengthMask
	

{Set Data Terminal Ready (DTR) in WR5 if this bit is set in the parameter.}
	LDA	RS232CParameter2Hi	; Check Command
	ANI	CPDTRMask	;Mask = 8
	JZ	CheckRTS
	LDA	TxWR5	; Set DTR bit if command bit is 1
	ORI	DTR
	STA	TxWR5

CheckRTS:
{Set Clear To Send (CTS) in WR5 if this bit is set in the parameter.}
	LDA	RS232CParameter2Hi	; Check Command
	ANI	CPRTSMask	;Mask = 10H
	JZ	CheckRingHeard
	LDA	TxWR5		; Set DTR bit if command bit is 1
	ORI	RTS
	CALL	UpdateTxWR5

CheckRingHeard:
{Turn off RingHeardLatch if ResetRingHeard is set in the parameter.}
	LDA	RS232CParameter2Hi	; Reset Ring Hard, if required
	ANI	CPRRHMask
	JZ	CheckCorrespondent
	XRA	A
	STA	RingHeardLatch

CheckCorrespondent:
{Check the Correspondent specified in RS232CParameter3Hi:
  0 = xerox800
  1 = xerox850
  2 = system6
  3 = cmcII
  4 = ttyHost
  5 = oisSystemElement
  6 = ibm3270Host
  7 = ibm2770Host
  8 = ibm6670Host
  9 = ibm6670
  10 = xerox860
  11 = oisSystemElementBSC
  12 = siemens9750

If we are running in BiSync mode, we assume the code is EBCDIC. Check to see if we have a correspondent that requires an ASCII code.}
	LDA	RS232CParameter3Hi	; Set Correspondents
	STA	CurrentCorrespondents
	CALL	RxInitBiSyncInput
	CALL	TxInitBiSyncInterrupts
	CPI	IBM3270Host
	JZ	IBM3270OrSiemens9750
	CPI	siemens9750
	LXI	H,EndOfBisyncFrame	;Assume not 3270 host
	JNZ	SetEOTEndFrameSwitch

{If the host is a 3270 or 9750, it requires special treatment for EOT EndOfFrame.}
IBM3270OrSiemens9750:
	LXI	H,EOT3270

SetEOTEndFrameSwitch:
	SHLD	EOTEndFrameSwitch

	CPI	Xerox850
	JZ	SetAsciiCode
	CPI	siemens9750
	JZ	SetAsciiCode
	CPI	xerox860
	JNZ	SaveSynCount

SetAsciiCode:
	LXI	H,AsciiCodeTable
	LXI	D,CurrentCode
	MVI	A,AsciiCodeTableSize	
	CALL	Copy

SaveSynCount:
{Save the number of SYN characters to send.}
	LDA	RS232CParameter2	; Save Sync Count value
	ANI	CPSyncCntMask
	STA	CurrentSyncCount

{Perform common initialization for Get and Put tasks.}
	XRA	A		
	STA	AbortGetFlag
	STA	AbortPutFlag
	LXI	H,TestStatusChange		; Fix for CTS
	SHLD	GetTaskStartAddress		; Fix for CTS
	LXI	H,StartGetTask
	SHLD	GetTaskResumeAddress
	LXI	H,StartPutTask
	SHLD	PutTaskResumeAddress
;
{Initialize depending on the current Mode.} 
	LDA	RS232CMode
	ORA	A
	JZ	InitializeSdlcMode
	CPI	CPAsyncMode
	JZ	InitializeAsyncMode

InitializeBisyncMode:
{Continue if mode is Bisync. Initialize character values for parsing depending on the character set.}
	LDA	BEL
	STA	BEL1
	STA	BEL6
	LDA	ENQ
	STA	ENQ1
	STA	ENQ2
	STA	ENQ4
	STA	ENQ6
	STA	ENQ9
	STA	ENQ10
	STA	ENQ11
	STA	ENQ12
	LDA	EOT
	STA	EOT1
	STA	EOT6
	LDA	ETB
	STA	ETB2
	STA	ETB4
	STA	ETB5
	STA	ETB6
	STA	ETB7
	STA	ETB8
	STA	ETB9
	STA	ETB10
	STA	ETB11
	STA	ETB12
	LDA	NAK
	STA	NAK1
	STA	NAK6
	LDA	SYN
	STA	SYN1
	STA	SYN2
	STA	SYN3
	STA	SYN4
	STA	SYN5
	STA	SYN6
	STA	SYN7
	STA	SYN8
	STA	SYN9
	STA	SYN10
	STA	SYN11
	STA	SYN12
	STA	SYN13		{6/30/83}
	STA	SYN14		{6/30/83}

{WR3 has been set up for the number of bits per character. Store this value wherever we want to disable CRC.}
	LDA	RxWR3
	ORI	RxEnable
	STA	DisableRxCRC1
	STA	DisableRxCRC2
	STA	DisableRxCRC3

{OR in RxCRCEnable and store this value wherever we want to enable the CRC generator.}
	ORI	RxCRCEnable
	STA	EnableRxCRC1
	STA	EnableRxCRC2
	STA	EnableRxCRC3
	STA	EnableRxCRC4

{OR in the SyncCharacterLoadInhibit bit and the EnterHuntMode bit. This is the initial state of the receiver.}
	LDA	RxWR3
	ORI	RxEnable+SyncCharacterLoadInhibit+EnterHuntPhase
	STA	EnterHuntMode1
	STA	EnterHuntMode2

{Initialize the values for the one second timer.}
	LXI	H,BisyncTimerTable
	LDA	CurrentBaudRate
	CALL	HLPlus2A
	MOV	A,M
	STA	OneSecondTimerLow
	INX	H
	MOV	A,M
	STA	OneSecondTimerHigh

{Set up the SIO chip. The order is important. Any deviation from this may cause the chip to do weird things.}
	DI
	LXI	H,8000H+RxCont
	CALL	CheckChannelReset
	
	MVI	M,PointToWR4+ResetExternalStatusInterrupts
	LDA	RxWR4
	MOV	M,A
	
	MVI	M,PointToWR5+ResetExternalStatusInterrupts
	LDA	RxWR5
	MOV	M,A
	
	MVI	M,PointToWR3
	LDA	RxWR3
	ORI	EnterHuntPhase+SyncCharacterLoadInhibit
	MOV	M,A
	
	MVI	M,PointToWR6
	LDA	CurrentSyncCharacter
	MOV	M,A

	MVI	M,PointToWR7
	LDA	CurrentSyncCharacter
	MOV	M,A

	MVI	M,PointToWR1+ResetExternalStatusInterrupts
	LDA	RxWR1
	MOV	M,A

	
{5/17/83 add reset of Interrupt Vector in channel B}
	LXI	H,8000H+TxCont
	CALL	CheckAndResetChannelReset
	
	MVI	M,PointToWR2
	MVI	M,0

	MVI	M,PointToWR4+ResetExternalStatusInterrupts
	LDA	TxWR4
	MOV	M,A
	
	MVI	M,PointToWR6
	MVI	A,Filler
	MOV	M,A

	MVI	M,PointToWR7+ResetExternalStatusInterrupts
	MVI	A,Filler
	MOV	M,A

	MVI	M,PointToWR1+ResetExternalStatusInterrupts
	LDA	TxWR1
	MOV	M,A

	MVI	M,PointToWR5+ResetExternalStatusInterrupts
	LDA	TxWR5
	MOV	M,A
	
	JMP	ReturnSuccess

{ 1 Jul 83
Check to see if we are to do a Channel Reset.  The routines are re-entrant.  It is assumed that the HL register pair points to the memory mapped port of either the receiver or the transmitter.  If so do it if not then don't.  This subroutine has two entry points:
CheckAndResetChannelReset:		this entry indicates that the channel
				        reset has been done and resets 
					ChannelNeedsReset flag.
					 
CheckChannelReset:			this entry checks to see if a channel 
					reset is required.}
CheckAndResetChannelReset:
	PUSH	PSW
	LDA	ChannelNeedsReset
	ORA	A
	JZ	ExitCheckChannelReset
	XRA	A
	STA	ChannelNeedsReset
	JMP	DoChannelReset

ChannelNeedsReset:
	DB	1

CheckChannelReset:
	PUSH	PSW
	LDA	ChannelNeedsReset
	ORA	A
	JZ	ExitCheckChannelReset
DoChannelReset:
	MVI	M,ChannelReset
ExitCheckChannelReset:
	POP	PSW
	RET

SetChannelResetFlag:
	PUSH	PSW
	MVI	A,1
	STA	ChannelNeedsReset
	POP	PSW
	RET


InitializeSdlcMode:
	LXI	H,8000H+RxCont		;HL points to Rx Control register
	DI
	{MVI	M,ChannelReset}
	CALL	CheckChannelReset

{Set WR6 for the Sdlc sync character}
	MVI	M,ResetExternalStatusInterrupts+PointToWR6
	LDA	RS232CParameter3
	MOV	M,A

{Set WR7 to the Sdlc flag character.}
	MVI	M,ResetExternalStatusInterrupts+PointToWR7
	MVI	M,7EH

{WR4 has been set up for X1 ClockMode and Sdlc mode.}
	MVI	M,ResetExternalStatusInterrupts+PointToWR4
	LDA	RxWR4
	MOV	M,A

{WR3 has been set up for the number of bits per character and CRC Enable.}
	MVI	M,ResetExternalStatusInterrupts+PointToWR3
	LDA	RxWR3
	MOV	M,A

{WR1 has been set up for ExternalIntEnable, IntOnAllRxCharacters (status affects parity)}
	MVI	M,ResetExternalStatusInterrupts+PointToWR1
	LDA	RxWR1
	MOV	M,A

{Now initialize Channel B, the Tx channel}
	LXI	H,8000H+TxCont		;HL points to TxControl register
	{MVI	M,ChannelReset}
	CALL	CheckAndResetChannelReset

{5/17/83 add reset of Interrupt Vector in channel B}
	{MVI	A,PointToWR2
	OUT	TxCont
	XRA	A			;Clear the accumulator
	OUT	TxCont}
	
	MVI	M,PointToWR2
	MVI	M,0

{Set WR7 to the Sdlc flag character.}
	MVI	M,ResetExternalStatusInterrupts+PointToWR7
	MVI	M,7EH
	JMP	SetTxWR4


InitializeAsyncMode:
	LXI	H,8000H+RxCont		;HL points to Rx Control register
	DI
	{MVI	M,ChannelReset}
	CALL	CheckChannelReset

{WR4 has been set up for X16 ClockMode, the number of stop bits/character, and the parity specified by the client's parameter record.}
	MVI	M,ResetExternalStatusInterrupts+PointToWR4
	LDA	RxWR4
	MOV	M,A

{WR3 has been set up for the number of bits per character}
	MVI	M,ResetExternalStatusInterrupts+PointToWR3
	LDA	RxWR3
	MOV	M,A

{WR1 has been set up for ExternalIntEnable, IntOnAllRxCharacters (status affects parity)}
	MVI	M,ResetExternalStatusInterrupts+PointToWR1
	LDA	RxWR1
	MOV	M,A

{Now initialize Channel B, the Tx channel}
	LXI	H,8000H+TxCont		;HL points to TxControl register
	{MVI	M,ChannelReset}
	CALL	CheckAndResetChannelReset

{5/17/83 add reset of Interrupt Vector in channel B}
	{MVI	A,PointToWR2
	OUT	TxCont
	XRA	A			;Clear the accumulator
	OUT	TxCont}
	
	MVI	M,PointToWR2
	MVI	M,0

SetTxWR4:
{WR4 has been set up for X16 ClockMode, the number of stop bits/character, and the parity specified by the client's parameter record.}
	MVI	M,ResetExternalStatusInterrupts+PointToWR4
	LDA	TxWR4
	MOV	M,A

{WR5 has been set up for the number of bits/character, DataTerminalReady (if specified in the client's parameter record), RequestToSend (if specified in the client's parameter record).}
	MVI	M,ResetExternalStatusInterrupts+PointToWR5
	LDA	TxWR5
	MOV	M,A

{WR1 has been set up for StatusAffectsVector, ExternalIntEnable, TxIntEnable}
	MVI	M,ResetExternalStatusInterrupts+PointToWR1
	LDA	TxWR1
	MOV	M,A
	
ReturnSuccess:
{Return Success in the CSB.}
	EI
	LXI	H,XferSuccess
	SHLD	RS232CParameter
	LXI	H,SendParameter
	JMP	ReturnResult
;
DoSetRS366Status:
	LDA	RS232CParameter2	; Read New RS366 Status
	ANI	RS366StatusMask
	CALL	SetRS366	
	JMP	ResetMiscTaskFlag
;
DoGetStatus:
	IN	RS366Reg	; Read RS366 Reg Condition
	STA	RS366Buffer
	ANI	DLO+PND+COS+ACR+PWI
	STA	RS232CDeviceStatusHi	;Save RS366 Reg Condition in Device Status

{Get Data Carrier Detect bit from RR0.}
	IN	RxCont
	ANI	BreakAbort+DCD	; Bk ABT is only on Async Mode
	MOV	D,A		;Save DCD in D

{Get Clear To Send Detect bit from RR0.}
	IN	TxCont
	ANI	CTS
	ORA	D
	MOV	D,A		;Save DCD and CTS in D

{Get DataSetReady bit from RS366Buffer.}
	DB	opMVIA	;A ← RS366Buffer
RS366Buffer:
	DB	0
	ANI	DSRdy	; Data Set Ready?
	JZ	CheckRingIndicator
	MVI	A,DataSetReady	; IF Yes, DataSetReady bit Set
	ORA	D
	MOV	D,A		;Save DataSetReady, DCD and CTS in D

CheckRingIndicator:
{Get RingIndicator from RS366Buffer.}
	LDA	RS366Buffer
	ANI	Ring		; Ring Heard?
	JZ	CheckRingHeardLatch
	MVI	A,RingIndicator	; If Yes, Ring Indicator bit Set
	ORA	D
	MOV	D,A
	STA	RingHeardLatch	; Set RingHeard Latch

CheckRingHeardLatch:
	DB	opMVIA	;A ← RingHeardLatch
RingHeardLatch:
	DB	0
	ORA	A
	JZ	WriteDeviceStatus
	MVI	A,RingHeard	; IF Yes, Ring Heard bit set
	ORA	D
	MOV	D,A

WriteDeviceStatus:
	MOV	A,D
	STA	RS232CDeviceStatus
	LXI	H,SendDeviceStatus

ReturnResult:
	CALL	WriteCPBuffer
	JMP	ResetMiscTaskFlag
;
DoMinorSetParameters:
	LDA	TxWR5 
	ANI	0FFH-DTR-RTS		;Turn off DTR and RTS
	MOV	D,A			;Save TxWR5 in D
	LDA	RS232CParameter2Hi	
	ANI	CPDTRMask
	JZ	RTSControl
	MOV	A,D			; Set DTR bit if command bit is 1
	ORI	DTR
	MOV	D,A			;Save TxWR5 in D

RTSControl:
	LDA	RS232CParameter2Hi	; Check Command
	ANI	CPRTSMask
	MOV	A,D		; Set RTS bit if command bit is 1
	JZ	ControlSigSet
	ORI	RTS
ControlSigSet:
	CALL	UpdateTxWR5
	LDA	TxWR5
	LXI	H,TxCont+8000H	;HL points to TxCont register
	DI
	MVI	M,PointToWR5+ResetExternalStatusInterrupts		
	MOV	M,A		;Send new WR5 command
	EI

{If ResetRingHeard bit is set, reset the RingHeardLatch.}
	CALL	CheckResetRingHeard

ResetMiscTaskFlag:
	LXI	H,ZeroMiscFlag
	CALL	WriteCPBuffer

{ 7/12/83 issue wakeup to the head after simple command as well as after puts and gets }
	LHLD	RS232CTaskWakeMask
	CALL	DoNakedNotify
		 
	JMP	MiscYield

SaveMiscResumeAddressAndYield:
	SHLD	MiscTaskResumeAddress
MiscYield:
	DS	0
{Pass control to the next task specified in Domino.cfg}

	END