From 486427c9fecf302e9fd4c0c3e1d7a74b1bf40187 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sun, 3 Jun 2018 14:38:38 -0700 Subject: [PATCH] HP2100: Release 28 See HP2100/hp2100_release.txt for details of the release. --- HP2100/hp2100_baci.c | 153 ++- HP2100/hp2100_cpu.c | 687 ++++++++---- HP2100/hp2100_cpu.h | 75 +- HP2100/hp2100_cpu1.c | 5 +- HP2100/hp2100_cpu2.c | 19 +- HP2100/hp2100_cpu4.c | 7 +- HP2100/hp2100_cpu5.c | 17 +- HP2100/hp2100_defs.h | 48 +- HP2100/hp2100_di_da.c | 247 +++-- HP2100/hp2100_diag.txt | 102 +- HP2100/hp2100_dp.c | 667 +++++++++--- HP2100/hp2100_dq.c | 329 ++++-- HP2100/hp2100_dr.c | 268 +++-- HP2100/hp2100_ds.c | 370 +++++-- HP2100/hp2100_fp1.c | 11 +- HP2100/hp2100_ipl.c | 2070 +++++++++++++++++++++++++++---------- HP2100/hp2100_mpx.c | 250 +++-- HP2100/hp2100_ms.c | 297 ++++-- HP2100/hp2100_mux.c | 603 ++++++++--- HP2100/hp2100_release.txt | 278 ++++- HP2100/hp2100_stddev.c | 295 ++++-- HP2100/hp2100_sys.c | 138 ++- doc/hp2100_doc.doc | Bin 624128 -> 666112 bytes 23 files changed, 5151 insertions(+), 1785 deletions(-) diff --git a/HP2100/hp2100_baci.c b/HP2100/hp2100_baci.c index 3662ea13..6b844f4b 100644 --- a/HP2100/hp2100_baci.c +++ b/HP2100/hp2100_baci.c @@ -25,6 +25,7 @@ BACI 12966A Buffered Asynchronous Communications Interface + 01-Nov-17 JDB Fixed serial output buffer overflow handling 15-Mar-17 JDB Trace flags are now global Changed DEBUG_PRI calls to tprintfs 10-Mar-17 JDB Added IOBUS to the debug table @@ -87,13 +88,13 @@ an "external rate" that is equivalent to 9600 baud, as most terminals were set to their maximum speeds. - We support the 12966A connected to an HP terminal emulator via Telnet. - Internally, we model the BACI as a terminal multiplexer with one line. The - simulation is complicated by the half-duplex nature of the card (there is - only one FIFO, used selectively either for transmission or reception) and the - double-buffered UART (a Western Digital TR1863A), which has holding registers - as well as a shift registers for transmission and reception. We model both - sets of device registers. + We support the 12966A connected to an HP terminal emulator via Telnet or a + serial port. Internally, we model the BACI as a terminal multiplexer with + one line. The simulation is complicated by the half-duplex nature of the + card (there is only one FIFO, used selectively either for transmission or + reception) and the double-buffered UART (a Western Digital TR1863A), which + has holding registers as well as a shift registers for transmission and + reception. We model both sets of device registers. During an output operation, the first character output to the card passes through the FIFO and into the transmitter holding register. Subsequent @@ -122,12 +123,12 @@ as an "optimized (fast) timing" option. Optimization makes three improvements: - 1. On output, characters in the FIFO are emptied into the Telnet buffer as a + 1. On output, characters in the FIFO are emptied into the line buffer as a block, rather than one character per service call, and on input, all of - the characters available in the Telnet buffer are loaded into the FIFO as - a block. + the characters available in the line buffer are loaded into the FIFO as a + block. - 2. The ENQ/ACK handshake is done locally, without involving the Telnet + 2. The ENQ/ACK handshake is done locally, without involving the terminal client. 3. Input occurring during an output operation is delayed until the second or @@ -318,7 +319,7 @@ /* Unit references */ #define baci_term baci_unit[0] /* terminal I/O unit */ -#define baci_poll baci_unit[1] /* Telnet polling unit */ +#define baci_poll baci_unit[1] /* line polling unit */ /* BACI state variables */ @@ -391,11 +392,11 @@ t_stat baci_detach (UNIT *uptr); baci_deb BACI debug list baci_dev BACI device descriptor - Two units are used: one to handle character I/O via the Telnet library, and - another to poll for connections and input. The character I/O service routine - runs only when there are characters to read or write. It operates at the - approximate baud rate of the terminal (in CPU instructions per second) in - order to be compatible with the OS drivers. The Telnet poll must run + Two units are used: one to handle character I/O via the multiplexer library, + and another to poll for connections and input. The character I/O service + routine runs only when there are characters to read or write. It operates at + the approximate baud rate of the terminal (in CPU instructions per second) in + order to be compatible with the OS drivers. The line poll must run continuously, but it can operate much more slowly, as the only requirement is that it must not present a perceptible lag to human input. To be compatible with CPU idling, it is co-scheduled with the master poll timer, which uses a @@ -404,14 +405,14 @@ t_stat baci_detach (UNIT *uptr); DEVICE baci_dev; -TMLN baci_ldsc = { 0 }; /* line descriptor */ -TMXR baci_desc = { 1, 0, 0, &baci_ldsc }; /* device descriptor */ +TMLN baci_ldsc = { 0 }; /* line descriptor */ +TMXR baci_desc = { 1, 0, 0, &baci_ldsc, NULL, &baci_dev }; /* device descriptor */ DIB baci_dib = { &baci_io, BACI, 0 }; UNIT baci_unit[] = { { UDATA (&baci_term_svc, UNIT_ATTABLE | UNIT_FASTTIME, 0) }, /* terminal I/O unit */ - { UDATA (&baci_poll_svc, UNIT_DIS, POLL_FIRST) } /* Telnet poll unit */ + { UDATA (&baci_poll_svc, UNIT_DIS, POLL_FIRST) } /* line poll unit */ }; REG baci_reg [] = { @@ -466,15 +467,15 @@ MTAB baci_mod[] = { { UNIT_CAPSLOCK, UNIT_CAPSLOCK, "CAPS LOCK down", "CAPSLOCK", NULL, NULL, NULL }, { UNIT_CAPSLOCK, 0, "CAPS LOCK up", "NOCAPSLOCK", NULL, NULL, NULL }, - { MTAB_XTD | MTAB_VDV | MTAB_NC, 0, "LOG", "LOG", &tmxr_set_log, &tmxr_show_log, &baci_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NC, 0, NULL, "NOLOG", &tmxr_set_nolog, NULL, &baci_desc }, + { MTAB_XDV | MTAB_NC, 0, "LOG", "LOG", &tmxr_set_log, &tmxr_show_log, &baci_desc }, + { MTAB_XDV | MTAB_NC, 0, NULL, "NOLOG", &tmxr_set_nolog, NULL, &baci_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTION", NULL, NULL, &tmxr_show_cstat, &baci_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, NULL, &tmxr_show_cstat, &baci_desc }, - { MTAB_XTD | MTAB_VDV, 0, NULL, "DISCONNECT", &tmxr_dscln, NULL, &baci_desc }, + { MTAB_XDV | MTAB_NMO, 1, "CONNECTION", NULL, NULL, &tmxr_show_cstat, &baci_desc }, + { MTAB_XDV | MTAB_NMO, 0, "STATISTICS", NULL, NULL, &tmxr_show_cstat, &baci_desc }, + { MTAB_XDV, 0, NULL, "DISCONNECT", &tmxr_dscln, NULL, &baci_desc }, - { MTAB_XTD | MTAB_VDV, 1u, "SC", "SC", &hp_set_dib, &hp_show_dib, (void *) &baci_dib }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, ~1u, "DEVNO", "DEVNO", &hp_set_dib, &hp_show_dib, (void *) &baci_dib }, + { MTAB_XDV, 1u, "SC", "SC", &hp_set_dib, &hp_show_dib, (void *) &baci_dib }, + { MTAB_XDV | MTAB_NMO, ~1u, "DEVNO", "DEVNO", &hp_set_dib, &hp_show_dib, (void *) &baci_dib }, { 0 } }; @@ -768,7 +769,7 @@ return stat_data; The terminal service routine is used to transmit and receive characters. In terminal mode, it is started when a character is ready for output or when - the Telnet poll routine determines that there are characters ready for input + the line poll routine determines that there are characters ready for input and stopped when there are no more characters to output or input. When the terminal is quiescent, this routine does not run. @@ -808,11 +809,11 @@ return stat_data; first character after an ENQ is not an ACK. Finally, fast timing enables buffer combining. For output, all characters - present in the FIFO are unloaded into the Telnet buffer before initiating a - packet send. For input, all characters present in the Telnet buffer are - loaded into the FIFO. This reduces network traffic and decreases simulator - overhead (there is only one service routine entry per block, rather than one - per character). + present in the FIFO are unloaded into the line buffer before initiating a + packet send. For input, all characters present in the line buffer are loaded + into the FIFO. This reduces network traffic and decreases simulator overhead + (there is only one service routine entry per block, rather than one per + character). In fast output mode, it is imperative that not less than 1500 instructions elapse between the first character load to the FIFO and the initiation of @@ -826,6 +827,46 @@ return stat_data; To avoid this, the OTx output character handler does an absolute schedule for the first character to ensure that a full character time is used. + + + Implementation notes: + + 1. The terminal multiplexer library "tmxr_putc_ln" routine returns + SCPE_STALL if it is called when the transmit buffer is full. When the + last character is added to the buffer, the routine returns SCPE_OK but + also changes the "xmte" field of the terminal multiplexer line (TMLN) + structure from 1 to 0 to indicate that further calls will be rejected. + The "xmte" value is set back to 1 when the tranmit buffer empties. + + This presents two approaches to handling buffer overflows: either call + "tmxr_putc_ln" unconditionally and test for SCPE_STALL on return, or call + "tmxr_putc_ln" only if "xmte" is 1. The former approach adds a new + character to the transmit buffer as soon as space is available, while the + latter adds a new character only when the buffer has completely emptied. + With either approach, transmission must be rescheduled after a delay to + allow the buffer to drain. + + It would seem that the former approach is more attractive, as it would + allow the simulated I/O operation to complete more quickly. However, + there are two mitigating factors. First, the library attempts to write + the entire transmit buffer in one host system call, so there is usually + no time difference between freeing one buffer character and freeing the + entire buffer (barring host system buffer congestion). Second, the + routine increments a "character dropped" counter when returning + SCPE_STALL status. However, the characters actually would not be lost, + as the SCPE_STALL return would schedule retransmission when buffer space + is available, . This would lead to erroneous reporting in the SHOW + STATISTICS command. + + Therefore, we adopt the latter approach and reschedule transmission if + the "xmte" field is 0. Note that the "tmxr_poll_tx" routine still must + be called in this case, as it is responsible for transmitting the buffer + contents and therefore freeing space in the buffer. + + 2. The "tmxr_putc_ln" library routine returns SCPE_LOST if the line is not + connected. We ignore this error so that an OS may output an + initialization "welcome" message even when the terminal is not connected. + This permits the simulation to continue while ignoring the output. */ t_stat baci_term_svc (UNIT *uptr) @@ -834,12 +875,16 @@ uint32 data_bits, data_mask; const t_bool fast_timing = (baci_term.flags & UNIT_FASTTIME) != 0; const t_bool is_attached = (baci_term.flags & UNIT_ATT) != 0; t_stat status = SCPE_OK; -t_bool xmit_loop = TRUE; t_bool recv_loop = TRUE; +t_bool xmit_loop = (baci_ldsc.xmte != 0); /* TRUE if the transmit buffer is not full */ /* Transmission */ +if (baci_ldsc.xmte == 0) /* if the transmit buffer is full */ + tprintf (baci_dev, DEB_XFER, "Transmission stalled for full buffer\n"); + + while (xmit_loop && (baci_uart_thr & IN_VALID)) { /* valid character in UART? */ data_bits = 5 + (baci_cfcw & OUT_CHARSIZE); /* calculate number of data bits */ data_mask = (1 << data_bits) - 1; /* generate mask for data bits */ @@ -864,6 +909,14 @@ while (xmit_loop && (baci_uart_thr & IN_VALID)) { /* valid character in UA if (status == SCPE_OK) /* transmitted OK? */ tprintf (baci_dev, DEB_XFER, "Character %s transmitted from the UART\n", fmt_char ((uint8) baci_uart_tr)); + + else { + tprintf (baci_dev, DEB_XFER, "Character %s transmission failed with status %d\n", + fmt_char ((uint8) baci_uart_tr), status); + + if (status == SCPE_LOST) /* if the line is not connected */ + status = SCPE_OK; /* then ignore the output */ + } } } @@ -879,11 +932,12 @@ while (xmit_loop && (baci_uart_thr & IN_VALID)) { /* valid character in UA else /* receive mode */ baci_uart_thr = CLEAR_HR; /* clear holding register */ - xmit_loop = fast_timing && !baci_enq_seen; /* loop if fast mode and char not ENQ */ + xmit_loop = (fast_timing && ! baci_enq_seen /* loop if fast mode and char not ENQ */ + && baci_ldsc.xmte != 0); /* and buffer space is available */ } - else - xmit_loop = FALSE; + else /* otherwise transmission failed */ + xmit_loop = FALSE; /* so drop out of the loop */ } @@ -971,12 +1025,11 @@ return status; } -/* BACI Telnet poll service. +/* BACI line poll service. - This service routine is used to poll for Telnet connections and incoming - characters. If characters are available, the terminal I/O service routine is - scheduled. It starts when the socket is attached and stops when the socket - is detached. + This service routine is used to poll for connections and incoming characters. + If characters are available, the terminal I/O service routine is scheduled. + It starts when the line is attached and stops when the line is detached. Implementation notes: @@ -1025,16 +1078,16 @@ baci_term.wait = service_time (baci_icw); /* set terminal I/O time if (baci_term.flags & UNIT_ATT) { /* device attached? */ baci_poll.wait = POLL_FIRST; /* set up poll */ - sim_activate (&baci_poll, baci_poll.wait); /* start Telnet poll immediately */ + sim_activate (&baci_poll, baci_poll.wait); /* start line poll immediately */ } else - sim_cancel (&baci_poll); /* else stop Telnet poll */ + sim_cancel (&baci_poll); /* else stop line poll */ return SCPE_OK; } -/* Attach controller */ +/* Attach line */ t_stat baci_attach (UNIT *uptr, CONST char *cptr) { @@ -1044,20 +1097,20 @@ status = tmxr_attach (&baci_desc, uptr, cptr); /* attach to socket */ if (status == SCPE_OK) { baci_poll.wait = POLL_FIRST; /* set up poll */ - sim_activate (&baci_poll, baci_poll.wait); /* start Telnet poll immediately */ + sim_activate (&baci_poll, baci_poll.wait); /* start line poll immediately */ } return status; } -/* Detach controller */ +/* Detach line */ t_stat baci_detach (UNIT *uptr) { t_stat status; baci_ldsc.rcve = 0; /* disable line reception */ -sim_cancel (&baci_poll); /* stop Telnet poll */ +sim_cancel (&baci_poll); /* stop line poll */ status = tmxr_detach (&baci_desc, uptr); /* detach socket */ return status; } @@ -1105,8 +1158,10 @@ baci_dsrw = 0; /* clear status referenc baci_cfcw = baci_cfcw & ~OUT_ECHO; /* clear echo flag */ baci_icw = baci_icw & OUT_BAUDRATE; /* clear interface control */ -if (baci_term.flags & UNIT_DIAG) /* diagnostic mode? */ +if (baci_term.flags & UNIT_DIAG) { /* diagnostic mode? */ baci_status = baci_status & ~IN_MODEM | IN_SPARE; /* clear loopback status, set BA */ + baci_ldsc.xmte = 1; /* enable transmitter */ + } return; } diff --git a/HP2100/hp2100_cpu.c b/HP2100/hp2100_cpu.c index eec1305a..fa758bb7 100644 --- a/HP2100/hp2100_cpu.c +++ b/HP2100/hp2100_cpu.c @@ -1,7 +1,7 @@ /* hp2100_cpu.c: HP 21xx/1000 Central Processing Unit/MEM/MP/DCPC simulator Copyright (c) 1993-2016, Robert M. Supnik - Copyright (c) 2017, J. David Bryan + Copyright (c) 2017-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,11 @@ DCPC1,DCPC2 12897B Dual Channel Port Controller MP 12581A/12892B Memory Protect + 21-May-18 JDB Changed "access" to "mem_access" to avoid clashing + 07-May-18 JDB Modified "io_dispatch" to display outbound signals + 01-May-18 JDB Multiple consecutive CLC 0 operations are now omitted + 02-Apr-18 JDB SET CPU 21MX now configures an M-Series model + 22-Feb-18 JDB Reworked "cpu_ibl" into "cpu_copy_loader" 11-Aug-17 JDB MEM must be disabled when DMS is disabled 01-Aug-17 JDB Changed SET/SHOW CPU [NO]IDLE to use sim_*_idle routines 22-Jul-17 JDB Renamed "intaddr" to CIR; added IR @@ -892,14 +897,6 @@ -/* External data */ - -extern DIB clk_dib; /* CLK DIB for idle check */ -extern DIB ptr_dib; /* PTR DIB for BBL configuration */ - -extern const BOOT_ROM ptr_rom, dq_rom, ms_rom, ds_rom; /* boot ROMs for cpu_boot routine */ - - /* CPU program constants */ @@ -961,6 +958,7 @@ REG *pcq_r = NULL; /* PC queue reg ptr */ uint32 cpu_configuration; /* the current CPU option set and model */ uint32 cpu_speed = 1; /* the CPU speed, expressed as a multiplier of a real machine */ +t_bool is_1000 = FALSE; /* TRUE if the CPU is a 1000 M/E/F-Series */ uint32 dev_prl [2] = { ~0u, ~0u }; /* device priority low bit vector */ uint32 dev_irq [2] = { 0u, 0u }; /* device interrupt request bit vector */ @@ -985,9 +983,13 @@ static HP_WORD saved_MR = 0; /* M-register value between SCP static uint32 fwanxm = 0; /* first word addr of nx mem */ static uint32 jsb_plb = 2; /* protected lower bound for JSB */ -static uint32 exec_mask = 0; /* the current instruction execution trace mask */ -static uint32 exec_match = D16_UMAX; /* the current instruction execution trace matching value */ -static uint32 indirect_limit = 16; /* the indirect chain length limit */ +static uint32 exec_mask = 0; /* the current instruction execution trace mask */ +static uint32 exec_match = D16_UMAX; /* the current instruction execution trace matching value */ +static uint32 indirect_limit = 16; /* the indirect chain length limit */ +static uint32 last_select_code = 0; /* the last select code sent over the I/O backplane */ + +static uint32 tbg_select_code = 0; /* the time-base generator select code (for RTE idle check) */ +static DEVICE *loader_rom [4] = { NULL }; /* the four boot loader ROM sockets in a 1000 CPU */ /* Memory Expansion Unit local state */ @@ -1013,30 +1015,6 @@ static t_bool defer_tab [] = { /* deferral table, indexed by I/ }; -/* Basic Binary Loader */ - -static const BOOT_ROM bbl = { - 0107700, 0063770, 0106501, 0004010, - 0002400, 0006020, 0063771, 0073736, - 0006401, 0067773, 0006006, 0027717, - 0107700, 0102077, 0027700, 0017762, - 0002003, 0027712, 0003104, 0073774, - 0017762, 0017753, 0070001, 0073775, - 0063775, 0043772, 0002040, 0027751, - 0017753, 0044000, 0000000, 0002101, - 0102000, 0037775, 0037774, 0027730, - 0017753, 0054000, 0027711, 0102011, - 0027700, 0102055, 0027700, 0000000, - 0017762, 0001727, 0073776, 0017762, - 0033776, 0127753, 0000000, 0103710, - 0102310, 0027764, 0102510, 0127762, - 0173775, 0153775, 0100100, 0177765, - 0000000, 0000000, 0000000, 0000000 - }; - -#define BBL_FWA 072 /* BBL location to store negative FWA */ - - /* CPU features table. The feature table is used to validate CPU feature changes within the subset @@ -1122,10 +1100,12 @@ static t_stat set_model (UNIT *uptr, int32 new_model, CONST char *cptr, void static t_stat set_option (UNIT *uptr, int32 option, CONST char *cptr, void *desc); static t_stat clear_option (UNIT *uptr, int32 option, CONST char *cptr, void *desc); static t_stat set_loader (UNIT *uptr, int32 enable, CONST char *cptr, void *desc); +static t_stat set_roms (UNIT *uptr, int32 option, CONST char *cptr, void *desc); static t_stat set_exec (UNIT *uptr, int32 option, CONST char *cptr, void *desc); static t_stat show_stops (FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat show_model (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +static t_stat show_roms (FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat show_exec (FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat show_speed (FILE *st, UNIT *uptr, int32 val, CONST void *desc); @@ -1269,14 +1249,15 @@ static MTAB cpu_mod [] = { { UNIT_MODEL_MASK, UNIT_2114, "", "2114", &set_model, &show_model, (void *) "2114" }, { UNIT_MODEL_MASK, UNIT_2100, "", "2100", &set_model, &show_model, (void *) "2100" }, { UNIT_MODEL_MASK, UNIT_1000_E, "", "1000-E", &set_model, &show_model, (void *) "1000-E" }, - { UNIT_MODEL_MASK, UNIT_1000_E, NULL, "21MX-E", &set_model, &show_model, (void *) "1000-E" }, { UNIT_MODEL_MASK, UNIT_1000_M, "", "1000-M", &set_model, &show_model, (void *) "1000-M" }, - { UNIT_MODEL_MASK, UNIT_1000_M, NULL, "21MX-M", &set_model, &show_model, (void *) "1000-M" }, #if defined (HAVE_INT64) { UNIT_MODEL_MASK, UNIT_1000_F, "", "1000-F", &set_model, &show_model, (void *) "1000-F" }, #endif + { UNIT_MODEL_MASK, UNIT_1000_M, NULL, "21MX-M", &set_model, &show_model, (void *) "1000-M" }, + { UNIT_MODEL_MASK, UNIT_1000_E, NULL, "21MX-E", &set_model, &show_model, (void *) "1000-E" }, + { UNIT_EAU, UNIT_EAU, "EAU", "EAU", &set_option, NULL, NULL }, { UNIT_EAU, 0, "no EAU", NULL, NULL, NULL, NULL }, { MTAB_XDV, UNIT_EAU, NULL, "NOEAU", &clear_option, NULL, NULL }, @@ -1345,6 +1326,8 @@ static MTAB cpu_mod [] = { { MTAB_XDV, 512 * 1024, NULL, "512K", &set_size, NULL, NULL }, { MTAB_XDV, 1024 * 1024, NULL, "1024K", &set_size, NULL, NULL }, + { MTAB_XDV | MTAB_NMO, 0, "ROMS", "ROMS", &set_roms, &show_roms, NULL }, + { MTAB_XDV | MTAB_NMO, 1, "STOPS", "STOP", &set_stops, &show_stops, NULL }, { MTAB_XDV, 0, NULL, "NOSTOP", &set_stops, NULL, NULL }, { MTAB_XDV | MTAB_NMO, 2, "INDIR", "INDIR", &set_stops, &show_stops, NULL }, @@ -1472,16 +1455,16 @@ typedef struct { const char *name; /* the classification name */ } ACCESS_PROPERTIES; -static const ACCESS_PROPERTIES access [] = { /* indexed by ACCESS_CLASS */ +static const ACCESS_PROPERTIES mem_access [] = { /* indexed by ACCESS_CLASS */ /* debug_flag name */ /* ------------ ------------------- */ - { TRACE_FETCH, "instruction fetch" }, /* instruction fetch */ - { TRACE_DATA, "data" }, /* data access */ - { TRACE_DATA, "data" }, /* data access, alternate map */ - { TRACE_DATA, "unprotected" }, /* data access, system map */ - { TRACE_DATA, "unprotected" }, /* data access, user map */ - { TRACE_DATA, "dma" }, /* DMA channel 1, port A map */ - { TRACE_DATA, "dma" } /* DMA channel 2, port B map */ + { TRACE_FETCH, "instruction fetch" }, /* instruction fetch */ + { TRACE_DATA, "data" }, /* data access */ + { TRACE_DATA, "data" }, /* data access, alternate map */ + { TRACE_DATA, "unprotected" }, /* data access, system map */ + { TRACE_DATA, "unprotected" }, /* data access, user map */ + { TRACE_DATA, "dma" }, /* DMA channel 1, port A map */ + { TRACE_DATA, "dma" } /* DMA channel 2, port B map */ }; @@ -1718,7 +1701,6 @@ t_bool mp_mem_changed; /* TRUE if the MP or MEM registe static FLIP_FLOP mp_flag = CLEAR; /* MP flag flip-flop */ static FLIP_FLOP mp_flagbuf = CLEAR; /* MP flag buffer flip-flop */ static FLIP_FLOP mp_evrff = SET; /* enable violation register flip-flop */ -static t_bool is_1000 = FALSE; /* TRUE if the CPU is a 1000 M/E/F-Series */ static char meu_indicator; /* last map access indicator (S | U | A | B | -) */ static uint32 meu_page; /* last physical page number accessed */ @@ -1820,24 +1802,31 @@ static const BITSET_NAME inbound_names [] = { /* Inbound signal names, in IOSI "ENF", /* 000000000002 */ "IOI", /* 000000000004 */ "IOO", /* 000000000010 */ - "SKF", /* 000000000020 */ - "SFS", /* 000000000040 */ - "SFC", /* 000000000100 */ - "STC", /* 000000000200 */ - "CLC", /* 000000000400 */ - "STF", /* 000000001000 */ - "CLF", /* 000000002000 */ - "EDT", /* 000000004000 */ - "CRS", /* 000000010000 */ - "POPIO", /* 000000020000 */ - "IAK", /* 000000040000 */ - "SIR" /* 000000100000 */ + "SFS", /* 000000000020 */ + "SFC", /* 000000000040 */ + "STC", /* 000000000100 */ + "CLC", /* 000000000200 */ + "STF", /* 000000000400 */ + "CLF", /* 000000001000 */ + "EDT", /* 000000002000 */ + "CRS", /* 000000004000 */ + "POPIO", /* 000000010000 */ + "IAK", /* 000000020000 */ + "SIR" /* 000000040000 */ }; static const BITSET_FORMAT inbound_format = /* names, offset, direction, alternates, bar */ { FMT_INIT (inbound_names, 0, lsb_first, no_alt, no_bar) }; +static const BITSET_NAME outbound_names [] = { /* Outbound signal names, in IOSIGNAL order */ + "SKF" /* 000000200000 */ + }; + +static const BITSET_FORMAT outbound_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (outbound_names, 16, lsb_first, no_alt, no_bar) }; + + /* I/O instruction sub-opcodes */ #define soHLT 0 /* halt */ @@ -1890,9 +1879,10 @@ static uint32 io_dispatch (uint32 select_code, IOCYCLE signal_set, HP_WORD dat execution. This involves verifying that there are no device conflicts (e.g., two devices with the same select code) and initializing the I/O state. These actions accommodate reconfiguration of the I/O device settings and program - counter while the simulator was stopped. The prelude also responds to one - command-line switch: if "-B" is specified, the current set of simulation stop - conditions is bypassed for the first instruction executed. + counter while the simulator was stopped. The prelude also picks up the + time-base generator's select code for use in idle testing, and it checks for + one command-line switch: if "-B" is specified, the current set of simulation + stop conditions is bypassed for the first instruction executed. Second, the memory protect abort mechanism is set up. MP aborts utilize the "setjmp/longjmp" mechanism to transfer control out of the instruction @@ -2139,6 +2129,7 @@ static const char *const mp_mem_formats [] = { /* MP/MEM regist static uint32 exec_save; /* the trace flag settings saved by an EXEC match */ static uint32 idle_save; /* the trace flag settings saved by an idle match */ +DEVICE *tbg_dptr; int abortval; uint32 intrq, dmarq; /* set after setjmp */ t_bool exec_test; /* set after setjmp */ @@ -2158,6 +2149,13 @@ sim_switches &= ~SWMASK ('P'); /* clear the power-on sw if (hp_device_conflict ()) /* if device assignment is inconsistent */ return SCPE_STOP; /* then inhibit execution */ +tbg_dptr = find_dev ("CLK"); /* get a pointer to the time-base generator device */ + +if (tbg_dptr == NULL) /* if the TBG device is not present */ + return SCPE_IERR; /* then something is seriously wrong */ +else /* otherwise */ + tbg_select_code = ((DIB *) tbg_dptr->ctxt)->select_code; /* get the select code from the device's DIB */ + io_initialize (); /* set up the I/O data structures */ cpu_ioerr_uptr = NULL; /* and clear the I/O error unit pointer */ @@ -2450,26 +2448,56 @@ return; /* CPU global utility routines */ -/* Install an initial binary loader into memory. +/* Install a bootstrap loader into memory. - This routine copies the initial binary loader contained in "rom" to the last - 64 words of main memory, limited by a 32K memory size. If "dev" contains a + This routine copies the bootstrap loader specified by "boot" into the last 64 + words of main memory, limited by a 32K memory size. If "sc" contains the select code of an I/O interface (i.e., select code 10 or above), this routine - will configure the I/O instructions in the IBL to the supplied select code. - On exit, P will be set to point at the first word of the loader, and S will - be altered as directed by the "sr_clear" and "sr_set" masks. + will configure the I/O instructions in the loader to the supplied select + code. On exit, P will be set to point at the loader starting program + address, and S will be altered as directed by the "sr_clear" and "sr_set" + masks if the current CPU is a 1000. - If I/O configuration is requested, each instruction in the IBL is examined as - it is copied to memory. If the instruction is a non-HLT I/O instruction - referencing a select code >= 10, the select code will be reset by subtracting - 10 and adding the value of the select code supplied in the "dev" parameter. - This permits configuration of IBLs that address two- or three-card - interfaces. Passing a "dev" value of 0 will inhibit configuration. + The currently configured CPU family (21xx or 1000) determines which of two + BOOT_LOADER structures is accessed from the "boot" array. Each structure + contains the 64-word loader array and three indicies into the loader + array that specify the start of program execution, the element containing the + DMA control word, and the element containing the (negative) address of the + first loader word in memory. - As an example, passing a "dev" value of 24 octal will alter these + 21xx-series loaders consist of subsections handling one or two devices. A + two-part loader is indicated by a starting program index other than 0, i.e., + other than the beginning of the loader. An example is the Basic Moving-Head + Disc Loader (BMDL), which consists of a paper tape loader section starting at + index 0 and a disc loader section starting at index 50 octal. For these + loaders, I/O configuration depends on the "start_index" field of the selected + BOOTSTRAP structure: I/O instructions before the starting index are + configured to the current paper-tape reader select code, and instructions at + or after the starting index are configured to the device select code + specified by "sc". Single-part loaders specify a starting index of 0, and + all I/O instructions are configured to the "sc" select code. + + 1000-series loaders are always single part and always start at index 0, so + they are always configured to use the "sc" select code. + + If a given device does not have both a 21xx-series and a 1000-series loader, + the "start_index" field of the undefined loader will be set to the "IBL_NA" + value. If this routine is called to copy an undefined loader, it will reject + the call with a "Command not allowed" error. + + If I/O configuration is requested, each instruction in the loader array is + examined as it is copied to memory. If the instruction is a non-HLT I/O + instruction referencing a select code >= 10, the select code will be reset by + subtracting 10 and adding the value of the select code supplied by the "sc" + parameter (or the paper-tape reader select code, as above). This permits + configuration of loaders that address two- or three-card interfaces. Passing + an "sc" value of 0 will inhibit configuration, and the loader array will be + copied verbatim. + + As an example, passing an "sc" value of 24 octal will alter these I/O-group instructions as follows: - IBL Configured + Loader Configured Instruction Instruction Note ----------- ----------- ------------------------------ OTA 10 OTA 24 Normal configuration @@ -2477,46 +2505,92 @@ return; STC 6 STC 6 DCPC configuration not changed HLT 11 HLT 11 Halt instruction not changed - If configuration is performed, the routine will also alter the next-to-last - word unconditionally as above. This word is assumed to contain a DCPC - control word; it is configured to reference the supplied select code. + If configuration is performed, two additional operations may be performed. + First, the routine will alter the word at the index specified by the + "dma_index" field of the selected BOOTSTRAP structure unconditionally as + above. This word is assumed to contain a DMA control word; it is configured + to reference the supplied select code. Second, it will set the word at the + index specified by the "fwa_index" field to the two's-complement of the + starting address of the loader in memory. This value may be used by the + loader to check that it will not be overwritten by loaded data. - Finally, the routine sets the last word to the two's-complement of the - starting address of the IBL. This value may be used by the loader to check - that it will not be overwritten by loaded data. + If either field is set to the IBL_NA value, then the corresponding + modification is not made. For example, the 21xx Basic Binary Loader (BBL) + does not use DMA, so its "dma_index" field is set to IBL_NA, and so no DMA + control word modification is done. + + This routine also unconditionally sets the P register to the starting + address for loader execution. This is derived from the "start_index" field + and the starting memory address to which the loader is copied. + + Finally, if the current CPU is a 1000-series machine, the S register bits + corresponding to those set in the "sr_clear" value are masked off, and the + bits corresponding to those in the "sr_set" value are set. In addition, the + select code from the "sc" value is shifted left and ORed into the value. + This action presets the S-register to the correct value for the selected + loader. + + + Implementation notes: + + 1. The paper-tape reader's select code is determined on each entry to the + routine to accommodate select code reassignment by the user. */ -void cpu_ibl (const BOOT_ROM rom, int32 dev, HP_WORD sr_clear, HP_WORD sr_set) +t_stat cpu_copy_loader (const LOADER_ARRAY boot, uint32 sc, HP_WORD sr_clear, HP_WORD sr_set) { -int32 i; -MEMORY_WORD wd; +uint32 index, base, ptr_sc; +MEMORY_WORD word; +DEVICE *ptr_dptr; -set_loader (NULL, TRUE, NULL, NULL); /* enable loader (ignore errors) */ +if (boot [is_1000].start_index == IBL_NA) /* if the bootstrap is not defined for the current CPU */ + return SCPE_NOFNC; /* then reject the command */ -PR = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */ - -for (i = 0; i < IBL_LNT; i++) { /* copy bootstrap */ - wd = rom [i]; /* get word */ - - if (dev >= VARDEV /* if reconfiguration is desired */ - && (wd & I_NMRMASK) == I_IO /* and this is an I/O instruction */ - && (wd & I_DEVMASK) >= VARDEV /* and the referenced select code is >= 10B */ - && I_GETIOOP (wd) != soHLT) /* and it's not a halt instruction */ - M [PR + i] = (wd + (dev - VARDEV)) & DMASK; /* then reconfigure the select code */ +else if (boot [is_1000].start_index > 0 && sc > 0) { /* if this is a two-part loader with I/O reconfiguration */ + ptr_dptr = find_dev ("PTR"); /* then get a pointer to the paper tape reader device */ + if (ptr_dptr == NULL) /* if the PTR device is not present */ + return SCPE_IERR; /* then something is seriously wrong */ else /* otherwise */ - M [PR + i] = wd; /* copy the instruction verbatim */ + ptr_sc = ((DIB *) ptr_dptr->ctxt)->select_code; /* get the select code from the device's DIB */ } -if (dev >= VARDEV) /* if reconfiguration was performed */ - M [PR + IBL_DPC] = M [PR + IBL_DPC] + dev - VARDEV /* then patch the DMA control word */ - & DMASK; +else /* otherwise this is a single-part loader */ + ptr_sc = 0; /* or I/O reconfiguration is not requested */ -M [PR + IBL_END] = (~PR + 1) & DMASK; /* fill in start of boot */ +base = MEMSIZE - 1 & ~IBL_MASK & LA_MASK; /* get the base memory address of the loader */ +PR = base + boot [is_1000].start_index & R_MASK; /* and store the starting program address in P */ -SR = (SR & sr_clear) | sr_set; /* modify the S register as indicated */ +set_loader (NULL, TRUE, NULL, NULL); /* enable the loader (ignore errors if not 21xx) */ -return; +for (index = 0; index < IBL_SIZE; index++) { /* copy the bootstrap loader to memory */ + word = boot [is_1000].loader [index]; /* get the next word */ + + if (sc == 0) /* if reconfiguration is not requested */ + M [base + index] = word; /* then copy the instruction verbatim */ + + else if ((word & I_NMRMASK) == I_IO /* otherwise if this is an I/O instruction */ + && (word & I_DEVMASK) >= VARDEV /* and the referenced select code is >= 10B */ + && I_GETIOOP (word) != soHLT) /* and it's not a halt instruction */ + if (index < boot [is_1000].start_index) /* then if this is a split loader */ + M [base + index] = word + (ptr_sc - VARDEV) & DV_MASK; /* then reconfigure the paper tape reader */ + else /* otherwise */ + M [base + index] = word + (sc - VARDEV) & DV_MASK; /* reconfigure the target device */ + + else if (index == boot [is_1000].dma_index) /* otherwise if this is the DMA configuration word */ + M [base + index] = word + (sc - VARDEV) & DV_MASK; /* then reconfigure the target device */ + + else if (index == boot [is_1000].fwa_index) /* otherwise if this is the starting address word */ + M [base + index] = NEG16 (base); /* then set the negative starting address of the bootstrap */ + + else /* otherwise the word is not a special one */ + M [base + index] = word; /* so simply copy it */ + } + +if (is_1000) /* if the CPU is a 1000 */ + SR = SR & sr_clear | sr_set | IBL_TO_SC (sc); /* then modify the S register as indicated */ + +return SCPE_OK; /* return success with the loader copied to memory */ } @@ -2561,6 +2635,10 @@ return; do this in preference to calling the recalculation routines directly, as some extended firmware instructions call this routine multiple times, and there is no point in recalculating until all calls are complete. + + 6. The I/O dispatcher returns NOTE_SKIP if the interface asserted the SKF + signal. We must recalculate interrupts if the originating SFS or SFC + instruction included the CLF signal (e.g., SFS 0,C). */ t_stat cpu_iog (HP_WORD IR, t_bool iotrap) @@ -2605,12 +2683,13 @@ ioreturn = io_dispatch (dev, signal_set, iodata); /* dispatch the I/O sign iostat = IOSTATUS (ioreturn); /* extract status */ iodata = IODATA (ioreturn); /* extract return data value */ -if (iostat == SCPE_OK) { /* if instruction execution succeeded */ - if ((sop == soSFC || sop == soSFS) /* then if it is an SFC or SFS */ - && (IOSIGNAL) iodata == ioSKF) /* and SKF is asserted */ - PR = PR + 1 & LA_MASK; /* then bump P to skip then next instruction */ +if (iostat == NOTE_SKIP) { /* if the interface asserted SKF */ + PR = PR + 1 & LA_MASK; /* then bump P to skip then next instruction */ + return (IR & I_HC ? NOTE_IOG : SCPE_OK); /* and request recalculation of interrupts if needed */ + } - else if (sop == soLIX) /* otherwise if is it an LIA or LIB */ +else if (iostat == SCPE_OK) { /* otherwise if instruction execution succeeded */ + if (sop == soLIX) /* then if is it an LIA or LIB */ ABREG [ab] = iodata; /* then load the returned data */ else if (sop == soMIX) /* otherwise if it is an MIA or MIB */ @@ -2926,11 +3005,11 @@ if (index <= 1 && map < PAMAP) /* if the A/B register i else /* otherwise */ TR = (HP_WORD) M [index]; /* return the physical memory value */ -tpprintf (dptr, access [classification].debug_flag, +tpprintf (dptr, mem_access [classification].debug_flag, DMS_FORMAT " %s%s\n", meu_indicator, meu_page, MR, TR, - access [classification].name, - access [classification].debug_flag == TRACE_FETCH ? "" : " read"); + mem_access [classification].name, + mem_access [classification].debug_flag == TRACE_FETCH ? "" : " read"); return TR; } @@ -3056,10 +3135,10 @@ else if (index < fwanxm) /* otherwise if the loca TR = value; /* save the value */ -tpprintf (dptr, access [classification].debug_flag, +tpprintf (dptr, mem_access [classification].debug_flag, DMS_FORMAT " %s write\n", meu_indicator, meu_page, MR, TR, - access [classification].name); + mem_access [classification].name); return; } @@ -3393,11 +3472,22 @@ return; interrupt system and turn it off." 4. Select code 0 cannot interrupt, so there is no SIR handler. + + 5. To guarantee proper initialization, the 12920A terminal multiplexer + requires that the Control Reset (CRS) I/O signal be asserted for a + minimum of 100 milliseconds. In practice, this is achieved by executing + 131,072 (128K) CLC 0 instructions in a tight loop. This is not necessary + in simulation, and in fact is detrimental, as 262,000+ trace lines will + be written for each device that enables IOBUS tracing. To avoid this, + consecutive CLC 0 operations after the first are omitted. This is + detected by checking the select code and signal set of the last I/O + operation. */ static uint32 cpuio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) { -uint32 sc; +static IOCYCLE last_signal_set = ioNONE; /* the last set of I/O signals processed */ +uint32 sc; IOSIGNAL signal; IOCYCLE working_set = signal_set; /* no SIR handler needed */ @@ -3459,8 +3549,11 @@ while (working_set) { break; case ioCLC: /* clear control flip-flop */ - for (sc = CRSDEV; sc <= MAXDEV; sc++) /* send CRS to devices */ - io_dispatch (sc, ioCRS, 0); /* from select code 6 and up */ + if (last_select_code != 0 /* if the last I/O instruction */ + || (last_signal_set & ioCLC) == 0) /* was not a CLC 0 */ + for (sc = CRSDEV; sc <= MAXDEV; sc++) /* then assert the CRS signal */ + if (devs [sc] != NULL) /* to all occupied I/O slots */ + io_dispatch (sc, ioCRS, 0); /* from select code 6 and up */ break; default: /* all other signals */ @@ -3470,6 +3563,8 @@ while (working_set) { working_set = working_set & ~signal; /* remove current signal from set */ } +last_signal_set = signal_set; /* save the current signal set for the next call */ + return stat_data; } @@ -3682,11 +3777,10 @@ return SCPE_OK; /* return success status If this is the first call after simulator startup, the initial memory array is allocated, the default CPU and memory size configuration is set, and the SCP-required program counter pointer is set to point to the REG array element - corresponding to the P register. - - If this is a power-on reset ("RESET -P"), the default Basic Binary Loader is - installed in protected memory (the upper 64 words of the defined memory - size). + corresponding to the P register. In addition, the loader ROM sockets of the + 1000-series CPUs are populated with the initial ROM set, and the Basic Binary + Loader (BBL) is installed in protected memory (the upper 64 words of the + defined memory size). Implementation notes: @@ -3695,30 +3789,33 @@ return SCPE_OK; /* return success status order automatically. A fixed setting runs the risk of it not being updated if a change in the register order is made. - 2. A power-on reset installs the BBL in 21xx machines. The IBL copy routine - sets the last loader word to the two's complement of the loader starting - address and configures the second-to-last word (nominally the DMA control - word) to the I/O select code. For the BBL, the starting address location - is five locations back, and the DMA control word is not used, so these - fixups are performed after copying. + 2. The initial set of installed HP 1000 boot loader ROMs is: + + Socket ROM Boot Device + ------ ------ ------------------------ + 0 12992K 2748 Paper Tape Reader + 1 12992A 7900 or 2883 Disc Drive + 2 12992D 7970 Magnetic Tape Drive + 3 12992B 7905/06/20/25 Disc Drive */ static t_stat cpu_reset (DEVICE *dptr) { -if (M == NULL) { /* initial call after startup? */ - pcq_r = find_reg ("PCQ", NULL, dptr); /* get PC queue pointer */ +if (M == NULL) { /* if this is the initial call after simulator startup */ + pcq_r = find_reg ("PCQ", NULL, dptr); /* then get the PC queue pointer */ - if (pcq_r) /* defined? */ - pcq_r->qptr = 0; /* initialize queue */ - else /* not defined */ - return SCPE_IERR; /* internal error */ + if (pcq_r == NULL) /* if the PCQ register is not present */ + return SCPE_IERR; /* then something is seriously wrong */ + else /* otherwise */ + pcq_r->qptr = 0; /* initialize the register's queue pointer */ - M = (MEMORY_WORD *) calloc (PASIZE, sizeof (MEMORY_WORD)); /* alloc mem */ + M = (MEMORY_WORD *) calloc (PASIZE, /* allocate and zero the main memory array */ + sizeof (MEMORY_WORD)); /* to the maximum configurable size */ - if (M == NULL) /* alloc fail? */ - return SCPE_MEM; + if (M == NULL) /* if the allocation failed */ + return SCPE_MEM; /* then report a "Memory exhausted" error */ - else { /* do one-time init */ + else { /* otherwise perform one-time initialization */ for (sim_PC = dptr->registers; /* find the P register entry */ sim_PC->loc != &PR && sim_PC->loc != NULL; /* in the register array */ sim_PC++); /* for the SCP interface */ @@ -3728,27 +3825,22 @@ if (M == NULL) { /* initial call after st MEMSIZE = 32768; /* set the initial memory size */ set_model (NULL, UNIT_2116, NULL, NULL); /* and the initial CPU model */ + + loader_rom [0] = find_dev ("PTR"); /* install the 12992K ROM in socket 0 */ + loader_rom [1] = find_dev ("DQC"); /* and the 12992A ROM in socket 1 */ + loader_rom [2] = find_dev ("MSC"); /* and the 12992D ROM in socket 2 */ + loader_rom [3] = find_dev ("DS"); /* and the 12992B ROM in socket 3 */ + + loader_rom [0]->boot (0, loader_rom [0]); /* install the BBL via the paper tape reader boot routine */ + set_loader (NULL, FALSE, NULL, NULL); /* and then disable the loader, which was enabled */ } } -if (sim_switches & SWMASK ('P')) { /* if this is a power-on reset */ - if (! is_1000) { /* then if the CPU is configured as a 21xx machine */ - cpu_ibl (bbl, ptr_dib.select_code, /* then install the BBL and configure it */ - IBL_S_NOCLR, IBL_S_NOSET); /* to the paper tape reader's select code */ - - M [PR + BBL_FWA] = M [PR + IBL_END]; /* move the BBL starting address to correct location */ - M [PR + IBL_DPC] = bbl [IBL_DPC]; /* and restore the last two words of the BBL */ - M [PR + IBL_END] = bbl [IBL_END]; /* that are overwritten by the 1000 IBL */ - - set_loader (NULL, FALSE, NULL, NULL); /* disable the loader, which was enabled by cpu_ibl */ - } - - IOPOWERON (&cpu_dib); /* issue the PON signal to the CPU */ - } - -else /* PRESET */ - IOPRESET (&cpu_dib); +if (sim_switches & SWMASK ('P')) /* if this is a power-on reset */ + IOPOWERON (&cpu_dib); /* then issue the PON signal to the CPU */ +else /* otherwise */ + IOPRESET (&cpu_dib); /* issue a PRESET */ sim_brk_dflt = SWMASK ('N'); /* the default breakpoint type is "nomap" as MEM is disabled */ @@ -3756,36 +3848,68 @@ return SCPE_OK; } -/* IBL routine (CPU boot) */ +/* Device boot routine. + + This routine is called by the BOOT CPU and LOAD CPU commands to copy the + specified boot loader ROM program into the upper 64 words of the logical + address space. It is equivalent to pressing the IBL (Initial Binary Loader) + button on the front panel of a 1000 M/E/F-Series CPU. + + On entry, the S register must be set to indicate the specific boot loader ROM + and the associated device select code to be copied, as follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | - - | select code | - - - - - - | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Bits 15-14 select one of four loader ROM sockets on the CPU board that may + contain ROMs. If the specified socket does, the contents of the ROM are + copied into the upper 64 words of memory and configured to use the specified + select code. The unspecified bits of the S register are available for use by + the bootstrap program. + + If the select code is less than 10 octal, the loader is not copied, and the + O (overflow) register is set to 1. A successful copy and configuration + clears the O register. + + The 21xx-series CPUs do not provide the IBL function. If this routine is + invoked while the CPU is configured as one of these machines, the command is + rejected. + + + Implementation notes: + + 1. In hardware, a non-existent ROM (i.e., an empty socket) reads as though + all words contain 177777 octal. This would result in the loader area of + memory containing 62 all-ones words, followed by a word set to 177777 + + SC - 000010, where SC is the configured select code, followed by a word + set to the negative starting address of the loader. This is not + simulated; instead, an attempt to boot from an empty socket is rejected + with "Command not allowed." +*/ static t_stat cpu_boot (int32 unitno, DEVICE *dptr) { -int32 dev = (SR >> IBL_V_DEV) & I_DEVMASK; -int32 sel = (SR >> IBL_V_SEL) & IBL_M_SEL; +const int32 select_code = IBL_SC (SR); /* the select code from S register bits 11-6 */ +const int32 rom_socket = IBL_ROM (SR); /* the ROM socket number from S register bits 15-14 */ -if (dev < 010) - return SCPE_NOFNC; - -switch (sel) { - - case 0: /* PTR boot */ - cpu_ibl (ptr_rom, dev, IBL_S_NOCLR, IBL_S_NOSET); - break; - - case 1: /* DP/DQ boot */ - cpu_ibl (dq_rom, dev, IBL_S_NOCLR, IBL_S_NOSET); - break; - - case 2: /* MS boot */ - cpu_ibl (ms_rom, dev, IBL_S_NOCLR, IBL_S_NOSET); - break; - - case 3: /* DS boot */ - cpu_ibl (ds_rom, dev, IBL_S_NOCLR, IBL_S_NOSET); - break; +if (is_1000) /* if this is a 1000-series CPU */ + if (select_code < VARDEV) { /* then if the select code is invalid */ + O = 1; /* then set the overflow register */ + return SCPE_ARG; /* and reject the IBL with "Invalid argument" */ } -return SCPE_OK; + else if (loader_rom [rom_socket] == NULL) /* otherwise if the ROM socket is empty */ + return SCPE_NXDEV; /* then reject with "Non-existent device" */ + + else { /* otherwise */ + O = 0; /* clear overflow to indicate a good IBL */ + return loader_rom [rom_socket]->boot (select_code, NULL); /* and copy the ROM into memory */ + } + +else /* otherwise this is a 21xx machine */ + return SCPE_NOFNC; /* and IBL isn't supported */ } @@ -3930,7 +4054,7 @@ if (is_1000) /* loader unsupported */ else { /* 21xx CPU? */ set_loader (uptr, FALSE, NULL, NULL); /* save loader to shadow RAM */ MEMSIZE = new_size; /* set new memory size */ - fwanxm = (uint32) MEMSIZE - IBL_LNT; /* reserve memory for loader */ + fwanxm = (uint32) MEMSIZE - IBL_SIZE; /* reserve memory for loader */ } for (i = fwanxm; i < old_size; i++) /* zero non-existent memory */ @@ -4052,7 +4176,7 @@ if (result == SCPE_OK) { /* if the ch if (is_1000) fwanxm = (uint32) MEMSIZE; /* loader reserved only for 21xx */ else /* 2100 or 211x */ - fwanxm = (uint32) MEMSIZE - IBL_LNT; /* reserve memory for loader */ + fwanxm = (uint32) MEMSIZE - IBL_SIZE; /* reserve memory for loader */ } return result; @@ -4188,23 +4312,23 @@ return SCPE_OK; static t_stat set_loader (UNIT *uptr, int32 enable, CONST char *cptr, void *desc) { -static BOOT_ROM loader; -int32 i; +static MEMORY_WORD loader [IBL_SIZE]; +uint32 i; t_bool is_enabled = (fwanxm == MEMSIZE); if (is_1000 || MEMSIZE == 0) /* valid only for 21xx and for initialized memory */ return SCPE_NOFNC; if (is_enabled && (enable == 0)) { /* disable loader? */ - fwanxm = (uint32) MEMSIZE - IBL_LNT; /* decrease available memory */ - for (i = 0; i < IBL_LNT; i++) { /* copy loader */ + fwanxm = (uint32) MEMSIZE - IBL_SIZE; /* decrease available memory */ + for (i = 0; i < IBL_SIZE; i++) { /* copy loader */ loader [i] = M [fwanxm + i]; /* from memory */ M [fwanxm + i] = 0; /* and zero location */ } } else if ((!is_enabled) && (enable == 1)) { /* enable loader? */ - for (i = 0; i < IBL_LNT; i++) /* copy loader */ + for (i = 0; i < IBL_SIZE; i++) /* copy loader */ M [fwanxm + i] = loader [i]; /* to memory */ fwanxm = (uint32) MEMSIZE; /* increase available memory */ } @@ -4213,6 +4337,100 @@ return SCPE_OK; } +/* Change the set of installed loader ROMs. + + This validation routine is called to install loader ROMs in the four + available sockets of a 1000-series CPU. The routine processes commands of + the form: + + SET CPU ROMS=[][;[][;[][;[]]]] + + On entry, "cptr" points at the the first character of the ROM list. The + option value and the unit and description pointers are not used. + + All four ROM sockets are set for each command. If no devices are specified, + then all sockets are emptied. Otherwise, specifying a valid device name + installs the device loader ROM into the socket corresponding to the position + of the device name in the list. Sockets may be left empty by omitting the + corresponding device name or by supplying fewer than four device names. + + Loader ROMs may only be altered if the current CPU model is a 1000-series + machine, and a device must be bootable and have a loader ROM assigned, or the + command will be rejected. A rejected command does not alter any of the ROM + assignments. + + Example commands and their effects on the installed ROM sockets follow: + + Command Action + --------------------- ------------------------------------------------- + SET CPU ROMS= Remove ROMs from sockets 0-3 + SET CPU ROMS=PTR Install PTR in 0; leave 1-3 empty + SET CPU ROMS=DS;MS Install DS in 0 and MS in 1; leave 2 and 3 empty + SET CPU ROMS=;;DPC Install DPC in 2; leave 0, 1, and 3 empty + SET CPU ROMS=DQC;;;DA Install DQC in 0 and DA in 3; leave 1 and 2 empty + + + Implementation notes: + + 1. Entering "SET CPU ROMS" without an equals sign or list is rejected with a + "Missing value" error. This is to prevent accidental socket clearing + when "SHOW CPU ROMS" was intended. +*/ + +static t_stat set_roms (UNIT *uptr, int32 option, CONST char *cptr, void *desc) +{ +DEVICE *dptr; +char gbuf [CBUFSIZE]; +uint32 socket = 0; +DEVICE *rom [4] = { NULL }; + +if (is_1000 == FALSE) /* if the CPU is not a 1000-series unit */ + return SCPE_NOFNC; /* then reject the command */ + +else if (cptr == NULL) /* otherwise if the list is not specified */ + return SCPE_MISVAL; /* then report that the list is missing */ + +else if (*cptr == '\0') { /* otherwise if the list is null */ + loader_rom [0] = NULL; /* then empty */ + loader_rom [1] = NULL; /* all of the */ + loader_rom [2] = NULL; /* ROM sockets */ + loader_rom [3] = NULL; + } + +else { /* otherwise */ + while (*cptr) { /* loop through the arguments */ + cptr = get_glyph (cptr, gbuf, ';'); /* get the next argument */ + + if (socket == 4) /* if all four sockets have been set */ + return SCPE_2MARG; /* then reject the command */ + + else if (gbuf [0] == '\0') /* otherwise if the device name is omitted */ + rom [socket++] = NULL; /* then empty the corresponding socket */ + + else { /* otherwise we have a device name */ + dptr = find_dev (gbuf); /* so find the associated DEVICE pointer */ + + if (dptr == NULL) /* if the device name is not valid */ + return SCPE_NXDEV; /* then reject the command */ + + else if (dptr->boot == NULL) /* otherwise if it's valid but not bootable */ + return SCPE_NOFNC; /* then reject the command */ + + else /* otherwise */ + rom [socket++] = dptr; /* install the boot loader ROM */ + } + } + + loader_rom [0] = rom [0]; /* install the ROM set */ + loader_rom [1] = rom [1]; /* now that we have */ + loader_rom [2] = rom [2]; /* a valid */ + loader_rom [3] = rom [3]; /* device list */ + } + +return SCPE_OK; /* report that the command succeeded */ +} + + /* Change the instruction execution trace criteria. This validation routine is called to configure the criteria that select @@ -4363,6 +4581,75 @@ return SCPE_OK; } +/* Show the set of installed loader ROMs. + + This display routine is called to show the set of installed loader ROMs in + the four available sockets of a 1000-series CPU. On entry, the "st" + parameter is the open output stream. The other parameters are not used. + + The routine prints a table of ROMs in this format: + + Socket Device ROM + ------ ------- ------ + 0 PTR 12992K + 1 DQC 12992A + 2 DS 12992B + 3 + + If a given socket contains a ROM, the associated device name and HP part + number for the loader ROM are printed. + + This routine services an extended modifier entry, so it must add the trailing + newline to the output before returning. +*/ + +static t_stat show_roms (FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ +struct LOOKUP_TABLE { + char *name; /* device name */ + char suffix; /* ROM part number suffix */ + }; + +static const struct LOOKUP_TABLE lookup [] = { /* table of device names and ROM part numbers */ + { "DQC", 'A' }, /* 12992A 7900/7901/2883 Disc Loader */ + { "DS", 'B' }, /* 12992B 7905/7906/7920/7925 Disc Loader */ + { "MSC", 'D' }, /* 12992D 7970 Magnetic Tape Loader */ + { "DPC", 'F' }, /* 12992F 7900/7901 Disc Loader */ + { "DA", 'H' }, /* 12992H 7906H/7920H/7925H/9885 Disc Loader */ + { "IPLI", 'K' }, /* 12992K Paper Tape Loader */ + { "PTR", 'K' }, /* 12992K Paper Tape Loader */ + { NULL, '?' } + }; + +CONST char *dname; +uint32 socket, index; +char letter = '?'; + +fputc ('\n', st); /* skip a line */ +fputs ("Socket Device ROM\n", st); /* and print */ +fputs ("------ ------- ------\n", st); /* the table header */ + +for (socket = 0; socket < 4; socket++) /* loop through the sockets */ + if (loader_rom [socket] == NULL) /* if the socket is empty */ + fprintf (st, " %u \n", socket); /* then report it as such */ + + else { /* otherwise the socket is occupied */ + dname = loader_rom [socket]->name; /* so get the device name */ + + for (index = 0; lookup [index].name; index++) /* search the lookup table */ + if (strcmp (lookup [index].name, dname) == 0) { /* for a match to the device name */ + letter = lookup [index].suffix; /* and get the part number suffix */ + break; + } + + fprintf (st, " %u %-4s 12992%c\n", /* print the ROM information */ + socket, dname, letter); + } + +return SCPE_OK; /* return success status */ +} + + /* Show the instruction execution trace criteria. This display routine is called to show the criteria that select instruction @@ -4722,7 +5009,7 @@ switch (UPPER_BYTE (IR)) { /* dispatch on bits 15-8 && (mem_fast_read (PR, dms_ump) & I_MRG) == I_ISZ) /* and *-1 is ISZ */ && mp_fence == 0 /* and the MP fence is zero */ && M [xeqt] == 0 /* and no program is executing */ - && M [tbg] == clk_dib.select_code) /* and the TBG select code is set */ + && M [tbg] == tbg_select_code) /* and the TBG select code is set */ || PR == err_PC - 3 /* or the jump target is *-3 (DOS through DOS-III) */ && M [PR] == I_STF /* and *-3 is STF 0 */ @@ -5827,7 +6114,8 @@ for (i = 0; sim_devices [i] != NULL; i++) { /* loop through all of t devs [dibptr->select_code] = dptr; /* then set the device pointer into the device table */ dibs [dibptr->select_code] = dibptr; /* and set the DIB pointer into the dispatch table */ - dibptr->io_handler (dibptr, ioSIR, 0); /* set the interrupt request state */ + if (dibptr->select_code >= SIRDEV) /* if this device receives SIR */ + dibptr->io_handler (dibptr, ioSIR, 0); /* then set the interrupt request state */ } } @@ -5872,21 +6160,19 @@ return; Implementation notes: - 1. For select codes < 10 octal, an IOI signal reads the floating S-bus - (high on the 1000, low on the 21xx). For select codes >= 10 octal, an - IOI reads the floating I/O bus (low on all machines). + 1. For select codes < 10 octal, an IOI signal reads the floating S-bus + (high on the 1000, low on the 21xx). For select codes >= 10 octal, an + IOI reads the floating I/O bus (low on all machines). - 2. If the UNSC simulation stop is set, a stop will occur when an unassigned - device is accessed. An exception is a CLC 0 instruction, which asserts - the CRS signal to all I/O devices from select code 6 up. This is a - legitimate access and does not cause a stop. + 2. The last select code used is saved for use by the CPU I/O handler in + detecting consecutive CLC 0 executions. */ static uint32 io_dispatch (uint32 select_code, IOCYCLE signal_set, HP_WORD data) { uint32 stat_data; -if (devs [select_code] != NULL) { /* if the I/O slot is occupied */ +if (dibs [select_code] != NULL) { /* if the I/O slot is occupied */ tpprintf (devs [select_code], TRACE_IOBUS, "Received data %06o with signals %s\n", data, fmt_bitset (signal_set, inbound_format)); @@ -5895,11 +6181,14 @@ if (devs [select_code] != NULL) { /* if the I/O slot i signal_set, IORETURN (SCPE_OK, data)); - tpprintf (devs [select_code], TRACE_IOBUS, "Returned data %06o\n", IODATA (stat_data)); - } + tpprintf (devs [select_code], TRACE_IOBUS, "Returned data %06o with signals %s\n", + IODATA (stat_data), fmt_bitset (stat_data, outbound_format)); -else if (signal_set == ioCRS) /* otherwise the slot is empty, but if this is a CRS */ - return SCPE_OK; /* then it's legal to send it to unassigned slots */ + last_select_code = select_code; /* save the select code for CLC 0 detection */ + + if (stat_data & ioSKF) /* if the interface asserted SKF */ + stat_data = IORETURN (NOTE_SKIP, 0); /* then notify the caller to increment P */ + } else if (signal_set & ioIOI) /* otherwise if it is an input request */ if (select_code < VARDEV && is_1000) /* then if it is an internal device of a 1000 CPU */ diff --git a/HP2100/hp2100_cpu.h b/HP2100/hp2100_cpu.h index 7774e709..72957e96 100644 --- a/HP2100/hp2100_cpu.h +++ b/HP2100/hp2100_cpu.h @@ -1,7 +1,7 @@ /* hp2100_cpu.h: HP 2100 CPU declarations Copyright (c) 2005-2016, Robert M. Supnik - Copyright (c) 2017, J. David Bryan + Copyright (c) 2017-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,8 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. + 22-Feb-18 JDB Reworked "cpu_ibl" into "cpu_copy_loader" + Cleaned up IBL definitions, added loader structure 22-Jul-17 JDB Renamed "intaddr" to CIR; added IR 14-Jul-17 JDB Removed calc_defer() prototype 11-Jul-17 JDB Moved "ibl_copy" and renamed to "cpu_ibl" @@ -507,32 +509,50 @@ #define I_SFS 0102300u /* SFS instruction */ #define I_STF 0102100u /* STF instruction */ -/* IBL assignments */ -#define IBL_V_SEL 14 /* ROM select <15:14> */ -#define IBL_M_SEL 03 -#define IBL_PTR 0000000u /* ROM 0: 12992K paper tape reader (PTR) */ -#define IBL_DP 0040000u /* ROM 1: 12992A 7900 disc (DP) */ -#define IBL_DQ 0060000u /* ROM 1: 12992A 2883 disc (DQ) */ -#define IBL_MS 0100000u /* ROM 2: 12992D 7970 tape (MS) */ -#define IBL_DS 0140000u /* ROM 3: 12992B 7905/06/20/25 disc (DS) */ -#define IBL_MAN 0010000u /* RPL/manual boot <13:12> */ -#define IBL_V_DEV 6 /* select code <11:6> */ -#define IBL_OPT 0000070u /* options in <5:3> */ -#define IBL_DP_REM 0000001u /* DP removable <0:0> */ -#define IBL_DS_HEAD 0000003u /* DS head number <1:0> */ -#define IBL_LNT 64 /* boot ROM length in words */ -#define IBL_MASK (IBL_LNT - 1) /* boot length mask */ -#define IBL_DPC (IBL_LNT - 2) /* DMA ctrl word */ -#define IBL_END (IBL_LNT - 1) /* last location */ +/* Initial Binary Loader. -#define IBL_S_CLR 0000000u /* cpu_ibl mask to clear the S register */ -#define IBL_S_NOCLR 0177777u /* cpu_ibl mask to preserve the S register */ -#define IBL_S_NOSET 0000000u /* cpu_ibl mask to preserve the S register */ + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | - - | select code | - - - - - - | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +*/ -#define IBL_SET_SC(s) ((HP_WORD) ((s) << IBL_V_DEV)) /* position the select code in the S register */ +#define IBL_WIDTH 6 /* loader ROM address width */ +#define IBL_MASK ((1u << IBL_WIDTH) - 1) /* loader ROM address mask (2 ** 6 - 1) */ +#define IBL_MAX ((1u << IBL_WIDTH) - 1) /* loader ROM address maximum (2 ** 6 - 1) */ +#define IBL_SIZE (IBL_MAX + 1) /* loader ROM size in words */ -typedef MEMORY_WORD BOOT_ROM [IBL_LNT]; /* boot ROM data */ +#define IBL_START 0 /* ROM array index of the program start */ +#define IBL_DMA (IBL_MAX - 1) /* ROM array index of the DMA configuration word */ +#define IBL_FWA (IBL_MAX - 0) /* ROM array index of the negative starting address */ +#define IBL_NA (IBL_MAX + 1) /* "not-applicable" ROM array index */ + +#define IBL_S_CLEAR 0000000u /* cpu_copy_loader mask to clear the S register */ +#define IBL_S_NOCLEAR 0177777u /* cpu_copy_loader mask to preserve the S register */ +#define IBL_S_NOSET 0000000u /* cpu_copy_loader mask to preserve the S register */ + +#define IBL_ROM_MASK 0140000u /* ROM socket selector mask */ +#define IBL_SC_MASK 0007700u /* device select code mask */ +#define IBL_USER_MASK ~(IBL_ROM_MASK | IBL_SC_MASK) + +#define IBL_ROM_SHIFT 14 +#define IBL_SC_SHIFT 6 + +#define IBL_ROM(s) (((s) & IBL_ROM_MASK) >> IBL_ROM_SHIFT) +#define IBL_SC(s) (((s) & IBL_SC_MASK) >> IBL_SC_SHIFT) + +#define IBL_TO_SC(c) ((c) << IBL_SC_SHIFT & IBL_SC_MASK) + + +typedef struct { + uint32 start_index; /* the array index of the start of the program */ + uint32 dma_index; /* the array index of the DMA configuration word */ + uint32 fwa_index; /* the array index of the negative starting address */ + MEMORY_WORD loader [IBL_SIZE]; /* the 64-word bootstrap loader program */ + } BOOT_LOADER; + +typedef BOOT_LOADER LOADER_ARRAY [2]; /* array (21xx, 1000) of bootstrap loaders */ /* Memory management */ @@ -641,6 +661,7 @@ extern UNIT *cpu_ioerr_uptr; /* pointer to a unit with an unr extern uint32 cpu_configuration; /* the current CPU option set and model */ extern uint32 cpu_speed; /* the CPU speed, expressed as a multiplier of a real machine */ +extern t_bool is_1000; /* TRUE if the CPU is a 1000 M/E/F-Series */ /* CPU global SCP support routines declared in scp.h @@ -656,10 +677,10 @@ extern void cpu_post_cmd (t_bool from_scp); /* CPU global utility routines */ -extern void cpu_ibl (const BOOT_ROM rom, int32 dev, HP_WORD sr_clear, HP_WORD sr_set); -extern t_stat cpu_iog (HP_WORD IR, t_bool iotrap); -extern uint32 calc_int (void); -extern t_stat resolve (HP_WORD MA, HP_WORD *address, uint32 irq); +extern t_stat cpu_copy_loader (const LOADER_ARRAY boot, uint32 sc, HP_WORD sr_clear, HP_WORD sr_set); +extern t_stat cpu_iog (HP_WORD IR, t_bool iotrap); +extern uint32 calc_int (void); +extern t_stat resolve (HP_WORD MA, HP_WORD *address, uint32 irq); /* Memory global utility routines */ diff --git a/HP2100/hp2100_cpu1.c b/HP2100/hp2100_cpu1.c index 0f64cf19..b878c106 100644 --- a/HP2100/hp2100_cpu1.c +++ b/HP2100/hp2100_cpu1.c @@ -26,6 +26,7 @@ CPU1 Extended arithmetic and optional microcode dispatchers + 07-Sep-17 JDB Removed unnecessary "uint16" casts 01-Aug-17 JDB Changed TIMER and RRR 16 to test for undefined stops 07-Jul-17 JDB Changed "iotrap" from uint32 to t_bool 26-Jun-17 JDB Replaced SEXT with SEXT16 @@ -871,11 +872,11 @@ for (i = 0; i < OP_N_F; i++) { break; case OP_VAR: /* inline variable operand */ - (*op++).word = (uint16) PR; /* get pointer to variable */ + (*op++).word = PR; /* get pointer to variable */ break; case OP_ADR: /* inline address operand */ - (*op++).word = (uint16) MA; /* get address (set by "resolve" above) */ + (*op++).word = MA; /* get address (set by "resolve" above) */ break; case OP_ADK: /* address of int constant */ diff --git a/HP2100/hp2100_cpu2.c b/HP2100/hp2100_cpu2.c index c1aa49a3..d3fadd8b 100644 --- a/HP2100/hp2100_cpu2.c +++ b/HP2100/hp2100_cpu2.c @@ -27,6 +27,7 @@ CPU2 Floating-point, dynamic mapping, extended, and I/O processor instructions + 07-Sep-17 JDB Removed unnecessary "uint16" casts 10-Jul-17 JDB Renamed the global routine "iogrp" to "cpu_iog" 26-Jun-17 JDB Replaced SEXT with SEXT16 22-Mar-17 JDB Corrected comments regarding IR bit 11 selecting A/B @@ -480,11 +481,11 @@ switch (entry) { /* decode IR<3:0> */ break; case 030: /* RSA, RSB 10x730 (OP_N) */ - ABREG[absel] = (uint16) dms_upd_sr (); /* save stat */ + ABREG [absel] = dms_upd_sr (); /* save stat */ break; case 031: /* RVA, RVB 10x731 (OP_N) */ - ABREG[absel] = (uint16) dms_upd_vr (err_PC); /* return updated violation register */ + ABREG [absel] = dms_upd_vr (err_PC); /* return updated violation register */ break; case 032: /* DJP 105732 (OP_A) */ @@ -659,7 +660,7 @@ switch (entry) { /* decode IR<4:0> */ break; case 004: /* CXA, CXB 10x744 (OP_N) */ - ABREG[absel] = (uint16) XR; /* copy from XR */ + ABREG [absel] = XR; /* copy from XR */ break; case 005: /* LDX 105745 (OP_K)*/ @@ -675,8 +676,8 @@ switch (entry) { /* decode IR<4:0> */ case 007: /* XAX, XBX 10x747 (OP_N) */ t = XR; /* exchange XR */ - XR = ABREG[absel]; - ABREG[absel] = (uint16) t; + XR = ABREG [absel]; + ABREG [absel] = t; break; case 010: /* SAY, SBY 10x750 (OP_A) */ @@ -698,7 +699,7 @@ switch (entry) { /* decode IR<4:0> */ break; case 014: /* CYA, CYB 10x754 (OP_N) */ - ABREG[absel] = (uint16) YR; /* copy from YR */ + ABREG [absel] = YR; /* copy from YR */ break; case 015: /* LDY 105755 (OP_K) */ @@ -714,8 +715,8 @@ switch (entry) { /* decode IR<4:0> */ case 017: /* XAY, XBY 10x757 (OP_N) */ t = YR; /* exchange YR */ - YR = ABREG[absel]; - ABREG[absel] = (uint16) t; + YR = ABREG [absel]; + ABREG [absel] = t; break; /* EIG module 2 */ @@ -1044,7 +1045,7 @@ switch (entry) { /* decode IR<5:0> */ break; case 002: /* READF 105462 (OP_N) */ - AR = (uint16) iop_sp; /* copy stk ptr */ + AR = iop_sp; /* copy stk ptr */ break; case 003: /* INS 105463 (OP_N) */ diff --git a/HP2100/hp2100_cpu4.c b/HP2100/hp2100_cpu4.c index cbd1fb39..470627f3 100644 --- a/HP2100/hp2100_cpu4.c +++ b/HP2100/hp2100_cpu4.c @@ -1,6 +1,6 @@ /* hp2100_cpu4.c: HP 1000 FPP/SIS - Copyright (c) 2006-2016, J. David Bryan + Copyright (c) 2006-2017, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ CPU4 Floating Point Processor and Scientific Instruction Set + 07-Sep-17 JDB Replaced "uint16" cast with "HP_WORD" for FPK assignment 05-Aug-16 JDB Renamed the P register from "PC" to "PR" 24-Dec-14 JDB Added casts for explicit downward conversions 09-May-12 JDB Separated assignments from conditional expressions @@ -315,7 +316,7 @@ switch (entry) { /* decode IR<6:0> */ case 0007: /* [stk] 105007 (OP_A) */ O = 0; /* clear overflow */ - stk_ptr = (uint16) PR; /* save ptr to next buf */ + stk_ptr = PR; /* save ptr to next buf */ rtn_addr = op[0].word; /* save return address */ while (TRUE) { @@ -712,7 +713,7 @@ switch (entry) { /* decode IR<3:0> */ op[1].fpk[1] = op[1].fpk[1] | 2; /* set "exponent" to 1 */ } - op[2].fpk[0] = (uint16) exponent; + op[2].fpk[0] = (HP_WORD) exponent; fp_exec (0120, &op[3], op[2], NOP); /* op3 = FLT(exponent) */ fp_exec (0020, &op[4], op[1], plus_1); /* op4 = op1 - 1.0 */ diff --git a/HP2100/hp2100_cpu5.c b/HP2100/hp2100_cpu5.c index 0a9f78cf..33405287 100644 --- a/HP2100/hp2100_cpu5.c +++ b/HP2100/hp2100_cpu5.c @@ -26,6 +26,7 @@ CPU5 RTE-6/VM and RTE-IV firmware option instructions + 07-Sep-17 JDB Replaced "uint16" casts with "HP_WORD" for A/B assignments 15-Jul-17 JDB Replaced "vma_resolve" with "resolve" 26-Jun-17 JDB Replaced SEXT with SEXT16 06-Jun-17 HV Fixed bug in cpu_vma_lbp "last suit + 1" handler @@ -623,7 +624,7 @@ if (!p30) /* matched suit for 1st * must be in idx 0 of PTE */ if (pgidx==01777) { /* suit switch situation */ pgidx = 0; /* select correct idx 0 */ - suit = (uint16) (pagid + 1); /* suit needs increment */ + suit = (HP_WORD) (pagid + 1 & D16_MASK); /* suit needs increment with wraparound */ if (suit==0) { /* is it page 65536? */ offset += 02000; /* adjust to 2nd page */ suit = NILPAGE; @@ -653,8 +654,8 @@ else { return cpu_vma_fault(IR, pagid+1,page31,31,ptepg,faultab,faultpc); } -AR = (uint16) pagid; /* return pagid in A */ -BR = (uint16) (page30 + offset); /* mapped address in B */ +AR = (HP_WORD) pagid; /* return pagid in A */ +BR = (HP_WORD) (page30 + offset); /* mapped address in B */ return SCPE_OK; } @@ -1261,7 +1262,7 @@ YR = ReadW(MA); WriteW(vout++, MA); vin++; /* copy address of N */ if (imax==0) goto easy; /* easy case */ -AR = (uint16) (k / imax); AR++; /* calculate K/IMAX */ +AR = (HP_WORD) (k / imax); AR++; /* calculate K/IMAX */ if (negflag) goto hard; /* had a negative index? */ if (YR > AR) goto hard; @@ -1427,7 +1428,7 @@ if ((idext0 & 0100000) || /* was nonstd MSEG? */ e->npgs = msnum==e->msegno ? lastpgs : e->msegsz; /* for last MSEG, only map available pgs */ if (!cpu_ema_mmap01(e)) return FALSE; /* map npgs pages at ipgs */ } -BR = (uint16) (e->mseg + e->msoff); /* return address of element */ +BR = (HP_WORD) (e->mseg + e->msoff); /* return address of element */ return TRUE; /* and everything done */ } @@ -1481,7 +1482,7 @@ if (npgs < e->msegsz) { e->mseg = mseg; /* logical stat of MSEG */ if (!cpu_ema_emat(e)) goto em16; /* do a std mapping */ } else { - BR = (uint16) (mseg + e->offs); /* logical start of buffer */ + BR = (HP_WORD) (mseg + e->offs); /* logical start of buffer */ e->npgs = bufpgs; /* S5 # pgs required */ e->ipgs = e->pgoff; /* S6 page offset to reqd pg */ if (!cpu_ema_mmap02(e)) goto em16; /* do nonstd mapping */ @@ -1561,7 +1562,7 @@ if (xidex) { /* is EMA declared? */ idext0 = ReadWA(xidex+0) | 0100000; /* set NS flag in id extension */ WriteS (xidex + 0, idext0); /* save back value */ AR = 0; /* was successful */ - BR = (uint16) (mseg + offs); /* calculate log address */ + BR = (HP_WORD) (mseg + offs); /* calculate log address */ (*rtn)++; /* return via good exit */ return SCPE_OK; } @@ -1584,7 +1585,7 @@ while (ndim > 0) { if (sum & 0xffff8000) goto em15; /* overflow? */ ndim--; } -BR = (uint16) (abase + sum); /* add displacement */ +BR = (HP_WORD) (abase + sum); /* add displacement */ (*rtn)++; /* return via good exit */ return SCPE_OK; diff --git a/HP2100/hp2100_defs.h b/HP2100/hp2100_defs.h index bf5a1e86..782cc2ef 100644 --- a/HP2100/hp2100_defs.h +++ b/HP2100/hp2100_defs.h @@ -1,7 +1,7 @@ /* hp2100_defs.h: HP 2100 System architectural declarations Copyright (c) 1993-2016, Robert M. Supnik - Copyright (c) 2017 J. David Bryan + Copyright (c) 2017-2018 J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,9 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. + 07-May-18 JDB Added NOTE_SKIP, simplified setSKF macro + 02-May-18 JDB Added "SIRDEV" for first device to receive the SIR signal + 16-Oct-17 JDB Suppressed logical-not-parentheses warning on clang 30-Aug-17 JDB Replaced POLL_WAIT with POLL_PERIOD 07-Aug-17 JDB Added "hp_attach" 20-Jul-17 JDB Removed STOP_OFFLINE, STOP_PWROFF stop codes @@ -185,6 +188,7 @@ */ #if defined (__clang__) + #pragma clang diagnostic ignored "-Wlogical-not-parentheses" #pragma clang diagnostic ignored "-Wlogical-op-parentheses" #pragma clang diagnostic ignored "-Wbitwise-op-parentheses" #pragma clang diagnostic ignored "-Wshift-op-parentheses" @@ -330,9 +334,9 @@ #define STOP_NOTAPE 8 /* no tape */ #define STOP_EOT 9 /* end of tape */ -#define NOTE_IOG 10 /* I/O instr executed */ -#define NOTE_INDINT 11 /* indirect intr */ - +#define NOTE_IOG 10 /* an I/O instruction was executed */ +#define NOTE_INDINT 11 /* an interrupt occurred while resolving an indirect address */ +#define NOTE_SKIP 12 /* the SKF signal was asserted by an I/O interface */ /* Modifier validation identifiers */ @@ -742,6 +746,7 @@ typedef enum { INITIAL, SERVICE } POLLMODE; /* poll synchronization #define DI_DC 044 /* 12821A Disc Interface with CS/80 disc and tape devices */ #define OPTDEV 002 /* start of optional devices */ +#define SIRDEV 004 /* start of devices that receive SIR */ #define CRSDEV 006 /* start of devices that receive CRS */ #define VARDEV 010 /* start of variable assignments */ #define MAXDEV 077 /* end of select code range */ @@ -781,9 +786,9 @@ typedef enum { INITIAL, SERVICE } POLLMODE; /* poll synchronization 2. The ioSKF signal is never sent to an I/O handler. Rather, it is returned from the handler if the SFC or SFS condition is true. If the condition - is false, ioNONE is returned instead. As these two values are returned - in the 16-bit data portion of the returned value, their assigned values - must be <= 100000 octal. + is false, ioNONE is returned instead. As the ioSKF value is returned in + the upper 16 bits of the returned value, its assigned value must be >= + 200000 octal. 3. An I/O handler will receive ioCRS as a result of a CLC 0 instruction, ioPOPIO and ioCRS as a result of a RESET command, and ioPON, ioPOPIO, and @@ -818,21 +823,22 @@ typedef enum { ioNONE = 0000000, /* -- -- -- -- -- no sig ioIOI = 0000004, /* -- -- T4 T5 -- I/O data input (CPU) T2 T3 -- -- -- I/O data input (DMA) */ ioIOO = 0000010, /* -- T3 T4 -- -- I/O data output */ - ioSKF = 0000020, /* -- T3 T4 T5 -- skip on flag */ - ioSFS = 0000040, /* -- T3 T4 T5 -- skip if flag is set */ - ioSFC = 0000100, /* -- T3 T4 T5 -- skip if flag is clear */ - ioSTC = 0000200, /* -- -- T4 -- -- set control flip-flop (CPU) + ioSFS = 0000020, /* -- T3 T4 T5 -- skip if flag is set */ + ioSFC = 0000040, /* -- T3 T4 T5 -- skip if flag is clear */ + ioSTC = 0000100, /* -- -- T4 -- -- set control flip-flop (CPU) -- T3 -- -- -- set control flip-flop (DMA) */ - ioCLC = 0000400, /* -- -- T4 -- -- clear control flip-flop (CPU) + ioCLC = 0000200, /* -- -- T4 -- -- clear control flip-flop (CPU) -- T3 T4 -- -- clear control flip-flop (DMA) */ - ioSTF = 0001000, /* -- T3 -- -- -- set flag flip-flop */ - ioCLF = 0002000, /* -- -- T4 -- -- clear flag flip-flop (CPU) + ioSTF = 0000400, /* -- T3 -- -- -- set flag flip-flop */ + ioCLF = 0001000, /* -- -- T4 -- -- clear flag flip-flop (CPU) -- T3 -- -- -- clear flag flip-flop (DMA) */ - ioEDT = 0004000, /* -- -- T4 -- -- end data transfer */ - ioCRS = 0010000, /* -- -- -- T5 -- control reset */ - ioPOPIO = 0020000, /* -- -- -- T5 -- power-on preset to I/O */ - ioIAK = 0040000, /* -- -- -- -- T6 interrupt acknowledge */ - ioSIR = 0100000 } IOSIGNAL; /* -- -- -- T5 -- set interrupt request */ + ioEDT = 0002000, /* -- -- T4 -- -- end data transfer */ + ioCRS = 0004000, /* -- -- -- T5 -- control reset */ + ioPOPIO = 0010000, /* -- -- -- T5 -- power-on preset to I/O */ + ioIAK = 0020000, /* -- -- -- -- T6 interrupt acknowledge */ + ioSIR = 0040000, /* -- -- -- T5 -- set interrupt request */ + + ioSKF = 0200000 } IOSIGNAL; /* -- T3 T4 T5 -- skip on flag */ typedef uint32 IOCYCLE; /* a set of signals forming one I/O cycle */ @@ -1003,7 +1009,7 @@ struct dib { /* the Device Information Block #define BIT_V(S) ((S) & 037) /* convert select code to bit position */ #define BIT_M(S) (1u << BIT_V (S)) /* convert select code to bit mask */ -#define setSKF(B) stat_data = IORETURN (SCPE_OK, (uint16) ((B) ? ioSKF : ioNONE)) +#define setSKF(B) stat_data = ((B) ? ioSKF : ioNONE) #define setPRL(S,B) dev_prl[(S)/32] = dev_prl[(S)/32] & ~BIT_M (S) | (((B) & 1) << BIT_V (S)) #define setIRQ(S,B) dev_irq[(S)/32] = dev_irq[(S)/32] & ~BIT_M (S) | (((B) & 1) << BIT_V (S)) @@ -1023,7 +1029,7 @@ struct dib { /* the Device Information Block /* Bitset formatting. - See the comments at the "fmt_bitset" function (hp3000_sys.c) for details of + See the comments at the "fmt_bitset" function (hp2100_sys.c) for details of the specification of bitset names and format structures. */ diff --git a/HP2100/hp2100_di_da.c b/HP2100/hp2100_di_da.c index 991e4a86..c427b6bb 100644 --- a/HP2100/hp2100_di_da.c +++ b/HP2100/hp2100_di_da.c @@ -1,6 +1,6 @@ /* hp2100_di_da.c: HP 12821A HP-IB Disc Interface simulator for Amigo disc drives - Copyright (c) 2011-2017, J. David Bryan + Copyright (c) 2011-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ DA 12821A Disc Interface with Amigo disc drives + 21-Feb-18 JDB ATTACH -N now creates a full-size disc image 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" 15-Mar-17 JDB Changed DEBUG_PRI calls to tprintfs 09-Mar-17 JDB Deprecated LOCKED/WRITEENABLED for PROTECT/UNPROTECT @@ -1080,6 +1081,9 @@ return status; The unspecified responses are illegal conditions; for example, the simulator does not allow an attached unit to be disabled. + If a new file is specified, the file is initialized to its capacity by + writing a zero to the last byte in the file. + Implementation notes: @@ -1091,19 +1095,36 @@ return status; specifying a validation routine works for the DISABLED case but not the ENABLED case -- set_unit_enbdis returns SCPE_UDIS before calling the validation routine. + + 2. The C standard says, "A binary stream need not meaningfully support fseek + calls with a whence value of SEEK_END," so instead we determine the + offset from the start of the file to the last byte and seek there. */ t_stat da_attach (UNIT *uptr, CONST char *cptr) { -t_stat result; +t_stat result; +t_addr offset; +const uint8 zero = 0; const int32 unit = uptr - da_unit; /* calculate the unit number */ result = dl_attach (&icd_cntlr [unit], uptr, cptr); /* attach the drive */ -if (result == SCPE_OK) /* was the attach successful? */ - di [da].acceptors |= (1 << unit); /* set the unit's accepting bit */ +if (result == SCPE_OK) { /* if the attach was successful */ + di [da].acceptors |= (1 << unit); /* then set the unit's accepting bit */ -return result; + if (sim_switches & SWMASK ('N')) { /* if this is a new disc image */ + offset = (t_addr) /* then determine the offset of */ + (uptr->capac * sizeof (int16) - sizeof zero); /* the last byte in a full-sized file */ + + if (sim_fseek (uptr->fileref, offset, SEEK_SET) != 0 /* seek to the last byte */ + || fwrite (&zero, sizeof zero, 1, uptr->fileref) == 0 /* and write a zero to fill */ + || fflush (uptr->fileref) != 0) /* the file to its capacity */ + clearerr (uptr->fileref); /* clear and ignore any errors */ + } + } + +return result; /* return the result of the attach */ } @@ -1130,17 +1151,131 @@ return result; } -/* Boot an Amigo disc drive. +/* 7906H/20H/25H disc bootstrap loader (12992H). - The ICD disc bootstrap program is loaded from the HP 12992H Boot Loader ROM - into memory, the I/O instructions are configured for the interface card's - select code, and the program is run to boot from the specified unit. The - loader supports booting the disc at bus address 0 only. Before execution, - the S register is automatically set as follows: + The HP 1000 uses the 12992H boot loader ROM to bootstrap the ICD discs. Bit + 12 of the S register determines whether an RPL or manual boot is performed. + Bits 1-0 specify the head number to use. - 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - ------ ------ ---------------------- ------------- ----- - ROM # 0 1 select code reserved head + The loader reads 256 words from cylinder 0 sector 0 of the specified head + into memory starting at location 2011 octal. Loader execution ends with one + of the following instructions: + + * HLT 11 - the drive aborted the transfer due to an unrecoverable error + * JSB 2055,I - the disc read succeeded + + The ICD drives are not supported on the 2100/14/15/16 CPUs, so no 21xx loader + is provided. +*/ + +static const LOADER_ARRAY da_loaders = { + { /* HP 21xx Loader does not exist */ + IBL_NA, /* loader starting index */ + IBL_NA, /* DMA index */ + IBL_NA, /* FWA index */ + { 0 } }, + + { /* HP 1000 Loader ROM (12992H) */ + IBL_START, /* loader starting index */ + IBL_DMA, /* DMA index */ + IBL_FWA, /* FWA index */ + { 0102501, /* 77700: START LIA 1 GET SWITCH REGISTER SETTING */ + 0100044, /* 77701: LSL 4 SHIFT A LEFT 4 */ + 0006111, /* 77702: CLE,SLB,RSS SR BIT 12 SET FOR MANUAL BOOT? */ + 0100041, /* 77703: LSL 1 NO. SHIFT HEAD # FOR RPL BOOT */ + 0001424, /* 77704: ALR,ALR SHIFT HEAD 2, CLEAR SIGN */ + 0033744, /* 77705: IOR HDSEC SET EOI BIT */ + 0073744, /* 77706: STA HDSEC PLACE IN COMMAND BUFFER */ + 0017756, /* 77707: JSB BTCTL SEND DUMMY,U-CLR,PP */ + 0102510, /* 77710: LIA IBI READ INPUT REGISTER */ + 0101027, /* 77711: ASR 7 SHIFT DRIVE 0 RESPONSE TO LSB */ + 0002011, /* 77712: SLA,RSS DID DRIVE 0 RESPOND? */ + 0027710, /* 77713: JMP *-3 NO, GO LOOK AGAIN */ + 0107700, /* 77714: CLC 0,C */ + 0017756, /* 77715: JSB BTCTL SEND TALK, CL-RD,BUS HOLDER */ + 0002300, /* 77716: CCE */ + 0017756, /* 77717: JSB BTCTL TELL CARD TO LISTEN */ + 0063776, /* 77720: LDA DMACW LOAD DMA CONTROL WORD */ + 0102606, /* 77721: OTA 6 OUTPUT TO DCPC */ + 0106702, /* 77722: CLC 2 READY DCPC */ + 0063735, /* 77723: LDA ADDR1 LOAD DMA BUFFER ADDRESS */ + 0102602, /* 77724: OTA 2 OUTPUT TO DCPC */ + 0063740, /* 77725: LDA DMAWC LOAD DMA WORD COUNT */ + 0102702, /* 77726: STC 2 READY DCPC */ + 0102602, /* 77727: OTA 2 OUTPUT TO DCPC */ + 0103706, /* 77730: STC 6,C START DCPC */ + 0102206, /* 77731: TEST SFC 6 SKIP IF DMA NOT DONE */ + 0117750, /* 77732: JSB ADDR2,I SUCCESSFUL END OF TRANSFER */ + 0102310, /* 77733: SFS IBI SKIP IF DISC ABORTED TRANSFER */ + 0027731, /* 77734: JMP TEST RECHECK FOR TRANSFER END */ + 0102011, /* 77735: ADDR1 HLT 11B ERROR HALT */ + 0000677, /* 77736: UNCLR OCT 677 UNLISTEN */ + 0000737, /* 77737: OCT 737 UNTALK */ + 0176624, /* 77740: DMAWC OCT 176624 UNIVERSAL CLEAR,LBO */ + 0000440, /* 77741: LIST OCT 440 LISTEN BUS ADDRESS 0 */ + 0000550, /* 77742: CMSEC OCT 550 SECONDARY GET COMMAND */ + 0000000, /* 77743: BOOT OCT 0 COLD LOAD READ COMMAND */ + 0001000, /* 77744: HDSEC OCT 1000 HEAD,SECTOR PLUS EOI */ + 0000677, /* 77745: UNLST OCT 677 ATN,PRIMARY UNLISTEN,PARITY */ + 0000500, /* 77746: TALK OCT 500 SEND READ DATA */ + 0100740, /* 77747: RDSEC OCT 100740 SECONDARY READ DATA */ + 0102055, /* 77750: ADDR2 OCT 102055 BOOT EXTENSION STARTING ADDRESS */ + 0004003, /* 77751: CTLP OCT 4003 INT=LBO,T,CIC */ + 0000047, /* 77752: OCT 47 PPE,L,T,CIC */ + 0004003, /* 77753: OCT 4003 INT=LBO,T,CIC */ + 0000413, /* 77754: OCT 413 ATN,P,L,CIC */ + 0001015, /* 77755: OCT 1015 INT=EOI,P,L,CIC */ + 0000000, /* 77756: BTCTL NOP */ + 0107710, /* 77757: CLC IBI,C RESET IBI */ + 0063751, /* 77760: BM LDA CTLP LOAD CONTROL WORD */ + 0102610, /* 77761: OTA IBI OUTPUT TO CONTROL REGISTER */ + 0102710, /* 77762: STC IBI RETURN IBI TO DATA MODE */ + 0037760, /* 77763: ISZ BM INCREMENT CONTROL WORD POINTER */ + 0002240, /* 77764: SEZ,CME */ + 0127756, /* 77765: JMP BTCTL,I RETURN */ + 0063736, /* 77766: LABL LDA UNCLR LOAD DATA WORD */ + 0037766, /* 77767: ISZ LABL INCREMENT WORD POINTER */ + 0102610, /* 77770: OTA IBI OUTPUT TO HPIB */ + 0002021, /* 77771: SSA,RSS SKIP IF LAST WORD */ + 0027766, /* 77772: JMP LABL GO BACK FOR NEXT WORD */ + 0102310, /* 77773: SFS IBI SKIP IF LAST WORD SENT TO BUS */ + 0027773, /* 77774: JMP *-1 RECHECK ACCEPTANCE */ + 0027757, /* 77775: JMP BTCTL+1 */ + 0000010, /* 77776: DMACW ABS IBI */ + 0170100 } } /* 77777: ABS -START */ + }; + +/* Device boot routine. + + This routine is called directly by the BOOT DA and LOAD DA commands to copy + the device bootstrap into the upper 64 words of the logical address space. It + is also called indirectly by a BOOT CPU or LOAD CPU command when the + specified HP 1000 loader ROM socket contains a 12992H ROM. + + When called in response to a BOOT DA or LOAD DA command, the "unitno" + parameter indicates the unit number specified in the BOOT command or is zero + for the LOAD command, and "dptr" points at the DA device structure. The + bootstrap supports loading only from the disc at bus address 0 only. The + 12992F loader ROM will be copied into memory and configured for the DA select + code. The S register will be set as it would be by the front-panel + microcode. + + When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the + select code to be used for configuration, and "dptr" will be NULL. As above, + the 12992H loader ROM will be copied into memory and configured for the + specified select code. The S register is assumed to be set correctly on entry + and is not modified. + + The loader expects the S register to be is set as follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | 0 1 | select code | reserved | head | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Bit 12 must be 1 for a manual boot. Bits 5-2 are nominally zero but are + reserved for the target operating system. For example, RTE uses bit 5 to + indicate whether a standard (0) or reconfiguration (1) boot is desired. The boot routine sets bits 15-6 of the S register to appropriate values. Bits 5-3 and 1-0 retain their original values, so S should be set before @@ -1149,83 +1284,21 @@ return result; than 0 is desired. */ -static const BOOT_ROM da_rom = { - 0102501, /* START LIA 1 GET SWITCH REGISTER SETTING */ - 0100044, /* LSL 4 SHIFT A LEFT 4 */ - 0006111, /* CLE,SLB,RSS SR BIT 12 SET FOR MANUAL BOOT? */ - 0100041, /* LSL 1 NO. SHIFT HEAD # FOR RPL BOOT */ - 0001424, /* ALR,ALR SHIFT HEAD 2, CLEAR SIGN */ - 0033744, /* IOR HDSEC SET EOI BIT */ - 0073744, /* STA HDSEC PLACE IN COMMAND BUFFER */ - 0017756, /* JSB BTCTL SEND DUMMY,U-CLR,PP */ - 0102510, /* LIA IBI READ INPUT REGISTER */ - 0101027, /* ASR 7 SHIFT DRIVE 0 RESPONSE TO LSB */ - 0002011, /* SLA,RSS DID DRIVE 0 RESPOND? */ - 0027710, /* JMP *-3 NO, GO LOOK AGAIN */ - 0107700, /* CLC 0,C */ - 0017756, /* JSB BTCTL SEND TALK, CL-RD,BUS HOLDER */ - 0002300, /* CCE */ - 0017756, /* JSB BTCTL TELL CARD TO LISTEN */ - 0063776, /* LDA DMACW LOAD DMA CONTROL WORD */ - 0102606, /* OTA 6 OUTPUT TO DCPC */ - 0106702, /* CLC 2 READY DCPC */ - 0063735, /* LDA ADDR1 LOAD DMA BUFFER ADDRESS */ - 0102602, /* OTA 2 OUTPUT TO DCPC */ - 0063740, /* LDA DMAWC LOAD DMA WORD COUNT */ - 0102702, /* STC 2 READY DCPC */ - 0102602, /* OTA 2 OUTPUT TO DCPC */ - 0103706, /* STC 6,C START DCPC */ - 0102206, /* TEST SFC 6 SKIP IF DMA NOT DONE */ - 0117750, /* JSB ADDR2,I SUCCESSFUL END OF TRANSFER */ - 0102310, /* SFS IBI SKIP IF DISC ABORTED TRANSFER */ - 0027731, /* JMP TEST RECHECK FOR TRANSFER END */ - 0102011, /* ADDR1 HLT 11B ERROR HALT */ - 0000677, /* UNCLR OCT 677 UNLISTEN */ - 0000737, /* OCT 737 UNTALK */ - 0176624, /* DMAWC OCT 176624 UNIVERSAL CLEAR,LBO */ - 0000440, /* LIST OCT 440 LISTEN BUS ADDRESS 0 */ - 0000550, /* CMSEC OCT 550 SECONDARY GET COMMAND */ - 0000000, /* BOOT OCT 0 COLD LOAD READ COMMAND */ - 0001000, /* HDSEC OCT 1000 HEAD,SECTOR PLUS EOI */ - 0000677, /* UNLST OCT 677 ATN,PRIMARY UNLISTEN,PARITY */ - 0000500, /* TALK OCT 500 SEND READ DATA */ - 0100740, /* RDSEC OCT 100740 SECONDARY READ DATA */ - 0102055, /* ADDR2 OCT 102055 BOOT EXTENSION STARTING ADDRESS */ - 0004003, /* CTLP OCT 4003 INT=LBO,T,CIC */ - 0000047, /* OCT 47 PPE,L,T,CIC */ - 0004003, /* OCT 4003 INT=LBO,T,CIC */ - 0000413, /* OCT 413 ATN,P,L,CIC */ - 0001015, /* OCT 1015 INT=EOI,P,L,CIC */ - 0000000, /* BTCTL NOP */ - 0107710, /* CLC IBI,C RESET IBI */ - 0063751, /* BM LDA CTLP LOAD CONTROL WORD */ - 0102610, /* OTA IBI OUTPUT TO CONTROL REGISTER */ - 0102710, /* STC IBI RETURN IBI TO DATA MODE */ - 0037760, /* ISZ BM INCREMENT CONTROL WORD POINTER */ - 0002240, /* SEZ,CME */ - 0127756, /* JMP BTCTL,I RETURN */ - 0063736, /* LABL LDA UNCLR LOAD DATA WORD */ - 0037766, /* ISZ LABL INCREMENT WORD POINTER */ - 0102610, /* OTA IBI OUTPUT TO HPIB */ - 0002021, /* SSA,RSS SKIP IF LAST WORD */ - 0027766, /* JMP LABL GO BACK FOR NEXT WORD */ - 0102310, /* SFS IBI SKIP IF LAST WORD SENT TO BUS */ - 0027773, /* JMP *-1 RECHECK ACCEPTANCE */ - 0027757, /* JMP BTCTL+1 */ - 0000010, /* DMACW ABS IBI */ - 0170100 /* ABS -START */ - }; - t_stat da_boot (int32 unitno, DEVICE *dptr) { -if (GET_BUSADR (da_unit [unitno].flags) != 0) /* booting is supported on bus address 0 only */ - return SCPE_NOFNC; /* report "Command not allowed" if attempted */ +static const HP_WORD da_preserved = 0000073u; /* S-register bits 5-3 and 1-0 are preserved */ +static const HP_WORD da_manual_boot = 0010000u; /* S-register bit 12 set for a manual boot */ -cpu_ibl (da_rom, da_dib.select_code, /* copy the boot ROM to memory and configure */ - IBL_OPT | IBL_DS_HEAD, /* the S register accordingly */ - IBL_DS | IBL_MAN | IBL_SET_SC (da_dib.select_code)); +if (dptr == NULL) /* if we are being called for a BOOT/LOAD CPU */ + return cpu_copy_loader (da_loaders, unitno, /* then copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* but do not alter the S register */ -return SCPE_OK; +else if (GET_BUSADR (da_unit [unitno].flags) != 0) /* otherwise BOOT DA is supported on bus address 0 only */ + return SCPE_NOFNC; /* so reject other addresses as unsupported */ + +else /* otherwise this is a BOOT/LOAD DA */ + return cpu_copy_loader (da_loaders, da_dib.select_code, /* so copy the boot loader to memory */ + da_preserved, da_manual_boot); /* and configure the S register if 1000 CPU */ } diff --git a/HP2100/hp2100_diag.txt b/HP2100/hp2100_diag.txt index d982e292..4a39f1be 100644 --- a/HP2100/hp2100_diag.txt +++ b/HP2100/hp2100_diag.txt @@ -1,6 +1,6 @@ SIMH/HP 21XX DIAGNOSTICS PERFORMANCE ==================================== - Last update: 2017-02-15 + Last update: 2018-05-15 The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation. @@ -488,13 +488,13 @@ TEST RESULT: Passed. -------------------------------------- -DSN 143300 - General Purpose Register -------------------------------------- +------------------------------------------- +DSN 143300 - General Purpose Register (LPS) +------------------------------------------- TESTED DEVICE: LPS (hp2100_lps.c) -CONFIGURATION: sim> set LPS diag +CONFIGURATION: sim> set LPS DIAGNOSTIC sim> deposit S 000014 sim> reset sim> go 100 @@ -1096,9 +1096,9 @@ TEST RESULT: Passed. -------------------------------------- -DSN 143300 - General Purpose Register -------------------------------------- +------------------------------------------- +DSN 143300 - General Purpose Register (PIF) +------------------------------------------- TESTED DEVICE: PIF (hp2100_pif.c) @@ -1136,6 +1136,81 @@ TEST REPORT: GENERAL PURPOSE REGISTER DIAGNOSTIC, DSN 143300 TEST RESULT: Passed. +TEST NOTES: Only test 00 (Basic I/O Test) is executed. The other tests are + not applicable, as the 12620A card has no data path circuitry. + + + +-------------------------------------------- +DSN 143300 - General Purpose Register (IPLI) +-------------------------------------------- + +TESTED DEVICE: IPLI (hp2100_ipl.c) + +CONFIGURATION: sim> set IPLI DIAGNOSTIC + + sim> deposit S 000032 + sim> reset + sim> go 100 + + Programmed halt, T: 102074 (HLT 74) + + sim> deposit S 000000 + sim> go + +TEST REPORT: GENERAL PURPOSE REGISTER DIAGNOSTIC, DSN 143300 + + H024 PRESS PRESET (EXT&INT),RUN + + Programmed halt, T: 102024 (HLT 24) + + sim> reset + sim> go + + H025 BASIC I-O COMPLETED + + PASS 000001 + + Programmed halt, T: 102077 (HLT 77) + +TEST RESULT: Passed. + + + +-------------------------------------------- +DSN 143300 - General Purpose Register (IPLO) +-------------------------------------------- + +TESTED DEVICE: IPLO (hp2100_ipl.c) + +CONFIGURATION: sim> set IPLI DIAGNOSTIC + + sim> deposit S 000033 + sim> reset + sim> go 100 + + Programmed halt, T: 102074 (HLT 74) + + sim> deposit S 000000 + sim> go + +TEST REPORT: GENERAL PURPOSE REGISTER DIAGNOSTIC, DSN 143300 + + H024 PRESS PRESET (EXT&INT),RUN + + Programmed halt, T: 102024 (HLT 24) + + sim> reset + sim> go + + H025 BASIC I-O COMPLETED + + PASS 000001 + + Programmed halt, T: 102077 (HLT 77) + +TEST RESULT: Passed. + --------------------------------------------------- @@ -2128,7 +2203,7 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC HALT instruction 102002 - sim> set DPC0 unloaded + sim> set DPC0 unload sim> go H40 PROTECT U/D THEN READY UNIT 0 @@ -2136,15 +2211,14 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC [CTRL+E] Simulation stopped - sim> set DPC0 locked - sim> set DPC0 loaded + sim> set DPC0 load,protect sim> go H41 CLEAR U/D PROTECT,LOAD,PUSH RUN HALT instruction 102002 - sim> set DPC0 writeenabled + sim> set DPC0 unprotect sim> go H71 PRESS PRESET(S) THEN PRESS RUN @@ -3355,8 +3429,8 @@ TESTED DEVICE: IPLI, IPLO (hp2100_ipl.c) BINARY TAPE: 24197-60001 Rev. B -CONFIGURATION: sim> set IPLI DIAG - sim> set IPLO DIAG +CONFIGURATION: sim> set IPLI DIAGNOSTIC + sim> set IPLO DIAGNOSTIC sim> deposit S 003332 sim> reset sim> go 2 diff --git a/HP2100/hp2100_dp.c b/HP2100/hp2100_dp.c index 71d7291f..665e4474 100644 --- a/HP2100/hp2100_dp.c +++ b/HP2100/hp2100_dp.c @@ -1,7 +1,7 @@ /* hp2100_dp.c: HP 2100 12557A/13210A disc simulator Copyright (c) 1993-2016, Robert M. Supnik - Copyright (c) 2017 J. David Bryan + Copyright (c) 2017-2018 J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,6 +27,10 @@ DP 12557A 2870 disc subsystem 13210A 7900 disc subsystem + 27-Feb-18 JDB Corrected the conditions that clear drive status + Added the BMDL + 13-Feb-18 JDB First Status is now cleared on Read, etc. + 26-Jan-18 JDB ATTACH -N now creates a full-size disc image 03-Aug-17 JDB Changed perror call for I/O errors to cprintf 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" 22-Apr-17 JDB Added fall-through comment for FNC_STA case in dpcio @@ -82,7 +86,7 @@ - 7900A Disc Drive Operating and Service Manual (07900-90002, February 1975) - 13210A Disc Drive Interface Kit Operating and Service Manual - (13210-90003, November 1974) + (13210-90003, May 1978) - 12557A Cartridge Disc Interface Kit Operating and Service Manual (12557-90001, Sepember 1970) @@ -124,12 +128,103 @@ drive's current position register during a read, i.e., the "on-disc" address field is assumed to match the current position. - The following implemented behaviors have been inferred from secondary sources - (diagnostics, operating system drivers, etc.), due to absent or contradictory - authoritative information; future correction may be needed: + NOTE: 13210A manuals dated November 1974 and earlier contain errors in the + schematics. See the comments preceding the "dpcio" routine for details. - 1. Status bit 15 (ATTENTION) does not set bit 0 (ANY ERROR) on the 12557A. - 2. Omitting STC DC before Status Check does not set DC flag but does poll. + + The 13210A interfaces respond to I/O instructions as follows: + + Output Data Word format (OTA and OTB): + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | command | - - | P | D | - - - - - - | unit | command + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | write data | data + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - - - - - - - - | cylinder address | data + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - - - - - - | head | - - - | sector address | data + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - - - - - - - - - - | sector count | data + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + D = Defective Track + P = Protected Track + + Command: + + 0000 = Status Check + 0001 = Write Data + 0010 = Read Data + 0011 = Seek Record + 0101 = Refine Sector + 0110 = Check Data + 1001 = Initialize Data + 1011 = Address Record + + The 12557A interface responds identically, except that the sector address and + sector count fields use one fewer bit each, i.e., use bits 3-0 and 4-0, + respectively. + + + Input Data Word format (LIA and LIB): + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - - - - - - - - - - - - | attention | command + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | read data | data + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - | F | O | - | U | P | - | S | - | N | C | A | G | B | D | E | data + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + F = First Status + O = Overrun + U = Drive Unsafe + P = Data Protected + S = Seek Check + N = Not Ready + C = End of Cylinder + A = Address Error + G = Flagged Cylinder + B = Drive Busy + D = Data Error + E = Any Error + + The 12557A interface responds identically, except that the status word is + extended as follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | T | F | O | R | U | H | I | S | - | N | C | A | G | B | D | E | data + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where the differing bits are: + + T = Attention + R = Read/Write Unsafe + H = Access Hunting + I = Seek Incomplete + + + Implementation notes: + + 1. The following implemented behaviors have been inferred from secondary + sources (diagnostics, operating system drivers, etc.), due to absent or + contradictory authoritative information; future correction may be needed: + + - 12557A status bit 15 (ATTENTION) does not set bit 0 (ANY ERROR). + + - 12557A clears status after a Check Status command, but 13210A does + not. + + - Omitting STC DC before Status Check does not set DC flag but does + poll. */ @@ -158,7 +253,13 @@ #define DP_SIZE3 (DP_NUMSF * DP_NUMCY * DP_NUMSC3 * DP_NUMWD) #define DP_NUMDRV 4 /* # drives */ -/* Command word */ +/* Command word. + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | command | - - | P | D | - - - - - - | unit | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +*/ #define CW_V_FNC 12 /* function */ #define CW_M_FNC 017 @@ -197,35 +298,51 @@ #define DA_CKMASK3 077 #define DA_CKMASK (dp_ctype ? DA_CKMASK3 : DA_CKMASK2) -/* Status in dpc_sta[drv], (u) = unused in 13210, (d) = dynamic */ +/* Status in dpc_sta [drv]. -#define STA_ATN 0100000 /* attention (u) */ -#define STA_1ST 0040000 /* first status */ -#define STA_OVR 0020000 /* overrun */ -#define STA_RWU 0010000 /* rw unsafe NI (u) */ -#define STA_ACU 0004000 /* access unsafe NI */ -#define STA_HUNT 0002000 /* hunting NI (12557) */ -#define STA_PROT 0002000 /* protected (13210) */ -#define STA_SKI 0001000 /* incomplete NI (u) */ -#define STA_SKE 0000400 /* seek error */ + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - | F | O | - | U | P | - | S | - | N | C | A | G | B | D | E | 13210A + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | T | F | O | R | U | H | I | S | - | N | C | A | G | B | D | E | 12557A + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + + Implementation notes: + + 1. The Data Protected, Not Ready, and Any Error bits are determined + dynamically. The other status bits are stored in the drive status array. +*/ + +#define STA_ATN 0100000 /* (T) Attention (12557) */ +#define STA_1ST 0040000 /* (F) First status */ +#define STA_OVR 0020000 /* (O) Overrun */ +#define STA_RWU 0010000 /* (R) Read/Write Unsafe (12557) */ +#define STA_ACU 0004000 /* (U) Drive Unsafe */ +#define STA_PROT 0002000 /* (P) Data Protected (13210) */ +#define STA_HUNT 0002000 /* (H) Access Hunting (12557) */ +#define STA_SKI 0001000 /* (I) Seek Incomplete (12557) */ +#define STA_SKE 0000400 /* (S) Seek Check */ /* 0000200 (unused) */ -#define STA_NRDY 0000100 /* not ready (d) */ -#define STA_EOC 0000040 /* end of cylinder */ -#define STA_AER 0000020 /* addr error */ -#define STA_FLG 0000010 /* flagged */ -#define STA_BSY 0000004 /* seeking */ -#define STA_DTE 0000002 /* data error */ -#define STA_ERR 0000001 /* any error (d) */ +#define STA_NRDY 0000100 /* (N) Not Ready */ +#define STA_EOC 0000040 /* (C) End of Cylinder */ +#define STA_AER 0000020 /* (A) Address Error */ +#define STA_FLG 0000010 /* (G) Flagged Cylinder */ +#define STA_BSY 0000004 /* (B) Drive Busy */ +#define STA_DTE 0000002 /* (D) Data Error */ +#define STA_ERR 0000001 /* (E) Any Error */ #define STA_ERSET2 (STA_1ST | STA_OVR | STA_RWU | STA_ACU | \ STA_SKI | STA_SKE | STA_NRDY | \ STA_EOC | STA_AER | STA_DTE) /* 12557A error set */ + #define STA_ERSET3 (STA_ATN | STA_1ST | STA_OVR | STA_RWU | STA_ACU | \ STA_SKI | STA_SKE | STA_NRDY | STA_EOC | STA_AER | \ STA_FLG | STA_BSY | STA_DTE) /* 13210A error set */ -#define STA_ANYERR (dp_ctype ? STA_ERSET3 : STA_ERSET2) +#define STA_ANYERR (dp_ctype ? STA_ERSET3 : STA_ERSET2) #define STA_UNLOADED (dp_ctype ? (STA_NRDY | STA_BSY) : STA_NRDY) + #define STA_MBZ13 (STA_ATN | STA_RWU | STA_SKI) /* zero in 13210 */ struct { @@ -329,12 +446,38 @@ MTAB dpd_mod [] = { { 0 } }; +/* Debugging trace list */ + +static DEBTAB dpd_deb [] = { + { "IOBUS", TRACE_IOBUS }, /* trace I/O bus signals and data words received and returned */ + { NULL, 0 } + }; + +/* Device descriptor */ + DEVICE dpd_dev = { - "DPD", &dpd_unit, dpd_reg, dpd_mod, - 1, 10, DP_N_NUMWD, 1, 8, 16, - NULL, NULL, &dpc_reset, - NULL, NULL, NULL, - &dpd_dib, DEV_DISABLE + "DPD", /* device name */ + &dpd_unit, /* unit array */ + dpd_reg, /* register array */ + dpd_mod, /* modifier array */ + 1, /* number of units */ + 10, /* address radix */ + DP_N_NUMWD, /* address width = 4 GB */ + 1, /* address increment */ + 8, /* data radix */ + 16, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &dpc_reset, /* reset routine */ + NULL, /* boot routine */ + NULL, /* attach routine */ + NULL, /* detach routine */ + &dpd_dib, /* device information block pointer */ + DEV_DISABLE | DEV_DEBUG, /* device flags */ + 0, /* debug control flags */ + dpd_deb, /* debug flag name array */ + NULL, /* memory size change routine */ + NULL /* logical device name */ }; /* DPC data structures @@ -405,12 +548,38 @@ MTAB dpc_mod [] = { { 0 } }; +/* Debugging trace list */ + +static DEBTAB dpc_deb [] = { + { "IOBUS", TRACE_IOBUS }, /* trace I/O bus signals and data words received and returned */ + { NULL, 0 } + }; + +/* Device descriptor */ + DEVICE dpc_dev = { - "DPC", dpc_unit, dpc_reg, dpc_mod, - DP_NUMDRV, 8, 24, 1, 8, 16, - NULL, NULL, &dpc_reset, - &dpc_boot, &dpc_attach, &dpc_detach, - &dpc_dib, DEV_DISABLE + "DPC", /* device name */ + dpc_unit, /* unit array */ + dpc_reg, /* register array */ + dpc_mod, /* modifier array */ + DP_NUMDRV, /* number of units */ + 8, /* address radix */ + 24, /* address width = 4 GB */ + 1, /* address increment */ + 8, /* data radix */ + 16, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &dpc_reset, /* reset routine */ + &dpc_boot, /* boot routine */ + &dpc_attach, /* attach routine */ + &dpc_detach, /* detach routine */ + &dpc_dib, /* device information block pointer */ + DEV_DISABLE | DEV_DEBUG, /* device flags */ + 0, /* debug control flags */ + dpc_deb, /* debug flag name array */ + NULL, /* memory size change routine */ + NULL /* logical device name */ }; @@ -549,6 +718,7 @@ return stat_data; flip-flops. Only the 12557A has a command flip-flop. IRQ, PRL, and SRQ are standard. + Implementation notes: 1. In hardware, the command channel card passes PRH to PRL. The data card @@ -558,6 +728,30 @@ return stat_data; the command card is interrupting. This works in hardware, but we must break PRL at the command card under simulation to allow the command card to interrupt. + + 2. The 13210 manual says that a Check Status command clears the status + register, which consists of status word bits 14, 13, 11, 10, 8, 5, 4, 3, + 1, and 0, i.e., all except bit 6 "Not Ready" and bit 2 "Drive Busy", + which are direct pass-throughs from the drive. However, the schematic + shows that the register is cleared on STC assertion for any command + OTHER than Check Status. In other words, every command except Check + Status clears the old status in order to assert new status (so two + successive Check Status commands will return the same status word, + contrary to the manual). The simulator implements the schematic + behavior. + + 3. The schematics contained in 13210A manuals dated November 1974 and + earlier show that CRS does not clear the status register, but examining + the hardware PCA shows that it does. The simulator implements the + hardware behavior. + + 4. The schematics contained in 13210A manuals dated November 1974 and + earlier show that CRS clears the attention register, but examining the + hardware PCA shows that it does not. The signal marked CRS is actually + the XFER CYL signal from the sequencer, so the register is actually + cleared when a Check Status or Seek command is issued. However, later + PCAs did add CRS to the other two clearing conditions. The simulator + implements this later behavior. */ uint32 dpcio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) @@ -625,6 +819,11 @@ while (working_set) { if (dp_ctype == A12557) /* 12557? */ dpc.command = CLEAR; /* clear command */ + + for (drv = 0; drv < DP_NUMDRV; drv++) /* clear drive status */ + dpc_sta [drv] &= /* for each drive */ + ~(STA_1ST | STA_OVR | STA_RWU | STA_ACU | STA_EOC + | STA_AER | STA_FLG | STA_DTE); break; @@ -654,6 +853,11 @@ while (working_set) { drv = CW_GETDRV (dpc_obuf); /* get fnc, drv */ fnc = CW_GETFNC (dpc_obuf); /* from cmd word */ + if (fnc != FNC_STA) /* if this is not a status command */ + dpc_sta [drv] &= /* then clear the status register */ + ~(STA_OVR | STA_RWU | STA_ACU | STA_EOC + | STA_AER | STA_FLG | STA_DTE); + switch (fnc) { /* case on fnc */ case FNC_SEEK: /* seek */ @@ -732,7 +936,7 @@ dpc_eoc = 0; /* clear end cyl */ dpc_busy = drv + 1; /* set busy */ dpd_xfer = 1; /* xfer in prog */ dpc_unit[drv].FNC = fnc; /* save function */ -dpc_sta[drv] = dpc_sta[drv] & ~STA_ATN; /* clear ATN */ +dpc_sta[drv] &= ~(STA_ATN | STA_1ST); /* clear Attention and First Status */ sim_activate (&dpc_unit[drv], time); /* activate unit */ return; } @@ -755,6 +959,8 @@ return; Status check - transfer status, finish operation Check data chk - transfer sector count + + The 12557A clears status after a Check Status command. The 13210A does not. */ t_stat dpd_svc (UNIT *uptr) @@ -836,10 +1042,14 @@ switch (uptr->FNC) { /* case function */ dpdio (&dpd_dib, ioENF, 0); /* set dch flg */ } - dpc_sta[drv] = dpc_sta[drv] & /* clr sta flags */ - ~(STA_ATN | STA_1ST | STA_OVR | - STA_RWU | STA_ACU | STA_EOC | - STA_AER | STA_FLG | STA_DTE); + if (dp_ctype == A13210) + dpc_sta [drv] &= ~STA_ATN; /* clear the current drive's attention bit */ + else + dpc_sta[drv] &= + ~(STA_ATN | STA_1ST | STA_OVR | + STA_RWU | STA_ACU | STA_EOC | + STA_AER | STA_FLG | STA_DTE); + dpc_poll = 1; /* enable polling */ for (i = 0; i < DP_NUMDRV; i++) { /* loop thru drives */ if (dpc_sta[i] & STA_ATN) { /* any ATN set? */ @@ -1063,15 +1273,44 @@ return SCPE_OK; } -/* Attach routine */ +/* Attach a drive unit. + + The specified file is attached to the indicated drive unit, and the heads are + loaded, which will will set the First Status and Attention bits in the drive + status. If a new file is specified, the file is initialized to its capacity + by writing a zero to the last byte in the file. + + + Implementation notes: + + 1. The C standard says, "A binary stream need not meaningfully support fseek + calls with a whence value of SEEK_END," so instead we determine the + offset from the start of the file to the last byte and seek there. +*/ t_stat dpc_attach (UNIT *uptr, CONST char *cptr) { -t_stat r; +t_stat result; +t_addr offset; +const uint8 zero = 0; -r = attach_unit (uptr, cptr); /* attach unit */ -if (r == SCPE_OK) dpc_load_unload (uptr, 0, NULL, NULL);/* if OK, load heads */ -return r; +result = attach_unit (uptr, cptr); /* attach the drive */ + +if (result == SCPE_OK) { /* if the attach was successful */ + dpc_load_unload (uptr, 0, NULL, NULL); /* then load the heads */ + + if (sim_switches & SWMASK ('N')) { /* if this is a new disc image */ + offset = (t_addr) /* then determine the offset of */ + (uptr->capac * sizeof (int16) - sizeof zero); /* the last byte in a full-sized file */ + + if (sim_fseek (uptr->fileref, offset, SEEK_SET) != 0 /* seek to the last byte */ + || fwrite (&zero, sizeof zero, 1, uptr->fileref) == 0 /* and write a zero to fill */ + || fflush (uptr->fileref) != 0) /* the file to its capacity */ + clearerr (uptr->fileref); /* clear and ignore any errors */ + } + } + +return result; /* return the result of the attach */ } @@ -1140,82 +1379,278 @@ return SCPE_OK; } -/* 7900/7901 bootstrap routine (HP 12992F ROM) */ +/* 7900/2870 disc bootstrap loaders (BMDL and 12992F). -const BOOT_ROM dp_rom = { - 0106710, /*ST CLC DC ; clr dch */ - 0106711, /* CLC CC ; clr cch */ - 0017757, /* JSB STAT ; get status */ - 0067746, /*SK LDB SKCMD ; seek cmd */ - 0106610, /* OTB DC ; cyl # */ - 0103710, /* STC DC,C ; to dch */ - 0106611, /* OTB CC ; seek cmd */ - 0103711, /* STC CC,C ; to cch */ - 0102310, /* SFS DC ; addr wd ok? */ - 0027710, /* JMP *-1 ; no, wait */ - 0006400, /* CLB */ - 0102501, /* LIA 1 ; read switches */ - 0002011, /* SLA,RSS ; <0> set? */ - 0047747, /* ADB BIT9 ; head 2 = removable */ - 0106610, /* OTB DC ; head/sector */ - 0103710, /* STC DC,C ; to dch */ - 0102311, /* SFS CC ; seek done? */ - 0027720, /* JMP *-1 ; no, wait */ - 0017757, /* JSB STAT ; get status */ - 0067776, /* LDB DMACW ; DMA control */ - 0106606, /* OTB 6 */ - 0067750, /* LDB ADDR1 ; memory addr */ - 0106602, /* OTB 2 */ - 0102702, /* STC 2 ; flip DMA ctrl */ - 0067752, /* LDB CNT ; word count */ - 0106602, /* OTB 2 */ - 0063745, /* LDB RDCMD ; read cmd */ - 0102611, /* OTA CC ; to cch */ - 0103710, /* STC DC,C ; start dch */ - 0103706, /* STC 6,C ; start DMA */ - 0103711, /* STC CC,C ; start cch */ - 0102311, /* SFS CC ; done? */ - 0027737, /* JMP *-1 ; no, wait */ - 0017757, /* JSB STAT ; get status */ - 0027775, /* JMP XT ; done */ - 0037766, /*FSMSK 037766 ; status mask */ - 0004000, /*STMSK 004000 ; unsafe mask */ - 0020000, /*RDCMD 020000 ; read cmd */ - 0030000, /*SKCMD 030000 ; seek cmd */ - 0001000, /*BIT9 001000 ; head 2 select */ - 0102011, /*ADDR1 102011 */ - 0102055, /*ADDR2 102055 */ - 0164000, /*CNT -6144. */ - 0, 0, 0, 0, /* unused */ - 0000000, /*STAT 0 */ - 0002400, /* CLA ; status request */ - 0102611, /* OTC CC ; to cch */ - 0103711, /* STC CC,C ; start cch */ - 0102310, /* SFS DC ; done? */ - 0027763, /* JMP *-1 */ - 0102510, /* LIA DC ; get status */ - 0013743, /* AND FSMSK ; mask 15,14,3,0 */ - 0002003, /* SZA,RSS ; drive ready? */ - 0127757, /* JMP STAT,I ; yes */ - 0013744, /* AND STMSK ; fault? */ - 0002002, /* SZA */ - 0102030, /* HLT 30 ; yes */ - 0027700, /* JMP ST ; no, retry */ - 0117751, /*XT JSB ADDR2,I ; start program */ - 0120010, /*DMACW 120000+DC */ - 0000000 /* -ST */ + The Basic Moving-Head Disc Loader (BMDL) consists of two programs. The + program starting at address x7700 loads absolute paper tapes into memory. + The program starting at address x7750 loads a disc-resident bootstrap from + the 7900 or 2870 disc drive into memory. The S register setting does not + affect loader operation. + + For a 2100/14/15/16 CPU, entering a LOAD DPC or BOOT DPC command loads the + BMDL into memory and executes the disc portion starting at x7750. The + bootstrap reads 6144 (for a 7900) or 3072 (for a 2870) words from cylinder 0, + head 0, sector 0 into memory starting at location 2011 octal. Loader + execution ends with the following instruction: + + * JSB 2055,I - the disc read completed. + + The BMDL configures DMA for an oversize (~32000 word) transfer and expects + the disc to terminate the operation with End of Cylinder (EOC) status. + + The HP 1000 uses the 12992F boot loader ROM to bootstrap the 7900 disc. Bit + 0 of the S register determines whether the boot extension is read from + subchannel 0 (the fixed platter) or subchannel 1 (the removable platter). + The loader reads 6144 words from cylinder 0 sector 0 of the specified + subchannel into memory starting at location 2011 octal. Loader execution + ends with one of the following instructions: + + * HLT 30 - a drive fault occurred. + * JSB 2055,I - the disc read succeeded. + + The loader automatically retries the operations for all disc errors other + than a drive fault. + + + Implementation notes: + + 1. After the BMDL has been loaded into memory, the paper tape portion may be + executed manually by setting the P register to the starting address + (x7700). + + 2. For compatibility with the "cpu_copy_loader" routine, the BMDL device I/O + instructions address select codes 10 and 11. + + 3. As published, the BMDL is configured to read from head 0 (the removable + platter, a.k.a. subchannel 1). To read from head 2 (the fixed platter, + subchannel 0), the head/sector control word must be changed. +*/ + +#define BMDL_SUBCHANNEL_0 031000 /* BMDL control word to address subchannel 0 instead of 1 */ + +static const LOADER_ARRAY dp_loaders = { + { /* HP 21xx Basic Moving-Head Disc Loader (BMDL-7900) */ + 050, /* loader starting index */ + 077, /* DMA index */ + 034, /* FWA index */ + { 0002401, /* 77700: PTAPE CLA,RSS Paper Tape start */ + 0063721, /* 77701: LDA 77721 */ + 0107700, /* 77702: CLC 0,C */ + 0002307, /* 77703: CCE,INA,SZA,RSS */ + 0102077, /* 77704: HLT 77 */ + 0017735, /* 77705: JSB 77735 */ + 0007307, /* 77706: CMB,CCE,INB,SZB,RSS */ + 0027702, /* 77707: JMP 77702 */ + 0077733, /* 77710: STB 77733 */ + 0017735, /* 77711: JSB 77735 */ + 0017735, /* 77712: JSB 77735 */ + 0074000, /* 77713: STB 0 */ + 0077747, /* 77714: STB 77747 */ + 0047734, /* 77715: ADB 77734 */ + 0002140, /* 77716: SEZ,CLE */ + 0102055, /* 77717: HLT 55 */ + 0017735, /* 77720: JSB 77735 */ + 0177747, /* 77721: STB 77747,I */ + 0040001, /* 77722: ADA 1 */ + 0067747, /* 77723: LDB 77747 */ + 0006104, /* 77724: CLE,INB */ + 0037733, /* 77725: ISZ 77733 */ + 0027714, /* 77726: JMP 77714 */ + 0017735, /* 77727: JSB 77735 */ + 0054000, /* 77730: CPB 0 */ + 0027701, /* 77731: JMP 77701 */ + 0102011, /* 77732: HLT 11 */ + 0000000, /* 77733: OCT 000000 */ + 0100100, /* 77734: OCT 1n0100 */ + 0000000, /* 77735: NOP */ + 0006400, /* 77736: CLB */ + 0103710, /* 77737: STC 10,C */ + 0102310, /* 77740: SFS 10 */ + 0027740, /* 77741: JMP 77740 */ + 0107410, /* 77742: MIB 10,C */ + 0002240, /* 77743: SEZ,CME */ + 0127735, /* 77744: JMP 77735,I */ + 0005727, /* 77745: BLF,BLF */ + 0027737, /* 77746: JMP 77737 */ + 0000000, /* 77747: OCT 000000 */ + 0030000, /* 77750: DISC IOR 0 Disc start */ + 0067741, /* 77751: LDB 77741 */ + 0106611, /* 77752: OTB 11 */ + 0103711, /* 77753: STC 11,C */ + 0063750, /* 77754: LDA 77750 */ + 0102610, /* 77755: OTA 10 */ + 0103710, /* 77756: STC 10,C */ + 0102611, /* 77757: OTA 11 */ + 0103711, /* 77760: STC 11,C */ + 0063777, /* 77761: LDA 77777 */ + 0102606, /* 77762: OTA 6 */ + 0063732, /* 77763: LDA 77732 */ + 0102602, /* 77764: OTA 2 */ + 0103710, /* 77765: STC 10,C */ + 0102702, /* 77766: STC 2 */ + 0102602, /* 77767: OTA 2 */ + 0106611, /* 77770: OTB 11 */ + 0103710, /* 77771: STC 10,C */ + 0103706, /* 77772: STC 6,C */ + 0103711, /* 77773: STC 11,C */ + 0102311, /* 77774: SFS 11 */ + 0027774, /* 77775: JMP 77774 */ + 0117717, /* 77776: JSB 77717,I */ + 0120010 } }, /* 77777: OCT 120010 */ + + { /* HP 1000 Loader ROM (12992F) */ + IBL_START, /* loader starting index */ + IBL_DMA, /* DMA index */ + IBL_FWA, /* FWA index */ + { 0106710, /* 77700: ST CLC DC ; clr dch */ + 0106711, /* 77701: CLC CC ; clr cch */ + 0017757, /* 77702: JSB STAT ; get status */ + 0067746, /* 77703: SK LDB SKCMD ; seek cmd */ + 0106610, /* 77704: OTB DC ; cyl # */ + 0103710, /* 77705: STC DC,C ; to dch */ + 0106611, /* 77706: OTB CC ; seek cmd */ + 0103711, /* 77707: STC CC,C ; to cch */ + 0102310, /* 77710: SFS DC ; addr wd ok? */ + 0027710, /* 77711: JMP *-1 ; no, wait */ + 0006400, /* 77712: CLB */ + 0102501, /* 77713: LIA 1 ; read switches */ + 0002011, /* 77714: SLA,RSS ; <0> set? */ + 0047747, /* 77715: ADB BIT9 ; head 2 = removable */ + 0106610, /* 77716: OTB DC ; head/sector */ + 0103710, /* 77717: STC DC,C ; to dch */ + 0102311, /* 77720: SFS CC ; seek done? */ + 0027720, /* 77721: JMP *-1 ; no, wait */ + 0017757, /* 77722: JSB STAT ; get status */ + 0067776, /* 77723: LDB DMACW ; DMA control */ + 0106606, /* 77724: OTB 6 */ + 0067750, /* 77725: LDB ADDR1 ; memory addr */ + 0106602, /* 77726: OTB 2 */ + 0102702, /* 77727: STC 2 ; flip DMA ctrl */ + 0067752, /* 77730: LDB CNT ; word count */ + 0106602, /* 77731: OTB 2 */ + 0063745, /* 77732: LDB RDCMD ; read cmd */ + 0102611, /* 77733: OTA CC ; to cch */ + 0103710, /* 77734: STC DC,C ; start dch */ + 0103706, /* 77735: STC 6,C ; start DMA */ + 0103711, /* 77736: STC CC,C ; start cch */ + 0102311, /* 77737: SFS CC ; done? */ + 0027737, /* 77740: JMP *-1 ; no, wait */ + 0017757, /* 77741: JSB STAT ; get status */ + 0027775, /* 77742: JMP XT ; done */ + 0037766, /* 77743: FSMSK OCT 037766 ; status mask */ + 0004000, /* 77744: STMSK OCT 004000 ; unsafe mask */ + 0020000, /* 77745: RDCMD OCT 020000 ; read cmd */ + 0030000, /* 77746: SKCMD OCT 030000 ; seek cmd */ + 0001000, /* 77747: BIT9 OCT 001000 ; head 2 select */ + 0102011, /* 77750: ADDR1 OCT 102011 */ + 0102055, /* 77751: ADDR2 OCT 102055 */ + 0164000, /* 77752: CNT DEC -6144. */ + 0000000, /* 77753: NOP */ + 0000000, /* 77754: NOP */ + 0000000, /* 77755: NOP */ + 0000000, /* 77756: NOP */ + 0000000, /* 77757: STAT NOP */ + 0002400, /* 77760: CLA ; status request */ + 0102611, /* 77761: OTC CC ; to cch */ + 0103711, /* 77762: STC CC,C ; start cch */ + 0102310, /* 77763: SFS DC ; done? */ + 0027763, /* 77764: JMP *-1 */ + 0102510, /* 77765: LIA DC ; get status */ + 0013743, /* 77766: AND FSMSK ; mask 15,14,3,0 */ + 0002003, /* 77767: SZA,RSS ; drive ready? */ + 0127757, /* 77770: JMP STAT,I ; yes */ + 0013744, /* 77771: AND STMSK ; fault? */ + 0002002, /* 77772: SZA */ + 0102030, /* 77773: HLT 30 ; yes */ + 0027700, /* 77774: JMP ST ; no, retry */ + 0117751, /* 77775: XT JSB ADDR2,I ; start program */ + 0120010, /* 77776: DMACW ABS 120000+DC */ + 0000000 } } /* 77777: ABS -ST */ }; + +/* Device boot routine. + + This routine is called directly by the BOOT DPC and LOAD DPC commands to copy + the device bootstrap into the upper 64 words of the logical address space. + It is also called indirectly by a BOOT CPU or LOAD CPU command when the + specified HP 1000 loader ROM socket contains a 12992F ROM. + + When called in response to a BOOT DPC or LOAD DPC command, the "unitno" + parameter indicates the unit number specified in the BOOT command or is zero + for the LOAD command, and "dptr" points at the DPC device structure. The + bootstrap supports loading only from unit 0, and the command will be rejected + if another unit is specified (e.g., BOOT DPC1). Otherwise, depending on the + current CPU model, the BMDL or 12992F loader ROM will be copied into memory + and configured for the DPD/DPC select code pair. If the CPU is a 1000, the S + register will be set as it would be by the front-panel microcode. + + When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the + select code to be used for configuration, and "dptr" will be NULL. As above, + the BMDL or 12992F loader ROM will be copied into memory and configured for + the specified select code. The S register is assumed to be set correctly on + entry and is not modified. + + In either case, if the CPU is a 21xx model, the paper tape portion of the + BMDL will be automatically configured for the select code of the paper tape + reader. + + For the 12992F boot loader ROM for the HP 1000, the S register is set as + follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | 0 0 | select code | reserved | 0 0 | S | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + S = the subchannel number + + Bit 0 specifies the subchannel containing the operating system. For the + 7900, either the fixed (0) or removable (1) platter may be specified. For + the 7901, bit 0 must be 1. If the -R switch is specified for the BOOT or + LOAD command, the loader ROM will be configured to boot from the removable + platter instead of the fixed platter. + + Bits 5-3 are nominally zero but are reserved for the target operating system. + For example, RTE uses bit 5 to indicate whether a standard (0) or + reconfiguration (1) boot is desired. + + + Implementation notes: + + 1. In hardware, the BMDL was hand-configured for the disc and paper tape + reader select codes when it was installed on a given system. Under + simulation, the LOAD and BOOT commands automatically configure the BMDL + to the current select codes of the PTR and DP devices. + + 2. As installed, the BMDL is configured to read from the removable platter + (a.k.a. subchannel 1). If the -R switch is specified to read from the + fixed platter (subchannel 0), the head number in the head/sector control + word in memory is changed from 0 to 2. +*/ + t_stat dpc_boot (int32 unitno, DEVICE *dptr) { -const int32 dev = dpd_dib.select_code; /* data chan select code */ +static const HP_WORD dp_preserved = 0000070u; /* S-register bits 5-3 are preserved */ +const uint32 subchannel = sim_switches & SWMASK ('R') ? 1 : 0; /* the selected boot subchannel */ +t_stat status; -if (unitno != 0) /* boot supported on drive unit 0 only */ - return SCPE_NOFNC; /* report "Command not allowed" if attempted */ +if (dptr == NULL) /* if we are being called for a BOOT/LOAD CPU */ + status = cpu_copy_loader (dp_loaders, unitno, /* then copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* but do not alter the S register */ -cpu_ibl (dp_rom, dev, IBL_OPT, /* copy the boot ROM to memory and configure */ - IBL_DP | IBL_SET_SC (dev) /* the S register accordingly */ - | (sim_switches & SWMASK ('R') ? IBL_DP_REM : 0)); +else if (unitno != 0) /* otherwise a BOOT DPC for a non-zero unit */ + return SCPE_NOFNC; /* is rejected as unsupported */ -return SCPE_OK; +else /* otherwise this is a BOOT/LOAD DPC */ + status = cpu_copy_loader (dp_loaders, dpd_dib.select_code, /* so copy the boot loader to memory */ + dp_preserved, subchannel); /* and configure the S register if 1000 CPU */ + +if (status == SCPE_OK && subchannel == 0 /* if loader installed OK and boot is from subchan 0 */ + && (PR & IBL_MASK) == dp_loaders [0].start_index) /* and the BMDL was installed */ + mem_deposit (PR, BMDL_SUBCHANNEL_0); /* then change the control word to use head 2 */ + +return status; /* return the status of the installation */ } diff --git a/HP2100/hp2100_dq.c b/HP2100/hp2100_dq.c index 3ae777c0..48c9f89f 100644 --- a/HP2100/hp2100_dq.c +++ b/HP2100/hp2100_dq.c @@ -1,7 +1,7 @@ /* hp2100_dq.c: HP 2100 12565A Disc Interface and 2883 disc drive simulator Copyright (c) 1993-2006, Bill McDermith - Copyright (c) 2004-2017, J. David Bryan + Copyright (c) 2004-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,8 @@ DQ 12565A Disc Interface and 2883 disc drive + 27-Feb-18 JDB Added the BMDL + 15-Feb-18 JDB ATTACH -N now creates a full-size disc image 03-Aug-17 JDB Changed perror call for I/O errors to cprintf 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" 09-Mar-17 JDB Deprecated LOCKED/WRITEENABLED for PROTECT/UNPROTECT @@ -885,15 +887,43 @@ for (drv = 0; drv < DQ_NUMDRV; drv++) { /* loop thru drives */ return SCPE_OK; } -/* Attach routine */ +/* Attach a drive unit. + + The specified file is attached to the indicated drive unit, and the heads are + loaded. If a new file is specified, the file is initialized to its capacity + by writing a zero to the last byte in the file. + + + Implementation notes: + + 1. The C standard says, "A binary stream need not meaningfully support fseek + calls with a whence value of SEEK_END," so instead we determine the + offset from the start of the file to the last byte and seek there. +*/ t_stat dqc_attach (UNIT *uptr, CONST char *cptr) { -t_stat r; +t_stat result; +t_addr offset; +const uint8 zero = 0; -r = attach_unit (uptr, cptr); /* attach unit */ -if (r == SCPE_OK) dqc_load_unload (uptr, 0, NULL, NULL);/* if OK, load heads */ -return r; +result = attach_unit (uptr, cptr); /* attach the drive */ + +if (result == SCPE_OK) { /* if the attach was successful */ + dqc_load_unload (uptr, 0, NULL, NULL); /* then load the heads */ + + if (sim_switches & SWMASK ('N')) { /* if this is a new disc image */ + offset = (t_addr) /* then determine the offset of */ + (uptr->capac * sizeof (int16) - sizeof zero); /* the last byte in a full-sized file */ + + if (sim_fseek (uptr->fileref, offset, SEEK_SET) != 0 /* seek to the last byte */ + || fwrite (&zero, sizeof zero, 1, uptr->fileref) == 0 /* and write a zero to fill */ + || fflush (uptr->fileref) != 0) /* the file to its capacity */ + clearerr (uptr->fileref); /* clear and ignore any errors */ + } + } + +return result; /* return the result of the attach */ } /* Detach routine */ @@ -915,84 +945,227 @@ else uptr->flags = uptr->flags & ~UNIT_UNLOAD; /* indicate load */ return SCPE_OK; } -/* 7900/7901/2883/2884 bootstrap routine (HP 12992A ROM) */ -const BOOT_ROM dq_rom = { - 0102501, /*ST LIA 1 ; get switches */ - 0106501, /* LIB 1 */ - 0013765, /* AND D7 ; isolate hd */ - 0005750, /* BLF,CLE,SLB */ - 0027741, /* JMP RD */ - 0005335, /* RBR,SLB,ERB ; <13>->E, set = 2883 */ - 0027717, /* JMP IS */ - 0102611, /*LP OTA CC ; do 7900 status to */ - 0103711, /* STC CC,C ; clear first seek */ - 0102310, /* SFS DC */ - 0027711, /* JMP *-1 */ - 0002004, /* INA ; get next drive */ - 0053765, /* CPA D7 ; all cleared? */ - 0002001, /* RSS */ - 0027707, /* JMP LP */ - 0067761, /*IS LDB SEEKC ; get seek comnd */ - 0106610, /* OTB DC ; issue cyl addr (0) */ - 0103710, /* STC DC,C ; to dch */ - 0106611, /* OTB CC ; seek cmd */ - 0103711, /* STC CC,C ; to cch */ - 0102310, /* SFS DC ; addr wd ok? */ - 0027724, /* JMP *-1 ; no, wait */ - 0006400, /* CLB */ - 0102501, /* LIA 1 ; get switches */ - 0002051, /* SEZ,SLA,RSS ; subchan = 1 or ISS */ - 0047770, /* ADB BIT9 ; head 2 */ - 0106610, /* OTB DC ; head/sector */ - 0103710, /* STC DC,C ; to dch */ - 0102311, /* SFS CC ; seek done? */ - 0027734, /* JMP *-1 ; no, wait */ - 0063731, /* LDA ISSRD ; get read read */ - 0002341, /* SEZ,CCE,RSS ; iss disc? */ - 0001100, /* ARS ; no, make 7900 read */ - 0067776, /*RD LDB DMACW ; DMA control */ - 0106606, /* OTB 6 */ - 0067762, /* LDB ADDR1 ; memory addr */ - 0077741, /* STB RD ; make non re-executable */ - 0106602, /* OTB 2 */ - 0102702, /* STC 2 ; flip DMA ctrl */ - 0067764, /* LDB COUNT ; word count */ - 0106602, /* OTB 2 */ - 0002041, /* SEZ,RSS */ - 0027766, /* JMP NW */ - 0102611, /* OTA CC ; to cch */ - 0103710, /* STC DC,C ; start dch */ - 0103706, /* STC 6,C ; start DMA */ - 0103711, /* STC CC,C ; start cch */ - 0037773, /* ISZ SK */ - 0027773, /* JMP SK */ - 0030000, /*SEEKC 030000 */ - 0102011, /*ADDR1 102011 */ - 0102055, /*ADDR2 102055 */ - 0164000, /*COUNT -6144. */ - 0000007, /*D7 7 */ - 0106710, /*NW CLC DC ; set 'next wd is cmd' flag */ - 0001720, /* ALF,ALF ; move to head number loc */ - 0001000, /*BIT9 ALS */ - 0103610, /* OTA DC,C ; output cold load cmd */ - 0103706, /* STC 6,C ; start DMA */ - 0102310, /* SFS DC ; done? */ - 0027773, /* JMP *-1 ; no, wait */ - 0117763, /*XT JSB ADDR2,I ; start program */ - 0120010, /*DMACW 120000+DC */ - 0000000 /* -ST */ +/* 2883 disc bootstrap loaders (BMDL and 12992A). + + The Basic Moving-Head Disc Loader (BMDL) consists of two programs. The + program starting at address x7700 loads absolute paper tapes into memory. + The program starting at address x7750 loads a disc-resident bootstrap from + the 2883 disc drive into memory. The S register setting does not affect + loader operation. + + For a 2100/14/15/16 CPU, entering a LOAD DQC or BOOT DQC command loads the + BMDL into memory and executes the disc portion starting at x7750. For a 1000 + CPU, the 12992A boot loader ROM is used. In either case, the bootstrap reads + 128 words from cylinder 0, head 0, sector 0 into memory starting at location + 2011 octal. Loader execution ends with the following instruction: + + * JMP 2055,I - the disc read completed. + + Note that the BMDL does a JMP 2055,I and the 12992A does a JSB 2055,I. +*/ + +static const LOADER_ARRAY dq_loaders = { + { /* HP 21xx Basic Moving-Head Disc Loader (BMDL-2883) */ + 050, /* loader starting index */ + 076, /* DMA index */ + 077, /* FWA index */ + { 0002701, /* 77700: PTAPE CLA,CCE,RSS Paper Tape start */ + 0063722, /* 77701: LDA 77722 */ + 0002307, /* 77702: CCE,INA,SZA,RSS */ + 0102077, /* 77703: HLT 77 */ + 0017735, /* 77704: JSB 77735 */ + 0007307, /* 77705: CMB,CCE,INB,SZB,RSS */ + 0027702, /* 77706: JMP 77702 */ + 0077733, /* 77707: STB 77733 */ + 0017735, /* 77710: JSB 77735 */ + 0017735, /* 77711: JSB 77735 */ + 0074000, /* 77712: STB 0 */ + 0077734, /* 77713: STB 77734 */ + 0067734, /* 77714: LDB 77734 */ + 0047777, /* 77715: ADB 77777 */ + 0002040, /* 77716: SEZ */ + 0102055, /* 77717: HLT 55 */ + 0017735, /* 77720: JSB 77735 */ + 0040001, /* 77721: ADA 1 */ + 0177734, /* 77722: STB 77734,I */ + 0037734, /* 77723: ISZ 77734 */ + 0000040, /* 77724: CLE */ + 0037733, /* 77725: ISZ 77733 */ + 0027714, /* 77726: JMP 77714 */ + 0017735, /* 77727: JSB 77735 */ + 0054000, /* 77730: CPB 0 */ + 0027701, /* 77731: JMP 77701 */ + 0102011, /* 77732: HLT 11 */ + 0000000, /* 77733: NOP */ + 0000000, /* 77734: NOP */ + 0000000, /* 77735: NOP */ + 0006600, /* 77736: CLB,CME */ + 0103710, /* 77737: STC 10,C */ + 0102310, /* 77740: SFS 10 */ + 0027740, /* 77741: JMP 77740 */ + 0106410, /* 77742: MIB 10 */ + 0002041, /* 77743: SEZ,RSS */ + 0127735, /* 77744: JMP 77735,I */ + 0005767, /* 77745: BLF,CLE,BLF */ + 0027737, /* 77746: JMP 77737 */ + 0177600, /* 77747: OCT 177600 */ + 0063775, /* 77750: DISC LDA 77775 Disc start */ + 0102611, /* 77751: OTA 11 */ + 0103711, /* 77752: STC 11,C */ + 0102311, /* 77753: SFS 11 */ + 0027753, /* 77754: JMP 77753 */ + 0067776, /* 77755: LDB 77776 */ + 0106606, /* 77756: OTB 6 */ + 0067732, /* 77757: LDB 77732 */ + 0106602, /* 77760: OTB 2 */ + 0102702, /* 77761: STC 2 */ + 0067747, /* 77762: LDB 77747 */ + 0106602, /* 77763: OTB 2 */ + 0001000, /* 77764: ALS */ + 0106711, /* 77765: CLC 11 */ + 0102611, /* 77766: OTA 11 */ + 0103710, /* 77767: STC 10,C */ + 0103706, /* 77770: STC 6,C */ + 0103711, /* 77771: STC 11,C */ + 0102311, /* 77772: SFS 11 */ + 0027772, /* 77773: JMP 77772 */ + 0127717, /* 77774: JMP 77717,I */ + 0020000, /* 77775: OCT 020000 */ + 0120010, /* 77776: ABS 120000+DC */ + 0100100 } }, /* 77777: ABS -PTAPE */ + + { /* HP 1000 Loader ROM (12992A) */ + IBL_START, /* loader starting index */ + IBL_DMA, /* DMA index */ + IBL_FWA, /* FWA index */ + { 0102501, /* 77700: ST LIA 1 ; get switches */ + 0106501, /* 77701: LIB 1 */ + 0013765, /* 77702: AND D7 ; isolate hd */ + 0005750, /* 77703: BLF,CLE,SLB */ + 0027741, /* 77704: JMP RD */ + 0005335, /* 77705: RBR,SLB,ERB ; <13>->E, set = 2883 */ + 0027717, /* 77706: JMP IS */ + 0102611, /* 77707: LP OTA CC ; do 7900 status to */ + 0103711, /* 77710: STC CC,C ; clear first seek */ + 0102310, /* 77711: SFS DC */ + 0027711, /* 77712: JMP *-1 */ + 0002004, /* 77713: INA ; get next drive */ + 0053765, /* 77714: CPA D7 ; all cleared? */ + 0002001, /* 77715: RSS */ + 0027707, /* 77716: JMP LP */ + 0067761, /* 77717: IS LDB SEEKC ; get seek comnd */ + 0106610, /* 77720: OTB DC ; issue cyl addr (0) */ + 0103710, /* 77721: STC DC,C ; to dch */ + 0106611, /* 77722: OTB CC ; seek cmd */ + 0103711, /* 77723: STC CC,C ; to cch */ + 0102310, /* 77724: SFS DC ; addr wd ok? */ + 0027724, /* 77725: JMP *-1 ; no, wait */ + 0006400, /* 77726: CLB */ + 0102501, /* 77727: LIA 1 ; get switches */ + 0002051, /* 77730: SEZ,SLA,RSS ; subchan = 1 or ISS */ + 0047770, /* 77731: ADB BIT9 ; head 2 */ + 0106610, /* 77732: OTB DC ; head/sector */ + 0103710, /* 77733: STC DC,C ; to dch */ + 0102311, /* 77734: SFS CC ; seek done? */ + 0027734, /* 77735: JMP *-1 ; no, wait */ + 0063731, /* 77736: LDA ISSRD ; get read read */ + 0002341, /* 77737: SEZ,CCE,RSS ; iss disc? */ + 0001100, /* 77740: ARS ; no, make 7900 read */ + 0067776, /* 77741: RD LDB DMACW ; DMA control */ + 0106606, /* 77742: OTB 6 */ + 0067762, /* 77743: LDB ADDR1 ; memory addr */ + 0077741, /* 77744: STB RD ; make non re-executable */ + 0106602, /* 77745: OTB 2 */ + 0102702, /* 77746: STC 2 ; flip DMA ctrl */ + 0067764, /* 77747: LDB COUNT ; word count */ + 0106602, /* 77750: OTB 2 */ + 0002041, /* 77751: SEZ,RSS */ + 0027766, /* 77752: JMP NW */ + 0102611, /* 77753: OTA CC ; to cch */ + 0103710, /* 77754: STC DC,C ; start dch */ + 0103706, /* 77755: STC 6,C ; start DMA */ + 0103711, /* 77756: STC CC,C ; start cch */ + 0037773, /* 77757: ISZ SK */ + 0027773, /* 77760: JMP SK */ + 0030000, /* 77761: SEEKC OCT 030000 */ + 0102011, /* 77762: ADDR1 OCT 102011 */ + 0102055, /* 77763: ADDR2 OCT 102055 */ + 0164000, /* 77764: COUNT DEC -6144. */ + 0000007, /* 77765: D7 DEC 7 */ + 0106710, /* 77766: NW CLC DC ; set 'next wd is cmd' flag */ + 0001720, /* 77767: ALF,ALF ; move to head number loc */ + 0001000, /* 77770: BIT9 ALS */ + 0103610, /* 77771: OTA DC,C ; output cold load cmd */ + 0103706, /* 77772: STC 6,C ; start DMA */ + 0102310, /* 77773: SFS DC ; done? */ + 0027773, /* 77774: JMP *-1 ; no, wait */ + 0117763, /* 77775: XT JSB ADDR2,I ; start program */ + 0120010, /* 77776: DMACW ABS 120000+DC */ + 0170100 } } /* 77777: MAXAD ABS -ST ; max addr */ }; + +/* Device boot routine. + + This routine is called directly by the BOOT DQC and LOAD DQC commands to copy + the device bootstrap into the upper 64 words of the logical address space. + It is also called indirectly by a BOOT CPU or LOAD CPU command when the + specified HP 1000 loader ROM socket contains a 12992A ROM. + + When called in response to a BOOT DQC or LOAD DQC command, the "unitno" + parameter indicates the unit number specified in the BOOT command or is zero + for the LOAD command, and "dptr" points at the DQC device structure. The + bootstrap supports loading only from unit 0, and the command will be rejected + if another unit is specified (e.g., BOOT DQC1). Otherwise, depending on the + current CPU model, the BMDL or 12992A loader ROM will be copied into memory + and configured for the DQD/DQC select code pair. If the CPU is a 1000, the S + register will be set as it would be by the front-panel microcode. + + When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the + select code to be used for configuration, and "dptr" will be NULL. As above, + the BMDL or 12992A loader ROM will be copied into memory and configured for + the specified select code. The S register is assumed to be set correctly on + entry and is not modified. + + In either case, if the CPU is a 21xx model, the paper tape portion of the + BMDL will be automatically configured for the select code of the paper tape + reader. + + For the 12992A boot loader ROM for the HP 1000, the S register is set as + follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | 1 0 | select code | reserved | 0 0 0 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Bits 5-3 are nominally zero but are reserved for the target operating system. + For example, RTE uses bit 5 to indicate whether a standard (0) or + reconfiguration (1) boot is desired. + + + Implementation notes: + + 1. In hardware, the BMDL was hand-configured for the disc and paper tape + reader select codes when it was installed on a given system. Under + simulation, the LOAD and BOOT commands automatically configure the BMDL + to the current select codes of the PTR and DQ devices. +*/ + t_stat dqc_boot (int32 unitno, DEVICE *dptr) { -const int32 dev = dqd_dib.select_code; /* data chan select code */ +static const HP_WORD dq_preserved = 0000070u; /* S-register bits 5-3 are preserved */ +static const HP_WORD dq_standard = 0020000u; /* S-register bit 13 set for a standard boot */ -if (unitno != 0) /* boot supported on drive unit 0 only */ - return SCPE_NOFNC; /* report "Command not allowed" if attempted */ +if (dptr == NULL) /* if we are being called for a BOOT/LOAD CPU */ + return cpu_copy_loader (dq_loaders, unitno, /* then copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* but do not alter the S register */ -cpu_ibl (dq_rom, dev, IBL_OPT, /* copy the boot ROM to memory and configure */ - IBL_DQ | IBL_SET_SC (dev)); /* the S register accordingly */ +else if (unitno != 0) /* otherwise a BOOT DQC for a non-zero unit */ + return SCPE_NOFNC; /* is rejected as unsupported */ -return SCPE_OK; +else /* otherwise this is a BOOT/LOAD DQC */ + return cpu_copy_loader (dq_loaders, dqd_dib.select_code, /* so copy the boot loader to memory */ + dq_preserved, dq_standard); /* and configure the S register if 1000 CPU */ } diff --git a/HP2100/hp2100_dr.c b/HP2100/hp2100_dr.c index 50a21a74..48c1b7f7 100644 --- a/HP2100/hp2100_dr.c +++ b/HP2100/hp2100_dr.c @@ -1,7 +1,7 @@ /* hp2100_dr.c: HP 2100 12606B/12610B fixed head disk/drum simulator Copyright (c) 1993-2016, Robert M. Supnik - Copyright (c) 2017 J. David Bryan + Copyright (c) 2017-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,6 +27,8 @@ DR 12606B 2770/2771 fixed head disk 12610B 2773/2774/2775 drum + 27-Feb-18 JDB Added the BBDL, reworked drc_boot to use cpu_copy_loader + 21-Feb-18 JDB ATTACH -N now creates a full-size disc image 19-Jul-17 JDB Removed "dr_stopioe" variable and register 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" 27-Feb-17 JDB ibl_copy no longer returns a status code @@ -637,15 +639,29 @@ sim_cancel (&drd_unit[TMR_INH]); return SCPE_OK; } -/* Attach routine */ +/* Attach a drive unit. + + The specified file is attached to the indicated drive unit. If a new file is + specified, the file is initialized to its capacity by setting the high-water + mark to the last byte in the file. +*/ t_stat drc_attach (UNIT *uptr, CONST char *cptr) { -int32 sz = sz_tab[DR_GETSZ (uptr->flags)]; +t_stat result; +const int32 sz = sz_tab [DR_GETSZ (uptr->flags)]; -if (sz == 0) return SCPE_IERR; -uptr->capac = sz; -return attach_unit (uptr, cptr); +if (sz == 0) + return SCPE_IERR; +else + uptr->capac = sz; + +result = attach_unit (uptr, cptr); /* attach the drive */ + +if (result == SCPE_OK && (sim_switches & SWMASK ('N'))) /* if the attach was successful and a new image was specified */ + uptr->hwmark = (uint32) uptr->capac; /* then set the high-water mark to the last byte */ + +return result; /* return the result of the attach */ } /* Set protected track count */ @@ -712,125 +728,159 @@ return SCPE_OK; } -/* Basic Binary Disc Loader. +/* 277x fixed disc/drum bootstrap loaders (BBDL). - The Basic Binary Disc Loader (BBDL) contains two programs. The program + The Basic Binary Disc Loader (BBDL) consists of two programs. The program starting at address x7700 loads absolute paper tapes into memory. The program starting at address x7760 loads a disc-resident bootstrap from the - 277x fixed-head disc/drum. Entering a BOOT DRC command loads the BBDL into - memory and executes the disc portion starting at x7760. The bootstrap issues - a CLC 0,C to clear the disc track and sector address registers and then sets - up a 64-word read from track 0 sector 0 to memory locations 0-77 octal. It - then stores a JMP * instruction in location 77, starts the read, and jumps to + 277x fixed-head disc/drum into memory. The S register setting does not + affect loader operation. + + Entering a LOAD DRC or BOOT DRC command loads the BBDL into memory and + executes the disc portion starting at x7760. The bootstrap issues a CLC 0,C + to clear the disc track and sector address registers and then sets up a + 64-word read from track 0 sector 0 to memory locations 0-77 octal. It then + stores a JMP * instruction in location 77, starts the read, and jumps to location 77. The JMP * causes the CPU to loop until the last word read from - the disc overlays location 77 which, typically, would be a JMP instruction to - the start of the disc-resident bootstrap. + the disc extension overlays location 77 which, typically, would be a JMP + instruction to the start of the disc-resident bootstrap. The success or + failure of the transfer is not checked. - In hardware, the BBDL was hand-configured for the disc and paper tape reader - select codes when it was installed on a given system. Under simulation, we - treat it as a standard HP 1000 loader, even though it is not structured that - way, and so the cpu_ibl mechanism used to load and configure it must be - augmented to account for the differences. + The HP 1000 does not support the 277x drives, so there is no 1000 boot loader + ROM for these peripherals. Attempting to LOAD DRC or BOOT DRC while the CPU + is configured as a 1000 will be rejected. - Implementaion notes: + Implementation notes: - 1. The full BBDL is loaded into memory, even though only the disc portion - will be used. + 1. After the BBDL is loaded into memory, the paper tape portion may be + executed manually by setting the P register to the starting address + (x7700). - 2. For compatibility with the cpu_ibl routine, the loader has been changed - from the standard HP version. The device I/O instructions are modified - to address locations 10 and 11. + 2. For compatibility with the cpu_copy_loader routine, the BBDL has been + altered from the standard HP version. The device I/O instructions are + modified to address select codes 10 and 11. + + 3. The "HP 20854A Timeshared BASIC/2000, Level F System Operator's Manual" + (HP 02000-90074, November 1974) lists an IBL procedure for booting a 21MX + (i.e., 1000 M-Series) CPU from the fixed-head disc. However, there is no + evidence that a fixed-head disc boot loader ROM ever existed. Moreover, + the procedure listed is suspicious, as it specifies the command channel + select code instead of the data channel select code, so I/O instruction + configuration would be incorrect. Also, the equivalent 2100 boot + procedure printed adjacently gives the wrong BBDL starting address (it is + listed correctly in the 1973 version of the manual). Actually, the 21MX + and 2100 procedures appear to be verbatim copies of the moving-head disc + boot procedures listed two pages earlier. Consequently, it would appear + that 21MX-based 2000 F TSB systems with fixed-head drives must boot from + paper tape. */ -static const BOOT_ROM dr_rom = { - 0107700, /* ST2 CLC 0,C START OF PAPER TAPE LOADER */ - 0002401, /* CLA,RSS */ - 0063726, /* CONT2 LDA CM21 */ - 0006700, /* CLB,CCE */ - 0017742, /* JSB READ2 */ - 0007306, /* LEDR2 CMB,CCE,INB,SZB */ - 0027713, /* JMP RECL2 */ - 0002006, /* EOTC2 INA,SZA */ - 0027703, /* JMP CONT2+1 */ - 0102077, /* HLT 77B */ - 0027700, /* JMP ST2 */ - 0077754, /* RECL2 STB CNT2 */ - 0017742, /* JSB READ2 */ - 0017742, /* JSB READ2 */ - 0074000, /* STB A */ - 0077757, /* STB ADR11 */ - 0067757, /* SUCID LDB ADR11 */ - 0047755, /* ADB MAXAD */ - 0002040, /* SEZ */ - 0027740, /* JMP RESCU */ - 0017742, /* LOAD2 JSB READ2 */ - 0040001, /* ADA B */ - 0177757, /* CM21 STB ADR11,I */ - 0037757, /* ISZ ADR11 */ - 0000040, /* CLE */ - 0037754, /* ISZ CNT2 */ - 0027720, /* JMP SUCID */ - 0017742, /* JSB READ2 */ - 0054000, /* CPB A */ - 0027702, /* JMP CONT2 */ - 0102011, /* HLT 11B */ - 0027700, /* JMP ST2 */ - 0102055, /* RESCU HLT 55B */ - 0027700, /* JMP ST2 */ - 0000000, /* READ2 NOP */ - 0006600, /* CLB,CME */ - 0103710, /* RED2 STC PR,C */ - 0102310, /* SFS PR */ - 0027745, /* JMP *-1 */ - 0107410, /* MIB PR,C */ - 0002041, /* SEZ,RSS */ - 0127742, /* JMP READ2,I */ - 0005767, /* BLF,CLE,BLF */ - 0027744, /* JMP RED2 */ - 0000000, /* CNT2 NOP */ - 0000000, /* MAXAD NOP */ - 0020000, /* CWORD ABS 20000B+DC */ - 0000000, /* ADR11 NOP */ +static const LOADER_ARRAY dr_loaders = { + { /* HP 21xx Basic Binary Disc Loader (BBDL) */ + 060, /* loader starting index */ + 056, /* DMA index */ + 055, /* FWA index */ + { 0107700, /* 77700: ST2 CLC 0,C START OF PAPER TAPE LOADER */ + 0002401, /* 77701: CLA,RSS */ + 0063726, /* 77702: CONT2 LDA CM21 */ + 0006700, /* 77703: CLB,CCE */ + 0017742, /* 77704: JSB READ2 */ + 0007306, /* 77705: LEDR2 CMB,CCE,INB,SZB */ + 0027713, /* 77706: JMP RECL2 */ + 0002006, /* 77707: EOTC2 INA,SZA */ + 0027703, /* 77710: JMP CONT2+1 */ + 0102077, /* 77711: HLT 77B */ + 0027700, /* 77712: JMP ST2 */ + 0077754, /* 77713: RECL2 STB CNT2 */ + 0017742, /* 77714: JSB READ2 */ + 0017742, /* 77715: JSB READ2 */ + 0074000, /* 77716: STB A */ + 0077757, /* 77717: STB ADR11 */ + 0067757, /* 77720: SUCID LDB ADR11 */ + 0047755, /* 77721: ADB MAXAD */ + 0002040, /* 77722: SEZ */ + 0027740, /* 77723: JMP RESCU */ + 0017742, /* 77724: LOAD2 JSB READ2 */ + 0040001, /* 77725: ADA B */ + 0177757, /* 77726: CM21 STB ADR11,I */ + 0037757, /* 77727: ISZ ADR11 */ + 0000040, /* 77730: CLE */ + 0037754, /* 77731: ISZ CNT2 */ + 0027720, /* 77732: JMP SUCID */ + 0017742, /* 77733: JSB READ2 */ + 0054000, /* 77734: CPB A */ + 0027702, /* 77735: JMP CONT2 */ + 0102011, /* 77736: HLT 11B */ + 0027700, /* 77737: JMP ST2 */ + 0102055, /* 77740: RESCU HLT 55B */ + 0027700, /* 77741: JMP ST2 */ + 0000000, /* 77742: READ2 NOP */ + 0006600, /* 77743: CLB,CME */ + 0103710, /* 77744: RED2 STC PR,C */ + 0102310, /* 77745: SFS PR */ + 0027745, /* 77746: JMP *-1 */ + 0107410, /* 77747: MIB PR,C */ + 0002041, /* 77750: SEZ,RSS */ + 0127742, /* 77751: JMP READ2,I */ + 0005767, /* 77752: BLF,CLE,BLF */ + 0027744, /* 77753: JMP RED2 */ + 0000000, /* 77754: CNT2 NOP */ + 0000000, /* 77755: MAXAD NOP */ + 0020010, /* 77756: CWORD ABS 20000B+DC */ + 0000000, /* 77757: ADR11 NOP */ + 0107700, /* 77760: DLDR CLC 0,C START OF FIXED DISC LOADER */ + 0063756, /* 77761: LDA CWORD */ + 0102606, /* 77762: OTA 6 */ + 0002700, /* 77763: CLA,CCE */ + 0102611, /* 77764: OTA CC */ + 0001500, /* 77765: ERA */ + 0102602, /* 77766: OTA 2 */ + 0063777, /* 77767: LDA WRDCT */ + 0102702, /* 77770: STC 2 */ + 0102602, /* 77771: OTA 2 */ + 0103706, /* 77772: STC 6,C */ + 0102710, /* 77773: STC DC */ + 0067776, /* 77774: LDB JMP77 */ + 0074077, /* 77775: STB 77B */ + 0024077, /* 77776: JMP77 JMP 77B */ + 0177700 } }, /* 77777: WRDCT OCT -100 */ - 0107700, /* DLDR CLC 0,C START OF FIXED DISC LOADER */ - 0063756, /* LDA CWORD */ - 0102606, /* OTA 6 */ - 0002700, /* CLA,CCE */ - 0102611, /* OTA CC */ - 0001500, /* ERA */ - 0102602, /* OTA 2 */ - 0063777, /* LDA WRDCT */ - 0102702, /* STC 2 */ - 0102602, /* OTA 2 */ - 0103706, /* STC 6,C */ - 0102710, /* STC DC */ - 0067776, /* LDB JMP77 */ - 0074077, /* STB 77B */ - 0024077, /* JMP77 JMP 77B */ - 0177700 /* WRDCT OCT -100 */ + { /* HP 1000 Loader ROM does not exist */ + IBL_NA, /* loader starting index */ + IBL_NA, /* DMA index */ + IBL_NA, /* FWA index */ + { 0 } } }; -#define BBDL_MAX_ADDR 0000055 /* ROM index of the maximum address word */ -#define BBDL_DMA_CNTL 0000056 /* ROM index of the DMA control word */ -#define BBDL_DISC_START 0000060 /* ROM index of the disc loader */ + +/* Device boot routine. + + This routine is called by the LOAD DRC and BOOT DRC commands to copy the + device bootstrap into the upper 64 words of the logical address space. On + entry, the "unitno" parameter is checked to ensure that it is 0, as the + bootstrap only loads from unit 0. Then the BBDL is loaded into memory, the + disc portion is configured for the DRD/DRC select code pair, and the paper + tape portion is configured for the select code of the paper tape reader. + + + Implementation notes: + + 1. The fixed-head disc/drum device is not supported on the HP 1000, so this + routine cannot be called by a BOOT CPU or LOAD CPU command. + + 2. In hardware, the BBDL was hand-configured for the disc and paper tape + reader select codes when it was installed on a given system. Under + simulation, the LOAD and BOOT commands automatically configure the BBDL + to the current select codes of the PTR and DR devices. + */ t_stat drc_boot (int32 unitno, DEVICE *dptr) { -const HP_WORD dev = (HP_WORD) drd_dib.select_code; /* data chan select code */ +if (unitno != 0) /* a BOOT DRC for a non-zero unit */ + return SCPE_NOFNC; /* is rejected as unsupported */ -if (unitno != 0) /* boot supported on drive unit 0 only */ - return SCPE_NOFNC; /* report "Command not allowed" if attempted */ - -cpu_ibl (dr_rom, dev, IBL_S_NOCLR, IBL_S_NOSET); /* copy the boot ROM to memory and configure */ - -mem_deposit (PR + BBDL_MAX_ADDR, mem_examine (PR + IBL_END)); /* move the maximum address word */ -mem_deposit (PR + BBDL_DMA_CNTL, (HP_WORD) dr_rom [BBDL_DMA_CNTL] + dev); /* set up the DMA control word */ - -mem_deposit (PR + IBL_DPC, (HP_WORD) dr_rom [IBL_DPC]); /* restore the overwritten word */ -mem_deposit (PR + IBL_END, (HP_WORD) dr_rom [IBL_END]); /* restore the overwritten word */ - -PR = PR + BBDL_DISC_START; /* select the starting address */ - -return SCPE_OK; +else /* otherwise this is a BOOT/LOAD DRC */ + return cpu_copy_loader (dr_loaders, drd_dib.select_code, /* so copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* and preserve the S register */ } diff --git a/HP2100/hp2100_ds.c b/HP2100/hp2100_ds.c index 9376e82f..fb7d0eb2 100644 --- a/HP2100/hp2100_ds.c +++ b/HP2100/hp2100_ds.c @@ -1,7 +1,7 @@ /* hp2100_ds.c: HP 13037D/13175D disc controller/interface simulator Copyright (c) 2004-2012, Robert M. Supnik - Copyright (c) 2012-2017 J. David Bryan + Copyright (c) 2012-2018 J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,9 @@ DS 13037D/13175D disc controller/interface + 07-May-18 JDB Removed "dl_clear_controller" status return + 27-Feb-18 JDB Added the BMDL + 21-Feb-18 JDB ATTACH -N now creates a full-size disc image 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" 15-Mar-17 JDB Trace flags are now global Changed DEBUG_PRI calls to tprintfs @@ -436,7 +439,6 @@ static const char * const output_state [] = { "Data", "Command" }; const char * const hold_or_clear = (signal_set & ioCLF ? ",C" : ""); uint16 data; -t_stat status; IOSIGNAL signal; IOCYCLE working_set = IOADDSIR (signal_set); /* add ioSIR if needed */ t_bool command_issued = FALSE; @@ -542,10 +544,8 @@ while (working_set) { if (PRESET_ENABLE) { /* is preset enabled for this interface? */ fifo_clear (); /* clear the FIFO */ - status = dl_clear_controller (&mac_cntlr, /* do a hard clear of the controller */ - ds_unit, hard_clear); - - stat_data = IORETURN (status, 0); /* return the status from the controller */ + dl_clear_controller (&mac_cntlr, ds_unit, /* do a hard clear of the controller */ + hard_clear); } break; @@ -1015,23 +1015,43 @@ return SCPE_OK; Attention bits in the drive status, so we poll the drives to ensure that the CPU is notified that the drive is now online. + If a new file is specified, the file is initialized to its capacity by + writing a zero to the last byte in the file. + Implementation notes: 1. If we are called during a RESTORE command, the drive status will not be changed, so polling the drives will have no effect. + + 2. The C standard says, "A binary stream need not meaningfully support fseek + calls with a whence value of SEEK_END," so instead we determine the + offset from the start of the file to the last byte and seek there. */ t_stat ds_attach (UNIT *uptr, CONST char *cptr) { -t_stat result; +t_stat result; +t_addr offset; +const uint8 zero = 0; result = dl_attach (&mac_cntlr, uptr, cptr); /* attach the drive */ -if (result == SCPE_OK) /* was the attach successful? */ - poll_drives (); /* poll the drives to notify the CPU */ +if (result == SCPE_OK) { /* if the attach was successful */ + poll_drives (); /* then poll the drives to notify the CPU */ -return result; + if (sim_switches & SWMASK ('N')) { /* if this is a new disc image */ + offset = (t_addr) /* then determine the offset of */ + (uptr->capac * sizeof (int16) - sizeof zero); /* the last byte in a full-sized file */ + + if (sim_fseek (uptr->fileref, offset, SEEK_SET) != 0 /* seek to the last byte */ + || fwrite (&zero, sizeof zero, 1, uptr->fileref) == 0 /* and write a zero to fill */ + || fflush (uptr->fileref) != 0) /* the file to its capacity */ + clearerr (uptr->fileref); /* clear and ignore any errors */ + } + } + +return result; /* return the result of the attach */ } @@ -1056,115 +1076,259 @@ return result; } -/* Boot a MAC disc drive. +/* MAC disc bootstrap loaders (BMDL and 12992B). - The MAC disc bootstrap program is loaded from the HP 12992B Boot Loader ROM - into memory, the I/O instructions are configured for the interface card's - select code, and the program is run to boot from the specified unit. The - loader supports booting from cylinder 0 of drive unit 0 only. Before - execution, the S register is automatically set as follows: + The Basic Moving-Head Disc Loader (BMDL) consists of two programs. The + program starting at address x7700 loads absolute paper tapes into memory. + The program starting at address x7750 loads a disc-resident bootstrap from + the MAC disc drive into memory. The S register specifies the head to use. - 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - ------ ------ ---------------------- --------- --------- - ROM # 0 1 select code reserved head + For a 2100/14/15/16 CPU, entering a LOAD DS or BOOT DS command loads the BMDL + into memory and executes the disc portion starting at x7750. The bootstrap + reads 2047 words from cylinder 0 sector 0 of the specified head into memory + starting at location 2011 octal. Loader execution ends with one of the + following instructions: - The boot routine sets bits 15-6 of the S register to appropriate values. - Bits 5-3 and 1-0 retain their original values, so S should be set before - booting. These bits are typically set to 0, although bit 5 is set for an RTE - reconfiguration boot, and bits 1-0 may be set if booting from a head other - than 0 is desired. + * HLT 11B - the disc read failed. + * JSB 2055,I - the disc read completed. + + The HP 1000 uses the 12992B boot loader ROM to bootstrap the disc. The head + number is obtained from bits 2-0 of the existing S-register value when the + loader is executed. Bits 5-3 of the existing S-register value are also + retained and are available to the boot extension program. The loader reads + 6144 words from cylinder 0 sector 0 of the specified head into memory + starting at location 2011 octal. Loader execution ends with one of the + following instructions: + + * HLT 30 - the drive is not ready.. + * JSB 2055,I - the disc read succeeded. + + The loader automatically retries the operations for all disc errors other + than a drive fault. Implementation notes: - 1. The Loader ROMs manual indicates that bits 2-0 select the head to use, - implying that heads 0-7 are valid. However, Table 5 has entries only for - heads 0-3, and the boot loader code will malfunction if heads 4-7 are - specified. The code masks the head number to three bits but forms the - Cold Load Read command by shifting the head number six bits to the left. - As the head field in the command is only two bits wide, specifying heads - 4-7 will result in bit 2 being shifted into the opcode field, resulting - in a Recalibrate command. + 1. After the BMDL has been loaded into memory, the paper tape portion may be + executed manually by setting the P register to the starting address + (x7700). + + 2. For compatibility with the "cpu_copy_loader" routine, the BMDL device I/O + instructions address select codes 10 and 11. */ +static const LOADER_ARRAY ds_loaders = { + { /* HP 21xx Basic Moving-Head Disc Loader (BMDL-7905) */ + 050, /* loader starting index */ + 076, /* DMA index */ + 034, /* FWA index */ + { 0002401, /* 77700: PTAPE CLA,RSS Paper Tape start */ + 0063722, /* 77701: LDA 77722 */ + 0107700, /* 77702: CLC 0,C */ + 0002307, /* 77703: CCE,INA,SZA,RSS */ + 0102077, /* 77704: HLT 77 */ + 0017735, /* 77705: JSB 77735 */ + 0007307, /* 77706: CMB,CCE,INB,SZB,RSS */ + 0027702, /* 77707: JMP 77702 */ + 0077733, /* 77710: STB 77733 */ + 0017735, /* 77711: JSB 77735 */ + 0017735, /* 77712: JSB 77735 */ + 0074000, /* 77713: STB 0 */ + 0077747, /* 77714: STB 77747 */ + 0047734, /* 77715: ADB 77734 */ + 0002140, /* 77716: SEZ,CLE */ + 0102055, /* 77717: HLT 55 */ + 0017735, /* 77720: JSB 77735 */ + 0040001, /* 77721: ADA 1 */ + 0177747, /* 77722: STB 77747,I */ + 0067747, /* 77723: LDB 77747 */ + 0006104, /* 77724: CLE,INB */ + 0037733, /* 77725: ISZ 77733 */ + 0027714, /* 77726: JMP 77714 */ + 0017735, /* 77727: JSB 77735 */ + 0054000, /* 77730: CPB 0 */ + 0027701, /* 77731: JMP 77701 */ + 0102011, /* 77732: HLT 11 */ + 0000000, /* 77733: NOP */ + 0100100, /* 77734: RRL 16 */ + 0000000, /* 77735: NOP */ + 0006400, /* 77736: CLB */ + 0103710, /* 77737: STC 10,C */ + 0102310, /* 77740: SFS 10 */ + 0027740, /* 77741: JMP 77740 */ + 0106410, /* 77742: MIB 10 */ + 0002240, /* 77743: SEZ,CME */ + 0127735, /* 77744: JMP 77735,I */ + 0005727, /* 77745: BLF,BLF */ + 0027737, /* 77746: JMP 77737 */ + 0000000, /* 77747: NOP */ + 0067777, /* 77750: DISC LDB 77777 */ + 0174001, /* 77751: STB 1,I */ + 0006004, /* 77752: INB */ + 0063732, /* 77753: LDA 77732 */ + 0170001, /* 77754: STA 1,I */ + 0067776, /* 77755: LDB 77776 */ + 0106606, /* 77756: OTB 6 */ + 0106702, /* 77757: CLC 2 */ + 0102602, /* 77760: OTA 2 */ + 0102702, /* 77761: STC 2 */ + 0063751, /* 77762: LDA 77751 */ + 0102602, /* 77763: OTA 2 */ + 0102501, /* 77764: LIA 1 */ + 0001027, /* 77765: ALS,ALF */ + 0013767, /* 77766: AND 77767 */ + 0000160, /* 77767: CLE,ALS */ + 0106710, /* 77770: CLC 10 */ + 0103610, /* 77771: OTA 10,C */ + 0103706, /* 77772: STC 6,C */ + 0102310, /* 77773: SFS 10 */ + 0027773, /* 77774: JMP 77773 */ + 0117717, /* 77775: JSB 77717,I */ + 0000010, /* 77776: SLA */ + 0002055 } }, /* 77777: SEZ,SLA,INA,RSS */ -const BOOT_ROM ds_rom = { - 0017727, /* START JSB STAT GET STATUS */ - 0002021, /* SSA,RSS IS DRIVE READY ? */ - 0027742, /* JMP DMA YES, SET UP DMA */ - 0013714, /* AND B20 NO, CHECK STATUS BITS */ - 0002002, /* SZA IS DRIVE FAULTY OR HARD DOWN ? */ - 0102030, /* HLT 30B YES, HALT 30B, "RUN" TO TRY AGAIN */ - 0027700, /* JMP START NO, TRY AGAIN FOR DISC READY */ - 0102011, /* ADDR1 OCT 102011 */ - 0102055, /* ADDR2 OCT 102055 */ - 0164000, /* CNT DEC -6144 */ - 0000007, /* D7 OCT 7 */ - 0001400, /* STCMD OCT 1400 */ - 0000020, /* B20 OCT 20 */ - 0017400, /* STMSK OCT 17400 */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* NOP */ - 0000000, /* STAT NOP STATUS CHECK SUBROUTINE */ - 0107710, /* CLC DC,C SET STATUS COMMAND MODE */ - 0063713, /* LDA STCMD GET STATUS COMMAND */ - 0102610, /* OTA DC OUTPUT STATUS COMMAND */ - 0102310, /* SFS DC WAIT FOR STATUS#1 WORD */ - 0027733, /* JMP *-1 */ - 0107510, /* LIB DC,C B-REG = STATUS#1 WORD */ - 0102310, /* SFS DC WAIT FOR STATUS#2 WORD */ - 0027736, /* JMP *-1 */ - 0103510, /* LIA DC,C A-REG = STATUS#2 WORD */ - 0127727, /* JMP STAT,I RETURN */ - 0067776, /* DMA LDB DMACW GET DMA CONTROL WORD */ - 0106606, /* OTB 6 OUTPUT DMA CONTROL WORD */ - 0067707, /* LDB ADDR1 GET MEMORY ADDRESS */ - 0106702, /* CLC 2 SET MEMORY ADDRESS INPUT MODE */ - 0106602, /* OTB 2 OUTPUT MEMORY ADDRESS TO DMA */ - 0102702, /* STC 2 SET WORD COUNT INPUT MODE */ - 0067711, /* LDB CNT GET WORD COUNT */ - 0106602, /* OTB 2 OUTPUT WORD COUNT TO DMA */ - 0106710, /* CLDLD CLC DC SET COMMAND INPUT MODE */ - 0102501, /* LIA 1 LOAD SWITCH */ - 0106501, /* LIB 1 REGISTER SETTINGS */ - 0013712, /* AND D7 ISOLATE HEAD NUMBER */ - 0005750, /* BLF,CLE,SLB BIT 12=0? */ - 0027762, /* JMP *+3 NO,MANUAL BOOT */ - 0002002, /* SZA YES,RPL BOOT. HEAD#=0? */ - 0001000, /* ALS NO,HEAD#1, MAKE HEAD#=2 */ - 0001720, /* ALF,ALS FORM COLD LOAD */ - 0001000, /* ALS COMMAND WORD */ - 0103706, /* STC 6,C ACTIVATE DMA */ - 0103610, /* OTA DC,C OUTPUT COLD LOAD COMMAND */ - 0102310, /* SFS DC IS COLD LOAD COMPLETED ? */ - 0027766, /* JMP *-1 NO, WAIT */ - 0017727, /* JSB STAT YES, GET STATUS */ - 0060001, /* LDA 1 */ - 0013715, /* AND STMSK A-REG = STATUS BITS OF STATUS#1 WD */ - 0002002, /* SZA IS TRANSFER OK ? */ - 0027700, /* JMP START NO,TRY AGAIN */ - 0117710, /* EXIT JSB ADDR2,I YES, EXEC LOADED PROGRAM _@ 2055B */ - 0000010, /* DMACW ABS DC */ - 0170100, /* ABS -START */ + { /* HP 1000 Loader ROM (12992B) */ + IBL_START, /* loader starting index */ + IBL_DMA, /* DMA index */ + IBL_FWA, /* FWA index */ + { 0017727, /* 77700: START JSB STAT GET STATUS */ + 0002021, /* 77701: SSA,RSS IS DRIVE READY ? */ + 0027742, /* 77702: JMP DMA YES, SET UP DMA */ + 0013714, /* 77703: AND B20 NO, CHECK STATUS BITS */ + 0002002, /* 77704: SZA IS DRIVE FAULTY OR HARD DOWN ? */ + 0102030, /* 77705: HLT 30B YES, HALT 30B, "RUN" TO TRY AGAIN */ + 0027700, /* 77706: JMP START NO, TRY AGAIN FOR DISC READY */ + 0102011, /* 77707: ADDR1 OCT 102011 */ + 0102055, /* 77710: ADDR2 OCT 102055 */ + 0164000, /* 77711: CNT DEC -6144 */ + 0000007, /* 77712: D7 OCT 7 */ + 0001400, /* 77713: STCMD OCT 1400 */ + 0000020, /* 77714: B20 OCT 20 */ + 0017400, /* 77715: STMSK OCT 17400 */ + 0000000, /* 77716: NOP */ + 0000000, /* 77717: NOP */ + 0000000, /* 77720: NOP */ + 0000000, /* 77721: NOP */ + 0000000, /* 77722: NOP */ + 0000000, /* 77723: NOP */ + 0000000, /* 77724: NOP */ + 0000000, /* 77725: NOP */ + 0000000, /* 77726: NOP */ + 0000000, /* 77727: STAT NOP STATUS CHECK SUBROUTINE */ + 0107710, /* 77730: CLC DC,C SET STATUS COMMAND MODE */ + 0063713, /* 77731: LDA STCMD GET STATUS COMMAND */ + 0102610, /* 77732: OTA DC OUTPUT STATUS COMMAND */ + 0102310, /* 77733: SFS DC WAIT FOR STATUS#1 WORD */ + 0027733, /* 77734: JMP *-1 */ + 0107510, /* 77735: LIB DC,C B-REG = STATUS#1 WORD */ + 0102310, /* 77736: SFS DC WAIT FOR STATUS#2 WORD */ + 0027736, /* 77737: JMP *-1 */ + 0103510, /* 77740: LIA DC,C A-REG = STATUS#2 WORD */ + 0127727, /* 77741: JMP STAT,I RETURN */ + 0067776, /* 77742: DMA LDB DMACW GET DMA CONTROL WORD */ + 0106606, /* 77743: OTB 6 OUTPUT DMA CONTROL WORD */ + 0067707, /* 77744: LDB ADDR1 GET MEMORY ADDRESS */ + 0106702, /* 77745: CLC 2 SET MEMORY ADDRESS INPUT MODE */ + 0106602, /* 77746: OTB 2 OUTPUT MEMORY ADDRESS TO DMA */ + 0102702, /* 77747: STC 2 SET WORD COUNT INPUT MODE */ + 0067711, /* 77750: LDB CNT GET WORD COUNT */ + 0106602, /* 77751: OTB 2 OUTPUT WORD COUNT TO DMA */ + 0106710, /* 77752: CLDLD CLC DC SET COMMAND INPUT MODE */ + 0102501, /* 77753: LIA 1 LOAD SWITCH */ + 0106501, /* 77754: LIB 1 REGISTER SETTINGS */ + 0013712, /* 77755: AND D7 ISOLATE HEAD NUMBER */ + 0005750, /* 77756: BLF,CLE,SLB BIT 12=0? */ + 0027762, /* 77757: JMP *+3 NO,MANUAL BOOT */ + 0002002, /* 77760: SZA YES,RPL BOOT. HEAD#=0? */ + 0001000, /* 77761: ALS NO,HEAD#1, MAKE HEAD#=2 */ + 0001720, /* 77762: ALF,ALS FORM COLD LOAD */ + 0001000, /* 77763: ALS COMMAND WORD */ + 0103706, /* 77764: STC 6,C ACTIVATE DMA */ + 0103610, /* 77765: OTA DC,C OUTPUT COLD LOAD COMMAND */ + 0102310, /* 77766: SFS DC IS COLD LOAD COMPLETED ? */ + 0027766, /* 77767: JMP *-1 NO, WAIT */ + 0017727, /* 77770: JSB STAT YES, GET STATUS */ + 0060001, /* 77771: LDA 1 */ + 0013715, /* 77772: AND STMSK A-REG = STATUS BITS OF STATUS#1 WD */ + 0002002, /* 77773: SZA IS TRANSFER OK ? */ + 0027700, /* 77774: JMP START NO,TRY AGAIN */ + 0117710, /* 77775: EXIT JSB ADDR2,I YES, EXEC LOADED PROGRAM @ 2055B */ + 0000010, /* 77776: DMACW ABS DC */ + 0170100 } } /* 77777: ABS -START */ }; + +/* Device boot routine. + + This routine is called directly by the BOOT DS and LOAD DS commands to copy + the device bootstrap into the upper 64 words of the logical address space. + It is also called indirectly by a BOOT CPU or LOAD CPU command when the + specified HP 1000 loader ROM socket contains a 12992B ROM. + + When called in response to a BOOT DS or LOAD DS command, the "unitno" + parameter indicates the unit number specified in the BOOT command or is zero + for the LOAD command, and "dptr" points at the DS device structure. The + bootstrap supports loading only from unit 0, and the command will be rejected + if another unit is specified (e.g., BOOT DS1). Otherwise, depending on the + current CPU model, the BMDL or 12992B loader ROM will be copied into memory + and configured for the DS select code. If the CPU is a 1000, the S register + will be set as it would be by the front-panel microcode. + + When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the + select code to be used for configuration, and "dptr" will be NULL. As above, + the BMDL or 12992B loader ROM will be copied into memory and configured for + the specified select code. The S register is assumed to be set correctly on + entry and is not modified. + + In either case, if the CPU is a 21xx model, the paper tape portion of the + BMDL will be automatically configured for the select code of the paper tape + reader. + + For the 12992B boot loader ROM for the HP 1000, the S register is set as + follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | 0 1 | select code | reserved | 0 | head | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Bit 12 must be 1 for a manual boot. Bits 5-3 are nominally zero but are + reserved for the target operating system. For example, RTE uses bit 5 to + indicate whether a standard (0) or reconfiguration (1) boot is desired. + + + Implementation notes: + + 1. In hardware, the BMDL was hand-configured for the disc and paper tape + reader select codes when it was installed on a given system. Under + simulation, the LOAD and BOOT commands automatically configure the BMDL + to the current select codes of the PTR and DS devices. + + 2. The HP 1000 Loader ROMs manual indicates that bits 2-0 select the head to + use, implying that heads 0-7 are valid. However, Table 5 has entries + only for heads 0-3, and the boot loader code will malfunction if heads + 4-7 are specified. The code masks the head number to three bits but + forms the Cold Load Read command by shifting the head number six bits to + the left. As the head field in the command is only two bits wide, + specifying heads 4-7 will result in bit 2 being shifted into the opcode + field, resulting in a Recalibrate command. +*/ + t_stat ds_boot (int32 unitno, DEVICE *dptr) { -if (unitno != 0) /* boot supported on drive unit 0 only */ - return SCPE_NOFNC; /* report "Command not allowed" if attempted */ +static const HP_WORD ds_preserved = 0000073u; /* S-register bits 5-3 and 1-0 are preserved */ +static const HP_WORD ds_manual_boot = 0010000u; /* S-register bit 12 set for a manual boot */ -cpu_ibl (ds_rom, ds_dib.select_code, /* copy the boot ROM to memory and configure */ - IBL_OPT | IBL_DS_HEAD, /* the S register accordingly */ - IBL_DS | IBL_MAN | IBL_SET_SC (ds_dib.select_code)); +if (dptr == NULL) /* if we are being called for a BOOT/LOAD CPU */ + return cpu_copy_loader (ds_loaders, unitno, /* then copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* but do not alter the S register */ -return SCPE_OK; +else if (unitno != 0) /* otherwise a BOOT DS for a non-zero unit */ + return SCPE_NOFNC; /* is rejected as unsupported */ + +else /* otherwise this is a BOOT/LOAD DS */ + return cpu_copy_loader (ds_loaders, ds_dib.select_code, /* so copy the boot loader to memory */ + ds_preserved, ds_manual_boot); /* and configure the S register if 1000 CPU */ } diff --git a/HP2100/hp2100_fp1.c b/HP2100/hp2100_fp1.c index 2dc48449..bea02531 100644 --- a/HP2100/hp2100_fp1.c +++ b/HP2100/hp2100_fp1.c @@ -1,6 +1,6 @@ /* hp2100_fp1.c: HP 1000 multiple-precision floating point routines - Copyright (c) 2005-2016, J. David Bryan + Copyright (c) 2005-2017, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the author. + 07-Sep-17 JDB Replaced "uint16" casts with "HP_WORD" for OP assignments 16-May-16 JDB Reformulated the definitions of op_mask 24-Dec-14 JDB Added casts for explicit downward conversions Changed fp_ucom return from uint32 to uint16 @@ -480,7 +481,7 @@ int32 i; OP packed; if (precision == in_s) - packed.word = (uint16) (unpacked >> 48) & DMASK; /* pack single integer */ + packed.word = (HP_WORD) (unpacked >> 48) & DMASK; /* pack single integer */ else if (precision == in_d) packed.dword = (uint32) (unpacked >> 32) & DMASK32; /* pack double integer */ @@ -490,7 +491,7 @@ else { precision = fp_t; /* only four mantissa words */ for (i = 3; i >= 0; i--) { /* pack fp 2 to 4 words */ - packed.fpk[i] = (uint16) unpacked & DMASK; + packed.fpk[i] = (HP_WORD) unpacked & DMASK; unpacked = unpacked >> 16; } } @@ -530,8 +531,8 @@ switch (unpacked.precision) { /* merge exponent into c break; case fp_e: /* place in separate word */ - packed.fpk[4] = (uint16) (unpacked.exponent << FP_V_EXP | - (unpacked.exponent < 0) << FP_V_ESIGN); + packed.fpk[4] = (HP_WORD) (unpacked.exponent << FP_V_EXP | + (unpacked.exponent < 0) << FP_V_ESIGN); break; case fp_a: /* no action for value in accum */ diff --git a/HP2100/hp2100_ipl.c b/HP2100/hp2100_ipl.c index 42633913..e398b2c1 100644 --- a/HP2100/hp2100_ipl.c +++ b/HP2100/hp2100_ipl.c @@ -1,7 +1,7 @@ /* hp2100_ipl.c: HP 12875A Processor Interconnect simulator Copyright (c) 2002-2016, Robert M. Supnik - Copyright (c) 2017, J. David Bryan + Copyright (c) 2017-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,10 @@ IPLI, IPLO 12875A Processor Interconnect + 22-May-18 JDB Added process synchronization commands + 01-May-18 JDB Removed ioCRS counter, as consecutive ioCRS calls are no longer made + 26-Mar-18 JDB Converted from socket to shared memory connections + 28-Feb-18 JDB Added the special IOP BBL 13-Aug-17 JDB Revised so that only IPLI boots 19-Jul-17 JDB Removed unused "ipl_stopioe" variable and register 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" @@ -65,10 +69,12 @@ 09-May-03 RMS Added network device flag 31-Jan-03 RMS Links are full duplex (found by Mike Gemeny) - Reference: + References: - 12875A Processor Interconnect Kit Operating and Service Manual (12875-90002, January 1974) - + - 12566B, 12566B-001, 12566B-002, 12566B-003 Microcircuit Interface Kits + Operating and Service Manual + (12566-90015, April 1976) The 12875A Processor Interconnect Kit consists four 12566A Microcircuit Interface cards. Two are used in each processor. One card in each system is @@ -79,137 +85,423 @@ on the lower priority card and received on the higher priority card. Two sets of cards are used to support simultaneous transmission in both directions. + + + Implementation notes: + + 1. The "IPL" ("InterProcessor Link") designation is used throughout this + file for historical reasons, although HP designates this device as the + Processor Interconnect Kit. */ + +#include + #include "hp2100_defs.h" #include "hp2100_cpu.h" -#include "sim_sock.h" -#include "sim_tmxr.h" -#include "sim_rev.h" - +#include "sim_timer.h" #if (SIM_MAJOR >= 4) - #define sim_close_sock(socket,master) sim_close_sock (socket) + #include "sim_fio.h" +#else + #include "sim_shmem.h" #endif -typedef enum { ipli, iplo } CARD_INDEX; /* card index number */ -#define CARD_COUNT 2 /* count of cards supported */ - -#define UNIT_V_DIAG (UNIT_V_UF + 0) /* diagnostic mode */ -#define UNIT_V_ACTV (UNIT_V_UF + 1) /* making connection */ -#define UNIT_V_ESTB (UNIT_V_UF + 2) /* connection established */ -#define UNIT_V_HOLD (UNIT_V_UF + 3) /* character holding */ -#define UNIT_DIAG (1 << UNIT_V_DIAG) -#define UNIT_ACTV (1 << UNIT_V_ACTV) -#define UNIT_ESTB (1 << UNIT_V_ESTB) -#define UNIT_HOLD (1 << UNIT_V_HOLD) -#define IBUF buf /* input buffer */ -#define OBUF wait /* output buffer */ -#define DSOCKET u3 /* data socket */ -#define LSOCKET u4 /* listening socket */ +/* Process synchronization definitions */ -extern DIB ptr_dib; /* need PTR select code for boot */ +/* Windows process synchronization */ -int32 ipl_edtdelay = 1; /* EDT delay (msec) */ -int32 ipl_ptime = 31; /* polling interval */ +#if defined (_WIN32) + +#pragma push_macro("CONST") +#undef CONST + +#include + +#pragma pop_macro("CONST") + + +typedef HANDLE EVENT; /* the event type */ + +#define NO_EVENT NULL /* the initial (undefined) event value */ + + +/* UNIX process synchronization */ + +#elif defined (HAVE_SEMAPHORE) + +#include +#include +#include + +typedef sem_t *EVENT; /* the event type */ + +#define NO_EVENT SEM_FAILED /* the initial (undefined) event value */ + +static t_bool event_fallback = FALSE; /* TRUE if semaphores are defined but not supported */ + + +/* Process synchronization stub */ + +#else + +typedef uint32 EVENT; /* the event type */ + +#define NO_EVENT 0 /* the initial (undefined) event value */ + + +#endif + + + +/* Program limits */ + +#define CARD_COUNT 2 /* count of cards supported */ + + +/* ATTACH mode switches */ + +#define SP SWMASK ('S') /* SP switch */ +#define IOP SWMASK ('I') /* IOP switch */ + +#define LISTEN SWMASK ('L') /* listen switch (deprecated) */ +#define CONNECT SWMASK ('C') /* connect switch (deprecated) */ + + +/* Per-unit state variables */ + +#define ID u3 /* session identifying number */ + + +/* Unit flags */ + +#define UNIT_DIAG_SHIFT (UNIT_V_UF + 0) /* diagnostic mode */ + +#define UNIT_DIAG (1u << UNIT_DIAG_SHIFT) + + +/* Unit references */ + +typedef enum { + ipli, /* inbound card index */ + iplo /* outbound card index */ + } CARD_INDEX; + +#define ipli_unit ipl_unit [ipli] /* inbound card unit */ +#define iplo_unit ipl_unit [iplo] /* outbound card unit */ + + +/* Device information block references */ + +#define ipli_dib ipl_dib [ipli] /* inbound card DIB */ +#define iplo_dib ipl_dib [iplo] /* outbound card DIB */ + + +/* IPL state */ typedef struct { - FLIP_FLOP control; /* control flip-flop */ - FLIP_FLOP flag; /* flag flip-flop */ - FLIP_FLOP flagbuf; /* flag buffer flip-flop */ - int32 hold; /* holding character */ + HP_WORD output_word; /* output word register */ + HP_WORD input_word; /* input word register */ + FLIP_FLOP command; /* command flip-flop */ + FLIP_FLOP control; /* control flip-flop */ + FLIP_FLOP flag; /* flag flip-flop */ + FLIP_FLOP flagbuf; /* flag buffer flip-flop */ } CARD_STATE; -CARD_STATE ipl [CARD_COUNT]; /* per-card state */ - -IOHANDLER iplio; - -t_stat ipl_svc (UNIT *uptr); -t_stat ipl_reset (DEVICE *dptr); -t_stat ipl_attach (UNIT *uptr, CONST char *cptr); -t_stat ipl_detach (UNIT *uptr); -t_stat ipl_boot (int32 unitno, DEVICE *dptr); -t_stat ipl_dscln (UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat ipl_setdiag (UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_bool ipl_check_conn (UNIT *uptr); - -/* Debug flags table */ - -DEBTAB ipl_deb [] = { - { "CMDS", DEB_CMDS }, - { "CPU", DEB_CPU }, - { "XFER", DEB_XFER }, - { "IOBUS", TRACE_IOBUS }, /* interface I/O bus signals and data words */ - { NULL, 0 } - }; - -/* Common structures */ - -DEVICE ipli_dev, iplo_dev; - -static DEVICE *dptrs [] = { &ipli_dev, &iplo_dev }; +static CARD_STATE ipl [CARD_COUNT]; /* per-card state */ -UNIT ipl_unit [] = { - { UDATA (&ipl_svc, UNIT_ATTABLE, 0) }, - { UDATA (&ipl_svc, UNIT_ATTABLE, 0) } - }; +/* IPL I/O device state. -#define ipli_unit ipl_unit [ipli] -#define iplo_unit ipl_unit [iplo] + The 12566B Microcircuit Interface provides a 16-bit Data Out bus and a 16-bit + Data In bus, as well as an outbound Device Command signal and an inbound + Device Flag signal to indicate data availability. The output and input + states are modelled by a pair of structures that also contain Boolean flags + to indicate cable connectivity. + + The two interface cards provided each may be connected in one of four + possible ways: + + 1. No connection (the I/O cable is not connected). + + 2. Loopback connection (a loopback connector is in place). + + 3. Cross connection (an I/O cable connects one card to the other card in the + same machine). + + 4. Processor interconnection (an I/O cable connects a card in one machine to + a card in the other machine). + + In simulation, these four connection states are modelled by setting input and + output pointers (accessors) to point at the appropriate state structures, as + follows: + + 1. The input and output accessors point at separate local input and output + state structures. + + 2. The input and output accessors point at a single local state structure. + + 3. The input and output accessors of one card point at the separate local + state structures of the other card. + + 4. The input and output accessors of one card point at the separate shared + state structures of the other card. + + Connection is accomplished by having an output accessor and an input accessor + point at the same state structure. Graphically, the four possibilities are: + + 1. No connection: + + +------------------+ + card [n].output --> | Data Out | + +------------------+ + | Device Command | + +------------------+ + + +------------------+ + card [n].input --> | Data In | + +------------------+ + | Device Flag | + +------------------+ -DIB ipl_dib [] = { - { &iplio, IPLI, 0 }, - { &iplio, IPLO, 1 } - }; + 2. Loopback connection: -#define ipli_dib ipl_dib [ipli] -#define iplo_dib ipl_dib [iplo] + +------------------+------------------+ + card [n].output --> | Data Out | Data In | <-- card [n].input + +------------------+------------------+ + | Device Command | Device Flag | + +------------------+------------------+ -/* IPLI data structures + 3. Cross connection: - ipli_dev IPLI device descriptor - ipli_unit IPLI unit descriptor - ipli_reg IPLI register list + +------------------+------------------+ + card [0].output --> | Data Out | Data In | <-- card [1].input + +------------------+------------------+ + | Device Command | Device Flag | + +------------------+------------------+ + + +------------------+------------------+ + card [0].input --> | Data In | Data Out | <-- card [1].output + +------------------+------------------+ + | Device Flag | Device Command | + +------------------+------------------+ + + + 4. Processor interconnection: + + +------------------+------------------+ + card [0].output --> | Data Out | Data In | <-- card [1].input + +------------------+------------------+ + | Device Command | Device Flag | + +------------------+------------------+ + + +------------------+------------------+ + card [0].input --> | Data In | Data Out | <-- card [1].output + +------------------+------------------+ + | Device Flag | Device Command | + +------------------+------------------+ + + +------------------+------------------+ + card [1].output --> | Data Out | Data In | <-- card [0].input + +------------------+------------------+ + | Device Command | Device Flag | + +------------------+------------------+ + + +------------------+------------------+ + card [1].input --> | Data In | Data Out | <-- card [0].output + +------------------+------------------+ + | Device Flag | Device Command | + +------------------+------------------+ + + In all but case 1, two accessors point at the same structure but with + different views. */ -REG ipli_reg [] = { - { ORDATA (IBUF, ipli_unit.IBUF, 16) }, - { ORDATA (OBUF, ipli_unit.OBUF, 16) }, - { FLDATA (CTL, ipl [ipli].control, 0) }, - { FLDATA (FLG, ipl [ipli].flag, 0) }, - { FLDATA (FBF, ipl [ipli].flagbuf, 0) }, - { ORDATA (HOLD, ipl [ipli].hold, 8) }, - { DRDATA (TIME, ipl_ptime, 24), PV_LEFT }, - { DRDATA (EDTDELAY, ipl_edtdelay, 32), REG_HIDDEN | PV_LEFT }, - { ORDATA (SC, ipli_dib.select_code, 6), REG_HRO }, - { ORDATA (DEVNO, ipli_dib.select_code, 6), REG_HRO }, +typedef struct { + t_bool cable_connected; /* TRUE if the inbound cable is connected */ + t_bool device_flag_in; /* external DEVICE FLAG signal state */ + HP_WORD data_in; /* external DATA IN signal bus */ + } INPUT_STATE, *INPUT_STATE_PTR; + +typedef struct { + t_bool cable_connected; /* TRUE if the outbound cable is connected */ + t_bool device_command_out; /* external DEVICE COMMAND signal state */ + HP_WORD data_out; /* external DATA OUT signal bus */ + } OUTPUT_STATE, *OUTPUT_STATE_PTR; + +typedef struct { /* the normal ("forward direction") state view */ + INPUT_STATE input; + OUTPUT_STATE output; + } FORWARD_STATE; + +typedef struct { /* the cross-connected ("reverse direction") state view */ + OUTPUT_STATE output; + INPUT_STATE input; + } REVERSE_STATE; + +typedef union { /* the state may be accessed in either direction */ + FORWARD_STATE forward; + REVERSE_STATE reverse; + } IO_STATE, *IO_STATE_PTR; + +typedef IO_STATE IO_ARRAY [CARD_COUNT]; /* an array of I/O states for the two cards */ + +static IO_ARRAY dev_bus; /* the local device I/O bus states */ + +typedef struct { + INPUT_STATE_PTR input; /* the input accessor */ + OUTPUT_STATE_PTR output; /* the output accessor */ + } STATE_PTRS; + +static STATE_PTRS io_ptrs [CARD_COUNT] = { /* the card accessors pointing at the local state */ + { &dev_bus [ipli].forward.input, /* card [0].input */ + &dev_bus [ipli].forward.output }, /* card [0].output */ + + { &dev_bus [iplo].forward.input, /* card [1].input */ + &dev_bus [iplo].forward.output } /* card [1].output */ + }; + + +/* IPL interface state */ + +static t_bool cpu_is_iop = FALSE; /* TRUE if this is the IOP instance, FALSE if SP instance */ +static int32 edt_delay = 1; /* EDT delay (msec) */ +static int32 poll_wait = 50; /* maximum poll wait time */ + +static char event_name [PATH_MAX]; /* the event name */ +static uint32 event_error = 0; /* the host OS error code from a failed process sync call */ +static t_bool wait_aborted = FALSE; /* TRUE if the user aborted a SET IPL WAIT command */ +static EVENT event_id = NO_EVENT; /* the synchronization event */ +static SHMEM *memory_region = NULL; /* a pointer to the shared memory region descriptor */ + + +/* IPL local SCP support routines */ + +static IOHANDLER ipl_interface; + +static t_stat ipl_set_diag (UNIT *uptr, int32 value, CONST char *cptr, void *desc); +static t_stat ipl_set_sync (UNIT *uptr, int32 value, CONST char *cptr, void *desc); + +static t_stat ipl_reset (DEVICE *dptr); +static t_stat ipl_boot (int32 unitno, DEVICE *dptr); + +static t_stat ipl_attach (UNIT *uptr, CONST char *cptr); +static t_stat ipl_detach (UNIT *uptr); + + +/* IPL local utility routines */ + +static t_stat card_service (UNIT *uptr); +static void activate_unit (UNIT *uptr); +static void abort_handler (int signal); + + +/* Process synchronization routines */ + +static uint32 create_event (const char *name, EVENT *event); +static uint32 destroy_event (const char *name, EVENT *event); +static t_bool event_is_undefined (EVENT event); +static uint32 wait_event (EVENT event, uint32 wait_in_ms, t_bool *signaled); +static uint32 signal_event (EVENT event); + + +/* IPL SCP data structures */ + +/* Device information blocks */ + +static DIB ipl_dib [CARD_COUNT] = { + { &ipl_interface, /* the device's I/O interface function pointer */ + IPLI, /* the device's select code (02-77) */ + 0 }, /* the card index if multiple interfaces are supported */ + + { &ipl_interface, /* the device's I/O interface function pointer */ + IPLO, /* the device's select code (02-77) */ + 1 } /* the card index if multiple interfaces are supported */ + }; + + +/* Unit lists */ + +static UNIT ipl_unit [CARD_COUNT] = { + { UDATA (&card_service, UNIT_ATTABLE, 0) }, + { UDATA (&card_service, UNIT_ATTABLE, 0) } + }; + + +/* Register lists */ + +static REG ipli_reg [] = { +/* Macro Name Location Width Offset Flags */ +/* ------ -------- ---------------------- ----- ------ -------------------- */ + { ORDATA (IBUF, ipl [ipli].input_word, 16) }, + { ORDATA (OBUF, ipl [ipli].output_word, 16) }, + { FLDATA (CTL, ipl [ipli].control, 0) }, + { FLDATA (FLG, ipl [ipli].flag, 0) }, + { FLDATA (FBF, ipl [ipli].flagbuf, 0) }, + { DRDATA (TIME, poll_wait, 24), PV_LEFT }, + { DRDATA (EDTDELAY, edt_delay, 32), PV_LEFT | REG_HIDDEN }, + { DRDATA (EVTERR, event_error, 32), PV_LEFT | REG_HRO }, + { ORDATA (SC, ipli_dib.select_code, 6), REG_HRO }, + { ORDATA (DEVNO, ipli_dib.select_code, 6), REG_HRO }, { NULL } }; -MTAB ipl_mod [] = { -/* Mask Value Match Value Print String Match String Validation Display Descriptor */ -/* ---------- ----------- ----------------- ------------ ------------- ------- ---------- */ - { UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAGNOSTIC", &ipl_setdiag, NULL, NULL }, - { UNIT_DIAG, 0, "link mode", "LINK", &ipl_setdiag, NULL, NULL }, +static REG iplo_reg [] = { +/* Macro Name Location Width Offset Flags */ +/* ------ -------- ---------------------- ----- ------ -------------------- */ + { ORDATA (IBUF, ipl [iplo].input_word, 16) }, + { ORDATA (OBUF, ipl [iplo].output_word, 16) }, + { FLDATA (CTL, ipl [iplo].control, 0) }, + { FLDATA (FLG, ipl [iplo].flag, 0) }, + { FLDATA (FBF, ipl [iplo].flagbuf, 0) }, + { DRDATA (TIME, poll_wait, 24), PV_LEFT }, + { ORDATA (SC, iplo_dib.select_code, 6), REG_HRO }, + { ORDATA (DEVNO, iplo_dib.select_code, 6), REG_HRO }, + { NULL } + }; -/* Entry Flags Value Print String Match String Validation Display Descriptor */ -/* -------------------- ----- ------------ ------------ ------------ ------------- ----------------- */ - { MTAB_XDV, 0u, NULL, "DISCONNECT", &ipl_dscln, NULL, NULL }, - { MTAB_XDV, 2u, "SC", "SC", &hp_set_dib, &hp_show_dib, (void *) &ipl_dib }, - { MTAB_XDV | MTAB_NMO, ~2u, "DEVNO", "DEVNO", &hp_set_dib, &hp_show_dib, (void *) &ipl_dib }, + +/* Modifier lists */ + +static MTAB ipl_mod [] = { +/* Mask Value Match Value Print String Match String Validation Display Descriptor */ +/* ---------- ----------- ----------------- ------------ -------------- ------- ---------- */ + { UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAGNOSTIC", &ipl_set_diag, NULL, NULL }, + { UNIT_DIAG, 0, "link mode", "LINK", &ipl_set_diag, NULL, NULL }, + +/* Entry Flags Value Print String Match String Validation Display Descriptor */ +/* -------------------- ----- ------------ ------------ -------------- ------------- ----------------- */ + { MTAB_XDV, 0u, NULL, "WAIT", &ipl_set_sync, NULL, NULL }, + { MTAB_XDV, 1u, NULL, "SIGNAL", &ipl_set_sync, NULL, NULL }, + { MTAB_XDV, 2u, "SC", "SC", &hp_set_dib, &hp_show_dib, (void *) &ipl_dib }, + { MTAB_XDV | MTAB_NMO, ~2u, "DEVNO", "DEVNO", &hp_set_dib, &hp_show_dib, (void *) &ipl_dib }, { 0 } }; + +/* Debugging trace lists */ + +static DEBTAB ipl_deb [] = { + { "CMD", TRACE_CMD }, /* trace interface or controller commands */ + { "CSRW", TRACE_CSRW }, /* trace interface control, status, read, and write actions */ + { "PSERV", TRACE_PSERV }, /* trace periodic unit service scheduling calls and entries */ + { "XFER", TRACE_XFER }, /* trace data transmissions */ + { "IOBUS", TRACE_IOBUS }, /* trace I/O bus signals and data words received and returned */ + { NULL, 0 } + }; + + +/* Device descriptors */ + DEVICE ipli_dev = { - "IPLI", /* device name */ + "IPL", /* device name (logical name "IPLI") */ &ipli_unit, /* unit array */ ipli_reg, /* register array */ ipl_mod, /* modifier array */ @@ -219,8 +511,8 @@ DEVICE ipli_dev = { 1, /* address increment */ 16, /* data radix */ 16, /* data width */ - &tmxr_ex, /* examine routine */ - &tmxr_dep, /* deposit routine */ + NULL, /* examine routine */ + NULL, /* deposit routine */ &ipl_reset, /* reset routine */ &ipl_boot, /* boot routine */ &ipl_attach, /* attach routine */ @@ -233,26 +525,6 @@ DEVICE ipli_dev = { NULL /* logical device name */ }; -/* IPLO data structures - - iplo_dev IPLO device descriptor - iplo_unit IPLO unit descriptor - iplo_reg IPLO register list -*/ - -REG iplo_reg [] = { - { ORDATA (IBUF, iplo_unit.IBUF, 16) }, - { ORDATA (OBUF, iplo_unit.OBUF, 16) }, - { FLDATA (CTL, ipl [iplo].control, 0) }, - { FLDATA (FLG, ipl [iplo].flag, 0) }, - { FLDATA (FBF, ipl [iplo].flagbuf, 0) }, - { ORDATA (HOLD, ipl [iplo].hold, 8) }, - { DRDATA (TIME, ipl_ptime, 24), PV_LEFT }, - { ORDATA (SC, iplo_dib.select_code, 6), REG_HRO }, - { ORDATA (DEVNO, iplo_dib.select_code, 6), REG_HRO }, - { NULL } - }; - DEVICE iplo_dev = { "IPLO", /* device name */ &iplo_unit, /* unit array */ @@ -264,8 +536,8 @@ DEVICE iplo_dev = { 1, /* address increment */ 16, /* data radix */ 16, /* data width */ - &tmxr_ex, /* examine routine */ - &tmxr_dep, /* deposit routine */ + NULL, /* examine routine */ + NULL, /* deposit routine */ &ipl_reset, /* reset routine */ NULL, /* boot routine */ &ipl_attach, /* attach routine */ @@ -278,13 +550,22 @@ DEVICE iplo_dev = { NULL /* logical device name */ }; +static DEVICE *dptrs [CARD_COUNT] = { + &ipli_dev, + &iplo_dev + }; + + /* I/O signal handler for the IPLI and IPLO devices. - In the link mode, the IPLI and IPLO devices are linked via network - connections to the corresponding cards in another CPU instance. In the - diagnostic mode, we simulate the attachment of the interprocessor cable - between IPLI and IPLO in this machine. + In the link mode, the IPLI and IPLO devices are linked via a shared memory + region to the corresponding cards in another CPU instance. If only one or + the other device is in the diagnostic mode, we simulate the attachment of a + loopback connector to that device. If both devices are in the diagnostic + mode, we simulate the attachment of the interprocessor cable between IPLI and + IPLO in this machine. + Implementation notes: @@ -329,9 +610,9 @@ DEVICE iplo_dev = { a data response to the SP. This improves the race condition by delaying the IOP until the SP has a chance to receive the last word, recognize its own DMA input completion, drop out of the SFS loop, and execute the - STC/CLC. The delay, "ipl_edtdelay", is initialized to one millisecond - but is exposed via a hidden IPLI register, "EDTDELAY", that allows the - user to lengthen the delay if necessary. + STC/CLC. The delay, "edt_delay", is initialized to one millisecond but + is exposed via a hidden IPLI register, "EDTDELAY", that allows the user + to lengthen the delay if necessary. The condition is only improved, and not solved, because "sleep"ing the IOP doesn't guarantee that the SP will actually execute. It's possible @@ -339,51 +620,31 @@ DEVICE iplo_dev = { sleep expiration, the SP still has not executed the STC/CLC. Still, in testing, the incidence dropped dramatically, so the problem is much less intrusive. - - 2. The operating manual for the 12920A Terminal Multiplexer says that "at - least 100 milliseconds of CLC 0s must be programmed" by systems employing - the multiplexer to ensure that the multiplexer resets. In practice, such - systems issue 128K CLC 0 instructions. As we provide debug logging of - IPL resets, a CRS counter is used to ensure that only one debug line is - printed in response to these 128K CRS invocations. - - 3. The STC handler may return "Unit not attached", "I/O error", or "No - connection on interprocessor link" status if the link fails or is - improperly configured. If the error is corrected, the operation may be - retried by resuming simulated execution. */ -uint32 iplio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) +static uint32 ipl_interface (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) { -CARD_INDEX card = (CARD_INDEX) dibptr->card_index; /* set card selector */ -UNIT *const uptr = &(ipl_unit [card]); /* associated unit pointer */ const char *iotype [] = { "Status", "Command" }; -int32 sta; -char msg [2]; -static uint32 crs_count [CARD_COUNT] = { 0, 0 }; /* per-card cntrs for ioCRS repeat */ +const CARD_INDEX card = (CARD_INDEX) dibptr->card_index; /* set card selector */ +UNIT *const uptr = &(ipl_unit [card]); /* associated unit pointer */ IOSIGNAL signal; IOCYCLE working_set = IOADDSIR (signal_set); /* add ioSIR if needed */ -if (crs_count [card] && !(signal_set & ioCRS)) { /* counting CRSes and not present? */ - tpprintf (dptrs [card], DEB_CMDS, "[CRS] Control cleared %d times\n", - crs_count [card]); - - crs_count [card] = 0; /* clear counter */ - } - while (working_set) { signal = IONEXT (working_set); /* isolate next signal */ switch (signal) { /* dispatch I/O signal */ case ioCLF: /* clear flag flip-flop */ - ipl [card].flag = ipl [card].flagbuf = CLEAR; + ipl [card].flag = CLEAR; + ipl [card].flagbuf = CLEAR; break; case ioSTF: /* set flag flip-flop */ case ioENF: /* enable flag */ - ipl [card].flag = ipl [card].flagbuf = SET; + ipl [card].flag = SET; + ipl [card].flagbuf = SET; break; @@ -398,87 +659,68 @@ while (working_set) { case ioIOI: /* I/O data input */ - stat_data = IORETURN (SCPE_OK, uptr->IBUF); /* get return data */ + stat_data = IORETURN (SCPE_OK, ipl [card].input_word); /* get return data */ - tpprintf (dptrs [card], DEB_CPU, "[LIx] %s = %06o\n", iotype [card ^ 1], uptr->IBUF); + tpprintf (dptrs [card], TRACE_CSRW, "%s input word is %06o\n", + iotype [card ^ 1], ipl [card].input_word); break; - case ioIOO: /* I/O data output */ - uptr->OBUF = IODATA (stat_data); /* clear supplied status */ + case ioIOO: /* I/O data output */ + ipl [card].output_word = IODATA (stat_data); /* clear supplied status */ - tpprintf (dptrs [card], DEB_CPU, "[OTx] %s = %06o\n", iotype [card], uptr->OBUF); + io_ptrs [card].output->data_out = ipl [card].output_word; + + tpprintf (dptrs [card], TRACE_CSRW, "%s output word is %06o\n", + iotype [card], ipl [card].output_word); break; case ioPOPIO: /* power-on preset to I/O */ - ipl [card].flag = ipl [card].flagbuf = SET; /* set flag buffer and flag */ - uptr->OBUF = 0; /* clear output buffer */ + ipl [card].flag = SET; /* set flag buffer and flag */ + ipl [card].flagbuf = SET; + ipl [card].output_word = 0; /* clear output buffer */ + + io_ptrs [card].output->data_out = 0; break; case ioCRS: /* control reset */ - if (crs_count [card] == 0) /* first reset? */ - ipl [card].control = CLEAR; /* clear control */ - - crs_count [card] = crs_count [card] + 1; /* increment count */ - break; - - case ioCLC: /* clear control flip-flop */ ipl [card].control = CLEAR; /* clear ctl */ - - tpprintf (dptrs [card], DEB_CMDS, "[CLC] Control cleared\n"); break; case ioSTC: /* set control flip-flop */ - tpprintf (dptrs [card], DEB_CMDS, "[STC] Control set\n"); + ipl [card].control = SET; /* set ctl */ - if (uptr->flags & UNIT_ATT) { /* attached? */ - if (!ipl_check_conn (uptr)) { /* not established? */ - cpu_ioerr_uptr = uptr; /* save the failing unit */ - return IORETURN (STOP_NOCONN, 0); /* lose */ + io_ptrs [card].output->device_command_out = TRUE; /* assert Device Command */ + + if (uptr->flags & UNIT_DIAG) /* if this card is in the diagnostic mode */ + if (ipl_unit [card ^ 1].flags & UNIT_DIAG) { /* then if both cards are in diagnostic mode */ + ipl_unit [card ^ 1].wait = 1; /* then schedule the other card */ + activate_unit (&ipl_unit [card ^ 1]); /* for immediate reception */ } - msg [0] = UPPER_BYTE (uptr->OBUF); - msg [1] = LOWER_BYTE (uptr->OBUF); - sta = sim_write_sock (uptr->DSOCKET, msg, 2); - - tpprintf (dptrs [card], DEB_XFER, "[STC] Socket write = %06o, status = %d\n", - uptr->OBUF, sta); - - if (sta == SOCKET_ERROR) { /* if the write fails, report it to the console */ - cprintf ("%s simulator processor interconnect socket write error\n", - sim_name); - return IORETURN (SCPE_IOERR, 0); /* and stop the simulator with an I/O error */ + else { /* otherwise simulate a loopback */ + uptr->wait = 1; /* by scheduling this card */ + activate_unit (uptr); /* for immediate reception */ } - ipl [card].control = SET; /* set ctl */ - - sim_os_sleep (0); /* yield */ - } - - else if (uptr->flags & UNIT_DIAG) { /* diagnostic mode? */ - ipl [card].control = SET; /* set ctl */ - ipl_unit [card ^ 1].IBUF = uptr->OBUF; /* output to other */ - iplio ((DIB *) dptrs [card ^ 1]->ctxt, ioENF, 0); /* set other flag */ - } - - else - return IORETURN (SCPE_UNATT, 0); /* lose */ + tpprintf (dptrs [card], TRACE_XFER, "Word %06o sent to link\n", + ipl [card].output_word); break; case ioEDT: /* end data transfer */ - if ((cpu_unit.flags & UNIT_IOP) && /* are we the IOP? */ - (signal_set & ioIOO) && /* and doing output? */ - (card == ipli)) { /* on the input card? */ + if (cpu_is_iop /* if this is the IOP instance */ + && signal_set & ioIOO /* and the card is doing output */ + && card == ipli) { /* on the input card */ - tpprintf (dptrs [card], DEB_CMDS, "[EDT] Delaying DMA completion interrupt for %d msec\n", - ipl_edtdelay); + tprintf (ipli_dev, TRACE_CMD, "Delaying DMA completion interrupt for %d msec\n", + edt_delay); - sim_os_ms_sleep (ipl_edtdelay); /* delay completion */ + sim_os_ms_sleep (edt_delay); /* then delay DMA completion */ } break; @@ -508,389 +750,1155 @@ return stat_data; /* Unit service - poll for input */ -t_stat ipl_svc (UNIT *uptr) +static t_stat card_service (UNIT *uptr) { -CARD_INDEX card; -int32 nb; -char msg [2]; +static uint32 delta [CARD_COUNT] = { 0, 0 }; /* per-card accumulated time between receptions */ +const CARD_INDEX card = (CARD_INDEX) (uptr == &iplo_unit); /* set card selector */ +t_stat status = SCPE_OK; -if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ - return SCPE_OK; +tpprintf (dptrs [card], TRACE_PSERV, "Poll delay %d service entered\n", + uptr->wait); -sim_activate (uptr, ipl_ptime); /* reactivate */ +delta [card] = delta [card] + uptr->wait; /* update the accumulated time */ -if (!ipl_check_conn (uptr)) /* check for conn */ - return SCPE_OK; /* not connected */ +if (io_ptrs [card].input->device_flag_in == TRUE) { /* if the Device Flag is asserted */ + io_ptrs [card].input->device_flag_in = FALSE; /* then clear it */ -nb = sim_read_sock (uptr->DSOCKET, msg, ((uptr->flags & UNIT_HOLD)? 1: 2)); + ipl [card].input_word = io_ptrs [card].input->data_in; /* read the data input lines */ -if (nb < 0) { /* connection closed? */ - cprintf ("%s simulator processor interconnect socket read error\n", - sim_name); - return SCPE_IOERR; + tpprintf (dptrs [card], TRACE_XFER, "Word %06o delta %u received from link\n", + ipl [card].input_word, delta [card]); + + ipl_interface (&ipl_dib [card], ioENF, 0); /* set the flag */ + + io_ptrs [card].output->device_command_out = FALSE; /* reset Device Command */ + + uptr->wait = 1; /* restart polling at the minimum time */ + delta [card] = 0; /* and clear the accumulated time */ } -else if (nb == 0) /* no data? */ - return SCPE_OK; +else { /* otherwise Device Flag is denied */ + uptr->wait = uptr-> wait * 2; /* so double the wait time for the next check */ -card = (CARD_INDEX) (uptr == &iplo_unit); /* set card selector */ + if (uptr->wait > poll_wait) /* if the new time is greater than the maximum time */ + uptr->wait = poll_wait; /* then limit it to the maximum */ -if (uptr->flags & UNIT_HOLD) { /* holdover byte? */ - uptr->IBUF = (ipl [card].hold << 8) | (((int32) msg [0]) & 0377); - uptr->flags = uptr->flags & ~UNIT_HOLD; + if (io_ptrs [card].input->cable_connected == FALSE /* if the interconnecting cable is not present */ + && cpu_ss_ioerr != SCPE_OK) { /* and the I/O error stop is enabled */ + cpu_ioerr_uptr = uptr; /* then save the failing unit */ + status = STOP_NOCONN; /* and report the disconnection */ + } } -else if (nb == 1) { - ipl [card].hold = ((int32) msg [0]) & 0377; - uptr->flags = uptr->flags | UNIT_HOLD; - } -else - uptr->IBUF = ((((int32) msg [0]) & 0377) << 8) | (((int32) msg [1]) & 0377); -iplio ((DIB *) dptrs [card]->ctxt, ioENF, 0); /* set flag */ +if (uptr->flags & UNIT_ATT) /* if the link is active */ + activate_unit (uptr); /* then continue to poll for input */ -tpprintf (dptrs [card], DEB_XFER, "Socket read = %06o, status = %d\n", - uptr->IBUF, nb); - -return SCPE_OK; +return status; /* return the event service status */ } -t_bool ipl_check_conn (UNIT *uptr) -{ -SOCKET sock; +/* Reset the IPL. -if (uptr->flags & UNIT_ESTB) /* established? */ - return TRUE; + This routine is called for a RESET, RESET IPLI, or RESET IPLO command. It is + the simulation equivalent of the POPIO signal, which is asserted by the front + panel PRESET switch. -if (uptr->flags & UNIT_ACTV) { /* active connect? */ - if (sim_check_conn (uptr->DSOCKET, 0) <= 0) - return FALSE; - } - -else { - sock = sim_accept_conn (uptr->LSOCKET, NULL); /* poll connect */ - - if (sock == INVALID_SOCKET) /* got a live one? */ - return FALSE; - - uptr->DSOCKET = sock; /* save data socket */ - } - -uptr->flags = uptr->flags | UNIT_ESTB; /* conn established */ -return TRUE; -} - - -/* Reset routine. - - Implementation notes: - - 1. We set up the first poll for socket connections to occur "immediately" - upon execution, so that clients will be connected before execution - begins. Otherwise, a fast program may access the IPL before the poll - service routine activates. + For a power-on reset, the logical name "IPLI" is assigned to the first + processor interconnect card, so that it may referenced either as that name or + as "IPL" for use when a SET command affects both interfaces. */ -t_stat ipl_reset (DEVICE *dptr) +static t_stat ipl_reset (DEVICE *dptr) { UNIT *uptr = dptr->units; DIB *dibptr = (DIB *) dptr->ctxt; /* DIB pointer */ CARD_INDEX card = (CARD_INDEX) dibptr->card_index; /* card number */ -hp_enbdis_pair (dptr, dptrs [card ^ 1]); /* make pair cons */ +hp_enbdis_pair (dptr, dptrs [card ^ 1]); /* ensure that the pair state is consistent */ -if (sim_switches & SWMASK ('P')) /* initialization reset? */ - uptr->IBUF = uptr->OBUF = 0; /* clr buffers */ +if (sim_switches & SWMASK ('P')) { /* initialization reset? */ + ipl [card].input_word = 0; + ipl [card].output_word = 0; + + if (ipli_dev.lname == NULL) /* logical name unassigned? */ + ipli_dev.lname = strdup ("IPLI"); /* allocate and initialize the name */ + } IOPRESET (dibptr); /* PRESET device (does not use PON) */ -if (uptr->flags & UNIT_ATT) /* socket attached? */ - sim_activate (uptr, POLL_FIRST); /* activate first poll "immediately" */ -else - sim_cancel (uptr); /* deactivate unit */ +if (uptr->flags & UNIT_ATT) { /* if the link is active */ + uptr->wait = poll_wait; /* then continue to poll for input */ + activate_unit (uptr); /* at the idle rate */ + } + +else /* otherwise the link is inactive */ + sim_cancel (uptr); /* so stop input polling */ -uptr->flags = uptr->flags & ~UNIT_HOLD; /* clear holding flag */ return SCPE_OK; } -/* Attach routine +/* Attach one end of the interconnecting cables. - attach -l - listen for connection on port - attach -c - connect to ip address and port + This routine connects the IPL device pair to a shared memory region. This + simulates connecting one end of the processor interconnect kit cables to the + card pair in this CPU. The command is: + + ATTACH [ -S | -I ] IPL + + ...where is a user-selected decimal number between 1 and 65535 that + uniquely identifies the instance pair to interconnect. The -S or -I switch + indicates whether this instance is acting as the System Processor or the I/O + Processor. The command will be rejected if either device is in diagnostic + mode, or if the is omitted, malformed, or out of range. + + For backward compatibility with prior IPL implementations that used network + interconnections, the following commands are also accepted: + + ATTACH [ -L ] [ IPLI | IPLO] + ATTACH -C [ IPLI | IPLO] + + For these commands, -L or no switch indicates the SP instance, and -C + indicates the IOP instance. and used to indicate the + network port numbers to use, but now it serves only to supply the code + number from the lesser of the two values. + + Local memory is allocated to hold the code number string, which serves as the + "attached file name" for the SCP SHOW command. If memory allocation fails, + the command is rejected. + + This routine creates a shared memory region and an event (semaphore) that are + used to coordinate a data exchange with the other simulator instance. If -S + or -I is specified, then creation occurs after the ATTACH command is given + for either the IPLI or IPLO device, and both devices are marked as attached. + If -L or -C is specified, then both devices must be attached before creation + occurs using the lower port number. + + Two object names that identify the shared memory region and synchronization + event are derived from the (or lower ) number: + + /HP 2100-MEM- + /HP 2100-EVT- + + Each simulator instance must use the same (or pair) when + attaching for the interconnection to occur. This permits multiple instance + pairs to operate simultaneously and independently, if desired. + + Once shared memory is allocated, pointers to the region for the SP and IOP + instances are set so that the output card pointer of one instance and the + input card pointer of the other instance reference the same memory structure. + This accomplishes the interconnection, as a write to one instance's card will + be seen by a read from the other instance's card. + + If the shared memory allocation succeeds but the process synchronization + event creation fails, the routine returns "Command not completed" status to + indicate that interconnection without synchronization is permitted. + + + Implementation notes: + + 1. The implementation supports process synchronization only on the local + system. + + 2. The object names begin with slashes to conform to POSIX requirements to + guarantee that multiple instances to refer to the same shared memory + region. Omitting the slash results in implementation-defined behavior on + POSIX systems. */ -t_stat ipl_attach (UNIT *uptr, CONST char *cptr) +static t_stat ipl_attach (UNIT *uptr, CONST char *cptr) { -SOCKET newsock; -char *tptr = NULL; -t_stat r; +t_stat status; +int32 id_number; +char object_name [PATH_MAX]; +CONST char *zptr; +char *tptr; +IO_STATE_PTR isp; +UNIT *optr; -#if (SIM_MAJOR >= 4) +if ((ipli_unit.flags | iplo_unit.flags) & UNIT_DIAG) /* if either unit is in diagnostic mode */ + return SCPE_NOFNC; /* then the command is not allowed */ -uint32 i, t; -char host [CBUFSIZE], port [CBUFSIZE], hostport [2 * CBUFSIZE + 3]; +else if (uptr->flags & UNIT_ATT) /* otherwise if the unit is currently attached */ + ipl_detach (uptr); /* then detach it first */ -t_bool is_active; +id_number = (int32) strtotv (cptr, &zptr, 10); /* parse the command for the ID number */ -is_active = (uptr->flags & UNIT_ACTV) == UNIT_ACTV; /* is the connection active? */ +if (cptr == zptr || *zptr != '\0' || id_number == 0) /* if the parse failed or extra characters or out of range */ + return SCPE_ARG; /* then reject the attach with an invalid argument error */ -if (uptr->flags & UNIT_ATT) /* if IPL is currently attached, */ - ipl_detach (uptr); /* detach it first */ +else { /* otherwise a single number was specified */ + tptr = (char *) malloc (strlen (cptr) + 1); /* so allocate a string buffer to hold the ID */ -if ((sim_switches & SWMASK ('C')) || /* connecting? */ - ((sim_switches & SIM_SW_REST) && is_active)) { /* or restoring an active connection? */ - r = sim_parse_addr (cptr, host, /* parse the host and port */ - sizeof (host), "localhost", /* from the parameter string */ - port, sizeof (port), - NULL, NULL); + if (tptr == NULL) /* if the allocation failed */ + return SCPE_MEM; /* then reject the attach with an out-of-memory error */ - if ((r != SCPE_OK) || (port [0] == '\0')) /* parse error or missing port number? */ - return SCPE_ARG; /* complain to the user */ + else { /* otherwise */ + strcpy (tptr, cptr); /* copy the ID number to the buffer */ + uptr->filename = tptr; /* and assign it as the attached object name */ - sprintf(hostport, "%s%s%s%s%s", strchr(host, ':') ? "[" : "", host, strchr(host, ':') ? "]" : "", host [0] ? ":" : "", port); + uptr->flags |= UNIT_ATT; /* set the unit attached flag */ + uptr->ID = id_number; /* and save the ID number */ - newsock = sim_connect_sock (hostport, NULL, NULL); + uptr->wait = poll_wait; /* set up the initial poll time */ + activate_unit (uptr); /* and activate the unit to poll */ + } - if (newsock == INVALID_SOCKET) - return SCPE_IOERR; + if ((sim_switches & (SP | IOP)) == 0) /* if this is not a single-device attach */ + if (ipli_unit.ID == 0 || iplo_unit.ID == 0) /* then if both devices have not been attached yet */ + return SCPE_OK; /* then we've done all we can do */ - cprintf ("Connecting to %s\n", hostport); + else if (ipli_unit.ID < iplo_unit.ID) /* otherwise */ + id_number = ipli_unit.ID; /* determine */ + else /* the lower */ + id_number = iplo_unit.ID; /* ID number */ - uptr->flags = uptr->flags | UNIT_ACTV; - uptr->LSOCKET = 0; - uptr->DSOCKET = newsock; + else { /* otherwise this is a single-device attach */ + if (uptr == &ipli_unit) /* so if we are attaching the input unit */ + optr = &iplo_unit; /* then point at the output unit */ + else /* otherwise we are attaching the output unit */ + optr = &ipli_unit; /* so point at the input unit */ + + optr->filename = tptr; /* assign the ID as the attached object name */ + + optr->flags |= UNIT_ATT; /* set the unit attached flag */ + optr->ID = id_number; /* and save the ID number */ + + optr->wait = poll_wait; /* set up the initial poll time */ + activate_unit (optr); /* and activate the unit to poll */ + } + + sprintf (object_name, "/%s-MEM-%d", /* generate the shared memory area name */ + sim_name, id_number); + + status = sim_shmem_open (object_name, sizeof dev_bus, /* allocate the shared memory area */ + &memory_region, (void **) &isp); + + if (status != SCPE_OK) { /* if the allocation failed */ + ipl_detach (uptr); /* then detach this unit */ + return status; /* and report the error */ + } + + else { /* otherwise */ + cpu_is_iop = ((sim_switches & (CONNECT | IOP)) != 0); /* -C or -I imply that this is the I/O Processor */ + + if (cpu_is_iop) { /* if this is the IOP instance */ + io_ptrs [ipli].input = &isp [iplo].reverse.input; /* then cross-connect */ + io_ptrs [ipli].output = &isp [iplo].reverse.output; /* the input and output */ + io_ptrs [iplo].input = &isp [ipli].reverse.input; /* interface cards to the */ + io_ptrs [iplo].output = &isp [ipli].reverse.output; /* SP interface cards */ + } + + else { /* otherwise this is the SP instance */ + io_ptrs [ipli].input = &isp [ipli].forward.input; /* so connect */ + io_ptrs [ipli].output = &isp [ipli].forward.output; /* the interface cards */ + io_ptrs [iplo].input = &isp [iplo].forward.input; /* to the I/O cables */ + io_ptrs [iplo].output = &isp [iplo].forward.output; /* directly */ + } + + io_ptrs [ipli].output->cable_connected = TRUE; /* indicate that the cables */ + io_ptrs [iplo].output->cable_connected = TRUE; /* have been connected */ + } + + sprintf (event_name, "/%s-EVT-%d", /* generate the process synchronization event name */ + sim_name, id_number); + + event_error = create_event (event_name, &event_id); /* create the event */ + + if (event_error == 0) /* if event creation succeeded */ + return SCPE_OK; /* then report a successful attach */ + else /* otherwise */ + return SCPE_INCOMP; /* report that the command did not complete */ + } +} + + +/* Detach the interconnecting cables. + + This routine disconnects the IPL device pair from the shared memory region. + This simulates disconnecting the processor interconnect kit cables from the + card pair in this CPU. The command is: + + DETACH IPL + + For backward compatibility with prior IPL implementations that used network + interconnections, the following commands are also accepted: + + DETACH IPLI + DETACH IPLO + + In either case, the shared memory region and process synchronization event + are destroyed, and the card state pointers are reset to point at the local + memory structure. If a single ATTACH was done, a single DETACH will detach + both devices and free the allocated "file name" memory. The input poll is + also stopped. + + If the event destruction failed, the routine returns "Command not completed" + status to indicate that the error code register should be checked. +*/ + +static t_stat ipl_detach (UNIT *uptr) +{ +UNIT *optr; + +if ((uptr->flags & UNIT_ATT) == 0) /* if the unit is not attached */ + if (sim_switches & SIM_SW_REST) /* then if this is a restoration call */ + return SCPE_OK; /* then return success */ + else /* otherwise this is a manual request */ + return SCPE_UNATT; /* so complain that the unit is not attached */ + +if (ipli_unit.filename == iplo_unit.filename) { /* if both units are attached to the same object */ + if (uptr == &ipli_unit) /* then if we are detaching the input unit */ + optr = &iplo_unit; /* then point at the output unit */ + else /* otherwise we are detaching the output unit */ + optr = &ipli_unit; /* so point at the input unit */ + + optr->filename = NULL; /* clear the other unit's attached object name */ + + optr->flags &= ~UNIT_ATT; /* clear the other unit's attached flag */ + optr->ID = 0; /* and the ID number */ + + sim_cancel (optr); /* cancel the other unit's poll */ } -else { - if (sim_parse_addr (cptr, host, sizeof(host), NULL, port, sizeof(port), NULL, NULL)) - return SCPE_ARG; - sprintf(hostport, "%s%s%s%s%s", strchr(host, ':') ? "[" : "", host, strchr(host, ':') ? "]" : "", host [0] ? ":" : "", port); - newsock = sim_master_sock (hostport, &r); - if (r != SCPE_OK) - return r; - if (newsock == INVALID_SOCKET) - return SCPE_IOERR; - cprintf ("Listening on port %s\n", hostport); - uptr->flags = uptr->flags & ~UNIT_ACTV; - uptr->LSOCKET = newsock; - uptr->DSOCKET = 0; +free (uptr->filename); /* free the memory holding the ID number */ +uptr->filename = NULL; /* and clear the attached object name */ + +uptr->flags &= ~UNIT_ATT; /* clear the unit attached flag */ +uptr->ID = 0; /* and the ID number */ + +sim_cancel (uptr); /* cancel the poll */ + +io_ptrs [ipli].output->cable_connected = FALSE; /* disconnect the cables */ +io_ptrs [iplo].output->cable_connected = FALSE; /* from both cards */ + +io_ptrs [ipli].input = &dev_bus [ipli].forward.input; /* restore local control */ +io_ptrs [ipli].output = &dev_bus [ipli].forward.output; /* over the I/O state */ +io_ptrs [iplo].input = &dev_bus [iplo].forward.input; /* for both cards */ +io_ptrs [iplo].output = &dev_bus [iplo].forward.output; + +sim_shmem_close (memory_region); /* deallocate the shared memory region */ +memory_region = NULL; /* and clear the region pointer */ + +event_error = destroy_event (event_name, &event_id); /* destroy the event */ + +if (event_error == 0) /* if the destruction succeeded */ + return SCPE_OK; /* then report success */ +else /* otherwise */ + return SCPE_INCOMP; /* report that the command did not complete */ +} + + +/* Set the diagnostic or link mode. + + This validation routine is entered with the "value" parameter set to zero if + the unit is to be set into the link (normal) mode or non-zero if the unit is + to be set into the diagnostic mode. The character and descriptor pointers + are not used. + + In addition to setting or clearing the UNIT_DIAG flag, the I/O state pointers + are set to point at the appropriate state structure. The selected pointer + configuration depends on whether none, one, or both the IPLI and IPLO devices + are in diagnostic mode. + + If both devices are in diagnostic mode, the pointers are set to point at + their respective state structures but with the input and output pointers + reversed. This simulates connecting one of the interprocessor cables between + the two cards within the same CPU, permitting the Processor Interconnect + Cable Diagnostic to be run. + + If only one of the devices is in diagnostic mode, the pointers are set to + point at the device's state structure with the input and output pointers + reversed. This simulates connected a loopback connector to the card, + permitting the General Register Diagnostic to be run. + + If a device is in link mode, that device's pointers are set to point at the + corresponding parts of the device's state structure. This simulates a card + with no cable connected. + + If the device is attached, setting it into diagnostic mode will detach it + first. +*/ + +static t_stat ipl_set_diag (UNIT *uptr, int32 value, CONST char *cptr, void *desc) +{ +if (value) { /* if this is an entry into diagnostic mode */ + ipl_detach (uptr); /* then detach it first */ + uptr->flags |= UNIT_DIAG; /* before setting the flag */ } -uptr->IBUF = uptr->OBUF = 0; -uptr->flags = (uptr->flags | UNIT_ATT) & ~(UNIT_ESTB | UNIT_HOLD); -tptr = (char *) malloc (strlen (hostport) + 1); /* get string buf */ -if (tptr == NULL) { /* no memory? */ - ipl_detach (uptr); /* close sockets */ - return SCPE_MEM; + +else /* otherwise this is an entry into link mode */ + uptr->flags &= ~UNIT_DIAG; /* so clear the flag */ + +if (ipli_unit.flags & iplo_unit.flags & UNIT_DIAG) { /* if both devices are now in diagnostic mode */ + io_ptrs [ipli].input = &dev_bus [iplo].reverse.input; /* then connect the cable */ + io_ptrs [ipli].output = &dev_bus [ipli].forward.output; /* so that the outputs of one card */ + io_ptrs [iplo].input = &dev_bus [ipli].reverse.input; /* are connected to the inputs of the other card */ + io_ptrs [iplo].output = &dev_bus [iplo].forward.output; /* and vice versa */ + + io_ptrs [ipli].output->cable_connected = TRUE; /* indicate that the cable */ + io_ptrs [iplo].output->cable_connected = TRUE; /* has been connected between the cards */ } -strcpy (tptr, hostport); /* copy ipaddr:port */ + +else { /* otherwise */ + if (ipli_unit.flags & UNIT_DIAG) { /* if the input card is in diagnostic mode */ + io_ptrs [ipli].input = &dev_bus [ipli].reverse.input; /* then loop the card outputs */ + io_ptrs [ipli].output = &dev_bus [ipli].forward.output; /* back to the inputs and vice versa */ + io_ptrs [ipli].output->cable_connected = TRUE; /* and indicate that the card is connected */ + } + + else { /* otherwise the card is in link mode */ + io_ptrs [ipli].input = &dev_bus [ipli].forward.input; /* so point at the card state */ + io_ptrs [ipli].output = &dev_bus [ipli].forward.output; /* in the normal direction */ + io_ptrs [ipli].output->cable_connected = FALSE; /* and indicate that the card is not connected */ + } + + if (iplo_unit.flags & UNIT_DIAG) { /* otherwise */ + io_ptrs [iplo].input = &dev_bus [iplo].reverse.input; /* if the output card is in diagnostic mode */ + io_ptrs [iplo].output = &dev_bus [iplo].forward.output; /* then loop the card outputs */ + io_ptrs [iplo].output->cable_connected = TRUE; /* back to the inputs and vice versa */ + } /* and indicate that the card is connected */ + + else { + io_ptrs [iplo].input = &dev_bus [iplo].forward.input; /* otherwise the card is in link mode */ + io_ptrs [iplo].output = &dev_bus [iplo].forward.output; /* so point at the card state */ + io_ptrs [iplo].output->cable_connected = FALSE; /* in the normal direction */ + } /* and indicate that the card is not connected */ + } + +return SCPE_OK; +} + + +/* Synchronize the simulator instance. + + This validation routine is entered with the "value" parameter set to zero to + wait on the synchronization event or non-zero to signal the synchronization + event. The unit, character, and descriptor pointers are not used. + + This routine is called for the following commands: + + SET IPLI WAIT + SET IPLI SIGNAL + + If the event object has not been created yet by attaching the IPL device, the + routine returns "Command not allowed" status. For either command, the + routine returns "Command not completed" if the signal or wait function + returned an error to indicate that the error code register should be checked. + + To permit the user to abort the wait command, a CTRL+C handler is installed, + and waits of one second each are performed in a loop. The handler will set + the "wait_aborted" variable TRUE if it is called, and the loop then will + terminate and return with success status. + + + Implementation notes: + + 1. The "wait_event" routine returns TRUE if the event is signaled and FALSE + if it times out while waiting. +*/ + +static t_stat ipl_set_sync (UNIT *uptr, int32 value, CONST char *cptr, void *desc) +{ +const uint32 wait_time = 1000; /* the wait time in milliseconds */ +t_bool signaled; + +if (event_is_undefined (event_id)) /* if the event has not been defined yet */ + return SCPE_NOFNC; /* then the command is not allowed */ + +if (value) { /* if this is a SIGNAL command */ + event_error = signal_event (event_id); /* then signal the event */ + + if (event_error == 0) /* if signaling succeeded */ + return SCPE_OK; /* then report command success */ + else /* otherwise */ + return SCPE_INCOMP; /* report that the command did not complete */ + } + +else { /* otherwise it's a WAIT command */ + wait_aborted = FALSE; /* clear the abort flag */ + signal (SIGINT, abort_handler); /* and set up the CTRL+C handler */ + + do + event_error = wait_event (event_id, wait_time, /* wait for the event */ + &signaled); /* to be signaled */ + while (! (event_error || wait_aborted || signaled)); /* unless an error or user abort occurs */ + + signal (SIGINT, SIG_DFL); /* restore the default CTRL+C handler */ + + if (event_error == 0) /* if the wait function succeeded */ + return SCPE_OK; /* then report command success */ + else /* otherwise */ + return SCPE_INCOMP; /* report that the command did not complete */ + } +} + + +/* Handler for the CTRL+C signal. + + This handler is installed while waiting for a synchronization event. It is + called if the user presses CTRL+C to abort the wait command. +*/ + +static void abort_handler (int signal) +{ +wait_aborted = TRUE; /* the user has aborted the event wait */ +return; +} + + +/* Activate a unit. + + The specified unit is added to the event queue with the delay specified by + the unit wait field. + + + Implementation notes: + + 1. This routine may be called with wait = 0, which will expire immediately + and enter the service routine with the next sim_process_event call. + Activation is required in this case to allow the service routine to + return an error code to stop the simulation. If the service routine was + called directly, any returned error would be lost. +*/ + +static void activate_unit (UNIT *uptr) +{ +const CARD_INDEX card = (CARD_INDEX) (uptr == &iplo_unit); /* set card selector */ + +tpprintf (dptrs [card], TRACE_PSERV, "Poll delay %u service scheduled\n", + uptr->wait); + +sim_activate (uptr, uptr->wait); /* activate the unit with the specified wait */ + +return; +} + + +/* Processor interconnect bootstrap loaders (special BBL and 12992K). + + The special Basic Binary Loader (BBL) used by the 2000 Access system loads + absolute binary programs into memory from either the processor interconnect + interface or the paper tape reader interface. Two program entry points are + provided. Starting the loader at address x7700 loads from the processor + interconnect, while starting at address x7750 loads from the paper tape + reader. The S register setting does not affect loader operation. + + For a 2100/14/15/16 CPU, entering a LOAD IPLI or BOOT IPLI command loads the + special BBL into memory and executes the processor interconnect portion + starting at x7700. Loader execution ends with one of the following halt + instructions: + + * HLT 11 - a checksum error occurred; A/B = the calculated/tape value. + * HLT 55 - the program load address would overlay the loader. + * HLT 77 - the end of input with successful read; A = the paper tape select + code, B = the processor interconnect select code. + + The 12992K boot loader ROM reads an absolute program from the processor + interconnect or paper tape interfaces into memory. The S register setting + does not affect loader operation. Loader execution ends with one of the + following halt instructions: + + * HLT 11 - a checksum error occurred; A/B = the calculated/tape value. + * HLT 55 - the program load address would overlay the ROM loader. + * HLT 77 - the end of tape was reached with a successful read. + + + Implementation notes: + + 1. After the BMDL has been loaded into memory, the paper tape portion may be + executed manually by setting the P register to the starting address + (x7750). + + 2. For compatibility with the "cpu_copy_loader" routine, the BBL device I/O + instructions address select code 10. + + 3. For 2000B, C, and F versions that use dual CPUs, the I/O Processor is + loaded with the standard BBL configured for the select codes of the + processor interconnect interface. 2000 Access must use the special BBL + because the paper tape reader is connected to the IOP in this version; in + prior versions, it was connected to the System Processor and could use + the paper-tape portion of the BMDL that was installed in the SP. +*/ + +static const LOADER_ARRAY ipl_loaders = { + { /* HP 21xx 2000/Access special Basic Binary Loader */ + 000, /* loader starting index */ + IBL_NA, /* DMA index */ + 073, /* FWA index */ + { 0163774, /* 77700: PI LDA 77774,I Processor Interconnect start */ + 0027751, /* 77701: JMP 77751 */ + 0107700, /* 77702: START CLC 0,C */ + 0002702, /* 77703: CLA,CCE,SZA */ + 0063772, /* 77704: LDA 77772 */ + 0002307, /* 77705: CCE,INA,SZA,RSS */ + 0027760, /* 77706: JMP 77760 */ + 0017736, /* 77707: JSB 77736 */ + 0007307, /* 77710: CMB,CCE,INB,SZB,RSS */ + 0027705, /* 77711: JMP 77705 */ + 0077770, /* 77712: STB 77770 */ + 0017736, /* 77713: JSB 77736 */ + 0017736, /* 77714: JSB 77736 */ + 0074000, /* 77715: STB 0 */ + 0077771, /* 77716: STB 77771 */ + 0067771, /* 77717: LDB 77771 */ + 0047773, /* 77720: ADB 77773 */ + 0002040, /* 77721: SEZ */ + 0102055, /* 77722: HLT 55 */ + 0017736, /* 77723: JSB 77736 */ + 0040001, /* 77724: ADA 1 */ + 0177771, /* 77725: STB 77771,I */ + 0037771, /* 77726: ISZ 77771 */ + 0000040, /* 77727: CLE */ + 0037770, /* 77730: ISZ 77770 */ + 0027717, /* 77731: JMP 77717 */ + 0017736, /* 77732: JSB 77736 */ + 0054000, /* 77733: CPB 0 */ + 0027704, /* 77734: JMP 77704 */ + 0102011, /* 77735: HLT 11 */ + 0000000, /* 77736: NOP */ + 0006600, /* 77737: CLB,CME */ + 0103700, /* 77740: STC 0,C */ + 0102300, /* 77741: SFS 0 */ + 0027741, /* 77742: JMP 77741 */ + 0106400, /* 77743: MIB 0 */ + 0002041, /* 77744: SEZ,RSS */ + 0127736, /* 77745: JMP 77736,I */ + 0005767, /* 77746: BLF,CLE,BLF */ + 0027740, /* 77747: JMP 77740 */ + 0163775, /* 77750: PTAPE LDA 77775,I Paper tape start */ + 0043765, /* 77751: CONFG ADA 77765 */ + 0073741, /* 77752: STA 77741 */ + 0043766, /* 77753: ADA 77766 */ + 0073740, /* 77754: STA 77740 */ + 0043767, /* 77755: ADA 77767 */ + 0073743, /* 77756: STA 77743 */ + 0027702, /* 77757: EOT JMP 77702 */ + 0063777, /* 77760: LDA 77777 */ + 0067776, /* 77761: LDB 77776 */ + 0102077, /* 77762: HLT 77 */ + 0027702, /* 77763: JMP 77702 */ + 0000000, /* 77764: NOP */ + 0102300, /* 77765: SFS 0 */ + 0001400, /* 77766: OCT 1400 */ + 0002500, /* 77767: OCT 2500 */ + 0000000, /* 77770: OCT 0 */ + 0000000, /* 77771: OCT 0 */ + 0177746, /* 77772: DEC -26 */ + 0100100, /* 77773: ABS -PI */ + 0077776, /* 77774: DEF *+2 */ + 0077777, /* 77775: DEF *+2 */ + 0000010, /* 77776: PISC OCT 10 */ + 0000010 } }, /* 77777: PTRSC OCT 10 */ + + { /* HP 1000 Loader ROM (12992K) */ + IBL_START, /* loader starting index */ + IBL_DMA, /* DMA index */ + IBL_FWA, /* FWA index */ + { 0107700, /* 77700: ST CLC 0,C ; intr off */ + 0002401, /* 77701: CLA,RSS ; skip in */ + 0063756, /* 77702: CN LDA M11 ; feed frame */ + 0006700, /* 77703: CLB,CCE ; set E to rd byte */ + 0017742, /* 77704: JSB READ ; get #char */ + 0007306, /* 77705: CMB,CCE,INB,SZB ; 2's comp */ + 0027713, /* 77706: JMP *+5 ; non-zero byte */ + 0002006, /* 77707: INA,SZA ; feed frame ctr */ + 0027703, /* 77710: JMP *-3 */ + 0102077, /* 77711: HLT 77B ; stop */ + 0027700, /* 77712: JMP ST ; next */ + 0077754, /* 77713: STA WC ; word in rec */ + 0017742, /* 77714: JSB READ ; get feed frame */ + 0017742, /* 77715: JSB READ ; get address */ + 0074000, /* 77716: STB 0 ; init csum */ + 0077755, /* 77717: STB AD ; save addr */ + 0067755, /* 77720: CK LDB AD ; check addr */ + 0047777, /* 77721: ADB MAXAD ; below loader */ + 0002040, /* 77722: SEZ ; E =0 => OK */ + 0027740, /* 77723: JMP H55 */ + 0017742, /* 77724: JSB READ ; get word */ + 0040001, /* 77725: ADA 1 ; cont checksum */ + 0177755, /* 77726: STA AD,I ; store word */ + 0037755, /* 77727: ISZ AD */ + 0000040, /* 77730: CLE ; force wd read */ + 0037754, /* 77731: ISZ WC ; block done? */ + 0027720, /* 77732: JMP CK ; no */ + 0017742, /* 77733: JSB READ ; get checksum */ + 0054000, /* 77734: CPB 0 ; ok? */ + 0027702, /* 77735: JMP CN ; next block */ + 0102011, /* 77736: HLT 11 ; bad csum */ + 0027700, /* 77737: JMP ST ; next */ + 0102055, /* 77740: H55 HLT 55 ; bad address */ + 0027700, /* 77741: JMP ST ; next */ + 0000000, /* 77742: RD NOP */ + 0006600, /* 77743: CLB,CME ; E reg byte ptr */ + 0103710, /* 77744: STC RDR,C ; start reader */ + 0102310, /* 77745: SFS RDR ; wait */ + 0027745, /* 77746: JMP *-1 */ + 0106410, /* 77747: MIB RDR ; get byte */ + 0002041, /* 77750: SEZ,RSS ; E set? */ + 0127742, /* 77751: JMP RD,I ; no, done */ + 0005767, /* 77752: BLF,CLE,BLF ; shift byte */ + 0027744, /* 77753: JMP RD+2 ; again */ + 0000000, /* 77754: WC 000000 ; word count */ + 0000000, /* 77755: AD 000000 ; address */ + 0177765, /* 77756: M11 DEC -11 ; feed count */ + 0000000, /* 77757: NOP */ + 0000000, /* 77760: NOP */ + 0000000, /* 77761: NOP */ + 0000000, /* 77762: NOP */ + 0000000, /* 77763: NOP */ + 0000000, /* 77764: NOP */ + 0000000, /* 77765: NOP */ + 0000000, /* 77766: NOP */ + 0000000, /* 77767: NOP */ + 0000000, /* 77770: NOP */ + 0000000, /* 77771: NOP */ + 0000000, /* 77772: NOP */ + 0000000, /* 77773: NOP */ + 0000000, /* 77774: NOP */ + 0000000, /* 77775: NOP */ + 0000000, /* 77776: NOP */ + 0100100 } } /* 77777: MAXAD ABS -ST ; max addr */ + }; + + +/* Device boot routine. + + This routine is called directly by the BOOT IPLI and LOAD IPLI commands to + copy the device bootstrap into the upper 64 words of the logical address + space. It is also called indirectly by a BOOT CPU or LOAD CPU command when + the specified HP 1000 loader ROM socket contains a 12992K ROM. + + When called in response to a BOOT IPLI or LOAD IPLI command, the "unitno" + parameter indicates the unit number specified in the BOOT command or is zero + for the LOAD command, and "dptr" points at the IPLI device structure. + Depending on the current CPU model, the special BBL or 12992K loader ROM will + be copied into memory and configured for the IPLI select code. If the CPU is + a 1000, the S register will be set as it would be by the front-panel + microcode. + + When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the + select code to be used for configuration, and "dptr" will be NULL. As above, + the special BBL or 12992K loader ROM will be copied into memory and + configured for the specified select code. The S register is assumed to be + set correctly on entry and is not modified. + + For the 12992K boot loader ROM, the S register will be set as follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | 0 0 | IPLI select code | 0 0 0 0 0 0 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +*/ + +static t_stat ipl_boot (int32 unitno, DEVICE *dptr) +{ +static const HP_WORD ipl_ptx = 074u; /* the index of the pointer to the IPL select code */ +static const HP_WORD ptr_ptx = 075u; /* the index of the pointer to the PTR select code */ +static const HP_WORD ipl_scx = 076u; /* the index of the IPL select code */ +static const HP_WORD ptr_scx = 077u; /* the index of the PTR select code */ +t_stat status; +uint32 ptr_sc, ipl_sc; +DEVICE *ptr_dptr; + +ptr_dptr = find_dev ("PTR"); /* get a pointer to the paper tape reader device */ + +if (ptr_dptr == NULL) /* if the paper tape device is not present */ + return SCPE_IERR; /* then something is seriously wrong */ +else /* otherwise */ + ptr_sc = ((DIB *) ptr_dptr->ctxt)->select_code; /* get the select code from the device's DIB */ + +if (dptr == NULL) /* if we are being called for a BOOT/LOAD CPU command */ + ipl_sc = (uint32) unitno; /* then get the select code from the "unitno" parameter */ +else /* otherwise */ + ipl_sc = ipli_dib.select_code; /* use the device select code from the DIB */ + +status = cpu_copy_loader (ipl_loaders, ipl_sc, /* copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* but do not alter the S register */ + +if (status == SCPE_OK && mem_examine (PR + ptr_scx) <= MAXDEV) { /* if the copy succeeded and is the special BBL */ + mem_deposit (PR + ipl_ptx, (HP_WORD) PR + ipl_scx); /* then configure */ + mem_deposit (PR + ptr_ptx, (HP_WORD) PR + ptr_scx); /* the pointers */ + mem_deposit (PR + ipl_scx, (HP_WORD) ipli_dib.select_code); /* and select codes */ + mem_deposit (PR + ptr_scx, (HP_WORD) ptr_sc); /* for the loader */ + } + +return status; /* return the result of the boot configuration */ +} + + + +/* Process synchronization functions */ + + + +#if defined (_WIN32) + +/* Windows process synchronization */ + + +/* Create a synchronization event. + + This routine creates a synchronization event using the supplied name and + returns the event handle to the caller. If creation succeeds, the routine + returns 0. Otherwise, the error value is returned. + + The event is created with these attributes: no security, automatic reset, and + initially non-signaled. +*/ + +static uint32 create_event (const char *name, EVENT *event) +{ +*event = CreateEvent (NULL, FALSE, FALSE, name); /* create an auto-reset, initially not-signaled event */ + +tprintf (ipli_dev, TRACE_CMD, "Created event %p with identifier \"%s\"\n", + (void *) *event, name); + +if (*event == NULL) /* if event creation failed */ + return (uint32) GetLastError (); /* then return the error code */ +else /* otherwise the creation succeeded */ + return 0; /* so return success */ +} + + +/* Destroy a synchronization event. + + This routine destroys the synchronization event specified by the supplied + event handle. If destruction succeeds, the event handle is invalidated, and + the routine returns 0. Otherwise, the error value is returned. + + The event name parameter is not used but is present for interoperability. +*/ + +static uint32 destroy_event (const char *name, EVENT *event) +{ +BOOL status; + +if (*event == NULL) /* if the event does not exist */ + return 0; /* then indicate that it has already been destroyed */ + +else { /* otherwise the event exists */ + status = CloseHandle (*event); /* so close it */ + *event = NULL; /* and clear the event handle */ + + if (status == FALSE) /* if the close failed */ + return (uint32) GetLastError (); /* then return the error code */ + else /* otherwise the close succeeded */ + return 0; /* so return success */ + } +} + + +/* Test if the synchronization event exists. + + This routine returns TRUE if the supplied event handle does not exist and + FALSE if the handle refers to a defined event. +*/ + +static t_bool event_is_undefined (EVENT event) +{ +return (event == NULL); /* return TRUE if the event does not exist */ +} + + +/* Wait for a synchronization event. + + This routine waits for a synchronization event to be signaled or for the + supplied maximum wait time to elapse. If the event identified by the + supplied handle is signaled, the routine returns 0 and sets the "signaled" + flag to TRUE. If the timeout expires without the event being signaled, the + routine returns 0 with the "signaled" flag set to FALSE. If the event wait + fails, the routine returns the error value. + + + Implementation notes: + + 1. The maximum wait time may be zero to test the signaled state and return + immediately, or may be set to "INFINITE" to wait forever. The latter is + not recommended, as it provides the user with no means to cancel the wait + and return to the SCP prompt. +*/ + +static uint32 wait_event (EVENT event, uint32 wait_in_ms, t_bool *signaled) +{ +const DWORD wait_time = (DWORD) wait_in_ms; /* interval wait time in milliseconds */ +DWORD status; + +status = WaitForSingleObject (event, wait_time); /* wait for the event, but not forever */ + +tprintf (ipli_dev, TRACE_CMD, "Wait status is %lu\n", status); + +if (status == WAIT_FAILED) /* if the wait failed */ + return (uint32) GetLastError (); /* then return the error code */ + +else { /* otherwise the wait completed */ + *signaled = (status != WAIT_TIMEOUT); /* so set the flag TRUE if the wait did not time out */ + return 0; /* and return success */ + } +} + + +/* Signal the synchronization event. + + This routine signals a the synchronization event specified by the supplied + event handle. If signaling succeeds, the routine returns 0. Otherwise, the + error value is returned. +*/ + +static uint32 signal_event (EVENT event) +{ +BOOL status; + +status = SetEvent (event); /* signal the event */ + +if (status == FALSE) /* if the call failed */ + return (uint32) GetLastError (); /* then return the error code */ +else /* otherwise the signal succeeded */ + return 0; /* so return success */ +} + + + +#elif defined (HAVE_SEMAPHORE) + +/* UNIX process synchronization */ + + +/* Create the synchronization event. + + This routine creates a synchronization event using the supplied name and + returns an event object to the caller. If creation succeeds, the routine + returns 0. Otherwise, the error value is returned. + + Systems that define the semaphore functions but implement them as stubs will + return ENOSYS. We handle this case by enabling fallback to the unimplemented + behavior, i.e., emulating a process wait by a two-second sleep. All other + error returns are reported back to the caller. + + Regarding the choice of event name, the Single Unix Standard says: + + If [the] name begins with the character, then processes calling + sem_open() with the same value of name shall refer to the same semaphore + object, as long as that name has not been removed. If name does not begin + with the character, the effect is implementation-defined. + + Therefore, event names passed to this routine should begin with a slash + character. + + The event is created as initially not-signaled. +*/ + +static uint32 create_event (const char *name, EVENT *event) +{ +*event = sem_open (name, O_CREAT, S_IRWXU, 0); /* create an initially not-signaled event */ + +if (*event == SEM_FAILED) /* if event creation failed */ + if (errno == ENOSYS) { /* then if the function is not implemented */ + tprintf (ipli_dev, TRACE_CMD, "sem_open is unsupported on this system; using fallback\n"); + + event_fallback = TRUE; /* then fall back to event emulation */ + return 0; /* and claim that the open succeeded */ + } + + else { /* otherwise it is an unexpected error */ + tprintf (ipli_dev, TRACE_CMD, "sem_open error is %u\n", errno); + return (uint32) errno; /* so return the error code */ + } + +else { /* otherwise the creation succeeded */ + tprintf (ipli_dev, TRACE_CMD, "Created event %p with identifier \"%s\"\n", + (void *) *event, name); + return 0; /* so return success */ + } +} + + +/* Destroy the synchronization event. + + This routine destroys the synchronization event specified by the supplied + event name. If destruction succeeds, the event object is invalidated, and + the routine returns 0. Otherwise, the error value is returned. + + + Implementation notes: + + 1. If the other simulator instance destroys the event first, our + "sem_unlink" call will fail with ENOENT. This is an expected error, and + the routine returns success in this case. +*/ + +static uint32 destroy_event (const char *name, EVENT *event) +{ +int status; + +if (*event == SEM_FAILED) /* if the event does not exist */ + return 0; /* then indicate that it has already been deleted */ + +else { /* otherwise the event exists */ + status = sem_unlink (name); /* so delete it */ + *event = SEM_FAILED; /* and clear the event handle */ + + if (status != 0 && errno != ENOENT) { /* if the deletion failed */ + tprintf (ipli_dev, TRACE_CMD, "sem_unlink error is %u\n", errno); + return (uint32) errno; /* then return the error code */ + } + + else /* otherwise the deletion succeeded */ + return 0; /* so return success */ + } +} + + +/* Test if the synchronization event exists. + + This routine returns TRUE if the supplied event object does not exist and + FALSE if the object refers to a defined event. +*/ + +static t_bool event_is_undefined (EVENT event) +{ +if (event_fallback) /* if events are being emulated */ + return FALSE; /* then claim that the event is defined */ +else /* otherwise */ + return (event == SEM_FAILED); /* return TRUE if the event does not exist */ +} + + +/* Wait for the synchronization event. + + This routine waits for a synchronization event to be signaled or for the + supplied maximum wait time to elapse. If the event identified by the + supplied event object is signaled, the routine returns 0 and sets the + "signaled" flag to TRUE. If the timeout expires without the event being + signaled, the routine returns 0 with the "signaled" flag set to FALSE. If + the event wait fails, the routine returns the error value. + + + Implementation notes: + + 1. The maximum wait time may be zero to test the signaled state and return + immediately, or may be set to a large value to wait forever. The latter + is not recommended, as it provides the user with no means to cancel the + wait and return to the SCP prompt. +*/ + +static uint32 wait_event (EVENT event, uint32 wait_in_ms, t_bool *signaled) +{ +const int wait_time = (int) wait_in_ms / 1000; /* interval wait time in seconds */ +struct timespec until_time; +int status; + +if (event_fallback) { /* if events are being emulated */ + sim_os_sleep (2); /* then wait for two seconds */ + + *signaled = TRUE; /* indicate a signaled completion */ + return 0; /* and return success */ + } + +else if (clock_gettime (CLOCK_REALTIME, &until_time)) { /* get the current time; if it failed */ + tprintf (ipli_dev, TRACE_CMD, "clock_gettime error is %u\n", errno); + return (uint32) errno; /* then return the error number */ + } + +else /* otherwise */ + until_time.tv_sec = until_time.tv_sec + wait_time; /* set the (absolute) timeout expiration */ + +status = sem_timedwait (event, &until_time); /* wait for the event, but not forever */ + +*signaled = (status == 0); /* set the flag TRUE if the wait did not time out */ + +if (status) /* if the wait terminated */ + if (errno == ETIMEDOUT || errno == EINTR) /* then if it timed out or was manually aborted */ + return 0; /* then return success */ + + else { /* otherwise it's an unexpected error */ + tprintf (ipli_dev, TRACE_CMD, "sem_timedwait error is %u\n", errno); + return (uint32) errno; /* so return the error code */ + } + +else /* otherwise the event is signaled */ + return 0; /* so return success */ +} + + +/* Signal the synchronization event. + + This routine signals a the synchronization event specified by the supplied + event handle. If signaling succeeds, the routine returns 0. Otherwise, the + error value is returned. +*/ + +static uint32 signal_event (EVENT event) +{ +int status; + +if (event_fallback) /* if events are being emulated */ + return 0; /* then claim that the event was signaled */ +else /* otherwise */ + status = sem_post (event); /* signal the event */ + +if (status) { /* if the call failed */ + tprintf (ipli_dev, TRACE_CMD, "sem_post error is %u\n", errno); + return (uint32) errno; /* then return the error code */ + } + +else /* otherwise the event was signaled */ + return 0; /* so return success */ +} + + #else -uint32 i, t, ipa, ipp, oldf; +/* Process synchronization stubs. + + The stubs return success, rather than failure, because we want the callers to + continue as though synchronization is occurring, even though the host system + does not support the operations necessary to implement this. Without host + system synchronization support, the simulated system's OS might work, but if + the routines returned failure, then the simulator command files running on + such systems would refuse to run. + + + Implementation notes: + + 1. We provide an event wait by sleeping for a few seconds to give the other + simulator instance a chance to catch up. This has a reasonable chance of + working, provided the other instance isn't preempted during the sleep. +*/ + +static uint32 create_event (const char *name, EVENT *event) +{ +tprintf (ipli_dev, TRACE_CMD, "Synchronization is unsupported on this system; using fallback\n"); +return 0; +} + + +static uint32 destroy_event (const char *name, EVENT *event) +{ +return 0; +} + + +static t_bool event_is_undefined (EVENT event) +{ +return FALSE; +} + + +static uint32 wait_event (EVENT event, uint32 wait_in_ms, t_bool *signaled) +{ +sim_os_sleep (2); /* wait for two seconds */ + +*signaled = TRUE; /* then indicate a signaled completion */ +return 0; /* and return success */ +} + + +static uint32 signal_event (EVENT event) +{ +return 0; +} -r = get_ipaddr (cptr, &ipa, &ipp); -if ((r != SCPE_OK) || (ipp == 0)) - return SCPE_ARG; -oldf = uptr->flags; -if (oldf & UNIT_ATT) - ipl_detach (uptr); -if ((sim_switches & SWMASK ('C')) || - ((sim_switches & SIM_SW_REST) && (oldf & UNIT_ACTV))) { - if (ipa == 0) - ipa = 0x7F000001; - newsock = sim_connect_sock (ipa, ipp); - if (newsock == INVALID_SOCKET) - return SCPE_IOERR; - cprintf ("Connecting to IP address %d.%d.%d.%d, port %d\n", - (ipa >> 24) & 0xff, (ipa >> 16) & 0xff, - (ipa >> 8) & 0xff, ipa & 0xff, ipp); - uptr->flags = uptr->flags | UNIT_ACTV; - uptr->LSOCKET = 0; - uptr->DSOCKET = newsock; - } -else { - if (ipa != 0) - return SCPE_ARG; - newsock = sim_master_sock (ipp); - if (newsock == INVALID_SOCKET) - return SCPE_IOERR; - cprintf ("Listening on port %d\n", ipp); - uptr->flags = uptr->flags & ~UNIT_ACTV; - uptr->LSOCKET = newsock; - uptr->DSOCKET = 0; - } -uptr->IBUF = uptr->OBUF = 0; -uptr->flags = (uptr->flags | UNIT_ATT) & ~(UNIT_ESTB | UNIT_HOLD); -tptr = (char *) malloc (strlen (cptr) + 1); /* get string buf */ -if (tptr == NULL) { /* no memory? */ - ipl_detach (uptr); /* close sockets */ - return SCPE_MEM; - } -strcpy (tptr, cptr); /* copy ipaddr:port */ #endif - -uptr->filename = tptr; /* save */ -sim_activate (uptr, POLL_FIRST); /* activate first poll "immediately" */ -if (sim_switches & SWMASK ('W')) { /* wait? */ - for (i = 0; i < 30; i++) { /* check for 30 sec */ - t = ipl_check_conn (uptr); - if (t) /* established? */ - break; - if ((i % 10) == 0) /* status every 10 sec */ - cprintf ("Waiting for connection\n"); - sim_os_sleep (1); /* sleep 1 sec */ - } - if (t) /* if connected (set by "ipl_check_conn" above) */ - cprintf ("Connection established\n"); /* then report */ - } -return SCPE_OK; -} - -/* Detach routine */ - -t_stat ipl_detach (UNIT *uptr) -{ -if (!(uptr->flags & UNIT_ATT)) /* attached? */ - return SCPE_OK; - -if (uptr->flags & UNIT_ACTV) - sim_close_sock (uptr->DSOCKET, 1); - -else { - if (uptr->flags & UNIT_ESTB) /* if established, */ - sim_close_sock (uptr->DSOCKET, 0); /* close data socket */ - sim_close_sock (uptr->LSOCKET, 1); /* closen listen socket */ - } - -free (uptr->filename); /* free string */ -uptr->filename = NULL; -uptr->LSOCKET = 0; -uptr->DSOCKET = 0; -uptr->flags = uptr->flags & ~(UNIT_ATT | UNIT_ACTV | UNIT_ESTB); -sim_cancel (uptr); /* don't poll */ -return SCPE_OK; -} - -/* Disconnect routine */ - -t_stat ipl_dscln (UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ -if (cptr) - return SCPE_ARG; -if (((uptr->flags & UNIT_ATT) == 0) || - (uptr->flags & UNIT_ACTV) || - ((uptr->flags & UNIT_ESTB) == 0)) - return SCPE_NOFNC; -sim_close_sock (uptr->DSOCKET, 0); -uptr->DSOCKET = 0; -uptr->flags = uptr->flags & ~UNIT_ESTB; -return SCPE_OK; -} - -/* Diagnostic/normal mode routine */ - -t_stat ipl_setdiag (UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ -if (val) { - ipli_unit.flags = ipli_unit.flags | UNIT_DIAG; - iplo_unit.flags = iplo_unit.flags | UNIT_DIAG; - } -else { - ipli_unit.flags = ipli_unit.flags & ~UNIT_DIAG; - iplo_unit.flags = iplo_unit.flags & ~UNIT_DIAG; - } -return SCPE_OK; -} - -/* Interprocessor link bootstrap routine (HP Access Manual) */ - -#define MAX_BASE 073 -#define IPL_PNTR 074 -#define PTR_PNTR 075 -#define IPL_DEVA 076 -#define PTR_DEVA 077 - -static const BOOT_ROM ipl_rom = { - 0163774, /*BBL LDA ICK,I ; IPL sel code */ - 0027751, /* JMP CFG ; go configure */ - 0107700, /*ST CLC 0,C ; intr off */ - 0002702, /* CLA,CCE,SZA ; skip in */ - 0063772, /*CN LDA M26 ; feed frame */ - 0002307, /*EOC CCE,INA,SZA,RSS ; end of file? */ - 0027760, /* JMP EOT ; yes */ - 0017736, /* JSB READ ; get #char */ - 0007307, /* CMB,CCE,INB,SZB,RSS ; 2's comp; null? */ - 0027705, /* JMP EOC ; read next */ - 0077770, /* STB WC ; word in rec */ - 0017736, /* JSB READ ; get feed frame */ - 0017736, /* JSB READ ; get address */ - 0074000, /* STB 0 ; init csum */ - 0077771, /* STB AD ; save addr */ - 0067771, /*CK LDB AD ; check addr */ - 0047773, /* ADB MAXAD ; below loader */ - 0002040, /* SEZ ; E =0 => OK */ - 0102055, /* HLT 55 */ - 0017736, /* JSB READ ; get word */ - 0040001, /* ADA 1 ; cont checksum */ - 0177771, /* STB AD,I ; store word */ - 0037771, /* ISZ AD */ - 0000040, /* CLE ; force wd read */ - 0037770, /* ISZ WC ; block done? */ - 0027717, /* JMP CK ; no */ - 0017736, /* JSB READ ; get checksum */ - 0054000, /* CPB 0 ; ok? */ - 0027704, /* JMP CN ; next block */ - 0102011, /* HLT 11 ; bad csum */ - 0000000, /*RD 0 */ - 0006600, /* CLB,CME ; E reg byte ptr */ - 0103700, /*IO1 STC RDR,C ; start reader */ - 0102300, /*IO2 SFS RDR ; wait */ - 0027741, /* JMP *-1 */ - 0106400, /*IO3 MIB RDR ; get byte */ - 0002041, /* SEZ,RSS ; E set? */ - 0127736, /* JMP RD,I ; no, done */ - 0005767, /* BLF,CLE,BLF ; shift byte */ - 0027740, /* JMP IO1 ; again */ - 0163775, /* LDA PTR,I ; get ptr code */ - 0043765, /*CFG ADA SFS ; config IO */ - 0073741, /* STA IO2 */ - 0043766, /* ADA STC */ - 0073740, /* STA IO1 */ - 0043767, /* ADA MIB */ - 0073743, /* STA IO3 */ - 0027702, /* JMP ST */ - 0063777, /*EOT LDA PSC ; put select codes */ - 0067776, /* LDB ISC ; where xloader wants */ - 0102077, /* HLT 77 */ - 0027702, /* JMP ST */ - 0000000, /* NOP */ - 0102300, /*SFS SFS 0 */ - 0001400, /*STC 1400 */ - 0002500, /*MIB 2500 */ - 0000000, /*WC 0 */ - 0000000, /*AD 0 */ - 0177746, /*M26 -26 */ - 0000000, /*MAX -BBL */ - 0007776, /*ICK ISC */ - 0007777, /*PTR IPT */ - 0000000, /*ISC 0 */ - 0000000 /*IPT 0 */ - }; - -t_stat ipl_boot (int32 unitno, DEVICE *dptr) -{ -const HP_WORD devi = (HP_WORD) ipli_dib.select_code; -const HP_WORD devp = (HP_WORD) ptr_dib.select_code; - -cpu_ibl (ipl_rom, devi, IBL_S_CLR, /* copy the boot ROM to memory and configure */ - IBL_SET_SC (devi) | devp); /* the S register accordingly */ - -mem_deposit (PR + MAX_BASE, (~PR + 1) & DMASK); /* fix ups */ -mem_deposit (PR + IPL_PNTR, (HP_WORD) ipl_rom [IPL_PNTR] | PR); -mem_deposit (PR + PTR_PNTR, (HP_WORD) ipl_rom [PTR_PNTR] | PR); -mem_deposit (PR + IPL_DEVA, devi); -mem_deposit (PR + PTR_DEVA, devp); -return SCPE_OK; -} diff --git a/HP2100/hp2100_mpx.c b/HP2100/hp2100_mpx.c index 9243715a..86443de0 100644 --- a/HP2100/hp2100_mpx.c +++ b/HP2100/hp2100_mpx.c @@ -25,6 +25,7 @@ MPX 12792C 8-Channel Asynchronous Multiplexer + 01-Nov-17 JDB Fixed serial output buffer overflow handling 26-Jul-17 JDB Changed BITFIELD macros to field constructors 22-Apr-17 JDB Corrected missing compound statements 15-Mar-17 JDB Trace flags are now global @@ -73,8 +74,8 @@ character editing, echoing, ENQ/ACK handshaking, and read terminator detection, substantially reducing the load on the CPU over the earlier 12920 multiplexer. It was supported by HP under RTE-MIII, RTE-IVB, and RTE-6/VM. - Under simulation, it connects with HP terminal emulators via Telnet to a - user-specified port. + Under simulation, it connects with HP terminal emulators via Telnet or serial + ports. The single interface card contained a Z80 CPU, DMA controller, CTC, four two-channel SIO UARTs, 16K of RAM, 8K of ROM, and I/O backplane latches and @@ -246,7 +247,7 @@ #define MPX_CNTLS 2 /* number of control units */ #define mpx_cntl (mpx_unit [MPX_PORTS + 0]) /* controller unit */ -#define mpx_poll (mpx_unit [MPX_PORTS + 1]) /* Telnet polling unit */ +#define mpx_poll (mpx_unit [MPX_PORTS + 1]) /* polling unit */ /* Character constants */ @@ -826,7 +827,7 @@ static int32 mpx_iolen = 0; /* length of current I/O xfer */ static t_bool mpx_uien = FALSE; /* unsolicited interrupts enabled */ static uint32 mpx_uicode = 0; /* unsolicited interrupt reason and port */ -struct { +static struct { FLIP_FLOP control; /* control flip-flop */ FLIP_FLOP flag; /* flag flip-flop */ FLIP_FLOP flagbuf; /* flag buffer flip-flop */ @@ -955,16 +956,16 @@ static DIB mpx_dib = { /* Unit list. The first eight units correspond to the eight multiplexer line ports. These - handle character I/O via the Telnet library. A ninth unit acts as the card - controller, executing commands and transferring data to and from the I/O - buffers. A tenth unit is responsible for polling for connections and socket - I/O. It also holds the master socket. + handle character I/O via the multiplexer library. A ninth unit acts as the + card controller, executing commands and transferring data to and from the I/O + buffers. A tenth unit is responsible for polling for connections and line + I/O. It also holds the master socket for Telnet connections. The character I/O service routines run only when there are characters to read or write. They operate at the approximate baud rates of the terminals (in CPU instructions per second) in order to be compatible with the OS drivers. The controller service routine runs only when a command is executing or a - data transfer to or from the CPU is in progress. The Telnet poll must run + data transfer to or from the CPU is in progress. The poll service must run continuously, but it may operate much more slowly, as the only requirement is that it must not present a perceptible lag to human input. To be compatible with CPU idling, it is co-scheduled with the master poll timer, which uses a @@ -986,7 +987,7 @@ static UNIT mpx_unit [] = { { UDATA (&line_service, UNIT_FASTTIME, 0) }, /* terminal I/O line 6 */ { UDATA (&line_service, UNIT_FASTTIME, 0) }, /* terminal I/O line 7 */ { UDATA (&cntl_service, UNIT_DIS, 0) }, /* controller unit */ - { UDATA (&poll_service, POLL_FLAGS, 0), POLL_FIRST } /* Telnet poll unit */ + { UDATA (&poll_service, POLL_FLAGS, 0), POLL_FIRST } /* poll unit */ }; @@ -1626,21 +1627,20 @@ return SCPE_OK; /* Multiplexer line service. The line service routine is used to transmit and receive characters. It is - started when a buffer is ready for output or when the Telnet poll routine + started when a buffer is ready for output or when the poll service routine determines that there are characters ready for input, and it is stopped when there are no more characters to output or input. When a line is quiescent, this routine does not run. Service times are selected to approximate the baud rate setting of the multiplexer port. "Fast timing" mode enables three optimizations. First, buffered characters - are transferred via Telnet in blocks, rather than a character at a time; this - reduces network traffic and decreases simulator overhead (there is only one - service routine entry per block, rather than one per character). Second, - ENQ/ACK handshaking is done locally, without involving the Telnet client. - Third, when editing and echo is enabled, entering BS echoes a backspace, a - space, and a backspace, and entering DEL echoes a backslash, a carriage - return, and a line feed, providing better compatibility with prior RTE - terminal drivers. + are transferred in blocks, rather than a character at a time; this reduces + line traffic and decreases simulator overhead (there is only one service + routine entry per block, rather than one per character). Second, ENQ/ACK + handshaking is done locally, without involving the client. Third, when + editing and echo is enabled, entering BS echoes a backspace, a space, and a + backspace, and entering DEL echoes a backslash, a carriage return, and a line + feed, providing better compatibility with prior RTE terminal drivers. Each read and write buffer begins with a reserved header byte that stores per-buffer information, such as whether handshaking should be suppressed @@ -1654,7 +1654,7 @@ return SCPE_OK; write buffer is freed, and a UI check is made if the controller is idle, in case a write buffer request is pending. - For input, the character is retrieved from the Telnet buffer. If a BREAK was + For input, the character is retrieved from the line buffer. If a BREAK was received, break status is set, and the character is discarded (the current multiplexer library implementation always returns a NUL with a BREAK indication). If the character is an XOFF, and XON/XOFF pacing is enabled, a @@ -1685,6 +1685,59 @@ return SCPE_OK; service entry. This allows the CPU time to unload the first buffer before the second fills up. Once the first buffer is freed, the routine shifts back to burst mode to fill the remainder of the second buffer. + + 4. The terminal multiplexer library "tmxr_putc_ln" routine returns + SCPE_STALL if it is called when the transmit buffer is full. When the + last character is added to the buffer, the routine returns SCPE_OK but + also changes the "xmte" field of the terminal multiplexer line (TMLN) + structure from 1 to 0 to indicate that further calls will be rejected. + The "xmte" value is set back to 1 when the tranmit buffer empties. + + This presents two approaches to handling buffer overflows: either call + "tmxr_putc_ln" unconditionally and test for SCPE_STALL on return, or call + "tmxr_putc_ln" only if "xmte" is 1. The former approach adds a new + character to the transmit buffer as soon as space is available, while the + latter adds a new character only when the buffer has completely emptied. + With either approach, transmission must be rescheduled after a delay to + allow the buffer to drain. + + It would seem that the former approach is more attractive, as it would + allow the simulated I/O operation to complete more quickly. However, + there are two mitigating factors. First, the library attempts to write + the entire transmit buffer in one host system call, so there is usually + no time difference between freeing one buffer character and freeing the + entire buffer (barring host system buffer congestion). Second, the + routine increments a "character dropped" counter when returning + SCPE_STALL status. However, the characters actually would not be lost, + as the SCPE_STALL return would schedule retransmission when buffer space + is available, . This would lead to erroneous reporting in the SHOW + STATISTICS command. + + Therefore, we adopt the latter approach and reschedule transmission if + the "xmte" field is 0. Note that the "tmxr_poll_tx" routine still must + be called in this case, as it is responsible for transmitting the buffer + contents and therefore freeing space in the buffer. + + 5. The "tmxr_putc_ln" library routine returns SCPE_LOST if the line is not + connected. We ignore this error so that an OS may output an + initialization "welcome" message even when the terminal is not connected. + This permits the simulation to continue while ignoring the output. + + 6. The serial transmit buffer provided by the terminal multiplexer library + is restricted to one character. Therefore, attempting to send several + characters in response to input, e.g., echoing " " in + response to receiving a , will fail with SCPE_STALL. Calling + "tmxr_poll_tx" between characters will not clear the buffer if the line + speed has been set explicitly. + + To avoid having to do our own buffering for echoed characters, we call + the "tmxr_linemsg" routine which loops internally until the characters + have been transmitted. This is ugly but is a consequence of the buffer + restriction imposed by the TMXR library. + + 7. Because ENQ/ACK handshaking is handled entirely on the multiplexer card + with no OS involvement, FASTTIME "local handling" consists simply of + omitting the handshake even if it is configured by the multiplexer. */ static t_stat line_service (UNIT *uptr) @@ -1699,15 +1752,20 @@ uint8 ch; int32 chx; uint32 buffer_count, write_count; t_stat status = SCPE_OK; -t_bool recv_loop = !fast_binary_read; /* bypass if fast binary read */ -t_bool xmit_loop = !(fast_binary_read || /* bypass if fast read or output suspended */ - (mpx_flags [port] & (FL_WAITACK | FL_XOFF))); +t_bool recv_loop = !fast_binary_read; /* bypass if fast binary read */ +t_bool xmit_loop = !(fast_binary_read /* bypass if fast read */ + || mpx_flags [port] & (FL_WAITACK | FL_XOFF) /* or output suspended */ + || mpx_ldsc [port].xmte == 0); /* or buffer full */ tprintf (mpx_dev, DEB_CMDS, "Port %d service entered\n", port); /* Transmission service */ +if (mpx_ldsc [port].xmte == 0) /* if the transmit buffer is full */ + tprintf (mpx_dev, DEB_XFER, "Port %d transmission stalled for full buffer\n", + port); + write_count = buf_len (iowrite, port, get); /* get the output buffer length */ while (xmit_loop && write_count > 0) { /* character available to output? */ @@ -1723,16 +1781,17 @@ while (xmit_loop && write_count > 0) { /* character available t continue; /* continue with the first output character */ } - if (mpx_flags [port] & FL_DO_ENQACK) /* do handshake for this buffer? */ - mpx_enq_cntr [port] = mpx_enq_cntr [port] + 1; /* bump character counter */ - - if (mpx_enq_cntr [port] > ENQ_LIMIT) { /* ready for ENQ? */ - mpx_enq_cntr [port] = 0; /* clear ENQ counter */ - mpx_ack_wait [port] = 0; /* clear ACK wait timer */ - - mpx_flags [port] |= FL_WAITACK; /* set wait for ACK */ + if (mpx_enq_cntr [port] >= ENQ_LIMIT) { /* ready for ENQ? */ ch = ENQ; status = tmxr_putc_ln (&mpx_ldsc [port], ch); /* transmit ENQ */ + + if (status == SCPE_OK || status == SCPE_LOST) { /* if transmission succeeded or is ignored */ + mpx_enq_cntr [port] = 0; /* then clear the ENQ counter */ + mpx_ack_wait [port] = 0; /* and the ACK wait timer */ + + mpx_flags [port] |= FL_WAITACK; /* set wait for ACK */ + } + xmit_loop = FALSE; /* stop further transmission */ } @@ -1740,17 +1799,32 @@ while (xmit_loop && write_count > 0) { /* character available t ch = buf_get (iowrite, port) & data_mask; /* get char and mask to bit width */ status = tmxr_putc_ln (&mpx_ldsc [port], ch); /* transmit the character */ - write_count = write_count - 1; /* count the character */ - xmit_loop = (status == SCPE_OK) && fast_timing; /* and continue transmission if enabled */ + if (status == SCPE_OK || status == SCPE_LOST) { /* if transmission succeeded or is ignored */ + write_count = write_count - 1; /* then count the character */ + + xmit_loop = (fast_timing /* continue transmission if enabled */ + && mpx_ldsc [port].xmte != 0); /* and buffer space is available */ + + if (mpx_flags [port] & FL_DO_ENQACK) /* if ENQ/ACK handshaking is enabled */ + mpx_enq_cntr [port] += 1; /* then bump the character counter */ + } + + else /* otherwise transmission failed */ + xmit_loop = FALSE; /* so exit the loop */ } - if (status != SCPE_OK) /* if the transmission failed */ - xmit_loop = FALSE; /* then exit the loop */ - - else + if (status == SCPE_OK) tprintf (mpx_dev, DEB_XFER, "Port %d character %s transmitted\n", port, fmt_char (ch)); + else { + tprintf (mpx_dev, DEB_XFER, "Port %d character %s transmission failed with status %d\n", + port, fmt_char (ch), status); + + if (status == SCPE_LOST) /* if the line is not connected */ + status = SCPE_OK; /* then ignore the output */ + } + if (write_count == 0) { /* buffer complete? */ buf_free (iowrite, port); /* free buffer */ @@ -1831,10 +1905,8 @@ while (recv_loop) { /* OK to process? */ if (rt & RT_ENAB_ECHO) { /* echo enabled? */ tmxr_putc_ln (&mpx_ldsc [port], BS); /* echo BS */ - if (fast_timing) { /* fast timing mode? */ - tmxr_putc_ln (&mpx_ldsc [port], ' '); /* echo space */ - tmxr_putc_ln (&mpx_ldsc [port], BS); /* echo BS */ - } + if (fast_timing) /* fast timing mode? */ + tmxr_linemsg (&mpx_ldsc [port], " \b"); /* echo space and BS */ } continue; @@ -1847,8 +1919,7 @@ while (recv_loop) { /* OK to process? */ if (fast_timing) /* fast timing mode? */ tmxr_putc_ln (&mpx_ldsc [port], '\\'); /* echo backslash */ - tmxr_putc_ln (&mpx_ldsc [port], CR); /* echo CR */ - tmxr_putc_ln (&mpx_ldsc [port], LF); /* and LF */ + tmxr_linemsg (&mpx_ldsc [port], "\r\n"); /* echo CR and LF */ } continue; @@ -1865,7 +1936,8 @@ while (recv_loop) { /* OK to process? */ if ((ch == CR) && (rt & RT_END_ON_CR)) { if (rt & RT_ENAB_ECHO) /* echo enabled? */ - tmxr_putc_ln (&mpx_ldsc [port], LF); /* send LF */ + tmxr_linemsg (&mpx_ldsc [port], "\n"); /* send LF */ + mpx_param = RS_ETC_CR; /* set termination condition */ } @@ -1981,15 +2053,15 @@ else { /* normal service */ tprintf (mpx_dev, DEB_CMDS, "Port %d service stopped\n", port); } -return SCPE_OK; +return status; } -/* Telnet poll service. +/* Poll service. - This service routine is used to poll for Telnet connections and incoming - characters. It starts when the socket is attached and stops when the socket - is detached. + This service routine is used to poll for connections and incoming characters. + It is started when the listening socket or a serial line is attached and is + stopped when the socket and all lines are detached. Each line is then checked for a pending ENQ/ACK handshake. If one is pending, the ACK counter is incremented, and if it times out, another ENQ is @@ -2054,10 +2126,10 @@ return SCPE_OK; 1. Under simulation, we also clear the input buffer register, even though the hardware doesn't. - 2. We set up the first poll for Telnet connections to occur "immediately" - upon execution, so that clients will be connected before execution - begins. Otherwise, a fast program may access the multiplexer before the - poll service routine activates. + 2. We set up the first poll for connections to occur "immediately" upon + execution, so that clients will be connected before execution begins. + Otherwise, a fast program may access the multiplexer before the poll + service routine activates. 3. We must set the "emptying_flags" and "filling_flags" values here, because they cannot be initialized statically, even though the values are @@ -2079,10 +2151,10 @@ mpx_ibuf = 0; /* clear input buffer */ if (mpx_poll.flags & UNIT_ATT) { /* network attached? */ mpx_poll.wait = POLL_FIRST; /* set up poll */ - sim_activate (&mpx_poll, mpx_poll.wait); /* start Telnet poll immediately */ + sim_activate (&mpx_poll, mpx_poll.wait); /* start poll immediately */ } else - sim_cancel (&mpx_poll); /* else stop Telnet poll */ + sim_cancel (&mpx_poll); /* else stop poll */ return SCPE_OK; } @@ -2092,23 +2164,32 @@ return SCPE_OK; We are called by the ATTACH MPX command to attach the multiplexer to the listening port indicated by . Logically, it is the multiplexer - device that is attached; however, SIMH only allows units to be attached. - This makes sense for devices such as tape drives, where the attached media is - a property of a specific drive. In our case, though, the listening port is a - property of the multiplexer card, not of any given serial line. As ATTACH - MPX is equivalent to ATTACH MPX0, the port would, by default, be attached to - the first serial line and be reported there in a SHOW MPX command. + device that is attached; however, SIMH only allows units to be attached. This + makes sense for devices such as tape drives, where the attached media is a + property of a specific drive. In our case, though, the listening port is a + property of the multiplexer card, not of any given line. As ATTACH MPX is + equivalent to ATTACH MPX0, the port would, by default, be attached to the + first line and be reported there in a SHOW MPX command. - To preserve the logical picture, we attach the port to the Telnet poll unit, - which is normally disabled to inhibit its display. Attaching to a disabled - unit is not allowed, so we first enable the unit, then attach it, then - disable it again. Attachment is reported by the "show_status" routine below. + To preserve the logical picture, we attach the listening port to the poll + unit (unit 9), which is normally disabled to inhibit its display. Serial + ports are attached to line units 0-7 normally. Attachment is reported by the + "show_status" routine below. - A direct attach to the poll unit is only allowed when restoring a previously - saved session. + The connection poll service routine is synchronized with the other input + polling devices in the simulator to facilitate idling. - The Telnet poll service routine is synchronized with the other input polling - devices in the simulator to facilitate idling. + + Implementation notes: + + 1. If we are being called as part of RESTORE processing, we may see a + request to attach the poll unit (unit 9). This will occur if unit 9 was + attached when the SAVE was done. In this case, the SIM_SW_REST flag will + be set in "sim_switches", and we will allow the call to succeed. + + 2. If the poll unit is attached, it will be enabled as part of RESTORE + processing. We always unilaterally disable this unit to ensure that it + remains hidden. */ static t_stat mpx_attach (UNIT *uptr, CONST char *cptr) @@ -2133,15 +2214,21 @@ return status; /* Detach the multiplexer. - Normally, we are called by the DETACH MPX command, which is equivalent to - DETACH MPX0. However, we may be called with other units in two cases. + We are called by the DETACH MPX command to detach the listening port and all + Telnet sessions. We will also be called by DETACH ALL, RESTORE, and during + simulator shutdown. For DETACH ALL and RESTORE, we must not fail the call, + or processing of other units will cease. - A DETACH ALL command will call us for unit 9 (the poll unit) if it is - attached. Also, during simulator shutdown, we will be called for units 0-8 - (detach_all in scp.c calls the detach routines of all units that do NOT have - UNIT_ATTABLE), as well as for unit 9 if it is attached. In both cases, it is - imperative that we return SCPE_OK, otherwise any remaining device detaches - will not be performed. + + Implementation notes: + + 1. During simulator shutdown, we will be called for units 0-8 (detach_all in + scp.c calls the detach routines of all units that do NOT have + UNIT_ATTABLE), as well as for unit 9 if it is attached. + + 2. We cannot fail a direct DETACH MPX9 (poll unit), because we cannot tell + that case apart from a DETACH ALL (a RESTORE will have the SIM_SW_REST + flag set in "sim_switches"). */ static t_stat mpx_detach (UNIT *uptr) @@ -2157,7 +2244,7 @@ if ((uptr == mpx_unit) || (uptr == &mpx_poll)) { /* base unit or poll uni sim_cancel (&mpx_unit [i]); /* cancel any scheduled I/O */ } - sim_cancel (&mpx_poll); /* stop Telnet poll */ + sim_cancel (&mpx_poll); /* stop poll */ } return status; @@ -2413,9 +2500,8 @@ switch (mpx_cmd) { mpx_enq_cntr [0] = 0; /* clear port 0 ENQ counter */ mpx_ack_wait [0] = 0; /* clear port 0 ACK wait timer */ - tmxr_putc_ln (&mpx_ldsc [0], ESC); /* send fast binary read */ - tmxr_putc_ln (&mpx_ldsc [0], 'e'); /* escape sequence to port 0 */ - tmxr_poll_tx (&mpx_desc); /* flush output */ + tmxr_linemsg (&mpx_ldsc [0], "\033e"); /* send the fast binary read escape sequence to port 0 */ + tmxr_poll_tx (&mpx_desc); /* and flush the output */ next_state = exec; /* set execution state */ break; @@ -2557,7 +2643,7 @@ return set_flag; } -/* Poll for new Telnet connections */ +/* Poll for new connections */ static void poll_connection (void) { diff --git a/HP2100/hp2100_ms.c b/HP2100/hp2100_ms.c index 59d6acd3..64305519 100644 --- a/HP2100/hp2100_ms.c +++ b/HP2100/hp2100_ms.c @@ -1,7 +1,7 @@ /* hp2100_ms.c: HP 2100 13181B/13183B Digital Magnetic Tape Unit Interface simulator Copyright (c) 1993-2016, Robert M. Supnik - Copyright (c) 2017, J. David Bryan + Copyright (c) 2017-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,6 +27,8 @@ MS 13181B Digital Magnetic Tape Unit Interface 13183B Digital Magnetic Tape Unit Interface + 28-Feb-18 JDB Added the BMTL + 23-Feb-18 JDB Eliminated "msc_boot" references to A and S registers 20-Jul-17 JDB Removed "msc_stopioe" variable and register 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" 15-Mar-17 JDB Trace flags are now global @@ -1239,91 +1241,234 @@ switch (cmd & 0377) { } } -/* 7970B/7970E bootstrap routine (HP 12992D ROM) */ -const BOOT_ROM ms_rom = { - 0106501, /*ST LIB 1 ; read sw */ - 0006011, /* SLB,RSS ; bit 0 set? */ - 0027714, /* JMP RD ; no read */ - 0003004, /* CMA,INA ; A is ctr */ - 0073775, /* STA WC ; save */ - 0067772, /* LDA SL0RW ; sel 0, rew */ - 0017762, /*FF JSB CMD ; do cmd */ - 0102311, /* SFS CC ; done? */ - 0027707, /* JMP *-1 ; wait */ - 0067774, /* LDB FFC ; get file fwd */ - 0037775, /* ISZ WC ; done files? */ - 0027706, /* JMP FF ; no */ - 0067773, /*RD LDB RDCMD ; read cmd */ - 0017762, /* JSB CMD ; do cmd */ - 0103710, /* STC DC,C ; start dch */ - 0102211, /* SFC CC ; read done? */ - 0027752, /* JMP STAT ; no, get stat */ - 0102310, /* SFS DC ; any data? */ - 0027717, /* JMP *-3 ; wait */ - 0107510, /* LIB DC,C ; get rec cnt */ - 0005727, /* BLF,BLF ; move to lower */ - 0007000, /* CMB ; make neg */ - 0077775, /* STA WC ; save */ - 0102211, /* SFC CC ; read done? */ - 0027752, /* JMP STAT ; no, get stat */ - 0102310, /* SFS DC ; any data? */ - 0027727, /* JMP *-3 ; wait */ - 0107510, /* LIB DC,C ; get load addr */ - 0074000, /* STB 0 ; start csum */ - 0077762, /* STA CMD ; save address */ - 0027742, /* JMP *+4 */ - 0177762, /*NW STB CMD,I ; store data */ - 0040001, /* ADA 1 ; add to csum */ - 0037762, /* ISZ CMD ; adv addr ptr */ - 0102310, /* SFS DC ; any data? */ - 0027742, /* JMP *-1 ; wait */ - 0107510, /* LIB DC,C ; get word */ - 0037775, /* ISZ WC ; done? */ - 0027737, /* JMP NW ; no */ - 0054000, /* CPB 0 ; csum ok? */ - 0027717, /* JMP RD+3 ; yes, cont */ - 0102011, /* HLT 11 ; no, halt */ - 0102511, /*ST LIA CC ; get status */ - 0001727, /* ALF,ALF ; get eof bit */ - 0002020, /* SSA ; set? */ - 0102077, /* HLT 77 ; done */ - 0001727, /* ALF,ALF ; put status back */ - 0001310, /* RAR,SLA ; read ok? */ - 0102000, /* HLT 0 ; no */ - 0027714, /* JMP RD ; read next */ - 0000000, /*CMD 0 */ - 0106611, /* OTB CC ; output cmd */ - 0102511, /* LIA CC ; check for reject */ - 0001323, /* RAR,RAR */ - 0001310, /* RAR,SLA */ - 0027763, /* JMP CMD+1 ; try again */ - 0103711, /* STC CC,C ; start command */ - 0127762, /* JMP CMD,I ; exit */ - 0001501, /*SL0RW 001501 ; select 0, rewind */ - 0001423, /*RDCMD 001423 ; read record */ - 0000203, /*FFC 000203 ; space forward file */ - 0000000, /*WC 000000 */ - 0000000, - 0000000 +/* 7970B/7970E bootstrap loaders (BMTL and 12992D). + + The Basic Magnetic Tape Loader (BMTL) reads an absolute binary program from + tape into memory. Before execution, the S register must be set as follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - - - - - - - - - - | file number | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + If S-register bits 5-0 are zero, the file located at the current tape + position is read. If the bits are non-zero, the tape is rewound, and the + file number (1 - n) specified by the bits is read. + + The 12992D boot loader ROM reads an absolute program from tape into memory. + If S-register bit 0 is 0, the file located at the current tape position is + read. If bit 0 is 1, the tape is rewound, and the file number (1 - n) + specified by the A-register value is read. + + For either loader, the tape format must be absolute binary, and a tape mark + must end the file. Loader execution ends with one of the following + instructions: + + * HLT 00 - a tape read (parity) error occurred. + * HLT 11 - a checksum error occurred; A/B = the calculated/tape value. + * HLT 77 - the end of the file was reached with a successful read. +*/ + +static const LOADER_ARRAY ms_loaders = { + { /* HP 21xx Basic Magnetic Tape Loader (BMTL) */ + 000, /* loader starting index */ + IBL_NA, /* DMA index */ + IBL_NA, /* FWA index */ + { 0102501, /* 77700: MTAPE LIA 1 */ + 0013775, /* 77701: AND 77775 */ + 0003007, /* 77702: CMA,INA,SZA,RSS */ + 0027714, /* 77703: JMP 77714 */ + 0073777, /* 77704: STA 77777 */ + 0067771, /* 77705: LDB 77771 */ + 0017761, /* 77706: JSB 77761 */ + 0102311, /* 77707: SFS 11 */ + 0027707, /* 77710: JMP 77707 */ + 0067773, /* 77711: LDB 77773 */ + 0037777, /* 77712: ISZ 77777 */ + 0027706, /* 77713: JMP 77706 */ + 0067772, /* 77714: LDB 77772 */ + 0017761, /* 77715: JSB 77761 */ + 0103710, /* 77716: STC 10,C */ + 0017740, /* 77717: JSB 77740 */ + 0005727, /* 77720: BLF,BLF */ + 0007004, /* 77721: CMB,INB */ + 0077777, /* 77722: STB 77777 */ + 0017740, /* 77723: JSB 77740 */ + 0074000, /* 77724: STB 0 */ + 0077776, /* 77725: STB 77776 */ + 0017740, /* 77726: JSB 77740 */ + 0177776, /* 77727: STB 77776,I */ + 0040001, /* 77730: ADA 1 */ + 0037776, /* 77731: ISZ 77776 */ + 0037777, /* 77732: ISZ 77777 */ + 0027726, /* 77733: JMP 77726 */ + 0017740, /* 77734: JSB 77740 */ + 0054000, /* 77735: CPB 0 */ + 0017740, /* 77736: JSB 77740 */ + 0102011, /* 77737: HLT 11 */ + 0000000, /* 77740: NOP */ + 0102310, /* 77741: SFS 10 */ + 0027745, /* 77742: JMP 77745 */ + 0107510, /* 77743: LIB 10,C */ + 0127740, /* 77744: JMP 77740,I */ + 0102311, /* 77745: SFS 11 */ + 0027741, /* 77746: JMP 77741 */ + 0102511, /* 77747: LIA 11 */ + 0013774, /* 77750: AND 77774 */ + 0067777, /* 77751: LDB 77777 */ + 0001727, /* 77752: ALF,ALF */ + 0002020, /* 77753: SSA */ + 0102077, /* 77754: HLT 77 */ + 0002003, /* 77755: SZA,RSS */ + 0006002, /* 77756: SZB */ + 0102000, /* 77757: HLT 0 */ + 0027714, /* 77760: JMP 77714 */ + 0000000, /* 77761: NOP */ + 0106611, /* 77762: OTB 11 */ + 0102511, /* 77763: LIA 11 */ + 0001323, /* 77764: RAR,RAR */ + 0001310, /* 77765: RAR,SLA */ + 0027762, /* 77766: JMP 77762 */ + 0103711, /* 77767: STC 11,C */ + 0127761, /* 77770: JMP 77761,I */ + 0001501, /* 77771: OCT 1501 */ + 0001423, /* 77772: OCT 1423 */ + 0000203, /* 77773: OCT 203 */ + 0016263, /* 77774: OCT 16263 */ + 0000077, /* 77775: OCT 77 */ + 0000000, /* 77776: NOP */ + 0000000 } }, /* 77777: NOP */ + + { /* HP 1000 Loader ROM (12992D) */ + IBL_START, /* loader starting index */ + IBL_DMA, /* DMA index */ + IBL_FWA, /* FWA index */ + { 0106501, /* 77700: ST LIB 1 ; read sw */ + 0006011, /* 77701: SLB,RSS ; bit 0 set? */ + 0027714, /* 77702: JMP RD ; no read */ + 0003004, /* 77703: CMA,INA ; A is ctr */ + 0073775, /* 77704: STA WC ; save */ + 0067772, /* 77705: LDA SL0RW ; sel 0, rew */ + 0017762, /* 77706: FF JSB CMD ; do cmd */ + 0102311, /* 77707: SFS CC ; done? */ + 0027707, /* 77710: JMP *-1 ; wait */ + 0067774, /* 77711: LDB FFC ; get file fwd */ + 0037775, /* 77712: ISZ WC ; done files? */ + 0027706, /* 77713: JMP FF ; no */ + 0067773, /* 77714: RD LDB RDCMD ; read cmd */ + 0017762, /* 77715: JSB CMD ; do cmd */ + 0103710, /* 77716: STC DC,C ; start dch */ + 0102211, /* 77717: SFC CC ; read done? */ + 0027752, /* 77720: JMP STAT ; no, get stat */ + 0102310, /* 77721: SFS DC ; any data? */ + 0027717, /* 77722: JMP *-3 ; wait */ + 0107510, /* 77723: LIB DC,C ; get rec cnt */ + 0005727, /* 77724: BLF,BLF ; move to lower */ + 0007000, /* 77725: CMB ; make neg */ + 0077775, /* 77726: STA WC ; save */ + 0102211, /* 77727: SFC CC ; read done? */ + 0027752, /* 77730: JMP STAT ; no, get stat */ + 0102310, /* 77731: SFS DC ; any data? */ + 0027727, /* 77732: JMP *-3 ; wait */ + 0107510, /* 77733: LIB DC,C ; get load addr */ + 0074000, /* 77734: STB 0 ; start csum */ + 0077762, /* 77735: STA CMD ; save address */ + 0027742, /* 77736: JMP *+4 */ + 0177762, /* 77737: NW STB CMD,I ; store data */ + 0040001, /* 77740: ADA 1 ; add to csum */ + 0037762, /* 77741: ISZ CMD ; adv addr ptr */ + 0102310, /* 77742: SFS DC ; any data? */ + 0027742, /* 77743: JMP *-1 ; wait */ + 0107510, /* 77744: LIB DC,C ; get word */ + 0037775, /* 77745: ISZ WC ; done? */ + 0027737, /* 77746: JMP NW ; no */ + 0054000, /* 77747: CPB 0 ; csum ok? */ + 0027717, /* 77750: JMP RD+3 ; yes, cont */ + 0102011, /* 77751: HLT 11 ; no, halt */ + 0102511, /* 77752: ST LIA CC ; get status */ + 0001727, /* 77753: ALF,ALF ; get eof bit */ + 0002020, /* 77754: SSA ; set? */ + 0102077, /* 77755: HLT 77 ; done */ + 0001727, /* 77756: ALF,ALF ; put status back */ + 0001310, /* 77757: RAR,SLA ; read ok? */ + 0102000, /* 77760: HLT 0 ; no */ + 0027714, /* 77761: JMP RD ; read next */ + 0000000, /* 77762: CMD NOP */ + 0106611, /* 77763: OTB CC ; output cmd */ + 0102511, /* 77764: LIA CC ; check for reject */ + 0001323, /* 77765: RAR,RAR */ + 0001310, /* 77766: RAR,SLA */ + 0027763, /* 77767: JMP CMD+1 ; try again */ + 0103711, /* 77770: STC CC,C ; start command */ + 0127762, /* 77771: JMP CMD,I ; exit */ + 0001501, /* 77772: SL0RW OCT 1501 ; select 0, rewind */ + 0001423, /* 77773: RDCMD OCT 1423 ; read record */ + 0000203, /* 77774: FFC OCT 203 ; space forward file */ + 0000000, /* 77775: WC NOP */ + 0000000, /* 77776: NOP */ + 0000000 } } /* 77777: NOP */ }; + +/* Device boot routine. + + This routine is called directly by the BOOT MSC and LOAD MSC commands to copy + the device bootstrap into the upper 64 words of the logical address space. + It is also called indirectly by a BOOT CPU or LOAD CPU command when the + specified HP 1000 loader ROM socket contains a 12992D ROM. + + When called in response to a BOOT MSC or LOAD MSC command, the "unitno" + parameter indicates the unit number specified in the BOOT command or is zero + for the LOAD command, and "dptr" points at the MSC device structure. The + bootstrap supports loading only from unit 0, and the command will be rejected + if another unit is specified (e.g., BOOT MSC1). Otherwise, depending on the + current CPU model, the BMTL or 12992D loader ROM will be copied into memory + and configured for the MSD/MSC select code pair. If the CPU is a 1000, the S + register will be set as it would be by the front-panel microcode. + + When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the + select code to be used for configuration, and "dptr" will be NULL. As above, + the BMTL or 12992D loader ROM will be copied into memory and configured for + the specified select code. The S register is assumed to be set correctly on + entry and is not modified. + + For the 12992D boot loader ROM for the HP 1000, the S register is set as + follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | 0 0 | select code | 0 0 0 0 0 | F | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + F = Read current/specified file (0/1) + + If bit 0 is 0, the file located at the current tape position is read. If bit + 0 is 1, the tape is rewound, and the file number (1 - n) specified by the + A-register content is read. +*/ + t_stat msc_boot (int32 unitno, DEVICE *dptr) { -const int32 dev = msd_dib.select_code; /* get data chan device no */ +static const HP_WORD ms_preserved = 0000000u; /* no S-register bits are preserved */ +static const HP_WORD ms_reposition = 0000001u; /* S-register bit 0 set for a repositioning boot */ -if (unitno != 0) /* boot supported on drive unit 0 only */ - return SCPE_NOFNC; /* report "Command not allowed" if attempted */ +if (dptr == NULL) /* if we are being called for a BOOT/LOAD CPU */ + return cpu_copy_loader (ms_loaders, unitno, /* then copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* but do not alter the S register */ -cpu_ibl (ms_rom, dev, IBL_OPT, /* copy the boot ROM to memory and configure */ - IBL_MS | IBL_SET_SC (dev)); /* the S register accordingly */ +else if (unitno != 0) /* otherwise a BOOT MSC for a non-zero unit */ + return SCPE_NOFNC; /* is rejected as unsupported */ -if ((sim_switches & SWMASK ('S')) && AR) /* if -S is specified and the A register is non-zero */ - SR = SR | 1; /* then set to skip to the file number in A */ - -return SCPE_OK; +else /* otherwise this is a BOOT/LOAD MSC */ + return cpu_copy_loader (ms_loaders, msd_dib.select_code, /* so copy the boot loader to memory */ + ms_preserved, /* and configure the S register if 1000 CPU */ + sim_switches & SWMASK ('S') ? ms_reposition : 0); } + /* Calculate tape record CRC and LRC characters */ static uint32 calc_crc_lrc (uint8 *buffer, t_mtrlnt length) diff --git a/HP2100/hp2100_mux.c b/HP2100/hp2100_mux.c index 25b67148..52e335c6 100644 --- a/HP2100/hp2100_mux.c +++ b/HP2100/hp2100_mux.c @@ -1,7 +1,7 @@ /* hp2100_mux.c: HP 2100 12920A Asynchronous Multiplexer Interface simulator Copyright (c) 2002-2016, Robert M. Supnik - Copyright (c) 2017 J. David Bryan + Copyright (c) 2017-2018 J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,8 @@ MUX,MUXL,MUXC 12920A Asynchronous Multiplexer Interface + 01-May-18 JDB Removed ioCRS counter, as consecutive ioCRS calls are no longer made + 28-Apr-18 JDB Fixed output completion IRQ when port is not connected 03-Aug-17 JDB Control card device renamed from MUXM to MUXC MUXC now enabled/disabled independently of MUX and MUXL Modified to use the "odd_parity" array in hp2100_sys.c @@ -101,6 +103,124 @@ 801-type automatic dialers). Under simulation, only one control card is supported. + The multiplexer responds to I/O instructions as follows: + + Upper Data Card output word format (OTA and OTB): + + 15 |14 13 12 |11 10 9 | 8 7 6 | 5 4 3 | 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | - | channel number | - - - - - - - - - - | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + + Upper Data Card input word format (LIA, LIB, MIA, and MIB): + + 15 |14 13 12 |11 10 9 | 8 7 6 | 5 4 3 | 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | S | channel number | - - - - - - | D | B | L | R | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + S = Seeking + D = Diagnose + B = Break status + L = Character lost + R = Receive/send (0/1) character interrupt + + + Lower Data Card output control word format (OTA and OTB): + + 15 |14 13 12 |11 10 9 | 8 7 6 | 5 4 3 | 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | 1 | R | I | E | D | char size | baud rate | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + R = Receive/send (0/1) configuration + I = Enable interrupt + E = Echo (receive)/parity (send) + D = Diagnose + + Character size: + + The three least-significant bits of the sum of the data, parity, and stop + bits. For example, 7E1 is 1001, so 001 is coded. + + Baud rate: + + The value (14400 / device bit rate) - 1. For example, 2400 baud is 005. + + + Lower Data Card output data word format (OTA and OTB): + + 15 |14 13 12 |11 10 9 | 8 7 6 | 5 4 3 | 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | 0 | 1 | - - | S | transmit data | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + S = Sync bit + + Transmit data: + + Right-justified with leading one bits. + + + Lower Data Card input word format (LIA, LIB, MIA, and MIB): + + 15 |14 13 12 |11 10 9 | 8 7 6 | 5 4 3 | 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | P | channel | receive data | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + P = Computed parity + + Receive data: + + Right-justified with leading one bits + + + Control Card output word format (OTA and OTB): + + 15 |14 13 12 |11 10 9 | 8 7 6 | 5 4 3 | 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | S | U |channel number | - - |EC2|EC1|C2 |C1 |ES2|ES1|SS2|SS1| + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + + Control Card input word format (LIA, LIB, MIA, and MIB): + + 15 |14 13 12 |11 10 9 | 8 7 6 | 5 4 3 | 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | 1 1 |channel number |I2 |I1 | 0 0 0 0 |ES2|ES1|S2 |S1 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + S = Scan + U = Update + ECx = Enable command bit x + Cx = Command bit x + ESx = Enable status bit x + Sx = Status bit x + SSx = Stored status bit x + Ix = Interrupt bit x + + The control card provides two serial control outputs and two serial status + inputs for each of the 16 channels. The card connects to the Request to Send + (CA) and Data Terminal Ready (CD) control lines and the Data Carrier Detect + (CF) and Data Set Ready (CC) status lines. Addressable latches hold the + control line values and assert them continuously to the 16 channels. In + addition, a 16-word by 4-bit RAM holds the expected state for each channel's + status lines and the corresponding interrupt enable bits to provide + notification if those lines change. + + Implementation notes: 1. If a BREAK is detected during an input poll, and we are not in diagnostic @@ -142,6 +262,23 @@ before the output character transmit interrupt). If an output operation is not in progress, then the BREAK will be recognized at the next input poll. + + 2. In simulation, establishing a port connection asserts DSR to the control + card. If the port is configured as a dataset connection (SET MUXLn + DATASET), DCD is also asserted. Disconnecting denies DSR and DCD. The + control card responds to DTR denying by dropping the port connection. + The RTS setting has no effect. + + 3. When a Bell 103 dataset answers a call, it asserts DSR first. After the + handshake with the remote dataset completes, DCD asserts, typically + between 1.3 and 3.6 seconds later. Similarly, when the remote dataset + terminates the call by sending a long (1.5 second) space, the local + dataset drops DSR first, followed by DCD after approximately 30 + milliseconds. The dataset simulation does not model these delays; DSR + and DCD transition up and down together. This implies that the control + card software driver will see only one interrupt for each transition pair + instead of the expected two (presuming both DSR and DCD are enabled to + interrupt). */ @@ -181,6 +318,7 @@ #define UNIT_MDM (1 << UNIT_V_MDM) #define UNIT_DIAG (1 << UNIT_V_DIAG) + /* Channel number (OTA upper, LIA lower or upper) */ #define MUX_V_CHAN 10 /* channel num */ @@ -205,12 +343,47 @@ #define OTL_CHAR 03777 /* char mask */ #define OTL_PAR 0200 /* char parity */ +#define BAUD_RATE(p) ((28800 / (OTL_BAUD (p) + 1) + 1) / 2) + +static const uint32 bits_per_char [8] = { /* bits per character, indexed by OTL_LNT encoding */ + 9, 10, 11, 12, 5, 6, 7, 8 + }; + +static const BITSET_NAME lower_parameter_names [] = { /* lower data card parameter word names */ + "\1send\0receive", /* bit 14 */ + "enable interrupt", /* bit 13 */ + "enable parity/echo", /* bit 12 */ + "diagnose" /* bit 11 */ + }; + +static const BITSET_FORMAT lower_parameter_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (lower_parameter_names, 11, msb_first, has_alt, append_bar) }; + +static const BITSET_NAME lower_data_names [] = { /* lower data card output data word names */ + "send", /* bit 14 */ + NULL, /* bit 13 */ + NULL, /* bit 12 */ + "sync" /* bit 11 */ + }; + +static const BITSET_FORMAT lower_data_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (lower_data_names, 11, msb_first, no_alt, append_bar) }; + + /* LIA, lower = received data */ #define LIL_PAR 0100000 /* parity */ #define PUT_DCH(x) (((x) & MUX_M_CHAN) << MUX_V_CHAN) #define LIL_CHAR 01777 /* character */ +static const BITSET_NAME lower_input_names [] = { /* lower data card input data word names */ + "\1odd parity\0even parity", /* bit 15 */ + }; + +static const BITSET_FORMAT lower_input_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (lower_input_names, 0, msb_first, has_alt, append_bar) }; + + /* LIA, upper = status */ #define LIU_SEEK 0100000 /* seeking NI */ @@ -219,6 +392,29 @@ #define LIU_LOST 0000002 /* char lost */ #define LIU_TR 0000001 /* trans/rcv */ +static const BITSET_NAME upper_status_names [] = { /* upper data card status word names */ + "seeking", /* bit 15 */ + NULL, /* bit 14 */ + NULL, /* bit 13 */ + NULL, /* bit 12 */ + NULL, /* bit 11 */ + NULL, /* bit 10 */ + NULL, /* bit 9 */ + NULL, /* bit 8 */ + NULL, /* bit 7 */ + NULL, /* bit 6 */ + NULL, /* bit 5 */ + NULL, /* bit 4 */ + "diagnose", /* bit 3 */ + "break" /* bit 2 */ + "lost", /* bit 1 */ + "\1send\0receive" /* bit 0 */ + }; + +static const BITSET_FORMAT upper_status_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (upper_status_names, 0, msb_first, has_alt, no_bar) }; + + /* OTA, control */ #define OTC_SCAN 0100000 /* scan */ @@ -237,8 +433,29 @@ #define OTC_SS2 0000002 /* SSn flops */ #define OTC_SS1 0000001 #define OTC_RW (OTC_ES2|OTC_ES1|OTC_SS2|OTC_SS1) -#define RTS OTC_C2 /* C2 = rts */ -#define DTR OTC_C1 /* C1 = dtr */ + +static const BITSET_NAME cntl_control_names [] = { /* control card control word names */ + "scan", /* bit 15 */ + "update", /* bit 14 */ + NULL, /* bit 13 */ + NULL, /* bit 12 */ + NULL, /* bit 11 */ + NULL, /* bit 10 */ + NULL, /* bit 9 */ + NULL, /* bit 8 */ + "EC2", /* bit 7 */ + "EC1", /* bit 6 */ + "\1C2\0~C2", /* bit 5 */ + "\1C1\0~C1", /* bit 4 */ + "ES2", /* bit 3 */ + "ES1", /* bit 2 */ + "\1S2\0~S2", /* bit 1 */ + "\1S1\0~S1" /* bit 0 */ + }; + +static const BITSET_FORMAT cntl_control_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (cntl_control_names, 0, msb_first, has_alt, no_bar) }; + /* LIA, control */ @@ -251,13 +468,46 @@ #define LIC_S2 0000002 /* Sn flops */ #define LIC_S1 0000001 #define LIC_V_I 8 /* S1 to I1 */ -#define CDET LIC_S2 /* S2 = cdet */ -#define DSR LIC_S1 /* S1 = dsr */ #define LIC_TSTI(ch) (((muxc_lia[ch] ^ muxc_ota[ch]) & \ ((muxc_ota[ch] & (OTC_ES2|OTC_ES1)) >> OTC_V_ES)) \ << LIC_V_I) +static const BITSET_NAME cntl_status_names [] = { /* control card status word names */ + "I2", /* bit 9 */ + "I1", /* bit 8 */ + NULL, /* bit 7 */ + NULL, /* bit 6 */ + NULL, /* bit 5 */ + NULL, /* bit 4 */ + "ES2", /* bit 3 */ + "ES1", /* bit 2 */ + "\1S2\0~S2", /* bit 1 */ + "\1S1\0~S1" /* bit 0 */ + }; + +static const BITSET_FORMAT cntl_status_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (cntl_status_names, 0, msb_first, has_alt, no_bar) }; + +/* Control card #1 serial line bits */ + +#define RTS OTC_C2 /* Control card #1 C2 = Request to Send */ +#define DTR OTC_C1 /* Control card #1 C1 = Data Terminal Ready */ +#define DCD LIC_S2 /* Control card #1 S2 = Data Carrier Detect */ +#define DSR LIC_S1 /* Control card #1 S1 = Data Set Ready */ + +static const BITSET_NAME cntl_line_names [] = { /* Control card serial line status names */ + "RTS", /* bit 5 */ + "DTR", /* bit 4 */ + NULL, /* bit 3 */ + NULL, /* bit 2 */ + "DCD", /* bit 1 */ + "DSR" /* bit 0 */ + }; + +static const BITSET_FORMAT cntl_line_format = /* names, offset, direction, alternates, bar */ + { FMT_INIT (cntl_line_names, 0, msb_first, no_alt, no_bar) }; + /* Program constants */ @@ -440,9 +690,9 @@ static MTAB muxl_mod [] = { /* Debugging trace list */ static DEBTAB muxl_deb [] = { - { "CMDS", DEB_CMDS }, - { "CPU", DEB_CPU }, - { "XFER", DEB_XFER }, + { "CSRW", TRACE_CSRW }, /* Interface control, status, read, and write actions */ + { "SERV", TRACE_SERV }, /* Channel unit service scheduling calls */ + { "XFER", TRACE_XFER }, /* Data receptions and transmissions */ { "IOBUS", TRACE_IOBUS }, /* interface I/O bus signals and data words */ { NULL, 0 } }; @@ -520,7 +770,8 @@ static MTAB muxu_mod [] = { /* Debugging trace list */ static DEBTAB muxu_deb [] = { - { "CPU", DEB_CPU }, + { "CSRW", TRACE_CSRW }, /* Interface control, status, read, and write actions */ + { "PSERV", TRACE_PSERV }, /* Poll unit service scheduling calls */ { "IOBUS", TRACE_IOBUS }, /* interface I/O bus signals and data words */ { NULL, 0 } }; @@ -601,8 +852,8 @@ static MTAB muxc_mod [] = { /* Debugging trace list */ static DEBTAB muxc_deb [] = { - { "CMDS", DEB_CMDS }, - { "CPU", DEB_CPU }, + { "CSRW", TRACE_CSRW }, /* Interface control, status, read, and write actions */ + { "XFER", TRACE_XFER }, /* Data receptions and transmissions */ { "IOBUS", TRACE_IOBUS }, /* interface I/O bus signals and data words */ { NULL, 0 } }; @@ -646,26 +897,16 @@ DEVICE muxc_dev = { 1. The operating manual says that "at least 100 milliseconds of CLC 0s must be programmed" by systems employing the multiplexer to ensure that the multiplexer resets. In practice, such systems issue 128K CLC 0 - instructions. As we provide debug logging of multiplexer resets, a CRS - counter is used to ensure that only one debug line is printed in response - to these 128K CRS invocations. + instructions. In simulation, only one ioCRS invocation is required to + reset the multiplexer. */ uint32 muxlio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) { -int32 ln; -const char *hold_or_clear = (signal_set & ioCLF ? ",C" : ""); -static uint32 crs_count = 0; /* cntr for ioCRS repeat */ +int32 ln; IOSIGNAL signal; IOCYCLE working_set = IOADDSIR (signal_set); /* add ioSIR if needed */ -if (crs_count && !(signal_set & ioCRS)) { /* counting CRSes and not present? */ - tprintf (muxl_dev, DEB_CMDS, "[CRS] Multiplexer reset %d times\n", - crs_count); - - crs_count = 0; /* clear counter */ - } - while (working_set) { signal = IONEXT (working_set); /* isolate next signal */ @@ -673,9 +914,6 @@ while (working_set) { case ioCLF: /* clear flag flip-flop */ muxl.flag = muxl.flagbuf = CLEAR; - - tprintf (muxl_dev, DEB_CMDS, "[CLF] Flag cleared\n"); - mux_data_int (); /* look for new int */ break; @@ -683,8 +921,6 @@ while (working_set) { case ioSTF: /* set flag flip-flop */ case ioENF: /* enable flag */ muxl.flag = muxl.flagbuf = SET; - - tprintf (muxl_dev, DEB_CMDS, "[STF] Flag set\n"); break; @@ -699,19 +935,28 @@ while (working_set) { case ioIOI: /* I/O data input */ - stat_data = IORETURN (SCPE_OK, muxl_ibuf); /* merge in return status */ + tprintf (muxl_dev, TRACE_CSRW, "Input data is channel %u | %s%04o\n", + MUX_CHAN (muxl_ibuf), + fmt_bitset (muxl_ibuf, lower_input_format), + muxl_ibuf & LIL_CHAR); - tprintf (muxl_dev, DEB_CPU, "[LIx%s] Data = %06o\n", hold_or_clear, muxl_ibuf); + stat_data = IORETURN (SCPE_OK, muxl_ibuf); /* merge in return status */ break; case ioIOO: /* I/O data output */ muxl_obuf = IODATA (stat_data); /* store data */ + if (muxl_obuf & OTL_P) - tprintf (muxl_dev, DEB_CPU, "[OTx%s] Parameter = %06o\n", hold_or_clear, muxl_obuf); + tprintf (muxl_dev, TRACE_CSRW, "Parameter is %s%u bits | %u baud\n", + fmt_bitset (muxl_obuf, lower_parameter_format), + bits_per_char [OTL_LNT (muxl_obuf)], + BAUD_RATE (muxl_obuf)); else - tprintf (muxl_dev, DEB_CPU, "[OTx%s] Data = %06o\n", hold_or_clear, muxl_obuf); + tprintf (muxl_dev, TRACE_CSRW, "Output data is %s%04o\n", + fmt_bitset (muxl_obuf, lower_data_format), + muxl_obuf & OTL_CHAR); break; @@ -721,83 +966,87 @@ while (working_set) { case ioCRS: /* control reset */ - if (crs_count == 0) { /* first reset? */ - muxl.control = CLEAR; /* clear control flip-flop */ + muxl.control = CLEAR; /* clear control flip-flop */ - for (ln = 0; ln < SEND_CHAN_COUNT; ln++) { /* clear transmit info */ - mux_xbuf[ln] = mux_xpar[ln] = 0; - muxc_ota[ln] = muxc_lia[ln] = mux_xdon[ln] = 0; - } - - for (ln = 0; ln < RECV_CHAN_COUNT; ln++) { - mux_rbuf[ln] = mux_rpar[ln] = 0; /* clear receive info */ - mux_sta[ln] = mux_rchp[ln] = 0; - } + for (ln = 0; ln < SEND_CHAN_COUNT; ln++) { /* clear transmit info */ + mux_xbuf[ln] = mux_xpar[ln] = 0; + muxc_ota[ln] = muxc_lia[ln] = mux_xdon[ln] = 0; + } + + for (ln = 0; ln < RECV_CHAN_COUNT; ln++) { + mux_rbuf[ln] = mux_rpar[ln] = 0; /* clear receive info */ + mux_sta[ln] = mux_rchp[ln] = 0; } - crs_count = crs_count + 1; /* increment count */ break; case ioCLC: /* clear control flip-flop */ muxl.control = CLEAR; - - tprintf (muxl_dev, DEB_CMDS, "[CLC%s] Data interrupt inhibited\n", hold_or_clear); break; - case ioSTC: /* set control flip-flop */ - muxl.control = SET; /* set control */ + case ioSTC: /* set control flip-flop */ + muxl.control = SET; /* set control */ - ln = MUX_CHAN (muxu_obuf); /* get chan # */ + ln = MUX_CHAN (muxu_obuf); /* get chan # */ - if (muxl_obuf & OTL_TX) { /* transmit? */ - if (ln < SEND_CHAN_COUNT) { /* line valid? */ - if (muxl_obuf & OTL_P) { /* parameter? */ - mux_xpar[ln] = (uint16) muxl_obuf; /* store param value */ - tprintf (muxl_dev, DEB_CMDS, "[STC%s] Transmit channel %d parameter %06o stored\n", - hold_or_clear, ln, muxl_obuf); + if (muxl_obuf & OTL_TX) /* if this is a send parameter or data */ + if (ln >= SEND_CHAN_COUNT) /* then report if the channel number is out of range */ + tprintf (muxl_dev, TRACE_CSRW, "Send channel %d invalid\n", + ln); + + else if (muxl_obuf & OTL_P) { /* otherwise if this is a parameter store */ + mux_xpar[ln] = (uint16) muxl_obuf; /* then save it */ + + tprintf (muxl_dev, TRACE_CSRW, "Channel %d send parameter %06o stored\n", + ln, muxl_obuf); + } + + else { /* otherwise this is a data store */ + if (mux_xpar[ln] & OTL_TPAR) /* if parity is enabled */ + muxl_obuf = muxl_obuf & ~OTL_PAR /* then replace the parity bit */ + | XMT_PAR (muxl_obuf); /* with the calculated value */ + + mux_xbuf[ln] = (uint16) muxl_obuf; /* load buffer */ + + if (sim_is_active (&muxl_unit[ln])) { /* still working? */ + mux_sta[ln] = mux_sta[ln] | LIU_LOST; /* char lost */ + + tprintf (muxl_dev, TRACE_CSRW, "Channel %d send data overrun\n", + ln); } - else { /* data */ - if (mux_xpar[ln] & OTL_TPAR) /* parity requested? */ - muxl_obuf = /* add parity bit */ - muxl_obuf & ~OTL_PAR | - XMT_PAR(muxl_obuf); - mux_xbuf[ln] = (uint16) muxl_obuf; /* load buffer */ + else { + if (muxu_unit.flags & UNIT_DIAG) /* loopback? */ + mux_ldsc[ln].conn = 1; /* connect this line */ - if (sim_is_active (&muxl_unit[ln])) { /* still working? */ - mux_sta[ln] = mux_sta[ln] | LIU_LOST; /* char lost */ - tprintf (muxl_dev, DEB_CMDS, "[STC%s] Transmit channel %d data overrun\n", - hold_or_clear, ln); - } - else { - if (muxu_unit.flags & UNIT_DIAG) /* loopback? */ - mux_ldsc[ln].conn = 1; /* connect this line */ - sim_activate (&muxl_unit[ln], muxl_unit[ln].wait); - tprintf (muxl_dev, DEB_CMDS, "[STC%s] Transmit channel %d data %06o scheduled\n", - hold_or_clear, ln, muxl_obuf); - } + sim_activate (&muxl_unit[ln], muxl_unit[ln].wait); + + tprintf (muxl_dev, TRACE_CSRW, "Channel %d send data %06o stored\n", + ln, muxl_obuf); + + tprintf (muxl_dev, TRACE_SERV, "Channel %d delay %d service scheduled\n", + ln, muxl_unit [ln].wait); } } - else - tprintf (muxl_dev, DEB_CMDS, "[STC%s] Transmit channel %d invalid\n", hold_or_clear, ln); - } - else /* receive */ - if (ln < RECV_CHAN_COUNT) /* line valid? */ - if (muxl_obuf & OTL_P) { /* parameter? */ - mux_rpar[ln] = (uint16) muxl_obuf; /* store param value */ - tprintf (muxl_dev, DEB_CMDS, "Receive channel %d parameter %06o stored\n", - ln, muxl_obuf); - } + else /* otherwise this is a receive parameter */ + if (ln >= RECV_CHAN_COUNT) /* report if the channel number is out of range */ + tprintf (muxl_dev, TRACE_CSRW, "Receive channel %d invalid\n", + ln); - else - tprintf (muxl_dev, DEB_CMDS, "Receive channel %d parameter %06o invalid action\n", - ln, muxl_obuf); + else if (muxl_obuf & OTL_P) { /* otherwise if this is a parameter store */ + mux_rpar[ln] = (uint16) muxl_obuf; /* then save it */ + + tprintf (muxl_dev, TRACE_CSRW, "Channel %d receive parameter %06o stored\n", + ln, muxl_obuf); + } + + else /* otherwise a data store to a receive channel is invalid */ + tprintf (muxl_dev, TRACE_CSRW, "Channel %d receive output data word %06o invalid\n", + ln, muxl_obuf); - else - tprintf (muxl_dev, DEB_CMDS, "[STC%s] Receive channel %d invalid\n", hold_or_clear, ln); break; @@ -850,15 +1099,17 @@ while (working_set) { case ioIOI: /* I/O data input */ stat_data = IORETURN (SCPE_OK, muxu_ibuf); /* merge in return status */ - tprintf (muxu_dev, DEB_CPU, "[LIx] Status = %06o, channel = %d\n", - muxu_ibuf, MUX_CHAN(muxu_ibuf)); + tprintf (muxu_dev, TRACE_CSRW, "Status is channel %u | %s\n", + MUX_CHAN (muxu_ibuf), + fmt_bitset (muxu_ibuf, upper_status_format)); break; case ioIOO: /* I/O data output */ muxu_obuf = IODATA (stat_data); /* store data */ - tprintf (muxu_dev, DEB_CPU, "[OTx] Data channel = %d\n", MUX_CHAN(muxu_obuf)); + tprintf (muxu_dev, TRACE_CSRW, "Channel %d is selected\n", + MUX_CHAN (muxu_obuf)); break; @@ -882,7 +1133,6 @@ return stat_data; uint32 muxcio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) { -const char *hold_or_clear = (signal_set & ioCLF ? ",C" : ""); uint16 data; int32 ln, old; IOSIGNAL signal; @@ -895,9 +1145,6 @@ while (working_set) { case ioCLF: /* clear flag flip-flop */ muxc.flag = muxc.flagbuf = CLEAR; - - tprintf (muxc_dev, DEB_CMDS, "[CLF] Flag cleared\n"); - mux_ctrl_int (); /* look for new int */ break; @@ -905,8 +1152,6 @@ while (working_set) { case ioSTF: /* set flag flip-flop */ case ioENF: /* enable flag */ muxc.flag = muxc.flagbuf = SET; - - tprintf (muxc_dev, DEB_CMDS, "[STF] Flag set\n"); break; @@ -926,8 +1171,8 @@ while (working_set) { (muxc_ota[muxc_chan] & (OTC_ES2 | OTC_ES1)) | /* ES2, ES1 */ (muxc_lia[muxc_chan] & (LIC_S2 | LIC_S1))); /* S2, S1 */ - tprintf (muxc_dev, DEB_CPU, "[LIx%s] Status = %06o, channel = %d\n", - hold_or_clear, data, muxc_chan); + tprintf (muxc_dev, TRACE_CSRW, "Status is channel %u | %s\n", + muxc_chan, fmt_bitset (data, cntl_status_format)); muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* incr channel */ stat_data = IORETURN (SCPE_OK, data); /* merge in return status */ @@ -938,6 +1183,9 @@ while (working_set) { data = IODATA (stat_data); /* clear supplied status */ ln = muxc_chan = OTC_CHAN (data); /* set channel */ + tprintf (muxc_dev, TRACE_CSRW, "Control is channel %u | %s\n", + muxc_chan, fmt_bitset (data, cntl_control_format)); + if (data & OTC_SCAN) muxc_scan = 1; /* set scan flag */ else muxc_scan = 0; @@ -954,14 +1202,22 @@ while (working_set) { muxc_ota[ln] = (muxc_ota[ln] & ~OTC_C1) | (data & OTC_C1); - if (muxu_unit.flags & UNIT_DIAG) /* loopback? */ + tprintf (muxc_dev, TRACE_XFER, "Channel %d line status is %s\n", + ln, fmt_bitset (muxc_ota [ln], cntl_line_format)); + + if (muxu_unit.flags & UNIT_DIAG) { /* loopback? */ muxc_lia[ln ^ 1] = /* set S1, S2 to C1, C2 */ (muxc_lia[ln ^ 1] & ~(LIC_S2 | LIC_S1)) | (muxc_ota[ln] & (OTC_C1 | OTC_C2)) >> OTC_V_C; + tprintf (muxc_dev, TRACE_XFER, "Channel %d line status is %s\n", + ln ^ 1, fmt_bitset (muxc_lia [ln ^ 1], cntl_line_format)); + } + else if ((muxl_unit[ln].flags & UNIT_MDM) /* modem ctrl? */ && (old & DTR) && !(muxc_ota[ln] & DTR)) { /* DTR drop? */ - tprintf (muxc_dev, DEB_CMDS, "Channel %d disconnected by DTR drop\n", ln); + tprintf (muxc_dev, TRACE_CSRW, "Channel %d disconnected by DTR drop\n", + ln); tmxr_linemsg (&mux_ldsc[ln], "\r\nDisconnected from the "); tmxr_linemsg (&mux_ldsc[ln], sim_name); @@ -969,12 +1225,12 @@ while (working_set) { tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */ muxc_lia[ln] = 0; /* dataset off */ + + tprintf (muxc_dev, TRACE_XFER, "Channel %d disconnect dropped DCD and DSR\n", + ln); } } /* end update */ - tprintf (muxc_dev, DEB_CPU, "[OTx%s] Parameter = %06o, channel = %d\n", - hold_or_clear, data, ln); - if ((muxu_unit.flags & UNIT_DIAG) && (!muxc.flag)) /* loopback and flag clear? */ mux_ctrl_int (); /* status chg may interrupt */ break; @@ -1030,6 +1286,9 @@ t_stat muxi_svc (UNIT *uptr) int32 ln, c; t_bool loopback; +tprintf (muxu_dev, TRACE_PSERV, "Poll delay %d service entered\n", + uptr->wait); + loopback = ((muxu_unit.flags & UNIT_DIAG) != 0); /* diagnostic mode? */ if (!loopback) { /* terminal mode? */ @@ -1043,16 +1302,21 @@ if (!loopback) { /* terminal mode? */ ln = tmxr_poll_conn (&mux_desc); /* look for connect */ if (ln >= 0) { /* got one? */ + mux_ldsc[ln].rcve = 1; /* rcv enabled */ + muxc_lia[ln] = muxc_lia[ln] | DSR; /* set dsr */ + if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */ (muxc_ota[ln] & DTR)) /* DTR? */ - muxc_lia[ln] = muxc_lia[ln] | CDET; /* set cdet */ - muxc_lia[ln] = muxc_lia[ln] | DSR; /* set dsr */ - mux_ldsc[ln].rcve = 1; /* rcv enabled */ + muxc_lia[ln] = muxc_lia[ln] | DCD; /* set DCD */ + + tprintf (muxc_dev, TRACE_XFER, "Channel %d connected\n", + ln); } + tmxr_poll_rx (&mux_desc); /* poll for input */ } -for (ln = 0; ln < SEND_CHAN_COUNT; ln++) { /* loop thru lines */ +for (ln = 0; ln < SEND_CHAN_COUNT; ln++) { /* loop thru lines */ if (mux_ldsc[ln].conn) { /* connected? */ if (loopback) { /* diagnostic mode? */ c = mux_xbuf[ln ^ 1] & OTL_CHAR; /* get char from xmit line */ @@ -1065,7 +1329,7 @@ for (ln = 0; ln < SEND_CHAN_COUNT; ln++) { /* loop thru lines c = SCPE_BREAK; /* supply it now */ else - c = tmxr_getc_ln (&mux_ldsc[ln]); /* get char from Telnet */ + c = tmxr_getc_ln (&mux_ldsc[ln]); /* get char from line */ if (c) /* valid char? */ mux_receive (ln, c, loopback); /* process it */ @@ -1086,56 +1350,68 @@ return SCPE_OK; t_stat muxo_svc (UNIT *uptr) { -int32 c, fc, ln, altln; +const int32 ln = uptr - muxl_unit; /* line # */ +const int32 altln = ln ^ 1; /* alt. line for diag mode */ +int32 c, fc; t_bool loopback; +t_stat result = SCPE_OK; -ln = uptr - muxl_unit; /* line # */ -altln = ln ^ 1; /* alt. line for diag mode */ +tprintf (muxl_dev, TRACE_SERV, "Channel %d service entered\n", + ln); fc = mux_xbuf[ln] & OTL_CHAR; /* full character data */ -c = fc & 0377; /* Telnet character data */ +c = fc & 0377; /* line character data */ loopback = ((muxu_unit.flags & UNIT_DIAG) != 0); /* diagnostic mode? */ -if (mux_ldsc[ln].conn) { /* connected? */ - if (mux_ldsc[ln].xmte) { /* xmt enabled? */ - if (loopback) /* diagnostic mode? */ - mux_ldsc[ln].conn = 0; /* clear connection */ +if (mux_ldsc[ln].xmte) { /* xmt enabled? */ + if (loopback) /* diagnostic mode? */ + mux_ldsc[ln].conn = 0; /* clear connection */ - else if (mux_defer[ln]) /* break deferred? */ - mux_receive (ln, SCPE_BREAK, loopback); /* process it now */ + else if (mux_defer[ln]) /* break deferred? */ + mux_receive (ln, SCPE_BREAK, loopback); /* process it now */ - if ((mux_xbuf[ln] & OTL_SYNC) == 0) { /* start bit 0? */ - TMLN *lp = &mux_ldsc[ln]; /* get line */ - c = sim_tt_outcvt (c, TT_GET_MODE (muxl_unit[ln].flags)); + if ((mux_xbuf[ln] & OTL_SYNC) == 0) { /* start bit 0? */ + TMLN *lp = &mux_ldsc[ln]; /* get line */ + c = sim_tt_outcvt (c, TT_GET_MODE (muxl_unit[ln].flags)); - if (mux_xpar[ln] & OTL_DIAG) /* xmt diagnose? */ - mux_diag (fc); /* before munge */ + if (mux_xpar[ln] & OTL_DIAG) /* xmt diagnose? */ + mux_diag (fc); /* before munge */ - if (loopback) { /* diagnostic mode? */ - mux_ldsc[altln].conn = 1; /* set recv connection */ - sim_activate (&muxu_unit, 1); /* schedule receive */ - } - - else { /* no loopback */ - if (c >= 0) /* valid? */ - tmxr_putc_ln (lp, c); /* output char */ - tmxr_poll_tx (&mux_desc); /* poll xmt */ - } + if (loopback) { /* diagnostic mode? */ + mux_ldsc[altln].conn = 1; /* set recv connection */ + sim_activate (&muxu_unit, 1); /* schedule receive */ } - mux_xdon[ln] = 1; /* set for xmit irq */ + else { /* no loopback */ + if (c >= 0) /* valid? */ + result = tmxr_putc_ln (lp, c); /* output char */ + tmxr_poll_tx (&mux_desc); /* poll xmt */ + } + } - if (loopback || c >= 0) - tprintf (muxl_dev, DEB_XFER, "Channel %d character %s sent\n", + else if (mux_ldsc [ln].conn == 0) /* sync character isn't seen by receiver */ + result = SCPE_LOST; /* so report transfer success if connected */ + + mux_xdon[ln] = 1; /* set for xmit irq */ + + if (loopback || c >= 0) + if (result == SCPE_LOST) + tprintf (muxl_dev, TRACE_XFER, "Channel %d character %s discarded by connection loss\n", ln, fmt_char ((uint8) (loopback ? fc : c))); - } + else + tprintf (muxl_dev, TRACE_XFER, "Channel %d character %s sent\n", + ln, fmt_char ((uint8) (loopback ? fc : c))); + } - else { /* buf full */ - tmxr_poll_tx (&mux_desc); /* poll xmt */ - sim_activate (uptr, muxl_unit[ln].wait); /* wait */ - return SCPE_OK; - } +else { /* buf full */ + tmxr_poll_tx (&mux_desc); /* poll xmt */ + sim_activate (uptr, muxl_unit[ln].wait); /* wait */ + + tprintf (muxl_dev, TRACE_SERV, "Channel %d delay %d service rescheduled\n", + ln, muxl_unit [ln].wait); + + return SCPE_OK; } if (!muxl.flag) mux_data_int (); /* scan for int */ @@ -1154,15 +1430,15 @@ if (c & SCPE_BREAK) { /* break? */ mux_sta[ln] = mux_sta[ln] | LIU_BRK; /* set break status */ if (diag) - tprintf (muxl_dev, DEB_XFER, "Channel %d break detected\n", ln); + tprintf (muxl_dev, TRACE_XFER, "Channel %d break detected\n", ln); else - tprintf (muxl_dev, DEB_XFER, "Channel %d deferred break processed\n", ln); + tprintf (muxl_dev, TRACE_XFER, "Channel %d deferred break processed\n", ln); } else { mux_defer[ln] = 1; /* defer break */ - tprintf (muxl_dev, DEB_XFER, "Channel %d break detected and deferred\n", ln); + tprintf (muxl_dev, TRACE_XFER, "Channel %d break detected and deferred\n", ln); return; } @@ -1184,7 +1460,7 @@ else { /* normal */ mux_rchp[ln] = 1; /* char pending */ -tprintf (muxl_dev, DEB_XFER, "Channel %d character %s received\n", +tprintf (muxl_dev, TRACE_XFER, "Channel %d character %s received\n", ln, fmt_char ((uint8) c)); if (mux_rpar[ln] & OTL_DIAG) /* diagnose this line? */ @@ -1209,7 +1485,8 @@ for (i = FIRST_TERM; i <= LAST_TERM; i++) { /* rcv lines */ mux_rchp[i] = 0; /* clr char, stat */ mux_sta[i] = 0; - tprintf (muxl_dev, DEB_CMDS, "Receive channel %d interrupt requested\n", i); + tprintf (muxl_dev, TRACE_CSRW, "Channel %d receive interrupt requested\n", + i); muxlio (&muxl_dib, ioENF, 0); /* interrupt */ return; @@ -1224,7 +1501,8 @@ for (i = FIRST_TERM; i <= LAST_TERM; i++) { /* xmt lines */ mux_xdon[i] = 0; /* clr done, stat */ mux_sta[i] = 0; - tprintf (muxl_dev, DEB_CMDS, "Transmit channel %d interrupt requested\n", i); + tprintf (muxl_dev, TRACE_CSRW, "Channel %d send interrupt requested\n", + i); muxlio (&muxl_dib, ioENF, 0); /* interrupt */ return; @@ -1239,7 +1517,8 @@ for (i = FIRST_AUX; i <= LAST_AUX; i++) { /* diag lines */ mux_rchp[i] = 0; /* clr char, stat */ mux_sta[i] = 0; - tprintf (muxl_dev, DEB_CMDS, "Receive channel %d interrupt requested\n", i); + tprintf (muxl_dev, TRACE_CSRW, "Channel %d receive interrupt requested\n", + i); muxlio (&muxl_dib, ioENF, 0); /* interrupt */ return; @@ -1267,10 +1546,10 @@ line_count = (muxc_scan ? TERM_COUNT : 1); /* check one or all line for (i = 0; i < line_count; i++) { if (muxc_scan) /* scanning? */ muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* step channel */ - if (LIC_TSTI (muxc_chan)) { /* status change? */ - tprintf (muxc_dev, DEB_CMDS, "Control channel %d interrupt requested (poll = %d)\n", - muxc_chan, i + 1); + if (LIC_TSTI (muxc_chan)) { /* status change? */ + tprintf (muxc_dev, TRACE_CSRW, "Channel %u interrupt requested\n", + muxc_chan); muxcio (&muxc_dib, ioENF, 0); /* set flag */ break; @@ -1310,10 +1589,12 @@ mux_rpar[i] = mux_xpar[i] = 0; mux_rchp[i] = mux_xdon[i] = 0; mux_sta[i] = mux_defer[i] = 0; muxc_ota[i] = muxc_lia[i] = 0; /* clear modem */ -if (mux_ldsc[i].conn && /* connected? */ - ((muxu_unit.flags & UNIT_DIAG) == 0)) /* term mode? */ - muxc_lia[i] = muxc_lia[i] | DSR | /* cdet, dsr */ - (muxl_unit[i].flags & UNIT_MDM? CDET: 0); + +if (mux_ldsc [i].conn /* connected? */ + && (muxu_unit.flags & UNIT_DIAG) == 0) /* term mode? */ + muxc_lia[i] = muxc_lia[i] | DSR /* DCD, dsr */ + | (muxl_unit[i].flags & UNIT_MDM ? DCD : 0); + sim_cancel (&muxl_unit[i]); return; } @@ -1342,7 +1623,7 @@ muxc_chan = muxc_scan = 0; /* init modem scan */ if (muxu_unit.flags & UNIT_ATT) { /* master att? */ muxu_unit.wait = POLL_FIRST; /* set up poll */ - sim_activate (&muxu_unit, muxu_unit.wait); /* start Telnet poll immediately */ + sim_activate (&muxu_unit, muxu_unit.wait); /* start poll immediately */ } else sim_cancel (&muxu_unit); /* else stop */ @@ -1370,7 +1651,7 @@ status = tmxr_attach (&mux_desc, uptr, cptr); /* attach */ if (status == SCPE_OK) { muxu_unit.wait = POLL_FIRST; /* set up poll */ - sim_activate (&muxu_unit, muxu_unit.wait); /* start Telnet poll immediately */ + sim_activate (&muxu_unit, muxu_unit.wait); /* start poll immediately */ } return status; @@ -1418,7 +1699,7 @@ t_stat mux_setdiag (UNIT *uptr, int32 val, CONST char *cptr, void *desc) int32 ln; if (val) { /* set diag? */ - mux_detach (uptr); /* detach lines */ + mux_detach (uptr); /* detach Telnet lines */ for (ln = 0; ln < TERM_COUNT; ln++) /* enable transmission */ mux_ldsc[ln].xmte = 1; /* on all lines */ } diff --git a/HP2100/hp2100_release.txt b/HP2100/hp2100_release.txt index 8a86d776..460c22ed 100644 --- a/HP2100/hp2100_release.txt +++ b/HP2100/hp2100_release.txt @@ -1,6 +1,6 @@ SIMH/HP 2100 RELEASE NOTES ========================== - Last update: 2017-09-06 + Last update: 2018-05-23 This file documents the release history of the simulator for the Hewlett-Packard @@ -56,7 +56,7 @@ The simulator has been tested with the following operating systems: - SIO, BCS, and MTS. - - 2000E, 2000F, and 2000/Access Time-Shared BASIC. + - 2000E, 2000F, and 2000 Access Time-Shared BASIC. - DOS, DOS-M, and DOS-III. @@ -68,6 +68,18 @@ PDF version of the same manual is available at: http://alum.mit.edu/www/jdbryan/hp2100_doc.pdf +For those intending to run 2000F or 2000/Access Time-Shared BASIC, a monograph +entitled "Running HP 2000 Time-Shared BASIC on SIMH" is available at: + + http://simh.trailing-edge.com/docs/running_hp_2000_tsb.pdf + +It discusses the requirements for successful TSB startup and operation and the +issues involved in synchronizing the dual-CPU simulation setup required by TSB. +TSB has run successfully on SIMH for many years, but the advent of multi-core +host machines has increased the difficulty in getting the two SIMH instances to +coordinate properly. The paper presents some configuration guidelines that +improve the probability of successfully running TSB. + ------------------ Available Software @@ -98,6 +110,15 @@ restore programs is available from the HP Computer Museum at: The archive contains instructions and a simulator command file. +Preconfigured 2000E, 2000F, and 2000 Access software kits are available from the +SIMH software repository here: + + http://simh.trailing-edge.com/software.html + +Each kit contains a bootable disc image and associated command files that +automate the system startup process. Command files to perform new system +generations are also included. + QCTerm, an HP 700 terminal emulator for Microsoft Windows, is available from the HP Computer Museum at: @@ -157,6 +178,259 @@ Revision 5010: +====================== +Release 28, 2018-05-23 +====================== + +This release of the HP 2100 simulator adds the following features: + + - The IPLI and IPLO devices now use shared memory instead of network sockets to + simulate the 12875A Processor Interconnect kit that is used to communicate + between the System Processor and the I/O Processor of the HP 2000B, C, F, and + Access Time-Shared BASIC operating systems. This change, in addition to a + new, adaptive service scheduling routine, improves data transfer time between + the processes by a factor of 7 to 1. + + - Commands have been added to the IPL device to permit synchronization between + the two simulator processes running the HP 2000 Time-Shared BASIC operating + system. This greatly improves system startup reliability and permits the use + of the HP-documented startup procedure of cross-loading the I/O Processor + program from the System Processor. + + - The DIAGNOSTIC options of the IPLI and IPLO devices have been reworked to + permit testing with the HP General Register Diagnostic as well as the + Processor Interconnect Cable Diagnostic. + + - The DEBUG options of the IPLI and IPLO devices have been expanded. + + - The BOOT command now installs the correct binary loader for the CPU model. + For example, BOOT PTR installs and runs the Basic Binary Loader (BBL) if the + CPU is configured as a 2114/15/16 or 2100, or the 12992K Paper Tape Loader + ROM if the CPU is configured as a 1000 M/E/F-Series. Prior releases + installed the HP 1000 loader ROM regardless of the CPU model. + + - The LOAD command has been extended to permit copying of internal device boot + loaders into memory. LOAD is identical to BOOT except that the + CPU is neither preset nor run. In particular, LOAD CPU is the equivalent of + pressing the IBL button on the HP 1000 front panel. + + - The new SET CPU ROMS command permits altering the set of preinstalled boot + loader ROMs for 1000 CPUs. The new SHOW CPU ROMS command displays the + currently installed set. + + - The -N (new file) option to the ATTACH command for disc devices now creates a + full-size image file, equivalent to formatting the new disc before use. + + +-------------------- +Implementation Notes +-------------------- + + - The abbreviated "SET CPU 21MX" command no longer sets the CPU to an E-Series + model (i.e., to a 21MX-E, a.k.a. 1000-E); instead, it configures the CPU as + an original 21MX (a.k.a. 1000-M). If an E-Series configuration is desired, + it must be requested explicitly with the "SET CPU 21MX-E" command. + + - The "RESET -P CPU" command no longer restores the BBL to the protected memory + area of 21xx machines. The "LOAD PTR" command may be used to perform this + function. + + - The previous behavior of the "ATTACH -N" command for disc devices, i.e., + creating a new zero-length image file, may be emulated by first deleting the + file and then attaching it without specifying the -N switch. For instance, + the "DELETE " and "ATTACH " commands produce a new + zero-length file as "ATTACH -N " did before this change. The + "ATTACH -N" behavior of other devices, e.g., magnetic tape drives and + printers, did not change; a zero-length file is still created. + + - With the change to a shared-memory implementation, only a single "ATTACH IPL" + command is required per instance to establish communication. The System + Processor instance issues an "ATTACH -S IPL " command, and the I/O + Processor instance must issue a corresponding "ATTACH -I IPL " command, + where the parameter is a user-selected decimal number that identifies + the instance pair. The prior "ATTACH [-L | -C] [ IPLI | IPLO ] " + commands are deprecated but retained, so that existing command files will + still work. However, they too will use shared memory rather than network + connections. Consequently, the SP and IOP instances are now required to + execute on the same machine, and the option is no longer + supported. + + - Multiple consecutive CLC 0 instruction executions now cause only a single CRS + assertion to the I/O devices. Therefore, IOBUS tracing when running HP 2000 + Time-Shared BASIC systems no longer generates a pair of trace lines for each + of the 131,072 consecutive CLC 0 executions typically used to initialize the + 12920A Asynchronous Multiplexer. + + - The 12875A Processor Interconnect section of the HP2100 User's Guide has been + revised to describe the new ATTACH protocol and process synchronization + commands. + + - A list of device boot loaders installed for given device/CPU combinations has + been added to the user's guide. + + - The "21MX-M" and "21MX-E" CPU options that had been inadvertently omitted + from the last release of the user's guide have been restored. + + - The "Running HP 2000 Time-Shared BASIC on SIMH" monograph has been revised to + cover the application of the new process synchronization commands to TSB + startup command files. + + - Preconfigured software kits for 2000E, 2000F, and 2000 Access that employ + the new shared memory and process synchronization commands are now available; + see the "Available Software" section above for details. + + +---------- +Bugs Fixed +---------- + + 1. PROBLEM: Serial port output stalls are not handled properly. + + VERSION: Release 27. + + OBSERVATION: The TTY, BACI, MPX, and MUX devices support I/O via host + serial ports as well as via Telnet connections. While TTY, BACI, and MPX + output via Telnet works correctly, output via serial ports fails. TTY + output drops characters if the serial port stalls. Attempting to output to + the BACI results in "Console Telnet output stall" and a simulator stop. + Output to the MPX results in dropped characters and eventually an "IOPE" + (parity error) message from RTE. + + CAUSE: The terminal multiplexer library (sim_tmxr.c, part of the SIMH + framework) had provided a 256-byte output buffer for each line, independent + of the connection type (Telnet or serial). The library was changed to + reduce the serial buffer size to one byte. The BACI and MPX devices are + internally buffered and default to a "FASTTIME" mode that sends the entire + internal buffer to the library output routine. When the routine receives + the second character, it returns SCPE_STALL status to indicate a buffer + overflow. The device simulations did not expect and did not properly + handle this status. + + The TTY and MUX devices are not buffered internally and were not affected + by the loss of serial buffering. However, the TTY would drop output + characters if the host serial buffer overflowed. + + RESOLUTION: Modify "tto_svc" (hp2100_stddev.c), "baci_term_svc" + (hp2100_baci.c), and "line_service" (hp2100_mpx.c) to handle terminal + multiplexer library buffer overflows properly. + + STATUS: Fixed in Release 28. + + + 2. PROBLEM: The PTR device DIAGNOSTIC option shown in the user's guide does + not exist. + + VERSION: Release 27. + + OBSERVATION: The "HP2100 Simulator User's Guide" says that specifying the + DIAGNOSTIC option for the PTR device "converts the attached paper tape + image into a continuous loop" for use by the paper tape reader diagnostic + program. However, entering a "SET PTR DIAGNOSTIC" command gives a + "Non-existent parameter" error. + + CAUSE: The option name specified in the PTR device's modifier table is + "DIAG". It should be "DIAGNOSTIC" to match the option names used in the + other device simulations. + + RESOLUTION: Modify "ptr_mod" (hp_stddev.c) to use the correct option name. + + STATUS: Fixed in Release 28. + + + 3. PROBLEM: First Status is not cleared properly on the DP device. + + VERSION: Release 27. + + OBSERVATION: Execution of the RTE-I paper tape bootstrap for the 7900A and + the 2000F loader for the 7900A halts with disc errors. The offending disc + status word is 040001 octal, which denotes First Status and Any Error. + Both programs expect disc status to be clear after an initial Seek and Read + are performed. However, the disc drive and interface manuals state that + First Status is cleared by a Status Check command, which is not being + issued. + + CAUSE: Examination of the schematics in the 7900A Disc Drive Operating and + Service Manual (07900-90002 February 1975) and the 13210A Disc Drive + Interface Kit Operating and Service Manual (13210-90003 November 1974) + shows that, contrary to the documentation, First Status is cleared on a + Read, Write, Check Data, or Initialize command, as well as on a Status + Check command. The current DP implementation follows the manual + description rather than the schematics, so it fails to clear First Status + when the initial Read is performed. + + RESOLUTION: Modify "dp_goc" (hp2100_dp.c) to clear First Status as well as + Attention when one of the applicable commands is performed. + + STATUS: Fixed in Release 28. + + + 4. PROBLEM: 2000F and Access will not boot from a 7900 drive using the BMDL. + + VERSION: Release 27. + + OBSERVATION: Attempting to boot Time-Shared BASIC from a 7900 using the + Basic Moving-Head Disc Loader for the HP 2100 CPU results in a HLT 1 + (unrecoverable disc error) in the TSB loader. Booting the same system with + the 12992A loader ROM for the HP 1000 succeeds. + + The BMDL configures DMA for an oversize (~32000 word) transfer and expects + the disc to terminate the operation with End of Cylinder (EOC) status. The + TSB bootstrap successfully loads into memory. When it starts, it issues a + CLC 0,C followed by a Check Status command that is expected to return zero, + i.e., all status bits clear. However, the EOC bit is set, and the + bootstrap halts with a HLT 1. + + CAUSE: The "Disc Interface 1 PCA Schematic Diagram" in the HP 13210A Disc + Drive Interface Kit Operating and Service Manual (13210-90003, August 1974) + shows that the CRS signal, which is generated by the CLC 0 instruction, + does not affect the Status Register contents. However, examination of an + actual hardware interface PCA shows that CRS assertion does clear the + register. + + RESOLUTION: Modify "dpcio" (hp2100_dp.c) to clear the status register on + receipt of a CRS signal. Note that later versions of the service manual + (May 1975 and May 1978) show the correct CRS connection. + + STATUS: Fixed in Release 28. + + + 5. PROBLEM: Forcibly disconnected 2000E multiplexer ports are unresponsive. + + VERSION: Release 27. + + OBSERVATION: The HP Time-Shared BASIC system sets a limit on the time + allowed between dataset connection and login. By default, this is 120 + seconds but may be changed by the PHONES system operator command. If the + user does not complete a login within the time allowed, the dataset will be + disconnected. + + This action occurs as expected on the 2000E system, but while reconnecting + to the port succeeds, the line is unresponsive. More importantly, + attempting to SLEEP the system hangs after responding to the "MAG TAPE + SLEEP?" question. + + CAUSE: Examining the source code where the SLEEP hang occurs shows that + the system is waiting in a loop for output to complete on the disconnected + port. The forced disconnect code, which is shared by the PHONES, KILLID, + and SLEEP commands, calls the BYE processor to log out an active user. + However, for a PHONES disconnect, the user is not logged in. The BYE + processor handles this condition correctly, but it returns to a common + routine (LLEND) that outputs a line feed to the port. The multiplexer + simulation omits a write to a disconnected port but also erroneously omits + the output completion interrupt request. Consequently, TSB believes that + the output is still in progress and therefore waits, in an infinite loop, + for the completion interrupt that never occurs. Also, while the port is in + output mode, input is turned off, so the port appears to be unresponsive + when reconnected. + + RESOLUTION: Modify "muxo_svc" (hp2100_mux.c) to set "mux_xdon" to 1 to + trigger the completion interrupt regardless of whether or not the port is + connected to a Telnet session. + + STATUS: Fixed in Release 28. + + + ====================== Release 27, 2017-09-06 ====================== diff --git a/HP2100/hp2100_stddev.c b/HP2100/hp2100_stddev.c index 62439bfd..8d0f977c 100644 --- a/HP2100/hp2100_stddev.c +++ b/HP2100/hp2100_stddev.c @@ -1,7 +1,7 @@ /* hp2100_stddev.c: HP2100 standard devices simulator Copyright (c) 1993-2016, Robert M. Supnik - Copyright (c) 2017 J. David Bryan + Copyright (c) 2017-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,6 +29,9 @@ TTY 12531C buffered teleprinter interface TBG 12539C time base generator + 27-Feb-18 JDB Added the BBL + 22-Nov-17 JDB Fixed TTY serial output buffer overflow handling + 18-Sep-17 JDB Changed PTR "DIAG" modifier to "DIAGNOSTIC" 03-Aug-17 JDB PTP and TTY now append to existing file data 18-Jul-17 JDB The PTR device now handles the IOERR simulation stop 11-Jul-17 JDB Renamed "ibl_copy" to "cpu_ibl" @@ -370,7 +373,7 @@ REG ptr_reg[] = { }; MTAB ptr_mod[] = { - { UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAG", NULL }, + { UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAGNOSTIC", NULL }, { UNIT_DIAG, 0, "reader mode", "READER", NULL }, { MTAB_XTD | MTAB_VDV, 1u, "SC", "SC", &hp_set_dib, &hp_show_dib, (void *) &ptr_dib }, { MTAB_XTD | MTAB_VDV | MTAB_NMO, ~1u, "DEVNO", "DEVNO", &hp_set_dib, &hp_show_dib, (void *) &ptr_dib }, @@ -710,69 +713,223 @@ return SCPE_OK; } -/* Paper tape reader bootstrap routine (HP 12992K ROM) */ +/* Paper tape reader bootstrap loaders (BBL and 12992K). -const BOOT_ROM ptr_rom = { - 0107700, /*ST CLC 0,C ; intr off */ - 0002401, /* CLA,RSS ; skip in */ - 0063756, /*CN LDA M11 ; feed frame */ - 0006700, /* CLB,CCE ; set E to rd byte */ - 0017742, /* JSB READ ; get #char */ - 0007306, /* CMB,CCE,INB,SZB ; 2's comp */ - 0027713, /* JMP *+5 ; non-zero byte */ - 0002006, /* INA,SZA ; feed frame ctr */ - 0027703, /* JMP *-3 */ - 0102077, /* HLT 77B ; stop */ - 0027700, /* JMP ST ; next */ - 0077754, /* STA WC ; word in rec */ - 0017742, /* JSB READ ; get feed frame */ - 0017742, /* JSB READ ; get address */ - 0074000, /* STB 0 ; init csum */ - 0077755, /* STB AD ; save addr */ - 0067755, /*CK LDB AD ; check addr */ - 0047777, /* ADB MAXAD ; below loader */ - 0002040, /* SEZ ; E =0 => OK */ - 0027740, /* JMP H55 */ - 0017742, /* JSB READ ; get word */ - 0040001, /* ADA 1 ; cont checksum */ - 0177755, /* STA AD,I ; store word */ - 0037755, /* ISZ AD */ - 0000040, /* CLE ; force wd read */ - 0037754, /* ISZ WC ; block done? */ - 0027720, /* JMP CK ; no */ - 0017742, /* JSB READ ; get checksum */ - 0054000, /* CPB 0 ; ok? */ - 0027702, /* JMP CN ; next block */ - 0102011, /* HLT 11 ; bad csum */ - 0027700, /* JMP ST ; next */ - 0102055, /*H55 HALT 55 ; bad address */ - 0027700, /* JMP ST ; next */ - 0000000, /*RD 0 */ - 0006600, /* CLB,CME ; E reg byte ptr */ - 0103710, /* STC RDR,C ; start reader */ - 0102310, /* SFS RDR ; wait */ - 0027745, /* JMP *-1 */ - 0106410, /* MIB RDR ; get byte */ - 0002041, /* SEZ,RSS ; E set? */ - 0127742, /* JMP RD,I ; no, done */ - 0005767, /* BLF,CLE,BLF ; shift byte */ - 0027744, /* JMP RD+2 ; again */ - 0000000, /*WC 000000 ; word count */ - 0000000, /*AD 000000 ; address */ - 0177765, /*M11 -11 ; feed count */ - 0, 0, 0, 0, 0, 0, 0, 0, /* unused */ - 0, 0, 0, 0, 0, 0, 0, /* unused */ - 0000000 /*MAXAD -ST ; max addr */ + The Basic Binary Loader (BBL) performs three functions, depending on the + setting of the S register, as follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | C | - - - - - - - - - - - - - - | V | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + Where: + + C = Compare the paper tape to memory + V = Verify checksums on the paper tape + + If bit 15 is set to 1, the loader will compare the absolute program on tape + to the contents of memory. If bit 0 is set to 1, the loader will verify the + checksums of the absolute binary records on tape without altering memory. If + neither bit is set, the loader will read the absolute program on the paper + tape into memory. Loader execution ends with one of the following halt + instructions: + + * HLT 00 - a comparison error occurred; A = the tape value. + * HLT 11 - a checksum error occurred; A/B = the tape/calculated value. + * HLT 55 - the program load address would overlay the loader. + * HLT 77 - the end of tape was reached with a successful read. + + The 12992K boot loader ROM reads an absolute program on the paper tape into + memory. The S register setting does not affect loader operation. Loader + execution ends with one of the following halt instructions: + + * HLT 11 - a checksum error occurred; A/B = the calculated/tape value. + * HLT 55 - the program load address would overlay the ROM loader. + * HLT 77 - the end of tape was reached with a successful read. + + Note that the A/B register contents are in the opposite order of those in the + BBL when a checksum error occurs. +*/ + +static const LOADER_ARRAY ptr_loaders = { + { /* HP 21xx Basic Binary Loader (BBL) */ + 000, /* loader starting index */ + IBL_NA, /* DMA index (not used) */ + 072, /* FWA index */ + { 0107700, /* 77700: START CLC 0,C */ + 0063770, /* 77701: LDA 77770 */ + 0106501, /* 77702: LIB 1 */ + 0004010, /* 77703: SLB */ + 0002400, /* 77704: CLA */ + 0006020, /* 77705: SSB */ + 0063771, /* 77706: LDA 77771 */ + 0073736, /* 77707: STA 77736 */ + 0006401, /* 77710: CLB,RSS */ + 0067773, /* 77711: LDB 77773 */ + 0006006, /* 77712: INB,SZB */ + 0027717, /* 77713: JMP 77717 */ + 0107700, /* 77714: CLC 0,C */ + 0102077, /* 77715: HLT 77 */ + 0027700, /* 77716: JMP 77700 */ + 0017762, /* 77717: JSB 77762 */ + 0002003, /* 77720: SZA,RSS */ + 0027712, /* 77721: JMP 77712 */ + 0003104, /* 77722: CMA,CLE,INA */ + 0073774, /* 77723: STA 77774 */ + 0017762, /* 77724: JSB 77762 */ + 0017753, /* 77725: JSB 77753 */ + 0070001, /* 77726: STA 1 */ + 0073775, /* 77727: STA 77775 */ + 0063775, /* 77730: LDA 77775 */ + 0043772, /* 77731: ADA 77772 */ + 0002040, /* 77732: SEZ */ + 0027751, /* 77733: JMP 77751 */ + 0017753, /* 77734: JSB 77753 */ + 0044000, /* 77735: ADB 0 */ + 0000000, /* 77736: NOP */ + 0002101, /* 77737: CLE,RSS */ + 0102000, /* 77740: HLT 0 */ + 0037775, /* 77741: ISZ 77775 */ + 0037774, /* 77742: ISZ 77774 */ + 0027730, /* 77743: JMP 77730 */ + 0017753, /* 77744: JSB 77753 */ + 0054000, /* 77745: CPB 0 */ + 0027711, /* 77746: JMP 77711 */ + 0102011, /* 77747: HLT 11 */ + 0027700, /* 77750: JMP 77700 */ + 0102055, /* 77751: HLT 55 */ + 0027700, /* 77752: JMP 77700 */ + 0000000, /* 77753: NOP */ + 0017762, /* 77754: JSB 77762 */ + 0001727, /* 77755: ALF,ALF */ + 0073776, /* 77756: STA 77776 */ + 0017762, /* 77757: JSB 77762 */ + 0033776, /* 77760: IOR 77776 */ + 0127753, /* 77761: JMP 77753,I */ + 0000000, /* 77762: NOP */ + 0103710, /* 77763: STC 10,C */ + 0102310, /* 77764: SFS 10 */ + 0027764, /* 77765: JMP 77764 */ + 0102510, /* 77766: LIA 10 */ + 0127762, /* 77767: JMP 77762,I */ + 0173775, /* 77770: STA 77775,I */ + 0153775, /* 77771: CPA 77775,I */ + 0100100, /* 77772: RRL 16 */ + 0177765, /* 77773: STB 77765,I */ + 0000000, /* 77774: NOP */ + 0000000, /* 77775: NOP */ + 0000000, /* 77776: NOP */ + 0000000 } }, /* 77777: NOP */ + + { /* HP 1000 Loader ROM (12992K) */ + IBL_START, /* loader starting index */ + IBL_DMA, /* DMA index */ + IBL_FWA, /* FWA index */ + { 0107700, /* 77700: ST CLC 0,C ; intr off */ + 0002401, /* 77701: CLA,RSS ; skip in */ + 0063756, /* 77702: CN LDA M11 ; feed frame */ + 0006700, /* 77703: CLB,CCE ; set E to rd byte */ + 0017742, /* 77704: JSB READ ; get #char */ + 0007306, /* 77705: CMB,CCE,INB,SZB ; 2's comp */ + 0027713, /* 77706: JMP *+5 ; non-zero byte */ + 0002006, /* 77707: INA,SZA ; feed frame ctr */ + 0027703, /* 77710: JMP *-3 */ + 0102077, /* 77711: HLT 77B ; stop */ + 0027700, /* 77712: JMP ST ; next */ + 0077754, /* 77713: STA WC ; word in rec */ + 0017742, /* 77714: JSB READ ; get feed frame */ + 0017742, /* 77715: JSB READ ; get address */ + 0074000, /* 77716: STB 0 ; init csum */ + 0077755, /* 77717: STB AD ; save addr */ + 0067755, /* 77720: CK LDB AD ; check addr */ + 0047777, /* 77721: ADB MAXAD ; below loader */ + 0002040, /* 77722: SEZ ; E =0 => OK */ + 0027740, /* 77723: JMP H55 */ + 0017742, /* 77724: JSB READ ; get word */ + 0040001, /* 77725: ADA 1 ; cont checksum */ + 0177755, /* 77726: STA AD,I ; store word */ + 0037755, /* 77727: ISZ AD */ + 0000040, /* 77730: CLE ; force wd read */ + 0037754, /* 77731: ISZ WC ; block done? */ + 0027720, /* 77732: JMP CK ; no */ + 0017742, /* 77733: JSB READ ; get checksum */ + 0054000, /* 77734: CPB 0 ; ok? */ + 0027702, /* 77735: JMP CN ; next block */ + 0102011, /* 77736: HLT 11 ; bad csum */ + 0027700, /* 77737: JMP ST ; next */ + 0102055, /* 77740: H55 HLT 55 ; bad address */ + 0027700, /* 77741: JMP ST ; next */ + 0000000, /* 77742: RD NOP */ + 0006600, /* 77743: CLB,CME ; E reg byte ptr */ + 0103710, /* 77744: STC RDR,C ; start reader */ + 0102310, /* 77745: SFS RDR ; wait */ + 0027745, /* 77746: JMP *-1 */ + 0106410, /* 77747: MIB RDR ; get byte */ + 0002041, /* 77750: SEZ,RSS ; E set? */ + 0127742, /* 77751: JMP RD,I ; no, done */ + 0005767, /* 77752: BLF,CLE,BLF ; shift byte */ + 0027744, /* 77753: JMP RD+2 ; again */ + 0000000, /* 77754: WC 000000 ; word count */ + 0000000, /* 77755: AD 000000 ; address */ + 0177765, /* 77756: M11 DEC -11 ; feed count */ + 0000000, /* 77757: NOP */ + 0000000, /* 77760: NOP */ + 0000000, /* 77761: NOP */ + 0000000, /* 77762: NOP */ + 0000000, /* 77763: NOP */ + 0000000, /* 77764: NOP */ + 0000000, /* 77765: NOP */ + 0000000, /* 77766: NOP */ + 0000000, /* 77767: NOP */ + 0000000, /* 77770: NOP */ + 0000000, /* 77771: NOP */ + 0000000, /* 77772: NOP */ + 0000000, /* 77773: NOP */ + 0000000, /* 77774: NOP */ + 0000000, /* 77775: NOP */ + 0000000, /* 77776: NOP */ + 0100100 } } /* 77777: MAXAD ABS -ST ; max addr */ }; + +/* Device boot routine. + + This routine is called directly by the BOOT PTR and LOAD PTR commands to copy + the device bootstrap into the upper 64 words of the logical address space. + It is also called indirectly by a BOOT CPU or LOAD CPU command when the + specified HP 1000 loader ROM socket contains a 12992K ROM. + + When called in response to a BOOT DPC or LOAD DPC command, the "unitno" + parameter indicates the unit number specified in the BOOT command or is zero + for the LOAD command, and "dptr" points at the PTR device structure. + Depending on the current CPU model, the BBL or 12992K loader ROM will be + copied into memory and configured for the PTR select code. If the CPU is a + 1000, the S register will be set as it would be by the front-panel microcode. + + When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the + select code to be used for configuration, and "dptr" will be NULL. As above, + the BBL or 12992K loader ROM will be copied into memory and configured for + the specified select code. The S register is assumed to be set correctly on + entry and is not modified. + + For the 12992K boot loader ROM, the S register will be set as follows: + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | ROM # | 0 0 | PTR select code | 0 0 0 0 0 0 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +*/ + t_stat ptr_boot (int32 unitno, DEVICE *dptr) { -const int32 dev = ptr_dib.select_code; /* get device no */ +if (dptr == NULL) /* if we are being called for a BOOT/LOAD CPU */ + return cpu_copy_loader (ptr_loaders, unitno, /* then copy the boot loader to memory */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* but do not alter the S register */ -cpu_ibl (ptr_rom, dev, IBL_S_CLR, /* copy the boot ROM to memory and configure */ - IBL_PTR | IBL_SET_SC (dev)); /* the S register accordingly */ - -return SCPE_OK; +else /* otherwise this is a BOOT/LOAD PTR */ + return cpu_copy_loader (ptr_loaders, ptr_dib.select_code, /* so copy the boot loader to memory */ + IBL_S_CLEAR, IBL_S_NOSET); /* and configure the S register if 1000 CPU */ } @@ -1132,23 +1289,23 @@ return SCPE_OK; t_stat tto_svc (UNIT *uptr) { -int32 c; t_stat r; -c = tty_buf; /* get char */ -tty_buf = tty_shin; /* shift in */ -tty_shin = 0377; /* line inactive */ +r = tto_out (tty_buf); /* output the character */ -r = tto_out (c); /* output the character */ +if (r == SCPE_OK) { /* if the output succeeded */ + tty_buf = tty_shin; /* then shift the input line into the buffer */ + tty_shin = 0377; /* and set the input line to the marking state */ -if (r != SCPE_OK) { /* if an error occurred */ - sim_activate (uptr, uptr->wait); /* then schedule a retry */ - return (r == SCPE_STALL ? SCPE_OK : r); /* report a stall as success */ + ttyio (&tty_dib, ioENF, 0); /* set the flag */ + return SCPE_OK; /* and return success */ } -ttyio (&tty_dib, ioENF, 0); /* set flag */ +else { /* otherwise an error occurred */ + sim_activate (uptr, uptr->wait); /* so schedule a retry */ -return SCPE_OK; + return (r == SCPE_STALL ? SCPE_OK : r); /* report a stall as success */ + } } diff --git a/HP2100/hp2100_sys.c b/HP2100/hp2100_sys.c index e18c0d88..18cb772a 100644 --- a/HP2100/hp2100_sys.c +++ b/HP2100/hp2100_sys.c @@ -1,7 +1,7 @@ /* hp2100_sys.c: HP 2100 system common interface Copyright (c) 1993-2016, Robert M. Supnik - Copyright (c) 2017, J. David Bryan + Copyright (c) 2017-2018, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,9 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. + 07-Mar-18 JDB Added the GET_SWITCHES macro from scp.c + 22-Feb-18 JDB Added the option to the LOAD command + 07-Sep-17 JDB Replaced "uint16" cast with "MEMORY_WORD" for loader ROM 07-Aug-17 JDB Added "hp_attach" to attach a file for appending 01-Aug-17 JDB Added "ispunct" test for implied mnemonic parse 20-Jul-17 JDB Removed STOP_OFFLINE, STOP_PWROFF messages @@ -108,6 +111,12 @@ +/* Command-line switch parsing from scp.c */ + +#define GET_SWITCHES(cp) \ + if ((cp = get_sim_sw (cp)) == NULL) return SCPE_INVSW + + /* External I/O data structures */ extern DEVICE mp_dev; /* Memory Protect */ @@ -754,31 +763,31 @@ static const OP_DESC iog_desc = { /* Input/Output Group descriptor static const OP_TABLE iog_ops = { /* IOG opcodes, indexed by IR bits 11 + 8-6 */ { "HLT", 0102000u, opSCOHC }, - { "", 0102100u, opNone }, /* STF/CLF and STO/CLO */ - { "", 0102200u, opNone }, /* SFC and SOC */ - { "", 0102300u, opNone }, /* SFS and SOS */ + { "", 0102100u, opNone }, /* STF/CLF and STO/CLO */ + { "", 0102200u, opNone }, /* SFC and SOC */ + { "", 0102300u, opNone }, /* SFS and SOS */ { "MIA", 0102400u, opSCHC }, { "LIA", 0102500u, opSCHC }, { "OTA", 0102600u, opSCHC }, { "STC", 0102700u, opSCHC }, { "HLT", 0106000u, opSCOHC }, - { "", 0106100u, opNone }, /* STF/CLF and STO/CLO */ - { "", 0106200u, opNone }, /* SFC and SOC */ - { "", 0106300u, opNone }, /* SFS and SOS */ + { "", 0106100u, opNone }, /* STF/CLF and STO/CLO */ + { "", 0106200u, opNone }, /* SFC and SOC */ + { "", 0106300u, opNone }, /* SFS and SOS */ { "MIB", 0106400u, opSCHC }, { "LIB", 0106500u, opSCHC }, { "OTB", 0106600u, opSCHC }, { "CLC", 0106700u, opSCHC }, - { "STO", 0102101u, opNone, 0173777u }, /* STF 01 */ - { "STF", 0102100u, opSC, 0173700u }, /* STF nn */ - { "CLO", 0103101u, opNone, 0173777u }, /* CLF 01 */ - { "CLF", 0103100u, opSC, 0173700u }, /* CLF nn */ - { "SOC", 0102201u, opHC, 0172777u }, /* SFC 01 */ - { "SFC", 0102200u, opSCHC, 0172700u }, /* SFC nn */ - { "SOS", 0102301u, opHC, 0172777u }, /* SFS 01 */ - { "SFS", 0102300u, opSCHC, 0172700u }, /* SFS nn */ + { "STO", 0102101u, opNone, 0173777u }, /* STF 01 */ + { "STF", 0102100u, opSC, 0173700u }, /* STF nn */ + { "CLO", 0103101u, opNone, 0173777u }, /* CLF 01 */ + { "CLF", 0103100u, opSC, 0173700u }, /* CLF nn */ + { "SOC", 0102201u, opHC, 0172777u }, /* SFC 01 */ + { "SFC", 0102200u, opSCHC, 0172700u }, /* SFC nn */ + { "SOS", 0102301u, opHC, 0172777u }, /* SFS 01 */ + { "SFS", 0102300u, opSCHC, 0172700u }, /* SFS nn */ { NULL } }; @@ -1807,6 +1816,7 @@ static t_addr parse_addr (DEVICE *dptr, CONST char *cptr, CONST char **tptr) static t_stat hp_exdep_cmd (int32 arg, CONST char *buf); static t_stat hp_run_cmd (int32 arg, CONST char *buf); static t_stat hp_brk_cmd (int32 arg, CONST char *buf); +static t_stat hp_load_cmd (int32 arg, CONST char *buf); /* System interface local utility routines */ @@ -1869,7 +1879,7 @@ void (*sim_vm_init) (void) = &one_time_init; /* a pointer to the one-time ini DEVICE *sim_devices [] = { /* an array of pointers to the simulated devices */ &cpu_dev, /* CPU (must be first) */ &mp_dev, /* Memory Protect */ - &dma1_dev, &dma2_dev, /* DMA/DCPC */ + &dma1_dev, &dma2_dev, /* DMA/DCPC */ &ptr_dev, /* 2748 Paper Tape Reader */ &ptp_dev, /* 2895 Paper Tape Punch */ &tty_dev, /* 2752 Teleprinter */ @@ -1953,6 +1963,8 @@ static CTAB aux_cmds [] = { { "BREAK", &hp_brk_cmd, 0, NULL }, { "NOBREAK", &hp_brk_cmd, 0, NULL }, + { "LOAD", &hp_load_cmd, 0, NULL }, + { NULL } }; @@ -2038,19 +2050,22 @@ static CTAB aux_cmds [] = { t_stat sim_load (FILE *fptr, CONST char *cptr, CONST char *fnam, int flag) { -const int reclen [2] = { TO_WORD (57, 0), /* the two DUMP record length words */ - TO_WORD (7, 0) }; -const int reccnt [2] = { 57, 7 }; /* the two DUMP record word counts */ -BOOT_ROM loader; /* an array of 64 words */ -int record, count, address, word, checksum; -t_stat result; -int32 trailer = 1; /* > 0 while reading leader, < 0 while reading trailer */ -HP_WORD select_code = 0; /* select code to configure; 0 implies no configuration */ +const int reclen [2] = { TO_WORD (57, 0), /* the two DUMP record length words */ + TO_WORD (7, 0) }; +const int reccnt [2] = { 57, 7 }; /* the two DUMP record word counts */ +int record, count, address, word, checksum; +t_stat result; +int32 trailer = 1; /* > 0 while reading leader, < 0 while reading trailer */ +HP_WORD select_code = 0; /* select code to configure; 0 implies no configuration */ +LOADER_ARRAY boot = { /* an array of two BOOT_LOADER structures */ + { 000, IBL_NA, IBL_NA, { 0 } }, /* HP 21xx Loader */ + { IBL_START, IBL_DMA, IBL_FWA, { 0 } } /* HP 1000 Loader */ + }; if (flag == 0) { /* if this is a LOAD command */ if (*cptr != '\0') { /* then if a parameter follows */ - select_code = (HP_WORD) get_uint (cptr, 8, /* then parse it as an octal number */ - MAXDEV, &result); + select_code = /* then parse it as an octal number */ + (HP_WORD) get_uint (cptr, 8, MAXDEV, &result); if (result != SCPE_OK) /* if a parse error occurred */ return result; /* then report it */ @@ -2059,8 +2074,6 @@ if (flag == 0) { /* if this is a LOAD com return SCPE_ARG; /* then report a bad argument */ } - memset (loader, 0, sizeof loader); /* clear the boot loader ROM */ - while (TRUE) { /* read absolute binary records from the file */ do { /* skip any blank leader or trailer present */ count = fgetc (fptr); /* get the next byte from the tape */ @@ -2102,9 +2115,10 @@ if (flag == 0) { /* if this is a LOAD com if (word == EOF) /* if the word is not present */ return SCPE_FMT; /* then the tape format is bad */ - else { /* otherwise */ - loader [address++] = (uint16) word; /* save the data word in the loader array */ - checksum = checksum + word; /* and include it in the record checksum */ + else { /* otherwise */ + boot [0].loader [address] = (MEMORY_WORD) word; /* save the data word in */ + boot [1].loader [address++] = (MEMORY_WORD) word; /* both loader arrays */ + checksum = checksum + word; /* and include it in the record checksum */ } } @@ -2121,8 +2135,8 @@ if (flag == 0) { /* if this is a LOAD com trailer = -10; /* so prepare for a potential trailer */ } /* and loop until all records are read */ - cpu_ibl (loader, select_code, /* install the loader */ - IBL_S_NOCLR, IBL_S_NOSET); /* and configure the select code if requested */ + cpu_copy_loader (boot, select_code, /* install the loader */ + IBL_S_NOCLEAR, IBL_S_NOSET); /* and configure the select code if requested */ } @@ -3249,7 +3263,7 @@ while ((bitfmt.alternate || bitset) /* while more bits */ bnptr = bitfmt.names [index]; /* point at the name for the current bit */ if (bnptr) /* if the name is defined */ - if (*bnptr == '\1') /* then if this name has an alternate */ + if (*bnptr == '\1' && bitfmt.alternate) /* then if this name has an alternate */ if (bitset & test_bit) /* then if the bit is asserted */ bnptr++; /* then point at the name for the "1" state */ else /* otherwise */ @@ -3854,6 +3868,62 @@ return brk_cmd (arg, buf); /* return the result of } +/* Execute the LOAD command. + + This command is intercepted to permit a device boot routine to be loaded + into memory. The following command forms are valid: + + LOAD + LOAD [ ] + + If the first form is used, and the device name is valid and bootable, the + corresponding boot loader is copied into memory in the highest 64 locations + of the logical address space. Upon return, the loader will have been + configured for the device's select code or for the device and paper tape + reader select codes, in the case of a dual-use 21xx boot loader, and the P + register will have been set to point at the start of the loader. The loader + then may be executed by a RUN command. If the device name is valid, but the + device is not bootable, or no boot loader exists for the current CPU + configuration, the command is rejected. + + If the second form is used, the file containing a loader in absolute binary + form is read into memory and configured as above. See the "sim_load" + comments for details of this operation. + + + Implementation notes: + + 1. The "find_dev" routine requires that the device name be in upper case to + match. The "get_glyph" routine performs case-shifting on the input + buffer. +*/ + +static t_stat hp_load_cmd (int32 arg, CONST char *buf) +{ +CONST char *cptr; +char cbuf [CBUFSIZE]; +DEVICE *dptr = NULL; + +GET_SWITCHES (buf); /* parse any switches present */ + +cptr = get_glyph (buf, cbuf, '\0'); /* parse a potential device name */ + +if (cbuf [0] != '\0') { /* if the name is present */ + dptr = find_dev (cbuf); /* then see if it matches a device */ + + if (dptr != NULL) /* if it does */ + if (dptr->boot == NULL) /* then if the device is not bootable */ + return SCPE_NOFNC; /* then report "Command not allowed" */ + else if (*cptr != '\0') /* otherwise if more characters follow */ + return SCPE_2MARG; /* then report "Too many arguments" */ + else /* otherwise the device name stands alone */ + return dptr->boot (0, dptr); /* so load the corresponding boot loader */ + } + +return load_cmd (arg, buf); /* if it's not a device name, then try loading a file */ +} + + /* System interface local utility routines */ diff --git a/doc/hp2100_doc.doc b/doc/hp2100_doc.doc index 183e31c03ec91e7acc04ffba7e74ca3bc226a0ca..89be1a56293a1a005f23248faa1515ff781f19ff 100644 GIT binary patch literal 666112 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℘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 z z%S?<(lb|pe3>uxoti9y_h+6NiVS^G`skbt}p&-Z{hvHBYs)5XPFy&%@eSZYO#F#V* z3X{R0xO2b~%+0vjtj(~ZcL4mu&i{1YO1yHFIV^RdG00q&=FlBvKFd%T38P^QjE7CI z8TP^NkaRkI2^56ta1s1j`#+3HRj#d@E;Fp0nqicEC;Oq+z+EWmq#czPx4Yann%p)S z^^;LQ8)a9c|4rf~?*kYv?~DoxMh{1WRZ=9!_1A zx-9j09B3Vu`kOCWZ|m^c7@EQWNQaRy3id(XGk6{llA#iu2B*Ur&q@8aB*@1yJ__<|siAco{~*XxIo_ zU}tsq>B6MoY`7BIz^72|BK8f=hR%=%FTrs58oq=47c-v^E`W>SGN=i4VGs<3a{Jw(n){pwNn3WQlbu(xV{XolH%6lA)hY7G3 zOiyZrsY!$UVL}sQ(j+KM2Byt0F$v~o+)M`lnEL<6@gM1rvsK=tllm@oy$}?J6sQPV z_od$d8_t5W;aZS(;LrO1jZCz5{b&)>^Ae8b)%cua)VW5T zZ&Y=oE)^wt%S!}Y-ffM~ZARU0R6C>YHtK#+lDE84z~$Y~_#Eop0WTQO7mZ3srG|Ak z2W2U3y0qu%>0TwtZCWv3}*Ug&&MBmu;bl#$O0h#j~=nZc{1Uu=b@EXj^@zH=d5rnBn%73K|yt@tm!m>k$noEIg$GRp5G>ZE%B~3SY^~VMy)mKJEML; zmCdbkH=SpEVY*c_7;Gj5{e{9@*C)6gIsEcOSN6{J`Yv-bM{@DL#wa%VIy*(ZL^X3C#-qHUVVU~bSFvhrLN9^@?$B4O=z4c;D zj1hkNzss(gaT-ZtGmFCYsK*qjS3WKI%1mYey?Tt6ynaTH0DbnPxU|EWmFa_o>-Esf z*m6zu73g(QKCXB4+UR`jY9QB0zjD2^4~AUIwGr%x-yrX0oFhUCl!n?6z6V5}|C=*o z%EU3e2z)@~`R~Z9!1b4R?cDpaPKHwpMM=xJ2*ZVbYJ66T3R~kZopr8jjn8w|SI+v{ zSueWQ_$9GqOD|)%EzOfqr#?}irM}O0EOmzRV- zEqtG066#WnQlHm+pYg`$9aLGl?#)VBFY%{Nnzdey80fz`$;24Z${(3GF-EjnrUwI` zCPu@vJvUqHj%K8vY00l1qqh6Z@m8drce!E6Rx*Y~YiN$Qr8Qpjmu+PX3sPikBfIt2 zjGmcdiN6+Cj$_P5jp*;M24-T6@PGeA?VPmE7Z*OeY+CZynLMqv^GGcZ{S4RS&vD6T z{8pJA%h98(n2b+pn_Yx0Yl)F zt9bSss=+7l1N;QVYI5%gj)IHf3P^(|U^I+}A7L|`b2aIq6FdY5AWtpE|KLU#TZenr z@G*Q2Uqi)fn9l&$!u4=jUDh3eXX>$T37k`(aJaouQqUfj!wNV6CpKn$unFxU^o4=& zI*f-8U>Sz``5(?yv!V0-pZe#q+*fgUG*q2aua0 zLHnX%TZ13mKVonX{~!4bw#(zfnp{4^)gp;xw6A^5AYXLMk1@d0B4dCu#;4%_aba9<43Wz zoL|G1vW~6)GAr^7$l&LDJ^gss&iCAL>rKrX+oM?e-_v=p&Gm5g_nl6YP^ZpTpQ^skWyYtW`ZV%=9ydNc)#oWO%4Vhfm#p;4#I*ND4D1@u zt*;jm+!*&v!n*lsGT7N}DYZ?`kRSc=&LcC1$%qdR&dL)ZIo_W3#kvjIUdFJT_W%0b zv`^9eWm_4;g2LIY*XF`3{$<{7{igD1#CAW%i1+-NAST9$r)PLMm>45Gr-aRHmvfcm zhgtD|NnZWU^)oH`no?@(XHL#3bURv}`YGE{TR*+y*L#|Y-$I^fD*9(_wDiZ{!Fu=} zrqb_DgSFBAcPM@9692?2{t4cIbguvo;kGRyH-At#TWf~;(^6~(-u820l?E*2xr2j9a+*aVwl z3v7cOuoHFz*Zx1QU-Q-SrHkjyp7HKmZ*cYBm%ji0yV~lipKc#xec;-)evi1$sP#r| zFlwVwn~d6Q)K;T*7`4l&y+-Xf>UU9L&wkKZmoaP{3A@}`6V_|kL}#6|LBq~<)+rmq zFrFOU`J=`jw@Izzowe1i5U@=wIiuK);m#pWGUq6jQDvn5=62ccrF{3nZ(#a~+!bcb z?jImx2mD`Y#peD=`+v05MN?krgOG=7p}deEO2aX59Hc^7C=V4tu9+&reefaV;hN|Q zkn5<Y`{TlYtz`oCR>wMSkt#4}9AY5`Q{O0a>ZLo%;*r}#Q zT`wxEV=bK3%UQj}3fJ`d94oTUSNK|)Fzg6wWhAVwY%mPF*@cDgAP#e$;A-zgv7|n| zh2i#Sl7u=n*{CT-O*3kSQSTe|iBX>#^|?{Yjru~A?BPlbw@+UgpH)V!Mjap4(F|q& z??K)HSlP3K_`>%JZFih~oV}6l)_IDzPHK^_adMr4mlv*Hq-wFs#VeLfEmf*?kz?{5 z_uKJ1%WN*U{)DvTy?OLJM?e2ROvV)x`(1*3S*_#oZ|&u7Oe_C@x;d_p2->k1G9F`j ztL91IIo#brO6(Z>et7boJX-f9f=488nOdFfS5Tqp9Zug<>)-kacv0sMK zkYJZ?t`N<2pb_TE?I-`YH^R6LYw7u!7?Z{bh^CS&y7Zez<@%O~; z+_ebuwN6@>e|ffY44iCyZ)o^mo?~) zkUlwH+3MKmM10_wek&KJ#SgEZ2vi8g6AJ3mP z^_}so{PKLSC(|Ab&-|N&{jrvU>&0fRj`nS{F#n4risDC;Lk=P1KT-&#`fZal56R=VxLP&7h^1LBySbuQX#F#Wj7`L&5y$zWdlg0?+<|Y5@%v>pHJ(^;rn&^rE2_KQgx*}M5&y+ICMG*+%y~tE!fZ4_5r5yjFY1nfGQt1c zN~5J@UV^mSmEcS`8+y`i_lmaP=g@v%441*(&;jm;2VopcfJra~=D>%LN*jLyNPFKO zq|JX1a3Nd)S3*N*1ah3Ufo||PJOMr7Ip_s)3?ATkE7FGfBybtj zgZrTuya^w`ckmOOa4XNFz$I`sw1PX~N$3Nw!dox{mfXhN2KW{7+|F|=a5EIUgZVBn z5MG1x?qvQ142S7ZsU5!~oCob;H|&KI+Y<*%;E1~zLj|7e+RH!rzp#^k5lccvMgFNB zY}*oK{D))4f6+|0G27Rh{ZW8*-(}iIhFKstO4&%c{8^or-#H(@VG8)a_vL8$%{zks zyH7ytZ@(T}fBy>nwo(SWH?R9<<>&I!w<#03`SbFC=bq~J&;z{s^Tul%)uHmZtCYGj zw_mPZ>S4IhCnVIVXVvF9-)Fq>37-y@d}jMT>x|ESQQ{+y^t#-`XKi)5!N}ZhUSQ6}GCkIBSHnMmp;zw}O64XPw}l z8>rx{RQHTm8D}k)8TjEgmWU;L{Sk)SYx}&`kLt6@_sMVitni6g$wwZBb@`lZe9jal zK2?05ixK6d&gMqBF7Xfh`0oh#uf)WkYt-LwdE&d}sAaym@Wo{^pZ|TxmO0m20d4jD z9!JB15?VK#N9(23$;V*`yb7~n5uAB9Yq!89&;`1}qc8$S!6Nt;zJm==xC840L3Owi zZiV}yC-jDKFawNHV{f8SfYm=q?2ZJ61v#|9z_y&75tbsEqXE`pG z_#LyE3T#Azj}9&IJ7$xC5lj4z*~Azz&~KLp_@ZxI;YV;4#W10)2G7}2w(F#}0eYsV z^)ItJne+L-k@iNnrJw$`G%P5t^*t-)eJ*8wA!vK>5Vp1l!?CqZSck3cK_Tk5wh0$t zOS|Bn|NC&(^hs~LKK$hu`aJc-BM;oyt_@2;hqHC0&pL<6@~&UIQD)9Nb*m`xY3utu zZG4_npI*MtBIEOs`h4vBY&SkT)n}LQbEdq{+wIR;qGW&0_Rm(r_kcT}OT;HU1Gv;# zeVx@$EXkoihD$R_LY;b3eJ1!mi;d6c>a)!E`PumFLY0;Jn;Ye6uGfs1=l8KD#)$rd zy=rG-jOgz_SZHF5NHn(v32ih7HUEb~&y`C{e!PIUozP569(7d4u$)}~>2|bb(NEcq z+WP6u2q>X-QTpgM;P=x{p|!7m13P1Xt^Moc^r_up6Z{0ye~yMFqrGn!|LkhXvx&L+ z{X))j^R^j$_}>uzHbYx_m|S?)M301w`Db>-1*P@;EVs*kU-TR*FXu&tA+vKS*Z%YT z_uJ!NANk5l&-Zzz$75aY<6QtZgrivYJGd6Gn#_!rR`LQ27urHXoob^#xB5QqjnDm} z!nU}RvlcjOp|hTd%)jPDpogJ?Lg)cX8G$GUqznM!HzC*TXQ}eom24r^2_m ziH|&p=0d+UK0k;OpN+oHe&bVEd#e<`w>niqU9MG8Wu=}bQdW0ShGsOz2(zq*5p%|Q zWoTlI=(9c{H_z$sGP8Zomr`uPiD}8NxwkRvITugkx)xc(a?W;L{&qAh*1kl~ zY75IXjg)P?Ynr{p{R&re4I|e#4dFV_>zo1D{&miB^a^;2>zk*cVi&G`pfXg43*l0@ z6Ljo{cYsZwG~xB(Ltp6g?2|GVAUpx|3)mgAXME=$!Dow-not$P`CM*%YKsc%Uma&{ zaMlmbddWS3@v>Nw>tGC*>mmtt>TC5`<@*%+-uEdjO7b}x!=)^1d`=P-?%m1Gdcawo z#gZHz#Be#hE1^y;R-Yxl&t~J3M_Mw;Ckex)JQ-0oJ7sU413g4fT*q5&CBB=vDC_5! zdVJB_cQe9|$hqx}l;^k|(7LX5QR-*Luvq=f{Ti0(pK^0ML?!*aeAEqTpZwvsU{ za>V7NKhW=_IqRptH4O_=WE|>A(Dqu|YHg$Mh_=)1_`DZhfFW?oLyQB$mCyn1hkoz^ zOoLgl9}Ys}uJjksAO7<&eE`&e$Kgp>1>eGm$GCqEv*1VA0(H7E-Uj!;Q}7%Nhf(kW zd<6R-`El;I!)0(kJO)8`#{8f$w1ZC28J56$X!r#0H-lNQ64t^xDBpv=3eJMFAsv2% zJ@9x>)`EcdU@q*1!B3GEw!uC){^_LPMVJVaVJ&zkk+fVvOj&EwS7@FT0~=uZ=L< z$-(u1#&6MRzl9hvQo}9C~K|zcVlb)?~AQ%z*KB) z2XCSs#@4Efgn_FDlF#Ku4^P@bg z!ZRi2MigBWT3n5t?X0R|&zHt$wfd~_ zefArlK%VE7v#UH9F85O<)TuMor;6`W!}we!D%|^;&Km5jA!5l^hGMvUKbKIazEq#D ze4pQqPd+*0m3;DxQBLY^R?5^|_AT&hvxza{`JQ@&^J!v?xFtOyx99yzA4!qzb2F_q z+9T@@WL7(~-~VUaif+x{iiZ8oZ9qz*^;G)j(eMVm4b#Aso)P92j5+l;Lv1Ezmj3wi z`Mxiv#}#G<@&w<_2;=5^{q=U{PlD(@r81289UJ7Ym?yl$#NOoSE>p(iOuwCfoM~9J z4=5&WaAswz=VEh+{}48Uo|kRM{sl^N?sYUA1GPcU*BU@mXaQ}Y9q2jSec1N{ZT^Ne zUoZP;-b`-$F!zs#z`5-c&i$*e`=_6-Z9DLl-_jj4D(~0PHZ329OOYa>PL(q1IHSrL zRZ&#f4p(wkGiO~Vmb9PEF zN*y-M=p@NU|KbZX`QAUP58?}x=GqRr5k8s5nw@8D?+x;|PP(Ar87TvcH9fM>NomPn zWU^LnqQBy-Oy0izc1it3^;1T2BJYv+&bD*qNR^{e{$xvXbSD1%$DSg3B)h#VoUv{0 zMEl$m^m@BDc3Xx8TGL!$?X#i zm)mONv&N`zjrz{0A4ExR8!=pN`;5qQOn z?7*anFHD-Teq&-{;%8uDyd8+P=6_bNa;bgLw%%_a)Yi|;-w8e|lXrr@T~gD?XZTkl zW8J)xdRh~%hK``)sok-AKt35e1szwt7hA?wyMVa_9KF~3)lAF?FCvI9Oq$V~y+kG^ zeg-DSq#3;}hq-ylBc?kZg2SZbqsMVc88gpGnJ=Q;bxeID_GZ`u^%+aoG4{K#?}d)= zKFE7tB5Qz2`#)r$wEvy%miE71P1jac`H~jQsec=Fwo&I8b%`ix`7Xt9>F+Z>9gXT_ zRA-~Qi;~=)z;L;}VSL^+YNAn-jG84%a+{6ea@%NpHW{_qsI5lr7bUsTPz)Q16?pqCEB9iLGNryt}_9#?;IB!lW6!%BylFCVmDc#-thT-<>ou zCQW?d?aX0b|D`@=R+i3wgXZuP$bGRC?t>M9PVfM{0dk-09hd=n zzic=59+3NH;TX_L83W?^&(R~oiC2OSDF2;Mr_K;1HQ`JQ z7kaMoxlmM?<3-Nu=&bvlwZ>U%oyFrjvhG5-O2ne2Zk33_a)hTyK$vfzmAZw#V#)sW z!*Kiau7o-@#i;2HYaQIgwY443{_Q?s@)MS(_R%+MlUq zV&Yd96JyfU`$J8#0lD0pX8oEub{-W=8#|A3*U^V-|6edCb=ll7HDZciiY6wdP5&r12VT^BWwkKj>8gvcmKkt`phjNBl=J9cEQ9L;W=gB z%*in_wBVLfY01@+^*GSawB-8X$g%8|hIwO!*}kW#$E1t{`FW=$_b8DuEGQ~{aaPJb zmANcsU=YYWmvoo_I^Sgtw$6FU&zzTJC<2$jrEnQEdzNzucog>U-oE*Vbzd)Ay6^*e z3FPQuLk9Ma3p=sCtGTyaW#F7SP78=r=v!aZ%|tdE`biCB`uQVh41?GozL ze)ajy_sJ{gL(V5fRJfHQ&br=NEu8h7vwAt}7p!tJUn$WtjbG%|bhUKKz>vpte>!)l-ZT*bR`qcZvIeFGl+Z+8Bx)o_} zGKK|(vr<=E^46>QR6QQVvm|xdIZSlbYD#M#jLo( z+{7|>nv5`Rer8#>-MOK*?q$qff6AKch-k^@+HtMB=^xh`7CYX85;8AQ+h}QQsjLn@pA7eY;V3I@O~C^Ud|A>br94I0C(&;dFM z&ohn)Ga(qrb3;%JE`clHYPbfPL35Z0lcC}Z%teH{&=6jNbeIXVU_LB>PvJB83ciLP zU?c2+eQ@+3<}$!>PzEZ%iEt96!S68bMc(TL%itgse2ICja0%Q5x5FdQ1Kx!Nz?{Q9 z+xf>s*_&d|c8m4Hy6|;h>%z}g-Ul7BkKic>lYt->Zl@lfD%VW6oXBnTWMxAR^HBplO0t}b_ zD&upFQ4Ni{R#bR)(9BsqBNp>0+i?b!Ds6Y7W&BP%S11|gf5cz9*FQ-QZfTjr47}vN zneF@PV+sr@oWIzTivHVk^&Uy$_hRRlmOfVcR(D^;wfV8OHYf8xGTYBszn@54-xe*K>Q+}{D|&)dS?^xqw#{dgYw=XYUBw4atf+TH(&-2dsl4%@T>ziR7N&{^+CELyj~T`AUcR()qRlPke+ zE#NyN7IVh0k?XB6=eo{XM5WdhcN=~4`@sTv!u5d*7iK3?!T?(5)BWD1k?CEU7pi=O!Gs#xuEt!u0e$klz*TI}yzEbO+t zYU^iOa%|ruO#Y&+R7#?CR?eyAJXy|#PliW9&WR5~zN}+C5)2pG)cD+_J}rHpM~u&t>eJKrdDr;NQlHtr&ril@ zxBBeyeSSAS`DGoyuxCkjR+WfFPu0?e&2-i*XUQskk+e0OHON^niWT;dA7Mp$$mVkJ zgkhCjuX&vdyT^q!BdmPZMKAtFH0fG(6km zCKng}@OW9BPe;b|(;qF@u;9#$w~F$wI7S+KMV5@!zk(~mJ4Bh~A6aEKG8%7InRWFx zCnJx#MeT+3Q@)Yf`Wd8TRyU_oKV{tF3s?zj;aAuPNiQ=t0%hT3s0J5+9n16Y#F-c) z=KIBJVvLyIQ-4!FO^gxq`y}SpF(J1Bo>yq*+7YI|y?=yhSoWVW(^A)CRX_c$Xjtr; zG$H?{mHJxkXgiLbr0( zGtPR}S=YD~U+X%nw_EYGkFy?kE53FYOZM;y47Z1aB-E*4>NDK;dC&NKs6O+2pEbtk z2ld(L`|L43$=Y8P5Tl&bbFJfAzqM{l8D9bQpw8f=;9BSc-QbL9*-z(lE-Zl`hb9Hv zL5>GG4&)fnve$B#GXD{NgS^9;V+57qO1KKn9zmM|7r+&871V_7kZ&Yw)xd+0@@i60 z6i$LWpbK<|@$e?hg&$!P9E7T)Slb^K!6&c-cEVmL_Znl?PzkPqhHyVT1e0MJ?1o?A z*3q2Lz<78IioMRe&7j{{#zJ8=Y=lj4#yHM}fRkYPw{KVYk0xvf|Mmr2ys=;&>EE?) zqk3#PurG-Gr&gGOB#Znb=~{yL%jC)b!i@G7meF224xDiv(8&0&wB0$a%jV2CcZF%; zjo9Tk&_>Mmdmj^HM6ab@4kpHhXS>b+q0lPMDl%L3Z&wMId(_BDU$5KI{zE_0l6U>F zuXkq`-d)Dxep{^d@_<)2PsmU|Yf3$h*2$rKz5MSYyPv|7dJ6R zB-)GncZE#`Mwpw5=F#Ka6|=nW78qf6$B1YWdrkJY9C2R%U)pbvbF17FX^YRH-8~oF z8i1?;J9*+b-UsI9f3&==N&QHl{ItCFT>8*wFkG)WOG2Gmu0AV#pZ&(CxU9-2`INwL zDKC&vr>;<+D}A49j879$;n_k{XT9jGmz-5z*5nKQPH@%(&g$%}2V`Bo(66&tvWE}) z=REx-)a~I=^?AkjnPGfBP@g%z&kE!7J*u44(?rT^@iOlaHy39{^xvG2Tg%Gc5WC61 z2rsX=X0~h0TSX7DGHYG){twwoTJkj|^-NhmvwvQ$ThW$TbCj)Q42#vvob(A9x2Rk3 zx2R!3AvrJ7x;PPA&XK0VLeO)iU$FIDX^CGDixLy26*i*(XfFp7V?@hI@!WE8Wu92c zd>+34MK-BnIVq2<%mmUIB8<-E+HtLA?H|_~7NkfUoJhHs=iFD%k?UaVd2&Z=Jy)K9 zJrUl5yErGl8=i-YI2Y~%a*jM0M!{RKfA`jn>%Up?+2Xm}2pa!d`rzk#J^e)5L!Itv z*S6(#4P!;_TE5L@4aV(8?G_cbp?jQFURFU2@A91L)^e@ytOm|1>Q-NK*C;I8n&eE{#*ZhoI(eLDMMZ=;kP4Rejb1wDsGtg_=_1JP0hNjWFx_ z?$GVYXMADO4Dnlg6B9oJ6Jyf&JCLh(lZ=DGi9I(Et^)8*q0vQ(7yq=>4psMSZeSI2O<$)drreH&_2x=|yH8ZAn4dmY2&w$S)2HtHjzmKwEO zl;pMo!{zpk@!5b%mAafr`Hr0>M_%;LKWjV06Wr#pFO#NTSIvq~6Jyc@*?*ea)-b*6 z9lIl*=$o`>XYw5V2}fu?n(rTKShk;Av-_J(vUK-)9VXPp~V~f01zczmM;`BiKsUxi$D1HU%4EQ9HinpZ9(zZ@icH zKIP?&uaUK1BkR4&cyGqh;^4Zhw%r#|{+Gh#@CfL!(Ffa{1{h&_>1XVq)TFU}8*~1atE?88LIIzH56DtJ}HTPW@qSVoB+b4^^fEh#v?`LF@lo?Den# zN>SgnJva&bRHzKCLEDEe*lExWhJ%~`_ue7ae|SWeCv`p7qegWzs=HCoijto1ISiNn zb>lO}sBuQUY1AZ9lG{5NF1IDd=Od#&G3qm;R)~_^zQAy~?KD2SjM`(=KBEqblH3Bn zk1u2T__9WoH|j)Gs?^)uDq~ZvjIedAr&oPUj7bw;m^35Ob2T^r#KdgJ?2fm|hH&)AwN(tOxDef5T3q56=f@f%f&au+2|og!v^$_!G2Ej7bw;m^32>dxc?Q z;%8uDOqvn?BoY&2(s-LZ%*$WeQQwM^)^8n#OR>fHY%^+yQ9F&wqitythRdzA zX>X4<>Numy7*$D>?Au8gF1HJf&qYREV$@|uh3~DA+^!+m<#vq%Ffb8|hH{};BYB1V{+G$JihXTtxR7?UQxFlk2k&taID_!*cOlV-$% zg!avIikOFO`!Dq|v$B+HvntRL^!n^+Y`I432lGI$(^g~4wb}-#$n}_BuT{gAYqm?F z1L$>I7RG;)rIyOkS^&cx`(;htEpJo>qbeCyS(M~1ht61x7s%DiKxrct$ws$*1rQPT1?z;G>Jd*gGLQ5}rB*QidS zB)11JTy8^*&rqY%jT&y$C{dEzYZxxK*~aGsqdqihfl(ielH5MQaJlU@*LAISdnL&!pB0xXPXLfA0rahQnCocPI6&4xv3%lQiwQyn2yRhpeESx{VpxMEI8$dz+Ao3`1K8;zrmYC4zQ?aCGeum*{ z<~|8^YQIqjj5=skUa7;9TRsezzM`qwm5e&ss8ftOU6kZ@h8V|6y-lRd&Eao^sU-@+AlmG=VpWn~slFyghiZm;?=xhu?l zWwSf+#V~(&jGG@3K1Z8}JACr2Z64;e%Jb;Cd_2f~VA`E5yz3)&-#V7|1b5$B?<)r- zrESivEXz@z@4-H3%019);nnHP^MGdD|9lcAg4`RO3bVk!NBRp|?~|UvJy5wWE ze0KUir^zi@J+Ys-vnp9zyVcG>TOQT zI{qU+<~jQKZVASi-1hp1h7rH`F-FYvNB2yO5q|o=*3QYi;xPrjIL=?UNb7W3^63ez zFjywiP8FB=42jlNncpxDmiUwW%|vY@2Kc37VvHEz-*PcAMhxia6@`g0!gI=9^Q?^1 z{StWNPxu75mXoyKvP=3Y<)pTL#-0Gk{wz@4o*oaHw|`t{SWragtw_1P0WyE3DDzc{ z!9rLBMQ5U+G?am|a56N2hR_log0Ao|%!LnO349LA;A=Q;7HhykdAJd70>*-WT)*b4 zhxuBB}mv_Uv*b7bPvPLLe_#ta^!X%gsMds0#LCyI* z(+*qVs0B&E^&in5!F*T%TjA7?xitQ2Q{*<|ka2pJS@$fdxgT=50Hbd|k z;~H=RRD%6`gPl9}2K*;Ru#K60K0BD@C;#@swvfI1&A$M}i{O8dPx&XA=)Z8S&-^_7 zo!@)!JF@^~=AWAzSie?YMlxh&P_eGhY8$@9A0S(($FF=EG0=}0keDzT7|}A-dtA`O z1X-$?vL9Z}>{)OKPXJcTWM%fFj@BBYpILk}uO#!fq-}uKN!<}?10+oT^hb)e0g0b) z#MzeSr+NGBjfMp&@%m+{zfx}pfYe>7v&-Q(%~n1a7Wc}<#27JfnU~1K7%?zkLbE)(o;=h)p@JdFH0r!hUb4*J<>gbGN**_=CxE0OW--?Fid@K5+XpXX#jA7BEEJe=2 z;+3_u(Yrz0=@PWbCE-Y~ZGNA&b|&0Nn|c$hr9J%?#w=paD0~XXFJ|3ecozySVOJj()EFR+uwF$W8GQrGaTP-$`fmmG2hk_6^4y=VXY)AJR`cyJ%N3> zvwAtJw^(7?cd#P)-QviVm*++s#zo1gAEz{r}Z zsX=g*w8gny_HypL9e#mbum_59&RhZHbuW>3KThUlFE90f_K8OxxUXHC8?UW@b@Z2U zSF6o_pyhPxHlyw^s-01H8P!3QTnXQU;c~mr_}p*Q14cb))I&x+Y}BJhJ!aJ7Mm=Fv zPothOs+UoHjT&Io3!=h)W{|U1$&=w>*f(N@eco}dzih(~e!SGxjOBIaNbev$)w6^6 z!uN_j4HtZpanvkt)jWwkC)+wt@zzN#@-JU&zDt>?P0^ z%uU-IiwFI~=Yed9`~5UV#3G{o>tmT5k_n9EE(!|8j>l4^{UcD%vvpJQ>t{b~saugI zmfyzw+0XBf`{LElqS7WOTIMp=@jS?Q$IFloqu>qD@sG*aQ{Y3;v5=3km%?h0aS`T! z{jiQ(ehVWv{9Yc==c#TFb?k6^xZtCH>FB4l+>bHm!nNGJ5wTvOuTcYxdQp_5e+k2- zf6e&F!`89f#u+tHl%#(P!=;~Ud}bOo*QoH>?XdM-B;lbITbpFBgoQ0~Sym~DT!pli zFCB*6=)!K5urTfMZoQIJXI<&q`m4l}y{(Di_O_OUI#tK0x~NpC%ULbg_~&*e#b_^sucTlteuX>Ai3PX9&@#~YZPk{@dI@Ewm;c{pS*TVI11Kb36!QF5l z+z$_coBtbm|Hq5G|2^%&d+%(`qEEFW1?pO?P3GC9%|>k#B`w}|43|P4hK;p&Nk-)} zs-P%IUkJmcKi>G*r)kTXIC*|HOkdGYf3ETQk5Sc(x=564|6&Zc{U*kznNhNAN$k7b zBudh^#Bk~DiX|OPiu;U8L#68diQFn{)0*#$lxF1rMi{rT{%DYiF=>o2ZaL4OrMIUh zYqL=!jGLD{G!K^+=}5UJrS(|ruGZIH#Px@_;9d9(K8JjtbIu5-K@GS9f@RzbgeveK zxC=VLC>Rf`VFMIj&T}JBADTf+xCI8lP#6WHVKr=o9k3J1uHd~>@Gm$8u7k6{^n1z*Df$omE3(NGvpgMY($@E^DqZh%(M8eWG=UoyuL-hl1! z3$*w;DQE+)e#3TPI_!XbPC&u3mLb`XUe_kaEI zJS8|n`s1vWx3&R!sq@kf6oO(<3d%wy(6-?W>?-hYxEQpp_;uG7#sHUpJb%{IcP5Mt z9{_(md;q*fvj%@G0oSvY)Be7^-`}4hq0Z+_qyBAFRin-qCB0`g442+Mhh5vGXkb)R zqplYfUZu5g*0au%rAWeU^}=x58Y!VpjWTMqQE!NneI1YCQYlzgh`WjPX; zej_4P>Tn`uI@vFnNxm?(*$DIAuh;!F@r6m_CpmoV3~hn8+Ir30yiSqpx{TK;v9Q=% zz+z#s`tPm@3nfxt$K2-q_^*0)@Jd|qk{@HzT0{ZdFi#D z>_sdrvy~wu-^BVwzKI_e6qIwftKe$L$NAYApyzPav1`Dk&<^yRt_$`fkOm_`&+*>E zo(xl973ewNChRS+4T^Ct=dS+_wf@sk^Q`(SMh!D+gi+xW^U_w1CfK!g(~Qq_quw)W zrcrZ5Np5p7Ty86j&lg60Y1G$7tq~=;t;KM;?J_>QjoNF}KBImYCAl5MaJiK-{eWG; zvek> zuCw*py%M%uznf=)54HZ&cJt)wFGht=woB{xE5WYyOEoQI8KVxhPRz;Lmj26cOD{F) zFEi>2qpmV4Tv0~$?HYpJzO^wvw;FYuQFj=1mng~YZVZ>3EE5yEdgx(PPothTs+TCq zt+yDdG6s`dx2p+uE$J=B zrSFv2#;NjW|S&&D|C|ckBOzc&*7lr~b=5ka*=; zl{md0(iB_oiL}Jl`yvlxKLT=pq$2l2SStXY-G7(n+& zyWHR5&RcJ8ac#rM`@h4{)Sumx?pvHyEApf}&$mD6o_Vk2o@zhIS*s%!e)(l3nJ~ZW zoYmY}%NY*}j!z2LpSfd=TYsjoJdKhP22hV)T^uHp)1}m%xmZOvd;0I$f{Z6Q6UEOV|H}vs-`HQip4EkFyJm1iAldZt|HS{@47{ ziZ9G)aC|otlbtjs10zgs!~MNB!jIrh3&#db0E?^xb1dsBaHltyj}IMz_K%NPSY~7W zvEw7=7aJeavE!hmw8fc~tGBaixfNP!izQpGgW!)l-ZT*z7;OLCil&sd@++Fu!zF%lY{GF>i_&brgou!hIpV@oD zxLCm(j!sJ+lV5YzQt+S0)-Z2oZmu11nzw(%X;_dV^O9;t+iq#IGi$4*on8!|!7lg} zN~~o~2B-!XLKCQ@;la+ zfO2p$JONKZyY;Lm4imp;8_;Y6*C24tPf5Y~FbsynLf8SFe&!qnX25J%24BL@un&rD z;hAPQ6V8TOP#4<3?eH)>27_T3%z_W0J?x0A{P2Ca`hy%>8E1P%=77mtpboMAL-Wk~-(T3l#2C@iUuVF?!5dfgPXZa<8z_4^HMspB7m*7F~+ zH^EP!b$d5;c@NB|&MttfsjIc%lZ`SCz+ABCIsg;La5HGYb3M8}-1)w{Zf|{4bAA7N zRriGbInJ8AL(g~Kb=H&ee0z8f)YDm+t?bm_t)etQEIEslC6?TI+b9Wj>P_{T;QK5z zKA)=3XTHxK*g6r#|g{pK-=VmVFAhHOcpxZhSsK zm6JN1l`{TK4k!Iv=wIBM7$X+W(gb{(7$XMyw_8n&5v}~$;+k=`drPgInvs5H_RM_F zSLX2Rq-;sHk})jzwxT)vThXv+OOuk_db^9dyBqrcNIi#go4Ah%H-PrPrr3;Fs6VrO zng;#9B0fxPcZ^$nk>FSGw;9_1mGvK_4NjyiU*$Y%G>nDuFcBufWS9ceU%30kLZ6qtKN&vtb3@a5wKM(}(n?PL$!jI2AY!fLG^1u1^}bQF zjQYT+xkk-1YJpLUjQYr^rAB>j)C!}%G-{Qou&?^YStqy^XDWylJ_&jgR^;i>JLOjj z!(Mh_cet>hUD)js7U>1I=r*1bD@^+)RwO@})p?wpC+DxF6&idj!aJ_UkYnCc$*j>+ZSO^FZeRezW3}1+(9irN4B<_ntd$D?Oxp z5rGlL&G-5XY%`nMjjJCv>pv8g_E^eO$3$0QuZGQ_ti>B)}Z65{_}t1WyNo~61e}awk@w~Qr9mc*A^ZtZL+kNvUrsXtt_EV zoncfJqpFIM^ygr>6jvFatBtB{R6S9WzCMOaf2;Ai-KaZ_>L5ze--F@OKWcm)Gpf5$ zeML$7ei$x&y73uq)T>5~5hdxzVz~5E5UE)$`~P46L+5JfXIgUXxjG4xzsy^O|Hbt` za-%-qN!@M_UBNWoJN?>hgmKIH@(uowpvl^7)Cl8ddKnXA(imaf{4XkY&5XBl6PO?L z-&m36NV&h|m!ID2dYtel;APPJUL&wyg_)rDz~*Bwgf*}hzJ(Ip2a|haM?)%9fXZ+- z$o(=||4Y_@Ao##4D|DB)ySCeAD zQ3s65qiuYW-^Q1aP`8aEjXDaIDs?s|WuCk1KbXhI&2%y&jGI~i!Niy}Mi{q@bvGCE zU)la^9~0|;5`AXykNs3|M56UJJJ0`*^M6TmQXXHJG=BQSz|OqXb#@>#19P=kknt(G zo0IsQz*za~*j7+T+hm!;P#rFUi{Tp3IStu){@<(&@Ty;Uwc|hkA9Kt0{K+Z>PAvRP z(di`%mrqMx@|Uj!ka>yc3Nr9xb#05pN&RsGHSC?+eArj+c8{j$)>L@U{oQaQj9u6l;l<%!{t`V z_?&FiDMp=UR25N@+rKefZWkM$8b)1e)D=e6LZ!-_rQ9lGGl@UGFlW)}U1OD=_u6=W z@iQ`gP5j)vt>jWmmHl2lHq$$HMi86nt@+00e3~|^q}I>X)XNP} zd^_VhP#>B@Yq%B0!xZ=c=0egA)`x^5P!!ID^Wh@67;b>J&<@(elh79i!V54F-i7zz zeOL<{U^Dy-#eQK;DL4*}hiXs*u7s=LQ)srE=ZoM8cm@W;aCjTugHK>N`~ce_?;iFQ z%0VSK4=#a5a07IJPVf{w4aN6z9Rq{lC71|rLxugUX$Aj*yWs)o4})PM%z+P~-EX`j z7iPgih%EhfAlQZV=j;f!XafIp2MfRb2+_zL>qEcT8=V4~@fVrC*0v%K^;z4CLfDb<-_K^pN6e{{2FZO=XLyVZn*yQ5Ly5E;ZCgo9GeLy z$7)R$xp&9v?Xu#%Q+F8E-lz^nbrL1HJ%HiT_c1${Np8b1TyE2h&vc{S zH)@tqi$qCoi!oeo8;#G8Mr}4~i&1+;Np8RXAA4s4U}N<@{&VjzhOv`rVDqEo> zsf6tNmTZY+i6NC1B_u5hQHoG0N~P77XfLfQl}ZZ{Qu%+L_s%)@JkwlVGgDK)|9AB1 zKF@id^KR#y=Pd7e&x_#pR!aGS(n>2Qg^}=)L(XHmEJJ zcc8YYIP>p`l{dZc|G59R{jOt8>*l1p?Tht7?hVo>TfLutBG|s!0Qy}+VKj_~Kac$c zFMIImm&mFQ(L3vW*lthSA5|0Et4Ds z;72#`2^M$M9VpRr_)KX#mG-sLz86ir@(&1ZZ+VsH&Zo43N-LtYlA_7pN+Gztovv)o zP+AkEovE~Q&`L|6I-_YhRnjw>VCE=_E?0h>dws<(a3)UWPJaipGobiUV#{vMl=qHS zC^K*R>ychNPIK&|`qA;9Xx!-dj~zLVG5%9P%A};D9YeVV`8JphcY_^MS&X~{mcnCT z$5>uKei=5vRoJLY41vqDlTAkKpqE6lHU*(xxfxW~I#( zP4+em!R_rXWiwA{^Od$pY0E{Ey{$lSdwWvZJf*Z}l(tT3uZSjlTaV!O_L{PJU1@JA z?OmmPB%18)V+6OiuTaXwllBjH^NNLfmZP5X#HpMYb8p^JGF+>!N@|>MeW44Az0X_s z7rO5!$?K7kXJt18&xAzIY?z#_8cTJv|1$IZC;jt}mh9;HA4`~=Yf54yuE@?SB*}Pb zyk$F1U$4v-`y=x6<=FO5nZ>Etxc{PGm+Bc`^F^n*VucW1w?Qc9`!G8TO zmgR}ZXRFy!>e2mt*`fWLZw2{{t+erTgxZ@QKdbJh&FRr+BheC+*)TcZ^gTdUoxP;3 z{P|_wrgvt;f*mKxa}lYN55i#x^W4KeCnBp)?6|Of=AAYz?KALCN!Oe_^R94+Z$LufUwOU{J)swDf&);I=iTyL z{3NIa_WAfQWc!SKCbE4_z5;nAM8<>O-nRLb=hr^@=&}bF&YOGNjn_@OYShpH!RLS_ zM?dDTVeyJu!(yvwVzbS+`BvHNwKhNdHYdrNZmyiv5>56~8^MJ(R5ndT3+4|ubJF05 z#0qP3U0BGizZQ1V@ev8T3tU(;w-Vc#PU;p}$ekl7p{Q)=us>3Nz2f9Kx=nXf*O)vwVh3DWU*bU#qUhvlbeD0}L zk36t2_!9iYF(Zcb@6m-3py;3TZlm_6dce^LF7#drb=v*bW|436hO&9r+Pvr67`0wg zPP?X4qQ9n7O=VNh+SK=L8Y!FRq6PIv3nvY6(om7arw>DL*DzN?owmT*Ec9(2QZ|o@ z798agx@$@A2J3PrB(-Dp$NO@+GR_WVb9$?>9aE`~aU6T@QEzrZ#I3QxhIvmg z3d+1hzidmn_RF&^%eEZbGA!k{{2%xLXa}8OGF%U30i5uSw? z;1$>aufiMf4pcG;=0rFNPJx>U`~ba;76#HGr`n@_uzL}l_$YG1JA=o_y&H1oXNz6^WZ}03xi++q`)0; zH>`kFunk^^P~HSn5@br}p#vt?zu)(!^N;Ui$vnBZCvqHNci~oN08JoNKRh9Hh-Uc%xKC|vyyhyS4*4^Km7b6oZKMu+Bd+C(Kq$FD= z?QcrrZH26Ce>1)sn>~s>XS+u^O4_j066so#$K(lQXP(Eg$F-&1{>pK!Y=2Fj^y+0P z*A>8)?Te9Z`JRGo%lH$>ww!;1Y|DB{%CD4nb^KrkM5PS&`o2-_HZ<<0l}CpI-~l zfcSgy&$HkJe6c(S{^Fx|-q`#SE5beUzB3&DPkr4?M#;*|8OGvUfONT^igctw0rc+ zs13{fwb-NBU;ijJEY%Yv+p<`N^0<-q&?Y!LM}j#AHq!pt1V@r+I^?E31K-0*w0{P` zK*&LxM%qGkK-xnMp)oXv))2eVpDkMsySt1KTgmjf`6DIfXaAr|QD(kXR?D<35-Nv^ zRSwyY5Gmf8nP{@i)uP4SbHJ} z>+ZsSbyBceL$E?zLsnXdtPnR`E-eTf<-&%!u=Or%sDuT3?(J5b>*J)kvN~w6^-d?1 z`q74!cGBFRY}lPnI>XhUjgZPp89iD$UB>pIFdm-hC1;iTx6%so`*2J}nf3M`!l*5A z?!Z5clQaBQ{pUH~Not(;&Y~%a6BBHU*p9B+H?75AM#IwkW_-6KiEHiTtkQobl$kZb z(mPXo#`a9*$kDL$z6l>WQ{T?ykv^-R#J~Z z(7%;_ZXzT@At(XT?=1uN`ET_7FT4KBQP+QLWj%nr)a6QW@D`WTI*N_cx+<-gXpu7I zq}!Y{QzY>Zvk=@K9+FU}EmhhhN(&&G2lS3pwrT(d9Rn$`WW@nw*tG!PnvF zrDRD>Wz$ZMEVWMj>%T{Bm7r3FksL=nXd(OfWaY_wXYm7D_NlP^MUd zIT=oct}qa8hr8hg*aU|mxp;yp4V9oVw1nO;7$(6ra3i!SkzhJPjgs^wU>WRzP^koy z8|p$mI12{Br7#+9hEL%K*asy`CzuM*2%1Ar7z7L9VR#MRfN$VOC|oAN90#XB0~icL zU?^M#%U}hpgf*}ocED%w9po*WV2VO{I1$c-*3cUUz#te3SHM+pFWe9ImHuDNLB`4U zS=IjT*&Y02!yXg)&oenl?DY7ZJ;}d46qD$fZ;oK(*N*x|R|g2*|L-pKae1f+HNfVB z2FMMe1=u`s9`gCn6>R?KhddBcU@|-nImjnDp)*W^q2!lgP^@r*=>%(vq}v7}cuMzS7>Geq>^^>&= z&d5DmP&HNZv6N|b=T(|4ogKOC;QwliilY=|*2jx)dihEZUr8g&$e+A}l_huErrojE ztI_ngDVDWo?tZaW%5~F7%VZmSe>7OSaU;PyRI_Ws-VR!;Qhdof5`d!)q zm7p5L9yL=VZL!VNmW;$vJ5Y++n`+2D?q@2cEcdr4#ourg+1>Nh**QXpM z&Ofs$R5mjHS6J%ec+=N!?{y=+ZJTcnvTgUhh-}+_zadNeuN2reU?XH{2L|JRAHJK; zv!5Q9T>PhdAobb4eVdZfB5?buAe!u_B7zG& zN7=NoHs|{`I*5-QOW~s7SZEe>0HtUqldeMTm&ITv(0lXuo7^Cz#!-@AXt0z}D z=>(HIlq_vxS{!!9~WzGD*v`4f@k?XRu z{WZz)lvU}o^#a>(yBb+NX5T!)OKr79DVwLoWp>Am_{>JdW#$=WftcYZfHqZZ`rF@h zb6d@{(?4^*TSAh|B2WMAU+O%w^!6W_XBNrLBFiy@ly~)#$!GiIY14NiX)OKoru501 zf%L~8fuB%|sqc88< zqjNiZZK=P`6R+R`BK~ltlX#jheY(IO{)}@>^@n-nk#lkofIsg*SJCZdsPr41HdZw8 z`Qv<>`O0RwwOQfY$Rzyeeu7!}vY*d=n{Skj%(#!7zr5TOk%ISy0w3SN^-~wRl`8Ic zQeUaR0=s^;ChPClWLHV3yQ<07W{Ph!PuVO+D=TF=BWdkV;4z#11j||__Qw=w`KJ)u z%s;gZ%k|P0$fM22mLlfO&*_@y;gTtd2Xfhi2PF{Y@B03CT2Bx?UbJ4bVJ2U!aWz|R zx4do7o8L{Itd%*ly-l&r`g&GbD#q`ZW26pVBxnW5Sw;Nj1qCEb{@j^n*->P#X^&!$ zl=_4|)5o%BZTIWvHydVhrRST!$3OeysZZNo$?xiz%47Z(rA+jjd1{MN{P_Qbd`zWU zPRJ|O_PfEhB-!8ezUm!q*Zu4Ifk{#qr%mrtjEmbb^v1|`9K9E^9ZSC-S;o_49Q|96 zv2+7WC~9T+B|&rkAzp?c3a^Y!+D?sXpC)b}F0itj%uUrV6Dldd@XOlk=&G;P!K# zvbo6GwDWC-DVtH&X0&f}m$I2}Z5H@8OHj(n^OC)#mE_p9bi8JHy_tkZ*;|?T z%nHV5=1*Td%0c5iH@^d|_9izf+A^<`w#gC47leX0PONA0?t37n`$hBOewmc#S><>( zWuIj=L$=Sex*~Uj?jX;w?t@O{c*X-A%Jb|FwpHLA2Pk%Yf+-HF^S5E2cS355QZ~fb zN8B(ZzP))?=9Pb!;-5_*XKEhnF{OGmmlYFVoYm>xiL~zwy)X??lPIFRveY+oBFYhNO)t34zIBp$VlhyTW zvKA8R&iQ<6)7G~csBDH?n-RWE(3^DoS;nSv@+|rRkaFA|`obU>0$nK6y`cbQx)4-^ zYA_r|!f254{x*C7(V9mMdkNxY5Oh- z^+HD*F_p-Xv6X(Ig8jnXasuXO!c$S zl=zfMzS-3=6}2~K6)I!wsy!vmmFZ;JIC|WxOj0zz7A+<@G?G7UeQ%E@X_N7=*OUJo zcb8gILXMOEF@8!&8`n$!{Nj`2O>b#y4}vd1+T7p4VX$rQ2DGbf`@27~ZG+E5w(anZ z$n^WZ+4<=QudjdMndJ}h{Xf3{kur89-+%8G9nAd@KmNQwy0%N%$iQ3R z>%aGHig72R`zbA&?57NZ+j}tP=CqF1<`Um#poBV`U_37Ht-~ceka$(gJ(aAvGum&Z zgJ6;+AY$cawSFg3@LpIUdXJHJ#V(gL4Z=FPun`g##0^$93?y0FFcS8qlVok@;M%@M zaA&Gl(*J=?WuzR(ldh`CuiA96+h=OZlv2j+mg`9UQ(Kf`EwcDGGwtj%67#dN^n31o zv1tACRuL=PUvD%o`X0c)r|l=>O}XPOv$p^I3+31Lp^u|~Z2Qq$p79b%4Qnc8_Nw^I z-jC1B&xqM4L_*M}s+g~roWcqkE7utQx z@zREwLgJ7ADs3+!o!fzomB@HUPq-FtWxV4>knxX=@EW`YpMo6^`5O5fI0ANTBo|{M zxn*2r-}m2q{vmw(Zq*ejNoi8RW_F?ZJ5$V ziYD=|KydLVDVuARcB9g66)o_>Go18NMB;6P*W5_p&raIsq$93%ZftE8@@uOG66(&W zk+o^;+jLYmU9C+w-)5?^xxw1pC_*_I1ItMIs^*?5MzM$4pZCg_QOa}vmbEbzbgq-zr;Wf8M=qca~*jK)oTB=~8b?yS-H3%h)i_%jAoMF=pp%KW~ z^;ysY&Vfsy6ZC_Da4B2?qhKtIhpXWZm<#jZK3D*2;Td=VBHw>`N5230#PSE{-^t9s zl(C~}|96hj{-0x?@7&=(-;wnTqyF)6r9Gjvr$rMlzZSuH)OVE4drI4`v`<8n_@5%U z_}?g-@01oik#d&5+W3e4_{pj!$*;76N;^(8Iesw&x7TXQrn=H?l$pej{H4K3R{)6NXcu0StyA zFchwWWv~KP!W!5PJK!_;4)QkRJz*#hC&HP~8tea6 zORxQ?@Bj9U$6vohy1xP+fz1bBAb$x7q^Zpl`H)rH>ruZXsV%DTC`Fk)>JJL4Eh>&u zl-Z;AcqLP9QE`-_%pOgNYX_c@h^qYm`$~Ou{znn1kB=pN3y{W@z?T1N$km|l)TgKV2&~J)NvfP5 zXUlmpznlkath*Rzs~D}6*3QPi*pJ^^+4NP~0Huuoc!F8B!614+M?np zMVYB@4XG_Ej#8A_(oCO$+Fcq4@SiFFe^pj5puAoNww*o}c>>%8s-dLrhEkN-(r3Io zrM9RzN>OH+-hp@gzfb(vrN8p}(e__{@yAC?tfpxGO4#Nrb)udk+%>Ui~=2rLRCuaXnoiuLrh|30a z>2P5rae}e+^xuA8fdjK|zl+Q`JY(*Ge+yzwlh#fk-QcA6Wh5jB+wP>(B2Qt7JKjBy zt>i}OD?6!hJa`jKqn332JZdZ0t%KnOdjDAE~xuH+Iz7U#BP<7F`u48WtV@ zvE#(1XxcJ)3gxmM_+u_lyNf}{(EES8ygkIefu7MnBG&T<|3_> zPTJpeS6OiW_TTsZpZMYQ(tJ4KGS)U7?0DM>WIN{e7P1|8`w4ju?1lP_waGYK6KDzk zc-&a@>tGYOcRyZwX3e7yGZA$5tv6mfam*D%`uD!LZEETV{?dQH|9G64eFH>Z-AWDu z@N%PYs?M+7D<0NqvTRJ?2_N)rmMfblMGKC$+DX4U>99!ROMgRf`<2<-(W8_QO>AUA z8D~>Z*)*~?jeVPr%BF|4>FL|(H~y}+HWPiDU_}IXC~LYl*}_XhXGT(1>NNi3yiQKo$--yZLnYKj=g zvHObF6i59sSNzu{JNB+CZBC0GFPhVAn91Y&WO-il2D}gUxk;F3AFBTMr(7AOs5ux) znY_eaJils-Qaq!7P&}rzmGkoMwSDW--cS3R-YNjzTQ~onIe|Cw23@_~JB z))Lu1I~#y3&(Gw!+5I5T&g7Zdw;<2WQkY{G{tZW#_^RnpNujf`jzHIS=yJp=w zZSvJu4!^8l_t@+IB-@%euU`{4mrz%$oo8*@_%^|0Cuei3wVC1DY?DxD^RBg#W#n9F z9&z7Jllgl=tzQ(ug~|*4QJbI*AT5LXzRiWorh{l=BaH#KpUaiamDXmAZ*#Y@iT$2` z^n6xGjG(O}ErzmEzOy2oxA;%$VlMzQCu`02d4A$32lbZ&IEtCS9Dp*jN6D~Hwtm9y z$o{7HPW~~k{~|j(icj*7W&M*4Glh;;M&()dqae?-GfF7lj{FDh z;1ZY&*TQmm40ggdkZ>{Q3C*Adw1RWtL0Aea;5+yMy0&M2JS>C?d@v@L1L@|;NJ09UwsW$ z0tmhcz$yVJn$F^*ZTcN+*;VfZ{f&xx{-czPtS}I`lw!5A0^6JR2wz!aDY*TFQn5pITC zK+5B7Fbi&nJ-fe_ufA=0<+;@>AL4`WJo=Z{zk7DNsI^NI=Ob?rf9tfHlr~*7@v*lc zIGY*DW~S0+D{YR_<|^$jrQM^ndzCg{X$zIMSZPa?wp3}$mG-F8R*4qWDo;4+ZTGC{ z9VeBS{z_mMtaKJg@`krv8+Fp|=-6qndX5B`(tk(#$2nf01`py?V!v$oFWcfWb42*p zuK$o;c~vepwo=`1F{im+vo&MSR{rE~TJq)+!w7q|KIEq66~H)bhB>b34p zTHyL?3q=avk(XCN5eXaZ!iKuAQ4$u^lS!_xms_M@f71Vp#J$4B zZR^5Dy10W~tsH!#N?IgC2y*9txomgZ6-pbev@uE>tF&NdirdT8YTG2GO;*}9O1oBR z*Q1q^G8`*C8_7l5ztgQCze;K7Z&8XeOSNLv4H@NlDQ*403vqG0x7RjQAiCa0dh5gd z9jk9-X6255Q`~e`0!fUg+^(nWZh|ea4c>&e;azwiK7fzl6W9Tt!%p}L)TmgTRl-3( zL&a8p_RaneDE{SSwH)>MGQt>L`KGw|<;=6OUsbF%aKc|{WMnh(Kw!om{jw4zEYr?gX) zR#R!Ul~z}2^+l88Hb8JkYN%{ZS6U;bHBnkKrJbd;7D_wX9QM}A@_eOTs5F`69=$&u zmDU-pjFi!|X;^cSm;I`FvWczuR$lw^e=C9gt5+&BIpQs|RTwip2W0#-PB$Lg%zp@I z)Z$!mDk*+;Q;NSKE;+S5^8e}jUwOqJ`)PX(>H7!B7o z8ul4{P5&8uFqhhS;=$JDGT&yZggP6w=7|gaZ?7s=13+`?`YS}VUp8qP%pOz^0Z;ch?S1D>Pk5VS@_9Ce*O7V>TK`}G)f9%>$ zcC_98`fDxOuz%aCPHtGpCdTa+^A{rJo##Ao(XTxOopUx*og3S{#M zt3--6_G^>jxWlXF^UrS%t0dS?R=oXwTWW~|c2D=kGdi9Z>^#lKV8 z+^w{EO1ob)iN6TJ#Sgv@;k4&fj2D%*(Z=88$A3rJe5kY?O8Zi@pf>-?NhM{JFL)QO zg?lFFshG*e*cn`jVJ#btX<_p1T&=k5sAGj87f<>?dHo@O#nr zg)iVsIHx!BTHt)R5ZXZp=n6ex5DbR7{dk@N%i&qr48IA?{K)jbgX}@R4iTLw5|P+> zFw-M-9hii?)pB`XhUjI}KHf5|#`6yNepV^UZ28Teo!X+}C`Fm|9};T^UU0w+jVxOB>(NYXjt^^x@g$qqE?pQ;IEZm^T-Qkag1<#>%HlE$L`(MJ5q;7!_r%s zE>iDUyWou6IAChMll)hHx)SBsmjCL=HJ~Y2UvMt+dC&)}Ux?lDS4q5lgqM11%RjaQ zKVxR-4E#snY6n@D{x&y7(>mVuzW$seQ&ZjL0#j7#;*6y65aJDksbK4Yn~g5Ebnt0R9bVTohzEeZ;jyM zw?`=>^>}8|avSmAfbYQ8`|%dvOqae1nROt3M?n?ecrT$-tTXtpl>aTHTY71@pYQ_^ zqWxvtak-K6LItpGx~j-0!x>=PcP)`yK^L%Xz5d7p;Yv7$^}iBT8B0={UO%(2Y?C}* z1i|I;;Hz&=tE%Gb^)qYR_;vjFXQ>!1m3EHO+K48{KOeyzvA446r?i1e3s$L?_(S~o zS1Oy}3v_PZ{v%vPx9zb3KPlD~MtwVkhwt?-p#hd=4VmZ%vcaZ4{q+e#wAZ8By zucW{D(pD<%Nzvr^s}bB@Ur{z2 zl(t!E!OGMU{{uh1UVZv|72`*x{UVygKOjPx_eh^(NxO=qUqi5CF=rvSgsx!6W#TQq zOEO#fW@L5;nRX!lObJy3{a4Drl*f3|v_E!(U@F*gw_A{JgZsgb!99$;3^sxtkK2a) z27C)LHfPuUV*U5WWc~MnBkJ{M zPge1R^=F-BJsZEiAHR)?Aq&lxk#W?lOj{Xujko+~y7iUm?pw^^n|LqbKVSasSot2( z?Pn;$n7AD`FNItNT7n%zZ-d+x27w(v&mV+HzUyJ-K8~{7cp2%2w63G0&9oyf0 z^<~Qc(nXa2;QMcv^-E{{=YcX4(Bf{SsHveEPRI;d?je=msN#g9Ku*-TK{ zM5RqZD~9PDUi^;F8M zeLi*$^0_bt?6b1lkmXs~7O>CD;=OtPY7iN^`_*IJ{dmuy>fg45|4RCcKh8)Re?+`b zpjdaF=|dy98#chtP@ZR{J>f9VOMiprJSQCme;WIrK5gQt!96;+zo4}(h>>U4AIX{p z!ISMuGM6uqDm&?Uo@$w5;jqaWN<2tt>e{KvB1dMtRmLLn{?2&WaWD%`R^5q&jdNiW zT-aC%3y$-l?7cuZWOACwlB_w|BA)sZrqMZ1eJe`T)8D4F*-D!)n#5m#;NpLvY(7%j zr%L-)G>QKmf{R~S)kam6R#j=ie0quBfM6HDKT2tNzMavuJfTm5sRA#9=}UWnXW8+V zJh|8QZ&;RVaqdz_WDuK*T0R0YSK$eG2K+e-zoX~qPq~N2&=NX9 zXXpbHVG^W3xdHeC_y9hHvI7Z&DiE0m^zr*|Y+k=^4PS(3BG8N*rc4|=YWU#(y}Gt{ z3F~rgNcu2ADGfWRg_D9WYy?}4jCBW6$VvA(X}(B7i9~Sw)=w1WVPRmi!MFK9LS2mD zsiExW3*V-+dioYT=M$Ss{?oS(%BGKKV$;{R8LVtB7cID=kxqKTNl!Ydd}Ku$)~W95 z)}}e+q+gx16c1Zo%4|l{I`)zu2VJ@$#C|nvo!0VECLSs_%0hR_Hu zfdMcPu7Nw@UU&wcg&!dCQr;bd3Q!s9!)b6nTm*w)2&BMNxDW1!=iwFj9KM3X5E{(f zF{lWwpe-!Fj5RIcC3tTL&n1UacfqUh8q^%d^+J7U2&Y41Xbxw?h0qRO7)jj+B}efs zG^hc+VGzuOd*Eq!8Meb`P+~OmYay~6(68pe-UH@`-wzo6i->M%9|?Dgmat7TUu?HF zHb&O@NvxkVnI98f2`KU{u*iHcnFVILXT)cpLfZOyV9Q*atND$+zS$Pf%EX=+9Osr7 z{k9Ms8aI?Qcrr@%gQ6f9=;`c{7ulIf<1+#pqUM z+6&pMu)pFLtn7XZN*$awJ^eC$8{4H^ZwD#UxhS7fuJb`*C;{ccmh&peRpC^yWxfe= zGw2Am{M&WkwrqIuSr!1l|DL(G-FVFeSqi9Ir;FU_iQwwmjnbx-I&zcWiv3hVoy})T z`$B2*DTE;YE(90jfU?meJcre`BR0Na;KaqxrN&g`<<#ie=(kgg%eJ8YF5#q>P72=l z47N^pVYi4RS9~jiJEDB}Cwh!v+*)kb`!>P&vx~9E?q{!Wa|oquS|1*7dT;s2OQhIE z$seILGrcGoQf~EkaAQnGnfX@n%5HvKYI`|Tt1?|S*)VDKve4jiB|2!D32HQTn z4*3R{3%0Gc0C^Ftg(vTcCPcg+%T?dh&HVR%{fD?}*XpaDN>OIs1!R?&eh$d^cz~b& zHkTdyeBiE0HjdqgDIjg}jHJ75uYXT`X|w+f2jLIMNxR#&;qxNrhw@P z{vbJAEq26?f*HU5E~M({B1$_>X(dIInz9sv+iOK-bE49!E3LL@K@DBUNqwBuS0vec zKLoe;@e=B^iAtNSwChBZ_}3%27;}`(ol3h$X$wS?_zMwS{3n#nYNb7eRz}KjylENx zyH2b8f}<2w($qkoQj}SrLEi4Vd$JZ?TRAhH^@PL{xl{5sr4D!@!Fo^oYu~hx!$!l> z^Q`NV?RNY7=QsRl-DgQnWy`J{Not+=#{;9~-<@S1>1U@`Myn8B73zWQf1iPT$WH^M z?DMxQZSQGni;ANZW!9%xTsw#uW%$1Osc-MA^^yL4jfO?XS)*a=lC3Pi!C#h~kxeDL zcbgw=TO*SC>Am?A$&c19I3rhDRNa&;<14Y!x-r|@fE{|qCl;4`q}sox;)hF`&st>$1nH5Zfu8D~}LuM~B^mQM5TnA)P^C`Fkq?U&gd zq-1sntGpeg75_8oFa9{QX)a^ymElA<2kbceMab=8C=7%B@IK@1vFCrMuKzZcn#+C} z^`X7)>3$xWt&toA;3psB%Ye>LzKRlUXKz*78%ldmH1V_VBe?hnmCa$L{h_oR;zK2V zP6QXfgz~JVl~zt^l|_^ICm^`^b(Kv6rJbg<#-d65CI~KmM`hDVXOHg{NmNiS0c~cv$V7wd%HT?{e;Hks8UpyRVn`EMC9l_jy`d1!863lrsevSKb!xLsv>~qjr$o5(2T4eh?)Xx2QYwM<$*FC*(#I!jU<29HWJsO?SJK<{*`mGJ7oP_UbM#UDkWDQOc~By-jM1QhLpg&&+>rpmty~ z{+zUFp1S2y5d-P{%*s$o+pL!X4R*?E->d1B3Bidj8 zh&Ie5+p_op`9S6;lw@u~snj_N4f#C{&V(+|6;!>v!Jn9;wkTz`pL}YIQhNJ+0<}dc zy=QoNM#Kz1DYrQw&HhZfPs%fW6qm}Whx7B9JA*7cianZt6dM-JXC_(ZrNo=|eM$d` zFbSr?-Ea@ggJ0n=lpjM|0A9O_?*l;jap>?Nd<5mkqeE4w32DCrde0p*r%$^kb^c%K zmq49oe_YMITPs@NBcE|nuqH!fF#l+XFd{7zcyR>pe9Njsdk{LD#B+$`j# zB1xUl48fh{#S-eYZq}x|Z*!HhNwGGQeVe6>f)K6WIm> zU@(k;QSdMJWya79*$m9f59nOLF&>8x}M%V%m zPGSGB`x?G)2-i<#Kd=H`hqc!;_6cpLF@Fs11v?3B|F8RH{jWXz6KT)yd=W1AZ;zh# z^@H*MMa?iKp8aR{!ek=(!kdXT3oMxb)x)NFR+nq#vX!!7l=F5*S0~!cv&#Hzu{bA{ zW!g+lL{o}?Icemqm}PQIby>7;a-8_!^vdYXg!^T54f-pPL|K&bS`dnZEw^ouZP}fK zY|HOc$hHg{%BL;IQNO?Xu}2=bj}O7!Fl9Vn0qEc3lHhYN&R?yzK5dQf)AmTHv-!i? z9Pw@RcbFSmzjqpfi`h>?opzbE8RFZ_RW|dj%>v(MiL%k(SdP?D3?jL2u|4^N>jy-} zw1NQYk;+tL?rfS#t>(10qDftIfp4SNkQrlbWT6-rbD@MfZK<_cCPLYG)Bn}iy-d5& zlZ{et_g||}Ta?nr?>wt5O7RbKG&%lOlQew2ZzYG4FD#XkI4_B`NwY5R1qITE9YZ@a z#!>7g*gdBtUQi%ySO(^W|HaX4Ti-vL4Kul={{5@6y~UoS{9f-X*Tz()_*<0H_HA#I z+Tw)=VrF_lcjkUNn2T?()c&RcIKa-17)4!1PsWO}P(w9o0kCX?}>r-7%xb0KDj%@o>>Ky>ae;3W06Ilv^rC_>s zkbC0)xfaaVGUh2QpDb*IG%ql96cvJt>7NyMcmt9a>lrk%CTzj*} zJKArCee#3(t}UOE*gV<#UHhAo_(>rv+uzKzckFSj7qP!`94p&juf0>ij%^erEsp~k z;|Mc;k>HJC+{F0BEpQvmhCARcxCicq`LGZc!2_@a9)@MG9ApgSQFt5|Gib# ze&XXlb8ekBdE6C4`uFIP<|Cjkm-dsg;btr23zlMRy>Y=X0m^&rjf^Yx~n2tNX`{t@u`f z?2hrjFTqC!d2E?W?~Cl&6=rfsoh)g-8lHl+@GPu@7vLq>2J#H!4XAisg1G<|z~}G< z*k>9Yd8W|~`oJI<2BY9Am;fmtYrh5G0DpGP;}6|;`;42en-skC+oA0_WE)pEy{E=3 zw=3;KrG28b&y=QD@&8(F`&Mb+ix$+CKRBt5)S5w9U6FznghnAnRuGyfxjYD4@4~Kj zVf$Rz1PKfF68#!aOR3YP6>~O%yXJNh>a_Ms>!`F&O6#JuZc6K+v|dWrMi>>@(&t8824=DcS{6lgy-KB*oD^(Q}pM115l;_k7;Q@FU zmcv%~9KM2Y;RpB$_QK8^`6d=ry@~Z6U+HwTkF2KVaN z>THt`F3GI#V5Z!)pGNyKJSaEG5)gRXq0E+xc;Lx$*MhKhE-b}`eec31Nm$^4Yq|M# zwVf1vAtBg0PdvYPW%*2k^TWYPQBKp((iTY!w{5x7o>SWMN_$ahFDotmRi`#7n^%?g zn$or@?G2^9rL=d@N=rFSo5uh9{h3Wwkbl$^!&!D-MGx z3fIE*Fb!^mn_xQJ0yBV@;eOe}KlA-}=DS~l|I9A_eV+P%3HJU)?7RSf<9Fuc)PFVy zbXZ)(3oz{0$rg>kp0~hbY^{rF?_NIkNbW zRqzz7gY{s2%2wpp;UlpAWhe4iupg|i`5pNP6vuB^zf&H$BAf=+2Q@=J3)+MAN53CB zbin`bcmDSOPG}JLm;b~1FHC7&mo?#pkjWKh#5T;Zze2ndNle~c6YQaJBmG;e2?AA_Sc)4pXuY-_N(1@ zy5E1#lNIGx)eTBf>%b~Sb>LMTrKn|Ge{hL`pcG}csFP=RpC_9;V=BtbxB9c3{+pDo z)3z$(TgmnBUERy|_w5tkvOMo9X>wL(rfDdc(NgeO{con1>*~|XyQS*wO0`0lQj}Sr zU_{m1NfxiG6J1#$-tX*2*VU1@@|S)d$@p8r{`z0GT>IxKVN%YcVdVGapO)_E0nl zq<`!EsnV6{>V9aB3V`2=VPc6{wD{#0XD!rxaCQmipDY+M?npMVV!O0kIS>&D5^dL6xG+mijyJ_7#Z#new02MIAIwGZkl*zqgojs5(;(s+-bPdR3|%F2Q{7l2b#>w7@=8JQL#- zeyh;7F{ADJXs<9DmR|cm+D^4COH)|t%G=-$m3kn72B}XUge4$pFLmj` z{Re+KxZnQ7yeI$Lkd1eMZ~xRVLtB{~@?@}vG5I1-4Mpb3p~+v#6si>}b79DoU-^2? z3M+RsuDJ52gyW&ojQKe$&q&E}f0lm z^Wb%|^Wb%}^WgQe^WgQf^WY7#^Wdju=fShh!$~>MMh{mzJ3USU*ftCO7`u1EY^Tr-!SXogS`kc6zwF z+3DfxW~Ya%o1JaAy4mUB>Sd>gtCyV~u3mO}xO&;?;p%0lhpU&J9EYy= zL$);_>t&~htDl`7P9FDU+ikC(ogS`!c6zw_+3DfxXQzjg=Ze{w;j*!pT0c8IT>b3y za1FB4!!^iG57!_&JzRtA^l%Nb)5A5$P7l{0J3X9C+Q>Hd+8{eUT!X;FJSvmeYa^+lec~@87p)CAG%PP-4?qP z$`@w-v8;T{pHlP+QfMeCQ-gFGNt#_s%3Vqc97y);Z~F1upKX0{Cz4V71(Wt7S$H&7 z!%}T~25H+fH3Qco-NhaCA?66;3^>Z=Col{8AG`dSS$6r7m3z|ElkzH;dnq@jCzmWY zb99jTM+ITS;z2oMx5krMoy6jchVL9$677+w#xyf zVv#vewg0L1nmxFGX5ImjwAq|)+Q{_1yRZnZG(oO3a$T!PoP^YiTD$0#vtwOU z@QM@r$PwebGJ8>}`J!0lS{fK~3%931y4NB_Fdr6?D`>>%(Z#`F}NN$%o8dvSQv)F4G(@Fg$4fNST&bJPJ_O`V}p*Xb=UgUr}SK znKsxL4pqZG2S@E4^b3qB$iIZjVKJ2A(z`O{ppp5bfY>%7ee#=gIkq&c`f;We%$fZ5 zcy`y)y;XF-SNDq zmp7EhT+G=G;f_d`%{Jp$y~h*@?x`_N%n4YZ6>5TY0n?K6lWw=%0qNjXFj57KBK}CW z$Qc&pOq#bYN@mGNX32;Ds!aTLpqa-;q*Ne=1kHO3KMC zp2<~n>MGNNO~Dbw14oW1zz*SnWB+RjJ1)$&oq*=e{u1iSx=$&XT)2 zmV0?AIZL|XhBGL|aT4;AbmGt@87ucA_pXeut7eLD4q<-t zh2+dHVDFLoCu~Z)I~Xa@O-wCpUkuVXnY=5#S}7lA1tmqUSI*=(Q^o`}mL!mziKK>P zD9TJE1$gUb}MuA0NG!ubnL{3=ApC|n0i&t9w2t5)3FnunTJwM zDNCd{;hd|Q4tUAlVac!3W*Hll?UCeL$+eeZpJd~c7y`Vo@}|I6maEE+Nz`F4MqN*cCtO01$lYvaVX2cjV@x$hsV*XDq+l&(#FgyXH1Xtj5)rKF_(`sru4w>ufgv?!yLuOaYkg3QEy0>==nJ-6#%s0GIzU0o3 z+4ES))Z7pddhDu1DCE8x}T`$A(Rgo5E(}U9{+z zg-wO$!sdiG@iU)<%>zG$&8FYNrexj(bAQla&KgXXn9Lq z-uV6`WXxy4;ml6>6269A@D1#S1TsibCP#k3)jPKFb^JqXJ9LQ z4Tm8QiBSZ^ub&EMK}YBXm%|v~BW7j}EP!S3JZy!}U_ay`ZH|Kzpf0q8j&LbVfLmc6 zNE*J8&zK>k+x2Cs|4HPl;eL4hB+~Q@V?KcSjYy})#yr}De9+98*Pzl_?5nvkceY@E zr1NoY$q(@C1;*66h_r3Tf?4g2`J{_6i@F-~V>gyxr2sy~pxO3;#-t22<{c<;r7?|J zXeeZ(ANh|CQ@GY)tWlkV%1^(38)czd)W|l0Rgw zro~sSJgvS8A@fMpkQsUsYtmK=nf|AT%;u)F>RN=%B6uGM$h-x~y+dX)oH~#iY-q^L zfQ^)`#LMXk!`skqB*z~WGId9XOwn;18)jS`G9N>si6L_%$J{CAM!3C?{rzfXruC)fe~*77?4Ga+*+JPzaV4dq`8nLpsmH$vtj z{6zBmA#?inkSX;6{sabn7&5y*4w)N14VfN0LZ%*tyZq;*6V&-4WZr@IDdkC+hH58;%@6QgwXhj=a@aJ&e}zv8n}g7^M%Y|?8vd+F*yL{-Hs>{G zU(lpg*xcJTY<{~qY!cds%@weuL)d%_r{iQsbZ1+?u(_pw*xWxLY`WqHYYq>aGe%%{ zW!MZG6E>Z3K$XXZO|9`^^RzHIY>G_@o1w4(@?H}*|vz`>1M9yYC4 zgiY0zoa>`uQ~t5AnG4@Txu?QrFAi|ovy88-3!4w&o#(?Q_ZIHaYhkk=2EGwCuYh@z z>wq`lgtx+`B`kkCY&yLYHkIB*hT89i&DF5@gnRX$Z@yBf9Jfo747&&1z`&bJ$G%h4`=)_CSLJVKWVC;jmXi_1{TP zsCXo7W*O>~WL6o6tx$%#<~+zzFu_zSmS8r))x{G`-BPTa4<$?URp~OUqJ2DH8G~C- zV1<5IeIkA0lZao9RmN&2m~zxrS3|zqd|3ue9ab-a-DmLSu||B&0LC_E<*_CS=0{j} zCUMWEZaa^C!b&K5KC5_NkYK)tp%*2Xi`ub*_{FSvLjAWF26sv@KSQ6+3FbZM(}jJ( zQ(al@tQ)J6QAc*_&kExM`AWbbzIX#`AMSRGLw9rMZVA>tMtoC-LhJ0h|gHeRBph z0$hM;3TFZ?z_f&O;9O`8=feeX5wrtbg25da>8o^wZqNgILT~5;xCql92EwH<7>2+w z7!H@i6)*}$!x$I~<6#0!gh`MBQvjD?a24hTz)hH&VLIFjGhi0rF3cR53%Ct)H{1jF z!F<4dnEPQ7EQSYR2|Nr-VL7aXN8vG81y90iz z4Yt7>@D{ucxDfLmybs&qL-+_jfluKx_#Ae^m#_=I0bGgM4d26$@Dt!N%+IhNeu0B< z2z~`zg!uz-5her)kOLAS333Cjf>mpbDF6kbFcbyc25k)T9N;!gX`l&f%0UIF2$i4; z;5y7nfa@^T;S|7y7~F@r4O18DLjyPsP6ynF!F`yf&I+ zLTCrL5Yqv0AqKZ$a2E!5VR}GM=mUMB9}ECohQU=B+=LkdLt!|KfGYsEVXlO$U>x8& z3~s~VHfUp!_W+k+u7&FXmmwc=F}Mwb+mMg1m>GbpFt`ab8*YcWa3|ai_rSeyA1s9X zVKF=aOW+|`3Xi}FSP758DtH1`!&C4yJOj_dI(PwIgqPtJ*Z>=0GrS6~!8UjU-h{W| z9e5AkhY#Q*_!vHg9q>8qgfHQ1*ahFhckn&@06)PV*bDpM7dQyN!eRIwj)2KQ-h(jY zfJDdzxgi z7z{&TC=7!Ua5-E7qu@#y17l$vTn&>T1t!B3m2p=qLRGmFOdlT1Ot*8tETx zr+<|2Hu>cpd<1=?ne>ZJppSk#eWE4wgG$i-nyaQZ&d@A)+s?PdBp($A?) z|7LO>+T2a(8_=hzK!2v-+1Nl~`Y~tIkC8si^7gc|>9f?LztW{!$V{c5QiMKAhyJwP zhtdwGf0A-J?Q{Ahv*?qIr5{prV#pMu|1mhV-!Y2*M)=-srQ6bkJ5H{nfd>f4jn{%mbFB?ZYb8^^>rgCjg z<@(&Uw5g|s%_J(;GE}N<@1T!ySJ-?&rP<(tuz8FMvf(4dp_2T3Mc7QClDv&da^n-U zy{Qy?QX#h7Lf>O6ZCon6F>glN&H1VDs=iBKf=cgGD!ON=T)22>>snUpcaAUrd+ceTfz5P5^)x99W?7A?)G@~*p*@>@i!Ie}d z<+>!8?;xogU)SwL+<|;?YfyrzOa-zI-lqcDJ}T12%zrgsWK7|>R1Wf`NBP=M=b4c< zBHcan9sB@$fUcY&ISt8a=*Ah6)P$&;b3hU#Lw+Ec`RXF$8&DERZc_nBa#ICJZc`m< zLOo~*r$b|C1})%hAoEyV>lC9z&UUpw1tbH19XP2 z&;xowALtJQ;W8KwBVjaL1><2NTm#p_4RABu26w`@Ik^tV!ys}Ms0tUt5EuqiVLmK` zr{EoU4-Ua`xu`?nH0S`GU>wYWJK-64A3lVke`IrDJ;;dJN-onbmW1j}F>d3fn?4FYCszp1ed|J zumBdpvmoQ-AHiP8&)|9?s0fXr8MK38a5=mQKfoR+nvXUU)P+tk3dX=)@FYA1;rz72 zpdy?FJ)k!%ftO(e~+gHW_EX$@z-6e(p?mP!jn_E12SS)c`~g+f_^2nCr6h_V$G1verhZe^<|AfTY)M8Uz*syL8w z|IatMYp-yr*S>yt|JA@d>196mP6kJSJi}Uc;NXsvPH5 zw8I1}#xj&D&v!)(hG915U?nzU3qHl~_!H$T@LkXdH(@wNVgo+MS2&5Ni@6>~Z6u-% z24gCwVNrTpMF9iuWUpp*37{h&x<|kw=J6 zJcq}RvG4H_zBtZ&C)l637cb#W>}=sMPNGyi&++)7{Q%!U&z#DZ=Kjwk>MUhKw5_|%zo(gha}&axGd63UnPz{M z#u&5BKDQ@y_nQ4VW`C~PpJ(>DX`$mW2^}{sbPt&Q1!jMt*7!&H+07OA2R#Pxdu1lH##a&YGRW)W;1=B1DT=Ssxi^q%<=DR*0S%KeIAz3Z8!VxoBa>W z{tic64US{}E@E(VME9ZD-@RFXf2s>)u9Qovs$2cZ6?0~0CV8hjcI+@*8WXMSXP$~U zn+#H3s``=UoJGujQFCfB^KV^Y^V?*ODPjJt>uvLjn{7s!e{+LH*MdG*^yc5X{$>9< zx!fTCad~~~YMAq;GmFcK8Rk4Qoqw?cT_GFM8=ahw%$z|hZ%|jf$xPU4&biI(>-yKq zEwu6rt*c=x-%vS+v162XxTj26u8?C-9Cz<>#&@5sr?#19USg)(t*hqo?!A;j(A9Hv zXXPz+-D>47Dt|GmmaeErEF=z{Yp->?mD8xaMved69Pg%`$}5a8m!dntm2f%bu*?W; za@(Q!N!>8<%x*I>TM!uS;@qK8R#I?6WA3?ph9*8}q0yemZ`>$rEjV$by%R`i9$_wT zy3vivCeqFCq?=xhw@WvB9ZCoL%*5cEhO7hJI(!04Pi&Cx-_w(CD3#q9+E7LoAe3E0 z9!m3^lh3$RmThR`(u~RgLg{-x+e9dXbCeVyzKO*&DRbaEYAn(0mlM&{)?F`8&IQOlU%TM&JTApg8mW4cHg*P?Beo?@;a! zc_>R1Ae5hkJd|8w1QeIP=d;fUWpI82bn6?)8N@gJ9SC`xkq;M8D1GDX`=G@cIeYmI z%@08fjWR9**@M1u^JCCLqa4EghUTZBg+>`VfrQ34bsr%#q5Ta|c2a&rc{JpqysQAB zJQng$lG~l{xI7;6P?FalP$+$m*%O2^IKKguxDO~azDLQ=A&;|40fy2y&Q1j_&aNmx zX#NRWXrc=cn$tlGO|=4q=1kB+Q$4`Y_@?f&geJ7V0aXhS%5xzPWsL%a(jD?pRw+Oz zm6aUYJzhD$Q2L(FT!b<>zX3H15Sp-{h33itL*skQ77h6x)KiN5Ubhtsc_?|Z6Hq99 z(^-k2?O7i17 z30j=-wh!IE{|5NRS=EroS+f8`=^JNpL5s6%3lN%Xf)<+V3lN&dK?_ZM0YcLxXrWPg zu>7X(ri3Q6zncjK2xYU7hq6@xLfJgzp=?orP+lAIQ1X5y-M^o8ea~mt5z65FZYBm8 z8sFalmEa8RQPMiVQ0ka3<0&(076PTnMK{X$Rc5?Z5_E^BET0M+hq+WLss+VgHPYH6 z`m1|GUJ1qRNW)yr!?Sn}?_oPCHgXu3pdlKeJ9=OeCgW*5gRyZAV;mM?G1lW{9K^Rc zi*p!#jl&p&$FUMGU@bnxZgg(!FuLG&q@jNkhmnM7n2uF=0^v=mW(PG<3-L%mU-ZKS z+=;Wi7JCk@+B=Ly48$Nz!BjktHTVEKpjRqXj&3rK=$lhUeJ2G9W)WYbVZBW49TUfc z>YOPm7yBf|N~SQErf6s_qq2jOC`xqeIk($8hc!hdG>=dK>$bCQ_aE%VvDwS0T&s6X zUDlQ}MP*E{q+rPH3Jp^rjWB2P)U#KMqvJz<(U*NxJ_y&@)c|aiC|h{^LN;5&VBsJ&W`oJ9;kY zKMwTl#D5&<36=ji&~rWiaiC{x50Q2*JQnmMX(K6K$HH>Y99Fv469@mHR!+A6Z>pU5 zEv!vP@KKJioMT&0432rmCOZ~^2@^$^ko9?6i zpWl=h=l|GNzL@_IDDS|3sFg#buw8h5Q@)n}uqltpf4WvqivM)2dtCqNTKD4q)3tez z$N5_4_&+$$jmSRl=w8%2M(4zwDZ1mTM^Oiz2b$$NALt6}JJ0z*bL5;4bYE1D^()P2 znVhtvYe&5ts#N8j!%CyNdr^#zWf_G)Lu-nz-7`2}r*XE_9Cu_-(LKgG&skr~=$NpU z(UtUm&+meF4r_|8xXyXb{(40-=j^YmpM)a3^vEv;FPr#Gal3D1%_V5N!dq{BP7@LJ zX|bTOIjy@{9k3d2RJ)mK!=N$Kn&dI9sm-(|W_uah-i7PbwEB50*C3B+4fB}R$eiZ= zerkolw^0E5u*BuDPAXru{SJ0a+jtm$Q!-H9cX!oPE3~6>2%}{>w?9Rud+6>r|5$zRTsb$6z&sp=oWY40bfB!FQTc zxcxe<2YJ;Tsm;Rxz{=yJ?!wJ}mb8uL0l5emVR7*MOL?U(SC2HOMp0 z?9+9_JkoW;Jifac^sozO!#vWp+OoG_&OTn$61@F#_VJ>2)a{qEj~BHj> z)1cMPi2ZW*ai%6x?3c5TGc_e-znp!XsUaf!UdmXTbRMcm0X(j+RA$mDK( z8kMgt;dSMuTzxI40+f|h@bUx|X}rPo4OGJN9+l#3rxJ{lmPz5{qIk6CwPa~oB}chy z9fm4XPw7PETQ`%NaSN4g^`av0!4Bi=402~?P+=GEzZYM^@C9;b$oy%vjf#?a%lyy* zD)y$bt>2G0jP}&RBvs2$@oE(+hiyfLtnI0AHiOElsDbi9YL48#oJv>Uq9R>tC%T6U zs*X{+;*zsY<5_AQ>P?M9tIAXPXk{t}jdmF|uA~AfY7~m5_JG<6E@NCLDu=q6im3Wg zsZ=r*o(`i@QgTt$DK4GRCvM4fGigMCnfmbBh024}LoDi}0ra%85l9XkjZ_E(J?GLBIX%14Qzkt%QNHK(P%dpe63`N@kcif} z0d3G0?a&?_&=H-`8C}p7ioYnn+yK7hlWcq?3q3$uj3X^pPvT|xftF>Y#fwRct4WK; zGFg_i*q*ewgtR!Hw76*{%aayIkrvOA7Dv8E#W35s3nVRy(&0Rhn@ET4NQb^ICoN7O zElwdV#*r46krua;7M)alU3nBaaWko?jhH7vw#GTxJ5=<-JpbwSy4^ZTN|H8WNXKgYW-QG}B=dJm8c7(>=i#K$ z8%TS7%;s*aCKjw_P^~dm1B_OaS$${*Wd!NiYJIRj>rrDZbs3}kr-p1JgC-8Vt-;24 zrsuu&cAl+|VA*tX6xDQt8Z7Z{aS$O>V-af9Mol{Clhtr!AJ(73_whD><83k~_Z$l0 zzlS@WE!p_Q#C1|6Ilq$GJ4jXAaJJgSSLew?vp*C(T?P zx$FIBb}nTzP3IPG9T2$|rO2^x(59{gh^RF0$=PP0I``JuUOJ8KTTER+Sl+#AjBedCy-}3}4lEb^1y6 zcCLyMtS&0N^t7yh%+*DOv%0A8BtEk`&FXJ;G5qG|TBT1)bybXHl`B|flC{beTIC8> znWR-}PP+- zx^~I?5Uat)bWLcV*@r2zNZyp461{*_$GrpLxfv zVANw&-1;+qK^C}vU349;M+|G5e`hkts8S)TEU`dabaHh6|q^=y7#=wu}Sxf(ZzYdxRu@qDi6vZlY``Fw}x z^Fhz&ZJy7EJ)d`aKG$|y>$}P`R2{t9PM+)joj1{Hr~mvpk;UHBfTaAgS!87gvYnodx9uekLXS?+Tt}avAl9uUPdcGsG7$Ghi<_s_53M2S*kwtPg zrSGh}zHWrElX>kth->w9#^tOh+UP;JQ@I{aH?N#EXE)|(?5XNbYfz{7^6jjxQPP8d zaoj_sbG0AK49z3V@9#US{>}-M=ll0G!!v|!TG#ZWm?l8{b7&`DuK+MEXORqiH@ut(^7x+2PL5lFG+vTHqyHXD`{Z}x{d$0_S6Y?wK%>5eaD(ZBGJHu>K zx0)x^9bKxqr1$tz9!r=}zsRhLM%EsZ^iVU-T2~qz*#-mON}>K}jk+|G92M%mrUVcl z!wgqcd2VxK$*UMot=Hr(Ft&|ueCevt@{Vtkw8j?p1B-ztA~r>?H`a3^E2Bf+r+Yoq zWjsTUMPOZN@}4g2th1Ket(-Y^mAOamYD8z}Fhp~H(m8kx$GjTEO((_ZEH=taHMPt$ za~q~wP4rsp$ot+s@2S=r3j6sDwUw%<92mwd5ad7&hzn$tbH0n935wBD0r2|Tl zPcuQuN7I)=ORj(tCi#+_9H^2Ix+**lofZB@B=kF~AARok&70v^&$_tAGc%KKVW>OX zWQG?p9KlexrV|;KWH^hVE+}-$(t!?FxlFjP1Wv+>FduRzwa_ubT54elov1!$_tnS!Ew(w@?Aw zpmpzr@&x{Z@4ddZsbXK|eQ&Sg=1`fF`mD@K4V87KVg2$&%x&?f?XWU|&^iOiL%4`p z6%^h2>#KE79i5h9ZpaFh@fs1pf3vGiU!!k=7U~6sX`Sb@#;HJE|E}#4`?u-QF43H- zZ)}cf+p%5e4&Ac9c>?40i1$vi=M(rB$3q1bOK(i!pc}|QZ%A>Yx)gj%AZxE7f3;+e zmW;29){JS&_}0v=zg3*JfpHgWvx>c`?L8H9QRv38FEl*i`OLultUan2Qn9(AWE75O zzc*tq)FX?~Dl8PkI2A2QB`eW-3{jU%#AF^Nr0@XWD&$npQ~YNX%c-DKe@{WDSpG^S z^Rd5YZQkrijT_F=BUo-QTeiaBiEJ}mb&THT@F>$1Zgm=Z!>i(c|C#V+kPSNAe7rN9 z@6_KDeih8pzy5stQ9OdmE36sHNGCi$dcw#cS6E~DoI9-J*dOCqr{YSPw91wp!(TCk zBZVz0K2sSx!py!MZ^ohum}!m?=29(~I*z@jBE~8bseR}he;K4fh3PQ-#b0p4q(Z|N zhN&rqKNXg5ZNk)q@&4m!AhDtSph9@o1CtmtOM3`0<(*c~%mS~+d;^FhJ$$T3x>c;z zrNHP|;?Dc|8jcd}+j@S&*oH!&3gg!{VN`Kf|6#P>mn?F@{wc#ztnGXOfBQ$d{{FY) z{l5O0Q-IwYfU3a6p7uU0R-Q#or8_7riHXpC{v=FB zCZ=F2?#47s#|+HGEX>9|xEFIU7xQo*=Hq@mfCX5HMOcg_Sc+wM5D#HF9>ybh6f5u; z9>+?o!V`EBPvL1igJcP#W}d4TYr`NbixId z&*5D{BLa~qf}$vf;Jm}Xp45>?I(kB=al%S><&7k3%cS)+=OoEjvi3S?w+^>x1tw% zLwTir(GUHRgaH_cK}bdl24e_@A{DpccBEk#h9ey#FcKLUh0#!+=U9xx9T<-ZxDyj` z7brV#Hb9)oa0;g4ZcM{;%)m^{!ff1wdoc%dF%S1)KJLc@Sb&9CgvD5brC5ds@er2d zVLXCIu>z0baje8DJb@?i6rRR2coxrLHJ-;BynwZM5$o_0*5hTof>-exUdJ1F6K~;d zY`{ir!e(s2R&2vNco*+sJKo0!*nyqcg%7bCd$1QD;bZK>etd#Y@fi-_b9{j>@fE(t zH#mrI@f{A~FuunR_z^$h2#(?yj^hM=#xKaiulNnW<0SsTpZE)Z;}rhEX`I1XoP!(s z;aAZ=CtL_aI3l1n%8NkllNW>9CRfYkYL{HCl9xgh)E+tS1RG^h4&_k+ynkWv{)NH& z7Y6TN7?+_EE=OftfoN1gRa8TD)Id$tg5GGj5_+Sd4)jJtUBsXsVo@Ir&=8FfhilLn zP0$q0&>Yv|I$RGmw;hiJv_vZ;qBU+n8?;3`v_}VYL??7c7j(sqxC!0R9X)U}dg2z` zieBiAKIn^n=#L}}z(5Q_GEy)YLogJnxDB@>4Z|=T=@@~L;2msZ6h>nV#$p`qz<5l+ zotTKbFbR{9i7A+hyD<&ZF#|I(3$t+#?!_F;#XQ`H`M4hsU;!3l5f)l*g37fG6Td@uA;9b0j?RXy_Uzl z-{2s=#dkP_!}uOQ;79y~BRGm%`^H5mfs!bND3nGSltnp|M+ICA-l{b&!KJtim2f$z zkHVlH03#Z_E?`teHB?6p)I=@R2K59OSD_BBMqR|99%4}+4bTwOCt$?k8Z<@|G(|Hs z$F;Z)*P{jEk${$Hg+#Q*4QPY5XovRbfR3P^0;4m!pet^~P3VU1=mF|6FnZz^+=^c4 zjXvlL>Nqg^BMAdA5QC766b!}?3`Ht#1Mi|4X&46TMljMb0wa-uQ5X%qAutx>a0kX? z0`9~_+=WS)j7&_yRNReen2s5kiCLJ9dvGu2U@qq2KFr7ccmNBq5R0%FORyBn@E{(- zay*Pj@F-T`F+7fyScNC>B%Z?4cm~hnIjqL>Sc4a^7B6BQUc!33j92g~Uc>8n18?Fj zyp0Xmh)vjxE!c`}cn9y|J#5GO_y9Yw6T9#sc4H6r;v;;Feb|pr@F_mS0ep@x@Fl*& z*Z2kp@h!f?Asoi{_yIrSCmg|19K&&(z|Z&vS@;#d;dh+GANUi0;cuM6KRAsuIE!;| zLpS`Yh}a1i!Vr!KM4||aq8N(fB9uT$ltL6rqYTQT9Ll2tE(Wi|8<*fxT!u=x9F=he zqEQ7^Q4Q5m12s_#wQ(h`LLFRgynb`kAS)}-76SAhR3lI ztMCM##8Y@0&)``+ht+r@B?@HM=SH}EFj!rRz@jo5_E*n+Lt zhIjBT-otjhj}Nc|JFyENVmJ0+FFwM@*oXc21fSwF9Kh%J0$<`Qe2s5#5Z~fE9KvCI zk00wP#W5Vm3H*#-kcD6I8-B-0=)3>P@Gtz0Q}_p`aR!=xj-eYyILAMna6y&g zYC3h4229o1n(NehQP}lS)W|n z0meY`R#O65^n!Ux8hQbi+AnBP&C z^8F*2LX?_e@H>;Aku|O@YK{#j=UQ9UOZM9L?b!NYGfWyY+AN1P+|TmfQMC&Y|9|M* z6J@O-{DNZ;9(iIuM{8Y2}7U@dbeb4 zHHCdYnpbgkET#pz3Uj^+q(1L=*U;a>-s8?Y^qog(xA45}8-xG9{-%))x2u?S{G5O8 zu1MNA?_Jfz^g&~Wr3@c!J`?QJP4BNV$~>6$cZ_#>OcUc|({&?#Q(EEQ{}W^2zW@(K BsxSZm literal 624128 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 z%0D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