HP2100: Latest changes from Dave Bryan.
hp2100_ipl.c: - Exposed "ipl_edtdelay" via a REG_HIDDEN register to allow user tuning of the EDT delay that works around a race condition in the HP 2000/Access Time-Shared BASIC system. - Corrected typos in comments and strings. - Merged SIMH 3.x and 4.x socket calls via conditionals, so that the module may be compiled for either version. hp2100_mux.c: - Corrected a typo in the RTS macro definition. hp2100_sys.c: - Added a cast to int for the parameter to "isspace" to avoid a compiler warning. hp2100_bugfixes.txt - Added a description of the IPL hidden register fix.
This commit is contained in:
parent
4baecec0b1
commit
1d6c14be3d
4 changed files with 117 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
|||
HP 2100 SIMULATOR BUG FIX WRITEUPS
|
||||
==================================
|
||||
Last update: 2015-01-03
|
||||
Last update: 2015-09-14
|
||||
|
||||
|
||||
1. PROBLEM: Booting from magnetic tape reports "HALT instruction, P: 77756
|
||||
|
@ -6789,3 +6789,27 @@
|
|||
modifying the S register directly.
|
||||
|
||||
STATUS: Fixed in version 4.0-0.
|
||||
|
||||
|
||||
|
||||
267. ENHANCEMENT: Add a register to the IPLI device to configure the DMA delay.
|
||||
|
||||
VERSION: 3.9-0
|
||||
|
||||
OBSERVATION: Occasionally, the 2000 Access terminal multiplexer does not
|
||||
initialize properly; the problem is more prevalent on multiprocessor
|
||||
systems.
|
||||
|
||||
There is a race condition between the system processor (SP) and the I/O
|
||||
processor (IOP) during initialization. The problem occurs if the IOP DMA
|
||||
completion interrupt routine finishes before the SP DMA completion
|
||||
interrupt routine. As a workaround, the simulator suspends the IOP process
|
||||
for one millisecond before signaling a DMA completion (EDT) interrupt.
|
||||
Depending on system loading, this time may be insufficient.
|
||||
|
||||
RESOLUTION: Modify "ipli_reg" (hp2100_ipl.c) to add a hidden register,
|
||||
EDTDELAY, that allows the user to configure the completion delay. The
|
||||
register value is expressed in milliseconds and defaults to one
|
||||
millisecond.
|
||||
|
||||
STATUS: Fixed in version 4.0-0.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_ipl.c: HP 2000 interprocessor link simulator
|
||||
|
||||
Copyright (c) 2002-2014, Robert M Supnik
|
||||
Copyright (c) 2002-2015, Robert M Supnik
|
||||
|
||||
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,10 @@
|
|||
|
||||
IPLI, IPLO 12875A interprocessor link
|
||||
|
||||
14-Sep-15 JDB Exposed "ipl_edtdelay" via a REG_HIDDEN to allow user tuning
|
||||
Corrected typos in comments and strings
|
||||
05-Jun-15 JDB Merged 3.x and 4.x versions using conditionals
|
||||
11-Feb-15 MP Revised ipl_detach and ipl_dscln for new sim_close_sock API
|
||||
30-Dec-14 JDB Added S-register parameters to ibl_copy
|
||||
12-Dec-12 MP Revised ipl_attach for new socket API
|
||||
25-Oct-12 JDB Removed DEV_NET to allow restoration of listening ports
|
||||
|
@ -72,6 +76,13 @@
|
|||
#include "hp2100_cpu.h"
|
||||
#include "sim_sock.h"
|
||||
#include "sim_tmxr.h"
|
||||
#include "sim_rev.h"
|
||||
|
||||
|
||||
#if (SIM_MAJOR >= 4)
|
||||
#define sim_close_sock(socket,master) sim_close_sock (socket)
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum { ipli, iplo } CARD_INDEX; /* card index number */
|
||||
|
||||
|
@ -172,6 +183,7 @@ REG ipli_reg [] = {
|
|||
{ ORDATA (HOLD, ipl [ipli].hold, 8) },
|
||||
{ DRDATA (TIME, ipl_ptime, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ipl_stopioe, 0) },
|
||||
{ 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 },
|
||||
{ NULL }
|
||||
|
@ -256,7 +268,7 @@ DEVICE iplo_dev = {
|
|||
The STC/CLC normally would cause a second "request device table" command
|
||||
to be recognized by the IOP, except that the IOP DMA setup routine
|
||||
"DMAXF" (in D61.asm) has specified an end-of-block CLC that holds off the
|
||||
IPL interrupt, and the completion interrupt routine "DMACP" ends with a
|
||||
IPL interrupt, and the completion interrupt routine "DMCMP" ends with a
|
||||
STC,C that clears the IPL flag.
|
||||
|
||||
In hardware, the two CPUs are essentially interlocked by the DMA
|
||||
|
@ -266,7 +278,7 @@ DEVICE iplo_dev = {
|
|||
that guarantee does not hold. If the STC/CLC occurs after the STC,C,
|
||||
then the IOP starts a second device table DMA transfer, which the SP is
|
||||
not expecting. The IOP never processes the subsequent "start
|
||||
timesharing" command, and the muxtiplexer is non-reponsive.
|
||||
timesharing" command, and the multiplexer is non-responsive.
|
||||
|
||||
We employ a workaround that decreases the incidence of the problem: DMA
|
||||
output completion interrupts are delayed to allow the other SIMH instance
|
||||
|
@ -276,7 +288,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.
|
||||
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.
|
||||
|
||||
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
|
||||
|
@ -574,10 +588,14 @@ return SCPE_OK;
|
|||
t_stat ipl_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
SOCKET newsock;
|
||||
uint32 i, t;
|
||||
char host [CBUFSIZE], port [CBUFSIZE], hostport [2 * CBUFSIZE + 3];
|
||||
char *tptr = NULL;
|
||||
t_stat r;
|
||||
|
||||
#if (SIM_MAJOR >= 4)
|
||||
|
||||
uint32 i, t;
|
||||
char host [CBUFSIZE], port [CBUFSIZE], hostport [2 * CBUFSIZE + 3];
|
||||
|
||||
t_bool is_active;
|
||||
|
||||
is_active = (uptr->flags & UNIT_ACTV) == UNIT_ACTV; /* is the connection active? */
|
||||
|
@ -636,6 +654,60 @@ if (tptr == NULL) { /* no memory? */
|
|||
return SCPE_MEM;
|
||||
}
|
||||
strcpy (tptr, hostport); /* copy ipaddr:port */
|
||||
|
||||
#else
|
||||
|
||||
uint32 i, t, ipa, ipp, oldf;
|
||||
|
||||
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;
|
||||
printf ("Connecting to IP address %d.%d.%d.%d, port %d\n",
|
||||
(ipa >> 24) & 0xff, (ipa >> 16) & 0xff,
|
||||
(ipa >> 8) & 0xff, ipa & 0xff, ipp);
|
||||
if (sim_log)
|
||||
fprintf (sim_log,
|
||||
"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;
|
||||
printf ("Listening on port %d\n", ipp);
|
||||
if (sim_log)
|
||||
fprintf (sim_log, "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? */
|
||||
|
@ -644,7 +716,7 @@ if (sim_switches & SWMASK ('W')) { /* wait? */
|
|||
if (t) /* established? */
|
||||
break;
|
||||
if ((i % 10) == 0) /* status every 10 sec */
|
||||
printf ("Waiting for connnection\n");
|
||||
printf ("Waiting for connection\n");
|
||||
sim_os_sleep (1); /* sleep 1 sec */
|
||||
}
|
||||
if (t) /* if connected (set by "ipl_check_conn" above) */
|
||||
|
@ -661,12 +733,12 @@ if (!(uptr->flags & UNIT_ATT)) /* attached? */
|
|||
return SCPE_OK;
|
||||
|
||||
if (uptr->flags & UNIT_ACTV)
|
||||
sim_close_sock (uptr->DSOCKET);
|
||||
sim_close_sock (uptr->DSOCKET, 1);
|
||||
|
||||
else {
|
||||
if (uptr->flags & UNIT_ESTB) /* if established, */
|
||||
sim_close_sock (uptr->DSOCKET); /* close data socket */
|
||||
sim_close_sock (uptr->LSOCKET); /* closen listen socket */
|
||||
sim_close_sock (uptr->DSOCKET, 0); /* close data socket */
|
||||
sim_close_sock (uptr->LSOCKET, 1); /* closen listen socket */
|
||||
}
|
||||
|
||||
free (uptr->filename); /* free string */
|
||||
|
@ -688,7 +760,7 @@ if (((uptr->flags & UNIT_ATT) == 0) ||
|
|||
(uptr->flags & UNIT_ACTV) ||
|
||||
((uptr->flags & UNIT_ESTB) == 0))
|
||||
return SCPE_NOFNC;
|
||||
sim_close_sock (uptr->DSOCKET);
|
||||
sim_close_sock (uptr->DSOCKET, 0);
|
||||
uptr->DSOCKET = 0;
|
||||
uptr->flags = uptr->flags & ~UNIT_ESTB;
|
||||
return SCPE_OK;
|
||||
|
@ -790,7 +862,7 @@ const int32 devi = ipli_dib.select_code;
|
|||
const int32 devp = ptr_dib.select_code;
|
||||
|
||||
if (ibl_copy (ipl_rom, devi, IBL_S_CLR, /* copy the boot ROM to memory and configure */
|
||||
IBL_SET_SC (devi) | devp)) /* the S register accordingly */
|
||||
IBL_SET_SC (devi) | devp)) /* the S register accordingly */
|
||||
return SCPE_IERR; /* return an internal error if the copy failed */
|
||||
|
||||
WritePW (PC + MAX_BASE, (~PC + 1) & DMASK); /* fix ups */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator
|
||||
|
||||
Copyright (c) 2002-2014, Robert M Supnik
|
||||
Copyright (c) 2002-2015, Robert M Supnik
|
||||
|
||||
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 @@
|
|||
|
||||
MUX,MUXL,MUXM 12920A terminal multiplexor
|
||||
|
||||
29-Jun-15 JDB Corrected typo in RTS macro definition
|
||||
24-Dec-14 JDB Added casts for explicit downward conversions
|
||||
10-Jan-13 MP Added DEV_MUX and additional DEVICE field values
|
||||
10-Feb-12 JDB Deprecated DEVNO in favor of SC
|
||||
|
@ -221,7 +222,7 @@
|
|||
#define OTC_SS2 0000002 /* SSn flops */
|
||||
#define OTC_SS1 0000001
|
||||
#define OTC_RW (OTC_ES2|OTC_ES1|OTC_SS2|OTC_SS1)
|
||||
#define RTS OCT_C2 /* C2 = rts */
|
||||
#define RTS OTC_C2 /* C2 = rts */
|
||||
#define DTR OTC_C1 /* C1 = dtr */
|
||||
|
||||
/* LIA, control */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_sys.c: HP 2100 simulator interface
|
||||
|
||||
Copyright (c) 1993-2014, Robert M. Supnik
|
||||
Copyright (c) 1993-2015, Robert M. Supnik
|
||||
|
||||
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 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
18-Jun-15 JDB Added cast to int for isspace parameter
|
||||
24-Dec-14 JDB Added casts to t_addr and t_value for 64-bit compatibility
|
||||
Made local routines static
|
||||
05-Feb-13 JDB Added hp_fprint_stopped to handle HLT instruction message
|
||||
|
@ -430,10 +431,12 @@ static const int32 vtab[] = {
|
|||
|
||||
#define FMTASC(x) ((x) < 040)? "<%03o>": "%c", (x)
|
||||
|
||||
#if (SIM_MAJOR >= 4)
|
||||
/* Use scp.c provided fprintf function */
|
||||
#define fprintf Fprintf
|
||||
#define fputs(_s,f) Fprintf(f,"%s",_s)
|
||||
#define fputc(_c,f) Fprintf(f,"%c",_c)
|
||||
#endif
|
||||
|
||||
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw)
|
||||
|
@ -615,7 +618,7 @@ t_stat r, ret;
|
|||
char *cptr, gbuf[CBUFSIZE];
|
||||
|
||||
cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
||||
while (isspace (*iptr)) iptr++; /* absorb spaces */
|
||||
while (isspace ((int) *iptr)) iptr++; /* absorb spaces */
|
||||
if ((sw & SWMASK ('A')) || ((*iptr == '\'') && iptr++)) { /* ASCII char? */
|
||||
if (iptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||
val[0] = (t_value) iptr[0] & 0177;
|
||||
|
|
Loading…
Add table
Reference in a new issue