.TITLE JSHOW File: JSHW50.MAC ; Multiprocessor V5 ; DATACOMM. HELP-PROGRAM, Shows counters, DEVICE LISTS, device STATUS&SIZE ; read/write PROTECTION SCHEME and POSSIBLY applies CHANGES TO IT. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++; ; COPYRIGHT (c) 1985 by ; ; H.H. Klin. Neuro. AZG ; ; ; ; This software is furnished under a LICENSE and may be USED ONLY IN ; ; ACCORDANCE WITH THE TERMS OF SUCH LICENSE. This software or ; ; any other copies thereof may not be provided or otherwise made ; ; available to any other person. NO TITLE TO AND OWNERSHIP OF THE ; ; SOFTWARE IS HEREBY TRANSFERRED. ; ; ; ; The information in this software is subject to change without notice. ; ; ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++; ; h.h. nkg. JAN-82 ; MAY-82 with account printout ; NOV-84 "CONTINUE" MENU (V4) ; JAN-85 V5 ; ************* NO user edits in this program ************* .MCALL .LOOKUP,.READW, .CLOSE,.EXIT, .PRINT,.GTLIN, .RCTRLO,.SERR .MCALL .SPFUN, .WRITW, .DSTAT,.PURGE,.FETCH,.SETTOP,.RELEAS,.HERR .ENABL LC START:: GTINFO: .LOOKUP #AREA,#0,#FILE ;Open info file BCS ABORT .READW #AREA,#0,#DVLIST,#256.,#0 ;Get DEVICE LIST BCS ABORT .READW #AREA,#0,#SIZTAB,#256.,#1 BCS ABORT JMP ALLUP ABORT: .PRINT #NOINFO .EXIT FILE: .RAD50 /SY JBINFODAT/ DVLIST: .BLKW 16.*4. MESSAG: .BYTE 0 MTCHAN: .BYTE 0 DVSTAT: .WORD 0 ; 2nd device available mask (1st mask is in DCJOB) ; reflects also disk available(refects only channel open) DASCII: .BLKW 190. SIZTAB: .BLKW 16.*2 RWSTAT: .BLKW 7.*2 JOBDEF: .BLKW 7.*2 .BLKW 196. AREA: .BLKW 6 NOINFO: .ASCIZ /?JSHOW-F-Unable to get data from SY:JBINFO.DAT!/ .EVEN ALLUP: CALL ACCNT ;Counter display + set JOB address list BR MENU ITEM1: .WORD OPT1 ITEM2: .WORD OPT2 ITEM3: .WORD OPT3 ITEM4: .WORD OPT4 ITEM5: .WORD OPT5 SELECT: .WORD 0 LF: .BYTE 12,200 OPT1: .ASCIZ \SHOW ALL\ OPT2: .ASCIZ \DEVICES\ OPT3: .ASCIZ \R&W\ OPT4: .ASCIZ \CHANGE R&W\ OPT5: .ASCIZ \EXIT :\ .EVEN MENU: MOV #1,R1 ;Default option 10$: .PRINT #LF MOV #5,R4 ;No. of options MOV #ITEM1,R5 ;Address first string CALL QS MOV R1,SELECT ;Selected item no. CMP #2,R1 BHIS 2$ CMP #3,R1 BEQ 3$ CMP #4,R1 BEQ 4$ .CLOSE #0 .EXIT 2$: CALL SHOWDV CMP #1,SELECT BEQ 3$ MOV #5,R1 ;Default option set now to EXIT BR 10$ 3$: CALL SHOWRW MOV #4,R1 ;Default option set now to CHANGE RW BR 10$ 4$: CALL CHANRW MOV #3,R1 ;Default option set now to SHOW RW BR 10$ ;======================== End of MAIN program ========================; ;============ Accounting & Setup job data block pointers ===========; ACCNT: .PRINT #HEAD1 ;Print account header (only once) .PRINT #HEAD2 ; *** Try to correspond with each JOB *** CLR JOBMAX CLR COUNT MOV #JOBDEF,R2 ;Set up JOB list pointer MOV #JOBPT,R4 NEXTJB: MOV COUNT,R0 ADD #60,R0 MOVB R0,JBID MOVB #'-,HDJBID ;JOBNUMBER in job handler TST (R2) ;End of list? BNE 1$ RETURN 1$: MOV #HDR50,R1 MOV (R2),R0 MOV R2,-(SP) CALL R50ASC ;Convert physical JOB-handler name MOV (SP)+,R2 .DSTAT #DEVICE,R2 BCS NOJOB ;JOB handler not in system? CLR R1 BISB DEVICE,R1 ;Get device iden SUB #300,R1 ADD #60,R1 MOVB R1,HDJBID ; MOV DEVICE+4,R0 BEQ NOJOB ; or not loaded? ; CMP -(R0),-(R0) ;Point to interrupt offset MOV @R0,R1 ;Get offset ADD R1,R0 ;Now pointing to interrupt entry SUB #4,R0 ;Points ERRPT (see JOB handlers) MOV @R0,(R4) ;Store in pointer list ; Print counters: MOV (R4),R5 ;Pointer to ERROR BEQ NOJOB INC JOBMAX ;Count No Jobs running TST (R5)+ ;Pointer to IOCNT HI MOV (R5)+,R0 ;IOCNT HI MOV (R5)+,R1 ;IOCNT LO MOV #LINE,R3 ;Pointer to text field. CALL C10DBI MOVB #' ,(R3)+ MOV #4,R1 ;Further more 4 numbers. 2$: MOV (R5)+,R0 CALL CNVDEC SOB R1,2$ MOVB #200,@R3 ;Set stopper .PRINT #JBIDEN .PRINT #HDIDEN .PRINT #LINE ; ; Further job properties: ; ADD #6,R5 ;Skip CHSTAT, RDSTAT, WTSTAT BIT #100000,@R5 BEQ 6$ BIT #40000,@R5 BEQ 5$ .PRINT #BTSPD BR NXTLIN 5$: .PRINT #SPD BR NXTLIN ; 6$: BIT #40000,@R5 BEQ 7$ .PRINT #BT BR NXTLIN 7$: .PRINT #CRLF NXTLIN: TST (R2)+ ; Skip vector TST (R2)+ ; Point to next TST (R4)+ ; Advance pointer in JOBPT list INC COUNT JMP NEXTJB NOJOB: .PRINT #JBIDEN .PRINT #HDIDEN .PRINT #PNOJOB CLR (R4) ; Clear entry in JOBPT list BR NXTLIN ; ----------------------ACCOUNT INFO---------------------- HEAD1: .BYTE 12 ;LF ;jbnam1234567890123456789012 123456 123456 123456 123456 .ASCIZ / JOB Hndlr Nr. IO Checks Protoc Buffer No. / HEAD2: .ASCIZ / --- ----- requests errors errors size blocks/ BTSPD: .ASCIZ / BOOT & SPDIR code/ SPD: .ASCIZ / SPDIR, No BOOT/ BT: .ASCIZ / BOOT, No SPDIR/ JBIDEN: .ASCII / DCJOB/ JBID: .ASCII / /<200> HDIDEN: .ASCII /(/ HDJBID: .ASCII / ,/ HDR50: .ASCII / )/<200> PNOJOB: .ASCII / not running!/ CRLF: .BYTE 0 LINE: .BLKB 81. .EVEN JOBPT: .WORD 0,0,0,0, 0,0,0,1 COUNT: .WORD 0 JOBMAX: .WORD 0 ;=============== SHOW Device names, status, size etc. ================; ; shows devicename (RAD50 representation), iden., size, status SHOWDV: .PRINT #HEADDV .SERR ;Intercept ABORT program on fatal error CLR COUNT MOV #DVLIST,R4 MOV #SIZTAB,R5 CLR DVSTAT LOOP: CMP COUNT,#16. BLT NXTDEV ; ; Done: return ; ============ ; Store device list & status & sizes & JOB list: ; 1$: .WRITW #AREA,#0,#DVLIST,#256.,#0 ;Update DVSTAT BCS 2$ .WRITW #AREA,#0,#SIZTAB,#256.,#1 ;Update STATUS & SIZE BCS 2$ CMP #1,SELECT BNE 3$ ;Go to common exit. MOV #RETURN,STRING MOV #1,NRCHAR ;Max. nr. chars / line MOV #QARG,R5 ;Set argument list for QA CALL QA ;Get a line BR 3$ 2$: .PRINT #NOUPDT 3$: .HERR ;ABORT program on fatal error RETURN NXTDEV: MOV #LINE,R1 ; ; Setup device no.: ; MOV COUNT,R0 MOVB #' ,(R1) CMP R0,#9. BLOS 2$ MOVB #'1,(R1) SUB #10.,R0 2$: TSTB (R1)+ ADD #60,R0 MOVB R0,(R1)+ MOVB #' ,(R1)+ ; ;=============== Setup ACTUAL device STATUS and SIZEs ==============; FILST$ = 100000 ; Random access SPECL$ = 10000 ; No directory VARSZ$ = 400 ; Variable size volume ; CLR (R5) ;Initial status CLR 2(R5) ;Initial size MOV #1,R3 ASH COUNT,R3 ;Set up bit mask in R3 MOV R3,MASK TST (R4) ;Device specified? BEQ NEXTCH .DSTAT #DEVICE,R4 ;Check device still in system BCS NEXTCH TST DEVICE+4 ;Load address BNE LOADED MOV @#50,R3 ;Load R3 with high program limit. TST (R3)+ ;Make R3 point to free space MOV DEVICE+2,R2 ;Handler size! ADD R3,R2 ;New high limit needed! BCS NEXTCH .SETTOP R2 ;Do limit request. BCS NEXTCH CMP @#50,R2 ;Enough memory? BLO NEXTCH .FETCH R3,R4 ;Load device pointed by R4 BCS NEXTCH LOADED: MOV DEVICE,(R5) ;Initial status (normally always ; .not.0 (i.e. RK status = 100000) BIT #SPECL$,DEVICE ;No Directory? BNE SETCH .LOOKUP #AREA,#1,R4 BCS NEXTCH ; ; Examine device: ; MOV DEVICE+6,2(R5) BIT #FILST$,DEVICE ; Random access device? BEQ SETCH ; ; Examine: disk or file ; TST 2(R4) BEQ 3$ ; ; Must be file (size is in R0): ; MOV #-1,(R5) ; -1 status indicates FILE (FILST$=up) MOV R0,2(R5) ; size in blocks BR SETCH 3$: BIT #VARSZ$,DEVICE BEQ 4$ MOV #1,2(R5) ; Size 1 block marks variable vol. ; ; Random access: try to read 1 word in block 0 to see if really exists... ; 4$: .READW #AREA,#1,#DUMMY,#1,#0 ;Dummy read BCS NEXTCH SETCH: BIS MASK,DVSTAT NEXTCH: MOV (R5)+,STATUS MOV (R5)+,SIZE ; ; Setup device name: ; MOV (R4)+,R0 ;Device name MOV R0,DVNAME CALL R50ASC MOVB #':,(R1)+ MOV (R4)+,R0 ;File name CALL R50ASC MOV (R4)+,R0 CALL R50ASC MOVB #'.,(R1)+ MOV (R4)+,R0 ;Extension CALL R50ASC BIT MASK,DVSTAT ;bit mask BNE IDEN ; No device: NODEV: MOVB #200,(R1) .PRINT #LINE .PRINT #PNODEV JMP NEXT ; IDEN: CMP STATUS,#-1 BNE 2$ MOVB #' ,(R1)+ MOVB #' ,(R1)+ MOVB #' ,(R1)+ MOVB #'F,(R1)+ MOVB #'I,(R1)+ MOVB #'L,(R1)+ MOVB #'E,(R1)+ MOVB #' ,(R1)+ BR 10$ ; 2$: MOV #57,R0 ;No. of DEC "standard" devices MOV #DECLST,R2 3$: CMPB STATUS,R0 BEQ 5$ DEC R0 BPL 3$ ; ; NO "DEC" device, print iden. no. ; CLR R0 BISB STATUS,R0 MOV R1,R3 CALL CNVOCT MOV R3,R1 MOVB #' ,(R1)+ BR 10$ ; ; "DEC": ; 5$: ASL R0 ADD #DECLST,R0 MOVB #' ,(R1)+ MOVB #' ,(R1)+ MOVB #' ,(R1)+ MOVB #' ,(R1)+ MOVB #' ,(R1)+ MOVB (R0)+,(R1)+ MOVB (R0)+,(R1)+ MOVB #' ,(R1)+ ; ; Now print size: ; 10$: MOV SIZE,R0 CMP #1,R0 BNE PSIZE ; ; Variable size volume (this SPFUN is only done for random access): ; .SPFUN #AREA,#1,#373,#SIZE,#1,#BLK BCS SIZERR MOV SIZE,R0 BR PSIZE SIZERR: MOV #NOSIZE,R0 MOV #9.,R2 1$: MOVB (R0)+,(R1)+ SOB R2,1$ BR CHARAC ;------------------------ Print size in blocks ----------------------; PSIZE: MOV R1,R3 CALL CNVDEC MOV R3,R1 MOVB #'.,(R1)+ MOVB #' ,(R1)+ ; ; Check if file: ; CHARAC: CMP #-1,STATUS BNE NOFILE ; File: MOVB #200,(R1) .PRINT #LINE .PRINT #PFILE NEXT: CMPB COUNT,MESSAG BNE 1$ .PRINT #FLAG1 BR 3$ 1$: CMPB COUNT,MTCHAN BNE 2$ .PRINT #FLAG2 BR 3$ 2$: .PRINT #CRLF 3$: INC COUNT .CLOSE #1 ;Close open channel .RELEAS #DVNAME ; ..and release it's device if loaded JMP LOOP ; Print device properties: ; NOFILE: MOVB #' ,(R1)+ MOVB #' ,(R1)+ MOV #8.,R0 MOV #200,R3 MOV #DVP8,R2 PROP: BITB R3,STATUS+1 BEQ 30$ .REPT 5 MOVB (R2)+,(R1)+ .ENDR MOVB #' ,(R1)+ BR 31$ 30$: ADD #5,R2 31$: ASR R3 SOB R0,PROP ; MOVB #200,(R1) .PRINT #LINE BR NEXT MASK: .WORD 0 DUMMY: .WORD 0 DVNAME: .WORD 0,0 STATUS: .WORD 0 SIZE: .WORD 0 BLK: .BLKW 4 DEVICE: .BLKW 4 DECLST: .ASCII /RKDTELLPTTDLDYPC10MTRFCTCR15DS17MMDPDXDM24NL262730/ .ASCII /313233DDMSPDPD40LSMQDRXT45LDVMDUSLDZDWPISPXL / DVP8: .ASCII /Filst/ DVP7: .ASCII /Ronly/ DVP6: .ASCII /Wonly/ DVP5: .ASCII /Specl/ DVP4: .ASCII /Hndlr/ DVP3: .ASCII /Spfun/ DVP2: .ASCII /Abtio/ DVP1: .ASCII /Varsz/ HEADDV: .ASCII <12>/No Device name iden. size characteristic/ .BYTE 12,0 PNODEV: .ASCII / .. .. Not in system /<200> PFILE: .ASCII / * File * /<200> FLAG1: .ASCIZ <11>/ << Messages/ FLAG2: .ASCIZ <11>/ << Magtape/ NOSIZE: .ASCII / Sizerr / RETURN: .ASCIZ <12>/Press RETURN to continue / NOUPDT: .ASCIZ /?JSHOW-W-Cannot update device STATUS & SIZE list!/ .EVEN ;-------------- END SHOW Device names, status, size etc. -------------; ;----------------- Change READ and/or WRITE ACCESS -------------------; CHANRW: .PRINT #STR0 1$: MOV #STR3,STRING MOV #1,NRCHAR ;Max. nr. chars / line MOV #QARG,R5 ;Set argument list for QA CALL QA ;Get a line MOVB INPUT,R0 ;JOB nr. TST NRCHAR ;NO INPUT? BEQ EXITRW MOVB R0,JBID BIC #^C177,R0 SUB #60,R0 BMI 1$ CMP R0,#6 ;Max. JOB no. = 6 BHI 1$ ; ; Set up JOB's STATUS data block: ; MOV #JOBPT,R5 ASL R0 ADD R0,R5 MOV @R5,R4 BNE 5$ .PRINT #JBIDEN .PRINT #PNOJOB BR CHANRW 5$: ADD #16,R4 ; ; R4 contains JOB data block pointer ; MOV (R4)+,CHSTAT ;Acces JOB STATUS MOV (R4)+,RDSTAT MOV (R4)+,WTSTAT MOV (R4) ,JBSTAT TST -(R4) MOV R4,SAVE ;Points to WTSTAT MOVB JBSTAT,R0 ADD #60,R0 MOVB R0,JBID MOV #STR1,STRING MOV #2,NRCHAR ;Max. nr. chars / line MOV #QARG,R5 ;Set argument list for QA CALL QA ;Get a line TST NRCHAR ;NO INPUT? BNE CHANGE EXITRW: RETURN CHANGE: CMP #"RS,INPUT ;1 st char BEQ 5$ 1$: CMP #"RC,INPUT BEQ 5$ 2$: CMP #"WS,INPUT ;1 st char BEQ 5$ 3$: CMP #"WC,INPUT BEQ 5$ .PRINT #ILLCMD RETURN 5$: MOV INPUT,CONTRL NEWINP: MOV #STR2,STRING MOV #2,NRCHAR ;Max. nr. chars / line MOV #QARG,R5 ;Set argument list for QA CALL QA ;Get a line TST NRCHAR ;NO INPUT? BEQ EXITRW CLR R2 CLR R3 CMP NRCHAR,#1 BEQ CHAR1 CMP NRCHAR,#2 BNE NEWINP CHAR2: BISB INPUT,R3 ;Process most significant digit SUB #'0,R3 BLT NEWINP CMP R3,#1 BHI NEWINP BNE 1$ MOV #10.,R3 1$: BISB INPUT+1,R2 BR SAME ;Process least significant digit CHAR1: BISB INPUT,R2 ;1 st char in R2 SAME: SUB #60,R2 ;ASCII offset -> 0-9 BLT NEWINP ADD R3,R2 ;Compose total unit nr. CMP R2,#16. BHIS NEWINP ; ; Change mask of READ or WRITE status ; MOV #1,R1 ASH R2,R1 BIT R1,CHSTAT BNE 6$ .PRINT #NOCHAN ;Not available device cannot be set! JMP NEWINP 6$: MOV RDSTAT,R3 CMPB #'R,CONTRL BEQ 7$ MOV WTSTAT,R3 7$: CMPB #'C,CONTRL+1 BEQ 10$ BIS R1,R3 BR 11$ 10$: BIC R1,R3 11$: CMPB #'R,CONTRL BNE 12$ ;To get WTSTAT SUB #2,SAVE ;To get RDSTAT 12$: MOV R3,@SAVE ;Access JOB PROT. STAT. JMP CHANRW ;--------------------- End of CHANGE R/W code ------------------------; QARG: .WORD 0 STRING: .WORD STR1 .WORD INPUT .WORD NRCHAR INPUT: .BLKB 10. NRCHAR: .WORD 10. SAVE: .WORD 0 CONTRL: .WORD 0 STR0: .ASCIZ <12>/Change ?/ STR1: .ASCIZ /RS, RC, WS, WC :/ STR2: .ASCIZ /Device nr. 0-15 :/ STR3: .ASCIZ /Give JOB nr. :/ NOCHAN: .ASCIZ /?JSHOW-F-Device not available?/ ILLCMD: .ASCIZ /?JSHOW-W-Illegal command?/ .EVEN ;---------------------End of CHANGE R/W routine------------------------; ;-------------------- Print READ & WRITE ACCESS -----------------------; OFFD = 21. ;Length DVLIST line. OFFR = 1 ;Offset to Read indicator OFFW = 5 ; " " Write " OFFN = 3 ; " " Not open " OFFC = 7 ; " " Double OFFC1= 8. ; write enalble indic. OFFT = 9. ;Total offset for each job. HEADP: .WORD 0 ;HEADER POINTER LISTP: .WORD 0 ;LIST " ;--------------Do status read for each JOB----------------- SHOWRW: CLR CHECKW ;Double write enable flag MOV JOBMAX,COUNT MOV #HEADJB,HEADP MOV #SHLIST,LISTP MOV #JOBPT,R4 ;Set up data pointer list NXTJRW: MOV (R4)+,R5 BEQ NXTJRW DEC COUNT BMI PRW ;All done? ADD #16,R5 MOV (R5)+,CHSTAT ;Acces JOB STATUS MOV (R5)+,RDSTAT MOV (R5)+,WTSTAT MOV (R5)+,JBSTAT MOVB JBSTAT,R0 ADD #60,R0 MOVB R0,JBID ;COPY JOB IDEN. MOV HEADP,R5 ; INTO HEADER MOV #JBIDEN,R0 .REPT 7 MOVB (R0)+,(R5)+ .ENDR ADD #OFFT,HEADP CLRB @HEADP MOV LISTP,R3 ADD #OFFT,LISTP CLR R1 NEXTDV: MOV #1,R2 ASH R1,R2 ;--------- channel open? ---------- MOVB #' ,(R3) ; Eliminate 0 stopper MOVB #' ,OFFR(R3) MOVB #' ,OFFW(R3) MOVB #'N,OFFN(R3) BIT R2,CHSTAT ; Channel to handler OPEN? BEQ 3$ MOVB #'?,OFFN(R3) BIT R2,DVSTAT ; Drive "rotating"? BEQ 5$ MOVB #' ,OFFN(R3) ; Device O.K. ;---------- read access? ----------- 5$: MOVB #'-,OFFR(R3) BIT R2,RDSTAT BEQ 2$ MOVB #'R,OFFR(R3) 2$: MOVB #'-,OFFW(R3) MOVB #' ,OFFC(R3) MOVB #' ,OFFC1(R3) ;---------- write access? ---------- BIT R2,WTSTAT BEQ 3$ MOVB #'W,OFFW(R3) BIT R2,CHECKW BEQ 4$ MOVB #'<,OFFC(R3) MOVB #'=,OFFC1(R3) 4$: BIS R2,CHECKW 3$: CLRB OFFT(R3) ;Terminate line printout ADD #50.,R3 ;To next device. INC R1 CMP R1,#16. BLO NEXTDV JMP NXTJRW ; Print the ASCII data block: PRW: .PRINT #HEADER MOV HEADP,R0 SUB #HEADJB,R0 MOV #UNL,R1 ADD R0,R1 CLRB @R1 ;Set stopper in underline .PRINT #UNLINE MOV #DASCII,R1 MOV #SHLIST,R2 MOV #16.,R3 2$: .PRINT R1 .PRINT R2 ADD #OFFD,R1 ADD #50.,R2 SOB R3,2$ .PRINT #UNLINE .PRINT #EXPL RETURN HEADER: .ASCII <12>/Central device / HEADJB: .ASCIZ / / UNLINE: .ASCII /--------------------/ UNL: .ASCIZ /----------------------------------------------/ EXPL: .ASCIZ /R=read, W=write, N=no device, ?=disk not available?/ ;1 234567890123456789012345678901234567890123456789 SHLIST: .ASCIZ <0>/ /;DEV. # 0 .ASCIZ <0>/ /;DEV. # 1 .ASCIZ <0>/ /;DEV. # 2 .ASCIZ <0>/ /;DEV. # 3 .ASCIZ <0>/ /;DEV. # 4 .ASCIZ <0>/ /;DEV. # 5 .ASCIZ <0>/ /;DEV. # 6 .ASCIZ <0>/ /;DEV. # 7 .ASCIZ <0>/ /;DEV. # 8 .ASCIZ <0>/ /;DEV. # 9 .ASCIZ <0>/ /;DEV. #10 .ASCIZ <0>/ /;DEV. #11 .ASCIZ <0>/ /;DEV. #12 .ASCIZ <0>/ /;DEV. #13 .ASCIZ <0>/ /;DEV. #14 .ASCIZ <0>/ /;DEV. #15 .EVEN ; -------------------------------------------------- CHSTAT: .WORD 0 RDSTAT: .WORD 0 WTSTAT: .WORD 0 JBSTAT: .WORD 0 CHECKW: .WORD 0 ; ====================== End of print R/W access ====================; ; -----------------INTEGER TO ASCII CONVERSION------------ .SBTTL CONVER FORMAT=7. ;If defined gives number format ;--------------------------------------------------------- ; DouBle Integer to ASCII conversion: R0=high part, R1=Low part ; Max. value 32000K C10DBI::DIV #1000.,R0 MOV #7,FORM CALL CNV10 ;CONVERT RESULT MOVB #'K,(R3)+ MOV R1,R0 ;CONVERT REMAINDER MOV #4,FORM BR CNV10 ;--------------------------------------------------------- ; Integer to ASCII conversion(decimal): R0=value CNVDEC::MOV #FORMAT,FORM CNV10: MOV R2,-(SP) MOV #10.,R2 BR GO ;--------------------------------------------------------- ; Integer to ASCII conversion(octal): R0=value CNVOCT::MOV #FORMAT,FORM CNV8: MOV R2,-(SP) MOV #8.,R2 GO: MOV R4,-(SP) MOV R1,-(SP) .IIF DF FORMAT,CLR R4 CALL CONVRT CLRB @R3 MOV (SP)+,R1 MOV (SP)+,R4 MOV (SP)+,R2 RETURN CONVRT: MOV R0,R1 CLR R0 DIV R2,R0 MOV R1,-(SP) .IIF DF FORMAT,INC R4 TST R0 BEQ 1$ CALL CONVRT 1$: .IF DF FORMAT NEG R4 BEQ 30$ CMP R2,#8. BEQ 5$ DEC R4 5$: ADD FORM,R4 BLE 15$ 10$: MOVB #' ,(R3)+ SOB R4,10$ 15$: CMP R2,#8. BEQ 30$ 20$: MOVB #' ,(R3)+ 30$: .ENDC ; FORMAT MOVB (SP)+,@R3 BISB #'0,(R3)+ RETURN FORM: .WORD 0 ;--------------------------- 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 ;======================= TERMINAL I/O Routines ========================; ;======================================================================; ; CALLING SEQUENCE: ; CALL QS (query for selection) ; ; R5 = pointer address list of strings STR1, STR2, STR3, ; R4 = No. of total strings ; R1 = on input: default string no. ; on output: selected string no. ; Input from KEYBOARD IS COMPARED WITH STR1,.. ; and ISEL is set to the seq number of the FIRST FITTING ARGUMENT ; ; leaves the present value of ISEL INTACT ; All argument strings are printed in lower case, ; with as exception the string indicated ; by the present value of isel, which is in upper case. ; .MCALL .TTYOUT,.GTLIN,.PRINT ; QS:: MOV R5,FRST ;KEEP POINTER ADDR FIRST ARG MOV R4,NARG ;SAVE No arguments ;------------------- Check validity ISEL ----------------------; MOV R4,R2 ASL R2 ADD R5,R2 TST R1 ;TEST ISEL BLE 6$ ;NEGATIVE CMP R1,R4 ;HIGHER THAN MAX ARG? BLOS 7$ ;NO, OK 6$: MOV #1,R1 ;SET ISEL DEFAULT 7$: MOV R1,IS ;KEEP CURRENT ISEL FOR RETRIES ; ;----------------- Output textstring list ---------------------; CLR R2 ;KEEPS STRING NUMBER 1$: MOV (R5)+,R3 ;ADDR NEXT STRING INC R2 ;UPDATE STRING NR 2$: TSTB (R3) ;NULL=END OF STRING BEQ 5$ CMPB (R3),#101 ;CHARACTER? BLO 4$ ;IF NOT, LEAVE ALONE CMPB (R3),#172 ; BHI 4$ CMP R2,R1 ;PRESENT STRING DESIGNATED BY ISEL? BNE 3$ ;NO, MAKE LOWER CASE BICB #40,(R3) ;YES, UPPER CASE BR 4$ ;AND PRINT 3$: BISB #40,(R3) ;LOWER CASE 4$: .TTYOUT (R3)+ ;OUTPUT THIS CHAR BR 2$ ;AND GET NEXT ONE ; 5$: DEC R4 ;ALL ARGS DONE? BEQ READ ;YES,GET ANSWER .PRINT #SPSLSP ;OUTPUT Space Slash Space BR 1$ ;GET NEXT ARG ; ;---------------------- Process input -------------------------; ; READ: .GTLIN #LINE ;GET ANSWER TSTB @#LINE ;CR? BEQ RET ;YES,LEAVE ISEL ALONE CMPB #33,LINE ;ESCAPE? YES, EXIT! BEQ EXIT MOV FRST,R5 ;ADDR FIRST STRING CLR R1 ;ISEL=0 MOV NARG,R4 ;ARG CNT INC R4 ;BECAUSE TEST-BEFORE-ACTION 1$: MOV #LINE,R0 ;CHAR POINTER ANSWER TSTB (R0) ;ANSWER CR ONLY? BEQ REPEAT ;WON'T DO MOV (R5)+,R3 ;CHAR POINT CURRENT ARG INC R1 ;UPDATE ISEL DEC R4 ;UPDATE ARG CNT BEQ REPEAT ;NO ARG FITS, TRY AGAIN ;-------------- Compare string a with input -------------------; 2$: TSTB (R0) ;NULL? BEQ RET ;YES, GET OUT OF HERE MOVB (R3)+,R2 ;GET CHAR FROM STRING BICB #40,(R0) ;MAKE IT UPPER CASE BIC #40,R2 ;MAKE IT UPPER CASE 3$: CMPB R2,(R0)+ ;AND COMPARE BEQ 2$ ;YES, CARRY ON BR 1$ ;NO, TRY NEXT ARGUMENT ; REPEAT: MOV FRST,R5 ;POINT TO FIRST TEXT ARG MOV IS,R1 ;RESTORE ORG ISEL MOV NARG,R4 ;RESTORE TO INITIAL VALUE .PRINT #BELL BR QS ;AND REPEAT THE WHOLE THING RET: RETURN ;BACK TO CALLER EXIT: .EXIT ; FRST: .WORD 0 IS: .WORD 0 NARG: .WORD 0 BELL: .BYTE 7,200 SPSLSP: .ASCII % / %<200> ; =========================== 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 .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 #LINE,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 #LINE ;Print input field MOV @6(R5),R1 ;Get nr. of char. INC R1 ;Nr. of char. plus field delimiter MOV #LINE,R2 ;Get address of local answer string 50$: MOVB #10,(R2)+ ;Complete field with backspaces SOB R1,50$ .GTLIN #LINE,#LINE ;Print backspaces and read answer MOV #LINE,R2 CALL STRIP0 ;Strip leading, multiple and following ;blanks MOV @6(R5),R1 ;Max. permitted nr. of char. in answer MOV #LINE,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 ;Count the number of chars. 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) ;Store number of chars actually being input. TERMIN: CLRB @R4 ;Reset question string terminator RETURN ;Return to main program!! .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 .END START