mirror of
https://github.com/livingcomputermuseum/Darkstar.git
synced 2026-03-02 10:06:45 +00:00
39 lines
23 KiB
Plaintext
39 lines
23 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>BisyncInput.asm
|
||
Modification History:
|
||
Dennis DEG : 27-Mar-85 1:19:45: Make changes to handle PAD character in 9750 mode.
|
||
Dennis DEG : 6-Nov-84 15:34:54: Call DisableCRCSub after recieving DLE STX to disable sync stripping
|
||
Dennis DEG : 1-Sep-84 16:52:20: Add copyright notice.
|
||
Dennis DEG : 3-Apr-84 22:14:04: ITB checksum error in 2780 mode.
|
||
Dennis DEG : 12-Jan-84 16:43:57: screwup after ITB character.
|
||
Dennis DEG : 10-Jan-84 23:38:07: Another transparent data bug.
|
||
Dennis DEG : 30-Nov-83 20:20:49: Fix bug in 9750 mode of not throwing out filler character.
|
||
Dennis DEG : 28-Nov-83 11:37:09: Fix handling of transparent data.
|
||
Dennis DEG : 26-Oct-83 17:41:42: Fix bug introduced during changes to support 9750.
|
||
Dennis DEG : 9-Oct-83 16:40:47: Changes to support 9750.
|
||
Dennis DEG : 30-Jun-83 11:08:27: More fixes to meet IBM spec.
|
||
Dennis DEG : 29-Jun-83 15:01:50: ITB fixes
|
||
CrF CRF : 11-Nov-82 10:05:45: Move POPs before EI to avoid possible stack
|
||
overflow.
|
||
Jim JXF : September 17, 1982 9:28 AM: Allow Async mode to have client
|
||
buffer size larger than our Rx buffer.
|
||
Jim JXF : September 8, 1982 2:05 PM: Fix DLE SYN bug.
|
||
Jim JXF : May 20, 1982 1:57 PM
|
||
Jim JXF : May 10, 1982 8:10 AM: Created file.
|
||
}
|
||
|
||
{ Copyright (C) 1982, 1983, 1984, 1985 by Xerox Corporation. All rights reserved.}
|
||
|
||
|
||
Get "SysDefs"
|
||
Get "RS232CDefs"
|
||
|
||
IMP RxBisyncStateSwitch ;From BisyncInterrupts
|
||
IMP StoreFrameHeader ;From RS232CInterrupts
|
||
IMP CharactersUntilBoundary ;From RS232CInterrupts
|
||
IMP CurrentCharLengthMask ;From RS232CMisc
|
||
|
||
EXP BEL6
|
||
EXP EnableRxCRC1
|
||
EXP EnableRxCRC2
|
||
EXP EnableRxCRC3
|
||
EXP EnableRxCRC4
|
||
EXP EndOfBisyncFrame
|
||
EXP EOTEndFrameSwitch
|
||
EXP EOT3270
|
||
EXP DisableRxCRC1
|
||
EXP DisableRxCRC2
|
||
EXP DisableRxCRC3
|
||
EXP ENQ6
|
||
EXP ENQ9
|
||
EXP ENQ10
|
||
EXP ENQ11
|
||
EXP EnterHuntMode1
|
||
EXP EnterHuntMode2
|
||
EXP EOT6
|
||
EXP ETB7
|
||
EXP ETB8
|
||
EXP ETB9
|
||
EXP ETB10
|
||
EXP ETB11
|
||
EXP NAK6
|
||
EXP PadAfterBCC
|
||
EXP RxBisyncInitial
|
||
EXP RxEndBCC2
|
||
EXP RxInitBiSyncInput
|
||
EXP RxMaxFrameSize
|
||
EXP SetBisyncCompletion
|
||
EXP SYN7
|
||
EXP SYN8
|
||
EXP SYN9
|
||
EXP SYN10
|
||
EXP SYN11
|
||
EXP SYN13 {6/30/83}
|
||
EXP SYN14 {6/30/83}
|
||
EXP TerminateBisyncFrame
|
||
;
|
||
{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
|
||
}
|
||
;
|
||
BisyncSwitches:
|
||
DW SOHContinue
|
||
DW RxHeaderSyn
|
||
DW Non9750CRCEnable
|
||
DW RxNonTransparentModeSYN
|
||
DW RxInterBlockCRC1
|
||
DW TModeCRCEnable
|
||
DW Non9750CRCDisable
|
||
DW RxEndingCRC1
|
||
DW RxDataAfterDLE
|
||
DW StoreBisyncChar
|
||
|
||
Siemens9750Switches:
|
||
DW SOH9750Mode
|
||
DW RxHeaderSyn1
|
||
DW CRC9750Enable
|
||
DW RxNTModeSYN1
|
||
DW RxBCCNext
|
||
DW ContinueRxTransparentMode
|
||
DW DisableCRC9750
|
||
DW RxEndingBCC1
|
||
DW SkipCRCEnAfterDLE
|
||
DW Filler9750Mode
|
||
|
||
RxInitBiSyncInput:
|
||
{RxInitBiSync is a procedure which on input contains the current correspondent (Siemens 9750 or other bisync correspondents). On exit all registers are unchanged.}
|
||
|
||
PUSH D ;Save the contents of the DE register pair
|
||
PUSH H ;Save the contents of the HL register pair
|
||
LXI H,0 ;Prepare to get the value of the Stack Pointer
|
||
DI ;Make sure that stack does not get modified
|
||
DAD SP ;Find out where the stack lives
|
||
XCHG ;save the old SP in DE
|
||
|
||
CPI Siemens9750Correspondent
|
||
JNZ BisyncSetup
|
||
|
||
SiemensSetup:
|
||
LXI SP,Siemens9750Switches
|
||
JMP SetBisyncSwitches
|
||
|
||
BisyncSetup:
|
||
LXI SP,BisyncSwitches
|
||
|
||
SetBisyncSwitches:
|
||
POP H
|
||
SHLD InputSOHSwitch
|
||
POP H
|
||
SHLD RxHeaderSwitch
|
||
POP H
|
||
SHLD CRCEnableSwitch
|
||
POP H
|
||
SHLD RxNTModeSwitch
|
||
POP H
|
||
SHLD RxITBCRCSwitch
|
||
POP H
|
||
SHLD TModeCRCSwitch
|
||
POP H
|
||
SHLD Non9750CRC1Switch
|
||
POP H
|
||
SHLD RxEndingCRCorBCCSwitch
|
||
POP H
|
||
SHLD ContRxAfterDLESwitch
|
||
POP H
|
||
SHLD ThrowOutFiller
|
||
|
||
XCHG ;Prepare to restore old stack pointer
|
||
SPHL ;Restore old stack pointer
|
||
EI ;It is now safe to allow stack to change
|
||
POP H ;Restore HL
|
||
POP D ;Restore DE
|
||
RET
|
||
|
||
InputChar:
|
||
{This routine masks off all uninteresting bits, ie. if the character length is 8 nothing happens to it otherwise the 8-n upper bits get masked off for n = 5..7. The routine is re-entrant as long as the PSW is not needed. On exit the Accumulator will have the input data}
|
||
IN RxData
|
||
PUSH H
|
||
LXI H,CurrentCharLengthMask
|
||
ANA M
|
||
POP H
|
||
RET
|
||
|
||
|
||
|
||
RxBisyncInitial:
|
||
{This is the initial receive state. The CRC generator is off. We are waiting for the first character. The receiver is in Hunt mode, which means it is searching for two contiguous sync characters. The SIO chip is set for SyncCharacterLoadInhibit so that leading Sync characters will not be loaded or cause interrupts. Come here when we receive the first character that is not a sync character.}
|
||
|
||
XRA A ;set the BCC to zero (important only for
|
||
STA BlockCheckChar ; 9750 mode)
|
||
|
||
CALL InputChar ;Read character
|
||
CPI STX
|
||
JZ FirstRxCharIsSTX
|
||
|
||
CPI SOH
|
||
JZ FirstRxCharIsSOH
|
||
|
||
CPI DLE
|
||
JZ FirstRxCharIsDLE
|
||
|
||
{EOT is a special character if the host is a 3270. In this case, we enter Hunt mode right away. If the host is not a 3270, we simply end the frame. This switch is set by Misc when the mode and the Correspondent is determined.}
|
||
DB opCPI
|
||
EOT6: DB 0
|
||
DB opJZ
|
||
EOTEndFrameSwitch:
|
||
DW EOT3270
|
||
; JZ EOT3270
|
||
; JZ EndOfBisyncFrame
|
||
|
||
DB opCPI
|
||
BEL6: DB 0
|
||
JZ EndOfBisyncFrame
|
||
|
||
DB opCPI
|
||
NAK6: DB 0
|
||
JZ EndOfBisyncFrame
|
||
|
||
DB opCPI
|
||
ENQ6: DB 0
|
||
JZ EndOfBisyncFrame
|
||
|
||
DB opJMP
|
||
ThrowOutFiller:
|
||
DW StoreBisyncChar
|
||
; DW Filler9750Mode
|
||
|
||
Filler9750Char EQU 7FH
|
||
|
||
Filler9750Mode:
|
||
CPI Filler9750Char
|
||
JZ ExitBisyncDataInt
|
||
|
||
{Continue if the character is not any of the above. We stay in this state.}
|
||
JMP StoreBisyncChar
|
||
|
||
EOT3270:
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;M ¬ EnterHuntMode
|
||
EnterHuntMode1:
|
||
DB 0
|
||
JMP StoreBisyncChar
|
||
;
|
||
FirstRxCharIsSOH:
|
||
LXI H,StartRxHeader
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
StartRxHeader:
|
||
{We are about to read the first Header character following SOH or continue after a SYN character. The CRC generator is off. Unless the next character is a SYN, we want to include it in the CRC.}
|
||
CALL InputChar
|
||
DB opCPI
|
||
SYN7: DB 0
|
||
JZ ExitBisyncDataInt
|
||
|
||
{The following code up to and including the label SOHContinue were added for Siemens 9750 support. In Siemens 9750 mode we turn on the BCC generator after the first SOH or first STX and it remains on until we finish receiving the message including the ETB or ETX.}
|
||
|
||
DB opJMP
|
||
InputSOHSwitch:
|
||
DW SOHContinue
|
||
; DW SOHContinue
|
||
; DW SOH9750Mode
|
||
|
||
SOH9750Mode:
|
||
LXI H,AccumulateBCC
|
||
SHLD InputBCCSwitch
|
||
JMP RejoinSOH
|
||
|
||
SOHContinue:
|
||
{If the first character of the header is not SYN, turn on the CRC generator to include the character in the CRC. During receive, the CRC accumulation is delayed eight bits. We must read a character, decide whether or not to continue CRC accumulation, and disable/enable CRC before the next character is transferred to the buffer.}
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;RxCont ¬ WR3 OR RxCRCEnable
|
||
EnableRxCRC1:
|
||
DB 0
|
||
|
||
RejoinSOH:
|
||
CPI STX
|
||
JZ ContinueRxNonTransparentMode
|
||
|
||
CPI DLE
|
||
JZ LookForSTXAfterRxDLENext {modified 6/30/83}
|
||
|
||
CPI ETX
|
||
JZ RxEndingCRCNext
|
||
|
||
DB opCPI
|
||
ETB7: DB 0
|
||
JZ RxEndingCRCNext
|
||
|
||
{Continue if the character is not any of the above. Pass to RxHeader state.}
|
||
LXI H,RxHeader
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
;
|
||
RxHeader:
|
||
{We are about to read the next Header character. The CRC generator is on. Unless the next character is a SYN, we want to include it in the CRC.}
|
||
CALL InputChar
|
||
DB opCPI
|
||
SYN8: DB 0
|
||
|
||
DB opJZ
|
||
RxHeaderSwitch:
|
||
DW RxHeaderSyn
|
||
; JZ RxHeaderSyn
|
||
; JZ RxHeaderSyn1
|
||
|
||
CPI STX
|
||
JZ ContinueRxNonTransparentMode
|
||
|
||
CPI DLE
|
||
JZ LookForSTXAfterRxDLENext {modified 6/30/83}
|
||
|
||
CPI ETX
|
||
JZ RxEndingCRCNext
|
||
|
||
DB opCPI
|
||
ETB8: DB 0
|
||
JZ RxEndingCRCNext
|
||
|
||
{Continue if the character is not any of the above. Stay in this state. Leave the CRC generator on.}
|
||
JMP StoreBisyncChar
|
||
|
||
RxHeaderSyn:
|
||
{Come here if we got a SYN character in the header. The SYN character does not get included in the checksum, and it does not get stored in the input buffer. Disable the CRC generator.}
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;RxCont ¬ WR3 OR RxCRCEnable
|
||
DisableRxCRC1:
|
||
DB 0
|
||
|
||
RxHeaderSyn1:
|
||
LXI H,StartRxHeader
|
||
SHLD RxBisyncStateSwitch
|
||
JMP ExitBisyncDataInt
|
||
;
|
||
FirstRxCharIsSTX:
|
||
LXI H,StartRxNonTransparentMode
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
EnableCRCSub:
|
||
DB opJMP
|
||
CRCEnableSwitch:
|
||
DW Non9750CRCEnable
|
||
; DW Non9750CRCEnable
|
||
; DW CRC9750Enable
|
||
|
||
CRC9750Enable:
|
||
LXI H,AccumulateBCC
|
||
SHLD InputBCCSwitch
|
||
RET
|
||
|
||
Non9750CRCEnable:
|
||
{If the first character of the header is not SYN, turn on the CRC generator to include the character in the CRC. During receive, the CRC accumulation is delayed eight bits. We must read a character, decide whether or not to continue CRC accumulation, and disable/enable CRC before the next character is transferred to the buffer.}
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;RxCont ¬ WR3 OR RxCRCEnable
|
||
EnableRxCRC2:
|
||
DB 0
|
||
RET
|
||
|
||
|
||
StartRxNonTransparentMode:
|
||
{We are about to read the first character in NonTransparent Mode or continue after a SYN character. The CRC generator is off. Unless the next character is SYN, we want to include it in the CRC.}
|
||
CALL InputChar
|
||
DB opCPI
|
||
SYN9: DB 0
|
||
JZ ExitBisyncDataInt
|
||
|
||
{The following code up to and including the label Non9750CRCEnable were added for Siemens 9750 support. In Siemens 9750 mode we turn on the BCC generator after the first SOH or first STX and it remains on until we finish receiving the message including the ETB or ETX.}
|
||
|
||
CALL EnableCRCSub
|
||
|
||
RejoinSTX:
|
||
CPI ETX
|
||
JZ RxEndingCRCNext
|
||
|
||
DB opCPI
|
||
ETB9: DB 0
|
||
JZ RxEndingCRCNext
|
||
|
||
CPI ITB
|
||
JZ RxInterBlockCRCNext
|
||
|
||
DB opCPI
|
||
ENQ9: DB 0
|
||
JZ EndOfBisyncFrame
|
||
|
||
ContinueRxNonTransparentMode:
|
||
LXI H,RxNonTransparentMode
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
;
|
||
DisableCRCAndExit:
|
||
CALL DisableCRCSub
|
||
JMP ExitBisyncDataInt
|
||
|
||
RxITBContinueNTMode:
|
||
{After ITB we may optionally receive SYN (without including them in the checksum). }
|
||
CALL InputChar
|
||
DB opCPI
|
||
SYN13: DB 0
|
||
JZ DisableCRCAndExit
|
||
CALL EnableCRCSub
|
||
LXI H,RxNonTransparentMode
|
||
SHLD RxBisyncStateSwitch
|
||
JMP RxNTMode
|
||
|
||
RxNonTransparentMode:
|
||
{We are receiving characters in NonTransparent mode. The CRC generator is on. Unless the next character is SYN, we want to include it in the CRC.}
|
||
CALL InputChar
|
||
|
||
RxNTMode:
|
||
DB opCPI
|
||
SYN10: DB 0
|
||
|
||
DB opJZ
|
||
RxNTModeSwitch:
|
||
DW RxNonTransparentModeSYN
|
||
; JZ RxNonTransparentModeSYN
|
||
; JZ RxNTModeSYN1
|
||
|
||
CPI ETX
|
||
JZ RxEndingCRCNext
|
||
|
||
DB opCPI
|
||
ETB10: DB 0
|
||
JZ RxEndingCRCNext
|
||
|
||
CPI ITB
|
||
JZ RxInterBlockCRCNext
|
||
|
||
DB opCPI
|
||
ENQ10: DB 0
|
||
JZ EndOfBisyncFrame
|
||
|
||
{Continue if the character is not any of the above. We stay in NonTransparent Mode.}
|
||
JMP StoreBisyncChar
|
||
|
||
RxNonTransparentModeSYN:
|
||
{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.}
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;RxCont ¬ WR3 OR RxCRCDisable
|
||
DisableRxCRC2:
|
||
DB 0
|
||
|
||
RxNTModeSYN1:
|
||
LXI H,StartRxNonTransparentMode
|
||
SHLD RxBisyncStateSwitch
|
||
JMP ExitBisyncDataInt
|
||
;
|
||
RxInterBlockCRCNext:
|
||
{Come here when we have just read an ITB character. The next two characters we receive will be CRC characters. The CRC generator is on.}
|
||
{LXI H,RxInterBlockCRC1}
|
||
|
||
DB opLXIH
|
||
RxITBCRCSwitch:
|
||
DW RxInterBlockCRC1
|
||
; DW RxInterBlockCRC1
|
||
; DW RxBCCNext
|
||
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
RxInterBlockCRC1:
|
||
{Read and store the first Interblock CRC character.}
|
||
CALL InputChar
|
||
LXI H,RxInterBlockCRC2
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
RxBCCNext:
|
||
{Read and store the Block Check Character. This is what the 9750 uses for vertical parity checking.}
|
||
RxInterBlockCRC2:
|
||
{Read and store the second Interblock CRC character. The result of the CRC will not be available until two characters later. Maybe someday we will get around to checking the CRC. For now, we will wait until the end of the block.}
|
||
|
||
CALL InputChar
|
||
PUSH PSW ;save character
|
||
|
||
LDA TransparentDataFlag ;If we were in transparent mode then
|
||
ORA A ;stay there. 6/29/83
|
||
|
||
JNZ ContinueITBRxTransparentMode
|
||
|
||
ContinueITBRxNonTransparentMode:
|
||
{6/30/83}
|
||
LXI H,RxITBContinueNTMode
|
||
JMP SaveLastByteChecksum
|
||
|
||
ContinueITBRxTransparentMode:
|
||
LXI H,RxITBContinueTMode
|
||
|
||
SaveLastByteChecksum:
|
||
POP PSW ;restore character
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
;
|
||
FirstRxCharIsDLE:
|
||
{Come here if the first Rx character is DLE. Look for STX to enter transparent mode. Any other character will be EndOfFrame. The CRC generator is not on. The STX is NOT included in the checksum.}
|
||
LXI H,LookForSTXAfterFirstRxDLE
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
LookForSTXAfterFirstRxDLE:
|
||
CALL InputChar
|
||
CPI STX
|
||
JNZ EndOfBisyncFrame
|
||
|
||
CALL DisableCRCSub
|
||
LXI H,StartRxTransparentMode
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
;
|
||
{ITB fixes. 6/29/83}
|
||
TransparentDataFlag:
|
||
DB 0
|
||
StartRxTransparentMode:
|
||
{We are about to receive the first character in Transparent Mode or continue after DLE SYN. We want to include the next character in the CRC unless it is DLE.}
|
||
|
||
MVI A,1 ;Indicate Transparent mode. 6/29/83
|
||
STA TransparentDataFlag
|
||
|
||
CALL InputChar
|
||
CPI DLE
|
||
JZ DisableCRCNow
|
||
|
||
DB opJMP
|
||
TModeCRCSwitch:
|
||
DW TModeCRCEnable
|
||
; DW TModeCRCEnable
|
||
; DW ContinueRxTransparentMode
|
||
|
||
TModeCRCEnable:
|
||
{Turn on the CRC generator to include the character in the CRC. During receive, the CRC accumulation is delayed eight bits. We must read a character, decide whether or not to continue CRC accumulation, and disable/enable CRC before the next character is transferred to the buffer.}
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;RxCont ¬ WR3 OR RxCRCEnable
|
||
EnableRxCRC3:
|
||
DB 0
|
||
JMP ContinueRxTransparentMode
|
||
|
||
RxITBContinueTMode:
|
||
{We can have SYN* followed by DLE STX only, after ITB in Transparent mode. The CRC generator is off.}
|
||
CALL InputChar
|
||
DB opCPI
|
||
SYN14: DB 0
|
||
JZ DisableCRCAndExit
|
||
CPI DLE
|
||
JNZ IllegalRxSequence
|
||
CALL EnableCRCSub ;Make sure the CRC generator is on.
|
||
|
||
LookForSTXAfterRxDLENext:
|
||
LXI H,LookForSTXAfterRxDLE
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
LookForSTXAfterRxDLE:
|
||
{Come here after the sequence ITB BCC SYN* DLE or SOH DLE. The only valid character that can follow is STX to start Transparent Mode. The CRC generator may or may not be on. The STX needs to be included in the CRC.}
|
||
CALL InputChar
|
||
CPI STX
|
||
JNZ IllegalRxSequence
|
||
CALL EnableCRCSub
|
||
|
||
JMP ContinueRxTransparentMode
|
||
|
||
NoRoomForDLE:
|
||
{This is a sneaky way of saving the contents of the registers and faking a subroutine call while in the middle of a subroutine. E contains the completion code.}
|
||
PUSH H ;Save the HL register temporarily.
|
||
LXI H,RetAddr ;RetAddr is where we enventually want to return to.
|
||
XTHL ;This restores HL while putting the return address on the stack.
|
||
PUSH PSW ;Now set up the stack with the registers that the new subroutine is going to POP in the correct order.
|
||
PUSH H
|
||
PUSH D
|
||
MVI E,4 ;Set EndOfBlock CompletionCode
|
||
{The stack should now look like:
|
||
|
||
TOS: DE
|
||
HL
|
||
PSW
|
||
RetAddr
|
||
|
||
Where TOS is what the Stack pointer is pointing to.}
|
||
|
||
JMP SetNewBisyncBoundary ;CALL the subroutine.
|
||
|
||
RetAddr:
|
||
DI ;unfortunately we had an EI executed on us.
|
||
JMP ReEnter
|
||
|
||
RxTransparentMode:
|
||
{We are receiving characters in Transparent mode. The only interesting character to look for is DLE. The CRC generator is on.}
|
||
CALL InputChar
|
||
CPI DLE
|
||
JNZ StoreBisyncChar
|
||
|
||
DisableCRCNow:
|
||
CALL DisableCRCSub
|
||
|
||
LookForRxDataNext:
|
||
LXI H,LookForRxDataAfterDLE
|
||
SHLD RxBisyncStateSwitch
|
||
JMP ExitBisyncDataInt
|
||
|
||
DisableCRCSub:
|
||
DB opJMP
|
||
Non9750CRC1Switch:
|
||
DW Non9750CRCDisable
|
||
; DW Non9750CRCDisable
|
||
; DW DisableCRC9750
|
||
|
||
DisableCRC9750:
|
||
LXI H,CheckBoundary
|
||
SHLD InputBCCSwitch
|
||
RET
|
||
|
||
Non9750CRCDisable:
|
||
{Come here when we want to turn the CRC generator off.}
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;RxCont ¬ WR3 OR RxCRCDisable
|
||
DisableRxCRC3:
|
||
DB 0
|
||
RET
|
||
|
||
LookForRxDataAfterDLE:
|
||
{Read the character following DLE in Transparent mode. The CRC geneator is off. Unless the character is SYN, we will include it in the checksum.}
|
||
CALL InputChar
|
||
DB opCPI
|
||
SYN11: DB 0
|
||
JZ DLESyn
|
||
|
||
DB opJMP
|
||
ContRxAfterDLESwitch:
|
||
DW RxDataAfterDLE
|
||
; DW RxDataAfterDLE
|
||
; DW SkipCRCEnAfterDLE
|
||
|
||
RxDataAfterDLE:
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR3
|
||
DB opMVIM ;RxCont ¬ WR3 OR RxCRCEnable
|
||
EnableRxCRC4:
|
||
DB 0
|
||
|
||
SkipCRCEnAfterDLE:
|
||
|
||
{This next section is to insert a DLE in the clients buffer except in the case of DLE SYN where the DLE SYN are both removed}
|
||
PUSH PSW
|
||
MVI A,DLE
|
||
CALL StoreBSCChar
|
||
JZ NoRoomForDLE
|
||
ReEnter:
|
||
POP PSW
|
||
|
||
|
||
CPI DLE
|
||
JZ ContinueRxTransparentMode
|
||
|
||
DB opCPI
|
||
ENQ11: DB 0
|
||
JZ EndOfBisyncFrame
|
||
|
||
DB opCPI
|
||
ETB11: DB 0
|
||
JZ RxEndingCRCNext
|
||
|
||
CPI ETX
|
||
JZ RxEndingCRCNext
|
||
|
||
CPI AltoETX
|
||
JZ RxEndingCRCNext
|
||
|
||
CPI ITB
|
||
JZ RxInterBlockCRCNext
|
||
|
||
IllegalRxSequence:
|
||
STAX B
|
||
INX B
|
||
PUSH D
|
||
MVI E,8 ;Set CompletionCode IllegalSequence
|
||
MVI A,38H ;Issue Return From Int Command
|
||
OUT RxCont
|
||
JMP TerminateBisyncFrame
|
||
|
||
DLESyn:
|
||
{Come here if we found DLE SYN in Transparent mode.}
|
||
LXI H,StartRxTransparentMode
|
||
SHLD RxBisyncStateSwitch
|
||
JMP ExitBisyncDataInt
|
||
;
|
||
RxEndingCRCNext:
|
||
{Come here when we have received the last character of the frame. The next two characters we receive will be CRC characters. The CRC generator is on.}
|
||
|
||
LXI H,TransparentDataFlag ;set non-transparent mode. 6/29/83
|
||
MVI M,0
|
||
|
||
DB opLXIH
|
||
RxEndingCRCorBCCSwitch:
|
||
DW RxEndingCRC1
|
||
; DW RxEndingCRC1
|
||
; DW RxEndingBCC1
|
||
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
RxEndingBCC1:
|
||
{Read and store the BCC. If all has went well the accumulated BCC should be zero after storing the BCC in the buffer.}
|
||
CALL InputChar
|
||
|
||
LXI H,PadAfterBCC ;Mark the fact that we are expecting a PAD
|
||
MVI M,1 ;character next.
|
||
|
||
LXI H,RxEndingBCC2
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
PadAfterBCC DB 0
|
||
|
||
RxEndingBCC2:
|
||
PUSH D ;Save DE
|
||
MVI E,80H ;Set up as good (does not affect flags)
|
||
|
||
RxCheckForGoodBCC:
|
||
XRA A
|
||
STA PadAfterBCC
|
||
|
||
LDA BlockCheckChar
|
||
ORA A ;Check to make sure BCC shows column parity (all zero).
|
||
MOV A,E
|
||
JZ SetBisyncCompletion
|
||
ORI 40H ;Indicate bad BCC (CRC)
|
||
JMP SetBisyncCompletion
|
||
|
||
RxEndBCC2:
|
||
POP PSW ;get current error status
|
||
MOV E,A ;move it to the E register
|
||
JMP RxCheckForGoodBCC
|
||
|
||
RxEndingCRC1:
|
||
{Read and store the first Interblock CRC character.}
|
||
CALL InputChar
|
||
LXI H,RxEndingCRC2
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
RxEndingCRC2:
|
||
{Read and store the second Interblock CRC character.}
|
||
CALL InputChar
|
||
LXI H,RxEndingCRC3
|
||
JMP ChangeStateAndStoreBisyncChar
|
||
|
||
RxEndingCRC3:
|
||
{Read and throw away the character following the second CRC character. We are guaranteed at least three fill characters following the CRC, so we are only throwing away fill characters. The CRC result will not be available until one character later.}
|
||
CALL InputChar
|
||
LXI H,RxEndingCRC4
|
||
SHLD RxBisyncStateSwitch
|
||
JMP ExitBisyncDataInt
|
||
|
||
EndOfBisyncFrame:
|
||
|
||
STAX B ;Store character
|
||
INX B
|
||
PUSH D
|
||
MVI E,80H ;E ¬ EndOfFrame CompletionCode
|
||
JMP SendEndingReturnFromInt
|
||
|
||
RxEndingCRC4:
|
||
{Read and throw away the second fill character following the second CRC character. The result of the CRC is now available in WR1.}
|
||
PUSH D ;Save DE
|
||
CALL InputChar
|
||
LXI H,8000H+RxCont
|
||
MVI M,PointToWR1
|
||
MOV A,M
|
||
ANI 40H ;A ¬ 40 if CRC error
|
||
ORI 80H
|
||
|
||
SetBisyncCompletion:
|
||
{Come here from RxSpecialInt in BisyncInterrupts.}
|
||
MOV E,A ;Set CompletionCode
|
||
|
||
SendEndingReturnFromInt:
|
||
MVI A,38H ;Issue Return From Int Command
|
||
OUT RxCont
|
||
|
||
TerminateBisyncFrame:
|
||
{We get called here from Get in case an abort is requested. The CompletionCode is in E. Turn off the CRC generator, Enter Hunt Phase, turn on InhibitSyncCharacterLoad.}
|
||
LXI H,8000H+RxCont
|
||
MVI M,ResetRxCRCChecker+PointToWR3
|
||
DB opMVIM
|
||
EnterHuntMode2:
|
||
DB 0
|
||
|
||
LXI H,TransparentDataFlag ;set non-transparent mode. 6/29/83
|
||
MVI M,0
|
||
|
||
LXI H,CheckBoundary ;Turn off the BCC mechanism
|
||
SHLD InputBCCSwitch
|
||
|
||
LXI H,RxBisyncInitial
|
||
SHLD RxBisyncStateSwitch
|
||
JMP SetNewBisyncBoundary
|
||
|
||
StoreBSCChar:
|
||
{A = last character read. Store this character in the RxFifo. Decrement CharactersUntilBoundary and test for boundary. If we have filled a block, ship this frame back to the CP and start a new frame.}
|
||
STAX B
|
||
INX B
|
||
|
||
{The code from here up to and including the label CheckBoundary were added for Klamath 11.0b and beyond to support Siemens' 9750 terminal. The major problem with the Siemens terminal is that it does not use the standard Cyclic Redundancy Check mechanism so we need to support their flakey method.
|
||
|
||
In the normal case we will always jump to CheckBoundary, thereby only paying only a 10 state time penalty for the JMP instruction. In 9750 mode we will jump to CheckBoundary until the character following the first SOH (start of heading) or STX (start of text) is found.}
|
||
|
||
DB opJMP
|
||
InputBCCSwitch:
|
||
DW CheckBoundary
|
||
; JMP CheckBoundary
|
||
; JMP AccumulateBCC
|
||
|
||
BCCMask EQU 7FH
|
||
|
||
BlockCheckChar:
|
||
DB 0
|
||
|
||
AccumulateBCC:
|
||
CPI AsciiSYN ;check to see if character is sync character.
|
||
JZ CheckBoundary ;If it is then do not modify BCC.
|
||
LXI H,BlockCheckChar ;Reference the Block Check Character.
|
||
XRA M ;calculate the modulo 2 sum of each column.
|
||
ANI BCCMask ;mask off the parity bit.
|
||
MOV M,A ;save the new Block Check Character.
|
||
|
||
CheckBoundary:
|
||
LHLD CharactersUntilBoundary
|
||
DCX H
|
||
SHLD CharactersUntilBoundary
|
||
MOV A,H
|
||
ORA L
|
||
RET
|
||
|
||
ContinueRxTransparentMode:
|
||
LXI H,RxTransparentMode
|
||
|
||
ChangeStateAndStoreBisyncChar:
|
||
SHLD RxBisyncStateSwitch
|
||
|
||
StoreBisyncChar:
|
||
CALL StoreBSCChar
|
||
JZ BisyncBlockFull
|
||
|
||
ExitBisyncDataInt:
|
||
MVI A,38H ;Issue Return From Int Command
|
||
OUT RxCont
|
||
POP H
|
||
POP PSW
|
||
EI ;Enable interrupts
|
||
RET
|
||
|
||
BisyncBlockFull:
|
||
{End this Bisync frame and start a new frame. Then continue in the same state when we get the next input character.}
|
||
PUSH D ;Save DE
|
||
MVI E,4 ;Set EndOfBlock CompletionCode
|
||
MVI A,38H ;Issue Return From Int Command
|
||
OUT RxCont
|
||
|
||
SetNewBisyncBoundary:
|
||
{RxMaxFrameSize is the number of characters until our next boundary.}
|
||
DB opLXIH ;HL ¬ RxMaxFrameSize
|
||
RxMaxFrameSize:
|
||
DW 0
|
||
SHLD CharactersUntilBoundary
|
||
JMP StoreFrameHeader
|
||
|
||
END
|
||
@
|
||
|
||
|
||
1.1.1.1
|
||
log
|
||
@first add
|
||
@
|
||
text
|
||
@@
|