Trailing-Edge
-
PDP-10 Archives
-
bb-r775c-bm_tops20_ks_upd_3
-
sources/memman.mac
There are 10 other files named memman.mac in the archive. Click here to see a list.
TITLE MEMMAN - MEMORY MANAGEMENT ROUTINES
; IDENT 1-004
;****************************************************************************
;* *
;* COPYRIGHT (C) 1978, 1985 *
;* BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. *
;* ALL RIGHTS RESERVED. *
;* *
;* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *
;* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *
;* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *
;* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *
;* OTHER PERSON. 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. *
;* *
;****************************************************************************
;
;FACILITY: EDT VERSION 3
;
;AUTHOR : GRAHAM BEECH CREATION DATE : 11-APR-1983
;FUNCTIONAL DESCRIPTION:
;
; THIS MODULE CONTAINS ROUTINES TO HANDLE THE ALLOCATION
; AND DEALLOCATION OF DYNAMIC MEMORY FOR THE WORK FILE
; AND OTHER SCRATCH AREAS.
;
;MODIFIED BY:
;
; 1-001 Original. GB 11-Apr-1983
; 1-002 Rewritten using new allocation scheme. GB 27-Jun-1983
; 1-003 Modify to include DEAMEM - deallocate all memory, so that EDT can
; be made restartable. CJG 11-Oct-1983
; 1-004 Check that only memory in the legal range is deallocated. CJG 11-Oct-1983
; 1-005 Make BPWORD an external location so that we can change byte size more
; easily. CJG 15-Dec-1983
;--
PAGE
TWOSEG
RELOC 0
SEARCH MONSYM
SEARCH MACSYM
INTERN ALLHEA,DEAHEA,ALLPAG,DEAPAG,DEAMEM
EXTERN BPWORD
T1=1
T2=2
T3=3
T4=4
T5=5
T6=6
P=17
PAGE
SUBTTL Local storage
; Free memory is organised into a linked list of noncontiguous
; blocks with FFREE pointing to the first block.
;
; The first word of each block contains the size of the block
; in the left half and a pointer to the next block (or zero)
; in the right half.
;
; When memory is allocated it is allocated from the end of the
; first block which is large enough, and the length is reduced
; by the number of words allocated.
;
; When memory is deallocated it is linked into the list of free
; blocks at the appropriate place (the list is always ordered by
; address). If two blocks can be concatenated into one then
; this is done.
INIT: BLOCK 1 ;Initialised flag
FFREE: BLOCK 1 ;Pointer to first free block
FREPGS: BLOCK 1 ;Number of free pages "allocated"
FFLOW: BLOCK 1 ;First free location
FFHIGH: EXP 400000 ;Last free location + 1
PAGE
SUBTTL ALLHEA - Allocate heap
RELOC 400000
;
; ALLOCATE THE REQUESTED NO. OF BYTES OF SCRATCH MEMORY
;
; ARGUMENTS ON STACK :-
; #BYTES OF MEMORY REQUIRED
; ADDRESS OF WORD WHICH GETS ADDRESS OF FIRST ALLOCATED WORD
;
ALLHEA::
SKIPN INIT ;Memory initalised?
CALL INIMEM ;No. Do it now
MOVE T1,@-2(P) ;Get # bytes required
ADD T1,BPWORD ;Make it words
SUBI T1,1 ;...
IDIV T1,BPWORD ;...
MOVEI T2,FFREE ;Get first free ptr
ALLHE1: MOVEI T4,(T2) ;Save previous address
HRRZ T2,(T2) ;Get address of next free
JUMPE T2,ALLHE8 ;Is there one?
HLRZ T3,(T2) ;Get length of this block
CAIGE T3,(T1) ;Big enough?
JRST ALLHE1 ;No - try for another
SUBI T3,(T1) ;Reduce its size
JUMPN T3,ALLHE4 ;Any left?
HRRZI T3,(T2) ;No - unlink it from the chain
HRRM T3,(T4) ;....
ALLHE4: HRLM T3,(T2) ;Store new size
ADDI T2,(T3) ;Get address of allocated memory
MOVEM T2,@-1(P) ;...and return it
MOVEI T1,1 ;Success.
RET
ALLHE8: SETZ T1, ;Return failure
RET
PAGE
SUBTTL DEAHEA - Deallocate heap
; DEALLOCATE HEAP STORAGE
;
; ARGUMENTS ON STACK:-
; # BYTES BEING RELEASED
; ADDRESS OF FIRST WORD TO BE RELEASED
;
DEAHEA::
MOVE T2,@-2(P) ;Get # bytes
ADD T2,BPWORD ;Convert to words
SUBI T2,1 ;...
IDIV T2,BPWORD ;...
DEAHE0: MOVE T1,@-1(P) ;Get address
CAML T1,FFLOW ;If too low ..
CAML T1,FFHIGH ;Or too high ..
RET ;Then ignore it
MOVEI T3,FFREE ;Get first free
DEAHE1: MOVEI T4,(T3) ;Remember previous
HRRZ T3,(T3) ;..and get next
JUMPE T3,DEAHE2 ;Is there one?
CAIG T3,(T1) ;Find address > block
JRST DEAHE1 ;...we are releasing
DEAHE2: HLRZ T5,(T4) ;Get length of previous
ADDI T5,(T4) ;See if we can concatenate
CAIN T5,(T1) ;...with previous block
JRST DEAHE3 ;Yes. Just need to change length
HRRM T1,(T4) ;No. Link the block
HRRM T3,(T1) ;..into the chain.
HRLM T2,(T1) ;...
RET
DEAHE3: HLRZ T5,(T4) ;Get the length
ADDI T5,(T2) ;Add length of block being released
MOVEI T1,(T5) ;Copy new length
ADDI T1,(T4) ;Add address of this block
CAIE T1,(T3) ;Combine with next?
JRST DEAHE4 ;No.
HLRZ T1,(T3) ;Yes. get length of next
ADDI T5,(T1) ;Total length
HRRZ T1,(T3) ;Forward pointer
HRRM T1,(T4) ;Update link
DEAHE4: HRLM T5,(T4) ;Update length
RET
PAGE
SUBTTL ALLPAG - Allocate pages
; ALLOCATE PAGES OF FREE MEMORY
;
; ARGUMENTS ON STACK :-
; #PAGES REQUIRED
; ADDRESS OF WORD WHICH GETS ADDRESS OF FIRST ALLOCATED PAGE
;
ALLPAG::
SKIPN INIT ;Memory initalised?
CALL INIMEM ;No. Do it now
MOVE T1,@-2(P) ;Get # pages required
IMULI T1,^D512 ;Make it words
MOVE T2,FFREE ;Get first free ptr
TLNE T2,777 ;Check its a page boundary
JRST ALLPA9 ;This should never happen!!
HLRZ T3,(T2) ;Get the length of the block
CAIGE T3,(T1) ;Check big enough..
JRST ALLPA9 ;No. Don't look any futher
MOVEM T2,@-1(P) ;Return address of allocated page(s)
HRRZ T4,(T2) ;Get forward pointer
SUBI T3,(T1) ;Reduce length by amount we want
JUMPN T3,ALLPA2 ;Any left?
HRRM T4,FFREE ;No. Next block is now first free
MOVEI T1,1 ;Success.
RET
ALLPA2: ADDI T2,(T1) ;Point to new first free
HRLM T3,(T2) ;Store updated length
HRRM T4,(T2) ;Store forward pointer
HRRM T2,FFREE ;Update first free pointer
MOVEI 1,1 ;Success.
RET
ALLPA9: SETZ T1, ;Return failure
RET
PAGE
SUBTTL DEAPAG - Deallocate a page
; DEALLOCATE PAGES OF HEAP STORAGE
;
; ARGUMENTS ON STACK:-
; # PAGES BEING RELEASED
; ADDRESS OF FIRST WORD TO BE RELEASED
;
DEAPAG::
MOVE T2,@-2(P) ;Get size
IMULI T2,^D512 ;Convert to words
JRST DEAHE0 ;Use common code
PAGE
SUBTTL DEAMEM - Deallocate all memory
;DEALLOCATE ALL ALLOCATED MEMEORY
;
;NO ARGUMENTS ARE REQUIRED AND NO VALUE IS RETURNED
DEAMEM:
MOVN T4,FREPGS ;Make an AOBJN pointer to first page
MOVSS T4
HRRI T4,^D256 ;Last+1 = page 400
SUB T4,FREPGS ;-count,,first
DEMEM1:
MOVSI T1,.FHSLF
HRRI T1,(T4) ;Get a page to test
RPACS ;See what access we have
ERJMP .+1
TXNN T2,PA%PEX ;Does it exist?
JRST DEMEM2 ;No - ignore it
MOVE T2,T1 ;Copy page number
SETO T1,
SETZ T3, ;Just one page
PMAP ;Lose it
ERJMP .+1
DEMEM2:
AOBJN T4,DEMEM1 ;Loop over all pages
SETZM INIT
SETZM FREPGS ;Clean up
RET ;Done
PAGE
SUBTTL INIMEM - Initialise memory
INIMEM:
HRRZI T3,^D256 ;Setup a count
INIM01: MOVSI T1,.FHSLF ;Get page access bits
HRRI T1,-1(T3) ;...
RPACS ;...
ERJMP .+1 ;...
JUMPN T2,INIM02 ;Jump if existing page
SOJGE T3,INIM01 ;Loop for loseg addresses
INIM02: MOVEI T1,^D256 ;Compute no. of free pages
SUBI T1,(T3) ;...
MOVEM T1,FREPGS ;Save number of pages "allocated"
IMULI T1,^D512 ;Convert to words.
IMULI T3,^D512 ;Get address of first free page
HRLZM T1,(T3) ;Store length of free block
MOVEM T3,FFREE ;Point to first free block
MOVEM T3,FFLOW ;Save absolute low limit
SETOM INIT ;Flag memory initialised
RET
END