1
0
mirror of https://github.com/simh/simh.git synced 2026-04-28 20:57:26 +00:00

Notes For V3.0-1

RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially
debugged.  Do NOT enable these features for normal operations.

1. New Features in 3.0-1

1.1 PDP-1

- Added block loader format support to LOAD.
- Changed BOOT PTR to allow loading of all of the first bank of memory.

1.2 PDP-18b Family

- Added PDP-4 EAE support.
- Added PDP-15 FP15 support.
- Added PDP-15 XVM support.
- Added PDP-15 "re-entrancy ECO".
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.

2. Bugs Fixed in 3.0-1

2.1 PDP-11/VAX

- Fixed bug in user disk size (found by Chaskiel M Grundman).

2.2 PDP-1

- Updated CPU, line printer, standard devices to detect indefinite I/O wait.
- Fixed incorrect logical, missing activate, break in drum simulator.
- Fixed bugs in instruction decoding, overprinting for line printer.

2.3 PDP-10

- Fixed bug in RP read header.

2.4 PDP-18b Family

- Fixed bug in PDP-4 line printer overprinting.
- Fixed bug in PDP-15 memory protect/skip interaction.
- Fixed bug in RF set size routine.
- Increased PTP TIME for PDP-15 operating systems.

2.5 PDP-8

- Fixed bug in DF, RF set size routine.

2.6 Nova

- Fixed bug in DSK set size routine.

2.7 1401

- Revised fetch to model hardware more closely.

2.8 Ibm1130

- Fixed bugs found by APL 1130.

2.9 Altairz80

- Fixed bug in real-time clock on Windows host.

2.10 HP2100

-- Fixed DR drum sizes.
-- Fixed DR variable capacity interaction with SAVE/RESTORE.

3. New Features in 3.0 vs prior releases

3.1 SCP and Libraries

- Added ASSIGN/DEASSIGN (logical name) commands.
- Changed RESTORE to unconditionally detach files.
- Added E11 and TPC format support to magtape library.
- Fixed bug in SHOW CONNECTIONS.
- Added USE_ADDR64 support

3.2 All magtapes

- Magtapes support SIMH format, E11 format, and TPC format (read only).
- SET <tape_unit> FORMAT=format sets the specified tape unit's format.
- SHOW <tape_unit> FORMAT displays the specified tape unit's format.
- Tape format can also be set as part of the ATTACH command, using
  the -F switch.

3.3 VAX

- VAX can be compiled without USE_INT64.
- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support
  files > 2GB.
- VAX ROM has speed control (SET ROM DELAY/NODELAY).

4. Bugs Fixed in 3.0 vs prior releases

4.1 VAX

- Fixed CVTfi bug: integer overflow not set if exponent out of range
- Fixed EMODx bugs:
  o First and second operands reversed
  o Separated fraction received wrong exponent
  o Overflow calculation on separated integer incorrect
  o Fraction not set to zero if exponent out of range
- Fixed interval timer and ROM access to pass power-up self-test even on very
  fast host processors (fixes from Mark Pizzolato).

4.2 1401

- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS.
- Fixed MCE bug, BS off by 1 if zero suppress.
- Fixed chaining bug, D lost if return to SCP.
- Fixed H branch, branch occurs after continue.
- Added check for invalid 8 character MCW, LCA.
- Fixed magtape load-mode end of record response.

4.3 Nova

- Fixed DSK variable size interaction with restore.

4.4 PDP-1

- Fixed DT variable size interaction with restore.

4.5 PDP-11

- Fixed DT variable size interaction with restore.
- Fixed bug in MMR1 update (found by Tim Stark).
- Added XQ features and fixed bugs:
  o Corrected XQ interrupts on IE state transition (code by Tom Evans).
  o Added XQ interrupt clear on soft reset.
  o Removed XQ interrupt when setting XL or RL (multiple people).
  o Added SET/SHOW XQ STATS.
  o Added SHOW XQ FILTERS.
  o Added ability to split received packet into multiple buffers.
  o Added explicit runt and giant packet processing.

4.6 PDP-18B

- Fixed DT, RF variable size interaction with restore.
- Fixed MT bug in MTTR.

4.7 PDP-8

- Fixed DT, DF, RF, RX variable size interaction with restore.
- Fixed MT bug in SKTR.

4.8 HP2100

- Fixed bug in DP (13210A controller only), DQ read status.
- Fixed bug in DP, DQ seek complete.

