.TITLE SEND - SEND MESSAGE TO SND... ; ; ; A COUPLE OF MACROS TO SIMPLIFY PARSING: ; ; .MACRO GETC CALL GETCHR .ENDM ; .MACRO EQUAL CHAR,LOC CMP #CHAR,R5 BEQ LOC .ENDM ; .MACRO DIFF CHAR,LOC CMP #CHAR,R5 BNE LOC .ENDM ; .MACRO RANGE CHARLO,CHARHI,LOC,?L1 CMP #CHARLO,R5 BHI L1 CMPH #CHARHI,R5 BHIS LOC L1: .ENDM ; .MACRO OUTOF CHARLO,CHARHI,LOC CMP #CHARLO,R5 BHI LOC CMP #CHARHI,R5 BLO LOC .ENDM ; ; A MACRO FOR SPOOLING NONWORD ALIGNED MESSAGES ; .MACRO SPOOLB BLOCK,MES,LEN MOV MES,-(SP) MOV LEN,-(SP) SP$LOD BLOCK CALL MOVSPL .ENDM ; ; ; AND THE MACROS WE CALL ; .MCALL CALL,RETURN,ENTER,LEAVE .MCALL DIR$,EXIT$S .MCALL QIO$,ALUN$,GLUN$,GMCR$,WTSE$ .MCALL SPOOL$,SP$BGN,SP$END,SPBLK$ .MCALL TINIT,PSTR,ERROR .MCALL FDBDF$,FDRC$A,FDOP$A,NMBLK$ .MCALL OPEN$,GET$,CLOSE$ .MCALL CSI1,CSI2,CSI$ .MCALL FSRSZ$ ; ; FSRSZ$ 1 ; ; ; ; A FEW CONSTANTS: ; TTILUN=1 TTIEVF=1 SPLUN=2 SPEVF=2 QULUN=3 QUEVF=3 INFLUN=4 ; SPACE=40 EOF=-1 ; .SBTTL >READ INPUT COMMAND ; ; START: TINIT QULUN,QUEVF DIR$ #ASSIGN ;GET TI DIR$ #GETLUN ;AND FIGURE OUT WHO IT IS CLR SENDTI ;INITIAL GUESS FOR WHO TO SEND TO MOV #ANON,ID ;INITIAL GUESS FOR ID MOV #LANON,IDLEN CLR IOSTAT ;PRETEND NO ERRORS YET DIR$ #GETMCR ;TRY TO GET MCR COMMAND BCS 2$ ;NO SUCH MOV #GETMCR+G.MCRB,R1 ;ADDRESS OF LINE MOVB $DSW,R2 ;LENGTH BMI 2$ ;THIS SHOULDN'T HAPPEN, BUT... 1$: GETC ;SKIP OVER SEND EQUAL EOF,2$ ;RUN OUT OF COMMAND DIFF SPACE,1$ BR 6$ ;STILL LIFE IN THE LINE 2$: DIR$ #PROMPS ;ISSUE SND> PROMPT DIR$ #TREAD ;READ COMMAND LINE DIR$ #TWAIT ;WAIT FOR IT TSTB IOSTAT ;DID IT WORK? BPL 3$ ;SURE CMPB #IE.EOF,IOSTAT ;MAYBE BEQ 3$ ;YUP EXIT$S ;CAN'T GET A COMMAND, GIVE UP ; 3$: MOV #INBUF,R1 ;ADDRESS OF LINE MOV IOSTAT+2,R2 ;LENGTH READ BNE 5$ ;THERE IS SOME 4$: TSTB IOSTAT ;EOF FROM LAST TIME? BPL 2$ ;NO, TRY AGAIN EXIT$S ;YES, GIVE UP ; 5$: GETC ;GET FIRST CHAR 6$: EQUAL SPACE,5$ ;SKIP OVER BLANKS EQUAL EOF,4$ ;NOTHING ON LINE, TRY READING SOME MORE EQUAL '*,95$ ;MAYBE PA MESSAGE EQUAL 'T,7$ ;HE TYPED TT, SKIP OVER THEM OUTOF '0,'9,INPERR ;HAS TO BE TERMINAL ID CLR R3 BR 9$ ;IT IS 7$: GETC ;SHOULD BE SECOND T DIFF 'T,INPERR ;CHECK CLR R3 ;TERMINAL NUMBER ACCUMULATOR GETC ;CHECK FOR STAR EQUAL '*,95$ ;GOT IT BR 85$ ;NO, CHECK FOR NUMBER 8$: GETC 85$: OUTOF '0,'9,10$ ;FINISHED READING TERMINAL NUMBER 9$: SUB #'0,R5 ASL R3 ;MULTIPLY ACCUMULATOR BY 8 ASL R3 ASL R3 ADD R5,R3 ;AND ADD IN NEW DIGIT BR 8$ ;ON TO NEXT DIGIT ; 95$: MOV #-1,R3 ;INDICATE PA GETC ;AND GET NEXT CHARACTER 10$: MOV R3,SENDTI ;REMEMBER TERMINAL NUMBER DIFF ':,12$ ;MAYBE FOLLOWED BY : 11$: GETC ;IN WHICH CASE, IGNORE IT 12$: EQUAL SPACE,11$ ;AND SKIP BLANKS EQUAL EOF,INPUT ;GO AHEAD AND START SENDING DIFF '=,14$ ;MAY BE FOLLOWED BY EQUAL SIGN 13$: GETC ;IN WHICH CASE IGNORE IT EQUAL SPACE,13$ ;AND ANY BLANKS FOLLOWING 14$: MOV R1,R4 ;SAVE POSITION POINTER 145$: EQUAL EOF,149$ ;FORCED END OF ID EQUAL '/,15$ ;EXPLICIT END OF ID GETC ;GET A CHARACTER BR 145$ ;AND CONTINUE LOOKING FOR END ; 149$: INC R1 ;MOVE 'OVER' EOF 15$: CMP R1,R4 ;GOT END BEQ 16$ ;NO ID MOV R4,ID ;SAVE ID POINTER DEC ID NEG R4 ADD R1,R4 ;COMPUTE LENGTH OF ID MOV R4,IDLEN ;AND SAVE IT 16$: EQUAL EOF,INPUT ;NO MORE ON LINE, READ MESSAGE 17$: GETC ;TRY GETTING ANOTHER CHARACTER EQUAL SPACE,17$ ;SKIP OVER LEADING BLANKS EQUAL EOF,INPUT ;NONE LEFT CALL SPSTRT ;START SPOOLING EQUAL '@,18$ ;INDIRECT FILE FOR MESSAGE DEC R1 ;BACK UP OVER CHAR INC R2 ;.. MOV R2,TEMP ;LENGTH OF MESSAGE SPOOL$ R0,#TEMP,#1 ;SEND LENGTH SPOOLB R0,R1,R2 ;SEND MESSAGE BR FIN ;AND CLOSE THINGS OFF ; 18$: CALL INFILE ;SEND MESSAGE FROM FILE ; FIN: SPOOL$ R0,#ZERO,#1 ;SEND TERMINATOR SP$END R0 ;CLOSE SPOOL EXIT$S ;AND FINISHED ; INPERR: ERROR ^*/INPUT FORMAT ERROR/* ; ; DIE:: EXIT$S ; ; ERRPFX::PSTR ^*/SND - /* RETURN ; ; .SBTTL >READ MESSAGE ; ; INPUT: CALL SPSTRT ;START SPOOLING INLUP: TSTB IOSTAT ;OK TO READ? BMI FIN ;NO CMP #IS.ESC,IOSTAT ;MAYBE BEQ FIN ;NO DIR$ #PROMPA ;PROMPT WITH ASTERISK DIR$ #TREAD ;READ LINE DIR$ #TWAIT ;WAIT FOR IT TSTB IOSTAT ;READ OK? BPL 1$ ;YES CMPB #IE.EOF,IOSTAT ;MAYBE BNE FIN ;NO 1$: TST IOSTAT+2 ;ANY CHARS READ? BEQ INLUP ;NO, JUST READ ANOTHER LINE CMPB #'@,INBUF ;FILE REQUEST? BNE 2$ ;NO, JUST OUTPUT MESSAGE MOV #INBUF+1,R1 ;ADDRESS OF FILESPEC MOV IOSTAT+2,R2 ;LENGTH OF FILESPEC+@ DEC R2 ;LENGTH OF FILESPEC CALL INFILE ;OUTPUT IT BR INLUP ;AND ON TO NEXT LINE ; 2$: SPOOL$ R0,#IOSTAT+2,#1 SPOOLB R0,#INBUF,IOSTAT+2 BR INLUP .SBTTL >OUTPUT MESSAGE FROM FILE ; ; R1 CONTAINS ADDRESS OF FILESPEC ; R2 CONTAINS LENGTH OF FILESPEC ; INFILE: ENTER R0 CSI1 #CSIBLK,R1,R2,CS1ERR ;PARSE FILE SPEC CSI2 #CSIBLK,OUTPUT,,CS2ERR ;AND EXTRACT FILENAME OPEN$ #INFDB,,,,,,,,IOERR ;OPEN FILE 1$: GET$ #INFDB ;READ A RECORD BCC 2$ ;GOT IT CMPB #IE.EOF,INFDB+F.ERR ;MAYBE EOF? BEQ 3$ ;YES, FINISHED CALL IOERR ;NO, SOMETHING WORSE 2$: TST INFDB+F.NRBD ;CHECK LINE HAS NON-ZERO LENGTH BEQ 1$ ;ELSE IGNORE IT SPOOL$ #SPBLK,#INFDB+F.NRBD,#1 ;LENGTH OF LINE SPOOLB R0,INFDB+F.NRBD+2,INFDB+F.NRBD ;AND LINE ITSELF BR 1$ ;ON TO NEXT LINE ; 3$: CLOSE$ R0,IOERR ;CLOSE FILE LEAVE ;AND BE OFF RETURN .SBTTL >START SPOOLING ; SPSTRT: SP$BGN #SPBLK SPOOL$ R0,#SENDTI,#1 CLRB FROMTI+3 SPOOL$ R0,#FROMTI+2,#1 SPOOL$ R0,#IDLEN,#1 SPOOLB R0,ID,IDLEN RETURN ; .SBTTL >SPOOL BYTE ALIGNED MESSAGES ; MOVSPL: ENTER R1,R2,R3 MOV 10(SP),R2 MOV 12(SP),R1 ;GET POINTER TO MESSAGE MOV #SPBUF,R3 ;AND WHERE TO MOVE IT TO 1$: MOVB (R1)+,(R3)+ ;SLOWLY MOVE IT SOB R2,1$ ;ONE BYTE AT A TIME CLRB (R3)+ ;WITH A NULL AT THE END BIC #1,R3 ;BACK OFF TO WORD BOUNDARY SUB #SPBUF,R3 ;COMPUTE WORD LENGTH ASR R3 ;.. SPOOL$ R0,#SPBUF,R3 LEAVE MOV (SP)+,2(SP) TST (SP)+ RETURN ; ; .SBTTL >GET A CHARACTER ; ; GETCHR: DEC R2 ;ANY LEFT? SXT R5 ;IF NONE, RETURN -1 BMI 2$ MOVB (R1)+,R5 ;GET A CHAR BIC #177600,R5 ;GET RID OF EXTRA BITS BEQ GETCHR ;NOTHING THERE CMP #'A+40,R5 ;LOWER CASE? BHI 1$ ;NO CMP #'Z+40,R5 ;MAYBE BLO 1$ ;NO SUB #40,R5 ;YES, CONVERT TO UPPER CASE 1$: CMP #'I-100,R5 ;CONTROL-I (TAB)? BNE 2$ ;NO MOV #SPACE,R5 ;YES, CONVERT TO SPACE 2$: RETURN ; .SBTTL >VARIABLES AND SUCH LIKE ; ; ; ; SPBLK: SPBLK$ SND...,,-1,,,SPLUN,SPEVF ; CSI$ .EVEN CSIBLK: .BLKB C.SIZE ; ; INFDB: FDBDF$ FDRC$A FD.PLC,INBUF,LINBUF FDOP$A INFLUN,CSIBLK+C.DSDS,DEFNMB,FO.RD ; DEFNMB: NMBLK$ ,MSG,0,SY,0 ; ; ASSIGN: ALUN$ TTILUN,TI,0 GETLUN: GLUN$ TTILUN,FROMTI GETMCR: GMCR$ PROMPS: QIO$ IO.WLB,TTILUN,,,,, PROMPA: QIO$ IO.WLB,TTILUN,,,,, TREAD: QIO$ IO.RLB,TTILUN,TTIEVF,,IOSTAT,, TWAIT: WTSE$ TTIEVF ; FROMTI: .BLKW 6 IOSTAT: .BLKW 2 ; SBUF: .ASCII /SND>/ LSBUF=.-SBUF ABUF: .ASCII /*/ LABUF=.-ABUF ANON: .ASCII /THE PERSON(?)/ LANON=.-ANON .EVEN LINBUF=1000 INBUF: .BLKB LINBUF .EVEN SPBUF: .BLKW 401 ; ID: .BLKW 1 IDLEN: .BLKW 1 SENDTI: .BLKW 1 TEMP: .WORD 0 ZERO: .WORD 0 ; .END START