first go at making rk unix bootable

This commit is contained in:
Neil Webber 2024-05-03 07:50:11 -05:00
parent 9434ea843e
commit fb71067946

72
boot.py
View file

@ -4,6 +4,7 @@ from kw11 import KW11
from kl11 import KL11 from kl11 import KL11
from dc11 import DC11 from dc11 import DC11
from rp import RPRM from rp import RPRM
from rk11 import RK11
import breakpoints import breakpoints
@ -66,6 +67,59 @@ def boot_hp(p, /, *, addr=0o10000, deposit_only=False, switches=0):
return addr if deposit_only else None return addr if deposit_only else None
def boot_rk(p, /, *, addr=0o10000, deposit_only=False, switches=0):
"""Deposit, then run, instructions to read first 1KB of drive 0 --> addr.
RETURN VALUE: addr if deposit_only else None
If no 'addr' given, it defaults to something out of the way.
If not deposit_only (default):
* The instructions are loaded to 'addr'
* They are executed.
* Return value is None.
* NOTE: The next start address depends on what those instructions do.
* TYPICALLY, the next start address will be zero.
If deposit_only:
* The instructions are loaded to 'addr'
* 'addr' is returned.
"""
# this is the sort of thing that would be keyed in from
# the console switches (if the machine was not equipped
# with a boot rom option to hold it instead)
#
# It is a minimalist program, with lots of assumptions, to read 1K
# from block zero of drive 0 into location 0. The execution start
# at zero is done elsewhere.
#
# NOTE WELL: THIS ASSUMES THE MACHINE IS IN RESET CONDITION WHICH
# MEANS MANY OF THE DEVICE REGISTERS ARE ASSUMED TO BE ZERO
#
# MOV #177406,R0
# MOV #177400,(R0)
# MOV #5,-(R0)
program_insts = (
0o012700, # MOV #177406,R0
0o177406,
0o012710, # MOV #177400,(R0)
0o177400,
0o012740, # MOV #5,-(R0)
0o000005,
0o0 # HALT
)
for o, w in enumerate(program_insts):
p.physRW(addr + o + o, w)
p.r[p.PC] = addr
if not deposit_only:
p.run()
return addr if deposit_only else None
def boot_bin(p, fname, /, *, addr=0, deposit_only=False, def boot_bin(p, fname, /, *, addr=0, deposit_only=False,
little_endian=True, skipwords=8): little_endian=True, skipwords=8):
"""Read a binary file 'fname' into location 'addr' and execute it. """Read a binary file 'fname' into location 'addr' and execute it.
@ -252,20 +306,23 @@ def boot_lda(p, fname, /, *, force_run=True):
return rawaddr return rawaddr
def make_unix_machine(*, loglevel='INFO', drivenames=[]): def make_unix_machine(*, loglevel='INFO', drivenames=[], rk=False):
p = PDP1170(loglevel=loglevel) p = PDP1170(loglevel=loglevel)
p.associate_device(KW11(p.ub), 'KW') # line clock p.associate_device(KW11(p.ub), 'KW') # line clock
p.associate_device(KL11(p.ub), 'KL') # console p.associate_device(KL11(p.ub), 'KL') # console
p.associate_device(RPRM(p.ub, *drivenames), 'RP') # disk drive if rk:
p.associate_device(RK11(p.ub, *drivenames), 'RK') # disk drive
else:
p.associate_device(RPRM(p.ub, *drivenames), 'RP') # disk drive
p.associate_device(DC11(p.ub), 'DC') # additional serial poirts p.associate_device(DC11(p.ub), 'DC') # additional serial poirts
return p return p
def boot_unix(p, runoptions={}): def boot_unix(p, runoptions={}, diskboot=boot_hp):
# load, and execute, the key-in bootstrap # load, and execute, the key-in bootstrap
boot_hp(p) diskboot(p)
print(bootmsg) print(bootmsg)
print("There will be no prompt; type 'boot' in your OTHER window") print("There will be no prompt; type 'boot' in your OTHER window")
@ -286,6 +343,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--debug', action='store_true') parser.add_argument('--debug', action='store_true')
parser.add_argument('--drive', action='append', default=[], dest='drives') parser.add_argument('--drive', action='append', default=[], dest='drives')
parser.add_argument('--rk', action='store_true')
parser.add_argument('--instlog', action='store_true') parser.add_argument('--instlog', action='store_true')
parser.add_argument('--lda', action='store', default=None) parser.add_argument('--lda', action='store', default=None)
args = parser.parse_args() args = parser.parse_args()
@ -295,7 +353,7 @@ if __name__ == "__main__":
bkpts = [] bkpts = []
if args.debug: if args.debug:
pdpoptions['loglevel'] = 'DEBUG' pdpoptions['loglevel'] = 'DEBUG'
bkpts.append(breakpoints.MemChecker(1000000)) bkpts.append(breakpoints._MemChecker(1000000))
if args.instlog: if args.instlog:
bkpts.append(breakpoints.Logger()) bkpts.append(breakpoints.Logger())
@ -306,9 +364,11 @@ if __name__ == "__main__":
else: else:
runoptions['breakpoint'] = breakpoints.MultiBreakpoint(*bkpts) runoptions['breakpoint'] = breakpoints.MultiBreakpoint(*bkpts)
p = make_unix_machine(**pdpoptions) p = make_unix_machine(**pdpoptions, rk=args.rk)
if args.lda: if args.lda:
boot_lda(p, args.lda) boot_lda(p, args.lda)
elif args.rk:
boot_unix(p, runoptions=runoptions, diskboot=boot_rk)
else: else:
boot_unix(p, runoptions=runoptions) boot_unix(p, runoptions=runoptions)