$title('MP/M II V2.0 System Generation') gensys: 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 */ 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 copyright (*) byte data ( 'COPYRIGHT (C) 1981, DIGITAL RESEARCH '); declare serial$number (6) byte data ( '654321'); 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; Ld$Rl: procedure byte external; end Ld$Rl; Fx$Wr: procedure external; end Fx$Wr; declare fcb (1) byte external; declare fcb16 (1) byte external; declare tbuff (1) byte external; declare maxb address external; /* B D O S P r o c e d u r e & F u n c t i o n C a l l s */ system$reset: procedure; call mon1 (0,0); end system$reset; write$console: procedure (char); declare char byte; call mon1 (2,char); end write$console; print$console$buffer: procedure (buffer$address); declare buffer$address address; call mon1 (9,buffer$address); end print$console$buffer; read$console$buffer: procedure (buffer$address); declare buffer$address address; declare buf based buffer$address (1) byte; buf(1) = 0; if automatic then return; call mon1 (10,buffer$address); buf(buf(1)+2) = 0; end read$console$buffer; open$file: procedure (fcb$address) byte; declare fcb$address address; declare fcb based fcb$address (1) byte; fcb(12), /* ex = 0 */ fcb(32) = 0; /* cr = 0 */ return mon2 (15,fcb$address); end open$file; close$file: procedure (fcb$address); declare fcb$address address; call mon1 (16,fcb$address); end close$file; search$first: procedure (fcb$address) byte; declare fcb$address address; return mon2 (17,fcb$address); end search$first; search$next: procedure (fcb$address) byte; declare fcb$address address; return mon2 (18,fcb$address); end search$next; delete$file: procedure (fcb$address); declare fcb$address address; call mon1 (19,fcb$address); end delete$file; read$record: procedure (fcb$address); declare fcb$address address; if mon2 (20,fcb$address) <> 0 then do; call print$console$buffer (.( 'Disk read error','$')); call system$reset; end; end read$record; write$record: procedure (fcb$address); declare fcb$address address; if mon2 (21,fcb$address) <> 0 then do; call print$console$buffer (.( 'Disk write error','$')); call system$reset; end; end write$record; create$file: procedure (fcb$address); declare fcb$address address; declare fcb based fcb$address (1) byte; if mon2 (22,fcb$address) = 255 then do; call print$console$buffer (.( 'Directory full','$')); call system$reset; end; fcb(32) = 0; /* set cr = 0 */ end create$file; set$DMA$address: procedure (DMA$address); declare DMA$address address; call mon1 (26,DMA$address); end set$DMA$address; read$random$record: procedure (fcb$address); declare fcb$address address; if mon2 (33,fcb$address) <> 0 then do; call print$console$buffer (.( 'Disk read error','$')); call system$reset; end; end read$random$record; write$random$record: procedure (fcb$address); declare fcb$address address; if mon2 (34,fcb$address) <> 0 then do; call print$console$buffer (.( 'Disk write error','$')); call system$reset; end; end write$random$record; compute$file$size: procedure (fcb$address); declare fcb$address address; call mon1 (35,fcb$address); end compute$file$size; set$random$record: procedure (fcb$address); declare fcb$address address; call mon1 (36,fcb$address); end set$random$record; /* D a t a S t r u c t u r e s */ declare automatic boolean; declare autoRSP boolean; declare systemdat boolean; declare err$msg$adr address; declare hexASCII (16) byte data ( '0123456789ABCDEF'); declare bit$mask (8) byte data ( 0000$0001b, 0000$0010b, 0000$0100b, 0000$1000b, 0001$0000b, 0010$0000b, 0100$0000b, 1000$0000b); declare brsps (16) structure ( record address, base address, stkptr address, name (8) byte); declare FCBin (33) byte public; declare FCBout (36) byte public 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 system$dat$fcb (33) byte initial ( 0,'SYSTEM ','DAT',0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0); declare rsp$filename (*) byte initial ( ' RSP',' $'); declare brsp$filename (*) byte initial ( ' BRS','$'); declare nmb$sect address; declare sctbfr (1) structure ( record (128) byte) public at (.memory); declare link address at (.memory); declare offset byte public; declare prgsiz address public; declare bufsiz address public; declare cur$top address initial (0); declare cur$overlay (2) byte at (.cur$top); declare cur$base byte at (.cur$overlay(1)); declare rsp structure ( OSadr address, link address, status byte, priority byte, stkptr address, name (8) byte, console byte, memseg byte ) at (.sctbfr); declare prev$top byte; declare memory$bit$map (8) structure ( page (32) byte) initial ( 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,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 system$data (256) byte; declare default$system$data (256) byte data ( /* System Data: default byte assignments ----------------------------- */ 0ffh, /* 000-000 Mem$top, top page of memory */ 4, /* 001-001 Nmb$cns, number of consoles */ 6, /* 002-002 Brkpt$RST, breakpoint RST # */ 0ffh, /* 003-003 Add system call user stacks, boolean */ 0ffh, /* 004-004 Bank switched memory, boolean */ 0ffh, /* 005-005 Z80 version, boolean */ 0ffh, /* 006-006 banked bdos, boolean */ 0, /* 007-007 ODOS/BDOS top+1 (BNKBDOS XIOS jmp tbl) base page */ 0, /* 008-008 ODOS/BDOS base page */ 0,0, /* 009-010 used by CP/NET for mstr cfg tbl addr */ 0, /* 011-011 XDOS base page */ 0, /* 012-012 RSP's (BNKXIOS top+1) base page */ 0, /* 013-013 BNKXIOS base page */ 0, /* 014-014 BNKBDOS base page */ 4, /* 015-015 Max$mem$seg, max memory segment number */ /* 016-047 Memory segment table, filled in by GENSYS if */ /* memory bank switched, otherwise by MPMLDR */ 0,0c0h,0,0, 0,0c0h,0,1, 0,0c0h,0,2, 0,0c0h,0,3, 0,0c0h,0,4, 0,0c0h,0,5, 0,0c0h,0,6, 0,0c0h,0,7, /* 048-063 Breakpoint vector table, filled in by DDTs */ 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, /* 064-079 Unassigned */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 080-095 System call user stacks */ 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, /* 096-119 Unassigned */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0, /* 120-121 Nmb records in MPM.SYS */ 60, /* 122-122 # ticks/sec */ 1, /* 123-123 System Drive */ 0c0h, /* 124-124 Common Memory Base */ 0, /* 125-125 Number of Rsp's */ 0,0, /* 126-127 Listcp address */ /* 128-143 Subflg, submit flag array */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 144-180 Copyright message */ 'COPYRIGHT (C) 1981, DIGITAL RESEARCH ', /* 181-186 Serial # */ '654321', 16, /* 187-187 Max locked records/process */ 16, /* 188-188 Max open files/process */ 0,0, /* 189-190 # list items */ 0,0, /* 191-192 Pointer to base of lock table free space */ 32, /* 193-193 Total system locked records */ 32, /* 194-194 Total system open files */ 0ffh, /* 195-195 Dayfile logging */ 1, /* 196-196 Temporary file drive */ 1, /* 197-197 Number of printers */ /* 198-240 Unassigned */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0, 0, /* 241-241 Common Xdos base */ 0, /* 242-242 Banked Xdos base */ 0, /* 243-243 Tmp pd base */ 0, /* 244-244 Console dat base */ 0,0, /* 245-246 Bdos/Xdos base */ 0, /* 247-247 Tmp base address */ 0, /* 248-248 Nmb brsps */ 0, /* 249-249 Nrsp base address */ 0,0, /* 250-251 Nrspl, non-resident rsp process link */ 0,0, /* 252-253 Sysdatadr, MP/M data page address */ 0,0 /* 254-255 Rspl, resident system process link, the address */ /* of the next Rsp, list terminates with a zero. */ ); $include (sysdat.lit) declare lnbfr (14) byte initial (12); declare xdos003 (6) byte; /* to actxioscommonbase009 */ declare resbdos009 (3) byte; /* to xdos009 */ declare sysdatadr (2) byte; /* to xdos012 */ /* to actxioscommonbase015 */ declare resbdos012 (6) byte; /* to actxioscommonbase003 */ declare bnkxios000 (256) byte; /* to xiosjmptbl000 */ declare wordadr address; declare word based wordadr address; declare act$xios$common$base address; declare cmn$xdos$record address; declare cmn$xdos$jmp$tbl (20) address; declare cmn$buffer$adr address; /* L o c a l P r o c e d u r e s */ crlf: procedure; call write$console (0dh); call write$console (0ah); end crlf; upper: procedure(b) byte; declare b byte; if b < ' ' then return 0dh; /* all non-graphics */ /* translate alpha to upper case */ if b >= 'a' and b <= 'z' then b = b and 101$1111b; /* upper case */ return b; end upper; set$bit: procedure (bank,page); declare (bank,page,i) byte; i = shr (page,3); memory$bit$map(bank).page(i) = memory$bit$map(bank).page(i) or bit$mask(page and 07h); end set$bit; reset$bit: procedure (bank,page); declare (bank,page,i) byte; i = shr (page,3); memory$bit$map(bank).page(i) = memory$bit$map(bank).page(i) and (not(bit$mask(page and 07h))); end reset$bit; test$bit: procedure (bank,page) boolean; declare (bank,page) byte; return ((memory$bit$map(bank).page(shr (page,3)) and bit$mask(page and 07h)) <> 0); end test$bit; get$response: procedure (val$adr); declare val$adr address; declare val based val$adr byte; call write$console ('('); if val = 0ffh then call write$console ('Y'); else call write$console ('N'); call print$console$buffer (.(') ? ','$')); call read$console$buffer (.lnbfr); if lnbfr(1) = 0 then return; /* accept default */ val = (upper(lnbfr(2)) = 'Y'); end get$response; dsply$hex: procedure (val); declare val byte; call write$console (hexASCII(shr (val,4))); call write$console (hexASCII(val and 0fh)); end dsply$hex; dsply$hex$adr: procedure (val); declare val address; call write$console (' '); call write$console (' '); call dsply$hex (high (val)); call dsply$hex (low (val)); call write$console ('H'); end dsply$hex$adr; dsply$hex$high$adr: procedure (val); declare val byte; call dsply$hex$adr (double (val)*256); end dsply$hex$high$adr; dsply$param: procedure (val,base); declare (val,base) byte; declare (digit,pdigit) byte; call write$console ('('); pdigit = false; if base = 10 then do; call write$console ('#'); digit = '0'; do while val >= 100; pdigit = true; digit = digit + 1; val = val - 100; end; if pdigit then do; call write$console (digit); digit = '0'; end; do while val >= 10; pdigit = true; digit = digit + 1; val = val - 10; end; if pdigit then call write$console (digit); call write$console ('0'+val); end; else do; call dsply$hex (val); end; call print$console$buffer (.(') ? ','$')); end dsply$param; get$param: procedure (string$adr,val$adr,pbase); declare (string$adr,val$adr) address; declare pbase byte; declare base byte; declare val based val$adr byte; declare string based string$adr (1) byte; declare char byte; declare lbindx byte; prompt$read: procedure; call print$console$buffer (string$adr); if string(0) = ' ' then do; call write$console ('('); call dsply$hex (val); do lbindx = 1 to 3; val$adr = val$adr + 1; if (lbindx=3) and (not bank$switched) then do; val = 0; end; else do; call write$console (','); call dsply$hex (val); end; end; val$adr = val$adr - 3; call print$console$buffer (.(') ? ','$')); end; else do; call dsply$param (val,pbase); end; base = 16; lbindx = 1; call read$console$buffer (.lnbfr); end prompt$read; call prompt$read; if lnbfr(1) = 0 then do; /* accept default value */ call crlf; return; end; val = 0; do while (char := upper(lnbfr(lbindx:=lbindx+1))) <> 0dh; if char = ',' then do; val$adr = val$adr + 1; val = 0; base = 16; end; else do; if char = '#' then do; base = 10; end; else do; char = char - '0'; if (base = 16) and (char > 9) then do; if char > 16 then char = char - 7; else char = 255; end; if char < base then do; val = val*base + char; end; else do; char, val = 0; call print$console$buffer (.(0ah,0dh, '<- bad character, re-enter',0ah,0dh,'$')); call prompt$read; val = 0; end; end; end; end; call crlf; end get$param; write$system$dat: procedure; call close$file (.FCBout); call compute$file$size (.FCBout); wordadr = .FCBout(33); nmb$records = word; if open$file (.FCBout) = 0ffh then do; go to error; end; word = 0; calì set$DMA$addresó (.system$data); call write$random$record (.FCBout); call set$DMA$address (.system$data(128)); word = 1; call write$random$record (.FCBout); word = 2*(mem$top-xios$jmp$tbl$base); call set$DMA$address (.bnkxios000+128); call write$random$record (.FCBout); call set$DMA$address (.bnkxios000); word = word + 1; calì write$random$recorä (.FCBout); call set$DMA$address (.sctbfr(0)); word = cmn$xdos$record; call read$random$record (.FCBout); call move (40,.cmn$xdos$jmp$tbl,.sctbfr(0).record(14)); call write$random$record (.FCBout); call close$file (.FCBout); system$dat$fcb(32) = 0; /* cr = 0 */ calì set$DMA$addresó (.system$data); call write$record (.system$dat$fcb); call set$DMA$address (.system$data(128)); call write$record (.system$dat$fcb); call close$file (.system$dat$fcb); end write$system$dat; setup$mem$seg$tbl: procedure; declare (i,j,k,l,ok,accept) byte; /* Fill common memory bits of non-bank zero */ do i = 1 to 7; do j = common$base to 0ffh; call set$bit (i,j); end; end; /* Fill lock table region */ i = cur$base - 1; cur$base = cur$base - high (total$list$items*10+255); do j = cur$base to i; call set$bit (0,j); end; call print$console$buffer (.(0dh,0ah,0ah, ' LCKLSTS DAT','$')); call dsply$hex$high$adr (cur$base); call dsply$hex$high$adr (i-cur$base+1); lock$free$space$adr = double (cur$base)*256; /* Fill Console dat region */ if nmb$cns <> 0 then do; i = cur$base - 1; cur$base = cur$base - nmb$cns; do j = cur$base to i; call set$bit (0,j); end; call print$console$buffer (.(0dh,0ah, ' CONSOLE DAT','$')); call dsply$hex$high$adr (cur$base); call dsply$hex$high$adr (i-cur$base+1); console$dat$base = cur$base; end; /* Create first memory segment table entry */ system$data(16) = cur$base; system$data(17) = 0ffh - cur$base + 1; system$data(18) = 80h; /* Attrib set to pre-alloc */ system$data(19) = 0; /* Bank zero forced */ nmb$mem$seg = nmb$mem$seg + 1; accept = false; do while not accept; /* Bank switched memory segment table input */ call print$console$buffer (.(0dh,0ah,0ah, 'Enter memory segment table:',0ah,0dh,'$')); i = 16; j = 0; do while j < nmb$mem$seg; if bank$switched then do; call get$param (.(' Base,size,attrib,bank ','$'), .system$data(i),16); end; else do; call get$param (.(' Base,size,attrib ','$'), .system$data(i),16); end; if (system$data(i+2) and 80h) = 0 then do; if test$bit (system$data(i+3),system$data(i)) then do; call print$console$buffer (.( '*** Memory conflict - cannot trim segment ***', 0dh,0ah,'$')); if automatic then do; fcb(1) = ' '; go to start; end; end; else do; if system$data(i+1) = 0 then do; call print$console$buffer (.( '*** Entry error - zero length segment ***', 0dh,0ah,'$')); end; else do; ok = true; k = system$data(i); l = system$data(i+1) + 1; do while ok and ((l:=l-1) <> 0); if test$bit (system$data(i+3),k) then ok = false; else k = k + 1; end; if ok then do; do k = system$data(i) to system$data(i)+ system$data(i+1) - 1; call set$bit (system$data(i+3),k); end; j = j + 1; i = i + 4; end; else do; system$data(i+1) = k - system$data(i); call print$console$buffer (.( '*** Memory conflict - segment trimmed ***', 0dh,0ah,'$')); end; end; end; end; else do; do k = system$data(i) to system$data(i)+ system$data(i+1) - 1; call set$bit (system$data(i+3),k); end; j = j + 1; i = i + 4; end; end; call crlf; i = 16; do j = 1 to nmb$mem$seg; if j = 1 then call print$console$buffer (.(' MP/M II Sys','$')); else call print$console$buffer (.(' Memseg Usr','$')); call dsply$hex$high$adr (system$data(i)); call dsply$hex$high$adr (system$data(i+1)); if bank$switched then do; call print$console$buffer (.(' Bank ','$')); call dsply$hex (system$data(i+3)); end; call crlf; i = i + 4; end; accept = true; call print$console$buffer (.(0dh,0ah, 'Accept new memory segment table entries ','$')); call get$response (.accept); if not accept then do; i = 16; do k = 1 to nmb$mem$seg; do j = system$data(i) to system$data(i)+ system$data(i+1) - 1; call reset$bit (system$data(i+3),j); end; i = i + 4; end; end; end; /* do while not accept */ end setup$mem$seg$tbl; load$reloc: procedure (file$name$adr,sys$dat$param$adr); declare (file$name$adr,sys$dat$param$adr) address; declare sys$dat$param based sys$dat$param$adr byte; declare header$record structure ( fill1 byte, psize address, fill2 byte, dsize address, fill3 (122) byte); declare (i,j) byte; call move (11,(err$msg$adr:=file$name$adr),.FCBin(1)); if open$file (.FCBin) = 0ffh then do; go to error; end; call set$DMA$address (.header$record); call read$record (.FCBin); prgsiz = header$record.psize; bufsiz = header$record.dsize; if shr(prgsiz+255,7) > nmb$sect then do; call print$console$buffer (.(0dh,0ah, '*** File cannot fit into GENSYS buffer ***','$')); go to error; end; i = cur$base - 1; prev$top = cur$base; cur$base = cur$base - high (prgsiz + bufsiz + 255); do j = i to cur$base-1; call set$bit (0,j); end; sys$dat$param = cur$base; offset = cur$base; call read$record (.FCBin); call print$console$buffer (.(0dh,0ah,' ','$')); call print$console$buffer (err$msg$adr); call dsply$hex$adr (cur$top); call dsply$hex$high$adr (prev$top-cur$base); if Ld$Rl <> 0 then do; go to error; end; end load$reloc; load$reloc$write$bnkrsps: procedure; declare cntr byte; if nmb$brsps = 0 then return; cntr = 0; call crlf; do while cntr <> nmb$brsps; call move (8,.brsps(cntr).name,.brsp$filename); call load$reloc (.brsp$filename,.brsp$base); wordadr = .sctbfr + 2; brsps(cntr).stkptr = word; link = brsps(cntr).base; word = brspl; brspl = cur$top; call FxWr; cntr = cntr + 1; end; cntr = 0; wordadr = .FCBout(33); call set$DMA$address (.sctbfr); do while cntr <> nmb$brsps; word = brsps(cntr).record; call read$random$record (.FCBout); rsp.stkptr = brsps(cntr).stkptr; call write$random$record (.FCBout); cntr = cntr + 1; end; end load$reloc$write$bnkrsps; load$reloc$write$rsps: procedure; declare rspnames (16) structure ( char (8) byte); declare (i,cntr,ret) byte; nmb$rsps = 0; nmb$brsps = 0; rspl = 0; brspl = 0; rsp$base = 0; brsp$base = 0; call move (13,.(0,'????????RSP',0),.fcbin(0)); ret = search$first (.fcbin); if ret <> 255 then do; rsp$filename(11) = ' '; call print$console$buffer (.(0dh,0ah,0ah, 'Select Resident and Banked System Processes:',0dh,0ah,'$')); do while ret <> 255; call move (8,(.sctbfr+(ret mod 4)*32+1),.rsp$filename); call write$console (' '); call print$console$buffer (.rsp$filename); ret = 0; call get$response (.ret); if (ret or autoRSP) then do; call move (8,.rsp$filename,.rspnames(nmb$rsps)); nmb$rsps = nmb$rsps + 1; end; if autoRSP then call write$console ('Y'); call crlf; ret = search$next (.fcbin); end; if nmb$rsps <> 0 then do; rsp$filename(11) = '$'; cntr = 0; do while cntr <> nmb$rsps; call move (8,.rspnames(cntr),.rsp$filename); call load$reloc (.rsp$filename,.rsp$base); if cur$base < common$base then do; call print$console$buffer (.(0dh,0ah, '*** GENSYS Failure - RSP extends below ', 'the common base ***','$')); go to start; end; else do; link = rspl; rspl = cur$top; call FxWr; if rsp.memseg = 0 then do; wordadr = .FCBout(33); call set$random$record (.FCBout); brsps(nmb$brsps).record = word - 1; brsps(nmb$brsps).base = cur$top; do i = 0 to 7; ret = (rsp.name(i) and 0111$1111b); if (ret >= 'a') and (ret <= 'z') then ret = (ret and 101$1111b); brsps(nmb$brsps).name(i) = ret; end; nmb$brsps = nmb$brsps + 1; end; end; cntr = cntr + 1; end; call crlf; end; end; rsp$base = high (cur$top); end load$reloc$write$rsps; write$preamble: procedure; declare i byte; do i = 0 to 127; sctbfr(0).record(i) = 0; end; call set$DMA$address (.sctbfr); /* start with zeroed system data page */ i = (mem$top-cur$base+1)*2 + 1; do while (i:=i-1) <> 0; call write$record (.FCBout); end; end write$preamble; get$default$file: procedure; declare ret byte; call print$console$buffer (.(0dh,0ah,0ah, 'Default entries are shown in (parens).',0dh,0ah, 'Default base is Hex, precede entry with # for decimal', 0dh,0ah,0ah,'$')); if (ret:=open$file (.system$dat$fcb)) <> 255 then do; call print$console$buffer (.( 'Use SYSTEM.DAT for defaults ','$')); ret = 0ffh; call get$response (.ret); if ret then do; call set$DMA$address (.system$data(0)); call read$record (.system$dat$fcb); call set$DMA$address (.system$data(128)); call read$record (.system$dat$fcb); return; end; end; else do; call create$file (.system$dat$fcb); end; call move (256, .default$system$data, .system$data); end get$default$file; setup$system$dat: procedure; declare (i,j,ok) byte; call get$default$file; ok = false; do while not ok; system$dat$fcb(32) = 0; call move (43,.copyright,.system$data(144)); call crlf; call get$param (.('Top page of operating system ','$'), .mem$top,16); call get$param (.('Number of TMPs (system consoles) ','$'), .nmb$cns,10); call get$param (.('Number of Printers ','$'), .nmb$printers,10); call get$param (.('Breakpoint RST ','$'), .brkpt$RST,16); call print$console$buffer ( .('Add system call user stacks ','$')); call get$response (.sys$call$stks); call print$console$buffer (.(0dh,0ah, 'Z80 CPU ','$')); call get$response (.z80$cpu); call crlf; call get$param (.('Number of ticks/second ','$'), .ticks$per$second,10); call print$console$buffer ( .('System Drive (','$')); call write$console ('A'+system$drive-1); call print$console$buffer (.(':) ? ','$')); call read$console$buffer (.lnbfr); if lnbfr(1) <> 0 then system$drive = ((upper(lnbfr(2))-'A'+1) and 0fh); call crlf; call print$console$buffer ( .('Temporary file drive (','$')); call write$console ('A'+temp$file$drive-1); call print$console$buffer (.(':) ? ','$')); call read$console$buffer (.lnbfr); if lnbfr(1) <> 0 then temp$file$drive = ((upper(lnbfr(2))-'A'+1) and 0fh); call crlf; call get$param (.('Maximum locked records/process ','$'), .max$locked$records,10); call get$param (.('Total locked records/system ','$'), .total$system$locked$records,10); call get$param (.('Maximum open files/process ','$'), .max$open$files,10); call get$param (.('Total open files/system ','$'), .total$system$open$files,10); total$list$items = double(total$system$locked$records) + double(total$system$open$files); call print$console$buffer (.('Bank switched memory ','$')); call get$response (.bank$switched); call crlf; nmb$mem$seg = nmb$mem$seg - 1; call get$param (.('Number of user memory segments ','$'), .nmb$mem$seg,10); if bank$switched then do; call get$param (.('Common memory base page ','$'), .common$base,16); end; else do; common$base = 0; end; /* call print$console$buffer (.( 'Banked BDOS file manager ','$')); call get$response (.banked$bdos); call crlf; */ banked$bdos = 0ffh; call print$console$buffer (.( 'Dayfile logging at console ','$')); call get$response (.day$file); call crlf; if mem$top <> 0ffh then do; call print$console$buffer (.(0dh,0ah,0ah, ' RESERVED ','$')); call dsply$hex$high$adr (mem$top+1); call dsply$hex$high$adr ((0ffh-(mem$top+1))+1); end; call print$console$buffer (.(0dh,0ah, ' SYSTEM DAT','$')); call dsply$hex$high$adr (mem$top); call dsply$hex$adr (0100h); i = mem$top; if nmb$cns <> 0 then do; call print$console$buffer (.(0dh,0ah, ' TMPD DAT','$')); i = i - 1; if nmb$cns > 4 then i = i - 1; call dsply$hex$high$adr (i); call dsply$hex$high$adr (shr(nmb$cns+3,2)); tmpd$base = i; end; if sys$call$stks then do; call print$console$buffer (.(0dh,0ah, ' USERSYS STK','$')); do j = 0 to nmb$mem$seg-1; user$stacks(j) = double(i)*256 - double(j)*64; end; i = i - 1; if nmb$mem$seg > 4 then i = i - 1; call dsply$hex$high$adr (i); call dsply$hex$high$adr (shr(nmb$mem$seg+3,2)); end; call print$console$buffer (.(0dh,0ah, ' XIOSJMP TBL','$')); xios$jmp$tbl$base = i - 1; call dsply$hex$high$adr (xios$jmp$tbl$base); call dsply$hex$adr (0100h); call print$console$buffer (.(0dh,0ah,0ah, 'Accept new system data page entries ','$')); ok = true; call get$response (.ok); if not ok then nmb$mem$seg = nmb$mem$seg + 1; call crlf; end; /* of do while not ok */ /* Fill system data page to top of memory */ do cur$base = mem$top to 0ffh; call set$bit (0,cur$base); end; cur$base = mem$top; /* Fill tmpd.dat region */ if nmb$cns <> 0 then do; cur$base = cur$base - 1; call set$bit (0,cur$base); if nmb$cns > 4 then do; cur$base = cur$base - 1; call set$bit (0,cur$base); end; end; /* Fill usersys.stk region */ if sys$call$stks then do; cur$base = cur$base - 1; call set$bit (0,cur$base); if nmb$mem$seg > 4 then do; cur$base = cur$base - 1; call set$bit (0,cur$base); end; end; /* Fill xiosjmp.tbl page */ cur$base = cur$base - 1; call set$bit (0,cur$base); xios$jmp$tbl$base = cur$base; end setup$system$dat; setup$MPM$sys: procedure; call print$console$buffer (.( 0dh,0ah,0ah, 'MP/M II V2.0 System Generation',0dh,0ah, 'Copyright (C) 1981, Digital Research', 0dh,0ah,'$')); if open$file (.fcbout) <> 0ffh then call delete$file (.fcbout); call create$file (.fcbout); end setup$MPM$sys; initialization: procedure; nmb$sect = shr ((maxb-.sctbfr+1),7); if fcb(1) = '$' then do; automatic = (upper (fcb(2)) = 'A'); autoRSP = (upper (fcb(3)) = 'R'); end; else do; automatic = false; autoRSP = false; end; end initialization; /* G e n s y s M a i n P r o g r a m */ start: call initialization; call setup$MPM$sys; call setup$system$dat; sysdatadr(0) = 0; sysdatadr(1) = mem$top; call write$preamble; call load$reloc (.('RESBDOS SPR$'),.resbdos$base); call Fx$Wr; call move (3,.sctbfr(0).record(009),.resbdos009); call move (6,.sctbfr(0).record(012),.resbdos012); call load$reloc (.('XDOS SPR$'),.xdos$base); call move (3,.resbdos009,.sctbfr(0).record(009)); call move (2,.sysdatadr,.sctbfr(0).record(012)); call Fx$Wr; call move (6,.sctbfr(0).record(003),.xdos003); wordadr = .FCBout(33); call set$random$record (.FCBout); cmn$xdos$record = word - 1; call load$reloc$write$rsps; if bank$switched then call load$reloc (.('BNKXIOS SPR$'),.bnkxios$base); else call load$reloc (.('RESXIOS SPR$'),.bnkxios$base); wordadr = .sctbfr(0).record(001); act$xios$common$base = word; if act$xios$common$base < (double (common$base)*256) then do; call print$console$buffer (.(0dh,0ah, '*** Gensys Failure - XIOS common base below ', 'the actual common base ***','$')); fcb(1) = ' '; go to start; end; call move (6,.resbdos012,(act$xios$common$base-cur$top)+.sctbfr(0).record(003)); call move (6,.xdos003,(act$xios$common$base-cur$top)+.sctbfr(0).record(009)); call move (2,.sysdatadr,(act$xios$common$base-cur$top)+.sctbfr(0).record(015)); call move (256,.sctbfr(0).record(000),.bnkxios000); call Fx$Wr; call load$reloc (.('BNKBDOS SPR$'),.bnkbdos$base); call Fx$Wr; call load$reloc (.('BNKXDOS SPR$'),.bnkxdos$base); call move (2,.sysdatadr,.sctbfr(0).record(0)); call move (2,.cmn$buffer$adr,.sctbfr(0).record(2)); call Fx$Wr; call move (40,.sctbfr(0).record(4),.cmn$xdos$jmp$tbl); if nmb$cns <> 0 then do; call load$reloc (.('TMP SPR$'),.tmp$base); call move (2,.sysdatadr,.sctbfr(0).record(0)); call Fx$Wr; end; call load$reloc$write$bnkrsps; call setup$mem$seg$tbl; call write$system$dat; call print$console$buffer (.(0dh,0ah,0ah, '** GENSYS DONE **','$')); call system$reset; error: call print$console$buffer (.(0dh,0ah, 'GENSYS error: ','$')); call print$console$buffer (err$msg$adr); call system$reset; end gensys;