/ K08V2.PA PDP-8 KERMIT VER 2.0 1-OCT-87 / / COPYRIGHT (C) TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK 1987 / PERMISSION IS GRANTED TO ANY INDIVIDUAL OR INSTITUTION TO COPY OR USE THIS / DOCUMENT AND THE PROGRAMS DESCRIBED IN IT, EXCEPT FOR EXPLICITY COMMERCIAL / PURPOSES. / 013 1-OCT-87 VERSION 2.0 R.SCHLERF LEDERLE LABS (914)732-2186 / CHANGED RKIOT/RTIOT TO 43/44 (REMOTE LINE IOT) {LOCAL PREFERENCE} / CHANGED 'ESCAPE' CHAR TO ^] (CHG CONX1) FOR {GENERIC KERMIT CONFORMITY} / ADDED VERSION / COMMAND BANNER AT STARTUP {FOR MINI-HELP} / INCORPORATED K278 PATCHES /003 /004 /005 /006 /009 /010 (NO INTERRUPTS) / DELETED 'ERRMSG'. CLOOP9+2 NOW POINTS TO 'STXERR' {FOR PROGRAM SPACE} / REPLACED 'BACK ON PDP8' MESSAGE WITH BEEP{FOR GENERIC KERMIT CONFORMITY} / DELETED 'SENDING FILE XXXXXX.XX CREATED ON DD-MMM-YY' NOW IT JUST SAYS / 'SENDING FILE XXXXXX.XX' {FOR GENERIC KERMIT COMFORMITY} / MAKE THIS KERMIT IGNORE ASCII BIT 8(IGNORE PARITY) ON BOTH REMOTE AND / TTY INPUT LINES. PARITY IS SET TO SPACE ON OUTPUT LINES / / REORG. K08V2.PA TO GET ENOUGH SPACE FOR ABOVE (MOVED CODE INTO HOLES) / REMOTE AND TTY BOARDS MUST BE AT THE SAME BAUD RATE.(WORKS TO 9600 BAUD) / ON KL8-JA ALL SOLDER JUMPERS OUT (STD. DEC CONFIG.),SWITCH 'R=' OFF / WRITTEN ON PDP-8E WITH RX-01'S, 2 KL8-JA BOARDS,BUT NO REAL-TIME CLOCK. / UNDER OS-8 VERSION KBM V3Q - CCL V1F / K08V2 WORKS WITH VAX-8650,DUAL DEC-1090(SMP) AND VAXMATE (PC/AT CLONE) / TESTED USING THE FOLLOWING SET UP INFORMATION: / VAX (KERMIT-32 V3.2.075,VMS V 4.5) SETUP= 'SET TERM/DEVICE_TYPE=VT102' / VAX TERMINAL PARITY SHOULD BE 'NONE'. / DEC-10 (K10MIT V2(124),TOPS-10 V7.02) SETUP= 'SET TTY VT102' / DEC-10 TERMINAL PARITY SHOULD BE 'NONE'. / VAXMATE (PC-500) USING MS-KERMIT VER 2.29 (8 BITS PARITY NONE ) / K08V2.PA IS VERY 'BARE-BONES'! THERE ARE NO FRILLS,NO TERMINAL EMULATION / NO BINARY FILE TRANSFER,NO FILE-ATTRIBUTE TRANSMISSION,NO PARITY SELECT. / THERE IS CONTROL-CHARACTER AND DEL QUOTING, BUT NO 8TH BIT QUOTING. / THERE IS FILE-NAME WILDCARDING,AND SUPPORT FOR OTHER THAN THE SYS:DEVICE / IT'S NOT VERY FLASHY, BUT, YOU CAN GET THERE FROM HERE !! / TO MAKE K08V2.PA MORE READABLE REPLACE (ABOUT 1750) /~ WITH /~ / THE /~ MAKES THE FILE EASIER TO HANDLE (SMALLER) ON RX-01'S / THE 'RECEIVE' COMMAND DOES NOT WORK IN /013K. MUST FIX THAT SOME TIME ! / 010 13-MAR-86 Mart (K278.PA)/DISK FULL STUFF / 009 13-MAR-86 Mart+SSta (K278.PA)/BRK AND GET BUGFIX / 006 10-MAR-86 Mart+SSta (K278.PA)/PARSE DEVICE FROM GET / 005 10-MAR-86 Mart+SSta (K278.PA)/TAKE DATE OUT OF FILE / 004 10-MAR-86 Mart+SSta (K278.PA)/FIX MAX BUF ON RECEIVE / 003 10-MAR-86 SSta (K278.PA)/ALLOW 2 PG HANDLER / 30-JUL-84 JERRY SANDS (K08MIT.PA) AUTHOR / 18-JUL-85 RANDY HIPPE (K08MIT.PA) AUTHOR / PROGRAM TO DO FILE TRANSFERS USING THE "KERMIT" PROTOCOL / / IMPLEMENTS THE FOLLOWING COMMANDS: / / 1. CONNECT {CONNECT TO REMOTE COMPUTER} / 2. BYE {STOP REMOTE KERMIT, BUT DON'T LOG OUT} / 3. EXIT {RETURN TO OS-8,BUT DON'T TELL REMOTE ANYTHING} / 4. SEND {SEND A FILE TO REMOTE KERMIT SERVER} / 5. GET {GET A FILE FROM A REMOTE KERMIT SERVER} / / SUPPORTS WILDCARDING FOR "SEND" AND "GET" I.E SEND *.TX OR GET *.TXT. / DEFINITIONS TKSF= 6031/~CONSOLE KEYBOARD FLAG TKRB= 6036/~CONSOLE KEYBOARD BUFFER TTSF= 6041/~CONSOLE TELEPRINTER FLAG TTLS= 6046/~CONSOLE TELEPRINTER BUFFER / CHANGE THE FOLLOWING TWO DEFINITIONS AND REASSEMBLE / RKIOT= 43/~DEFINE REMOTE RECEIVE IOT /m013 RTIOT= 44/~DEFINE REMOTE TRANSMIT IOT /m013 / RKSF= RKIOT^10+6001/~DEFINE REMOTE INPUT IOT RKRB= RKIOT^10+6006/~ RTSF= RTIOT^10+6001/~DEFINE REMOTE OUTPUT IOT RTLS= RTIOT^10+6006/~ SOH= 1/~START OF PACKET CHAR CONX1= 0035/~DEFINE FIRST "CONNECT" EXIT CHAR "^]" /m013H CONX2= 0103/~DEFINE SECOND "CONNECT" EXIT CHAR "C" /m013H CR= 215 SPACE= 240 DELETE= 377 LINSIZ= 40/~KEYBOARD LINE BUFFER SIZE / STATE DEFINITIONS STDAT= "D&137/~DATA STACK= "Y&137/~ACK STNAK= "N&137/~NAK STSIN= "S&137/~SEND INIT STBRK= "B&137/~BREAK LINK STFIL= "F&137/~FILENAME HEADER STEOF= "Z&137/~END OF FILE OR REPLY STERR= "E&137/~ERROR PACKET STATT= "A&137/~FILE ATTRIBUTES STRIN= "R&137/~RECEIVE INIT STEOT= "B&137/~BREAK TRANSMISSION STGEN= "G&137/~KERMIT GENERIC COMMAND DEFCK= "1&177/~DEFAULT 1 CHAR CHECKSUM DEFEOL= 15+40/~CR IS DEFAULT EOL DEFQCTL= "#&177/~"#" IS DEFAULT QCTL DECIMAL DEFMAXL= 94/~DEFAULT MAX SIZE OCTAL / PAGE ZERO REGISTERS / AUTO INDEX *10 X10, 0/~GENERAL AUTO INDEX 10 X11, 0/~GENERAL AUTO INDEX 11 X12, 0/~GENERAL AUTO INDEX 12 X13, 0/~GENERAL AUTO INDEX 13 X14, 0/~GENERAL AUTO INDEX 14 X15, 0/~GENERAL AUTO INDEX 15 X16, 0/~GENERAL AUTO INDEX 16 X17, 0/~GENERAL AUTO INDEX 17 / REGULAR PAGE ZERO REGISTERS TEMP, 0 RCHAR, 0/~REMOTE LINE CURRENT INPUT CHAR TCHAR, 0/~TERMINAL LINE CURRENT INPUT CHAR SCAN1, 0/~ SCAN2, 0/~ KEYDSP, 0/~DISPATCH ADDRESS FOR KEYWORD MATCH BININP, 0/~BINARY REGISTER FOR DECIMAL INPUT PTABLE, 0/~ LPTR, 0/~HOLDS LINE POINTER CONFLG, 0/~FLAG FOR EXIT CONNECT STATE, 0/~CURRENT STATE RETRY, -10/~NUMBER OF RE-TRYS RTRYC, 0/~USE THIS FOR ACTUAL COUNTER CCFLAG, 0/~FLAG FOR ^C TYPED / CURRENT PACKET I-O DATA PAKPTR, 0/~POINTER TO OUTPUT PACKET POINTER PAKCKS, 0/~HOLDS CURRENT OUTPUT PACKET CHECKSUM TOTAL CURSEQ, 0/~CURRENT SEQ NUMBER QFLAG, 0/~NON-ZERO WHEN NO CONTROL QUOTING / KERMIT MODE FLAG MLINE= 1/~KERMIT IS ON-LINE MSEND= 2/~KERMIT IS IN SEND MODE MREC= 3/~KERMIT IS IN RECEIVE MODE KMODE, 0/~CURRENT MODE OF KERMIT / RECEIVE "INIT" REGISTERS RMAXL, DEFMAXL+40/~MAX LENGTH FOR DATA PACKET (DEFAULT) RTIME, 0/~TIME-OUT VALUE RNPAD, 0/~NUMBER OF PADDING CHARS RPADC, 0/~CHAR USED FOR PADDING REOL, DEFEOL/~TERMINATOR CHAR USED FOR END OF PACKET RQCTL, DEFQCTL/~CONTROL CHAR PREFIX CHAR RQBIN, 0/~PARITY CHAR PREFIX CHAR (CHARS GT 177) RCHKT, DEFCK/~CHECKSUM TYPE (DEFAULT TYPE 1) RREPT, 0/~PREFIX CHAR FOR REPEATED CHARS RCAPAS, 0/~EXTRA CAPABILITY BIT MASK USR, 7700/~POINTER TO USER SERVICE ROUTINES HNDADR, 0/~FILE DEVICE HANDLER ADDRESS FORCEP, 0/~FLAG FOR FORCED OUTPUT OF PACKET WHEN THERE IS /~ NO DATA (JUST SOH, LEN, SEQ, AND CHECKSUM) PRSERR, 0/~HOLDS PARSE POSITION FOR REPORTING ERRORS PACK6P, 0/~POINTER TO STORAGE OF 6 BIT CHARS PACK6F, 0/~FLAG FOR WHICH BYTE TO STORE GET6P, 0/~POINTER USED IN THE GET6 ROUTINE GET6F, 0/~FLAG USED IN THE GET6 ROUTINE MOVE4, 0/~COUNTER FOR "MOVE" INIFLG, 0/~INIT DONE FLAG / FILE NAME PARSE REGISTERS FNPTR, 0/~POINTER TO WHERE TO PUT A PARSED FILE NAME WILDF, 0/~WILD CARD IN FILE NAME FLAG / FILE INFORMATION FSBLK, 0/~FILE START BLOCK FLEN, 0/~FILE LENGTH DEVNUM, 0/~PARSED DEVICE NUMBER HERE OFFLG, 0/~OUTPUT FILE OPEN FLAG ODNAME, 0/~POINTER TO USER SPECIFIED DEVICE FOR OUTPUT ODNUMB, 0/~OUTPUT DEVICE NUMBER DIRBLK, 0/~CURRENT DIRECTORY BLOCK IN CORE DWORD, 0/~POINTER TO NEXT ENTRY TO TRY DPTR, 0/~POINTER TO FILE ENTRYS / OFTEN USED CONSTANTS C77, 0077 C177, 0177 C377, 0377 C7400, 7400 MARK, 0200/a013H SET ASCII BIT 8 FOR COMMAND INPUTS MCTRLZ, -232 PARITY, 0000/a013/m013H PARITY MASK(0200=MARK PARITY 0000=SPACE PARITY) UPTEMP, 0/~TEMP FOR OS/8 UNPACK ROUTINE / POINTER FOR THE PACKET INPUT AND OUTPUT ROUTINES SPACK= JMS I ./~SEND A PACKET TO REMOTE SPACK0/~PUT IN A POINTER FPACK= JMS I ./~FORMAT PACKET FPACK0/~PUT IN THE POINTER RPACK= JMS I ./~RECEIVE A PACKET FROM REMOTE ILINK/~PUT IN A POINTER / POINTERS FOR OUTPUT ROUTINES TTYOUT= JMS I ./~PRINT ONE CHAR ON TTY OTTY PRI8B= JMS I ./~PRINT 8 BIT STRING ON TTY PRI8B0/~PUT IN THE POINTER PRI6B= JMS I ./~PRINT 6 BIT STRING ON TTY PRI6B0/~PUT IN THE POINTER REMOUT= JMS I ./~SEND ONE CHAR DOWN REMOTE LINE OREM/~PUT IN THE POINTER REM8B= JMS I ./~SEND 8 BIT STRING DOWN REMOTE LINE REM8B0/~PUT IN THE POINTER REM6B= JMS I ./~SEND 6 BIT STRING DOWN REMOTE LINE REM6B0/~PUT IN THE POINTER / MISC. RTDISP= JMS I ./~ROUTINE TO DISPATCH BASED ON "RRTYP" DISPA0/~POINTER TO ROUTINE PACK6= JMS I ./~DEFINE CALL TO ROUTINE PACK60/~POINTER TO ROUTINE SCANC= JMS I ./~SCAN FOR CHAR COMMAND SCANC0/~PUT IN THE POINTER GET6= JMS I ./~DEFINE THE INSTRUCTION GET60/~PUT IN THE POINTER MOVE= JMS I ./~DEFINE CALL TO MOVE ROUTINE MOVE0/~POINTER CLEAR= JMS I ./~DEFINE CALL FOR "CLEAR" ROUTINE CLEAR0/~POINTER BEEP, TEXT "@G@" CRLF, TEXT "@M@J@" RUBOUT, TEXT "@H @H@" /BEGINNING OF PROGRAM *200 START, CLA CLL TTLS/~INIT PRINTER OUTPUT LINE RTLS/~INIT REMOTE OUTPUT LINE BANNER, PRI6B; BANTXT /DISPLAY VERSION BANNER PRI6B; CRLF /PRINT A BLANK LINE HELPTX, PRI6B; HLPMSG /DISPLAY THE COMMANDS PRI6B; CRLF /PRINT A BLANK LINE BSTXT, PRI6B; BS /DISPLAY BS PRI6B; CRLF /PRINT A BLANK LINE CLOOP, CLA CLL DCA CCFLAG/~CLEAR THE ^C FLAG DCA KMODE/~CLEAR THE MODE FLAG PRI6B; PROMPT/~DISPLAY THE USER PROMPT JMS LININP/~GET INPUT LINE FROM USER TAD (TMPTBL/~GET ADDRESS OF PARSE TABLE DCA PTABLE/~STORE FOR PARSER TAD (LINBUF/~GET ADDRESS OF INPUT LINE BUFFER CLOOP1, JMS KEYPRS/~PARSE OFF A KEYWORD JMP CLOOP9/~NO MATCH ON KEYWORD JMP CLOOP/~END OF LINE DETECTED DCA LPTR/~STORE POINTER TO NEXT POS ON LINE JMS I KEYDSP/~DISPATCH TO SERVICE JMP CLOOP7/~ERROR RETURN FROM SERVICE DISPATCH TAD LPTR/~RE-GET COMMAND LINE POINTER JMP CLOOP1/~CONTINUE LINE PARSE CLOOP7, SZA/~SKIP IF NO RETURNING MESSAGE PRI6B/~DISPLAY DISPATCH ERROR MSG JMP CLOOP/~BACK TO COMMAND LOOP CLOOP9, CLA CLL PRI6B; STXERR /~DISPLAY COMMAND SYNTAX ERROR MESSAGE JMP CLOOP/~GO AGAIN / COMMAND TABLE LOOKUP / ROUTINE TO LOOK THRU A TABLE OF SINGLE CHAR COMMANDS FOR A MATCH / AND RETURN THE DISPATCH ADDRESS FOR A MATCH IN THE AC. IF NO MATCH / IS FOUND IN THE TABLE (THE TABLE ENDS WITH A COMMAND OF ZERO) A / RETURN + 2 IS TAKEN, ELSE A RETURN + 3 IS TAKEN. / ENTER: AC = COMMAND TO FIND / CALL + 2 = ADDRESS OF DISPATCH TABLE / EXIT: DISPATCH ADDRESS IN THE AC / RETURN + 3 SCANC0, 0 CIA/~NEGATE THE COMMAND DCA SCANC8/~STORE LOCALLY TAD I SCANC0/~GET ADDRESS OF DISPATCH TABLE ISZ SCANC0/~BUMP RETURN POINTER DCA SCANC9/~STORE POINTER LOCALLY SKP/~SKIP INTO LOOP BELOW SCANC1, ISZ SCANC9/~BUMP THE POINTER TAD I SCANC9/~GET A COMMAND FROM THE TABLE SNA/~SKIP IF NOT END OF TABLE JMP I SCANC0/~END OF TABLE, RETURN +2 FOR ERROR ISZ SCANC9/~BUMP POINTER TAD SCANC8/~COMPARE WITH COMMAND WE ARE LOOKING FOR SZA CLA/~SKIP IF IS A MATCH JMP SCANC1/~NO MATCH, TRY AGAIN TAD I SCANC9/~GET DISPATCH ADDRESS ISZ SCANC0/~BUMP RETURN FOR MATCH JMP I SCANC0/~AND RETURN IN AC SCANC8, 0/~LOCAL STORAGE FOR COMMAND TO LOOK FOR SCANC9, 0/~LOCAL POINTER FOR COMMAND TABLE / ROUTINE TO FORMAT A PACKET OF DATA / CALL: FPACK / DATA ADDRESS (DATA MUST ALREADY BE CONTROL/QUOTED AND MUST / NOT BE LONGER THAN THE LARGEST PACKET) / PACKET TYPE FPACK0, 0 CLA CLL/~INSURE CLEAR AC TAD I FPACK0/~GET THE DATA ADDRESS DCA FP1/~STORE IN SOURCE POINTER ISZ FPACK0/~BUMP ARGUMENT POINTER TAD I FPACK0/~NOW GET TYPE DCA RSTYP/~STORE ISZ FPACK0/~BUMP ARGUMENT POINTER TAD (RSDTA/~GET ADDRESS OF DATA BUFFER DCA FP2/~STORE IN DESTINATION POINTER TAD (40+3/~SET FOR LENGTH COUNTER DCA RSLEN/~STORE IN PACKET DCA FP3/~INIT CHECKSUM TAD CURSEQ/~GET CURRENT SEQ NUMBER AND C77/~MOD 64 TAD (40/~CHAR IT DCA RSSEQ/~PUT INTO PACKET FPACK2, TAD I FP1/~GET A CHAR FROM SOURCE SPA/~SKIP IF NOT END JMP FPACK3/~END TAD FP3/~COMBINE WITH CHECKSUM DCA FP3/~AND RETURN TAD I FP1/~GET CHAR BACK AGAIN DCA I FP2/~NOW PUT INTO DESTINATION ISZ RSLEN/~BUMP THE LENGTH ISZ FP1/~BUMP THE SOURCE POINTER ISZ FP2/~BUMP THE DESTINATION POINTER JMP FPACK2/~LOOP FPACK3, CLA CLL/~CLEAR THE AC TAD FP3/~GET CACULATED CHECKSUM TAD RSLEN/~INCLUDE THE LENGTH TAD RSSEQ/~AND THE SEQUENCE TAD RSTYP/~AND THE TYPE JMS CKSUM/~GET IT CORRECT DCA I FP2/~STORE WITH PACKET ISZ FP2/~BUMP PACKET POINTER TAD REOL/~GET ANY END OF LINE TO INCLUDE TAD (-40/~MAKE IT A REAL CHAR SNA/~SKIP IF EOL CHAR REQUIRED JMP FPACK4/~NO EOL CHAR DCA I FP2/~STORE EOL CHAR WITH PACKET ISZ FP2/~BUMP POINTER FPACK4, STA/~AC = -1 DCA I FP2/~PACKET NOW COMPLETE TAD RETRY/~SET UP RE-TRY COUNTER DCA RTRYC ISZ CURSEQ/~BUMP SEQUENCE NUMBER FOR NEXT TIME NOP/~PROTECT ISZ JMP I FPACK0/~RETURN FP1, 0/~POINTER TO SOURCE DATA FP2, 0/~POINTER TO PACKET BUFFER FP3, 0/~RUNNING CHECKSUM PAGE / ROUTINE TO SEND THE FORMATTED PACKET / ARGUMENTS: CALL + 1 NON-ZERO = AWAIT RESPONSE / ZERO = DO NOT AWAIT RESPONSE / CALL + 2 DISPATCH TABLE SPACK0, 0 REM8B; RSBUF/~SEND PACKET JUST COMPLETED TAD I SPACK0/~DO WE GET A RESPONSE? ISZ SPACK0/~BUMP POINTER PAST ARGUMENT SNA CLA/~SKIP IF YES JMP I SPACK0/~ALL DONE HERE RPACK/~GET PACKET BACK FROM REMOTE TAD I SPACK0/~DID WE WANT A DISPATCH? ISZ SPACK0/~BUMP PAST ARGUMENT SNA/~SKIP IF YES JMP I SPACK0/~EXIT IF NO RTDISP/~DISPATCH JMP I SPACK0/~NOT FOUND, GOTTA RETURN / ROUTINE TO CLEAR WORDS OF MEMORY / ENTER WITH: AC = MINUS NUMBER OF WORDS TO CLEAR / MQ = ADDRESS OF WHERE TO START THE CLEAR CLEAR0, 0 DCA CLEAR5/~STORE COUNT OF WORDS MQA/~GET ADDRESS OF CLEAR DCA CLEAR6/~STORE IN POINTER DCA I CLEAR6/~ZERO A WORD ISZ CLEAR6/~BUMP POINTER ISZ CLEAR5/~BUMP COUNTER JMP .-3/~LOOP JMP I CLEAR0/~DONE CLEAR5, 0/~TEMP FOR "CLEAR" ROUTINE CLEAR6, 0/~TEMP FOR "CLEAR" ROUTINE / ROUTINE TO DISPATCH TO ROUTINE BASED ON VALUE OF "RRTYP" / ADDRESS OF DISPATCH TABLE CAN BE IN THE AC OR AT CALL + 1. RETURN / IF NO MATCH FOUND, DISPATCH IF MATCH FOUND DISPA0, 0 SZA/~SKIP IF DISPATCH TABLE NOT IN AC JMP DISPA1/~USE VALUE IN AC TAD I DISPA0/~GET VALUE FROM CALL + 1 ISZ DISPA0/~BUMP RETURN PAST ARGUMENT DISPA1, DCA DISPA2/~STORE ADDRESS TAD RRTYP/~GET VALUE OF "RRTYP" SCANC/~FIND MATCH IN TABLE DISPA2, 0/~ADDRESS OF TABLE HERE JMP I DISPA0/~NOT FOUND IN TABLE, RETURN DCA DISPA2/~PUT DISPATCH ADDRESS INTO A POINTER JMP I DISPA2/~AND DISPATCH TO IT / ROUTINE TO PUT CHARS INTO A BUFFER TO GET READY TO FORMAT A PACKET. / ENTER WITH CHAR IN THE AC / IF THE CHAR NEEDS CONTROL QUOTING, IT WILL BE ADDED / EXIT + 2 IF EVERYTHING IS OK / EXIT + 1 IF BUFFER IS FULL OPBUF, 0 JMS OPRE/~CHECK FOR PREFIX JMP OPBUF1/~NO PREFIX DCA OP1/~SAVE CONVERTED CHAR TAD RQCTL/~GET QUOTE CHAR TO USE DCA I OP2/~PUT RETURNED PREFIX INTO BUFFER ISZ OP2/~BUMP POINTER TAD OP1/~GET BACK CONVERTED CHAR OPBUF1, DCA I OP2/~PUT INTO BUFFER ISZ OP2/~BUMP POINTER STA/~AC = -1 DCA I OP2/~ALWAYS TERMINATE BUFFER TAD RMAXL/~GET MAX BUFFER LENGTH TAD (-40+HOLDBF-4/~ CIA TAD OP2/~COMPARE WITH WHAT WE HAVE SPA CLA/~SKIP IF NO ROOM JMP OPBUF2/~HAVE ROOM JMS INIOPB/~RESET BUFFER JMP I OPBUF/~TAKE RETURN + 1 OPBUF2, ISZ OPBUF/~BUMP RETURN FOR BUFFER NOT FULL JMP I OPBUF/~DONE OP1, 0/~TEMP LOCATION OP2, HOLDBF/~POINTER FOR HOLD BUFFER / ROUTINE TO RE-SET THE HOLD BUFFER INIOPB, 0 TAD (HOLDBF/~RE-SET BUFFER POINTER DCA OP2 JMP I INIOPB / ROUTINE TO CACULATE A 1 BYTE CHECKSUM CKSUM, 0 DCA CKSUM1/~STORE TEMP TAD CKSUM1/~GET BACK BSW/~GET BITS 6-7 INTO BITS 0-1 AND (3/~KEEP ONLY BITS 0-1 TAD CKSUM1/~GET ORIGINAL AND C77/~KEEP ONLY BITS 0-5 TAD (40/~MAKE A CHAR(CHECKSUM) JMP I CKSUM/~DONE, RETURN IN AC CKSUM1, 0/~TEMP FOR "CKSUM" / ROUTINE TO CHECK FOR A CONTROL C / SET FLAG "CCFLAG" IF ^C IS TYPED CCCK, 0 CLA CLL/~INSURE CLEAR AC TAD KMODE/~GET KERMITS MODE TAD (-MLINE/~CHECK FOR ON-LINE SNA CLA/~SKIP IF NOT ON-LINE JMP CCCK2/~NO CTRL/C CHECK IF ON-LINE JMS ITTY/~CHECK FOR INPUT FROM CONSOLE SKP/~GOT SOMETHING FROM CONSOLE JMP CCCK2/~NO INPUT FROM CONSOLE AND C177/~CLEAR TOP BITS TAD (-3/~CHECK FOR CTRL/C SZA CLA/~SKIP IF CTRL/C JMP CCCK2/~^C NOT TYPED IAC DCA CCFLAG/~SET ^C FLAG CCCK2, JMP I CCCK/~RETURN PAGE / ROUTINE TO INPUT CHARS FROM REMOTE UNTIL A "SOH" CHAR IS FOUND GETSOH, 0 JMS IREMW/~GET A CHAR FROM REMOTE JMP I GETSOH/~TIME-OUT TAD (-SOH/~COMPARE WITH "SOH" SZA CLA/~SKIP IF SAME JMP GETSOH+1/~LOOP TILL WE GET ONE ISZ GETSOH/~BUMP FOR GOOD RETURN JMP I GETSOH/~GOT ONE, DONE / ROUTINE TO GET A CHAR FROM THE REMOTE LINE AND UPDATE CHECKSUM GETIR, 0 JMS IREMW/~GET A CHAR FROM REMOTE JMP I GETIR/~TIME-OUT RETURN DCA GETIR1/~STORE TEMP TAD GETIR1/~GET CHAR BACK TAD ILINK9/~ADD CHECKSUM DCA ILINK9/~RETURN UPDATED CHECKSUM TAD GETIR1/~RE-GET CURRENT INPUT CHAR TAD (-15/~CHECK FOR A RETURN SNA CLA/~SKIP IF NOT A RETURN JMP I GETIR/~WAS A RETURN, TAKE EXIT + 1 TAD GETIR1/~RE-GET CHAR FOR RETURN ISZ GETIR/~BUMP FOR GOOD RETURN JMP I GETIR/~AND RETURN IN THE AC GETIR1, 0/~TEMP LOCAL TO "GETIR" / LOW LEVEL PROGRAMMED I-O THRU TERMINAL LINES / ROUTINE TO GET INPUT FROM THE REMOTE INPUT LINE / RETURN + 1 IF INPUT FOUND / RETURN + 2 IF NO INPUT FOUND IREM, 0 CLA CLL/~INSURE CLEAR AC RKSF/~CHECK FOR INPUT JMP IREM1/~NO INPUT, RETURN + 2 RKRB/~READ ANY INPUT DCA RCHAR/~STORE REMOTE CHAR TAD RCHAR/~RE-GET THE CHAR AND [177/a013H (IGNORE PARITY BIT ON INPUT)/m013J MOVED HERE DCA RCHAR/a013J SAVE STRIPPED CHAR TAD RCHAR/a013J RE-GET CHAR JMP I IREM/~DONE IREM1, ISZ IREM/~NO INPUT, BUMP RETURN JMP I IREM / ROUTINE TO WAIT FOR A CHAR FROM THE REMOTE LINE / RETURN + 2 WITH CHAR INPUT IN THE AC / RETURN + 1 IF TIME-OUT WAITING FOR CHAR IREMW, 0 CLA CLL/~INSURE CLEAR AC DCA IREMW9/~RE-SET TIMER COUNTER TAD (-100/~SET HIGH ORDER /~m013D RETRY CONSTANT DCA IREMW8 IREMW1, JMS IREM/~CALL INPUT REMOTE ROUTINE JMP IREMW2/~RETURN HERE IF CHAR WAS INPUT JMS CCCK/~CHECK FOR A CONTROL/C ISZ IREMW9/~BUMP TIMER-COUNTER JMP IREMW1/~NO TIME-OUT YET ISZ IREMW8/~BUMP HIGH ORDER JMP IREMW1/~NO TIME-OUT YET JMP I IREMW/~TIME-OUT IREMW2, ISZ IREMW/~BUMP RETURN FOR NO TIME-OUT JMP I IREMW/~AND EXIT IREMW8, 0 IREMW9, 0 / ROUTINE TO GET INPUT FROM THE CONSOLE TERMINAL / RETURN + 1 IF INPUT FOUND WITH THE INPUT BYTE IN THE AC / RETURN + 2 IF NO INPUT FOUND WITH GARBAGE IN THE AC ITTY, 0 TKSF/~CHECK FOR INPUT JMP ITTY1/~NO INPUT, RETURN BELOW TKRB/~READ THE INPUT /d013J AND [177/~MASK OUT THE ASCII PARITY BIT /m013H /d013H TAD PARITY/~SET PARITY /m013 (d013H IGNORE PARITY ON INPUT) DCA TCHAR/~STORE AS CURRENT TERMINAL CHAR TAD TCHAR/~RE-GET JMP I ITTY/~RETURN ITTY1, ISZ ITTY/~BUMP RETURN FOR NO INPUT JMP I ITTY/~AND RETURN / INPUT FROM CONSOLE TTY WITH WAIT ITTYW, 0 JMS ITTY/~GO FETCH A CHAR FROM CONSOLE JMP I ITTYW/~RETURN HERE IF CHAR INPUT JMP ITTYW+1/~ELSE WAIT FOR INPUT / ROUTINE TO INPUT AND ECHO CHARS FROM THE KEYBOARD INECO, 0 JMS ITTYW/~GET A CHAR FROM THE KEYBOARD TTYOUT/~DISPLAY THE CHAR ON THE SCREEN JMP I INECO/~DONE / REMOTE OUTPUT ROUTINE - OUTPUT THE BYTE IN THE AC OREM, 0 RTSF/~CHECK OUTPUT FLAG JMP .-1/~WAIT UNTIL READY /d013J AND [177/~IGNORE PARITY /a013E/a003/m013H /d013J TAD PARITY/FORCE PARITY BIT ON OR OFF/a013H RTLS/~SEND THE CHAR CLA CLL/~RETURN CLEAR AC AND LINK JMP I OREM/~DONE / CONSOLE OUTPUT ROUTINE - OUTPUT THE BYTE IN THE AC OTTY, 0 TTSF/~CHECK OUTPUT FLAG JMP .-1/~WAIT TILL READY /d013J TAD PARITY/a013H FORCE ASCII BIT 8 ON OR OFF TTLS/~SEND THE CHAR JMP I OTTY/~DONE PAGE / HOLD BUFFER FOR CHAR OUTPUT DECIMAL HOLDBF, ZBLOCK 92 OCTAL / ROUTINE TO CHECK FOR CONTROL PREFIX / ENTER WITH CHAR TO CHECK IN THE AC / EXIT + 1 WITH CHAR IN THE AC IF NO PREFIX QUOTING / EXIT + 2 WITH PROPER CHAR IN THE AC AND QUOTING IS REQUIRED OPRE, 0 MQL/~SAVE CHAR TAD QFLAG/~CHECK FOR IN CTRL QUOTE MODE SZA CLA/~SKIP IF YES JMP OPRE1/~NO QUOTE PREFIX MQA/~GET CHAR AND (7740/~QUICK CHECK FOR LT 40 SNA CLA/~SKIP IF NOT CONTROL JMP OPRE2/~PREFIX QUOTE MQA/~GET CHAR TAD (-177/~CHECK FOR "DELETE" SNA CLA/~SKIP IF NOT JMP OPRE2/~PREFIX QUOTE MQA/~GET CHAR CIA/~NEGATE FOR COMPARE TAD RQCTL/~SEE IF SAME AS QUOTE CHAR SZA CLA/~SKIP IF PREFIX QUOTE JMP OPRE1/~NO PREFIX QUOTE TAD RQCTL/~PREFIX WITH PREFIX JMP OPRE3/~PREFIX WITH THE PREFIX OPRE1, MQA/~GET CHAR JMP I OPRE/~DONE OPRE2, MQA/~GET CHAR TAD (100/~MAKE IT PRINTABLE AND C177/~IN CASE WAS 177 OPRE3, ISZ OPRE/~BUMP FOR PREFIX RETURN JMP I OPRE/~DONE PAGE / ROUTINE TO SCAN A TEXT LINE FOR KEYWORD DELIMITERS. ROUTINE EXPECTS / THE AC TO POINT TO A TEXT LINE TO SCAN AND FINDS THE FIRST NON-SPACE, / NON-END OF LINE CHAR IN THE LINE AND SETS "SCAN1" TO POINT TO IT. / NEXT WE FIND THE LAST CHAR IN THE LINE THAT IS A NON-SPACE, NON-END / OF LINE AND STORE A POINTER TO IT IN "SCAN2". KEYWORDS ARE DELIMITED / BY A BEGINNING OF LINE OR SPACE AT THE BEGINNING AND AN END OF LINE / OR A SPACE AT THE END / ENTER: AC = POINTER TO COMMAND LINE / EXIT: (SUCCESS) SCAN1 = POINTER TO FIRST CHAR OF KEYWORD / SCAN2 = POINTER TO LAST CHAR OF KEYWORD / RETURN = RETURN + 2 (NO WORDS LEFT IN LINE) / EXIT: (FAIL) RETURN = RETURN + 1 SCNEL, 0 JMS NOSP/~FIND FIRST NON-SPACE JMP I SCNEL/~END OF LINE RETURN DCA SCAN1/~RETURN SCAN LINE POINTER TAD SCAN1/~RE-GET SCAN LINE POINTER JMS SP/~FIND FIRST SPACE OR EOL NOP/~RETURN HERE ON EOL TAD (-1/~BACK UP TO PREVIOUS CHAR DCA SCAN2/~SET END ELEMENT POINTER ISZ SCNEL/~TAKE SUCCESS RETURN JMP I SCNEL/~DONE / ROUTINE TO SCAN THRU A TEXT LINE LOOKING FOR THE NEXT SPACE / ENTER ROUTINE WITH THE LINE POINTER IN THE AC / EXIT: RETURN + 2 WITH AC = POINTER TO SPACE / RETURN + 1 WITH AC = POINTER TO END OF LINE SP, 0 DCA SCANTP/~USE A TEMP POINTER SKP/~SKIP INTO LOOP BELOW SP1, ISZ SCANTP/~BUMP LINE POINTER TAD I SCANTP/~GET A CHAR SPA/~SKIP IF NOT END OF LINE JMP SP3/~GOT AN END OF LINE TAD (-SPACE/~COMPARE WITH A SPACE SZA CLA/~SKIP IF IS A SPACE JMP SP1/~LOOP TILL SPACE OR EOL ISZ SP/~BUMP RETURN FOR SPACE FOUND SP3, CLA CLL/~INSURE A CLEAR AC TAD SCANTP/~GET POINTER VALUE JMP I SP/~RETURN IN AC / ROUTINE TO SCAN THRU A TEXT LINE FOR THE FIRST NON-SPACE / ENTER ROUTINE WITH POINTER TO THE LINE IN THE AC / EXIT: RETURN + 2 WITH AC = POINTER TO NON-SPACE / RETURN + 1 WITH AC = POINTER TO END OF LINE NOSP, 0 DCA SCANTP/~USE A TEMP POINTER SKP/~SKIP INTO LOOP BELOW NOSP1, ISZ SCANTP/~BUMP THE LINE POINTER TAD I SCANTP/~GET A CHAR FROM THE LINE SPA/~SKIP IF NOT EOL JMP NOSP3/~EXIT IF EOL TAD (-SPACE/~COMPARE WITH A SPACE SNA CLA/~SKIP IF NOT SPACE JMP NOSP1/~LOOP TILL SPACE OR EOL ISZ NOSP/~BUMP RETURN FOR SPACE FOUND NOSP3, CLA CLL/~INSURE CLEAR AC TAD SCANTP/~GET POINTER JMP I NOSP/~RETURN IN AC / ROUTINE TO FIND AN END CHAR IN A STRING / ENTER ROUTINE WITH POINTER TO THE STRING IN THE AC / EXIT WITH THE POINTER TO THE FIRST MINUS CHAR IN THE AC FNDEND, 0 DCA SCANTP/~PUT POINTER IN SCANTP FEND1, TAD I SCANTP/~GET A CHAR FROM THE STRING SPA CLA/~SKIP IF NOT END JMP FEND2/~EXIT IF END OF STRING ISZ SCANTP/~BUMP THE POINTER JMP FEND1/~LOOP TILL NON-END OF STRING FEND2, TAD SCANTP/~GET POINTER TO NON-END OF STRING JMP I FNDEND/~EXIT WITH POINTER IN AC SCANTP, 0/~USED IN THE SCAN ROUTINES "SP", "NOSP", "FNDNUL" / ROUTINE TO LOOKUP THE KEY WORD POINTED TO BY THE AC IN THE TABLE POINTED / TO BY PTABLE. / RETURN + 1 IF NO MATCH IS FOUND WITH AC = ENTRY VALUE / RETURN + 2 IF NO KEYWORD IS FOUND (EOL DETECTED) / RETURN + 3 IF MATCH IS FOUND WITH THE NEXT PARSE POSITION IN THE LINE / IN THE AC AND THE DISPATCH ADDRESS FROM THE TABLE IN "KEYDSP" KEYPRS, 0 DCA LOOK3/~SAVE IN CASE OF FAIL TAD LOOK3/~RE-GET /d013H AND (137/m013H MAKE CHAR UC, IGNORE PARITY JMS SCNEL/~TRY TO SCAN OFF A KEYWORD JMP KP45/~END OF LINE ENCOUNTERED TAD PTABLE/~GET ADDRESS OF TABLE DCA LOOK2/~STORE IN LOCAL POINTER KP10, TAD SCAN1/~GET ADDRESS OF SCAN ELEMENT DCA LOOK1/~INTO LOCAL POINTER KP20, TAD I LOOK1/~GET A CHAR FROM THE SCAN ELEMENT CIA/~NEGATE FOR COMPARE TAD I LOOK2/~GET A CHAR FROM THE TABLE ELEMENT SZA CLA/~SKIP IF MATCH JMP KP90/~NO MATCH, SET TO LOOK AT NEXT TABLE ENTRY TAD LOOK1/~CHECK IF ALL ENTERED CHARS MATCH CIA/~NEGATE TO COMPARE TAD SCAN2/~HAVE WE MATCHED TO THE TERMINATOR? SNA CLA/~SKIP IF NO JMP KP40/~YES, GOT ENOUGH TO MATCH ISZ LOOK1/~MORE TO MATCH, BUMP SCAN ELEMENT POINTER ISZ LOOK2/~BUMP TABLE ELEMENT POINTER JMP KP20/~CONTINUE MATCH LOOP KP40, TAD LOOK2/~GET CURRENT TABLE POINTER JMS FNDEND/~FIND A NULL MARK IAC/~BUMP BY 1 DCA LOOK1/~STORE IN A POINTER TAD I LOOK1/~GET DISPATCH ADDRESS DCA KEYDSP/~PUT INTO DISPATCH ADDRESS ISZ KEYPRS/~BUMP RETURN ISZ KEYPRS/~BUMP AGAIN CLA CLL IAC/~AC = 1 TAD SCAN2/~GET POINTER TO END OF CURRENT KEY JMP I KEYPRS/~RETURN / END OF LINE ENCOUNTERED ON PARSE KP45, ISZ KEYPRS/~BUMP RETURN ONCE FOR EOL / NO MATCHES IN THE TABLE HERE KP50, TAD LOOK3/~GET ORIGINAL AC JMP I KEYPRS/~RETURN / FAILURE ON CURRENT TABLE ENTRY, SET FOR NEXT ENTRY (IF THERE IS ONE) AND / TRY AGAIN KP90, TAD LOOK2/~GET TABLE POINTER JMS FNDEND/~FIND NEXT TABLE ENTRY IAC/~NEXT ENTRY IS 2 PAST THE NULL IAC DCA LOOK2/~RE-SET LOCAL TABLE POINTER TAD I LOOK2/~CHECK END OF TABLE SNA CLA/~SKIP IF NOT END OF THE TABLE JMP KP50/~TAKE NOT FOUND EXIT JMP KP10/~TRY MATCH ON THIS ENTRY LOOK1, 0 LOOK2, 0 LOOK3, 0 / ROUTINE TO MOVE WORDS OF MEMORY / ENTER WITH: "MOVE1" = MINUS THE NUMBER OF WORDS TO MOVE / AC = SOURCE ADDRESS / MQ = DESTINATION ADDRESS MOVE0, 0 DCA MOVE5/~STORE SOURCE ADDRESS IN LOCAL POINTER MQA/~GET DESTINATION ADDRESS DCA MOVE6/~STORE IN LOCAL POINTER MOVE1, TAD I MOVE5/~GET A WORD FROM THE SOURCE DCA I MOVE6/~MOVE TO DESTINATION ISZ MOVE5/~BUMP SOURCE POINTER ISZ MOVE6/~BUMP DESTINATION COUNTER ISZ MOVE4/~BUMP COUNTER JMP MOVE1/~LOOP JMP I MOVE0/~DONE MOVE5, 0/~SOURCE POINTER FOR "MOVE" MOVE6, 0/~DESTINATION POINTER FOR "MOVE" PAGE / ROUTINE TO PARSE OFF A DEVICE NAME FROM THE COMMAND LINE. / ENTER WITH: POINTER TO COMMAND LINE IN THE AC / NON-ERROR EXIT: RETURN + 2 / POINTER TO REMAINDER OF LINE IN THE AC / DEVNUM = DEVICE NUMBER TO USE / ':' IS THE 5TH CHAR IF NOT DEFAULT DEVICE / ERROR EXIT: RETURN + 1 / ORIGINAL AC DPARS, 0 DCA DPAR10/~SAVE INITIAL POINTER TO LINE TAD DPAR10/~GET POINTER JMS NOSP/~GET PAST ANY LEADING SPACES JMP DFDEV/~GOT END OF LINE, USE DEFAULT DEVICE DCA DPAR11/~SAVE POINTER TO LINE DCA DEVNAM/~INIT DEVICE NAME FOR "INQUIRE" DCA DEVNAM+1 DCA DEVNUM/~INIT DEVICE NUMBER TAD (DEVNAM/~GET ADDRESS OF WHERE TO PUT DEV NAME DCA PACK6P/~STORE IN PACK6 POINTER DCA PACK6F/~INIT PACK6 FLAG FOR LOW BYTE TAD (-4/~SET UP A COUNTER DCA DPAR13/~FOR NO MORE THAN 4 CHARS DPAR1, TAD I DPAR11/~GET A CHAR FROM THE LINE SNA/~SKIP IF NOT EOL JMP DFDEV/~GOT AN EOL, USE DEFAULT DEVICE TAD (-":/~CHECK FOR END OF DEVICE NAME SNA CLA/~SKIP IF NOT END OF DEVICE NAME JMP DPAR2/~DEVICE NAME SET UP TAD I DPAR11/~RE-GET CHAR ISZ DPAR11/~BUMP LINE POINTER PACK6/~PACK 6 BIT ISZ DPAR13/~BUMP CHAR COUNTER JMP DPAR1/~CAN CONTINUE SKP/~DO NOT BUMP POINTER AGAIN ISZ DPAR11/~BUMP TO NEXT CHAR TAD I DPAR11/~GET CHAR AFTER THE 4TH TAD (-":/~THIS MUST BE A ":" SZA CLA/~SKIP IF YES, ALL IS OK JMP DFDEV/~USE THE DEFAULT DEVICE DPAR2, ISZ DPAR11/~BUMP POINTER PAST ":" TAD (DEVNAM/~GET PARSED DEVICE NAME ADDRESS JMP DPAR4/~DO AN OS/8 "INQUIRE" DFDEV, TAD DPAR10/~GET ORIGINAL AC FOR DCA DPAR11/~RETURN POINTER DPAR4, JMS DVNUM/~GET DEVICE NUMBER JMP DPAR8/~DEVICE NAME ERROR DCA DEVNUM/~RETURN FOR CALLING PROGRAM TAD DPAR11/~GET CURRENT POINTER ISZ DPARS/~BUMP RETURN JMP I DPARS DPAR8, CLA CLL/~INSURE CLEAR AC TAD DPAR10/~GET ORIGINAL AC JMP I DPARS/~TAKE ERROR EXIT DPAR10, 0/~TEMP FOR DPARS DPAR11, 0/~TEMP FOR DPARS DPAR13, 0/~TEMP FOR DPARS DEFDEV, DEVICE DSK/~DEFAULT DEVICE DEVNAM, FILENAME ZZZZZZ.ZZ / ROUTINE TO RETURN A DEVICE NUMBER FOR A DEVICE NAME / ENTER AC = ADDRESS OF DEVICE NAME / OR / ENTER AC = 0 IF DEFAULT "DSK" IS TO BE USED / EXIT + 2 WITH DEVICE NUMBER IN AC IF ALL OK / EXIT + 1 IF INVALID DEVICE DVNUM, 0 SNA/~SKIP IF DEVICE NAME SPECIFIED TAD (DEFDEV/~ELSE USE DEFAULT DCA DVNUM9/~SAVE IN LOCAL POINTER TAD I DVNUM9/~GET FIRST 2 CHARS OF NAME DCA DVNUM5/~PUT INTO CALL ISZ DVNUM9/~BUMP POINTER TAD I DVNUM9/~GET LAST 2 CHARS OF NAME DCA DVNUM5+1/~PUT INTO CALL CIF 10/~CALL USER SERVICE FOR "INQUIRE" JMS I USR 12/~FUNCTION CODE 12 DVNUM5, 0/~FIRST 2 BYTES OF DEVICE NAME 0/~LAST 2 BYTES OF DEVICE NAME 0/~ENTRY POINT OF HANDLER RETURNED HERE JMP I DVNUM/~ERROR, TAKE ERROR EXIT TAD DVNUM5+1/~DEVICE NUMBER ISZ DVNUM/~BUMP RETURN FOR NO ERROR JMP I DVNUM/~RETURN DVNUM9, 0/~LOCAL FOR "DVNUM" / ROUTINE TO CONVERT A STRING OF BYTES INTO PDP8 CHARS WHICH HAVE / THE TOP BIT (BIT 7) SET. / ENTER: AC = ADDRESS OF STRING / OR / CALL + 1 = ADDRESS OF STRING / EXIT: STRING HAS TOP BYTE SET / STRING IS TERMINATED ON A MINUS WORD XLATE8, 0 SZA/~SKIP IF ADDRESS AT CALL + 1 JMP XLAT81/~ADDRESS IN AC TAD I XLATE8/~GET ADDRESS FROM CALL + 1 ISZ XLATE8/~BUMP RETURN PAST ADDRESS XLAT81, DCA XLAT89/~STORE IN LOCAL POINTER XLAT82, TAD I XLAT89/~GET A BYTE FROM STRING SPA/~SKIP IF NOT TERMINATOR JMP XLAT83/~CLEAR AC AND EXIT AND C177/~MASK OUT THE ASCII PARITY BIT /m013 TAD [200/~SET MARK PARITY /m013H DCA I XLAT89/~RETURN IT ISZ XLAT89/~BUMP THE POINTER JMP XLAT82/~LOOP XLAT83, CLA CLL/~INSURE CLEAR AC JMP I XLATE8/~DONE WITH THIS STRING XLAT89, 0/~LOCAL POINTER FOR "XLATE8" / ROUTINE TO GO THRU A STRING OF BYTES AND INSURE THE TOP BIT / (BIT 8) IS CLEAR. / ENTER WITH ADDRESS OF STRING IN AC OR AT CALL + 1 / THE STRING TERMINATES ON A MINUS WORD XLATE7, 0 SZA/~SKIP IF ADDRESS NOT IN AC JMP XLAT71/~ADDRESS IN AC TAD I XLATE7/~GET ADDRESS FROM CALL + 1 ISZ XLATE7/~BUMP RETURN XLAT71, DCA XLAT79/~STORE ADDRESS IN POINTER XLAT72, TAD I XLAT79/~GET A CHAR FROM STRING SPA/~SKIP IF NOT END OF STRING JMP XLAT73/~END OF STRING, TERMINATE AND C177/~IGNORE PARITY DCA I XLAT79/~RETURN ISZ XLAT79/~BUMP POINTER JMP XLAT72/~LOOP XLAT73, CLA CLL/~INSURE CLEAR AC JMP I XLATE7/~RETURN XLAT79, 0/~POINTER FOR "XLATE7" PAGE / ROUTINE TO PARSE OFF A FILE NAME / FILE NAME TO BE PARSED MUST BE LETTERS OR DIGITS AND BE NO MORE THAN / SIX CHARS FOR THE NAME AND TWO CHARS FOR THE EXTENSION. / FILENAMES REQUIRE 'MARK' PARITY ASCII / ENTER WITH: AC = POINTER TO FILE NAME TO PARSE / FNPTR = POINTER TO WHERE TO PUT THE PARSED FILE NAME / NON-ERROR EXIT: AC = POINTER TO REMAINDER OF COMMAND LINE / RETURN THE CALL + 2 / ERROR EXIT: AC = ORIGINAL POINTER / RETURN THE CALL + 1 PFNAM, 0 DCA PFN10/~SAVE POINTER TO FILE NAME STRING TAD PFN10/~GET POINTER TO NAME JMS XLATE8/~INSURE PARITY BIT SET TAD FNPTR/~GET POINTER TO FILE NAME BLOCK MQL/~SET FOR "CLEAR" ROUTINE TAD (-4/~FOUR WORDS TO CLEAR OUT CLEAR/~INIT THE FILE NAME BLOCK TAD PFN10/~GET THE STRING POINTER JMS NOSP/~GET PAST ANY LEADING SPACES JMP PFNAM9/~GOT EOL, NO FILE NAME DCA PFN11/~SAVE POINTER TAD FNPTR/~GET FILE NAME BLOCK POINTER DCA PACK6P/~SET UP THE "PACK6" POINTER DCA PACK6F/~INIT THE "PACK6" FLAG TAD (-6/~MAX OF 6 CHARS FOR FILE NAME DCA PFN15/~PUT INTO COUNTER DCA WILDF/~INIT THE WILD CARD FLAG JMS NAM/~MOVE AND PACK FILE NAME TAD I PFN11/~GET THE TERM CHAR SPA/~SKIP IF NOT EOL JMP PFNAM7/~EOL MEANS END OF FILE NAME TAD (-"./~WAS IT A "."? SNA/~SKIP IF NO JMP PFNAM3/~GO HANDLE EXTENSION TAD (".-" /~CHECK FOR A SPACE SZA CLA/~SKIP IF WAS A SPACE JMP PFNAM9/~NOT A SPACE, GOT AN ERROR JMP PFNAM7/~IS A SPACE, END OF FILE NAME PFNAM3, ISZ PFN11/~BUMP PAST THE "." CLA CLL CML IAC RAL/~AC = 3 TAD FNPTR/~GET FILE NAME BLOCK POINTER DCA PACK6P/~SET "PACK6" POINTER DCA PACK6F/~INIT "PACK6" FLAG CLA CLL CMA RAL/~AC = -2 DCA PFN15/~COUNTER FOR 2 EXT CHARS JMS NAM/~NOW DO THE EXTENSION TAD I PFN11/~GET THE TERM CHAR SPA/~SKIP IF NOT EOL JMP PFNAM7/~GOT COMPLETE FILE NAME HERE TAD (-" /~CAN BE A SPACE SZA CLA/~SKIP IF IT WAS JMP PFNAM9/~GOT A FILE NAME ERROR PFNAM7, ISZ PFNAM/~BUMP RETURN FOR GOOD FILE NAME CLA CLL/~INSURE CLEAR AC TAD PFN11/~GET CURRENT STRING POINTER JMP I PFNAM/~AND RETURN PFNAM9, CLA CLL/~INSURE CLEAR AC TAD PFN10/~GET ORIGINAL STRING POINTER JMP I PFNAM/~TAKE ERROR RETURN PFN10, 0/~TEMP FOR PFNAM ROUTINE PFN11, 0/~TEMP FOR PFNAM ROUTINE PFN15, 0/~TEMP FOR PFNAM ROUTINE / LOCAL ROUTINE TO "PFNAM" TO MOVE IN THE FILE NAME OR FILE EXTENSION / ENTER WITH "PFN11" POINTING TO WHERE TO GET THE NAME OR EXTENSION / AND "PFN15" EQUAL TO THE MAX NUMBER OF CHARS (6 FOR NAME, 2 FOR EXT) / THIS ROUTINE CHECKS FOR WILD CARD CHARS "*" AND "?" AND PUTS THE / "?" CHAR IN FOR ANY CHARS IN THE NAME THAT ARE WILD. ALSO IF ANY / WILD CARD CHARS ARE FOUND THE FLAG "WILDC" IS SET SO BEFORE PARSING / ANY FILE NAME THE "WILDC" FLAG SHOULD BE INITIALIZED. NAM, 0 NAM0, TAD I PFN11/~GET A CHAR FROM THE STRING JMS ALPNUM/~MUST BE ALPHA OR NUMBER SKP/~NOT A ALPHA NUMERIC JMP NAM3/~IS ALPHA NUMERIC TAD (-"?/~IS IT A SINGLE WILD CARD CHAR SNA/~SKIP IF NO JMP NAM2/~YES, JUST PUT IT IN TAD ("?-"*/~IS IT A MULTIPLE WILD CARD CHAR? SZA CLA/~SKIP IF YES JMP I NAM/~TAKE THE FILE NAME ERROR EXIT ISZ WILDF/~SET FLAG FOR WILD CARD FOUND NAM1, TAD ("?/~FILL REMAINING WITH WILD CARD CHAR PACK6/~PUT IN NAME BLOCK ISZ PFN15/~BUMP CHAR COUNTER JMP NAM1/~LOOP TILL ALL FILLED ISZ PFN11/~BUMP THE STRING POINTER JMP NAM9/~EXIT WITH "PFN11" POINTING TO NEXT CHAR NAM2, ISZ WILDF/~SET FLAG FOR WILD CARD FOUND TAD ("?/~GET THE WILD CHAR NAM3, PACK6/~PUT THE CHAR INTO THE FILE NAME BLOCK ISZ PFN11/~BUMP THE STRING POINTER ISZ PFN15/~BUMP THE CHAR COUNTER JMP NAM0/~LOOP NAM4, TAD I PFN11/~NOW GET TO A TERMINATOR CHAR JMS ALPNUM/~BY FINDING FIRST NON-ALPHNUMERIC JMP NAM9/~NOW WE CAN QUIT CLA CLL/~IGNORE EXCESS CHARS ISZ PFN11/~BUMP THE STRING POINTER JMP NAM4/~LOOP NAM9, CLA CLL/~LEAVE WITH A CLEAR AC JMP I NAM/~RETURN / ROUTINE TO SEND A PACKET / ENTER WITH ADDRESS OF PACKET DATA IN CALL + 1 / AND TYPE OF PACKET IN CALL + 2 / EXIT CALL + 4 IF ACK RETURNED / EXIT CALL + 3 IF NAK OR OTHER PACKET TYPE RETURNED SNDP, 0 TAD I SNDP/~GET DATA ADDRESS DCA SNDP1/~STORE IN CALL ISZ SNDP/~BUMP POINTER TAD I SNDP/~GET PACKET TYPE DCA SNDP2/~STORE IN CALL ISZ SNDP/~BUMP FPACK/~FORMAT A PACKET SNDP1, 0/~DATA ADDRESS GOES HERE SNDP2, 0/~PACKET TYPE GOES HERE SNDP3, SPACK/~SEND A DATA PACKET 1/~GET RESPONSE SNDP9/~RESPONSE DISPATCH TABLE ADDRESS / HERE ON NOT "NAK" OR "ACK" RESPONSE SKP / HERE ON "ACK" SNDP5, ISZ SNDP/~BUMP RETURN ISZ SNDP/~BUMP RETURN JMP I SNDP/~EXIT / HERE ON NAK SNDP4, ISZ RTRYC/~BUMP THE RE-TRY COUNTER JMP SNDP3/~RE-TRY JMP I SNDP/~TAKE RETURN + 3 SNDP9, STACK; SNDP5/~ACK STACK; SNDP4/~NAK 0 PAGE / ROUTINE TO PARSE OFF A DECIMAL NUMBER / ENTER ROUTINE WITH A POINTER TO THE PARSE LINE IN THE AC / EXIT: RETURN + 1 FOR NO NUMBER / RETURN + 2 FOR INVALID NUMBER / RETURN + 3 FOR VALID NUMBER / IN ALL CASES ON RETURN THE AC WILL CONTAIN A POINTER TO THE NEXT / CHAR TO PARSE IN THE LINE. ANY NUMBER PARSED WILL BE CONVERTED / TO BINARY AND PUT INTO THE REGISTER "BININP". DECPRS, 0 JMS NOSP/~GET PAST ANY LEADING SPACES JMP I DECPRS/~GOT AN END OF LINE, AC POINTS TO IT DCA DP10/~SAVE POINTER TO LINE TAD DP10/~RE-GET POINTER TO LINE DCA DP11/~STORE IN OUR LINE POINTER DCA BININP/~INIT BINARY REGISTER DCA DP13/~INIT PARSED NUMBER FLAG SKP/~SKIP INTO LOOP BELOW DP1, ISZ DP11/~BUMP THE LINE POINTER TAD I DP11/~GET A CHAR FROM THE LINE JMS DECCK/~CHECK FOR PROPER ASCII DECIMAL JMP DP5/~NOT PROPER ASCII DECIMAL ISZ DP13/~FLAG NUMBER INPUT TAD (-"0/~MAKE BINARY DCA DP12/~AND STORE TAD BININP/~GET PREVIOUS INPUT JMS MUL10/~AND MULTIPLY TIMES 10 SZL/~SKIP IF NO OVERFLOW ENCOUNTERED JMP DP6/~GOT AN OVERFLOW ERROR TAD DP12/~COMBINE WITH CURRENT INPUT SZL/~SKIP IF NO OVERFLOW ERROR JMP DP6/~GOT AN OVERFLOW ERROR DCA BININP/~RETURN ACCUMULATED SUM JMP DP1/~LOOP DP5, CLA CLL/~AC MAY NOT BE CLEAR TAD DP13/~ANY NUMBERS INPUT YET? SNA CLA/~SKIP IF YES JMP DP6/~TAKE THE NO NUMBER INPUT RETURN ISZ DECPRS/~BUMP THE RETURN ISZ DECPRS/~TWICE FOR GOOD NUMBER INPUT RETURN TAD DP11/~GET POINTER TO LINE JMP I DECPRS/~AND RETURN DP6, CLA CLL/~AC MAY NOT BE CLEAR TAD DP10/~GET ORIGINAL LINE POINTER ISZ DECPRS/~BUMP THE RETURN JMP I DECPRS/~TAKE THE INVALID NUMBER RETURN DP10, 0/~TEMP FOR DECPRS DP11, 0/~TEMP FOR DECPRS DP12, 0/~TEMP FOR DECPRS DP13, 0/~TEMP FOR DECPRS / ROUTINE TO MULTIPLY THE VALUE OF THE AC TIMES 10 / VALUE IN THE AC IS ASSUMED BINARY / THE NUMBER IS RETURNED IN THE AC. IF THE LINK IS SET THE MULTIPLY / OVERFLOWED 12 BITS. MUL10, 0 DCA MULTMP/~SAVE THE NUMBER TAD MULTMP/~GET THE NUMBER BACK CLL RTL/~MULTIPLY TIMES 4 TAD MULTMP/~TIMES 5 SZL/~SKIP IF NO OVERFLOW SKP/~GOT OVERFLOW RAL/~TIMES 10 JMP I MUL10/~RETURN NUMBER IN AC /~THE LINK HAS ANY OVERFLOW MULTMP, 0/~TEMP STORAGE FOR MUL10 ROUTINE / ROUTINE TO CHECK FOR A VALID ASCII DECIMAL VALUE / ENTER WITH ASCII CHAR IN THE AC / EXIT RETURN + 1 IF NON-VALID ASCII DECIMAL WITH CHAR IN AC / EXIT RETURN + 2 IF VALID ASCII DECIMAL WITH CHAR IN AC DECCK, 0 DCA DECCK5/~STORE THE CHAR TO CHECK TAD DECCK5/~GET THE CHAR TAD (-"0/~CHECK FOR LESS THAN 0 SPA/~SKIP IF NOT LESS THAN 0 JMP DECCK1/~NON-ASCII DECIMAL TAD ("0-"9-1/~CHECK GREATER THAN 9 SMA CLA/~SKIP IF LE 9 JMP DECCK1/~INVALID ASCII DECIMAL ISZ DECCK/~BUMP RETURN FOR VALID ASCII DECIMAL DECCK1, TAD DECCK5/~RE-GET ORIGINAL CHAR IN AC JMP I DECCK/~RETURN DECCK5, 0/~TEMP FOR "DECCK" ROUTINE / ROUTINE TO INPUT A COMMAND LINE FROM THE KEYBOARD LININP, 0 TAD (LINBUF/~GET ADDRESS OF LINE BUFFER DCA LIN50/~STORE IN A POINTER LIN1, JMS ITTYW/~INPUT A CHAR AND (177/a013H STRIP PARITY BIT TAD [200/a013D SET PARITY TO MARK FOR COMMANDS AND FILENAMES /m013H DCA TCHAR/a013H STORE CHAR WITH PARITY SET TO MARK TAD TCHAR/a013H RE-GET CHAR TAD (-CR/~CHECK FOR A RETURN TYPED SNA/~SKIP IF NOT A RETURN JMP LIN2/~LINE IS INPUT TAD (CR-DELETE/~CHECK FOR A DELETE CHAR SNA CLA/~SKIP IF NOT A DELETE JMP LIN5/~OFF TO HANDLE A DELETE TAD LIN50/~GET VALUE OF LINE POINTER TAD (-LINBUF-LINSIZ/~COMPARE WITH END OF LINE BUFFER SMA CLA/~SKIP IF ROOM IN LINE BUFFER JMP LIN10/~BEEP FOR FULL BUFFER TAD TCHAR/~RE-GET CHAR JUST INPUT TTYOUT/~ECHO CHAR TO TTY DCA I LIN50/~STORE IN THE LINE BUFFER ISZ LIN50/~BUMP THE LINE BUFFER POINTER STA/~AC = -1 DCA I LIN50/~TERMINATE THE LINE JMP LIN1/~LOOP TILL A RETURN TYPED LIN2, STA/~AC = -1 DCA I LIN50/~INSURE STRING TERMINATED PRI6B; CRLF/~SEND A CR/LF JMP I LININP/~DONE / HANDLE A DELETE TYPED IN LIN5, TAD LIN50/~FIND OUT FIRST IF... TAD (-LINBUF/~WE ARE AT THE BEGINNING OF THE LINE SNA CLA/~SKIP IF NO JMP LIN1/~JUST IGNORE THE DELETE STA/~AC = -1 TAD LIN50/~GET THE LINE POINTER DCA LIN50/~RETURN BACKED UP DCA I LIN50/~ZERO THE CHAR PRI6B; RUBOUT/~ERASE THE CHAR FROM THE SCREEN JMP LIN1/~BACK TO INPUT / HANDLE FULL LINE BUFFER HERE LIN10, CLA CLL/~INSURE CLEAR AC PRI6B; BEEP/~SEND BUFFER FULL WARNING JMP LIN1/~BACK TO MAIN LOOP WAIT FOR RETURN OR DELETE KEY LIN50, 0/~TEMP POINTER FOR "LININP" ROUTINE / ROUTINE TO PRINT THE DATA IN THE RECEIVED PACKET PRIPAK, 0 PRI8B; RRDTA/~PRINT THE DATA PRI6B; CRLF/~ADD IN A CR/LF JMP I PRIPAK/~DONE PAGE / ROUTINE TO HANDLE THE "CONNECT" COMMAND CONSRV, 0 ISZ CONSRV/~ALWAYS NON-ERROR RETURN PRI6B; CONMSG/~TELL THEM WE ARE CONNECTING TAD (MLINE/~SET MODE ONLINE DCA KMODE DCA CONFLG/~RE-SET CONNECT FLAG CONSR1, JMS IREM/~GET ANY INPUT FROM REMOTE COMPUTER TTYOUT/~RETURN HERE ON INPUT FROM REMOTE, SEND /~ TO THE TELEPRINTER DEVICE JMS ITTY/~GET ANY INPUT FROM KEYBOARD SKP/~RETURN HERE ON INPUT FROM KEYBOARD JMP CONSR1/~NO KEYBOARD INPUT, CONTINUE POLL TAD (-CONX1/~CHECK FOR FIRST EXIT CHAR SZA/~SKIP IF IS FIRST EXIT CHAR JMP CONSR5/~NOT FIRST EXIT CHAR STA/~SET AC = -1 DCA CONFLG/~MAKE FLAG = -1 JMP CONSR1/~CONTINUE POLL CONSR5, TAD (CONX1-CONX2/~CHECK FOR SECOND EXIT CHAR SZA CLA/~SKIP IF IT IS JMP CONSR9/~JUST ECHO AND EXIT ISZ CONFLG/~WE SKIP IF FIRST CHAR CAME BEFORE JMP CONSR9/~FIRST CHAR DID NOT COME IN PRI6B; BEEP/~BELL TO AFTER 'CONNECT' EXIT /m013 JMP I CONSRV/~DONE WITH CONNECT SERVICE CONSR9, DCA CONFLG/~RE-SET THE CONNECT FLAG TAD TCHAR/~GET CHAR JUST ENTERED JMS OREM/~DISPLAY ON THE TERMINAL CLA CLL/~INSURE CLEAR AC JMP CONSR1/~CONTINUE POLL LOOP / ROUTINE TO HANDLE THE "BYE" COMMAND BYESRV, 0 FPACK/~FORMAT A PACKET SRVBYE/~PACKET DATA ADDRESS STGEN/~PACKET TYPE BYE2, SPACK/~SEND PACKET 1/~AWAIT RESPONSE BYE20/~DISPATCH LIST FOR RESPONSE / NAK OR UNDEFINED RESPONSE HERE BYE5, ISZ RTRYC/~BUMP RE-TRY COUNTER JMP BYE2/~GET RESPONSE AND TRY AGAIN TAD (NOBYE/~FAILED, RETURN MESSAGE JMP I BYESRV / ACK HERE BYE10, ISZ BYESRV/~BUMP FOR NON-ERROR EXIT JMP I BYESRV/~DONE BYE20, STACK; BYE10/~ACK STNAK; BYE5/~NAK 0 SRVBYE, "F&137/~SERVER KERMIT COMMAND TO SHUT DOWN -1/~END OF DATA / EXIT OS/8 KERMIT OS8, 0 PRI6B; EXTXT/~DISPLAY WE ARE EXITING CLA CLL JMP I (7600/~BACK TO OS8 / REMOTE LINK INPUT ROUTINE / CALL = RPACK ILINK, 0 TAD RETRY/~SET UP A RE-TRY COUNT DCA ILINK6/~RE-TRY COUNT FOR INPUT ERRORS ILINK0, JMS GETSOH/~FIRST GET THE "SOH" BYTE JMP ILINK2/~RETURN HERE ON TIME-OUT DCA ILINK9/~INIT CHECKSUM REGISTER TAD (RRLEN/~GET REMOTE RECEIVE BUFFER ADDRESS DCA ILINK8/~STORE IN LOCAL POINTER JMS GETIR/~GET A CHAR JMP ILINK2/~GOT A RETURN OR TIME-OUT DCA I ILINK8/~STORE LENGTH IN BUFFER TAD I ILINK8/~GET LENGTH CHAR BACK TAD (-40-1/~CHAR FUNCTION - LENGTH BYTE CIA/~NEGATE FOR COUNTER DCA ILINK7/~STORE IN LOCAL COUNTER ILINK1, ISZ ILINK8/~BUMP POINTER JMS GETIR/~GET NEXT CHAR JMP ILINK2/~GOT A RETURN DCA I ILINK8/~STORE IN BUFFER ISZ ILINK7/~BUMP COUNTER JMP ILINK1/~LOOP ISZ ILINK8 STA DCA I ILINK8 TAD ILINK9/~GET CACULATED CHECKSUM JMS CKSUM/~CACULATE 1 BYTE CHECKSUM CIA/~NEGATE FOR COMPARE DCA ILINK7/~STORE TEMP JMS GETIR/~NOW GET CHECKSUM JMP ILINK2/~GOT A RETURN TAD ILINK7/~COMPARE WITH CACULATED CHECKSUM SNA CLA/~SKIP IF NOT SAME JMP ILINK4/~ARE SAME ILINK2, CLA CLL/~INSURE CLEAR AC ISZ ILINK6/~BUMP RE-TRY COUNTER JMP ILINK3/~CAN RE-TRY TAD (FPERR/~GET MESSAGE FOR FATAL PACKET ERROR JMP CLOOP7/~AND ABORT THE MESS ILINK3, TAD CCFLAG/~CHECK IF ^C TYPED SZA CLA/~SKIP IF NO JMP ABORT/~ABORT THIS JMS SNDNAK/~SEND BACK A "NAK" JMP ILINK0/~AND TRY AGAIN ILINK4, TAD CCFLAG/~WAS A ^C TYPED? SNA CLA/~SKIP IF YES JMP I ILINK/~NOPE, RETURN JMP ABORT ILINK6, 0/~LOCAL TO "ILINK" ILINK7, 0/~LOCAL TO "ILINK" ILINK8, 0/~LOCAL TO "ILINK" ILINK9, 0/~LOCAL TO "ILINK" PAGE / ROUTINE TO SERVICE A SEND REQUEST SNDSRV, 0 TAD (MSEND/~FIRST SET MODE TO SEND DCA KMODE/~PUT INTO MODE FLAG TAD LPTR/~GET CURRENT LINE POINTER DCA PRSERR/~SAVE LINE POSITION TAD PRSERR/~GET LINE POSITION JMS DPARS/~TRY TO PARSE OFF A DEVICE NAME JMP S50/~RETURN A DEVICE NAME ERROR DCA PRSERR/~SAVE LINE POINTER TAD (FNBLK/~GET FILE NAME BLOCK ADDRESS DCA FNPTR/~STORE IN POINTER TAD PRSERR/~GET STRING POINTER JMS PFNAM/~PARSE OFF THE FILE NAME JMP S52/~FILE NAME PARSE ERROR DCA PRSERR/~SAVE THE STRING POINTER TAD PRSERR/~GET THE STRING POINTER JMS NOSP/~FIND THE END OF STRING SKP/~GOT END OF STRING HERE JMP S50/~SYNTAX ERROR DCA PRSERR/~RETURN POINTER TAD DEVNUM/~GET THE DEVICE NUMBER PARSED JMS HFETCH/~FETCH A HANDLER FOR THIS JMP S54/~HANDLER FETCH ERROR DCA DIRBLK/~INIT FOR DIRECTORY SEARCH DCA FILFND/~INIT FILE FOUND FLAG DCA INIFLG/~CLEAR THE INIT DONE FLAG SNDSV1, TAD (FNBLK/~GET FILE NAME BLOCK ADDRESS DCA FCMP1/~SET FOR FILE TO FINE JMS LOOKUP/~FIND A MATCH FOR THIS FILE JMP S56/~DIRECTORY I-O ERROR JMP S00/~FILE NOT FOUND ISZ FILFND/~BUMP FILE FOUND COUNT JMS SNDPRO/~PROCESS THIS FILE FOR SEND JMP S60/~ERROR IN FILE SEND PROCESS TAD WILDF/~WAS WILD CARD FILE SPEC? SZA CLA/~SKIP IF NO JMP SNDSV1/~GOT WILD CARD, TRY FOR NEXT S00, TAD FILFND/~CHECK FOR ANY FILES FOUND SNA CLA/~SKIP IF YES JMP S58/~RETURN FILE NOT FOUND ERROR JMS BRKXMT/~BREAK THE SEND TAD PRSERR/~GET CURRENT CURSOR POSITION DCA LPTR/~UPDATE ISZ SNDSRV/~BUMP RETURN JMP I SNDSRV/~AND DONE / ERROR HANDLING FOR SEND PROCESS S50, CLA CLL/~INSURE CLEAR AC TAD (DEVERR/~GET DEVICE SPECIFICATION ERROR JMP I SNDSRV/~TAKE THE ERROR EXIT S52, CLA CLL/~INSURE CLEAR AC TAD (STXERR/~GET SYNTAX ERROR MESSAGE JMP I SNDSRV/~TAKE ERROR EXIT S54, CLA CLL/~INSURE CLEAR AC TAD (HFERR/~GET HANDLER FETCH ERROR MESSAGE JMP I SNDSRV/~TAKE ERROR EXIT / RETURN A DIRECTORY I-O ERROR MESSAGE S56, CLA CLL/~INSURE CLEAR AC TAD (DIOERR/~GET DIRECTORY I-O ERROR MESSAGE JMP I SNDSRV/~TAKE THE ERROR EXIT / RETURN A FILE NOT FOUND ERROR S58, TAD (NOFND/~GET ADDRESS OF MESSAGE JMP I SNDSRV/~RETURN VIA ERROR RETURN / RETURN A SEND PROCESS ERROR S60, TAD (SPERR/~GET A SEND PROCESS ERROR MESSAGE JMP I SNDSRV/~TAKE THE ERROR EXIT FILFND, 0/~HOLDS COUNT OF # OF FILES FOUND FNBLK, 0 0 0 0 / ROUTINE TO RE-SET THE SEND BRKXMT, 0 CLA CLL/~INSURE CLEAR AC DCA INIFLG/~CLEAR THE INIT SEND FLAG FPACK/~FORMAT A PACKET NODATA/~NO DATA FOR THIS PACKET STEOT/~"EOT" PACKET TYPE SPACK/~SEND THE PACKET 0/~NO RESPONSE JMP I BRKXMT/~DONE / ROUTINE TO SEND OUT A NAK WITHOUT DISTURBING THE NORMAL PACKET BUFFER SNDNAK, 0 TAD CURSEQ/~GET CURRENT SEQ NUMBER TAD (40-1/~CHAR IT AND SUB 1 AND C77/~MOD 64 DCA NAKPAK+2/~PUT IN NAK PACKET BUFFER TAD NAKPAK+1/~GET LENGTH TAD NAKPAK+2/~GET SEQ TAD NAKPAK+3/~GET TYPE JMS CKSUM/~CACULATE CHECKSUM DCA NAKPAK+4/~PUT IN CHECKSUM TAD REOL/~GET ANY EOL REQUIRED TAD (-40/~UN-CHAR IT SNA/~SKIP IF USING STA/~NO EOL, PUT IN -1 INSTEAD DCA NAKPAK+5/~PUT EOL IN REM8B; NAKPAK/~SEND NAK TO REMOTE JMP I SNDNAK/~DONE NAKPAK, 0 43/~LENGTH OF NAK PACKET 0/~SEQ NUMBER GOES HERE STNAK/~DATA TYPE 0/~CHECKSUM 0/~EOL IF USED -1/~TERMINATE NOFND, TEXT "FILE NOT FOUND@M@J@" PAGE / ROUTINE TO SERVICE A "GET" COMMAND GETSRV, 0 TAD LPTR/~GET CURRENT LINE POINTER DCA PRSERR/~SAVE TAD PRSERR/~RE-GET IT JMS DPARS /PARSE OUT THE DEVICE NAME/a006 JMP GSRV50 /ERROR IN DEVICE NAME /a006 JMS NOSP /FIND BEGINNING OF A FILE NAME JMP GSRV22 /GOT EOL, NO FILE NAME /a006 DCA GSRV90/~STORE BEGINNING ADDRESS TAD GSRV90/~NOW WE LOOK FOR JMS SP/~THE END OF THE LINE SKP/~GOT THE END OF THE LINE HERE JMP .-2/~NOT END YET, CONTINUE DCA PRSERR/~STORE POINTER TO EOL STA/~AC = -1 DCA I PRSERR/~TERMINATE FILE NAME WITH -1 DCA CURSEQ/~RE-SET THE SEQUENCE TAD GSRV90/~GET ADDRESS OF FILE NAME JMS XLATE7/~INSURE 7 BIT ASCII FILE NAME GSRV10, FPACK/~FORMAT THE PACKET GSRV90, 0/~DATA ADDRESS HERE STRIN/~RECIEVE INIT PACKET GSRV12, SPACK/~SEND THE PACKET 1/~GET RESPONSE GSRV80/~DISPATCH TABLE / SERVICE A NAK OR UNDEFINED GSRV15, ISZ RTRYC/~BUMP THE RE-TRY COUNTER JMP GSRV12/~TRY AGAIN JMP I GETSRV/~GIVE UP / SERVICE A SEND/INIT FROM THE REMOTE GSRV20, JMS INPSRV/~HANDLE JUST LIKE A RECEIVE JMP GSRV21/~ERROR RETURN FROM "INPSRV" ISZ GETSRV/~BUMP RETURN FOR NO ERROR TAD PRSERR/~UPDATE THE CURRENT LINE POINTER DCA LPTR GSRV21, JMP I GETSRV GSRV22, CLA CLL /MAKE SURE WE ARE CLEAR TAD (NOFND /ERROR FILE NAME NOT FOUND JMP I GETSRV /ERROR RETURN / GOT AN ERROR PACKET, DISPLAY ERROR AND ABORT GSRV40, JMS PRIPAK/~PRINT OUT THE ERROR PACKET JMP I GETSRV/~TAKE THE ERROR EXIT / DEVICE ERROR /a006 GSRV50, CLA CLL /MAKE SURE IT IS CLEAR /a006 TAD (DEVERR /ERROR MESSAGE ADDRESS /a006 JMP I GETSRV /RETURN ERROR /a006 / DISPATCH TABLE GSRV80, STERR; GSRV40/~ERROR PACKET RETURNED STSIN; GSRV20/~SEND INIT PACKET RETURNED STNAK; GSRV15/~NAK PACKET RETURNED 0/~TERMINATE TABLE /ROUTINE TO SERVICE A "RECEIVE" COMMAND RECSRV, 0 TAD LPTR/~GET CURRENT LINE POINTER DCA PRSERR/~SAVE IT TAD PRSERR/~GET IT BACK JMS NOSP/~GO FIND END OF LINE SKP/~GOT END OF LINE HERE JMP RECS60/~SOMETHING ELSE ON LINE, ERROR RPACK/~GET SEND/INIT PACKET FROM REMOTE RTDISP; RECS80/~DISPATCH BASED ON "RRTYP" JMP RECS60/~DON'T KNOW WHAT IT IS / GOT A SEND INIT PACKET RECS10, JMS INPSRV/~OFF TO HANDLE INPUT JMP RECS60/~ERROR RETURN / TAKE THE NON-ERROR RETURN RECS20, ISZ RECSRV/~BUMP FOR NON-ERROR RETURN JMP I RECSRV / TAKE THE ERROR RETURN RECS60, CLA JMP I RECSRV/~TAKE ERROR EXIT / DISPATCH TABLE RECS80, STSIN; RECS10/~SEND INIT PACKET DISPATCH STEOT; RECS60/~END OF CONNECTION STBRK; RECS20/~BREAK TRANSMISSION 0 RECS90, 0/~TEMP FOR "RECSRV" DEVERR, TEXT "DEVICE NAME ERROR@M@J@" DIOERR, TEXT "DIRECTORY IO ERROR@M@J@" ERRDSK, TEXT "DISK WRITE ERROR (NO ROOM ?)@M@J@" PAGE / ROUTINE TO SERVICE INPUT OF A FILE INPSRV, 0 TAD (MREC/~SET UP CURRENT MODE DCA KMODE/~FOR RECEIVE JMS SETINI/~SET UP INIT REGISTERS DCA CURSEQ/~RE-SET THE SEQUENCE NUMBER FPACK/~FORMAT A PACKET INIDAT/~PACKET DATA ADDRESS STACK/~"ACK" PACKET TYPE INPS01, SPACK/~SEND A PACKET 1/~AWAIT RESPONSE INPS91 /~DISPATCH TABLE ADDRESS / NAK OR UNDEFINED RESPONSE HERE INPS02, ISZ RTRYC/~GOT A NAK, CHECK RE-TRY COUNT JMP INPS01/~RE-TRY THE INIT IER02, JMS INPS60/~GIVE UP INPS03, FPACK/~FORMAT A PACKET NODATA/~NO DATA STACK/~"ACK" PACKET TYPE INPS05, SPACK/~SEND A PACKET 1/~AWAIT RESPONSE INPS90/~DISPATCH TABLE ADDRESS IER05, JMS INPS60 /UNDEFINED RESPONSE / GOT A DATA PACKET, WRITE TO OUTPUT FILE INPS10, TAD OFFLG/~CHECK THE OUTPUT FILE FLAG SNA CLA/~SKIP IF OUTPUT FILE OPEN IER10, JMS INPS60 /ABORT AND EXIT JMS WRIPAK/~WRITE THE PACKET TO THE FILE JMP INPS60/~ERROR WRITING PACKET JMP INPS03/~LOOP / GOT A FILE HEADER PACKET, OPEN FILE INPS20, TAD OFFLG/~CHECK IF OUTPUT FILE OPEN SZA CLA/~SKIP IF NO IER20, JMS INPS60 /ABORT IF FILE ALREADY OPEN TAD RRLEN/~GET CURRENT PACKET LENGTH TAD (-40-3/~CACULATE LENGTH OF DATA SPA/~SKIP IF DATA IN THE PACKET IER21, JMS INPS60 /ELSE AN ERROR TAD (RRDTA/~CACULATE LAST BYTE IN DATA DCA INPS81/~STORE IN POINTER STA/~AC = -1 DCA I INPS81/~TERMINATE NAME WITH A MINUS WORD TAD (FNBLK/~GET ADDRESS OF FILE NAME BLOCK DCA FNPTR/~SAVE FOR NAME PARSE TAD (RRDTA/~GET ADDRESS OF DATA IN PACKET JMS PFNAM/~PARSE OFF THE FILE NAME IER23, JMS INPS60 /ERROR IN FILE NAME / GET TARGET DEVICE CLA CLL/~CLEAR AC FROM FILE NAME PARSE TAD DEVNUM /GET DEVICE NUMBER PARSED /a006 DCA ODNUMB /SAVE OUTPUT DEVICE NUMBER TAD ODNUMB/~GET NUMBER BACK JMS HFETCH/~FETCH HANDLER FOR THIS DEVICE IER24, JMS INPS60 /HANDLER FETCH ERROR TAD (FNBLK/~GET ADDRESS OF FILE NAME BLOCK DCA INPS22/~PUT IN CALL TAD ODNUMB/~GET DEVICE NUMBER CIF 10/~IF = 1 JMS I USR/~CALL USER SERVICE ROUTINE 3/~ENTER INPS22, 0/~ 0/~ IER22, JMS INPS60 /ERROR (NO ROOM?) TAD INPS22/~GET NEW FILE START BLOCK DCA FSBLK/~SAVE TAD INPS22+1/~GET NEW FILE SIZE TAD (2/~CLOSE USES 2 BLOCKS ALLOW FOR IT /a010 DCA FLEN/~SAVE ISZ OFFLG/~SET FLAG FOR OUTPUT FILE OPEN JMS INIOUT/~INIT FOR OUTPUT TAD FNPTR/~GET POINTER TO 6 BIT FILE NAME JMS FILN8/~MAKE 8 BIT FORMATTED STRING PRI6B; FRMSG/~LET USER KNOW PRI8B; NAMBUF/~WHICH FILE WE ARE RECEIVING PRI6B; CRLF JMP INPS03/~LOOP / GOT AN END OF FILE PACKET INPS30, TAD OFFLG/~ANY OUTPUT FILE OPEN? SNA CLA/~SKIP IF YES IER30, JMS INPS60 /ERROR /a006 JMS CLOSEF/~CLOSE THE FILE IER31, JMS INPS60 /ERROR CLOSING THE FILE /a006 /d009 DCA OFFLG/~RE-SET FILE OPEN FLAG JMP INPS03/~CONTINUE / GOT AN END OF TRANSMISSION PACKET INPS40, TAD OFFLG/~WAS A FILE OPEN? SZA CLA/~SKIP IF NO JMS CLOSEF/~CLOSE ANY OPEN FILE NOP /ERROR CLOSING THE FILE /a009 FPACK/~FORMAT A PACKET NODATA/~NO DATA IN PACKET STACK/~"ACK" PACKET TYPE SPACK/~SEND THE PACKET 0/~NO RESPONSE ISZ INPSRV/~BUMP RETURN FOR NO ERROR JMP I INPSRV/~TAKE NON-ERROR EXIT / GOT AN ERROR PACKET INPS50, JMS PRIPAK/~PRINT THE PACKET DATA INPEXT, JMP I INPSRV /AND TAKE THE ERROR EXIT / TEMPS FOR "INPSRV" INPS80, 0 INPS81, 0 FPERR, TEXT "@M@JFATAL PACKET ERROR@M@J@" PAGE / ERROR DISPATCH TABEL FOR 'GET' AND 'RECEIVE' COMMANDS /a010 TBLDSP, IER05+1;FPERR /FATAL PACKAGE RECEIVED ERROR IER23+1;SYNERR /FILENAME SYNTAX ERROR IER24+1;DEVERR /DEVICE NAME ERROR IER22+1;ERRDSK /DISK FULL ERROR (NO ROOM) IER31+1;DIOERR /DIRECTORY IO ERROR,ERROR CLOSING FILE 0 /TERMINATE TABEL / ERROR HANDLING FOR INPUT INPS60, NOP /DUMMY RETURN FOR ERROR DISPATCH /m010 FPACK/~FORMAT A PACKET NODATA/~NO DATA STBRK /"NAK" PACKET TYPE /m010 SPACK/~SEND THE PACKET 0/~NO RESPONSE TAD (TBLDSP-2/~ GET THE TABLE ADDRESS -2 DCA X10/~SAVE IN INDEX REGISTER INERLP, ISZ X10/~ INCREMENT INDEX TAD I X10/~ GET THE TABLE ENTRY SNA/~ SKIP IF NOT END JMP NOTFND/~ NOT FOUND CIA/~ NEGATE TAD INPS60/~ GET THE ENTRY ADDRESS SZA CLA/~ MATCH JMP INERLP/~ TRY NEXT TAD I X10/~ GET TABLE ENTRY SKP NOTFND, TAD (RECERR/~GET ERROR MESSAGE JMP INPEXT/~TAKE THE ERROR RETURN / DISPATCH TABLES FOR "INPSRV" INPS90, STDAT; INPS10/~HANDLE DATA PACKETS STEOF; INPS30/~HANDLE EOF PACKET STEOT; INPS40/~HANDLE END OF TRANSMISSION PACKET STFIL; INPS20/~HANDLE FILE NAME PACKET STERR; INPS50/~HANDLE ERROR PACKET 0/~TERMINATE TABLE INPS91, STNAK; INPS02/~HANDLE A NAK PACKET STFIL; INPS20/~HANDLE FILE NAME PACKET STERR; INPS50/~HANDLE ERROR PACKET 0/~TERMINATE TABLE / ROUTINE TO CHECK FOR AN ALPHABETIC OR NUMERIC CHAR / ENTER WITH THE CHAR IN THE AC / EXIT + 2 IF ALPHABETIC OR NUMERIC WITH CHAR IN THE AC / EXIT + 1 IF NON-ALPHABETIC OR NUMERIC WITH CHAR IN THE AC ALPNUM, 0 JMS ALPHA/~CHECK FOR ALPHA FIRST SKP/~NON-ALPHA RETURN, MUST CHECK NUMERIC JMP ALPNM1/~IS ALPHA, TAKE RETURN + 2 JMS NUMRC/~CHECK IF NUMERIC SKP/~NOT NUMERIC ALPNM1, ISZ ALPNUM/~BUMP RETURN FOR ALPHA-NUMERIC JMP I ALPNUM/~DONE / ROUTINE TO CHECK FOR AN ALPHABETIC CHARACTOR / ROUTINE ASSUMES UPPER CASE / ENTER ROUTINE WITH CHAR IN THE AC / EXIT + 2 IF THE CHAR IS ALPHABETIC WITH THE CHAR IN THE AC / EXIT + 1 IF THE CHAR IS NOT ALPHABETIC WITH THE CHAR IN THE AC ALPHA, 0 DCA ALPHA1/~STORE THE CHAR FOR RETURN TAD ALPHA1/~GET THE CHAR TAD (-"Z-1/~TESTING FOR LETTER A-Z CLL/~INIT LINK FOR A FLAG TAD ("Z-"A+1 SZL/~SKIP IF NOT A LETTER ISZ ALPHA/~IS A LETTER, BUMP RETURN CLA CLL/~CLEAR AC TAD ALPHA1/~RESTORE CHAR IN THE AC JMP I ALPHA/~TAKE PROPER RETURN ALPHA1, 0/~TEMP FOR ALPHA ROUTINE / ROUTINE TO CHECK FOR A NUMERIC CHARACTOR / ENTER WITH THE CHAR TO CHECK IN THE AC / EXIT + 2 IF NUMERIC WITH THE CHAR IN THE AC / EXIT + 1 IF NON-NUMERIC WITH THE CHAR IN THE AC NUMRC, 0 DCA NUMRC1/~SAVE THE CHAR FOR RETURN TAD NUMRC1/~GET THE CHAR BACK TAD (-"9-1/~TESTING FOR 0-9 CLL/~INIT LINK FOR A FLAG TAD ("9-"0+1 SZL/~SKIP IF NOT A DIGIT ISZ NUMRC/~BUMP RETURN FOR NUMERIC CLA CLL/~CLEAR AC TAD NUMRC1/~RESTORE CHAR IN THE AC JMP I NUMRC/~DONE NUMRC1, 0/~TEMP FOR NUMRC CHECK ROUTINE PAGE / ROUTINE TO PACK TWO 6 BIT CHARS IN A 12 BIT WORD / ROUTINE EXPECTS POINTER AT "PACK6P" TO BE POINTING TO WHERE TO PUT / THE CHARS AND THE FLAG "PACK6F" TO FLAG HIGH BYTE OR LOW BYTE FOR / PACKING (4000 = HIGH BYTE, 0 = LOW BYTE) / CALL: PACK6 PACK60, 0 AND C77/~STRIP TO 6 BITS DCA PACK6T/~STORE TEMP CLA CLL CML RAR/~SET LINK=0, AC = 4000 TAD PACK6F/~GET CURRENT FLAG DCA PACK6F/~RETURN, LINK NOW CONTAINS FLAG SZL/~SKIP IF LINK IS ZERO (ON FIRST BYTE) TAD I PACK6P/~GET FIRST BYTE TAD PACK6T/~COMBINE WITH SECOND BYTE SNL/~SKIP IF ON SECOND BYTE BSW/~SWAP AROUND DCA I PACK6P/~RETURN SZL/~SKIP IF FIRST BYTE ISZ PACK6P/~BUMP POINTER TO NEXT JMP I PACK60/~DONE PACK6T, 0/~TEMP FOR "PACK6" ROUTINE / ROUTINE TO FETCH A DEVICE HANDLER BY HANDLER NUMBER / ENTER WITH NUMBER IN AC / EXIT WITH "HNDADR" POINTING TO ENTRY TO THE HANDLER AND RETURN / PLUS 2 IF SUCCESSFUL, AND RETURN + 1 IF ERROR HFETCH, 0 DCA HNUM/~STORE HANDLER NUMBER TAD (HNDLR/~GET THE HANDLER LOAD ADDRESS IAC /BUGFIX FOR 2 PAGE HANDLET /a003 DCA HADR /STORE IN CALL TAD HNUM/~GET HANDLER NUMBER BACK CIF 10/~USER IN FIELD 1 JMS I USR/~CALL USER SERVICE 0001/~FETCH IS FUNCTION 1 HADR, 0/~PUT WERE TO LOAD HANDLER HERE SKP/~ERROR LOADING HANDLER HERE ISZ HFETCH/~BUMP FOR NO ERROR CLA CLL/~INSURE CLEAR AC TAD HADR/~GET RETURNED HANDLER ADDRESS DCA HNDADR/~PUT WHERE ALL CAN ACCESS JMP I HFETCH/~RETURN HNUM, 0/~LOCAL TEMP FOR "HFETCH" / ROUTINE TO INPUT A BLOCK FROM DISK / ENTER WITH BLOCK NUMBER IN THE AC, AND THE BUFFER ADDRESS IN THE MQ / EXIT + 1 IF ERROR ON INPUT / EXIT + 2 IF SUCCESSFUL BLKIN, 0 DCA BLKIN1/~STORE BLOCK NUMBER IN CALL MQA/~GET THE BUFFER ADDRESS DCA BLKIN0/~PUT INTO THE CALL JMS I HNDADR/~CALL THE HANDLER FOR SERVICE 0200/~INPUT 2 128 WORD RECORDS BLKIN0, 0/~TO THE I-O BUFFER BLKIN1, 0/~BLOCK NUMBER HERE SKP/~ERROR RETURN ISZ BLKIN/~BUMP FOR SUCCESS RETURN CLA CLL/~RETURN AC = 0 JMP I BLKIN / ROUTINE TO WRITE A BLOCK TO THE DISK / ENTER: AC = BLOCK NUMBER TO WRITE / EXIT: RETURN + 2 = WRITE SUCCESSFUL / RETURN + 1 = WRITE FAILED BLKOUT, 0 DCA BLKOU1/~PUT BLOCK NUMBER IN CALL JMS I HNDADR/~CALL THE HANDLER 4200/~WRITE 1 BLOCK IOBUF/~OUTPUT BUFFER ADDRESS BLKOU1, 0/~BLOCK NUMBER GOES HERE SKP/~ERROR ON THE WRITE ISZ BLKOUT/~BUMP RETURN FOR NO ERROR CLA CLL/~RETURN AC = 0 JMP I BLKOUT/~EXIT / ROUTINE TO LOOKUP A FILE IN THE DIRECTORY / RETURN + 1 ON DIRECTORY I-O ERROR / RETURN + 2 IF FILE NOT FOUND / RETURN + 3 IF FILE FOUND / INITIALIZE DIRBLK TO ZERO IF DIRECTORY SEARCH FROM BEGINNING, / ELSE THE DIRECTORY SEARCH BEGINS WITH THE LAST MATCH. LOOKUP, 0 TAD DIRBLK/~CHECK IF START FROM BEGINNING SNA CLA/~SKIP IF NO JMP LUP1/~MUST READ IN BEGINNING OF DIRECTORY JMP LUP25/~CONTINUE SEARCH LOOP LUP0, TAD SLINK/~GET NEXT ENTRY NUMBER SNA CLA/~SKIP IF IS A NEXT ENTRY JMP LUP30/~NO NEXT ENTRY LUP1, TAD (DIRBUF/~GET THE DIRECTORY BUFFER ADDRESS MQL/~PUT INTO MQ REGISTER ISZ DIRBLK/~BUMP THE BLOCK NUMBER TAD DIRBLK/~GET THE BLOCK NUMBER IN THE AC JMS BLKIN/~INPUT A DIRECTORY BLOCK JMP I LOOKUP/~DIRECTORY I-O ERROR TAD SBLOCK/~GET STARTING BLOCK FOR THIS SEGMENT DCA FSBLK/~SAVE TO KEEP TRACK OF FILE POSITIONS TAD (SFILS/~GET POINTER TO FILE ENTRY BEGINNING DCA DPTR/~STORE IN A POINTER LUP20, TAD DPTR/~GET POINTER TO ENTRY IAC/~ADD 1 DCA DWORD/~DWORD POINTS TO LENGTH OF EMPTY TAD I DPTR/~GET FIRST WORD FROM ENTRY SNA CLA/~SKIP IF IS A FILE NAME JMP LUP25/~NOT FILE, HANDLE EMPTY TAD SADDNL/~GET NUMBER OF ADDITIONAL INFO WORDS CIA/~GOTTA MAKE IT POSITIVE TAD DPTR/~ADD CURRENT POINTER TAD (5-1/~POINT TO LENGTH OF FILE DCA DWORD/~SAVE FOR NEXT TRY TAD I DWORD/~CHECK FOR TENTATIVE FILE SNA CLA/~GOOD FILE HAS SOME LENGTH JMP LUP25/~TENTATIVE FILE, SKIP IT TAD DPTR/~NOW GET THIS TRY JMS FMATCH/~TRY TO MATCH JMP LUP25/~NO MATCH TAD DPTR/~GET POINTER TO NAME JMS FILN8/~GET FILE NAME INTO A BUFFER TAD SADDNL/~GET NUMBER OF ADDITIONAL WORDS SNA CLA /SKIP IF DATE IS PRESENT JMP LUP22/~NO DATE IN THIS DIRECTORY TAD DPTR/~GET POINTER TO FILE NAME TAD (4/~GET PAST THE NAME DCA DPTR/~STORE IN POINTER TAD I DPTR/~GET THE DATE WORD LUP22, JMS FILD8 /AND CONVERT /m013 TAD I DWORD/~GET FILE LENGTH DCA FLEN/~STORE LENGTH OF FILE TAD DWORD/~GET POINTER TO NEXT ENTRY IAC/~BUMP AHEAD TO NEXT ENTRY DCA DPTR/~SET FOR POSSIBLE NEXT SEARCH ISZ LOOKUP/~BUMP FOR FILE FOUND LUP30, ISZ LOOKUP/~JUMP HERE FOR FILE NOT FOUND JMP I LOOKUP LUP25, TAD I DWORD/~GET PREVIOUS SIZE CIA/~MAKE IT POSITIVE TAD FSBLK/~GET CURRENT START BLOCK DCA FSBLK/~UPDATE CURRENT START BLOCK TAD DWORD/~GET POINTER TO PREVIOUS IAC/~POINT TO CURRENT DCA DPTR/~RETURN TO POINTER ISZ SENTRY/~BUMP ENTRY COUNTER JMP LUP20/~CONTINUE LOOP JMP LUP0/~GO TRY NEXT DIRECTORY SEGMENT PAGE / DIRECTORY BLOCK BUFFER DIRBUF= ./~DEFINE BEGINNING OF BUFFER SENTRY, 0/~# OF ENTRYS IN SEGMENT SBLOCK, 0/~STARTING BLOCK NUMBER OF FIRST FILE SLINK, 0/~LINK TO NEXT DIRECTORY SEGMENT STENT, 0/~POINTER TO LAST WORD OF TENTATIVE ENTRY SADDNL, 0/~# OF ADDITIONAL INFO WORDS SFILS, 0/~BEGINNING OF FILE ENTRYS *DIRBUF ZBLOCK 400/~RESERVE SPACE FOR DIRECTORY SEGMENT PAGE HNDLR=./~DEFINE HANDLER LOAD LOCATION *HNDLR+400/~RESERVE SPACE FOR 2 PAGE HANDLER IOSIZ= 400 IOBUF, ZBLOCK IOSIZ / ROUTINE TO COMPARE TWO FILE NAMES FOR EQUALITY / THE ROUTINE WILL CHECK EACH OF THE 8 FILE NAME CHARS AND IF A / CHAR IN THE FIRST FILE NAME (THE ONE WE ARE LOOKING FOR) CONTAINS / A "?" IT WILL MATCH ON THE SECOND FILE NAME CHAR. / ENTER WITH "FCMP1" POINTING TO THE FILE NAME TO FIND, AND "FCMP2" / POINTING TO THE FILE NAME TO TRY AND MATCH. EXIT + 1 IF NO MATCH / AND EXIT + 2 IF MATCH. (IF NON-ZERO AC ON ENTRY, THE AC IS ASSUMED / TO HAVE THE VALUE FOR "FCMP2") FMATCH, 0 SZA/~SKIP IF NO ARGUMENT IN AC DCA FCMP2/~THIS ARGUMENT CAME IN THE AC TAD FCMP1/~GET ADDRESS OF FIRST FILE NAME BLOCK DCA GET6P/~STORE IN A POINTER DCA GET6F/~INIT FLAG FOR "GET6" ROUTINE TAD FCMP2/~GET ADDRESS OF SECOND FILE NAME BLOCK DCA FMATP/~STORE IN A LOCAL POINTER DCA FMATF/~INIT LOCAL FLAG TAD (-10/~8 CHARS TO DO DCA FMATC/~STORE IN LOCAL COUNTER FMAT1, CLA CLL CML RAR/~AC=4000, LINK=0 TAD FMATF/~GET FLAG DCA FMATF/~RETURN FLAG, LINK CONTAINS STATUS TAD I FMATP/~GET A WORD FROM THE SECOND NAME SZL/~SKIP IF ON THE TOP BYTE ISZ FMATP/~GOTTA BUMP THE POINTER SNL/~SKIP IF ON THE BOTTOM BYTE BSW/~SWAP TOP BYTE TO BOTTOM AND C77/~KEEP ONLY BOTTOM 6 BITS DCA FMATT/~STORE IN A TEMP GET6/~NOW GET A CHAR FROM FIRST NAME TAD (-77/~CHECK IF WILD SNA/~SKIP IF NO JMP FMAT2/~NO MATCH CHECK ON A WILD CARD TAD C77/~RESTORE THE CHAR CIA/~NEGATE FOR COMPARE TAD FMATT/~COMPARE WITH SECOND FILE NAME SZA CLA/~SKIP IF IS A MATCH JMP I FMATCH/~THIS IS NOT A MATCH FMAT2, ISZ FMATC/~BUMP COUNTER JMP FMAT1/~LOOP, MORE TO CHECK ISZ FMATCH/~BUMP RETURN FOR MATCH JMP I FMATCH/~GOT A MATCH FMATP, 0/~POINTER FOR "FMATCH" FMATC, 0/~COUNTER FOR "FMATCH" FMATF, 0/~FLAG FOR "FMATCH" FMATT, 0/~TEMP FOR "FMATCH" FCMP1, 0/~POINTER FOR FIRST FILE NAME BLOCK FCMP2, 0/~POINTER FOR SECOND FILE NAME BLOCK / OS8 DIRECTORY FILE DATA SETUP / ENTER WITH THE DIRECTORY DATE WORD IN THE AC / EXIT WITH THE DATE IN THE BUFFER "DATBUF" FILD8, 0 DCA FILD89 /SAVE THE DATE WORD TAD FILD89 /GET DATA WORD AND (7 /KEEP ONLY YEAR BITS TAD (116 /ADD 78 YEARS MQL /PUT INTO MQ REGISTER TAD (DATEYR /GET POINTER TO YEAR JMS DECCON /CONVERT TO ASCII DATE TAD FILD89 /GET DATE WORD BACK CLL RTR /SHIFT DAY DOWN RAR AND (37 /KEEP ONLY DAY BITS MQL /PUT IN MQ REGISTER TAD (DATEDA /GET POINTER TO DAY JMS DECCON /CONVERT TO ASCII DAY TAD FILD89 /GET DATE WORD BACK BSW /GET MONTH CLL RTR /DOWN AND (17 /KEEP ONLY MONTH BITS MQL /INTO MQ REGISTER TAD (DATEMO /GET ADDRESS OF WHERE TO PUT MONTH JMS DECCON /CONVERT JMP I FILD8 /ALL DONE / FILD89, 0 /TEMP FOR "FILD8" / ROUTINE TO CONVERT A BINARY VALUE INTO A TWO DIGIT ASCII DECIMAL / NUMBER. ENTER WITH WHERE TO STORE THE CONVERTED NUMBER IN THE / AC AND THE NUMBER IN THE MQ REGISTER. DECCON, 0 DCA DECC20/~STORE THE POINTER TAD ("0&177-1/~GET AN ASCII ZERO DCA I DECC20/~START OUT WITH A ZERO MQA/~GET THE BINARY VALUE DECC01, ISZ I DECC20/~BUMP TAD (-12/~SUB 10 SMA/~SKIP IF NO MORE DIVISION JMP DECC01/~ELSE KEEP GOING TAD (12+"0&177/~CONVERT REMAINDER TO ASCII ISZ DECC20/~BUMP POINTER DCA I DECC20/~STORE /d013L JMS FMTDAT /FORMAT FOR PRINTING JMP I DECCON/~DONE DECC20, 0 /LOCAL POINTER TO DECCON /d013L COMMENT OUT THIS WHOLE ROUTINE FOR SPACE AND GENERIC KERMIT CONFORMITY / ROUTINE TO SET UP THE DATE IN A MM-DD-YY FORMAT TO PUT IN FRONT / OF A FILE TO PASS THE FILES DATE (TEMPORY AND NOT PART OF THE / KERMIT PROTOCAL) /d013L FMTDAT, 0 / TAD DATEMO /GET FIRST CHAR OF DATE / DCA FDATE /MOVE IT / TAD DATEMO+1 / DCA FDATE+1 / TAD DATEDA / DCA FDATE+3 / TAD DATEDA+1 / DCA FDATE+4 / TAD DATEYR / DCA FDATE+6 / TAD DATEYR+1 / DCA FDATE+7 / JMP I FMTDAT /QUICK AND DIRTY DATBUF, "#&177 /FILE CREATION DATE ATTRIBUTE 6+40 /LENGTH OF DATE (CHAR(X)) DATEYR, 0 /ASCII YEAR GOES HERE 0 DATEMO, 0 /ASCII MONTH GOES HERE 0 DATEDA, 0 /ASCII DAY GOES HERE 0 -1 /TERMINATE / FORMATED DATE GOES HERE SETDAT, "<&177 /COMMENT SIGN / FDATE, 0 / 0 / "-&177 / 0 / 0 / "-&177 / 0 / 0 / 12 / 15 / -1 PAGE / ROUTINE TO INPUT BYTES FROM THE LOOKED UP INPUT FILE / ROUTINE EXPECTS THE DEVICE NUMBER IN "DEVNUM", THE FILES START / BLOCK NUMBER IN "FSBLK", AND THE FILES LENGTH IN "FLEN" / ENTER: "DEVNUM", "FSBLK", AND "FLEN" ARE PROPERLY INITIALIZED / EXIT: RETURN + 3 WITH THE CHAR IN THE AC IF SUCCESSFUL / RETURN + 2 IF END OF FILE / RETURN + 1 IF FATAL I-O ERROR UNPACK, 0 JMP I .+1/~DISPATCH TO PROPER CO-ROUTINE UNPEXT, 0/~EXIT POINT FOR UNPACK AND C377/~KEEP ONLY CHAR BITS DCA UPTEMP/~SAVE THE CHAR TAD UPTEMP/~GET BACK TAD MCTRLZ/~CHECK FOR EOF SZA CLA/~SKIP IF EOF ISZ UNPACK/~BUMP FOR SUCCESSFUL RETURN TAD UPTEMP/~GET CHAR BACK UNPEOF, ISZ UNPACK/~RETURN HERE IF EOF UNPERR, JMP I UNPACK/~RETURN HERE IF FATAL I-O ERROR / HERE FOR CHAR 1 UNPAK1, TAD I UNPAKP/~GET A WORD FROM THE BUFFER ISZ UNPAKP/~BUMP POINTER FOR CHAR 2 JMS UNPEXT/~SET CO-ROUTINE POINTER AND EXIT / HERE FOR CHAR 2 TAD I UNPAKP/~GET CHAR 2 JMS UNPEXT/~SET CO-ROUTINE POINTER AND EXIT / HERE FOR CHAR 3 STA/~SET AC = -1 TAD UNPAKP/~AC = POINTER - 1 DCA UNPAKT/~STORE IN TEMP TAD I UNPAKT/~GET PREVIOUS CHAR AND C7400/~KEEP ONLY BITS 0-3 CLL RTR/~SHIFT DOWN TO BITS 4-7 RTR/~GOTIT DCA UNPAKT/~SAVE IT TAD I UNPAKP/~GET THE NEXT HALF AND C7400/~KEEP ONLY BITS 0-3 CLL RTL/~GET DOWN TO BITS 8-11 RTL/~ RAL/~GOTIT TAD UNPAKT/~COMBINE JMS UNPEXT/~EXIT / HERE TO CHECK FOR BUFFER EMPTY AND READ IN NEXT BLOCK IF NEEDED CLA CLL/~INSURE CLEAR LINK ISZ UNPAKP/~BUMP BUFFER POINTER TAD UNPAKP/~GET OUR CURRENT POINTER TAD (-IOBUF-IOSIZ/~COMPARE WITH THE END OF BUFFER CLA/~CLEAR JUST THE AC SNL/~IF LINK SET WE ARE PAST END OF BUFFER JMP UNPAK1/~CONTINUE UNPACKING ISZ FCBLK/~BUMP THE CURRENT BLOCK ISZ FLEN/~BUMP THE FILE LENGTH COUNTER SKP/~NOT END OF FILE JMP UNPEOF/~RETURN END OF FILE HERE / ENTER HERE ON FIRST READ CALL FOR FILE INPUT UNPAK5, TAD [IOBUF/~GET ADDRESS OF INPUT BUFFER MQL/~PUT INTO MQ TAD FCBLK/~GET THE FILES CURRENT BLOCK JMS BLKIN/~AND READ IN THE NEXT BLOCK JMP UNPERR/~TAKE I-O ERROR RETURN TAD [IOBUF/~GET ADDRESS OF BEGINNING OF BUFFER DCA UNPAKP/~SET UP POINTER JMP UNPAK1/~NOW START UNPACKING THIS BUFFER UNPAKP, 0/~POINTER FOR UNPACK ROUTINE UNPAKT, 0/~TEMP FOR UNPACK ROUTINE FCBLK, 0/~FILE CURRENT BLOCK / ROUTINE TO INITIALIZE FOR FILE INPUT. THIS ROUTINE SETS UP THE / CURRENT BLOCK TO BE READ FROM THE FILE AND SETS THE CO-ROUTINE / DISPATCH ADDRESS TO BEGIN READING BYTES FROM THE FILE. CALL THIS / ROUTINE AFTER SETTING UP THE FOLLOWING: / DEVNUM = OS/8 DEVICE NUMBER / FSBLK = STARTING BLOCK NUMBER / FLEN = FILE SIZE INPINT, 0 TAD FSBLK/~GET FILES STARTING BLOCK DCA FCBLK/~STORE LOCAL FOR INPUT ROUTINE TAD (UNPAK5/~GET ADDRESS OF FIRST CO-ROUTINE DCA UNPEXT/~STORE FOR FIRST DISPATCH JMP I INPINT/~INPUT IS INITIALIZED / ROUTINE TO WRITE A BYTE TO THE OUTPUT FILE /a013H(ANY PARITY DATA) / ENTER: AC = BYTE TO WRITE / EXIT: + 2 = WRITE SUCCESSFUL / + 1 = WRITE NOT SUCCESSFUL WRIBYT, 0 /d013J AND [177/~MASK OUT THE ASCII PARITY BIT /m013 /d013J TAD PARITY/~SET PARITY TO MARK OR SPACE /m013F /m013H JMP I WRIB01/~JUMP INTO CO-ROUTINE WRIB01, 0/~CO-ROUTINE ADDRESS HERE ISZ WRIBYT/~BUMP RETURN FOR SUCCESS WRIB02, JMP I WRIBYT/~EXIT WRIB10, JMS WRIB01/~JUMP HERE TO START BYTE 1 NEXT / HERE TO WRITE BYTE 1 WRIB11, DCA I WRIBP/~STORE BYTE IN BUFFER ISZ WRIBP/~BUMP POINTER JMS WRIB01/~DONE WITH FIRST / HERE TO WRITE BYTE 2 DCA I WRIBP/~STORE BYTE IN BUFFER JMS WRIB01/~DONE WITH SECOND / HERE TO WRITE BYTE 3 DCA WRIBT/~STORE THE CHAR TEMP STA/~AC = -1 TAD WRIBP/~GET BUFFER POINTER DCA WRIBP/~BACK UP POINTER BY 1 TAD WRIBT/~GET CHAR BACK RTL; RTL/~SHIFT HIGH BITS OF BYTE UP IN THE WORD AND C7400/~KEEP ONLY TOP 4 BITS TAD I WRIBP/~COMBINE WITH BYTE IN THE BUFFER DCA I WRIBP/~AND RETURN ISZ WRIBP/~BUMP POINTER TAD WRIBT/~GET CHAR BACK BSW; RTL/~GET LOW 4 BITS UP AND C7400/~KEEP ONLY THOSE BITS TAD I WRIBP/~COMBINE DCA I WRIBP/~AND RETURN ISZ WRIBP/~BUMP POINTER AHEAD CLA CLL/~INSURE LINK IS CLEAR TAD WRIBP/~GET CURRENT BUFFER POINTER TAD (-IOBUF-IOSIZ/~CHECK FOR BUFFER FULL CLA/~CLEAR AC, LINK HAS STATUS SNL/~SKIP IF BUFFER FULL JMP WRIB10/~BUFFER NOT FULL, LEAVE TAD FCBLK/~GET CURRENT BLOCK TO WRITE JMS BLKOUT/~AND WRITE IT JMP WRIB02/~ERROR WRITING ISZ OFLEN/~BUMP FILE SIZE COUNTER ISZ FCBLK/~BUMP CURRENT BLOCK NUMBER ISZ FLEN/~BUMP DISK ROOM COUNT SKP/~HERE IF MORE ROOM ON DISK JMP WRIB02/~NO MORE ROOM, ERROR TAD [IOBUF/~GET BUFFER ADDRESS DCA WRIBP/~RE-SET BUFFER POINTER JMP WRIB10/~BACK TO START OVER WRIBP, 0/~POINTER FOR FILE WRITE ROUTINES WRIBT, 0/~TEMP FOR FILE WRITE ROUTINES OFLEN, 0/~COUNTER FOR OUTPUT FILE LENGTH / FILE OUTPUT ROUTINES / ROUTINE TO INITIALIZE FOR OUTPUT / ENTER: FSBLK = STARTING BLOCK FOR OUTPUT FILE / FLEN = MAX SIZE FOR FILE / EXIT: NOTHING INIOUT, 0 TAD [IOBUF/~GET BUFFER ADDRESS DCA WRIBP/~PUT INTO POINTER TAD FSBLK/~GET FILE START BLOCK DCA FCBLK/~PUT INTO FILE CURRENT BLOCK STA/~AC = -1 TAD FLEN/~GET FILE LENGTH DCA FLEN/~STORE AS -FILE LENGTH -1 DCA OFLEN/~INIT ACTUAL FILE LENGTH COUNTER TAD (WRIB11/~INSURE CO-ROUTINE LINK SET DCA WRIB01 JMP I INIOUT PAGE / ROUTINE TO FLUSH THE BUFFER AND CLOSE THE OUTPUT FILE / ENTER: NOTHING / EXIT: + 2 = FILE CLOSE SUCCESSFUL / + 1 = FILE CLOSE NOT SUCCESSFUL CLOSEF, 0 TAD (32/~PUT IN AN EOF JMP CLO15/~SEND IT FIRST CLO10, TAD WRIBP/~GET CURRENT BUFFER POINTER TAD (-IOBUF/~COMPARE WITH BEGINNING SNA CLA/~SKIP IF BUFFER NOT EMPTY JMP CLO20/~BUFFER EMPTY, QUIT CLO15, JMS WRIBYT/~WRITE OUT A ZERO JMP CLOXIT /ERROR IN WRITING /m009 JMP CLO10/~GO AGAIN CLO20, TAD OFLEN/~GET OUTPUT FILE LENGTH DCA CLOF1/~PUT INTO CALL TAD ODNUMB/~GET OUTPUT DEVICE NUMBER CIF 10/~USR IN FIELD 1 JMS I USR/~CALL USR 4/~CLOSE FUNCTION FNBLK/~ADDRESS OF FILE NAME BLOCK CLOF1, 0/~FILE LENGTH HERE SKP/~ERROR HERE ISZ CLOSEF/~BUMP RETURN FOR NO ERROR CLOXIT, CLA CLL /ALWAYS RETURN AC = 0 /m009 DCA OFFLG /CLEAR THE OUTPUT FILE OPEN FLAG /a009 /~THIS HAPPENS EVEN IF INPUT CLOSE /a009 /~FILE,BUT IT SHOULD NOT MATTER /a009 JMP I CLOSEF / ROUTINE TO WRITE THE CURRENT INPUT PACKET TO THE OUTPUT FILE / ENTER: NOTHING / EXIT: + 2 = WRITE SUCCESSFUL / + 1 = WRITE NOT SUCCESSFUL WRIPAK, 0 TAD RRLEN/~GET LENGTH OF PACKET TAD (RRDTA-40-3/~CACULATE END OF BUFFER DCA W90/~PUT INTO POINTER DCA I W90/~ZERO AFTER END OF BUFFER TAD (RRDTA/~GET ADDRESS OF DATA DCA W90/~PUT INTO POINTER W10, TAD I W90/~GET A CHAR FROM PACKET SNA/~SKIP IF NOT END JMP W60/~END, EXIT CIA/~NEGATE FOR COMPARE TAD RQCTL/~COMPARE WITH CURRENT QUOTE CHAR SNA CLA/~SKIP IF NOT QUOTE CHAR JMP W20/~IS QUOTE, HANDLE SPECIAL TAD W92/~WAS LAST CHAR A QUOTE? SZA CLA/~SKIP IF NO TAD (-100/~IT WAS, FIX UP THIS CHAR JMP W25/~HANDLE REST BELOW W20, TAD W92/~CURRENT CHAR A QUOTE, CHECK PREVIOUS SNA CLA/~SKIP IF YES JMP W30/~JUST THIS CHAR IS QUOTE, SET FLAG W25, TAD I W90/~GET CHAR FROM BUFFER JMS WRIBYT/~SEND TO OUTPUT JMS I WRIPAK/~ERROR IN OUTPUT JMP W35/~FINISH BELOW W30, CLA CLL IAC/~GOTA SET FLAG FOR QUOTE CHAR W35, DCA W92/~SET UP QUOTE FLAG ISZ W90/~BUMP POINTER JMP W10/~LOOP W60, ISZ WRIPAK/~BUMP RETURN FOR OK JMP I WRIPAK/~DONE W90, 0/~POINTER FOR "WRIPAK" W92, 0/~TEMP FOR "WRIPAK" PAGE / SEND PROCESSING SNDPRO, 0 TAD INIFLG/~CHECK IF SEND/INIT HAS BEEN DONE SZA CLA/~SKIP IF NO JMP SNDP10/~RIGHT INTO FILE TRANSFER TAD (DEFCK/~SET UP DEFAULT CHECKSUM DCA RCHKT TAD (DEFEOL/~GET DEFAULT EOL DCA REOL/~AND SET IT TAD (DEFQCTL/~GET DEFAULT QUOTE CONTROL CHAR DCA RQCTL/~AND SET IT UP TAD (DEFMAXL+40/~GET DEFAULT MAX BUFFER SIZE DCA RMAXL/~SET IT UP DCA CURSEQ/~RE-SET SEQUENCE NUMBER JMS SNDI00/~HANDLE "SEND-INIT" JMP SNDP80/~ERROR IN "SEND-INIT" / SEND FILE HEADER DISPATCH ROUTINE SNDP10, FPACK/~FORMAT A PACKET NAMBUF/~ADDRESS OF FILE HEADER FOR DATA STFIL/~"FIL" PACKET TYPE SNDP11, SPACK/~SEND A PACKET 1/~AWAIT RESPONSE SNDP96/~DISPATCH TABLE ADDRESS / GOT A NAK OR UNDEFINED HERE SNDP12, ISZ RTRYC/~BUMP THE COUNTER JMP SNDP11/~TRY AGAIN JMP SNDP80/~ERROR / FILE CREATION DATE HANDLING SNDP15, TAD RCAPAS/~CHECK IF REMOTE SUPPORTS FILE AND (10/~ ATTRIBUTES SNA CLA/~SKIP IF YES JMP SNDP20/~SKIP IF NO FPACK/~FORMAT PACKET DATBUF/~DATE DATA STATT/~"ATT" PACKET TYPE SNDP16, SPACK/~SEND THE PACKET 1/~AWAIT RESPONSE SNDP98/~DISPATCH TABLE ADDRESS JMP SNDP80/~NONE OF THE TYPES IN OUR TABLE / GOT ACK HERE SNDP20, CLA CLL PRI6B; FSMSG/~TELL USER WE ARE SENDING A FILE PRI8B; NAMBUF/~TELL THEM THE NAME OF THE FILE JMS SLOOP SKP /ERROR RETURN ISZ SNDPRO /BUMP FOR NON-ERROR EXIT JMP I SNDPRO SNDP80, TAD (SPERR/~GET ERROR MESSAGE JMP I SNDPRO/~TAKE ERROR EXIT / DATA SEND LOOP / ROUTINE TO GET CHARS FROM THE INPUT BUFFER AND SEND THEM TO REMOTE / VIA PACKET TRANSFERS. RETURN + 1 IF ERROR, + 2 IF DONE. SLOOP, 0 JMS INIOPB/~INIT OUTPUT PACKET HOLD BUFFER JMS INPINT/~INIT INPUT FILE SLOP01, JMS UNPACK/~UNPACK A CHAR FROM THE BUFFER JMP SLOP75/~HERE ON FATAL I-O ERROR JMP SLOP15/~HERE ON EOF AND C177/~MASK OUT THE ASCII PARITY BIT/m013 JMS OPBUF/~PUT INTO PACKET BUFFER SKP/~RETURN HERE ON BUFFER FULL JMP SLOP01/~RETURN HERE IF STILL ROOM / PACKET IS FULL HERE, WE MUST SEND IT FPACK/~FORMAT A PACKET HOLDBF/~DATA ADDRESS STDAT/~"DAT" PACKET TYPE SLOP05, SPACK/~SEND PACKET 1/~AWAIT RESPONSE SLOP90/~RESPONSE TABLE ADDRESS / HERE ON NAK OR FALL THRU ON UNDEFINED RESPONSE ABOVE SLOP10, ISZ RTRYC/~BUMP THE RE-TRY COUNTER JMP SLOP05/~TRY AGAIN JMP SLOP75/~GIVE UP / HERE ON END OF FILE -- SEND THEM WHAT WE HAVE SLOP15, FPACK/~FORMAT A PACKET HOLDBF/~ADDRESS OF DATA STDAT/~"DAT" PACKET TYPE SLOP20, SPACK/~SEND A PACKET 1/~AWAIT RESPONSE SLOP92/~DISPATCH TABLE ADDRESS / NAK FOR LAST PACKET SLOP25, ISZ RTRYC/~BUMP RE-TRY COUNTER JMP SLOP20/~TRY AGAIN JMP SLOP75/~GIVE UP / ACK FOR FINAL PACKET, SEND AN EOF PACKET SLOP35, JMS SNDP/~SEND A PACKET NODATA/~NO DATA STEOF/~MAKE IT AN EOF PACKET JMP SLOP75/~NAK JMP SLOP75/~NOT NAK OR ACK ISZ SLOOP/~EOF ACCEPTED, BUMP FOR GOOD RETURN JMP I SLOOP/~TAKE GOOD RETURN / JUMP HERE FOR ERROR EXIT SLOP75, TAD (SPERR/~GET ADDRESS OF ERROR MESSAGE JMP I SLOOP/~EXIT SLOP90, STACK; SLOP01/~ACK, CONTINUE STNAK; SLOP10/~NAK, HANDLE 0 SLOP92, STACK; SLOP35/~ACK, CONTINUE STNAK; SLOP25/~NAK, HANDLE 0 PAGE / COMMAND DISPATCH TABLE FOR SEND SERVICE SNDP96, STACK; SNDP15/~FILE HEADER ACKNOWLEDGED STNAK; SNDP12/~NAK RETURNED, RE-TRY 0/~END OF TABLE SNDP98, STACK; SNDP20/~DATE ATTRIBUTE ACKNOWLEDGED 0/~END OF TABLE / ROUTINE TO HANDLE A "SEND-INIT" COMMAND / RETURN + 1 IF ERROR / RETURN + 2 IF SUCCESSFUL SNDI00, 0 FPACK/~FORMAT A PACKET INIDAT/~ADDRESS OF DATA FOR PACKET STSIN/~"SIN" PACKET TYPE SNDI02, SPACK/~SEND A PACKET 1/~AWAIT RESPONSE SNDI80/~RESPONSE TABLE TYPE / HERE ON NAK OR UNDEFINED SNDI05, ISZ RTRYC/~BUMP RE-TRY COUNTER JMP SNDI02/~TRY AGAIN JMP I SNDI00/~TAKE ERROR EXIT / HERE ON ACK SNDI10, JMS SETINI/~SET UP THE INIT REGISTERS CLA CLL IAC/~NOW FLAG THE SEND/INIT DONE DCA INIFLG/~BY MAKING THIS NON-ZERO ISZ SNDI00/~BUMP FOR NON-ERROR RETURN JMP I SNDI00/~BACK TO MAIN SEND PROCESSING SNDI80, STACK; SNDI10 /GOT AN ACK STNAK; SNDI05 /NAK 0 /END OF TABLE / ROUTINE TO MOVE THE SEND/INIT OR RECEIVE/INIT PACKET INTO THE / INIT REGISTERS SETINI, 0 TAD (RMAXL/~GET ADDRESS OF RECEIVE INIT REGISTERS MQL/~SAVE FOR "CLEAR" ROUTINE TAD (RMAXL-RCAPAS-1/~GET MINUS LENGTH OF # OF REGISTERS CLEAR /CLEAR OUT A CHUNK OF MEMORY TAD (RMAXL/~GET ADDRESS OF RECEIVE INIT REGISTERS MQL/~SAVE FOR "MOVE" ROUTINE TAD RRLEN/~GET LENGTH OF PACKET JUST INPUT TAD (-40-4/~COUNT OF DATA RECEIVED CIA/~MAKE IT NEGATIVE DCA MOVE4/~SAVE FOR "MOVE" ROUTINE TAD (RRDTA/~ADDRESS OF DATA IN PACKET MOVE/~MOVE THE INIT REGISTERS JMP I SETINI/~DONE / HANDLE AN ABORT REQUEST ABORT, CLA CLL/~INSURE CLEAR AC DCA CCFLAG/~RE-SET THIS FLAG TAD KMODE/~GET CURRENT MODE TAD (-MSEND/~IS IT A SEND? SZA/~SKIP IF YES JMP ABORT2/~NOT SEND JMS SNDP/~SEND OUT A PACKET ABORT9/~WHICH HAS A "D" IN THE DATA STEOF/~AND IS AN EOF PACKET NOP/~WE GOT NAK BACK HERE NOP/~WE GOT NEITHER NAK OR ACK HERE JMS BRKXMT/~BREAK THE SEND JMP ABORT3/~FINISH THE ABORT ABORT2, TAD (MSEND-MREC/~CHECK IF IN RECEIVE MODE SZA CLA/~SKIP IF YES JMP ABORT3/~JUST BACK TO COMMAND LOOP JMS SNDP/~SEND A PACKET BACK FOR AN ABORT NODATA /NO DATA/a009 STBRK /BREAK TRANSMISSION /a009 NOP/~NAK HERE CLA TAD OFFLG /GET FILE OPEN FLAG /a009 SZA CLA /IT SHOULD BE OPEN YET? /a009 JMS CLOSEF /SO CLOSE IT!!! /a009 CLA ABORT3, TAD (CCABRT/~GET ADDRESS OF ERROR MESSAGE JMP CLOOP7/~DISPLAY THE ABORT ABORT9, "D&137/~DATA PACKET FOR SEND ABORT -1 CCABRT, TEXT "@M@JCONTROL-C ABORT@M@J@" PAGE / ROUTINE TO PRINT 6 BIT BYTES ON THE TTY. ENTER WITH THE ADDRESS OF / THE TEXT IN THE AC OR IN THE CALL + 1. PRI6B0, 0 SZA/~SKIP IF TEXT ADDRESS AT CALL + 1 JMP PRI6B1/~ADDRESS IN THE AC TAD I PRI6B0/~GET THE ADDRESS ISZ PRI6B0/~BUMP THE RETURN PRI6B1, MQL/~SAVE IN THE MQ REGISTER TAD (OTTY/~GET ADDRESS OF THE TTY OUTPUT ROUTINE JMS SIXB/~DO THE PRINT JMP I PRI6B0/~DONE / SIX BIT TEXT REMOTE OUTPUT ROUTINE / ROUTINE TO OUTPUT FROM 6 BIT STORAGE TO THE REMOTE LINE. ENTER WITH / THE ADDRESS OF THE TEXT IN THE AC OR WITH A CLEAR AC THE ADDRESS IS / AT THE CALL + 1 REM6B0, 0 SZA/~SKIP IF ADDRESS AT CALL + 1 JMP REM6B1/~ADDRESS IN THE AC TAD I REM6B0/~GET ADDRESS AT CALL + 1 ISZ REM6B0/~BUMP THE RETURN REM6B1, MQL/~PUT ADDRESS IN MQ REGISTER TAD (OREM/~GET ADDRESS OF REMOTE OUTPUT ROUTINE JMS SIXB/~DO THE OUTPUT JMP I REM6B0/~DONE / SIX BIT TEXT PRINT ROUTINE / ENTER WITH ADDRESS OF TEXT IN AC AND THE ADDRESS OF THE OUTPUT / ROUTINE TO USE IN THE MQ REGISTER / A NULL BYTE SIGNALS A CONTROL CHAR IS NEXT / TWO NULL BYTES SIGNAL END OF TEXT SIXB, 0 DCA SIXBP/~AND STORE IN A LOCAL POINTER MQA/~GET THE OUTPUT ROUTINE ADDRESS DCA GET6P/~STORE ADDRESS IN POINTER DCA GET6F/~INIT BYTE FLAG SIXB1, GET6/~GET A BYTE FROM THE STRING SNA/~SKIP IF NOT NULL JMP SIXB3/~HANDLE CONTROL CHAR TAD (240/~CONSTRUCT PROPER ASCII AND C77 TAD (240 AND C177 /m013F SIXB2, JMS I SIXBP/~AND SEND CLA CLL/~INSURE CLEAR AC JMP SIXB1/~LOOP SIXB3, GET6/~GET BYTE FOLLOWING NULL BYTE SNA/~SKIP IF IS A CONTROL BYTE JMP I SIXB/~GOT END OF STRING TAD (200/~CONSTRUCT A CONTROL CHAR JMP SIXB2/~AND GO PRINT SIXBP, 0/~POINTER USED IN THE "SIXB" ROUTINE / ROUTINE TO PRINT 8 BIT CHARS ON THE TTY. ENTER ROUTINE WITH THE / ADDRESS OF THE TEXT IN THE AC OR IF AC IS ZERO THE ADDRESS IS IN / THE CALL + 1. TEXT TERMINATES ON A MINUS WORD. PRI8B0, 0 SZA/~SKIP IF ADDRESS NOT IN AC JMP PRI8B1/~ADDRESS IS IN THE AC TAD I PRI8B0/~GET ADDRESS FROM CALL + 1 ISZ PRI8B0/~BUMP RETURN POINTER PRI8B1, MQL/~SAVE ADDRESS IN MQ TAD (OTTY/~GET ADDRESS OF TTY OUTPUT ROUTINE JMS EIGHTB/~AND SEND IT JMP I PRI8B0/~ALL DONE / ROUTINE TO SEND 8 BIT CHARS DOWN THE REMOTE LINE. ENTER ROUTINE WITH / THE ADDRESS OF THE TEXT IN THE AC OR IF AC IS ZERO THE ADDRESS IS IN / THE CALL + 1. TEXT TERMINATES ON A MINUS WORD. REM8B0, 0 SZA/~SKIP IF ADDRESS NOT IN AC JMP REM8B1/~ADDRESS IN AC TAD I REM8B0/~GET ADDRESS FROM CALL + 1 ISZ REM8B0/~BUMP RETURN REM8B1, MQL/~PUT ADDRESS IN MQ TAD (OREM/~GET ADDRESS OF REMOTE OUTPUT ROUTINE JMS EIGHTB/~AND SEND THE STRING JMP I REM8B0/~DONE / ROUTINE TO SEND 8 BIT DATA / ENTER WITH ADDRESS OF DATA IN THE MQ AND THE ADDRESS OF THE ROUTINE / TO TAKE EACH BYTE IN THE AC. TEXT TERMINATES ON A MINUS WORD. EIGHTB, 0 DCA EIGHT5/~STORE POINTER TO ROUTINE MQA/~GET THE POINTER TO THE TEXT DCA EIGHT6/~STORE IN LOCAL POINTER EIGHT1, TAD I EIGHT6/~GET A CHAR ISZ EIGHT6/~BUMP THE POINTER SPA/~SKIP IF NOT EOL JMP EIGHT2/~GOT EOL JMS I EIGHT5/~CALL OUTPUT ROUTINE CLA CLL/~INSURE CLEAR AC JMP EIGHT1/~LOOP EIGHT2, CLA CLL/~CLEAR THE AC JMP I EIGHTB/~DONE EIGHT5, 0/~POINTER TO ROUTINE TO DO OUTPUT EIGHT6, 0/~POINTER TO TEXT TO OUTPUT / ROUTINE TO UNPACK 6 BIT CHARS FROM MEMORY / BEFORE CALLING INIT "GET6P" AS A POINTER TO THE STRING LOCATION / AND "GET6F" SHOULD BE ZEROED TO START WITH THE TOP BYTE OF THE / FIRST MEMORY LOCATION. GET60, 0 CLA CLL CML RAR/~SET AC=4000, LINK=0 TAD GET6F/~GET THE FLAG DCA GET6F/~RETURN THE FLAG TAD I GET6P/~GET TWO BYTES SZL/~SKIP IF TOP BYTE ISZ GET6P/~BOTTOM BYTE, PREPARE FOR NEXT TOP SNL/~SKIP IF BOTTOM BYTE BSW/~GET TOP BYTE INTO BOTTOM AND C77/~STRIP UNUSED BITS JMP I GET60/~DONE / LOCAL ROUTINE TO "FILN8" TO MAKE THE 6 BIT CHAR IN THE AC INTO / 8 BITS AND STORE IN A STRING MOV8, 0 SNA/~SKIP IF NOT A NULL CHAR TAD (" &77/~PUT IN A SPACE IF NULL TAD (240/~CONVERT BACK TO 8 BIT AND C77 TAD (240 AND C177/~CLEAR ASCII BIT 8 /m013F DCA I MOV8P/~PUT IN THE LINE ISZ MOV8P/~BUMP POINTER JMP I MOV8/~DONE MOV8P, 0/~POINTER FOR "MOV8" ROUTINE / ROUTINE TO PULL A FILE NAME IN 6 BIT POINTED TO BY THE / AC AND PLACE IN THE FILE NAME BUFFER IN 8 BIT ADDING IN / THE "." TO SEPERATE FILE NAME AND EXTENSION. A MINUS WORD / WILL FOLLOW THE NAME FILN8, 0 DCA GET6P/~SET POINTER FOR "GET6" DCA GET6F/~SET FLAG FOR "GET6" TAD (NAMBUF/~GET ADDRESS OF THE NAME BUFFER DCA MOV8P/~SET IN A POINTER TAD (-6/~6 NAME CHARS TO DO DCA FILN8C/~SAVE IN COUNTER GET6/~PULL A CHAR SZA/~SKIP IF A SPACE JMS MOV8/~PUT INTO THE BUFFER ISZ FILN8C/~BUMP COUNTER JMP .-4/~LOOP TILL ALL 6 DONE TAD (".&77/~GET A PERIOD JMS MOV8/~PUT WITH FILE NAME CLA CLL CMA RAL/~AC = -2 DCA FILN8C/~2 EXTENSION CHARS GET6/~GET NEXT CHAR SZA/~SKIP IF A SPACE JMS MOV8/~PUT WITH NAME ISZ FILN8C/~BUMP COUNTER JMP .-4/~LOOP STA/~AC = -1 DCA I MOV8P/~TERMINATE THE STRING JMP I FILN8/~AND RETURN FILN8C, 0/~COUNTER FOR "FILN8" PAGE / PARSE TABLES TMPTBL, "C; "O; "N; "N; "E; "C; "T -1/~MARK END OF THIS ENTRY CONSRV/~SERVICE DISPATCH ADDRESS "B; "Y; "E -1/~MARK END OF THIS ENTRY BYESRV/~SERVICE DISPATCH ADDRESS "E; "X; "I; "T -1/~MARK END OF THIS ENTRY OS8/~SERVICE DISPATCH ADDRESS "S; "E; "N; "D -1/~END OF THIS ENTRY SNDSRV/~SERVICE ADDRESS "G; "E; "T -1/~END OF THIS ENTRY GETSRV/~SERVICE ADDRESS "R; "E; "C; "E; "I; "V; "E -1/~MARK END OF THIS ENTRY RECSRV/~SERVICE ADDRESS -1/~MARK END OF THE TABLE / KEYBOARD LINE BUFFER LINBUF, ZBLOCK LINSIZ/~LINE BUFFER / REMOTE PACKET INPUT BUFFER RRBUF, 0 /MARK RRLEN, 0 /PACKET LENGTH RRSEQ, 0 /PACKET SEQ RRTYP, 0 /PACKET TYPE DECIMAL RRDTA, ZBLOCK 91/~DATA GOES HERE OCTAL RTERMI, 0 /ADD LOCATION WHERE TERMINATOR IS STORED /a004 /~ON RECEIVE IF BUFFER IS AT MAX LENGTH. /a004 / REMOTE PACKET OUTPUT BUFFER RSBUF, SOH/~PACKET BUFFER (BEGINS WITH "SOH") RSLEN, 0/~PACKET LENGTH GOES HERE RSSEQ, 0/~PACKET SEQUENCE GOES HERE RSTYP, 0/~PACKET TYPE GOES HERE DECIMAL RSDTA, ZBLOCK 91/~DATA GOES HERE 0/~CHECKSUM HERE ON MAX PACKET 0/~EOL (IF USED HERE ON MAX PACKET) 0/~INTERNAL TERMINATOR HERE ON MAX PACKET OCTAL / FILE NAME BUFFER NAMBUF, ZBLOCK 12/~ROOM FOR FILE NAME, EXTENSION AND TERMINATOR / SEND-INIT PACKET DEFINITION INIDAT, DECIMAL 94+32/~94 CHARS MAX OCTAL "/&177 /NO TIME-OUT " &177/~NO PADDING 0+100&177/~NO PADDING CHAR " &177+15/~CR FOR EOL "#&177/~QUOTE CHAR "N&137/~NO 8TH BIT QUOTING "1&177/~CHECK TYPE 1 " &177/~NO REPEAT CHAR " &177+0/~NO EXTRA CAPABILITY NODATA, -1/~END OF DATA (USE THIS FOR SENDING NO-DATA) / TEXT STORAGE CONMSG, TEXT "@M@J[CONNECTING TO HOST, TYPE ^]C TO RETURN TO PDP8]@M@J@" EXTXT, TEXT "KERMIT EXIT@M@J@" FRMSG, TEXT "RECEIVING FILE @" FSMSG, TEXT "SENDING FILE @" PROMPT, TEXT "@M@JKERMIT-8 V2>@" / TEXT FOR ERROR MESSAGES HFERR, TEXT "HANDLER FETCH ERROR@M@J@" NOBYE, TEXT "KERMIT SERVER BYE FAILURE@M@J@" RECERR, TEXT "RECEIVE FAILED@M@J" SPERR, TEXT "SEND ERROR@M@J" STXERR, TEXT "COMMAND SYNTAX ERROR@M@J" SYNERR, TEXT "FILENAME SYNTAX ERROR@M@J@" BANTXT, TEXT "@M@JKERMIT-8 V 2.0 1-OCT-87 7-BIT TEXT-ONLY FILE TRANSFER@M@J@" HLPMSG, TEXT "COMMANDS: CONNECT,SEND,GET,BYE,EXIT ESC-CHAR: ^]C@M@J" BS, TEXT "THANKS TO: BILL SMITH AND DINGER MILLER@M@J@" $$$$$$$$$$ / NOTE TO HACKERS: USE 'BS' FOR YOUR OWN BANNER INFORMATION, BUT / PLEASE LEAVE 'BANTXT' AND 'HLPMSG' FOR THE USERS. / BE CAREFUL NOT TO ENCROACH ON LOCATIONS ABOVE 7600.