This entire module probably needs refactoring, it's getting a bit messy especially regarding messages. That said .. implement ability to select use_stdin for console emulation

This commit is contained in:
Neil Webber 2024-05-11 16:16:57 -05:00
parent aeefc45355
commit 8b55fe047d

55
boot.py
View file

@ -8,13 +8,16 @@ from rk11 import RK11
import breakpoints import breakpoints
STDMSG = """\ STDMSG_SOCKET = """\
Starting PDP11; this window is NOT THE EMULATED PDP-11 CONSOLE. Starting PDP11; this window is NOT THE EMULATED PDP-11 CONSOLE.
*** In another window, telnet/nc to localhost:1170 to connect. *** In another window, telnet/nc to localhost:1170 to connect.
Terminal should be in raw mode. On a mac, this is a good way: Terminal should be in raw mode. On a mac, this is a good way:
(stty raw; nc localhost 1170; stty sane) (stty raw; nc localhost 1170; stty sane)
""" """
STDMSG_STDIN = """Starting PDP11\n"""
STDMSG = None # will get set to one or the other of the above
def boot_hp(p, /, *, addr=0o10000, deposit_only=False, switches=0): def boot_hp(p, /, *, addr=0o10000, deposit_only=False, switches=0):
"""Deposit, then run, instructions to read first 1KB of drive 0 --> addr. """Deposit, then run, instructions to read first 1KB of drive 0 --> addr.
@ -302,18 +305,20 @@ def boot_lda(p, fname, /, *, force_run=True, msg=None):
return rawaddr return rawaddr
addr = rawaddr - 1 addr = rawaddr - 1
if msg: _bootmsg(msg)
print(msg.format(STDMSG))
p.run(pc=addr) p.run(pc=addr)
return rawaddr return rawaddr
def make_unix_machine(*, loglevel='INFO', drivenames=[], def make_unix_machine(*, loglevel='INFO', drivenames=[],
rk=False, telnet=False): rk=False, telnet=False, use_stdin=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, send_telnet=telnet), 'KL') # console
console = KL11(p.ub, send_telnet=telnet, use_stdin=use_stdin)
p.associate_device(console, 'KL')
if rk: if rk:
p.associate_device(RK11(p.ub, *drivenames), 'RK') # disk drive p.associate_device(RK11(p.ub, *drivenames), 'RK') # disk drive
else: else:
@ -326,13 +331,22 @@ def boot_unix(p, /, *, runoptions={}, diskboot=boot_hp, msg="{}\n"):
# load, and execute, the key-in bootstrap # load, and execute, the key-in bootstrap
diskboot(p) diskboot(p)
_bootmsg(msg)
if msg:
print(msg.format(STDMSG))
p.run(pc=0, **runoptions) p.run(pc=0, **runoptions)
def _bootmsg(msg):
"""Print out optional message, formatting it with STDMSG too."""
# note: this is a hack but when doing stdin need \r which is mostly
# harmless when not doing stdin
if msg:
for c in msg.format(STDMSG):
if c == '\n':
print('\r', end='')
print(c, end='')
# USE: # USE:
# python3 boot.py # python3 boot.py
# #
@ -346,6 +360,8 @@ if __name__ == "__main__":
parser.add_argument('--drive', action='append', default=[], dest='drives') parser.add_argument('--drive', action='append', default=[], dest='drives')
parser.add_argument('--telnet', action='store_true', parser.add_argument('--telnet', action='store_true',
help="Send RFC854 sequences to console on start") help="Send RFC854 sequences to console on start")
parser.add_argument('--stdin', action='store_true',
help="Console stdin/rawmode instead of socket")
parser.add_argument('--rk', action='store_true') 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)
@ -368,7 +384,8 @@ if __name__ == "__main__":
else: else:
runoptions['breakpoint'] = breakpoints.MultiBreakpoint(*bkpts) runoptions['breakpoint'] = breakpoints.MultiBreakpoint(*bkpts)
p = make_unix_machine(**pdpoptions, rk=args.rk, telnet=args.telnet) p = make_unix_machine(**pdpoptions, rk=args.rk,
telnet=args.telnet, use_stdin=args.stdin)
unixboot_options = {} unixboot_options = {}
if args.bootmsg: if args.bootmsg:
@ -377,19 +394,27 @@ if __name__ == "__main__":
# the default boot messages are a bit hokey, in that they sort of # the default boot messages are a bit hokey, in that they sort of
# know that booting an rk is the older bootstrap and booting hp is # know that booting an rk is the older bootstrap and booting hp is
# the newer unix bootstrap, but so be it. Specify --bootmsg to override. # the newer unix bootstrap, but so be it. Specify --bootmsg to override.
if args.stdin:
window_textra = ""
window_textra2 = ""
STDMSG = STDMSG_STDIN
else:
window_textra = " in that OTHER window"
window_textra2 = "******* EVERYTHING TYPED HERE IS IGNORED *****\n"
STDMSG = STDMSG_SOCKET
if args.rk: if args.rk:
unixboot_options['diskboot'] = boot_rk unixboot_options['diskboot'] = boot_rk
if not args.bootmsg: if not args.bootmsg:
unixboot_options['msg'] = "{}\n" + \ unixboot_options['msg'] = "{}\n" + \
"At '@' prompt in that OTHER window, " + \ f"At '@' prompt{window_textra}, " + \
"(typically) type: unix\n" + \ f"(typically) type: unix\n{window_textra2}"
"********* EVERYTHING TYPED HERE IS IGNORED *********"
else: else:
if not args.bootmsg: if not args.bootmsg:
unixboot_options['msg'] = "{}\n" + \ unixboot_options['msg'] = "{}\n" + \
"There will be no prompt; type 'boot' in OTHER window\n" + \ f"There will be no prompt; type 'boot'{window_textra}\n" + \
"Then, at the ':' prompt, typically type: hp(0,0)unix\n" + \ "Then, at the ':' prompt, typically type: hp(0,0)unix\n" + \
"********* EVERYTHING TYPED HERE IS IGNORED *********" f"{window_textra2}"
if args.lda: if args.lda:
boot_lda(p, args.lda) boot_lda(p, args.lda)