Trailing-Edge
-
PDP-10 Archives
-
BB-H506D-SM_1983
-
cobol/source/mmangr.mac
There are 6 other files named mmangr.mac in the archive. Click here to see a list.
; UPD ID= 3369 on 1/30/81 at 9:02 AM by WRIGHT
TITLE MMANGR - Memory manager
SUBTTL D. WRIGHT
;COPYRIGHT (C) 1981 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.
SEARCH MMANGU ;Search memory manager universal file
;Picks up TOPS20 definition
IFN TOPS20,<
SEARCH MONSYM,MACSYM
>
IFE TOPS20,<
SEARCH UUOSYM,MACTEN
>
SALL
;AC definitions
T1=1 ;Usual temps
T2=2
T3=3
T4=4
T5=5
P1=6 ;Perm.
P2=7
P3=10
P=17 ;Pushdown ptr.
;Entry points to MMANGR:
ENTRY INITM ;Initialize memory manager
ENTRY MMGPMP ;Entry to pass page map of section 0
ENTRY INITMU ;Initialize one user
ENTRY FINFRE ;Find free pages
ENTRY RETRN ;Return pages to free pool
IFE TOPS20,<
TWOSEG 400K ;Two-segment program, relocate to 400K
>;End IFE TOPS20
SUBTTL MACROS
IFN TOPS20,<
DEFINE TYPE (ADDR),<
HRROI 1,ADDR
PSOUT%
>;END DEFINE TYPE
>;END IFN TOPS20
IFE TOPS20,<
DEFINE TYPE (ADDR),<
OUTSTR ADDR
>;END DEFINE TYPE
>;END IFE TOPS20
DEFINE $TEXT(STRING),<
XLIST
ASCIZ |STRING|
LIST
>;END DEFINE $TEXT
SUBTTL INITM - Initialize memory manager
;Called only once by a program when it first starts up.
;If the main program runs in section 0 but you want the memory
;manager to use memory in other sections, the program must first
;map itself to section 1, then call INITM in section 1.
;
;Call:
; 1/ flags (MM%UXS)
;Return:
; 1/ Status 0=ok, 1=problem
INITM: PUSH P,T1 ;SAVE AC1 FOR A SECOND.
SETZM MMDST ;CLEAR DATA AREA
MOVE T1,[MMDST,,MMDST+1]
BLT T1,MMDEN
POP P,T1 ;RESTORE AC1
IFN TOPS20,<
SETZM MMEXSC ;CLEAR "USE EXTENDED SECTIONS" FLAG
TXNN T1,MM%UXS ;DOES HE WANT TO ALLOW THEM?
JRST INITM2 ;NO
XMOVEI T1,INITM ;WHERE ARE WE?
TLNN T1,-1 ;IN SECTION 0?
JRST INITM0 ;YES, GIVE WARNING AND GO ON
SETOM MMEXSC ;SET "ALLOW EXTENDED ADDRESSES" FLAG
JRST INITM2 ;GO ON
INITM0: TYPE [ASCIZ/%MMANGR: (INITM) Memory will only be managed in section 0
/]
>;END IFN TOPS20
INITM2:
IFN TOPS20, XMOVEI T1,MYPGS ;GET START OF MY 2 PAGES
IFE TOPS20, MOVEI T1,MYPGS ;Get start of my page
TRZE T1,777 ; ROUND UP TO NEAREST PAGE
ADDI T1,1000
MOVEM T1,PTRLSU ;POINTER TO USER DATA
IFN TOPS20,<
ADDI T1,1000 ;NEXT PAGE
MOVEM T1,PTRLSS ;POINTER TO SECTION DATA
>;END IFN TOPS20
IFE TOPS20,<
JRST RETST0 ;RETURN STATUS 0
>;END IFE TOPS20
IFN TOPS20,<
;FIND A FREE SECTION TO USE FOR MEMORY ALLOCATION
SKIPN MMEXSC ;USE EXTENDED SECTIONS?
JRST RETST0 ;NO, JUST RETURN STATUS 0
PUSHJ P,FINPRS ;FIND A PRIVATE SECTION I CAN TAKE OVER.
JRST INITE3 ;?CAN'T, GIVE UP
MOVE T2,PTRLSS ;GET PTR TO SECTION DATA
AOS .MSNSH(T2) ;Count another section defined
ADDI T2,.MSSSB ;POINT TO START OF 1ST SECTION BLOCK
MOVEM T1,.MSSCN(T2) ;STORE SECTION NUMBER
; EVERYTHING ELSE IN ENTRY IS ZERO
JRST RETST0 ;RETURN STATUS 0
INITE3: TYPE TPRINI
TYPE [ASCIZ/ Can't find a private section
/]
JRST RETST1 ;RETURN STATUS 1
>;END IFN TOPS20
;Print this first on INITM errors
TPRINI: $TEXT <?MMANGR: Routine "INITM" encountered a problem:
>
IFN TOPS20,<
;ROUTINE TO FIND A PRIVATE SECTION AND CREATE IT.
; RETURNS .+1 IF CAN'T
; RETURNS .+2 IF GOT ONE, SEC # IN T1
;USES T1 AND T2 ONLY
FINPRS: DMOVEM T3,MMAC34 ;SAVE USER ACS 3 AND 4
MOVEI T3,2000 ;START LOOKING WITH SECTION 2
MOVEI T4,^D20 ; STOP AFTER THIS MANY TRIES
RPSLP: MOVE T1,T3 ;GET PAGE NUMBER TO CHECK
HRLI T1,.FHSLF ;MY FORK
RPACS% ;DOES SECTION EXIST?
ERJMP RPSL11 ;FOUND AN UNUSED ONE!
ADDI T3,1000 ;BUMP PAGE NUMBER TO NEXT SECTION
SOJG T4,RPSLP ; TRY A BUNCH OF TIMES
JRST CCRETP ;? TOO BAD
RPSL11: LSH T3,-^D9 ;T3= SECTION NUMBER
SETZ T1, ;WANT PRIVATE SECTIONS
HRLI T2,.FHSLF ;SECTION IN THIS FORK
HRR T2,T3 ;GET SECTION NUMBER
MOVE T4,T3 ;SAVE SECT #
MOVX T3,PM%RD!PM%WR+1 ;READ WRITE AND ONE SECTION
SMAPLP: SMAP% ;TELL MONITOR WE WANT TO USE OTHER SECTIONS
ERJMP CCRETP ;FAILED
MOVE T1,T4 ;RETURN SECTION NUMBER IN T1
DMOVE T3,MMAC34 ;RESTORE ACS 3 AND 4
AOS (P) ;SKIP RETURN
POPJ P, ;RETURN
CCRETP: DMOVE T3,MMAC34 ;RESTORE ACS 3 AND 4
POPJ P, ;RETURN .+1
>;END IFN TOPS20
SUBTTL MMGPMP - Copy section 0 map
;CALL:
; 1/ ptr to section 0 map
;Return:
; 1/ Status 0
MMGPMP: PUSH P,T3 ;SAVE AC 3
PUSH P,T2 ;AND T2
MOVE T3,[-SCMPSZ,,SC0MAP] ;AOBJN PTR TO SC0MAP
MMGPM1: MOVE T2,(T1) ;GET A WORD
MOVEM T2,(T3) ; COPY IT TO MY MAP
ADDI T1,1 ;BUMP #1 POINTER
AOBJN T3,MMGPM1 ;LOOP
POP P,T2 ;Restore ac2
POP P,T3 ;RESTORE AC 3
SETOM HAVSC0 ;SET "HAVE A SECTION 0 MAP" FLAG
JRST RETST0
SUBTTL INITMU - Initialize memory manager for a user
;Called once for every module that uses the memory manager.
;Call:
; 1/ flags (MM%CRM, MM%UXS)
; 2/ SIXBIT NAME
; 3/ (If MM%CRM set) Address of routine to return memory usage
; 4/ (If MM%CRM set) Address of routine to cut back memory usage
;Return:
; 1/ Status 0=ok, 1=problem
INITMU: DMOVEM T5,MMAC56 ;SAVE A COUPLE ACS
AOS T5,NMMODS ;GET # OF MODULES
CAILE T5,MNPPAG ;Exceeded one page of info?
JRST INMUE0 ;YES, COMPLAIN
SKIPN T5,PTRLSU ;GET PTR TO LIST OF USERS
JRST INMUE1 ;ERROR- PTR NOT SETUP
INIU1: SKIPN .MNNXT(T5) ;IS THERE A NEXT BLOCK?
JRST INIU2 ;NO, LINK TO END
MOVE T5,.MNNXT(T5) ;GET PTR TO NEXT BLOCK
JRST INIU1 ;SEARCH FOR END OF CHAIN
INIU2: SKIPN .MNNAM(T5) ;IS NAME OF THIS ONE NULL?
JRST INIU3 ;YES, FIRST ONE
MOVE P1,T5 ;GET START OF NEXT BLOCK
ADDI P1,.MNSIZ
MOVEM P1,.MNNXT(T5) ;STORE IN CURRENT ENTRY
MOVE T5,P1 ;SET T5= START OF THIS BLOCK
INIU3: MOVEM T1,.MNNFL(T5) ;STORE FLAGS
MOVEM T2,.MNNAM(T5) ;STORE NAME
TXNN T1,MM%CRM ;ADDRS GIVEN?
JRST INIU4 ;NO
MOVEM T3,.MNARU(T5) ; YES, STORE ADDRESSES OF ROUTINES
MOVEM T4,.MNACB(T5)
INIU4: DMOVE T5,MMAC56 ;RESTORE SAVED ACS
JRST RETST0 ;RETURN STATUS 0
;ERRORS IN INITMU
INMUE0: TYPE IMUEH ;TYPE HEADER
TYPE [ASCIZ/ Too many modules called the initialize routine
/]
DMOVE T5,MMAC56 ;RESTORE ACS
JRST RETST1 ;RETURN STATUS 1
INMUE1: TYPE IMUEH ;TYPE HEADER
TYPE [ASCIZ/ "INITM" routine not called by main program
/]
DMOVE T5,MMAC56 ;RESTORE ACS
JRST RETST1 ;RETURN STATUS 1
IMUEH: $TEXT <?MMANGR: "INITMU" routine encountered a problem:
>
SUBTTL FINFRE - Find free pages
;Call:
; 1/ flags (MM%GSS, MM%NCL)
; 2/ number of pages
;Returns:
; 1/ Status 0=ok, 1=can't get (system error), 2=can't get (user error)
; 2/ Address of start of block
;If status returned = 2, then message has been typed out
FINFRE: SKIPN MMEXSC ;Extended sections available?
TXO T1,MM%GSS ;No, whether he cares or not we are
; going to get memory in his current section
DMOVEM T1,MMAC12 ;SAVE ACS 1 & 2
DMOVEM T3,MMAC34 ;SAVE ACS 3 & 4
IFN TOPS20,<
SETOM SECRST ;Assume no section restriction
TXNN T1,MM%GSS ;Get core in current section?
JRST FINFR1 ;No, use extended sections
>;END IFN TOPS20
IFE TOPS20,<
SETZM SECRST ;Restricted to section 0
JRST FINRS0 ;Get memory from section 0
>
;GET CALLER'S SECTION
IFN TOPS20,<
MOVE T2,(P) ;Get top of pushdown stack
TLZ T2,770000 ;CLEAR PC FLAGS
HLRZ T2,T2 ;SECTION # IN T2
MOVEM T2,SECRST ;Remember we are restricted to this section
JUMPE T2,FINRS0 ;Restricted to section 0
;Use extended sections.. fall into "FINFR1"
; continued on next page..
;Here if we will use extended sections
;SECRST/ section number to restrict us to, or -1
FINFR1: MOVE T1,MMAC12+1 ;Try to find this many pages
MOVE T2,MMAC12 ;Flags in t2
PUSHJ P,FINSOM ;. .
JUMPE T1,FINFRG ;Return if got 'em
;Didn't get them. We have to create another section.
MOVE T4,T2 ;Save address of last section page
MOVE T3,.MSNSH(T4) ;Get # of sections defined on this page
CAIE T3,MSPPAG ;Is it at the maximum already?
JRST FINFR2 ;No
;Try to get another section page from a section we have already
PUSH P,SECRST ;Don't restrict us to a section now
SETOM SECRST ;. .
MOVEI T1,1 ;Try to find this many pages
MOVX T2,0 ;No flags
PUSHJ P,FINSOM
POP P,SECRST ;Restore section restriction, if any
JUMPN T1,FINFR2 ;Jump if can't find a free page
MOVEM T2,.MSPNX(T4) ;Link last page to this new one
MOVE T4,T2 ;T4= address of new page
;Here to create a new section and try again
FINFR2: PUSHJ P,FINPRS ;Go get a private section
JRST FINFR9 ;Can't
;Got it. Create a section block for it (tacked on end of list).
MOVE T3,.MSNSH(T4) ;Get # of sections defined on this page
CAIE T3,MSPPAG ;Is it at the maximum?
JRST FINFR3 ;No
HRLZ T3,T1 ;T3= address of new section-page
MOVEM T3,.MSPNX(T4) ;Store address of next section-page
MOVE T4,T3 ;T4= address of new section-page
MOVEI T2,1 ;1 section defined on this page
MOVEM T2,.MSNSH(T4)
MOVE T3,T4
ADDI T3,.MSSSB ;T3= address of section block to define
JRST FINFR4
;Same section-page can be used
FINFR3: IMULI T3,.MSSIZ ;Get offset of next section block
ADD T3,T4 ; Get absolute address
MOVE T2,T3 ;store "next" address in previous section entry
SUBI T2,.MSSIZ
MOVEM T3,.MSNXT(T2) ;. .
;Increment # sections defined on this page
MOVEI T2,1
ADDM T2,.MSNSH(T4)
;Here with T3 = address of section-block
; t4 = address of current section-block page
; T1 = section number of new section
;At this point, .MSNSH(T4) has been updated
;All that needs to be done is to create the section block info itself
FINFR4: MOVEM T1,.MSSCN(T3) ;Store section number in entry
HRLZ T1,T1 ;Get address of first page in section
CAMN T1,T4 ; Is this first page used?
SKIPA T1,[1B0] ;Yes, mark it as not free
SETZ T1, ;No, mark it as free
MOVEM T1,.MSPGD(T3) ;Store 1st word of page data
SETZM .MSNXT(T3) ;Clear "next" pointer
;Set pages-in-use bits to all zeroes
MOVEI T1,<^D512/^D36> ; Number of words minus 1
SETZM .MSPGD+1(T3) ;Clear a word
SOJG T1,.-1 ; Do them all
;Try original request again
MOVE T1,MMAC12+1 ;Number of pages he wants
MOVE T2,MMAC12 ;Flags
PUSHJ P,FINSOM
JUMPE T1,FINFRG ;Got 'em, return status 0
TYPE [ASCIZ/?MMANGR: Internal error
/]
MOVEI T1,1 ;Return status 1
JRST FINFRG
;Couldn't create another private section
FINFR9: MOVEI T1,1 ;Return status 1
JRST FINFRG
;Here to return to user, restoring acs 3 and 4
;Come here with status in T1
FINFRG: DMOVE T3,MMAC34 ;Restore acs
POPJ P, ;Return
;Big subroutine to try to find N pages.
;Call: SECRST/ section to restrict ourselves to
; T1/ Number of pages desired
; T2/ Flags (MM%NCL)
;Returns:
; T1/ status 0=ok, 1=can't get
; T2/ address of first location gotten (if status 0)
; or address of last section-page (if status 1)
;only t1, t2 smashed
FINSOM: PUSH P,T4 ;SAVE SOME ACS
PUSH P,T3
PUSH P,T2 ;Top of stack -1 is flags
PUSH P,T1 ;Top of stack is # of pages
MOVE T1,PTRLSS ;GET PTR TO FIRST SECTION-BLOCK PAGE
MOVE T2,T1 ;GET PTR TO FIRST SECTION DEFINED IN THAT PAGE
SKIPG T3,SECRST ;Restricted to a particular section?
JRST FINSM1 ;No
TYPE [ASCIZ/%MMANGR: FINFRE will not restrict memory
to a particular section except section 0
/]
;Here with T2 pointing to start of a page of section blocks.
FINSM1: ADDI T2,.MSSSB
FINSM2: MOVEM T2,CURSCB ;SAVE CURRENT SECTION BLOCK ADDRESS
MOVE T1,(P) ;# pages desired..
PUSHJ P,CHKFPS ;Check for enough free pages in current section
JRST FINSM3 ;Not enough in this section, try next one
;Met our goal in this section, t1= starting address
MOVE T3,-1(P) ;Check to see if we should clear memory
TXNE T3,MM%NCL
JRST FNSM2A ;Don't bother
MOVE T3,T1 ;Start of block
SETZM (T3) ;Clear 1st word
MOVE T4,T1 ;Start of block
ADDI T4,1 ;+1
MOVE T2,(P) ;Get # pages
LSH T2,^D9 ;# WORDS
SUBI T2,1 ;# TO BLT
EXTEND T2,[XBLT] ;Clear memory
FNSM2A:
IFN TOPS20, ADJSP P,-1 ;Throw away old T1
IFE TOPS20, POP P,(P)
POP P,T2 ;RESTORE OTHER ACS
POP P,T3
POP P,T4
MOVE T2,T1 ;Return start of block in T2
JRST RETST0 ;RETURN STATUS 0
; Continued on following page..
;"FINSOM" routine, continued.
;Come here if not enough free pages found in current section,
; look at next section
FINSM3: MOVE T1,CURSCB ;GET PTR TO CURRENT SECTION
SKIPN T2,.MSNXT(T1) ;Skip if there is another one
JRST FINSM4 ;NO, check for sections on another page
MOVEM T2,CURSCB ;Make this the current section block
JRST FINSM2 ;Loop back to see if enough free pages here
;Look for another page of section blocks
FINSM4: TRZ T1,777 ;POINT TO START OF PAGE
SKIPE T2,.MSPNX(T1) ;Skip if there's not another section-block page
JRST FINSM1 ;Go look at the section blocks on this page
;Have to return "No success"
IFN TOPS20,<
ADJSP P,-2 ;Throw away old T1, T2
>
IFE TOPS20,<
POP P,(P)
POP P,(P)
>
POP P,T3 ;Restore user's T3
POP P,T4 ;Restore user's T4
;Set T2= Address of last section block page looked at
MOVE T2,T1
JRST RETST1 ;And return status 1
>;END IFN TOPS20
;Find pages, restricted to section 0
;MMAC12+1/ number of pages desired
FINRS0: PUSH P,P1 ;SAVE AC
MOVE P1,[POINT 1,SC0MAP] ;POINT TO PAGE MAP
SETZ T4, ;START AT PAGE 0
FINR01: ILDB T2,P1 ;Look for a free one
JUMPE T2,.+2
AOJA T4,FINR01
CAILE T4,777 ;Did we find any?
JRST FINR0N ;No, no room
HRRZ T1,T4 ;Assume this is it
HRRZ T3,MMAC12+1 ;Countdown
MOVEM P1,SAVEPB ;Save page table byte ptr
ADDI T4,1 ;Account for pages we found
FINR02: SOJLE T3,FINR0G ;Got 'em.. mark as taken
ILDB T2,P1 ;Look some more
ADDI T4,1 ;On next page now
CAILE T4,777
JRST FINR0N ;No room
JUMPE T2,FINR02 ;Still OK.. keep going
;This clump won't do.. try again
JRST FINR01
FINR0G: MOVE P1,SAVEPB ;Get byte ptr at start of clump
SETO T2, ;Set flag to -1
DPB T2,P1 ;Mark that page
MOVE T3,MMAC12+1 ;# of pages
SOJLE T3,FINR0R ;Return when marked them all
IDPB T2,P1
JRST .-2
FINR0N: POP P,P1 ;RESTORE AC
DMOVE T3,MMAC34 ;Restore AC's
JRST RETST1 ;Return status 1 (system error)
FINR0R: MOVE T2,T1 ;Return t2= address
LSH T2,^D9
IFE TOPS20,<
PUSHJ P,CRPGS ;Go create the pages
JRST FINR0N ;?Problem, return status 1
>;END IFE TOPS20
MOVE P1,MMAC12 ;Get user's ac 1
TXNE P1,MM%NCL ;Don't bother to clear memory?
JRST FINRRN ;Just return
;Clear memory we gave him
;t2= Starting address of the block
;MMAC12+1 = number of pages to clear
SETZM (T2) ;Clear first address
IFN TOPS20,<
XMOVEI T3,. ;What section are we in?
TLNN T3,-1 ;Non-zero section?
JRST FINRR2 ;No
;Clear memory with XBLT
PUSH P,P2 ;Save acs for XBLT
PUSH P,P3
MOVE P1,MMAC12+1 ;# pages
LSH P1,^D9 ;# words to copy
SUBI P1,1 ;. .
MOVE P2,T2 ;Location of source block
MOVEI P3,1(T2) ;Location of destination block
EXTEND P1,[XBLT] ;** Clear memory **
POP P,P3
POP P,P2
JRST FINRRN ;Done clearing memory
>;END IFN TOPS20
;Here if we are not running in an extended section
FINRR2: HRL T3,T2
HRRI T3,1(T2) ;Starting BLT word
MOVE T4,MMAC12+1 ;# PAGES
LSH T4,^D9 ;# WORDS GOTTEN
ADDI T4,-1(T2) ;Ending address
BLT T3,(T4) ;** Clear the memory **
FINRRN: POP P,P1 ;Restore AC
DMOVE T3,MMAC34 ;restore AC's
JRST RETST0 ;And set status = 0
IFE TOPS20,<
;CRPGS - Routine to create the pages we will give user.
;Skip return if OK, else POPJ after typing the message
;Inputs:
; MMAC12+1/ number of pages
; T1 = starting page number
;Uses T1-T3
;The pages must not exist.
CRPGS: MOVEM T1,PGUADR+1 ;Save first page number
MOVEI T1,1 ;Create one page at a time
MOVEM T1,PGUADR ; Save argument count
MOVE T3,MMAC12+1 ;Get # of pages
CRPGS0: MOVE T1,[.PAGCD,,PGUADR] ;Ready to create page
PAGE. T1, ;Create the page..
JRST CRPGSE ;Error
SOJLE T3,CPOPJ1 ;Jump if all done
AOS PGUADR+1 ;Increment page number
JRST CRPGS0 ;Loop
CRPGSE: TYPE [ASCIZ/?MMANGR: Can't create a page: /]
CAIN T1,PAGCE% ;Page should not exist, but does
JRST CRPCE ;That's the error
TYPE [ASCIZ/ PAGE. error code = /]
PUSHJ P,TYPOCT ;Type octal number
TYPE CRLF
POPJ P, ;Error return
CRPCE: TYPE [ASCIZ/ Page number /]
MOVE T1,PGUADR+1 ;Get page number
PUSHJ P,TYPOCT ;Type it
TYPE [ASCIZ/ already exists
/]
POPJ P, ;Error return
;Routine to type octal number from T1
TYPOCT: IDIVI T1,8 ;Divide by base
PUSH P,T2 ;Save remainder
SKIPE T1 ;Done?
PUSHJ P,TYPOCT ;No, stack it
POP P,T1 ;Restore digit
ADDI T1,"0" ;Make ASCII
OUTCHR T1 ;Type it
POPJ P, ;Recurse
CRLF: ASCIZ /
/ ;Address of a CRLF
>;END IFE TOPS20
IFN TOPS20,<
;Routine to find a clump of free pages in the current section
; If found, it marks them "INUSE" and modifies the section block.
;
;Call:
; CURSCB/ address of current section block
; T1/ number of pages desired
;Returns:
; .+1 if can't
; .+2 if did, T1/ global address of start of block
;May use AC's T1-T4
;
;Note: This routine may be called several times during one call to "FINFRE",
; so it must be fast!
CHKFPS: PUSH P,P1 ;Save P1
PUSH P,P2 ;and P2
MOVE P2,CURSCB ;get address of current section block
MOVE P1,[POINT 1,.MSPGD(P2)] ;P1 = ptr to pages in the section
SETZ T4, ;T4= page offset being considered
CHKFP1: ILDB T2,P1 ;Look for a free one
JUMPE T2,.+2
AOJA T4,CHKFP1
CAILE T4,777 ;Did we find any?
JRST CHKFNR ;No, no room
MOVEM T4,PSBLPG ;Remember page number incase this is it
HRRZ T3,T1 ;Countdown
MOVEM P1,SAVEPB ;Save page table byte ptr
ADDI T4,1 ;Account for page we found
CHKFP2: SOJLE T3,CHKFPG ;Got 'em.. mark as taken
ILDB T2,P1 ;Look some more
ADDI T4,1 ;On next page now
CAILE T4,777
JRST CHKFNR ;No room
JUMPE T2,CHKFP2 ;Still OK.. keep going
JRST CHKFP1 ;This clump won't do.. try again
;Continued on next page..
;CHKFPS routine (continued)
;Here when we found a clump of pages that will do.
;T1/ number of pages
;PSBLPG/ starting page offset in section
;SAVEPB/ saved BP to page table where the clump starts
;P1 and P2 have been pushed on the stack
CHKFPG: AOS -2(P) ;Success, give skip return
MOVE T3,T1 ;# of pages in T3
MOVE T1,PSBLPG ;Get starting page offset
LSH T1,^D9 ;Make address offset
MOVE T2,CURSCB ;Current section block
HRL T1,.MSSCN(T2) ;Put section number in address, to get
; Global address of start of block in T1
MOVE P1,SAVEPB ;Get byte ptr at start of clump
SETO T2, ;Set flag to -1
DPB T2,P1 ;Mark that page
SOJLE T3,CHKFNR ;Return when marked them all
IDPB T2,P1
JRST .-2
CHKFNR: POP P,P2 ;Restore P1, P2
POP P,P1
POPJ P, ;RETURN
>;END IFN TOPS20
SUBTTL RETRN - Return pages to memory manager
;Call:
; 1/ flags
; 2/ Number of pages
; 3/ Address of start of block to return
;Returns:
; 1/ Status 0=ok, 1=Not returnable (message typed)
RETRN: CAILE T2,1000 ;Can't return more than 1000 pages at a time
JRST RETE01
JUMPE T2,RETST0 ;Return 0 pages--done
TRNE T3,777 ;Must be on an even page boundary
JRST RETE02 ;No, error
IFN TOPS20,<
TLNE T3,-1 ;Returning pages in non-zero sections?
JRST RETNR1 ;Yes
>
;Return pages in section 0
SKIPN HAVSC0 ;Do we have a section 0 map?
JRST RETE04 ;No
LSH T3,-^D9 ;Get T3= starting page number
DMOVEM T3,MMAC34 ;SAVE ACS 3, 4
ADD T3,T2 ;Start + # returned
CAILE T3,1000 ;Must be less than 1000
JRST RETE03 ;?no, give error
MOVE T3,MMAC34 ;Restore ac 3
MOVE T4,[POINT 1,SC0MAP] ;Point to section 0 map
SOJL T3,RETNR0 ;Jump when positioned to page #
IBP T4 ;Bump byte ptr
JRST .-2 ;Loop
RETNR0: MOVEM T4,SAVRBP ;Save byte ptr of starting page
;Make sure bits are set now
MOVE T1,T2 ;# PAGES, 1 TO 1000
ILDB T3,T4 ;Get bit
JUMPE T3,RETE05 ;? Not set, return "not returnable"
SOJG T1,.-2 ;Loop for all
;All set.. clear them now
IFE TOPS20,<
MOVEM T2,SAVRNP ;Save # pages returned
>;END IFE TOPS20
MOVE T4,SAVRBP ;Get back byte ptr
SETZ T3, ;Clear bits
IDPB T3,T4 ;Clear bit for a page
SOJG T2,.-1 ;Loop for all
IFE TOPS20,<
PUSHJ P,DLPGS ;Delete pages
JRST RET341 ;Error, restore 3,4 return status 1
>;END IFE TOPS20
JRST RET340 ;Restore 3, 4, return status 0
; RETRN routine (Cont'd)
IFE TOPS20,<
;DLPGS - TOPS10 routine to delete pages when they are returned to mem. manager.
; The pages are deleted via the PAGE. UUO. If the UUO gets an error because
;the page is already gone, there is no problem. Any other kind of UUO error
;causes a message to be typed out and the POPJ return taken.
;Inputs:
; MMAC34/ Starting page number
; SAVRNP/ Number of pages
;Uses T1-T3
DLPGS: MOVE T1,MMAC34 ;Get starting page number
MOVEM T1,PGUADR+1 ;Save for PAGE. UUO
MOVEI T1,1 ;One argument
MOVEM T1,PGUADR ;. .
MOVX T1,PA.GAF ;Get flag that says destroy page
IORM T1,PGUADR+1 ;Put in arg block
MOVE T3,SAVRNP ;Get number of pages
DLPGS0: MOVE T1,[.PAGCD,,PGUADR] ;Prepare for PAGE. UUO
PAGE. T1, ;Destroy one page
JRST DLPGSE ;Error, go see why
DLPGS1: SOJLE T3,CPOPJ1 ;Skip return if done
HRRZ T1,PGUADR+1 ;Increment page #
ADDI T1,1
HRRM T1,PGUADR+1 ; . .
JRST DLPGS0 ;Loop
;PAGE. UUO failed
DLPGSE: CAIN T1,PAGME% ;Page should exist, but does not
JRST DLPGS1 ;Yes, it doesn't matter.
TYPE [ASCIZ/?MMANGR: RETRN routine can't destroy a page,
PAGE. UUO error code = /]
PUSHJ P,TYPOCT ;Type octal error code
TYPE CRLF
POPJ P, ;Give error return
>;END IFE TOPS20
; RETRN routine (Cont'd)
IFN TOPS20,<
;Here to return pages in a non-zero section
RETNR1: DMOVEM T3,MMAC34 ;Save acs 3,4
HLRZ T4,T3 ;Get t4= section number
TLZ T3,-1 ;Clear section number
LSH T3,-^D9 ;Get t3= starting page number offset in section
ADD T3,T2 ;Start + # returned
CAILE T3,1000 ;Must be less than 1000
JRST RETE03 ;?No, give error
SUB T3,T2 ;Restore page offset
;Search thru the list of section blocks for that section
;Section # to look for is in T4
MOVE T1,PTRLSS ;Get pointer to section blocks
RETNR2: MOVE T2,T1 ;Get t2= starting section block
ADDI T2,.MSSSB
RETNR3: CAMN T4,.MSSCN(T2) ;Does this section block match
JRST RETNR4 ;Yes, go return pages here
SKIPE T2,.MSNXT(T2) ;No, is there a "next" block?
JRST RETNR3 ;Yes, go check it
SKIPE T1,.MSPNX(T1) ;No, is there another section-block page?
JRST RETNR2 ;Yes, go check it
JRST RETE06 ;?Can't find that section block
;Come here when the section-block pointer is in T2
RETNR4: MOVE T1,T2 ;GET T1= ptr to page data
ADDI T1,.MSPGD ;. .
MOVEM T1,RBPT+1 ;Save return byte ptr address
MOVX T1,1B12+<POINT 1,0> ;Extended byte ptr
MOVEM T1,RBPT ;First word of byte ptr
SOJL T3,RETNR5 ;Jump when positioned to page #
IBP RBPT ;. .
JRST .-2
RETNR5: DMOVE T1,RBPT ;Save this place
DMOVEM T1,SAVRBP ;. .
;Make sure bits are on
MOVE T1,MMAC12+1 ;Number of pages, 1 to 1000
ILDB T3,RBPT ;Get bit
JUMPE T3,RETE05 ;?Not set, return "not returnable"
SOJG T1,.-2 ;Look for all
;All set.. clear them now
MOVE T2,MMAC12+1 ;Number of pages
SETZ T3, ;Clear bits
IDPB T3,SAVRBP ;Clear bit for a page
SOJG T2,.-1 ;Loop for all
JRST RET340 ;Restore 3,4 return status 0
DMOVE T3,MMAC34 ;Restore acs 3,4
JRST RETST0 ;Return status 0
>;END IFN TOPS20
SUBTTL RETRN errors
RETE01: TYPE RETEH ;Type header
TYPE [ASCIZ/ Attempt to return more than 1000 pages at a time
/]
JRST RETST1 ;Return status 1
RETE02: TYPE RETEH ;Type header
TYPE [ASCIZ/ Input starting address of block not on a page boundary
/]
JRST RETST1 ;Return status 1
RETE03: TYPE RETEH ;Type header
TYPE [ASCIZ/ Input starting address of block + # pages returned
goes over a section boundary
/]
JRST RET341 ;Return status 1, restore acs
IFN TOPS20,<
RETE04: TYPE RETEH ;Type header
TYPE [ASCIZ/ Attempt to return pages to section 0, but no
section 0 page map was supplied when "INITM" was called
/]
JRST RETST1
>
IFE TOPS20,<
RETE04: TYPE RETEH ;Type header
TYPE [ASCIZ/ Attempt to return pages before page map was supplied
/]
JRST RETST1
>;END IFE TOPS20
RETE05: TYPE RETEH ;Type header
TYPE [ASCIZ/ Attempt to return pages that were not reserved
/]
JRST RET341 ;Return status 1, restore acs
IFN TOPS20,<
RETE06: TYPE RETEH ;Type header
TYPE [ASCIZ/ Attempt to return pages to a section with no reserved pages
/]
JRST RET341 ;Return status 1, restore acs
>;END IFN TOPS20
RETEH: $TEXT <?MMANGR: RETRN routine can't return memory, reason:
>
SUBTTL Return status routines
RET341: DMOVE T3,MMAC34 ;Restore acs 3 and 4
JRST RETST1 ;Return status 1
RET340: DMOVE T3,MMAC34 ;Restore acs 3 and 4
RETST0: TDZA T1,T1 ;SET STATUS TO 0 and skip
RETST1: MOVEI T1,1 ;SET STATUS TO 1
POPJ P, ;RETURN
CPOPJ1: AOS (P) ;Skip returns
CPOPJ: POPJ P, ;Single returns
SUBTTL DATA SECTION
;Data used by the memory manager
IFE TOPS20,<
RELOC 0 ;Relocate to low-segment
>;END IFE TOPS20
MMDST==. ;START OF DATA
MMAC12: BLOCK 2 ;USER'S ACS 1 AND 2
MMAC34: BLOCK 2 ;USER'S ACS 3 AND 4
MMAC56: BLOCK 2
MMAC78: BLOCK 2
MMEXSC: BLOCK 1 ;ALLOWED TO USE EXTENDED SECTIONS
NMMODS: BLOCK 1 ;NUMBER OF MODULES CONNECTED
NMSECS: BLOCK 1 ;NUMBER OF EXTENDED SECTIONS IN USE
HAVSC0: BLOCK 1 ;FLAG FOR "HAVE SECTION 0"
SC0MAP: BLOCK <^D512/^D36>+1 ;A PAGE MAP FOR SECTION 0
SCMPSZ==.-SC0MAP ;NUMBER OF WORDS NEEDED
SAVEPB: BLOCK 1 ;SAVED BP TO SC0MAP
PTRLSU: BLOCK 1 ;POINTER TO LIST OF USERS
SECRST: BLOCK 1 ;SECTION WE ARE RESTRICTED TO USING (FINFRE)
CURSCB: BLOCK 1 ;CURRENT SECTION BLOCK POINTER
PSBLPG: BLOCK 1 ;Saved page number in "CHKFPS" routine
SAVRBP: BLOCK 2 ;Saved BP used by RETRN
RBPT: BLOCK 2 ;Byte ptr to extended section
;TOPS20- only locations
IFN TOPS20,<
MYPGS: BLOCK ^D512*3 ;Two pages for my lists
PTRLSS: BLOCK 1 ;Pointer to list of section maps
>;END IFN TOPS20
;TOPS10- only locations
IFE TOPS20,<
MYPGS: BLOCK ^D512*2 ;One page for my lists
PGUADR: BLOCK 2 ;PAGE. UUO argument block
SAVRNP: BLOCK 1 ;(RETRN) Number of pages to return
>;END IFE TOPS20
MMDEN==.-1 ;END OF DATA
END