Improved boot support
This commit is contained in:
parent
5724ea071e
commit
6513654e82
1 changed files with 91 additions and 19 deletions
110
boot.py
110
boot.py
|
@ -1,6 +1,27 @@
|
|||
import time
|
||||
from machine import PDP1170
|
||||
from kw11 import KW11
|
||||
from kl11 import KL11
|
||||
from rp import RPRM
|
||||
|
||||
def boot_hp(p, /, *, addr=0o10000):
|
||||
"""Read the first 1KB of drive 0 into location 'addr'."""
|
||||
|
||||
def boot_hp(p, /, *, addr=0o10000, deposit_only=False):
|
||||
"""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
|
||||
|
@ -29,12 +50,33 @@ def boot_hp(p, /, *, addr=0o10000):
|
|||
for o, w in enumerate(program_insts):
|
||||
p.physRW(addr + o + o, w)
|
||||
|
||||
return addr
|
||||
p.r[p.PC] = addr
|
||||
if not deposit_only:
|
||||
p.run()
|
||||
|
||||
# at this point in real life the user would have to set the switches
|
||||
# to deposit zero into the PC and then hit start; that takes time
|
||||
# and means the bootstrap doesn't have to have code to wait for the
|
||||
# drive to complete the read operation. Instead of adding code to
|
||||
# the "pretend this was keyed in" program above, this delay works.
|
||||
time.sleep(0.25)
|
||||
|
||||
return addr if deposit_only else None
|
||||
|
||||
|
||||
def boot_file(p, fname, /, *, addr=0, little_endian=True, skipwords=8):
|
||||
"""Read a raw binary image of pdp11 data into location 'addr'."""
|
||||
def boot_bin(p, fname, /, *, addr=0, deposit_only=False,
|
||||
little_endian=True, skipwords=8):
|
||||
"""Read a binary file 'fname' into location 'addr' and execute it.
|
||||
RETURN VALUE: addr if deposit_only else None
|
||||
|
||||
NOTE: fname is in the host system, not on an emulated drive.
|
||||
If no 'addr' given, it defaults to ZERO.
|
||||
If deposit_only=True, the instructions are not executed.
|
||||
|
||||
little_endian (default True) dictates the fname byte order.
|
||||
skipwords (default 8 -- a.out header) will seek that many 16-bit
|
||||
words into the file before beginning to load.
|
||||
"""
|
||||
with open(fname, 'rb') as f:
|
||||
bb = f.read()
|
||||
|
||||
|
@ -65,20 +107,50 @@ def boot_file(p, fname, /, *, addr=0, little_endian=True, skipwords=8):
|
|||
|
||||
for a, w in enumerate(words[skipwords:]):
|
||||
p.physmem[a] = w
|
||||
return p
|
||||
|
||||
p.r[p.PC] = addr
|
||||
if not deposit_only:
|
||||
p.run()
|
||||
return addr if deposit_only else None
|
||||
|
||||
|
||||
def boot_unix(p=None, loglevel='INFO'):
|
||||
|
||||
if p is None:
|
||||
p = PDP1170(loglevel='INFO')
|
||||
|
||||
p.associate_device(KW11(p.ub), 'KW') # line clock
|
||||
p.associate_device(KL11(p.ub), 'KL') # console
|
||||
p.associate_device(RPRM(p.ub), 'RP') # disk drive
|
||||
|
||||
# load, and execute, the key-in bootstrap
|
||||
boot_hp(p)
|
||||
|
||||
print("Starting PDP11; this window is NOT THE EMULATED PDP-11 CONSOLE.")
|
||||
print("*** In another window, telnet/nc to localhost:1170 to connect.")
|
||||
print(" Terminal should be in raw mode. On a mac, this is a good way:")
|
||||
print(" (stty raw; nc localhost 1170; stty sane)")
|
||||
print("")
|
||||
print("There will be no prompt; type 'boot' in your OTHER window")
|
||||
print("")
|
||||
print("Then, at the ':' prompt, typically type: hp(0,0)unix")
|
||||
|
||||
p.run(pc=0)
|
||||
|
||||
|
||||
# USE:
|
||||
# python3 boot.py
|
||||
#
|
||||
# to start up unix (or whatever system is on the drive)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import time
|
||||
from machine import PDP1170
|
||||
p = PDP1170(loglevel='INFO')
|
||||
pc = boot_hp(p)
|
||||
print("starting PDP11; telnet/nc to localhost:1170 to connect to console")
|
||||
print("There will be no prompt; type 'boot' to start boot program")
|
||||
p.run(pc=pc)
|
||||
# technically need to confirm the drive is RDY, i.e., the read
|
||||
# completed, but using a delay is a lot simpler and works fine.
|
||||
# In real life, humans would have manipulated console switches to
|
||||
# start execution at location 0, which is also a source of delay. :)
|
||||
time.sleep(0.05)
|
||||
p.run(pc=0)
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--debug', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
boot_unix(loglevel='DEBUG')
|
||||
else:
|
||||
boot_unix()
|
||||
|
|
Loading…
Add table
Reference in a new issue