.TITLE KERMIT .SBTTL S Hecht/D Stevens/R McQueen ;++ ; Main module for PRO/Kermit command scanning. This will communicate ; its desires to the KERFIL.TSK ;-- ; Version number .IDENT /1.0.10/ ; Directives .ENABLE LC ; Allow lower case ascii strings .NLIST BEX .LIBRARY /KERMLB/ ; Kermit macro library .SBTTL Revision History ;++ ; Version 1.0.00 ; ; 1.0.00 Create this module ; ; 1.0.01 By: Robert C. McQueen On: 15-Feb-1984 ; Clean random routines, delete ones that are not used any more ; delete global symbols that don't need to be.... ; ; 1.0.02 By: Robert C. McQueen On: 5-March-1984 ; No need to attach to the terminal, so don't do it. ; ; 1.0.03 By: Robert C. McQueen On: 14-March-1984 ; Redo the inter-task communications. ; ; 1.0.04 By: Robert C. McQueen On: 19-March-1984 ; Implement support for additional generic commands. ; ; 1.0.05 By: Robert C. McQueen On: 20-March-1984 ; Change WAIT to SNDPKT to avoid a global symbol conflict. ; ; 1.0.06 By: David Stevens On: 21-March-1984 ; Change input routines from IO.RVB to IO.RPR, read after ; prompt. Also remove useless data locations. Also fix ; the check for accepting a null input, and C$GET requires ; input. ; ; 1.0.07 By: Robert C. McQueen On: 23-March-1984 ; Make INPUT2 return the correct information. ; ; 1.0.08 By: Robert C. McQueen On: 27-March-1984 ; Append the positioning strings to the beginning in INPUT and ; INPUT2. ; ; 1.0.09 By: Robert C. McQueen On: 5-April-1984 ; Fix the RESUME typeout problem (I hope). ; ; 1.0.10 By: Robert C. McQueen On: 16-April-1984 ; Move some routines to support KERCON being a seperate task. ;-- .SBTTL External symbols ; Get the KERMLB definitions .MCALL KERDEF KERDEF ; Get the general symbol definitions .MCALL CHRDEF ; Macro for special character CHRDEF ; definitions (.CHxxx) .MCALL BLSRTN ; Allow use of BLISS macros from .MCALL BLSCAL ; library .MCALL PJMP .MCALL MSG ; Text definition macro ; ; System routines used in Kermit ; .MCALL QIOW$C .MCALL QIOW$S .MCALL DIR$ .MCALL ABRT$C ; Abort task. .MCALL MRKT$S ; Mark time .MCALL ALUN$C ; Assign LUN .MCALL WTSE$S ; Wait for single event flag .MCALL RQST$C ; Request a task (start it up) .MCALL CLEF$S ; Clear event flag .SBTTL Data area for Kermit ;++ ; The following are the various flags that are found in KERMIT ;-- .PSECT $BYTE$, RW, D RESFLG: .BLKB ; Byte flag for resuming typeout .SBTTL Data for Baud rate conversion to ascii .PSECT $PLIT$, RO, D ; ; Data for Senfil system call ; WLDCRD: .asciz '*.*;*' ; Wild card specification. .even WCDLEN: .word 5 ; Number of wildcard parameters. SDTXT: .asciz 'Possible files to send:' .even LSDTXT: .word 27 PRPT1: .asciz 'To make selections press SELECT' .even LPRPT1: .word 37 PRPT2: .asciz 'Make selection and press DO' .even LPRPT2: .word 34 .sbttl Table for oldfil system call SENFIL: .byte lensfl,0 .word status .word nochos .word files .word fsize .word wldcrd .word wcdlen .word sdtxt .word lsdtxt .word prpt1 .word lprpt1 .word prpt2 .word lprpt2 lensfl= <.-senfil>/2-1 .sbttl Messages ; ; Error messages ; ERRRQS: .asciz 'Error trying to run KERFIL - make sure it is installed' ; Error message for the request .even ; task routine ; ; Messages for Status Display ; MSG STAT, STATMG: .ASCII <.CHCSI>'4;50HLast'<.CHCSI>'4;65HTotal' .ASCII <.CHCSI>'5;50H----'<.CHCSI>'5;65H-----' .ASCII <.CHCSI>'7;5HThe number of bytes sent:' .ASCII <.CHCSI>'8;5HThe number of data bytes sent:' .ASCII <.CHCSI>'9;5HThe number of packets for sent:' .ASCII <.CHCSI>'10;5HThe number of NAK packets sent:' .ASCII <.CHCSI>'11;5HThe number of bytes received:' .ASCII <.CHCSI>'12;5HThe number of data bytes received:' .ASCII <.CHCSI>'13;5HThe number of packets for received:' .ASCII <.CHCSI>'14;5HThe number of NAK packets received:' .ASCIZ <.CHCSI>'23;5HPress RESUME key to continue'<.CHCRT> .EVEN ; ; Prompt for input ; INPHDR: .ASCII <.CHCSI>/4;10H/ .ASCII /Press MAIN SCREEN or EXIT to return to the main menu/ .ASCIZ <.CHCSI>/8;10H/ M$PMT1: .ASCIZ <.CHCSI>/12;10H/ M$PMT2: .ASCIZ <.CHCSI>/14;10H/ GETTXT: .ASCII / Enter the name of the file(s) you wish to get/ .ASCII <.CHCSI>/9;10H/ .ASCIZ / from the remote system and press RETURN/ FILPMT::.ASCIZ /Remote File Name: / WRONGK: .ASCII <.CHESC>/7/<.CHCSI>/18;10H/ .ASCIZ /You pressed the wrong function key. /<.CHESC>/8/ NOINP: .ASCII <.CHESC>/7/<.CHCSI>/18;10H/ .ASCIZ /Must be specified ! /<.CHESC>/8/ I$HDR: .ASCIZ /Files To Be Received/ HDR$L = .-I$HDR .EVEN .SBTTL Entry point for KERMIT ;++ ; This is the starting point of Pro/Kermit. The first thing that is done ; is the initialization and then to call the command scanner to do the work. ;-- .PSECT $CODE$, RO, I FROG: JSR PC,INICMD ; Initialize the command processing JSR PC,INILIB ; Initialize the library routines BLSCAL TT.INIT ; Initialize terminal processing ALUN$C XKLUN,XK,0,$CODE$ ; Assign XK LUN JSR PC,DEFINI ; Initialize the default file processing DIR$ #ASSIGN,IOERR ; Do the assign terminal LUN routine ; located at assign. ; ; Initialize the intertask communication ; MOV #N$KER,R0 ; Claim I'm KERMIT MOV #N$FIL,R1 ; And I talk to KERFIL JSR PC,IT$INI ; Initialize intertask ; ; Now and try to start the task ; JSR PC,STAFIL ; Start KERFIL BCC 20$ ; Branch if not started ; ; Here if the task is already active, determine what to do about it ; JSR PC,CHKACT ; Check active task ; ; Here to do the command scanning ; 20$: CLR CONNECT.FLAG ; Clear the connected to own line flag JSR PC,COMMAN ; Process commands JSR PC,EXFIL ; Tell KERFIL to go away JMP EXIT ; Exit this process .SBTTL CHKACT - Check what to do about an active task ;++ ; This routine will determine what to do about an active task. ;-- .PSECT $CODE$, RO, I .GLOBL CHKACT ; Global routine CHKACT: CLRB RESFLG ; Clear RESUME flag BIT #TRUE,RUN ; Is it really running already? BEQ 99$ ; No, just return to the caller MRKT$S ,#10,#1 ; Wait for a ten ticks BIT #TRUE,RUN ; May have been just starting up BEQ 99$ ; Continue ; ; Here if the task is already running, if that is the case display the menu ; to the user to determine what to do. ; JSR PC,CMDRUN ; Do the command processing for a ; KERFIL that is running TSTB RESFLG ; Use resume type out? BNE CHKACT ; Yes, could have exited before done again TST MAIFLG ; User want MAIN SCREEN BEQ 99$ ; No, don't exit JMP EXIT ; Get out ; ; Now just return to the caller ; 99$: RTS PC ; Just return for now ; ; Here if we want to abort the KERFIL task and then try again. ; CHKABT::MOV #$TKABT,R0 ; Force the KERFIL to abort JSR PC,IT$SND ; Send the data BIT #TRUE,RUN ; Is it really running already? BEQ RET ; No, just return to the caller MRKT$S ,#2,#2 ; Wait for a two seconds BIT #TRUE,RUN ; Did it shut down? BEQ RET ; Continue ABRT$C KERFIL,$CODE$ ; Abort the task PJMP STAFIL ; Start KERFIL RET: RTS PC ; Return to the caller ; ; Here if we want to resume the file transfer ; CHKRES::INCB RESFLG ; Flag we got a resume MOV #$TKPAI,R0 ; Have to paint the screen PJMP SNDPKT ; Send the pack and wait until the ; other end is finished .SBTTL STATUS command ;++ ; This routine will output the status information that is kept in the data ; area of KERMSG. It will paint the box first than fill in the text and ; finally print the numbers in the box. ; ; Usage: ; JSR PC,STATUS ; (Return) ; ;-- STATE:: ; ; Attach to the terminal, clear the screen, turn off the cursor, and ; print out the status message. ; BLSCAL PAINT,<#M$STAT,#STAT$L,#20.>,+ ; Paint the border BLSCAL TT.TEXT,#CUROFF,+ ; Turn the cursor off BLSCAL TT.TEXT,#STATMG,- ; Output the text ; ; Reposition the cursor to correspond to the first status message. ; MOV #6,R4 ; Set line count at 5. JSR PC,STCRMV ; Jump to status cursor movement. ; ; Take the absolute value of the number of bytes sent, convert it ; to decimal, and output it. ; Reposition the cursor one line down. ; MOV SMSG.TOTAL.CHARS,R2 ; Get total chars for this pass JSR PC,CHGDEC ; Call ascii conversion subroutine. JSR PC,STCR65 ; Position again MOV SND.TOTAL.CHARS,R2 ; Get total since startup JSR PC,CHGDEC ; Print it JSR PC,STCRMV ; Jump to status cursor movement. ; ; Print the number of data characters sent ; MOV SMSG.DATA.CHARS,R2 ; Move send data count into R2. JSR PC,CHGDEC ; Call ascii conversion routine. JSR PC,STCR65 ; Move out to totals column MOV SND.DATA.CHARS,R2 ; Total data sent JSR PC,CHGDEC ; Print the total JSR PC,STCRMV ; Jump to status cursor movement. ; ; Convert the send packet count to decimal and output it. ; Reposition the cursor one line down. ; MOV SMSG.COUNT,R2 ; Move send packet count into R2. JSR PC,CHGDEC ; Call ascii conversion routine. JSR PC,STCR65 ; Move to total column MOV SND.COUNT,R2 ; Total packet count JSR PC,CHGDEC ; Print it JSR PC,STCRMV ; Jump to status cursor movement. ; ; Print the number of NAK's sent ; MOV SMSG.NAKS,R2 ; Move send NAK count into R2. JSR PC,CHGDEC ; Call ascii conversion routine. JSR PC,STCR65 ; Move out to totals column MOV SND.NAKS,R2 ; Total naks sent JSR PC,CHGDEC ; Print the total JSR PC,STCRMV ; Jump to status cursor movement. ; ; Take the absolute value of the number of bytes received, convert it ; to decimal, and output it. ; Reposition the cursor one line down. ; MOV RMSG.TOTAL.CHARS,R2 ; Get total chars for this pass JSR PC,CHGDEC ; Call ascii conversion subroutine. JSR PC,STCR65 ; To column 65 MOV RCV.TOTAL.CHARS,R2 ; Get total since startup JSR PC,CHGDEC ; Print it JSR PC,STCRMV ; Jump to status cursor movement. ; ; Print the number of data characters received ; MOV RMSG.DATA.CHARS,R2 ; Move received data count into R2. JSR PC,CHGDEC ; Call ascii conversion routine. JSR PC,STCR65 ; Move out to totals column MOV RCV.DATA.CHARS,R2 ; Total data received JSR PC,CHGDEC ; Print the total JSR PC,STCRMV ; Jump to status cursor movement. ; ; Convert the receive packet count to decimal and output it. ; Reposition the cursor one line down. ; MOV RMSG.COUNT,R2 ; Move receive packet count into R2. JSR PC,CHGDEC ; Call ascii conversion subroutine. JSR PC,STCR65 ; Move out to totals column MOV RCV.COUNT,R2 ; Total packets received JSR PC,CHGDEC ; Print the total JSR PC,STCRMV ; Jump to status cursor movement. ; ; Print the number of NAK's received ; MOV RMSG.NAKS,R2 ; Move received NAK count into R2. JSR PC,CHGDEC ; Call ascii conversion routine. JSR PC,STCR65 ; Move out to totals column MOV RCV.NAKS,R2 ; Total naks received JSR PC,CHGDEC ; Print the total JSR PC,STCRMV ; Jump to status cursor movement. ; ; Print out the last error message received. ; MOV #17.,R5 ; Set for line 17 MOV #4,R2 ; Set for column 4 JSR PC,CURABS ; Position the cursor BLSCAL TT.TEXT,#LAST.ERROR ; Print out the last error message. ; ; Position cursor at line 22, column 1; turn on the cursor and output ; everything. Wait for the resume key to be pressed. ; MOV #22.,R5 ; Set for line 18. MOV #1,R2 ; Set for column 1. JSR PC,CURABS ; Position the cursor. BLSCAL TT.TEXT,#CURON ; Output the text BLSCAL TT.OUTPUT ; Output any remaining characters CALL WTRES ; Wait for RESUME key to be pressed ; before continuing. RTS PC ; Return to the caller ;++ ; ; Position cursor for last pass field ; ;-- STCRMV: INC R4 ; Incrament the line counter. MOV R4,R5 ; Put line number into R5 MOV #50.,R2 ; Put column number into R5. PJMP CURABS ; Move the cursor. ; Position for totals field STCR65: MOV R4,R5 ; Get correct line MOV #65.,R2 ; And column 65 PJMP CURABS ; Position .SBTTL Generic commands -- C$BYE ;++ ; This command will instruct KERFIL to send the LOGOUT generic command, ; followed by an instruction to KERFIL to exit and will cause KERMIT to exit ; to P/OS. ;-- C$BYE:: JSR PC,CHKACT ; Is the other end running? JSR PC,C$LOGO ; Send it to KERFIL JSR PC,EXFIL ; Tell KERFIL to go away JMP EXIT ; Leave KERMIT .SBTTL Generic commands -- C$FINI - Finish command ;++ ; This command will instruct KERFIL to send the generic EXIT command to the ; remote KERMIT. This will then return to the upper level. ;-- C$FINI::JSR PC,CHKACT ; Is the other end running? JSR PC,CLRGEN ; Clear the generic arguments MOV #GC.EXIT,GENCMD ; Store the generic command MOV #$TKGEN,R0 ; Send a generic command to the other ; task PJMP SNDPKT ; Send the data and assume it worked .SBTTL Generic commands -- C$LOGO - Logout command ;++ ; This command will instruct KERFIL to send the generic LOGOUT command to the ; remote KERMIT. This will then wait until the remote finishes processing the ; command before returning to the upper level. ;-- C$LOGO::JSR PC,CHKACT ; Is the other end running? JSR PC,CLRGEN ; Clear the generic arguments MOV #GC.LOGOUT,GENCMD ; Store the generic command MOV #$TKGEN,R0 ; Get the function to send PJMP SNDPKT ; Go send command wait until finished .SBTTL C$SERV - Enter server mode ;++ ; This routine will insturct the KERFIL task to enter server mode. It will ; then wait until the remote is finished. ;-- C$SERV::JSR PC,CHKACT ; Is the other end running? MOV #$TKSRV,R0 ; Get the function PJMP SNDPKT ; Send the function to the remote .SBTTL STAFIL - Start KERFIL ;++ ; This routine will start the KERFIL task. It will return only if it was ; able to start KERFIL. ; ; Usage: ; JSR PC,STAFIL ; (Return) ; ; On return: ; Carry set if active ; Carry clear if not active ;-- .PSECT $CODE$, RO, I STAFIL: RQST$C KERFIL,,,,,$CODE$ ; Request task KERFIL to be started CMP @#$DSW,#IS.SUC ; If successful then go on BEQ 20$ ; CMP @#$DSW,#IE.ACT ; If already active then go on BEQ 10$ ; Branch if the task is not active ; ; Here if there was some type of error starting the task up ; MOV @#$DSW,STATUS ; Save the status CLR STAT1 ; Clear the extra status word JMP RQSERR ; Jump to the fatal error routine ; ; Here if KERFIL was started ok ; 20$: CLC ; Clear the carry RTS PC ; Return to the caller ; ; Here if KERFIL was already active ; 10$: SEC ; Set the carry RTS PC ; Return to the caller .SBTTL EXFIL - Cause KERFIL to exit ;++ ; This routine will cause KERFIL to exit to P/OS. This routine is called from ; various levels. ;-- EXFIL:: BIT #TRUE,RUN ; Is the RUN bit up? BEQ 10$ ; Branch if it is idle RTS PC ; Otherwise just return 10$: MOV #$TKXIT,R0 ; Get the exit function PJMP IT$SDA ; Just send the data and go away .SBTTL C$RECV - Send the RECEIVE command to the remote ;++ ; This routine will send the RECEIVE command to the KERFIL task. ; The routine will wait until KERFIL acks the information sent to it. ;-- C$RECV::JSR PC,CHKACT ; Is KERFIL running currently? CLR RCVBUF ; Flag no file MOV #$TKRCV,R0 ; Get the function PJMP SNDPKT ; Send the function and wait for reply .SBTTL C$SEND - Send file(s) to the remote Kermit ;++ ; Send command processing. This routine will determine the number of files ; that we have to send to the remote and then send the data to KERXFR to send ; the information. Note the file specifications are read directly into the ; common. ; ; Usage: ; JSR PC,C$SEND ; (Return) ; ;-- C$SEND::JSR PC,CHKACT ; Is KERFIL active still? 5$: MOV #20.,NOCHOS ; Reset the number of possible choices. MOV #SENFIL,R5 ; Set up call to Oldfile sys. routine. CALL OLDFIL ; Call the system routine. CMP STATUS,#ST.KEY ; See if a function key was pressed. BNE 10$ ; If not a function key then branch. CMP STAT1,#KY.MAI ; See if it was the Main Screen key. BEQ 99$ ; Exit if it was CMP STAT1,#KY.EXI ; See if it was the Exit key. BEQ 99$ ; Exit if it was BLSCAL TT.CHAR,#.CHBEL ; Output a bell BLSCAL TT.OUTPUT ; Output any remaining characters BR 5$ ; Jump back and try again 10$: MOV #$TKSND,R0 ; Get the function to send to KERFIL JSR PC,SNDPKT ; Send the information and wait for OK ; ; Now to return to the command processing. We must first reinitialize the ; frame files that are open. ; 99$: PJMP INICMD ; Initialize the command processing .SBTTL C$GET - Get a file(s) from the remote Kermit ;++ ; This routine will implement the GET command. It will input the file ; specifications from the user and then call KERFIL to do the work. ; ; Usage: ; JSR PC,C$GET ; (Return) ; ; On return: ; - Command completed, or ; - User requested return to KERMIT ;-- C$GET:: JSR PC,CHKACT ; Is KERFIL active still? BLSCAL INPUT,<#TRUE,#I$HDR,#HDR$L,#GETTXT,#FILPMT> TST R0 ; Get a file specification? BEQ 10$ ; Yes, get the files RTS PC ; Return to the caller 10$: MOV #$TKRCV,R0 ; Get the function PJMP SNDPKT ; Wait until the other end responds .SBTTL INPUT - Input a line of text from the user ;++ ; This routine will paint a box and then prompt the user for a single ; line of input. The input is left in RCVBUF and the length is left ; in ????. ; ; Usage: ; ; BLSCAL INPUT,Flag,Header,Header.lenght,Text,Prompt ; ; Flag - True/False to determine if a null field is allowed. ; Header - Address of the header text. ; Header.length - Number of bytes in the header ; Text - A single line of text to output ; Prompt - Prompt for the user ; ;-- .PSECT $CODE$, RO, I BLSRTN INPUT,5, JSR PC,SETESC ; Allow escape sequences MOV HEADER+2(SP),R0 ; Get the header address MOV HDRLEN+2(SP),R1 ; And the length BLSCAL PAINT,,+ ; Put box around prompt. BLSCAL TT.TEXT,#INPHDR,+ ; Output the header BLSCAL TT.TEXT,2+..STKO+TEXT(SP),+ ; Output the other text BLSCAL TT.OUTPUT,,- ; Output any remaining characters MOV #M$PMT1,R0 ; Build the prompt MOV PROMPT+2(SP),R1 ; Put address of prompt into R1. JSR PC,BLDPMT ; Build it ; ; This will now call the routine to read the text from the user's terminal ; MOV FLAG+2(SP),R0 ; Get the flag JSR PC,DOINP ; Get the input TST R0 ; Normal return ? BNE 99$ ; No, EXIT of MAIN SCREEN pressed. MOV IOSTAT+2,GEN.1S ; Move the length CMP #MAX.MSG,IOSTAT+2 ; Make sure this is small enough BGE 10$ ; Too big, skip this MOV #MAX.MSG,GEN.1S ; Move the size 10$: BLSCAL BL$MOV, ; Move the text CLR R0 ; Return a zero to top level 99$: RTS PC ; Return to caller. .SBTTL INPUT2 - Input two lines of text ;++ ; This routine will input two lines of text from the user. The text will ; be stored in the generic command argument blocks along with the length. ; ; Usage: ; ; BLSCAL INPUT,Flag,Header,Header.lenght,Text,Prompt,Prompt2 ; ; Flag - True/False to determine if a null field is allowed. ; Header - Address of the header text. ; Header.length - Number of bytes in the header ; Text - A single line of text to output ; Prompt - Prompt for the user ; Prompt2 - Second prompt for the user ; ;-- .PSECT $CODE$, RO, I BLSRTN INPUT2,5, JSR PC,SETESC ; Allow escape sequences MOV HEADER+2(SP),R0 ; Get the header address MOV HDRLEN+2(SP),R1 ; And the length BLSCAL PAINT,,+ ; Put box around prompt. BLSCAL TT.TEXT,#INPHDR,+ ; Output the header BLSCAL TT.TEXT,2+..STKO+TEXT(SP),+ ; Output the other text BLSCAL TT.OUTPUT,,- ; Output any remaining characters MOV #M$PMT1,R0 ; Get the address of the position string MOV PROMPT+2(SP),R1 ; Put address of first prompt in R1 JSR PC,BLDPMT ; Build the prompt MOV FLAG+2(SP),R0 ; Get the flag JSR PC,DOINP ; Get the input TST R0 ; Continue with routine ? BNE 99$ ; No, return to user. ; ; Here if we got something from the user ; MOV IOSTAT+2,GEN.1S ; Move the length CMP #MAX.MSG,IOSTAT+2 ; Make sure this is small enough BGE 10$ ; Too big, skip this MOV #MAX.MSG,GEN.1S ; Move the size 10$: BLSCAL BL$MOV,,+ ; Move the text BLSCAL TT.OUTPUT,,- ; Force it out MOV #M$PMT2,R0 ; Get the position string MOV PRMPT2+2(SP),R1 ; Get address of second prompt. JSR PC,BLDPMT ; Build the prompt string MOV FLAG+2(SP),R0 ; Get the flags again ASR R0 ; Shift so we just get the other one JSR PC,DOINP ; Get the other string TST R0 ; Stay with routine ? BNE 99$ ; No, return to user. ; ; Here if we got the second argument ; MOV IOSTAT+2,GEN.2S ; Move the length CMP #MAX.MSG,IOSTAT+2 ; Make sure this is small enough BGE 20$ ; Too big, skip this MOV #MAX.MSG,GEN.2S ; Move the size 20$: BLSCAL BL$MOV, ; Move the text CLR R0 ; Clear so we do the right thing 99$: RTS PC ; Return to the caller .SBTTL BLDPMT - Build the prompt string ;++ ; This routine will build the prompt string. ; ; Usage: ; MOV Pos.text.addr,R0 ; MOV Prompt.text.addr,R1 ; JSR PC,BLDPMT ; (Return) ; ; On return: ; R1 - Address of the prompt ; R2 - Length of the text ;-- .PSECT $CODE$, RO, I BLDPMT: MOV #BUFF1,R2 ; Address to store it 10$: MOVB (R0)+,(R2)+ ; Store a byte BNE 10$ ; Loop until finished ; ; Here if the prompt is copied ; TSTB -(R2) ; Back up the poniter 20$: MOVB (R1)+,(R2)+ ; Store the next byte BNE 20$ ; Loop for all of these too SUB #BUFF1+1,R2 ; Calculate the number of bytes MOV #BUFF1,R1 ; Point to the buffer RTS PC ; Return to the caller .SBTTL DOINP - Read a line of text from the user ;++ ; This routine will read a line of text from the user's terminal. ; ; Usage: ; MOV Flag,R0 - Save the flag ; MOV PROMPT.ADDRESS,R1 - Address of prompt into R1 ; MOV PROMPT.LENGTH,R2 - Length of prompt into R2 ; JSR PC,DOINP ; (Return) ; ;-- .PSECT $CODE$, RO, I DOINP:: QIOW$S #IO.RPR!TF.BIN,#TERLUN,#TTREFN,,#IOSTAT,,<#RCVBUF,#100.,,R1,R2> TST R0 ; Is no input valid ? BEQ 20$ ; Yes, branch. TST IOSTAT+2 ; Did we get any characters ? BNE 20$ ; Yes, branch. BLSCAL TT.TEXT,#NOINP ; Queue up the error message. BLSCAL TT.OUTPUT ; Output it. BR DOINP ; Try again. ; ; Here if we got an input file name. ; 20$: MOV R0,-(SP) ; Save the flag value. JSR PC,CHKEXT ; Check what we got. CMP #1,R0 ; Was it a bad function key ? BNE 30$ ; No, continue. MOV (SP)+,R0 ; Resore the flag value. BR DOINP ; Try again. ; ; If here then we got a good input file name. ; 30$: MOV IOSTA1,R1 ; Get the number of characters input CLRB RCVBUF(R1) ; Clear the last byte TST (SP)+ ; Remove the item from the stack RTS PC ; Return to caller. .SBTTL Exit Check for Rcvfile CHKEXT: CLR R0 ; Give a good return MOV IOSTAT+2,R2 ; Get the count of characters BEQ 99$ ; Just return if nothing MOV #RCVBUF,R1 ; Put address of input buffer into R1. 10$: CMPB #.CHESC,(R1)+ ; Is the character an "ESCAPE" ? BEQ 20$ ; Yes, branch. SOB R2,10$ ; Decrement the character count RTS PC ; Just return if no escape ; ; Here if we have an ; 20$: DEC R2 ; Decrement the count of characters BLT 99$ ; Branch if no more characters CMPB #'[,(R1)+ ; Was the next character a "[" ? BNE 105$ ; No, branch. DEC R2 ; Decrement the count of characters BLT 99$ ; Branch if no more characters CMPB #'2,(R1)+ ; Was the next a "2" ? BNE 105$ ; No, branch. CMPB #'0,(R1) ; Was the next a "0" ? ( MAIN SCREEN ) BEQ 90$ ; Yes, branch. DEC R2 ; Decrement the count of characters BLT 99$ ; Branch if no more characters CMPB #'1,(R1)+ ; Or was that one a "1" ? ( EXIT ) BNE 105$ ; Neither then branch. 90$: MOV #2,R0 ; Set up an EXIT return. 99$: RTS PC ; Return to caller. 105$: BLSCAL TT.TEXT,#WRONGKEY ; Output the text BLSCAL TT.OUTPUT ; Output any remaining characters MOV #1,R0 ; Set up a WRONG FUNCTION KEY return. RTS PC ; Return to the caller .SBTTL SETESC - Allow escape sequences on this command ;++ ; This will allow escape sequences on the following QIOs. ; ; Usage: ; JSR PC,SETESC ; (Call back) ; ; On return: ; This routine is stack to return to, so we can disallow escape ; escape sequences. ;-- .PSECT $PLIT$, RO, D IOLOC: .BYTE TC.ESQ,1 ; Recognize escape sequences .PSECT $CODE$, RO, I .GLOBL SETESC SETESC:: QIOW$C SF.SMC,TERLUN,5,,IOSTAT,,,$CODE$ QIOW$C IO.ATT!TF.ESQ,TERLUN,TTAEFN,,IOSTAT,,,$CODE$ JSR PC,@(SP)+ ; Call the caller back QIOW$C IO.DET,TERLUN,TTAEFN,,IOSTAT,,,$CODE$ RTS PC ; Return to the caller .SBTTL Convert from ascii to binary ;++ ; INPUT: R2 Address of buffer with ascii ; R5 Original base of number ; ; OUTPUT: R1 Contains binary value ; ; REGISTERS used: R0, R1, R2, R5 ; R0 Temporary value location (destroyed) ; R1 (value returned) ; R2 (destroyed) ; R5 (preserved) ; ASCBIN::CLR R1 ; Clear out result location 10$: MOVB (R2)+,R0 ; Get first digit BEQ 99$ ; Check for end SUB #'0,R0 ; Get binary value of digit CLC ; Clear the carry for the mult. MUL R5,R1 ; Shift the rest of the answer over ; one place (multiply by base) ADD R0,R1 ; Add in last digit BR 10$ ; Loop for all digits 99$: RTS PC ; Return to sender ; ; This routine checks to see if input values are legal for the base specified ; ; INPUT: R2 Address of buffer with ascii ; R5 Original base of number ; ; OUTPUT: Carry set if bad character was found. ; ; REGISTERS used: R0, R2, R5 ; R0 temporary value holder (destroyed) ; R2 (destroyed) ; R5 (preserved) ; BASCHK:: MOVB (R2)+,R0 ; Get first digit CLC ; Clear carry BEQ 99$ ; Check for end SUB #'0,R0 ; Convert to binary digit BMI 90$ ; If less then ascii zero then bad SUB R5,R0 ; Subtract base value BPL 90$ ; If greater than or equal to the ; ascii of base then bad BR BASCHK ; Loop for the rest 90$: SEC ; Set carry since bad character found 99$: RTS PC ; Return to sender .SBTTL SNDPKT - Send the function to KERFIL and wait until it finishes ;++ ; This routine will send a function to the KERFIL task and then wait until ; it completes the operation that we requested. ; ; Usage: ; R0 - Function to send ; JSR PC,SNDPKT ; (Return) ; ; On return: ; Function completed, KERFIL still active, or KERFIL dead ;-- .PSECT $CODE$, RO, I .GLOBL SNDPKT SNDPKT: JSR PC,IT$SND ; Send the information to the other end ; ; Now wait until we get the response from the other end. ; WTSE$S #ITCEFN ; Wait until we are told to go again CLEF$S #ITCEFN ; Clear the event flag JSR PC,IT$RDA ; Get the data ; RTS PC ; Return to sender .SBTTL Error routines ; ; Error routine for the ReQueSt task directive (starts KERFIL) ; ; INPUT: None ; ; OUTPUT: The request task error message is displayed and a fatal error ; is given. Control returns to P/OS Main menu RQSERR: MOV #ERRRQS,ADRERR ; Get the error message to be printed MOV #8.,BASE ; Set up for octal conversion JMP ERROR ; call the main error routine .SBTTL Generic command processing - CLRGEN - Clear generic arguments ; This routine will clear the generic command arguments so that KERMSG ;will not think there is something there. ; ; Usage: ; JSR PC,CLRGEN ; (return here, all registers intact) ; CLRGEN::CLR GEN.1SIZE ; No first argument CLRB GEN.1DATA ; In case someone thinks its ASCIZ CLR GEN.2SIZE ; No second argument CLRB GEN.2DATA ; In case someone thinks its ASCIZ CLR GEN.3SIZE ; No third argument CLRB GEN.3DATA ; In case someone thinks its ASCIZ RTS PC .SBTTL DEFINI - Initlialize the default file processing ;++ ; This routine will determine if the default file contains the ; default parameters for the XK port. It will then read them into the ; common area if they are in the file. If they are not it will read ; the current parameters into the default area. ;-- XK.IDX== "XK ; Index to XK parameters .PSECT $CODE$, RO DEFINI: JSR PC,DF.INI ; Initialize the default file MOV #XK.IDX,R0 ; Get the record to read JSR PC,DF.RD ; Read the record TST R1 ; Did we read anything? BGT 10$ ; Yes, skip this ; Here if there were no parameters in the file, so just use what ; the port is currently set at as the parameters and some other things ; that we must default. JSR PC,XK.INT ; Initialize the XK port BLSCAL BL$MOV,<#CURXKL,#ORGXKP,#CURXKP> ; Move the parameters ; ; Now make some parameters consistant ; MOV #TC.PAR,R0 ; Get the parity setting MOV #CURXKP,R1 ; From this block JSR PC,FNDXKP ; Find the parameter TST R0 ; Find it? BEQ 4$ ; No, skip this (should be there) CLRB @R0 ; Clear to turn off parity ; ; Here to set the data character size ; 4$: MOV #TC.FSZ,R0 ; Get the data size JSR PC,FNDXKP ; Find the parameter TST R0 ; Did we find it? BEQ 6$ ; Branch if not MOVB #8.,@R0 ; Set to 8 bit characters ; ; Now write the defaults ; 6$: MOV #XK.IDX,R0 ; Index for the file MOV #CURXKP,R1 ; Address of the parameters MOV #CURXKL,R2 ; Length of the block JSR PC,DF.WT ; Write the parameters ; ; Now to shut down the port, since we don't need it ; JSR PC,XK.SHT ; Shut down the XK again BR 30$ ; Copy over to the default area ; Here if we have parameters in the default file for the XK port. ; Just copy the parameters to the correct area, so we can use them ; later. 10$: CMP #CURXKL,R1 ; Have enough area? BEQ 20$ ; Long enough area MOV #CURXKL,R1 ; No, use this length 20$: BLSCAL BL$MOV, ; Move the parameters ; ; Now copy the parameters to the default area ; 30$: BLSCAL BL$MOV,<#CURXKL,#CURXKP,#DEFXKP> ; ; Close the parameter file now. ; JSR PC,DF.FIN ; Finished with this for now RTS PC ; Return to the caller .SBTTL End of KERMIT .END FROG ; That's all folks! (Ribbit)