.MCALL .MODULE .MODULE ELINIT,VERSION=11,COMMENT= ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ; ; Edit Who Date Description of modification ; ---- --- ---- --------------------------- ; 001 WLD 23-JUN-92 Fix bug if extending but not ; initializing an error log ; file that has been filled. ; 002 WLD 24-JUN-92 Fix problem with local symbols. ; 003 WLD 25-JUN-92 Do not allow error log to be ; shortened unless being initialized. ; ; Edit History: ; ; 001 15-Feb-80 09:43 Gentry, Martin (70039) [240,121] ; Re-ordering of .GTIM and .DATE ; Plus some general clean-up. ; (001) ; ; 009 June, 1988 ; Comments and clean up. Matthew Sacks ; .SBTTL CONDITIONAL ASSEMBLY SUMMARY ;*************** Conditional Assembly Summary ******************************** ; ; ELR$G (1) standard conditional ; ; ERL$U (10.) number of distinct device units for which ; the error logger keeps statistics ; ;***************************************************************************** .SBTTL DEFINITIONS .LIBRARY "SRC:SYSTEM.MLB" ;+ ; ELINIT QUERIES THE OPERATOR FOR ERRLOG.DAT FILE MAINTENANCE/CREATION ; SENDING THE HEADER AS A MESSAGE TO THE EL TASK UPON COMPLETION ; OF THE DIALOGUE - ELINIT IS RUN BY THE USER AS A BACKGROUND JOB - ; A FATAL ERROR OCCURRS IF THE EL TASK IS NOT ACTIVE AT THE TIME ; THE HEADER RECORD (MESSAGE) IS SENT ;- .MCALL .CLOSE, .CSISP, .DATE .MCALL .DSTAT, .ENTER, .EXIT .MCALL .GTIM, .GTLIN, .LOOKU .MCALL .PRINT, .PURGE, .READW .MCALL .RENAM, .SDAT, .WRITE .MCALL .WRITW, .ASSUME .BR .MCALL .ELSDF .FIXDF .SYCDF .CF1DF .SGNDF ; INVOKE SYSTEM.MLB MACROS .ELSDF ;error logger statistics record format .FIXDF ;monitor fixed offsets .SYCDF ;monitor impure area .CF1DF ;config word number 1 .SGNDF ;system generation word ELR$G = 1 ;THIS MUST BE FORCED .IIF NDF ERL$U, ERL$U=10. ;NUMBER OF STATISTICS ENTRIES .Assume ERL$U LE 22.,MESSAGE=<;ELINIT:Too Many Loggable Units> ;SYMBOLIC DEFINITIONS MSKCF1 = ^C014001 ;MASK FOR TESTING MATCH OF CONFIG N0CHAR = '0 ;ASCII FOR THE CHARACTER '0' RADDEC = 10. ;DECIMAL RADIX VALUE BLKSIZ = 256. ;BLOCK SIZE IN WORDS ELIOCH = 0 ;ERROR LOGGER IO CHANNEL ETIOCH = 1 ;ERROR LOGGER TEMP FILE IO CHANNEL MSGCHN = 2 ;EL TASK MESSAGE COMMUNICATION CHANNEL FATAL$ = 10 ;FATAL ERROR INDICATOR ;HEADER OFFSET DEFINITIONS OMPARE = <*2> ;MEMORY PARITY COUNT OCPARE = <*2> ;CACHE ERROR COUNT ONXREC = <*2> ;NEXT RECORD POINTER ONXBLK = <*2> ;NEXT BLOCK POINTER OSIZEB = <*2>;FILE SIZE IN BLOCKS OCONFG = <*2>;CONFIGURATION .SBTTL ERROR LOGGING SUBSYSTEM INITIALIZATION ELINIT::.GTLIN #LINBUF,#MESDEV ;PROMPT USER FOR LOG FILE TSTB LINBUF ;ANY RESPONSE? BEQ DEVCHK ;NOPE, USE DEFAULT .CSISPC #FILSPC,#DEFEXT,#LINBUF ;NOW PARSE THE RESPONSE MOV (SP)+,R1 ;CHECK FOR GARBAGE ON STACK ASL R1 ;BYTES-TO-CLEAR=#OF-ITEMS*2 ADD R1,SP ;RESET SP MOV ISPEC,ELFILE ;OTHERWISE STORE SPECIFIED DEVICE MOV ISPEC,ELTEMP ;INTO EL FILESPEC AND TEMP FILESPEC DEVCHK: .DSTAT #INSTAT,#ELFILE ;GET STATUS OF DEVICE BCC 1$ ;GOT IT... JMP FCHERR ;DEVICE NOT FOUND 1$: TST INSTAT+4 ;IS IT LOADED? BNE 2$ ;YES... JMP FCHERR ;NOPE, SO WE CAN'T USE IT 2$: .LOOKUP #INSTAT,#ELIOCH,#ELFILE ;LOOKUP ERRLOG.DAT BCC LOOKOK ;FOUND IT... TSTB @#$ERRBY ;ERROR, WHAT'S WRONG? BNE LOOKNO ;FILE NOT FOUND...(IT'S OKAY) JMP CHNERR ;OTHER LOOKUP ERRORS ARE FATAL LOOKNO: .PRINT #MESW MOV R1,-(SP) ; SAVE R1 MOV #ELFILE,R0 ; R0 -> FILESPEC IN RAD50 MOV #NFTEMP,R1 ; R1 -> BUFFER FOR ASCII CONVERSION CALL $FNASC ; GO CONVERT RAD50 -> ASCII (ulblib routine) .PRINT #MESNFD ; TELL USER FILE NOT FOUND .PRINT #NFTEMP ; TELL USER WHAT FILESPEC MOV (SP)+,R1 ; RESTORE R1 MOV SMAXSZ,BUFBLK+OSIZEB ; SET DEFAULT FILE SIZE BR CREATE ; AND GO CREATE FILE LOOKOK: .READW #INSTAT,#ELIOCH,#BUFBLK,#BLKSIZ,#0 ;READ HEADER BLOCK BCC 1$ ;GOT IT... JMP IORERR ;ERROR READING HEADER BLOCK... 1$: CMP BUFBLK,OFIXED ;EXPECTED OFFSET? BNE INVALD ;NOPE.. TST BUFBLK+ONXREC ;PHYSICAL RECORD NUMBER VALID? BMI INVALD ;NOPE... TST BUFBLK+ONXBLK ;BLOCK NUMBER VALID? BLE INVALD ;NOPE... MOV @#$SYPTR,R1 ;GET BASE OF RMON MOV $CNFG1(R1),R2 ;GET CONFIG WORD 1 BIC #MSKCF1,R2 ;CLEAR THE DON'T CARES MOV BUFBLK+OCONFG,R3 ;GET CONFIG WORD 1 FROM THE HEADER BIC #MSKCF1,R3 ;CLEAR THE DON'T CARES CMP R3,R2 ;DO THE 2 WORDS MATCH BNE INVALD ;NO, INVALID HEADER MOV $SYSGE(R1),R2 ;GET SYSGEN FEATURES WORD MOV BUFBLK+OCONFG+2,R3 ; FROM HEADER ALSO CMP R3,R2 ;DO THE 2 WORDS MATCH BNE INVALD ;NO, INVALID HEADER TST BUFBLK+OMPARE ;CHECK # OF MEMORY PARITY ERRORS BMI INVALD ;CAN'T HAVE NEGATIVE COUNT TST BUFBLK+OCPARE ;CHECK # OF CACHE PARITY ERRRORS BMI INVALD ;CAN'T HAVE NEGATIVE COUNT ;VALID FILE FOUND MOV BUFBLK+ONXBLK,R0 ;GET HIGHEST BLOCK USED JSR PC,NUMBER ; AND PRINT IT .PRINT #MESUS1 ; 'BLOCKS USED OUT OF' MOV BUFBLK+OSIZEB,R0 ;NOW GET FILE SIZE JSR PC,NUMBER ; AND PRINT IT .PRINT #MESUS2 ;PRINT REMAINDER OF MESSAGE .GTLIN #LINBUF,#MESINI ;PROMPT USER FOR DECISION ; ZERO AND RE-INITIALIZE? TSTB LINBUF ;DEFAULT? BEQ CHANGE ;BEQ: DON'T REINITIALIZE FILE CMPB LINBUF,#'Y ;NOT DEFAULT, USER RESPONDING 'YES'? BEQ INITF ;YES... BR CHANGE INVALD: .PRINT #MESIV1 ;TELL USER CURRENT FILE IS INVALID .PRINT #MESIV2 ;AND HAS BEEN RENAMED ERRLOG.TMP .PURGE #ELIOCH ;FREE UP CHANNEL FOR RENAME OPERATION .RENAME #INSTAT,#ELIOCH,#ELFILE ;RENAME FILE ERRLOG.TMP MOV #100.,BUFBLK+OSIZEB ;FORCE THE DEFAULT SIZE BCC CREATE ;GO SET FLAG TO CREATE FILE CMPB @#$ERRBY,#3 ;IS THE FILE PROTECTED? BNE 1$ ;NO JMP PRTERR ;YES, THAT'S A FATAL ERROR 1$: JMP BADERR ;ILLEGAL - ERROR IN RENAME OPERATION CREATE: INCB FCREAT ;SET 'FILE CREATE' FLAG INITF: INCB FINIT ;SET 'FILE INITIALIZE' FLAG CHANGE: .PRINT #MESSZ1 ;PRINT FIRST HALF OF PROMPT MOV BUFBLK+OSIZEB,R0 ;GET DEFAULT FILE SIZE MOV R0,SMAXSZ ; SET IT JSR PC,NUMBER ; AND PRINT IT .GTLIN #LINBUF,#MESSZ2 ;ANY CHANGE IN FILE SIZE? ; (USE SECOND HALF OF PROMPT) TSTB LINBUF ;RESPONSE = CR ALONE? BEQ DOIT ;YES, ASSUME CURRENT OR DEFAULT SIZE MOV #LINBUF,R0 ;R0->ASCII STRING TO CONVERT JSR PC,ABCVRT ;CONVERT IT CMP R0,#1 ;CHECK VALIDITY OF SIZE REQUESTED BLE 1$ ;MUST BE AT LEAST 2 BLOCKS TSTB FINIT ;ARE WE INITIALIZING THE FILE? BNE 2$ ;YES, SO DON'T CHECK AGAINST CURRENT ; SIZE CMP R0,SMAXSZ ;REQUESTED SIZE:CURRENT SIZE? BHIS 2$ ;OK, CONTINUE 1$: .PRINT #MESF ;PRINT WARNING .PRINT #MESILL ;ILLEGAL COMMAND BISB #,@#$USRRB ;SET FATAL ERROR LEVEL IN ERROR BYTE BR CHANGE ;AND RE-PROMPT USER 2$: MOV R0,BUFBLK+OSIZEB ;PUT NEW SIZE INTO CURRENT HEADER MOV R0,SMAXSZ ;ALSO INTO POSSIBLE REINIT. HEADER INCB FCHGSZ ;CHANGE IN SIZE INDICATED SET FLAG DOIT: TSTB FCREAT ;DO WE NEED A NEW FILE? BNE 1$ ;YES, GO CREATE ONE TSTB FCHGSZ ;NO SO FAR -- TEST FOR CHANGED SIZE BEQ 6$ ;NO SIZE CHANGE - UES EXISTING FILE 1$: TSTB FINIT ;NEED TO INITIALIZE? BNE 2$ ;NO, DON'T NEED TO RENAME .PURGE #ELIOCH ;FREE THE CHANNEL IN CASE IT'S IN USE .RENAME #INSTAT,#ELIOCH,#ELFILE BCC 2$ ;ERROR IN RENAME CMPB @#$ERRBY,#3 ;IS IT A FILE PROTECTION ERROR? BNE 13$ ;NO 14$: JMP PRTERR ;YES, THAT'S A FATAL ERROR 13$: JMP BADERR ;ILLEGAL ERROR - GO TELL USER 2$: .PURGE #ELIOCH ;FREE THE CHANNEL PRIOR TO LOOKUP .ENTER #INSTAT,#ELIOCH,#ELFILE,SMAXSZ ;CREATE FILE OF GIVEN SIZE ;POSSIBLY NEW SIZE BCC 4$ ;ENTER OK GO FINISH UP TSTB @#$ERRBY ;IS THE ERROR CHANNEL IN USE BEQ 3$ ;YES, AND THAT'S NOT GOOD CMPB @#$ERRBY,#3 ;IS IT A FILE PROTECTION ERROR? BEQ 14$ ;YES, THAT'S A FATAL ERROR JMP FULERR ;NO, ERROR IS NO ROOM - GO TELL USER 3$: JMP BADERR ;ERROR IN ENTER - GO TELL USER 4$: MOV SMAXSZ,R1 ;LAST BLOCK IN FILE IS ONE LESS DEC R1 ; THAN FILE SIZE .WRITW #INSTAT,#ELIOCH,#BUFBLK,#BLKSIZ,R1 ;WRITE TO LAST BLOCK BCC 5$ ;ERROR IN WRITE? JMP IORERR ;YES, GO TELL USER AND EXIT 5$: .CLOSE #ELIOCH ;ABLE TO CREATE FILE OF THIS SIZE? BCS 14$ ;ONLY ERROR ON CLOSE IS IF ; PROTECTED FILE ALREADY EXISTS .LOOKUP #INSTAT,#ELIOCH,#ELFILE BCC 6$ ;ERROR IN LOOKUP JMP BADERR ;GO TELL USER - ILLEGAL ERROR 6$: TSTB FINIT ;HEADER NEEDS (RE-) INITIALIZATION? BEQ 8$ ;NO, DO WE NEED TO COPY THE OLD FILE? .GTIM #INSTAT,#INTIM1 ;USING CORE COPY OF HEADER, ; GET CURRENT TIME AND SAVE IT ; (DONE FIRST FOR DATE ROLLOVER) .DATE ;THEN GET DATE MOV R0,INIDAT ; AND STORE IT ALSO MOV @#$SYPTR,R1 ;GET POINTER TO BASE OF RMON MOV $CNFG1(R1),CNFGW1 ;CONFIGURATION WORD 1 INTO HEADER MOV $SYSGE(R1),CNFGW2 ;CONFIGURATION WORD 2 INTO HEADER ; (ACTUALLY SYSGEN FEATURES WORD) .WRITW #INSTAT,#ELIOCH,#HEADER,#HEDRWD,#0 ;WRITE HEADER BCC 7$ ;ERROR IN WRITE? JMP IORERR ;YES, GO TELL USER 7$: .PRINT #MESGEN ;PRINT NEW FILE GENERATED MESSAGE BR DONE ;GO TELL USER ALL SET NOW 8$: MOV #HEDRWD,R2 ;SET COUNT FOR COPYING HEADER MOV #HEADER,R3 ;GET ADDRESS OF BOTH HEADER AND MOV #BUFBLK,R4 ;TEMPORARY COPY OF DISK HEADER 9$: MOV (R4)+,(R3)+ ;DO TRANSFER DEC R2 ;ARE WE DONE YET? BNE 9$ ;NO, GO BACK .WRITW #INSTAT,#ELIOCH,#HEADER,#HEDRWD,#0 ;YES, WRITE HEADER BCC 10$ ;ERROR IN WRITE? JMP IORERR ;YES, GO TELL USER 10$: TSTB FCHGSZ ;NEED TO COPY REST OF FILE? BEQ DONE ;NO, GO TELL USER ALL DONE .LOOKUP #INSTAT,#ETIOCH,#ELTEMP ;LOOKUP ERRLOG.TMP FILE TO COPY BCC 11$ ;ERROR IF NOT FOUND TSTB @#$ERRBY ;WHAT IS THE ERROR BNE BADERR ;FILE NOT FOUND - ILLEGAL ERROR JMP CHNERR ;CHANNEL IN USE 11$: CLR R2 ;Copy existing blocks of error log 112$: INC R2 ;other than header by .READing a block ;from the old file and .WRITING it to ;the new file. .READW #INSTAT,#ETIOCH,#BUFBLK,#BLKSIZ,R2 BCC 113$ ;BR if OK. TSTB @#$ERRBY ;EOF? BEQ 114$ ;BR if yes. BR IORERR ;BR if error. 113$: .WRITW #INSTAT,#ELIOCH,#BUFBLK,#BLKSIZ,R2 BCS IORERR ;BR if write error. CMP R2,PNXBLK ;DONE? BLO 112$ ;BR if not. 114$: .PURGE #ETIOCH ;FREE THE TEMPORARY-FILE CHANNEL DONE: MOV @#$SYPTR,R1 ;R1->BASE OF RMON BIT #STASK$,$SYSGE(R1) ;RUNNING UNDER SYSTEM TASKING MONITOR? BEQ 2$ ;NOPE... .LOOKUP #INSTAT,#MSGCHN,#JBDES ;LOOKUP CHANNEL TO EL TASK BCC 1$ ;ERROR IN LOOKUP? TSTB @#$ERRBY ;WHAT IS IT BNE 3$ ;MUST BE NO JOB BY THAT NAME ACTIVE JMP CHNERR ;OTHERWISE CHANNEL IS IN USE 1$: .WRITE #INSTAT,#MSGCHN,#HEADER,#HEDRWD ;SEND THE HEADER BCC 4$ ;ERROR? JMP BADERR ;ILLEGAL ERROR, CHANNEL NOT OPENED 2$: .SDAT #INSTAT,#HEADER,#HEDRWD ;SEND HEADER TO FOREGROUND JOB BCC 4$ ;ERROR IF NO EL TASK 3$: MOV #MESNFG,R2 ;NO EL TASK ACTIVE BR FTLEXT ;AND EXIT 4$: .PRINT #MESDON ;TELL USER ERROR LOGGING INITIATED BR ALLEXT ;AND EXIT BADERR: MOV #MESBAD,R2 ;ILLEGAL ERROR BR FTLEXT IORERR: MOV #MESIOR,R2 ;IO ERROR BR FTLEXT FCHERR: MOV #MESFCH,R2 ;DEVICE NOT AVAILABLE BR FTLEXT FULERR: MOV #MESFUL,R2 ;DEVICE FULL BR FTLEXT CHNERR: MOV #MESCHN,R2 ;CHANNEL ERROR BR FTLEXT PRTERR: MOV #MESPRT,R2 ;PROBLEM WITH PROTECTED FILE .BR FTLEXT ;FALL THRU TO FTLEXT: FTLEXT: .PRINT #MESF .PRINT R2 BISB #,@#$USRRB ;SET FATAL ERROR BIT IN USER ERR BYTE ALLEXT: .PURGE #ETIOCH ;FREE THE CHANNELS .PURGE #ELIOCH ;CLEAN UP CLR R0 .EXIT ;ALL DONE .SBTTL MESSAGES .ENABL LC .NLIST BIN MESW: .NLCSI TYPE=I,PART=PREFIX .ASCII /W-/<200> MESF: .NLCSI TYPE=I,PART=PREFIX .ASCII /F-/<200> MESDEV: .ASCII /What is the name of the device for the ERRLOG.DAT file/ .ASCII / ? /<200> MESNFD: .ASCII /File not found /<200> NFTEMP: .WORD 0,0,0,0,0,0,0,0 MESSZ1: .ASCII /How many blocks for the ERRLOG.DAT file MESSZ2: .ASCII />? /<200> MESUS1: .ASCIZ / blocks currently in use of/ MESUS2: .ASCIZ / possible total in ERRLOG.DAT file/ MESINI: .ASCII /Do you want to zero the ERRLOG.DAT file and re-initialize/ .ASCII \ (YES/NO) ? \<200> MESGEN: .ASCIZ /New ERRLOG.DAT file generated/ MESIV1: .ASCIZ /The current ERRLOG.DAT file is invalid/ MESIV2: .ASCIZ /The invalid file is renamed ERRLOG.TMP/ MESDON: .ASCIZ /RT-11 ERROR LOGGING INITIATED/ MESILL: .ASCIZ /Invalid command/ MESFCH: .ASCIZ /Device not available/ MESCHN: .ASCIZ /Channel error/ MESIOR: .ASCIZ /ERRLOG.DAT file IO error/ MESBAD: .ASCIZ /Internal error/ MESFUL: .ASCIZ /Device full/ MESNFG: .ASCIZ /ERRLOG task not active/ MESPRT: .ASCIZ /Protected file already exists ERRLOG.DAT/ .LIST BIN .DSABL LC .SBTTL DATA AREA FCREAT: .BYTE 0 ;FILE CREATION FLAG (1=YES, 0=NO) FINIT: .BYTE 0 ;FILE INITILIZATION FLAG (1=YES, 0=NO) FCHGSZ: .BYTE 0 ;FILE SIZE CHANGE FLAG (1=YES, 0=NO) .EVEN INSTAT: .BLKW 5 ;EMT ARGUMENT BLOCK JBDES: .RAD50 /MQ/ ;JOB DESCRIPTOR FOR EL TASK .ASCII /ERRLOG/ ;USED TO SEND THE HEADER TO EL TASK ;*** [START CRITICAL ORDERING] *** ELFILE: .RAD50 /SY/ ;RAD50 FOR LOOKUP AND RENAME .RAD50 /ERR/ ;MUST BE .RAD50 /LOG/ ;IN THIS .RAD50 /DAT/ ;ORDER ELTEMP: .RAD50 /SY/ ;FOR .RAD50 /ERR/ ;RENAME .RAD50 /LOG/ ;REQUEST .RAD50 /TMP/ ;*** [END CRITICAL ORDERING] *** LINBUF: .BLKB 82. ;IO LINE BUFFER FILSPC: OSPEC: .BLKW 3*5. ISPEC: .BLKW 6*4. DEFEXT: .WORD 0,0 ;DEFAULT EXTENSIONS FOR CSI .WORD 0,0 BUFBLK: .BLKW ;TEMPORARY STORAGE FOR HEADER BLOCK ;DURING INIT ;HEADER BLOCK DEFINITION ; *** NOTE *** ; The following information is order critical HEADER: OFIXED: .WORD <*2> ;OFFSET TO START OF FIXED PART OF HEADER BLOCK DEVSTS: .WORD -1 ;DEVICE STATISTICS - INIT TO BUFFER TERMINATOR .BLKW ;THE DEVICE STATISTICS ENTRIES CERECR: .WORD 0 ;TOTAL ERROR RECORDS RECEIVED CMENTB: .WORD 0 ;COUNT OF MISSED ENTRIES - BUFFER FULL CMENTF: .WORD 0 ;COUNT OF MISSED ENTRIES - FILE FULL CMENTR: .WORD 0 ;COUNT OF MISSED ENTRIES - TASK NOT READY CMPARE: .WORD 0 ;# OF MEMORY PARITY ERRORS CCPARE: .WORD 0 ;# OF CACHE PARITY ERRORS PNXREC: .WORD 1 ;NEXT PHYSICAL RECORD NUMBER PNXBLK: .WORD 1 ;BLOCK NUMBER OF NEXT RECORD PNXWRD: .WORD 0 ;OFFSET WITHIN BLOCK OF NEXT RECORD SMAXSZ: .WORD 100. ;MAXIMUM SIZE OF ERROR FILE IN BLOCKS CNFGW1: .WORD 0 ;CONFIG WORD 1 CNFGW2: .WORD 0 ;CONFIG WORD 2 INIDAT: .WORD 0 ;DATE OF INITIALIZATION INTIM1: .WORD 0 ;TIME OF INITIALIZATION - WORD 1 INTIM2: .WORD 0 ;TIME OF INITIALIZATION - WORD 2 HEDRSZ = ;SIZE OF HEADER RECORD IN BYTES HEDRWD = ; End of critical ordering .SBTTL NUMBER - BINARY TO DECIMAL ASCII ;+ ; NUMBER CONVERTS A NUMBER TO DECIMAL AND PRINTS IT ; ; R0 = NUMBER TO BE CONVERTED/PRINTED ; ; JSR PC,NUMBER ; ; VALUE OF NUMBER IS OUTPUT TO TTY ;- NUMBER: CLR R2 ;ZERO COUNT 1$: MOV #10.,R1 ;DIVIDE THE NUMBER BY 10.. JSR PC,DIV ADD #60,R1 ;MAKE THE REMAINDER ASCII. MOV R1,-(SP) ;SAVE ON THE STACK. INC R2 ;KEEP COUNT. TST R0 ;TEST IF DONE. BNE 1$ ;NO. MOV #LINBUF,R3 ;YES,USE LINBUF TO STORE NUMBER TO PRINT. 2$: MOVB (SP)+,(R3)+ ;STORE THE CHARACTERS. DEC R2 ;TEST IF DONE. BNE 2$ ;NO. MOVB #200,(R3) ;YES,STORE THE PRINT TERMINATOR. .PRINT #LINBUF ;PRINT THE NUMBER. RTS PC .SBTTL DIV - DIVISION ROUTINE ;+ ; DIV PERFORMS DIVISION WITH INPUTS AND OUTPUTS AS GIVEN ; ; R0 = DIVIDEND ; R1 = DIVISOR ; ; JSR PC,DIV ; ; R0 = QUOTIENT ; R1 = REMAINDER ;- DIV: MOV #20,-(SP) ;SET LOOP COUNT MOV R1,-(SP) ;SAVE DIVISOR FOR SUBTRACTS CLR R1 ;CLEAR REMAINDER 30$: ASL R0 ;DOUBLE LEFT SHIFT ROL R1 ; CMP R1,(SP) ;SUBTRACT OUT DIVISOR? BLO 40$ ;IF LO NO SUB (SP),R1 ;SUBTRACT OUT DIVISOR INC R0 ;ADD IN LOW BIT 40$: DEC 2(SP) ;DECREMENT REPEAT COUNT BGT 30$ ;IF GT MORE TO GO 50$: CMP (SP)+,(SP)+ ;CLEAN STACK RTS PC .SBTTL ABCVRT - DECIMAL ASCII TO BINARY ;+ ; ABCVRT CONVERTS A POSITIVE ASCII DECIMAL STRING TO A NUMBER ; ; R0 -> INPUT STRING ; ; JSR PC,ABCVRT ; ; R0 = VALUE OF CONVERTED NUMBER ;- ABCVRT: MOV R3,-(SP) ;SAVE R3 AND R4 MOV R4,-(SP) ; CLR R4 ;CLEAR ACCUMULATOR 1$: MOVB (R0)+,R3 ;GET NEXT CHARACTER SUB #N0CHAR,R3 ;CHECK FOR DIGIT CMPB R3,#RADDEC ; BHIS 2$ ;NO, END OF NUMBER ASL R4 ;MULTIPLY ADD R4,R3 ;BY ASL R4 ;10. ASL R4 ; ADD R3,R4 ;PUT IN NEW DIGIT BR 1$ ;GET NEXT DIGIT 2$: MOV R4,R0 ;ALL DONE STORE RESULT MOV (SP)+,R4 ;RESTORE MOV (SP)+,R3 ;REGISTERS RTS PC ;AND RETURN .END ELINIT