mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 17:34:06 +00:00
534 lines
8.6 KiB
NASM
534 lines
8.6 KiB
NASM
title 'MP/M II V2.0 Main Program'
|
||
name 'mpm'
|
||
|
||
dseg
|
||
@@mpm:
|
||
public @@mpm
|
||
cseg
|
||
;mpm:
|
||
@mpm:
|
||
public @mpm
|
||
;do;
|
||
|
||
;$include (copyrt.lit)
|
||
|
||
;/*
|
||
; Copyright (C) 1979,1980,1981
|
||
; Digital Research
|
||
; P.O. Box 579
|
||
; Pacific Grove, CA 93950
|
||
;
|
||
; Revised:
|
||
; 14 Sept 81 by Thomas Rolander
|
||
;*/
|
||
|
||
;$include (common.lit)
|
||
;$nolist
|
||
;$include (proces.lit)
|
||
;$nolist
|
||
;$include (queue.lit)
|
||
;$nolist
|
||
;$include (xdos.lit)
|
||
;$nolist
|
||
;$include (xdos.ext)
|
||
;$nolist
|
||
;$include (bdosi.ext)
|
||
;$nolist
|
||
;$include (datapg.ext)
|
||
;$nolist
|
||
|
||
; xdos:
|
||
extrn xdos
|
||
; procedure (func,info) address external;
|
||
; declare func byte;
|
||
; declare info address;
|
||
; end xdos;
|
||
|
||
; syinit:
|
||
extrn syinit
|
||
; procedure external;
|
||
; end syinit;
|
||
|
||
; xidle:
|
||
extrn xidle
|
||
; procedure external;
|
||
; end xidle;
|
||
|
||
; xbdos:
|
||
extrn xbdos
|
||
; procedure (func,info) address external;
|
||
; declare func byte;
|
||
; declare info address;
|
||
; end xbdos;
|
||
|
||
; maxcns:
|
||
extrn maxcns
|
||
; procedure byte external;
|
||
; end maxcons;
|
||
|
||
; declare datapg (1) byte external;
|
||
extrn datapg
|
||
|
||
; declare sysdat address external;
|
||
extrn sysdat
|
||
|
||
; declare rlr address external;
|
||
extrn rlr
|
||
|
||
; declare qlr address external;
|
||
extrn qlr
|
||
|
||
; declare nmb$segs byte external;
|
||
extrn nmbsegs
|
||
|
||
; declare nmb$cns byte external;
|
||
extrn nmbcns
|
||
|
||
; declare nmb$lst byte external;
|
||
extrn nmblst
|
||
|
||
; declare m$seg$tbl (1) structure (
|
||
extrn msegtbl
|
||
; base byte,
|
||
; size byte,
|
||
; attrib byte,
|
||
; bank byte );
|
||
|
||
|
||
;/*
|
||
; Init Process Data Segment
|
||
;
|
||
; *** Note:
|
||
; Portions of the following 'data' have been moved into csegs
|
||
; for the purposes of combining all the initialization code and data
|
||
; together in one place so that it can be overlayed by the user
|
||
; process stack table.
|
||
;
|
||
;
|
||
; declare stktbl (max$usr$pr)
|
||
; structure (loc (10) address) public;
|
||
stktbl:
|
||
public stktbl
|
||
;
|
||
;
|
||
;*/
|
||
; declare init$pd process$descriptor
|
||
; initial (idlepd,rtr$status,254,0,'Init ',0,0ffh,0,0,0080h,0);
|
||
public initpd
|
||
initpd:
|
||
dw idlepd ; pl
|
||
db 0 ; status
|
||
db 254 ; priority
|
||
dw 0 ; stkptr
|
||
db 'Init ' ; name
|
||
db $-$ ; console
|
||
db 0ffh ; memseg (system)
|
||
dw $-$ ; b
|
||
dw $-$ ; thread
|
||
dw 0080h ; disk set DMA
|
||
db $-$ ; disk select / user code
|
||
dw $-$ ; dcnt
|
||
db $-$ ; searchl
|
||
dw $-$ ; searcha
|
||
ds 2 ; drvact
|
||
ds 20 ; registers
|
||
ds 2 ; scratch
|
||
|
||
; declare init$stk (24) address
|
||
; initial (restarts,0C7C7H);
|
||
; /* this stack area is in the system data page */
|
||
|
||
dseg
|
||
;/*
|
||
; Idle Process Data Segment
|
||
;*/
|
||
; declare idle$pd process$descriptor
|
||
; initial (0,rtr$status,255,.idlentrypt,'Idle ',0,0ffh,0,0,0080h,0);
|
||
public idlepd
|
||
idlepd:
|
||
dw $-$ ; pl
|
||
db 0 ; status
|
||
db 255 ; priority
|
||
dw idlentrypt ; stkptr
|
||
db 'Idle ' ; name
|
||
db $-$ ; console
|
||
db 0ffh ; memseg (system)
|
||
dw $-$ ; b
|
||
dw $-$ ; thread
|
||
dw 0080h ; disk set DMA
|
||
db $-$ ; disk select / user code
|
||
dw $-$ ; dcnt
|
||
db $-$ ; searchl
|
||
dw $-$ ; searcha
|
||
ds 2 ; drvact
|
||
ds 20 ; registers
|
||
ds 2 ; scratch
|
||
|
||
; declare idle$stk (10) address
|
||
; initial (restarts,0C7C7H);
|
||
public idlestk
|
||
idlestk:
|
||
dw 0c7c7h,0c7c7h,0c7c7h
|
||
dw 0c7c7h,0c7c7h,0c7c7h
|
||
dw 0c7c7h,0c7c7h,0c7c7h
|
||
idlentrypt:
|
||
dw idle
|
||
|
||
cseg
|
||
|
||
; declare tmp$pd$adr address;
|
||
tmppdadr:
|
||
ds 2
|
||
; declare tmp$pd based tmp$pd$adr process$descriptor;
|
||
; declare tmp$stk$adr address;
|
||
tmpstkadr:
|
||
ds 2
|
||
; declare tmp$stk based tmp$stk$adr (114) address;
|
||
; declare sys$dat based tmp$pd$adr (1) byte;
|
||
|
||
; declare console$dat$adr address;
|
||
consoledatadr:
|
||
ds 2
|
||
|
||
dseg
|
||
|
||
; declare disk$mx userqcb public
|
||
; initial (0,0,'MXDisk ');
|
||
diskmx:
|
||
public diskmx
|
||
dw $-$ ; pointer
|
||
dw $-$ ; msgadr
|
||
db 'MXDisk ' ; name
|
||
|
||
; declare list$mx userqcb public
|
||
; initial (0,0,'MXList ');
|
||
listmx:
|
||
public listmx
|
||
dw $-$ ; pointer
|
||
dw $-$ ; msgadr
|
||
db 'MXList ' ; name
|
||
|
||
cseg
|
||
|
||
; memory descriptor offsets:
|
||
size equ 0001h
|
||
attrib equ 0002h
|
||
bank equ 0003h
|
||
|
||
|
||
;/*
|
||
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
||
; Idle Program
|
||
|
||
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
;*/
|
||
|
||
; declare ret byte;
|
||
; declare (i,j) byte;
|
||
i: ds 1
|
||
j: ds 1
|
||
|
||
; declare tick$pd process$descriptor external;
|
||
extrn tickpd
|
||
|
||
; declare rspladr address;
|
||
rspladr:
|
||
ds 2
|
||
; declare rspl based rspladr address;
|
||
; declare temp address;
|
||
temp: ds 2
|
||
|
||
; declare mem$segs$adr address;
|
||
memsegsadr:
|
||
ds 2
|
||
; declare mem$segs based mem$segs$adr (1) byte;
|
||
; declare mem$banks$adr address;
|
||
membanksadr:
|
||
ds 2
|
||
; declare mem$banks based mem$banks$adr (1) byte;
|
||
|
||
; declare template (16) byte initial (
|
||
; 0,0,0,198,0,0,'Tmpx ',' '+80h,0,0ffh);
|
||
template:
|
||
dw $-$ ; pl
|
||
db 0 ; status
|
||
db 198 ; priority
|
||
dw $-$ ; stkptr
|
||
db 'Tmpx ',' '+80h ; name
|
||
db $-$ ; console
|
||
db 0 ; banked OS
|
||
|
||
; mpm:
|
||
mpm:
|
||
public mpm
|
||
; procedure public;
|
||
|
||
; stackptr = .init$stk+48;
|
||
; rlr = .init$pd;
|
||
lhld sysdat
|
||
mvi l,245
|
||
lxi d,xbdos
|
||
mov m,e
|
||
inx h
|
||
mov m,d
|
||
|
||
mvi l,0f0h
|
||
sphl ; stackptr = sysdat + f0h
|
||
; call syinit;
|
||
|
||
CALL SYINIT
|
||
; ret = xdos (open$queue,.disk$mx);
|
||
LXI D,DISKMX
|
||
MVI C,87H
|
||
CALL XDOS
|
||
; ret = xdos (open$queue,.list$mx);
|
||
LXI D,LISTMX
|
||
MVI C,87H
|
||
CALL XDOS
|
||
|
||
; ret = xdos (create,.tick$pd);
|
||
LXI D,TICKPD
|
||
MVI C,90H
|
||
CALL XDOS
|
||
; ret = xdos (create,.clock$pd);
|
||
; ret = xdos (create,.cli$pd);
|
||
; ret = xdos (create,.attch$pd);
|
||
|
||
; rspladr = (tmp$pd$adr:=xdos (system$data$adr,0)) + 252;
|
||
|
||
; /* system$data(252-253) = address of data page */
|
||
lhld sysdat
|
||
mov a,h
|
||
mvi l,243
|
||
mov h,m
|
||
mvi l,0
|
||
SHLD TMPPDADR
|
||
mov h,a
|
||
mvi l,244
|
||
mov h,m
|
||
mvi l,0
|
||
shld consoledatadr
|
||
mov h,a
|
||
|
||
; rspl = .datapg;
|
||
|
||
; /* system$data(15) = max memory segment followed by table */
|
||
mvi l,0fch
|
||
LXI B,DATAPG
|
||
MOV M,C
|
||
INX H
|
||
MOV M,B
|
||
; mem$segs$adr = tmp$pd$adr + 15;
|
||
|
||
; /* system$data(32) = memory bank table */
|
||
mvi l,0fh
|
||
SHLD MEMSEGSADR
|
||
; mem$banks$adr = tmp$pd$adr + 32;
|
||
|
||
; /* system$data(254-255) = resident system process list head */
|
||
mvi l,20h
|
||
SHLD MEMBANKSADR
|
||
; rspladr = rspladr + 2;
|
||
mvi l,0feh
|
||
SHLD RSPLADR
|
||
|
||
; /* setup the memory segment table */
|
||
; nmb$segs = mem$segs(0);
|
||
LHLD MEMSEGSADR
|
||
MOV A,M
|
||
STA NMBSEGS
|
||
INX H
|
||
XCHG ; DE = .MEM$SEGS(1)
|
||
LXI H,MSEGTBL ; HL = .MEM$SEG$TBL(0).BASE
|
||
; do i = 1 to nmb$segs;
|
||
RLC
|
||
RLC
|
||
MOV C,A
|
||
@4:
|
||
; mem$seg$tbl(i-1).base = mem$segs(i);
|
||
; mem$seg$tbl(i-1).size = mem$size(i-1);
|
||
; mem$seg$tbl(i-1).attrib = mem$attribs(i-1);;
|
||
; mem$seg$tbl(i-1).bank = mem$banks(i-1);
|
||
LDAX D
|
||
MOV M,A
|
||
INX H
|
||
INX D
|
||
; end;
|
||
DCR C
|
||
JNZ @4
|
||
|
||
; call bdos (disk$reset);
|
||
mvi c,0dh
|
||
call xbdos
|
||
|
||
lhld rspladr
|
||
; temp = rspl;
|
||
|
||
; /* create the processes on the resident system process
|
||
; list and set the first two bytes of the PRL to xbdos adr */
|
||
MOV E,M
|
||
INX H
|
||
MOV D,M
|
||
XCHG
|
||
SHLD TEMP
|
||
; do while temp <> 0;
|
||
@2:
|
||
LHLD TEMP
|
||
MOV A,H
|
||
ORA L
|
||
JZ @3
|
||
; rspladr = temp;
|
||
SHLD RSPLADR
|
||
; temp = rspl;
|
||
MOV E,M
|
||
INX H
|
||
MOV D,M
|
||
XCHG
|
||
SHLD TEMP
|
||
; rspl = .xbdos;
|
||
LXI B,XBDOS
|
||
XCHG
|
||
MOV M,B
|
||
DCX H
|
||
MOV M,C
|
||
; ret = xdos (create,rspladr + 2);
|
||
INX H
|
||
INX H
|
||
XCHG
|
||
MVI C,90H
|
||
CALL XDOS
|
||
; end;
|
||
JMP @2
|
||
@3:
|
||
; nmb$lst = sysdat(197);
|
||
LHLD sysdat
|
||
mvi l,197
|
||
mov a,m
|
||
sta nmb$lst
|
||
|
||
; /* see if consoles configured > max physical consoles */
|
||
; if (nmb$cns:=sys$dat(1)) > maxcns then
|
||
CALL MAXCNS
|
||
LHLD sysdat
|
||
inx h
|
||
CMP M
|
||
JC @1
|
||
MOV A,M
|
||
; do;
|
||
; nmb$cns = maxcns;
|
||
@1:
|
||
STA NMBCNS
|
||
; end;
|
||
|
||
; /* create TMP process descriptors, one per console */
|
||
; i = nmb$cns;
|
||
STA I
|
||
; do while i <> 0;
|
||
@6:
|
||
LDA I
|
||
ORA A
|
||
JZ @7
|
||
; tmp$stk$adr = .tmp$pd.scratch(0);
|
||
lhld consoledatadr
|
||
mvi l,34h
|
||
shld tmpstkadr
|
||
; call move (16,.template,.tmp$pd);
|
||
lhld tmppdadr
|
||
xchg
|
||
LXI B,TEMPLATE
|
||
MVI L,10H
|
||
LDAX B
|
||
STAX D
|
||
INX B
|
||
INX D
|
||
DCR L
|
||
JNZ $-5H
|
||
; tmp$pd.stkptr = .tmp$stk(101);
|
||
LXI B,0CAH
|
||
LHLD TMPSTKADR
|
||
DAD B
|
||
MOV B,H
|
||
MOV C,L
|
||
LHLD TMPPDADR
|
||
XCHG
|
||
LXI H,4H
|
||
DAD D
|
||
MOV M,C
|
||
INX H
|
||
MOV M,B
|
||
; i = i - 1;
|
||
LXI H,I
|
||
DCR M
|
||
; tmp$pd.name(3) = i + '0';
|
||
MOV A,M
|
||
MOV B,A
|
||
ADI 30H
|
||
LXI H,9H
|
||
DAD D
|
||
MOV M,A
|
||
; tmp$pd.console = i;
|
||
LXI H,0EH
|
||
DAD D
|
||
MOV M,B
|
||
; tmp$pd.disk$slct = i;
|
||
LXI H,16H
|
||
DAD D
|
||
MOV M,B
|
||
; do j = 0 to 100;
|
||
MVI C,202
|
||
LHLD TMPSTKADR
|
||
@8:
|
||
; tmp$stk(j) = 0C7C7H;
|
||
MVI M,0C7H
|
||
INX H
|
||
; end;
|
||
DCR C
|
||
JNZ @8
|
||
; tmp$stk(101) = .tmp;
|
||
lxi b,sysdat+1
|
||
ldax b
|
||
mov b,a
|
||
mvi c,247
|
||
ldax b
|
||
mov b,a
|
||
mvi c,2
|
||
MOV M,C
|
||
INX H
|
||
MOV M,B
|
||
|
||
lhld consoledatadr
|
||
inr h
|
||
shld consoledatadr
|
||
|
||
; ret = xdos (create,.tmp$pd);
|
||
LHLD TMPPDADR
|
||
XCHG
|
||
lxi h,64
|
||
dad d
|
||
shld tmppdadr
|
||
|
||
MVI C,90H
|
||
CALL XDOS
|
||
; end;
|
||
JMP @6
|
||
@7:
|
||
|
||
; /* Terminate the initialization process */
|
||
; ret = xdos (terminate,0ffh);
|
||
MVI C,8FH
|
||
MVI E,0FFH
|
||
JMP XDOS
|
||
|
||
; /* Idle Process */
|
||
idle:
|
||
; do forever;
|
||
; call xidle;
|
||
CALL XIDLE
|
||
; end;
|
||
JMP idle
|
||
|
||
; end mpm;
|
||
;end mpm;
|
||
END
|
||
|