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:
committed by
Mark Pizzolato
parent
59aa4a73b1
commit
9c4779c061
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user