.TITLE KERSND - Send/Receive on XK port .SBTTL Robert McQueen/Nick Bush/Stuart Hecht/David Stevens ; Version number .IDENT /1.0.03/ ; Directives .LIBRARY /KERMLB/ ; Pro/Kermit macro library .SBTTL Revision History ;++ ; 1.0.000 By: Robert C. McQueen On: 1-December-1983 ; Create this module from other modules ; ; 1.0.01 By: Robert C. McQueen On: 6-March-1984 ; Remove ABORTFLAG checks (obs). ; ; 1.0.02 By: Robert C. McQueen On: 14-March-1984 ; Add ABORT flag and check it in RECEIVE. This will allow ; the user to abort the KERFIL process from KERMIT. ; ; 1.0.03 By: Robert C. McQueen On: 22-May-1984 ; Fix off by one in the counting of characters received. ; RECEIVE was only allowing 93 not 94. ;-- .SBTTL .MCALLs for RSX directives ; The following are the various MCALLs that KERXK uses. .MCALL QIOW$S ; QIO and wait .MCALL QIOW$C ; QIO and wait .MCALL MRKT$S ; Set a mark time request .MCALL CMKT$S ; Cancel mark time requests .MCALL RDEF$S ; Read event flags ; The following causes the KERMIT definitions to be read and defined .MCALL KERDEF ; Get the KERMIT definitions KERDEF ; Define all of the KERMIT symbols .MCALL BLSRTN ; Macro to define entry point .SBTTL Bliss interface routines -- SEND ; This routine will send a message to the remote Kermit ; ; INPUT: The address of the buffer and the length to be ; sent must be on the stack under the return address ; ; STACK: return address ; number of characters to send ; buffer address ; ; OUTPUT: The message is sent to the remote Kermit ; Nothing is changed in this routine ; ; REGISTERS destroyed: NONE ; .PSECT $CODE$, RO BLSRTN SEND,2, ; Define the routine entry point ; ; First clear out any pending input from the XK. This kills garbage that has ; shown up while we were processing things. JSR PC,XK.CIB ; Clear the buffer ; Now just send the buffer MOV BUFADR(SP),R0 ; Get the buffer address MOV BUFLEN(SP),R1 ; Get the buffer length QIOW$S #IO.WAL,#XKLUN,#XKWEFN,,#IOSTAT,, MOV #ABORTED,R0 ; Assume it didn't work TST $DSW ; Check if directive worked BMI 90$ ; No, give up TSTB IOSTAT ; Compare to see if error BMI 90$ ; If no error then skip MOV #KNORMAL,R0 ; All ok 90$: RTS PC ; Return to sender .SBTTL Bliss Interface -- RECIEVE - Read XK characters ; This routine will receive a message from the remote Kermit ; ; INPUT: The address of the buffer must be on ; the stack under the return address ; ; STACK: return address ; address of number of characters (returned) ; buffer address ; ; OUTPUT: The message is received from the remote Kermit ; The length of the buffer is put on the stack ; ; REGISTERS destroyed: NONE ; .PSECT $CODE$, RO BLSRTN RECEIVE,3, ; Define the entry point JSR PC,XK.TIM ; Start timer MOV R0,R2 ; Copy the timeout value for XK.INP 10$: MOV RCVBUF(SP),R1 ; Point at first byte of buffer CLR R3 ; Clear count of characters we have seen RDEF$S #GENEFN ; Check to see if time is up CMP $DSW,#IS.SET ; If set then BEQ 80$ ; branch to timeout exit JSR PC,XK.INP ; Get a character BCS 85$ ; If we got an error, return it CMP #TRUE,ABORT ; Was this aborted? BEQ 85$ ; Yes, just exit TST R0 ; Check if any characters read BEQ 10$ ; No, try again CMPB @R1,RCV.SOH ; Check for start of header BNE 10$ ; If not, check timeout and try again INC R1 ; Point at next character INC R3 ; Got one character ; Here after we have gotten the start of packet character. Now pick up the ;rest 20$: RDEF$S #GENEFN ; Check to see if time is up CMP $DSW,#IS.SET ; If set then BEQ 80$ ; branch to timeout exit ; ; Check if someone requested an abort by typing the key ; JSR PC,XK.INP ; Get another character BCS 85$ ; If I/O fails, abort CMP #TRUE,ABORT ; Was this aborted? BEQ 85$ ; Yes, just exit TST R0 ; Check if we got something BEQ 20$ ; No, try again CMPB @R1,RCV.SOH ; Check for start of header BEQ 10$ ; Restart buffer if so INC R3 ; Count the character CMPB (R1)+,RCV.EOL ; Get end of line character? BEQ 90$ ; Yes, go return CMP R3,#MAX.MSG ; Fill buffer completly yet? BLE 20$ ; If not, just get next character DEC R1 ; Otherwise, back up one character BR 20$ ; And try again ; Here if we ran out of time. Return the timeout 80$: MOV #TIMEOUT,R0 ; Get the status RTS PC ; And return ; Here if we got some error that makes it impossible to continue the transfer ; Return "Aborted" 85$: MOV #ABORTED,R0 ; Give up RTS PC ; Let caller figure out how ; ; Here when we got the end of line character. Save the count ; 90$: MOV R3,@RCVLEN(SP) ; Save the character count MOV #KNORMAL,R0 ; Give good return 99$: RTS PC ; Return to sender .SBTTL Bliss interface -- IBM_WAIT - Wait for the IBM character ;++ ; This routine will wait for the IBM turn around character. Currently ; this routine is just a dummy ;-- .PSECT $CODE$, RO BLSRTN IBM.WAIT,2,, JSR PC,XK.TIM ; Set up our timeout MOV R0,R2 ; Copy QIO timeout parameter MOV #CHAR,R1 ; Get address of our temp ADD SP,R1 ; . . . 10$: RDEF$S #GENEFN ; Check to see if time is up CMP $DSW,#IS.SET ; If set then BEQ 80$ ; branch to timeout exit JSR PC,XK.INP ; Read a character BCS 85$ ; If error, return it TST R0 ; Check if we got anything BEQ 10$ ; No, try again BIC #200,@R1 ; Clear the parity bit CMPB @R1,IBM.CHAR ; This the character we want? BNE 10$ ; No, try again MOV #KNORMAL,R0 ; Yes, return normal RTS PC ; And return ; Here if we timed out while waiting. Return the status 80$: MOV #TIMEOUT,R0 ; Get the status value RTS PC ; And return ; Here if the QIO failed 85$: MOV #ABORTED,R0 ; Just give up RTS PC ; And return .SBTTL CRCCLC - Calculate the CRC-CCITT for a string ; ; Subroutine to calculate the CRC (using CCITT polynomial) for a string ; of bytes. ; ; Call: ; MOV #Address,-(SP) ; Address of string ; MOV Length,-(SP) ; Length of string ; JSR PC,CRCCLC ; Determine CRC ; ; Returned in R0 ; ;From BLISS: ; CRC=CRCCLC(.Address,.Length) ; LEN=14 ; Offset to length ADDR=16 ; Offset to address CRCCLC::JSR R1,$SAVE4 ; Save R1-R4 MOV LEN(SP),R4 ; Get the length of the string MOV ADDR(SP),R3 ; And the address MOV #0,R1 ; Initial CRC value is 0 ; Now loop for all of the characters in the string 10$: MOVB (R3)+,R0 ; Get a character XOR R1,R0 ; Include new byte MOV R0,R2 ; Get a copy BIC #^C17,R0 ; Extract 4 low bits ASL R0 ; Byte address to word index MOV CRCTB2(R0),R0 ; Get the table entry BIC #^C360,R2 ; Get high four bits ASH #-3,R2 ; Shift over for table offset MOV CRCTAB(R2),R2 ; Get the other half XOR R2,R0 ; XOR modifier values CLRB R1 ; Clear low byte of CRC SWAB R1 ; Put high byte in low byte XOR R0,R1 ; Produce new CRC SOB R4,10$ ; Loop for all bytes of the string MOV R1,R0 ; Return the result in R0 RTS PC ; ANd return ; Data tables for CRC-CCITT .PSECT $PLIT$, RO , D CRCTAB: .WORD 0 .WORD 10201 .WORD 20402 .WORD 30603 .WORD 41004 .WORD 51205 .WORD 61406 .WORD 71607 .WORD 102010 .WORD 112211 .WORD 122412 .WORD 132613 .WORD 143014 .WORD 153215 .WORD 163416 .WORD 173617 CRCTB2: .WORD 0 .WORD 10611 .WORD 21422 .WORD 31233 .WORD 43044 .WORD 53655 .WORD 62466 .WORD 72277 .WORD 106110 .WORD 116701 .WORD 127532 .WORD 137323 .WORD 145154 .WORD 155745 .WORD 164576 .WORD 174367 .SBTTL End of KERSND .END