diff --git a/HP2100/hp2100_bugfixes.txt b/HP2100/hp2100_bugfixes.txt index be2f05e8..5c415780 100644 --- a/HP2100/hp2100_bugfixes.txt +++ b/HP2100/hp2100_bugfixes.txt @@ -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. diff --git a/HP2100/hp2100_ipl.c b/HP2100/hp2100_ipl.c index 27d4391a..a50008d4 100644 --- a/HP2100/hp2100_ipl.c +++ b/HP2100/hp2100_ipl.c @@ -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 */ diff --git a/HP2100/hp2100_mux.c b/HP2100/hp2100_mux.c index 2f5cb950..23363ec7 100644 --- a/HP2100/hp2100_mux.c +++ b/HP2100/hp2100_mux.c @@ -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 */ diff --git a/HP2100/hp2100_sys.c b/HP2100/hp2100_sys.c index 2a6f6807..45b7c138 100644 --- a/HP2100/hp2100_sys.c +++ b/HP2100/hp2100_sys.c @@ -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;