.MCALL .MODULE .MODULE LINK,VERSION=45,COMMENT= IDENT=NO,MODNAME=LINK7,GLOBAL=.LINK7 ; 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 SAVE AND REL FILE OUTPUT .ENABL GBL ; CER,MAS,SHD,DBB,LB .IIF NDF LDA$ LDA$= 1 ;TURN ON LDA FEATURE .IIF NDF REL$ REL$= 1 ;TURN ON REL FILE SUPPORT .IIF NDF EIS$ EIS$= 0 ;SAY NO EIS AVAILABLE ; EDIT HISTORY ; HANDLE ABS SECTION WITH 0 LENGTH & DON'T STORE TEXT ;CER02 ; FIX OVERLAYED REL INFORMATION FROM LIRBARIES ;CER03 ; FIX LDA TEXT BLOCK OUTPUT ;MAS04 ; ADD WORD RELOCATION ERROR ;MAS06 ; PUT OVERLAY HANDLER IN SYSLIB ;MAS07 ; LIBRARY MODULES INTO OVERLAYS ;MAS10 ; FIX /X BITMAP PROBLEM ;MAS11 ; XM OVERLAYS ;MAS15 ; FIX TST AND CMP WHERE SHOULD BE ADD OR SUBT ;MAS17 ; REORGANIZE OVERLAYS, AND TIGHTEN CODE ;MAS21 ; FIX RELOCATION OF OVERLAY HANDLER GBL DEFINITIONS ;MAS25 ; FIX BYTE RELOCATION ERROR MESSAGE ;MAS38 ; FIX RELOCATION OF ABS,CON PSECTS ;SHD01 ; FIX .VSECT RELOCATION BUG ;SHD02 ; FIX ABS REFERENCE RELOCATION FOLLOWING A VSECT REFERENCE ;SHD03 ; ALLOW ADDITIVE RELOCATION OF GLOBAL IN OVERLAYS IF IT IS NOT ; REFERENCED IN AN EXTERNAL SEGMENT ;DBB01 ; FIX BYTE DISPLACEMENT BUG ;DBB02 ; OUTPUT OVERLAY TABLE WHEN ROOT IS ENTIRELY FROM LIBRARY ;DBB03 ; ADD GLOBAL CROSS REFERENCE ;DBB04 ; ADD SUPPORT FOR PSECTS WITH SAV ATTRIBUTE ;DBB05 ; CLEAN UP END-OF-FILE PROCESSING AND STACK MAINTENANCE ;DBB06 ; STANDARDIZE PROGRAMMED REQUESTS ;DBB07 ; ADD I-D SPACE CODE ;LB .SBTTL - MEMORY ORGANIZATION ;+ ; THE LIBRARY MODULE LIST AND INPUT BUFFER AREA HAS BEEN SUBDIVIDED INTO: ; ; *-------------------------------* ; PA2LML-! ! ; ! LIBRARY MODULE LIST ! ; ! (ENDS WITH 0) ! ; *-------------------------------* ; STLML- ! ! ; ! MODULE SECTION TBL ! ; ! (MAX 2 BLKS) ! ; *-------------------------------* ; BITBAD-! ! ; ! SAV FILE MASTER BITMAP ! ; ! ! ; *-------------------------------* ; CACHER-! ! ; ! CACHE CONTROL BLK ! ; ! ! ; *-------------------------------* ; ESZRBA-! ! ; ! 1 BLK RELOCATION INFO BUFR ! ; ! (IF REQUIRED) ! ; *-------------------------------* ; CBUF- ! ! ; ! CREF OUTPUT BUFFER ! ; ! (IF REQUIRED) ! ; *-------------------------------* ; OBUF- ! ! ; ! CACHE OUTPUT BUFFER(S) ! ; ! ! ; *-------------------------------* ; IBUF- ! ! ; ! AT LEAST 1 BLK INPUT BUFR ! ; ! ! ; *-------------------------------* ;- .SBTTL - FORMAT OF SAV FILE MASTER BITMAP ;+ ; EACH BIT IN THE SAV FILE MASTER BIT MAP REPRESENTS A ONE BLOCK (1000 OCTAL ; BYTES) AREA IN THE SAV FILE. THE APROPRIATE BIT IS SET WHEN THE BLOCK ; IS INSERTED INTO THE CACHE. ; ; HIGH BYTE LOW BYTE ; !------------------------!------------------------! ; BITBAD-!10 11 12 13 14 15 16 17 ! 0 1 2 3 4 5 6 7 ! ; !------------------------!------------------------! ; !30 31 32 33 34 35 36 37 !20 21 22 23 24 25 26 27 ! ; !------------------------!------------------------! ; ! !40 41 42 43 44 45 46 47 ! ; !------------------------!------------------------! ; : ; : CONTINUED FOR EACH ; : BLOCK IN SAV FILE ; ; NOTES FOR SEPARATED I-D SPACE ; ; BITBAD POINTS TO THE BITMAP FOR THE D-SPACE CODE. IBITBD POINTS TO ; THE BITMAP FOR THE I-SPACE CODE. THE FORMAT FOR BOTH BITMAPS IS THE ; SAME. THE ONLY DIFFERENCE IS THAT BITMAP CONTAINS ABSOLUTE FILE ; BLOCK NUMBERS - A BITMAP VALUE OF 300 MEANS THAT FILE BLOCKS 0 AND 1 ; ARE WRITTEN. IBITBD POINTS TO BLOCK NUMBERS RELATIVE TO THE I-SPACE ; CCB - AN IBITBD VALUE OF 300 MEANS I-SPACE BLOCKS 0 AND 1 ARE WRITTEN. ; THESE ARE THE FIRST 2 FILE BLOCKS AFTER ALL THE D-SPACE BLOCKS. ; I-SPACE BLOCK 0 = DBASE + 0, I-SPACE BLOCK 0 = DBASE + 1, ETC. ;- .SBTTL - FORMAT OF CACHE CONTROL BLOCKS ;+ ; CACHE CONTROL BLOCK ALWAYS START ON A WORD BOUNDARY ; ; !-------------------------------! ; CASHER-!REL BLOCK NUMBER IN OUTPUT FILE! INITIALLY = 0 ; !-------------------------------! ; !LEAST RECENTLY USED TIME STAMP ! INITIALLY = -1 (177777 OCTAL) ; !-------------------------------! ; !START ADDR OF 1ST 1 BLK BUFFER ! 1 BLOCK = 1000 OCTAL BYTES ; !-------------------------------! ; !REL BLOCK NUMBER IN OUTPUT FILE! INITIALLY = 0 ; !-------------------------------! ; !LEAST RECENTLY USED TIME STAMP ! INITIALLY = -1 ; !-------------------------------! ; !START ADDR OF 2ND 1 BLK BUFFER ! 1000 AFTER 1ST 1 BLK BUFFER ; !-------------------------------! ; : ; : CONTINUED FOR EACH CACHE BLOCK ; : (USUALLY 3 CACHE BLOCKS) ;- .SBTTL - MISCELLANEOUS MACRO DEFINITIONS .MCALL .BR .READW .REOPEN .WDBDF .WRITW ;MAS15 ;DBB07 .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*100!ETYP .ENDM .IF Z EIS$ .MACRO SOB R,L DEC R BNE L .ENDM .ENDC ;+ ; SUBROUTINE CALL AND RETURN TO MAIN PROGRAM, EQUIVILENT TO: ; CALL SUBR ; RETURN ;- .MACRO CALLR SUBR JMP SUBR .ENDM .MACRO SYMADR R ASL R MOV R,-(SP) ASL R ASL R ADD (SP)+,R ADD SYEN0,R .ENDM .WDBDF ;SET UP OFFSETS AND STATUS BITS FOR WDBS ;MAS15 .PSECT DATA,D .WORD 14 ;ERROR HANDLER INDEX(1ST PHYSICAL LOC IN OVLY) .SBTTL DATA FOR OVERLAY HANDLER GLOBAL LOOKUPS ; THE NEXT 4 MUST BE IN THE FOLLOWING ORDER VDF1: .RAD50 /$VDF1/ ;/V OVERLAY HANDLER LOCATIONS ;MAS25+ .RAD50 /$VDF4/ ;THAT REQUIRE RELOCATION .RAD50 /$VDF5/ .RAD50 /$VDF2/ ; THE NEXT 2 MUST BE IN THE FOLLOWING ORDER ODF1: .RAD50 /$ODF1/ ;/O OVERLAY HANDLER LOCATIONS .RAD50 /$ODF2/ ;THAT REQUIRE RELOCATION ;MAS25- ; I-D SPACE VARIABLES PSIZE: .WORD 0 ;SIZE OF THE CURRENT PSECT IN WORDS TXTSP: .WORD 0 ;SPACE OF TEXT IN TXTBLK ; 0 -> I-SPACE, NONZERO -> D-SPACE RLDSP: .WORD 0 ;SPACE OF LATEST RLD ; 0 -> I-SPACE, NONZERO -> D-SPACE TLNSAV: .WORD 0 ;SAVE TXTLEN TBKSAV: .BLKB 128. ;SAVE TXTBLK CONTENTS (SIZE=RECSIZ) JSRADR: .WORD 0 ;START ADDRESS OF JSR,R5 INST IN I-SPACE ROOT .PSECT CODE .SBTTL PASS2:: PRODUCE SAVE IMAGE FILE PASS2:: MOV #PAS1.5,R0 ;R0 -> LIBRARY PASS INDICATOR TSTB @R0 ;PAS1.5 = 0 IF STARTING PASS BNE 10$ ;NE -> PASS ALREADY STARTED JMP PA2 ;GO TO PASS2, START FOR NON-OVERLAID PASS2 10$: ASRB @R0 ;BIT 0 INTO CARRY & CLEAR IT, STILL NEG BCC ENDP2 ;C=1 IF ON LIBRARY PASS JMP LP2 ;GO DO 2ND HALF OF PASS (LIBRARIES) .SBTTL ENDP2 END OF PASS2, FINISH UP THIS LINK ENDP2: .IF NE LDA$ TST SWITCH ;LDA OUTPUT? BPL 20$ ;NO IF + CLR R2 ;PREPARE TO OUTPUT LAST BUFF(6 BYTES) MOV #BEGBLK+6,R1 ;CREATE A TRANFER BLOCK CALL LDAOUT MOV IBUF,R0 ;END OF OUTPUT BUFR - BUFR PTR SUB R2,R0 ;GIVES # OF BYTES TO FILL BUFR BEQ 40$ ;IF 0 THEN EXACTLY FILLED 10$: CLRB (R2)+ ;CLEAR REMAINDER OF BUFR SOB R0,10$ CALL WRIT0 ;WRITE OUT LAST BUFFER BR 40$ ;FINISH UP & CLOSE FILES 20$: .ENDC ;LDA$ .IF NE REL$ TSTB SWITCH ;FOREGROUND LINK ? BPL 40$ ;NO IF + MOV #-2,R0 ;INDICATE END OF REL INFO CALL RELWRD CLR R0 ;FILL REMAINDER OF BUFR WITH 0'S MOV #255.,R1 ;& FORCE OUT LAST BUFR 30$: CALL RELWRD ;DOES NOT MATTER THAT R0 GETS CLOBBERED SOB R1,30$ ;ON PART OF NEXT BUFR .ENDC ;REL$ 40$: TST CBPTR ;IS THERE A CREF FILE TO CLOSE? ;DBB04+ BEQ 60$ ;NO CREF IF EQ MOV #511.,R3 ;SET CNT TO FORCE LAST BUFFER OUT CLR R0 ;ZERO REMAINDER OF BUFFER 50$: CALL PUTCHR ;OUTPUT A NULL BYTE SOB R3,50$ ;REPEAT ; UPDATE SYSCOM AREA IN BLK 0 IF REQUIRED 60$: TST SWITCH ;LDA OUTPUT? ;DBB04- BMI 140$ ;MI -> YES, DONE, GO CLOSE BIT FLGWD,#FG.XX ;SUPPRESS WRITING CCB INFO? BNE 80$ ;YES, HE ASKED FOR IT MOV HLRT,-(SP) ;SAVE I-SPACE HIGH LIMIT OF ROOT SEGMENT BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 70$ ;BRANCH IF NOT MOV DBASE,R0 ;GET I-SPACE CCB BLK NUMBER MOV IBITBD,BITMAP ;GET I-SPACE BITMAP MOV SP,IFLG ;SAY WE'RE WRITING I-SPACE CCB CALL GETBUF ;GET A BUFR FOR IT MOV IBITBD,R2 ;R2 -> BLOCKS WRITTEN I-SPACE BITMAP MOV (SP)+,R0 ;GET I-SPACE ROOT HIGH LIMIT CALL IWRTBM ;WRITE I-SPACE BITMAP MOV DHLRT,-(SP) ;GET D-SPACE ROOT HIGH LIMIT 70$: CLR R0 ;UPDATE SYSCOM AREA IN BLK 0 MOV BITBAD,BITMAP ;GET BLK 0 BITMAP (D-SPACE FOR /J) CLR IFLG ;SAY WE'RE DOING BLK 0 (D-SPACE FOR /J) CALL GETBUF ;GET A BUFR FOR IT MOV BITBAD,R2 ;R2 -> BLOCKS WRITTEN BITMAP - BLK 0 (D-SPACE IF /J) MOV (SP)+,R0 ;GET HIGH LIMIT (HLRT OR DHLRT) CALL DWRTBM ;WRITE BITMAP (BLK 0) ; WRITE OUT CURRENT BLOCKS IN CACHE BUFRS 80$: MOV CACHER,R1 ;R1 -> CACHE CTRL BLK MOV NUMBUF,R2 ;R2 = NUMBER OF CACHED BUFFERS 90$: CMP #-1,(R1)+ ;WAS REL BLK EVER WRITTEN ? BEQ 100$ ;NO IF EQ, MUST BE END OF LIST CALL WRTLRU ;WRITE IT VIA CACHE CONTROL BLOCK ADD #6,R1 ;R1 -> NEXT REL BLK # IN CACHE CTRL BLK SOB R2,90$ ;LOOP FOR ALL BUFFERS ; /Z VALUE ALL TOTALLY UNUSED BLKS 100$: MOV OBUF,R2 ;R2 -> OUTPUT BUFFER CALL ZSWFIL ;INIT BUFR CLR R1 ;START AT BLOCK ZERO MOV BITBAD,BITMAP ;START WITH BLOCK 0 BITMAP CLR IFLG ;SAY WE'RE DOING BLK 0 110$: MOV R1,R0 ;BITST NEEDS INPUT IN R0 CALL BITST ;WAS THIS BLK WRITTEN INTO ? BNE 120$ ;NO IF EQ MOV R1,OBLK ;REL BLK TO WRITE CALL WRIT0 ;WRITE SET UP BLOCK 120$: INC R1 ;BUMP TO NEXT BLOCK BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 130$ ;BRANCH IF NOT CMP DBASE,R1 ;ARE WE AT THE I-SPACE CCB YET? BHI 110$ ;BRANCH IF NOT MOV IBITBD,BITMAP ;GET I-SPACE BITMAP ADDRESS MOV SP,IFLG ;SAY WE'RE WRITING I-SPACE CCB 130$: CMP ENDRT,R1 ;DONE ENTIRE SAV FILE ? BHI 110$ ;NO IF HI 140$: JMP GBLCRF ;GO DO CREF AND CLOSE FILES .SBTTL WRITE OUT BITMAPS ;+ ; WRITE OUT BITMAP ; ; DWRTBM ENTRY POINT WRITES THE BITMAP TO BLK 0 AND IS ALWAYS USED. ; IWRTBM ENTRY POINT WRITES THE I-SPACE BITMAP AND IS USED ONLY ; WITH /J. ; ; INPUTS: ; R0 CONTAINS THE HIGH LIMIT (HLRT OR DHLRT) ;- .ENABL LSB DWRTBM: TSTB FLGWD ;PROGRAM OVERLAYED ? BPL IWRTBM$ ;NO IF + BIS #OVJOB,JSW(R1) ;INDICATE PROGRAM IS OVERLAYED IWRTBM: ADD #B$TMAP,R1 ;FOR CORE CONTROL BLK ADD #511.,R0 ;TO # OF BLKS FOR ROOT (ROUND UP) BIC #777,R0 SWAB R0 ;C=0 NOW ROR R0 ;NUMBER OF BITS TO COPY FROM BITMAP MOV R0,-(SP) ;SAVE IT ASR R0 ;DIV BY 8. GIVES BYTES TO MOVE ASR R0 ASR R0 BEQ 20$ ;HANDLE ONLY 1 BYTE CASE 10$: MOVB (R2)+,(R1)+ ;COPY OVER SAV FILE BITMAP FOR ROOT SOB R0,10$ 20$: MOV (SP)+,R0 ;DETERMINE REMAINDER OF BITS TO COPY BIC #^C7,R0 ;REM OF DIVIDE BEQ 30$ ;NO MORE BYTES TO COPY (MAY BE 32K CASE, ;SO DON'T CLOBBER LOC 400 MOVB @R2,@R1 ;LAST BYTE REQUIRED TO COPY BICB BTMSK(R0),@R1 ;CLEAR NON-ROOT BITS IN SAV FILE BITMAP 30$: RETURN ;FROM WHENCE WE CAME .DSABL LSB .SBTTL NXTP2 REOPEN NEXT FILE & INIT VARIABLES ;+ ; THE LIBRARY FILES MUST BE PROCESSED IN THE SAME ORDER AS DURING PASS 1 ; SO THAT 'CON' SECTIONS ADD UP CORRECTLY IN MODULE SECTION TABLE CORRECTLY ; TO GET CORRECT SECTION OFFSET PC VALUE. ; INPUT: R0 = START OF SAVESTATUS AREA - 4 ;- .ENABL LSB 10$: TST @R0 ;IS THIS LAST FILE ? BMI 50$ ;YES IF -, SO FINISH UP THIS LINK SUB #S.VSIZ+2,R0 ;R0 -> NEXT FILE BLK NXTP2: MOV (R0)+,IEOI ;SET OVERLAY PTR IN BUFFER STATUS MOV (R0)+,SEGNUM ;EXTRACT THE SEGMENT # FROM END BIC #^CSY.SEG,SEGNUM ; FLAG WORD, CURRENT INPUT SEGMENT # TSTB PAS1.5 ;ARE WE ON LIBRARY PASS ? BPL 20$ ;NO IF + BIT #FL.IB,-(R0) ;SKIP NON-LIBRARY FILES DURING LIBRARY PASS BEQ 10$ ;LIBRARY FILE IF SET BR 30$ ;PROCESS LIBR FILE ON LIBR PASS 20$: BIT #FL.IB,-(R0) ;SKIP LIBR FILE ON 1ST HALF OF PASS BNE 10$ 30$: TST (R0)+ ;PROCESS THIS FILE & R0 -> 5 WD SAVESTATUS BLK MOV R0,FILPT ;UPDATE FILE PTR CLR CURBLK ;RESET RELATIVE BLK COUNTER .REOPEN #PRAREA,#3,FILPT ;REOPEN CHAN 3 ;DBB07 BCS 40$ ;SHOULD NOT HAPPEN RETURN 40$: ERROR$ ERR2,E$F,E$FIL ;READ ERROR IN 50$: JMP ENDPAS ;GO SET UP FOR LIBRARY PASS ;DBB06 .DSABL LSB .SBTTL - NOW CREATE OVERLAY SEGMENT TBL "$OVTAB" ;+ ; FINISH UP OVERLAID PASS2 HANDLER SETUP ; ; 3 WORDS PER ENTRY ,, FOR /O SEG. ; (,, FOR /V SEGMENTS) ; THE 3 WORD ENTRY APPEARS FOR EACH SEGMENT AND FOLLOWS THE ;MAS07 ; OVERLAY HANDLER ;MAS07 ;- .IF NE REL$ ;MAS25+ DOREL: CALL LOOKUP ;LOOKUP GLOBAL SYMBOL IN OVERLAY HANDLER BCS 10$ ;NOT FOUND, RETURN WITHOUT REL INFORMATION MOV S.YVAL(R0),R2 ;GET ADDRESS OF SYMBOL ADD #4,R2 ;ADJUST PROPERLY MOV R1,R0 ;GET INFORMATION TO RELOCATE CALL BLDREL ;BUILD REL INFORMATION 10$: RETURN .ENDC ;REL$ ;MAS25- .SBTTL PA2OVL:: ENTRY POINT TO FINISH OVERLAY HANDLER SETUP PA2OVL:: .IF NE REL$ ;MAS25+ ;+ ; RELOCATATIBLE INFORMATION IN THE OVERLAY HANDLERS MUST HAVE RELOCATION ; FORCED BY THE LINKER. THE INFORMATION DOES NOT APPEAR TO BE RELOCATIBLE WHEN ; ASSEMBLED, AND WILL NOT DO SO AUTOMATICALLY. THE UNDEFINED GLOBALS THAT ARE ; DEFINED AT LINK TIME, AND REPRESENT ADDRESSES IN THE RESULTANT REL FILE ; MUST BE RELOCATED IN THIS MANNER. THESE GLOBALS ARE MARKED BY GLOBAL SYMBOLS ; IN THE OVERLAY HANDLERS. ; ; THESE SYMBOLS ARE FIRST LOOKED UP TO OBTAIN THE CORRECT ADDRESS, THE ; INFORMATION STORED AT THE LOCATION IS OBTAINED, AND THE RELOCATION ; INFORMATION IS BUILT. ;- TSTB FLGWD ;IS PROGRAM OVERLAID? BPL STBL ;PL -> NO OVERLAY HANDLER GBLS TO RELOCATE BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 10$ ;BRANCH IF NOT MOV ZTAB,JSRADR ;SAVE START ADDRESS FOR JSR,R5 INST (WRITZ) 10$: CLR LKWD ;CLEAR TO LOOK UP GLOBAL SYMBOL MOV R2,-(SP) ;SAVE PREVIOUS CALC FOR REL START ADDRESS BITB #XM.OVR,FLGWD ;/V OR /O OVERLAY? BEQ 20$ ;EQ -> /O MOV #VDF1,R3 ;LOOKUP $VDF1 IN HANDLER MOV HLRT,R1 ;INFORMATION TO BE RELOCATED FOR $VDF1 CALL DOREL ;LOOKUP AND DO REL INFORMATION MOV WDBCNT,R1 ;GET INFORMATION TO RELOCATE FOR $VDF4 CALL DOREL MOV HSWVAL,R1 ;INFORMATION TO RELOCATE FOR $VDF5 CALL DOREL MOV HGHLIM,R1 ;INFORMATION TO RELOCATE FOR $VDF2 CALL DOREL BR 30$ 20$: MOV #ODF1,R3 ;SET UP TO LOOKUP $ODF1 MOV HLRT,R1 ;INFORMATION TO RELOCATE CALL DOREL MOV HGHLIM,R1 ;INFORMATION TO RELOCATE FOR $ODF2 CALL DOREL 30$: MOV (SP)+,R2 ;RESTORE R2 .ENDC ;REL$ ;MAS25- STBL: TST R.GNB(R5) ;IS THIS A /V PARTITION? ;MAS15+ BPL 10$ ;+ -> NOT /V MOV #1,VIRSIZ ;RESET VIRSIZ TO 1 -> NOW DOING /V ADD #14.,WDBCNT ;ADD SIZE OF WDB FOR THIS PARTITION ;MAS15- BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 10$ ;BRANCH IF NOT ADD #14.,WDBCNT ;ADD SIZE OF WDB FOR THIS PARTITION 10$: MOV R.GSGP(R5),R3 ;R3 -> SEGMENT BLK 20$: MOV @R5,R0 ;PICK UP CORE ADDR OF OVERLAY SUB #2,R0 ;SUB 2 FOR ID WORD ;MAS07 BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 30$ ;BRANCH IF NOT SUB #4,R0 ;SUB 2 MORE WORDS FOR I-SPACE OVERLAY MOV SP,TXTSP ;WDPUT WILL BE USING D-SPACE 30$: TST VIRSIZ ;WHEN DOING /V TABLE, INSERT WDB ADDR ;MAS15+ BEQ 40$ ;= -> NOT /V PARTITION MOV WDBCNT,R0 ;REPLACE R0 WITH WDB ADDR FOR /V SEG. ;MAS15- 40$: ;MAS15 .IF NE REL$ ADD #2,R2 ;SETUP FOR REL INFO (ADD 2) ;MAS07 CALL BLDREL ;REL INFO FOR CORE ADR ADD #4,R2 ;R2 -> NEXT ENTRY (ADD 4) ;MAS07 .ENDC ;REL$ CALL WDPUT ;AND WRITE IT MOV S.GBSB(R3),R0 ;REL BLK # OF OUTPUT FILE BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 50$ ;BRANCH IF NOT ADD DBASE,R0 ;ADD I-SPACE CCB BLK # TO GIVE ABS BLK # 50$: CALL WDPUT MOV S.GHCL(R3),R0 ;SEGMENT LENGTH (IN BYTES) INC R0 ;ROUND UP CLC ROR R0 ;CONVERT TO WORDS INC R0 ;PLUS ONE FOR ID WORD BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 60$ ;BRANCH IF NOT ADD #2,R0 ;A TOTAL OF 3 ID WORDS FOR I-SPACE OVERLAYS 60$: CALL WDPUT ;SIZE OF SEGMENT IN WORDS BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 100$ ;BRANCH IF NOT MOV R.GSAD(R5),R0 ;PICK UP D CORE ADDR OF OVERLAY TST VIRSIZ ;WHEN DOING /V TABLE, INSERT WDB ADDR BEQ 70$ ;= -> NOT /V PARTITION MOV WDBCNT,R0 ;REPLACE R0 WITH WDB ADDR FOR /V SEG. ADD #14.,R0 ;ADD SIZE OF I-SPACE WDB 70$: TST S.GHLD(R3) ;IS THERE A D-SPACE OVERLAY? BNE 80$ ;BRANCH IF YES CLR R0 ;ZERO A WORD CALL WDPUT ;IN TXTBLK CLR R0 ;ZERO 2 WORDS IN TXTBLK BR 90$ ; [S.GHLD(R3) IS 0 HERE] 80$: CALL WDPUT ;AND WRITE IT (NO ID WORDS FOR D-SPACE) MOV S.GBBD(R3),R0 ;D REL BLK # OF OUTPUT FILE 90$: CALL WDPUT MOV S.GHLD(R3),R0 ;D SEGMENT LENGTH (IN BYTES) INC R0 ;ROUND UP CLC ROR R0 ;CONVERT TO WORDS CALL WDPUT ;SIZE OF SEGMENT IN WORDS 100$: MOV S.GNXP(R3),R3 ;LINK TO NEXT SEGMENT THIS REGION BNE 20$ ;0 WHEN NO MORE SEGMENTS MOV R.GNXP(R5),R5 ;LINK TO NEXT REGION BNE STBL ;0 WHEN NO MORE REGIONS .SBTTL - NEXT CREATE DUMMY SUBROUTINE FOR EACH ENTRY POINT ;+ ; A DUMMY SUBROUTINE OF THE FOLLOWING FORM IS ENTERED FOR EACH ;MAS07+ ; ENTRY POINT TO THE OVERLAY HANDLER. ; ; .PSECT $OTABL,D,GBL,OVR ; JSR R5,$OVRH ;CALL TO OVERLAY CODE ; ;(JSR R5,$OVRHV FOR /V ROUTINES) ; .WORD ;# OF DESIRED SEGMENT ; .WORD ;ACTUAL CORE ADDR ;MAS07- ; ; FOR /J, THIS IS ; .PSECT $ZTABL,I,GBL,OVR ; JSR R5,$OVRH ;CALL TO OVERLAY CODE ; ;(JSR R5,$OVRHV FOR /V ROUTINES) ; .PSECT $OTABL,D,GBL,OVR ; .WORD ;# OF DESIRED SEGMENT ; .WORD ;ACTUAL CORE ADDR ; ; THE 2 WORDS WILL BE PUT INTO THE .SAV FILE HERE. THE JSR,R5 INSTRUCTION ; WILL BE PUT INTO THE .SAV FILE AT /TBS/ ; ;HIPHYS:: STARTS OUT WITH /O ENTRY POINT ADDRESS IN IT. ; IT IS REPLACED WITH THE CONTENTS OF REGION:: WHEN /V ; PARTITIONS ARE DONE. ;- MOV OVRG1,R5 ;R5 -> OVERLAY REGION 1 BLK DUMSUB: TST R.GNB(R5) ;IS THIS /V PARTITION? ;MAS15+ BPL 10$ ;+ -> NOT /V MOV REGION,HIPHYS ;SET HIPHYS TO /V ENTRY POINT ;MAS15- 10$: MOV R.GSGP(R5),R5 ;R5 -> SEGMENT BLK 20$: MOV @R5,R3 ;R3 -> SECTION LIST FOR THIS SEGMENT 30$: BIC #SY.ENB,R3 ;ENTRY # PTR LINKS SEG SYMBOLS TOGETHER BEQ 70$ ;END OF THIS SEGMENT SYMADR R3 ;CONVERT ENTRY # TO SYM TBL ADR BIT #SY.IND,@R3 ;SHOULD SYMBOL HAVE TBL ENTRY? BEQ 60$ ;NO BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 40$ ;BRANCH IF NOT CALL WRITZ ;WRITE $ZTABL PSECT BR 60$ ;MERGE BELOW 40$: MOV #4537,R0 ;YES, JSR R5,$OVRH OR $OVRHV CALL WDPUT ;WRITE JSR INSTR MOV HIPHYS,R0 ;HIPHYS CONTAINS CORRECT ENTRY POINT ;MAS15 .IF NE REL$ ADD #4,R2 ;R2 -> CORE ADR FOR BOTTOM VALUE ;MAS17 CALL BLDREL ;ADR & CODE OF $OVRH OR $OVRHV ADD #4,R2 ;ADD 4 ;MAS17 .ENDC ;REL$ CALL WDPUT 50$: MOV S.GID(R5),R0 ;OVERLAY ID NUMBER CALL WDPUT MOV -(R3),R0 ;ACTUAL ENTRY POINT .IIF NE REL$ CALL BLDREL ;REL FOR ENTRY ADR CALL WDPUT MOV R4,R0 ;ADDR IN TXTBLK SUB #TXTBLK+8.+2,R0 ;CALC REL ADDR ADD TXTBLK,R0 ;ADD BASE ADDR OF BLOCK MOV R0,(R3)+ ;CHANGE ADDR IN SYMBOL TABLE -> DUMMY SUBR 60$: MOV @R3,R3 ;LINK TO NEXT ENTRY IN SYMBOL TABLE BR 30$ 70$: MOV R5,R3 ;SAVE SEGMENT PTR TEMPORARILY MOV S.GNXP(R5),R5 ;LINK TO NEXT SEGMENT BNE 20$ MOV S.GRGP(R3),R5 ;POINT TO REGION BLK MOV R.GNXP(R5),R5 ;LINK TO NEXT REGION BNE DUMSUB .SBTTL - CREATE WINDOW DEFINITION BLOCKS (WDB'S) ;+ ; IF THIS IS A /V LINK, THEN BUILD WDB'S NOW ;MAS15+ ; ; WDB STRUCTURE: ; ; *-----------------------* ;BASE PAR = 1,2,3,4,5,6, OR 7 ; ! BASE PAR ! ID ! -> ;AND WILL BE CALCULATED NOW BASED ; !-----------------------! ;ON THE START ADDR OF THE PARTITION ; ! BASE VIRTUAL ADDRESS ! ; !-----------------------! ;SET NOW TO LARGEST SEGMENT SIZE IN ; ! WINDOW SIZE ! -> ;PARTITION (32. WORD MULT.) ; !-----------------------! ; ! XM REGION ID = -1 ! ; !-----------------------! ;OFFSET IN THE XM REGION WILL BE ; ! OFFSET IN XM REGION ! -> ;CALCULATED NOW (32. WORD MULT.) ; !-----------------------! ; ! LENGTH TO MAP ! -> ;SET NOW, TO SAME AS WINDOW SIZE ; !-----------------------! ; ! STATUS ! -> ;SET WS.MAP IN STATUS WORD TO FORCE ; *-----------------------* ;IMPLICIT MAP WHEN WINDOW CREATED ; ; THE WINDOW SIZE, AND THE LENGTH TO MAP ARE CALCULATED BY THE ; OVERLAY HANDLER FROM THE SEGMENT SIZE. EVERYTHING ELSE IS ; DEFINED BY THE MONITOR AT RUN TIME. ; ; REGISTER USE: ; R0,R1,R2 -> TEMPS ; R5 -> PARTITION BLOCK POINTER ; R3 -> XM REGION OFFSET (I-SPACE IF /J I&D SPACE JOB) ; R2 -> XM REGION OFFSET (D-SPACE IF /J I&D SPACE JOB) ;- BITB #XM.OVR,FLGWD ;IS THIS A /V LINK? BEQ SETUP ;= -> NOT /V CLR WDBRGO ;OFFSET INTO REGION BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 80$ ;BRANCH IF NOT MOV #6,WDBIDX ;6 EXTRA BYTES (I-SPACE ID ROUTINE) BIS #,WDBSTS ;INDICATE I-SPACE WDB IN W.NSTS 80$: MOV OVRG1,R5 ;R5 -> OVERLAY (REGION) PARTITION BLOCK 1 WDBS: TST R.GNB(R5) ;IS THIS A /V PARTITION? BPL 20$ ;- -> /V PARTITION ;+ ; HAVE /V PARTITION BLOCK, NOW SET UP A WDB FOR IT. ; DO BASE PAR FIRST ;- 10$: MOV @R5,R1 ;GET START ADDR REGION MOV R.GHL(R5),R0 ;GET HIGH LIMIT OF PARTITION CALL MKWDBI ;MAKE I-SPACE WDB BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 20$ ;BRANCH IF NOT MOV R.GSAD(R5),R1 ;GET START ADDR REGION (D-SPACE /J) MOV R.GHLD(R5),R0 ;GET HIGH LIMIT OF PARTITION (D-SPACE /J) CALL MKWDBD ;MAKE D-SPACE WDB 20$: MOV R.GNXP(R5),R5 ;LINK TO THE NEXT BLOCK BNE WDBS ;0 -> LAST BLOCK .BR SETUP ;MAS15- .SBTTL PA2: START PASS2, NON-OVERLAID PA2: .SBTTL - SET UP TO PROCESS INPUT MODULES SETUP: BIS #PA.SS2,FLGWD ;SET PASS SWITCH BISB #1,PAS1.5 ;LIBRARY PASS REQUIRED BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ LP2 ;BRANCH IF NOT LP2: MOV SP,EOFSP ;SAVE SP FOR END-OF-FILE PROCESSING ;DBB06 MOV FILPT1,R0 ;R0 -> START OF SAVESTATUS AREA -4 MOV #NXTP2,NXTFIL ;NEXT FILE PROCESSING ROUTINE CALL NXTP2 ;SETUP 1ST FILE INFORMATION CALL NEWBUF ;READ 1ST BUFR .SBTTL * MAJOR LOOP TO PROCESS ALL FILE'S BINARY RECORDS * ;+ ; DURING INPUT OF THE OBJECT MODULES ; R4 -> NEXT INPUT BYTE ; R5 = BYTE COUNT IN CURRENT FORMATTED BINARY BLOCK ;- 10$: CALL NEWBLK ;ENTER MAIN PASS2 LOOP HERE ASL R0 ;MAKE WORD INDEX CMP #DSPTBE-DSPTBL,R0 ;LEGAL BLOCK TYPE? BLOS ILFMT ;NO CALL @DSPTBL(R0) ;CALL BLOCK DEPENDENT ROUTINE BR 10$ ;GO AGAIN ILFMT: ERROR$ ERR4,E$F,E$FIL ;ILLEGAL RECORD TYPE IN .PSECT DATA .SBTTL - FORMATTED BINARY RECORD TYPE DISPATCH TABLE DSPTBL: .WORD ILFMT ; 0 - ILLEGAL BLOCK TYPE .WORD GSD ; 1 - START GSD RECORD .WORD SKPBLK ; 2 - END OF GSD .WORD DMPTXT ; 3 - TXT .WORD RLD ; 4 - RLD .WORD SKPBLK ; 5 - ISD (INTERNAL SYMBOL DEFINITION) .WORD MODND ; 6 - MODULE END .WORD LIBPA2 ; 7 - LIBRARY HEADER RECORD .WORD SKPBLK ;10 - END OF LIBRARY FILE DSPTBE: ;END OF TABLE .PSECT CODE .SBTTL MODND MODULE END RECORD ;+ ; AT THE END OF EACH MODULE THE BASE ADR OF EACH SECTION ; IS UPDATED AS DETERMINED BY THE MST. ;- MODND: CALL TDMP0 ;DUMP TXT BLK IF ANY MOV STLML,R0 ;R0 -> START OF MODULE SECTION TABLE TST ESWVAL ;ARE THERE ANY PROGRAM SECTIONS? BEQ 20$ ;BRANCH IF NOT ("C" CAN DO THIS) 10$: MOV (R0)+,R1 ;SECTION SYMBOL TABLE ADR ADD (R0)+,-(R1) ;SIZE CONTRIBUTION OF SECTION TO VALUE WD DEC ESWVAL ;LOOP FOR # OF ENTRIES IN MST BNE 10$ ;MUST BE AT LEAST 1 SECTION IN EACH MODULE ;ESWVAL = 0 AT END OF LOOP 20$: BIT FLGWD,#LB.OBJ ;LIBR PROCESSING ? BEQ 30$ ;NO CALLR LIBPA2 ;YES, LIBPA2 WILL RETURN 30$: CALLR SKPBLK ;SKIP CURRENT F.B. BLK, IT WILL RETURN .SBTTL GSD PROCESS GSD RECORD DURING PASS 2 ;+ ; ONLY CSECT'S AND PSECT'S ENTRIES ARE PROCESSED DURING PASS 2. ; THE SECTION NAME IS LOOKED UP AND ITS SYMBOL TABLE ADDR IS ENTERED IN ; THE MODULE SECTION TABLE (MST) SO THAT COMPLEX RELOCATION CAN REFERENCE ; THE SECTION BY NUMBER. THE NUMBER IS A BYTE SO MAX IS 255. ; STKBLK = 4 WORD TEMPORARY STORAGE AREA FOR GSD RECORD. ;- .ENABL LSB 10$: MOV #4,R2 ;8 BYTES IN EACH GSD ITEM MOV #STKBLK,R3 ;R3 -> STORAGE AREA FOR GSD BLK MOV R3,R1 ;COPY PTR 20$: CALL GETWD ;GET A WORD OF GSD RECORD MOV R0,(R1)+ ;STORE IT AWAY SOB R2,20$ MOVB S$YCOD(R3),R0 ;NO, GET CODE BYTE IN R0 BEQ 40$ ;IF EQ IT IS A MODULE NAME ;DBB04 DEC R0 ;IS IT A CSECT OR ASECT ENTRY? BEQ 90$ ;YES CMP #4-1,R0 ;IS IT A GLOBAL SYMBOL? ;DBB04 BEQ 50$ ;YES IF EQ ;DBB04 CMP #5-1,R0 ;IS IT A PSECT ENTRY? BEQ 130$ ;YES CMP #7-1,R0 ;IS IT A VSECT ENTRY? BEQ 130$ ;YES IF EQ GSD: 30$: TST R5 ;ANY BYTES REMAINING IN BLK? BGT 10$ ;YES, PROCESS NEXT GSD ITEM CALLR BYTE ;SKIP CHECKSUM BYTE(BYTE WILL RETURN) 40$: MOV #CRFLIN+6,R1 ;6-BYTE AREA TO STORE ASCII MODULE NAME ;DBB04+ CALL R50ASC ;CONVERT MODULE NAME FROM RAD50 TO ASCII BR 30$ ;CONTINUE PROCESSING GSD 50$: CLR R0 ;SET UP FLAG BYTE BIT #SY$DEF,S$YFLG(R3) ;IS REFERENCE A DEFINITION? BEQ 60$ ;IF EQ NO MOV #200,R0 ;SET DEFINITION BIT IN FLAG 60$: BIT #LB.OBJ,FLGWD ;IS CURRENT MODULE A LIBRARY MODULE? BEQ 70$ ;IF EQ NO INC R0 ;SET LIBRARY MODULE BIT 70$: MOVB R0,CRFLIN+12. ;PUT FLAG BYTE IN BUFFER MOV #CRFLIN,R1 ;6-BYTE AREA TO STORE ASCII SYMBOL NAME CALL R50ASC ;CONVERT SYMBOL NAME FROM RAD50 TO ASCII MOV #16.,R2 ;A RECORD IS 16. BYTES LONG MOV #CRFLIN,R1 ;SET UP CHARACTER POINTER IN CREF RECORD 80$: MOVB (R1)+,R0 ;GET NEXT CHARACTER IN R0 CALL PUTCHR ;WRITE CHARACTER TO BUFFER SOB R2,80$ ;REPEAT UNTIL RECORD IS WRITTEN BR 30$ ;CONTINUE PROCESSING GSD ;DBB04- 90$: MOV #CS$REL,R0 ;SET FLAGS AS A BLANK PSECT TST @R3 ;IS THIS A BLANK NAME? BEQ 120$ ;YES CMP (R3)+,(PC)+ ;IS IT AN ASECT ? .RAD50 /. A/ BNE 100$ ;NO CMP #^RBS.,@R3 BNE 100$ MOV #CS$GBL+CS$ALO,R0 ;YES, SET BITS FOR ABS PSECT BR 110$ 100$: MOV #CS$GBL+CS$ALO+CS$REL,R0 ;FLAG FOR NAMED SECTION 110$: TST -(R3) ;R3 -> 1ST WD OF NAME 120$: MOVB R0,S$YFLG(R3) ;SET FLAGS BYTE IN GSD BLK ;GO PROCESS AS A PSECT 130$: MOV #^CSY.SEC,LKMSK ;CARE ABOUT SECTION FLAG MOV #SY.SEC,LKWD ;SECTION BIT FOR MATCH BITB #CS$SAV,S$YFLG(R3) ;DOES PSECT HAVE SAV ATTRIBUTE? ;DBB05+ BEQ 140$ ;IF EQ NO BISB #CS$GBL,S$YFLG(R3) ; FORCE PSECT TO ROOT VIA GBL ATTRIBUTE 140$: BITB #CS$GBL,S$YFLG(R3) ; LOCAL OR GLOBAL SECTION ? ;DBB05- BNE 150$ ;LCL IF 0 MOV #^C,LKMSK ;CARE ABOUT SECTION & SEGMENT # BIS SEGNUM,LKWD ;LOCAL SECTION QUALIFIED BY SEG # 150$: CALL LOOKUP ;LOOKUP SECTION NAME IN SYM TBL BCS 170$ ;C =1 IF NOT FOUND * SHOULD NOT HAPPEN * MOV ESWVAL,R3 ;# OF SYMBOLS IN TBL ASL R3 ;MAKE A 2 WORD OFFSET ASL R3 ADD STLML,R3 ;R3 -> NEXT FREE TABLE SLOT MOV R0,(R3)+ ;SYM TBL ADDR OF SECTION IN MST CLR @R3 ;ASSUME CONTRIBUTION OF 0 FOR THIS SECTION ; CS$LIB IS UNUSED. I'M NOT SURE WHAT IF ANYTHING SPECIAL IS ;DBB05+ ; DESIRED IF PSECT IS A LIB PSECT ; ; BITB S.YFLG(R0),#CS$LIB!CS$ALO ;DON'T UPDATE SECTION BASE ; ; IF LIB OR OVR SECTION ; BNE 160$ ;YES IT WAS A LIB OR OVR SECTION ;DBB05- BITB S.YFLG(R0),#CS$ALO ;DON'T UPDATE SECTION BASE IF OVR SECT BNE 160$ ;YES IT WAS AN OVR SECTION ; BITB S.YFLG(R0),#CS$REL ;SAME FOR ABSOLUTE SECTION ;SHD01 ; BEQ 160$ ;YES IT WAS AN ABSOLUTE SECTION ;SHD01 MOV STKBLK+6,@R3 ;SIZE OF SECTION AS CONTRIB BY THIS MOD BITB S.YFLG(R0),#CS$TYP ;IS IT A DATA SECTION? BNE 160$ ;YES INC @R3 ;ROUND ALL SECTIONS EXCEPT "CON" DATA BIC #1,@R3 ; SECTIONS TO WORD BOUNDARIES 160$: INC ESWVAL ;ONE MORE ENTRY IN MST BR 30$ 170$: ERROR$ ERR21,E$F,E$FIL ;BAD GSD IN .DSABL LSB .SBTTL LIBPA2 LIBRARY PROCESING ROUTINE ;+ ; THIS ROUTINE INSURES THAT THE LINKER,DURING PASS2, ; PROCESSES THE LIBRARY OBJECT MODULES EXACTLY AS THEY ; WERE ENCOUNTERED DURING PASS1. ;- LIBPA2: MOV LMLPTR,R1 ;R1 -> CURRENT LML ENTRY TO PROCESS MOV IBUF,R4 ;START ADR OF 1 BLK BUFR MOV CURBLK,R2 MOV IBKINC,R0 ;# OF BLKS IN CURRENT BUFR SUB R0,R2 ;GIVES THE CURRENT BLK IN CORE NOW MOV (R1)+,R5 ;LIBRARY FILE # & HIGH PART OF BLK # SWAB R5 ;ISOLATE LIBRARY FILE # CMPB LIBNB,R5 ;STARTING A NEW LIBRARY FILE ? BNE 80$ ;YES IF NE CLRB R5 ;BECAUSE OF SIGN EXTEND BISB 1(R1),R5 ;LOW ORDER REL BLK # BITS ROR R5 ;C=0 FROM CMPB 10$: CMP R5,R2 ;REQUESTED MOD IN BUFFER ? BEQ 30$ ;YES BLO 20$ ;NO, LOOKING FOR IS .LT. CURRENT ADD #512.,R4 ;.GT. BUT MAY BE IN CORE, NXT BLK'S BUFR ADDR INC R2 ;BUMP BLK # LOOKING FOR SOB R0,10$ ;LOOP, IT MAY BE HERE ;NOT IN CORE, SO READ IT IN 20$: MOV R5,CURBLK ;IND MOD BLK ADR CALL NEWBUF ;GET THE CORRECT BLK # 30$: MOV (R1)+,R0 ;BYTE OFFSET WORD OF LML BIC #^C777,R0 ;ISOLATE BYTE OFFSET ADD R0,R4 ;R4 -> CORRECT BYTE IN BLK MOV (R1)+,SEGNUM ;AND SET SEGMENT # FOR THIS LIB MOD ;MAS10 MOV R1,LMLPTR ;UPDATE LML PTR BIS #LB.OBJ,FLGWD ;IND PROCESSING LIBR FILE MOV -(R1),R0 ;GET CURRENT SEGMENT NUMBER ;MAS10+ BEQ 70$ ;IF SEGMENT 0 THEN ALL SET ASL R0 ;AND MAKE IT TIMES 6 ADD @R1,R0 ASL R0 BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 40$ ;BRANCH IF NOT ASL R0 ;I&D SPACE IS SEG. # * 14 40$: MOV R0,-(SP) ;AND SAVE IT ON STACK MOV #ASECT,R0 ;GET ROOT SEGMENT BLOCK 50$: MOV S.GNXP(R0),R1 ;GET NEXT OSDB BNE 60$ ;LAST IN REGION? MOV S.GRGP(R0),R0 ;YES, GET NEXT REGION MOV R.GNXP(R0),R0 ;AND GET NEXT SEGMENT BEQ ILERR ;0-> ILLEGAL ERROR MOV R.GSGP(R0),R1 ;NEXT OSDB BEQ ILERR ;0->ILLEGAL ERROR 60$: MOV R1,R0 ;RESET TO LOOP PROPERLY CMP S.GID(R1),@SP ;RIGHT SEGMENT? BNE 50$ ;NO->TRY FOR NEXT ONE MOV S.GBSB(R1),SEGBLK ;GET BASE BLOCK MOV @S.GRGP(R1),SEGBAS ;GET BASE OF REGION SUB #2,SEGBAS ;ALLOW FOR REGION ID (1 WORD) TST (SP)+ ;RESET SP ;MAS10- BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 70$ ;BRANCH IF NOT SUB #4,SEGBAS ;REGION ID ROUTINE IS 3 WORDS (INSTEAD OF 1) MOV S.GBBD(R1),DSGBLK ;GET D-SPACE BASE BLOCK MOV S.GRGP(R1),R0 ;GET REGION START ADDR IN R0 MOV R.GSAD(R0),DSGBAS ;GET D-SPACE BASE OF REGION MOV R1,R0 ;RESET (AGAIN) TO LOOP PROPERLY 70$: RETURN ;RETURN TO MAIN PROCESSING ; ALL THE REQUIRED MODULES IN THE LIBRARY HAVE BEEN PROCESSED. ; RESET ALL POINTERS, TERMINATE THE LIBRARY FILE ; AND GO BACK TO IN LINE PROCESSING. 80$: TST -(R1) ;BACKUP -> LIBRARY FILE # OF NEXT FILE MOV R1,LMLPTR ;UPDATE LML PTR INCB LIBNB ;NEXT LIBRARY FILE NUMBER BIC #LB.OBJ,FLGWD ;RESET LIB SWITCHES CALLR CLOSE ;READ NEXT FILE(WILL CALL "NEWBUF") ;CLOSE WILL RETURN TO PASS2 ILERR: ERROR$ ERR0,E$F,E$FIL ;ILLEGAL ERROR ;MAS10 .SBTTL - TXT AND RLD BLOCKS ;+ ; THE FIRST TXT BLOCK IN AN OBJECT MODULE MUST BE PRECEDED BY AN RLD BLOCK. ; TXT BLOCKS CONTAIN THE ACTUAL BINARY FORM OF THE PROGRAMS AND ARE ; FORMATTED AS SHOWN: ; +-------------------------------+ ; ! ID WD (TXT=3) ! ; +-------------------------------+ ; ! LOAD ADR OF FOLLOWING DATA ! ; +-------------------------------+ ; ! LOAD DATA ! ; . ; . ; +-------------------------------+ ; THE LOAD ADDRESS OF A TXT BLOCK GIVES THE RELATIVE ADR OF THE FIRST ; BYTE OF THE ABS LOAD DATA. THE ADR IS RELATIVE TO THE BASE OF THE LAST ; PROGRAM SECTION GIVEN IN A LOCATION COUNTER DEFINITION RLD CMD. ; ; RLD BLOCKS CONTAIN VARIABLE LENGTH RLD CMDS, USED TO MODIFY AND ; COMPLETE THE INFORMATION CONTAINED IN TXT BLOCKS. EXCEPT FOR THE LOCATION ; COUNTER CMDS, RLD INFO MUST APPEAR IN AN RLD BLOCK IMMEDIATLY FOLLOWING ; THE TXT BLOCK TO BE MODIFIED. ; THE LOCATION COUNTER CMDS (7 & 8) ARE THE ONLY 2 RLD CMDS THAT MUST ; APPEAR PRECEDING THE TXT BLOCKS MODIFIED IN ORDER TO DECLARE A PROGRAM ; SECTION FOR LOADING THE FIRST TEXT BLOCK. ; ; THE FORMAT OF EACH RLD CMD IS: ; +-----------------------+ ; ! REL REF !B! CMD ! ; +-----------------------+ ; ! 2 WD RAD50 NAME ! ; +-----------------------+ ; ! CONSTANT ! ; +-----------------------+ ; EACH PART EXCEPT THE 1ST WD IS OPTIONAL, AN RLD CMD MAY BE 1, 2, 3, ; OR 4 WORDS LONG. ; B IS SET FOR A BYTE CMD. THE RELATIVE REFERENCE FIELD IS A POINTER ; INTO THE PRECEDING TXT BLOCK USED FOR MODIFICATION. THE BEGINNING ; OF THE TXT BLOCK IS THE ID WORD (1ST WD OF BLK). THUS, THE SMALLEST ; REL REF WILL NORMALLY BE 4 (1ST DATA BYTE OF TXT BLK). ; THE NAME FIELD HOLDS A GLOBAL OR PSECT NAME IF THE CMD REQUIRES IT. ; THE CONSTANT HOLDS A RELATIVE ADR OR ADDITIVE QUANITY IF CMD REQUIRES IT. ;- .SBTTL RLD PROCESS RLD'S .ENABL LSB 10$: CLR LKWD ;IND NOT A SECTION LOOKUP CALL BYTE ;CMD BYTE OF RLD IN R0 MOV R0,-(SP) ;STORE THE COMMAND BYTE CALL BYTE ;DISPLACEMENT BYTE SUB #2,R5 ;SUBTRACT FROM LEN OF RLD BLK MOV R0,R1 ;GET RELATIVE REFERENCE IN R1 MOV R1,R3 ;COPY DISPLACEMENT ADD #TXTBLK-2,R1 ;LOC OF TARGET IN TXTBLK BIT TXTBLK,#1 ;IS TXT BLK ON ODD BOUNDARY? BEQ 20$ ;IF EQ-NO INC R1 ;YES-INCR RELATIVE REFERENCE, SINCE BLK ;WAS SHIFTED BY A BYTE IN 'DMPTXT'. 20$: ADD TXTBLK,R3 ;PROG ADDR OF TARGET MOV @SP,R2 ;GET COMMAND BYTE BIC #^C177,R2 ;ISOLATE THE CMD # CMP #LRLDTB,R2 ;LEGAL CMD TYPE ? BLO RLDERR ;BAD IF LO CMP #7,R2 ;ALL SYMBOLS USED WITH CODES .GT. 7 BHI 30$ ; ARE SECTION NAMES MOV #SY.SEC,LKWD ;A SECTION NAME & BIS SEGNUM,LKWD ; SEGMENT NUMBER FOR LOOKUP 30$: CLR R0 ;FOR NO SIGN EXTEND BISB RLDTBL(R2),R0 ; & GET DISPATCH OFFSET ASL R0 ;DOUBLE THE DISPATCH OFFSET .IF NE REL$ CLRB NUMCOL ;RESET TO + RELOCATION MOV R3,R2 ;FOR REL FILE OUTPUT .ENDC ;REL$ SUB #2,R3 ;CURRENT LOC+2 (YES, SUBTRACT) NEG R3 ;MINUS CURR LOC + 2 CALL RLDST(R0) ;CALL RLD PROCESSING ROUTINE TST (SP)+ ;GET RID OF CMD BYTE SPACE RLD: TST R5 ;ANY MORE BYTES REMAINING IN RECORD? BGT 10$ ;YES BNE RLDERR ;SHOULD NOT HAPPEN CALLR BYTE ;SKIP CHECKSUM & RETURN TO RECORD TYPE DETERMINATION .DSABL LSB .PSECT DATA ; INPUT TO THE FOLLOWING SUBROUTINES IS: ; R0 FREE TO USE ; R1 -> LOCATION TO MODIFY IN TXT BLK ; R3 = CURRENT VIRTUAL ADR RLDTBL: .BYTE /2 ; 0 NOT USED .BYTE /2 ; 1 INTERNAL RELOCATION 2 WDS .BYTE /2 ; 2 GLOBAL 3 WDS .BYTE /2 ; 3 INTERNAL DISPLACED 2 WDS .BYTE /2 ; 4 GLOBAL DISPLACED 3 WDS .BYTE /2 ; 5 GLOBAL ADDITIVE 4 WDS .BYTE /2 ; 6 GLOBAL ADDITIVE DISPLACED 4 WDS .BYTE /2 ; 7 LOCATION COUNTER DEFINITION 4 WDS .BYTE /2 ;10 LOCATION COUNTER MODIFICATION 2 WDS .BYTE /2 ;11 SET PROGRAM LIMITS 1 WDS .BYTE /2 ;12 PSECT 3 WDS .BYTE /2 ;13 NOT USED .BYTE /2 ;14 PSECT DISPLACED 3 WDS .BYTE /2 ;15 PSECT ADDITIVE 4 WDS .BYTE /2 ;16 PSECT ADDITIVE DISPLACED 4 WDS .BYTE /2 ;17 COMPLEX VARIABLE LRLDTB= .-RLDTBL-1 ;LARGEST ALLOWED RLD ITEM TYPE .PSECT CODE RLDST: ;START OF RLD PROCESSING ROUTINES RLDERR: ERROR$ ERR36,E$F,E$FIL ;BAD RLD IN .SBTTL RLDGR GLOBAL RELOCATION ;+ ; RELOCATES A DIRECT POINTER TO A GLOBAL SYMBOL. THE VALUE OF THE ; GLOBAL SYMBOL IS OBTAINED & STORED. ; E.G. MOV #GLOBAL,R0 ;- .ENABL LSB RLDGR: CLR R3 ;FORCE 0 AS CONSTANT .IF NE REL$ CALL RLDLK ;LOOKUP SYMBOL IN SYM TBL BNE IMGOUT ;REL SYM IF NE BR 10$ ;ABS SO NO REL INFO .IFTF .SBTTL RLDGDR GLOBAL DISPLACED REL ;+ ; RELATIVE REFERENCE TO GLOBAL SYMBOL. THE GLOBAL VALUE IS OBTAINED AND ; THE ADDRESS + 2 THAT THE RELOCATED VALUE IS TO BE WRITTEN INTO IS ; SUBTRACTED FROM THE VALUE & RESULT STORED. ; E.G. CLR GLOBAL ;- RLDGDR: .IFT DECB NUMCOL ;IND NEG RELOC .IFTF CALL RLDLK ;ADD SYMBOL VALUE TO R3 .IFT BEQ IMGOUT ;IF ABS THEN REL INFO REQUIRED 10$: CLR R2 ;NO REL INFO REQ .IFTF BR IMGOUT .SBTTL RLDGAR GLOBAL ADDITIVE REL ;+ ; RELOCATED A DIRECT POINTER TO A GLOBAL SYMBOL WITH AN ADDITIVE CONSTANT ; THE SYMBOL VALUE IS ADDED TO THE SPECIFIED CONSTANT & STORED. ; E.G. MOV #GLOBAL+2,R0 ;- RLDGAR: CLR R3 ;ADD 0 AS CONSTANT .IFT CALL RLDLK ;LOOKUP SYMBOL IN SYMBOL TABLE BNE 30$ ;REL SYM IF NE BR 20$ ;ABS SO NO REL INFO .IFTF .SBTTL RLDGAD GLOBAL ADDITIVE DISPLACED REL ;+ ; RELATIVE REFERENCE TO A GLOBAL SYMBOL WITH AN ADDITIVE CONSTANT. THE ; GLOBAL VALUE AND THE CONSTANT ARE ADDED. THE ADDRESS + 2 THAT THE ; RELOCATED VALUE IS TO BE WRITTEN INTO IS SUBTRACTED FROM THE RESULTANT ; ADDITIVE VALUE & STORED. ; E.G. CLR GLOBAL-2 ;- RLDGAD: .IFT DECB NUMCOL ;IND NEG RELOCATION .IFTF CALL RLDLK .IFT BEQ 50$ ;IF ABS REL INFO REQUIRED 20$: CLR R2 ;IND NO REL OUTPUT 30$: .ENDC ;REL$ MOV @R0,-(SP) ;IS SYMBOL IN OVERLAY BY BIC #^CSY.SEG,(SP)+ ; ISOLATING THE SEGMENT # BEQ 50$ ;NO, SO OKAY ; DETERMINE IF GLOBAL SYMBOL IN OVERLAY IS AN ADDITIVE REFERENCE BIT #CS$TYP*400!SY.SEC,@R0 ;IF SECTION NAME OR GLOBAL ; DEFINED IN A DATA SECTION BNE 50$ ;IF EITHER BIT SET THEN OK BIT #CS$REL*400,@R0 ;ABSOLUTE SYMBOLS NOT ADDITIVE REF BEQ 50$ ;ABS IF 0 BIT #SY.IND,-S.YSN(R0) ;IF NO EXTERNAL REFERENCE ;DBB01 BEQ 50$ ; THEN OK ;DBB01 MOV R0,-(SP) ;SAVE SYM TBL PTR IN CASE OF ERROR CALL GETWD ;GET GLOBAL DISPLACEMENT TST R0 ;DISP MUST BE ZERO ? BEQ 40$ ;NO ERROR IF 0 MOV @SP,R0 ;RESTORE SYMBOL TBL PTR CMP -(R0),-(R0) ;R0 -> SYMBOL NAME ERROR$ ERR37,E$W,E$SYM,R0 ;ADDITIVE REF OF MOV SEGNUM,R0 ;GET SEG # ERROR$ ERR40,E$W,E$REG,R0 ;AT SEGMENT # 40$: TST (SP)+ ;GET RID OF PTR BR IMGOUT .SBTTL RLDIR INTERNAL REL ;+ ; DIRECT POINTER TO AN ADDRESS WITHIN A MODULE. THE CURRENT ; SECTION BASE ADDRESS IS ADDED TO A SPECIFIED CONSTANT ANT THE RESULT ; STORED IN THE IMAGE FILE AT THE CALCULATED ADDRESS(I.E., DISPLACEMENT ; BYTE ADDED TO VALUE CALCULATED FROM THE LOAD ADDRESS OF THE PREVIOUS ; TEXT BLOCK). ; E.G. A: MOV #A,R0 ;- RLDIR: MOV BASE,R3 ;ADD SECTION BASE .IIF NE REL$ BR 50$ .SBTTL RLDIDR INTERNAL DISPLACED REL ;+ ; RELATIVE REFERENCE TO AN ABSOLUTE ADDRESS FROM WITHIN A ; RELOCATABLE SECTION. THE ADDRESS + 2 THAT THE RELOCATED VALUE IS TO BE ; WRITTEN INTO IS SUBTRACTED FROM THE SPECIFIED CONSTANT & RESULTS STORED. ; E.G. CLR 177550 ;- RLDIDR: .IIF NE REL$ DECB NUMCOL ;IND NEG RELOCATION 50$: CALL GETWD ;GET GLOBAL DISP ;DBB02+ TSTB 2(SP) ;BYTE COMMAND? BPL 60$ ;IF PL NO TSTB R0 ;NEGATIVE DISPLACEMENT? BPL 60$ ;IF PL NO MOVB R0,R0 ;SIGN EXTEND 60$: ADD R0,R3 ;DBB02- IMGOUT::TSTB 2(SP) ;TEST IF BYTE COMMAND BPL 80$ ;NO, GO STORE WORD MOVB R3,@R1 ;STORE BYTE MOV R3,R0 ;COPY R3 ;MAS21+ SWAB R0 ;DO TESTS ON LOW BYTE BEQ 90$ ;LOW BYTE = 0 -> FITS IN 8 BITS INCB R0 ;IF MINUS, THEN ALL 8 BITS SET, AND BEQ 90$ ;THIS MAKES BYTE = 0 ;MAS21- MOV #TXTBLK+2,R0 ;GET ADDR WORD IN TEXT BUFFER ;MAS38+ SUB R0,R1 ;SUB ADDR OF TEXT CURRENTLY BEING RELOCATED ADD TXTBLK,R1 ;ADD ABS. ADDR OF START OF BUFFER TO GET ;THE ADDRESS OF THE BYTE IN ERROR ERROR$ ERR41,E$W,E$REG,R1 ;BYTE RELOCATION ERROR AT ;MAS38- 70$: RETURN 80$: ROR R1 ;MUST BE EVEN FOR WORD STORE? BCS 100$ ;BAD DATA PSECT CONCATINATION ;MAS06 ROL R1 MOV R3,@R1 ;STORE WORD IN TXT BLK 90$: .IF NE REL$ TST R2 ;SHOULD ANY REL INFO BE OUTPUT ? BEQ 70$ ;NO IF 0 MOV R3,R0 ;VALUE STORED INTO PROGRAM TEXT CALLR BLDREL ;PLACE ADR & CODE INTO REL INFO BUFR .IFF RETURN .ENDC ;REL$ 100$: ERROR$ ERR55,E$F,E$FIL ;WORD RELOCATION ERROR AT ;MAS06 .DSABL LSB .SBTTL RLDSPL SET PROGRAM LIMITS ;+ ; .LIMIT VALUES ARE STORED. ;- RLDSPL: .IF NE REL$ MOV BOTTOM,R0 ;ORIGINAL VALUE IN REL INFO BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 10$ ;BRANCH IF NOT MOV DBOTTM,R0 ;.LIMIT IS D-SPACE 10$: MOV R0,(R1)+ ;SET LOWER PROGRAM LIMIT INTO TEXT CALL BLDREL ;R2 HAS ADR ADD #2,R2 ;ADDRESS OF .LIMIT+2 MOV HGHLIM,@R1 ;SET PROGRAM HIGH LIMIT INTO TEXT MOV @R1,R0 ;AND FOR REL INFO CALLR BLDREL ;IT WILL RETURN .IFF MOV BOTTOM,(R1)+ ;SET LOWER PROGRAM LIMIT INTO TEXT BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 20$ ;BRANCH IF NOT MOV DBOTTM,-2(R1) ;.LIMIT IS D-SPACE 20$: MOV HGHLIM,@R1 ;SET PROGRAM HIGH LIMIT INTO TEXT RETURN .ENDC ;REL$ .SBTTL RLDLCM LOCATION COUNTER MODIFICATION ;+ ; THE CURRENT SECTION BASE IS ADDED TO THE SPECIFIED CONSTANT ; & RESULT IS STORED AS THE CURRENT LOCATION CTR. ; DOES NOT REALLY USE THIS INFORMATION LEFT IN R3 ;- .ENABL LSB RLDLCM: MOV BASE,R3 BR 30$ .SBTTL RLDLCD LOCATION COUNTER DEFINITION ;+ ; DECLARES A CURRENT SECTION & LOCATION COUNTER VALUE ;- RLDLCD: CLR R3 ;VALUE WD OF SYM TBL GIVES ADR CLR MBPTR ;0 SAYS TO STORE TXT INFO ;CER02 CALL RLDLK ;LOOKUP SECTION NAME BNE 20$ ;REL IF NE ;CER02 MOV R0,-(SP) ;SAVE R0, R0 -> FLAG WORD IN SYMTAB ENTRY CMP (R0)+,(R0)+ ;R0 -> NODE OF SYMBOL TBL ;CER02 CMP ASECT,R0 ;ARE WE LOOKING AT THE ASECT? ;CER02 BEQ 10$ ;YES IF EQ ;CER02 INC MBPTR ;SAY NOT TO STORE TXT FOR ABS SECTION ;CER02 10$: MOV (SP)+,R0 ;RESTORE R0 20$: MOV R3,BASE ;SET UP NEW SECTION BASE BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 30$ ;BRANCH IF NOT MOV @R0,RLDSP ;ASSUME WE HAVE A D-SPACE PSECT BIC #^C,RLDSP ;0 = I-SPACE; CS$TYP*400 = D-SPACE 30$: CALL GETWD ;GET WORD AFTER SECTION NAME ADD R0,R3 ;BASE OF SECTION + OFFSET = RETURN ; CURRENT LOCATION COUNTER .DSABL LSB .SBTTL COMPLEX RELOCATION STRING PROCESSING (GLOBAL ARITHMETIC) ;+ ; BEGST= ESWNAM ;TEMP TO SAVE BEGINNING OF STACK ; ENDST= ESWNAM+2 ;TEMP TO SAVE END OF STACK ; MSTNS= ESWVAL ;MODULE SECTION TABLE NUMBER OF ENTRIES ; MAX OF 38. DATA BYTES, IF ALL CMDS WERE PUSH CONST WOULD ; REQUIRE 26 BYTES OF STACK SPACE. ; THE INTERNAL STACK SPACE IS TAKEN FROM PROGRAM STACK SPACE, THE NEW SP ; IS MOVED DOWN(LOWER ADR) & THE INTERNAL ONE IS BETWEEN THE OLD ONE & THE ; NEW ONE. ;- RLDCPX: MOV R1,-(SP) ;SAVE R1 & R3 MOV R3,-(SP) ;VIRTUAL ADR WILL BE USED IF STORE DISPLACED CMP -(SP),-(SP) ;ALLOCATE GUARD WDS FROM STACK MOV SP,R3 ;MARK BOTTOM OF STACK MOV R3,ESWNAM ;SAVE BOTTOM OF OLD STACK SUB #30.,SP ;ALLOCATE STACK SPACE FOR R3 USE MOV SP,ESWNAM+2 ;MARK TOP OF STACK NEW STACK 10$: CALL BYTE ;COMMAND BYTE IN R0 DEC R5 ;BOOKKEEP THE BYTE COUNT CMP #LGCPX,R0 ;LEGAL CMD TYPE ? BLO 20$ ;NO, BAD FORMAT CLR R1 ;FOR NO SIGN EXTEND BISB CPXVCT(R0),R1 ; & GET DISPATCH OFFSET ASL R1 ;DOUBLE THE DISPATCH OFFSET CALL CPXSUB(R1) ;CALL PROCESSING ROUTINE TST R5 ;CHECK BYTE COUNT BGT 10$ ;OK GO AGAIN 20$: JMP RLDERR ;BAD COUNT .PSECT DATA CPXVCT: ;COMPLEX RELOCATION PROCESSING VECTOR .BYTE /2 ; 0 NOP .BYTE /2 ; 1 ADD .BYTE /2 ; 2 SUBTRACT .BYTE /2 ; 3 MULTIPLY .BYTE /2 ; 4 DIVIDE .BYTE /2 ; 5 'AND' .BYTE /2 ; 6 'OR' .BYTE /2 ; 7 'XOR' .BYTE /2 ;10 NEGATE .BYTE /2 ;11 COMPLEMENT .BYTE /2 ;12 STORE .BYTE /2 ;13 STORE DISPLACED .BYTE /2 ;14 ILLEGAL FORMAT .BYTE /2 ;15 ILLEGAL FORMAT .BYTE /2 ;16 PUSH GLOBAL'S VALUE .BYTE /2 ;17 PUSH RELOCATABLE VALUE .BYTE /2 ;20 PUSH CONSTANT LGCPX= .-CPXVCT-1 .PSECT CODE ; SUBTRACT (SP)+,@SP ;THIS ROUTINE MUST COME 1ST OR CHANGE DISPATCHING CPXSUB: NEG @R3 ;NEGATE TOP ITEM ON STACK ; ADD (SP)+,@SP CPXADD: ADD (R3)+,@R3 ;ADD TOP 2 ITEMS BR CPXRTN ;CHECK STACK, EXIT ; NEGATE -(SP) CPXNEG: DEC @R3 ;DECREMENT TOP ITEM ; COMPLEMENT @SP CPXCOM: COM @R3 ;COMPLEMENT TOP ITEM ; COMPLEX RELOCATION -- 'NOP' CPXNOP: RETURN ;EXIT ; AND (SP)+,@SP CPXAND: COM @R3 ;COMPLEMENT TOP ITEM BIC (R3)+,@R3 ;'AND' BOTH ITEMS BR CPXRTN ;CHECK STACK, EXIT ; EXCLUSIVE OR (SP)+,@SP CPXXOR: MOV 2(R3),R0 ;FETCH 2ND ITEM BIC (R3)+,@R3 ;CLEAR BITS SET IN BOTH, 2ND ITEM BIC R0,-(R3) ;DITTO 1ST ITEM ; 'OR' (SP)+,@SP CPXOR: BIS (R3)+,@R3 ;'OR' BOTH ITEMS BR CPXRTN ;EXIT ; MULTIPLY (SP)+,@SP CPXMUL: .IF Z EIS$ MOV (R3)+,R0 ;GET TOP ITEM MOV @R3,R1 ;DO A SIMPLE ADD LOOP ; BEQ CPXRTN ;MULT BY 0, RESULT IS 0 ;MAS21 INC R0 ;MAS21 NEG @R3 ;DO A SIMPLE ADD LOOP 10$: ADD R1,@R3 ; SINCE SPEED IN NOT IMPORTANT HERE ; SUB #1,R0 ;MAS21+ ; BCC 10$ DEC R0 BNE 10$ ;MAS21- .IFF MOV (R3)+,R1 ;GET TOP ITEM, REG MUST BE ODD MUL (R3)+,R1 ;MULTIPLY TOP TWO ITEMS MOV R1,-(R3) ;STORE RESULT .ENDC ;EIS$ BR CPXRTN ;EXIT ; DIVIDE (SP)+,@SP CPXDIV: .IF NE EIS$ MOV 2(R3),R1 ;FETCH LOW PART SXT R0 ;EXTEND SIGN DIV (R3)+,R0 ;DIVIDE EM UP BVC 30$ ;OK, DIVISOR NOT ZERO .IFF MOV (R3)+,R0 ;VERIFY DIVISOR .NE. 0 BNE 10$ ;OK, PROCEED .IFTF ERROR$ ERR33,E$W,E$FIL ;COMPLEX RELOCATION DIVIDE BY 0 IN CLR @R3 ;FORCE RESULT OF 0 BR CPXRTN ;EXIT .IFF 10$: MOV @R3,R1 ;DIVIDEND MOV #-1,@R3 ;INIT RESULT VALUE 20$: INC @R3 ;USE A SIMPLE SUBTRACT LOOP SUB R0,R1 BCC 20$ .IFT 30$: MOV R0,@R3 ;REPLACE TOP ITEM WITH RESULT .ENDC ;EIS$ ; BR CPXRTN ;CHECK STACK, EXIT ; CHECK FOR STACK OVERFLOW/UNDERFLOW CPXRTN: CMP ESWNAM,R3 ;CHECK STACK PTR VS START BHI CPXEXT ;IF .LO. -OK ;STACK OVERFLOW/UNDERFLOW ERROR CPXERR: ERROR$ ERR35,E$F,E$FIL ;BAD COMPLEX RELOCATION IN ; PUSH CONSTANT .ENABL LSB CPXPC: CLR R1 ;CLEAR RELOCATION BASE BR 10$ ;GET CONSTANT, PUSH ON STACK ; PUSH GLOBL SYMBOL VALUE CPXPGB: CLR LKWD ;LOOKUP'S HERE ARE FOR GLOBALS MOV R3,-(SP) ;SAVE INTERNAL STACK PTR CLR R3 ;ADD 0 IN RLDLK CALL RLDLK ;GET SYMBOL VALUE IN R3 .IIF NE REL$ CALL ERR.51 ;PROCESS COMPLEX RELOCATION ERROR ;MAS21 MOV R3,R0 ;COPY VALUE MOV (SP)+,R3 BR 20$ ;PUSH SYMBOL VALUE ; PUSH RELOCATABLE VALUE CPXPRL: CALL BYTE ;GET SECTION NUMBER IN R0 DEC R5 ;BYTE COUNT CMP ESWVAL,R0 ;SEE IF SECTION NO. OK BLO CPXERR ;NO, ERROR ASL R0 ;CONVERT SECTION # TO 2 WD INDEX ASL R0 ADD STLML,R0 ;GET ENTRY IN TABLE MOV @R0,R0 ;GET SYM TBL ADR OF SECTION MOV -(R0),R1 ;BASE ADR OF SECTION BIT -(R0),#CS$REL*400 ;REL SECTION? .IIF NE REL$ CALL ERR.51 ;PROCESS COMPLEX RELOCATION ERROR ;MAS21 10$: CALL GETWD ;GET OFFSET WITHIN SECTION ADD R1,R0 ;RELOCATE OFFSET 20$: MOV R0,-(R3) ;PUSH RESULT CMP ESWNAM+2,R3 ;SEE IF 'PUSH' CAUSED OVERFLOW BHIS CPXERR ;YES, ERROR CPXEXT: RETURN ;NO, EXIT .DSABL LSB .IF NE REL$ ;MAS21+ ; PROCESS COMPLEX RELOCATION ERROR MESSAGE FOR REL LINK ERR.51: BEQ 10$ ;NO IF EQ TSTB SWITCH ;FORGROUND LINK ? BPL 10$ ;NO IF + CMP -(R0),-(R0) ;R0 -> SYMBOL NAME ERROR$ ERR51,E$W,E$SYM,R0 ;COMPLEX RELOCATION OF 10$: RETURN .ENDC ;REL$ ;MAS21- ;+ ; COMPLEX STORE DISPLACED ; THIS OPERATION TERMINATES A COMPLEX RELOCATION STRING ;- CPXSTD: ADD 6(R3),@R3 ;SUBTRACT VIRTUAL ADR ;SAVED VALUE OF R3 ON CALL TO 'RLDCPX' ;+ ; COMPLEX STORE NOT DISPLACED ; THIS OPERATION TERMINATES A COMPLEX RELOCATION STRING ;- CPXSTO: MOV (R3)+,R0 ;FETCH DATA TO BE STORED CMP ESWNAM,R3 ;CHECK STACK BNE CPXERR ;ERROR IF NOT AT BEGINNING MOV R3,SP ;BACK TO NORMAL STACK USAGE ADD #6,SP ;GUARD WORDS & SAVED R3 WE DON'T CARE ABOUT MOV (SP)+,R1 MOV R0,R3 ;VALUE TO BE STORED CLR R2 ;DON'T OUTPUT ANY REL INFO CALLR IMGOUT ;OUTPUT TASK IMAGE DATA .SBTTL RLDLK RLD SYMBOL LOOKUP ROUTINE ;+ ; SUBROUTINE TO LOOKUP THE SYMBOL IN THE CURRENT RLD ITEM, ; AND ADD ITS VALUE TO R3. ; INPUT: R5 = # OF BYTES IN BLK ; R4 -> CURRENT INPUT BYTE ; LKWD = 0 FOR GLOBAL SYMBOL LOOKUP ; = SY.SEC + SEGMENT # FOR SECTION NAME LOOKUP ; ENDBUF = ADDR OF THE END OF BUFR ; ; OUTPUT:R5 REDUCED BY 4 ; R0 -> FLAGS WORD OF SYMBOL IN SYM TBL ; R4 & ENDBUF UPDATED AS REQUIRED ; Z = 0 SYMBOL IS RELOCATABLE (NE) ; Z = 1 SYMBOL IS ABSOLUTE (EQ) ;- RLDLK: MOV R3,-(SP) ;SAVE CURRENT R3 MOV #TEMP,R3 ;R3 -> AREA TO STORE RLD ITEM CALL GETWD ;1ST WORD OF SYMBOL NAME MOV R0,@R3 CALL GETWD ;2ND WORD OF SYMBOL NAME MOV R0,2(R3) MOV #^CSY.SEC,LKMSK ;MASK WORD FOR GLOBAL LOOKUP TST LKWD ;GLOBAL SYMBOL ? BEQ 10$ ;YES IF 0 MOV #^C,LKMSK ;SECTION NAME LOOKUP 10$: CALL LOOKUP ;SYMBOL MUST HAVE BEEN DEFINED BCC 20$ ;C=1 IF NOT FOUND TST LKWD ;IF GLOBAL LOOKUP THEN ERROR BEQ 50$ MOV #SY.SEC,LKWD ;LOOKUP SECTION NAME IN ROOT CALL LOOKUP ; SINCE NOT FOUND IN CURRENT SEGMENT BCS 50$ ;MUST FIND IT THIS TIME 20$: MOV -(R0),R3 ;GET SYMBOL'S VALUE BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 30$ ;BRANCH IF NOT MOV R3,PSIZE ;SAVE PSECT SIZE 30$: ADD (SP)+,R3 ;ADD FORMER R3 VAL .IF NE REL$ ;SHD02+ BIC #FG.TT,FLGWD ;INIT VSECT FLAG CMP -6(R0),(PC)+ ;IS IT A VSECT? .RAD50 \. V\ BNE 40$ ;IF NE NO CHANCE CMP -4(R0),(PC)+ ;2ND CHECK FOR VSECT .RAD50 \IR.\ BNE 40$ ;IF NE NOT VSECT BIS #FG.TT,FLGWD ;SAY ITS A VSECT 40$: .ENDC ;REL$ ;SHD02- BIT -(R0),#SY$REL*400 ;IS SYMBOL ABSOLUTE ? RETURN 50$: ERROR$ ERR46,E$F,E$FIL ;BAD RLD SYMBOL IN .SBTTL DMPTXT WRITE TEXT TO OUTPUT FILE ;+ ; IF TXT BLKS WHICH ARE ON AN ODD BOUNDARY, THE DATA BYTES (BUT NOT THE ; ADDRESS) ARE SHIFTED DOWN IN MEMORY (HIGHER) BY ONE BYTE WHEN THE BLOCK ; IS FIRST READ IN, AND SHIFTED BACK UP WHEN THE BLOCK IS OUTPUT. ; INPUT: R5 = # OF DATA BYTES IN OBJ BLK ; R4 -> CURRENT DATA BYTE OF BUFR ; ENDBUF = END OF INPUT BUFR ; ; OUTPUT: NEW TXT BLK IS READ IN AT "TXTBLK" ; ;- .ENABL LSB ;MAS21 DMPTXT: CALL TDMP0 ;GET RID OF OLD BLOCK BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 10$ ;BRANCH IF NOT MOV RLDSP,TXTSP ;SET UP CORRECT SPACE FOR TEXT BLOCK 10$: MOV R5,TXTLEN ;LENGTH OF NEW BLOCK AS CURRENT MOV #TXTBLK,R3 ;R3 -> AREA TO STORE TEXT INFO MOV R3,R1 ;COPY ADDR OF TXTBLK 20$: CMP ENDBUF,R4 ;CHECK IF ANY MORE BYTES TO MOVE BHI 30$ CALL NEWBUF ;READ A NEW INPUT BUFFER LOAD 30$: MOVB (R4)+,(R3)+ ;MOVE TXT BLOCK INCLUDING CKSUM DEC R5 ;LENGTH CTR BGE 20$ ;MORE ADD BASE,@R1 ;ADD BASE TO GIVE ABS LOAD ADDR ;+ ; IF THE /X SWITCH IS USED, THEN DO NOT OUTPUT THE BITMAP IN ;MAS11+ ; BLOCK ZERO OF THE SAVE FILE IF THE PROGRAM USES LOCATIONS ; 360-377 IN AN ASECT OR PSECT. ;- BIT SWITCH,#SW.X ;/X SWITCH USED? BEQ 40$ ;NO DON'T DO TESTS FOR LOC 360-377 CMP #400,@R1 ;IS TXTBLK AT >400? BLOS 40$ ;YES-> DOESN'T USE 360-377 MOV @R1,R2 ;MIGHT USE BITMAP AREA, ADD LENGTH TO ADD TXTLEN,R2 ;START OF TEXT (MAKES VALUE 2 HIGHER THAN REQ) CMP #360+2,R2 ;IS PROGRAM USING BITMAP AREA? BHIS 40$ ;NO->DON'T SET FLAG BIS #FG.XX,FLGWD ;YES->SET FLAG NOT TO OUTPUT BITMAP 40$: BIT #1,(R1)+ ;IS PROG ADDR OF TXTBLK ODD? ;MAS11- BEQ 60$ ;IF EQ-NO 50$: MOVB -(R3),1(R3) ;YES-MOVE BLK DOWN IN MEMORY(HIGHER) CMP R3,R1 ;DONE WHOLE BLOCK? BNE 50$ ;IF NE-NO 60$: TST MBPTR ;SHOULD THE TXT BE STORED? ;CER02 BEQ 70$ ;YES IF EQ ;CER02 CLRTXL: CLR TXTLEN ;MARK TXT BLOCK EMPTY ;CER02 ;MAS21 70$: RETURN ;YES-GO ON ;CER02 .DSABL LSB ;MAS21 .SBTTL TDMP0 CHECK IF TEXT BLOCK IS ON ODD BOUNDARY ;+ ; IF SO-MOVE IT BACK THEN OUTPUT IT. TEXT WAS MOVED AT DMPTXT. ; USES R1,R2,R3,R0 ;- TDMP0: MOV #TXTBLK,R1 ;ADDR OF TXTBLK BIT #1,(R1)+ ;IS PROG ADDR IN TXTBLK ODD? BEQ 20$ ;IF EQ-NO MOV TXTLEN,R2 ;YES-PUT LENGTH IN R2 10$: MOVB 1(R1),(R1)+ ;MOVE TXT BACK A BYTE(LOWER) DEC R2 ;MOVED ALL? BGE 10$ ;IF GE-NO 20$: .SBTTL DMP0 DUMP TEXT SUBROUTINE ;+ ; COME HERE TO UNLOAD CONTENTS OF TEXT BUFFER ; INPUT:SEGBAS = ABS ADDR OF BASE OF CURRENT SEGMENT ; SEGBLK = REL BLK # FOR START OF THIS SEGMENT ; TXTBLK = ABS ADR OF TEXT FOLLOWED BY THE ACTUAL TEXT ; TXTLEN = NUMBER OF BYTES OF TEXT INFO ; ; I-D SPACE ; HERE WE WRITE OUT THE PREVIOUS TEXT BLOCK. TXTSP TELLS WHETHER ; THIS BLOCK IS I OR D SPACE. 0 -> I-SPACE, NONZERO -> D-SPACE ;- .ENABL LSB ;MAS04 DMP0: MOV TXTLEN,R2 ;AND GET LEN OF OLD BLK SUB #2,R2 BLE CLRTXL ;EXIT IF NO TXT ;MAS21+ MOV #TXTBLK,R3 ;ADDR OF WORD ALIGNED TEXT MOV R3,R1 ;R1 -> TEXT INFO TO COUNT ;MAS21- .IF NE LDA$ TST SWITCH ;IS OUTPUT AN LDA FILE ? BMI LDAOUT ;NO IF + ;MAS21 .IFTF ; MOV #TXTBLK,R3 ;ADDR OF WORD ALIGNED TEXT ;MAS21 MOV (R3)+,R0 ;R0 = FINAL ABS ADR OF TEXT BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 20$ ;BRANCH IF NOT 10$: TST TXTSP ;IS IT I-SPACE? BEQ 20$ ;BRANCH IF YES CMP DHLRT,R0 ;IS ADDR FOR A D-SPACE OVERLAY ? BHI 30$ ;NO IF .GT. (SO GBL SECTION OF OVRLY FILE WORK) SUB DSGBAS,R0 ;REDUCE ADR BY D SEGMENT BASE BR 30$ ;MERGE BELOW 20$: CMP HLRT,R0 ;IS ADDR FOR AN OVERLAY ? BHI 30$ ;NO IF .GT. (SO GBL SECTION OF OVRLY FILE WORK) SUB SEGBAS,R0 ;REDUCE ADR BY SEGMENT BASE 30$: MOV R0,-(SP) ;SAVE ABS ADR CLRB R0 ;THIS PLUS ROR GETS BLOCK NUMBER ;MAS21 SWAB R0 ;C=0 NOW ROR R0 ;R0 = REL BLK # BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 50$ ;BRANCH IF NOT TST TXTSP ;IS THIS BLOCK D-SPACE? BEQ 40$ ;BRANCH IF NOT CMP DHLRT,TXTBLK ;IS ADR FOR A D-SPACE OVERLAY ? BHI 60$ ;NO IF HI (GBL SECTION IN ROOT SUPPORT) ADD DSGBLK,R0 ;OFFSET BY START OF SEGMENT(0 FOR ROOT) BR 60$ ;MERGE BELOW 40$: ADD DBASE,R0 ;I-SPACE - ADD IN BASE BLOCK OF I-SPACE 50$: CMP HLRT,TXTBLK ;IS ADR FOR AN OVERLAY ? BHI 60$ ;NO IF HI (GBL SECTION IN ROOT SUPPORT) ADD SEGBLK,R0 ;OFFSET BY START OF SEGMENT(0 FOR ROOT) 60$: MOV BITBAD,BITMAP ;GET BLK 0 BITMAP ADDRESS (D-SPACE IF /J) CLR IFLG ;SAY WE'RE WRITING BLK 0 BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 70$ ;BRANCH IF NOT TST TXTSP ;IS THIS BLOCK D-SPACE? BNE 70$ ;BRANCH IF YES, WE HAVE THE RIGHT BITMAP MOV IBITBD,BITMAP ;GET I-SPACE BITMAP ADDRESS MOV SP,IFLG ;SAY WE'RE DOING I-SPACE 70$: CALL GETBUF ;GET A BUFR ADR MOV @SP,R0 ;ABS ADR BIC #^C777,R0 ;DETERMINE OFFSET INTO BUFR ADD R0,R1 ;R1 -> PROPER POSITION IN OUTPUT BUFR NEG R0 ADD #512.,R0 ;# OF BYTES THAT FIT CMP R0,R2 ;FIND THE MIN OF FIT OR LENGTH BLOS 80$ MOV R2,R0 ;LENGTH IS SMALLER THAN FIT 80$: ADD R0,@SP ;UPDATE ABS ADR OF TXTBLK SUB R0,R2 ;REDUCE TEXT LENGTH BY AMOUNT THAT FITS 90$: MOVB (R3)+,(R1)+ ;MOVE TXT BLK TO OUTPUT BUFFER SOB R0,90$ MOV (SP)+,R0 ;RESTORE ABS ADR TST R2 ;ALL BYTES COPIED ? BGT 30$ ;NO IF GT BEQ CLRTXL ;MAS21 JMP ILERR ;ILLEGAL ERROR .SBTTL LDAOUT LDA OUTPUT ROUTINES ;+ ; INPUT:R1 -> TEXT TO OUTPUT ; R2 = # OF BYTES TO OUTPUT ; ; OUTPUT:R2 = NEW OUTPUT BUFR PTR ; CLOBBERS R3 ;- LDAOUT: MOV R2,R3 ;COPY OF LENGTH CALL FBSTRT ;START A FOMATTED BINARY BLK CMPB (R3)+,(R3)+ ;ADD 2 100$: MOVB (R1)+,R0 ;NEXT BYTE TO BE OUTPUT ;MAS04 CALL LDABYT ;WRITE TO OUTPUT SOB R3,100$ ;LOOP FOR ALL ;MAS04 MOV CKSUM,R0 ;CLOSE OUT FB BLOCK WITH CHECKSUM CALL LDABYT MOV R2,MODNAM ;SAVE FINAL BUFFER PT JMP CLRTXL ;MAS04 ;MAS21 .DSABL LSB ;MAS04 FBSTRT: ADD #6,R2 ;CALC ACTUAL LENGTH OF BLK MOV R2,-(SP) ;SAVE LENGTH MOV MODNAM,R2 ;SET UP BUFFER POINTER CLR CKSUM ;INIT THE CHECKSUM MOV #1,R0 ;FLAG BEGINNING OF FB BLK CALL LDABYT CLR R0 CALL LDABYT MOV @SP,R0 ;OUTPUT LENGTH WORD CALL LDABYT MOV (SP)+,R0 SWAB R0 ;FALL INTO LDABYT AND RETURN ; R0 = BYTE TO OUTPUT LDABYT: SUB R0,CKSUM ;COMPUTE CHECKSUM MOVB R0,(R2)+ ;MOVE TO OUTPUT BUFFER CMP IBUF,R2 ;BUFFER FULL ? BHI 10$ ;NO, JUST RETURN MOV OBUF,R2 ;INIT BUFR PTR CALL WRIT0 ;WRITE BLOCK OBLK FROM OBUF INC OBLK ;BUMP OUTPUT BLK # 10$: RETURN .ENDC ;LDA$ .SBTTL OV7DUM:: DUMMY ENTRY POINT TO MAKE IT RESIDENT OV7DUM::RTS R5 .SBTTL WDPUT SUBR TO CREATE TXT BLOCKS ;+ ; INPUT: R0 = WORD TO OUTPUT IN "TXTBLK" ; R4 = CURRENT PTR IN "TXTBLK" AREA ; CALLS DMP0 SUBROUTINE WHEN TXTBLK FILLS UP. ; CLOBBERS R0 & R1 ;- WDPUT: MOV R0,(R4)+ ;OUTPUT WORD TO TXT BLOCK ADD #2,TXTLEN CMP #TXTBLK+<60.*2>,R4 ;BLOCK FULL? BHIS 10$ ;NO, JUST RETURN MOV TXTBLK,-(SP) ;SAVE ADDR OF CURRENT BLOCK MOV R2,-(SP) MOV R3,-(SP) CALL DMP0 ;DUMP TXT TO OUTPUT MOV (SP)+,R3 MOV (SP)+,R2 MOV #2,TXTLEN ;INDICATE EMPTY BLOCK MOV #TXTBLK,R4 ;RESET R4 POINTER ;MAS21 ADD #<60.*2>,@SP ;CALC ADDR OF NEW BLOCK MOV (SP)+,(R4)+ ;MAS21 10$: RETURN .SBTTL DMPID OUTPUT OVERLAY ID WORD ;+ ; CALLED FROM THE ROOT WHEN A NEW FILE STARTS AN NEW OVERLAY SEGMENT ; INPUT: R4 -> OVERLAY SEGMENT BLK ; ; /J PROCESSING ; ; DMPID IS CALLED WHENEVER THERE IS AN OVERLAY. THERE WILL ALWAYS ; BE AN I OVERLAY, WHICH MAY OR MAY NOT HAVE A D OVERLAY ASSOCIATED ; WITH IT. IF THERE IS A D OVERLAY, DSGBAS AND DSGBLK ARE SET HERE. ; ; D-SPACE OVERLAYS DO NOT HAVE AN ID WORD. I-SPACE OVERLAYS HAVE 3 ID ; WORDS CONSISTING OF ; ; MOV (PC)+,R0 ; .WORD #< * 14 (OCTAL)> ; RETURN ; ; ALSO WRITTEN AS ; ; MOV #< * 14 (OCTAL)>,R0 ; RETURN ;- DMPID:: TST (R4)+ ;R4 -> OVERLAY REGION BLK FOR THIS SEG MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) CALL TDMP0 ;DUMP TEXT BLOCK, IF PRESENT ;DBB03 MOV @(R4)+,R2 ;BASE ADDR OF OVERLAY REGION ;MAS21+ BIT #SW.J,SWIT1 ;ARE WE DOING I-D SPACE? BEQ 20$ ;BRANCH IF NOT TST S.GHLD-4(R4) ;IS THERE A D-SPCE OVERLAY FOR THIS I OVERLAY? BEQ 10$ ;BRANCH IF NOT MOV R2,-(SP) ;SAVE R2 AND MOV R4,-(SP) ;R4 FOR I-SPACE TST -(R4) ;BACK TO REGION ADDRESS FOR D-SPACE MOV @R4,R2 ;REGION BLOCK ADDRESS TO R2 MOV R.GSAD(R2),DSGBAS ;SET D SEGMENT BASE TST -(R4) ;BACK TO BASE OF SEGMENT BLOCK MOV S.GBBD(R4),DSGBLK ;SET D BASE BLOCK ON OUTPUT FILE MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R2 ;AND R2 FOR I-SPACE 10$: SUB #6,R2 ;ALLOW FOR 3 ID WORDS FOR I-SPACE CLR TXTSP ;THIS IS ALWAYS I-SPACE MOV #12700,TXTBLK+2 ;MOV (PC)+,R0 INSTRUCTION MOV (R4)+,TXTBLK+4 ;SEGMENT ID # TO OUTPUT (S.GID) MOV #207,TXTBLK+6 ;RETURN INSTRUCTION MOV #8.,TXTLEN ;3 WORDS TO OUTPUT BR 30$ 20$: MOV #4,TXTLEN ;ONLY THE ID WORD IS OUTPUT SUB #2,R2 ;ALLOW FOR ID WORD MOV (R4)+,TXTBLK+2 ;SEGMENT ID # TO OUTPUT (S.GID) 30$: MOV (R4)+,SEGBLK ;BASE BLOCK ON OUTPUT FILE 40$: MOV R2,SEGBAS ;SET SEGMENT BASE MOV R2,TXTBLK ;ABS ADR FOR OUTPUT ;MAS21- CALL DMP0 ;BEGIN NEW OVERLAY REGION MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 RETURN .SBTTL WRITZ I-D SPACE SUBR - WRITE CALL TO OVERLAY HANDLER ;+ ; WRITZ WRITES THE 2 WORD OVERLAY REFERENCE ENTRIES INTO THE D-SPACE ; ROOT, AND WRITES THE JSR,R5 INSTRUCTION INTO THE I-SPACE ROOT. ; ; INPUT: R0 = WORD TO OUTPUT IN "TXTBLK" ; R4 = CURRENT PTR IN "TXTBLK" AREA ; CALLS DMP0 SUBROUTINE WHEN TXTBLK FILLS UP. ; CLOBBERS R0 ;- WRITZ: MOV R1,-(SP) MOV R2,-(SP) MOV S.GID(R5),R0 ;OVERLAY ID NUMBER INTO D-SPACE ROOT CALL WDPUT MOV -(R3),R0 ;ACTUAL ENTRY POINT INTO D-SPACE ROOT CALL WDPUT MOV R4,-(SP) ;SAVE R4 AFTER WE PUT THE 2 WORD ENTRY IN MOV TXTLEN,TLNSAV ;SAVE TEXT POINTER MOV #TXTBLK,R0 ;SAVE TXTBLK MOV #,R2 ;NUMBER OF WORDS TO SAVE MOV #TBKSAV,R1 ;OUTPUT BUFFER 10$: MOV (R0)+,(R1)+ DEC R2 BGT 10$ MOV TXTSP,-(SP) ;SAVE THE SWAPPED OUT TEXT'S SPACE CLR TXTSP ;SAY WE'RE PROCESSING I-SPACE MOV #2,TXTLEN ;MARK BLOCK EMPTY MOV #TXTBLK+2,R4 ;SET TEXT POINTER MOV JSRADR,TXTBLK ;START ADDRESS IN TXTBLK FOR THIS JSR,R5 20$: MOV R3,-(SP) ;SAVE POINTER TO SYMTAB AT VALUE MOV #4537,R0 ;JSR R5,$OVRH OR $OVRHV CALL WDPUT ;WRITE JSR INSTR MOV HIPHYS,R0 ;HIPHYS CONTAINS CORRECT ENTRY POINT CALL WDPUT CALL DMP0 ;WRITE OUT THIS BLOCK MOV R4,R0 ;ADDR IN TXTBLK SUB #TXTBLK+4.+2,R0 ;CALC REL ADDR ADD JSRADR,R0 ;ADD BASE ADDR OF BLOCK MOV (SP)+,R3 ;R3 -> VALUE IN SYMTAB MOV R0,(R3)+ ;CHANGE ADDR IN SYMBOL TABLE -> DUMMY SUBR ADD #4,JSRADR ;SAVE START ADDR FOR NEXT JSR,R5 MOV TLNSAV,TXTLEN ;RESTORE TEXT POINTER MOV #TXTBLK,R0 ;RESTORE TXTBLK MOV #,R2 ;NUMBER OF WORDS TO RESTORE MOV #TBKSAV,R1 ;ADDRESS OF SAVE AREA 30$: MOV (R1)+,(R0)+ DEC R2 BGT 30$ MOV (SP)+,TXTSP ;RESTORE THE SWAPPED IN TEXT'S SPACE MOV (SP)+,R4 ;RESTORE MOV (SP)+,R2 ;SAVED MOV (SP)+,R1 ;REGISTERS RETURN ;FROM WHEN WE CAME .SBTTL BLDREL BUILD REL BLOCK ROUTINE ;+ ; THIS ROUTINE BUILDS THE RESIDENT REL BLOCK, AND THE OVERLAY ; REL BLOCK. THE RELS CONSIST OF POINTERS, RELATIVE ADDRESS FROM ; START OF ROOT, TO THE RELOCATED CODE IN THE TEXT BLOCK. ; (NOTE: THE ADDRESS IS SHIFTED RIGHT ONE BIT, AND BIT 15 IS ; EITHER 0 OR 1.,E.G. 1 = NEGATIVE RELOCATION, 0 = ADDITIVE RELOCATION ) ; ; INPUT:R2 = THE PROGRAM ADDRESS OF THE CODE IN THE TEXT BLOCK.(+4) ; R0 = ORIGINAL CODE TO GET MODIFIED BY FRUN ; NUMCOL = NON-ZERO, PERFORM NEGATIVE RELOCATION ; NUMCOL = 0, PERFORM POSITIVE RELOCATION ; MODNAM+2 = RELOCATION BASE VALUE TO CORRECT PROGRAM ADDRESS ; (RELBAS+4 FOR ROOT, SEGBAS+4 FOR OVERLAYS ; YSWNAM USED TO INDICATE AN OVERLAY SEGMENT CHANGE(INIT T0 0) ; ; OUTPUT:R2 IS THE SAME ;- .IF NE REL$ .ENABL LSB BLDREL: TSTB SWITCH ;DOING FOREGROUND LINK ? BPL 100$ ;NO IF +, SO JUST RETURN CMP #RELBAS+4,R2 ;IF THE ADDRESS IS IN THE ASECT THEN REL BHI 100$ ; INFORMATION IS NOT REQUIRED(FRUN HANDLES ; THE ADDRESS VALUES IN THE VECTORS SPECIAL) BIT #FG.TT,FLGWD ; VSECT? ;SHD02 BEQ 10$ ;IF EQ NO ;SHD03+ BIC #FG.TT,FLGWD ;ELSE CLEAR BIT FOR FUTURE GENERATIONS BR 100$ ;AND SPLIT WITH A JOB WELL DONE 10$: MOV R2,-(SP) ;SAVE ADR ;SHD03- MOV R0,-(SP) ;CODE TO OUTPUT CMP SEGNUM,YSWNAM ;NEW OVERLAY ? BEQ 60$ ;NO ;CER03 MOV #-1,R0 ;START OF OVERLAY INFORMATION CALL RELWRD MOV R5,-(SP) ;SAVE IT MOV SEGNUM,-(SP) ;GET SEGMENT # MOV @SP,YSWNAM ;SEGMENT # INTO CURRENT OVERLAY INDICATOR BEQ 110$ ;IF 0 THEN BACK TO ROOT, GBL SECTION INTO ROOT;CER03 ; HANDLE INFO FROM LIBRARIES ;CER03 MOV SEGBLK,R0 ;RELATIVE BLOCK # OF NEW SEGMENT CALL RELWRD ASL @SP ;TIMES 6 GIVES SEG ID ADD SEGNUM,@SP ASL @SP ;NOW HAVE SEGMENT ID MOV OVSPTR,R0 ;R0 -> START OF OVERLAY SEGMENT BLKS 20$: CMP S.GID(R0),@SP ;AT CORRECT OVERLAY ? BEQ 40$ ;YES MOV S.GNXP(R0),R5 ;ANOTHER SEGMENT BLK ? BNE 30$ ;YES MOV S.GRGP(R0),R0 ;R0 -> OVERLAY REGION BLK FOR THIS SEG MOV R.GNXP(R0),R0 ;R0 -> NEXT OVL REGION BLK MOV R.GSGP(R0),R0 ;R0 -> SEGMENT BLK OF NEW REGION BR 20$ 30$: MOV R5,R0 ;IND NEW SEGMENT BLK SAME REGION BR 20$ 40$: MOV S.GHCL(R0),R0 ;SIZE OF SEGMENT ASR R0 ;CALC. # OF WORDS IN OVERLAY INC R0 ;INCLUDE OVERLAY ID WORD CALL RELWRD ;OVERLAY LENGTH IN REL BLK MOV SEGBAS,R0 ;PROGRAM ADR CORRECTION FOR OVERLAYS ADD #4,R0 ; = SEGBAS + 4 ;MAS17 MOV R0,MODNAM+2 ; & KEEP IT 50$: MOV (SP)+,R5 ;MAS21+ ; TST (SP)+ ;POP SEGMENT # OFF STACK MOV (SP)+,R5 ;RESTORE IT 60$: SUB MODNAM+2,R2 ;CORRECT PGM TXT ADR FOR REL MOVB NUMCOL,R0 NEGB R0 ; TSTB NUMCOL ;POSITIVE RELOCATION ? ; BEQ 70$ ;YES ; SEC ;SET C BIT ;MAS21- 70$: ROR R2 ;IND RELOCATION TYPE & WORD OFFSET MOV R2,R0 ;PROPER REG FOR OUTPUT CALL RELWRD ;PLACE REL IN BUFFER MOV (SP)+,R0 ;CODE TO BE MODIFIED BY FRUN MOV (SP)+,R2 ;RESTORE IT ; CALLR RELWRD ;FALL INTO RELWRD & RETURN .SBTTL RELWRD PLACE THE WORD IN R0 INTO THE REL BUFFER ;+ ; MODNAM -> THE CURRENT POSITION IN THE REL BUFFER. ;- RELWRD: MOV R0,@MODNAM ;OUTPUT REL WORD ADD #2,MODNAM ;BUMP PTR TO NEXT WORD CMP MODNAM,ENDLML ;END OF REL BUFFER ? BLO 100$ ;NO TST ODBLK ;REL FILE OUTPUT ? BEQ 90$ ;NO MOV R0,-(SP) ;MAS21 .WRITW #PRAREA,#0,ESZRBA,#256.,YSWNAM+2 ;WRITE REL ;DBB07 MOV (SP)+,R0 ;MAS21 BCC 90$ TSTB @#ERRBYT ;WRITE BEYOND EOF ? BEQ 80$ ;ES IF 0 ERROR$ ERR6,E$F,E$PRT ;SAV FILE ERROR 80$: ERROR$ ERR52,E$F,E$PRT ;REL WRITE BEYOND EOF 90$: INC YSWNAM+2 ;UPDATE REL BLK # MOV ESZRBA,MODNAM ;RESET REL PTR ;MAS21 100$: RETURN 110$: CLR R0 ;RETURN TO THE ROOT SEGMENT FOR REL INFO;CER03+ CALL RELWRD ;FILE REL BLK # CALL RELWRD ;# OF WORDS IN SEGMENT(0 TRIGGERS FRUN) MOV #RELBAS+4,MODNAM+2 ;RESET RELOCATION BASE ADDR CLR YSWNAM ;RESET OVERLAY SEGMENT CHANGE BR 50$ ;GO ABOUT NORMAL PROCESSING ;THE LIBRARY FILES WILL ALWAYS BE LAST ;CER03- .DSABL LSB .ENDC ;REL$ .PSECT DATA .EVEN WDBRGO: .WORD 0 ;OFFSET INTO REGION WDBSTS: .WORD WS.MAP ;I-SPACE WDB STATUS WORD .WORD WS.MAP!WS.D ;D-SPACE WDB STATUS WORD WDBIDX: .WORD 2 ;I-SPACE WDB ADDITIONAL BYTES FOR ID .WORD 0 ;D-SPACE WDB ADDITIONAL BYTES FOR ID .PSECT CODE .ENABL LSB MKWDBD: MOV #2,R3 ;INDICATE D-SPACE WDB BR 10$ MKWDBI: CLR R3 10$: MOV R0,-(SP) ;SAVE PARTITION HIGH LIMIT SUB R1,@SP ;SUBTRACT OUT LOW LIMIT CLR R0 ;GET READY TO ROTATE HIGH 3 BITS INTO R0 ROL R1 ;THIS WILL PUT THE ROL R0 ;CORRECT PAR ROL R1 ;IN THE LOW BYTE ROL R0 ;OF R0, AND THE ROL R1 ;HIGH BYTE WILL ROL R0 ;BE ZERO SWAB R0 ;MOVE PAR TO HIGH BYTE FOR STORAGE IN WDB CALL WDPUT ;AND STORE IT ; NOW DO BASE VIRTUAL ADDRESS CLR R0 ;NOW DO ZERO FOR BASE VIRT ADDR, CALL WDPUT ;AND STORE IT ; WINDOW SIZE ( ALSO LENGTH TO MAP CALCULATION, AS THEY ARE EQUAL) MOV (SP)+,R0 ;GET (HIGH LIMIT - LOW LIMIT) OF PARTITION ADD WDBIDX(R3),R0 ;ADD IN ID OFFSET (0, 2, OR 6) ;C=0 FROM ADD WHICH WILL NOT OVERFLOW ROL R0 ;AND CONVERT FROM BYTES ROL R0 ;TO 32. WORD ROLB R0 ;(100 OCTAL BYTE) SWAB R0 ;MULTIPLE FOR WINDOW SIZE, AND LENGTH TO MAP MOV R0,-(SP) ;SAVE A COPY FOR LENGTH TO MAP CALL WDPUT ;STORE IN WINDOW LENGTH ; XM REGION ID MOV #-1,R0 ;REGION ID = -1, FOR KMON LOADING OF REGIONS CALL WDPUT ;STORE IN REGION ID ; OFFSET INTO XM REGION MOV WDBRGO,R0 ;GET OFFSET INTO REGION (1ST = 0) CALL WDPUT ;STORE IT ADD @SP,WDBRGO ;ADD LENGTH OF PARTITION TO PREVIOUS OFFSET ; LENGTH TO MAP = WINDOW SIZE (PREVIOUSLY CALCULATED) MOV (SP)+,R0 ;GET SAVED SIZE FOR LENGTH TO MAP CALL WDPUT ;STORE IT ; STATUS WORD MOV WDBSTS(R3),R0 ;SET MAP BIT (AND WS.D OR WS.I FOR /J) CALLR WDPUT ;STORE IT AND RETURN .DSABL LSB .SBTTL PUTCHR OUTPUT A CHARACTER TO THE CREF FILE ;DBB04+ ;+ ; INPUT: R0 = CHARACTER ; ; OUTPUT:A BUFFER IS WRITTEN AS REQUIRED ; R0 = SAME CHARACTER ;- .ENABL LSB PUTCHR: MOV R0,-(SP) ;SAVE CHARACTER TO OUTPUT MOV #CBPTR,R0 ;R0 -> OUTPUT BUFR PTR TST @R0 ;IS CREF FILE DESIRED? BEQ 10$ ;NO CREF IF EQ MOVB @SP,@(R0)+ ;PUT CHAR INTO BUFR INC -(R0) ;BUMP POINTER CMP CBEND,@R0 ;AT THE END OF BUFR? BHI 10$ ;NO MOV CBUF,@R0 ;YES, SET START OF BUFR INC -(R0) ;BUMP REL BLOCK # TST -(R0) ;R0 -> CWAREA .WRITW ,#11 ;WRITE TO CREF FILE ;DBB07 BCC 10$ ;NO ERRORS ERROR$ ERR76,E$W,E$PRT ;CREF WRITE ERROR CLR CBPTR ;ABORT CREF BUT 10$: MOV (SP)+,R0 RETURN ; CONTINUE OTHER THINGS .DSABL LSB .SBTTL R50ASC: RAD50 TO ASCII CONVERSION ;+ ; INPUT: R1 -> ASCII CHAR OUTPUT AREA ; R3 -> 2-WORD RAD50 TO CONVERT ; USAGE: R2 & R0 = TEMPORARY ; R4 -> DIVISION TABLE ; @SP = # OF CHARACTERS TO BE OUTPUT ; OUTPUT:R3 -> R3 + 4 ; R1 -> NEXT FREE OUTPUT BYTE ; CLOBBERS R0 ;- R50ASC: MOV R4,-(SP) ;SAVE R4 & R2 MOV R2,-(SP) MOV #6,-(SP) ;# OF CHARS TO OUTPUT 10$: MOV #DIVTAB,R4 ;R4 -> DIVISION TABLE MOV (R3)+,R2 ;R2 = CURRENT INPUT WORD 20$: TST -(R4) ;NEW WORD REQUIRED YET? BEQ 10$ ;YES CLR R0 ;INITIALIZE QUOTIENT REG 30$: INC R0 ;DIVIDE BY APPROPRIATE POWER OF 50(8) SUB @R4,R2 BCC 30$ DEC R0 ADD @R4,R2 ;RESTORE DIVIDEND TST R0 ;CHARACTER IS A BLANK? BEQ 40$ ;YES CMP #33,R0 ;DOLLAR SIGN, PERIOD, OR DIGIT? BLO 50$ ;PERIOD OR DIGIT BEQ 60$ ;DOLLAR SIGN ADD #40,R0 ;ELSE ALPHA (A-Z) OR QUESTION MARK 40$: ADD #16,R0 50$: ADD #11,R0 60$: ADD #11,R0 70$: MOVB R0,(R1)+ ;STORE CONVERTED CHARACTER IN OUTPUT DEC @SP ;LOOP FOR MORE CHARS BNE 20$ ;YES TST (SP)+ ;POP CTR MOV (SP)+,R2 MOV (SP)+,R4 RETURN .PSECT DPURE,D .WORD 0 ;END-OF-TABLE FLAG .WORD 1 .WORD 50 .WORD 3100 DIVTAB=. ; BIT MASK TABLE TO CLEAR MASTER BITMAP NON-ROOT BITS BTMSK: .BYTE 377,177,77,37,17,7,3,1 .PSECT IMPURE CRFLIN: .BLKB 16. ;DBB04- .PSECT PATCH .BLKW 64. ;PSECT FOR PATCHES .END