.MCALL .MODULE .MODULE LIBR,VERSION=12,COMMENT= IDENT=NO,MODNAME=LIBR5,GLOBAL=.LIBR5 ; 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. .SBTTL MACRO LIBRARY CREATION .ENABL GBL ; CER,MAS,DBB .IIF NDF EIS$ EIS$=0 ;SAY EIS NOT AVAILABLE ; EDIT HISTORY: ; ADD .ENTER AND .CLOSE PROTECTION VIOLATION ERROR MESSAGES ;MAS07 ; FIX SEARCH PROBLEM WITH SIGNIFICANT "." ;MAS08 ; FIX STACK POINTER MAINTENANCE PROBLEM WITH QUICKSORT ;DBB01 ; ALLOW "{","|","}", AND "~" IN MACROS ;DBB02 ; GENERATE WARNING FOR DUPLICATE MACROS AND IGNORE ALL BUT FIRST ;DBB03 ; ALLOW KEYWORDS AND MACRO NAMES TO BE IN MIXED UPPER-LOWER CASE ;DBB04 ; ALLOW 128TH HELP MACRO TO BE ADDED TO HELP TEXT ;GWT01 ; TEST FOR PAIRING OF .MACRO AND .ENDM KEYWORDS ;LB ; 11 15-May-91 WFG Update version numbers of all LIBR files ; 12 13-Jan-98 TDS Update all version numbers to 12 for 5.7 ; .SBTTL - SYMBOLIC DEFINITIONS SPACE= 40 TAB= 11 LF= 12 FF= 14 CR= 15 BYTBLK= 512. ;BYTE BLOCK SIZE ENTSIZ= 10 ;LENGTH OF SORT ITEM IN BYTES .SBTTL - DEFINE MACRO LIBRARY HEADER L$TYP= 0 ;LIBRARY TYPE L$ID= 1 ;LIBRARY FILE ID L$VER= 2 ;LIBRARY VERSION L$DAT= 6 ;DATE AND TIME LAST INSERT L$ES= 22 ;SIZE EPT ENTRIES L$ET= 24 ;EPT STARTING RELATIVE BLOCK L$EI= 26 ;NO. OF EPT ENTRIES ALLOCATED L$EA= 30 ;NO. OF EPT ENTRIES AVAILABLE L$MS= 32 ;SIZE MNT ENTRIES L$MT= 34 ;MNT STARTING REL BLOCK L$MI= 36 ;NO. MNT ENTRIES ALLOCATED L$MA= 40 ;NO. MNT ENTRIES AVAILABLE L$LD= 42 ;LOGICALLY DELETED L$LA= 46 ;CONTIGUOUS SPACE L$NX= 52 ;NEXT INSERT RELATIVE BLOCK .SBTTL - MACRO DEFINITION MODULE TYPE TY$MAC= 1 ;MACRO DEF MODULE TYPE M$MAC= 10 ;MNT ENTRY SIZE ID$= 2 ;LIBRARY FILE ID .SBTTL - MACRO DEFINITIONS .MCALL .CLOSE,.DATE,.WRITW,.GTIM,.SETTOP .MACRO ERROR$ ERNB,SEV,ETYP,REG .IF NB REG .IIF DIF , MOV REG,R0 .IFF .IIF IDN , CLR R0 .ENDC JSR R5,ERROOT .BYTE ERNB, SEV*200!ETYP .ENDM .IF Z EIS$ .MACRO SOB A,B DEC A BNE B .ENDM .ENDC .WORD 10 ;ERROR HANDLING INDEX WORD(IN A DATA SECTION) ;MUST BE 1ST PHYSICAL LOCATION OF EACH OVERLAY GTIM: .WORD 21*400 ;.GTIM CODE & QUICKSORT FLAG SRTFLG: ;BUBBLE SORT FLAG .BLKW ;ADR TO STORE 2 WD TIME VALUE ; THIS OVERLAY CREATES THE USER REQUESTED MACRO LIBRARY. .SBTTL MACLBR:: CREATE A MACRO LIBRARY ; CREATE THE LIBRARY HEADER BLOCK IN THE OUTPUT FILE MACLBR:: ; IF THE INPUT AND OUTPUT FILE NAMES ARE THE SAME THEN GIVE ERROR. MOV #ODBLK,R0 ;R0 -> OUTPUT FILE SPEC TST (R0)+ ;WAS AN OUTPUT FILE GIVEN ? BEQ 30$ ;YES IF 0 MOV #ODBLK+2+<3*5*2>,R1 ;R1 -> INPUT FILE SPECS MOV #6,R2 ;MAX OF 6 INPUT FILES 10$: CMP @R0,@R1 ;FILNAM.TYP THE SAME ? BNE 20$ ;NO IF NE CMP 2(R0),2(R1) BNE 20$ CMP 4(R0),4(R1) BNE 20$ ERROR$ ERR27,E$F,E$PRT ;INPUT AND OUTPUT FILES SAME NAME 20$: ADD #8.,R1 ;NEXT INPUT FILE SOB R2,10$ 30$: MOV EPTST,R3 ;R3 -> START OF RESIDENT ENTRY POINT TBL ;INCLUDES A 1 BLK HEADER & MODULE NAME TBL MOV R3,EPTPTR ;INIT EPT BUFR PTR AT START OF BUFR CLR R0 ;CLEAR OUT A 1 BLK HEADER MOV #256.,R1 ;1 BLK = 256 WORDS 40$: CALL PUTEPT SOB R1,40$ MOV #ID$*400+TY$MAC,@R3 ;MACRO LIBRARY TYPE & FILE ID MOV #L.HVER,L$VER(R3) ;LIBRARY VERSION NO. MOV #M$MAC,L$MS(R3) ;SIZE MNT ENTRY MOV #1,L$MT(R3) ;MNT STARTING REL BLOCK MOV DEFMNT,R0 ;GET MNT ENTRY NO. ADD #77,R0 ;MAKE IT MULTIPLE OF 64 BIC #77,R0 MOV R0,L$MI(R3) ;NO. OF MNT ALLOCATED MOV R0,L$MA(R3) ;NO. OF MNT AVAILABLE ASL R0 ASL R0 SWAB R0 MOV R0,OBLK ;INIT REL BLK # -1 FOR OUTPUT MOV #GTIM,R0 ;R0 -> .GTIM REQUEST AREA ADD #L$DAT+2,R3 ;ADR TO STORE TIME VALUE IN HEADER MOV R3,2(R0) ;ADR OF 2 WD TIME IN REQ AREA .GTIM .DATE ;GET TODAY'S DATE MOV R0,-(R3) ;PUT DATE IN HEADER CALL INIO ;PREPARE FOR INPUT .SBTTL INMAC INSERT MACRO NAMES IN THE MACRO NAME TABLE (MNT) ;+ ; THIS ROUTINE SCANS FOR FIRST LEVEL MACRO DEFINITIONS IN THE INPUT FILE. ; IT CREATES THE MNT ENTRY FOR EACH DEFINITION IT FINDS AND ONLY SWITCHES ; TO THE MAIN PROGRAM LOOP WHEN IT IS SCANNING LINES OF A MACRO DEFINITION ; WHICH MUST BE WRITTEN TO THE LIBRARY FILE. THEREFORE IT MUST DO ITS OWN ; INPUT WHILE IT SCANNING OUTSIDE OF A MACRO DEFINITION. ; R4 MUST BE PRESERVED DURING INPUT OPERATIONS ;- .ENABL LSB INMAC: CALL NEWBLK ;GET INPUT LINE TST DEPLA ;ARE WE INSIDE A MACRO DEFINITION ALREADY? BHI 90$ ;YES CLR COBDEF ;OTHERWISE INDICATE NO END OF MODULE 10$: CALL SCAN ;SCAN FOR NEXT KEY WORD BCS 20$ ;IF NONE FOUND READ NEW LINE CMP R0,#4 ;IS IT .MACRO, .IRP, .IRPC, OR .REPT? BLT 15$ ;IF YES, BRANCH INC ENDMNM ;IT'S AN .ENDM OR .ENDR BR 20$ ;MERGE BELOW 15$: INC MACNUM ;INC .MACRO-TYPE KEYWORD COUNTER TST R0 ;IS KEY WORD ".MACRO"? BEQ 30$ ;YES 20$: CALL NEWBLK ;READ NEXT LINE BR 10$ ;BACK TO SCAN 30$: MOV R3,R2 ;COPY END OF LINE POINTER SUB R1,R2 ;MACRO DEF FOUND, CALCULATE CHARS LEFT ; IN CURRENT LINE BLE 20$ ;IGNORE LINE IF NO MACRO NAME CALL R50WRD ;CONVERT 1ST WD OF NAME TST R0 ;WERE ANY CHARACTERS CONVERTED ? BEQ 20$ ;IF NO NAME, READ NEW LINE MOV R0,-(SP) ;PUSH 1ST WD OF NAME ;DBB03 CLR R0 ;ASSUME 3 CHARS OR LESS IN NAME TST R2 ;WAS A TERMINATOR FOUND ? BMI 40$ ;YES, NO MORE CHARACTERS TO CONVERT CALL R50WRD ;CONVERT SECOND WORD 40$: MOV R0,-(SP) ;PUSH 2ND WD OF MACRO NAME ;DBB03+ CLR (PC)+ ;ASSUME NO DUPLICATE NAMES INSERR: .BLKW ;DUPLICATE MACRO NAME FLAG MOV EPTPTR,R0 ;START SEARCH FROM END OF MNT BR 60$ 50$: TST -(R0) ;SKIP OVER FIRST HALF OF SYMBOL 60$: CMP R0,EPTST ;ARE WE DONE SEARCHING? BLOS 70$ ;BRANCH IF YES CMP -(R0),-(R0) ;SKIP OVER BLOCK # AND BYTE DISPLACEMENT CMP -(R0),@SP ;DOES CURRENT MACRO NAME MATCH THIS ENTRY? BNE 50$ ;BRANCH IF NO MATCH CMP -(R0),2(SP) ;2ND HALF MATCHES; DOES 1ST HALF? BNE 60$ ;BRANCH IF NO MATCH MOV R0,-(SP) ;SAVE R0 ERROR$ ERR35,E$W,E$SYM ;DUPLICATE MACRO NAME OF "MACRO NAME" MOV (SP)+,R0 ;RESTORE R0 INC INSERR ;FLAG THE MATCH SO WE'LL SKIP THIS MACRO 70$: TST INSERR ;DO WE HAVE A NEW MNT ENTRY? BNE 80$ ;BRANCH IF WE'RE SKIPPING THIS MACRO MOV 2(SP),R0 ;GET 1ST HALF OF MACRO NAME CALL PUTEPT ;PLACE IT IN MNT MOV (SP)+,R0 ;GET 2ND HALF OF MACRO NAME CALL PUTEPT ;PLACE IT IN MNT TST (SP)+ ;CLEAN UP STACK ;DBB03- MOV OBLK,R0 ;CURRENT OUTPUT BLK # INC R0 ;BUMPED BEFORE WRITE CALL PUTEPT MOV OBPTR,R0 ;GET CURRENT OUTPUT BUFR PTR TO SUB OBUF,R0 ; & CALC BYTE DISPLACEMENT CALL PUTEPT 80$: INC DEPLA ;WE ARE IN A MACRO DEF NOW BR 110$ ;HAVE LINE WRITTEN TO LBR FILE 90$: CALL SCAN ;SCAN FOR KEY WORD BCS 110$ ;WRITE LINE IF NONE FOUND CMP R0,#4 ;.MACRO, .REPT, .IRPC OR .IRP? BGE 100$ ;IF NOT, BRANCH INC DEPLA ;OTHERWISE INC MACRO DEPTH INC MACNUM ;INC .MACRO-TYPE KEYWORD COUNTER BR 110$ ;AND WRITE LINE 100$: INC ENDMNM ;IT'S .ENDM OR .ENDR , INC COUNTER 105$: DEC DEPLA ;MUST HAVE BEEN ".ENDM" OR ".ENDR" BNE 110$ ;WRITE LINE IF STILL IN MACRO DEF INC COBDEF ;OTHER INDICATE END OF MACRO DEF ;WRITE LAST LINE AND ADJUST POINTERS 110$: CALL PUTLIN ;WRITE OUT CURRENT LINE TST COBDEF ;CHECK END FLAG BLE INMAC ;IF NOT SET, CONTINUE READING MODULE MOV EPTST,R0 ;UPDATE HDR DEC L$MA(R0) ;AVAILABLE MNT - 1 BGE INMAC ;YES ERROR$ ERR11,E$F,E$PRT ;MACRO NAME TABLE FULL, USE /M:NNN .DSABL LSB .SBTTL SCAN SCANS FOR KEY WORDS IN THE INPUT SOURCE FILES. ;+ ; OUTPUT: ; C = 1 IF NO KEY WORD WAS FOUND ON CURRENT LINE. ; C = 0 IF A KEY WORD WAS FOUND, AND ; R1 -> FIRST CHARACTER OF OPERAND FIELD (OR PAST END OF LINE) ; R3 -> PAST LAST CHAR ON CURRENT LINE ; R0 = 0 IF IT WAS ".MACRO" ; 1 IF IT WAS ".REPT" ; 2 IF IT WAS ".IRPC" ; 3 IF IS WAS ".IRP" ; 4 IF IT WAS ".ENDM" ; 5 IF IT WAS ".ENDR" ;- SCAN: MOV R5,-(SP) ;SAVE IT MOV #TEMP,R1 ;R1 -> LINE BUFR MOV MODCNT,R3 ;PICK UP CHARACTER COUNT ADD R1,R3 ;R3 -> CHAR PAST END OF LINE 10$: BIS #1,R2 ;INITIALLY INDICATE NO KEY WORD ON LINE CALL SKIP ;POINT R1 TO FIRST NON BLANK BCS 50$ ;BRANCH IF NOTHING ON LINE CMPB #'.,@R1 ;FIRST CHAR "." (POSSIBLE KEY WORD)? BNE 20$ ;NO INC R1 ;OTHERWISE POINT TO NEXT CHARACTER JSR R5,CMPSTR ;SEE IF KEY WORD .WORD 6 .WORD MACSTR .WORD REPSTR .WORD IRCSTR .WORD IRSTR .WORD ENMSTR .WORD ENRSTR 20$: MOV R1,R5 ;SAVE CURRENT STRING POINTER CALL SKIP ;POINT TO NEXT NONBLANK BCS 40$ ;BRANCH ON LINE TERMINATION 30$: CMPB (R1)+,#': ;RESTART LINE SCAN FOR LABEL BEQ 10$ ;BRANCH IF SO CMPB -(R1),#'= ;CHECK FOR ASSIGNMENT STATEMENT SEC ;PREPARE TO RETURN STATUS OF NO KEY WORD BEQ 50$ ;RETURN IF ASSIGNMENT CMP R1,R5 ;SEE IF POINTER WAS BUMPED IN "SKIP" BNE 40$ ;IF IT WAS, THEN OPERATOR HAS BEEN SCANNED BIS #1,R2 ;COULD NOT HAVE SCANNED KEY WORD INC R1 ;OTHERWISE BUMP POINTER BR 20$ ;CONTINUE SCAN 40$: ROR R2 ;SET RETURN STATUS 50$: MOV (SP)+,R5 RETURN .SBTTL - KEY WORD STRINGS .NLIST BEX MACSTR: .ASCIZ /MACRO/ REPSTR: .ASCIZ /REPT/ IRCSTR: .ASCIZ /IRPC/ IRSTR: .ASCIZ /IRP/ ENMSTR: .ASCIZ /ENDM/ ENRSTR: .ASCIZ /ENDR/ .EVEN .LIST BEX .SBTTL CMPSTR COMPARE STRINGS ;+ ; THIS ROUTINE COMPARES A STRING IN THE INPUT BUFFER WITH A SET OF ; STRINGS POINTED TO IN THE CALL. IF A CHARACTER IN THE INPUT ; STREAM IS LOWERCASE AND THE CHARACTER IN THE SAME POSITION IN ; A TEMPLATE STRING IS UPPERCASE, THE CHARACTERS WILL BE TREATED ; AS A MATCH. HOWEVER, THE INPUT CHARACTER WILL REMAIN IN LOWERCASE. ; ; CALLED BY: JSR R5,CMPSTR ; .WORD COUNT ;# OF STRING POINTERS BEING PASSED ; .WORD STRPT0 ; .WORD STRPT1 ; ... ; ; WHERE: ; STRPT0,STRPT1,... ARE POINTERS TO ASCIZ STRINGS ; R1 -> THE TEST STRING ; ; OUTPUT: ; R2 = 1 IF NO MATCH WAS FOUND ;MAS08 ; R2 = 0 IF MATCH WAS FOUND, AND ; R1 -> FIRST CHARACTER OF OPERAND FIELD (OR PAST END OF LINE) ; R0 CONTAINS NUMBER OF STRING POINTER THAT WAS MATCHED. ;- CMPSTR: MOV (R5)+,R0 ;PICK UP COUNT MOV R0,-(SP) ;AND SAVE IT MOV R1,-(SP) ;SAVE STRING POINTER 10$: MOV @SP,R1 ;PICK UP INPUT STRING PTR MOV (R5)+,R2 ;PICK COMPARE STRING PTR 20$: TSTB @R2 ;AT END OF COMPARE STRING? BEQ 40$ ;MATCH IF SO MOVB (R1)+,-(SP) ;GET NEXT CHARACTER FROM INPUT STRING ;DBB04+ CMPB @SP,#141 ;IS CHARACTER CODE AT LEAST A L.C. 'A' BLO 30$ ;BRANCH IF NOT CMPB @SP,#172 ;IS CHARACTER CODE AT MOST A L.C. 'Z' BHI 30$ ;BRANCH IF NOT SUB #40,@SP ;CONVERT COPY OF INPUT CHAR TO U.C. 30$: CMPB (SP)+,(R2)+ ;COMPARE THIS CHARACTER ;DBB04- BEQ 20$ ;LOOP IF EQUAL SOB R0,10$ ;LOOP UNTIL STRING POINTERS EXHAUSTED MOV (SP)+,R1 ;RESTORE INPUT STRING POINTER TST (SP)+ ;POP SAVED COUNT MOV #1,R2 ;MAKE SURE R2 IS ODD ;MAS08 BR 50$ ;BRANCH TO EXIT 40$: TST (SP)+ ;THROW AWAY SAVED STRING POINTER ADD R0,R5 ;BUMP R5 PAST ADD R0,R5 ; LAST STRING PTR TST -(R5) ; & -> INSTRUCTION AFTER CALL SUB (SP)+,R0 ;CALCULATE NEGATIVE OF NUMBER OF MATCH NEG R0 ;MAKE POSITIVE CLR R2 ;INDICATE SUCCESSFUL MATCH 50$: .SBTTL OV5DUM:: DUMMY ENTRY POINT TO MAKE IT RESIDENT OV5DUM::RTS R5 .SBTTL SKIP POINT R1 TO THE NEXT NONBLANK IN THE CURRENT LINE. ;+ ; INPUT: ; R1 -> CURRENT CHAR POSITION IN LINE ; R3 -> PAST LAST CHAR ON CURRENT LINE ; ; OUTPUT: ; C = 0 IF SUCCESSFUL ; C = 1 IF ";" OR END OF LINE SEEN ; R3 = SAME AS INPUT ;- SKIP: CMP R1,R3 ;END OF LINE? BHIS 30$ ;BRANCH TO RETURN C-BIT SET IF SO CMPB #LF,@R1 ;LINE FEED? BEQ 30$ ;YES CMPB #FF,@R1 ;FORM FEED? BEQ 30$ ;YES CMPB #CR,@R1 ;CARRIAGE RETURN? BEQ 20$ ;YES, IGNORE 10$: CMPB #';,@R1 ;COMMENT FIELD? BEQ 30$ ;YES CMPB (R1)+,#TAB ;CURRENT CHARACTER A TAB? BEQ SKIP ;YES, SO BUMP PTR CMPB #SPACE,-(R1) ;CURRENT CHARACTER SPACE? CLC ;PREPARE TO RETURN C-BIT CLEAR IF NOT BNE 40$ ;YES, RETURN SUCCESSFULLY 20$: INC R1 ;BUMP POINTER PAST SPACE OR TAB BR SKIP ;CHECK NEXT CHAR 30$: SEC ; ";" OR END OF LINE 40$: RETURN .REPT 0 .SBTTL ELIM ELIMINATE TRAILING BLANKS AND TABS FROM THE CURRENT SOURCE LINE. ;+ ; INPUT: ; R1 CONTAINS CHARACTER OF CURRENT LINE ; R3 -> PAST LAST CHARACTER ON CURRENT LINE ; ; OUTPUT: ; R1 CONTAINS UPDATED CHARACTER COUNT ; R3 -> PAST LAST NONBLANK, NONTAB CHARACTER ON LINE ;- ELIM: CMPB -(R3),#TAB ;CURRENT LAST CHAR A TAB? BEQ 10$ ;IF EQ YES CMPB #SPACE,@R3 ;CURRENT LAST CHAR A BLANK? BNE 20$ ;IF NE NO 10$: DEC R1 ;REDUCE COUNT FOR TRAILING CHAR BNE ELIM ;IF NE MORE CHARS ON LINE 20$: INC R3 ;R3 -> PAST CURRENT END OF LINE RETURN .ENDR .SBTTL PUTLIN OUTPUT CURRENT LINE TO MACRO LIBRARY ; CLOBBERS R0,R1,R5,R3 .ENABL LSB PUTLIN: MOV MODCNT,R5 ;R5 = # OF BYTES IN CURRENT LINE BLE 30$ ;LINE IS EMPTY TST INSERR ;ARE WE SKIPPING THIS MACRO ;DBB03 BNE 20$ ;BRANCH IF YES; DON'T DO OUTPUT ;DBB03 MOV #TEMP,R3 ;R3 -> LINE BUFR 10$: MOVB (R3)+,R1 ;GET BYTE IN R1 & OUTPUT IT CALL PUTBYT SOB R5,10$ 20$: CLR MODCNT ;IF CALLED AGAIN WILL NOT OUTPUT SAME LINE 30$: RETURN .SBTTL PUTEPT PUT WORD INTO RESIDENT ENTRY POINT TABLE(R0=WORD) PUTEPT: MOV R0,@EPTPTR ;INSERT VALUE AT CURRENT PTR ADD #2,EPTPTR ;BUMP PTR TO NEXT WORD CMP EPTPTR,@#HIGH ;REACH THE HIGH LIMIT OF AVAILABLE MEMORY? BLO 30$ ERROR$ ERR3,E$F,E$PRT ;INSUFFICIENT MEMORY FOR MNT .DSABL LSB .SBTTL NEWBLK READ IN A LINE FROM THE INPUT FILE ;+ ; INPUT: ; R4 -> CURRENT BUFFER POSITION ; ENDBUF -> END OF BUFFER ; ; OUTPUT: ; MODCNT & R5 = NUMBER OF BYTES IN THE LINE ; R1 -> 1ST DATA WORD OF NEW BLK ; STORES THE LINE IN A TEMP BUFR AT "TEMP" ; CLOBBERS R0 ;- NEWBLK: CLR R5 ;BYTE COUNT MOV #TEMP,R1 ;R1 -> LINE BUFFER 10$: CALL BYTE ;GET NEXT INPUT BYTE IN R0 BIC #177600,R0 ;STRIP ASCII TO 7 BITS CMPB #177,R0 ;IGNORE CHAR? ;DBB02 BLOS 10$ ;YES INC R5 ;ASSUME GOOD CHARACTER MOVB R0,(R1)+ ;STUFF IT INTO LINE CMPB #SPACE,R0 ;GOOD CHAR? BLOS 10$ ;YES 20$: CMPB #LF,R0 ;LINE TERMINATER BNE 40$ ;TRY AGAIN 30$: MOV R5,MODCNT ;SAVE COUNT RETURN 40$: CMPB #CR,R0 ;LEAVE ALONE BEQ 10$ CMPB #TAB,R0 ;LEAVE TABS BEQ 10$ CMPB #FF,R0 ;ALTERNATE TERMINATER BEQ 30$ ;YES 50$: DEC R5 ;NO, IGNORE ALL OTHERS DEC R1 ;REMOVE FROM BUFFER BR 10$ .SBTTL R50WRD ASCII TO RAD50 CONVERSION ROUTINE FOR MACRO NAME'S ;+ ; REGISTER USAGE NOTES: ; R0 RAD50 VALUE TO BE RETURNED ; R1 ADRS OF NEXT INPUT CHARACTER ; R2 MAXIMUM NUMBER OF INPUT CHARACTERS LEFT(NEG IF NON-RAD50 FOUND) ; R3 WORK REGISTER ;- R50WRD: MOV R3,-(SP) ;SAVE IT MOV #2,-(SP) ;SET LOOP COUNT (3 CHARS/WORD) CLR R0 ;ZERO ACCUMULATOR WORD 10$: CLR -(SP) ;ZERO CURRENT RAD50 CHAR DEC R2 ;ANY CHARS LEFT TO PROCESS BMI 50$ ;NO MORE CHARS TO PROCESS MOV #R50TAB,R3 ;GET CONVERSION TABLE POINTER BISB (R1)+,@SP ;GET NEXT INPUT CHAR 20$: CMPB (R3)+,@SP ;.LE. UPPER LIMIT? BLO 30$ ;NOPE - NOT IN THIS RANGE CMPB (R3)+,@SP ;.GT. LOWER LIMIT? BLO 40$ ;YES - FOUND CONVERSION (AND SET CARRY) DEC R3 ;ELSE BUMP OVER REMAINDER 30$: ADD #3,R3 ; OF TABLE ENTRY TST @R3 ;END OF TABLE REACHED? BNE 20$ ;NOPE - CONTINUE LOOKING NEG R2 ;ELSE INDICATE NON-RAD50 CHAR FOUND CLR @SP ;MAKE CURRENT = 0 (AND CLEAR C) 40$: ADD @R3,@SP ;DO TRANSLATION 50$: ASL R0 ;MULTIPLY PREVIOUS BY 50(8) ASL R0 ASL R0 ADD R0,@SP ASL R0 ASL R0 ADD (SP)+,R0 ;AND ADD IN CURRENT CHAR DEC @SP ;ANY CHARS LEFT IN THIS WORD? BPL 10$ ;YES TST (SP)+ ;ELSE DISCARD LOOP COUNT MOV (SP)+,R3 RETURN ;AND RETURN R50TAB: .BYTE 172,140 ;a-z (LOWER CASE) ;DBB04 .WORD -140 ;DBB04 .BYTE 132,100 ;A-Z .WORD -100 .BYTE 71,57 ;0-9 .WORD -22 ; .BYTE 40,37 ;SPACE ;A SPACE IS A TERMINATOR ; .WORD -40 .BYTE 44,43 ;DOLLAR SIGN .WORD -11 .BYTE 56,55 ;PERIOD .WORD -22 .WORD 0 ;END OF TABLE FLAG (MUST BE ZERO) .SBTTL MACEXT:: ALL MACRO INPUT IS DONE ;+ ; DUMP THE REMAINING MACRO TEXT & FORCE OUT CURRENT BUFR. ; THEN PAD MNT WITH -1'S BEFORE CALLING QUICKSORT. ;- MACEXT::CMP MACNUM,ENDMNM ;DO .MACRO-TYPE AND .ENDM-TYPE OCCURRENCES MATCH? BEQ 5$ ;IF YES, BRANCH BLT 3$ ;BR IF THERE ARE MORE .ENDM'S THAN .MACRO'S ERROR$ ERR36,E$F,E$PRT ;TOO MANY .MACRO-TYPE STATMENTS 3$: ERROR$ ERR37,E$F,E$PRT ;TOO MANY .ENDM-TYPE STATMENTS 5$: CALL PUTLIN ;WRITE OUT ANYTHING REMAINING IN CURRENT LINE BUFR CLR R1 ;FORCE OUT CURRENT OUTPUT BUFR MOV #511.,R2 ; BY FILLING WITH 0'S 10$: CALL PUTBYT SOB R2,10$ MOV EPTST,R3 ;R3 -> START OF MNT AREA CMP L$MI(R3),L$MA(R3) ;IF # ALLOCATED & # FREE ARE THE SAME BNE 20$ ; THEN IT IS A NULL LIBRARY ERROR$ ERR14,E$F,E$PRT ;SAY NULL LIBRARY 20$: CLR -(SP) ;QUICKSORT STOP FLAG MOV EPTPTR,-(SP) ;SET STOP ADR FOR QUICKSORT MOV L$MA(R3),R2 ;# OF MNT'S LEFT UNUSED BEQ 40$ ;NO PADING REQUIRED ROL R2 ;TIMES 4 TO COUNT WDS ROL R2 MOV #-1,R0 ;PAD END OF MNT WITH -1'S 30$: CALL PUTEPT SOB R2,30$ 40$: ADD #BYTBLK,R3 ;STARTS AT BLK 1 MOV R3,-(SP) ;SET START ADR OF ITEMS TO SORT MOV #ENTSIZ,R0 ;SET UP PARAMETER CMPB 2(SP),#177777 ;ANY -1's PADDED AT END OF DIRECTORY ? BEQ QUICKS ;YES, BRANCH SUB R0,2(SP) ;DON'T SORT DUMMY TOPIC AT END THEN BR QUICKS ;GO SORT THE CORE LOAD DONSRT: TST (SP)+ ;POP QUICKSORT STOP FLAG ;DBB01 MOV EPTST,R1 ;R1 -> START OF RESIDENT EPT MOV EPTPTR,R2 ;END OF RESIDENT EPT SUB R1,R2 ;R2 = SIZE IN BYTES OF TBL ROR R2 ;C=0 AFTER SUB, NOW WORD COUNT .WRITW #TEMP,#0,R1,R2,#0 ;WRITE LIBR HEADER & EPT AT BLK 0 BCS 20$ .SETTOP FILPT1 ;CAUSE LESS SWAPPING, JUST ABOVE LOADED HANDLERS .CLOSE #0 ;MAKE LIB FILE PERMANENT BCC 10$ ;C=0 -> NO ERROR ON CLOSE ;MAS07+ CMPB #PROTCT,@#ERRBYT ;IS THIS A PROTECTION VIOLATION? BNE 20$ ;NE -> NO MOV #ODBLK,R0 ;POINT AT FILE NAME ERROR$ ERR33,E$W,E$FIL,R0 ;PROTECION VIOLATION ;MAS07- 10$: JMP REENTR ;DONE, GET NEXT COMMAND 20$: ERROR$ ERR23,E$F,E$PRT ;OUTPUT WRITE ERROR .SBTTL - QUICKSORT ROUTINE ;+ ; THIS ROUTINE SORTS A CORELOAD OF CREF DATA ; INPUT: ; R0 = ENTSIZ (THE NUMBER OF BYTES IN A SORT ENTRY) ; @SP = ADDRESS OF FIRST ITEM TO BE SORTED ; 2(SP) = ADDRESS OF LAST ITEM TO BE SORTED ; 4(SP) = 0 (USED AS END-OF-STACK FLAG) ; ; CALLING SEQUENCE: JMP QUICKS ;- QUICKS: MOV @SP,R1 ;LEFT POINTER BEQ DONSRT ;IF ZERO, THEN WE'RE DONE MOV 2(SP),R2 ;RIGHT POINTER CLR GTIM ;RESET WHICH-PTR-TO-MOVE FLAG MOV R2,R3 ;CHECK NUMBER OF ITEMS SUB R1,R3 ;GET # OF ITEMS - 1 (*ENTSIZ) BEQ QPOP2 ;ONLY ONE - IT'S SORTED ALREADY CMP #ENTSIZ*10.,R3 ;11 OR FEWER ITEMS ? BLO 10$ ;NOPE - CONTINUE QUICKSORT MOV R1,R4 ;ELSE SET UP FOR TWO-BUBBLE MOV R1,R5 ; SORT ADD R0,R5 BR SORT ;AND DO IT 10$: MOV R0,R3 ;SET LOOP COUNT MOV R1,R4 ;COPY LEFT PTR MOV R2,R5 ;AND RIGHT PTR 20$: CMP (R4)+,(R5)+ ;COMPARE PAIR OF ENTRIES BHI 80$ ;IF HIGH, MUST INTERCHANGE BLO 30$ ;IF LOW, OKAY SUB #2,R3 ;LOOP UNTIL DONE WITH ENTRY BNE 20$ 30$: TST GTIM ;SHOULD WE MOVE LEFT OR RIGHT PTR? BNE 50$ ;INC LEFT POINTER 40$: SUB R0,R2 ;DEC RIGHT POINTER BR 60$ ;GO SEE IF DONE WITH THIS PASS 50$: ADD R0,R1 ;BUMP LEFT PTR BY ONE ENTRY 60$: CMP R1,R2 ;DONE WITH THIS PASS? BLO 10$ ;NOPE - CONTINUE MOV 2(SP),R3 ;PICK UP FORMER RIGHT PTR MOV @SP,R2 ; AND FORMER LEFT POINTER MOV R1,R4 ;COPY THE ADDRESS WE STOPPED AT MOV R3,R5 ;AND THE FORMER RIGHT POINTER SUB R2,R4 ;SIZE OF LEFT PARTITION SUB R1,R5 ;SIZE OF RIGHT PARTION + ENTSIZ CMP R4,R5 ;WHICH PARTITION IS LARGER ? BHI 70$ ;THE LEFT ONE IS . . . ;+ ; ELSE THE RIGHT PARTITION IS THE LARGER. WE WISH TO STACK ; THE LARGER TO MINIMIZE STACK SIZE AT RUNTIME. ;- MOV R1,@SP ;STORE NEW LEFT PTR ADD R0,@SP ;AND ADD IN ENTSIZ TST R4 ;IS THE LEFT PART NULL? BEQ QUICKS ;YUP - JUST DO THE RIGHT SUB R0,R1 ;GET NEW STOP ADDR MOV R1,-(SP) ;AND STACK IT MOV R2,-(SP) ;ALSO STACK LEFT PTR BR QUICKS ;START SORTING LEFT PARTITION 70$: MOV R1,R2 ;GET STOP ADDRESS SUB R0,R2 ;BACK UP AN ENTRY MOV R2,2(SP) ;AND SET RIGHT PTR ON STACK TST R5 ;IS RIGHT PART NULL? BEQ QUICKS ;YUP - JUST DO THE LEFT MOV R3,-(SP) ;PUT NEW RIGHT PTR ON STACK ADD R0,R1 ;AND NEW LEFT POINTER MOV R1,-(SP) ;STACK IT BR QUICKS ;GO SORT ; EXCHANGE TWO ENTRIES JUST COMPARED. 80$: CMP -(R4),-(R5) ;RESET POINTERS FOR EXCHANGE 90$: MOV @R4,R0 ;EXCHANGE ONE WORD OF EACH MOV @R5,(R4)+ MOV R0,(R5)+ SUB #2,R3 ;LOOP UNTIL ALL WORDS SWITCHED BNE 90$ MOV #ENTSIZ,R0 ;RESET R0 VALUE COM GTIM ;SWITCH POINTER MOVEMENT BEQ 40$ ; AND UPDATE POINTERS BR 50$ QPOP2: CMP (SP)+,(SP)+ ;POP POINTERS BR QUICKS ;AND CONTINUE .SBTTL SORT LOWER-LEVEL SORT ROUTINE ;+ ; ROUTINE IS CALLED FROM QUICKSORT TO HANDLE PARTITIONS ; OF A SMALL NUMBER OF ITEMS (TO MINIMIZE SIZE OF STACK) ; INPUT: ; R0 = ENTSIZ ; R1 = ADDRESS OF FIRST ITEM TO BE SORTED ; R2 = ADDRESS OF LAST ITEM TO BE SORTED ; R4 = ADDRESS OF FIRST ITEM (=R1) ; R5 = ADDRESS OF SECOND ITEM ;- SORT: CLR SRTFLG ;CLEAR BACKUP FLAG 10$: CMP R4,R2 ;DONE YET? BHIS QPOP2 ;YUP - RETURN TO QUICKSORT MOV R0,R3 ;ELSE SET LOOP COUNT 20$: CMP (R4)+,(R5)+ ;COMPARE NEXT TWO ENTRIES BNE 30$ SUB #2,R3 BNE 20$ BR 40$ ;IF THEY WERE EQUAL, BRANCH 30$: CMP -(R4),-(R5) ;BACKUP POINTERS BHI 50$ ;BRANCH IF WE MUST EXCHANGE ADD R3,R4 ;ELSE UPDATE TO NEXT ITEM ADD R3,R5 40$: TST SRTFLG ;WERE WE GOING BACKWARDS? BEQ 10$ ;NOPE - JUST CONTINUE MOV SRTFLG,R4 ;ELSE PICK UP START ADDR MOV R4,R5 ;SET UP SECOND POINTER ADD R0,R5 ;PUSH UP ONE ITEM BR SORT ;AND CONTINUE 50$: MOV @R4,R0 ;EXCHANGE DISORDERED ITEMS MOV @R5,(R4)+ MOV R0,(R5)+ SUB #2,R3 BNE 50$ TST SRTFLG ;BACKING UP ALREADY? BNE 60$ ;YUP - SKIP POINTER SETUP MOV R4,SRTFLG ;ELSE NOTE WHERE TO RESTART 60$: MOV #ENTSIZ*2,R0 ;PREPARE TO BACK UP ONE ENTRY SUB R0,R4 SUB R0,R5 ASR R0 ;R0 = ENTSIZ CMP R5,R1 ;BACK TO THE BEGINNING? BHI 10$ ;NOPE - KEEP BACKING UP BR 40$ ;YES - RESET BACKUP AND CONTINUE .PSECT PATCH ;THIS IS A PATCH PSECT TO BE ;USED FOR BUG FIXES .BLKW 64. .END