{ 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