mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 01:14:21 +00:00
327 lines
5.4 KiB
NASM
327 lines
5.4 KiB
NASM
$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
|
||
|