mirror of
https://github.com/livingcomputermuseum/Darkstar.git
synced 2026-03-02 10:06:45 +00:00
39 lines
25 KiB
Plaintext
39 lines
25 KiB
Plaintext
head 1.1;
|
||
branch 1.1.1;
|
||
access ;
|
||
symbols start:1.1.1.1 Xerox:1.1.1;
|
||
locks ; strict;
|
||
comment @;; @;
|
||
|
||
|
||
1.1
|
||
date 2001.08.12.22.22.18; author freier; state Exp;
|
||
branches 1.1.1.1;
|
||
next ;
|
||
|
||
1.1.1.1
|
||
date 2001.08.12.22.22.18; author freier; state Exp;
|
||
branches ;
|
||
next ;
|
||
|
||
|
||
desc
|
||
@@
|
||
|
||
|
||
|
||
1.1
|
||
log
|
||
@Initial revision
|
||
@
|
||
text
|
||
@{ File: [Iris]<WMicro>DLion>BisyncInterrupts.asm
|
||
Modification History:
|
||
Dennis DEG : 27-Mar-85 1:24:20: Make changes to handle PAD character in 9750 mode.
|
||
Dennis DEG : 1-Sep-84 16:51:46: Add copyright notice.
|
||
Dennis DEG : 9-Oct-83 17:33:41: Siemens 9750 support.
|
||
Dennis DEG : 29-Jun-83 14:15:54: ITB fixes.
|
||
Tom TXC : 17-May-83 14:34:54Make sure use just 3 SIO interrupt bits
|
||
CrF CRF : 11-Nov-82 9:39:35: Move POPs before EIs to avoid possible stack
|
||
overflow.
|
||
Jim JXF : May 20, 1982 6:53 PM
|
||
Jim JXF : May 6, 1982 9:49 AM: Created file.
|
||
}
|
||
|
||
{ Copyright (C) 1982, 1983, 1985 by Xerox Corporation. All rights reserved.}
|
||
|
||
Get "SysDefs"
|
||
Get "RS232CDefs"
|
||
|
||
|
||
IMP CurrentSyncCharacter ;From RS232CMisc
|
||
IMP IllegalBisyncCharacterFlag ;From RS232CPut
|
||
IMP PadAfterBCC ;From BisyncInput
|
||
IMP PutCompletedFlag ;From RS232CPut
|
||
IMP RestartSIOCharacter ;From RS232CPut
|
||
IMP RxEndBCC2 ;From BisyncInput
|
||
IMP SetBisyncCompletion ;From BisyncInput
|
||
IMP StatusChangeFlag ;From RS232CGet
|
||
IMP TerminateBisyncFrame ;From BisyncInput
|
||
IMP TxBufferPointer ;From RS232CInterrupts
|
||
IMP TxUnderrunDetectedFlag ;From RS232CInterrupts
|
||
IMP TxWR5 ;From RS232CMisc
|
||
|
||
EXP BisyncRS232CInterrupt
|
||
EXP BEL1
|
||
EXP DisableTxCRC1
|
||
EXP EnableTxCRC1
|
||
EXP ENQ1
|
||
EXP ENQ2
|
||
EXP ENQ4
|
||
EXP ENQ12
|
||
EXP EOT1
|
||
EXP ETB2
|
||
EXP ETB4
|
||
EXP ETB5
|
||
EXP ETB6
|
||
EXP ETB12
|
||
EXP NAK1
|
||
EXP PrevBisyncDCD
|
||
EXP SYN1
|
||
EXP SYN2
|
||
EXP SYN3
|
||
EXP SYN4
|
||
EXP SYN5
|
||
EXP SYN6
|
||
EXP SYN12
|
||
EXP OneSecondTimerLow
|
||
EXP OneSecondTimerHigh
|
||
EXP RxBisyncExternalInt
|
||
EXP RxBisyncSpecialInt
|
||
EXP SyncCharacterCount
|
||
EXP TxBisyncInitial
|
||
EXP TxBisyncStateSwitch
|
||
EXP TxInitBiSyncInterrupts
|
||
;
|
||
{NOTE: These routines are written for speed. Much code has been duplicated. If necessary, space could be saved by making the exit code common.
|
||
|
||
The following characters are used in Bisync mode. Characters marked with an asterisk are the same in Ascii and Ebcdic. Other characters are different depending on the character set. Characters that differ are initialized by Misc.
|
||
|
||
AltoETX* Alto ETX so that Dandelions can talk to Altos.
|
||
|
||
BEL is a special 860 character used to change to voice mode. It has meaning when it appears at the beginning of a frame. In the middle of a frame, it is treated as data.
|
||
|
||
DLE* Data Link Escape is used for two character sequences.
|
||
|
||
ENQ Enquiry is used to bid for the line when using point to point connections. It indicates the end of a selection sequence. It is also used to request retransmission of the ACK/NAK response.
|
||
|
||
EOT End of Transmission indicates the end of a message which may contain a number of blocks.
|
||
|
||
ETB End of Transmission Block indicates the end of a block of characters that started with SOH or STX and indicates that the block check is coming next.
|
||
|
||
ETX* End of Text terminates a block which started with SOH or STX. It is the same as ETB except that it also means that there are no more data blocks to be sent.
|
||
|
||
ITB* End of Intermediate Transmission Block is used to separate the message into sections for error detection purposes. ITB indicates that the block check is coming next.
|
||
|
||
NAK Negative Acknowledgement indicates that the previous block was received in error.
|
||
|
||
SOH* Start of Heading
|
||
|
||
STX* Start of Text
|
||
|
||
SYN Sync character
|
||
}
|
||
;
|
||
BisyncRS232CInterrupt:
|
||
{ Come here in Bisync mode from Common when we get a RST 6.5 Interrupt from the Zilog SIO chip. Save state }
|
||
PUSH PSW
|
||
PUSH H
|
||
|
||
{Read the interruptVector to determine the cause of the interrupt. Multiply the vector by 2. This gives us a number which we can OR into the low bits of the jump table address. The jump table is in the Common so that we can assure its exact address and guarantee that the low 5 bits of the address are zero. }
|
||
MVI A,PointToWR2
|
||
OUT TxCont
|
||
IN TxCont ; Read Interrupt Vector
|
||
|
||
{Test for TxDataInt first. We want to call this routine so that we can also call it from the input end of frame routine if necessary.}
|
||
{ remove ORA A, replaced by the following}
|
||
ANI 0EH ;use just 3 bits from SIO 5/17/83
|
||
DB opJZ
|
||
TxBisyncStateSwitch:
|
||
DW TxBisyncInitial
|
||
|
||
DispatchOnBisyncInterruptVector:
|
||
RLC ;Interupt Vector * 2
|
||
ORI 40H ;Low address is 40H
|
||
MOV L,A
|
||
MVI H,20H ;High address is 20H
|
||
PCHL ;Jump to JumpTable
|
||
|
||
{BisyncJumpTable: @@2040H
|
||
JMP TxIllegalInt ;When Vecter =0 Tx Buffer Empty
|
||
DB 0
|
||
JMP TxBisyncExternalInt ;When Vecter =2 Ex Stat
|
||
DB 0
|
||
JMP TxIllegalInt ;When Vecter =4 Tx Char
|
||
DB 0
|
||
JMP ExitInterrupt ;When Vecter =6 Sp Tx Cond
|
||
DB 0
|
||
JMP RxIllegalInt ;When Vecter =8 Tx Buffer Empty
|
||
DB 0
|
||
JMP RxBisyncExternalInt ;When Vecter =A Ex Stat
|
||
DB 0
|
||
DB opJMP ;When Vecter =C Rx Char
|
||
RxBisyncStateSwitch:
|
||
DW RxBisyncInitial
|
||
DB 0
|
||
JMP RxBisyncSpecialInt ;When Vecter =E Sp Rx Cond
|
||
DB 0
|
||
}
|
||
;
|
||
{TxSubroutines used to simplify transmission so that most of the code used for Bisync can also be used for 9750}
|
||
|
||
TxDisableCRC:
|
||
{This routine disables, turns off, the CRC generator}
|
||
NOP ;In 9750 mode we replace this NOP with a RET
|
||
LXI H,8000H+TxCont
|
||
MVI M,PointToWR5+ResetExternalStatusInterrupts
|
||
DB opMVIM
|
||
DisableTxCRC1:
|
||
DB 0
|
||
RET
|
||
|
||
TxEnableCRC:
|
||
{This routine enables, turns on, the CRC generator}
|
||
NOP ;In 9750 mode we replace this NOP with a RET
|
||
LXI H,8000H+TxCont
|
||
MVI M,PointToWR5+ResetExternalStatusInterrupts
|
||
DB opMVIM
|
||
EnableTxCRC1:
|
||
DB 0
|
||
RET
|
||
|
||
SendChWithCRCorBCC:
|
||
{Transmit this character and accumulate the BCC}
|
||
OUT TxData
|
||
OptRet:
|
||
RET ;This RET is replaced by a NOP for 9750 mode.
|
||
PUSH PSW
|
||
PUSH H ;Save contents of HL
|
||
LXI H,TxBCC ;Point to the BCC
|
||
XRA M ;Accumulate the BCC
|
||
ANI 7FH ;Mask off the parity bit.
|
||
MOV M,A ;Restore the BCC
|
||
POP H ;Restore the contents of HL
|
||
POP PSW
|
||
RET ;Continue with next instruction
|
||
|
||
TxBCC:
|
||
DB 0
|
||
|
||
TxInitBiSyncInterrupts:
|
||
PUSH PSW
|
||
PUSH H
|
||
CPI Siemens9750Correspondent
|
||
JNZ BiSyncSetup
|
||
|
||
SiemensSetup:
|
||
MVI A,opRET
|
||
STA TxDisableCRC
|
||
STA TxEnableCRC
|
||
XRA A ;MVI A,opNOP
|
||
LXI H,TxInterBlockBCCNext
|
||
SHLD TxITBCRCSwitch
|
||
LXI H,TxEndingBCCNext
|
||
JMP SetupExit
|
||
|
||
BiSyncSetup:
|
||
XRA A ;MVI A,opNOP
|
||
STA TxDisableCRC
|
||
STA TxEnableCRC
|
||
MVI A,opRET
|
||
LXI H,TxInterBlockCRCNext
|
||
SHLD TxITBCRCSwitch
|
||
LXI H,TxEndingCRCNext
|
||
|
||
SetupExit:
|
||
SHLD EndBCCorCRCSwitch
|
||
STA OptRet
|
||
POP H
|
||
POP PSW
|
||
RET
|
||
|
||
;
|
||
TxBisyncInitial:
|
||
{Come here to initialize the transmitter. We sent one ModemSYN character (alternate ones and zeros) to prime the transmitter. We send two more ModemSYN characters in this state.}
|
||
LXI H,TxBCC ;Set accumulated BCC to 0
|
||
MVI M,0
|
||
|
||
MVI A,ModemSYN
|
||
OUT TxData
|
||
|
||
{Turn on the one second timer (i8253 Programmable Interval Timer Counter # 2).}
|
||
MVI A,TimeCMD
|
||
OUT OSCCont
|
||
DB opMVIA ;A ¬ OneSecondTimerLow
|
||
OneSecondTimerLow:
|
||
DB 0
|
||
OUT TimeReg
|
||
DB opMVIA ;A ¬ OneSecondTimerHigh
|
||
OneSecondTimerHigh:
|
||
DB 0
|
||
OUT TimeReg
|
||
LXI H,TxInitial1
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
TxInitial1:
|
||
{We sent one ModemSYN character to prime the transmitter and one more ModemSYN character. Send one more ModemSYN character.}
|
||
MVI A,ModemSYN
|
||
OUT TxData
|
||
|
||
{Initialize WR6 and WR7 with the current sync character. These characters will be sent by the chip automatically whenever we get transmit underrun.}
|
||
LXI H,8000H+TxCont
|
||
MVI M,PointToWR6
|
||
LDA CurrentSyncCharacter
|
||
MOV M,A
|
||
MVI M,PointToWR7+ResetTxCRCGenerator
|
||
MOV M,A
|
||
LXI H,SendSyncCharacters
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
SendSyncCharacters:
|
||
{We send the number of Sync Characters specified by the client.}
|
||
LDA CurrentSyncCharacter
|
||
OUT TxData
|
||
DB opMVIA ;A ¬ SyncCharacterCount
|
||
SyncCharacterCount:
|
||
DB 0
|
||
DCR A ;Decrement SyncCharacterCount
|
||
JZ SyncCharactersSent
|
||
|
||
STA SyncCharacterCount
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
SyncCharactersSent:
|
||
LXI H,StartTx
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
StartTx:
|
||
{This is the first Transmit state. We have sent the initial characters, and we are looking for SOH or STX. Send the next character from the client's buffer. The CRC generator is not turned on, and the next character sent will not be included in the CRC.}
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
OUT TxData ;Send the next character
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
|
||
CPI ETX
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
CPI STX
|
||
JZ FirstTxCharIsSTX
|
||
|
||
CPI SOH
|
||
JZ FirstTxCharIsSOH
|
||
|
||
CPI DLE
|
||
JZ FirstTxCharIsDLE
|
||
|
||
DB opCPI
|
||
EOT1: DB 0
|
||
JZ TxEndOfFrameNext
|
||
|
||
DB opCPI
|
||
BEL1: DB 0
|
||
JZ TxEndOfFrameNext
|
||
|
||
DB opCPI
|
||
NAK1: DB 0
|
||
JZ TxEndOfFrameNext
|
||
|
||
DB opCPI
|
||
ENQ1: DB 0
|
||
JZ TxEndOfFrameNext
|
||
|
||
{Continue if the character is not any of the above. We stay in this state.}
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
TxHeaderSyn:
|
||
{Come here if we got a SYN character in the header. The SYN character does not get included in the checksum, so we must turn off the CRC generator.}
|
||
CALL TxDisableCRC
|
||
OUT TxData ;Send the next character
|
||
|
||
{The next time we get a TxData interrupt, we want to turn the CRC generator back on.}
|
||
|
||
FirstTxCharIsSOH:
|
||
LXI H,StartTxHeader
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
StartTxHeader:
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
DB opCPI
|
||
SYN5: DB 0
|
||
JZ StartHeaderSyn
|
||
|
||
{We are about to send the first Header character following SOH. Turn on the CRC generator. If the CRC generator is turned on before the character is shifted into the serial shift register, the character will be included in the CRC.}
|
||
CALL TxEnableCRC
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
|
||
CPI STX
|
||
JZ ContinueTxNonTransparentMode
|
||
|
||
CPI DLE
|
||
JZ LookForSTXAfterTxDLE
|
||
|
||
CPI ETX
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
DB opCPI
|
||
ETB5: DB 0
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
{Continue if the character is not any of the above. Pass to TxHeader state.}
|
||
LXI H,TxHeader
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
StartHeaderSyn:
|
||
{Come here if we got a SYN character in the header. The SYN character does not get included in the checksum.}
|
||
|
||
StartNonTransparentModeSYN:
|
||
{Come here if we got a SYN character in non transparent mode. The SYN character does not get included in the checksum.}
|
||
|
||
TxInterBlockSYN:
|
||
{Come here if we got a SYN character following the ITB character. The SYN character does not get included in the checksum.}
|
||
|
||
OUT TxData ;Send the next character
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
TxHeader:
|
||
{We are sending header characters. The CRC generator is on. The next character will be included in the CRC unless we turn off the CRC checker.}
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
DB opCPI
|
||
SYN6: DB 0
|
||
JZ TxHeaderSyn
|
||
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
CPI STX
|
||
JZ ContinueTxNonTransparentMode
|
||
|
||
CPI DLE
|
||
JZ LookForSTXAfterTxDLE
|
||
|
||
CPI ETX
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
DB opCPI
|
||
ETB6: DB 0
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
{Continue if the character is not any of the above. Stay in this state.}
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
TxNonTransparentModeSYN:
|
||
{Come here if we got a SYN character in non transparent mode. The SYN character does not get included in the checksum, so we must turn off the CRC generator.}
|
||
CALL TxDisableCRC
|
||
OUT TxData ;Send the next character
|
||
|
||
{The next time we get a TxData interrupt, we want to turn the CRC generator back on.}
|
||
|
||
FirstTxCharIsSTX:
|
||
LXI H,StartTxNonTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
StartTxNonTransparentMode:
|
||
{We are about to send the first character in NonTransparent Mode, or we are continuing after a one second timeout or a SYN character. The CRC generator is off.}
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
|
||
DB opCPI
|
||
SYN2: DB 0
|
||
JZ StartNonTransparentModeSYN
|
||
|
||
{Turn on the CRC generator. If the CRC generator is turned on before the character is shifted into the serial shift register, the character will be included in the CRC.}
|
||
CALL TxEnableCRC
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
CPI ETX
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
DB opCPI
|
||
ETB2: DB 0
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
CPI ITB
|
||
JZ TxInterBlockBCCorCRCNext
|
||
|
||
DB opCPI
|
||
ENQ2: DB 0
|
||
JZ TxEndOfFrameNext
|
||
|
||
{Continue if the character is not any of the above. We pass to NonTransparent Mode.}
|
||
|
||
ContinueTxNonTransparentMode:
|
||
LXI H,TxNonTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
TxNonTransparentMode:
|
||
{We are sending characters in NonTransparent mode. The CRC generator is on.}
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
|
||
DB opCPI
|
||
SYN12: DB 0
|
||
JZ TxNonTransparentModeSYN
|
||
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
CPI ETX
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
DB opCPI
|
||
ETB12: DB 0
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
CPI ITB
|
||
JZ TxInterBlockBCCorCRCNext
|
||
|
||
DB opCPI
|
||
ENQ12: DB 0
|
||
JZ TxEndOfFrameNext
|
||
|
||
{Continue if the character is not any of the above. We stay in NonTransparent Mode. Check the timer to see if one second has elapsed since we started sending.}
|
||
IN RS366Reg
|
||
ANI TimeUp
|
||
JNZ ExitTxDataInt ;Enable Interrupts
|
||
|
||
{The one second timer has expired. We must send two sync characters.}
|
||
LXI H,NonTransparentModeTimeout1
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
;
|
||
NonTransparentModeTimeout1:
|
||
{Come here to send the first sync character after a one second timeout. The sync character does not get included in the checksum, so we must turn off the CRC generator.}
|
||
CALL TxDisableCRC
|
||
LDA CurrentSyncCharacter
|
||
OUT TxData
|
||
LXI H,NonTransparentModeTimeout2
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
NonTransparentModeTimeout2:
|
||
{Come here to send the second sync character after a one second timeout. Turn the timer back on.}
|
||
LDA CurrentSyncCharacter
|
||
OUT TxData
|
||
MVI A,TimeCMD
|
||
OUT OSCCont
|
||
LDA OneSecondTimerLow
|
||
OUT TimeReg
|
||
LDA OneSecondTimerHigh
|
||
OUT TimeReg
|
||
LXI H,StartTxNonTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
TxInterBlockBCCorCRCNext:
|
||
DB opJMP
|
||
TxITBCRCSwitch:
|
||
DW TxInterBlockCRCNext
|
||
; DW TxInterBlockCRCNext
|
||
; DW TxInterBlockBCCNext
|
||
|
||
TxInterBlockBCCNext:
|
||
LXI H,TxInterBlockBCC
|
||
JMP TxITBSet
|
||
|
||
TxInterBlockCRCNext:
|
||
{Come here when we have just sent an ITB character. The next time we get an interrupt for Transmit Buffer Empty, we will simply clear the interrupt. This will cause the CRC to be sent if we reset the Transmit Underrun/EOM bit.}
|
||
MVI A,ResetTxEOM
|
||
OUT TxCont
|
||
LXI H,TxInterBlockCRC
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
TxInterBlockBCC:
|
||
LDA TxBCC
|
||
CALL SendChWithCRCorBCC
|
||
|
||
TxInterBlockCRC:
|
||
{Send the InterBlock CRC. Set SendSyncFlag for the Put routine. We will never get another wakeup unless the Put routine primes the chip again by sending a sync character. Disable the CRC generator so that the Sync character will not be included in the CRC.}
|
||
LXI H,8000H+TxCont
|
||
MVI M,PointToWR5+ResetTxIntPending
|
||
CALL TxDisableCRC
|
||
LDA CurrentSyncCharacter
|
||
STA RestartSIOCharacter
|
||
LXI H,ContinueAfterTxInterBlockCRC
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
ContinueAfterTxInterBlockCRC:
|
||
{Continue here when the CRC has been sent following the ITB character. Start sending data again. The CRC generator is off.}
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
DB opCPI
|
||
SYN3: DB 0
|
||
JZ TxInterBlockSYN
|
||
|
||
CALL TxEnableCRC
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
CPI DLE
|
||
JZ LookForSTXAfterTxDLE
|
||
|
||
{In transparent mode we expect DLE after the BCC (CRC) or SYN SYN. Mod. to meet IBM spec.s 6/29/83}
|
||
LDA TransparentDataFlag
|
||
ORA A
|
||
JNZ IllegalTxSequence
|
||
|
||
{Continue if the character is not any of the above. We go back to Non Transparent state.}
|
||
LXI H,TxNonTransparentMode
|
||
|
||
TxITBSet:
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
;
|
||
FirstTxCharIsDLE:
|
||
{Come here if the first Tx character is DLE. Look for STX to enter transparent mode. Any other character will be EndOfFrame. The CRC generator is off. The STX is NOT included in the checksum.}
|
||
LXI H,LookForSTXAfterFirstTxDLE
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
LookForSTXAfterFirstTxDLE:
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
OUT TxData ;Send the next character
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
CPI STX
|
||
JNZ TxEndOfFrameNext
|
||
|
||
LXI H,StartTxTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
LookForSTXAfterTxDLE:
|
||
{Come here after the sequence ITB DLE or SOH DLE. The only valid character that can follow is STX to start Transparent Mode. The CRC generator is on. The STX in included in the CRC.}
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
CPI STX
|
||
JNZ IllegalTxSequence
|
||
|
||
{In Transparent Mode, we must change WR6 to DLE so that the SIO will send DLE SYN when it gets TxUnderrun.}
|
||
LXI H,8000H+TxCont
|
||
MVI M,PointToWR6
|
||
MVI M,DLE
|
||
|
||
ContinueTransparentMode:
|
||
LXI H,TxTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
{ITB fix of 6/29/83}
|
||
TransparentDataFlag:
|
||
DB 0
|
||
|
||
StartTxTransparentMode:
|
||
{We are about to send the first character in Transparent Mode or continue after a one second timeout. Turn on the CRC generator. If the CRC generator is turned on before the character is shifted into the serial shift register, the character will be included in the CRC.}
|
||
|
||
MVI A,1 ;Store non-zero value to indicate we are in transparent mode.
|
||
STA TransparentDataFlag ;mod of 6/29/83
|
||
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
|
||
CPI DLE
|
||
JZ StartTransparentModeDLE
|
||
|
||
CALL TxEnableCRC
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
|
||
{In Transparent Mode, we must change WR6 to DLE so that the SIO will send DLE SYN when it gets TxUnderrun.}
|
||
LXI H,8000H+TxCont
|
||
MVI M,PointToWR6
|
||
MVI M,DLE
|
||
LXI H,TxTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
TxTransparentMode:
|
||
{We are sending characters in Transparent mode. The CRC generator is on. The only interesting character to look for is DLE.}
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
|
||
CPI DLE
|
||
JZ TxTransparentModeDLE
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
|
||
{Check the timer to see if one second has elapsed since we started sending.}
|
||
IN RS366Reg
|
||
ANI TimeUp
|
||
JNZ ExitTxDataInt ;Enable Interrupts
|
||
|
||
{The one second timer has expired. We must send DLE and a sync character.}
|
||
LXI H,TransparentModeTimeout1
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
TransparentModeTimeout1:
|
||
{Come here to send the DLE after a one second timeout. The DLE character does not get included in the checksum, so we must turn off the CRC generator.}
|
||
CALL TxDisableCRC
|
||
MVI A,DLE
|
||
OUT TxData
|
||
LXI H,TransparentModeTimeout2
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
TransparentModeTimeout2:
|
||
{Come here to send the sync character after a one second timeout. Turn the timer back on.}
|
||
LDA CurrentSyncCharacter
|
||
OUT TxData
|
||
|
||
{Turn the timer back on.}
|
||
MVI A,TimeCMD
|
||
OUT OSCCont
|
||
LDA OneSecondTimerLow
|
||
OUT TimeReg
|
||
LDA OneSecondTimerHigh
|
||
OUT TimeReg
|
||
LXI H,StartTxTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
TxTransparentModeDLE:
|
||
{Come here if we got a DLE character in Transparent Mode. The DLE character does not get included in the checksum, so we must turn off the CRC generator. We want to turn the CRC generator back on when we get the next interrupt.}
|
||
CALL TxDisableCRC
|
||
|
||
StartTransparentModeDLE:
|
||
OUT TxData ;Send the next character
|
||
LXI H,LookForTxDataAfterDLE
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
LookForTxDataAfterDLE:
|
||
{Turn on the CRC generator and send the character following DLE in Transparent Mode.}
|
||
CALL TxEnableCRC
|
||
LHLD TxBufferPointer
|
||
MOV A,M
|
||
CALL SendChWithCRCorBCC ;Send the next character
|
||
INX H
|
||
SHLD TxBufferPointer
|
||
MOV H,A ;Save character sent in H
|
||
CPI DLE
|
||
JZ ContinueTransparentMode
|
||
|
||
{Assume we may exit Transparent Mode. Restore WR6 to the sync character. WR6 and WR7 get sent automatically by the SIO when it gets TxUnderrun.}
|
||
LXI H,8000H+TxCont
|
||
MVI M,PointToWR6
|
||
DB opMVIM ;M ¬ SYN
|
||
SYN1: DB 0
|
||
|
||
DB opCPI
|
||
ENQ4: DB 0
|
||
JZ TxEndOfFrameNext
|
||
|
||
DB opCPI
|
||
ETB4: DB 0
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
CPI ETX
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
CPI AltoETX
|
||
JZ TxEndingBCCorCRCNext
|
||
|
||
CPI ITB ;We should not leave Transparent Mode.
|
||
JZ TxInterBlockBCCorCRCNext
|
||
|
||
DB opCPI
|
||
SYN4: DB 0
|
||
JNZ IllegalTxSequence
|
||
|
||
{Come here if we got a SYN character in transparent mode. The SYN character does not get included in the checksum, so we must turn off the CRC generator. HL still points to TxCont.}
|
||
CALL TxDisableCRC
|
||
|
||
{The next time we get a TxData interrupt, we want to turn the CRC generator back on.}
|
||
LXI H,StartTxTransparentMode
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
IllegalTxSequence:
|
||
|
||
MVI A,1
|
||
STA IllegalBisyncCharacterFlag
|
||
|
||
{Fall through to TxEndOfFrameNext. 6/29/83}
|
||
|
||
TxEndOfFrameNext:
|
||
{Come here to end a frame with no CRC.}
|
||
|
||
XRA A ;clear transparent mode.
|
||
STA TransparentDataFlag ;mod of 6/29/83
|
||
|
||
LXI H,EndOfFrameNoCRC
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
EndingBCC:
|
||
LDA TxBCC
|
||
CALL SendChWithCRCorBCC
|
||
|
||
EndOfFrameNoCRC:
|
||
{Turn on the TxUnderrunDetectedFlag. Since we are not sending a CRC, we will not get underrun.}
|
||
MVI A,1
|
||
JMP TxEndOfFrame
|
||
|
||
TxEndingBCCorCRCNext:
|
||
XRA A ;clear transparent mode.
|
||
STA TransparentDataFlag ;mod of 6/29/83
|
||
|
||
DB opJMP
|
||
EndBCCorCRCSwitch:
|
||
DW TxEndingCRCNext
|
||
; DW TxEndingCRCNext
|
||
; DW TxEndingBCCNext
|
||
|
||
TxEndingBCCNext:
|
||
LXI H,EndingBCC
|
||
JMP EndCheckSumSet
|
||
|
||
TxEndingCRCNext:
|
||
{Come here when we have sent the last character of the frame. The next time we get an interrupt for Transmit Buffer Empty, we will simply clear the interrupt. This will cause the CRC to be sent if we reset the Transmit Underrun/EOM bit.}
|
||
|
||
MVI A,ResetTxEOM
|
||
OUT TxCont
|
||
|
||
LXI H,EndingCRC
|
||
|
||
EndCheckSumSet:
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
EndingCRC:
|
||
{Reset TxUnderrunDetected. When the CRC has been sent, TxUnderrunDetectedFlag will be set again. This lets the Put routine know that the CRC has been sent and it is OK to begin sending the Filler characters.}
|
||
XRA A
|
||
|
||
TxEndOfFrame:
|
||
{Reset TxIntPending. This will cause the CRC to be sent if TxEOM is reset. The chip will then send whatever is loaded into WR6 and WR7. We will load WR6 and WR7 with filler characters. We must send at least 3 filler characters. We will set RestartSIOCharacter so that the Put routine will send a filler character to get us started again. Otherwise we will never get another wakeup. We also reset TxUnderrunDetected. When the CRC has been sent, TxUnderrunDetectedFlag will be set again. This lets the Put routine know that the CRC has been sent and it is OK to begin sending the Filler characters.}
|
||
STA TxUnderrunDetectedFlag
|
||
LXI H,8000H+TxCont
|
||
MVI A,Filler
|
||
STA RestartSIOCharacter
|
||
MVI M,PointToWR6
|
||
MOV M,A
|
||
MVI M,PointToWR7+ResetTxIntPending
|
||
MOV M,A
|
||
LXI H,SendFiller2
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
SendFiller2:
|
||
{Come here when the Put routine has restarted the chip by sending a filler character. Send the second filler character.}
|
||
MVI A,Filler
|
||
OUT TxData
|
||
LXI H,SendFiller3
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
SendFiller3:
|
||
{Send the last filler character.}
|
||
MVI A,Filler
|
||
OUT TxData
|
||
|
||
PutCompletedNext:
|
||
LXI H,PutCompleted
|
||
SHLD TxBisyncStateSwitch
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
|
||
PutCompleted:
|
||
MVI A,ResetTxIntPending
|
||
OUT TxCont
|
||
STA PutCompletedFlag
|
||
|
||
ExitTxDataInt:
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable Interrupts
|
||
RET
|
||
;
|
||
RxBisyncExternalInt:
|
||
{ Come here when we get an External/Status interrupt. Register RR0 indicates the cause of the interrupt:
|
||
|
||
08: 00001000 Data Carrier Detect (DCD)}
|
||
|
||
IN RxCont ;Read RR0
|
||
ANI DCD
|
||
DB opCPI ;Compare to previous DCD
|
||
PrevBisyncDCD:
|
||
DB 0
|
||
STA PrevBisyncDCD ;Save current DCD
|
||
MVI A,ResetExternalStatusInterrupts
|
||
OUT RxCont
|
||
JNZ ExitBisyncInterrupt
|
||
|
||
{Continue if DataCarrierDetect has changed state. Notify the Get loop so that it will do a NakedNotify. We store ResetExternalStatusInterrupts in StatusChangeFlag.}
|
||
STA StatusChangeFlag
|
||
|
||
ExitBisyncInterrupt:
|
||
MVI A,38H ; Issue Return From Int Command (Ch-A Only)
|
||
OUT RxCont
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable interrupts
|
||
RET
|
||
;
|
||
RxBisyncSpecialInt:
|
||
{ Come here when we get a Special interrupt. Register RR1 indicates the cause of the interrupt:
|
||
|
||
20: 00100000 RxOverrun
|
||
10: 00010000 Parity error
|
||
|
||
RxOverrun means data is being overwritten because the channel's three-byte receiver buffer is full and a new character is being received.
|
||
|
||
A Parity Error occurs when the parity bit of the character does not match with the programmed parity. Once this bit is set, it remains set until the Error Reset Command is given.}
|
||
|
||
PUSH D ;Save DE
|
||
{Read the character that caused the interrupt and place it in the RxFifo as we would a normal character.}
|
||
IN RxData ;A ¬ RxData
|
||
STAX B ;Store character in Fifo
|
||
INX B
|
||
LXI H,8000H+RxCont ;Point to RxCont register
|
||
MVI M,PointToWR1
|
||
MOV A,M ;Read CompletionCode from RR1
|
||
ANI 0F0H
|
||
MVI M,ErrorReset
|
||
|
||
{ In 9750 mode if we are expecting a PAD character check to see if the checksum is valid or not. }
|
||
PUSH PSW
|
||
LDA PadAfterBCC
|
||
ORA A
|
||
JNZ RxEndBCC2
|
||
POP PSW
|
||
|
||
JMP SetBisyncCompletion ;In BisyncInput
|
||
|
||
END
|
||
@
|
||
|
||
|
||
1.1.1.1
|
||
log
|
||
@first add
|
||
@
|
||
text
|
||
@@
|