.TITLE MAIL ; Multiprocessor V5 ; DATACOMM. HELP-PROGRAM: ; 1. Puts news in mailbox. ; 2. Prints messages from mailbox. ; 3. Puts messages for JOBs in mailbox. ; To be run on JOB site. ;************** NO user edits in this program ***************** ; MAILBOX: message structure in file SY:JBINFO.DAT: ; -------- ; Block 0: DVLIST = Device list (RAD50 & ASCII) ; Block 1: Device size & Status, R/W protection, JOBDEF list ; BLock 2-8.: secundairy bootstraps each 1 block ; ! Block #MAIL! Block +1 ! Block +2 ! Block +3 ! Block +4 ! ; !-------------!------------!------------!-----------!------------!---- ; ! common info ! message TO ! mess. FROM ! mess. TO ! mess. FROM ! ; ! for ALL jobs! JOB 0 ! JOB 0 ! JOB 1 ! JOB 1 ! etc. ; Att. Mailbox data red by JOBs are truncated after 480. bytes! ; (16 words for SYS-info) MAIL=9. ;Block start address of messages in mailbox .MCALL .EXIT,.PRINT,.LOOKUP,.READW,.WRITW,.CLOSE .MCALL .GTLIN,.RCTRLO,.DATE,.TTYIN,.DSTAT .ENABL LC .GLOBL TIME ;_________________________START MAIN PROGRAM________________________ START:: ; ; Open channel ; .LOOKUP #AREA,#0,#FIL0 ;get DATA FILE / MAILBOX of host BCS LFAIL0 BR OK ; ; Error returns: ; LFAIL0: .PRINT #NOFILE .EXIT OK: .READW #AREA,#0,#SIZTAB,#100.,#1 BCS 200$ CALL BOOTS ;List of bootstraps available .READW #AREA,#0,#BUFFER,#256.,#MAIL BCS 200$ .PRINT #ALLNEW .PRINT #BUFFER .PRINT #ALLTXT ;Transmit message? CALL MAKEUP TST NC BEQ 1$ .WRITW #AREA,#0,#BUFFER,NC,#MAIL 200$: BCS HRDERR ;--------------Do correspondence for each JOB----------------- 1$: MOV #60,R5 MOV #JOBDEF,R2 ;Set up JOB list pointer NEXTJB: TST (R2) ;End of list? BEQ READY .DSTAT #STAT,R2 BCS COUNT ;JOB handler not in system? TST STAT+4 BEQ COUNT ; or not loaded? CLR R1 BISB STAT,R1 ;Get device iden SUB #300,R1 ASL R1 ;Make block address(2 blocks/job) INC R1 ; of JOB message (skip "for ALL") INC R1 ; (skip "to job") ADD #MAIL,R1 .READW #AREA,#0,#BUFFER,#256.,R1 BCS HRDERR DEC R1 ;Back to block "to job" MOV R1,WRTBLK MOVB R5,JOBID .PRINT #FRJOB ;Message? .PRINT #JOB .PRINT #BUFFER .PRINT #TOJOB ;Transmit message? .PRINT #JOB MOV R2,-(SP) MOV R5,-(SP) CALL MAKEUP MOV (SP)+,R5 MOV (SP)+,R2 TST NC BEQ COUNT .WRITW #AREA,#0,#BUFFER,NC,WRTBLK BCS HRDERR COUNT: INC R5 TST (R2)+ ;Skip vector TST (R2)+ ;Point to next BR NEXTJB ; Terminate: READY: .CLOSE #0 .EXIT HRDERR: .PRINT #IOERR BR READY ;________________________END OF MAIN_____________________________ FIL0: .RAD50 /SY JBINFODAT/ STAT: .BLKW 4 SIZTAB: .BLKW 16.*2 RWSTAT: .BLKW 7.*2 JOBDEF: .BLKW 7.*2 .BLKW 40. NOFILE: .ASCIZ /?MAIL-F-No file SY:JBINFO.DAT!/ IOERR: .ASCIZ /?MAIL-F-IO Error/ ALLNEW: .ASCII <12>/Current news for all>/<15><12> .ASCIZ /---------------------/ ALLTXT: .ASCII <012>/Replace news? Type>/<15><12> .ASCIZ /-------------------/ .EVEN FRJOB: .ASCII /Message FROM/<200> TOJOB: .ASCII <012>/Message FOR/<200> JOB: .ASCII / JOB/ JOBID: .ASCII / >/<12><0> .EVEN MAKEUP: MOV #DATA,BPOINT ;DATA=offset in BUFFER CLR NC ;Clear counter AGAIN:: MOV #70.,NRCHAR ;Max. nr. chars / line MOV #QARG,R5 ;Set argument list for QA CALL QA ;Get a line CMPB #' ,INPUT ;1 st char a blank? BEQ FINISH ;No, go on! MOV #INPUT,R3 ;Inp. pointer MOV BPOINT,R2 ;outp. buffer pointer MOVB #12,(R2)+ ;Insert LF MOVB #15,(R2)+ ; and CR ADD #2,NC ;Count LF+CR MOV NRCHAR,R1 2$: MOVB (R3)+,(R2)+ ;move CMP R2,#LAST ;Buffer full? BHI FINISH ;No->Ask for more input. INC NC SOB R1,2$ ; them MOV R2,BPOINT ; all BR AGAIN FINISH: CALL DATTIM CLRB @BPOINT ;Set stringterminator INC NC ;Count 1 more for terminator ASR NC ;Nr. chars-> nr. words BEQ 4$ ;For no input. BCC 3$ INC NC INC BPOINT CLRB @BPOINT 3$: ADD #38.,NC ;For DATTIM header 4$: RETURN ; WRTBLK: .WORD 0 QARG: .WORD 0 .WORD STRING .WORD INPUT .WORD NRCHAR STRING: .ASCIZ /?/ INPUT: .BLKB 70. ;1 LINE =70. bytes. NRCHAR: .WORD 70. AREA: .BLKW 5 HDMESS: .BYTE 12,11 ;LF, HORIZONTAL TAB .ASCII /Time / TIMSTR: .BLKB 8. ;1 .BYTE 40,40 DATSTR: .BLKB 17. .BYTE 15,12,15 BUFFER: .BLKW 19. DATA: .BLKW 237. ;2, 1+2=254. WORDS LAST: .WORD 0,0 BPOINT: .WORD 0 NC: .WORD 0 ; -------------------------------------------------- .SBTTL DATTIM DATTIM:: MOV #TIMARG,R5 CALL TIME ; ; R2=MONTH(1-12), R1=DAY(1-31), R3=YEAR(MODULUS 100) ; DATE:: .DATE MOV R0,R3 ;See Prog. Ref. 81-V4, pp. 2-26 BEQ 1$ BIC #^C37,R3 ADD #72.,R3 MOV R0,R1 ASL R1 ASL R1 ASL R1 SWAB R1 BIC #^C37,R1 MOV R0,R2 SWAB R2 ASR R2 ASR R2 BIC #^C37,R2 1$: MOV #DATSTR,R4 ;R4=date/tim pointer CALL CNVASC MOVB #' ,(R4)+ DEC R2 MOV R2,R1 ;*12. ASL R2 ASL R2 ASL R2 ASL R1 ASL R1 ADD R1,R2 MOV #MONTH,R1 ADD R2,R1 MOV #12.,R2 2$: MOVB (R1)+,(R4)+ SOB R2,2$ MOV R3,R1 CALL CNVASC MOV #BUFFER,R0 MOV #HDMESS,R1 MOV #38.,R2 3$: MOVB (R1)+,(R0)+ SOB R2,3$ RETURN MONTH: .ASCII /January 19/ .ASCII /February 19/ .ASCII / March 19/ .ASCII / April 19/ .ASCII / May 19/ .ASCII / June 19/ .ASCII / July 19/ .ASCII / August 19/ .ASCII /September 19/ .ASCII / October 19/ .ASCII /November 19/ .ASCII /December 19/ .EVEN TIMARG: .WORD 0 .WORD TIMSTR CNVASC: CLR R0 DIV #10.,R0 ADD #'0,R0 ADD #'0,R1 CMPB R0,#'0 BNE 1$ MOV #' ,R0 1$: MOVB R0,(R4)+ MOVB R1,(R4)+ RETURN ;________________________ Bootstrap list ____________________________; BOOTS: .PRINT #BTHEAD CLR R5 MOV #2,R3 ;1st boot block MOV #JOBDEF,R4 ;Set up JOB list pointer NXTJB: MOV R5,R0 ADD #60,R0 MOVB R0,JBID MOV #HDR50,R1 MOV (R4),R0 ;Job handler name BEQ BRET CALL R50ASC ;Convert physical JOB-handler name MOVB #':,HDEND .PRINT #JBIDEN .DSTAT #STAT,R4 BCC 1$ ;JOB handler in system? .PRINT #NOJOB ;Print NO! BR 10$ 1$: CLR R1 BISB STAT,R1 ;Get device iden SUB #300,R1 ADD #60,R1 MOVB R1,HDJBID ;JOBNUM in job handler .PRINT #HDIDEN ; ; Read 1 word in block to see if boot program is present. ; 10$: .READW #AREA,#0,#DUMMY,#1,R3 ;BOOT read BCS 25$ TST DUMMY BEQ 15$ .PRINT #BOOTOK 100$: CMP (R4)+,(R4)+ INC R5 INC R3 BR NXTJB 15$: .PRINT #NOBOOT BR 100$ 25$: .PRINT #RDBOOT BR 100$ BRET: RETURN DUMMY: .WORD 0 BTHEAD: .ASCII /Bootstrap program list>/<15><12> .ASCII /-----------------------/<12><0> JBIDEN: .ASCII / JOB/ JBID: .ASCII / , job handler = / HDR50: .ASCII / / HDEND: .ASCII /:, /<200> HDIDEN: .ASCII /jobnumber in handler = / HDJBID: .ASCII / , /<200> NOJOB: .ASCII /? NO handler in system ? /<200> BOOTOK: .ASCIZ /Bootstrap program O.K./ NOBOOT: .ASCIZ /NO Bootstrap program !/ RDBOOT: .ASCIZ /Error reading bootblock!/ .EVEN ;_____________________ Terminal I/O routines ________________________; .SBTTL TTCR TTCR:: .PRINT #RET 1$: .TTYIN CMPB R0,#12 BNE 1$ RETURN RET: .ASCIZ /Press RETURN to continue/ .EVEN .SBTTL QA ; ; Subroutine for reading alpha-numeric input, see QUERY.MAC. ; CALL QA('Question',Logical array,Nr. of char. (max. 80)) ; QA:: 10$: MOV 2(R5),R2 ;Get address of question 20$: TSTB (R2)+ ;Determine length of question and make BNE 20$ ;string terminator octal 200 to suppress MOVB #200,-(R2) ;cariage return line feed MOV R2,R4 ;Save address of question string terminator BIS #40010,@#44 ;Lower case mode (bit 3 and 14 of JSW) .RCTRLO ;First entry also lower case ; ; Make up local answer string to display input field ; MOV @6(R5),R1 ;Get max. nr. of characters 30$: MOV #LOCANS,R2 ;Get address of local answer string 40$: MOVB #' ,(R2)+ ;Fill field with blanks SOB R1,40$ MOV R4,R3 ;Get address of quest. string term MOVB -(R3),(R2)+ ;Last char. of quest. is field delimiter MOVB #200,(R2) ;Field term. to suppress CR-LF .PRINT 2(R5) ;Print question .PRINT #LOCANS ;Print input field MOV @6(R5),R1 ;Get nr. of char. INC R1 ;Nr. of char. plus field delimiter MOV #LOCANS,R2 ;Get address of local answer string 50$: MOVB #10,(R2)+ ;Complete field with backspaces SOB R1,50$ .GTLIN #LOCANS,#LOCANS ;Print backspaces and read answer MOV #LOCANS,R2 CALL STRIP0 ;Strip leading, multiple and following ;blanks MOV @6(R5),R1 ;Max. permitted nr. of char. in answer MOV #LOCANS,R2 ;Get address of local answer string MOV 4(R5),R3 ;Get address of globle answer string clr r0 60$: MOVB (R2)+,(R3)+ ;Place local answer in globle string BEQ 70$ ;No (more) characters in local answer inc r0 SOB R1,60$ BR 90$ 70$: TSTB -(R3) ;Point to string terminator 80$: MOVB #' ,(R3)+ ;Complete globle string with blanks SOB R1,80$ 90$: mov r0,@6(r5) ;Nr. of chars in input TERMIN: CLRB @R4 ;Reset question string terminator RETURN ;Return to main program!! LOCANS: .BLKB 82. .SBTTL STRIP0 ; ; Subroutine to remove leading, multiple and following blanks ; ***** String terminator must be 0 ***** ; ; R2 should point to the begin of the string. ; On return R1 points to string terminator. ; STRIP0:: TSTB (R2) ;R2 is string pointer BEQ END2 ;No input MOV R2,R1 ;R1 is character replace pointer MOV R2,R3 ;Save begin address CMPB (R2)+,#' BEQ 25$ ;First character is blank, maybe more 10$: TSTB (R2) BEQ END2 ;Input is ok CMPB (R2)+,#' BNE 10$ ;Character is not a blank, continue MOV R2,R1 ;It's a blank save succeeding address TSTB (R2) BEQ END0 ;Found string terminator CMPB (R2)+,#' BNE 10$ ;Second char. is not a blank, continue 20$: TSTB (R2) BEQ END0 ;Reached end of string 25$: CMPB (R2)+,#' BEQ 20$ ;Found an other blank TSTB -(R2) ;Point to char. that succeeds blanks 30$: MOVB (R2),(R1)+ ;Replace character TSTB (R2)+ BEQ END1 ;Reached end of string CMPB (R2),#' BNE 30$ ;Found an other char. to be replaced MOVB (R2)+,(R1)+ ;Terminate replaced char. with a blank BR 20$ END0: CMP R3,R1 ;Compare with begin adderss BEQ END3 MOVB (R2),-(R1) ;Replace termin., delete last blank(s) RETURN END1: TSTB -(R1) ;R1 points to string terminator!! RETURN END2: MOV R2,R1 RETURN END3: MOVB (R2),(R1) ;Only blanks, string termin. is first char. RETURN ;--------------------------- RAD50 => ASCII -------------------------------; ; RAD50 to ASCII conversion routine ; R0 = RAD50 characters INPUT ; R1 > OUTPUT BUFFER ; R2 is USED as a SCRATCH register ; R50ASC: CALL DIV50 ; DIVIDE BY 50(8) MOV R2,-(SP) ; SAVE THIRD CHARACTER CALL DIV50 ; AGAIN MOV R2,-(SP) ; AND SAVE SECOND CHARACTER CALL DIV50 ; ONCE MORE CALL 10$ ; CONVERT TO ALPHA AND OUTPUT MOV (SP)+,R2 ; REMEMBER SECOND CALL 10$ ; AND OUTPUT MOV (SP)+,R2 ; REMEMBER THIRD ; AND FALL THROUGH 10$: TST R2 ; SPACE ? BEQ 20$ ADD #40,R2 ; NO - ADD OFFSET FOR A-Z CMP R2,#72 ; ALPHA ? BLE 20$ SUB #56,R2 ; NO - OFFSET TO NUMERIC CMP R2,#16 ; NUMERIC, *, OR % ? BGE 20$ CLR R2 ; NO - FORCE TO BLANK 20$: ADD #40,R2 ; FINISH TRANSLATION MOVB R2,(R1)+ ; AND OUTPUT RETURN ; ; DIV50 ROUTINE - DUMB SUBTRACT-AND-INCREMENT, BUT WHO CARES ; DIV50: MOV R0,R2 CLR R0 1$: SUB #50,R2 BCS 2$ INC R0 BR 1$ 2$: ADD #50,R2 RETURN .END START