Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,553 @@
$title ('MP/M II V2.0 Loader')
mpmldr:
do;
/*
Copyright (C) 1979,1980,1981
Digital Research
P.O. Box 579
Pacific Grove, CA 93950
Revised:
14 Sept 81 by Thomas Rolander
*/
declare true literally '0FFH';
declare false literally '0';
declare forever literally 'while true';
declare boolean literally 'byte';
declare start label;
declare jmp$to$start structure (
jmp$instr byte,
jmp$location address ) data (
0C3H,.start-3);
declare signon (*) byte data (
0dh, /* Filler */
0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,
0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,0ah,
'MP/M II V2.0 Loader ',0dh,0ah,
'Copyright (C) 1981, Digital Research',0dh,0dh,0ah,'$');
/**************** Warning ******************/
/* */
/* This location must be at or above 015CH */
/* */
/*********************************************/
declare copyright (*) byte data (
'COPYRIGHT (C) 1981,');
declare company$name (*) byte data (
' DIGITAL RESEARCH ');
declare serial$number (6) byte data (
'654321');
declare err$msgadr address initial (.default$err$msg);
declare err$msg based err$msgadr (1) byte;
declare default$err$msg (*) byte data (
'Dsk rd err','$');
declare mon1 literally 'ldmon1';
declare mon2 literally 'ldmon2';
mon1:
procedure (func,info) external;
declare func byte;
declare info address;
end mon1;
mon2:
procedure (func,info) byte external;
declare func byte;
declare info address;
end mon2;
declare fcb (1) byte external;
declare fcb16 (1) byte external;
declare tbuff (1) byte external;
/**************************************
* *
* B D O S Externals *
* *
**************************************/
write$console:
procedure (char);
declare char byte;
call mon1 (2,char);
end write$console;
print$buffer:
procedure (buffer$address);
declare buffer$address address;
call mon1 (9,buffer$address);
end print$buffer;
reset$disk$system:
procedure;
call mon1 (13,0);
end reset$disk$system;
open$file:
procedure (fcb$address) byte;
declare fcb$address address;
return mon2 (15,fcb$address);
end open$file;
read$record:
procedure (fcb$address) byte;
declare fcb$address address;
return mon2 (20,fcb$address);
end read$record;
set$DMA$address:
procedure (DMA$address);
declare DMA$address address;
call mon1 (26,DMA$address);
end set$DMA$address;
/**************************************
* *
* Misc. BDOS procs *
* *
**************************************/
crlf:
procedure;
call write$console (0dh);
call write$console (0ah);
end crlf;
printdecimal:
procedure (n);
declare n byte;
declare (digit,pdigit) byte;
pdigit = false;
digit = '0';
do while n >= 100;
pdigit = true;
digit = digit + 1;
n = n - 100;
end;
if pdigit then
do;
call write$console (digit);
digit = '0';
end;
do while n >= 10;
pdigit = true;
digit = digit + 1;
n = n - 10;
end;
if pdigit then
call write$console (digit);
call write$console ('0'+n);
end printdecimal;
printnib:
procedure (n);
declare n byte;
if n > 9
then call write$console (n+'A'-10);
else call write$console (n+'0');
end printnib;
printhex:
procedure (b);
declare b byte;
call printnib (shr(b,4));
call printnib (b and 0fh);
end printhex;
printaddr:
procedure (a);
declare a address;
call write$console (' ');
call write$console (' ');
call printhex (high(a));
call printhex (low(a));
call write$console ('H');
end printaddr;
printstring:
procedure (sadr,sz);
declare sadr address;
declare sz byte;
declare s based sadr (1) byte;
declare i byte;
do i = 0 to sz-1;
call write$console (s(i) and 7fh);
end;
end printstring;
printname:
procedure (nadr);
declare nadr address;
call printstring (nadr,11);
end printname;
printitems:
procedure (nadr,base,size);
declare (nadr,base,size) address;
call print$name (nadr);
call printaddr (base);
call printaddr (size);
call crlf;
end printitems;
printitemsadr:
procedure (nadr,base,size);
declare nadr address;
declare (base,size) byte;
call printitems (nadr,
double (base)*256,
double (size)*256);
end printitemsadr;
match$serial:
procedure (cpyrtadr,memadr);
declare (cpyrtadr,memadr) address;
declare (i,j) byte;
declare cpyrt based cpyrtadr (1) byte;
declare mem based memadr (1) byte;
do forever;
i,j = -1;
do while cpyrt(i:=i+1) = mem(j:=j+1);
;
end;
if i > 23 then return;
if (memadr = 0) or (i > 17) then
do;
err$msgadr = .('Synchronization: Serial numbers do not match','$');
go to error;
end;
memadr = memadr + 1;
end;
end match$serial;
declare (base,cur$top,prev$top) address;
declare cur$record address;
declare sysdatadr address;
declare wordadr address;
declare word based wordadr address;
declare xios$common based cur$top structure (
jmpinstr byte,
base address );
declare actual$xios$common$base address;
declare nrec byte;
declare notdone boolean;
declare rspname (11) byte initial (
'????????RSP');
declare brspname (11) byte initial (
'????????BRS');
declare mpm$sys$fcb (36) byte initial (
0,'MPM ','SYS',0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
declare entry$point (3) address;
declare system$data (256) byte at (.fcb);
$include (sysdat.lit)
declare break boolean;
declare debug$RST byte;
declare destination based cur$top (1) byte;
declare link based cur$top address;
declare test$byte based cur$top byte;
declare rspcnt byte;
print2addr:
procedure;
call printaddr (cur$top);
call printaddr (prev$top-cur$top);
call crlf;
end print2addr;
load$system$data:
procedure;
declare cntr byte;
call set$DMA$address (.system$data);
if open$file (.mpm$sys$fcb) = 0ffh then
do;
call move (4,.(' ?','$'),.mpm$sys$fcb(12));
err$msgadr = .mpm$sys$fcb(1);
go to error;
end;
if read$record (.mpm$sys$fcb) <> 0 then
do;
go to error;
end;
call set$DMA$address (.system$data(128));
if read$record (.mpm$sys$fcb) <> 0 then
do;
go to error;
end;
sysdatadr,
cur$top = shl(double(mem$top),8);
call print$buffer (.(
'Nmb of consoles = ','$'));
call printnib (nmb$cns);
call print$buffer (.(0dh,0ah,
'Breakpoint RST # = ','$'));
call printnib (brkpt$RST);
/**********************************************************
if z80$cpu then
call print$buffer (.(0dh,0ah,
'Z80 Alternate register set saved/restored',
' by dispatcher','$'));
if bank$switched <> 0 then
do;
call print$buffer (.(0dh,0ah,
'Common base addr =','$'));
call printaddr (double (common$base) * 256);
end;
if banked$bdos then
call print$buffer (.(0dh,0ah,
'Banked BDOS file manager','$'));
call print$buffer (.(0dh,0ah,
'Nmb of ticks/second = ','$'));
call printdecimal (ticks$per$second);
call print$buffer (.(0dh,0ah,
'System drive = ','$'));
call write$console ('A'+system$drive-1);
call write$console (':');
call print$buffer (.(0dh,0ah,
'Max lckd recs/proc = ','$'));
call printdecimal (max$locked$records);
call print$buffer (.(0dh,0ah,
'Totl lckd recs/sys = ','$'));
call printdecimal (total$system$locked$records);
call print$buffer (.(0dh,0ah,
'Max open files/proc = ','$'));
call printdecimal (max$open$files);
call print$buffer (.(0dh,0ah,
'Totl open files/sys = ','$'));
call printdecimal (total$system$open$files);
call print$buffer (.(0dh,0ah,
'To<54> o<> MP/M-80 =','$'));
call printaddr (cur$top + 255);
*************************************************************/
call print$buffer (.(0dh,0ah,
'Memory Segment Table:',0dh,0ah,'$'));
call printitems (.('SYSTEM DAT'),cur$top,256);
cur$top = cur$top
- (prev$top := (shr(nmb$cns-1,2)+1)*256);
call printitems (.('TMPD DAT'),cur$top,prev$top);
if sys$call$stks then
do;
cur$top = cur$top
- (prev$top := (shr(nmb$mem$seg-2,2)+1)*256);
call printitems (.('USERSYS STK'),cur$top,prev$top);
end;
end load$system$data;
display$OS:
procedure;
declare (base,cntr) byte;
declare rspsadr (16) address;
declare temp$rspl address;
declare temp$rspl$adr based temp$rspl address;
call printitemsadr (.('XIOSJMP TBL'),
xios$jmp$tbl$base,
1);
call printitemsadr (.('RESBDOS SPR'),
resbdos$base,
xios$jmp$tbl$base-resbdos$base);
call printitemsadr (.('XDOS SPR'),
xdos$base,
resbdos$base-xdos$base);
if nmb$rsps <> 0 then
do;
cntr = 0;
temp$rspl = rspl;
do while (rspsadr(cntr):=temp$rspl) <> 0;
cntr = cntr + 1;
temp$rspl = temp$rspl$adr;
end;
rspsadr(cntr) = double (xdos$base)*256;
do while (cntr:=cntr-1) <> -1;
call move (8,rspsadr(cntr)+6+2,.rspname);
call printitems (.rspname,
rspsadr(cntr),
rspsadr(cntr+1)-rspsadr(cntr));
end;
end;
call printitemsadr (.('BNKXIOS SPR'),
bnkxios$base,
rsp$base-bnkxios$base);
call printitemsadr (.('BNKBDOS SPR'),
bnkbdos$base,
bnkxios$base-bnkbdos$base);
call printitemsadr (.('BNKXDOS SPR'),
bnkxdos$base,
bnkbdos$base-bnkxdos$base);
call printitemsadr (.('TMP SPR'),
tmp$base,
bnkxdos$base-tmp$base);
if nmb$brsps <> 0 then
do;
cntr = 0;
temp$rspl = brspl;
do while (rspsadr(cntr):=temp$rspl) <> 0;
cntr = cntr + 1;
temp$rspl = temp$rspl + 2;
temp$rspl = temp$rspl$adr;
end;
rspsadr(cntr) = double (tmp$base)*256;
do while (cntr:=cntr-1) <> -1;
call move (8,rspsadr(cntr)+4,.brspname);
call printitems (.brspname,
rspsadr(cntr),
rspsadr(cntr+1)-rspsadr(cntr));
end;
base = brsp$base;
end;
else
do;
base = tmp$base;
end;
cntr = base - high (total$list$items*10 + 255);
call printitemsadr (.('LCKLSTS DAT'),
cntr,
base-cntr);
if nmb$cns <> 0 then
do;
base = cntr;
cntr = base - nmb$cns;
call printitemsadr (.('CONSOLE DAT'),
cntr,
base-cntr);
end;
end display$OS;
display$mem$map:
procedure;
declare msgadr address;
call print$buffer (.(
'-------------------------',0dh,0ah,'$'));
msgadr = .('MP/M II Sys','$');
do nrec = 0 to nmb$mem$seg-1;
call print$buffer (msgadr);
msgadr = .('Memseg Usr','$');
call printaddr (shl(double(mem$seg$tbl(nrec).base),8));
call printaddr (shl(double(mem$seg$tbl(nrec).size),8));
if bank$switched <> 0 then
do;
call print$buffer (.(' Bank ','$'));
call printdecimal (mem$seg$tbl(nrec).bank);
end;
call crlf;
end;
end display$mem$map;
Restart$instr:
procedure;
disable; /* this disable is overlayed with RST x */
end Restart$instr;
xeq$mpm:
procedure;
declare brkpt$adr address data (.Restart$instr);
declare brkpt based brkpt$adr byte;
declare loc$0007 byte at (0007h);
stack$ptr = .entry$point(2);
/* if command tail starts with 'B' then break */
if break then
do;
if mem$top >= loc$0007 then
do;
errmsg$adr = .('No break, CP/M debugger overlaid by MP/M',
'$');
go to error;
end;
brkpt = 1100$0111b or shl(debug$RST,3);
call Restart$instr;
end;
end xeq$mpm;
command$tail:
procedure;
declare fcbstr$adr address;
declare fcbstr based fcbstr$adr (1) byte;
break = false;
fcbstr$adr = .fcb;
if fcbstr(1) = ' ' then
return;
if fcbstr(1) = '$' then
do;
if fcbstr(2) = 'B' then
do;
break = true;
if fcbstr(3) = ' '
then debug$RST = 7;
else debug$RST = fcbstr(3) and 0000$0111b;
end;
fcbstr$adr = .fcb16;
end;
if (fcbstr( 9) = 'S') and
(fcbstr(10) = 'Y') and
(fcbstr(11) = 'S') then
do;
call move (9,fcbstr$adr,.mpm$sys$fcb);
end;
end command$tail;
/*
Main Program
*/
start:
/* disable; -> removed from base of MP/M 1.x loader */
call reset$disk$system;
call command$tail;
call print$buffer (.signon);
call load$system$data;
cur$top = sysdatadr;
cur$record = 1;
do while (cur$record:=cur$record+1) <> nmb$records;
call set$DMA$address (cur$top:=cur$top-128);
if read$record (.mpm$sys$fcb) <> 0 then
do;
errmsg$adr = .('failed to read MPM.SYS','$');
go to error;
end;
end;
entry$point(2) = double (xdos$base)*256;
call match$serial (.company$name,.system$data);
call display$OS;
call display$mem$map;
call move (256,.system$data,sysdatadr);
call xeq$mpm;
error:
call print$buffer (.(0dh,0ah,
'MPMLDR error: ','$'));
call print$buffer (err$msgadr);
do forever;
stackptr = 0;
disable;
halt;
end;
end mpmldr;