;TITLE MAP - DECsystem-10 page mapper SUBTTL D. P. Mastrovito /DPM ;COPYRIGHT (C) 1980,1981,1982,1983,1984,1985,1986 BY ;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; ;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. ; Version numbers ; MAPMAJ==2 ;MAJOR VERSION MAPMIN==0 ;MINOR VERSION MAPEDT==57 ;EDIT NUMBER MAPWHO==0 ;WHO DID IT %%MAP== MAPDAY=="20" ;BUILD DAY MAPMON=="Mar" ;BUILD MONTH MAPYER=="86" ;BUILD YEAR SALL ;FOR CLEAN LISTINGS .DIRECT FLBLST ;FOR CLEANER LISTINGS SUBTTL Table of Contents ; Table of Contents for MAP %2(35) ; ; ; Section Page ; 1. Table of contents. . . . . . . . . . . . . . . . . . . 2 ; 2. Revision history . . . . . . . . . . . . . . . . . . . 3 ; 3. Compiler interface setup . . . . . . . . . . . . . . . 5 ; 4. Program interface definitions. . . . . . . . . . . . . 8 ; 5. Internal definitions . . . . . . . . . . . . . . . . . 9 ; 6. .MAPD - Deposit. . . . . . . . . . . . . . . . . . . . 11 ; 7. .MAPE - Examine. . . . . . . . . . . . . . . . . . . . 12 ; 8. .MAPG - GETTAB UUO simulation. . . . . . . . . . . . . 13 ; 9. .MAPI - Initialization . . . . . . . . . . . . . . . . 18 ; 10. .MAPJ - JOBPEK UUO simulation. . . . . . . . . . . . . 25 ; 11. Address mapping ; 11.1. Compute a mapped address. . . . . . . . . . . 27 ; 11.2. Convert virtual to physical addresses . . . . 28 ; 11.3. Copy a block of mapped data . . . . . . . . . 30 ; 11.4. KA relocation and protection. . . . . . . . . 31 ; 11.5. KI paging . . . . . . . . . . . . . . . . . . 32 ; 11.6. KL paging . . . . . . . . . . . . . . . . . . 33 ; 11.7. Dispatch tables . . . . . . . . . . . . . . . 35 ; 11.8. Monitor . . . . . . . . . . . . . . . . . . . 36 ; 11.9. Job . . . . . . . . . . . . . . . . . . . . . 38 ; 11.10. File. . . . . . . . . . . . . . . . . . . . . 40 ; 12. Cache management ; 12.1. Clear out the cache . . . . . . . . . . . . . 42 ; 12.2. Map the cache . . . . . . . . . . . . . . . . 43 ; 12.3. Set up the hash tables and links. . . . . . . 45 ; 12.4. Set cache size. . . . . . . . . . . . . . . . 46 ; 12.5. Allocate a chunk for the cache. . . . . . . . 47 ; 12.6. Deallocate a page from the cache. . . . . . . 48 ; 12.7. Find an entry in the cache. . . . . . . . . . 49 ; 12.8. Insert (replace) a new page in the cache. . . 50 ; 12.9. Move entry to top of list . . . . . . . . . . 51 ; 13. Text I/O ; 13.1. Character . . . . . . . . . . . . . . . . . . 52 ; 13.2. ASCIZ . . . . . . . . . . . . . . . . . . . . 53 ; 13.3. Sixbit. . . . . . . . . . . . . . . . . . . . 54 ; 13.4. Octal . . . . . . . . . . . . . . . . . . . . 55 ; 13.5. Filespec. . . . . . . . . . . . . . . . . . . 56 ; 13.6. Miscellaneous . . . . . . . . . . . . . . . . 57 ; 14. Paging ; 14.1. Check accessibility . . . . . . . . . . . . . 58 ; 14.2. Create/Destroy. . . . . . . . . . . . . . . . 59 ; 14.3. SPY page creation . . . . . . . . . . . . . . 60 ; 15. File I/O ; 15.1. Open a file . . . . . . . . . . . . . . . . . 61 ; 15.2. Close a file. . . . . . . . . . . . . . . . . 63 ; 15.3. Position a file . . . . . . . . . . . . . . . 64 ; 15.4. Input/Output. . . . . . . . . . . . . . . . . 65 ; 15.5. Scan a filespec . . . . . . . . . . . . . . . 66 ; 16. EXE file routines ; 16.1. Load and validate directory . . . . . . . . . 69 ; 16.2. Find a file page. . . . . . . . . . . . . . . 71 ; 16.3. Find a directory block. . . . . . . . . . . . 72 ; 17. FORTRAN interface. . . . . . . . . . . . . . . . . . . 73 ; 18. Context switch . . . . . . . . . . . . . . . . . . . . 74 ; 19. Error handling . . . . . . . . . . . . . . . . . . . . 75 ; 20. AC save routines . . . . . . . . . . . . . . . . . . . 82 ; 21. Literals . . . . . . . . . . . . . . . . . . . . . . . 84 ; 22. Data storage . . . . . . . . . . . . . . . . . . . . . 85 ; 23. End. . . . . . . . . . . . . . . . . . . . . . . . . . 86 SUBTTL Revision history ; 1 Creation. Map virtual monitor addresses. ; ; 2 Map physical monitor addresses. ; ; 3 Add job mapping. ; ; 4 Start adding code for file mapping. ; ; 5 Change calling conventions to always use a single AC. Add ; FORTRAN interface. ; ; 6 More work on file mapping. Accept ASCIZ filespecs. ; ; 7 Handle multiple directory page EXE files. ; ; 10 Implement new page caching routines. ; ; 11 Add TITLE. macro. ; ; 12 Shuffle lots of code into a more logical organization. Start ; to clean up initialization code. ; ; 13 Begin adding intelligent error handling. ; ; 14 Edit 10 broke file mapping badly. Make it work again. Remove ; all references to AC 'I' as well as the old paralell mapping ; tables. ; ; 15 Finally add code to handle GETTAB immediate of the range table. ; ; 16 Add support for pathological names. ; ; 17 Attempt to close off old channel from previous call early ; in the .MAPI routine. ; ; 20 Rewrite the FORTRAN interface. /WSM ; ; 21 Finish adding error handling for all non-I/O errors. ; ; 22 Store the CPU and paging type in the data block. ; ; 23 Add support for KL paging shared and indirect pointers. ; ; 24 Avoid an extra GETTAB simulation by reading low core location 22 ; to get paging type and APR serial number. Then convert serial ; number to CPU type. Always use physical addressing when looking ; at low core. ; ; 25 Redefine all FL.??? and FR.??? flags as 18 bit quantities. Fix ; bug in testing for physical pages that caused CSHFND to never ; find a page in the cache sometimes. Add AC save co-routines. ; 26 Remove .MPCOR mapping code and add code to handle virtual vs. ; physical memory addressing correctly. If the first 112K of the ; monitor is mapped one for one virtual to physical, remember this ; so subsequent address calculations can bypass expensive exec ; page mapping code. ; ; 27 Enhance the FORTRAN interface again by making it type out errors ; if the caller doesn't setup a return address. /WSM ; ; 30 Don't terminate text blocks with a NUL. This confuses FORTRAN. ; Zero the blocks instead. Don't use the caller's stack, set up ; an internal one. Invent a flag word in the data block which is ; non-zero if SPYing. Add flag MP.SPY to require SPYing if so ; requested. Remove the 20 page restriction on cache size. The ; sky's the limit or CORMAX (which ever comes first). Return the ; sixbit prefix so a superior program can do intelligent things. ; ; 31 Add support for reading funny space. Also fix bugs associated ; with KL paging indirect pointers. ; ; 32 GETTAB values for start and end of funny space, and the highest ; unmapped exec address. Remove code to compute these values and ; associated flags. ; ; 33 Speed up JOBPEK simulation by doing either a MOVE and MOVEM, ; DMOVE and DMOVEM, or a BLT to transfer data from mapped pages ; to user pages. Remove COUNT. macro. ; ; 34 Fix up filespec defaulting and better handle sixbit PPNs. ; Remove last references to ACs P1 and P2. ; ; 35 Incorporate the FORTRAN INCLUDE file in the MACRO sources. ; ; 36 Make hardware KI paging work. It's about time! ; ; 37 Make use of new FILOP. function to return the filespec of crash file. ; ; 40 Speed up initialization by a factor of two. ; ; 41 Edit 15 didn't quite make it. Teach OCTOUT about negative numbers. ; Type negative GETTAB tables as -n. ; ; 42 Rework GTBINI extensively by removing old BOOTWD hack to determine ; the CPU and paging type. Use the Exec Data Vector if we can. ; ; 43 Rewrite the TITLE. macro, add build string for WSM. Add symbolic ; offsets for initialization block. Add routine .MAPC to clear ; out the mapper statistics block. Don't set a PATH. block pointer ; if there's no directory (default [-] correctly). ; ; 44 Add crock to check for monitor's high segment being mapped. This ; will allow GETTABs of values in the high segment to work on unrun ; monitors. ; ; 45 In file mode, get the returned filespec with one FILOP. UUO, not ; two. Replace MPIFF% (Initialization Failed for File mapping) with ; a the more general code MPMIP% (Mapper Initialization failure). ; ; 46 Add .MAPI argument .MPDSN to specify the default section number to ; use if an address of 400000,,n is given. This will normally be set ; to zero to things don't break. Also, add an internal argument block ; so programs have to assemble in the argument block length. ; ; 47 Include cosmetic improvements and KL paging patch supplied by ; Joe Smith of the Colorado School of Mines. The KL paging stuff ; fixes an old WHO bug that caused address calculations to fail while ; trying to examine non-zero section addresses in a crash file. ; ; 50 Add copyrights to .MAC, .REL, and .FOR files. ; ; MAP %2(50) released with 7.02 ; ; 51 Add counter .MPJPU to tally up the number of JOBPEK UUOs executed. ; ; 52 Remove references to PAGADR. It's not needed. ; ; 53 During GETTAB initialization, if the highest unmapped exec address ; is known, use it instead of defaulting it to DEFUEA. ; ; 54 Correct FORTRAN definition of .MPJPU (JOBPEK UUOs executed). ; ; 55 Fix typo in error message. Update copyrights. ; ; 56 (RDH) Fix to handle extended/PSECTed monitors - use %CNSUP system ; uptime as "mapped" flag for .EXE files. ; ; 57 Process entry vector blocks in .EXE directories. SUBTTL Macros ; Macros to accumulate text ; DEFINE INIT. (ARG),< DEFINE ARG'.. (TEXT),< DEFINE APPND. (X,Y,Z),)> DEFINE ARG'., > ;END ARG'.. ARG'.. > ;END INIT. ; Macro to build a byte pointer to a masked quantity ; DEFINE POINTR (A,M),_<^L>>-1>>,A,<<^L<&<->>>>> ; Macro to generate calls to the error handler ; DEFINE ERR. (COD,RET),< PUSHJ P,[PUSHJ P,ERROR IFNB ,,,RET] > ; Macro to generate mapping error table entries ; DEFINE MERR. (SYM,TXT),< .XCREF ...ERR, MP'SYM'% ...ERR==...ERR+1 MP'SYM'%==:...ERR ''SYM'',,[ASCIZ |TXT|] > ; Macro to generate a TITLE, build, and version text ; DEFINE TITLE. (NAM,ABV,TXT),< MN1== IFE MN1, IFG MN1,> IFE ABV'MIN-^D26,>> IFE ABV'MIN-^D52,+>> IFN MN1, IFN MN2, MNV==<!MN2> ;; Generate TITLE INIT. (TTL) APPND. (,\ABV'MAJ,) IFN MNV,<APPND. (,\"MNV,)> APPND. (<(>,\ABV'EDT,<)>) IFN ABV'WHO,<APPND. (<->,\ABV'WHO,)> APPND. (< >,'TXT,) TTL. ;; Generate PRINTX INIT. (PTX) APPND. (<PRINTX ['NAM %>,\ABV'MAJ,) IFN MNV,<APPND. (,\"MNV,)> APPND. (<(>,\ABV'EDT,<)>) IFN ABV'WHO,<APPND. (<->,\ABV'WHO,)> APPND. (< >,'TXT,) IFN FTFORTRAN,<APPND. (< FORTRAN interface>,,)> appnd. (<]>,,) IF2,<PTX.> ;; Generate build date INIT. (BLD) APPND. (<ASCIZ |'NAM version >,\ABV'MAJ,) IFN MNV,<APPND. (,\"MNV,)> APPND. (<(>,\ABV'EDT,<)>) IFN ABV'WHO,<APPND. (<->,\ABV'WHO,)> APPND. (< built on >,\"ABV'DAY,<->) APPND. (\"ABV'MON,<->,\"ABV'YER) APPND. (<|>,,) ;; Generate program version INIT. (VER) APPND. (<ASCIZ |'NAM %>,\ABV'MAJ,) IFN MNV,<APPND. (,\"MNV,)> APPND. (<(>,\ABV'EDT,<)>) IFN ABV'WHO,<APPND. (<->,\ABV'WHO,)> APPND. (<|>,,) ;; Generate copyright text INIT. (CPY) IFE COMPILER,< APPND. (<ASCIZ |>,\"15,\"12) APPND. (<'NAM %>,\ABV'MAJ,) IFN MNV,<APPND. (,\"MNV,)> APPND. (<(>,\ABV'EDT,<)>) IFN ABV'WHO,<APPND. (<->,\ABV'WHO,)> APPND. (< 'TXT>,\"15,\"12) > IFN COMPILER,< APPND. (<ASCIZ |>,,) > APPND. (<COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION >,,) APPND. (<1980,1986. ALL RIGHTS RESERVED.>,,) APPND. (\"15,\"12,<|>) > TITLE. (MAP,MAP,<DECsystem-10 page mapper>) DEFINE STR (TEXT),<IFN COMPILER,<ASCIZ |TEXT|>> DEFINE CRLF,<IFN COMPILER,<BYTE(7)15,12>> DEFINE BLK% (MAC,FOR,WDS),< MAC==:<FOR==:OFFSET> CRLF STR < PARAMETER 'FOR = "> STR (\OFFSET) OFFSET==OFFSET+WDS > ;END DEFINE BLK% DEFINE SYM% (MAC,FOR,VAL),< IFDIF <None><MAC>,<MAC==:VAL> IFDIF <None><FOR>,< CRLF STR < PARAMETER 'FOR = "'VAL> > ;END IFDIF > ;END DEFINE SYM% SUBTTL MACRO-10/compiler interface setup OFF==0 ;TURNS A FEATURE TEST OFF ON==1 ;TURNS A FEATURE TEST ON COMPILER==0 ;INITIALLY NO COMPILER CODE HGHORG==400000 ;HIGH SEGMENT ORIGIN DEFINE FT (FTS,VAL),< IFNDEF FT'FTS,FT'FTS==VAL ;;SET DEFAULT VALUE IFN FT'FTS,<FT'FTS==FT'FTS&1> ;;NORMALIZE SETTING COMPILER==COMPILER+<IFN FT'FTS,<1>> ;;MAYBE TURN ON COMPILER CODE > ;END DEFINE FT FT FORTRAN,OFF ;FORTRAN INTERFACE IFG COMPILER-1,< PRINTX ? Multiple interfaces selected PASS2 END > IFE COMPILER,< SEARCH UUOSYM ;FOR TOPS-10 UUO SYMBOLS TWOSEG ;MAKE US SHARABLE RELOC HGHORG ;START LOADING HERE .MAP:: ENTRY .MAP,.MAPI,MAPI ;LOAD IF LIBRARY SEARCH COPYRI: CPY. ;GENERATE COPYRIGHT TEXT BUILD: BLD. ;GENERATE BUILD TEXT VERSIO: VER. ;GENERATE VERSION TEXT > ;END IFE COMPILER IFN COMPILER,<RIM10> SUBTTL Program interface definitions STR < ! > IFN COMPILER,<VER.> STR < ! Definitions for the FORTRAN interface ! !> IFN COMPILER,<CPY.> STR <! ! This file should be INCLUDEd any FORTRAN program ! wanting to use the MAP subroutine. Only flag, ! constants, and offset definitions are in this ! file. Read MAP.MAC for a complete discription of ! the calling sequences for the FORTRAN and MACRO ! interfaces to MAP. > OFFSET==0 STR < ! Initialization block offsets > BLK% .MPFNC, MPIFNC, 1 ; Flag and function code word BLK% .MPNPC, MPINPC, 1 ; Number of pages to cache BLK% .MPSPN, MPISPN, 1 ; Starting page number BLK% .MPDSN, MPIDSN, 1 ; Default section number BLK% .MPARG, MPIARG, 1 ; Function dependant argument ; zero for .MPMON ; job number for .MPJOB ; address of filespec for .MPFIL BLK% .MPMAX, MPDMAX, 0 ; Length of argument block STR < ! Initialization flags > SYM% MP.PPM, MPFPPM, 200000000000 ; Physical page mapping SYM% MP.PAT, MPFPAT, 100000000000 ; Enable patching SYM% MP.EXE, MPFEXE, 040000000000 ; EXE file mapping SYM% MP.PIO, MPFPIO, 020000000000 ; Physical-only OPEN/LOOKUP on file SYM% MP.RTM, MPFRTM, 010000000000 ; Return run time statistics SYM% MP.SIO, MPFSIO, 004000000000 ; Super I/O SYM% MP.JRM, MPFJRM, 002000000000 ; Use JOBPEK UUOs instead of simulation SYM% MP.SPY, MPFSPY, 001000000000 ; Job needs to SPY STR < ! Mapping functions > SYM% .MPMON, MPFMON, 0 ; Map the running monitor (PEEK) SYM% .MPJOB, MPFJOB, 1 ; Map a job in the running monitor (JOBPEK) SYM% .MPFIL, MPFFIL, 2 ; Map a data or EXE file (FILDDT) SYM% .MPFMX, MPFFMX, 2 ; Highest known mapping code STR < ! CPU type codes > SYM% .PDP6, PDP6, 1 ; CP166 processor SYM% .KA10, KA10, 2 ; KA10 processor SYM% .KI10, KI10, 3 ; KI10 processor SYM% .KL10, KL10, 4 ; KL10 processor SYM% .KS10, KS10, 5 ; KS10 processor SYM% .KC10, KC10, 6 ; KC10 processor STR < ! Paging codes > SYM% .KARPR, KARPR, 1 ; KA Relocation & Protection Registers SYM% .KIPAG, KIPAG, 2 ; KI paging on a KI10, KL10, or KS10 SYM% .KLPAG, KLPAG, 3 ; KL paging on a KL10 or KS10 SYM% .KCPAG, KCPAG, 4 ; KL paging on a KC10 STR < ! Random constants > SYM% .AP, None, 1 ; MACRO AC for argument passing SYM% .MPEWD, MPFEWD, 30 ; Length of ASCIZ error buffers SYM% .MPFWD, MPFFWD, 21 ; Length of ASCIZ filespec in words OFFSET==0 STR < ! Data block offsets > BLK% .MPDAT, MPDDAT, 1 ; Count of words in data block BLK% .MPVER, MPDVER, 1 ; MAP version number BLK% .MPSPY, MPDSPY, 1 ; Non-zero if SPYing BLK% .MPCPU, MPDCPU, 1 ; CPU type BLK% .MPPAG, MPDPAG, 1 ; Paging type BLK% .MPPGS, MPDPGS, 1 ; Number of pages availble for mapping BLK% .MPCPC, MPDCPC, 1 ; Cached page count BLK% .MPCPN, MPDCPN, 1 ; Starting cached page number BLK% .MPSEC, MPDSEC, 1 ; Default section number Z.BSTS==OFFSET BLK% .MPPGC, MPDPGC, 1 ; Count of mapped page creates BLK% .MPPGD, MPDPGD, 1 ; Count of mapped page destroys BLK% .MPADR, MPDADR, 1 ; Count of mapped address computations BLK% .MPEXM, MPDEXM, 1 ; Count of mapped examines BLK% .MPDEP, MPDDEP, 1 ; Count of mapped deposits BLK% .MPGTB, MPDGTB, 1 ; Count of mapped GETTABs BLK% .MPGTU, MPDGTU, 1 ; Count of GETTAB UUOs executed BLK% .MPJPK, MPDJPK, 1 ; Count of mapped JOBPEK UUOs BLK% .MPJPU, MPDJPU, 1 ; Count of JOBPEK UUOs executed BLK% .MPRTM, MPDRTM, 1 ; Run time BLK% .MPHSF, MPDHSF, 1 ; Count of hash table searches Z.ESTS==OFFSET BLK% .MPHSC, MPDHSC, 1 ; Count of hash table collisions BLK% .MPAFS, MPDAFS, .MPFWD ; Actual filespec BLK% .MPECD, MPDECD, 1 ; Mapping error code BLK% .MPPFX, MPDPFX, 1 ; Right justified sixbit prefix BLK% .MPMET, MPDMET, .MPEWD ; Mapping error text BLK% .MPXET, MPDXET, .MPEWD ; Extended error text BLK% .MPLEN, MPDLEN, 0 ; Length of data block IFN COMPILER,<END> SUBTTL Internal definitions ; Accumulators ; T1==1 ;FOUR T2==2 ; TEMPORARY T3==3 ; ACS T4==4 ; ... A1==5 ;4 ACS USED FOR A2==6 ; MAPPED ADDRESS A3==7 ; CALCULATIONS & A4==10 ; CACHE HANDLING VMA==11 ;VIRTUAL MEMORY ADDRESS PMA==12 ;PHYSICAL MEMORY ADDRESS SPT==13 ;SPT BASE ADDRESS F==14 ;FLAGS P==17 ;PDL .AP==T1 ;USER COMMUMICATES THROUGH THIS AC ; Random values ; PDLSIZ==50 ;INTERNAL PDL SIZE PAGSIZ==1000 ;SIZE OF A PAGE IN WORDS PAGNUM==^D20 ;DEFAULT NUMBER OF PAGES TO MAP HGHPAG==700 ;HIGHEST PAGE NUMBER +1 TO USE DEFPAG==HGHPAG-PAGNUM ;DEFAULT STARTING PAGE NUMBER ABSTAB==410 ;ADDRESS OF POINTER TO NUMTAB DEFEPT==1000 ;DEFAULT EPT ADDRESS DEFUEA==<<^D112*^D1024>-1> ;DEFAULT HIGHEST UNMAPPED EXEC ADDRESS DEFPBA==<^D112*^D1024> ;DEFAULT PER-PROCESS BEGINNING ADDRESS DEFPEA==<<^D112+^D16>*^D1024> ;DEFAULT PER-PROCESS ENDING ADDRESS DEFORG==400000 ;DEFAULT MONITOR'S HIGH SEGMENT ORIGIN FOPSIZ==.FOMAX ;SIZE OF A FILOP. UUO BLOCK LERSIZ==.RBMAX ;SIZE OF A LOOKUP/ENTER UUO BLOCK PTHSIZ==.PTLEL ;SIZE OF A PATH. UUO BLOCK FILSIZ==.FOFMX ;SIZE OF A RETURNED FILESPEC BLOCK ; Cache blocks ; ...X==. PHASE 0 .CBNHB:! BLOCK 1 ;NEXT HASH BLOCK .CBPHB:! BLOCK 1 ;PREVIOUS HASH BLOCK .CBNAB:! BLOCK 1 ;NEXT ACCESSED BLOCK .CBPAB:! BLOCK 1 ;PREVIOUS ACCESS BLOCK .CBPRC:! BLOCK 1 ;PROCESS PAGE NUMBER .CBUSR:! BLOCK 1 ;USER PAGE NUMBER .CBFLG:! BLOCK 1 ;FLAGS CB.AVA==1B0 ;CHUNK IS FREE CB.CRE==1B1 ;USER PAGE HAS BEEN CREATED CB.PHY==1B2 ;PHYSICAL PAGE (NOT VIRTUAL) CB.UPD==1B3 ;UPDATE PAGE ON NEXT REPLACE .CBLEN:! ;LENGTH DEPHASE ; RELOC ...X PURGE ...X ; Copy block offsets ; ...X==. PHASE 0 .CBWCT:! BLOCK 1 ;WORD COUNT .CBRAD:! BLOCK 1 ;READ ADDRESS (SOURCE) .CBWAD:! BLOCK 1 ;WRITE ADDRESS (DESTINATION) .CBXLN:! ;LENGTH DEPHASE ; RELOC ...X PURGE ...X SECTAB==540 ;OFFSET IN EPT OR UPT OF FIRST SECTION MAP POINTER MXSECN==37 ;MAXIMUM NUMBER OF SECTIONS ON A KL10 ; Flags in AC 'F' ; FL.XXX==400000 ;RESERVED FL.PPM==200000 ;.MAPI FLAG - PHYSICAL PAGE MAPPING FL.PAT==100000 ;.MAPI FLAG - PATCH FL.EXE== 40000 ;.MAPI FLAG - .EXE FILE MAPPING FL.PIO== 20000 ;.MAPI FLAG - PHYSICAL FILE I/O FL.RTM== 10000 ;.MAPI FLAG - RETURN RUNTIM STATISTICS FL.SIO== 4000 ;.MAPI FLAG - SUPER I/O FL.JRM== 2000 ;.MAPI FLAG - JOBPEK UUOS ON MONITOR FL.SPY== 1000 ;.MAPI FLAG - JOB NEEDS SPY/WE CAN SPY FL.INI==377000 ;.MAPI FLAGS FL.EPM== 100 ;EXEC PHYSICAL PAGE MAPPING FL.TPP== 40 ;TEMPORARY PHYSICAL PAGE MAPPING FL.GTS== 20 ;GETTAB SIMULATION SETUP FL.DEV== 10 ;FILESPEC SCANNER - DEVICE FL.NAM== 4 ;FILESPEC SCANNER - FILE NAME FL.EXT== 2 ;FILESPEC SCANNER - EXTENSION FL.DIR== 1 ;FILESPEC SCANNER - DIRECTORY FR.TYP==777777 ;MAPPING TYPE SUBTTL .MAPC - Clear out mapper statistics ; Routine to clear out the mapper statistics block ; Call: PUSHJ P,.MAPC ; <NON-SKIP> ; <SKIP> ; .MAPC:: PUSHJ P,CONTXT ;CONTEXT SWITCH MOVEI T1,MAPDAT ;POINT TO START OF MAPPER DATA SETZM Z.BSTS(T1) ;CLEAR FIRST WORD MOVSI T2,Z.BSTS(T1) ;GET START ADDRESS HRRI T2,Z.BSTS+1(T1) ;MAKE A BLT POINTER BLT T2,Z.ESTS-1(T1) ;CLEAR THE BLOCK JRST CPOPJ1 ;AND RETURN SUBTTL .MAPD - Deposit ; Deposit into a mapped location ; Call: MOVE .AP, ADDR ; PUSHJ P,.MAPD ; <NON-SKIP> ;FAILED ; <SKIP> ;SUCEEDED, ACS UNCHANGED ; ; ADDR: address to deposit into ; old contents ; new contents ; .MAPD:: PUSHJ P,CONTXT ;CONTEXT SWITCH MOVEI T1,3 ;3 WORDS IN BLOCK MOVE T2,USRACS+.AP ;GET ARG POINTER MOVE T1,0(T2) ;GET WORD 0 MOVEM T1,POKBLK+0 ;SAVE MOVE T1,1(T2) ;GET WORD 1 MOVEM T1,POKBLK+1 ;SAVE MOVE T1,2(T2) ;GET WORD 2 MOVEM T1,POKBLK+2 ;SAVE MOVE T1,POKBLK+0 ;GET ADDRESS TO DESPOSIT INTO PUSHJ P,ADDRESS ;COMPUTE A MAPPED ADDRESS ERR. (DAF,CPOPJ) ;DEPOSIT ADDRESS FAILURE MOVE T2,(T1) ;GET CONTENTS CAME T2,POKBLK+1 ;WHAT THE USER THINKS IT SHOULD BE? ERR. (DVM,CPOPJ) ;DEPOSIT VALUE DOESN'T MATCH CAMN T2,POKBLK+2 ;OLD CONTENTS SAME AS NEW CONTENTS? JRST CPOPJ1 ;YES - THEN NOTHING TO DO MOVE T3,POKBLK+2 ;GET WORD TO DEPOSIT PUSHJ P,@DEPTAB(F) ;DO IT POPJ P, ;FAILED AOS MAPDAT+.MPDEP ;COUNT THE DEPOSIT JRST CPOPJ1 ;RETURN SUBTTL .MAPE - Examine ; Examine a mapped location ; Call: MOVE T1, address ; PUSHJ P,.MAPE ; <NON-SKIP> ;FAILED ; <SKIP> ;SUCEEDED, T1:= C(ADDR) ; .MAPE:: PUSHJ P,CONTXT ;CONTEXT SWITCH MOVE T1,USRACS+.AP ;GET REAL T1 PUSHJ P,EXAMINE ;DO THE EXAMINE POPJ P, ;CAN'T MOVEM T1,USRACS+.AP ;STORE IN REAL T1 JRST CPOPJ1 ;RETURN PEXAMINE:TLOA F,FL.TPP ;ALLOW PHYSICAL PAGE MAPPING VEXAMINE:TLZ F,FL.TPP ;ALLOW VIRTUAL PAGE MAPPING EXAMINE:PUSHJ P,ADDRESS ;COMPUTE MAPPED ADDRESS ERR. (EAF,CPOPJ) ;EXAMINE ADDRESS FAILURE MOVE T1,(T1) ;GET CONTENTS AOS MAPDAT+.MPEXM ;COUNT THE EXAMINE JRST CPOPJ1 ;AND RETURN SUBTTL .MAPG - GETTAB UUO simulation ; This routine will simulate a GETTAB UUO. The calling sequence is exactly ; like a GETTAB UUO. If the simulation fails, and monitor mapping is being ; done, a GETTAB UUO will be tried. A skip return implies the requested ; monitor information has been retrieved. A non-skip return means the GETTAB ; arguments are illegal. ; ; Historical note: ; The GETTAB UUO (CALLI 41) is new with the 3.19 monitor release. The UUO was ; implemented to allow unprivileged programs to examine various monitor tables. ; CALL: HRROI AC, MONITOR JOB TABLE NUMBER ;NEG. TABLES FOR CUSTOMER ; HRLI AC, JOB NUMBER ;LH .EQ. -1 CURRENT JOB ; ;LH .EQ. -2 CURRENT HIGH-SEG ; CALL AC, [SIXBIT /GETTAB/] ;OR CALLI AC,41 ; .MAPG:: PUSHJ P,CONTXT ;CONTEXT SWITCH MOVE T1,USRACS+.AP ;GET REAL T1 PUSHJ P,GTBSIM ;DO THE GETTAB SIMULATION SKIPA ;FAILED AOS (P) ;SKIP MOVEM T1,USRACS+.AP ;STORE IN REAL T1 POPJ P, ;AND RETURN GTBSIM: MOVEM T1,GTBARG ;SAVE THE ARGUMENT HRRES T1 ;GET THE TABLE NUMBER CAIN T1,.GTIDX ;RANGE TABLE? HLRE T1,GTBARG ;YES--GET INDEX (TABLE NUMBER) ADD T1,NUMTAB ;OFFSET INTO NUMTAB PUSHJ P,EXAMINE ;READ NUMTAB ENTRY JRST GTBS.1 ;MAYBE NO PRIVS MOVEM T1,GTBNUM ;STORE FOR LATER LDB T1,GTBTYP ;GET TABLE TYPE CODE TLNE F,FL.GTS ;GETTAB SIMULATION SETUP? CAIL T1,GTBLEN ;DO WE KNOW ABOUT THIS TABLE? GTBS.1: MOVEI T1,0 ;NO--INDEX ZERO TO ATTEMPT GETTAB UUO MOVEM T1,GTBIDX ;SAVE INDEX FOR LATER HRRZ T2,GTBARG ;GET THE TABLE NUMBER CAIN T2,.GTIDX ;THE RANGE TABLE? MOVEI T1,.SLIXR ;YES PUSHJ P,@GTBTAB(T1) ;DO SOMETHING SKIPA T1,GTBIDX ;GET INDEX IF SIMULATION FAILED JRST GTBS.2 ;GOT IT JUMPN T1,GTBS.1 ;TRY THE UUO IF WE CAN MOVE T1,GTBARG ;LOST AGAIN--RELOAD THE ARGUMENT ERR. (GUF,CPOPJ) ;GETTAB UUO/SIMULATION FAILED GTBS.2: AOS MAPDAT+.MPGTB ;COUNT THE GETTAB JRST CPOPJ1 ;RETURN ; GETTAB simulator dispatch table ; GTBTAB: EXP UNKNTB ;UNKNOWN TABLE EXP ITEMTB ;ITEM NUMBER EXP JOBNTB ;JOB NUMBER EXP SEGNTB ;SEGMENT NUMBER EXP JPDBTB ;JOB NUMBER (DATA IN PDB) EXP RNGETB ;NEGATIVE AND POSITIVE NUMBERS GTBLEN==.-GTBTAB ;LENGTH OF TABLE ; Byte pointers to parts of GETTAB arguments. ; GTBMAX: POINTR (GTBNUM,SL.MAX) ;MAXIMUM ITEM NUMBER IN TABLE GTBTYP: POINTR (GTBNUM,SL.TYP) ;TYPE OF TABLE IDENTIFIER GTBMAC: POINTR (GTBNUM,SL.MAC) ;A MONITOR AC NUMBER GTBADR: POINTR (GTBNUM,SL.ADR) ;EXECUTIVE MODE ADDRESS OF TABLE IF ; SL.TYP=1,2,3 OR OFFSET TO PDB IF ; SL.TYP=4 ; GETTAB table types. The values here MUST correspond to the order of ; GTBTAB. They are included for documentation purposes and to force ; them into the symbol table, but are never referenced directly. ; .SLNIC==.SLNIC ;(0) NOT INCLUDED IN THIS CONFIGURATION .SLIXI==.SLIXI ;(1) INDEX BY ITEM NUMBER .SLIXJ==.SLIXJ ;(2) INDEX BY JOB NUMBER .SLIXS==.SLIXS ;(3) INDEX BY JOB NUMBER OR SEGMENT NUMBER .SLIXP==.SLIXP ;(4) INDEX BY JOB NUMBER (DATA IN PDB) .SLIXR==.SLIXR ;(5) INDEX BY NEGATIVE AND POSITIVE OFFSETS ; BITS 12,13 RESERVED FOR DEC ; Masks of low and high ranges of GETTAB tables indexed by negative and ; positive numbers (table type SL.IXR). These are never referenced but ; are included for documantaion and to force the symbols into the symbol ; table. ; ID.MIN==ID.MIN ;LOW RANGE OF TABLE ID.MAX==ID.MAX ;HIGH RANGE OF TABLE ; Unknown table type ; UNKNTB: MOVE T1,GTBARG ;PICK UP USER ARGUMENTS HRRZ T2,F ;GET JUST THE MAPPING TYPE CAIN T2,.MPMON ;MAPPING A RUNNING MONITOR? GETTAB T1, ;YES - TRY THE GETTAB UUO SOS (P) ;LOSE AOS MAPDAT+.MPGTU ;COUNT NUMBER OF GETTAB UUOS EXECUTED JRST CPOPJ1 ;RETURN ; Item table type ; ITEMTB: HLRE T1,GTBARG ;GET REQUESTED ITEM NUMBER LDB T2,GTBMAX ;GET MAXIMUM LENGTH OF THE TABLE SKIPL T1 ;NEGATIVE INDEX IS ILLEGAL CAMLE T1,T2 ;WITHIN LEGAL RANGE? POPJ P, ;NOPE LDB T2,GTBADR ;GET TABLE BASE ADDRESS ADD T1,T2 ;OFFSET INTO TABLE PUSHJ P,EXAMINE ;GET C(T1) POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN SUCESSFUL ; Job table type ; JOBNTB: HLRE T1,GTBARG ;GET JOB NUMBER CAMN T1,[-1] ;OUR JOB? MOVE T1,USRJOB ;YES - GET IT SKIPL T1 ;CAN'T HAVE A NEGATIVE JOB NUMBER CAMLE T1,JOBN ;WITHIN LEGAL RANGE? POPJ P, ;NOPE LDB T2,GTBADR ;GET TABLE BASE ADDRESS ADD T1,T2 ;INDEX INTO TABLE PUSHJ P,EXAMINE ;GET C(T1) POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN SUCESSFUL ; Segment table type ; SEGNTB: HLRE T1,GTBARG ;GET SEGMENT NUMBER CAMN T1,[-1] ;OUR JOB NUMBER? MOVE T1,USRJOB ;YES - LOAD OUR JOB NUMBER CAME T1,[-2] ;OUR SEGMENT NUMBER? JRST SEGN.1 ;NO MOVE T1,JBTSGN ;GET JOB TO SEG TRANSLATION ADD T1,USRJOB ;ADD IN OUR JOB NUMBER PUSHJ P,EXAMINE ;GET C(T1) POPJ P, ;CAN'T HRRZS T1 ;KEEP JUST THE SEGMENT NUMBER JUMPE T1,CPOPJ ;RETURN IF NO HIGH SEGMENT SEGN.1: SKIPL T1 ;CAN'T HAVE NEGATIVE JOB OR SEG NUMBERS CAMLE T1,SEGN ;WITHIN LEGAL RANGE? POPJ P, ;NOPE LDB T2,GTBADR ;GET TABLE BASE ADDRESS ADD T1,T2 ;OFFSET INTO TABLE PUSHJ P,EXAMINE ;GET C(T1) POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN SUCESSFUL ; PDB table type ; JPDBTB: HLRE T1,GTBARG ;GET INDEX CAMN T1,[-1] ;IS IT OUR JOB? MOVE T1,USRJOB ;YES - LOAD JOB NUMBER SKIPL T1 ;CAN'T HAVE NEGATIVE JOB NUMBERS CAMLE T1,JOBN ;WITHIN LEGAL RANGE? POPJ P, ;NOPE ADD T1,JBTPDB ;OFFSET INTO JBTPDB PUSHJ P,EXAMINE ;GET C(T1) POPJ P, ;CAN'T JUMPE T1,CPOPJ ;A PDB FOR REQUESTED JOB? HRRZS T1 ;KEEP JUST THE ADDRESS LDB T2,GTBADR ;GET INDEX INTO THE PDB ADD T1,T2 ;OFFSET INTO THE PDB PUSHJ P,EXAMINE ;GET C(T1) POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN SUCESSFUL RNGETB: LDB T1,GTBMAX ;GET MAXIMUM LENGTH OF THE TABLE LDB T2,GTBTYP ;GET TABLE TYPE? CAIE T2,.SLIXR ;INDEXED BY RANGE? JRST CPOPJ1 ;NO--FAKED OUT BY GTBSIM ADD T1,RNGTAB ;INDEX INTO RNGTAB PUSHJ P,EXAMINE ;GET RANGE OF GETTAB TABLE POPJ P, ;CAN'T MOVEM T1,GTBRNG ;SAVE RANGE HLRE T2,T1 ;GET LOWER LIMIT HRRE T3,T1 ;GET UPPER LIMIT HLRE T1,GTBARG ;GET USER SUPPLIED INDEX CAMG T1,T3 ;GREATER THAN UPPER LIMIT? CAMGE T1,T2 ;GREATER THAN OR EQUAL TO LOWER LIMIT? POPJ P, ;NOPE HRRE T2,GTBARG ;GET SUPPLIED TABLE NUMBER CAIN T2,.GTIDX ;RANGE TABLE? JRST RNGE.1 ;YES LDB T2,GTBADR ;GET THE BASE ADDRESS OF THE TABLE ADD T1,T2 ;ADD OFFSET PUSHJ P,EXAMINE ;GET C(T1) POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN SUCESSFUL RNGE.1: MOVE T1,GTBRNG ;GET LOWER,,UPPER LIMITS JRST CPOPJ1 ;AND RETURN SUBTTL .MAPI - Initialization ; This routine MUST be called before all others ; Call: MOVE .AP, flags + argument ; PUSHJ P,.MAPI ; <NON-SKIP> ;FAILED ; <SKIP> ;SUCEEDED ; .MAPI:: PUSH P,T1 ;SAVE T1 PUSH P,FILCHN ;SAVE OLD CHANNEL NUMBER MOVE T1,[ZBEG,,ZBEG+1] ;SET UP BLT SETZM ZBEG ;CLEAR FIRST WORD BLT T1,ZEND-1 ;CLEAR OUR DATA STORAGE POP P,FILCHN ;RESTORE OLD CHANNEL NUMBER POP P,T1 ;RESTORE T1 SETOM CTXFLG ;INIT CONTEXT FLAG PUSHJ P,CONTXT ;SAVE THE WORLD PUSHJ P,DATINI ;GET INITIALIZE DATA JRST MAPI.E ;CAN'T PUSHJ P,CSHCLR ;CLEAR OUT THE CACHE PUSHJ P,CSHMAP ;MAP THE HASH TABLE AND CHUNK PAGES JRST MAPI.E ;FAILED PUSHJ P,FILCLS ;CLOSE OFF CHANNEL FROM PREVIOUS CALL PUSHJ P,@INITAB(F) ;SETUP MAPPING JRST MAPI.E ;FAILED PUSHJ P,CSHINI ;SET UP HASH TABLE CHUNKS AND LINKS MOVE A1,PAGCNT ;GET COUNT OF AVAILABLE PAGES SETZM PAGCNT ;SO WE DON'T CONFUSE THINGS PUSHJ P,CSHSIZ ;SET UP CACHE SIZE JRST MAPI.E ;CAN'T PUSHJ P,SPYCHK ;SEE IF WE NEED TO SPY JRST MAPI.E ;NEED TO BUT CAN'T DO IT PUSHJ P,GTBINI ;INITIALIZE GETTAB STUFF AOS (P) ;SKIP MAPI.E: MOVEI T1,MAPDAT ;GET ADDRESS OF DATA BLOCK MOVEM T1,USRACS+.AP ;GIVE IT TO THE CALLER POPJ P, ;RETURN ; Data block setup ; DATINI: MOVEI T1,.MPLEN ;GET LENGTH OF DATA BLOCK MOVEM T1,MAPDAT+.MPDAT ;SAVE IT MOVE T1,[%%MAP] ;GET OUR VERSION MOVEM T1,MAPDAT+.MPVER ;SAVE IT MOVE T2,USRACS+.AP ;GET ARG POINTER MOVE F,.MPFNC(T2) ;GET FLAGS AND MAPPING TYPE AND F,[FL.INI,,FR.TYP] ;MAKE SURE THERE'S NO JUNK HRRZ T1,F ;JUST THE MAPPING TYPE CAILE T1,.MPFMX ;A GOOD NUMBER? ERR. (IMC,CPOPJ) ;ILLEGAL MAPPING TYPE DATI.1: SKIPN T1,.MPNPC(T2) ;GET NUMBER OF PAGES TO USE MOVEI T1,PAGNUM ;NONE--LOAD DEFAULT SKIPE T3,.MPSPN(T2) ;GET STARTING PAGE NUMBER JRST DATI.2 ;GOT SOMETHING MOVEI T3,HGHPAG ;GET HIGHEST PAGE TO USE SUBI T3,(T1) ;T2:= STARTING PAGE NUMBER DATI.2: MOVEM T1,MAPDAT+.MPPGS ;SAVE FOR CURIOUS PROGRAMS MOVEM T1,PAGCNT ;SAVE PAGE COUNT MOVEM T3,MAPDAT+.MPCPN ;SAVE FOR CURIOUS PROGRAMS SKIPGE T1,.MPDSN(T2) ;GET DEFAULT SECTION NUMBER MOVEI T1,0 ;ASSUME ZERO IF CALLER IS STUPID MOVEM T1,MAPDAT+.MPSEC ;SAVE IT JRST CPOPJ1 ;RETURN ; See if we can SPY and if it's required ; SPYCHK: MOVEM F,MAPFLG ;SAVE THE FLAGS AOS MAPDAT+.MPSPY ;ASSUME IT'S ALL GONNA WORK TLO F,FL.SPY ;CHEAT AND PRETEND WE CAN SPY MOVEI T1,0 ;AN ADDRESS TO LOOK AT PUSHJ P,PADDRESS ;LOAD IT INTO THE CACHE SKIPA F,MAPFLG ;CAN'T JRST CPOPJ1 ;GUESS WE CAN SPY SETZM MAPDAT+.MPSPY ;SO THE CALLER KNOW WHATS GOING ON TLZE F,FL.SPY ;DO WE NEED TO SPY? ERR. (ECS,CPOPJ) ;YES--AND WE CAN'T DO IT! JRST CPOPJ1 ;RETURN ; Determine the environment for GETTABing. This routine will try ; to figure out the CPU and paging type by looking at the Exec Data ; Vector and other data. If sucessful, some basic GETTABs will be ; performed for use later during GETTAB simulation. ; GTBINI: TLNE F,FL.PPM ;PHYSICAL PAGE MAPPING? POPJ P, ;THEN GETTABS ARE MEANINGLESS SETZM HGHUEA ;DON'T KNOW THIS ONE YET PJOB T1, ;GET OUR JOB NUMBER MOVEM T1,USRJOB ;SAVE IT SETZ T2, ;INIT INDEX GTBI.1: MOVE T1,GTBEXT+0(T2) ;GET LOCATION SKIPE GTBEXT+1(T2) ;HAVE AN OFFSET? ADD T1,@GTBEXT+1(T2) ;YES--ADD IT IN PUSHJ P,PEXAMINE ;GET C(T1) JRST GTBI.2 ;CAN'T MOVEM T1,@GTBEXT+2(T2) ;STORE RESULT ADDI T2,3 ;ACCOUNT FOR THREE WORD ENTRIES CAIGE T2,GTBEXL ;OFF THE END OF THE TABLE? JRST GTBI.1 ;NO--LOOP HLRZ T1,EDVCNT ;GET EDV CODE HRRZ T2,EDVCNT ;GET WORD COUNT CAIN T1,'EDV' ;LOOKING AT AN EDV? CAIGE T2,.EDEPT ;AND DOES THIS EDV CONTAIN NEEDED DATA? JRST GTBI.2 ;NO MOVE T1,EDVDAT ;GET FLAGS AND CPU DATA TLNE T1,(ED.KLP) ;THIS A KL PAGING MACHING? SETOM KLPFLG ;YES HRRZM T1,MAPDAT+.MPCPU ;SAVE CPU TYPE JRST GTBI.3 ;GO CHECKOUT THE PAGING ; Determine the CPU type. Here if the EDV contains junk or unreasonable ; data. We know at this point that the monitor is pre-702 because the EDV ; is invalid. This implies that the first 112K of the monitor is unmapped ; (KA10 or KI10), or mapped one-for-one virtual-to-physical (KL10). ; GTBI.2: MOVE T1,[%CCTYP] ;ARGUMENT TO RETURN CPU TYPE PUSHJ P,GTBFRC ;TRY THE BRUTE FORCE METHOD POPJ P, ;CAN'T MOVEM T1,MAPDAT+.MPCPU ;SAVE IT SETZM EPTADR ;DON'T BELEIVE THE EPT ADDRESS SETZM KLPFLG ;CLEAR THE KL PAGING FLAG ; Get the paging type ; GTBI.3: SKIPN T1,MAPDAT+.MPCPU ;GET CPU TYPE CODE POPJ P, ;UNKNOWN CPU TYPE MOVEI T2,.KARPR ;KA RELOCATION AND PROTECTION REGISTERS CAIE T1,.PDP6 ;CP166 CPU? CAIN T1,.KA10 ;KA10 CPU? JRST GTBI.4 ;YES TO EITHER CAIE T1,.KI10 ;A KI10 CPU? SKIPN KLPFLG ;WHAT KIND OF PAGING? SKIPA T2,[.KIPAG] ;KI10 MOVEI T2,.KLPAG ;KL10 CAIN T1,.KC10 ;KC10 CPU? MOVEI T2,.KCPAG ;A DIFFERENT FLAVOR OF KL PAGING GTBI.4: MOVEM T2,MAPDAT+.MPPAG ;SAVE PAGING TYPE SKIPLE EPTADR ;HAVE AN EDV? JRST GTBI.5 ;YES--MUST ASSUME THE EPT IS OK MOVE T1,[%CCTOS] ;ARGUMENT TO RETURN THE EPT ADDRESS PUSHJ P,GTBFRC ;TRY TO GET IT POPJ P, ;LOSE MOVEM T1,EPTADR ;SET IT JRST GTBI.5 ;GO DO SOME BASIC GETTABS ; Do some basic GETTABs needed later for GETTAB simulation ; GTBI.5: TLO F,FL.GTS ;LET GTBSIM DO IT'S STUFF SETZ T4, ;CLEAR INDEX GTBI.6: MOVE T1,GTBGTT+0(T4) ;GET A GETTAB ARGUMENT PUSHJ P,GTBSIM ;SIMULATE A GETTAB XCT GTBGTT+1(T4) ;DEFAULT VALUE OR RETURN XCT GTBGTT+2(T4) ;SAVE VALUE ADDI T4,2 ;ACCOUNT FOR THREE WORD ENTRIES CAIGE T4,GTBGTL-1 ;END OF THE TABLE? AOJA T4,GTBI.6 ;NO--LOOP MOVMS SEGN ;MAKE SEGN POSITIVE MOVE T1,JOBN ;GET THE NUMBER OF JOBS ADDM T1,SEGN ;ADD TO TOTAL OF SEGMENTS ; Here to see if the monitor's high segment is mapped yet. We GETTAB ; the system uptime. If it's not equal to zero, then the monitor ; probably ran for some amount of time and the high segment must have ; been mapped. ; GTBI.7: MOVE T1,[%CNSUP] ;SYSTEM UPTIME IN TICS PUSHJ P,GTBFRC ;READ FROM MONITOR/.EXE FILE SETZ T1, ;CAN'T READ, ASSUME NOT "MAPPED" MOVEM T1,HIFLAG ;IF .NE. 0 THEN "HISEG MAPPED" POPJ P, ;RETURN ; Here to do a GETTAB by the brute force method ; GTBFRC: SKIPE HGHUEA ;KNOW THIS ADDR YET? JRST GTBF.1 ;YES MOVEI T2,DEFUEA ;GET DEFAULT HIGHEST UNMAPPED ADDR MOVEM T2,HGHUEA ;SAVE TO WE DON'T DO PHYSICAL MAPPING PUSHJ P,GTBF.1 ;DO THE GETTAB SKIPA ;FAILED AOS (P) ;SKIP SETZM HGHUEA ;PUT BACK THE WAY WE FOUND IT POPJ P, ;AND RETURN GTBF.1: TLO F,FL.GTS ;ALLOW GTBSIM TO DO ITS STUFF PUSHJ P,GTBSIM ;TRY THE GETTAB POPJ P, ;FAILED JRST CPOPJ1 ;RETURN ; Here when we can't determine how to do GETTABs ; GTBI.E: TLZ F,FL.GTS ;COULDN'T SETUP GETTAB SIMULATION POPJ P, ;RETURN ; Table of locations, offsets, and storage words ; GTBEXT: EXP ABSTAB,000000,NUMTAB ;TABLE OF GETTAB TABLE POINTERS EXP .JBEDV,000000,EDVADR ;EDV ADDRESS EXP .EDCNT,EDVADR,EDVCNT ;EDV CODE AND WORD COUNT EXP .EDDAT,EDVADR,EDVDAT ;FLAGS AND CPU DATA EXP .EDEPT,EDVADR,EPTADR ;EPT ADDRESS EXP .EDSPT,EDVADR,SPTADR ;SPT ADDRESS GTBEXL==<.-GTBEXT> ;LENGTH OF TABLE ; Table of GETTAB arguments, defaults, and storage words ; GTBGTT: EXP <%VMHUA>,<MOVEI T1,DEFUEA>,<MOVEM T1,HGHUEA>;HIGHEST UNMAPPED EXEC ADDRESS EXP <%VMPPB>,<MOVEI T1,DEFPBA>,<MOVEM T1,PPABEG>;BEGINING PER-PROCESS ADDRESS EXP <%VMPPE>,<MOVEI T1,DEFPEA>,<MOVEM T1,PPAEND>;END PER-PROCESS ADDRESS EXP <%CNSJN>,<POPJ P,>,<HRRZM T1,JOBN> ;HIGHEST LEGAL JOB EXP <%CNSJN>,<POPJ P,>,<HLREM T1,SEGN> ;HIGHEST LEGAL SEGMENT EXP <%CNPDB>,<POPJ P,>,<HRRZM T1,JBTPDB> ;JBTPDB POINTER EXP <%CNVSH>,<MOVEI T1,DEFORG>,<MOVEM T1,HIORG> ;HIGH SEGMENT ORIGIN EXP <.GTSGN,,.GTSLF>,<POPJ P,>,<HRRZM T1,JBTSGN>;JBTSGN POINTER EXP <.GTIDX,,.GTSLF>,<POPJ P,>,<HRRZM T1,RNGTAB>;RNGTAB POINTER EXP <.GTADR,,.GTSLF>,<POPJ P,>,<HRRZM T1,JBTADR>;JBTADR POINTER EXP <.GTUPM,,.GTSLF>,<POPJ P,>,<HRRZM T1,JBTUPM>;JBTUPM POINTER GTBGTL==.-GTBGTT ;LENGTH OF TABLE SUBTTL .MAPJ - JOBPEK UUO simulation ; Simulate the JOBPEK UUO by by actually tracing down section and ; page maps for all types of paging. ; Call: MOVE .AP, argument address ; PUSHJ P,.MAPJ ; <NON-SKIP> ;FAILED ; <SKIP> ;SUCEEDED ; ; Arg + 0/ <flags>B9+<job>B17+<wordcount>B35 ; Arg + 1/ read address,,write address ; ; All legal JOBPEK flags are valid ; .MAPJ:: PUSHJ P,CONTXT ;CONTEXT SWITCH MOVE T2,USRACS+.AP ;GET ARG POINTER HRRZ T3,F ;GET MAPPING CODE CAIN T3,.MPMON ;MAPPING THE RUNNING MONITOR? TLNN F,FL.JRM ;JOBPEK UUOS ON THE RUNNING MONITOR? SKIPA T1,.MPFNC(T2) ;NO--GET FLAG WORD JRST [JOBPEK T2, ;DO THE UUO ERR. (JRW,CPOPJ) ;JOBPEK FAILED TO READ/WRITE JOB AOS MAPDAT+.MPJPU ;COUNT THE JOBPEK UUO EXECUTION JRST CPOPJ1] ;RETURN MOVEM T1,JPKFLG ;SAVE HRRZM T1,CPYBLK+.CBWCT ;SAVE WORD COUNT HLRZ T1,1(T2) ;GET THE READ ADDRESS MOVEM T1,CPYBLK+.CBRAD ;SAVE IT HRRZ T1,1(T2) ;GET THE WRITE ADDRESS MOVEM T1,CPYBLK+.CBWAD ;SAVE IT PUSHJ P,JPKSIM ;SIMULATE A JOBPEK UUO POPJ P, ;CAN'T JRST CPOPJ1 ;AND RETURN ; Here on internal calls ; JPKSIM: MOVE T1,JPKFLG ;GET FLAG WORD TLNE T1,(JK.UPM) ;READ A UPMP? JRST JPKUPM ;YES TLNE T1,(JK.EVA) ;READ EVM? JRST JPKEVA ;YES JRST JPKRED ;GO READ ; All sucessful JOBPEK code should exit through here ; JPKXIT: AOS MAPDAT+.MPJPK ;COUNT THE JOBPEK SIMULATION JRST CPOPJ1 ;RETURN ; JOBPEK read ; JPKRED: LDB T1,[POINT 9,JPKFLG,17] ;GET JOB NUMBER PUSHJ P,PHYUPT ;GET UPT ADDRESS POPJ P, ;CAN'T MOVE VMA,CPYBLK+.CBRAD ;GET READ ADDRESS PUSHJ P,PHYADR ;MAKE IT ADDRESSIBLE ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE MOVEM PMA,CPYBLK+.CBRAD ;SAVE READ ADDRESS MOVEI T1,CPYBLK ;POINT TO COPY BLOCK PUSHJ P,ADRCPY ;MOVE SOME DATA SKIPE .CBWCT(T1) ;MORE WORDS TO PROCESS? JRST JPKRED ;YES--LOOP BACK FOR MORE JRST JPKXIT ;FINISH UP ; JOBPEK UPMP read ; JPKUPM: TLNE T1,(JK.WRT) ;WANT TO WRITE THE UPMP? ERR. (IWU,CPOPJ) ;ILLEGAL TO WRITE THE UPMP HLRZS T1 ;GET HALF WORD WITH JOB NUMBER ANDI T1,777 ;KEEP JUST THE JOB NUMBER PUSHJ P,PHYUPT ;GET THE UPT ADDRESS POPJ P, ;CAN'T MOVE T1,PMA ;GET UPMP ADDRESS PUSHJ P,PADDRESS ;MAKE IT ADDRESSABLE ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE MOVEM T1,CPYBLK+.CBRAD ;SAVE READ ADDRESS MOVEI T1,CPYBLK ;POINT TO COPY BLOCK PUSHJ P,ADRCPY ;MOVE SOME DATA SKIPE .CBWCT(T1) ;MORE WORDS TO PROCESS? JRST JPKUPM ;YES--LOOP BACK FOR MORE JRST JPKXIT ;FINISH UP ; JOBPEK exec virtual address read ; JPKEVA: TLNE T1,(JK.WRT) ;WANT TO WRITE EVM? ERR. (IWE,CPOPJ) ;ILLEGAL TO WRITE EVM JPKE.1: LDB T1,[POINT 9,JPKFLG,17] ;GET JOB WE'RE GONNA LOOK AT PUSHJ P,PHYUPT ;GET IT'S UPT ADDRESS POPJ P, ;CAN'T MOVE VMA,CPYBLK+.CBRAD ;GET ADDRESS TO CONVERT PUSHJ P,PHYFUN ;COMPUTE MAPPED PHYSICAL FUNNY ADDRESS POPJ P, ;CAN'T MOVEM PMA,CPYBLK+.CBRAD ;SAVE READ ADDRESS MOVEI T1,CPYBLK ;POINT TO COPY BLOCK PUSHJ P,ADRCPY ;MOVE SOME DATA SKIPE .CBWCT(T1) ;MORE WORDS TO PROCESS? JRST JPKE.1 ;YES--LOOP BACK FOR MORE JRST JPKXIT ;FINISH UP SUBTTL Address mapping -- Compute a mapped address ; Call: MOVE T1, address ; PUSHJ P,ADDRESS ; <return> ; PADDRESS:TLOA F,FL.TPP ;ALLOW PHYSICAL PAGE MAPPING VADDRESS:TLZ F,FL.TPP ;ALLOW VIRTUAL PAGE MAPPING ADDRESS:TLZE T1,400000 ;CLEAR "SECTION RELATIVE" REFERENCES HRL T1,MAPDAT+.MPSEC ;LOAD DEFAULT SECTION NUMBER TLNN F,FL.SPY ;CAN WE SPY? ERR. (ECS,CPOPJ) ;NO TLNN F,FL.PPM!FL.TPP ;PHYSICAL PAGE MAPPING? PUSHJ P,@CVTTAB(F) ;SEE IF NECESSARY TO CONVERT ADDRESS JRST ADDR.1 ;NO ADDRESS FIXUP NECESSARY PUSHJ P,SAVEF ;SAVE F PUSHJ P,PHYEPT ;GET PHYSICAL EPT ADDRESS POPJ P, ;CAN'T MOVE VMA,T1 ;GET ADDRESS TO CONVERT PUSHJ P,PHYADR ;COMPUTE MAPPED PHYSICAL ADDRESS POPJ P, ;CAN'T MOVE T1,PMA ;GET ADDRESS OF MAPPED PHYSICAL ADDRESS AOS MAPDAT+.MPADR ;COUNT ADDRESS COMPUTATIONS JRST CPOPJ1 ;AND RETURN ADDR.1: MOVE A1,T1 ;GET ADDRESS TO MAP LSH A1,-11 ;CONVERT TO A PAGE NUMBER PUSHJ P,CSHFND ;SEE IF PAGE IN CACHE JRST ADDR.2 ;NOT FOUND PUSHJ P,CSHMRU ;MOVE TO TOP OF LIST JRST ADDR.4 ;ONWARD ADDR.2: PUSHJ P,CSHINS ;INSERT PAGE IN CACHE MOVSI A3,(CB.CRE) ;GET A BIT TDNN A3,.CBFLG(A2) ;PAGE ALREADY EXIST? JRST ADDR.3 ;NO PUSHJ P,@DESTAB(F) ;DESTROY THE PAGE POPJ P, ;CAN'T AOS MAPDAT+.MPPGD ;COUNT PAGE DESTROY ADDR.3: MOVE A1,T1 ;GET ADDRESS WE'RE GOING TO MAP LSH A1,-11 ;KEEP JUST THE PAGE NUMBER MOVEM A1,.CBPRC(A2) ;STORE NEW PROCESS PAGE NUMBER PUSHJ P,@CRETAB(F) ;CREATE THE PAGE POPJ P, ;CAN'T AOS MAPDAT+.MPPGC ;COUNT PAGE CREATE ADDR.4: MOVE A1,.CBUSR(A2) ;GET USER PAGE NUMBER LSH A1,11 ;CONVERT TO AN ADDRESS ANDI T1,PAGSIZ-1 ;KEEP JUST THE OFFSET INTO THE PAGE IOR T1,A1 ;FORM THE MAPPED ADDRESS AOS MAPDAT+.MPADR ;COUNT ADDRESS COMPUTATIONS JRST CPOPJ1 ;AND RETURN SUBTTL Address mapping -- Convert virtual to physical addresses ; Convert an exec virtual "funny" address to a mapped physical address ; Call: MOVE PMA, physcial address of UPT ; MOVE VMA, exec virtual "funny" address ; PUSHJ P,PHYFUN ; <NON-SKIP> ;FAILED ; <SKIP> ;PMA:= MAPPED PHYSICAL ADDRESS ; PHYFUN: CAML VMA,PPABEG ;RANGE CHECK IT CAML VMA,PPAEND ;MUST BE A "FUNNY PAGE" ADDRESS ERR. (IAD,CPOPJ) ;ILLEGAL ADDRESS MOVEM T1,PAGFUN ;SAVE T1 MOVE T1,MAPDAT+.MPPAG ;GET PAGING TYPE MOVE T1,FUNTAB-1(T1) ;GET FUNNY PAGE POINTER OFFSET IN UPT EXCH T1,PAGFUN ;SAVE IT AND RESTORE T1 JRST PHYCOM ;ENTER COMMON PHYSICAL ADDRESS CODE ; KA rel/prot: No per-process space to map. ; KI paging: The pointer to the first age of funny space (340) comes ; immediately after the pointer for the user's page 777. ; KL paging: The ADDI T1,SECTAB(T4) has to be cancelled, since ; the pointer to page 340 is the 340th word in the ; UPT. TOPS-10 changes the first (and only) word of ; the SPT to contain the address of the UPT whenever ; a context switch occurs. FUNTAB: EXP 0 ;KA RELOCATION AND PROTECTION REGISTERS EXP <777+1>-340 ;KI PAGING ON A KI10, KL10 OR KS10 EXP -SECTAB ;KL PAGING ON A KL10 OR KS10 EXP -SECTAB ;KL PAGING ON A KC10 ; Convert a virtual address to a mapped physical address ; Call: MOVE PMA, physical address of EPT or UPT ; MOVE VMA, virtual address ; PUSHJ P,PHYADR ; <NON-SKIP> ;FAILED ; <SKIP> ;PMA:= MAPPED PHYSICAL ADDRESS ; PHYADR: SETZM PAGFUN ;CLEAR FUNNY PAGE UPT OFFSET PHYCOM: PUSHJ P,SAVT4 ;SAVE T1, T2, T3, AND T4 MOVE T1,PMA ;GET EPT OR UPT ADDRESS MOVE T2,VMA ;GET VIRTUAL ADDRESS TO CONVERT MOVE T3,T2 ;COPY ADDRESS LSH T3,-11 ;CONVERT TO PAGE NUMBER MOVE T4,MAPDAT+.MPPAG ;GET PAGING TYPE PUSHJ P,@PHYTAB-1(T4) ;DISPATCH TO THE PROPER PAGING ROUTINES POPJ P, ;CAN'T CONVERT VRT TO PHY ADDRESS MOVE PMA,T1 ;GET PHYSICAL ADDRESS JRST CPOPJ1 ;AND RETURN PHYTAB: EXP KARPR ;KA RELOCATION AND PROTECTION REGISTERS EXP KIPAG ;KI PAGING ON A KI10, KL10 OR KS10 EXP KLPAG ;KL PAGING ON A KL10 OR KS10 ; EXP KCPAG ;KL PAGING ON A KC10 ; Return the physical address of the boot CPU's EPT ; Call: PUSHJ P,PHYEPT ; <NON-SKIP> ;FAILED ; <SKIP> ;PMA:= PHYSICAL ADDRESS, SPT:= SPT BASE ; PHYEPT: MOVE PMA,EPTADR ;GET THE EPT ADDRESS MOVE SPT,PMA ;HACK FOR TOPS-10 ONE WORD SPT TLO F,FL.EPM ;FLAG EXEC MAPPING TO TAKE PLACE JRST CPOPJ1 ;RETURN ; Return the physical address of a UPT ; Call: MOVE T1, job number ; PUSHJ P,PHYUPT ; <NON-SKIP> ;FAILED ; <SKIP> ;PMA:= PHYSICAL ADDRESS, SPT:= SPT BASE ; PHYUPT: CAMLE T1,JOBN ;RANGE CHECK ERR. (IJN,CPOPJ) ;ILLEGAL JOB NUMBER PUSHJ P,SAVT1 ;SAVE T1 ADD T1,JBTUPM ;OFFSET TO THE JOB'S UPMP ENTRY PUSHJ P,EXAMINE ;READ IT ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE HRRZ PMA,T1 ;UPMP PAGE NUMBER IS A RH QUANTITY JUMPE PMA,[ERR. (JSO,CPOPJ)] ;JOB SWAPPED OUT LSH PMA,11 ;CONVERT TO AN ADDRESS MOVE SPT,PMA ;HACK FOR TOPS-10 ONE WORD SPT JRST CPOPJ1 ;AND RETURN SUBTTL Address mapping -- Copy a block of mapped data ; Copy a mapped block of data ; Call: MOVE T1, copy-block-address ; PUSHJ P,ADRCPY ; ADRCPY: SKIPN A1,.CBWCT(T1) ;GET NUMBER OF WORDS TO MOVE POPJ P, ;NOTHING TO DO CAIG A1,2 ;MOVING A WORD OR TWO? JRST @[EXP ADRC.1 ;1 WORD EXP ADRC.2]-1(A1) ;2 WORDS JRST ADRC.3 ;MORE THAN 2 WORDS ADRC.1: MOVE A2,@.CBRAD(T1) ;GET A WORD MOVEM A2,@.CBWAD(T1) ;PUT A WORD JRST ADRC.4 ;UPDATE ADDRESSES AND RETURN ADRC.2: MOVE A2,.CBRAD(T1) ;GET ADDRESS ADDI A2,1 ;PLUS ONE TRNN A2,PAGSIZ-1 ;OVERFLOW TO THE NEXT PAGE? SOJA A1,ADRC.1 ;YES--JUST MOVE A SINGLE WORD DMOVE A2,@.CBRAD(T1) ;GET TWO WORDS DMOVEM A2,@.CBWAD(T1) ;PUT TWO WORDS JRST ADRC.4 ;UPDATE ADDRESSES AND RETURN ADRC.3: HRLZ A2,.CBRAD(T1) ;GET READ ADDRESS HRR A2,.CBWAD(T1) ;GET WRITE ADDRESS MOVE A3,.CBRAD(T1) ;GET READ ADDRESS AGAIN ADDI A3,PAGSIZ ;ROUND UP A PAGE TRZ A3,PAGSIZ-1 ; BUT NOT BEYOND A PAGE BOUNDRY SUB A3,.CBRAD(T1) ;GET MAXIMUM WORDS WE CAN BLT CAMLE A3,A1 ;TRYING TO MOVE TOO MANY WORDS? SKIPA A3,A1 ;YES--ONLY COPY AS MANY AS REQUESTED MOVE A1,A3 ;MAKE SURE THE COUNTS AGREE ADD A3,.CBWAD(T1) ;COMPUTE LAST ADDRESS +1 BLT A2,-1(A3) ;COPY DATA ADRC.4: EXCH A1,.CBWCT(T1) ;SWAP WORDS XFERED AND REQUESTED NUMBER SUBM A1,.CBWCT(T1) ;UPDATE COUNT ADDM A1,.CBRAD(T1) ;ADJUST SOURCE ADDRESS ADDM A1,.CBWAD(T1) ;ADJUST DESTINATION ADDRESS POPJ P, ;RETURN SUBTTL Address mapping -- KA relocation and protection KARPR: MOVE T3,T1 ;SAVE THE JOB NUMBER ADD T1,JBTADR ;OFFSET INTO THE RELOC AND PROT TABLE TLNN T2,777777 ;256K ADDRESS LIMITATION ON A KA10 PUSHJ P,EXAMINE ;READ THE ENTRY FOR JOB'S LOW SEGMENT ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE HLRZ T4,T1 ;GET PROTECTION CAMG T2,T4 ;WITHIN THE LOW SEGMENT? JRST KARPR3 ;YES KARPR1: SKIPN T1,JBTUPM ;HAVE THIS TABLE? JRST KARPR2 ;NO ADD T1,T3 ;INDEX TO THE LOW SEG ENTRY ADD T1,JOBN ;INDEX TO THE HIGH SEG ENTRY PUSHJ P,EXAMINE ;READ THAT WORD SETZ T1, ;CAN'T JUMPE T1,[ERR. (JNA,CPOPJ)] ;JOB NOT ADDRESSABLE HLRZ T4,T1 ;GET THE HIGH SEGMENT ORIGIN TRZA T4,PAGSIZ-1 ;CLEAR ANY JUNK KARPR2: MOVEI T4,400000 ;USE DEFAULT HIGH SEG ORIGIN MOVE T1,T3 ;GET THE JOB NUMBER BACK AGAIN ADD T1,JBTADR ;OFFSET INTO THE RELOC AND PROT TABLE ADD T1,JOBN ;PLUS JOBN TO GET SEGMENT ENTRY PUSHJ P,EXAMINE ;READ THE ENTRY FOR JOB'S HIGH SEGMENT ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE HLRZ T3,T1 ;GET HIGH SEGMENT LENGTH (PROTECTION) ADDI T3,(T4) ;COMPUTE THE END OF THE SEGMENT CAMG T2,T3 ;ADDRESS WITHIN THE BOUNDS CAMGE T2,T4 ; OF THE HIGH SEGMENT? ERR. (IAD,CPOPJ) ;ILLEGAL ADDRESS SKIPA ;JOIN COMMON CODE KARPR3: MOVEI T4,0 ;LOW SEG ORIGIN IS ZERO TLZ T1,777777 ;KEEP ONLY PHYSICAL RELOCATION ADDRESS SUB T2,T4 ;SUBTRACT SEGMENT ORIGIN ADDI T1,(T2) ;OFFSET TO DESIRED VIRTUAL ADDRESS PUSHJ P,PADDRESS ;MAKE IT ADDRESSIBLE ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE JRST CPOPJ1 ;AND RETURN SUBTTL Address mapping -- KI paging KIPAG: TLZN F,FL.EPM ;DOING EXEC PHYSICAL MAPPING? JRST KIPAG1 ;NO--UPMP DECODING CAIGE T2,^D112*^D1024 ;IS THE ADDRESS IN THE LOWER 112K? JRST KIPAG2 ;YES--THAT'S EASY CAIGE T2,^D128*^D1024 ;BETTER NOT BE IN FUNNY SPACE ERR. (IAD,CPOPJ) ;BECAUSE THATS AN ILLEGAL ADDRESS KIPAG1: LDB T3,[POINT 9,T2,26] ;GET THE TARGET PAGE NUMBER ADD T3,PAGFUN ;INCLUDE FUNNY PAGE OFFSET (IF ANY) LSHC T3,-1 ;DIVIDE BY TWO ADDI T1,(T3) ;COMPUTE UPMP INDEX PUSHJ P,PEXAMINE ;READ THE UPMP ENTRY FOR THAT PAGE ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE TLNN T4,400000 ;ODD PAGE? MOVSS T1 ;NO--SWAP HALVES SO LDB GETS RIGHT PAGE LDB T1,[POINT 13,T1,35] ;GET PAGE NUMBER OF TARGET PAGE LSH T1,11 ;CONVERT TO AN ADDRESS TDZA T2,[-1-<PAGSIZ-1>] ;GET OFFSET INTO THE PAGE KIPAG2: SKIPA T1,T2 ;GET PHYSICAL EXEC ADDRESS ADDI T1,(T2) ;COMPUTE PHYSICAL TARGET ADDRESS PUSHJ P,PADDRESS ;MAKE IT ADDRESSIBLE ERR. (IAD,CPOPJ) ;ILLEGAL ADDRESS JRST CPOPJ1 ;AND RETURN SUBTTL Address mapping -- KL paging KLPAG: MOVNI T4,2 ;GET INITIAL VALUE FOR POINTER FLAG MOVEM T4,PAGFLG ;SET IT HLRZ T4,T2 ;GET SECTION NUMBER CAILE T4,MXSECN ;RANGE CHECK SECTION NUMBER ERR. (IAD,CPOPJ) ;ILLEGAL ADDRESS ADDI T1,SECTAB(T4) ;INDEX INTO SECTION MAP POINTERS SKIPN T4,PAGFUN ;HAVE A FUNNY PAGE OFFSET? JRST KLPAGM ;NO--ONWARD ADD T1,PAGFUN ;INCLUDE FUNNY PAGE OFFSET (IF ANY) ADDI T1,(T3) ;AND OFFSET BY THE FUNNY PAGE NUMBER SETZ T3, ;SO WE DON'T DO USE IT TWICE AOS PAGFLG ;SAY WE'RE POINTING TO A PAGE MAP NOW ; Decode a map entry ; If PAGFLG = -2, T1 has addr in the section map part of EPT/UPT ; If PAGFLG = -1, T1 has addr of entry in the page map for this section ; If PAGFLG = 0, T1 had the mapping for the page in question ; ; T2 has virtual address ; T3 has virtual page number ; KLPAGM: PUSHJ P,PADDRESS ;COMPUTE THE ADDRESS OF A MAP ENTRY ERR. (JNA,CPOPJ) ;JOB NOT ADDRESSABLE AOSLE PAGFLG ;FLAG WHAT WE'RE LOOKING AT JRST KLPAGX ;FOUND THE PAGE WE'RE LOOKING FOR LDB T4,[POINT 3,(T1),2] ;GET THE ENTRY TYPE JRST @KLPAGT(T4) ;DISPATCH BASED ON POINTER TYPE KLPAGT: EXP KLPAG0 ;(0) NO ACCESS EXP KLPAG1 ;(1) IMMEDIATE EXP KLPAG2 ;(2) SHARED EXP KLPAG3 ;(3) INDIRECT EXP KLPAGE ;(4) ILLEGAL EXP KLPAGE ;(5) ILLEGAL EXP KLPAGE ;(6) ILLEGAL EXP KLPAGE ;(7) ILLEGAL KLPAGX: ANDI T2,PAGSIZ-1 ;GET JUST THE INDEX INTO THE PAGE ADDI T1,(T2) ;GET TARGET ADDRESS TO EXAMINE JRST CPOPJ1 ;RETURN KLPAGE: ERR. (UPC,CPOPJ) ;UNIMPLEMENTED KL PAGING CODE ; KL paging code 0 - No access ; KLPAG0: ERR. (NAP,CPOPJ) ;NO ACCESS TO REQUESTED PAGE ; KL paging code 1 - Immediate ; KLPAG1: MOVE T1,(T1) ;GET POINTER TLNE T1,77 ;STORAGE MEDIUM NON-ZERO? (TOPS20) ERR. (PNC,CPOPJ) ;PAGE NOT IN CORE ANDI T1,17777 ;KEEP JUST THE PAGE MAP PAGE NUMBER LSH T1,11 ;CONVERT TO AN ADDRESS SKIPN PAGFLG ;POINTING TO A PAGE MAP FOR A SECTION? JRST KLPAGM ;NO--LOOP BACK AND DECODE MAP POINTER ANDI T3,777 ;KEEP ONLY RELATIVE PAGE # IN SECTION ADDI T1,(T3) ;INDEX INTO PAGE MAP FOR TARGET PAGE SETZ T3, ;CLEAR FOR NEXT TIME JRST KLPAGM ;LOOP BACK AND DECODE MAP POINTER ; KL paging code 2 - Shared ; KLPAG2: HRRZ T1,(T1) ;GET INDEX INTO THE SPT CAIE T1,0 ;RANGE CHECK ERR. (SIR,CPOPJ) ;SPT INDEX OUT OF RANGE ADD T1,SPT ;OFFSET SETOM PAGFLG ;STILL LOOKING AT A PAGE MAP JRST KLPAGM ;LOOP BACK AND DECODE MAP POINTER ; KL paging code 3 - Indirect ; KLPAG3: LDB T4,[POINT 9,(T1),17] ;GET INDEX INTO SECONDARY PAGE MAP HRRZ T1,(T1) ;GET INDEX INTO THE SPT CAIE T1,0 ;RANGE CHECK ERR. (SIR,CPOPJ) ;SPT INDEX OUT OF RANGE ADD T1,SPT ;OFFSET ADDI T1,(T4) ;OFFSET INTO THE SECONDARY PAGE MAP SETOM PAGFLG ;STILL LOOKING AT A PAGE MAP JRST KLPAGM ;LOOP BACK AND DECODE MAP POINTER SUBTTL Address mapping -- Dispatch tables ; Initialization ; INITAB: EXP MONINI ;MONITOR EXP JOBINI ;JOB EXP FILINI ;FILE ; Page creation ; CRETAB: EXP MONCRE ;MONITOR EXP JOBCRE ;JOB EXP FILCRE ;FILE ; Page destruction ; DESTAB: EXP MONDES ;MONITOR EXP JOBDES ;JOB EXP FILDES ;FILE ; Deposit ; DEPTAB: EXP MONDEP ;MONITOR EXP JOBDEP ;JOB EXP FILDEP ;FILE ; Mapping code names ; CODTAB: [ASCIZ |monitor|] ;MONITOR [ASCIZ |job|] ;JOB [ASCIZ |file|] ;FILE ; Convert virtual to physical address ; CVTTAB: EXP MONCVT ;MONITOR EXP JOBCVT ;JOB EXP FILCVT ;FILE SUBTTL Address mapping -- Monitor ; Here at initialization to setup the page tables ; MONINI: TLNE F,FL.EXE ;CHECK FOR ILLEGAL FLAGS ERR. (CMF,CPOPJ) ;CONFLICTING MAPPING CODE AND FLAGS JRST CPOPJ1 ;RETURN ; Here to create a SPY page ; Call: MOVE A2, cache chunk address ; PUSHJ P,MONCRE ; <NON-SKIP> ;SPY PAGE CREATE FAILED ; <SKIP> ;PAGE CREATED ; MONCRE: PUSHJ P,SAVT2 ;SAVE T1 AND T2 MOVE T1,.CBPRC(A2) ;GET PROCESS PAGE NUMBER TO MAP MOVE T2,.CBUSR(A2) ;GET USER PAGE NUMBER TO MAP INTO PUSHJ P,PAGSPY ;CREATE A SPY PAGE POPJ P, ;CAN'T MOVE T1,.CBFLG(A2) ;GET FLAGS TLO T1,(CB.CRE) ;PAGE WAS JUST CREATED TLNE F,FL.PPM!FL.TPP ;PHYSICAL PAGE MAPPING? TLO T1,(CB.PHY) ;YES MOVEM T1,.CBFLG(A2) ;UPDATE FLAGS JRST CPOPJ1 ;RETURN ; Here to destroy a page ; Call: MOVE A2, cache chunk address ; PUSHJ P,MONDES ; <NON-SKIP> ;DESTROY FAILED ; <SKIP> ;USER PAGE DESTROYED ; MONDES: PUSHJ P,SAVT2 ;VE T1 AND T2 MOVSI T2,(CB.CRE) ;GET PAGE CREATED BIT TDNN T2,.CBFLG(A2) ;HAVE A PAGE THERE? POPJ P, ;NO MOVE T1,.CBUSR(A2) ;GET THE USER PAGE NUMBER PUSHJ P,PAGDES ;DESTROY IT POPJ P, ;CAN'T MOVSI T2,(CB.CRE!CB.PHY) ;GET SOME BITS ANDCAM T2,.CBFLG(A2) ;CLEAR THEM JRST CPOPJ1 ;RETURN ; Here to deposit a word in the running monitor. The arguments are ; nicely setup for the POKE. UUO and validity checking has already ; been done, so there's little to do. ; Call: MOVE T1, mapped address ; MOVE T2, old contents ; MOVE T3, new contents ; PUSHJ P,MONDEP ; MONDEP: ; *** TURN OFF PHYSICAL POKE FOR NOW *** ; TLNN F,FL.PPM ;PHYSICAL PAGE MAPPING? TDZA T2,T2 ;MONITOR VIRTUAL ADDRESSING MOVEI T2,UU.PHY ;PHYSICAL CORE ADDRESSING MOVE T1,[3,,POKBLK] ;SET UP UUO TLNE F,FL.PAT ;PATCHING? POKE. T1,(T2) ;WRITE A WORD ERR. (,CPOPJ) ;POKE. UUO FAILURE JRST CPOPJ1 ;RETURN ; Test if conversion from virtual to physical address is needed ; Call: PUSHJ P,MONCVT ; <NON-SKIP> ;NO CONVERSION NECESSARY ; <SKIP> ;CONVERT ; MONCVT: POPJ P, ;NEVER CONVERT SUBTTL Address mapping -- Job ; Here at initialization to validate arguments and pick up the ; job number. ; JOBINI: TLNN F,FL.PPM!FL.EXE ;CHECK FOR ILLEGAL FLAGS ERR. (CMF,CPOPJ) ;CONFLICTING MAPPING CODE AND FLAGS MOVE T1,USRACS+.AP ;GET ARGUMENT SKIPG T1,.MPARG(T1) ;GET JOB NUMBER ERR. (IJN,CPOPJ) ;ILLEGAL JOB NUMBER MOVEM T1,USRJOB ;WHICH IS THE JOB NUMBER FOR JOB MODE JRST CPOPJ1 ;RETURN ; Here to create a page and map in one page from the target job ; Call: MOVE A2, index into page tables ; PUSHJ P,JOBCRE ; <NON-SKIP> ;COULDN'T MAP PAGE ; <SKIP> ;PAGE MAPPED ; JOBCRE: TLNE F,FL.PPM!FL.TPP ;PHYSICAL PAGE MAPPING? POPJ P, ;CAN'T DO THAT FOR A JOB PUSHJ P,SAVT2 ;SAVE T1 AND T2 MOVSI T1,(CB.CRE) ;GET A BIT TDNE T1,.CBFLG(A2) ;HAS A PAGE BEEN CREATED? JRST JOBC.1 ;YES MOVE T1,.CBUSR(A2) ;GET A OUR PAGE NUMBER PUSHJ P,PAGACC ;CHECK PAGE ACCESSIBILITY SKIPA ;NOT THERE JRST JOBC.1 ;ONWARD PUSHJ P,PAGCRE ;DO IT POPJ P, ;CAN'T JOBC.1: MOVSI T2,(CB.CRE) ;GET A BIT IORM T2,.CBFLG(A2) ;MARK PAGE AS BEING CREATED JOBC.2: HRLZ T1,USRJOB ;GET JOB NUMBER HRRI T1,PAGSIZ ;WANT A WHOLE PAGE MOVEM T1,UUOARG+0 ;SAVE IT MOVE T1,.CBUSR(A2) ;GET OUR PAGE NUMBER HRL T1,.CBPRC(A2) ;GET PAGE WE'RE MAPPING LSH T1,11 ;CONVERT TO MAPPED ADDR,,USER ADDR MOVEM T1,UUOARG+1 ;SAVE IT MOVEI T1,UUOARG ;SET UP UUO JOBPEK T1, ;MAP THE JOB'S PAGE INTO OURS ERR. (,CPOPJ) ;JOBPEK UUO FAILURE PUSHJ P,JOBDES ;ZAP THE PAGE TABLE ENTRIES JFCL ;CAN'T FAIL JRST CPOPJ1 ;RETURN ; All that is needed to invalidate a mapped job page is to ; zap a couple of entries. It would be counterproductive ; to actually destroy the pages in question. ; JOBDES: PUSHJ P,SAVT1 ;SAVE T1 MOVSI T1,(CB.CRE) ;GET THE CREATED BIT ANDCAM T1,.CBFLG(A2) ;CLEAR IT JRST CPOPJ1 ;RETURN JOBDEP: TLNN F,FL.PAT ;PATCHING? POPJ P, ;NO HRLZ T4,USRJOB ;GET THE JOB NUMBER TLO T4,(JK.WRT) ;LITE THE WRITE BIT HRRI T4,1 ;WRITE ONLY ONE WORD MOVEM T4,UUOARG+0 ;SAVE FLAG WORD MOVSI T4,POKBLK+2 ;WORD TO WRITE IS IN POKBLK+2 HRR T4,POKBLK+0 ;GET USER VIRTUAL ADDRESS FOR JOB MOVEM T4,UUOARG+1 ;SAVE IT MOVEI T4,UUOARG ;SET UP UUO JOBPEK T4, ;WRITE THAT JOB'S CORE IMAGE ERR. (,CPOPJ) ;JOBPEK UUO FAILURE JRST JOBDES ;INVALIDATE THAT PAGE AND RETURN ; Test if conversion from virtual to physical address is needed ; Call: PUSHJ P,JOBCVT ; <NON-SKIP> ;NO CONVERSION NECESSARY ; <SKIP> ;CONVERT ; JOBCVT: POPJ P, ;NEVER CONVERT SUBTTL Address mapping -- File FILINI: MOVE T1,USRACS+.AP ;GET USER'S ARG POINTER MOVE T1,.MPARG(T1) ;GET ADDRESS OF FILESPEC PUSHJ P,FILOPN ;OPEN THE FILE ERR. (MIF,CPOPJ) ;MAPPER INITIALIZATION FAILURE TLNN F,FL.EXE ;EXE FILE MAPPING? JRST CPOPJ1 ;NO - ALL DONE PUSHJ P,EXEDIR ;LOAD .EXE DIRECTORY INTO CORE ERR. (MIF,CPOPJ) ;MAPPER INITIALIZATION FAILURE JRST CPOPJ1 ;RETURN ; Here to create a page and map in one page from a file ; Call: MOVE A2, index into page tables ; PUSHJ P,FILCRE ; <NON-SKIP> ;COULDN'T MAP PAGE ; <SKIP> ;PAGE MAPPED ; FILCRE: PUSHJ P,SAVT4 ;SAVE T1, T2, T3, AND T4 MOVSI T1,(CB.PHY) ;GET PHYSICAL BIT TLNE F,FL.PPM!FL.TPP ;DOING SOME FLAVOR OF PHYSICAL MAPPING? IORM T1,.CBFLG(A2) ;YES TLZ F,FL.TPP ;CLEAR TEMPORARY PHYSICAL PAGE MAPPING MOVE T1,.CBUSR(A2) ;GET PAGE IN QUESTION PUSHJ P,PAGCHK ;DOES IT EXIST POPJ P, ;NO--AND WE CAN'T CREATE IT MOVSI T1,(CB.CRE) ;GET A BIT IORM T1,.CBFLG(A2) ;REMEMBER WE JUST CREATED THE PAGE MOVE T1,.CBPRC(A2) ;GET PROCESS PAGE NUMBER PUSHJ P,EXEPAG ;FIND THE FILE PAGE NUMBER POPJ P, ;CAN'T LSH T1,2 ;MULTIPLY TIMES 4 TO GET BLOCK NUMBER TLNN F,FL.SIO ;SUPER I/O? ADDI T1,1 ;NO - ADJUST BLOCK NUMBER PUSHJ P,FILIPS ;POSITION FOR INPUT POPJ P, ;CAN'T MOVE T1,.CBUSR(A2) ;GET OUR PAGE NUMBER LSH T1,11 ;COMVERT TO AN ADDRESS SUBI T1,1 ;-1 HRLI T1,-PAGSIZ ;MAKE AN IOWD MOVEM T1,IOLIST ;SAVE IT PUSHJ P,FILRED ;READ THE PAGE POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN ; Here to destroy a page ; Call: MOVE A2, index into page tables ; PUSHJ P,MONDES ; <NON-SKIP> ;DESTROY FAILED ; <SKIP> ;USER PAGE DESTROYED ; FILDES: PUSHJ P,SAVT1 ;SAVE T1 MOVSI T1,(CB.CRE) ;GET A BIT TDNN T1,.CBFLG(A2) ;PAGE MUST EXIST POPJ P, ;LOSE MOVE T1,.CBUSR(A2) ;GET OUR PAGE NUMBER PUSHJ P,PAGDES ;DESTROY IT POPJ P, ;CAN'T MOVSI T1,(CB.CRE) ;GET THE CREATED BIT ANDCAM T1,.CBFLG(A2) ;CLEAR IT JRST CPOPJ1 ;RETURN FILDEP: TLNN F,FL.PAT ;PATCHING? POPJ P, ;NO HALT . ; Test if conversion from virtual to physical address is needed ; Call: PUSHJ P,FILCVT ; <NON-SKIP> ;NO CONVERSION NECESSARY ; <SKIP> ;CONVERT ; FILCVT: TLNN F,FL.GTS ;GETTABS SETUP? POPJ P, ;NOT A MONITOR IF NO GETTABS SIMULATION SKIPE HIORG ;SKIP IF WE DON'T KNOW THE HISEG ORIGIN CAMGE T1,HIORG ;BELOW THE HIGH SEG ORIGIN? JRST FILC.1 ;YES SKIPE HIFLAG ;HIGH SEGMENT MAPPED? AOS (P) ;YES--DECODE PAGE MAP POPJ P, ;ELSE TREAT AS A PHYSICAL REFERENCE FILC.1: CAMLE T1,HGHUEA ;BEYOND HIGHEST UNMAPPED EXEC ADDRESS? AOS (P) ;NEED TO CONVERT POPJ P, ;RETURN SUBTTL Cache management -- Clear out the cache ; This routine must be called at the start of cache initialization. ; It will attempt to destroy any pages available for caching so ; we can get a fresh start. ; CSHCLR: MOVE A1,MAPDAT+.MPCPN ;GET FIRST PAGE NUMBER MOVE A2,PAGCNT ;GET COUNT OF AVAILABLE PAGES CSHC.1: MOVE T1,A1 ;LOAD A PAGE NUMBER PUSHJ P,PAGACC ;DOES THE PAGE EXIST? SKIPA ;NO PUSHJ P,PAGDES ;DESTROY IT JFCL ;MAYBE THE PAGE WASN'T THERE ADDI A1,1 ;ADVANCE PAGE NUMBER SOJG A2,CSHC.1 ;LOOP FOR ALL PAGES POPJ P, ;AND RETURN SUBTTL Cache management -- Map the cache ; This routine will dynamically allocate the hash table ; and chunks out of the pages allotted for mapping. It is ; also responsible for setting and/or adjusting the count ; of available pages for caching and the starting page to ; cache. ; CSHMAP: MOVE A1,MAPDAT+.MPCPN ;GET FIRST PAGE NUMBER TO USE LSH A1,11 ;CONVERT TO AN ADDRESS MOVEM A1,HASHTA ;SAVE HASH TABLE ADDRESS MOVE A1,PAGCNT ;GET NUMBER OF PAGES TO CACHE LSH A1,2 ;MULTIPLY BY 4 TO GET HASH TABLE SIZE MOVEM A1,HASHTL ;SAVE LENGTH OF HASH TABLE ADD A1,HASHTA ;GET LAST ADDRESS IN HASH TABLE MOVEM A1,HASHCA ;SAVE AS ADDRESS OF FIRST CHUNK MOVE A2,PAGCNT ;GET NUMBER OF PAGES TO CACHE IMULI A2,.CBLEN ;GET WORDS NEEDED FOR CHUNKS ADDI A1,(A2) ;TOTAL UP WORDS NEEDED MOVE A2,A1 ;COPY NUMBER OF WORDS SUB A1,HASHCA ;GET LENGTH OF CHUNK AREA MOVEM A1,HASHCL ;SAVE IT TRZE A2,PAGSIZ-1 ;ON A PAGE BOUNDRY? ADDI A2,PAGSIZ ;ROUND UP LSH A2,-11 ;GET FIRST AVAILABLE PAGE FOR MAPPING MOVEM A2,CSHPAG ;SAVE IT SUB A2,MAPDAT+.MPCPN ;GET PAGES USED FOR TABLE AND CHUNKS MOVN A3,A2 ;GET NEGATIVE COUNT CAML A2,PAGCNT ;HAVE ENOUGH AVAILABLE? ERR. (HAF,CPOPJ) ;HASH TABLE ALLOCATION FAILURE EXCH A2,PAGCNT ;SWAP SUBM A2,PAGCNT ;UPDATE NEW NUMBER OF PAGES AVAILABLE IMULI A3,.CBLEN ;GET WORDS TO TRIM ADDM A3,HASHCL ;ADJUST LENGTH OF CHUNK AREA MOVE A1,HASHTA ;GET ADDRESS OF HASH TABLE LSH A1,-11 ;CONVERT TO A PAGE NUMBER MOVE A2,CSHPAG ;GET FIRST PAGE TO CACHE SUB A2,A1 ;GET NUMBER OF PAGES TO CREATE CSHM.1: MOVE T1,A1 ;GET A PAGE NUMBER PUSHJ P,PAGACC ;DOES THE PAGE ALREADY EXIST? SKIPA ;NOT THERE JRST CSHM.2 ;ON TO THE NEXT PAGE PUSHJ P,PAGCRE ;CREATE IT ERR. (HAF,CPOPJ) ;HASH TABLE ALLOCATION FAILURE CSHM.2: ADDI A1,1 ;POINT TO NEXT PAGE SOJG A2,CSHM.1 ;LOOP FOR ALL PAGES JRST CPOPJ1 ;RETURN SUBTTL Cache management -- Set up the hash tables and links ;Call: PUSHJ P,CSHINI ; <return> ; CSHINI: MOVE A1,HASHTA ;GET STARTING ADDRESS OF HASH TABLE SKIPA A2,HASHTL ;GET LENGTH OF HASH TABLE ; Link all hash entries to themselves CSHI.1: ADDI A1,2 ;ADDRESS OF SELF MOVEM A1,.CBNHB(A1) ;STORE NEXT MOVEM A1,.CBPHB(A1) ;AND PREVIOUS TO SELF SUBI A2,1 ;ADVANCE TO NEXT SOJG A2,CSHI.1 ;AND LOOP FOR ALL ; Link header entry links to themselves MOVEI A1,CBHEAD ;ADDRESS OF HEADER MOVEM A1,CBHEAD+.CBNAB ;STORE NEXT MOVEM A1,CBHEAD+.CBPAB ;AND PREVIOUS TO SELF MOVEM A1,CBHEAD+.CBNHB ;STORE NEXT IN INVALID LIST MOVEM A1,CBHEAD+.CBPHB ;AND PREVIOUS TO SELF MOVE A1,HASHCA ;POINT TO START OF CHUNKS MOVE A2,CSHPAG ;GET STARTING PAGE FOR CACHING MOVE A3,PAGCNT ;GET COUNT OF PAGES TO CACHE MOVSI A4,(CB.AVA) ;GET CHUNK AVAILABLE BIT CSHI.2: MOVEM A2,.CBUSR(A1) ;SAVE PAGE NUMBER FOR THIS CHUNK MOVEM A4,.CBFLG(A1) ;MARK CHUNK AVAILABLE MOVE T1,.CBUSR(A1) ;GET A PAGE NUMBER ADDI A1,.CBLEN ;POINT TO NEXT CHUNK ADDI A2,1 ;ADVANCE TO NEXT PAGE NUMBER SOJG A3,CSHI.2 ;LOOP POPJ P, ;RETURN SUBTTL Cache management -- Set cache size ; Change the cache size. This routine will increase ; or decrease the size of the cache on the fly. ; Call: MOVE A1, size of cache ; PUSHJ P,CSHSIZ ; <error> ;Cant allocate more space ; <normal> ;cache expanded/contracted ; CSHSIZ: SKIPGE A1 ;NEGATIVE SIZE IS BAD ERR. (ICS,CPOPJ) ;ILLEGAL CACHE SIZE REQUESTED PUSHJ P,SAVT1 ;SAVE T1 MOVE T1,A1 ;COPY SIZE SUB T1,PAGCNT ;MINUS CURRENT SIZE JUMPE T1,CPOPJ1 ;RETURN IF NO CHANGE JUMPG T1,CSHS.2 ;EXPAND CACHE CSHS.1: PUSHJ P,CSHDEA ;DEALLOCATE A CHUNK AOJL T1,CSHS.1 ;LOOP FOR ALL JRST CSHS.3 ;AND EXIT CSHS.2: PUSHJ P,CSHALC ;ALLOCATE A CHUNK ERR. (NFC,CPOPJ) ;NO FREE CHUNKS FOR CACHE SOJG T1,CSHS.2 ;LOOP FOR ALL CSHS.3: MOVE T1,PAGCNT ;GET UPDATED CACHED PAGE COUNT MOVEM T1,MAPDAT+.MPCPC ;TELL THE CALLER JRST CPOPJ1 ;RETURN SUBTTL Cache management -- Allocate a chunk for the cache ; Call: PUSHJ P,CSHALC ; <error> ;Cant allocate another chunk ; <normal> ;another chunk allocated ; CSHALC: MOVE A2,HASHCA ;POINT TO START OF CHUNKS MOVE A3,HASHCL ;GET LENGTH OF CHUNK AREA MOVSI A4,(CB.AVA) ;GET THE AVAILABLE CHUNK BIT CSHA.1: TDNE A4,.CBFLG(A2) ;CHUNK FREE? JRST CSHA.2 ;YES ADDI A2,.CBLEN ;POINT TO NEXT CHUNK SUBI A3,.CBLEN ;COUNT JUMPG A3,CSHA.1 ;LOOP 'TIL WE FIND ONE POPJ P, ;LOSE CSHA.2: ANDCAM A4,.CBFLG(A2) ;NO LONGER FREE AOS PAGCNT ;COUNT CHUNKS INSERTED ;Link new chunk at beginning of "free" hash list MOVE A3,CBHEAD+.CBNHB ;GET FORWARD FROM HEADER MOVE A4,.CBPHB(A3) ;AND PREVIOUS FROM TOP MOVEM A2,CBHEAD+.CBNHB ;INSERT US AT THE TOP MOVEM A2,.CBPHB(A3) ;PREVIOUS OF OLD TOP IS US MOVEM A3,.CBNHB(A2) ;NEXT OF US IS OLD TOP MOVEM A4,.CBPHB(A2) ;PREVIOUS OF US IS HEADER ;Clear out any trash SETZM .CBPRC(A2) ;CLEAR PROCESS PAGE NUMBER ;Link new chunk at end of accessed list MOVE A3,CBHEAD+.CBPAB ;GET FORWARD FROM HEADER MOVE A4,.CBNAB(A3) ;AND NEXT FROM TOP MOVEM A2,CBHEAD+.CBPAB ;INSERT US AT THE TOP MOVEM A2,.CBNAB(A3) ;NEXT OF OLD TOP IS US MOVEM A3,.CBPAB(A2) ;PREVIOUS OF US IS OLD TOP MOVEM A4,.CBNAB(A2) ;NEXT OF US IS HEADER JRST CPOPJ1 ;AND SKIP RETURN SUBTTL Cache management -- Deallocate a page from the cache ; Call: PUSHJ P,CSHDEA ; <return> ; CSHDEA: ; Delete from access chunk chain MOVE A2,CBHEAD+.CBPAB ;LAST CHUNK IN CACHE MOVE A3,.CBNAB(A2) ;GET NEXT MOVE A4,.CBPAB(A2) ;GET PREVIOUS MOVEM A3,.CBNAB(A4) ;REMOVE FROM FORWARD CHAIN MOVEM A4,.CBPAB(A3) ;REMOVE FROM PREVIOUS CHAIN ;Delete from hash chain MOVE A3,.CBNHB(A2) ;GET NEXT MOVE A4,.CBPHB(A2) ;GET PREVIOUS MOVEM A3,.CBNHB(A4) ;REMOVE FROM FORWARD CHAIN MOVEM A4,.CBPHB(A3) ;REMOVE FROM PREVIOUS CHAIN ;Return core, fix up cache size MOVE A3,.CBFLG(A2) ;GET THE FLAG WORD TLZE A3,(CB.CRE) ;PAGE REALLY EXIST? PUSHJ P,@DESTAB(F) ;YES--DESTROY IT JFCL TLO A3,(CB.AVA) ;MARK CHUNK AVAILABLE MOVEM A3,.CBFLG(A2) ;UPDATE FLAG WORD SOS PAGCNT ;CACHE IS 1 CHUNK SMALLER POPJ P, ;AND RETURN SUBTTL Cache management -- Find an entry in the cache ; Call: MOVE A1, page number ; PUSHJ P,CSHFND ; <error> ;page not in cache T2/ address to insert ; <normal> ;page in cache T2/ address of entry ; CSHFND: ; Hash page number to initial entry in table MOVE A4,HASHTL ;GET HASH TABLE LENGTH LSH A4,-1 ;DIVIDE BY 2 MOVE A2,A1 ;COPY PAGE NUMBER IDIV A2,A4 ;HASH INTO TABLE LSH A3,1 ;DOUBLE REMAINDER MOVE A4,HASHTA ;GET HASH TABLE ADDRESS ADDI A4,(A3) ;INDEX INTO IT MOVE A2,A4 ;COPY POINTER TO START AOS MAPDAT+.MPHSF ;COUNT HASH TABLE SEARCHES TLNN F,FL.PPM!FL.TPP ;PHYSICAL PAGE MAPPING? SKIPA A3,[TDNN A3,.CBFLG(A2)] ;GET TEST IF PHYSICAL BIT MUST BE OFF MOVE A3,[TDNE A3,.CBFLG(A2)] ;GET TEST IF PHYSICAL BIT MUST BE ON MOVEM A3,CSHXCT ;SAVE IT MOVSI A3,(CB.PHY) ;GET THE PHYSICAL BIT ; Loop through hash chain from initial probe ; CSHF.1: CAMN A4,.CBNHB(A2) ;SEE IF LOOPED AROUND POPJ P, ;YES--NOT IN TABLE MOVE A2,.CBNHB(A2) ;COPY CURRENT PAGE XCT CSHXCT ;TEST FOR PHYSICAL PAGE CAME A1,.CBPRC(A2) ;MATCH THE PROCESS PAGE NUMBER? SKIPA JRST CPOPJ1 ;FOUND IT--RETURN AOS MAPDAT+.MPHSC ;WRONG PAGE--COUNT COLLISIONS JRST CSHF.1 ;AND LOOP SUBTTL Cache management -- Insert (replace) a new page in the cache ; Call: MOVE A1, page number ; MOVE A2, entry to add after ; PUSHJ P,CSHINS ; <return> ; CSHINS: CAMN A2,CBHEAD+.CBPAB ;SAME AS ENTRY WE FIDDLE JRST [MOVEM A1,.CBPRC(A2) ;SAVE NEW PROCESS PAGE NUMBER JRST CSHMRU] ;AND MOVE TO TOP ; Store page number, replace last page in access chain PUSH P,A2 ;SAVE ENTRY TO ADD MOVE A2,CBHEAD+.CBPAB ;GET LAST IN CHAIN ;Unlink from old hash chain MOVE A3,.CBNHB(A2) ;GET NEXT MOVE A4,.CBPHB(A2) ;GET PREVIOUS MOVEM A3,.CBNHB(A4) ;REMOVE FROM FORWARD CHAIN MOVEM A4,.CBPHB(A3) ;REMOVE FROM PREVIOUS CHAIN ;Link this chunk into correct hash chain MOVE A1,A2 POP P,A2 ;RESTORE ENTRY TO ADD MOVE A4,.CBNHB(A2) ;AND NEXT LINK MOVEM A1,.CBNHB(A2) ;INSERT AFTER PREVIOUS MOVEM A1,.CBPHB(A4) ;AND AS PREVIOUS OF OLD MOVEM A2,.CBPHB(A1) ;STORE PREVIOUS OF OLD AS OURS MOVEM A4,.CBNHB(A1) ;STORE NEXT OF OLD AS OURS MOVE A2,A1 JRST CSHMRU ;AND MOVE ENTRY TO TOP OF LIST SUBTTL Cache management -- Move entry to top of list ; Call: MOVE A2, entry to move ; PUSHJ P,CSHMRU ; <return> ; CSHMRU: CAMN A2,CBHEAD+.CBNAB ;WE AT THE TOP? POPJ P, ;YES--SAVE SOME WORK ; Delete from current access chain position MOVE A3,.CBNAB(A2) ;GET NEXT MOVE A4,.CBPAB(A2) ;GET PREVIOUS MOVEM A3,.CBNAB(A4) ;REMOVE FROM FORWARD CHAIN MOVEM A4,.CBPAB(A3) ;REMOVE FROM PREVIOUS CHAIN ; Relink into "most recently used" position MOVE A3,CBHEAD+.CBNAB ;GET FORWARD FROM HEADER MOVE A4,.CBPAB(A3) ;AND PREVIOUS FROM TOP MOVEM A2,CBHEAD+.CBNAB ;INSERT US AT THE TOP MOVEM A2,.CBPAB(A3) ;PREVIOUS OF OLD TOP IS US MOVEM A3,.CBNAB(A2) ;NEXT OF US IS OLD TOP MOVEM A4,.CBPAB(A2) ;PREVIOUS OF US IS HEADER POPJ P, ;AND RETURN SUBTTL Text I/O -- Character ; Input a character converting tabs to spaces and lower to upper case ; Call: PUSHJ P,TYI ; <RETURN> ;T1:= CHARACTER ; TYI: ILDB T1,BYTPTR ;GET A CHARACTER CAIN T1,"I"-100 ;TAB? MOVEI T1," " ;YES - CONVERT TO A SPACE CAIG T1,"Z"+40 ;CHECK FOR A LOWER CASE CAIGE T1,"A"+40 ; CHARACTER THAT NEEDS TO BE SKIPA ; CONVERTED TO AN UPPER CASE TRZ T1," " ; CHARACTER POPJ P, ;RETURN ; Output a character ; Call: MOVE T1, character ; PUSHJ P,TYO ; <RETURN> ; TYO: SKIPN BYTPTR ;OUTPUT TO TTY? JRST [OUTCHR T1 ;YES POPJ P,] ;RETURN SOSLE BYTCNT ;COUNT CHARACTERS IDPB T1,BYTPTR ;SAVE CHARACTER POPJ P, ;RETURN SUBTTL Text I/O -- ASCIZ ; Output an ASCIZ string ; Call: MOVE T1, string address ; PUSHJ P,TSTRG ; <RETURN> ; TSTRG: HRLI T1,(POINT 7,) ;MAKE A BYTE POINTER PUSH P,T1 ;SAVE IT TSTR.1: ILDB T1,(P) ;GET A CHARACTER JUMPE T1,TSTR.2 ;DONE? PUSHJ P,TYO ;TYPE IT JRST TSTR.1 ;LOOP TSTR.2: POP P,T1 ;PHASE STACK POPJ P, ;RETURN SUBTTL Text I/O -- Sixbit ; Input a possibly quoted sixbit word ; Call: PUSHJ P,SIXIN ; <RETURN> ;T1:= WORD, T2:= TERMINATING CHARACTER ; SIXIN: MOVE T2,[POINT 6,T3] ;GET BYTE POINTER TO ATOM BUFFER PUSH P,[0] ;RESERVE A WORD SETZ T3, ;CLEAR RESULT PUSHJ P,FLUSH ;FLUSH LEADING SPACES AND TABS CAIN T1,"#" ;WANTS TO INPUT IN OCTAL? JRST OCTIN ;YES SKIPA ;ANALYZE CHARACTER SIXI.1: PUSHJ P,TYI ;GET A CHARACTER CAIN T1,"""" ;QUOTE CHARACTER? JRST SIXI.2 ;YES SKIPE (P) ;QUOTING? JUMPN T1,SIXI.4 ;ALL CHARACTERS ARE LEGAL JRST SIXI.3 ;NO SIXI.2: PUSHJ P,TYI ;GET NEXT CHARACTER CAIN T1,"""" ;ANOTHER QUOTE? JRST SIXI.4 ;SAVE IT SETCMM (P) ;NO - TOGGLE QUOTE FLAG SKIPE (P) ;QUOTING? JRST SIXI.4 ;YES SIXI.3: CAIL T1,"0" ;RANGE CAILE T1,"9" ; CHECK CAIL T1,"A" ; THE CAILE T1,"Z" ; CHARACTER JRST SIXI.5 ;NOT A GOOD CHARACTER SIXI.4: TLNE T2,77 ;WORD FULL YET? JRST SIXI.1 ;YES - IGNORE CHARACTER SUBI T1," " ;CONVERT ASCII TO SIXBIT IDPB T1,T2 ;SAVE THE CHARACTER JRST SIXI.1 ;GET ANOTHER ONE SIXI.5: MOVE T2,T1 ;GET TERMINATING CHARACTER MOVE T1,T3 ;GET RESULT POP P,(P) ;TRIM STACK POPJ P, ;RETURN ; Output a sixbit word ; Call: MOVE T1, word ; PUSHJ P,SIXOUT ; <RETURN> ; SIXOUT: SKIPN T2,T1 ;COPY WORD TO OUTPUT POPJ P, ;NOTHING TO DO SIXO.1: LSHC T1,6 ;SHIFT IN A CHARACTER ANDI T1,77 ;NO JUNK ADDI T1," " ;CONVERT TO ASCII PUSHJ P,TYO ;OUTPUT IT JUMPN T2,SIXO.1 ;LOOP POPJ P, ;RETURN SUBTTL Text I/O -- Octal ; Input an octal word ; Call: PUSHJ P,OCTIN ; <RETURN> ;T1:= WORD, T2:= TERMINATING CHARACTER ; OCTIN: SETZ T2, ;CLEAR RESULT AND MASK PUSHJ P,FLUSH ;EAT LEADING SPACES AND TABS CAIL T1,"A" ;CHECK FOR CAILE T1,"Z" ; A LETTER JRST OCTI.2 ;ASSUME A DIGIT PUSHJ P,BACKUP ;BACKUP THE BYTE POINTER JRST SIXIN ;GO INPUT SIXBIT OCTI.1: PUSHJ P,TYI ;GET A CHARACTER OCTI.2: CAIL T1,"0" ;RANGE CHECK CAILE T1,"7" ; FOR AN OCTAL DIGIT JRST OCTI.3 ;NO GOOD - FINISH UP LSH T2,3 ;SHIFT RESULT SUBI T1,"0" ;CONVERT ASCII TO OCTAL IOR T2,T1 ;INCLUDE THE DIGIT JRST OCTI.1 ;LOOP OCTI.3: EXCH T1,T2 ;SWAP RESULT AND TERMINATING CHARACTER POPJ P, ;RETURN ; Output an octal word ; Call: MOVE T1, word ; PUSHJ P,OCTOUT ; OCTOUT: SKIPL T1 ;NEGATIVE? JRST OCTO.1 ;NO PUSH P,T1 ;SAVE NUMBER MOVEI T1,"-" ;GET MINUS SIGN PUSHJ P,TYO ;OUTPUT IT POP P,T1 ;GET NUMBER MOVMS T1 ;MAKE IT POSITIVE OCTO.1: IDIVI T1,10 ;DIVIDE BY RADIX PUSH P,T2 ;SAVE REMAINDER SKIPE T1 ;DONE? PUSHJ P,OCTO.1 ;RECURSE POP P,T1 ;GET A DIGIT ADDI T1,"0" ;CONVERT TO ASCII JRST TYO ;OUTPUT CHARACTER AND RETURN ; Output a CRLF ; Call: PUSHJ P,TCRLF ; TCRLF: MOVEI T1,15 ;GET A <CR> PUSHJ P,TYO ;TYPE IT MOVEI T1,12 ;GET A <LF> JRST TYO ;TYPE IT AND RETURN ; Output a PC ; Call: MOVE T1, PC ; PUSHJ P,PCOUT ; PCOUT: TLNN T1,-1 ;A SECTION NUMBER? JRST PCOU.1 ;NO PUSH P,T1 ;SAVE PC HLRZS T1 ;GET SECTION PUSHJ P,OCTOUT ;TYPE IT MOVEI T1,"," ;GET SEPARATOR PUSHJ P,TYO ;TYPE IT PUSHJ P,TYO ;AGAIN POP P,T1 ;RESTORE PC HRRZS T1 ;GET RELATIVE PC PCOU.1: HRLO T2,T1 ;MAKE IT PC,,-1 PCOU.2: LSHC T1,3 ;SHIFT IN A DIGIT ANDI T1,7 ;STRIP OFF JUNK ADDI T1,"0" ;MAKE IT ASCII PUSHJ P,TYO ;TYPE IT TRNE T2,-1 ;DONE SIX DIGITS YET? JRST PCOU.2 ;NO--LOOP POPJ P, ;RETURN SUBTTL Text I/O -- Filespec ; Output a filespec ; Call: PUSHJ P,FILOUT ; <RETURN> ; FILOUT: MOVE T1,FOPBLK+.FODEV ;GET DEVICE PUSHJ P,SIXOUT ;OUTPUT IT MOVEI T1,":" ;GET SEPARATOR PUSHJ P,TYO ;TYPE COLON MOVE T1,LERBLK+.RBNAM ;GET NAME PUSHJ P,SIXOUT ;OUTPUT IT MOVEI T1,"." ;GET SEPARATOR PUSHJ P,TYO ;OUTPUT PERIOD HLLZ T1,LERBLK+.RBEXT ;GET EXTENSION PUSHJ P,SIXOUT ;OUTPUT IT MOVEI T1,"[" ;GET PATH DELIMITER PUSHJ P,TYO ;OUTPUT SKIPGE T1,PTHBLK+.PTPPN ;GET PPN JRST FILO.1 ;IT'S SIXBIT HLRZS T1 ;GET PROJECT NUMBER PUSHJ P,OCTOUT ;OUTPUT IT MOVEI T1,"," ;GET SEPARATOR PUSHJ P,TYO ;OUTPUT IT HRRZ T1,PTHBLK+.PTPPN ;GET PROGRAMMER NUMBER PUSHJ P,OCTOUT ;OUTPUT JRST FILO.2 ;ONWARD FILO.1: PUSHJ P,SIXOUT ;OUTPUT IT FILO.2: MOVEI T3,PTHBLK+.PTSFD ;POINT TO START OF SFDS FILO.3: SKIPN (T3) ;HAVE AN SFD JRST FILO.4 ;END OF PATH MOVEI T1,"," ;GET SEPARATOR PUSHJ P,TYO ;OUTPUT IT MOVE T1,(T3) ;GET AN SFD PUSHJ P,SIXOUT ;OUTPUT IT AOJA T3,FILO.3 ;LOOP FILO.4: MOVEI T1,"]" ;GET END OF PATH JRST TYO ;OUTPUT IT AND RETURN SUBTTL Text I/O -- Miscellaneous ; Set up byte pointer and count ; Call: MOVE T1, address to store text or 0 for TTY output ; MOVE T2, character count ; PUSHJ P,TXTSET ; TXTSET: SKIPE T1 ;OUTPUT TO TTY? HRLI T1,(POINT 7,) ;NO--MAKE A BYTE POINTER MOVEM T1,BYTPTR ;SAVE IT MOVEM T2,BYTCNT ;SAVE CHARACTER COUNT POPJ P, ;RETURN ; Flush leading spaces and tabs ; Call: PUSHJ P,FLUSH ; <RETURN> ;T1:= FIRST NON-BLANK CHARACTER ; FLUSH: PUSHJ P,TYI ;GET A CHARACTER CAIN T1," " ;A SPACE? JRST FLUSH ;YES - EAT IT POPJ P, ;RETURN ; Back up the text byte pointer 1 character ; Call: PUSHJ P,BACKUP ; ; On return, T1 has been updated with the current character ; BACKUP: MOVE T1,BYTPTR ;GET THE BYTE POINTER ADD T1,[70000,,0] ;BACKUP 1 CHARACTER SKIPG T1 ;OVER A WORD BOUNDRY? SUB T1,[430000,,1] ;YES - BACKUP A WORD MOVEM T1,BYTPTR ;SAVE UPDATED POINTER LDB T1,BYTPTR ;LOAD THE PREVIOUS CHARACTER POPJ P, ;RETURN SUBTTL Paging -- Check accessibility ; Check accessibility of a page in our address space ; Call: MOVE T1, page number ; PUSHJ P,PAGACC ; <NON-SKIP> ;PAGE DOES NOT EXIST ; <SKIP> ;PAGE EXISTS ; PAGACC: MOVEM T1,UUOARG ;SAVE PAGE NUMBER HRLI T1,.PAGCA ;LOAD A FUNCTION CODE PAGE. T1, ;READ ACCESS BITS SETO T1, ;ASSUME PAGE NOT THERE TLNN T1,(PA.GNE) ;NON-EXISTANT PAGE? AOS (P) ;NO MOVE T1,UUOARG ;RELOAD PAGE NUMBER POPJ P, ;RETURN ; Check to see if the a reference to a page will cause ; an illegal memory reference. If so, create it. ; Call: MOVE T1, page number ; PUSHJ P,PAGCHK ; <NON-SKIP> ;PAGE CREATE FAILED ; <SKIP> ;PAGE EXISTS ; PAGCHK: PUSHJ P,PAGACC ;CHECK ACCESSIBILITY JRST PAGCRE ;CREATE IT AND RETURN JRST CPOPJ1 ;IT ALREADY EXISTS SUBTTL Paging -- Create/Destroy ; Create or destroy a page in our address space ; Call: MOVE T1, page number ; PUSHJ P,PAGCRE/PAGDES ; <NON-SKIP> ;FAILED ; <SKIP> ;SUCEEDED ; PAGDES: TLO T1,(PA.GAF) ;LITE THE DESTROY BIT PAGCRE: MOVEM T1,UUOARG+1 ;SAVE IT MOVEI T1,1 ;ONE WORD MOVEM T1,UUOARG+0 ;SAVE WORD COUNT MOVE T1,[.PAGCD,,UUOARG] ;SET UP UUO PAGE. T1, ;CREATE OR DESTROY A PAGE ERR. (,.+2) ;CAN'T AOS (P) ;FORCE SKIP RETURN MOVE T1,UUOARG+1 ;RELOAD THE PAGE NUMBER TLZ T1,(PA.GAF) ;TURN OFF THE ALTERNATE FUNCTION BIT POPJ P, ;RETURN SUBTTL Paging -- SPY page creation ; Create a SPY page using physical or virtual mapping ; Call: MOVE T1, monitor page ; MOVE T2, user page ; PUSHJ P,PAGSPY ; <NON-SKIP> ;FAILED ; <SKIP> ;SUCEEDED ; PAGSPY: HRLZM T1,UUOARG+1 ;SAVE MONITOR PAGE NUMBER HRRM T2,UUOARG+1 ;SAVE USER PAGE NUMBER MOVEI T1,1 ;ONE WORD MOVEM T1,UUOARG+0 ;SAVE WORD COUNT MOVE T1,[.PAGSP,,UUOARG] ;SET UP UUO TLNN F,FL.PPM!FL.TPP ;PHYSICAL PAGE MAPPING? TDZA T2,T2 ;NO MOVEI T2,UU.PHY ;YES PAGE. T1,(T2) ;CREATE A SPY PAGE ERR. (,.+2) ;CAN'T AOS (P) ;FORCE SKIP RETURN TLZ F,FL.TPP ;CLEAR TEMPORARY PHYSICAL PAGE MAPPING HLRZ T1,UUOARG+1 ;RELOAD MONITOR PAGE NUMBER HRRZ T2,UUOARG+2 ;RELOAD USER PAGE NUMBER POPJ P, ;RETURN SUBTTL File I/O -- Open a file ; Open a file pointer to by the calling program ; Call: MOVE T1, address of ASCIZ filespec ; PUSHJ P,FILOPN ; FILOPN: PUSHJ P,SCAN ;SCAN FILESPEC AND LOAD UUO BLOCKS POPJ P, ;CAN'T TLNE F,FL.SIO ;SUPER I/O? TLNN F,FL.EXE ;AND .EXE FILE? SKIPA ;OK ERR. (CMF,CPOPJ) ;CONFLICTING MAPPING CODE AND FLAGS MOVEI T1,.FORED ;ASSUME ONLY READING TLNE F,FL.PAT ;PATCHING? MOVEI T1,.FOSAU ;YES - USE UPDATE MODE TLNE F,FL.SIO ;SUPER I/O? MOVEI T1,.FOSIO ;YES - USE SUPER I/O MODE TLO T1,(FO.ASC) ;ASSIGN A CHANNEL MOVEM T1,FOPBLK+.FOFNC ;SAVE FUNCTION WORD MOVEI T1,.IODMP ;DUMP MODE TLNE F,FL.PIO ;PHYSICAL ONLY LOOKUP/ENTER? TLO T1,(UU.PHS) ;YES MOVEM T1,FOPBLK+.FOIOS ;SAVE IT MOVEI T1,LERBLK ;GET LOOKUP/ENTER BLOCK ADDRESS MOVEM T1,FOPBLK+.FOLEB ;SAVE IT MOVEI T1,LERSIZ ;GET SIZE OF LOOKUP/ENTER BLOCK MOVEM T1,LERBLK+.RBCNT ;SAVE IT MOVE T1,[PTHSIZ,,PTHBLK] ;GET PATH BLOCK ADDRESS MOVEM T1,FOPBLK+.FOPAT ;SAVE FOR READING PATH BACK SKIPE PTHBLK+.PTPPN ;HAVE A DIRECTORY? HRRZM T1,LERBLK+.RBPPN ;YES--SAVE FOR LOOKUP/ENTER MOVE T1,[FILSIZ,,FILBLK] ;POINT TO THE BLOCK MOVEM T1,FOPBLK+.FOFSP ;SAVE RETURNED FILESPEC POINTER MOVE T1,[FOPSIZ,,FOPBLK] ;SET UP UUO FILOP. T1, ;OPEN THE FILE ERR. (,CPOPJ) ;FILOP. UUO FAILURE MOVE T1,FOPBLK+.FOFNC ;GET FUNCTION CODE WORD AND T1,[FO.CHN] ;KEEP JUST THE CHANNEL NUMBER MOVEM T1,FILCHN ;SAVE IT PUSHJ P,FILXTR ;EXTRACT THE FULL FILESPEC JRST CPOPJ1 ;RETURN ; Here to extract the actual filespec and return it ; to the caller. ; FILXTR: MOVE T1,PTHBLK+.PTSTR ;GET DEVICE NAME MOVEM T1,FOPBLK+.FODEV ;SET IT JUST INCASE PATH. UUO FAILS MOVEI T1,FILTAB ;POINT TO TABLE SKIPE FILBLK+.FOFDV ;HAVE A RETURNED FILESPEC? FILX.1: SKIPN (T1) ;END OF TABLE? JRST FILX.2 ;YES HLRZ T2,(T1) ;GET SOURCE ADDRESS HRRZ T3,(T1) ;GET DESTINATION ADDRESS SKIPE T4,(T2) ;GET A WORD MOVEM T4,(T3) ;PUT A WORD AOJA T1,FILX.1 ;LOOP FILX.2: SETZM MAPDAT+.MPAFS ;CLEAR FIRST WORD MOVE T1,[MAPDAT+.MPAFS,,MAPDAT+.MPAFS+1] ;SET UP BLT BLT T1,MAPDAT+.MPAFS+.MPFWD ;CLEAR BLOCK MOVEI T1,MAPDAT+.MPAFS ;POINT TO ACTUAL FILESPEC STORAGE MOVEI T2,<.MPFWD*5>-1 ;GET MAXIMUM BYTE COUNT PUSHJ P,TXTSET ;SETUP BYTE POINTER AND COUNT PUSHJ P,FILOUT ;OUTPUT FILESPEC POPJ P, ;RETURN ; Translation table ; FILTAB: FILBLK+.FOFDV,,FOPBLK+.FODEV ;DEVICE FILBLK+.FOFFN,,LERBLK+.RBNAM ;FILE NAME FILBLK+.FOFEX,,LERBLK+.RBEXT ;EXTENSION FILBLK+.FOFPP,,PTHBLK+.PTPPN ;PPN FILBLK+.FOFSF+0,,PTHBLK+.PTSFD+0;SFD #1 FILBLK+.FOFSF+1,,PTHBLK+.PTSFD+1;SFD #2 FILBLK+.FOFSF+2,,PTHBLK+.PTSFD+2;SFD #3 FILBLK+.FOFSF+3,,PTHBLK+.PTSFD+3;SFD #4 FILBLK+.FOFSF+4,,PTHBLK+.PTSFD+4;SFD #5 EXP 0 ;TERMINATE TABLE SUBTTL File I/O -- Close a file ; Close a file ; Call: PUSHJ P,FILCLS ; FILCLS: SKIPN T1,FILCHN ;WE ONLY USE EXTENDED CHANNELS POPJ P, ;DON'T ZAP CHANNEL ZERO IORI T1,.FOREL ;INCLUDE THE FUNCTION CODE MOVEM T1,FOPBLK+.FOFNC ;SAVE IT MOVE T1,[1,,FOPBLK] ;SET UP UUO FILOP. T1, ;CLOSE THE FILE JFCL ;IGNORE ERRORS SETZM FILCHN ;SO WE DON'T TRY THIS AGAIN POPJ P, ;RETURN SUBTTL File I/O -- Position a file ; Position file for input or output ; Call: MOVE T1, block number ; PUSHJ P,FILIPS ;INPUT ; PUSHJ P,FILOPS ;OUTPUT ; FILIPS: MOVEM T1,FOPBLK+.FOIOS ;SAVE BLOCK NUMBER MOVEI T1,.FOUSI ;USETI FUNCTION JRST FILPOS ;CONTINUE FILOPS: MOVEM T1,FOPBLK+.FOIOS ;SAVE BLOCK NUMBER MOVEI T1,.FOUSO ;USETO FUNCTION FILPOS: IOR T1,FILCHN ;INCLUDE THE CHANNEL NUMBER MOVEM T1,FOPBLK+.FOFNC ;SAVE FUNCTION WORD MOVE T1,[2,,FOPBLK] ;SET UP UUO FILOP. T1, ;POSITION FOR INPUT OR OUTPUT POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN SUBTTL File I/O -- Input/Output FILRED: SKIPA T1,[.FOINP] ;INPUT FUNCTION FILWRT: MOVEI T1,.FOOUT ;OUTPUT FUNCTION SETZM IOLIST+1 ;TERMINATE LIST IOR T1,FILCHN ;INCLUDE THE CHANNEL NUMBER MOVEM T1,FOPBLK+.FOFNC ;SAVE FUNCTION WORD MOVEI T1,IOLIST ;POINT TO THE I/O COMMAND LIST MOVEM T1,FOPBLK+.FOIOS ;TELL THE MONITOR MOVE T1,[2,,FOPBLK] ;SET UP UUO FILOP. T1, ;READ OR WRITE THE FILE POPJ P, ;CAN'T JRST CPOPJ1 ;RETURN SUBTTL File I/O -- Scan a filespec ; This routine will scan off a filespec and load the appropriate ; locations in the FILOP., LOOKUP/ENTER and PATH. UUO blocks ; Call: MOVE T1, address of ASCIZ filespec ; PUSHJ P,SCAN ; SCAN: HRLOI T2,377777 ;A LARGE NUMBER PUSHJ P,TXTSET ;SET UP FOR TEXT I/O SETZM FOPBLK ;CLEAR THE FIRST WORD MOVE T1,[FOPBLK,,FOPBLK+1] ;SET UP BLT BLT T1,FOPBLK+FOPSIZ-1 ;CLEAR THE FILOP. UUO BLOCK SETZM LERBLK ;CLEAR THE FIRST WORD MOVE T1,[LERBLK,,LERBLK+1] ;SET UP BLT BLT T1,LERBLK+LERSIZ-1 ;CLEAR THE LOOKUP/ENTER UUO BLOCK SETZM PTHBLK ;CLEAR THE FIRST WORD MOVE T1,[PTHBLK,,PTHBLK+1] ;SET UP BLT BLT T1,PTHBLK+PTHSIZ-1 ;CLEAR THE PATH. UUO BLOCK GETPPN T1, ;GET OUR PPN JFCL ;INCASE OF JACCT MOVEM T1,FILPPN ;SAVE IT TLZ F,FL.DEV!FL.NAM!FL.EXT!FL.DIR ;CLEAR SCANNER FLAGS SCAN.1: PUSHJ P,SIXIN ;GET A FILESPEC PART JUMPN T1,SCAN.4 ;SEE WHAT WE GOT SCAN.2: CAIN T2,"." ;AN EXTENSION? JRST SCAN.5 ;YES CAIE T2,"[" ;A PATH? CAIN T2,"<" ;2741 STYLE? JRST SCAN.6 ;YES TO EITHER CAIN T2," " ;SPACE? JRST SCAN.1 ;KEEP SCANNING PUSHJ P,BACKUP ;BACKUP TO THE TERMINATING CHARACTER JRST SCNDEF ;CHECK LEGALITY AND DO DEFAULTING ; Device ; SCAN.3: TLOE F,FL.DEV ;ALREADY HAVE A DEVICE? ERR. (DDI,CPOPJ) ;DOUBLE DEVICE ILLEGAL MOVEM T1,FOPBLK+.FODEV ;SAVE DEVICE JRST SCAN.1 ;KEEP SCANNING ; File name ; SCAN.4: CAIN T2,":" ;A DEVICE? JRST SCAN.3 ;YES TLOE F,FL.NAM ;ALREADY HAVE A FILE NAME? ERR. (DFI,CPOPJ) ;DOUBLE FILE NAME ILLEGAL MOVEM T1,LERBLK+.RBNAM ;SAVE FILE NAME JRST SCAN.2 ;GO EXAMINE TERMINATOR ; Extension ; SCAN.5: TLOE F,FL.EXT ;ALREADY HAVE AN EXTENSION ERR. (DEI,CPOPJ) ;DOUBLE EXTENSION ILLEGAL PUSHJ P,SIXIN ;GET A WORD HLLZM T1,LERBLK+.RBEXT ;SAVE EXTENSION JRST SCAN.2 ;GO EXAMINE TERMINATOR ; Path ; SCAN.6: TLOE F,FL.DIR ;ALREADY HAVE A DIRECTORY? ERR. (DPI,CPOPJ) ;DOUBLE PATH ILLEGAL PUSHJ P,SCNPTH ;SCAN A PATH POPJ P, ;FAILED CAIE T2,"]" ;END OF PATH? CAIN T2,">" ;2741 STYLE? JRST SCAN.1 ;YES - LOOP BACK FOR MORE JRST SCAN.2 ;NO - CHECK OTHER TERMINATORS ; Scan a path ; SCNPTH: PUSHJ P,FLUSH ;EAT LEADING SPACES AND TABS CAIN T1,"-" ;WANT DEFAULT PATH? JRST SCNP.4 ;YES PUSHJ P,BACKUP ;BACKUP THE BYTE POINTER PUSHJ P,OCTIN ;GET PROJECT NUMBER TLNN T1,777777 ;SIXBIT PPN? HRLZS T1 ;NO TLNN T1,777777 ;HAVE A PROJECT NUMBER? HLL T1,FILPPN ;NO IORM T1,PTHBLK+.PTPPN ;SAVE IT TRNE T1,777777 ;SIXBIT PPN? JRST SCNP.1 ;YES CAIE T2,"," ;MUST HAVE A COMMA HERE ERR. (PSE,CPOPJ) ;PATH SYNTAX ERROR PUSHJ P,OCTIN ;GET PROGRAMMER NUMBER TLNE T1,777777 ;SIXBIT PPN? HLRZS T1 ;YES--TRUNCATE TO 18 BITS TRNN T1,777777 ;HAVE A PROGRAMMER NUMBER? HRR T1,FILPPN ;NO IORM T1,PTHBLK+.PTPPN ;SAVE IT SCNP.1: MOVEI T4,PTHBLK+.PTSFD ;POINT TO START OF SFDS HRLI T4,-<PTHSIZ-.PTSFD-1> ;MAKE AN AOBJN POINTER SCNP.2: CAIE T2,"," ;LEGAL SEPARATOR? JRST CPOPJ1 ;NO--DONE PUSHJ P,SIXIN ;GET AN SFD JUMPE T1,[ERR. (NSI,CPOPJ)] ;NULL SFDS ARE ILLEGAL MOVEM T1,0(T4) ;SAVE IT AOBJN T4,SCNP.2 ;LOOP ERR. (SND,CPOPJ) ;SFDS NESTED TOO DEEP SCNP.4: SETOM PTHBLK+.PTFCN ;SET FUNCTION CODE MOVE T1,[PTHSIZ,,PTHBLK] ;SET UP UUO PATH. T1, ;READ OUR DEFAULT PATH ERR. (CRP,CPOPJ) ;UUO FAILED--CAN'T READ PATH PUSHJ P,FLUSH ;EAT SPACES AND TABS JRST CPOPJ1 ;AND RETURN ; Check for a legal filespec and do extension defaulting ; SCNDEF: MOVSI T1,'DSK' ;GET A DEVICE TLNN F,FL.DEV ;ONE SPECIFIED? MOVEM T1,FOPBLK+.FODEV ;DEFAULT TO DSK TLNN F,FL.NAM!FL.EXT!FL.DIR ;ANY FILESPEC PARTS? JRST CPOPJ1 ;NO TLNN F,FL.EXE ;.EXE FILE? JRST CPOPJ1 ;A DATA FILE MOVSI T1,'EXE' ;GET AN EXTENSION TLNN F,FL.EXT ;EXTENSION SPECIFIED? MOVEM T1,LERBLK+.RBEXT ;DEFAULT IT JRST CPOPJ1 ;RETURN SUBTTL EXE file routines -- Load and validate directory ; Read an .EXE file directory into core ; Call: PUSHJ P,EXEDIR ; <NON-SKIP> ;BAD DIRECTORY OR I/O ERROR ; <SKIP> ;DIRECTORY IN CORE ; EXEDIR: MOVEI T1,1 ;GET STARTING BLOCK NUMBER OF DIRECTORY PUSHJ P,FILIPS ;POSITION FOR INPUT POPJ P, ;CAN'T MOVE T2,CSHPAG ;GET STARTING PAGE NUMBER IN CACHE LSH T2,11 ;CONVERT TO AN ADDRESS MOVEM T2,DIRADR ;SAVE IT MOVE T3,T2 ;COPY IT SETZM DIRPGS ;CLEAR COUNT OF DIRECTORY PAGES EXED.1: MOVE T1,DIRADR ;GET DIRECTORY BASE ADDRESS MOVE T4,DIRPGS ;GET EXISTING COUNT OF DIRECTORY PAGES CAIL T4,PAGCNT ;ENOUGH FREE PAGES LEFT FOR MAPPING? ERR. (NRE,CPOPJ) ;NO ROOM TO CACHE .EXE FILE DIRECTORY LSH T4,-11 ;CONVERT TO ADDRESS OFFSET ADDI T1,-1(T4) ;GET ADDRESS OF AVAILABLE BUFFER HRLI T1,-PAGSIZ ;MAKE AN IOWD MOVEM T1,IOLIST ;SAVE IT MOVEI T1,1(T1) ;GET ADDRESS ON NEW PAGE LSH T1,-11 ;CONVERT TO A PAGE NUMBER PUSHJ P,PAGCHK ;MAKE SURE THE PAGE IS THERE POPJ P, ;CAN'T CREATE IT PUSHJ P,FILRED ;READ A PAGE ERR. (EIE,CPOPJ) ;.EXE FILE DIRECTORY INPUT ERROR AOS DIRPGS ;COUNT DIRECTORY PAGES READ INTO CORE TRZ T3,PAGSIZ-1 ;STRIP OFF INDEX INDEX INTO PAGE ADDI T3,PAGSIZ ;ROUND UP A PAGE EXED.2: SKIPE T1,(T2) ;END OF DIRECTORY? JRST EXED.3 ;NO MOVN T1,DIRPGS ;GET -NUMBER OF DIRECTORY PAGES ADDM T1,PAGCNT ;ADJUST COUNT OF FREE PAGES MOVNS T1 ;GET +NUMBER OF DIRECTORY PAGES ADDM T1,CSHPAG ;UPDATE FIRST FREE PAGE FOR CACHING JRST CPOPJ1 ;AND RETURN EXED.3: HLRZS T1 ;KEEP JUST THE BLOCK TYPE MOVE T4,[-EXELEN,,EXETAB] ;AOBJN POINTER TO EXE BLOCK TYPES CAME T1,(T4) ;A MATCH? AOBJN T4,.-1 ;LOOP JUMPGE T4,[ERR. (BED,CPOPJ)] ;BAD EXE FILE DIRECTORY HRRZ T1,(T2) ;GET OFFSET TO NEXT BLOCK ADD T2,T1 ;POINT TO IT CAMGE T2,T3 ;NEED ANOTHER DIRECTORY PAGE? JRST EXED.2 ;CHECK OUT ALL BLOCKS JRST EXED.1 ;GO READ ANOTHER PAGE INTO CORE SUBTTL EXE file routines -- Find a file page ; Search a directory for a page ; Call: MOVE T1, page number ; PUSHJ P,EXEPAG ; <NON-SKIP> ;PAGE NOT FOUND, I/O ERROR ; <SKIP> ;PAGE FOUND, T1:= FILE PAGE NUMBER ; EXEPAG: TLNN F,FL.EXE ;MAPPING AN .EXE FILE? JRST CPOPJ1 ;NO - THEN ITS A DATA FILE MOVE T4,T1 ;SAVE PAGE NUMBER MOVEI T1,.SVDIR ;GET DESIRED BLOCK TYPE PUSHJ P,EXEBLK ;SEARCH FOR IT ERR. (BED,CPOPJ) ;BAD EXE FILE DIRECTORY MOVE T1,T4 ;GET PAGE NUMBER BACK AGAIN ADDI T2,1 ;POINT TO NEXT WORD EXEP.1: HLRZ T3,.SVFPF(T2) ;GET POSSIBLE BLOCK TYPE CAIN T3,.SVEND ;END OF DIRECTORY? ERR. (NXA,CPOPJ) ;NON-EXISTANT ADDRESS IN FILE LDB T3,EXEREP ;GET REPEAT COUNT LDB T4,EXEPPN ;GET PROCESS PAGE NUMBER ADD T4,T3 ;GET ENDING PAGE NUMBER CAMGE T4,T1 ;HIGH PAGE LESS THAN TARGET PAGE? JRST EXEP.3 ;YES EXEP.2: CAMN T4,T1 ;FOUND THE PAGE WE WANT? JRST EXEP.4 ;YES SUBI T4,1 ;DECREMENT PAGE NUMBER SOJGE T3,EXEP.2 ;LOOP EXEP.3: ADDI T2,2 ;POINT TO NEXT DIRECTORY PAGE ENTRY JRST EXEP.1 ;TRY AGAIN EXEP.4: LDB T1,EXEFPN ;GET FILE PAGE NUMBER ADD T1,T3 ;ADD REPEAT COUNT JRST CPOPJ1 ;AND RETURN ; Byte pointers to directory entry parts ; EXEREP: POINTR (.SVPPC(T2),SV%REP) ;REPEAT COUNT EXEPPN: POINTR (.SVPPC(T2),SV%PPN) ;PROCESS PAGE NUMBER EXEFPN: POINTR (.SVFPF(T2),SV%FPN) ;FILE PAGE NUMBER SUBTTL EXE file routines -- Find a directory block ; Find a block in an .EXE directory ; Call: MOVE T1, block type ; PUSHJ P,EXEBLK ; <NON-SKIP> ;CAN'T FIND IT ; <SKIP> ;BLOCK FOUND ; ; On sucessful return, T1:= block type,,length and T2:= directory address ; EXEBLK: MOVE T2,[-EXELEN,,EXETAB] ;AOBJN POINTER TO EXE BLOCK TYPES CAME T1,(T2) ;A MATCH? AOBJN T2,.-1 ;LOOP JUMPGE T2,[ERR. (BED,CPOPJ)] ;BAD EXE FILE DIRECTORY MOVE T2,DIRADR ;GET STARTING ADDRESS OF DIRECTORY EXEB.1: SKIPN T3,(T2) ;END OF DIRECTORY? ERR. (BED,CPOPJ) ;BAD EXE FILE DIRECTORY HLRZS T3 ;PUT IN RH CAMN T3,T1 ;A MATCH? JRST EXEB.2 ;YES HRRZ T3,(T2) ;GET LENGTH ADD T2,T3 ;POINT TO NEXT BLOCK JRST EXEB.1 ;LOOP EXEB.2: MOVE T1,(T2) ;GET BLOCK TYPE,,LENGTH JRST CPOPJ1 ;AND RETURN ; Table of legal .EXE file directory block types ; EXETAB: EXP .SVDIR ;START OF FILE TO CORE MAP EXP .SVEND ;END OF EXE FILE DIRECTORY EXP .SVSTA ;ENTRY VECTOR EXELEN==.-EXETAB ;LENGTH OF TABLE SUBTTL FORTRAN interface MAPD:: MOVEI .AP,@0(16) ;GET ARGUMENT POINTER PUSHJ P,.MAPD ;DO A DEPOSIT JRST MAPFER ;ERROR POPJ P, ;AND RETURN MAPE:: MOVE .AP,@0(16) ;GET ARG PUSHJ P,.MAPE ;EXAMINE JRST MAPFER ;ERROR MOVE 0,.AP ;INTO 0 FOR FORTRAN FUNCTION POPJ P, ;AND RETURN MAPG:: MOVE .AP,@0(16) ;GET ARG PUSHJ P,.MAPG ;GETTAB SIMULATION JRST MAPFER MOVE 0,.AP ;INTO 0 FOR FORTRAN FUNCTION POPJ P, ;AND RETURN MAPI:: MOVEI .AP,@0(16) ;ADDRESS OF ARG BLOCK PUSHJ P,.MAPI ;INITIALIZE JRST MAPFER ;ERROR POPJ P, ;AND RETURN MAPJ:: MOVEI .AP,@0(16) ;ADDRESS OF ARG BLOCK PUSHJ P,.MAPJ ;DO A JOBPEK JRST MAPFER ;ERROR POPJ P, ;AND RETURN ; Here on an error. See if error dispatch provided on call ; MAPFER: HLRE T1,-1(16) ;GET ARG COUNT CAMLE T1,[-2] ;TWO OR MORE? JRST MAPFE1 ;NO MOVEI T1,@1(16) ;YES--GET DISPATCH HRRM T1,(P) ;STUFF ON STACK POPJ P, ;AND DISPATCH MAPFE1: OUTSTR [ASCIZ/?Unhandled MAP error: /] OUTSTR MAPDAT+.MPMET OUTSTR [BYTE(7) 15,12,0] OUTSTR MAPDAT+.MPXET EXIT SUBTTL Context switch ; Here to save the user's ACs and set up a new stack. This is a ; co-routine that may NOT be called recursively to save 'n' sets ; of ACs. Skip returns are handled. ; Call: PUSHJ P,CONTXT ; CONTXT: AOSE CTXFLG ;ALREADY CONTEXT SWITCHED? POPJ P, ;YES - THEN DO NOTHING MOVEM 0,USRACS+0 ;SAVE AC 0 MOVE 0,[1,,USRACS+1] ;SET UP BLT BLT 0,USRACS+17 ;SAVE ACS 1 - 17 MOVE P,[IOWD PDLSIZ,MAPPDL] ;SETUP INTERNAL PDL MOVE F,MAPFLG ;GET MAPPING FLAGS TLNE F,FL.RTM ;WANT TO ACCUMLATE RUNTIME? PUSHJ P,GETRTM ;YES SETZM MAPDAT+.MPECD ;CLEAR OUT ANY OLD ERROR CODE SETZM MAPDAT+.MPMET ;INSURE NO JUNK MAPPING ERROR TEXT SETZM MAPDAT+.MPXET ;INSURE NO JUNK EXTENDED ERROR TEXT MOVE T2,USRACS+P ;GET OLD PDL POINTER MOVEI T2,@0(T2) ;GET CALLER'S ADDRESS PUSHJ P,(T2) ;CALL THE CALLER TDZA T1,T1 ;INDICATE NON-SKIP RETURN HRROI T1,-1 ;INDICATE SKIP RETURN MOVEM T1,TFFLAG ;SET TRUE OR FALSE TLNE F,FL.RTM ;WANT TO ACCUMLATE RUNTIME? PUSHJ P,GETRTM ;YES MOVEM F,MAPFLG ;UPDATE MAPPING FLAGS MOVE 0,[USRACS+1,,1] ;SET UP BLT BLT 0,17 ;RESTORE THE ACS MOVE 0,USRACS+0 ;RELOAD AC 0 POP P,(P) ;PRUNE STACK SETOM CTXFLG ;RESET CONTEXT FLAG SKIPGE TFFLAG ;FUNCTION FAIL? CPOPJ1: AOS (P) ;NO - THEN SKIP CPOPJ: POPJ P, ;RETURN GETRTM: MOVSI T2,(RN.PCN) ;RETURN PRECISION RUNTIME RUNTIM T2, ;GET IT EXCH T2,CPUTIM ;SAVE IT AND GET PREVIOUS JUMPE T2,CPOPJ ;RETURN IF CALLED AT CONTEXT ENTRY SETZ T3, ;CLEAR FOR NEXT TIME EXCH T3,CPUTIM ;AND GET OUR RUNTIME NOW SUB T3,T2 ;COMPUTE IMCREMENTAL ADDM T3,MAPDAT+.MPRTM ;ACCUMULATE IT POPJ P, ;AND RETURN SUBTTL Error handling ERROR: DMOVEM T1,ERRACS+0 ;SAVE T1 & T2 DMOVEM T3,ERRACS+2 ;SAVE T3 & T4 MOVEI T1,@(P) ;GET ADDRESS OF ARGUMENTS MOVE T1,(T1) ;GET ERROR CODE,,RETURN ADDRESS POP P,(P) ;TRIM STACK SKIPN MAPDAT+.MPECD ;NESTED ERRORS? HLRZM T1,MAPDAT+.MPECD ;STORE NEW ERROR CODE HLL T1,(P) ;GET PC FLAGS OR SECTION NUMBER EXCH T1,(P) ;SET RETURN PC AND GET PC OF ERROR MOVEI T1,@T1 ;EXTRACT JUST THE PC SUBI T1,2 ;POINT TO OFFENDING INSTRUCTION MOVEM T1,ERRPC ;SAVE IT LDB T1,[POINT 9,@ERRPC,8] ;GET THE OPCODE SKIPE T1 ;OPCODE ZERO IS MEANINGLESS CAILE T1,100 ;A UUO? SKIPA PUSHJ P,ERRUUO ;GENERATE UUO ERROR TEXT PUSHJ P,ERRMAP ;DO THE MAPPING ERROR DMOVE T1,ERRACS+0 ;RESTORE T1 & T2 DMOVE T3,ERRACS+2 ;RESTORE T3 & T4 POPJ P, ;AND RETURN ; Here to type specific mapping errors ; ERRMAP: SETZM MAPDAT+.MPMET ;CLEAR THE FIRST WORD MOVE T1,[MAPDAT+.MPMET,,MAPDAT+.MPMET+1] ;SET UP BLT BLT T1,MAPDAT+.MPMET+.MPEWD-1 ;CLEAR ENTIRE BLOCK SKIPN T3,MAPDAT+.MPECD ;HAVE AN ERROR? POPJ P, ;NO HLLZ T1,MAPERR-1(T3) ;GET PREFIX HLRZM T1,MAPDAT+.MPPFX ;SAVE FOR CALLER MOVEI T1,MAPDAT+.MPMET ;STORE TEXT HERE MOVEI T2,<.MPEWD*5>-1 ;MAX NUMBER OF CHARACTERS PUSHJ P,TXTSET ;SET IT UP HRRZ T1,MAPERR-1(T3) ;GET ASSOCIATED ERROR TEXT PUSHJ P,TSTRG ;TYPE IT ERRM.1: CAIE T3,MPGUF% ;GETTAB UUO FAILURE? JRST ERRM.2 ;NO MOVEI T1,[ASCIZ |; table = |] ;GET TEXT PUSHJ P,TSTRG ;TYPE IT HRRE T1,USRACS+.AP ;GET TABLE NUMBER PUSHJ P,OCTOUT ;TYPE IT MOVEI T1,[ASCIZ |, index = |] ;GET TEXT PUSHJ P,TSTRG ;TYPE IT HLRE T1,USRACS+.AP ;GET INDEX PUSHJ P,OCTOUT ;TYPE IT JRST ERRM.X ;FINISH UP ERRM.2: CAIE T3,MPDAF% ;DEPOSIT ADDRESS FAILURE? CAIN T3,MPEAF% ;EXAMINE ADDRESS FAILURE? SKIPA T1,USRACS+.AP ;YES--GET ARGUMENT JRST ERRM.3 ;NO CAIN T3,MPDAF% ;DEPOSIT? MOVE T1,0(T1) ;GET ADDRESS PUSH P,T1 ;SAVE IT MOVEI T1,[ASCIZ |; address = |] ;GET TEXT PUSHJ P,TSTRG ;TYPE IT POP P,T1 ;RESTORE ADDRESS PUSHJ P,PCOUT ;TYPE IT JRST ERRM.X ;FINISH UP ERRM.3: CAIE T3,MPMIF% ;MAPPER INITIALIZATION FAILURE JRST ERRM.X ;NO HRRZ T3,F ;GET MAPPING CODE CAIE T3,.MPFIL ;FILE MODE? JRST ERRM.X ;NO MOVEI T1,[ASCIZ |; file = |] ;GET TEXT PUSHJ P,TSTRG ;TYPE IT MOVE T1,USRACS+.AP ;GET ARGUMENT ADDRESS MOVE T1,.MPARG(T1) ;GET ADDRESS OF FILESPEC ADDRESS SKIPE MAPDAT+.MPAFS ;HAVE ACTUAL FILESPEC YET? MOVEI T1,MAPDAT+.MPAFS ;YES--USE THAT PUSHJ P,TSTRG ;TYPE IT JRST ERRM.X ;FINISH UP ERRM.X: POPJ P, ;AND RETURN ; Table of mapping errors ; ...ERR==0 MAPERR: MERR. (BED,<Bad EXE file directory>) MERR. (CMF,<Conflicting mapping code and flags>) MERR. (CRP,<Cannot read default path>) MERR. (DAF,<Deposit address failure>) MERR. (DDI,<Double device illegal>) MERR. (DEI,<Double extension illegal>) MERR. (DFI,<Double file name illegal>) MERR. (DPI,<Double path illegal>) MERR. (DVM,<Deposit value doesn't match existing word>) MERR. (EAF,<Examine address failure>) MERR. (ECS,<Left eye can't SPY>) MERR. (EIE,<EXE file directory input error>) MERR. (GUF,<GETTAB UUO/simulation failure>) MERR. (HAF,<Hash table/chunk allocation failure>) MERR. (IAD,<Illegal address>) MERR. (ICS,<Illegal cache size requested>) MERR. (IJN,<Illegal job number>) MERR. (IMC,<Illegal mapping code>) MERR. (IWE,<Illegal to write Exec Virtual Memory>) MERR. (IWU,<Illegal to write the UPMP>) MERR. (JNA,<Job not addressable>) MERR. (JRW,<JOBPEK UUO failed to read/write another job>) MERR. (JSO,<Job swapped out>) MERR. (MIF,<Mapper initialization failure>) MERR. (NAP,<No access to requested page>) MERR. (NEB,<No EPT for boot CPU>) MERR. (NFC,<No free chunks for cache>) MERR. (NRE,<No room to cache EXE file directory>) MERR. (NSI,<Null SFD illegal>) MERR. (NXA,<Non-existant address in file>) MERR. (PNC,<Page not in core>) MERR. (PSE,<Path syntax error>) MERR. (SIR,<SPT index out of range>) MERR. (SND,<SFDs nested too deep>) MERR. (UPC,<Unimplemented KL paging code>) ; Here to type specific UUO error text ; ERRUUO: PUSHJ P,UUOERR ;TRANSLATE ERROR CODE SETZM MAPDAT+.MPXET ;CLEAR THE FIRST WORD MOVE T1,[MAPDAT+.MPXET,,MAPDAT+.MPXET+1] ;SET UP BLT BLT T1,MAPDAT+.MPXET+.MPEWD-1 ;CLEAR ENTIRE BLOCK MOVEI T1,MAPDAT+.MPXET ;STORE TEXT HERE MOVEI T2,<.MPEWD*5>-1 ;MAX NUMBER OF CHARACTERS PUSHJ P,TXTSET ;SET IT UP MOVEI T1,11 ;GET A <TAB> PUSHJ P,TYO ;TYPE IT MOVE T1,ERRNAM ;GET UUO NAME PUSHJ P,SIXOUT ;TYPE IT MOVEI T1,[ASCIZ | UUO error |] ;GET TEXT PUSHJ P,TSTRG ;TYPE IT LDB T1,[POINT 4,@ERRPC,12] ;GET UUO AC CAIG T1,T4 ;WITHIN THE RANGE CAIGE T1,T1 ;OF T1 - T4? SKIPA T1,(T1) ;NO--GET THE ERROR CODE MOVE T1,ERRACS-T1(T1) ;YES--RELOCATE AND GET THE CODE PUSHJ P,OCTOUT ;TYPE IT MOVEI T1,[ASCIZ | at PC |] ;GET TEXT PUSHJ P,TSTRG ;TYPE IT MOVE T1,ERRPC ;GET PC WHERE UUO FAILED PUSHJ P,PCOUT ;TYPE IT MOVEI T1,[ASCIZ |; |] ;GET SEPARATOR PUSHJ P,TSTRG ;TYPE IT MOVE T1,ERRTXT ;GET ADDRESS OF TEXT FOR THIS ERROR PUSHJ P,TSTRG ;TYPE IT PUSHJ P,TCRLF ;TYPE A CRLF MOVEI T1,11 ;GET A TAB PUSHJ P,TYO ;TYPE IT MOVEI T1,VERSIO ;POINT TO OUR VERSION PUSHJ P,TSTRG ;TYPE IT MOVEI T1,[ASCIZ | called from PC |] PUSHJ P,TSTRG ;TYPE TEXT MOVE T1,USRACS+P ;GET CALLER'S STACK POINTER MOVEI T1,@-1(T1) ;GET CALLER'S PC +1 SUBI T1,1 ;ADJUST IT PUSHJ P,PCOUT ;TYPE THE PC MOVEI T1,[ASCIZ |, Mode = |] ;GET TEXT PUSHJ P,TSTRG ;TYPE IT MOVE T1,CODTAB(F) ;GET MAPPING CODE NAME PUSHJ P,TSTRG ;TYPE IT MOVEI T1,[ASCIZ | (physical)|] ;MORE CHATTER TLNE F,FL.PPM ;PHYSICAL PAGE MAPPING? PUSHJ P,TSTRG ;YES POPJ P, ;RETURN ; Translate UUO error code to text ; Note: GETTAB failures are not trapped here ; UUOERR: MOVE T1,[-UUOTSZ,,UUOTAB] ;AOBJN POINTER MOVE T2,@ERRPC ;GET UUO IN QUESTION TDZ T2,[Z 17,@UU.PHY(17)] ;CLEAR OUT JUNK UUOE.1: CAMN T2,0(T1) ;A MATCH? JRST UUOE.2 ;YES ADD T1,[2,,2] ;ACCOUNT FOR THREE WORD ENTRIES AOBJN T1,UUOE.1 ;TRY THE NEXT ONE MOVE T2,['??????'] ;DON'T KNOW THAT ONE JRST UUOE.4 ;STRANGE UUOE.2: MOVE T2,1(T1) ;GET UUO NAME MOVE T1,2(T1) ;AOBJN POINTER TO UUO SPECIFIC TABLE LDB T3,[POINT 4,@ERRPC,12] ;GET UUO AC CAIG T3,T4 ;WITHIN THE RANGE CAIGE T3,T1 ;OF T1 - T4? SKIPA T3,(T3) ;NO--GET THE ERROR CODE MOVE T3,ERRACS-T1(T3) ;YES--RELOCATE AND GET THE CODE UUOE.3: HLRZ T4,(T1) ;GET AN ERROR CODE CAMN T3,T4 ;A MATCH? JRST UUOE.5 ;YES AOBJN T1,UUOE.3 ;LOOP UUOE.4: SKIPA T3,[[ASCIZ |Unknown UUO error code|]] UUOE.5: HRRZ T3,(T1) ;GET ERROR TEXT MOVEM T2,ERRNAM ;SAVE UUO NAME MOVEM T3,ERRTXT ;SAVE ERROR TEXT POPJ P, ;RETURN UUOTAB: EXP <FILOP.>,<SIXBIT /FILOP./>,<-FOPESZ,,FOPERR> EXP <JOBPEK>,<SIXBIT /JOBPEK/>,<-JPKESZ,,JPKERR> EXP <PAGE. >,<SIXBIT /PAGE. />,<-PAGESZ,,PAGERR> EXP <PATH. >,<SIXBIT /PATH. />,<-PATESZ,PATERR> EXP <POKE. >,<SIXBIT /POKE. />,<-POKESZ,,POKERR> UUOTSZ==.-UUOTAB ; FILOP. UUO errors ; FOPERR: ERFNF%,,[ASCIZ |File not found|] ERIPP%,,[ASCIZ |Incorrect PPN|] ERPRT%,,[ASCIZ |Protection failure|] ERFBM%,,[ASCIZ |File being modified|] ERDNA%,,[ASCIZ |Device not available|] ERNSD%,,[ASCIZ |No such device|] ERWLK%,,[ASCIZ |Write-locked|] ERSNF%,,[ASCIZ |SFD not found|] ERSLE%,,[ASCIZ |Search list empty|] ERLVL%,,[ASCIZ |SFD nest level too deep|] ERNCE%,,[ASCIZ |No-creates allowed in search list|] ERFCU%,,[ASCIZ |Can't update file|] ERENQ%,,[ASCIZ |File has outstanding locks set|] ERDDU%,,[ASCIZ |Device "down" and unusable|] ERDRS%,,[ASCIZ |Device is restricted|] ERDCM%,,[ASCIZ |Device controlled by MDA|] ERDAJ%,,[ASCIZ |Device allocated to another job|] ERIDM%,,[ASCIZ |Illegal I/O data mode|] ERNPC%,,[ASCIZ |No per-process space for extended channel|] ERNFC%,,[ASCIZ |No free channels available|] ERACR%,,[ASCIZ |Address check reading arguments|] ERACS%,,[ASCIZ |Address check storing answer|] FOPESZ==.-FOPERR ; JOBPEK UUO errors ; JPKERR: JKNPV%,,[ASCIZ |No privileges|] JKIJN%,,[ASCIZ |Illegal job number|] JKSWP%,,[ASCIZ |Job swapped out or in transit|] JKIAD%,,[ASCIZ |Illegal address|] JKDNA%,,[ASCIZ |Data not addressable|] JKPNC%,,[ASCIZ |Page not in core|] JKIOE%,,[ASCIZ |I/O error|] JKABZ%,,[ASCIZ |Allocated but zero page|] JPKESZ==.-JPKERR ; PAGE. UUO errors ; PAGERR: PAGUF%,,[ASCIZ |Unimplemented function|] PAGIA%,,[ASCIZ |Illegal argument|] PAGIP%,,[ASCIZ |Illegal page number|] PAGCE%,,[ASCIZ |Page can't exist but does|] PAGME%,,[ASCIZ |Page must exist but doesn't|] PAGMI%,,[ASCIZ |Page must be in core but isn't|] PAGCI%,,[ASCIZ |Page can't be in core but is|] PAGSH%,,[ASCIZ |Page is in a sharable high segment|] PAGIO%,,[ASCIZ |Paging I/O error|] PAGNS%,,[ASCIZ |No swapping space available|] PAGLE%,,[ASCIZ |Core limit exceeded|] PAGIL%,,[ASCIZ |Illegal if locked|] PAGNX%,,[ASCIZ |Cannot create allocated but zero page|] PAGNP%,,[ASCIZ |Not privileged|] PAGESZ==.-PAGERR ; PATH. UUO errors ; PATERR: PTNSJ%,,[ASCIZ |No such job|] PTNAI%,,[ASCIZ |Number of arguments illegal|] PATESZ==.-PATERR ; POKE. UUO errors ; POKERR: PKNPV%,,[ASCIZ |No privileges|] PKDIF%,,[ASCIZ |Old value doesn't match existing word|] PKBAD%,,[ASCIZ |Illegal address|] POKESZ==.-POKERR SUBTTL AC save routines ; Save T1 ; SAVT1: PUSH P,T1 ;SAVE T1 PUSHJ P,@-1(P) ;CALL THE CALLER SKIPA ;NON-SKIP RETURN AOS -2(P) ;ADJUST RETURN PC POP P,T1 ;RESTORE T1 SUB P,[1,,1] ;ADJUST STACK POPJ P, ;RETURN ; Save T1 and T2 ; SAVT2: ADD P,[2,,2] ;ADJUST STACK DMOVEM T1,-1(P) ;SAVE T1 AND T2 PUSHJ P,@-2(P) ;CALL THE CALLER SKIPA ;NON-SKIP RETURN AOS -3(P) ;ADJUST RETURN PC DMOVE T1,-1(P) ;RESTORE T1 AND T2 SUB P,[3,,3] ;ADJUST STACK POPJ P, ;RETURN ; Save T1, T2, and T3 ; SAVT3: ADD P,[3,,3] ;ADJUST STACK DMOVEM T1,-2(P) ;SAVE T1 AND T2 MOVEM T3,0(P) ;SAVE T3 PUSHJ P,@-3(P) ;CALL THE CALLER SKIPA ;NON-SKIP RETURN AOS -4(P) ;ADJUST RETURN PC DMOVE T1,-2(P) ;RESTORE T1 AND T2 MOVE T3,0(P) ;RESTORE T3 SUB P,[4,,4] ;ADJUST STACK POPJ P, ;RETURN ; Save T1, T2, T3, and T4 ; SAVT4: ADD P,[4,,4] ;ADJUST STACK DMOVEM T1,-3(P) ;SAVE T1 AND T2 DMOVEM T3,-1(P) ;SAVE T3 AND T4 PUSHJ P,@-4(P) ;CALL THE CALLER SKIPA ;NON-SKIP RETURN AOS -5(P) ;ADJUST RETURN PC DMOVE T1,-3(P) ;RESTORE T1 AND T2 DMOVE T3,-1(P) ;RESTORE T3 AND T4 SUB P,[5,,5] ;ADJUST STACK POPJ P, ;RETURN ; Save F ; SAVEF: PUSH P,F ;SAVE F PUSHJ P,@-1(P) ;CALL THE CALLER SKIPA ;NON-SKIP RETURN AOS -2(P) ;ADJUST RETURN PC POP P,F ;RESTORE F SUB P,[1,,1] ;ADJUST STACK POPJ P, ;RETURN SUBTTL Literals LIT MPHEND::! ;END OF THE HIGH SEGMENT HGHSIZ==MPHEND-HGHORG ;LENGTH OF THE HIGH SEGMENT SUBTTL Data storage RELOC 0 ;LOW SEGMENT MAPARG::BLOCK .MPMAX ;PLACE FOR PEOPLE TO PUT ARG BLOCKS ZBEG:! ;START OF DATA TO ZERO MAPDAT::BLOCK .MPLEN ;DATA TABLE CTXFLG: BLOCK 1 ;CONTEXT FLAG USRACS: BLOCK 20 ;USER'S ACS MAPPDL: BLOCK PDLSIZ ;INTERNAL PDL TFFLAG: BLOCK 1 ;TRUE/FALSE FLAG CPUTIM: BLOCK 1 ;USED FOR RUNTIM ACCUMULATION ERRACS: BLOCK 4 ;ERROR ACS (T1 - T4) ERRPC: BLOCK 1 ;ERROR PC ERRNAM: BLOCK 1 ;NAME OF UUO ERRTXT: BLOCK 1 ;ADDRESS OF UUO ERROR TEXT POKBLK: BLOCK 3 ;POKE. UUO BLOCK CPYBLK: BLOCK .CBXLN ;COPY BLOCK JPKFLG: BLOCK 1 ;JOBPEK FLAG WORD MAPFLG: BLOCK 1 ;MAPPING FLAGS USRJOB: BLOCK 1 ;USER JOB NUMBER UUOARG: BLOCK 2 ;UUO ARGUMENTS HASHTA: BLOCK 1 ;HASH TABLE ADDRESS HASHTL: BLOCK 1 ;HASH TABLE LENGTH HASHCA: BLOCK 1 ;ADDRESS OF FIRST CHUNK HASHCL: BLOCK 1 ;LENGTH OF CHUNK AREA PAGCNT: BLOCK 1 ;COUNT OF AVAILABLE PAGES FOR MAPPING CSHXCT: BLOCK 1 ;INSTRUCTION TO TEST PHYSICAL PAGE BIT CSHPAG: BLOCK 1 ;FIRST PAGE NUMBER FOR MAPPING CBHEAD: BLOCK .CBLEN ;CACHE BLOCK LIST HEADER PAGFUN: BLOCK 1 ;FUNNY PAGE UPT OFFSET PAGFLG: BLOCK 1 ;PAGE MAP ENTRY FLAG PAGIDX: BLOCK 1 ;SECONDARY PAGE MAP INDEX JOBN: BLOCK 1 ;NUMBER OF JOBS IN THE SYSTEM SEGN: BLOCK 1 ;NUMBER OF SEGMENTS IN THE SYSTEM KLPFLG: BLOCK 1 ;KL PAGING FLAG EDVADR: BLOCK 1 ;EDV ADDRESS EDVCNT: BLOCK 1 ;EDV COUNT WORD EDVDAT: BLOCK 1 ;EDV FLAGS AND CPU DATA WORD EPTADR: BLOCK 1 ;EPT ADDRESS SPTADR: BLOCK 1 ;SPT ADDRESS NUMTAB: BLOCK 1 ;POINTER TO NUMTAB IN THE MONITOR RNGTAB: BLOCK 1 ;POINTER TO RNGTAB IN THE MONITOR JBTSGN: BLOCK 1 ;POINTER TO JBTSGN IN THE MONITOR JBTPDB: BLOCK 1 ;POINTER TO JBTPDB IN THE MONITOR JBTADR: BLOCK 1 ;POINTER TO JBTADR IN THE MONITOR JBTUPM: BLOCK 1 ;POINTER TO JBTUPM IN THE MONITOR HIORG: BLOCK 1 ;MONITOR'S HIGH SEGMENT ORIGIN HIFLAG: BLOCK 1 ;HIGH SEGMENT MAPPED FALG HGHUEA: BLOCK 1 ;HIGHEST UNMAPPED EXEC ADDRESS PPABEG: BLOCK 1 ;BEGINING PER-PROCESS ADDRESS PPAEND: BLOCK 1 ;ENDING PER-PROCESS ADDRESS +1 GTBARG: BLOCK 1 ;GETTAB ARGUMENT GTBNUM: BLOCK 1 ;NUMTAB ENTRY FOR CURRENT GETTAB GTBIDX: BLOCK 1 ;INDEX INTO GETTAB DISPATCH TABLE GTBRNG: BLOCK 1 ;LOWER,,UPPER LIMIT FOR RANGE BYTPTR: BLOCK 1 ;BYTE POINTER BYTCNT: BLOCK 1 ;BYTE COUNT FILCHN: BLOCK 1 ;FILE CHANNEL NUMBER IOLIST: BLOCK 2 ;IOWD DIRADR: BLOCK 1 ;.EXE DIRECTORY ADDRESS DIRPGS: BLOCK 1 ;NUMBER OF PAGES IN .EXE DIRECTORY FOPBLK: BLOCK FOPSIZ ;FILOP. UUO BLOCK LERBLK: BLOCK LERSIZ ;LOOKUP/ENTER UUO BLOCK PTHBLK: BLOCK PTHSIZ ;PATH. UUO BLOCK FILBLK: BLOCK FILSIZ ;BLOCK TO RETURN FULL FILESPEC FILPPN: BLOCK 1 ;DEFAULT PPN ZEND:! ;END OF DATA TO ZERO SUBTTL End END