4.9 GRI

- Fixed bug in SC queue pointer management.
This commit is contained in:
Bob Supnik
2003-07-31 16:17:00 -07:00
committed by Mark Pizzolato
parent 4ffd3be790
commit f9564b81b9
74 changed files with 6938 additions and 2812 deletions

View File

@@ -13,14 +13,17 @@ commands may NOT be accurate. This should probably be fixed.
* usual yada-yada. Please keep this notice and the copyright in any distributions
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
*
* Revision History
* 15-jun-03 moved actual read on XIO read to end of time interval,
* as the APL boot card required 2 instructions to run between the
* time read was initiated and the time the data was read (a jump and a wait)
*
* 01-sep-02 corrected treatment of -m and -r flags in dsk_attach
* in cgi mode, so that file is opened readonly but emulated
* disk is writable.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to simh@ibm1130.org
*/
#include "ibm1130_defs.h"
@@ -75,6 +78,7 @@ static int16 dsk_sec[DSK_NUMDR] = {0}; /* next-sector-up */
static char dsk_lastio[DSK_NUMDR]; /* last stdio operation: IO_READ or IO_WRITE */
int32 dsk_swait = 50; /* seek time -- see how short a delay we can get away with */
int32 dsk_rwait = 50; /* rotate time */
static t_bool raw_disk_debug = FALSE;
static t_stat dsk_svc (UNIT *uptr);
static t_stat dsk_reset (DEVICE *dptr);
@@ -141,6 +145,15 @@ static int32 dsk_ilswlevel[DSK_NUMDR] =
2, 2, 2, 2
};
typedef enum {DSK_FUNC_IDLE, DSK_FUNC_READ, DSK_FUNC_VERIFY, DSK_FUNC_WRITE, DSK_FUNC_SEEK, DSK_FUNC_FAILED} DSK_FUNC;
static struct tag_dsk_action { /* stores data needed for pending IO activity */
int32 io_address;
uint32 io_filepos;
int io_nwords;
int io_sector;
} dsk_action[DSK_NUMDR];
/* xio_disk - XIO command interpreter for the disk drives */
/*
* device status word:
@@ -167,7 +180,7 @@ extern void void_backtrace (int afrom, int ato);
void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
{
int i, rev, nsteps, newcyl, sec, nwords;
t_addr newpos;
uint32 newpos; // changed from t_addr to uint32 in anticipation of simh 64-bit development
char msg[80];
UNIT *uptr = dsk_unit+drv;
int16 buf[DSK_NUMWD];
@@ -195,7 +208,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
nwords = M[iocc_addr++ & mem_mask]; /* get word count w/o upsetting SAR/SBR */
if (nwords == 0) /* this is bad -- locks up disk controller ! */
if (nwords == 0) /* this is bad -- on real 1130, this locks up disk controller ! */
break;
if (! BETWEEN(nwords, 1, DSK_NUMWD)) { /* count bad */
@@ -205,49 +218,32 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
sec = modify & 0x07; /* get sector on cylinder */
if ((modify & 0x0080) == 0) { /* it's real if not a read check */
if ((modify & 0x0080) == 0) { /* it's a real read if it's not a read check */
// ah. We have a problem. The APL boot card counts on there being time for at least one
// more instruction to execute between the XIO read and the time the data starts loading
// into core. So, we have to defer the actual read operation a bit. Might as well wait
// until it's time to issue the operation complete interrupt. This means saving the
// IO information, then performing the actual read in dsk_svc.
newpos = (uptr->CYL*DSK_NUMSC*DSK_NUMSF + sec)*2*DSK_NUMWD;
if (MEM_MAPPED(uptr)) {
memcpy(buf, (char *) uptr->filebuf + newpos, 2*DSK_NUMWD);
}
else {
if (uptr->pos != newpos || dsk_lastio[drv] != IO_READ) {
fseek(uptr->fileref, newpos, SEEK_SET);
dsk_lastio[drv] = IO_READ;
}
fxread(buf, 2, DSK_NUMWD, uptr->fileref); // read whole sector so we're in position for next read
uptr->pos = newpos + 2*DSK_NUMWD;
}
dsk_action[drv].io_address = iocc_addr;
dsk_action[drv].io_nwords = nwords;
dsk_action[drv].io_sector = sec;
dsk_action[drv].io_filepos = newpos;
void_backtrace(iocc_addr, iocc_addr + nwords - 1); // mark prev instruction as altered
trace_io("* DSK%d read %d words from %d.%d (%x, %x) to M[%04x-%04x]", drv, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
(iocc_addr + nwords - 1) & mem_mask);
// // this will help debug the monitor by letting me watch phase loading
// if (nwords >= 3)
// printf("* DSK%d XIO @ %04x read %d words from %d.%d (%x, %x) to M[%04x-%04x]\n", drv, prev_IAR, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
// (iocc_addr + nwords - 1) & mem_mask);
i = uptr->CYL*8 + sec;
if (buf[0] != i)
printf("*DSK read bad sector#\n");
for (i = 0; i < nwords; i++)
M[(iocc_addr+i) & mem_mask] = buf[i];
#ifdef TRACE_DMS_IO
if (trace_dms)
tracesector(0, nwords, iocc_addr & mem_mask, uptr->CYL*8 + sec);
#endif
uptr->FUNC = DSK_FUNC_READ;
}
else
else {
trace_io("* DSK%d verify %d.%d (%x)", drv, uptr->CYL, sec, uptr->CYL*8 + sec);
uptr->FUNC = func;
sim_activate(uptr, dsk_rwait);
if (raw_disk_debug)
printf("* DSK%d verify %d.%d (%x)", drv, uptr->CYL, sec, uptr->CYL*8 + sec);
uptr->FUNC = DSK_FUNC_VERIFY;
}
sim_activate(uptr, dsk_rwait);
break;
case XIO_INITW:
@@ -279,7 +275,8 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
trace_io("* DSK%d wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)", drv, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
// printf("* DSK%d XIO @ %04x wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)\n", drv, prev_IAR, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
if (raw_disk_debug)
printf("* DSK%d XIO @ %04x wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)\n", drv, prev_IAR, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
#ifdef TRACE_DMS_IO
if (trace_dms)
@@ -309,7 +306,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
uptr->pos = newpos + 2*DSK_NUMWD;
}
uptr->FUNC = func;
uptr->FUNC = DSK_FUNC_WRITE;
sim_activate(uptr, dsk_rwait);
break;
@@ -332,7 +329,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
else if (newcyl >= DSK_NUMCY)
newcyl = DSK_NUMCY-1;
uptr->FUNC = func;
uptr->FUNC = DSK_FUNC_SEEK;
uptr->CYL = newcyl;
sim_activate(uptr, dsk_swait); /* schedule interrupt */
@@ -371,30 +368,78 @@ static void diskfail (UNIT *uptr, int errflag)
{
sim_cancel(uptr); /* cancel any pending ops */
SETBIT(uptr->flags, errflag); /* set the error flag */
uptr->FUNC = XIO_FAILED; /* tell svc routine why it failed */
uptr->FUNC = DSK_FUNC_FAILED; /* tell svc routine why it failed */
sim_activate(uptr, 1); /* schedule an immediate op complete interrupt */
}
t_stat dsk_svc (UNIT *uptr)
{
int drv = uptr - dsk_unit;
int drv = uptr - dsk_unit, i, nwords, sec;
int16 buf[DSK_NUMWD];
uint32 newpos; // changed from t_addr to uint32 in anticipation of simh 64-bit development
int32 iocc_addr;
if (uptr->FUNC == DSK_FUNC_IDLE) /* service function called with no activity? not good, but ignore */
return SCPE_OK;
CLRBIT(dsk_dsw[drv], DSK_DSW_DISK_BUSY); /* activate operation complete interrupt */
CLRBIT(dsk_dsw[drv], DSK_DSW_DISK_BUSY); /* activate operation complete interrupt */
SETBIT(dsk_dsw[drv], DSK_DSW_OP_COMPLETE);
if (uptr->flags & (UNIT_OPERR|UNIT_HARDERR)) { /* word count error or data error */
SETBIT(dsk_dsw[drv], DSK_DSW_DATA_ERROR);
CLRBIT(uptr->flags, UNIT_OPERR); /* but don't clear hard error */
CLRBIT(uptr->flags, UNIT_OPERR); /* soft error is one time occurrence; don't clear hard error */
}
/* schedule interrupt */
SETBIT(ILSW[dsk_ilswlevel[drv]], dsk_ilswbit[drv]);
#ifdef XXXX
switch (uptr->FUNC) {
case XIO_CONTROL:
case XIO_INITR:
case XIO_INITW:
case XIO_FAILED:
switch (uptr->FUNC) { /* take care of business */
case DSK_FUNC_IDLE:
case DSK_FUNC_VERIFY:
case DSK_FUNC_WRITE:
case DSK_FUNC_SEEK:
case DSK_FUNC_FAILED:
break;
case DSK_FUNC_READ: /* actually read the data into core */
iocc_addr = dsk_action[drv].io_address; /* recover saved parameters */
nwords = dsk_action[drv].io_nwords;
newpos = dsk_action[drv].io_filepos;
sec = dsk_action[drv].io_sector;
if (MEM_MAPPED(uptr)) {
memcpy(buf, (char *) uptr->filebuf + newpos, 2*DSK_NUMWD);
}
else {
if (uptr->pos != newpos || dsk_lastio[drv] != IO_READ) {
fseek(uptr->fileref, newpos, SEEK_SET);
dsk_lastio[drv] = IO_READ;
uptr->pos = newpos;
}
fxread(buf, 2, DSK_NUMWD, uptr->fileref); // read whole sector so we're in position for next read
uptr->pos = newpos + 2*DSK_NUMWD;
}
void_backtrace(iocc_addr, iocc_addr + nwords - 1); // mark prev instruction as altered
trace_io("* DSK%d read %d words from %d.%d (%x, %x) to M[%04x-%04x]", drv, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
(iocc_addr + nwords - 1) & mem_mask);
// // this will help debug the monitor by letting me watch phase loading
if (raw_disk_debug)
printf("* DSK%d XIO @ %04x read %d words from %d.%d (%x, %x) to M[%04x-%04x]\n", drv, prev_IAR, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
(iocc_addr + nwords - 1) & mem_mask);
i = uptr->CYL*8 + sec;
if (buf[0] != i)
printf("*DSK read bad sector #\n");
for (i = 0; i < nwords; i++)
M[(iocc_addr+i) & mem_mask] = buf[i];
#ifdef TRACE_DMS_IO
if (trace_dms)
tracesector(0, nwords, iocc_addr & mem_mask, uptr->CYL*8 + sec);
#endif
break;
default:
@@ -402,8 +447,8 @@ t_stat dsk_svc (UNIT *uptr)
break;
}
uptr->FUNC = -1; // we're done with this operation
#endif
uptr->FUNC = DSK_FUNC_IDLE; // we're done with this operation
return SCPE_OK;
}
@@ -428,7 +473,7 @@ t_stat dsk_reset (DEVICE *dptr)
CLRBIT(uptr->flags, UNIT_OPERR|UNIT_HARDERR);
uptr->CYL = 0;
uptr->FUNC = -1;
uptr->FUNC = DSK_FUNC_IDLE;
dsk_dsw[drv] = (uptr->flags & UNIT_ATT) ? DSK_DSW_CARRIAGE_HOME : 0;
}
@@ -450,7 +495,7 @@ static t_stat dsk_attach (UNIT *uptr, char *cptr)
return rval;
uptr->CYL = 0; // reset the device
uptr->FUNC = -1;
uptr->FUNC = DSK_FUNC_IDLE;
dsk_dsw[drv] = DSK_DSW_CARRIAGE_HOME;
CLRBIT(uptr->flags, UNIT_RO|UNIT_ROABLE|UNIT_BUFABLE|UNIT_BUF|UNIT_RONLY|UNIT_OPERR|UNIT_HARDERR);
@@ -479,6 +524,7 @@ static t_stat dsk_attach (UNIT *uptr, char *cptr)
}
enable_dms_tracing(sim_switches & SWMASK('D'));
raw_disk_debug = sim_switches & SWMASK('G');
return SCPE_OK;
}
@@ -498,7 +544,7 @@ static t_stat dsk_detach (UNIT *uptr)
calc_ints();
uptr->CYL = 0;
uptr->FUNC = -1;
uptr->FUNC = DSK_FUNC_IDLE;
dsk_dsw[drv] = DSK_DSW_NOT_READY;
if (drv == 0) {
@@ -518,7 +564,7 @@ static t_stat dsk_boot (int unitno, DEVICE *dptr)
if ((rval = reset_all(0)) != SCPE_OK)
return rval;
return load_cr_boot(unitno);
return load_cr_boot(unitno, sim_switches);
}
#ifdef TRACE_DMS_IO