$title ('MP/M 1.1 Memory Management') name memmgr cseg ;memory$manager: ;do; ;$include (copyrt.lit) ;/* ; Copyright (C) 1979, 1980 ; Digital Research ; P.O. Box 579 ; Pacific Grove, CA 93950 ; ; Revised: ; 18 Jan 80 by Thomas Rolander ;*/ ;$include (common.lit) ;$nolist ;$include (memmgr.lit) ;$nolist ;$include (proces.lit) ;$nolist ;$include (datapg.ext) ;$nolist ;$include (proces.ext) ;$nolist ; declare rlr address external; extrn rlr ; declare nmbsegs byte external; extrn nmbsegs ; declare msegtbl (1) structure (memory$descriptor); extrn msegtbl ; declare maxseg literally 'nmbsegs - 1'; ; exitr: extrn exitr ; procedure external; ; end exitr; ; memory descriptor offsets size equ 1 attrib equ 2 ; declare user$process literally 'userpr'; ; user$process: userpr: public userpr ; procedure (pdadr) byte public; ; declare pdadr address; ; declare pd based pdadr process$descriptor; ; return not (pd.memseg = 0ffh); LXI H,0FH DAD B MOV A,M INR A RZ MVI A,0FFH RET ; end user$process; ; declare i byte; ; abs$rq: absrq: public absrq ; procedure (mdadr) byte public reentrant; ; declare mdadr address; ; declare md based mdadr memory$descriptor; ; enter$region; DI ; do i = 0 to maxseg; LDA NMBSEGS MOV E,A LXI H,MSEGTBL-2 @8: INX H INX H INX H INX H ; if (memsegtbl(i).attrib and allocated) = 0 then MVI A,80H ANA M JNZ @1 ; do; ; if memsegtbl(i).base = md.base then DCX H DCX H LDAX B CMP M INX H INX H JNZ @2 ; do; ; memsegtbl(i).attrib = memsegtbl(i).attrib ; or allocated; MVI A,80H ORA M MOV M,A ; md.size = memsegtbl(i).size; INX B DCX H MOV A,M STAX B ; md.attrib = memsegtbl(i).attrib; INX B INX H MOV A,M STAX B ; md.bank = memsegtbl(i).bank; inx b inx h mov a,m stax b ; rlrpd.memseg = i; LXI B,0FH LHLD RLR DAD B LDA NMBSEGS SUB E MOV M,A ; exit$region; CALL EXITR ; return 0; XRA A RET ; end; @2: ; end; @1: ; end; DCR E JNZ @8 ; exit$region; CALL EXITR ; return 0FFH; MVI A,0FFH RET ; end abs$rq; dseg ; declare j byte; ; declare fit$size byte; ; declare fit$index byte; fitindex: ds 1 cseg ; /* ; rel$rq: ; The purpose of the relocatable memory request procedure ; is to find the unallocated memory segment which best fits ; the size request. ; */ ; rel$rq: relrq: public relrq ; procedure (mdadr) byte public reentrant; ; declare mdadr address; ; declare md based mdadr memory$descriptor; ; enter$region; DI ; fit$size = 0ffh; MVI D,0FFH ; D = fitsize ; do j = 0 to maxseg; LDA NMBSEGS MOV E,A LXI H,MSEGTBL-2 INX B ; BC = .MD.SIZE @10: INX H INX H INX H INX H ; if (memsegtbl(j).attrib and allocated) = 0 then MVI A,80H ANA M JNZ @3 ; do; ; if memsegtbl(j).size >= md.size then DCX H LDAX B DCR A CMP M JNC @4 ; do; ; if memsegtbl(j).size <= fit$size then MOV A,D CMP M JC @5 ; do; ; fit$index = j; LDA NMBSEGS SUB E STA FITINDEX ; fit$size = memsegtbl(j).size; MOV A,M MOV D,A ; end; @5: ; end; @4: ; end; INX H @3: ; end; DCR E JNZ @10 @11: ; if fit$size <> 0ffh then INR D JZ @6 DCR D LHLD FITINDEX MVI H,0 DAD H DAD H LXI D,msegtbl ; MEMSEGTBL DAD D ; do; ; md.base = memsegtbl(fit$index).base; DCX B MOV A,M STAX B ; md.size = memsegtbl(fit$index).size; INX H INX B MOV A,M STAX B ; memsegtbl(fit$index).attrib = ; memsegtbl(fit$index).attrib or allocated; INX H MVI A,80H ORA M MOV M,A ; md.attrib = memsegtbl(fit$index).attrib; INX B STAX B ; md.bank = memsegtbl(fit$index).bank; inx h inx b mov a,m stax b ; rlrpd.memseg = fit$index; LXI B,0FH LHLD RLR DAD B LDA FITINDEX MOV M,A ; exit$region; CALL EXITR ; return 0; XRA A RET ; end; @6: ; exit$region; CALL EXITR ; return 0FFH; MVI A,0FFH RET ; end rel$rq; ; mem$fr: memfr: public memfr ; procedure (mdadr) public reentrant; ; declare mdadr address; ; declare md based mdadr memory$descriptor; ; declare i byte; ; do i = 0 to maxseg; LDA NMBSEGS MOV E,A LXI H,MSEGTBL-4 @12: INX H INX H INX H INX H ; if memsegtbl(i).base = md.base then LDAX B CMP M JNZ @7 ; do; ; if memsegtbl(i).bank = md.bank then PUSH H PUSH B INX H INX H INX H INX B INX B INX B LDAX B CMP M POP B POP H JNZ @7 ; do; ; memsegtbl(i).attrib = memsegtbl(i).attrib ; and (not allocated); INX H INX H MVI A,7FH ANA M MOV M,A ; return; RET ; end; ; end; @7: ; end; DCR E JNZ @12 ; end mem$fr; RET ;end memory$manager; END