mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-05 10:43:43 +00:00
3785 lines
138 KiB
Plaintext
3785 lines
138 KiB
Plaintext
TITLE LNKNEW - LOAD NEW BLOCKS MODULE FOR LINK
|
||
SUBTTL D.M.NIXON/DMN/JLd/TXR/JNG/DZN/PAH/PY/HD/RJF 5-Feb-88
|
||
|
||
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1973,1986,1988.
|
||
; ALL RIGHTS RESERVED.
|
||
;
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
|
||
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND 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. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
|
||
;TRANSFERRED.
|
||
;
|
||
;
|
||
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
|
||
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
|
||
;CORPORATION.
|
||
;
|
||
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
|
||
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
|
||
|
||
|
||
SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC,OVRPAR ;[1704]
|
||
SALL
|
||
|
||
ENTRY LNKNEW
|
||
EXTERN LNKSCN,LNKLOD,LNKCOR,LNKWLD,LNKLOG,LNKCST
|
||
|
||
|
||
CUSTVR==0 ;CUSTOMER VERSION
|
||
DECVER==6 ;DEC VERSION
|
||
DECMVR==0 ;DEC MINOR VERSION
|
||
DECEVR==2417 ;DEC EDIT VERSION
|
||
|
||
|
||
SEGMENT
|
||
|
||
|
||
;LOCAL ACC DEFINITIONS
|
||
INTERN R,RB,WC
|
||
|
||
R=R1 ;CURRENT RELOCATION COUNTER
|
||
RB=R+1 ;RELOCATION BYTE WORD
|
||
WC=R3 ;WORD COUNT
|
||
|
||
SUBTTL REVISION HISTORY
|
||
|
||
|
||
;START OF VERSION 1A
|
||
;52 ADD ASCIZ TEXT BLOCK
|
||
|
||
;START OF VERSION 2
|
||
;141 TURN ON AND FIX BUGS IN ASCII TEXT BLOCKS
|
||
|
||
;START OF VERSION 2B
|
||
;253 Correct problems with ASCII blocks: make work with
|
||
; CCL entry; cause multiple line blocks to not lose
|
||
; characters by initializing byte pointer once (here).
|
||
;404 Re-insert edits 344 and 340, which got lost.
|
||
;405 Recover if EOF encountered while reading ASCII text.
|
||
;411 Don't try to free core here that was freed in LNKSCN.
|
||
|
||
;START OF VERSION 2C
|
||
;454 Allow (but ignore) the trace blocks from MAKLIB.
|
||
;471 Add code for ALGOL debugging system.
|
||
;517 Make first word of ALGOL symbol file be 1044,,count.
|
||
;530 Get definition of triplet flag bits right.
|
||
;534 Store files from the same .TEXT block in the right order.
|
||
;557 Clean up the listing for release.
|
||
|
||
;START OF VERSION 3A
|
||
;560 Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)
|
||
|
||
|
||
;START OF VERSION 4
|
||
;731 SEARCH MACTEN,UUOSYM
|
||
;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
|
||
|
||
;Start of version 5I
|
||
;1000 Add Block 1070
|
||
|
||
;START OF VERSION 4A
|
||
;1174 Label and clean up all error messages.
|
||
;1212 Use E$$NEB instead of EOFTS label in T.1003 (in an off conditional).
|
||
;1217 Clean up the listings for release.
|
||
;1220 Release on both TOPS-10 and TOPS-20 as version 4A(1220).
|
||
;1303 Change the LNKLNM message to also include the file name.
|
||
;START OF VERSION 5
|
||
;1405 New blocks T.1010 thru T.1134 and supporting routines added.
|
||
;1426 Delete redundant T.1042-T.1044 routines introduced during merge.
|
||
;1430 Remove .NWBLK conditionals forcing an error from T.1060 blocks,
|
||
; and ignore them.
|
||
;1434 New block type 1004 ( byte pointer initialization ) added.
|
||
;1440 Apply edit 1240,1237, and 1120 to the new blocks.
|
||
;1443 Make sure PDV .REL blocks aren't in LINK-10.
|
||
;1445 Typo in block type 1004 corrected.
|
||
;1452 Lengthen LITYPE bounds to include all new blocks.
|
||
|
||
;START OF VERSION 5A
|
||
;1467 Change D.IN1 call to D.CNT at T1004C.
|
||
;1470 Correct stack discipline in T.1004 and make sure there are
|
||
; no index registers on return from T.1S6
|
||
;1471 Remove use of T.11XX and PB.1 from type 1130 blocks, which
|
||
; have no relocation words, also alter type 112x block to
|
||
; handle just one relocation byte.
|
||
;1472 Get the right number of chars for a function name and
|
||
; don't lose the count, in T.112X. Use symbols for the
|
||
; offsets. Also clean up the dispatch macros.
|
||
;
|
||
;1500-1677 Reserved for Maintenance
|
||
;1503 Make 1010-1034 blocks do thirty-bit reloc on their start addresses.
|
||
;
|
||
;1510 Test for include mode at LNKNEW+4.
|
||
;1701 Correct typos in T.1130 introduced during V5A source merge.
|
||
;1704 Handle Type 1045 block.
|
||
;1706 Handle COMMONs in Type 1045 properly.
|
||
;1707 Correct typo in 1706.
|
||
;1712 Call WRTPTR not WRTDAT at T1045C+3.
|
||
;1714 Remove increment of RC.CV in TNYBTL, this should be done at
|
||
; end of module.
|
||
;1720 Change POPJ to POP at REL.TB+2.
|
||
;1721 Correct space initialization at TNYBTB+17.
|
||
;1722 Fix RLADD not to lose right half is left half is absolute.
|
||
;1726 Fixes to 101X block processing to speed up loops and avoid some
|
||
; boundary errors.
|
||
;1730 Test limit values and handle overlays okay in Type 101x block
|
||
; processing.
|
||
;1742 Don't lose the section number when calling T.1AD from T.1004.
|
||
;1745 Don't lose T4 across the call to DY.GET in T.1045 processing.
|
||
;1754 Type 1072 block support.
|
||
;1770 Change JRST CPOPJ to POPJ P, at TSTSEG+5
|
||
;1776 Change call to T.1AD from T.1004, include call in T.1010-1034.
|
||
;2005 Store module name for 112x blocks.
|
||
;2007 Give the LNKUCB message a long error message.
|
||
;2020 Add a word to the typechecking blocks for linking them together.
|
||
;2022 Change tests at T1045C to terminate more surely.
|
||
;2026 Update copyright and cleanup listings.
|
||
;2031 Don't set the writable bit in OVERLW unless actually doing overlays.
|
||
;2072 Skip unused byte when relocating the address in type 102X blocks.
|
||
;2073 Add contents of WRTDAT, not address of WRTDAT in WRTPTR.
|
||
|
||
;Start of Version 6
|
||
;2200 Use 30 bit addresses in fixup blocks for SY.CHP
|
||
;2205 Don't add 30 bit address to 18 bit byte pointer.
|
||
;2212 Fix problems with type 1072 long polish block.
|
||
;2222 Implement the type 1050, 1051, and 1052 rel blocks.
|
||
;2223 Implement the type 1131 psect redirection block.
|
||
;2231 Fix typo in edit 2223.
|
||
;2236 Keep stack straight for long symbols in type 1131.
|
||
;2246 Fix chained and additive fixups.
|
||
;2247 Allow for .LOW. not existing yet.
|
||
;2254 Remove FAIL block header chain, use 30 bit NAMPTR.
|
||
;2255 Use 30 bit addresses for LS area fixups.
|
||
;2262 Implement the 1160 data block, use common code for the 1004 block.
|
||
;2266 Don't truncate type 112x symbol names.
|
||
;2270 Allow type 112x blocks to page.
|
||
;2272 Default psects to .LOW. and .HIGH. in the type 1131 block.
|
||
;2301 Handle error from D.CNT correctly.
|
||
;2303 Push correct register in non-symbolic type 1004 blocks.
|
||
;2305 Make 1070 blocks work, Make 1002 blocks work
|
||
;2307 Fix problem with typechecking routines with six character names.
|
||
;2310 Implement the type 1074 long symbol common block.
|
||
;2313 Make type 1004 and 1160 work in overlays.
|
||
;2324 Make polish chained fixup handlers clear P1 before calling SY.CHx.
|
||
;2326 Make 1003 (long title) blocks work
|
||
;2327 Fix problem with relocation in type 1160 block.
|
||
;2333 Set flags for fixup block in 1070 code.
|
||
;2340 Check for invalid psect index in 1074.
|
||
;2343 Fix problem with sparse data below address 140.
|
||
;2345 Clean up and fix t1003 block code.
|
||
;2366 Fix type 1160 block on TOPS-10.
|
||
;2377 Fix 1045 for long symbols.
|
||
;2400 Restore W2 after call to T.6RED in X03OK.
|
||
;2401 Fix off by one bug in 1002 block code.
|
||
;2403 New coporate copywrite statement.
|
||
;2410 Fix X160SS so TAB.UW doesn't get updated unless we are paging.
|
||
;2411 Fix all kinds of problems with long symbol entry counts.
|
||
;2417 Update copywrite statement to 1988.
|
||
|
||
SUBTTL BLOCK DISPATCH TABLES
|
||
|
||
|
||
XALL
|
||
NDSPTB: LITYPE (1000,1160) ;[2262]
|
||
NDISPL==.-NDSPTB
|
||
SALL
|
||
SUBTTL DISPATCH TO NEW BLOCK TYPE
|
||
|
||
|
||
;ENTER WITH BLOCK TYPE IN T1
|
||
;ALSO IN W1
|
||
|
||
LNKNEW: CAILE T1,1777 ;IS IT DEC SUPPLIED
|
||
JRST LNKCST ;NO, TRY CUSTOMER LINK ITEMS
|
||
CAIL T1,1000+NDISPL*2 ;IS IT LEGAL TYPE
|
||
JRST E$$IRB## ;[1174] NO, NOT YET AVAILABLE
|
||
TRNE FL,R.LIB!R.INC ;[1510] IN LIBRARY SEARCH MODE?
|
||
JRST T.SRCH ;YES, IGNORE IF NOT ENTRY BLOCK TYPE
|
||
HRREI T2,-<1000+NDISPL>(T1) ;OFFSET TYPE
|
||
JUMPGE T2,.+2 ;IF NEGATIVE, USE RHS
|
||
SKIPA T2,NDSPTB+NDISPL(T2) ;USE RIGHT HALF
|
||
HLRZ T2,NDSPTB(T2) ;USE LEFT HALF
|
||
JRST (T2) ;DISPATCH
|
||
|
||
|
||
|
||
;HERE IF IN LIBRARY SEARCH MODE - TEST FOR BLOCK TYPE 1001, 1002
|
||
|
||
T.SRCH: CAIN T1,1001 ;IS IT ENTRY BLOCK?
|
||
JRST T.1001 ;YES, SEE IF WE WANT IT
|
||
CAIN T1,1002 ;OR EXTENDED ENTRY BLOCK?
|
||
JRST T.1002
|
||
CAIN T1,1003 ;TITLE BLOCK (INCASE /INCLUDE)
|
||
JRST T.1003
|
||
JRST T.1000 ;IGNORE THIS BLOCK
|
||
|
||
|
||
SUBTTL BLOCK TYPE 1000 - JUNK WORDS
|
||
|
||
|
||
; ----------------
|
||
; ! 1000 ! COUNT !
|
||
; ----------------
|
||
; ! DATA WORD !
|
||
; ----------------
|
||
; ! DATA WORDS !
|
||
; ----------------
|
||
|
||
T.1000: HRRZ T1,W1 ;GET WORD COUNT
|
||
JUMPE T1,LOAD## ;JUST IGNORE
|
||
T1000A: CAML T1,DCBUF+2 ;ENOUGH WORDS IN BLOCK?
|
||
SOJA T1,T1000B ;NO, BUT ACCOUNT FOR INITIAL ILDB
|
||
ADDM T1,DCBUF+1 ;ADVANCE BYTE POINTER
|
||
MOVN T1,T1 ;NEGATE
|
||
ADDM T1,DCBUF+2 ;COUNT DOWN WORD COUNT
|
||
JRST LOAD## ;GET NEXT BLOCK
|
||
|
||
T1000B: SUB T1,DCBUF+2 ;COUNT DOWN WORDS IN BUFFER
|
||
PUSHJ P,D.INP## ;GET NEXT BUFFER
|
||
JRST T1000A ;FINISH OFF BLOCK
|
||
|
||
T1000C: MOVNI W1,400000(WC) ;[2262] PUT WORD COUNT IN W1
|
||
JRST T.1000 ;[2262] IGNORE REST OF BLOCK
|
||
|
||
SUBTTL BLOCK TYPE 1001 - SINGLE WORD ENTRIES
|
||
|
||
|
||
; ----------------
|
||
; ! 1001 ! COUNT !
|
||
; ----------------
|
||
; ! SYMBOLS !
|
||
; ----------------
|
||
; ! SYMBOLS !
|
||
; ----------------
|
||
|
||
IFE .NWBLK,<
|
||
T.1001==E$$IRB## ;[1174] ILLEGAL IF NOT THERE
|
||
> ;END IFE .NWBLK
|
||
|
||
IFN .NWBLK,<
|
||
T.1001: MOVEI T2,0(W1) ;GET NUMBER OF ENTRIES IN THIS MODULE
|
||
MOVE R3,T2 ;SAFE PLACE FOR COUNT DOWN
|
||
JUMPE T2,LOAD## ;IGNORE 0 ENTRIES
|
||
SKIPN ENTPTR ;ALREADY SOME ENTRIES FOR THIS MODULE?
|
||
JRST T1001E ;NO
|
||
HLRO T1,ENTPTR ;GET -NUMBER
|
||
SUB T2,T1 ;NUMBER WE NEED
|
||
PUSHJ P,DY.GET## ;GET IT
|
||
HRLZ T3,ENTPTR ;FORM BLT PTR
|
||
HRR T3,T1
|
||
HLRO T4,ENTPTR ;-NUMBER OF WORDS
|
||
MOVM W3,T4
|
||
ADDI W3,(T1) ;END OF BLT
|
||
BLT T3,-1(W3) ;MOVE ALL PREVIOUS ENTRIES
|
||
MOVN T2,T2 ;NEGATE NEW LENGTH
|
||
HRL T1,T2 ;FORM AOBJN POINTER
|
||
EXCH T1,ENTPTR ;SWAP POINTERS
|
||
HRRZ T1,T1 ;ADDRESS ONLY
|
||
MOVM T2,T4 ;AND LENGTH
|
||
PUSHJ P,DY.RET## ;GIVE SPACE BACK
|
||
JRST T1001D
|
||
;HERE WHEN THIS IS THE FIRST BLOCK TYPE 1001,1002 OR 4 SEEN.
|
||
|
||
T1001E: MOVN T1,T2
|
||
HRLM T1,ENTPTR ;LEFT HALF OF AOBJN PTR
|
||
PUSHJ P,DY.GET## ;GET SPACE
|
||
HRRM T1,ENTPTR ;FINISH POINTER
|
||
HRRZ W3,T1 ;DON'T NEED W3 FOR ANYTHING
|
||
T1001D: HRLI W3,(POINT 36) ;SO USE AS DEPOSIT BYTE POINTER
|
||
TRNN FL,R.LIB ;IN LIBRARY SEARCH MODE
|
||
JRST T1001B ;NO, JUST STORE SYMBOLS FOR LATER
|
||
T1001A: SOJLE R3,LOAD## ;END OF BLOCK
|
||
PUSHJ P,D.IN1## ;READ A WORD
|
||
MOVE W2,W1 ;PUT SYMBOL IN SYMBOL ACC
|
||
SETZ W1, ;ZERO FLAGS
|
||
IDPB W2,W3 ;STORE ENTRY
|
||
PUSHJ P,TRYSYM## ;SEE IF SYMBOL IS IN TABLE
|
||
JRST T1001A ;NO, TRY NEXT
|
||
TRZA FL,R.LIB ;UNDEF, CLEAR SKIP CONTROL
|
||
JRST T1001A ;DEFINED, DON'T NEED THIS DEFINITION
|
||
T1001B: SOJL R3,LOAD## ;END OF BLOCK
|
||
PUSHJ P,D.IN1##
|
||
IDPB W1,W3 ;STORE
|
||
JRST T1001B ;LOOP
|
||
>
|
||
SUBTTL BLOCK TYPE 1002 - LONG SYMBOL ENTRY
|
||
|
||
|
||
; ----------------
|
||
; ! 1002 ! COUNT !
|
||
; ----------------
|
||
; ! SYMBOL !
|
||
; ----------------
|
||
; ! MORE SYMBOL !
|
||
; ----------------
|
||
; // ... //
|
||
; ----------------
|
||
; ! 0 ! ;[2411]
|
||
; ----------------
|
||
|
||
IFE .NWBLK,<
|
||
T.1002==E$$IRB## ;[1174] ERROR UNLESS FIXED
|
||
> ;END IFE .NWBLK
|
||
|
||
IFN .NWBLK,<
|
||
T.1002: MOVEI R3,0(W1) ;GET NUMBER OF WORDS OF ENTRY IN THIS BLOCK
|
||
CAIG R3,2 ;[2401] TREAT 0 AND 1 AS T.1001
|
||
JRST T.1001 ;NOT A LONG SYMBOL
|
||
CAIL R3,<SYMSIZ-1> ;[2305] IS IT LONGER THAN MAX NAME SIZE?
|
||
PUSHJ P,E$$STL ;[2305] YES - GIVE ERROR
|
||
MOVEI T2,1 ;NEED ONE MORE WORD FOR POINTER
|
||
SKIPN ENTPTR ;ALREADY SOME ENTRIES FOR THIS MODULE?
|
||
JRST T1002E ;NO
|
||
HLRO T1,ENTPTR ;GET -NUMBER
|
||
SUB T2,T1 ;NUMBER WE NEED
|
||
PUSHJ P,DY.GET## ;GET IT
|
||
HRLZ T3,ENTPTR ;FORM BLT PTR
|
||
HRRI T3,1(T1) ;[2411] BUT LEAVE SPACE AT TOP
|
||
HLRO T4,ENTPTR ;-NUMBER OF WORDS
|
||
MOVM W3,T4
|
||
ADDI W3,(T1) ;END OF BLT
|
||
BLT T3,-1(W3) ;MOVE ALL PREVIOUS ENTRIES
|
||
MOVN T2,T2 ;NEGATE NEW LENGTH
|
||
HRL T1,T2 ;FORM AOBJN POINTER
|
||
EXCH T1,ENTPTR ;SWAP POINTERS
|
||
HRRZ T1,T1 ;ADDRESS ONLY
|
||
MOVM T2,T4 ;AND LENGTH
|
||
PUSHJ P,DY.RET## ;GIVE SPACE BACK
|
||
HRRZ W3,ENTPTR ;RESET W3 TO POINT TO TOP ITEM (HOLE)
|
||
JRST T1002D
|
||
T1002E: MOVN T1,T2
|
||
HRLM T1,ENTPTR ;LEFT HALF OF AOBJN PTR
|
||
PUSHJ P,DY.GET## ;GET SPACE
|
||
HRRM T1,ENTPTR ;FINISH POINTER
|
||
HRRZ W3,T1 ;DON'T NEED W3 FOR ANYTHING
|
||
T1002D: MOVE T2,R3 ;[2305] get count for this entry name
|
||
SUBI T2,1 ;[2401] don't count header word in sym length
|
||
PUSHJ P,DY.GET## ;[2305] get the space we need
|
||
MOVN T2,T2 ;[2305] negate the length
|
||
HRLS T2 ;[2305] make left half of aobjn pointer
|
||
HRR T2,T1 ;[2305] make right half of abojn (addres of dy
|
||
;[2305] block for name)
|
||
T1002L: PUSHJ P,D.IN1 ;[2305]
|
||
MOVEM W1,(T2) ;[2305] store a word
|
||
AOBJN T2,T1002L ;[2305]
|
||
JRST T1002B ;[2305]
|
||
|
||
MOVEI T2,-1(R3) ;THESE MANY EXTRA (AFTER FIRST) WORDS
|
||
ROTC T1,-1 ;CUT IN HALF
|
||
SKIPGE T1 ;NO CARRY
|
||
ADDI T2,1 ;EXTRA BLOCK FOR LAST WORD
|
||
IMULI T2,.L ;THESE MANY WORDS IN TRIPLETS
|
||
ADDI T2,.L ;PLUS INITIAL ONE
|
||
HRLZM T2,0(W3) ;STORE WORD COUNT IN EMPTY SLOT
|
||
TRNE T2,770000 ;UNLESS SYMBOL IS SUPER LONG
|
||
ADDI T2,1 ;IN WHICH CASE ONE MORE FOR COUNT
|
||
PUSHJ P,DY.GET## ;GET SPACE
|
||
HRRM T1,0(W3) ;STORE POINTER ADDRESS
|
||
TRNE T2,770000 ;FIX IF SUPER LONG
|
||
JRST [HRRZS 0(W3) ;CLEAR COUNT
|
||
MOVEM T2,0(T1) ;STORE AS FIRST WORD
|
||
AOJA T1,.+1] ;PASS OVER IT
|
||
HRRZ W3,T1 ;USE DATA BLOCK TO STORE ENTRY
|
||
HRLI W3,(POINT 36) ;SO USE AS DEPOSIT BYTE POINTER
|
||
MOVX W1,PT.SYM!PT.EXT ;SOME FLAGS
|
||
IDPB W1,W3
|
||
PUSHJ P,D.IN1## ;GET FIRST 6
|
||
IDPB W1,W3 ;STORE ALSO
|
||
MOVE W2,W1 ;SAVE FIRST 6 CHARS
|
||
SETZ W1, ;ZERO VALUE
|
||
IDPB W1,W3
|
||
T1002A: SOJLE R3,T1002B ;END OF BLOCK
|
||
MOVX W1,S.LST ;CLEAR LAST TRIPLET FLAG IN PREV
|
||
ANDCAM W1,-2(W3) ;SINCE WE NOW COME AFTER IT
|
||
MOVX W1,S.SYM!S.LNM!S.LST ;SECONDARY FLAGS
|
||
IDPB W1,W3
|
||
PUSHJ P,D.IN1## ;READ A WORD
|
||
IDPB W1,W3 ;STORE SYMBOL
|
||
SOJLE R3,T1002B ;END OF BLOCK
|
||
PUSHJ P,D.IN1## ;NO
|
||
IDPB W1,W3 ;STORE SECOND WORD
|
||
JRST T1002A ;LOOP
|
||
;HERE WHEN SYMBOL STORED
|
||
|
||
T1002B: HRL T1,R3 ;[2305] GET THE COUNT
|
||
MOVE T2,ENTPTR ;[2305]
|
||
MOVEM T1,(T2)
|
||
TRNN FL,R.LIB ;IN LIBRARY SEARCH MODE?
|
||
JRST LOAD## ;NO, SYMBOL STORED SO GET NEXT BLOCK
|
||
MOVE W2,(W3) ;[2411] ADDRESS OF SYMBOL NAME TO W2
|
||
SOS R3 ;[2411] NUMBER OF WORDS IN LONG SYMBOL
|
||
HRL W2,R3 ;[2411] COUNT,,ADDRESS OF SYMBOL NAME
|
||
PUSHJ P,TRYSYM## ;SEE IF SYMBOL IS IN TABLE
|
||
JRST LOAD## ;NO, GET NEXT BLOCK
|
||
TRZ FL,R.LIB ;UNDEF, CLEAR SKIP CONTROL
|
||
JRST LOAD## ;DEFINED, DON'T NEED THIS DEFINITION
|
||
>
|
||
SUBTTL BLOCK TYPE 1003 - NAME
|
||
|
||
|
||
|
||
|
||
|
||
|
||
; _____________________________________________________
|
||
; | 1003 | Long count |
|
||
; -----------------------------------------------------
|
||
; | 1 | Count of Title words |
|
||
; -----------------------------------------------------
|
||
; | Program Title |
|
||
; -----------------------------------------------------
|
||
; | additional program title |
|
||
; -----------------------------------------------------
|
||
; | additional program title |
|
||
; -----------------------------------------------------
|
||
; . . .
|
||
; _____________________________________________________
|
||
; | 2 | # ascii comment words |
|
||
; -----------------------------------------------------
|
||
; | comment word |
|
||
; -----------------------------------------------------
|
||
; | more comment words |
|
||
; -----------------------------------------------------
|
||
; . . .
|
||
; _____________________________________________________
|
||
; | 3 | count of compiler words |
|
||
; -----------------------------------------------------
|
||
; | compiler code | CPU bits |
|
||
; ------------------------------------------------------
|
||
; | Compiler name (in ascii) |
|
||
; ------------------------------------------------------
|
||
; | additional compiler name |
|
||
; ------------------------------------------------------
|
||
; | additional compiler name |
|
||
; ------------------------------------------------------
|
||
; . . .
|
||
; ______________________________________________________
|
||
; | 4 | 0 |
|
||
; ------------------------------------------------------
|
||
; | Compile Date and Time |
|
||
; ------------------------------------------------------
|
||
; | Compiler version number |
|
||
; ------------------------------------------------------
|
||
; | 5 | 0 |
|
||
; ------------------------------------------------------
|
||
; | Device Name |
|
||
; ------------------------------------------------------
|
||
; | UFD or 0 for TOPS-20 |
|
||
; ------------------------------------------------------
|
||
; | 6 | 0 |
|
||
; ------------------------------------------------------
|
||
; | Tops-10 file Name |
|
||
; ------------------------------------------------------
|
||
; | file extention | 0 |
|
||
; ------------------------------------------------------
|
||
; | 7 | number of SFDs |
|
||
; ------------------------------------------------------
|
||
; | SFD 1 |
|
||
; ------------------------------------------------------
|
||
; | SFD 2 |
|
||
; -----------------------------------------------------
|
||
; . . .
|
||
; ______________________________________________________
|
||
; | 10 | Number of TOPS-20 file |
|
||
; | | spec words (in ascii) |
|
||
; ------------------------------------------------------
|
||
; | TOPS-20 file spec |
|
||
; ------------------------------------------------------
|
||
; | more TOPS-20 file spec |
|
||
; ------------------------------------------------------
|
||
; . . .
|
||
; ______________________________________________________
|
||
; | 11 | 0 |
|
||
; ------------------------------------------------------
|
||
; | Source version number |
|
||
; ------------------------------------------------------
|
||
; | Date | Time |
|
||
; ------------------------------------------------------
|
||
IFE .NWBLK,<
|
||
T.1003==E$$IRB##
|
||
>
|
||
;HERE ON A BLOCK TYPE 1003 (NAME BLOCK)
|
||
|
||
;THE W'S CONTAIN THE CURRENT TRIPLET AND THE T'S ARE SCRATCH.
|
||
|
||
|
||
T.1003: RELOCATE (NONE) ;THIS BLOCK TYPE CONTAINS NO RELOCATION
|
||
TRNE FL,R.LIB!R.INC ;NEED AN EXCUSE TO LOAD THIS?
|
||
SKIPE INCPTR ;ANY POSSIBILITY WE'LL GET ONE?
|
||
CAIA ;DON'T NEED AN EXCUSE OR COULD GET ONE
|
||
JRST T1000C ;[2345] NO CHANCE, JUST IGNORE THIS BLOCK
|
||
PUSHJ P,D.GET1
|
||
PUSHJ P,T1003E ;ERROR
|
||
HLR T1,W1 ;[2326] get the sub-block code
|
||
HRRZS W1 ;[2326] save just sub-block count
|
||
CAIE T1,1 ;[2326] this is first sub-block must be name
|
||
;[2326] sub-block
|
||
JRST E$$IRB ;[2326] else the block is bad
|
||
XCT X03BIT(T1) ;[2326] set the correct bits in flag word (w1)
|
||
MOVE T1,W1 ;COPY FLAGS FOR DESTRUCTIVE TESTING
|
||
TXC T1,PT.SGN!PT.TTL ;THESE BITS SHOULD BE ON
|
||
TXZ T1,PT.EXT ;IGNORE THIS BIT HOWEVER
|
||
TROE FL,R.LOD ;DID WE SEE AND END BLOCK FOR LAST PRGM?
|
||
PUSHJ P,E$$NEB## ;[1212] WARN USER, BUT TRY TO CONTINUE
|
||
TRNE FL,R.FHS ;FORCED TO HIGH SEGMENT?
|
||
PUSHJ P,T1003H ;YES, MAKE SURE THERE IS ONE
|
||
PUSHJ P,X03TTL ;[2326] get the module name
|
||
|
||
;[2326] Now check /include /exclude to see if we have to load this module
|
||
|
||
TRNE FL,R.LIB!R.INC
|
||
JRST X03INC
|
||
SKIPN EXCPTR ;[2326] if any /excludes
|
||
SKIPE INCPTR ;[2326] no but may have to purge entry in
|
||
;[2326] include list.
|
||
JRST X03EXC ;[2326] see if should be excluded (t.6exc)
|
||
X03OK: TRZ FL,R.LIB!R.INC ;[2326] loading this module for sure
|
||
MOVEM W2,PRGNAM ;[2326] save name for error messages
|
||
SKIPE REDLO ;[2326] doing /REDIRECT
|
||
PUSHJ P,T.6RED## ;[2326] yes so do it
|
||
TRNE FL,R.FHS ;[2326] need to adjust relocation tables?
|
||
PUSHJ P,T.6RC## ;[2326] yes so do it
|
||
MOVE W2,PRGNAM ;[2400] get back name incase T.6RED called
|
||
MOVE T1,LSYM ;WORD COUNT IN LOCAL SYMBOL TABLE
|
||
MOVEM T1,NAMPTR ;POINT TO THIS TITLE BLOCK
|
||
|
||
PUSHJ P,E$$LMN## ;[2326] tell that this module is being loaded
|
||
SETZM W3 ;[2326] zero w3
|
||
PUSHJ P,X03ADD ;[2326] since it is loaded put in local symbol
|
||
;[2326] for map
|
||
AOS PRGNO ;[2326] one more module seen
|
||
X03SRT: PUSHJ P,D.GET1 ;[2326] get the next word
|
||
JRST X03ND ;[2345] go output seg info
|
||
HRRZ T1,W1 ;[2326] get count if any
|
||
HLRZ T2,W1 ;[2326] get the sub-block code for index
|
||
SKIPLE T2 ;[2345] Index must be greater than 0
|
||
CAIL T2,MAXBIT ;[2345] but less than maximun index
|
||
JRST T1003E ;[2345] Not a valid sub-block index code
|
||
XCT X03BIT(T2) ;[2326] set the appropriate bits in w1
|
||
XCT X03JMP(T2) ;[2326] go to the appropriate routine
|
||
|
||
|
||
;[2326] this routine handles the CPU code and the compiler name and code.
|
||
|
||
X03PRC: HRRZ P1,T1 ;[2326] save count of extra compiler name words
|
||
HLLZS W1 ;[2326] clear the count from flag word
|
||
PUSH P,W1 ;[2326] put the flags on the stack
|
||
PUSH P,P1 ;[2326] store the count since p1 is used later
|
||
PUSHJ P,D.GET1 ;[2326] get the next word
|
||
JRST T1003E ;[2345] something is wrong with rel blk
|
||
MOVE W2,W1 ;[2326] first compiler & CPU bits to w2
|
||
|
||
LDB T1,[POINT 6,W2,5] ;[2345] get runnable cpu bits
|
||
ANDI T1,CP.MSK ;[2326] clear CPUS we don't know about
|
||
SKIPN T1 ;[2345] asked for none?
|
||
MOVEI T1,CP.MSK ;[2326] yes--means all
|
||
HRRZM T1,CTYPE ;[2326] save with compiler type
|
||
MOVE T2,CPUTGT ;[2326] get target CPUs
|
||
JUMPE T2,x03TGT ;[2326] the CPU switches are not being used
|
||
TDON T1,T2 ;[2326] test for a good target switch
|
||
JRST E$$CPU## ;[2326] .DIRECTIVE is for wrong CPU
|
||
X03TGT: SKIPN OKCPUS ;[2345] can any CPU run this code?
|
||
JRST X03END ;[2345] no--forget this test
|
||
ANDM T1,OKCPUS ;[2326] enforce CPU flags
|
||
SKIPN OKCPUS ;[2326] can prog run at all now?
|
||
PUSHJ P,E$$CCD## ;[2326] no--CPU conflict detected
|
||
X03END: LDB T1,[POINT 12,W2,17] ;[2345] now get processor type
|
||
CAILE T1,CT.LEN ;[2326] check for range
|
||
SETZ T1, ;[2326] make it unknown
|
||
HRLM T1,CTYPE ;[2326] save compiler type
|
||
MOVE T2,PROCSN ;[2326] get list of procs seen so far
|
||
MOVE P1,T1 ;[2326] safe place
|
||
PUSH P,W2 ;[2345] put on stack for CT.NAM(t1) call
|
||
XCT CT.NAM##(T1) ;[2326] proc routines expect many ACs + (p)
|
||
MOVE T1,CT.BIT##(P1) ;[2326] get corresponding bit
|
||
IORM T1,PROCSN ;[2326] signal we have seen this one
|
||
IORM T1,LIBPRC ;[2326] a new module this library pass
|
||
POP P,W2 ;[2326] clear flags off stack
|
||
POP P,P1 ;[2326] restore count of name words
|
||
JUMPE P1,NONAME ;[2345] check for no compiler name
|
||
PUSHJ P,D.GET1 ;[2326] get next word - 1st name word
|
||
JRST T1003E ;[2345] something is wrong with rel blk
|
||
SKIPA W3,W1 ;[2345] put first compiler name word in w3
|
||
NONAME: SETZM W3 ;[2345] if no compiler word then put in 0
|
||
POP P,W1 ;[2345] restore compiler type and CPU bits
|
||
PUSHJ P,LS.ADD## ;[2326] store the triplet
|
||
SOS P1 ;[2326] decrement count of
|
||
JRST RELLP ;[2326] check and put rest of long compiler
|
||
;[2326] name in the ls area
|
||
|
||
;[2326] this routine takes the string stored as count,,address in w2 and builds
|
||
;[2326] triplets then stores them in ls area.
|
||
|
||
X03ADD: TLNE W2,770000 ;[2326] is it a long title?
|
||
PJRST LS.ADD## ;[2345] no - just one words worth - go do it
|
||
HLRZ P1,W2 ;[2326] count of words to p1
|
||
HLLZS W1 ;[2326] clear count form w1 need to set trip
|
||
;[2326] bits there
|
||
HRRZ P2,W2 ;[2326] the address of string to p2
|
||
CAILE P1,1 ;[2326] do we need extended triplets
|
||
TXC W1,PS.EXO ;[2326] yes extended triplets to follow
|
||
PUSHJ P,X031WD ;[2326] build primary triplet
|
||
TXZ W1,PS.EXO ;[2326] clear secondary following bit
|
||
TXZ W1,PT.SGN!PT.EXT;[2326] clear primary flags
|
||
TRPLP: JUMPLE P1,DONE ;[2326] have we finished?
|
||
CAIGE P1,2 ;[2326] need whole triplet?
|
||
JRST X031WD ;[2326] no - build last triplet
|
||
PUSHJ P,X03TRP ;[2326] yes - build whole triplet
|
||
JRST TRPLP ;[2326] go back and check for more
|
||
DONE: POPJ P, ;[2326] finished
|
||
|
||
|
||
;[2326] build whole triplet from string address stored in p2,
|
||
;[2326] count stored in p1.
|
||
|
||
X03TRP: DMOVE W2,@P2 ;[2326] put the 2 words in w2, w3
|
||
SUBI P1,2 ;[2326] two words stored so decrement count
|
||
ADDI p2,2 ;[2326] got two so bump address
|
||
PUSHJ P, LS.ADD## ;[2326] put them in the ls area
|
||
POPJ P,
|
||
|
||
;[2326] build a triplet with only one word of title left and store in ls area
|
||
|
||
X031WD: MOVE W2,@P2 ;[2326] get word form source and put in w2
|
||
SETZM W3 ;[2326] zero w3
|
||
SOS P1 ;[2326] subtract one from count
|
||
AOS P2 ;[2326] add one to the address
|
||
PJRST LS.ADD## ;[2345] store the triplet in the ls area
|
||
|
||
|
||
;[2326] This routine builds triplets from the rel file and stores them in the
|
||
;[2326] ls area enters with the flags in w1 and count in right half of w1.
|
||
;[2326] Gets the next two words and puts them in w2,and w3.
|
||
|
||
X03STR: HRRZ P1,T1 ;[2326] count of words to p1
|
||
PUSHJ P,X03TRW ;[2326] build primary triplet
|
||
RELLP: JUMPLE P1,X03SRT ;[2345] go back for next sub-block
|
||
CAIGE P1,2 ;[2326] need whole triplet?
|
||
JRST X031RW ;[2326] no - build last triplet
|
||
PUSHJ P,X03TRW ;[2326] yes - build whole triplet
|
||
JRST RELLP
|
||
|
||
|
||
;[2326] gets a word form the rel block and put it in w2, zeroes w3, then
|
||
;[2326] stores the triplet in the ls area.
|
||
|
||
X031RW: PUSH P,W1 ;[2326] save the flags
|
||
PUSHJ P,D.GET1 ;[2326] get the next word from the rel file
|
||
JRST T1003E ;[2345] something is wrong with the rel block
|
||
MOVE W2,W1 ;[2326] put the word in w2
|
||
SETZM W3 ;[2326] third word is a zero
|
||
POP P,W1 ;[2326] restore the flags
|
||
SUBI P1,1 ;[2326] decrease the count of words
|
||
PUSHJ P,LS.ADD## ;[2326] store the triplet in the ls area
|
||
JRST X03SRT ;[2345] back for the next sub-block
|
||
|
||
;[2326] gets two words from the rel block and puts them in w2,w3 then
|
||
;[2326] stores the triplet in the ls area.
|
||
|
||
X03TRW: PUSH P,W1 ;[2326] save the flags
|
||
PUSHJ P,D.GET1 ;[2326] get the next word for rel block
|
||
JRST T1003E ;[2345] something is wrong
|
||
MOVE W2,W1 ;[2326] word to w2
|
||
PUSHJ P,D.GET1 ;[2326] get the next word from the rel block
|
||
JRST T1003E ;[2345] block is bad
|
||
MOVE W3,W1 ;[2326] last word for the triplet
|
||
SUBI P1,2 ;[2326] 2 words gone
|
||
POP P,W1 ;[2326] get back the flags
|
||
PJRST LS.ADD## ;[2345] store the triplet in the ls area
|
||
|
||
;[2326] this routine gets the name words and builds the name in NAMBLK for
|
||
;[2326] testing against /INCLUDES, /EXCLUDES
|
||
|
||
|
||
X03TTL: HRRZ T2,W1 ;[2326]* count of title words to t2
|
||
CAIL T2,SYMSIZ ;[2345] is it longer than max symbol length?
|
||
PUSHJ P,E$$STL ;[2326] Yes - give an error
|
||
PUSH P,W1 ;[2326] save the flags
|
||
CAIG T2,1
|
||
JRST X03SHT ;[2326] just one word so put in w2
|
||
TXC W1,PT.EXT ;[2326] need additional triplets
|
||
MOVNS T2 ;[2326] negative count
|
||
HRLZS T2 ;[2326] put it in left half for AOBJN ptr
|
||
X03LP: PUSHJ P,D.GET1 ;[2326] get the next name word
|
||
JRST LOAD ;[2326] end of block
|
||
MOVEM W1,NAMBLK(T2) ;[2326] store the next word
|
||
AOBJN T2,X03LP ;[2326] done? - no get the next word
|
||
MOVEI W2,NAMBLK ;[2326] address of title to w2
|
||
POP P,W1 ;[2326] restore the flags
|
||
HRL W2,W1 ;[2326] count to left of w2
|
||
SETZM W3 ;[2326] zero last word of triplet
|
||
HLLZS W1 ;[2326] don't want count in flag word
|
||
POPJ P, ;[2326] all done
|
||
|
||
X03SHT: PUSHJ P,D.GET1 ;[2326] get the name word
|
||
JRST T1003E ;[2345] error bad rel block
|
||
SKIPN W2,W1 ;[2345] put it in w2
|
||
MOVE W2,[SIXBIT/.MAIN./] ;[2326] yes - use the default name
|
||
SETZM W3 ;[2326] zero w3
|
||
POP P,W1 ;[2326] restore the flags
|
||
POPJ P, ;[2326] return
|
||
|
||
|
||
;[2326] Now we have the name as count,,ptr in program name and stored in LS.
|
||
;[2326] lets see if we need to load this module.
|
||
|
||
X03INC: PUSHJ P,INCCHK## ;[2326] check /INCLUDES
|
||
SKIPA ;[2326] don't load this module
|
||
JRST X03OK ;[2326] found it in /INCLUDES so go load it
|
||
TRZA FL,R.LOD ;[2326] not there clear loading flag
|
||
X03POP: TRO FL,R.LIB ;[2326] cause module to be ignored by /EXCLUDE
|
||
POP P,W1 ;[2326] restore w1
|
||
JRST T1000C ;[2326] ignore rest of the block
|
||
|
||
;[2326] check the /EXCLUDE to see if it's there
|
||
|
||
X03EXC: PUSHJ P,EXCCHK## ;[2326] see if in the /EXCLUDE list
|
||
JRST X03POP ;[2326] yes so don't load this module
|
||
JRST X03OK ;[2326] not excluded so go load
|
||
|
||
X03STT: PUSHJ P,X03TRW ;[2326] store triplet in ls area
|
||
JRST X03SRT ;[2326] back for the next part
|
||
|
||
;[2326] table of bits that get set according to left half of sub-block flag
|
||
;[2326] word. The code in the sub-block flag word is the index into the table
|
||
;[2326] and the bits are saved in the first word of the ls triplets generated
|
||
;[2326] by the sub-blocks.
|
||
|
||
X03BIT: JFCL ;[2326]
|
||
TXO W1,PT.SGN!PT.TTL!PT.EXT ;[2345] sign, primary title, extended
|
||
MOVX W1,S.TTL!S.CMT ;[2345] comment
|
||
MOVX W1,S.TTL!S.PRC!S.CMT ;[2345] Processor
|
||
MOVX W1,S.TTL!S.CRE ;[2345] Creation date
|
||
MOVX W1,S.TTL!S.DEV ;[2345] Device
|
||
MOVX W1,S.TTL!S.NAM ;[2345] File name
|
||
MOVX W1,S.TTL!S.SFD ;[2345] Sfd
|
||
MOVX W1,S.TTL!S.FIL ;[2345] TOPS-20 file spec
|
||
MOVX W1,S.TTL!S.VER ;[2345] Source version number
|
||
MAXBIT== . - X03BIT ;[2345] table size
|
||
|
||
;[2326] Table of routines to execute based on the code in left half of
|
||
;[2326] sub-block flag word. Uses that code as index to table.
|
||
|
||
X03JMP: JRST T1003E ;[2345] Bad sub-block code
|
||
JRST T1003E ;[2345] Second name sub-block - error
|
||
JRST X03STR ;[2345] Comment sub-block - store ascii text
|
||
JRST X03PRC ;[2345] Compile/CPU sub-block check processor info
|
||
JRST X03STT ;[2345] Compile date/time/version # - 3 word sub-blocks
|
||
JRST X03STT ;[2345] Device/UFD - 3 word sub-block
|
||
JRST X03STT ;[2345] TOPS-10 file spec/ext - 3 word sub-block
|
||
JRST X03STR ;[2345] SFDs
|
||
JRST X03STR ;[2345] TOPS-20 file spec
|
||
JRST X03STT ;[2345] Source version number/date and time
|
||
|
||
;HERE IF /SEG:HIGH. MAKE SURE HIGH SEG EXISTS, THEN FAKE THE RC TABLES.
|
||
T1003H: PUSH P,W1 ;SAVE OVER SETRC CALL
|
||
SETZ W1, ;CREATE HIGH SEGMENT WITH DEFAULT ORIGIN
|
||
SKIPN SG.TB+2 ;HIGH SEGMENT EXIST ALREADY?
|
||
PUSHJ P,SETRC## ;NO, CREATE ONE
|
||
MOVEI R,1 ;NOW MAKE .LOW. POINT TO HIGH SEG
|
||
MOVE T1,SG.TB+2 ;ADDR OF HIGH SEG DATA BLOCK
|
||
MOVEM T1,@RC.TB ;MAKE .LOW. (RC #1) POINT TO IT
|
||
POP P,W1 ;RESTORE FLAGS OF NEXT TRIPLET
|
||
POPJ P,
|
||
|
||
;Here after all sub-blocks have been processed. Call TTLRCL to put the segment
|
||
;descriptor triplets in the LS area. Then go get the next block.
|
||
|
||
X03ND: PUSHJ P,TTLRLC## ;[2345] build segment info triplets-put in LS
|
||
JRST LOAD## ;[2345] get the next block
|
||
|
||
;HERE ON SOME TYPE OF ERROR OR INVALID FORMAT IN THE 1003 BLOCK TYPE
|
||
T1003E: MOVEI T1,1003 ;SHOULD NEVER GET HERE
|
||
JRST E$$IRB## ;[1174] SO WARN THE USER
|
||
|
||
|
||
|
||
|
||
SUBTTL BLOCK TYPE 1004 - BYTE ARRAY INITIALIZATION
|
||
|
||
|
||
; or
|
||
;
|
||
; ---------------- ----------------
|
||
; ! 1004 ! count ! ! 1004 ! count !
|
||
; ---------------- ----------------
|
||
; ! relocation ! ! relocation !
|
||
; ---------------- ----------------
|
||
; ! byte count ! ! global symbol!
|
||
; ---------------- ----------------
|
||
; ! byte pointer ! ! byte count !
|
||
; ---------------- ----------------
|
||
; ! byte string ! ! byte pointer !
|
||
; ---------------- ----------------
|
||
; ! ... ! ! byte string !
|
||
; ---------------- ----------------
|
||
; ! ... !
|
||
; ----------------
|
||
|
||
T.1004: PUSHJ P,RB.2## ;READ AND RELOCATE FIRST TWO WORDS
|
||
JRST LOAD## ;[2262] FAILED, TRY NEXT BLOCK
|
||
SETZ W3, ;[2205] VALUE OF SYMBOL (ZERO IF NONE)
|
||
TLNN W2,770000 ;IS IT A 6-BIT GLOBAL SYMBOL?
|
||
JRST T1004A ;NO
|
||
PUSH P,W1 ;YES, SAVE BYTE COUNT
|
||
PUSHJ P,T.1S6## ;CALL T.1 CODE TO EVALUATE SYMBOL
|
||
SKIPA W3,W2 ;[2262] KEEP THE SYMBOL VALUE
|
||
T1004A: PUSH P,W2 ;[2303] SAVE BYTE COUNT
|
||
LDB T3,[POINT 6,W1,11] ;GET BYTE SIZE
|
||
MOVEM T3,BYTSIZ ;[2262] SAVE IT
|
||
LDB T1,[POINT 6,W1,5] ;[2262] GET BYTE POSITION
|
||
MOVEM T1,BYTPOS ;[2262] SAVE IT
|
||
MOVEM W1,BYTADR ;[2262] STORE IT
|
||
MOVEI T1,1 ;[2262] GET THE REPETITION COUNT
|
||
MOVEM T1,REPCNT ;[2262] SET IT
|
||
SETZM FILCNT ;[2262] 1004 BLOCKS DON'T FILL
|
||
POP P,W1 ;[2262] GET THE BYTE COUNT
|
||
MOVEM W1,BYTCNT ;[2262] SAVE IT
|
||
PUSHJ P,X160SZ ;[2262] FIX UP THE BYTE POINTER
|
||
|
||
;[2262] The following calculation deliberately throws away the carry
|
||
;[2262] which may have occured by incrementing BYTADR in X160SZ. This
|
||
;[2262] is because FORTRAN uses a 777777 address in a byte pointer to
|
||
;[2262] point to the beginning of a common block.
|
||
|
||
HLLZ T2,LSTRRV ;[2262] GET THE SECTION NUMBER
|
||
HLLM T2,BYTADR ;[2205] PUT IT INTO THE ADDRESS (CLOBBER CARRY)
|
||
ADDM W3,BYTADR ;[2262] AND ADD THE SYMBOL
|
||
JRST T1160S ;[2262] JOIN THE COMMON CODE
|
||
|
||
;Enter here from error in T.1S code
|
||
;Clean up and just ignore this block.
|
||
|
||
T1004U::.ERR. (MS,.EC,V%L,L%W,S%W,USB,<Undefined symbol in byte array (type 1004) block>)
|
||
.ETC. (JMP,,,,,.ETIMF##)
|
||
POP P,T1 ;POP OFF THE RETURN ADDRESS
|
||
MOVE R3,-1(P) ;RESTORE THE WORD COUNT
|
||
SUBI R3,3 ;ACCOUNT FOR THE WORDS WE HAVE ALREADY READ
|
||
T1004Z: POP P,T1 ;CLEAN UP THE STACK
|
||
POP P,T1 ; ...
|
||
POP P,P3 ;[1470] ...
|
||
MOVE W1,R3 ;RESTORE WORD COUNT
|
||
JRST T.1000 ;AND JUST IGNORE THE BLOCK
|
||
|
||
SUBTTL BLOCK TYPE 1010-1014 RIGHT HALF RELOCATION
|
||
|
||
|
||
;
|
||
; --------------------
|
||
; ! 101X ! n ! header word
|
||
; !------------------!
|
||
; !b1!b2! ... !bi! -----
|
||
; !------------------! !
|
||
; ! beginning addr. ! !
|
||
; !------------------! !
|
||
; ! data 1 ! !--- subblock
|
||
; !------------------! !
|
||
; // .... // !
|
||
; !------------------!
|
||
; ! data(i-1) ! -----
|
||
; --------------------
|
||
; ...
|
||
|
||
;**;[2072] Replace 2 lines at T1004Z+25L. PAH 19-Jul-84
|
||
DEFINE NEWBLK(RBSIZ,RBNUM,RELTYP,ROFF<0>)< ;;[2072]
|
||
|
||
MOVE P1,[POINT RBSIZ,RB,<RBSIZ*ROFF>-1] ;;[2072]
|
||
MOVEI P2,RBNUM ;;NUMBER OF RELOC BYTES
|
||
MOVE P4,[ RELTYP ] ;;HOW TO DO THE RELOC
|
||
JRST T.NYBT ;;COMMON CODE TO INTERPRET THIS
|
||
> ;[1405]
|
||
|
||
CPSECT=.TEMP ;[2262] TEMPORARY
|
||
|
||
T.1010::
|
||
NEWBLK(2,^D18,RADD) ;[1405]
|
||
|
||
T.1011::
|
||
NEWBLK(3,^D12,RADD) ;[1405]
|
||
|
||
T.1012::
|
||
NEWBLK(6,6,RADD) ;[1405]
|
||
|
||
T.1013::
|
||
NEWBLK(9,4,RADD) ;[1405]
|
||
|
||
T.1014::
|
||
NEWBLK(18,2,RADD) ;[1405]
|
||
|
||
|
||
SUBTTL BLOCK TYPES 1020-1023 LEFT/RIGHT HALFWORD RELOCATION
|
||
|
||
;
|
||
; --------------------
|
||
; ! 102X ! n !
|
||
; !------------------!
|
||
; !l1,r1! ... !li,ri! --
|
||
; !------------------! |
|
||
; ! beginning addr. ! |
|
||
; !------------------! |
|
||
; ! data 1 ! |
|
||
; !------------------! | -- subblock
|
||
; // .... // |
|
||
; !------------------! |
|
||
; ! data(i-1) ! |
|
||
; -------------------- --
|
||
; ...
|
||
;
|
||
|
||
|
||
T.1020::
|
||
;**;[2072] Change 1 line at T.1020+1. PAH 19-Jul-84
|
||
NEWBLK(2,^D9,RLADD,1) ;[2072]
|
||
|
||
T.1021::
|
||
;**;[2072] Change 1 line at T.1021+1. PAH 19-Jul-84
|
||
NEWBLK(3,6,RLADD,1) ;[2072]
|
||
|
||
T.1022::
|
||
;**;[2072] Change 1 line at T.1022+1. PAH 19-Jul-84
|
||
NEWBLK(6,3,RLADD,1) ;[2072]
|
||
|
||
T.1023::
|
||
;**;[2072] Change 1 line at T.1023+1. PAH 19-Jul-84
|
||
NEWBLK(9,2,RLADD,1) ;[2072]
|
||
|
||
|
||
SUBTTL BLOCK TYPES 1030-1034 FOR 30-BIT RELOCATION
|
||
;
|
||
; --------------------
|
||
; ! 103X ! n ! header word
|
||
; !------------------!
|
||
; !b1!b2! ... !bi! -----
|
||
; !------------------! !
|
||
; ! beginning addr. ! !
|
||
; !------------------! !
|
||
; ! data 1 ! !--- subblock
|
||
; !------------------! !
|
||
; // .... // !
|
||
; !------------------!
|
||
; ! data(i-1) ! -----
|
||
; --------------------
|
||
;
|
||
|
||
|
||
T.1030::
|
||
NEWBLK(2,^D18,THADD) ;[1405]
|
||
|
||
T.1031::
|
||
NEWBLK(3,^D12,THADD) ;[1405]
|
||
|
||
T.1032::
|
||
NEWBLK(6,6,THADD) ;[1405]
|
||
|
||
T.1033::
|
||
NEWBLK(9,4,THADD) ;[1405]
|
||
|
||
T.1034::
|
||
NEWBLK(18,2,THADD) ;[1405]
|
||
|
||
SUBTTL SUBROUTINES SUPPORTING BLOCK TYPES 1010-1034
|
||
|
||
PB.1:
|
||
;
|
||
; This routine can return in one of three ways:
|
||
; +1 means the end of the REL block has been seen.
|
||
; +2 means the end of the sub-block has been seen.
|
||
; +3 means that a word has been placed in W1 and its
|
||
; corresponding psect index is found in R
|
||
;
|
||
TRNN WC,377777 ;[1405] END OF BLOCK?
|
||
JRST PB0 ;[1405] YES, RETURN +1
|
||
PUSHJ P,D.IN1## ;[1471] PICK UP A WORD
|
||
AOBJP WC,PB1 ;[1471] END OF SUBBLOCK?
|
||
ILDB R,P1 ;[1405] AND A PSECT INDEX
|
||
PB2: AOS (P) ;[1405]
|
||
PB1: AOS (P) ;[1405]
|
||
PB0: POPJ P, ;[1405]
|
||
|
||
PSORGN:
|
||
;
|
||
; On entry, R contains a psect index.
|
||
; Check this index against the total number seen.
|
||
; Return in R the pointer to this psect's relocation counter
|
||
|
||
JUMPE R,CPOPJ ;[1444] LEAVE ABS DATA ALONE
|
||
CAMG R,RC.NO ;PSECT INDEX EXIST?
|
||
JRST PSORG0 ;[1405] YES
|
||
CAIG R,2 ;[1405] MIGHT BE TWOSEG?
|
||
TRNN FL,R.TWSG ;[1405]
|
||
JRST E$$IPX## ;NO, GIVE ERROR
|
||
SKIPA ;[1405] YES, FETCH COUNTER DIRECTLY
|
||
PSORG0: HRRZ R,@RC.MAP ;[1444] GET INTERNAL PSECT NUMBER
|
||
MOVE R,@RC.TB ;[1405] FETCH COUNTER
|
||
SKIPGE RC.AT(R) ;[1405] ORIGIN SET?
|
||
PUSHJ P,R.ERR## ;[2247] NO, NEEDS AN ORIGIN
|
||
POPJ P, ;[1405] RETURN
|
||
|
||
RADD:
|
||
;
|
||
; Right-half relocation.
|
||
;
|
||
JUMPE R,CPOPJ ;[1444] LEAVE ABS VALUES ALONE
|
||
HRR T2,W1 ;[1444] PICK UP THE HALFWORD
|
||
PUSHJ P,TSTSEG ;[1444]
|
||
ADD T1,T2 ;[1444] ADD IN THE PSECT ORIGIN
|
||
HRR W1,T1 ;[1405] RELOCATED HALFWORD
|
||
POPJ P,
|
||
THADD:
|
||
;
|
||
; Thirty-bit relocation.
|
||
;
|
||
JUMPE R,CPOPJ ;[1444] LEAVE ABS VALUES ALONE
|
||
LDB T2,[POINT 30,W1,35] ;[1405] PICK UP EXTENDED ADDR
|
||
PUSHJ P,TSTSEG ;[1444]
|
||
ADD T1,T2 ;[1444] ADD IN THE PSECT ORIGIN
|
||
DPB T1,[POINT 30,W1,35] ;[1405] AND PUT IT BACK
|
||
POPJ P,
|
||
RLADD:
|
||
;
|
||
; Relocation of left and right halfwords.
|
||
;
|
||
JUMPE R,LADD ;[1722] LEAVE ABS VALUES ALONE
|
||
HLR T2,W1 ;[1444] PICK UP LEFT HALF
|
||
PUSHJ P,TSTSEG ;[1444]
|
||
ADD T1,T2 ;[1444] ADD IN THE PSECT ORIGIN
|
||
;**;[2072] Change 1 line at RLADD+8L. PAH 19-Jul-84
|
||
HRLM T1,W1 ;[2072] RELOCATED LEFT HALF
|
||
LADD: ILDB R,P1 ;[1722] FETCH NEXT RELOC BYTE
|
||
PUSHJ P,PSORGN ;[1405] CHECK IT OVER
|
||
JRST RADD ;[1405] FINISH WITH RIGHTHALF
|
||
|
||
TSTSEG:
|
||
; [1444] This routine picks up the value to be added in for relocating
|
||
; a word against a psect -- special case code for .HIGH. and .LOW. is
|
||
; here.
|
||
|
||
MOVE T1,RC.NM(R) ;[1444] WHAT IS IT?
|
||
CAME T1,[SIXBIT /.HIGH./] ;[1444] HIGHSEG?
|
||
CAMN T1,[SIXBIT /.LOW./] ;[1444] OR LOWSEG?
|
||
JRST [ MOVE T1,RC.SG(R) ;[1444] IF SO,
|
||
MOVE T1,LL.S0(T1) ;[1444] CALCULATE RELOCATION
|
||
ADD T1,RC.CV(R) ;[1444] SOMEWHAT DIFFERENTLY
|
||
SUB T1,RC.IV(R) ;[1444]
|
||
JRST CPOPJ ] ;[1444] AND RETURN
|
||
MOVE T1,RC.CV(R) ;[1727] ELSE RELOC WRT. ORIGIN
|
||
POPJ P, ;[1770]
|
||
|
||
T.NYBT:
|
||
;
|
||
; T.1010 through T.1037 come here after setting up ACs as follows:
|
||
; P1 -an initialized byte pointer for the relocation bytes
|
||
; P2 -number of relocation bytes in the word
|
||
; P4 -dispatch address for type of relocation (left,right,30bit)
|
||
;
|
||
SPUSH <P1,P2> ;[1405] SAVE REGISTERS
|
||
TNYBTB: MOVN T1,P2 ;[1726] WC GETS SUBBLOCK COUNT AGAIN
|
||
HRLI WC,-2(T1) ;[1726] COUNT INCLUDES RELOC WORD
|
||
; BEGIN PROCESSING A SUB-BLOCK
|
||
PUSHJ P,PB.1 ;[1405] FETCH FIRST WORD OF BLOCK
|
||
JRST [ SPOP <P2,P1>
|
||
JRST LOAD ] ;[1405] NO MORE IN BLOCK
|
||
JFCL ;[1405] "IMPOSSIBLE"
|
||
MOVE RB,W1 ;[1405] SETUP RELOC BYTE
|
||
MOVE P1,-1(P) ;[1405] RESET BYTEPOINTER
|
||
PUSHJ P,PB.1 ;[1405] FETCH START ADDRESS
|
||
JRST [ SPOP <P2,P1>
|
||
JRST LOAD ] ;[1405] NO MORE
|
||
JFCL ;[1405] "IMPOSSIBLE"
|
||
PUSHJ P,PSORGN ;[1405] FETCH THE RELOC COUNTER PTR
|
||
MOVEM R,CPSECT ;[1405] "CURRENT PSECT" COUNTER PTR
|
||
PUSHJ P,THADD ;[1503] RELOCATE THE START ADDR
|
||
MOVE P3,W1 ;[1405] PICK UP START ADDRESS
|
||
;
|
||
;[1721] Here compute the size of the subblock into P2 The number of
|
||
;[1721] of words in the rest of the block is in the right half of WC and the
|
||
;[1721] subblock cannot have more than P2-1 words in it.
|
||
;
|
||
HRROI T1,400000(WC) ;[1721] RECOVER SIZE OF BLOCK ( RH OF
|
||
MOVN T1,T1 ;[1721] WC CONTAINS -( SIZE + 400000 )
|
||
SUBI P2,2 ;[1721] SIZE OF SUBBLOCK IN P2 INCLUDES
|
||
;[1721] REL WORD, SO DECR IT ONCE AND
|
||
;[1721] AGAIN FOR THE FENCE IN
|
||
;[1721] "FINISH=START+SIZE-1" BELOW
|
||
CAIL P2,-1(T1) ;[1721] SHORT SUBBLOCK?
|
||
MOVEI P2,-1(T1) ;[1721] YES, USE SIZE OF BLOCK-1
|
||
ADDB P2,W1 ;[1776] HIGHEST LOCATION TO BE LOADED
|
||
PUSHJ P,T.1AD ;[1776]
|
||
JFCL ;[1776] THROW IT AWAY
|
||
JFCL ;[1776] DEFER IT AWHILE
|
||
TNYBTL: PUSHJ P,PB.1 ;[1405] FETCH A DATA WORD
|
||
JRST [ SPOP <P2,P1>
|
||
JRST LOAD ] ;[1405] NO MORE
|
||
JRST [ DMOVE P1,-1(P) ;[1726] FETCH PTR AND COUNT AGAIN
|
||
JRST TNYBTB ] ;[1405] RESET FOR NEXT SUBBLOCK
|
||
PUSHJ P,PSORGN ;[1405] GET ANY PSECT INDICES
|
||
PUSHJ P,@P4 ;[1405] DO THE RELOCATION
|
||
IFN FTOVERLAY,<
|
||
SKIPE RT.LB ;[1730] DOING OVERLAYS?
|
||
SKIPA W3,[JSP T1,CS.RHS##] ;[1730] YES, NOTE OVL RELOC
|
||
> ;[1401] END OF IFN FTOVERLAY
|
||
MOVE W3,[MOVEM W1,(P3)] ;[1730] NO, SIMPLE DEPOSIT
|
||
XCT W3 ;[1730]
|
||
AOJA P3,TNYBTL ;[1714] INCR DESTINATION PTR AND
|
||
;[1714] DO IT AGAIN
|
||
|
||
SUBTTL BLOCK TYPES 1042 AND 1043 - PROGRAM AND LIBRARY REQUESTS
|
||
|
||
; -----------------
|
||
; ! 1042 ! COUNT !
|
||
; -----------------
|
||
; ! DEVICE !
|
||
; -----------------
|
||
; ! FILE NAME !
|
||
; -----------------
|
||
; ! EXT !DIR CNT!
|
||
; -----------------
|
||
; ! PROJ ! PROG !
|
||
; -----------------
|
||
; ! SFD !
|
||
; -----------------
|
||
;
|
||
; .
|
||
;
|
||
; .
|
||
IFN .NWBLK,<
|
||
T.1042: SKIPA P1,[PRGPTR] ;TYPE 1042 IS PROGRAMS TO LOAD
|
||
T.1043: MOVEI P1,LIBPTR ;TYPE 1043 IS LIBRARIES TO SEARCH
|
||
RELOCATE (NONE) ;FILE NAMES ETC ARE NOT RELOCATABLE
|
||
PUSHJ P,D.TRIP ;GET THE 1ST THREE WORDS (REQUIRED)
|
||
JRST E$$IRR ;[1174] ERROR - NOT ENOUGH DATA WORDS
|
||
T1042A: MOVEI T2,R.LEN ;LENGTH OF A REQUEST/REQUIRE BLOCK
|
||
PUSHJ P,DY.GET## ;ALLOCATE ONE
|
||
DSTORE W1,<R.DEV(T1)>,<R.NAM(T1)> ;STORE DEVICE & FILENAME
|
||
HLLZM W3,R.EXT(T1) ;STORE EXTENSION, BUT NOT COUNT
|
||
HRRZ P2,W3 ;REMEMBER DIRECTORY LENGTH IN P2
|
||
JUMPE P2,T1042X ;DONE IF NO DIRECTORY GIVEN
|
||
PUSHJ P,D.GET1 ;GET THE PPN
|
||
JRST E$$IRR ;[1174] ERROR
|
||
MOVEM W1,R.PPN(T1) ;REMEMBER IT
|
||
SOJLE P2,T1042X ;DONE IF NO SFD'S
|
||
MOVE T2,T1 ;GET A COPY OF REQUEST BLOCK POINTER
|
||
HRLI T2,-5 ;MAKE AN AOBJN POINTER FOR SFD'S
|
||
T1042L: PUSHJ P,D.GET1 ;GET THE NEXT SFD
|
||
JRST E$$IRR ;[1174] NONE THERE, COUNT LIED
|
||
MOVEM W1,R.SFD(T2) ;STORE THIS SFD
|
||
SOJLE P2,T1042X ;QUIT IF COUNT RUNS OUT
|
||
AOBJN T2,T1042L ;OR IF NO MORE ROOM IN OUR BUFFERS
|
||
T1042X: PUSHJ P,T.RQST## ;GO CHAIN THIS REQUEST IN IF UNIQUE
|
||
PUSHJ P,D.TRIP ;ANYTHING ELSE THERE?
|
||
JRST LOAD## ;NO, LOAD NEXT BLOCK
|
||
JRST T1042A ;YES, LOAD IT TOO
|
||
|
||
E$$IRR::.ERR. (MS,.EC,V%L,L%W,S%W,IRR,<Illegal request/require block>) ;[1174]
|
||
.ETC. (JMP,,,,,.ETNMF##) ;[1174]
|
||
JRST LOAD## ;NOT ALWAYS A FATAL ERROR
|
||
|
||
SUBTTL BLOCK TYPE 1044 - BLOCK STRUCTURED ALGOL LOCAL SYMBOLS
|
||
|
||
; -----------------
|
||
; ! 1044 ! COUNT !
|
||
; -----------------
|
||
; ! STRUCTURED !
|
||
; -----------------
|
||
; ! ALGOL SYMBOLS !
|
||
; -----------------
|
||
; ! SIXBIT - MAY !
|
||
; -----------------
|
||
; ! BE EXTENDED !
|
||
; -----------------
|
||
;
|
||
; .
|
||
;
|
||
; .
|
||
|
||
|
||
;THIS BLOCK TYPE INSERTED IN EDIT 471
|
||
T.1044: SKIPE NOSYMS ;NO SYMBOLS REQUESTED?
|
||
PJRST T.1000 ;YES, DUMP THIS BLOCK
|
||
RELOCATE (NONE) ;NO RELOCATION INFO IN ALGOL SYMBOLS
|
||
T1044L: PUSHJ P,D.GET1 ;READ NEXT WORD OF DATA
|
||
JRST LOAD## ;END OF BLOCK
|
||
SKIPG AS.FR ;ENOUGH ROOM LEFT IN AS AREA?
|
||
JRST T1044G ;NO, GET SOME MORE
|
||
T1044P: MOVEM W1,@AS.PT ;PUT CURRENT DATUM IN PLACE
|
||
AOS AS.PT ;UPDATE FREE POINTER
|
||
SOS AS.FR ;AND FREE COUNT
|
||
AOS ASYM ;COUNT ONE MORE WORD OF ALGOL SYMBOLS
|
||
JRST T1044L ;LOOP OVER ENTIRE ALGOL SYMBOL BLOCK
|
||
|
||
;HERE TO GET MORE FREE SPACE IN THE AS AREA
|
||
T1044G: MOVEI P1,AS.IX ;POINT TO THE AS AREA FOR LNKCOR
|
||
SKIPN AS.LB ;HAS AREA BEEN SETUP?
|
||
JRST T1044I ;NO, GO INITIALIZE IT
|
||
MOVEI P2,1 ;EXPAND BY ONE BLOCK
|
||
PUSHJ P,LNKCOR## ;GET THE CORE
|
||
PUSHJ P,E$$MEF## ;CAN'T???
|
||
JRST T1044P ;NOW GO PUT THE SYMBOL INTO THE FILE
|
||
|
||
;HERE TO INITIALIZE THE AS AREA (FIRST TIME TYPE 1044 SEEN).
|
||
T1044I: PUSHJ P,XX.INI## ;CALL GENERAL INITIALIZER
|
||
AOS AS.PT ;RESERVE ROOM FOR COUNT WORD
|
||
SOS AS.FR ; BY DECREMENTING ALL COUNTS
|
||
AOS ASYM ; AS IF ONE WORD HAD BEEN USED
|
||
JRST T1044P ;NOW PUT AWAY THE DATA
|
||
> ;IFN .NWBLK
|
||
|
||
SUBTTL BLOCK TYPE 1045 - DECLARE WRITABLE OVERLAY LINKS
|
||
|
||
T.1045::
|
||
PUSHJ P,STDATA ;[1704] USE GENERAL ROUTINE
|
||
PUSH P,W2 ;[1704] SAVE THE BLOCK IOWD
|
||
MOVE T4,W2 ;[1707] PUT THE IOWD IN W1
|
||
MOVX T1,$OVWRITABLE ;[1704] WRITABLE OVERLAY IS INDICATED
|
||
SKIPE OVERLW ;[2031] DON'T SET UNLESS DOING OVERLAYS
|
||
IORM T1,OVERLW ;[1704] REMEMBER THIS
|
||
SKIPN WRTDAT ;[1704] HAS A TABLE BEEN SET UP?
|
||
JRST [ MOVEI T2,WR.LEN ;[1704] FETCH WORDS NEEDED
|
||
PUSH P,T4 ;[1745] SAVE POINTER
|
||
PUSHJ P,DY.GET## ;[1704] ...
|
||
POP P,T4 ;[1745] RESTORE POINTER
|
||
MOVEM T1,WRTDAT ;[1704]
|
||
JRST .+1 ] ;[1704]
|
||
MOVE T1,(T4) ;[1704] CHECK WRITABLE BIT OF BLOCK
|
||
TLNN T1,200000 ;[1704]
|
||
JRST T1045A ;[1704] CURRENT LINK NOT WRITABLE
|
||
HRLZI T1,400000 ;[1704] SET SIGN BIT IN WRTDAT
|
||
IORM T1,WRTDAT ;[1704] SO /LINK CAN DEAL WITH IT
|
||
T1045A: AOBJP T4,T1045X ;[1704] UNTIL NO MORE
|
||
MOVE W2,(T4) ;[1704] PICK UP FIRST NAME
|
||
TLNN W2,770000 ;[2377] IS IT A LONG NAME?
|
||
PUSHJ P,T1045L ;[2377] YES IT IS
|
||
MOVX W1,PT.SGN!PT.SYM!PS.GLB!PS.COM!PS.REL
|
||
;[1706] SET SOME LIKELY FLAGS
|
||
PUSHJ P,TRYSYM## ;[1706] SEE IF KNOWN COMMON NAME
|
||
JRST E$$UCB ;[1706] WHOLLY UNKNOWN
|
||
JRST E$$UCB ;[1706] UNDEFINED ( NOT COMMON )
|
||
MOVE T1,(P1) ;[1706] GET PRIMARY FLAGS
|
||
TXNN T1,PS.COM ;[1706] ALREADY COMMON?
|
||
JRST E$$SNC## ;[1706] NO, ERROR
|
||
;IN WHAT LINK DOES THIS COMMON RESIDE?
|
||
TXNE T1,PS.BGS ;[1706] FROM SOMEPLACE ELSE?
|
||
JRST T1045B ;[1706] YES! WHERE?
|
||
HRLZI T1,400000 ;[1706] SET SIGN BIT IN WRTDAT
|
||
IORM T1,WRTDAT ;[1706] SO /LINK CAN DEAL WITH IT
|
||
JRST T1045A ;[1706] AND LOOK AT THE NEXT ONE
|
||
T1045B: MOVS P1,LSTPTR ;[1706] WALK BACKWARDS THROUGH TREE
|
||
T1045C:
|
||
TRNN P1,-1 ;[2022] REACHED ROOT?
|
||
JRST T1045A ;[2022] YES, CHECK THE NEXT
|
||
HRRZ T1,(P1) ;[1706] GET LINK#
|
||
HRRZ P1,1(P1) ;[2022] AND NEXT PTR
|
||
PUSHJ P,WRTPTR ;[1712] SET IT WRITABLE
|
||
MOVX T2,OW.WRT ;[1706] ...
|
||
DPB T2,T1 ;[1706] ...
|
||
JRST T1045C ;[1706] DO IT AGAIN
|
||
T1045X: POP P,W2 ;[1704] THROW AWAY THE BLOCK
|
||
HLRZ T2,W2 ;[1704]
|
||
MOVN T2,T2 ;[1704]
|
||
HRRZ T1,W2 ;[1704]
|
||
PUSHJ P,DY.RET## ;[1704]
|
||
JRST LOAD## ;[1704] ALL DONE
|
||
|
||
T1045L: CAILE W2,<SYMSIZ+1> ;[2377] Less than max sym size?
|
||
PUSHJ P,E$$STL ;[2377] Too long - give error
|
||
CAIGE W2,2 ;[2377] Need at least one word of symbol
|
||
JRST E$$IRB ;[2377] No symbol - illegal rel block
|
||
CAIN W2,2 ;[2377] More than one word of symbol name?
|
||
JRST [ AOBJP T4,E$$IRB ;[2377] Bad REL block
|
||
MOVE W2,(T4) ;[2377] Move name to w2
|
||
POPJ P,]
|
||
PUSH P,T3
|
||
PUSH P,T2 ;[2377] Long name - save T2
|
||
HLRE T2,T4 ;[2377] Count for AOBJN pointer
|
||
ADD T2,W2 ;[2377] Add number of name words to count
|
||
PUSH P,T2 ;[2377] Save for the return
|
||
MOVNS W2 ;[2377] Negate it count
|
||
HRL T4,W2 ;[2377] Count for new AOBJN pointer
|
||
SETZ T2, ;[2377] Clear T2
|
||
t1045H: AOBJP T4,T1045E ;[2377] Bump the AOBJN pointer
|
||
MOVE T3,(T4) ;[2377] Get the next symbol name word
|
||
MOVEM T3,SYMBLK(T2) ;[2377] Move name to SYMBLK
|
||
AOS T2 ;[2377] Bump index
|
||
JRST T1045H ;[2377] Go get next word
|
||
T1045E: MOVEI T2,SYMBLK ;[2377] Address of SYMBLK
|
||
MOVMS W2 ;[2377] Make count positive
|
||
SOS W2 ;[2377] Minus one for count word
|
||
MOVSS W2 ;[2377] Into the left half
|
||
HRR W2,T2 ;[2377] W2 gets count,,address
|
||
POP P,T2 ;[2377] Restore count left in Rel block
|
||
HRL T4,T2 ;[2377] Count for AOBJP pointer for return
|
||
POP P,T2 ;[2377] Restore T2
|
||
POP P,T3 ;[2377] Restore T3
|
||
POPJ P, ;[2377] Return
|
||
|
||
E$$UCB::.ERR. (MS,.EC,V%L,L%W,S%W,UCB,<Unknown COMMON />) ;[2007]
|
||
.ETC. (SBX,.EC!.EP,,,,W2) ;[1706]
|
||
.ETC. (STR,,,,,,</ referenced >) ;[1706]
|
||
JRST T1045A ;[1706] TRY TO GET ANOTHER
|
||
|
||
;WRTPTR RETURNS A BYTE POINTER TO THE WRITABLE LINK FLAGS FOR A SPECIFIED LINK.
|
||
;THIS IS USED TO TEST AND SET THE WRITABLE STATUS OF A LINK. THE CALL IS:
|
||
;
|
||
; T1/ LINK NUMBER
|
||
;
|
||
;ON RETURN, T1 CONTAINS THE BYTE POINTER. T2 IS USED.
|
||
|
||
WRTPTR::
|
||
IDIVI T1,^D18 ;[1704] FLAGS ARE 2 BITS PER LINK
|
||
ADD T1,WRTDAT ;[2073] ADD BASE ADDRESS
|
||
HRLI T1,(POINT 2,0,35) ;[2073] ADD TEMPLATE BYTE POINTER
|
||
IMULI T2,-2 ;[1704] COMPUTE P FIELD OF BYTE POINTER
|
||
ADDI T2,^D36 ;[1704] ..
|
||
DPB T2,[POINT 6,T1,5] ;[1704] STORE IN P FIELD
|
||
POPJ P, ;[1704] DONE
|
||
|
||
|
||
|
||
SUBTTL BLOCK TYPE 1050 - PSECT NAME BLOCK
|
||
|
||
; --------------------- ---------------------
|
||
; ! 1050 ! COUNT ! ! 1050 ! COUNT !
|
||
; --------------------- ---------------------
|
||
; ! 0 ! INDEX ! ! 0 ! INDEX !
|
||
; --------------------- ---------------------
|
||
; ! SIXBIT PSECT NAME ! ! 0 ! MBZ ! COUNT !
|
||
; --------------------- ---------------------
|
||
; ! (ATTRIBUTES) ! ! SIXBIT PSECT NAME !
|
||
; --------------------- ---------------------
|
||
; ! (ORIGIN) ! ! ADDITIONAL NAME !
|
||
; --------------------- ---------------------
|
||
;
|
||
; .
|
||
;
|
||
; .
|
||
;
|
||
; ---------------------
|
||
; ! ADDITIONAL NAME !
|
||
; ---------------------
|
||
; ! (ATTRIBUTES) !
|
||
; ---------------------
|
||
; ! (ORIGIN) !
|
||
; ---------------------
|
||
|
||
|
||
;[2222] This block sets up W1-W3 and joins common code in the type 24
|
||
;[2222] block.
|
||
|
||
T.1050: SKIPLE MODTYP ;[2222] Twoseg seen in module?
|
||
PUSHJ P,E$$MPT## ;[2222] Yes, error
|
||
SETOM MODTYP ;[2222] Flag psects seen
|
||
PUSHJ P,D.GET1 ;[2222] Get the index
|
||
JRST LOAD## ;[2222] Empty block?
|
||
MOVEI P1,(W1) ;[2222] Save it in P1
|
||
PUSHJ P,SYM.IN ;[2222] Get the psect name
|
||
JRST [MOVEI T1,1050 ;[2222] No name?
|
||
JRST E$$RBS##] ;[2222] Bad rel block
|
||
PUSHJ P,D.GET1 ;[2222] Get the attributes
|
||
SETZ W1, ;[2222] No attributes
|
||
TXO W1,AT.PS ;[2222] Remember this psect seen in this module
|
||
MOVE W3,W1 ;[2222] Save attributes in W3
|
||
PUSHJ P,D.GET1 ;[2222] Get the origin
|
||
SETZ W1, ;[2222] No origin
|
||
JRST T.24B## ;[2222] Join common code
|
||
|
||
|
||
;[2222] Here to read a symbol from the rel file. Returns symbol
|
||
;[2222] in W2 if short, length,,pointer in W2 if long. Long symbols
|
||
;[2222] are placed in SYMBLK. Returns skip if successful, non-skip
|
||
;[2222] if rel block is too short.
|
||
|
||
SYM.IN: PUSHJ P,D.GET1 ;[2222] Get the name (first word)
|
||
POPJ P, ;[2222] No symbol!
|
||
MOVE W2,W1 ;[2222] Get the symbol
|
||
TLNE W2,770000 ;[2222] Long symbol?
|
||
JRST CPOPJ1 ;[2222] No, done
|
||
JUMPE W2,CPOPJ1 ;[2223] Done if zero
|
||
SYMIN1: CAIN W2,1 ;[2262] Short symbol in disguise?
|
||
JRST [PUSHJ P,D.GET1 ;[2223] Yes, get one word
|
||
POPJ P, ;[2223] No word means bad rel block
|
||
MOVE W2,W1 ;[2223] Put it in W2
|
||
JRST CPOPJ1] ;[2223] Return with a short symbol
|
||
PUSH P,W2 ;[2222] Save the count
|
||
MOVNS W2 ;[2222] Negate it
|
||
HRLZS W2 ;[2222] Put it in left half for AOBJN
|
||
SYMINL: PUSHJ P,D.GET1 ;[2222] Get a symbol word name
|
||
JRST [POP P,W2 ;[2222] No more, clear up the stack
|
||
POPJ P,] ;[2222] And return
|
||
MOVEM W1,SYMBLK(W2) ;[2222] Store the word
|
||
AOBJN W2,SYMINL ;[2222] Go back if more
|
||
POP P,W2 ;[2222] Get the count
|
||
HRLZS W2 ;[2222] Count in left half
|
||
HRRI W2,SYMBLK ;[2222] Address in right half
|
||
JRST CPOPJ1 ;[2222] Successful return
|
||
|
||
SUBTTL BLOCK TYPE 1051 - SET CURRENT PSECT
|
||
|
||
; ---------------------
|
||
; ! 1051 ! COUNT !
|
||
; ---------------------
|
||
; ! 0 ! INDEX !
|
||
; ---------------------
|
||
|
||
T.1051: PUSHJ P,D.GET1 ;[2222] Get the index
|
||
JRST LOAD## ;[2222] Empty block?
|
||
MOVEI R,(W1) ;[2222] Psect index in R
|
||
CAMLE R,RC.NO ;[2222] Psect index exist?
|
||
JRST E$$IPX ;[2222] No, give error
|
||
HRRZ R,@RC.MAP ;[2222] Get internal psect number
|
||
MOVEM R,RC.CUR ;[2222] Set as the current psect
|
||
JRST LOAD## ;[2222] Done
|
||
|
||
SUBTTL BLOCK TYPE 1052 - PSECT END BLOCK
|
||
|
||
; ---------------------
|
||
; ! 1052 ! COUNT !
|
||
; ---------------------
|
||
; ! 0 ! INDEX !
|
||
; ---------------------
|
||
; ! PSECT BREAK !
|
||
; ---------------------
|
||
;
|
||
; .
|
||
;
|
||
; .
|
||
;
|
||
; ---------------------
|
||
; ! 0 ! INDEX !
|
||
; ---------------------
|
||
; ! PSECT BREAK !
|
||
; ---------------------
|
||
|
||
T.1052: PUSHJ P,D.GET1 ;[2222] Get the index
|
||
JRST LOAD## ;[2222] No more?
|
||
MOVEI R,(W1) ;[2222] Psect index in R
|
||
CAMLE R,RC.NO ;[2222] Psect index exist?
|
||
JRST E$$IPX ;[2222] No, give error
|
||
HRRZ R,@RC.MAP ;[2222] Get internal psect number
|
||
PUSHJ P,D.GET1 ;[2222] Give me a break
|
||
JRST [MOVEI T1,1052 ;[2222] Rel block should not end here
|
||
JRST E$$RBS##] ;[2222] Give an error
|
||
PUSH P,RC.CUR ;[2222] Save the current psect
|
||
MOVEM R,RC.CUR ;[2222] Set as the current psect
|
||
MOVE P1,@RC.TB ;[2222] Get pointer to new psect
|
||
MOVE T1,W1 ;[2222] Put the break in T1
|
||
PUSHJ P,R.CUR## ;[2222] Relocate it
|
||
MOVE W1,T1 ;[2222] Get it back
|
||
POP P,RC.CUR ;[2222] Restore the current psect
|
||
PUSHJ P,CHKSZ0## ;[2222] Check for psect too big
|
||
CAMLE W1,RC.HL(P1) ;[2222] A new record for the break?
|
||
MOVEM W1,RC.HL(P1) ;[2222] Yes, set HL (CV fixed in T.5)
|
||
JRST T.1052 ;[2222] Go back for another
|
||
|
||
SUBTTL BLOCK TYPE 1060 - BINARY PATCH TRACE BLOCK (MAKLIB)
|
||
|
||
; -----------------
|
||
; ! 1060 ! COUNT !
|
||
; -----------------
|
||
; ! EDIT NAME !
|
||
; -----------------
|
||
; ! ACTIV ! LASTA !
|
||
; -----------------
|
||
; ! CREAT ! DATE !
|
||
; -----------------
|
||
; ! INSTL ! DATE !
|
||
; -----------------
|
||
; ! (RESERVED) !
|
||
; -----------------
|
||
; ! # ASC ! # PCO !
|
||
; ----------------- !
|
||
; ! ASC EDIT NAME ! ! MAY BE ZERO OR MORE OF
|
||
; ----------------- ! THESE ASSOC. EDIT BLOCKS
|
||
; ! B0 IF INCLUDE ! !
|
||
; ----------------- !
|
||
;
|
||
; . MAY BE ANY # AND COMBINATION OF BELOW
|
||
; -------------------------------------
|
||
; .
|
||
;
|
||
; (INSERT PCO) (REMOVE PCO) (RE-INSERT PCO)
|
||
;
|
||
; ----------------- ----------------- -----------------
|
||
; ! 1 ! COUNT ! ! 2 ! COUNT ! ! 3 ! COUNT !
|
||
; ----------------- ----------------- -----------------
|
||
; ! RELOC ! ADDR ! ! EDIT NAME ! ! EDIT NAME !
|
||
; ----------------- ----------------- -----------------
|
||
; ! ORG ! P ADR !
|
||
; -----------------
|
||
;
|
||
; .
|
||
;
|
||
; .
|
||
|
||
|
||
|
||
T.1060==T.1000 ;[1430] IGNORE BLOCK. SHOULD SOMEDAY GO INTO
|
||
; LS AREA FOR .MAP FILE.
|
||
|
||
SUBTTL BLOCK TYPE 1070 - LONG SYMBOL NAME
|
||
|
||
; ----------------- -----------------
|
||
; ! 1070 ! COUNT ! ! 1070 ! COUNT !
|
||
; ----------------- OR -----------------
|
||
; !CODE! N!R! 0 ! !CODE! N!R! 0 !
|
||
; ----------------- -----------------
|
||
; ! VALUE ! ! ( PSECTS ) !
|
||
; ----------------- -----------------
|
||
; ! NAME ! ! VALUE !
|
||
; ----------------- -----------------
|
||
; ! NAME !
|
||
; -----------------
|
||
; ! ( . . . ) !
|
||
; -----------------
|
||
; ! (ADD. VALUE ) !
|
||
; -----------------
|
||
; ! ( . . . ) !
|
||
; -----------------
|
||
|
||
IFN .NWBLK,<
|
||
;THIS BLOCK TYPE INSERTED IN EDIT 1000
|
||
T.1070: PUSHJ P,D.GET1 ;GET FLAG WORD
|
||
JRST LOAD## ;END OF BLOCK
|
||
MOVE P2,W1 ;SAVE ORIGINAL FLAG WORD IN P2
|
||
SETO R, ;ASSUME NO EXPLICIT PSECTS
|
||
TRZN W1,400000 ;IS THERE A PSECT-WORD?
|
||
JRST T1070A ;NO, JUMP
|
||
PUSHJ P,D.GET1 ;YES, GET IT
|
||
JRST LOAD## ;??
|
||
MOVE R,W1 ;R CONTAINS TEMPORARY PSECTS
|
||
T1070A: LDB RB,[POINT 3,P2,21] ;RB/ RELOC TYPE
|
||
PUSHJ P,REL.1 ;GET RELOCATED VALUE-- W1/FLAG, W3/VALUE
|
||
JRST LOAD## ;??
|
||
TXO W1,PT.SGN!PT.SYM ;FLAG IT SYMBOL
|
||
LDB W2,[POINT 7,P2,17] ;GET N--SYMBOL LENGTH
|
||
CAIL W2,<SYMSIZ-1> ;[2305] IS IT LONGER THAN MAX SYMBOL LENGTH?
|
||
PUSHJ P,E$$STL ;[2305] YES GIVE AN ERROR
|
||
JUMPG W2,[PUSHJ P,T1070E
|
||
JRST T1070B]
|
||
PUSH P,W1 ;SAVE FLAG
|
||
PUSHJ P,D.GET1 ;READ NAME (1 WORD)
|
||
JRST LOAD## ;??
|
||
MOVE W2,W1 ;MOVE TO RIGHT AC
|
||
POP P,W1 ;RECOVER FLAGS(PRIMARY SYMBOL FLAGS)
|
||
;THE ORIGINAL FLAG WORD STILL IN P2
|
||
T1070B:
|
||
.JDDT LNKNEW,T1070B,<<CAMN W2,$SYMBOL##>>
|
||
LDB T1,[POINT 7,P2,28] ;[2305] IS IT AN EXTENDED VALUE?
|
||
CAIL T1,<SYMSIZ-1> ;[2305] IS IT LONGER THAN MAX SYMBOL LENGTH?
|
||
PUSHJ P,E$$STL ;[2305] YES GIVE AN ERROR
|
||
SKIPE T1 ;[2305]
|
||
PUSHJ P,EXVAL ;[2305] YES SET UP COUNT,,PTR TO VALBLK
|
||
SETZ P1, ;P1 & P2 USED IN LSHC FOR DECODING
|
||
LSHC P1,3 ;GET FIRST DIGIT OF CODE
|
||
PUSHJ P,@T1070T(P1) ;DISPATCH
|
||
JRST T.1070 ;LOOP BACK FOR NEXT ENTRY
|
||
|
||
;FIRST DIGIT DISPATCH TABLE
|
||
T1070T: T.1070U ;0XX - NAME (NEVER SHOULD HAPPEN)
|
||
T1070L ;1XX - LOCAL
|
||
T1070G ;2XX - GLOBAL
|
||
SY.BH## ;3XX - BLOCK HEADER (FAIL)
|
||
REPEAT 4,<T1070U> ;4XX - 7XX UNDEFINED
|
||
|
||
;UNDEFINE CODE -- GIVE ERROR MSSG
|
||
T1070W: POP P,W1 ;RESTORE FLAG AND THEN ERROR
|
||
T1070U: JRST E$$URC## ;OUT WITH ERROR MESSAGE
|
||
|
||
;L - LOCAL SYMBOL
|
||
T1070L: TXO W1,PS.LCL ;DOING LOCAL DEFINITION
|
||
SETZ P1, ;SETUP FOR NEXT DIGIT
|
||
LSHC P1,3 ;OF 9-BIT CODE
|
||
XCT [JFCL ;10X
|
||
TXO W1,PS.DDT ;11X - SUPPRESSED TO DDT
|
||
TXO W1,PS.MPO ;12X - MAP ONLY
|
||
REPEAT 5,<JRST T1070U>](P1) ;13X - 17X NOT DEFINED
|
||
SETZ P1, ;SET UP TO GET 3RD DIGIT OF THE 9-BIT CODE
|
||
LSHC P1,3 ;
|
||
JRST SY.LS## ;FOR ALL 1XX CODE
|
||
|
||
;G - GLOBAL SYMBOL
|
||
T1070G: SETZ P1, ;P1 & P2 USED TO DECODE 9-BIT CODE
|
||
LSHC P1,3 ;GET 1ST DIGIT
|
||
XCT [JFCL ;20X
|
||
TXO W1,PS.DDT ;21X - SUPPRESSED TO DDT
|
||
TXO W1,PS.MPO ;22X - MAP ONLY
|
||
JRST T1070U ;23X - UNDEFINED
|
||
JRST T1070Q ;24X - GLOBAL REQUEST FOR CHIN FIXUP
|
||
JRST T1070Q ;25X - GLOBAL REQEST FOR ADDITIVE FIXUP
|
||
JRST T1070Q ;26X - GLOBAL REQUEST FOR SYMBOL FIXUP
|
||
JRST T1070U](P1) ;27X - UNDEFINED
|
||
SETZ P1, ;2ND DIGIT
|
||
LSHC P1,3 ;
|
||
JRST @[SY.GS## ;200,210,220 - GLOBAL DEFINITION (1WORD VALUE)
|
||
SY.GS## ;201,211,221 - (EXTENDED VALUE-NOT IMPLEMNETED)
|
||
EXVAL ;[2305] 202,212,222 - NOT DEFINED
|
||
SY.DGR## ;3 - RIGHT HALF DEFERRED
|
||
SY.DGL## ;4 - LEFT HALF DEFERRED
|
||
T1070D ;5 - BOTH HALVES DEFERRED
|
||
T1070D ;6 - 30BIT DEFERRED
|
||
T1070D](P1) ;7 - FULL WORD DEFERRED
|
||
T1070D: TXO W1,PS.UDF ;FULL WORD DEFERRED
|
||
JRST SY.DGR## ;
|
||
|
||
;[2305] Here if V is not zero - stores the value symbol in VALBLK and stores
|
||
;[2305] count,,valblk in w3
|
||
|
||
EXVAL: PUSH P,W1 ;[2305] save flags
|
||
MOVEM W3,VALBLK ;[2305] store the first word of extended value
|
||
MOVEI W3,VALBLK ;[2305] W3 get address of symbol name
|
||
AOS T1 ;[2305] add 1 to count of words (count in block
|
||
;[2305] is number of addtional words)
|
||
HRL W3,T1 ;[2305] W3 gets count,,valblk
|
||
SOS T1 ;[2305] sub 1 from count since one word
|
||
;[2305] has been stored
|
||
MOVNS T1 ;[2305] negative count for AOBJN
|
||
HRLZS T1 ;[2305] put it in the left half
|
||
AOS T1 ;[2305] add one to right half for word already
|
||
;[2305] done
|
||
EXVAL1: PUSHJ P,D.GET1 ;[2305] get next word of extended value symbol
|
||
jfcl
|
||
;**** ;jrst e$$isn ;[2305] should be more, something is rotten
|
||
MOVEM W1,VALBLK(T1) ;[2305] store the name word
|
||
AOBJN T1,EXVAL1 ;[2305] done? no go back for next word
|
||
POP P,W1 ;[2305] restore flags
|
||
POPJ P, ;[2305] return w3/ count,,valblk
|
||
|
||
|
||
;Q - GLOBAL REQUESTS (CODES 24X, 25X, 26X)
|
||
T1070Q: PUSH P,P1 ;STORE 2ND DIGIT
|
||
SETZ P1, ;SET UP FOR 3RD DIGIT
|
||
LSHC P1,3 ;
|
||
PUSH P,P1 ;STORE 3RD DIGIT ALSO
|
||
TXO W1,PS.REQ ;SET REQUEST FLAG
|
||
PUSHJ P,TRYSYM## ;LOCATE THE GLOBAL SYMBOL
|
||
JRST T1070I ;NOT FOUND, GO PUT IN
|
||
JRST T1070J ;FOUND BUT UNDEFINED, MUST WAIT
|
||
JUMPE W3,[ POP P,0(P) ;RESTORE STACK AND RETURN
|
||
POP P,0(P) ;FOR A FAKE REQUEST
|
||
POPJ P,] ;
|
||
IOR W1,0(P1) ;GET FLAGS
|
||
TXNN W1,PS.REL ;RELOCATABLE?
|
||
TDZA W1,W1 ;NO, CLEAR FLAGS
|
||
MOVX W1,FS.REL
|
||
MOVEM W1,SYMFLG ;SAVE IT FOR SYMBOL TABLE FIXUP
|
||
POP P,T3 ;RESTORE 3RD DIGIT
|
||
POP P,T1 ;RESTORE 2ND DIGIT
|
||
XCT T1070S(T3) ;[2246] set the bits for type of fixup
|
||
CAIN T1,4 ;CHAINED FIXUP?
|
||
JRST X70CH ;[2246] check what type of chained fixup
|
||
CAIE T1,6 ;SKIPE IF SYMBOL FIXUP
|
||
PJRST SY.AD0## ;JUMP IF ADDITIVE
|
||
MOVE W2,W3 ;[1002] EXPECT DEFINING SYMBOL IN W3 & REQUEST IN W2
|
||
PJRST SY.AS## ;GO DO SYMBOL TABLE FIXUP
|
||
|
||
X70CH: MOVE T2,W3 ;
|
||
MOVE W3,2(P1)
|
||
TXNE W1,FS.FXR ;[2246] right half chained fixup?
|
||
JRST SY.CHR## ;[2246] yes
|
||
TXNE W1,FS.FXL ;[2246] left half chained fixup?
|
||
JRST SY.CHL## ;[2246] yes
|
||
TXNE W1,FS.FXE ;[2246] thirty bit chained fixup?
|
||
JRST SY.CHE## ;[2246] yes
|
||
JRST SY.CHF## ;[2246] full word is all that's left
|
||
|
||
|
||
T1070S: JRST T1070X ;2X0 - NOT A REAL FIXUP, RESTORE W1 AND RETURN
|
||
JRST T1070W ;2X1 - NOT DEFINED
|
||
JRST T1070W ;2X2 - NOT DEFINED
|
||
TXO W1,FS.FXR ;2X3 - RIGHT HALF FIXUP
|
||
TXO W1,FS.FXL ;2X4 - LEFT HALF FIXUP
|
||
JRST T1070W ;2X5 - NOT DEFINED
|
||
TXO W1,FS.FXE ;2X6 - EXTENDED(30-BIT) FIXUP
|
||
TXO W1,FS.FXF ;2X7 - FULL WORD FIXUP
|
||
T1070X: POP P,W1 ;RESTORE W1, THEN RETURN
|
||
POPJ P,
|
||
|
||
;GLOBAL SYMBOL NOT IN TABLE
|
||
T1070I: POP P,T3 ;GET BACK 3RD DIGIT
|
||
POP P,T2 ;GET 2ND DIGIT
|
||
AOS USYM ;COUNT ONE MORE UNDEFINED
|
||
CAIN T2,4 ;CHAINED FIXUP
|
||
JRST X70CHF ;[2305] Yes go handle chained request
|
||
JUMPE T3,INSRT## ;NOT A REAL FIXUP
|
||
TXO W1,PS.FXP!PT.EXT ;SET FIXUP FLAG
|
||
PUSH P,W1 ;FLAGS ON STACK
|
||
MOVX W1,FP.SGN!FP.SYM!FP.PTR ;THESE ARE FOR THE FX BLOCK
|
||
XCT T1070S(T3) ;MORE FLAGS
|
||
CAIE T2,6 ;SKIPE IF SYMBOL FIXUP
|
||
JRST T1070Y ;JUMP IF ADDITIVE FIXUP
|
||
TXO W1,FS.FXS ;FLAG SYMBOL FIXUP
|
||
PUSHJ P,SY.QS## ;
|
||
JRST [SOS USYM ;NON LOADED LOCAL
|
||
POP P,W1 ;
|
||
POPJ P,]
|
||
T1070Y: TXNN W1,PS.EXO ;A LONG SYMBOL NAME?
|
||
JRST SY.RQ2## ;NO, JUMP
|
||
MOVE P1,LSTGBL ;[2255] GET GS POINTER INTO P1
|
||
ADD P1,GS.LB ;MAKE IT ABS
|
||
PUSHJ P,INSRT## ;GO INSRT THE SYMBOL FIRST
|
||
MOVE W3,2(P1) ;REQUEST ADDR IN W3
|
||
MOVE T1,LSTGBL ;[2255] GET THE GLOBAL POINTER
|
||
MOVE W3,LSTLCL ;[2255] AND THE LOCAL POINTER
|
||
PUSHJ P,SY.RA## ;GO EXTEND THE ENTRY
|
||
MOVE W3,P1 ;GET POINTER TO GS
|
||
SUB W3,GS.LB ;MAKE IT RELATIVE, NEEDED FOR INSRTL
|
||
POPJ P, ;RETURN
|
||
|
||
X70CHF: CAIN T3,3 ;[2305] is it a right half chained request
|
||
JRST INSRT## ;[2305] yes - so just put it in
|
||
PUSH P,W1 ;[2305] save the primary flags
|
||
MOVX W1,FP.SGN!FP.SYM!FP.PTR ;[2305]
|
||
TXO W1,FS.FXC ;[2305] indicate we have a chained request
|
||
XCT T1070S(T3) ;[2305] set bit for type chained fixup request
|
||
JRST SY.RQ2 ;[2305] say a prayer and off you go.
|
||
|
||
;GLOBAL SYMBOL FOUND IN TABLE BUT UNDEFINED
|
||
T1070J: POP P,T3 ;GET 3RD DIGIT
|
||
POP P,T2 ;GET 2ND DIGIT
|
||
JUMPE W3,CPOPJ ;DUMMY REQUEST
|
||
CAIN T2,4 ;CHAINED REQUEST
|
||
JRST [IORM W1,0(P1)
|
||
JRST SY.RU3##] ;YES, JUMP
|
||
MOVE W1,0(P1)
|
||
TXOE W1,PS.FXP ;ALREADY DEFERED FIXUPS?
|
||
JRST T1070K ;YES,
|
||
PUSH P,W1 ;NO, SAVE PRIMARY FLAGS
|
||
MOVX W1,FP.SGN!FP.SYM!FP.PTR ;[2333] SET SOME FLAGS FOR FX BLOCK
|
||
XCT T1070S(T3) ;SET FLAGS FOR FX BLOCK
|
||
MOVE T1,W2 ;[2255] NAME SHOULD BE IN T1 IF NOT SYMBOL
|
||
CAIE T2,6 ;SKIP IF SYMBOL FIXUP
|
||
JRST SY.RA## ;JUMP IF ADDITIVE FIXUP
|
||
EXCH W2,W3 ;[2305] GET READY FOR CALL TO SY.QS
|
||
TXO W1,FS.FXS ;FLAG SYMBOL FIXUP
|
||
PUSHJ P,SY.QS##
|
||
JRST T1070X
|
||
PUSHJ P,TRYSYM ;[2305]
|
||
JRST TX70RD ;[2305]
|
||
JRST TX70PD ;[2305]
|
||
JRST TX70TD ;[2305]
|
||
TX70RD: AOS USYM ;[2305]
|
||
JRST SY.RQ2## ;[2305]
|
||
TX70PD: EXCH W2,W3 ;[2305]
|
||
MOVE T1,LSTGBL ;[2255] GET THE GLOBAL POINTER
|
||
MOVE W3,LSTLCL ;[2255] AND THE LOCAL POINTER
|
||
JRST SY.RA##
|
||
TX70TD: JRST SY.RC0## ;[2305]
|
||
|
||
T1070K: MOVEI T1,0(P1)
|
||
ADDI T1,.L
|
||
SKIPG W1,0(T1)
|
||
JRST SY.RUH##
|
||
TXNN W1,S.FXP
|
||
JRST T1070K+1
|
||
MOVE P1,T1
|
||
MOVX W1,FP.SGN!FP.SYM!FP.PTR ;[2333] SET SOME FLAGS FOR FX BLOCK
|
||
XCT T1070S(T3)
|
||
CAIE T2,6 ;SKIP IF SYMBOL FIXUP
|
||
JRST T1070F ;JUMP IF ADDITIVE
|
||
TXO W1,FS.FXS ;FLAG SYMBOL FIXUP
|
||
PUSHJ P,SY.QS##
|
||
POPJ P,
|
||
T1070F: HRR W1,2(P1)
|
||
SUB P1,NAMLOC
|
||
PUSHJ P,SY.FX0##
|
||
ADD P1,NAMLOC
|
||
HRRM W3,2(P1)
|
||
POPJ P,
|
||
|
||
|
||
;E - EXTENDED SYMBOL NAME
|
||
T1070E: MOVEI T1,0(W2) ;N (NAME LENGTH ) IN W2
|
||
PUSH P,W1 ;SAVE FLAGS
|
||
PUSHJ P,D.GET1 ;GET 1ST WORD OF NAME
|
||
JRST LOAD## ;
|
||
PUSH P,W1 ;SAVE 1ST WORDS OF NAME
|
||
PUSHJ P,D.GET1 ;GET 2ND WORD OF NAME
|
||
JRST LOAD## ;
|
||
JUMPN W1,LNGNM ;WE DO HAVE A LONG NAME, JUMP
|
||
POP P,W2 ;ONLY A SHORT NAME , INTO W2
|
||
SOJLE T1,.+4 ;FINISHED?
|
||
PUSHJ P,D.GET1 ;NO, MORE NULLS PADDED
|
||
JRST LOAD## ;
|
||
JRST .-3 ;SKIPE OVER THEM
|
||
POP P,W1 ;RECOVER FLAGS
|
||
POPJ P, ;AND RETURN
|
||
|
||
|
||
|
||
;HERE IF WE REALLY HAVE A LONG NAME
|
||
; 0(P)/ 1ST WORD OF NAME
|
||
; -1(P)/ FLAGS
|
||
;[2305] stores the symbol name in SYMBLK
|
||
;[2305] stores count,,symblk in W2
|
||
|
||
LNGNM: POP P,W2 ;1ST WORD OF NAME
|
||
EXCH W1,0(P) ;FLAGS INTO W1, AND 2ND WORD OF NAME ON STACK
|
||
ADDI T1,1 ;[2305] number of words of symbol name
|
||
MOVEM W2,SYMBLK ;[2305] store the first word
|
||
HRLZ W2,T1 ;[2305] into the left half of w2
|
||
HRRI W2,SYMBLK ;[2305] address of symbol to w2
|
||
MOVEI T1,1 ;[2305] set up index to symblk
|
||
POP P,T2 ;[2305] get the second word
|
||
MOVEM T2,SYMBLK(T1) ;[2305] store it away
|
||
AOS T1
|
||
HLRZ T2,W2 ;[2305] get the count to t2
|
||
SUBI T2,2 ;[2305] minus the words already done
|
||
SKIPN T2 ;[2371] if only 2 words then
|
||
POPJ P, ;[2371] done so return
|
||
MOVNS T2 ;[2305] -count
|
||
HRLS T2
|
||
HRR T2,T1 ;[2305] AOBJN pointer
|
||
PUSH P,W1 ;[2305] save the flags
|
||
T1070M: PUSHJ P,D.GET1 ;[2305] get the next name word
|
||
JRST LOAD
|
||
MOVEM W1,SYMBLK(T2) ;[2305] store the next word
|
||
AOBJN T2,T1070M
|
||
POP P,W1 ;[2305] restore the flags
|
||
POPJ P,
|
||
|
||
SUBTTL BLOCK TYPE 1072 - POLISH FIXUPS (SUPPORT LONG SYMBOLS)
|
||
|
||
; ----------------
|
||
; ! 1072! COUNT !
|
||
; ----------------
|
||
; ! BYTE ! BYTE !
|
||
; ----------------
|
||
|
||
;THE POLISH FIXUP BLOCK IS STORED IN THE FX AREA
|
||
;THE ACTION IS :-
|
||
;(1) READ AND RELOCATE THE FIXUPS
|
||
; STORE THEM IN FX AREA
|
||
;(1A) FIND THE STORE OPERATOR, AND DELETE THE FIXUP IF
|
||
; NOT WANTED (DUE TO NON-LOADED LOCAL OR /ONLY).
|
||
;(2) CHECK AND EVALUATE GLOBAL REQUESTS
|
||
; STORE VALUES BACK IN FIXUP
|
||
;(3) IF THERE ARE NO UNDEFINED GLOBAL REQUESTS
|
||
; EVALUATE POLISH AND STORE
|
||
;(4) IF THERE ARE UNDEFINED REQUESTS
|
||
; LINK GLOBAL SYMBOL TO FIXUP AREA AND CONTINUE
|
||
;(5) WHEN LAST UNDEFINED GLOBAL IS DEFINED
|
||
; EVALUATE AND STORE
|
||
;(6) IF STORE ADDRESS IS PAGED TO DSK
|
||
; STORE BACK IN FIXUP AREA AND PROCESS AT END
|
||
|
||
;HERE TO READ BLOCK AND STORE IN FX AREA
|
||
T.1072: HRRZI T2,2(W1) ;WORD COUNT
|
||
HRLZM T2,T11FA ;STORE BLOCK SIZE
|
||
PUSHJ P,FX.GET## ;GET SPACE IN FX AREA
|
||
SUB T1,FX.LB ;RELATIVE
|
||
.JDDT LNKNEW,T.1072,<<CAMN T1,$FIXUP##>>
|
||
MOVE W2,T1 ;SAFE PLACE FOR POINTER
|
||
HRRM T1,T11FA ;STORE STARTING ADDRESS
|
||
MOVEI W3,2(W2) ;BYTE POINTER TO START OF FIXUP
|
||
HRLI W3,(POINT 18)
|
||
MOVEM W3,T11BP ;STORE INITIAL BYTE POINTER
|
||
SUBI W3,1 ;W3 ALSO POINTS TO GLOBAL COUNT
|
||
HRLI W1,(FP.SGN!FP.POL!FF.NEW) ;[2212] SET POLISH FIXUP BITS
|
||
ADDI W1,2 ;ACCOUNT FOR OVERHEAD WORDS
|
||
ADD W2,FX.LB ;FIX IN CORE
|
||
ADD W3,FX.LB ;...
|
||
MOVEM W1,(W2) ;STORE HEADER WORD PLUS SYMBOLS
|
||
SETZM 1(W2) ;CLEAR GLOBAL COUNT
|
||
ADDI W2,2 ;BYPASS
|
||
|
||
;Now read in 2 half words at a time from buffer
|
||
;Check to see if a half word is one of the following:
|
||
; 1. Psect index
|
||
; 2. Operator code
|
||
; 3. Store operator code
|
||
; 4. Data operator code
|
||
;[2212] The primary purpose here is to do the relocation calculation for
|
||
;[2212] a relocatable data when one is encountered, and to change the
|
||
;[2212] halfword relocatable operator and the store operators to a
|
||
;[2212] different format which allows section numbers to be preserved.
|
||
|
||
MOVE P2,T11BP ;[2212] Byte pointer which will find store op
|
||
SETZ P3, ;[2212] Start by reading the first halfword
|
||
PUSHJ P,X72GN ;[2212] Get the first halfword
|
||
JRST LOAD## ;[2212] Completely empty block
|
||
PUSH P,RC.CUR ;[2212] Save current psect
|
||
JRST X72RD2 ;[2212] Join the main loop
|
||
|
||
X72RDF: PUSHJ P,X72SGN ;[2212] Eat a fullword as two halfwords
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
X72RDH: PUSHJ P,X72SGN ;[2212] Eat a halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
|
||
;[2212] Read and decode the next operator
|
||
X72RD: PUSHJ P,X72SGN ;[2212] Get next halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
|
||
;[2212] Check for a psect index
|
||
X72RD2: CAIL T1,PL.IL ;[2212] Psect index?
|
||
JRST X72PSI ;[2212] Yes
|
||
|
||
;[2212] Check for a data operator
|
||
JUMPE T1,X72RDH ;[2212] If absolute halfword, ignore next half
|
||
CAIN T1,PL.ABF ;[2212] Absolute Fullword?
|
||
JRST X72RDF ;[2212] Yes, Ignore two halfwords
|
||
CAIN T1,PL.RLH ;[2212] Relocatable halfword?
|
||
JRST X72RRH ;[2212] Yes, relocate next halfword
|
||
CAIN T1,PL.RLF ;[2212] Relocatable fullword?
|
||
JRST X72RRF ;[2212] Yes, relocate the next fullword
|
||
|
||
;[2212] Check for an operator
|
||
CAIL T1,PL.OL ;[2212] Too low for operator?
|
||
CAILE T1,PL.OH ;[2212] Or too high?
|
||
CAIA ;[2212] Not an operator
|
||
JRST X72RD ;[2212] An operator, ignore it
|
||
|
||
;[2212] Check for a store operator or symbol operator
|
||
MOVE T2,T1 ;[2212] Get the code
|
||
TRZ T2,LENGTH ;[2212] Ignore the count
|
||
CAIL T2,PL.SL ;[2212] Store operator?
|
||
JRST X72SOP ;[2212] Yes
|
||
CAIN T2,PL.SYM ;[2212] Symbol operator?
|
||
JRST X72RDS ;[2212] Yes, skip a bunch of halfwords
|
||
PUSHJ P,X72IPO ;[2212] Not a valid operator
|
||
|
||
;[2212] Here to handle a psect index
|
||
X72PSI: MOVEI R,-400000(T1) ;[2212] Get the psect index
|
||
CAMLE R,RC.NO ;[2212] In bounds?
|
||
PUSHJ P,E$$IPX ;[2212] No, die
|
||
HRRZ R,@RC.MAP ;[2212] Get the internal psect index
|
||
MOVEM R,RC.CUR ;[2212] Set the current index
|
||
JRST X72RD ;[2212] Read more operators
|
||
|
||
;[2212] Here to relocate a fullword
|
||
X72RRF: PUSHJ P,X72SGN ;[2212] Get next halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
MOVE W3,T1 ;[2212] Keep this halfword
|
||
PUSHJ P,X72SGN ;[2212] Get next halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
HRL T1,W3 ;[2212] Get back the left half
|
||
PUSHJ P,R.CUR## ;[2212] Relocate it
|
||
JRST X72BAK ;[2212] Put back the whole word
|
||
|
||
;[2212] Here to relocate a halfword. This requires replacing the operator,
|
||
;[2212] since part of the operator field must be used to remember the section
|
||
;[2212] number.
|
||
X72RRH: PUSHJ P,X72SGN ;[2212] Get next halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
PUSHJ P,R.CUR## ;[2212] Relocate it
|
||
TLO T1,PL.NEW ;[2212] Set new halfword operator bits
|
||
|
||
;Here to put back a fullword in the polish string
|
||
X72BAK: JUMPE P3,X72BA1 ;[2212] Was last a right half?
|
||
HLRM T1,-1(W2) ;[2212] No, left half is in the previous word
|
||
HRL W1,T1 ;[2212] Right half is in left half of this one
|
||
JRST X72RD ;[2212] Continue reading the polish string
|
||
X72BA1: MOVE W1,T1 ;[2212] Just replace the entire word
|
||
JRST X72RD ;[2212] It will be stored soon
|
||
|
||
;[2212] Here to read a symbol
|
||
X72RDS: LSH T1,-^D9 ;[2212] Get the length
|
||
JUMPE T1,X72R50 ;[2212] Check for radix-50 special case
|
||
CAILE T1,MAXSYM/3-1 ;[2212] Make sure symbol not too big
|
||
PUSHJ P,E$$STL ;[2212] Can't handle it
|
||
MOVEI W3,1(T1) ;[2212] Count of halfwords to read
|
||
X72RS1: PUSHJ P,X72SGN ;[2212] Get next halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
SOJG W3,X72RS1 ;[2212] Ignore all of them
|
||
JRST X72RD ;[2212] Go back for next operator
|
||
X72R50: PUSHJ P,X72SGN ;[2212] Get next halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
MOVE W3,T1 ;[2212] Keep this half around
|
||
PUSHJ P,X72SGN ;[2212] Get next halfword
|
||
PUSHJ P,E$$NSO## ;[2212] Should not fall off end of block
|
||
PUSH P,W2 ;[2212] Keep the pointer safe
|
||
MOVE W2,T1 ;[2212] get the right half
|
||
HRL W2,W3 ;[2212] And the left half
|
||
PUSHJ P,R50T6## ;[2212] Convert it to sixbit
|
||
MOVE T1,W2 ;[2212] Put it where it belongs
|
||
POP P,W2 ;[2212] Get back the pointer
|
||
JRST X72BAK ;[2212] Put the word back in the block
|
||
|
||
;[2212] Here to get a polish halfword and store the previous one. This
|
||
;[2212] routine de-blocks the full words supplied by D.GET1 into halfwords.
|
||
;[2212] P3 / 0 to read left half, 1 to read right half
|
||
;[2212] P2 / Byte pointer for store op
|
||
;[2212] W2 / Byte pointer for store
|
||
;[2212] W1 / Full word read (returned)
|
||
;[2212] T1 / Next halfword (returned)
|
||
|
||
;[2212] This routine parallels the T11SGN routine in LNKOLD.
|
||
|
||
X72SGN: JUMPN P3,X72GN1 ;[2212] JUST PROCESSED RHS?
|
||
MOVEM W1,(W2) ;[2212] YES--STORE OLD WORD NOW
|
||
ADDI W2,1 ;[2212] COUNT ANOTHER WORD STORED
|
||
X72GN: JUMPN P3,X72GN1 ;[2212] TIME TO READ A NEW WORD?
|
||
PUSHJ P,D.GET1 ;[2212] YES--GET ONE
|
||
POPJ P, ;[2212] NO MORE--GIVE NON-SKIP RETURN
|
||
HLRZ T1,W1 ;[2212] FIRST TIME GIVE LHS
|
||
MOVEI P3,1 ;[2212] SIGNAL RHS FOR NEXT TIME
|
||
IBP P2 ;[2212] COUNT ANOTHER BYTE
|
||
JRST CPOPJ1 ;[2212] GIVE GOOD RETURN
|
||
|
||
X72GN1: HRRZ T1,W1 ;[2212] TIME FOR RHS
|
||
MOVEI P3,0 ;[2212] SIGNAL LHS FOR NEXT TIME
|
||
IBP P2 ;[2212] COUNT ANOTHER BYTE
|
||
JRST CPOPJ1 ;[2212] GIVE GOOD RETURN
|
||
|
||
|
||
;[2212] Here on store.
|
||
X72SOP: MOVEM W1,(W2) ;[2212] Make sure the last halfword is stored
|
||
ADD P2,FX.LB ;[2212] Relocate the store operator pointer
|
||
TRNE T1,S.ADR ;[2212] An address?
|
||
JRST X72SAD ;[2212] Yes, go handle it
|
||
|
||
;[2212] Here to test for a symbol and to determine if it is needed
|
||
PUSH P,T1 ;[2212] Save the store operator
|
||
MOVE T2,T1 ;[2212] Get a copy of the store operator
|
||
TRZ T2,777770 ;[2212] Clear all but last digit
|
||
PUSH P,[FS.FXF ;[2212] 754 Save bit for this fixup type
|
||
FS.FXE ;[2212] 755
|
||
FS.FXL ;[2212] 756
|
||
FS.FXR]-4(T2) ;[2212] 757
|
||
LSH T1,-^D9 ;[2212] Get the length
|
||
JUMPE T1,X72S50 ;[2212] Special if Radix 50
|
||
CAIN T1,1 ;[2212] Short symbol?
|
||
JRST X72SSM ;[2212] Yes, handle differently
|
||
|
||
;[2212] Here for long symbol. Copy it into SYMBLK.
|
||
CAILE T1,MAXSYM/3-1 ;[2212] Make sure symbol not too big
|
||
PUSHJ P,E$$STL ;[2212] Can't handle it
|
||
MOVE W3,T1 ;[2212] Keep the count in a better place
|
||
PUSH P,T1 ;[2212] And save it for SY.RQS call
|
||
MOVE P1,[POINT 18,SYMBLK] ;[2212] Get a pointer to a static area
|
||
X72SOL: PUSHJ P,X72BYT ;[2212] Get the next three characters
|
||
PUSHJ P,E$$ISM## ;[2212] Not complete?
|
||
IDPB T1,P1 ;[2212] Store the characters
|
||
SOJGE W3,X72SOL ;[2212] Keep going until all done
|
||
POP P,W3 ;[2212] Get the count back
|
||
ADDI W3,1 ;[2212] Make it a true count
|
||
TRNN W3,1 ;[2212] Is it odd?
|
||
JRST X72SEV ;[2212] No, even
|
||
SETZ T1, ;[2212] Yes,
|
||
IDPB T1,P1 ;[2212] Zero the extra halfword
|
||
ADDI W3,1 ;[2212] Account for it
|
||
X72SEV: LSH W3,-1 ;[2212] Convert to words
|
||
HRLZ W3,W3 ;[2212] Put count in left half
|
||
HRRI W3,SYMBLK ;[2212] Count,,Pointer
|
||
JRST X72SYM ;[2212] Go see if needed
|
||
|
||
;[2212] Here for radix-50 symbols. Replace with SIXBIT, treat as short symbol.
|
||
X72S50: PUSHJ P,X72BYT ;[2212] Get the next halfword
|
||
PUSHJ P,E$$ISM ;[2212] Not complete?
|
||
HRL W2,T1 ;[2212] Hold onto it
|
||
PUSHJ P,X72BYT ;[2212] Get one more
|
||
PUSHJ P,E$$ISM ;[2212] Not complete?
|
||
HRR W2,T1 ;[2212] Get the rest of the symbol
|
||
PUSHJ P,R50T6## ;[2212] Convert to SIXBIT
|
||
MOVE W3,W2 ;[2212] Get the symbol in the correct AC
|
||
JRST X72SYM ;[2212] Go see if needed
|
||
|
||
;[2212] Here for short symbol. Build it in W3.
|
||
X72SSM: PUSHJ P,X72BYT ;[2212] Get the next halfword
|
||
PUSHJ P,E$$ISM## ;[2212] Not complete?
|
||
HRL W3,T1 ;[2212] Hold onto it
|
||
PUSHJ P,X72BYT ;[2212] Get one more
|
||
PUSHJ P,E$$ISM ;[2212] Not complete?
|
||
HRR W3,T1 ;[2212] Get the rest of the symbol
|
||
; JRST X72SYM ;[2212] See if needed
|
||
|
||
;[2255] Here for a symbol. See if it is needed, and if so replace
|
||
;[2255] the symbol name and old store operator with the new store
|
||
;[2255] operator and the section number of the symbol in the LS area,
|
||
;[2255] followed by the rest of the LS pointer for the symbol, followed
|
||
;[2255] by the GS pointer to the symbol.
|
||
X72SYM: POP P,W1 ;[2212] Restore the bits
|
||
PUSHJ P,SY.QS## ;[2212] See if we want this symbol
|
||
JRST [POP P,0(P) ;[2212] Non-loaded local, clean up stack
|
||
PUSHJ P,T.11RT## ;[2212] Return block
|
||
JRST LOAD##] ;[2212] And exit
|
||
POP P,T1 ;[2212] Restore the op code
|
||
TRZ T1,^-7 ;[2212] Get the last digit
|
||
ADDI T1,PL.NSS ;[2212] Add the base for new fullword operator
|
||
LSH T1,^D12 ;[2212] Put it in the high order bits
|
||
HLRZ T2,LSTLCL ;[2255] Get the local symbols section number
|
||
ADD T1,T2 ;[2255] Put it in the opcode word
|
||
DPB T1,P2 ;[2212] Store the new store op code
|
||
HRRZ T2,LSTLCL ;[2212] Get the right half of the LS pointer
|
||
IDPB T2,P2 ;[2212] Store it
|
||
MOVE T2,LSTGBL ;[2255] Get the Global symbols pointer
|
||
IDPB T2,P2 ;[2212] Store it
|
||
;[2212] If this block is to be extended to handle FAIL block names
|
||
;[2212] code should be added here.
|
||
;[2212] It should read the symbol and store it into the block using P2
|
||
;[2212] so that it can be recognized correctly. This may make the
|
||
;[2212] block shorter but that should not matter.
|
||
JRST X72GC ;[2212] Check for undefined symbols
|
||
|
||
|
||
;[2212] Set up address for memory fixup
|
||
X72SAD: MOVE P1,T1 ;[2212] Save the store operator
|
||
TRNN T1,LENGTH ;[2212] Non-zero length?
|
||
JRST X72SAH ;[2212] No, it's a halfword store
|
||
|
||
;[2212] Here to handle fullword (possibly relocatable)
|
||
PUSHJ P,X72BYT ;[2212] Get a halfword
|
||
PUSHJ P,E$$NAP## ;[2212] Not complete?
|
||
MOVE W3,T1 ;[2212] Hold on to it
|
||
PUSHJ P,X72BYT ;[2212] Get another halfword
|
||
PUSHJ P,E$$NAP ;[2212] Not complete?
|
||
HRL T1,W3 ;[2212] Put fullword in T1
|
||
TRNE P1,S.REL ;[2212] Is this relocatable?
|
||
PUSHJ P,R.CUR ;[2212] Yes, relocate it
|
||
TRZ P1,^-7 ;[2212] Get the last digit
|
||
ADDI P1,PL.NSF ;[2212] Add the base for new fullword operator
|
||
LSH P1,^D12 ;[2212] Put it in the high order bits
|
||
DPB P1,P2 ;[2212] Store the new operator
|
||
HLRZ T2,T1 ;[2212] Get left half (section number)
|
||
IDPB T2,P2 ;[2212] Store it
|
||
IDPB T1,P2 ;[2212] Store right half (address)
|
||
JRST X72GC ;[2212] Check for undefined symbols
|
||
|
||
;[2212] Here to handle halfword (possibly relocatable)
|
||
X72SAH: PUSHJ P,X72BYT ;[2212] Get a halfword
|
||
PUSHJ P,E$$NAP ;[2212] Not complete?
|
||
TRNE P1,S.REL ;[2212] Is this relocatable?
|
||
PUSHJ P,R.CUR ;[2212] Yes, relocate it
|
||
TRZ P1,^-7 ;[2212] Get the last digit
|
||
ADDI P1,PL.NSH ;[2212] Add the base for new fullword operator
|
||
LSH P1,^D12 ;[2212] Put it in the high order bits
|
||
HLRZ T2,T1 ;[2212] Get left half (section)
|
||
ADD T2,P1 ;[2212] Add in the opcode
|
||
DPB T2,P2 ;[2212] Store it
|
||
IDPB T1,P2 ;[2212] Store right half (address)
|
||
JRST X72GC ;[2212] Check for undefined symbols
|
||
|
||
|
||
;[2212] Here to read a byte into T1. Similar to X72SGN except that
|
||
;[2212] the word is not stored and the byte pointers are not updated.
|
||
X72BYT: JUMPN P3,X72BT1 ;[2212] Just processed RHS?
|
||
PUSHJ P,D.GET1 ;[2212] Yes--get one
|
||
POPJ P, ;[2212] No more--Give non-skip return
|
||
HLRZ T1,W1 ;[2212] First time give LHS
|
||
MOVEI P3,1 ;[2212] Signal RHS for next time
|
||
JRST CPOPJ1 ;[2212] Give good return
|
||
|
||
X72BT1: HRRZ T1,W1 ;[2212] Time for RHS
|
||
MOVEI P3,0 ;[2212] Signal LHS for next time
|
||
JRST CPOPJ1 ;[2212] Give good return
|
||
|
||
;[2212] Here to count and evaluate global requests. This routine uses
|
||
;[2212] P1 and P2 as temporaries, and assumes that they are the accumulators
|
||
;[2212] after T4, since the extend instructions require 6 contiguous ACs.
|
||
|
||
X72GC: POP P,RC.CUR ;[2212] Restore the psect index
|
||
MOVE W1,T11BP ;[2212] Reset byte pointer
|
||
ADD W1,FX.LB ;[2212] Fix in core
|
||
JRST X72G1 ;[2212] Bypass first time
|
||
|
||
X72G0: IBP W1 ;[2212] Bypass next half word
|
||
X72G1: ILDB T1,W1 ;[2212] Read half word
|
||
CAIL T1,PL.NSO ;[2212] Store operator (new style)
|
||
JRST X72GE ;[2212] Yes
|
||
CAIL T1,PL.NEW ;[2212] Halfword data operator?
|
||
JRST X72G0 ;[2212] Yes, eat the next halfword
|
||
CAIL T1,PL.IL ;[2212] Psect index?
|
||
JRST X72G1 ;[2212] Yes, ignore it
|
||
JUMPE T1,X72G0 ;[2212] If absolute halfword eat 1 halfword
|
||
CAIE T1,PL.ABF ;[2212] Fullword absolute?
|
||
CAIN T1,PL.RLF ;[2212] Or fullword relocatable?
|
||
AOJA W1,X72G1 ;[2212] Yes, ignore the next 2 halfwords
|
||
CAIL T1,PL.OL ;[2212] Too low for operator?
|
||
CAILE T1,PL.OH ;[2212] Or too high?
|
||
CAIA ;[2212] Not an operator
|
||
JRST X72G1 ;[2212] An operator, ignore it
|
||
|
||
;[2212] Here if global symbol request. Find out if long or short, and
|
||
;[2212] prepare for TRYSYM.
|
||
MOVE T2,W1 ;[2212] Save the pointer for ILDB or MOVSLJ
|
||
SUB W1,FX.LB ;[2212] In case the area moves
|
||
PUSH P,W1 ;[2212] Save the pointer
|
||
LSH T1,-^D9 ;[2212] Get the length
|
||
PUSH P,T1 ;[2212] Save the length
|
||
CAIG T1,1 ;[2212] Short symbol (or converted radix-50)?
|
||
JRST X72GS ;[2212] Yes
|
||
|
||
;[2212] Here if long symbol. Copy it into SYMBLK and build a pointer to it
|
||
ADDI T1,1 ;[2212] Make into correct count
|
||
MOVE T4,T1 ;[2212] Also destination count
|
||
TLNE T4,1 ;[2212] Is it odd?
|
||
ADDI T4,1 ;[2212] Make it even (fullword for TRYSYM)
|
||
HRLZ W2,T4 ;[2212] Save the destination size
|
||
MOVE P1,[POINT 18,SYMBLK] ;[2212] Destination
|
||
EXTEND T1,[MOVSLJ T1, ;[2212] Move to word-aligned static area
|
||
0] ;[2212] Fill with zero byte if necessary
|
||
JFCL ;[2212] Destination is always largest
|
||
LSH W2,-1 ;[2212] Make the size in words
|
||
HRRI W2,SYMBLK ;[2212] Count,,pointer for TRYSYM
|
||
JRST X72TRY ;[2212] See if it's defined
|
||
|
||
;[2212] Here for short symbol
|
||
X72GS: ILDB T1,T2 ;[2212] Get left half of symbol
|
||
ILDB W2,T2 ;[2212] Get right half part
|
||
HRL W2,T1 ;[2212] Full symbol in W2
|
||
|
||
X72TRY: .JDDT LNKNEW,X72GS,<< CAMN W2,$SYMBOL##>>
|
||
MOVX W1,PT.SGN!PT.SYM ;[2212] Set the bits
|
||
PUSHJ P,TRYSYM## ;[2212] See if defined
|
||
JRST X72ND ;[2212] No, need to define it
|
||
JRST X72UN ;[2212] Undf, so just as bad
|
||
POP P,T1 ;[2212] Get the count back
|
||
POP P,W1 ;[2212] Restore byte pointer to start of symbol
|
||
ADD W1,FX.LB ;[2212] Add core offset
|
||
MOVEI T2,PL.ABF ;[2212] Get an absolute fullword operator
|
||
DPB T2,W1 ;[2212] Replace the symbol operator
|
||
MOVS T2,2(P1) ;[2212] Get value (reversed)
|
||
IDPB T2,W1 ;[2212] Store left half of value
|
||
MOVSS T2 ;[2212] Swap the value back
|
||
IDPB T2,W1 ;[2212] Store right half of value
|
||
SOJLE T1,X72G1 ;[2212] Find out how many words left
|
||
;[2212] (done if short symbol)
|
||
MOVEI T2,PL.IL ;[2212] Get a no-op (psect index is good here)
|
||
X72GZ: IDPB T2,W1 ;[2212] Clobber extra symbol name halfword
|
||
SOJG T1,X72GZ ;[2212] Continue until none left
|
||
JRST X72G1 ;[2212] Done with this symbol
|
||
|
||
X72GE: MOVE W3,T11BP ;[2212] Get pointer back to beginning
|
||
ADD W3,FX.LB ;[2212] Add base of area
|
||
SKIPN -1(W3) ;[2212] Any undefined globals?
|
||
PUSHJ P,T1072E ;[2212] No, evaluate fixup now
|
||
JRST LOAD## ;[2212] Else wait till all defined
|
||
|
||
;[2212] Here if global symbol not in global symbol table yet
|
||
;[2212] Treat as if additive global request
|
||
;[2212] Get extended triplet and point to fixup triplet in fixup area
|
||
;[2212] In turn this triplet points to the polish fixup
|
||
;[2212] NOTE AT THIS POINT W1, W2, AND W3 ARE USED FOR NON-SYMBOL
|
||
;[2212] STUFF, THEY MUST BE SAVED
|
||
|
||
X72ND: AOS USYM ;[2212] Increment undef count
|
||
TXO W1,PS.REQ ;Usual flags
|
||
PUSH P,W1 ;Save primary flags
|
||
PUSH P,[0] ;Zero value
|
||
MOVX W1,S.FXP ;Secondary symbol flag
|
||
PUSHJ P,GS.FX0## ;Put in global table
|
||
MOVX W1,FP.SGN!FP.SYM!FP.PTR!FP.POL ;
|
||
HRRZ W3,T11FA ;Address (relative to fx.lb) of polish
|
||
PUSHJ P,SY.FX0## ;Now put into fixup table
|
||
PUSHJ P,SY.GX0## ;Link to global
|
||
X72GD: POP P,W1 ;[2212] Get back the length
|
||
POP P,T1 ;[2212] And the byte pointer in a temporary
|
||
ADD T1,FX.LB ;[2212] Relocate again
|
||
SKIPN W1 ;[2212] Was this radix-50?
|
||
MOVEI W1,1 ;[2212] Yes, set to length-1
|
||
ADDI W1,1 ;[2212] Get the actual length
|
||
ADJBP W1,T1 ;[2212] Pass the symbol, result back in W1
|
||
MOVE W3,T11BP
|
||
ADD W3,FX.LB ;...
|
||
AOS -1(W3) ;Bump count of undefined symbols
|
||
JRST X72G1 ;Get next half word
|
||
|
||
;[2212] Here to see if fixup requests exist for this symbol
|
||
;[2212] If so add to chain, if not create chained list in extended symbol
|
||
X72UN: MOVE W1,0(P1) ;Flags go in W1 now
|
||
TXNE W1,PS.FXP ;Already fixups defered?
|
||
JRST X72DF ;[2212] Yes, just link to chain
|
||
MOVEI T1,.L ;[612] Need another triplet
|
||
PUSHJ P,SY.MOV## ;[612] So stretch current one
|
||
MOVX W1,PS.FXP ;[612] We now have a fixup triplet
|
||
IORM W1,0(P1) ;[612] So mark it
|
||
SUB T1,GS.LB ;[612] Get rel. addr of new triplet
|
||
PUSH P,T1 ;[612] Save it
|
||
MOVX W1,FP.SGN!FP.SYM!FP.PTR!FP.POL ;[612] Ptr to polish
|
||
HRRZ W3,T11FA ;[612] To try again when syms defined
|
||
PUSHJ P,SY.FX0## ;[612] Put w1-w3 in FX area
|
||
POP P,T1 ;[612] Restore pointer into GS
|
||
ADD T1,GS.LB ;[612] Make absolute again
|
||
MOVX W1,S.FXP!S.LST ;Pointer to fixup chain
|
||
TMOVEM W1,0(T1) ;[612] Store in new triplet
|
||
JRST X72GD ;[612] Return to scan rest of polish
|
||
|
||
|
||
;HERE IF FIXUP REQUEST EXISTS ALREADY
|
||
;JUST LINK INTO FRONT OF CHAIN
|
||
|
||
X72DF: ADDI P1,.L ;[2212] Look for additive global request
|
||
SKIPG W1,0(P1) ;Get secondary flags
|
||
PUSHJ P,E$$ISP## ;[2212] Primary or no flags set
|
||
TXNN W1,S.FXP ;Is this the one
|
||
JRST X72DF ;[2212] No try again
|
||
SKIPN W1,2(P1) ;Get pointer, better be non-zero
|
||
PUSHJ P,E$$ISP## ;[2212] Bad pointer
|
||
HRLI W1,(FP.SGN!FP.SYM!FP.PTR!FP.POL) ;
|
||
HRRZ W3,T11FA ;Point to polish
|
||
SUB P1,NAMLOC ;Incase core moves
|
||
PUSH P,P1 ;Save unrelocated pointer
|
||
PUSHJ P,SY.FX0## ;Put in fixup area
|
||
POP P,P1 ;Restore pointer
|
||
ADD P1,NAMLOC ;Relocate it
|
||
HRRM W3,2(P1) ;Fixup request pointer chain
|
||
JRST X72GD ;Get next half-word
|
||
|
||
;HERE TO EVALUATE POLISH FIXUP
|
||
T1072E::SKIPN W3,POLSTK ;[2212] Get stack pointer
|
||
PUSHJ P,T.11PD## ;[2212] Not setup yet
|
||
MOVEI T3,100 ;Incase of on operator
|
||
MOVEM T3,SVSAT
|
||
PUSH W3,[MXPLOP##+100] ;Fake operator
|
||
MOVE W2,T11BP ;Setup read byte pointer
|
||
IFN DEBSW,<
|
||
MOVEI W1,-2(W2) ;[632] POINT TO 1ST WORD OF BLOCK
|
||
> ;END IFN DEBSW
|
||
.JDDT LNKOLD,T1072E,<<CAMN W1,$FIXUP##>> ;[632]
|
||
ADD W2,FX.LB ;Fix in core
|
||
X72RP: ILDB W1,W2 ;Read a half-word
|
||
MOVEM W1,SAVCOD
|
||
CAIL W1,PL.NSO ;[2212] Store operator (new style)
|
||
JRST X72ST ;[2212] Yes
|
||
CAIL W1,PL.NEW ;[2212] Halfword data operator?
|
||
JRST X72RH ;[2212] Yes, eat the next halfword
|
||
CAIL W1,PL.IL ;[2212] Psect index?
|
||
JRST X72RP ;[2212] Yes, ignore it
|
||
JUMPE W1,X72AH ;[2212] If absolute halfword eat 1 halfword
|
||
CAIE W1,PL.ABF ;[2212] Fullword absolute?
|
||
CAIN W1,PL.RLF ;[2212] Or fullword relocatable?
|
||
JRST X72FO ;[2212] Yes, ignore the next 2 halfwords
|
||
CAIL W1,PL.OL ;[2212] Too low for operator?
|
||
CAILE W1,PL.OH ;[2212] Or too high?
|
||
JRST X72IPO ;[2212] Not an operator, illegal
|
||
; JRST X72OP ;[2212] An operator, stack it
|
||
|
||
;[2212] Handle operators
|
||
X72OP: AOBJN W3,.+2 ;[2212] Check for overflow
|
||
PUSHJ P,T.11PL# ;[2212] Overflow-go enlarge stack
|
||
MOVEM W1,(W3) ;[2212] Save operator on stack
|
||
MOVE T3,DESTB##-100(W1) ;Get number of operands needed
|
||
MOVEM T3,SVSAT ;Also save it
|
||
JRST X72RP ;[2212] Back for more
|
||
|
||
X72IPO: MOVE W1,SAVCOD ;[2212] Remember what's the problem
|
||
X72RPE: PUSHJ P,E$$IPO## ;[2212] Invalid polish operator
|
||
|
||
;[2212] Handle operands
|
||
|
||
;[2212] Absolute halfword
|
||
X72AH: ILDB T2,W2 ;[2212] Get the operand
|
||
JRST X72P0 ;[2212] Handle the value
|
||
|
||
;[2212] Relocatable halfword - Looks sort of like a fullword
|
||
X72RH: TRZA W1,PL.NEW ;[2212] Get rid of opcode, leaving section
|
||
|
||
;[2212] Relocatable or absolute Fullword
|
||
X72FO: ILDB W1,W2 ;[2212] Get the first halfword
|
||
ILDB T2,W2 ;[2212] Get the second halfword
|
||
HRL T2,W1 ;[2212] Put both together
|
||
; JRST X72P0 ;[2212] Handle the value
|
||
|
||
X72P0: SETZ T1, ;[2212] Value operand
|
||
X72P1: SOJL T3,X72ES ;[2212] Enough operands seen
|
||
AOBJN W3,.+2 ;[2212] Check for overflow
|
||
PUSHJ P,T.11PL# ;[2212] Overflow-go enlarge stack
|
||
MOVEM T2,(W3) ;[2212] Save operator on stack
|
||
HRLI T1,400000 ;Put in a value marker
|
||
AOBJN W3,.+2 ;[2212] Check for overflow
|
||
PUSHJ P,T.11PL# ;[2212] Overflow-go enlarge stack
|
||
MOVEM T1,(W3) ;[2212] Save operator on stack
|
||
JRST X72RP ;Get more polish
|
||
|
||
;Here when we have enough operands for the current operator
|
||
|
||
X72ES: SKIPN SVSAT ;[2212] Is it unary
|
||
JRST X72UO ;[2212] Yes, no need for 2nd operand
|
||
POP W3,T1 ;[2212] Pop off marker
|
||
POP W3,T1 ;And value
|
||
X72UO: POP W3,T3 ;Operator
|
||
XCT OPTAB##-100(T3) ;Both values just XCT
|
||
MOVE T2,T1 ;Get the current value
|
||
SKIPG T3,(W3) ;Is there a value in the stack?
|
||
MOVE T3,-2(W3) ;Yes, this must be the operator
|
||
MOVE T3,DESTB##-100(T3) ;Get number of operands needed
|
||
MOVEM T3,SVSAT ;Save it here
|
||
SKIPG (W3) ;Was there an operand
|
||
SUBI T3,1 ;Have one operand already
|
||
JRST X72P1 ;[2212] Go see what we should do now
|
||
|
||
;Here to store the final value
|
||
|
||
X72ST: MOVE T2,-2(W3) ;[2212] This should be the fake operator
|
||
CAIE T2,MXPLOP##+100 ;[2212] Is it
|
||
PUSHJ P,X72IPO ;[2212] No
|
||
ILDB T2,W2 ;[572] Get core addr or LS pointer
|
||
HRL T2,W1 ;[2212] Get the section (zero for symbols)
|
||
TLZ T2,PL.NMX ;[2212] Remove the high order (opcode) bits
|
||
MOVE W3,-1(W3) ;Get the value after ignoring the flag
|
||
LSH W1,-^D12 ;[2212] Get the opcode
|
||
PUSHJ P,@STRT72-PL.NS(W1) ;[2212] Call the correct fixup routine
|
||
PJRST T.11RT## ;[2212] All done, now give space back
|
||
|
||
;Store operator action table
|
||
;**;[2324] Change 2 lines at STRT72. PAH 16-Jul-84
|
||
STRT72: T11CHF## ;[2324] 0764 0774 Fullword chained
|
||
X72CHE ;[2324] 0765 0775 Thirty bit chained
|
||
T11CHL## ;[2212] 0766 0776 Left half chained
|
||
T11CHR## ;[2212] 0767 0777 Right half chained
|
||
X72FWS ;[2212] 1764 1774 Fullword chained
|
||
X72FWS ;[2212] 1765 1775 Thirty bit chained
|
||
X72FWS ;[2212] 1766 1776 Left half chained
|
||
X72FWS ;[2212] 1767 1777 Right half chained
|
||
T11SYF## ;[2212] xxx754 Fullword symbol
|
||
X72SYE ;[2212] xxx755 Thirty bit symbol
|
||
T11SYL## ;[2212] xxx756 Left half symbol
|
||
T11SYR## ;[2212] xxx757 Right half symbol
|
||
|
||
;**;[2324] Add 7 lines at STRT72+13. PAH 14-Jul-84
|
||
;[2324] Here to clear P1 before going to the thirty-bit chained fixup
|
||
;[2324] routine -- that routine calls others which interpret a nonzero
|
||
;[2324] value in P1 as a fixup block pointer.
|
||
X72CHE::SETZ P1, ;[2324] Clear leftover pointer so P1
|
||
;[2324] isn't treated as a fixup pointer
|
||
PUSHJ P,SY.CHF## ;[2324] Do the fullword chained fixup
|
||
POPJ P, ;[2324] And return to the dispatcher
|
||
|
||
X72SYE: MOVX W1,FS.FXE ;[2212] Thirty bit fixup
|
||
JRST SY.ASP## ;[2212] Join symbol fixup code
|
||
|
||
X72FWS: ILDB W2,W2 ;[2212] Get the next byte
|
||
HRL T2,W2 ;[2212] Put it in T2
|
||
MOVSS T2 ;[2212] Correct order
|
||
SUBI W1,<PL.NSF-PL.NSH> ;[2212] Fix up store opcode
|
||
PJRST @STRT72-PL.NS(W1) ;[2212] Go to the correct fixup routine
|
||
|
||
E$$STL::.ERR. (MS,.EC,V%L,L%F,S%F,STL,<Symbol too long>) ;[2007]
|
||
.ETC. (JMP,,,,,.ETIMF##)
|
||
|
||
|
||
SUBTTL BLOCK TYPE 1074 - FORTRAN COMMON BLOCK
|
||
|
||
; ---------------------------------
|
||
; ! 1074 ! COUNT !
|
||
; ---------------------------------
|
||
; ! PSECT INDEX ! SYMBOL LENGTH !
|
||
; ---------------------------------
|
||
; ! COMMON BLOCK LENGTH !
|
||
; ---------------------------------
|
||
; ! SIXBIT COMMON BLOCK NAME !
|
||
; ---------------------------------
|
||
; ! (MORE SIXBIT NAME) !
|
||
; ---------------------------------
|
||
|
||
T.1074::PUSHJ P,D.GET1 ;[2310] Get the index,,length
|
||
JRST LOAD## ;[2310] Empty block
|
||
HLRZ R,W1 ;[2310] Get the psect index
|
||
CAMLE R,RC.NO ;[2340] In bounds?
|
||
PUSHJ P,E$$IPX ;[2340] No, die
|
||
HRRZ R,@RC.MAP ;[2310] Convert to internal psect index
|
||
MOVE R,@RC.TB ;[2310] Get the RC block
|
||
MOVE W3,RC.CV(R) ;[2310] Get the current value
|
||
HRRZ W2,W1 ;[2310] Get number of characters
|
||
PUSHJ P,D.GET1 ;[2310] Get the COMMON block size
|
||
JRST [MOVEI T1,1074 ;[2310] No next word?
|
||
JRST E$$RBS##] ;[2310] Bad rel block
|
||
PUSH P,W1 ;[2310] Save the length
|
||
PUSHJ P,SYMIN1 ;[2310] Read the symbol
|
||
JRST [MOVEI T1,1074 ;[2310] Symbol fouled up?
|
||
JRST E$$RBS##] ;[2310] Bad rel block
|
||
POP P,W1 ;[2310] Restore the length
|
||
PUSHJ P,T.COMM## ;[2310] Build the common block
|
||
JRST LOAD## ;[2310] Done
|
||
HRRZ P1,@HT.PTR ;[2310] Set up pointer to symbol
|
||
ADD P1,GS.LB ;[2310] Unrelocate it
|
||
MOVE W3,.L+2(P1) ;[2310] Get the common length
|
||
ADDB W3,RC.CV(R) ;[2310] Bump relocation counter
|
||
CAML W3,RC.LM(R) ;[2310] Check against the limit
|
||
PUSHJ P,TOOBIG## ;[2310] Too big, give a warning
|
||
JRST LOAD## ;[2310]
|
||
> ;IFN .NWBLK
|
||
|
||
SUBTTL ASCIZ TEXT BLOCK
|
||
|
||
|
||
; -------------
|
||
; ! A S C I I !
|
||
; -------------
|
||
; ! T E X T 0 !
|
||
; -------------
|
||
|
||
IFN .ASBLK,<
|
||
LNKASC::TRNE FL,R.LIB!R.INC ;[602] ARE WE LOADING?
|
||
JRST ASCSKP ;[602] NO, SKIP OVER THIS TEXT BLOCK
|
||
MOVEI T2,^D128 ;USE STANDARD BUFFER OF 200 WORDS
|
||
PUSHJ P,DY.GET##
|
||
MOVEM T1,F.ASCC ;USE COUNT TO HOLD CURRENT POINTER
|
||
HRLI T1,(POINT 7,,35) ;BUILD THE BYTE POINTER
|
||
MOVEM T1,F.ASCI ;INITIAL AREA POINTER
|
||
ASCT0: MOVEI P1,1(T1) ;FIRST WORK IS USED AS A LINK IF MORE DATA
|
||
TLO P1,-^D127 ;FORM AOBJN POINTER
|
||
JRST ASCT2 ;JUMP INTO WORD STASHING LOOP
|
||
ASCT1: PUSHJ P,D.RED1## ;GET WORD FROM REL FILE
|
||
JRST ASCFIN ;END OF FILE
|
||
ASCT2: MOVEM W1,(P1) ;STORE TEXT WORD
|
||
TRNN W1,177B34 ;FINISHED IF NULL BYTE
|
||
JRST ASCFIN ;YES
|
||
AOBJN P1,ASCT1 ;NO, LOOP UNLESS BLOCK FULL
|
||
MOVEI T2,^D128 ;GET ANOTHER BLOCK
|
||
PUSHJ P,DY.GET##
|
||
MOVEM T1,@F.ASCC ;STORE POINTER
|
||
MOVEM T1,F.ASCC ;POINT TO NEW BLOCK
|
||
MOVEI P1,1(T1) ;FORM BYTE POINTER AGAIN
|
||
HRLI P1,-^D127
|
||
JRST ASCT1 ;AND CONTINUE
|
||
|
||
ASCFIN: MOVEI T1,^D127*5 ;CHARACTERS PER BLOCK
|
||
MOVEM T1,F.ASCC ;SET COUNT FOR FIRST BLOCK
|
||
PUSH P,F.NXZR ;REMEMBER POINTER TO END
|
||
PUSH P,F.INZR ;SAVE CURRENT FILE SPEC POINTERS
|
||
PUSH P,SWFLAG ;AND SWITCHES
|
||
INZLOC: SETZM F.INZR ;NOW CLEAR THEM
|
||
SETZM F.NXZR
|
||
SWFLOC: SETZM SWFLAG
|
||
ASZLOC: HLLZM FL,F.ASZR ;STORE GLOBAL FLAGS IN LH
|
||
JRST LNKSCN## ;GO TO SCANNER FOR INCORE COMMAND
|
||
|
||
|
||
;HERE TO PROCESS ASCII TEXT IN /INCLUDE OR /SEARCH MODE. JUST IGNORE IT.
|
||
ASCSKP: TRNN W1,177B34 ;[602] END OF ASCIZ STRING?
|
||
JRST LOAD## ;[602] YES, PROCESS NEXT BLOCK TYPE
|
||
PUSHJ P,D.IN1## ;[602] GET NEXT WORD, GOTO LOAD IF EOF
|
||
JRST ASCSKP ;[602] AND CONTINUE IGNORING IT
|
||
;RETURN HERE
|
||
ASCRET::HRRZ T1,F.ASZR ;SEEN ANY FILE NAMES YET?
|
||
JUMPN T1,ASCRT2 ;YES, NOT LOOKING AT SWITCHES
|
||
POP P,T1 ;RESTORE OLD SWFLAG
|
||
EXCH T1,SWFLAG ;PUT INCORE ONES FIRST
|
||
SKIPA T3,SWFLOC ;LOOK FOR END OF LIST
|
||
ASCRT1: MOVE T3,T2 ;STORE OLD
|
||
MOVE T2,(T3) ;GET NEXT POINTER
|
||
TRNE T2,-1 ;0 LINK IS END
|
||
JRST ASCRT1 ;NOT YET
|
||
HRRM T1,(T3) ;LINK OLD SWITCHES IN
|
||
PUSH P,SWFLAG ;NOW SAVE REVISED SWITCH LIST
|
||
ASCRT2: PUSHJ P,ASZCHN ;LINK NEW SPECS TO OLD F.ASZR
|
||
TRNE T1,-1 ;ANY SPECS SEEN THIS PASS?
|
||
PUSHJ P,INSEOL ;YES, INSERT /CRLF FOR SWITCHES
|
||
SETZM F.INZR ;NOW CLEAR VARIABLES FOR NEXT TIME
|
||
SETZM F.NXZR ;SO WON'T CONFUSE CLANS
|
||
MOVE T1,F.ASCI ;PICK UP POINTER TO CURRENT TEXT
|
||
CAME T1,[-1] ;REACHED EOF YET?
|
||
JRST LNKSCN## ;NO, GO PROCESS NEXT LINE
|
||
POP P,SWFLAG ;YES, RESTORE THINGS TO EARLIER
|
||
POP P,F.INZR ;OLD F.INZR (REST REAL COMMAND)
|
||
PUSHJ P,ASZCHN ;CHAIN OLD LINE TO END OF NEW
|
||
TRNE T1,-1 ;ANY MORE THIS REAL COMMAND LINE?
|
||
PUSHJ P,INSEOL ;YES, INSERT /CRLF
|
||
HLLO T2,F.ASZR ;LAST TIME, SO RESET GLOBAL FLAGS
|
||
TRNE T1,-1 ;T1 EITHER 0 OR ADDR OF SWITCH
|
||
MOVEM T2,2(T1) ;SWITCH, STORE VALUE
|
||
POP P,F.NXZR ;END OF NEW CHAIN SAME AS OLD
|
||
MOVE T1,F.ASZR ;PUT WHOLE CHAIN IN F.INZR
|
||
HRRZM T1,F.INZR ;SO LNKWLD CAN FIND IT
|
||
SETZM F.ASZR ;NOW CLEAN UP ASCII TEXT DATA BASE
|
||
SETZM F.ASCI ;..
|
||
SETZM F.ASCC ;..
|
||
SETZM F.ASCK
|
||
JRST LOAD ;CONTINUE WITH CURRENT .REL FILE
|
||
|
||
;HERE TO FOLLOW THE F.ASZR CHAIN, AND APPEND THE F.INZR CHAIN
|
||
; TO IT. RETURNS OLD F.INZR IN T1
|
||
|
||
ASZCHN: SKIPA T3,ASZLOC ;GET ADDR OF HEAD OF LIST
|
||
ASZCN1: MOVE T3,T2 ;REMEMBER LAST ADDR IN CASE END
|
||
HRRZ T2,F.NXT(T3) ;FOLLOW CHAIN
|
||
JUMPN T2,ASZCN1 ;IF NOT DONE, CONTINUE
|
||
MOVE T1,F.INZR ;GET START OF F.INZR CHAIN
|
||
HRRM T1,F.NXT(T3) ;STORE AT END OF F.ASZR CHAIN
|
||
POPJ P, ;DONE
|
||
;HERE TO PUT A GLOBAL SWITCH BLOCK ONTO THE SCAN BLOCK POINTED TO BY
|
||
; F.INZR TO INDICATE THAT /CRLF PROCESSING IS NEEDED BEFORE THIS FILE
|
||
; SPEC IS PROCESSED. THIS RESETS EOL DEFAULTS, ETC. SINCE THE POSITION
|
||
; OF CRLFS IS FORGOTTEN DURING ASCII BLOCK PROCESSING. THIS ROUTINE
|
||
; RETURNS THE ADDRESS OF THE ADDED SWITCH BLOCK IN T1.
|
||
|
||
INSEOL: MOVEI T2,3 ;SWITCH BLOCKS ARE 3 WORDS
|
||
PUSHJ P,DY.GET## ;GRAB ONE
|
||
MOVSI T2,3 ;1ST WORD IS LEN,,ADDR OF NEXT
|
||
MOVEM T2,0(T1) ;STORE IN BLOCK
|
||
MOVEI T2,%CRLF% ;2ND WORD IS TOKEN VALUE
|
||
MOVEM T2,1(T1) ;STORE IT TOO
|
||
HRRZ T2,F.INZR ;GET POINTER TO NEW SCAN BLOCK
|
||
HLRZ T3,F.SWP(T2) ;GET ADDR OF CURRENT SWITCHES
|
||
HRLM T1,F.SWP(T2) ;REPLACE WITH ADDR OF THIS BLOCK
|
||
HRRM T3,0(T1) ;LINK IN ANY OLD SWITCHES
|
||
POPJ P,
|
||
|
||
;NOW CALCULATE THE VALUE OF %CRLF% FROM THE SWMAC MACRO.
|
||
|
||
DEFINE SWMAC(A,B,C,D,E,F,G,H,I),<
|
||
IF1,<
|
||
IFIDN <B><CRLF>,<
|
||
IFNDEF %CRLF%,<
|
||
%CRLF%==TK.
|
||
>>
|
||
TK.==TK.+1
|
||
>>
|
||
|
||
TK.==0 ;INITIAL CONDITION
|
||
SWTCHS
|
||
|
||
>;END IFN .ASBLK
|
||
SUBTTL NEW BLOCK TYPE INPUT ROUTINES
|
||
|
||
|
||
COMMENT ^
|
||
|
||
THESE ROUTINES COUNT BLOCK LENGTH AND DO RELOCATION AS FOLLOWS:
|
||
|
||
AC WC CONTAINS THE NEGATIVE COUNT OF WORDS LEFT UNTIL THE NEXT
|
||
RELOCATION WORD IN THE LEFT HALF, AND THE NEGATIVE COUNT OF WORDS LEFT
|
||
IN THE CURRENT BLOCK IN THE RIGHT HALF. BIT 18 IS OFF SO THAT THE
|
||
OVERFLOW OF THE RIGHT HALF WILL NOT AFFECT THE LEFT HALF ON KA10'S.
|
||
THE ROUTINES FOR THOSE BLOCK TYPES THAT DO NOT EXPECT RELOCATION
|
||
WORDS SHOULD SET THE LEFT HALF OF WC TO 400000 (BY USE OF THE
|
||
RELOCATE MACRO) SO THAT THE CURRENT "RELOCATION BLOCK" WILL NEVER
|
||
EXPIRE.
|
||
AC RB CONTAINS THE CURRENT RELOCATION WORD. EACH TIME THAT
|
||
A NEW RELOCATION BYTE IS REQUIRED, RB (= R+1) IS SHIFTED C(RELSIZ)
|
||
BITS TO THE LEFT, THEREBY SETTING UP R. IF WE ARE NOT LOADING DATA
|
||
THAT CONTAINS RELOCATION WORDS, THIS CODE IS STILL EXECUTED, BUT
|
||
SINCE RB ALWAYS CONTAINS ZERO, THE CODE IS ALWAYS CONSIDERED ABSOLUTE.
|
||
NOTE THAT LH(WC) IS NOT KEPT UP TO DATE IF LOADING A BLOCK
|
||
TYPE THAT DOES NOT INCLUDE RELOCATION WORDS, AND PROCESSING ROUTINES
|
||
FOR THOSE BLOCK TYPES MAY SAVE OVERHEAD BY CALLING D.GET? INSTEAD OF
|
||
D.REL?, ALTHOUGH D.REL? WILL WORK CORRECTLY IF CALLED.
|
||
|
||
^
|
||
|
||
IFN .NWBLK,<
|
||
|
||
;SUBROUTINE TO READ IN A TRIPLET FROM THE CURRENT BLOCK.
|
||
;CALL IS:
|
||
;
|
||
; PUSHJ P,D.TRIP
|
||
; NO DATA RETURN (END OF BLOCK OR END OF FILE)
|
||
; HERE WITH W1-W3 SETUP
|
||
;
|
||
;USES W1-W3, T1-T2.
|
||
|
||
D.TRIP::PUSHJ P,D.GET1 ;GET NEXT WORD, CHECKING FOR END OF DATA
|
||
POPJ P, ;NONE LEFT
|
||
MOVE W3,W1 ;SAVE FLAGS FOR LATER
|
||
PUSHJ P,D.GET1 ;GET SYMBOL, IF THERE
|
||
POPJ P, ;IT'S NOT
|
||
MOVE W2,W1 ;POSITION SYMBOL CORRECTLY
|
||
PUSHJ P,D.REL1 ;NOW READ VALUE, POSSIBLY RELOCATING
|
||
POPJ P, ;OH WELL
|
||
EXCH W1,W3 ;PUT FLAGS & VALUE IN CORRECT PLACES
|
||
JRST CPOPJ1 ;GOOD RETURN
|
||
;ROUTINES TO GET THE NEXT WORD FROM THE DATA FILE AND DO ANY
|
||
;RELOCATION NECESSARY AS INDICATED BY RELSIZ, WC, AND RB. CALL IS:
|
||
;
|
||
; PUSHJ P,D.REL?
|
||
; NO DATA RETURN
|
||
; OK RETURN
|
||
;
|
||
;RETURNS THE NEXT WORD IN W1, OR W2 & W1. USES T1-T2.
|
||
|
||
|
||
D.REL2::PUSHJ P,D.REL1 ;GET THE FIRST WORD
|
||
POPJ P, ;NONE LEFT
|
||
MOVE W2,W1 ;SAVE FIRST WORD
|
||
;FALL IN TO GET SECOND WORD
|
||
D.REL1::TRNN WC,377777 ;MORE DATA IN THIS BLOCK?
|
||
POPJ P, ;NO, RETURN NO DATA
|
||
PUSHJ P,D.RED1## ;YES, GET NEXT WORD
|
||
JRST E$$PEF ;[1174] WORD COUNT WAS WRONG
|
||
AOBJN WC,DRELN ;GO RELOCATE UNLESS NEED NEW SUB-BLOCK
|
||
MOVE RB,W1 ;SAVE THE NEW RELOCATION WORD
|
||
MOVNI T1,^D36 ;FIND SIZE OF THIS SUB-BLOCK
|
||
IDIV T1,RELSIZ ;FROM THE BYTE SIZE
|
||
TRNE FL,R.LHR ;LEFT HALF RELOCATION DATA TOO?
|
||
ASH T1,-1 ;YES, ONLY 1/2 AS MANY WORDS IN BLOCK
|
||
HRL WC,T1 ;AND RESET SUB-BLOCK COUNT
|
||
PUSHJ P,D.GET1 ;NOW GET 1ST DATA WORD OF NEW BLOCK
|
||
POPJ P, ;???
|
||
DRELN: SETZ R, ;ZAP SOME BITS
|
||
LSHC R,@RELSIZ ;GRAB RELOCATION BYTE
|
||
JUMPE R,CPOPJ1 ;IF ABSOLUTE, WE'RE DONE
|
||
; SKIPN R,@RC.TB ;ELSE SET UP R FOR RELOCATION BLOCK
|
||
; JRST E$$IRC ;[1174] RELOCATED TO SEGMENT NOT SET UP
|
||
;********* ADD MORE CODE HERE ********************************
|
||
|
||
E$$IRC::.ERR. (MS,.EC,V%L,L%F,S%F,IRC,<Illegal relocation counter>) ;[1174]
|
||
.ETC. (JMP,,,,,.ETNMF##)
|
||
|
||
> ;END IFN .NWBLK<
|
||
;HERE TO GET THE NEXT WORD FROM THE CURRENT BLOCK. RETURNS NON-SKIP
|
||
;ON END OF BLOCK OR END OF FILE. EXPECTS WC TO BE SET UP FROM LNKLOD.
|
||
|
||
D.GET1::TRNN WC,377777 ;END OF BLOCK ON LAST WORD?
|
||
POPJ P, ;YES, NO MORE DATA
|
||
PUSHJ P,D.RED1## ;NO, GET NEXT WORD
|
||
JRST E$$PEF ;[1174] PREMATURE END OF FILE
|
||
AOJA WC,CPOPJ1 ;COUNT WORD & GIVE GOOD RETURN
|
||
|
||
CPOPJ1: AOS 0(P) ;THE USUAL
|
||
CPOPJ: POPJ P,
|
||
|
||
|
||
;HERE WHEN THE .REL FILE HAS A PREMATURE EOF.
|
||
|
||
E$$PEF::.ERR. (MS,.EC,V%L,L%F,S%W,PEF,<Premature end of file from file >) ;[1174]
|
||
.ETC. (FSP,,,,,DC)
|
||
POPJ P, ;TRY TO CONTINUE
|
||
SUBTTL WORD RELOCATION FOR BLOCK 1070
|
||
;ROUTINE TO RELOCATE A WORD (USED BY BLOCK 1070)
|
||
;
|
||
; PUSHJ P,REL.1
|
||
; NO DATA RETURN
|
||
; OK RETURN (W1/ RETURN VALUE)
|
||
;
|
||
;ENTER WITH:
|
||
;
|
||
; R/ TEMP. PSECTS (-1 IF NOT USED)
|
||
; RB/ RELOCATION TYPE
|
||
; RC.CUR/ CUREENT PSECT
|
||
;
|
||
;ACS USED: R,RB,T1,W1,W3
|
||
;
|
||
;RETURN VALUES:
|
||
; W1/ FLAG
|
||
; W3/ VALUE
|
||
|
||
IFN .NWBLK,<
|
||
;[1000]
|
||
REL.1::TRNN WC,377777 ;MORE DATA IN THIS BLOCK?
|
||
POPJ P, ;NO, RETURN NO DATA
|
||
PUSHJ P,D.GET1 ;GO GET A WORDS
|
||
POPJ P, ;???
|
||
MOVE W3,W1 ;RETURN VALUE IN W3
|
||
SETZ W1, ;CLEAR RETURN FLAG WORD
|
||
JUMPE RB,CPOPJ1 ;IF ABS, OK RETURN
|
||
MOVX W1,PS.REL ;RELOCATABLE SYMBOL
|
||
JUMPGE R,REL.T ;JUMP IF TEMPORARY PSECTS SPECIFIED
|
||
PUSHJ P,@[ REL.R ;1 - RIGHT HALF
|
||
REL.L ;2 - LEFT HALF
|
||
REL.B ;3 - BOTH HAVES
|
||
REL.E ;4 - EXTENDED(30BIT)
|
||
REL.F]-1(RB) ;5 - FULL WORD
|
||
JRST CPOPJ1 ;SKIP RETURN
|
||
|
||
REL.T: PUSH P,RC.CUR ;USE TEMP. PSECTS INSTEAD OF CURRENT ONE
|
||
PUSHJ P,@[ REL.TR ;1 - RIGHT HALF
|
||
REL.TL ;2 - LEFT HALF
|
||
REL.TB ;3 - BOTH HALVES
|
||
REL.TE ;4 - EXTENDED(30 BIT)
|
||
REL.TF]-1(RB) ;5 - FULL WORD
|
||
POP P,RC.CUR ;RESTORE ORIGINAL PSECT
|
||
JRST CPOPJ1 ;AND SKIP RETURN
|
||
|
||
REL.B: PUSHJ P,REL.L ;RELOCATE LEFT WITH CUREENT PSECT FIRST
|
||
JRST REL.R ;THEN DO THE SAME WITH RIGHT HALF
|
||
|
||
REL.TB: PUSH P,R ;SAVE FOR RIGHT
|
||
PUSHJ P,REL.TL ;RELOCATE LEFT WITH TEMP. PSECT
|
||
POP P,R ;[1720]
|
||
REL.TR: HRRZ R,@RC.MAP ;[1716] TRANSLATE RH PSECT INDEX TO INTERNAL
|
||
HRRM R,RC.CUR ;TEMPORARILY SWITCH CURRENT PSECT
|
||
REL.R: HRR T1,W3 ;ADDRESS IN T1
|
||
PUSHJ P,R.CUR## ;GO RELOCATE IT WITH CURRENT PSECT
|
||
HRR W3,T1 ;RETURN VALUE IN W3
|
||
POPJ P, ;
|
||
|
||
REL.TL: HLRZ R,R ;[1716] GET LH PSECT INDEX
|
||
HRRZ R,@RC.MAP ;[1716] TRANSLATE TO INTERNAL PSECT INDEX
|
||
HRRM R,RC.CUR ;[1716] SWITCH CURRENT PSECT
|
||
REL.L: HLR T1,W3 ;SET UP ADDRESS IN T1
|
||
PUSHJ P,R.CUR## ;GO RELOCATE IT
|
||
HRL W3,T1 ;RETURN VALUE IN W3
|
||
POPJ P, ;
|
||
|
||
REL.TE: HRRZ R,@RC.MAP ;[1716] TRANSLATE RH PSECT INDEX TO INTERNAL
|
||
HRRM R,RC.CUR ;SWITCH CURRENT PSECT
|
||
REL.E: LDB T1,[POINT 30,W3,35]
|
||
PUSHJ P,R.CUR## ;
|
||
LDB W3,[POINT 30,T1,35]
|
||
POPJ P,
|
||
|
||
REL.TF: HRRZ R,@RC.MAP ;[1716] TRANSLATE RH PSECT INDEX TO INTERNAL
|
||
HRRM R,RC.CUR ;SWITCH CURRENT PSECT
|
||
REL.F: MOVE T1,W3 ;SET UP ADDRESS IN T1
|
||
PUSHJ P,R.CUR## ;GO RELOCATE IT
|
||
MOVE W3,T1 ;RETURN VALUE IN W3
|
||
POPJ P, ;
|
||
> ;IFN .NWBLK
|
||
SUBTTL SUPPORT CODE FOR 11XX BLOCKS
|
||
|
||
DEFINE NEWBLX(SIZ,NUM,TYP,DSP,PRC,XIT)<
|
||
SETZM NORBYT ;;[1456]
|
||
PUSH P,[ PRC ] ;;DATA WORD PROCESSOR
|
||
MOVE P1,[POINT SIZ,RB] ;;HOW TO ACCESS RELOC BYTES
|
||
MOVEI P2,NUM ;;NUMBER OF RELOC BYTES
|
||
MOVE P4,[ TYP ] ;;HOW TO DO THE RELOC
|
||
PUSHJ P,DSP ;;COMMON CODE TO INTERPRET THIS
|
||
IFNB <XIT>,<PUSHJ P,XIT> ;;[1471]
|
||
JRST LOAD ;;TO GET BACK TO MAIN LOOP
|
||
> ;[1423]
|
||
|
||
|
||
|
||
|
||
T.11XX::
|
||
;
|
||
; T.1100 through T.1137 come here after setting up ACs as follows:
|
||
; P1 -an initialized byte pointer for the relocation bytes
|
||
; P2 -number of relocation bytes in the word
|
||
; P4 -dispatch address for type of relocation (30bit)
|
||
;
|
||
; First set up stack.
|
||
|
||
POP P,T1 ;[1405] UNSTACK RETURN ADDRESS
|
||
EXCH T1,(P) ;[1405] SWAP WITH PROCESSOR ADDRESS
|
||
PUSH P,T1 ;[1405] RETURN ONLY WHEN THRU
|
||
AOS P2 ;[1423] SUBBLOCK INCLUDING RELOC WORD
|
||
SPUSH <P1,P2> ;[1423] SAVE REGISTERS
|
||
MOVN T1,(P) ;[1423] SETUP WC
|
||
HRL WC,T1 ;[1423]
|
||
|
||
; Note the data blocksize as some processors need this data.
|
||
|
||
HRRZ P3,WC ;[1405]
|
||
TDO P3,[-1,,400000] ;[1405] REAL NEGATIVE NUMBER
|
||
MOVNS P3 ;[1405] NOW POSITIVE
|
||
PUSH P,P4 ;[1405] SAVE P4
|
||
IDIVI P3,1(P2) ;[1405] INCLUDE HEADER IN BLOCKSIZE
|
||
IMULI P3,1(P2) ;[1405] MAXIMUM DATA BLOCKSIZE
|
||
SKIPE P4 ;[1405] IF NONZERO RESIDUE
|
||
ADDI P3,-1(P4) ;[14YY] ADD IT, MINUS HEADER
|
||
POP P,P4 ;[1405] GET P4 BACK
|
||
|
||
T11XXR:
|
||
; BEGIN PROCESSING A SUB-BLOCK
|
||
|
||
PUSHJ P,PB.1 ;[1405] FETCH FIRST WORD OF BLOCK
|
||
JRST [ SPOP <T1,P2,P1>
|
||
POPJ P, ] ;[1405] NO MORE IN BLOCK
|
||
JFCL ;[1405] IMPOSSIBLE"
|
||
MOVE RB,W1 ;[1405] SETUP RELOC BYTE
|
||
MOVE P1,-1(P) ;[1405] RESET BYTEPOINTER
|
||
|
||
; BEGIN PROCESSING THE LIST
|
||
|
||
T11XXL: PUSHJ P,PB.1 ;[1423] FETCH A DATA WORD
|
||
JRST [ SPOP <T1,P2,P1>
|
||
POPJ P, ] ;[1423] NO MORE
|
||
JRST [ SKIPE RB,NORBYT ;[1456]
|
||
JRST T11XXA ;[1456]
|
||
MOVE P2,(P)
|
||
MOVE P1,-1(P)
|
||
MOVN T1,P2
|
||
HRL WC,T1
|
||
JRST T11XXR ] ;[1423] RESET FOR NEXT SUBBLOCK
|
||
T11XXA: PUSHJ P,PSORGN ;[1456] GET ANY PSECT INDICES
|
||
PUSHJ P,@P4 ;[1423] DO THE RELOCATION
|
||
PUSHJ P,@-2(P) ;[1405] AND THE PROCESSING
|
||
JRST T11XXL ;[1423] DO IT AGAIN
|
||
|
||
SUBTTL BLOCK TYPES 1100-1104 - PROGRAM DATA VECTORS
|
||
|
||
|
||
|
||
T.1100::
|
||
NEWBLX(2,^D18,THADD,T.11XX,T.110X) ;[1423]
|
||
|
||
T.1101::
|
||
NEWBLX(3,^D12,THADD,T.11XX,T.110X) ;[1423]
|
||
|
||
T.1102::
|
||
NEWBLX(6,6,THADD,T.11XX,T.110X) ;[1423]
|
||
|
||
T.1103::
|
||
NEWBLX(9,4,THADD,T.11XX,T.110X) ;[1423]
|
||
|
||
T.1104::
|
||
NEWBLX(18,2,THADD,T.11XX,T.110X) ;[1423]
|
||
|
||
|
||
|
||
T.110X: SKIPE W1 ;[1423] IGNORE ZEROS
|
||
MOVEM W1,PDVADR## ;[1423] STORE PDV ADDR
|
||
;** MAKE THIS WORK RIGHT FOR MULTIPLE PDVS **
|
||
POPJ P,
|
||
|
||
SUBTTL BLOCK TYPES 1120-1124 -- TYPE CHECKING BLOCKS
|
||
|
||
DEFINE T112XM(N)<
|
||
NEWBLX(N,<^D36/N>,THADD,T.11XX,T.112X,T112XP) > ;[1472]
|
||
|
||
T.1120::
|
||
T112XM(2) ;[1472]
|
||
T.1121::
|
||
T112XM(3) ;[1472]
|
||
T.1122::
|
||
T112XM(6) ;[1472]
|
||
T.1123::
|
||
T112XM(^D9) ;[1472]
|
||
T.1124::
|
||
T112XM(^D18) ;[1472]
|
||
|
||
T.112X: SETOM NORBYT ;[1456] DON'T READ ANY MORE RELOC BYTES
|
||
SKIPGE P3 ;[1405] FIRST TIME THRU?
|
||
JRST T112X ;[1405] NO
|
||
MOVEI T2,ABOVH(P3) ;[2270] MUST ALLOCATE A STORAGE BLOCK
|
||
SKIPE PAG.TP ;[2270] TP AREA PAGING?
|
||
JRST T112P ;[2270] YES
|
||
PUSHJ P,TP.GET## ;[2270] NO, ALLOCATE IN TP AREA
|
||
SKIPE PAG.TP ;[2270] DID IT JUST START PAGING?
|
||
T112P: PUSHJ P,DY.GET## ;[2270] PAGING, GET SPACE IN DY AREA
|
||
MOVEM T2,ABSIZ(T1) ;[2270] STORE SIZE
|
||
MOVE W3,PRGNAM ;[2005] GET THE MODULE NAME
|
||
MOVEM W3,ABMOD(T1) ;[2020] SAVE IT
|
||
MOVE W2,T1 ;[2270] ADDRESS OF THE BLOCK
|
||
MOVEI W3,ABABA(T1) ;[2020] SAVE A PTR
|
||
MOVN T2,P3 ;[1405]
|
||
HRL W3,T2 ;[1405] MAKE W3 AN AOBJN PTR
|
||
SETOM P3 ;[1405] SAY WE'VE BEEN HERE
|
||
T112X: MOVEM W1,(W3) ;[1405] STORE THE DATA
|
||
ADD W3,[1,,1] ;[1471]
|
||
POPJ P, ;[1405] GET MORE
|
||
T112XP:
|
||
MOVE T1,ABCNT(W2) ;[2266] GET THE CHARACTER COUNT
|
||
SUBI T1,1 ;[2307] ACCOUNT FOR THE NULL
|
||
IDIVI T1,6 ;[2307] IN WORDS
|
||
SKIPE T2 ;[2266] ANY LEFT?
|
||
ADDI T1,1 ;[2266] YES, NEED ONE MORE WORD
|
||
HRLZ W3,T1 ;[2266] PUT IT IN AS THE SYMBOL LENGTH
|
||
HRRI W3,SYMBLK ;[2266] THE SYMBOL IN WILL BE IN SYMBLK
|
||
SETZM SYMBLK-1(T1) ;[2266] MAKE SURE NO JUNK IN LAST WORD
|
||
MOVE T4,ABCNT(W2) ;[1472] NOTE COUNT
|
||
MOVE T2,[POINT 7,ABNAM(W2)] ;[1472]
|
||
MOVE T3,[POINT 6,SYMBLK] ;[2266] PUT IT IN SYMBLK
|
||
T112X0: SOJL T4,T112X1 ;[1472] STOP WHEN ALL CHARS DONE
|
||
ILDB T1,T2 ;[1472] PICK UP ASCII
|
||
JUMPE T1,T112X1 ;[1472] NUL MUST BE END OF ASCIZ
|
||
SUBI T1," " ;[1472] ASCII TO SIXBIT
|
||
IDPB T1,T3 ;[1472] ACCUMULATE
|
||
JRST T112X0 ;[1472]
|
||
T112X1: EXCH W3,W2 ;[1472] W2/SIXBIT,W3/PTR
|
||
PUSHJ P,SY.TYP## ;[1472]
|
||
POPJ P,
|
||
|
||
SUBTTL BLOCK TYPE 1130 -- COERCION BLOCK
|
||
|
||
T.1130::
|
||
PUSHJ P,STDATA ;[1704] USE GENERAL ROUTINE
|
||
MOVEM W2,COERPT ;[1405]
|
||
JRST LOAD## ;[1701]
|
||
|
||
SUBTTL BLOCK TYPE 1131 - PSECT REDIRECTION
|
||
|
||
; ---------------------
|
||
; ! 1131 ! COUNT !
|
||
; ---------------------
|
||
; ! 0 ! INDEX !
|
||
; ---------------------
|
||
; ! LOWSEG PSECT NAME !
|
||
; ---------------------
|
||
; ! HIGHSEG PSECT NAME!
|
||
; ---------------------
|
||
|
||
;Where a psect name is:
|
||
|
||
; --------------------- ---------------------
|
||
; ! SIXBIT PSECT NAME ! ! 0 ! MBZ ! COUNT !
|
||
; --------------------- ---------------------
|
||
; ! (ATTRIBUTES) ! ! SIXBIT PSECT NAME !
|
||
; --------------------- ---------------------
|
||
; ! ADDITIONAL NAME !
|
||
; ---------------------
|
||
;
|
||
; .
|
||
;
|
||
; .
|
||
;
|
||
; ---------------------
|
||
; ! ADDITIONAL NAME !
|
||
; ---------------------
|
||
|
||
|
||
T.1131: PUSHJ P,X131GT ;[2223] Get the low psect
|
||
JRST [MOVEI T1,1131 ;[2223] No psect name is
|
||
JRST E$$RBS##] ;[2223] an error
|
||
JUMPE W2,X131HI ;[2223] No symbol, try high segment
|
||
EXCH W2,REDLO ;[2223] Save it, get old
|
||
PUSHJ P,X131RT ;[2223] Return the old symbol
|
||
X131HI: PUSHJ P,X131GT ;[2223] Get the high psect
|
||
JRST [MOVEI T1,1131 ;[2223] No psect name is
|
||
JRST E$$RBS##] ;[2223] an error
|
||
JUMPE W2,X131DF ;[2272] Done if no symbol
|
||
EXCH W2,REDHI ;[2223] Save it, get old
|
||
PUSHJ P,X131RT ;[2223] Return the old symbol
|
||
X131DF: MOVE T1,['.LOW. '] ;[2272] Get the default low seg psect
|
||
SKIPN REDLO ;[2272] Is there a low seg psect?
|
||
MOVEM T1,REDLO ;[2272] No, default it
|
||
MOVE T1,['.HIGH.'] ;[2272] Get the default high seg psect
|
||
SKIPN REDHI ;[2272] Is there a high seg psect?
|
||
MOVEM T1,REDHI ;[2272] No, default it
|
||
JRST LOAD## ;[2223] Done
|
||
|
||
;[2223] Here to read a possibly long symbol into the DY area.
|
||
;[2223] On exit, W2 contains the symbol.
|
||
X131GT: PUSHJ P,D.GET1 ;[2223] Get the symbol
|
||
POPJ P, ;[2223] Not there
|
||
MOVE W2,W1 ;[2223] Put it in W2
|
||
TLNE W2,770000 ;[2223] Long symbol?
|
||
JRST CPOPJ1 ;[2223] No, done
|
||
CAIN W2,1 ;[2223] Short symbol in disguise?
|
||
JRST [PUSHJ P,D.GET1 ;[2223] Yes, get one word
|
||
POPJ P, ;[2223] No word means bad rel block
|
||
MOVE W2,W1 ;[2223] Put it in W2
|
||
JRST CPOPJ1] ;[2223] Return with a short symbol
|
||
MOVE T2,W2 ;[2223] Get the length
|
||
JUMPE T2,CPOPJ1 ;[2223] Zero, no symbol
|
||
PUSHJ P,DY.GET ;[2223] Allocate some space
|
||
HRL T1,T2 ;[2223] Build length,,address
|
||
PUSH P,T1 ;[2223] Store it
|
||
MOVNS W2 ;[2223] Negate the count
|
||
HRLZS W2 ;[2223] Put it in the left half
|
||
HRR W2,T1 ;[2223] Make an AOBJN word
|
||
X131GL: PUSHJ P,D.GET1 ;[2223] Get a word
|
||
JRST [POP P,W2 ;[2223] No more, clear up stack
|
||
POPJ P,] ;[2223] Return
|
||
MOVEM W1,(W2) ;[2223] Save the word
|
||
AOBJN W2,X131GL ;[2223] Do all words
|
||
POP P,W2 ;[2236] Restore count,,address
|
||
JRST CPOPJ1 ;[2223] Done, return OK
|
||
|
||
;[2223] Here to return a possibly long symbol in the DY area.
|
||
;[2223] On entry, W2 contains the symbol.
|
||
X131RT: HLRZ T2,W2 ;[2231] Get the count
|
||
JUMPE T2,CPOPJ ;[2223] Done if empty
|
||
TRNE T2,770000 ;[2223] Long symbol?
|
||
POPJ P, ;[2223] No, done
|
||
HRRZ T1,W2 ;[2223] Long symbol
|
||
PJRST DY.RET## ;[2223] Return the space
|
||
|
||
SUBTTL BLOCK TYPE 1160 -- SPARSE DATA
|
||
|
||
; --------------------------------
|
||
; | 1160 | Long Count |
|
||
; --------------------------------
|
||
; |R|F|B|P|Symlen| Psect |
|
||
; --------------------------------
|
||
; | Symbol (Symlen words) |
|
||
; --------------------------------
|
||
; |S| Origin address |
|
||
; --------------------------------
|
||
; | Repetition Count if R=1 |
|
||
; --------------------------------
|
||
; | Fill Count if F=1 |
|
||
; --------------------------------
|
||
; | Fill Byte if F=1 |
|
||
; --------------------------------
|
||
; | Byte Count if B=1 |
|
||
; --------------------------------
|
||
; | Data Bytes |
|
||
; --------------------------------
|
||
|
||
T.1160: PUSHJ P,D.GET1 ;[2262] Get the first word of the rel block
|
||
JRST LOAD## ;[2262] Empty block
|
||
MOVE R,W1 ;[2262] Save the psect number etc.
|
||
LDB T1,[POINTR R,X60.P] ;[2262] Get the byte position
|
||
MOVEM T1,BYTPOS ;[2262] Save it
|
||
LDB W2,[POINTR R,X60.SL] ;[2262] Get the symbol length
|
||
SETZ W3, ;[2262] Zero the symbol value
|
||
JUMPE W2,X160NS ;[2262] Is there a symbol?
|
||
PUSHJ P,SYMIN1 ;[2262] Read the symbol
|
||
JRST [MOVEI T1,1160 ;[2262] No symbol?
|
||
JRST E$$RBS##] ;[2262] Bad rel block
|
||
MOVX W1,PT.SGN!PT.SYM!PS.GLB ;[2262] Set the flags
|
||
PUSHJ P,TRYSYM## ;[2262] See if defined
|
||
JRST E$$USD ;[2262] Not even in table
|
||
JRST E$$USD ;[2262] Undefined, so still no use
|
||
MOVE W3,2(P1) ;[2262] Get value
|
||
IFN FTOVERLAY,< ;[2262]
|
||
CAMGE W3,PH+PH.ADD ;[2262] Make sure array is in this link
|
||
JRST T.1SE## ;[2262] No, must be common in father link
|
||
>;[2262] IFN FTOVERLAY
|
||
X160NS: PUSHJ P,D.GET1 ;[2262] Get the next word
|
||
JRST [MOVEI T1,1160 ;[2262] No next word?
|
||
JRST E$$RBS##] ;[2262] Bad rel block
|
||
LDB T1,[POINTR W1,X60.S] ;[2262] Get the byte size
|
||
MOVEM T1,BYTSIZ ;[2262] Save it
|
||
LDB T1,[ADDRES W1] ;[2262] Get the address part
|
||
ADD W3,T1 ;[2262] Add the symbol part
|
||
TRNN R,-1 ;[2262] Psect relocation required?
|
||
JRST X160NP ;[2262] No
|
||
PUSH P,R ;[2262] Keep the bits around
|
||
PUSH P,RC.CUR ;[2327] Save the current psect
|
||
PUSHJ P,REL.TE ;[2262] Relocate the address (30 bit)
|
||
POP P,RC.CUR ;[2327] Restore the current psect
|
||
HRRM R,0(P) ;[2262] Keep the RC block pointer
|
||
POP P,R ;[2262] Get them back
|
||
X160NP: MOVEM W3,BYTADR ;[2262] Save the low address for the data
|
||
MOVEI W1,1 ;[2262] Get the default repetition count
|
||
TXNN R,X60.R ;[2262] Repetition count?
|
||
JRST X160NR ;[2262] No
|
||
PUSHJ P,D.GET1 ;[2262] Get the repetition count
|
||
JRST [MOVEI T1,1160 ;[2262] No count?
|
||
JRST E$$RBS##] ;[2262] Bad rel block
|
||
JUMPE W1,T1000C ;[2262] If zero, don't bother
|
||
X160NR: MOVEM W1,REPCNT ;[2262] Save the repetition count
|
||
SETZM FILCNT ;[2262] Assume no fill
|
||
TXNN R,X60.F ;[2262] Fill required?
|
||
JRST X160NF ;[2262] No
|
||
PUSHJ P,D.GET1 ;[2262] Get fill count
|
||
JRST [MOVEI T1,1160 ;[2262] No count?
|
||
JRST E$$RBS##] ;[2262] Bad rel block
|
||
MOVEM W1,FILCNT ;[2262] Save it
|
||
PUSHJ P,D.GET1 ;[2262] Get fill character
|
||
JRST [MOVEI T1,1160 ;[2262] No character?
|
||
JRST E$$RBS##] ;[2262] Bad rel block
|
||
MOVEM W1,FILCHR ;[2262] Save it
|
||
X160NF: MOVEI W1,1 ;[2262] Default byte count
|
||
TXNN R,X60.B ;[2262] Byte count given?
|
||
JRST X160NB ;[2262] No, no byte count
|
||
PUSHJ P,D.GET1 ;[2262] Get byte count
|
||
JRST [MOVEI T1,1160 ;[2262] No count?
|
||
JRST E$$RBS##] ;[2262] Bad rel block
|
||
X160NB: MOVEM W1,BYTCNT ;[2262] Save it
|
||
PUSHJ P,X160SZ ;[2262] Set up for size calculations
|
||
T1160S: SUB W1,T1 ;[2262] Minus number of bytes in first word
|
||
IDIV W1,BYTPWD ;[2262] Number of extra words needed
|
||
SKIPE W2 ;[2262] Any extra bytes?
|
||
ADDI W1,1 ;[2262] Yes, account for them
|
||
ADD W1,BYTADR ;[2262] Add first address to get last
|
||
MOVEM W1,LSTBYT ;[2262] Remember it
|
||
MOVE P3,BYTADR ;[2262] Get the first byte address
|
||
HRRZS R ;[2262] Get only the psect number
|
||
SETOM TP.PP ;[2270] Don't page the TP area for this
|
||
PUSHJ P,T.1AD## ;[2262] Try and allocate all of it
|
||
JRST [SETZM TP.PP ;[2270] Allow TP area paging
|
||
JRST T1000C] ;[2270] And ignore it (/ONLY switch in use)
|
||
PUSHJ P,T160DF ;[2262] Move window if deferred (less than 140)
|
||
SETZM TP.PP ;[2270] Allow the TP area to page
|
||
IFN FTOVERLAY,< ;[2313]
|
||
MOVN T1,PH+PH.ADD ;[2313] Get -base of overlay
|
||
ADDM T1,BYTADR ;[2313] Offset the first address
|
||
ADDM T1,LSTBYT ;[2313] Offset the last address
|
||
>;[2313] IFN FTOVERLAY
|
||
|
||
;[2262] Memory has been allocated. Set up for the loop to copy from the
|
||
;[2262] rel file buffer into memory.
|
||
|
||
;[2262] Set up number of bytes available in current source buffer
|
||
MOVE R,RC.SG(R) ;[2262] Get the high/low segment index
|
||
MOVE T1,DCBUF+2 ;[2262] Get the number of words in the buffer
|
||
IMUL T1,BYTPWD ;[2262] Number of bytes in buffer
|
||
MOVEM T1,SRCCNT ;[2262] Remember it
|
||
|
||
;[2262] Set up number of bytes which can be stored into in current
|
||
;[2262] destination buffer
|
||
|
||
MOVE T4,TAB.AB(R) ;[2262] Get the top of the area
|
||
SUB T4,TAB.LB(R) ;[2262] Minus bottom equals size
|
||
ADD T4,TAB.LW(R) ;[2262] Add the value of the bottom to get top
|
||
SUB T4,BYTADR ;[2262] Minus start address is what's left
|
||
IMUL T4,BYTPWD ;[2262] Number of bytes available
|
||
MOVE T1,BYTPOS ;[2262] Save it
|
||
MOVE T3,BYTSIZ ;[2262] Get the byte size
|
||
IDIVI T1,(T3) ;[2262] See how many bytes left in first word
|
||
ADD T1,T4 ;[2262] Add bytes in first word
|
||
MOVEM T1,DSTCNT ;[2262] Destination count
|
||
|
||
;[2262] Build the source byte pointer. Note that pointer is to end of
|
||
;[2262] previous word, and will be bumped by the MOVSLJ.
|
||
|
||
MOVE T1,BYTSIZ ;[2262] Get the byte size
|
||
HRRZ T2,DCBUF+1 ;[2262] Get the source pointer to the buffer
|
||
DPB T1,[POINT 6,T2,11] ;[2262] Set up the byte size
|
||
|
||
;[2262] Build the destination byte pointer
|
||
MOVE P1,BYTADR ;[2262] Get the byte address
|
||
SUB P1,TAB.LW(R) ;[2262] Minus the window offset
|
||
ADD P1,TAB.LB(R) ;[2262] Relocate
|
||
DPB T1,[POINT 6,P1,11] ;[2262] Put byte size in the byte pointer
|
||
MOVE T1,BYTPOS ;[2262] Get the byte position
|
||
DPB T1,[POINT 6,P1,5] ;[2262] Put it in the byte pointer
|
||
|
||
MOVE W3,BYTCNT ;[2262] Get number of bytes to move
|
||
|
||
DMOVE T3,DCBUF+1 ;[2262] Get location and size of buffer
|
||
DMOVEM T3,BUFBEG ;[2262] Remember them
|
||
|
||
;[2262] Loop to copy from the input buffers to the output windows.
|
||
|
||
X160NX: PUSHJ P,X160BF ;[2262] Make sure the buffer is not empty
|
||
PUSHJ P,X160CW ;[2262] Check the window
|
||
|
||
;[2262] Find the number of bytes which can be copied
|
||
MOVE T4,W3 ;[2262] Get the number of bytes desired
|
||
CAMLE T4,SRCCNT ;[2262] More than in the source buffer?
|
||
MOVE T4,SRCCNT ;[2262] Yes, can't do more than that
|
||
CAMLE T4,DSTCNT ;[2262] More than can fit in window?
|
||
MOVE T4,DSTCNT ;[2262] Yes, do only that much
|
||
MOVN T1,T4 ;[2262] Get minus what will be copied
|
||
ADDM T1,SRCCNT ;[2262] Update the source count
|
||
ADDM T1,DSTCNT ;[2262] And the destination count
|
||
MOVE T1,T4 ;[2262] Put count in both places
|
||
SUB W3,T4 ;[2262] Remember how many have been done
|
||
SETZB T3,P2 ;[2262] Just to be safe
|
||
EXTEND T1,[MOVSLJ] ;[2262] Copy the string
|
||
JFCL ;[2262] Should not run out
|
||
JUMPN W3,X160NX ;[2262] Continue until all bytes copied
|
||
|
||
;[2262] Now fix up the source buffer pointers. Use stored original
|
||
;[2262] pointers and the source byte pointer.
|
||
|
||
SKIPGE DCBUF+1 ;[2262] Is it new buffer pointer never ILDB'd?
|
||
ADDI T2,1 ;[2262] Yes, Point at next word
|
||
HRRM T2,DCBUF+1 ;[2262] And fix up the pointer
|
||
HRRZ T3,BUFBEG ;[2262] Get the beginning of the buffer
|
||
ADD T3,BUFLEN ;[2262] Plus length is end of buffer
|
||
SUBI T3,(T2) ;[2262] Minus how far was used
|
||
MOVEM T3,DCBUF+2 ;[2262] Restore it into DCBUF
|
||
|
||
;[2262] Here to do fill if necessary
|
||
SKIPN W3,FILCNT ;[2262] Get the fill count
|
||
JRST X160RP ;[2262] None, go do repeat count
|
||
MOVX P3,<MOVSLJ> ;[2262] Get the op code for the fill
|
||
MOVE P4,FILCHR ;[2262] And the fill byte
|
||
|
||
X160FL: PUSHJ P,X160CW ;[2262] Check the window
|
||
|
||
;[2262] Find the number of bytes which can filled this time
|
||
MOVE T4,W3 ;[2262] Get the number of bytes desired
|
||
CAMLE T4,DSTCNT ;[2262] More than can fit in window?
|
||
MOVE T4,DSTCNT ;[2262] Yes, do only that much
|
||
SUB W3,T4 ;[2262] Remember how many have been done
|
||
MOVN T3,T4 ;[2262] Get minus what will be copied
|
||
ADDM T3,DSTCNT ;[2262] Update the destination count
|
||
SETZ T1, ;[2262] No source characters
|
||
SETZB T3,P2 ;[2262] Just to be safe
|
||
EXTEND T1,P3 ;[2262] Fill as many as possible
|
||
JFCL ;[2262] Skips if filling
|
||
JUMPN W3,X160FL ;[2262] Do them all
|
||
|
||
;[2262] Here to handle the repeat count
|
||
|
||
X160RP: SOSG REPCNT ;[2262] Need to copy again?
|
||
JRST LOAD## ;[2262] No, done
|
||
|
||
;[2262] Here to pick a method for handling the repeat count.
|
||
;[2262] If all of the data will fit in the current window, just
|
||
;[2262] copy it with the MOVSLJ. If one copy of the data will
|
||
;[2262] fit in memory, and there is more than about 1/4 of the
|
||
;[2262] window (must be at least 1 page) free, copy what is
|
||
;[2262] possible with the MOVSLJ, move the window, and continue
|
||
;[2262] copying. Otherwise, split the window into two smaller
|
||
;[2262] windows, get a copy of the data into one, and copy it
|
||
;[2262] to the other.
|
||
|
||
;[2366] On TOPS-10 there are a couple extra wrinkles. If the
|
||
;[2366] area is split into source and destination windows, their
|
||
;[2366] contents must not overlap. This means that the windows
|
||
;[2366] must be shorter than the size of the data items. This
|
||
;[2366] means that, for an item less than one page long, the
|
||
;[2366] window size would be zero. It is necessary to use a
|
||
;[2366] one window move for such data. It is also possible
|
||
;[2366] that the area will be only one page long. If it will
|
||
;[2366] be necessary to move the window, at least two pages
|
||
;[2366] will be necessary.
|
||
|
||
MOVE W3,FILCNT ;[2262] Get the fill count
|
||
ADDB W3,BYTCNT ;[2262] Include it in the byte count
|
||
IMUL W3,REPCNT ;[2262] Total number of bytes to move
|
||
|
||
IFE TOPS20,< ;[2366]
|
||
MOVE T1,BYTCNT ;[2366] Get number of bytes
|
||
IDIV T1,BYTPWD ;[2366] Size in words
|
||
CAIGE T1,.IPS ;[2366] Less than one page?
|
||
JRST X160SS ;[2366] Yes, special case
|
||
>;[2366] IFE TOPS20
|
||
|
||
MOVE T3,BYTADR ;[2262] Get the origin address
|
||
CAMGE T3,TAB.LW(R) ;[2262] Outside of the window?
|
||
JRST X160CX ;[2262] Yes, too big for one window
|
||
CAMG W3,DSTCNT ;[2262] That many bytes left?
|
||
JRST X160SM ;[2262] Yes, it will fit in one window
|
||
MOVE T1,TAB.AB(R) ;[2262] Get the upper bound
|
||
SUBI T1,(P1) ;[2262] Minus what is left
|
||
CAIG T1,.IPS ;[2262] More than a page?
|
||
JRST X160CX ;[2262] No, too big for one window
|
||
IMULX T1,4 ;[2262] 4 times what's left
|
||
MOVE T3,TAB.AB(R) ;[2262] Get the upper bound
|
||
SUB T3,TAB.LB(R) ;[2262] Minus the lower
|
||
CAMGE T1,T3 ;[2262] More than a quarter of the window left?
|
||
JRST X160CX ;[2262] No, use two windows
|
||
X160SM: MOVE T2,BYTADR ;[2262] Get the first copy's address
|
||
SUB T2,TAB.LW(R) ;[2262] Minus the window bound
|
||
ADD T2,TAB.LB(R) ;[2262] Relocate it
|
||
MOVE T3,BYTSIZ ;[2262] Get the byte size
|
||
DPB T3,[POINT 6,T2,11] ;[2262] Put byte size in the byte pointer
|
||
MOVE T3,BYTPOS ;[2262] Get the byte position
|
||
DPB T3,[POINT 6,T2,5] ;[2262] Put it in the byte pointer
|
||
X160SL: MOVE T1,W3 ;[2262] Get the number of bytes left to copy
|
||
CAML T1,DSTCNT ;[2262] Less than what can be done?
|
||
MOVE T1,DSTCNT ;[2262] Yes, do that many
|
||
SUB W3,T1 ;[2262] Update what's left to do
|
||
MOVN T4,T1 ;[2262] Get minus how many to do
|
||
ADDM T4,DSTCNT ;[2262] Update count of what's left
|
||
MOVE T4,T1 ;[2262] Both counts the same
|
||
SETZB T3,P2 ;[2262] Just to be safe
|
||
EXTEND T1,[MOVSLJ] ;[2262] Copy the string
|
||
JFCL ;[2262] Should not run out
|
||
JUMPE W3,LOAD## ;[2262] Check for done
|
||
HRRZ P3,T2 ;[2262] Get the source
|
||
SUB P3,TAB.LB(R) ;[2262] Unrelocate it
|
||
ADD P3,TAB.LW(R) ;[2262] Get the true address
|
||
TXZ P3,.IPM ;[2262] Put on a page boundary
|
||
MOVE P2,P3 ;[2262] Get the bottom of the window area
|
||
ADD P2,TAB.AB(R) ;[2262] Plus the upper area limit
|
||
SUB P2,TAB.LB(R) ;[2262] Minus the lower
|
||
CAMLE P2,LSTBYT ;[2262] Is this more than necessary?
|
||
MOVE P2,LSTBYT ;[2262] Yes, only get this much
|
||
TXO P2,.IPM ;[2262] Put on a page boundary
|
||
SUB T2,TAB.LB(R) ;[2366] Unrelocate the pointers
|
||
SUB P1,TAB.LB(R) ;[2366] In case the area moves
|
||
PUSH P,T2 ;[2366] Save the source pointer
|
||
PUSH P,P1 ;[2366] And the destination pointer
|
||
PUSH P,TAB.LW(R) ;[2366] And the current window bottom
|
||
PUSHJ P,@[EXP PG.LSG##,PG.HSG##]-1(R) ;[2262] Move the window
|
||
POP P,T1 ;[2262] Get back the old lower bound
|
||
SUB T1,TAB.LW(R) ;[2262] How far the window moved
|
||
MOVNS T1 ;[2262] Make it positive
|
||
POP P,P1 ;[2262] Get back the destination pointer
|
||
SUB P1,T1 ;[2262] Adjust the pointer
|
||
POP P,T2 ;[2262] Get back the source pointer
|
||
SUB T2,T1 ;[2262] Adjust the pointer
|
||
ADD T2,TAB.LB(R) ;[2366] Relocate the pointers
|
||
ADD P1,TAB.LB(R) ;[2366] Back into the correct area
|
||
|
||
;[2262] Note that this calculation is incorrect for the last time the window
|
||
;[2262] is moved, since the window may be shrunk. This is not important, as
|
||
;[2262] LSTBYT guarantees the bytes which will be moved will fit in the window.
|
||
|
||
IMUL T1,BYTPWD ;[2262] In bytes
|
||
ADDM T1,DSTCNT ;[2262] Update the destination counter
|
||
JRST X160SL ;[2262] Go back and copy more bytes
|
||
|
||
IFE TOPS20,<
|
||
;[2366] Here for case of less than one page. Make sure that
|
||
;[2366] there are at least 2 pages in the area.
|
||
|
||
X160SS: MOVE T1,TAB.AB(R) ;[2366] Get the top of the area
|
||
SUB T1,TAB.LB(R) ;[2366] Minus the bottom for size
|
||
CAILE T1,.IPS-1 ;[2366] One page?
|
||
JRST X160SM ;[2366] No, no problem
|
||
|
||
PUSH P,P1 ;[2366] Save the destination pointer
|
||
MOVEI P1,(R) ;[2366] Point to the area
|
||
MOVEI P2,1 ;[2366] Expand by one page
|
||
PUSHJ P,LNKCOR## ;[2366] Get the core
|
||
PUSHJ P,E$$MEF## ;[2366] Not even one page?
|
||
MOVE P1,TAB.AB(R) ;[2366] Get new upper bound
|
||
SUB P1,TAB.LB(R) ;[2366] Get new size
|
||
ADD P1,TAB.LW(R) ;[2366] Add window bottom
|
||
SKIPE TAB.UW(R) ;[2410] IF THIS AREA IS PAGING
|
||
MOVEM P1,TAB.UW(R) ;[2366] New windown top
|
||
MOVE P1,BYTPWD ;[2366] Get bytes per word
|
||
IMULI P1,.IPS ;[2366] Get bytes per page
|
||
ADDM P1,DSTCNT ;[2366] Update the destination counter
|
||
POP P,P1 ;[2366] Retrieve destination pointer
|
||
JRST X160SM ;[2366] Process as simple case
|
||
>;[2366] IFE TOPS20
|
||
|
||
;[2262] Here to handle the case where multiple copies will not fit
|
||
;[2262] in the window. Split the window, and use half for the source
|
||
;[2262] and half for the destination.
|
||
|
||
X160CX: MOVE T1,TAB.LW(R) ;[2262] Get the lower window bound
|
||
MOVE T2,TAB.UW(R) ;[2262] And the upper bound
|
||
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R) ;[2262] Empty the window
|
||
MOVE T2,TAB.AB(R) ;[2262] Get the maximum address
|
||
SUB T2,TAB.LB(R) ;[2262] Minus the minimum address
|
||
ADDI T2,1 ;[2262] Get actual window size
|
||
CAIL T2,2*.IPS ;[2366] At least two pages in area?
|
||
JRST X160CM ;[2366] Yes, no problem
|
||
MOVEI P1,(R) ;[2366] Point to the area
|
||
MOVEI P2,1 ;[2366] Expand by one page
|
||
PUSHJ P,LNKCOR## ;[2366] Get the core
|
||
PUSHJ P,E$$MEF## ;[2366] Not even one page?
|
||
MOVEI T2,2*.IPS ;[2366] Now there are two pages
|
||
|
||
X160CM: LSH T2,-1 ;[2262] Get size of half window
|
||
TRO T2,.IPM ;[2262] Put at end of page
|
||
|
||
IFE TOPS20,<
|
||
MOVE T4,W3 ;[2366] Get number of bytes
|
||
IDIV T4,BYTPWD ;[2366] Size in words
|
||
TRZ T4,.IPM ;[2366] Maximum window size to prevent overlap
|
||
SUBI T4,1 ;[2366] As an upper limit
|
||
CAMLE T2,T4 ;[2366] Window small enough?
|
||
MOVE T2,T4 ;[2366] No, use smaller size
|
||
>;[2366] IFE TOPS20
|
||
|
||
MOVE T1,TAB.LB(R) ;[2262] Get the lower bound
|
||
ADD T2,TAB.LB(R) ;[2262] End of lower window half
|
||
DMOVEM T1,DST.LB ;[2262] Save as the destination bounds
|
||
MOVEI T3,1(T2) ;[2262] Source LB is destination UB+1
|
||
|
||
IFE TOPS20,< ;[2366]
|
||
ADD T4,T3 ;[2366] Get the highest acceptable bound
|
||
CAML T4,TAB.AB(R) ;[2366] Is it OK?
|
||
JRST X160CZ ;[2366] Yes, no overlap possible
|
||
SETZM 1(T4) ;[2366] Zero first free word
|
||
HRLI T1,1(T4) ;[2366] From
|
||
HRRI T1,2(T4) ;[2366] To
|
||
BLT T3,@TAB.AB(R) ;[2366] Zero extra memory
|
||
MOVEM T4,TAB.AB(R) ;[2366] Set new bound
|
||
X160CZ:
|
||
>;[2366] IFE TOPS20
|
||
|
||
MOVE T4,TAB.AB(R) ;[2262] Get upper bound
|
||
DMOVEM T3,SRC.LB ;[2262] Save as the source bounds
|
||
MOVEM T2,TAB.AB(R) ;[2262] Set up destination window
|
||
|
||
HRRZ T1,P1 ;[2262] Get the destination address
|
||
SUB T1,TAB.LB(R) ;[2262] Relocate
|
||
ADD T1,TAB.LW(R) ;[2262] Make into an address
|
||
PUSH P,T1 ;[2262] Keep the address
|
||
TXZ T1,.IPM ;[2262] Set on block boundary
|
||
MOVEM T1,TAB.LW(R) ;[2262] New lower bound
|
||
MOVE T2,T1 ;[2262] Get the lower bound
|
||
ADD T2,DST.AB ;[2262] Add the destination upper bound
|
||
SUB T2,DST.LB ;[2262] Minus the lower is high address
|
||
MOVEM T2,TAB.UW(R) ;[2262] Save it
|
||
DMOVEM T1,DST.LW ;[2262] Save the window addresses
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R) ;[2262] Read the window
|
||
POP P,T1 ;[2262] Get back the destination address
|
||
SUB T1,DST.LW ;[2262] Subtract the lower window bound
|
||
ADD T1,DST.LB ;[2262] Unrelocate it
|
||
HRR P1,T1 ;[2262] Put it back in the byte pointer
|
||
MOVE W1,P1 ;[2262] Get the destination byte pointer
|
||
PUSHJ P,X160CB ;[2262] Count the remaining bytes in the window
|
||
MOVEM T1,DSTCNT ;[2262] Remember it
|
||
|
||
DMOVE T1,SRC.LB ;[2262] Now switch to the source window
|
||
MOVEM T1,TAB.LB(R) ;[2262] Store the source lower bound
|
||
MOVEM T2,TAB.AB(R) ;[2262] And upper
|
||
MOVE T1,BYTADR ;[2262] Get the source address
|
||
TXZ T1,.IPM ;[2262] Set on a page boundary
|
||
MOVEM T1,TAB.LW(R) ;[2262] Save the lower window
|
||
ADD T2,T1 ;[2262] Lower window plus upper bound
|
||
SUB T2,SRC.LB ;[2262] Minus lower bound is upper window
|
||
MOVEM T2,TAB.UW(R) ;[2262] Save it
|
||
DMOVEM T1,SRC.LW ;[2262] Save it
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R) ;[2262] Read the window
|
||
MOVE W1,BYTADR ;[2262] Get the source address
|
||
SUB W1,SRC.LW ;[2262] Subtract the lower window bound
|
||
ADD W1,SRC.LB ;[2262] Unrelocate it
|
||
MOVE T1,BYTSIZ ;[2262] Get the byte size
|
||
DPB T1,[POINT 6,W1,11] ;[2262] Put it in the byte pointer
|
||
MOVE T1,BYTPOS ;[2262] Get the source byte position
|
||
DPB T1,[POINT 6,W1,5] ;[2262] Put it in the byte pointer
|
||
PUSHJ P,X160CB ;[2262] Count the remaining bytes in the window
|
||
MOVEM T1,SRCCNT ;[2262] Remember it
|
||
MOVE T2,W1 ;[2262] Get the source address in memory
|
||
|
||
X160MB: PUSHJ P,X160SC ;[2262] Check the source window
|
||
PUSHJ P,X160DS ;[2262] And the destination window
|
||
|
||
;[2262] Find the number of bytes which can be copied
|
||
MOVE T4,W3 ;[2262] Get the number of bytes desired
|
||
CAMLE T4,SRCCNT ;[2262] More than in the source buffer?
|
||
MOVE T4,SRCCNT ;[2262] Yes, can't do more than that
|
||
CAMLE T4,DSTCNT ;[2262] More than can fit in window?
|
||
MOVE T4,DSTCNT ;[2262] Yes, do only that much
|
||
MOVN T1,T4 ;[2262] Get minus what will be copied
|
||
ADDM T1,SRCCNT ;[2262] Update the source count
|
||
ADDM T1,DSTCNT ;[2262] And the destination count
|
||
MOVE T1,T4 ;[2262] Put count in both places
|
||
SUB W3,T4 ;[2262] Remember how many have been done
|
||
SETZB T3,P2 ;[2262] Just to be safe
|
||
EXTEND T1,[MOVSLJ] ;[2262] Copy the string
|
||
JFCL ;[2262] Should not run out
|
||
JUMPN W3,X160MB ;[2262] Continue until all bytes copied
|
||
|
||
;[2262] Now unscrew the windows and return. Remove the source window,
|
||
;[2262] and leave the destination window only.
|
||
IFN TOPS20,< ;[2262]
|
||
DMOVE T1,SRC.LB ;[2262] Get the source bounds
|
||
MOVEM T1,TAB.LB(R) ;[2262] Set the lower bound
|
||
MOVEM T2,TAB.AB(R) ;[2262] And the upper
|
||
DMOVE T1,SRC.LW ;[2262] Get the window limits
|
||
MOVEM T1,TAB.LW(R) ;[2262] Set the lower window
|
||
MOVEM T2,TAB.UW(R) ;[2262] And the upper
|
||
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R) ;[2262] Write the window
|
||
> ;[2262] IFN TOPS20
|
||
IFE TOPS20,<
|
||
MOVE T1,SRC.LB ;[2262] Get the lower bound
|
||
HRL T1,SRC.LB ;[2262] In both halves
|
||
SETZM (T1) ;[2262] Zero the first word
|
||
ADDI T1,1 ;[2262] From,,to for zero
|
||
MOVE T2,SRC.AB ;[2262] How far to go
|
||
BLT T1,(T2) ;[2262] Zero the memory
|
||
>
|
||
DMOVE T1,DST.LB ;[2262] Get the source bounds
|
||
MOVEM T1,TAB.LB(R) ;[2262] Set the lower bound
|
||
MOVEM T2,TAB.AB(R) ;[2262] And the upper
|
||
DMOVE T1,DST.LW ;[2262] Get the window limits
|
||
MOVEM T1,TAB.LW(R) ;[2262] Set the lower window
|
||
MOVEM T2,TAB.UW(R) ;[2262] And the upper
|
||
JRST LOAD## ;[2262] Done
|
||
|
||
;[2262] Here if deferred. What this really means is that it goes
|
||
;[2262] below address 140. Since this block cannot be deferred, move
|
||
;[2262] the window to page zero. Note that this must be in the low seg
|
||
;[2262] because the high segment cannot start below 140.
|
||
;[2343] Uses R, T1, T2
|
||
|
||
T160DF: MOVE R,SG.TB+1 ;[2343] In low segment
|
||
MOVE T1,LW.LC ;[2262] Get the low bound
|
||
MOVE T2,UW.LC ;[2262] And the high bound
|
||
PUSHJ P,LC.OUT## ;[2262] Write the window
|
||
MOVE T1,LC.LB ;[2262] Get the base of the area
|
||
IORI T1,.IPM ;[2262] Want only one block
|
||
MOVEM T1,LC.AB ;[2262] Allocate it
|
||
SETZB T1,LW.LC ;[2343] Starting at address zero
|
||
MOVEI T2,.IPM ;[2262] Want one page
|
||
MOVEM T2,UW.LC ;[2343] Set the window correctly
|
||
PJRST LC.IN## ;[2262] Go get it
|
||
|
||
;[2262] Here to compute the byte size, and diddle the byte pointer
|
||
;[2262] if necessary.
|
||
;[2343] On input W1 contains the byte count
|
||
;[2343] On return W1 contains the total number of bytes
|
||
;[2343] Uses T1,T2,T3
|
||
|
||
X160SZ: MOVE T3,BYTSIZ ;[2262] Get the byte size
|
||
MOVEI T1,^D36 ;[2262] Bits per wordt
|
||
IDIVI T1,(T3) ;[2262] Bytes per word
|
||
MOVEM T1,BYTPWD ;[2262] Save it
|
||
ADD W1,FILCNT ;[2262] Byte count plus fill bytes
|
||
IMUL W1,REPCNT ;[2262] Times the repetition count
|
||
MOVE T1,BYTPOS ;[2262] Get the byte position
|
||
MOVE T3,BYTSIZ ;[2262] Get the byte size
|
||
IDIVI T1,(T3) ;[2262] See how many bytes left in first word
|
||
JUMPN T1,CPOPJ ;[2262] Done if something in first word
|
||
MOVEI T1,^D36 ;[2262] Need to point to beginning
|
||
MOVEM T1,BYTPOS ;[2262] of word
|
||
AOS BYTADR ;[2262] Next word
|
||
MOVE T1,BYTPWD ;[2262] Number of bytes in first word
|
||
POPJ P, ;[2262] Continue calculation
|
||
|
||
|
||
;[2262] Here to check that there is something in the rel
|
||
;[2262] file buffer. If it is empty, read some more.
|
||
;[2262] Also updates the source pointer in T2.
|
||
|
||
;[2262] Uses T1,T2,T3,T4
|
||
|
||
X160BF: SKIPLE SRCCNT ;[2262] Rel buffer empty?
|
||
POPJ P, ;[2262] No, return
|
||
SKIPN DCBUF ;[2262] If zero, reading from core
|
||
JRST X160B1 ;[2262] Read buffer from FX area
|
||
PUSHJ P,D.CNT## ;[2262] Get the next buffer from disk
|
||
JRST X160B2 ;[2262] Not expected to skip
|
||
IFN TOPS20,< ;[2301]
|
||
SKIPLE RFLEN ;[2301] But it did, is it EOF?
|
||
>;[2301] IFN TOPS20
|
||
IFE TOPS20,<
|
||
STATO DC,IO.EOF ;[2301] EOF?
|
||
>;[2301] IFE TOPS20
|
||
JRST D.ERR## ;[2262] It's an error
|
||
MOVEI T1,1160 ;[2301] EOF, get the block type
|
||
PUSHJ P,E$$RBS## ;[2301] Give an error
|
||
X160B1: PUSHJ P,FXREAD## ;[2262] Read buffer from FX area
|
||
|
||
;[2366] When doing buffered I/O on TOPS-10, after an IN UUO the
|
||
;[2366] second word of the buffer header contains a 004400 byte
|
||
;[2366] pointer which points to the word before the first data
|
||
;[2366] word. On TOPS-20 The code which does the PMAP% builds
|
||
;[2366] a 444400 byte pointer which points to the first data word
|
||
;[2366] of the buffer. Set up the correct style of byte pointer.
|
||
;[2366] Note that T2 already has the byte size in the correct place.
|
||
|
||
X160B2: TLZ T2,770000 ;[2262] Clear the byte pointer
|
||
IFN TOPS20,< ;[2366]
|
||
TLO T2,440000 ;[2262] And set for beginning of word
|
||
>;[2366] IFE TOPS20
|
||
HRR T2,DCBUF+1 ;[2262] At the beginning of the buffer
|
||
MOVE T1,DCBUF+2 ;[2262] Number of words in buffer
|
||
IMUL T1,BYTPWD ;[2262] Number of bytes in buffer
|
||
MOVEM T1,SRCCNT ;[2262] Remember what's available
|
||
DMOVE T3,DCBUF+1 ;[2262] Get location and size of buffer
|
||
DMOVEM T3,BUFBEG ;[2262] Remember them
|
||
POPJ P, ;[2262] Return
|
||
|
||
;[2262] Here to check that the start of the destination transfer is within
|
||
;[2262] the window, and to move the window if it is not.
|
||
;[2262] Also updates the destination pointer in P1.
|
||
|
||
;[2262] Uses T1,T3
|
||
|
||
X160CW: SKIPLE DSTCNT ;[2262] Any more space in the window?
|
||
POPJ P, ;[2262] Yes
|
||
PUSHJ P,X160PU ;[2262] Push up the window
|
||
MOVEM T1,DSTCNT ;[2262] Save destination count
|
||
POPJ P,
|
||
|
||
|
||
;[2262] Here to check that the start of the source transfer is within
|
||
;[2262] the window when using half-windows, and to move the window
|
||
;[2262] if it is not. Also updates the source pointer in T2.
|
||
|
||
;[2262] Uses T1,T3,T4
|
||
|
||
X160SC: SKIPLE SRCCNT ;[2262] Any more space in the window?
|
||
POPJ P, ;[2262] Yes
|
||
DMOVE T3,SRC.LB ;[2262] Get the source bounds
|
||
MOVEM T3,TAB.LB(R) ;[2262] Set the lower bound
|
||
MOVEM T4,TAB.AB(R) ;[2262] And the upper
|
||
DMOVE T3,SRC.LW ;[2262] Get the window limits
|
||
MOVEM T3,TAB.LW(R) ;[2262] Set the lower window
|
||
MOVEM T4,TAB.UW(R) ;[2262] And the upper
|
||
EXCH P1,T2 ;[2262] Swap pointers (X160P1 updates P1)
|
||
PUSHJ P,X160P1 ;[2262] Get new window
|
||
MOVEM T1,SRCCNT ;[2262] Update source count
|
||
EXCH P1,T2 ;[2262] Swap back pointers
|
||
MOVE T3,TAB.LB(R) ;[2262] Get the lower bound
|
||
MOVE T4,TAB.AB(R) ;[2262] And the upper
|
||
DMOVEM T3,SRC.LB ;[2262] Save the new source bounds
|
||
MOVE T3,TAB.LW(R) ;[2262] Get the lower window
|
||
MOVE T4,TAB.UW(R) ;[2262] And the upper
|
||
DMOVEM T3,SRC.LW ;[2262] Save the window limits
|
||
POPJ P, ;[2262] Done
|
||
|
||
;[2262] Here to check that the start of the source transfer is within
|
||
;[2262] the window when using half-windows, and to move the window
|
||
;[2262] if it is not. Also updates the source pointer in T2.
|
||
|
||
;[2262] Uses T1,T3,T4
|
||
|
||
X160DS: SKIPLE DSTCNT ;[2262] Any more space in the window?
|
||
POPJ P, ;[2262] Yes
|
||
DMOVE T3,DST.LB ;[2262] Get the destination bounds
|
||
MOVEM T3,TAB.LB(R) ;[2262] Set the lower bound
|
||
MOVEM T4,TAB.AB(R) ;[2262] And the upper
|
||
DMOVE T3,DST.LW ;[2262] Get the window limits
|
||
MOVEM T3,TAB.LW(R) ;[2262] Set the lower window
|
||
MOVEM T4,TAB.UW(R) ;[2262] And the upper
|
||
PUSHJ P,X160PU ;[2262] Get new window
|
||
MOVEM T1,DSTCNT ;[2262] Update source count
|
||
MOVE T3,TAB.LB(R) ;[2262] Get the lower bound
|
||
MOVE T4,TAB.AB(R) ;[2262] And the upper
|
||
DMOVEM T3,DST.LB ;[2262] Save the destination bounds
|
||
MOVE T3,TAB.LW(R) ;[2262] Set the lower window
|
||
MOVE T4,TAB.UW(R) ;[2262] And the upper
|
||
DMOVEM T3,DST.LW ;[2262] Get the window limits
|
||
POPJ P, ;[2262] Done
|
||
|
||
;[2262] Routine to actually move the window up.
|
||
;[2262] Returns updated destination count in T1
|
||
;[2262] Uses T1,T3
|
||
|
||
X160P1: PUSH P,T2 ;[2262] Save the destination byte pointer
|
||
JRST X160P2 ;[2262] And don't write the window
|
||
|
||
X160PU: PUSH P,T2 ;[2262] Save the source byte pointer
|
||
MOVE T1,TAB.LW(R) ;[2262] Get the lower bound
|
||
MOVE T2,TAB.UW(R) ;[2262] And the upper bound
|
||
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R) ;[2262] Write the window
|
||
X160P2: MOVE T1,TAB.UW(R) ;[2262] Get current upper window
|
||
ADDI T1,1 ;[2262] Plus one is new lower window
|
||
MOVE T2,T1 ;[2262] Get the low address
|
||
ADD T2,TAB.AB(R) ;[2262] Plus the upper area limit
|
||
SUB T2,TAB.LB(R) ;[2262] Minus the lower
|
||
CAMLE T2,LSTBYT ;[2262] Is this more than necessary?
|
||
MOVE T2,LSTBYT ;[2262] Yes, only get this much
|
||
TXO T2,.IPM ;[2262] Put on a block boundary
|
||
MOVEM T1,TAB.LW(R) ;[2262] Set the new lower bound
|
||
MOVEM T2,TAB.UW(R) ;[2262] And the new upper bound
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R) ;[2262] Read the window
|
||
MOVE T1,TAB.UW(R) ;[2262] Get the upper bound
|
||
SUB T1,TAB.LW(R) ;[2262] Minus the lower gives area size
|
||
MOVE T2,T1 ;[2262] Hold onto the size
|
||
ADD T2,TAB.LB(R) ;[2262] Plus the lower bound gives actual bound
|
||
MOVEM T2,TAB.AB(R) ;[2262] Store it
|
||
TLZ P1,770000 ;[2262] Clear the position bits
|
||
TLO P1,440000 ;[2262] Point to beginning of word
|
||
HRR P1,TAB.LB(R) ;[2262] Address is beginning of window
|
||
ADDI T1,1 ;[2262] Number of words in window
|
||
IMUL T1,BYTPWD ;[2262] How many bytes in window
|
||
POP P,T2 ;[2262] Get back the source byte pointer
|
||
POPJ P, ;[2262]
|
||
|
||
|
||
;[2262] Here to compute the number of bytes left in the current window.
|
||
;[2262] Assumes the area is paging.
|
||
;[2262] Accepts a byte pointer in W1
|
||
;[2262] Returns a byte count in T1
|
||
;[2262] Uses T1-T4
|
||
|
||
X160CB: MOVE T4,TAB.AB(R) ;[2262] Get the upper bound
|
||
SUBI T4,(W1) ;[2262] Minus start address is what's left
|
||
IMUL T4,BYTPWD ;[2262] Number of bytes available
|
||
LDB T1,[POINT 6,W1,5] ;[2262] Get the byte position
|
||
MOVE T3,BYTSIZ ;[2262] Get the byte size
|
||
IDIVI T1,(T3) ;[2262] See how many bytes left in first word
|
||
ADD T1,T4 ;[2262] Add bytes in first word
|
||
POPJ P, ;[2262] Return
|
||
|
||
E$$USD::.ERR. (MS,.EC,V%L,L%W,S%W,USD,<Undefined symbol >) ;[2262]
|
||
.ETC. (SBX,.EC!.EP,,,,W2) ;[2262]
|
||
.ETC. (STR,.EC,,,,,< in sparse data (type 1160) block>) ;[2262]
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[2262] Type the filename
|
||
JRST T1000C ;[2262] Ignore this block
|
||
|
||
.ZZ==.TEMP ;[2262] Allocate .TEMP space
|
||
U (BYTADR) ;[2262] First address for data store
|
||
U (BYTSIZ) ;[2262] Byte size
|
||
U (BYTCNT) ;[2262] Byte count
|
||
U (BYTPOS) ;[2262] Byte position
|
||
U (BYTPWD) ;[2262] Bytes per word
|
||
U (SRCCNT) ;[2262] Number of source bytes in buffer
|
||
U (DSTCNT) ;[2262] Number of destination bytes in window
|
||
U (LSTBYT) ;[2262] Last byte address
|
||
U (FILCHR) ;[2262] Fill Character
|
||
U (FILCNT) ;[2262] Fill count
|
||
U (REPCNT) ;[2262] Repetition count
|
||
|
||
;[2262] The next two words must be contiguous
|
||
U (BUFBEG) ;[2262] Beginning of buffer area copied
|
||
U (BUFLEN) ;[2262] Amount in buffer at beginning of copy
|
||
|
||
;[2262] The following four words must be contiguous
|
||
U (SRC.LB) ;[2262] TAB.LB(R) FOR SOURCE
|
||
U (SRC.AB) ;[2262] TAB.AB(R) FOR SOURCE
|
||
U (SRC.LW) ;[2262] TAB.LW(R) FOR SOURCE
|
||
U (SRC.UW) ;[2262] TAB.UW(R) FOR SOURCE
|
||
|
||
;[2262] The following four words must be contiguous
|
||
U (DST.LB) ;[2262] TAB.LB(R) FOR DESTINATION
|
||
U (DST.AB) ;[2262] TAB.AB(R) FOR DESTINATION
|
||
U (DST.LW) ;[2262] TAB.LW(R) FOR DESTINATION
|
||
U (DST.UW) ;[2262] TAB.UW(R) FOR DESTINATION
|
||
|
||
STDATA::
|
||
; Reads data out of a block without doing any relocation.
|
||
; Returns IOWD to storage in DY area holding the data in register W2.
|
||
; Uses T1-T2 and W1-W3.
|
||
|
||
HRRZ T2,WC ;[1471] GET BLOCKSIZE
|
||
TDO T2,[-1,,400000] ;[1471]
|
||
HRLM T2,WC ;[1471] SUBBLOCK=BLOCK
|
||
MOVNS T2 ;[1471] NOW POSITIVE
|
||
PUSHJ P,DY.GET## ;[1471] TO HOLD THE INFO
|
||
MOVE W3,T1 ;[1701] SAVE A PTR
|
||
MOVNS T2 ;[1701]
|
||
HRL W3,T2 ;[1701] MAKE W3 AN AOBJN PTR
|
||
MOVE W2,W3 ;[1701] W2 IS A BASE PTR
|
||
STDATL: PUSHJ P,D.IN1## ;[1471] PICK UP A WORD
|
||
MOVEM W1,(W3) ;[1471] STORE THE DATA
|
||
AOBJP W3,CPOPJ ;[1704] ALL DATA READ, NOW PROCESS IT
|
||
JRST STDATL ;[1471] GET ANOTHER WORD
|
||
|
||
|
||
SUBTTL THE END
|
||
|
||
|
||
NEWLIT: END
|