1
0
mirror of https://github.com/open-simh/simh.git synced 2026-04-29 21:27:07 +00:00

Notes For V3.8

The makefile now works for Linux and most Unix's. Howevr, for Solaris
and MacOS, you must first export the OSTYPE environment variable:

> export OSTYPE
> make

Otherwise, you will get build errors.

1. New Features

1.1 3.8-0

1.1.1 SCP and Libraries

- BREAK, NOBREAK, and SHOW BREAK with no argument will set, clear, and
  show (respectively) a breakpoint at the current PC.

1.1.2 GRI

- Added support for the GRI-99 processor.

1.1.3 HP2100

- Added support for the BACI terminal interface.
- Added support for RTE OS/VMA/EMA, SIGNAL, VIS firmware extensions.

1.1.4 Nova

- Added support for 64KW memory (implemented in third-party CPU's).

1.1.5 PDP-11

- Added support for DC11, RC11, KE11A, KG11A.
- Added modem control support for DL11.
- Added ASCII character support for all 8b devices.

1.2 3.8-1

1.2.1 SCP and libraries

- Added capability to set line connection order for terminal multiplexers.

1.2.2 HP2100

- Added support for 12620A/12936A privileged interrupt fence.
- Added support for 12792C eight-channel asynchronous multiplexer.

2. Bugs Fixed

Please see the revision history on http://simh.trailing-edge.com or
in the source module sim_rev.h.
This commit is contained in:
Bob Supnik
2009-02-08 09:06:00 -08:00
committed by Mark Pizzolato
parent 59aa4a73b1
commit 9c4779c061
286 changed files with 40587 additions and 19094 deletions

View File

@@ -1,6 +1,6 @@
/* id_io.c: Interdata CPU-independent I/O routines
Copyright (c) 2001-2006, Robert M. Supnik
Copyright (c) 2001-2008, 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"),
@@ -84,6 +84,7 @@ uint32 sch (uint32 dev, uint32 op, uint32 dat);
void sch_ini (t_bool dtpl);
t_stat sch_reset (DEVICE *dptr);
t_stat sch_set_nchan (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat sch_show_nchan (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat sch_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc);
/* Selector channel data structures
@@ -113,8 +114,8 @@ REG sch_reg[] = {
};
MTAB sch_mod[] = {
{ MTAB_XTD|MTAB_VDV|MTAB_VAL, 0, "channels", "CHANNELS",
&sch_set_nchan, NULL, &sch_reg[0] },
{ MTAB_XTD|MTAB_VDV, 0, "channels", "CHANNELS",
&sch_set_nchan, &sch_show_nchan, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "0", NULL,
NULL, &sch_show_reg, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "1", NULL,
@@ -166,14 +167,16 @@ switch (op) { /* case IO op */
case IO_WD: /* write data */
if (pawidth != PAWIDTH32) { /* 16b? max 4 */
if (sch_wdc[ch] >= 4) break; /* stop at 4 */
if (sch_wdc[ch] >= 4) /* stop at 4 */
break;
sch_sa[ch] = ((sch_sa[ch] << 8) | /* ripple ea to sa */
(sch_ea[ch] >> 8)) & DMASK16;
sch_ea[ch] = ((sch_ea[ch] << 8) | /* ripple ea low */
dat) & DMASK16; /* insert byte */
}
else { /* 32b? max 6 */
if (sch_wdc[ch] >= 6) break; /* stop at 6 */
if (sch_wdc[ch] >= 6) /* stop at 6 */
break;
if (sch_wdc[ch] != 5) { /* if not last */
sch_sa[ch] = ((sch_sa[ch] << 8) | /* ripple ea<15:8> to sa */
((sch_ea[ch] >> 8) & DMASK8)) & PAMASK32;
@@ -186,11 +189,14 @@ switch (op) { /* case IO op */
break;
case IO_SS: /* status */
if (sch_cmd[ch] & SCHC_GO) return STA_BSY; /* test busy */
if (sch_cmd[ch] & SCHC_SSTA) return 0; /* test sch sta */
if (sch_cmd[ch] & SCHC_GO) /* test busy */
return STA_BSY;
if (sch_cmd[ch] & SCHC_SSTA) /* test sch sta */
return 0;
else {
sdv = sch_sdv[ch]; /* get dev */
if (dev_tab[sdv] == 0) return CC_V; /* not there? */
if (dev_tab[sdv] == 0) /* not there? */
return CC_V;
dev_tab[sdv] (sdv, IO_ADR, 0); /* select dev */
t = dev_tab[sdv] (sdv, IO_SS, 0); /* get status */
return t & ~STA_BSY; /* clr busy */
@@ -232,7 +238,8 @@ t_bool sch_blk (uint32 dev)
{
uint32 ch = sch_tab[dev] - 1;
if ((ch < sch_max) && (sch_cmd[ch] & SCHC_GO)) return TRUE;
if ((ch < sch_max) && (sch_cmd[ch] & SCHC_GO))
return TRUE;
return FALSE;
}
@@ -240,7 +247,8 @@ return FALSE;
void sch_adr (uint32 ch, uint32 dev)
{
if (ch < sch_max) sch_sdv[ch] = dev;
if (ch < sch_max)
sch_sdv[ch] = dev;
return;
}
@@ -250,7 +258,8 @@ t_bool sch_actv (uint32 ch, uint32 dev)
{
if ((ch < sch_max) && /* chan valid, */
(sch_cmd[ch] & SCHC_GO) && /* on, and */
(sch_sdv[ch] == dev)) return TRUE; /* set for dev? */
(sch_sdv[ch] == dev)) /* set for dev? */
return TRUE;
return FALSE; /* no */
}
@@ -260,7 +269,8 @@ uint32 sch_rdmem (uint32 ch, uint8 *buf, uint32 cnt)
{
uint32 addr, end, xfr, inc;
if ((ch >= sch_max) || ((sch_cmd[ch] & SCHC_GO) == 0)) return 0;
if ((ch >= sch_max) || ((sch_cmd[ch] & SCHC_GO) == 0))
return 0;
addr = sch_sa[ch]; /* start */
end = sch_ea[ch]; /* end */
xfr = MIN (cnt, end - addr + 1); /* sch xfr cnt */
@@ -280,7 +290,8 @@ uint32 sch_wrmem (uint32 ch, uint8 *buf, uint32 cnt)
{
uint32 addr, end, xfr, inc;
if ((ch >= sch_max) || ((sch_cmd[ch] & SCHC_GO) == 0)) return 0;
if ((ch >= sch_max) || ((sch_cmd[ch] & SCHC_GO) == 0))
return 0;
addr = sch_sa[ch]; /* start */
end = sch_ea[ch]; /* end */
xfr = MIN (cnt, end - addr + 1); /* sch xfr cnt */
@@ -339,18 +350,22 @@ DIB *dibp;
uint32 i, newmax;
t_stat r;
if (cptr == NULL) return SCPE_ARG;
if (cptr == NULL)
return SCPE_ARG;
newmax = get_uint (cptr, 10, SCH_NUMCH, &r); /* get new max */
if ((r != SCPE_OK) || (newmax == sch_max)) return r; /* err or no chg? */
if (newmax == 0) return SCPE_ARG; /* must be > 0 */
if ((r != SCPE_OK) || (newmax == sch_max)) /* err or no chg? */
return r;
if (newmax == 0) /* must be > 0 */
return SCPE_ARG;
if (newmax < sch_max) { /* reducing? */
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && (dibp->sch >= (int32) newmax)) { /* dev using chan? */
printf ("Device %02X uses channel %d\n",
dibp->dno, dibp->sch);
if (sim_log) fprintf (sim_log, "Device %02X uses channel %d\n",
dibp->dno, dibp->sch);
dibp->dno, dibp->sch);
if (sim_log)
fprintf (sim_log, "Device %02X uses channel %d\n",
dibp->dno, dibp->sch);
return SCPE_OK;
}
}
@@ -360,12 +375,22 @@ sch_reset_ch (sch_max); /* reset chan */
return SCPE_OK;
}
/* Show number of channels */
t_stat sch_show_nchan (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf (st, "channels=%d", sch_max);
return SCPE_OK;
}
/* Show channel registers */
t_stat sch_show_reg (FILE *st, UNIT *uptr, int32 val, void *desc)
{
if (val < 0) return SCPE_IERR;
if (val >= (int32) sch_max) fprintf (st, "Channel %d disabled\n", val);
if (val < 0)
return SCPE_IERR;
if (val >= (int32) sch_max)
fprintf (st, "Channel %d disabled\n", val);
else {
fprintf (st, "SA: %05X\n", sch_sa[val]);
fprintf (st, "EA: %05X\n", sch_ea[val]);
@@ -383,7 +408,8 @@ void sch_ini (t_bool dtpl)
{
uint32 i;
for (i = 0; i < sch_max; i++) sch_tplte[i] = i;
for (i = 0; i < sch_max; i++)
sch_tplte[i] = i;
sch_tplte[sch_max] = TPL_END;
return;
}
@@ -453,9 +479,12 @@ return armdis;
int32 io_2b (int32 val, int32 pos, int32 old)
{
int32 t = (val >> pos) & 3;
if (t == 0) return old;
if (t == 1) return 1;
if (t == 2) return 0;
if (t == 0)
return old;
if (t == 1)
return 1;
if (t == 2)
return 0;
return old ^1;
}
@@ -465,9 +494,12 @@ uint32 IOReadBlk (uint32 loc, uint32 cnt, uint8 *buf)
{
uint32 i;
if (!MEM_ADDR_OK (loc) || (cnt == 0)) return 0;
if (!MEM_ADDR_OK (loc + cnt - 1)) cnt = MEMSIZE - loc;
for (i = 0; i < cnt; i++) buf[i] = IOReadB (loc + i);
if (!MEM_ADDR_OK (loc) || (cnt == 0))
return 0;
if (!MEM_ADDR_OK (loc + cnt - 1))
cnt = MEMSIZE - loc;
for (i = 0; i < cnt; i++)
buf[i] = IOReadB (loc + i);
return cnt;
}
@@ -475,9 +507,12 @@ uint32 IOWriteBlk (uint32 loc, uint32 cnt, uint8 *buf)
{
uint32 i;
if (!MEM_ADDR_OK (loc) || (cnt == 0)) return 0;
if (!MEM_ADDR_OK (loc + cnt - 1)) cnt = MEMSIZE - loc;
for (i = 0; i < cnt; i++) IOWriteB (loc + i, buf[i]);
if (!MEM_ADDR_OK (loc) || (cnt == 0))
return 0;
if (!MEM_ADDR_OK (loc + cnt - 1))
cnt = MEMSIZE - loc;
for (i = 0; i < cnt; i++)
IOWriteB (loc + i, buf[i]);
return cnt;
}
@@ -490,14 +525,19 @@ DIB *dibp;
uint32 newch;
t_stat r;
if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR;
if (cptr == NULL)
return SCPE_ARG;
if (uptr == NULL)
return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
if (dptr == NULL)
return SCPE_IERR;
dibp = (DIB *) dptr->ctxt;
if ((dibp == NULL) || (dibp->sch < 0)) return SCPE_IERR;
if ((dibp == NULL) || (dibp->sch < 0))
return SCPE_IERR;
newch = get_uint (cptr, 16, sch_max - 1, &r); /* get new */
if (r != SCPE_OK) return r;
if (r != SCPE_OK)
return r;
dibp->sch = newch; /* store */
return SCPE_OK;
}
@@ -509,11 +549,14 @@ t_stat show_sch (FILE *st, UNIT *uptr, int32 val, void *desc)
DEVICE *dptr;
DIB *dibp;
if (uptr == NULL) return SCPE_IERR;
if (uptr == NULL)
return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
if (dptr == NULL)
return SCPE_IERR;
dibp = (DIB *) dptr->ctxt;
if ((dibp == NULL) || (dibp->sch < 0)) return SCPE_IERR;
if ((dibp == NULL) || (dibp->sch < 0))
return SCPE_IERR;
fprintf (st, "selch=%X", dibp->sch);
return SCPE_OK;
}
@@ -527,15 +570,21 @@ DIB *dibp;
uint32 newdev;
t_stat r;
if (cptr == NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR;
if (cptr == NULL)
return SCPE_ARG;
if (uptr == NULL)
return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
if (dptr == NULL)
return SCPE_IERR;
dibp = (DIB *) dptr->ctxt;
if (dibp == NULL) return SCPE_IERR;
if (dibp == NULL)
return SCPE_IERR;
newdev = get_uint (cptr, 16, DEV_MAX, &r); /* get new */
if ((r != SCPE_OK) || (newdev == dibp->dno)) return r;
if (newdev == 0) return SCPE_ARG; /* must be > 0 */
if ((r != SCPE_OK) || (newdev == dibp->dno))
return r;
if (newdev == 0) /* must be > 0 */
return SCPE_ARG;
dibp->dno = newdev; /* store */
return SCPE_OK;
}
@@ -547,11 +596,14 @@ t_stat show_dev (FILE *st, UNIT *uptr, int32 val, void *desc)
DEVICE *dptr;
DIB *dibp;
if (uptr == NULL) return SCPE_IERR;
if (uptr == NULL)
return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
if (dptr == NULL)
return SCPE_IERR;
dibp = (DIB *) dptr->ctxt;
if ((dibp == NULL) || (dibp->dno == 0)) return SCPE_IERR;
if ((dibp == NULL) || (dibp->dno == 0))
return SCPE_IERR;
fprintf (st, "devno=%02X", dibp->dno);
return SCPE_OK;
}
@@ -571,35 +623,43 @@ for (i = 0; i < DEVNO; i++) {
dev_tab[i] = NULL;
sch_tab[i] = 0;
}
for (i = 0; i < (INTSZ * 32); i++) int_tab[i] = 0;
for (i = 0; i < (DEVNO / 32); i++) dmap[i] = 0;
for (i = 0; i < (INTSZ * 32); i++)
int_tab[i] = 0;
for (i = 0; i < (DEVNO / 32); i++)
dmap[i] = 0;
/* Test each device for conflict; add to map; init tables */
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru devices */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if ((dibp == NULL) || (dptr->flags & DEV_DIS)) continue; /* exist, enabled? */
if ((dibp == NULL) || (dptr->flags & DEV_DIS)) /* exist, enabled? */
continue;
dno = dibp->dno; /* get device num */
if (dibp->ini) dibp->ini (TRUE); /* gen dno template */
if (dibp->ini) /* gen dno template */
dibp->ini (TRUE);
tplte = dibp->tplte; /* get template */
if (tplte == NULL) tplte = dflt_tplte; /* none? use default */
if (tplte == NULL) /* none? use default */
tplte = dflt_tplte;
for ( ; *tplte != TPL_END; tplte++) { /* loop thru template */
t = (dno + *tplte) & DEV_MAX; /* loop thru template */
dmsk = 1u << (t & 0x1F); /* bit to test */
doff = t / 32; /* word to test */
if (dmap[doff] & dmsk) { /* in use? */
printf ("Device number conflict, devno = %02X\n", t);
if (sim_log) fprintf (sim_log,
"Device number conflict, devno = %02X\n", t);
if (sim_log)
fprintf (sim_log, "Device number conflict, devno = %02X\n", t);
return TRUE;
}
dmap[doff] = dmap[doff] | dmsk;
if (dibp->sch >= 0) sch_tab[t] = dibp->sch + 1;
if (dibp->sch >= 0)
sch_tab[t] = dibp->sch + 1;
dev_tab[t] = dibp->iot;
}
if (dibp->ini) dibp->ini (FALSE); /* gen int template */
if (dibp->ini) /* gen int template */
dibp->ini (FALSE);
tplte = dibp->tplte; /* get template */
if (tplte == NULL) tplte = dflt_tplte; /* none? use default */
if (tplte == NULL) /* none? use default */
tplte = dflt_tplte;
for (j = dibp->irq; *tplte != TPL_END; j++, tplte++)
int_tab[j] = (dno + *tplte) & DEV_MAX;
} /* end for i */