1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-05-02 22:24:22 +00:00

IBM360: Updated to fix bugs uncovered under diagnostics.

This commit is contained in:
Richard Cornwell
2024-03-12 12:27:02 -04:00
parent 91c816597c
commit 9462ee624f
8 changed files with 418 additions and 239 deletions

View File

@@ -104,7 +104,7 @@ UNIT cdr_unit[] = {
MTAB cdr_mod[] = {
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_card_set_fmt, &sim_card_show_fmt, NULL,
&sim_card_set_fmt, &sim_card_show_fmt, NULL,
"Set defualt format for reading cards in"},
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr,
&show_dev_addr, NULL, "Set device address"},

View File

@@ -154,7 +154,7 @@ UNIT chan_unit[] = {
DEVICE chan_dev = {
"CH", chan_unit, NULL, chan_mod,
MAX_CHAN, 8, 15, 1, 8, 8,
NULL, NULL, &chan_reset, NULL, NULL, NULL,
NULL, NULL, NULL /*&chan_reset*/, NULL, NULL, NULL,
NULL, DEV_DEBUG, 0, dev_debug,
NULL, NULL, &chan_help, NULL, NULL, &chan_description
};
@@ -490,7 +490,7 @@ start_cmd:
if (chan->chan_status & STATUS_CEND) {
chan->ccw_cmd = 0;
chan->ccw_flags |= FLAG_SLI; /* Force SLI for immediate command */
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x load) %x %04x end\n",
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x load) %x %04x end\n",
chan->daddr, chan->chan_status, chan->ccw_flags);
if (chan->chan_status & (STATUS_DEND)) {
irq_pend = 1;
@@ -856,10 +856,11 @@ startio(uint16 addr) {
return 2;
}
if (dev_status[addr] == SNS_DEVEND ||
dev_status[addr] == (SNS_DEVEND|SNS_CHNEND))
dev_status[addr] = 0;
/* Check for any pending status for this device */
if (dev_status[addr] != 0) {
if (dev_status[addr] & SNS_DEVEND)
dev_status[addr] |= SNS_BSY;
M[0x44 >> 2] = (((uint32)dev_status[addr]) << 24);
M[0x40 >> 2] = 0;
key[0] |= 0x6;
@@ -926,6 +927,18 @@ startio(uint16 addr) {
return 1;
}
/* If immediate command and not command chaining */
if ((chan->chan_status & (STATUS_CEND)) != 0
&& (chan->ccw_flags & FLAG_CC) == 0) {
M[0x40 >> 2] = 0;
M[0x44 >> 2] = ((uint32)chan->chan_status<<16);
key[0] |= 0x6;
chan->chan_status = 0;
sim_debug(DEBUG_EXP, &cpu_dev, "Channel store csw %03x %08x\n",
addr, M[0x44 >> 2]);
return 1;
}
return 0;
}
@@ -1167,12 +1180,6 @@ int testchan(uint16 channel) {
return 2;
}
/* If channel has pending status, return 1 */
if (chan->chan_status != 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "TCH CC %x cc=1, error\n", channel);
return 1;
}
/* Otherwise return 0. */
sim_debug(DEBUG_CMD, &cpu_dev, "TCH CC %x cc=0, ok\n", channel);
return 0;
@@ -1192,7 +1199,6 @@ t_stat chan_boot(uint16 addr, DEVICE *dptyr) {
for (i = 0; i < (MAX_CHAN * 256); i++)
dev_status[i] = 0;
chan_set_devs();
dev = find_device(addr);
chan = find_subchan(addr);
if (dev == NULL || chan == NULL) {
@@ -1307,8 +1313,7 @@ scan_chan(uint16 mask, int irq_en) {
/* Disconnect from device */
sim_debug(DEBUG_EXP, &cpu_dev, "Scan(%x %x %x %x %x) end\n", i,
chan->daddr, chan->chan_status, imask, mask);
if (//(chan->chan_status & STATUS_CEND) != 0 &&
((imask & mask) != 0 || loading != 0)) {
if (((imask & mask) != 0 || loading != 0)) {
pend = chan->daddr;
break;
}
@@ -1398,7 +1403,7 @@ chan_reset(DEVICE * dptr)
/*
* Scan all devices and create the device mapping.
*/
t_stat
void
chan_set_devs()
{
unsigned i, j;
@@ -1423,19 +1428,20 @@ chan_set_devs()
n = UNIT_G_SCHAN(uptr->flags)+1;
if ((uptr->flags & UNIT_M_CTYPE) == UNIT_BMUX)
n = 32;
/* If no device array, create one */
if (uptr->up8 == NULL)
uptr->up8 = calloc(256, sizeof(struct _dev));
if (uptr->up7 == NULL || (uint32)uptr->schans != n) {
if (uptr->up7 != NULL)
free(uptr->up7);
uptr->up7 = calloc(n, sizeof(struct _chanctl));
for (j = 0; j < n; j++) {
struct _chanctl *chan = &(chan_ctl[j]);
chan->daddr = NO_DEV;
}
/* Create device table */
if (uptr->up8 != NULL)
free(uptr->up8);
uptr->up8 = calloc(256, sizeof(struct _dev));
/* Create subchannel controls */
if (uptr->up7 != NULL)
free(uptr->up7);
uptr->up7 = calloc(n, sizeof(struct _chanctl));
for (j = 0; j < n; j++) {
struct _chanctl *chan = &(chan_ctl[j]);
chan->daddr = NO_DEV;
}
uptr->schans = n;
/* Initialize channel device address table to empty */
for (j = 0; j < 256; j++) {
struct _dev *dev = &(dev_tab[j]);
dev->dibp = NULL;
@@ -1473,7 +1479,7 @@ chan_set_devs()
}
}
return SCPE_OK;
return;
}
/* Sets the number of subchannels for a channel */

View File

@@ -129,8 +129,8 @@ uint8 clk_irq; /* Clock compare IRQ */
uint8 tod_irq; /* TOD compare IRQ */
int clk_state;
int timer_tics; /* Interval Timer is ever 3 tics */
uint32 idle_stop_msec = 0; // msec allowed after before stop cpu if idle
uint32 idle_stop_tm0; // sim_os_msec when start counting for idle time
uint32 idle_stop_msec = 0; /* msec allowed after before stop cpu if idle */
uint32 idle_stop_tm0; /* sim_os_msec when start counting for idle time */
#define CLOCK_UNSET 0 /* Clock not set */
@@ -194,6 +194,7 @@ uint32 idle_stop_tm0; // sim_os_msec when start counting for idle t
#define IRC_PER 0x0080 /* Per event */
#define AMASK 0x00ffffff /* Mask address bits */
#define WMASK 0x00fffffc /* Mask address to word boundry */
#define MSIGN 0x80000000 /* Minus sign */
#define MMASK 0x00ffffff /* Mantissa mask */
#define EMASK 0x7f000000 /* Exponent mask */
@@ -214,6 +215,8 @@ uint32 idle_stop_tm0; // sim_os_msec when start counting for idle t
#define NMASKL 0x00f0000000000000LL
#define UMASKL 0x0ffffffffffffff0LL
#define SNMASKL 0x0f00000000000000LL
#define DMASKL 0x0080000000000000LL
#define OMASKL 0xffffffff80000000LL
#define LDDBL(r,x) x = (((t_uint64)regs[r]) << 32) | ((t_uint64)regs[r|1]); \
if (hst_lnt) { hst[hst_p].src1 = ((x) >> 32); \
hst[hst_p].src2 = (x) & FMASK; }
@@ -311,7 +314,7 @@ int32 rtc_tps = 300;
UNIT cpu_unit[] = { {UDATA (&rtc_srv, UNIT_IDLE|UNIT_BINK|UNIT_FIX, MAXMEMSIZE)} };
REG cpu_reg[] = {
{ HRDATA (PC, PC, 24) },
{ HRDATA (PC, PC, 32) },
{ HRDATA (CC, cc, 2) },
{ HRDATA (PMASK, pmsk, 4) },
{ HRDATA (FLAGS, flags, 4) },
@@ -358,10 +361,17 @@ MTAB cpu_mod[] = {
{ MTAB_VDV, MEMAMOUNT(128), NULL, "2M", &cpu_set_size },
{ MTAB_VDV, MEMAMOUNT(256), NULL, "4M", &cpu_set_size },
{ MTAB_VDV, MEMAMOUNT(512), NULL, "8M", &cpu_set_size },
{ FEAT_370, FEAT_370, "IBM370", "IBM370", NULL, NULL, NULL, "Sets CPU to be a IBM370"},
{ FEAT_370, 0, "IBM360", "IBM360", NULL, NULL, NULL, "Sets CPU to be a IBM360"},
{ MTAB_VDV, MEMAMOUNT(768), NULL, "12M", &cpu_set_size },
{ MTAB_VDV, MEMAMOUNT(1024), NULL, "16M", &cpu_set_size },
{ FEAT_370, FEAT_370, "IBM370", "IBM370", NULL, NULL, NULL,
"Sets CPU to be a IBM370"},
{ FEAT_370, 0, "IBM360", "IBM360", NULL, NULL, NULL,
"Sets CPU to be a IBM360"},
{ FEAT_PROT, 0, NULL, "NOPROT", NULL, NULL, NULL, "No Storage protection"},
{ FEAT_PROT, FEAT_PROT, "PROT", "PROT", NULL, NULL, NULL, "Storage protection"},
{ FEAT_FPROT, 0, NULL, "NOFPROT", NULL, NULL, NULL, "No Fetch protection"},
{ FEAT_FPROT|FEAT_PROT, FEAT_FPROT|FEAT_PROT, "FPROT", "FPROT", NULL, NULL,
NULL, "Fetch protection"},
{ FEAT_UNIV, FEAT_UNIV, "UNIV", "UNIV", NULL, NULL, NULL, "Universal instruction"},
{ FEAT_UNIV, 0, NULL, "NOUNIV", NULL, NULL, NULL, "Basic instructions"},
{ FEAT_UNIV, FEAT_FLOAT, "FLOAT", "FLOAT", NULL, NULL, NULL,
@@ -674,16 +684,18 @@ ReadFull(uint32 addr, uint32 *data)
/* Check storage key */
if (st_key != 0) {
uint8 k;
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
if ((cpu_unit[0].flags & (FEAT_PROT|FEAT_DAT)) == 0) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
k = key[pa >> 11];
if ((k & 0x8) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return 1;
if ((cpu_unit[0].flags & (FEAT_FPROT|FEAT_DAT)) != 0) {
uint8 k = key[pa >> 11];
if ((k & 0x8) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
}
}
@@ -710,10 +722,12 @@ ReadFull(uint32 addr, uint32 *data)
return 1;
/* Check access protection */
if (st_key != 0) {
k = key[temp >> 11];
if ((k & 0x8) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return 1;
if ((cpu_unit[0].flags & (FEAT_FPROT|FEAT_DAT)) != 0) {
uint8 k = key[temp >> 11];
if ((k & 0x8) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
}
}
}
@@ -730,7 +744,7 @@ ReadFull(uint32 addr, uint32 *data)
/* Update access flag */
key[pa >> 11] |= 0x4;
/* sim_debug(DEBUG_DATA, &cpu_dev, "RD A=%08x %08x\n", addr, *data); */
sim_debug(DEBUG_DATA, &cpu_dev, "RD A=%08x %08x\n", addr, *data);
return 0;
}
@@ -830,7 +844,7 @@ WriteFull(uint32 addr, uint32 data)
if (st_key != 0) {
uint8 k;
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
if ((cpu_unit[0].flags & (FEAT_PROT|FEAT_DAT)) == 0) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
@@ -903,7 +917,7 @@ WriteFull(uint32 addr, uint32 data)
M[pa2] |= 0xffffff00 & (data << 8);
break;
}
/* sim_debug(DEBUG_DATA, &cpu_dev, "WR A=%08x %08x\n", addr, data); */
sim_debug(DEBUG_DATA, &cpu_dev, "WR A=%08x %08x\n", addr, data);
return 0;
}
@@ -940,7 +954,7 @@ WriteByte(uint32 addr, uint32 data)
if (st_key != 0) {
uint8 k;
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
if ((cpu_unit[0].flags & (FEAT_PROT|FEAT_DAT)) == 0) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
@@ -959,7 +973,7 @@ WriteByte(uint32 addr, uint32 data)
pa >>= 2;
mask = 0xff;
data &= mask;
/* sim_debug(DEBUG_DATA, &cpu_dev, "WR A=%08x %02x\n", addr, data); */
sim_debug(DEBUG_DATA, &cpu_dev, "WR A=%08x %02x\n", addr, data);
data <<= offset;
mask <<= offset;
M[pa] &= ~mask;
@@ -1006,17 +1020,17 @@ WriteHalf(uint32 addr, uint32 data)
/* Check storage key */
if (st_key != 0) {
uint8 k;
uint8 k;
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
k = key[pa >> 11];
if ((k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
if ((cpu_unit[0].flags & (FEAT_PROT|FEAT_DAT)) == 0) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
k = key[pa >> 11];
if ((k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return 1;
}
}
if (offset == 3) {
@@ -1070,7 +1084,7 @@ WriteHalf(uint32 addr, uint32 data)
mask = 0xffff;
data &= mask;
/* sim_debug(DEBUG_DATA, &cpu_dev, "WR A=%08x %04x\n", addr, data); */
sim_debug(DEBUG_DATA, &cpu_dev, "WR A=%08x %04x\n", addr, data);
switch (offset) {
case 0:
M[pa] &= ~(mask << 16);
@@ -1115,7 +1129,6 @@ sim_instr(void)
t_uint64 src2L;
t_uint64 destL; /* 64 bit destination */
t_uint64 dest2L; /* Upper 64 bit for product */
/* Initialize DAT translation values */
if (Q370) {
switch((cregs[0] >> 22) & 03) {
@@ -1233,6 +1246,7 @@ wait_loop:
/* CPU IDLE */
if (flags & WAIT && irq_en == 0 && ext_en == 0)
return STOP_HALT;
if (idle_stop_msec) {
/* check idle time */
if (idle_stop_tm0 == 0) {
@@ -1543,7 +1557,7 @@ opr:
case OP_SSK:
dest = src1;
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
if ((cpu_unit[0].flags & (FEAT_DAT|FEAT_PROT)) == 0) {
storepsw(OPPSW, IRC_OPR);
goto supress;
} else if (flags & PROBLEM) {
@@ -1561,14 +1575,16 @@ opr:
} else {
if ((cpu_unit[0].flags & FEAT_DAT) != 0)
key[addr1 >> 11] = src1 & 0xfe;
else
else if ((cpu_unit[0].flags & FEAT_FPROT) != 0)
key[addr1 >> 11] = src1 & 0xf8;
else
key[addr1 >> 11] = src1 & 0xf0;
}
break;
case OP_ISK:
dest = src1;
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
if ((cpu_unit[0].flags & (FEAT_DAT|FEAT_PROT)) == 0) {
storepsw(OPPSW, IRC_PROT);
} if (flags & PROBLEM) {
/* Try to do quick ISK */
@@ -1583,8 +1599,12 @@ opr:
dest &= 0xffffff00;
if (ec_mode)
dest |= key[addr1 >> 11] & 0xfe;
else
dest |= key[addr1 >> 11] & 0xf8;
else {
if ((cpu_unit[0].flags & FEAT_FPROT) != 0)
dest |= key[addr1 >> 11] & 0xf8;
else
dest |= key[addr1 >> 11] & 0xf0;
}
regs[reg1] = dest;
per_mod |= 1 << reg1;
}
@@ -1840,26 +1860,46 @@ set_cc3:
goto supress;
}
fill = 0;
LDDBL(reg1, src1L);
if (src1L & MSIGNL) {
src1 = regs[reg1];
src1h = regs[reg1|1];
if (src1 & MSIGN) {
fill = 3;
src1L = NEG(src1L);
src1h ^= FMASK;
src1 ^= FMASK;
if (src1h == FMASK)
src1 ++;
src1h++;
}
if (src2 & MSIGN) {
fill ^= 1;
src2 = NEG(src2);
}
src2L = src1L % (t_uint64)src2;
src1L = src1L / (t_uint64)src2;
dest = 0;
for (reg = 0; reg < 32; reg++) {
/* Shift left by one */
src1 <<= 1;
if (src1h & MSIGN)
src1 |= 1;
src1h <<= 1;
/* Subtract remainder from divisor */
desth = src1 - src2;
/* Shift quotent left one bit */
dest <<= 1;
/* If remainder larger then divisor replace */
if ((desth & MSIGN) == 0) {
src1 = desth;
dest |= 1;
}
}
/* Check for overflow */
if ((src1L & 0xFFFFFFFF80000000LL) != 0) {
if ((dest & MSIGN) != 0 && dest != MSIGN) {
storepsw(OPPSW, IRC_FIXDIV);
goto supress;
}
src1 = (uint32)(src2L & FMASK);
dest = (uint32)(src1L & FMASK);
if (fill & 1)
dest = NEG(dest);
if (fill & 2)
@@ -1985,7 +2025,11 @@ char_save:
dest = regs[reg1];
if (hst_lnt)
hst[hst_p].src1 = dest;
dest = ((uint32)dest) >> (addr1 & 0x3f);
addr1 &= 0x3f;
if (addr1 > 31)
dest = 0;
else
dest = dest >> (addr1);
regs[reg1] = dest;
per_mod |= 1 << reg1;
break;
@@ -1994,7 +2038,11 @@ char_save:
dest = regs[reg1];
if (hst_lnt)
hst[hst_p].src1 = dest;
dest = ((uint32)dest) << (addr1 & 0x3f);
addr1 &= 0x3f;
if (addr1 > 31)
dest = 0;
else
dest = dest << addr1;
regs[reg1] = dest;
per_mod |= 1 << reg1;
break;
@@ -2003,7 +2051,12 @@ char_save:
dest = regs[reg1];
if (hst_lnt)
hst[hst_p].src1 = dest;
dest = (int32)dest >> (addr1 & 0x3f);
addr1 &= 0x3f;
if (addr1 > 31) {
dest = ((dest & MSIGN) != 0) ? FMASK : 0;
} else {
dest = (int32)dest >> (addr1 & 0x3f);
}
goto set_cc;
case OP_SLA:
@@ -2387,11 +2440,10 @@ save_dbl:
if (TransAddr(addr1, &src1) ||
TransAddr(addr1+reg, &src1) ||
TransAddr(addr2, &src1) ||
TransAddr(addr2+reg, &src1)) {
TransAddr(addr2-reg, &src1)) {
goto supress;
}
}
addr2 += reg;
do {
if (ReadByte(addr2, &src1))
goto supress;
@@ -2655,6 +2707,11 @@ save_dbl:
/* Convert packed decimal to binary */
case OP_CVB:
/* If not on double word boundry and store feature not set */
if ((addr1 & 07) != 0 && (cpu_unit[0].flags & FEAT_STOR) == 0) {
storepsw(OPPSW, IRC_SPEC);
goto supress;
}
if (ReadFull(addr1, &src1))
goto supress;
if (ReadFull(addr1+4, &src1h))
@@ -2664,7 +2721,7 @@ save_dbl:
storepsw(OPPSW, IRC_DATA);
goto supress;
}
dest = 0;
destL = 0;
/* Convert upper first */
for(temp = 28; temp >= 0; temp-=4) {
int d = (src1 >> temp) & 0xf;
@@ -2672,7 +2729,7 @@ save_dbl:
storepsw(OPPSW, IRC_DATA);
goto supress;
}
dest = (dest * 10) + d;
destL = (destL * 10) + d;
}
/* Convert lower */
for(temp = 28; temp > 0; temp-=4) {
@@ -2681,22 +2738,26 @@ save_dbl:
storepsw(OPPSW, IRC_DATA);
goto supress;
}
dest = (dest * 10) + d;
destL = (destL * 10) + d;
}
/* Check if too big */
if (dest & MSIGN) {
if ((destL & OMASKL) != 0 && destL != (uint64_t)MSIGN) {
storepsw(OPPSW, IRC_FIXDIV);
regs[reg1] = dest;
goto supress;
}
/* Twos compliment if needed */
if (fill == 0xB || fill == 0xD)
dest = NEG(dest);
regs[reg1] = dest;
destL = ~destL + 1;
regs[reg1] = (uint32)(destL & FMASK);
break;
/* Convert binary to packed decimal */
case OP_CVD:
/* If not on double word boundry and store feature not set */
if ((addr1 & 07) != 0 && (cpu_unit[0].flags & FEAT_STOR) == 0) {
storepsw(OPPSW, IRC_SPEC);
goto supress;
}
dest = regs[reg1];
src1 = 0;
src1h = 0;
@@ -2730,14 +2791,19 @@ save_dbl:
/* Edit string, mark saves address of significant digit */
case OP_ED:
case OP_EDMK:
if (ReadByte(addr1, &src1))
if (ReadFull(addr1 & WMASK, &src1h))
goto supress;
zone = (flags & ASCII) ? 0x50: 0xf0;
src1 = (src1h >> (8 * (3 - (addr1 & 0x3)))) & 0xff;
fill = digit = (uint8)src1;
temp = 0; /* Hold zero flag */
e2 = 0; /* Significance indicator */
e1 = 1; /* Need another source char */
cc = 0;
if (ReadFull(addr2 & WMASK, &src2h)) {
goto supress;
}
src2 = (src2h >> (8 * (3 - (addr2 & 0x3)))) & 0xff;
for (;;) {
uint8 t;
switch(digit) {
@@ -2745,11 +2811,15 @@ save_dbl:
case 0x20: /* Digit selector */
/* If we have not run out of source, grab next pair */
if (e1) {
if (ReadByte(addr2, &src2))
goto supress;
if ((addr2 & 0x3) == 0) {
if (ReadFull(addr2, &src2h)) {
goto supress;
}
}
src2 = (src2h >> (8 * (3 - (addr2 & 0x3)))) & 0xff;
addr2++;
/* Check if valid */
if (src2 > 0xa0) {
if (src2 >= 0xa0) {
storepsw(OPPSW, IRC_DATA);
goto supress;
}
@@ -2798,14 +2868,19 @@ save_dbl:
if (!e2)
digit = fill;
}
if (WriteByte(addr1, digit))
if (WriteByte(addr1, digit)) {
goto supress;
}
addr1++;
if (reg == 0)
break;
reg --;
if (ReadByte(addr1, &src1))
goto supress;
if ((addr1 & 0x3) == 0) {
if (ReadFull(addr1, &src1h)) {
goto supress;
}
}
src1 = (src1h >> (8 * (3 - (addr1 & 0x3)))) & 0xff;
digit = src1;
}
cc = temp;
@@ -2968,6 +3043,7 @@ save_dbl:
case OP_370:
if (Q370) {
if (reg > 0x13) {
printf("Invalid 0xb2%02x %08x\n\r", reg, addr1);
storepsw(OPPSW, IRC_OPR);
goto supress;
}
@@ -3097,14 +3173,14 @@ save_dbl:
goto supress;
break;
case 0xa: /* SPKA */
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
if ((cpu_unit[0].flags & (FEAT_DAT|FEAT_PROT)) == 0) {
storepsw(OPPSW, IRC_OPR);
goto supress;
}
st_key = 0xf0 & addr1;
break;
case 0xb: /* IPK */
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
if ((cpu_unit[0].flags & (FEAT_DAT|FEAT_PROT)) == 0) {
storepsw(OPPSW, IRC_OPR);
goto supress;
}
@@ -3340,7 +3416,6 @@ save_dbl:
~page_mask) & AMASK) >> page_shift;
intval_en = ((dest & 0x400) != 0);
tod_en = ((dest & 0x800) != 0);
// temp = 1;
break;
case 0x1: /* Segment table address and length */
temp = 1;
@@ -3589,6 +3664,9 @@ save_dbl:
case OP_HER:
/* Split number apart */
e1 = (src2L & EMASKL) >> 56;
if ((op & 0x10) != 0) {
src2L &= HMASKL;
}
destL = src2L & MSIGNL;
/* Create guard digit */
src2L = (src2L & MMASKL) << 4;
@@ -3605,7 +3683,8 @@ save_dbl:
if (pmsk & EXPUND) {
storepsw(OPPSW, IRC_EXPUND);
} else {
destL = e1 = 0;
destL = src2L = 0;
e1 = 0;
}
}
/* Remove guard digit */
@@ -3613,8 +3692,10 @@ save_dbl:
}
/* Check for zero */
if (src2L == 0)
destL = e1 = 0;
if (src2L == 0) {
destL = 0;
e1 = 0;
}
/* Restore result */
src2L |= (((t_uint64)e1 << 56) & EMASKL) | destL;
@@ -3653,7 +3734,7 @@ save_dbl:
} else {
fpregs[reg1] = (src2L & HMASKL) | (fpregs[reg1] & LMASKL);
}
if (src1L != 0)
if ((src1L & MMASKL) != 0)
cc = (src2L & MSIGNL) ? 1 : 2;
break;
@@ -3745,101 +3826,112 @@ save_dbl:
case OP_AER: /* 3A */
case OP_AUR: /* 3E */
/* Extract numbers and adjust */
e1 = (src1L & EMASKL) >> 56;
e2 = (src2L & EMASKL) >> 56;
fill = 0;
if (src1L & MSIGNL)
fill |= 2;
if (src2L & MSIGNL)
fill |= 1;
/* Make 32 bit and create guard digit */
src1 = (uint32)((src1L >> 28) & (MMASK << 4));
src2 = (uint32)((src2L >> 28) & (MMASK << 4));
temp = e1 - e2;
if (temp > 0) {
if (temp > 8) {
src2 = 0;
} else {
/* Shift src2 right if src1 larger expo - expo */
src2 >>= 4 * temp;
}
} else if (temp < 0) {
if (temp < -8) {
src1 = 0;
} else {
/* Shift src1 right if src2 larger expo - expo */
src1 >>= 4 * -temp;
}
e1 = e2;
}
/* Exponents should be equal now. */
/* Add results */
if (fill == 2 || fill == 1) {
/* Different signs do subtract */
src2 ^= XMASK;
dest = src1 + src2 + 1;
if (dest & CMASK)
dest &= XMASK;
else {
fill ^= 2;
dest ^= XMASK;
dest++;
}
e1 = (src1L & EMASKL) >> 56;
e2 = (src2L & EMASKL) >> 56;
fill = 0;
if (src1L & MSIGNL)
fill |= 2;
if (src2L & MSIGNL)
fill |= 1;
/* Make 32 bit and create guard digit */
src1 = (uint32)((src1L >> 28) & (MMASK << 4));
src2 = (uint32)((src2L >> 28) & (MMASK << 4));
temp = e1 - e2;
if (temp > 0) {
if (temp > 7) {
src2 = 0;
} else {
dest = src1 + src2;
/* Shift src2 right if src1 larger expo - expo */
src2 >>= 4 * temp;
}
/* If overflow, shift right 4 bits */
if (dest & CMASK) {
dest >>= 4;
e1 ++;
if (e1 >= 128) {
storepsw(OPPSW, IRC_EXPOVR);
}
}
/* Set condition codes */
cc = 0;
if ((op & 0xE) != 0xE) {
if (dest != 0)
cc = (fill & 2) ? 1 : 2;
else
dest = e1 = fill = 0;
} else if (temp < 0) {
temp = -temp;
if (temp > 7) {
src1 = 0;
} else {
if ((dest & 0xffffff0) != 0)
cc = (fill & 2) ? 1 : 2;
else
dest = e1 = fill = 0;
/* Shift src1 right if src2 larger expo - expo */
src1 >>= 4 * temp;
}
e1 = e2;
}
/* Check signifigance exception */
if (cc == 0 && pmsk & SIGMSK) {
storepsw(OPPSW, IRC_SIGNIF);
goto fpstore1;
/* Exponents should be equal now. */
/* Add results */
if (fill == 2 || fill == 1) {
/* Different signs do subtract */
src2 ^= XMASK;
dest = src1 + src2 + 1;
if (dest & CMASK)
dest &= XMASK;
else {
fill ^= 2;
dest ^= XMASK;
dest++;
}
} else {
dest = src1 + src2;
}
/* Check if we are normalized addition */
if ((op & 0xE) != 0xE) {
if (cc != 0) { /* Only if non-zero result */
while ((dest & SNMASK) == 0) {
dest <<= 4;
e1 --;
}
/* Check if underflow */
if (e1 < 0) {
if (pmsk & EXPUND) {
storepsw(OPPSW, IRC_EXPUND);
} else {
dest = 0;
fill = e1 = 0;
}
/* If overflow, shift right 4 bits */
if (dest & CMASK) {
dest >>= 4;
e1 ++;
if (e1 >= 128) {
storepsw(OPPSW, IRC_EXPOVR);
}
}
/* Set condition codes */
cc = 0;
if ((op & 0xE) != 0xE) {
if (dest != 0) {
cc = (fill & 2) ? 1 : 2;
} else {
if ((pmsk & SIGMSK) == 0) {
e1 = 0;
}
fill = 0;
}
} else {
if ((dest & 0xffffff0) != 0) {
cc = (fill & 2) ? 1 : 2;
} else {
if ((pmsk & SIGMSK) == 0) {
e1 = 0;
}
dest = 0;
fill = 0;
}
}
/* Check signifigance exception */
if (cc == 0 && pmsk & SIGMSK) {
storepsw(OPPSW, IRC_SIGNIF);
goto fpstore1;
}
/* Check if we are normalized addition */
if ((op & 0xE) != 0xE) {
if (cc != 0) { /* Only if non-zero result */
while ((dest & SNMASK) == 0) {
dest <<= 4;
e1 --;
}
/* Check if underflow */
if (e1 < 0) {
if (pmsk & EXPUND) {
storepsw(OPPSW, IRC_EXPUND);
} else {
dest = 0;
fill = e1 = 0;
}
}
}
}
}
/* Remove DP Guard bit */
dest >>= 4;
/* Remove DP Guard bit */
dest >>= 4;
fpstore1:
/* Store result */
@@ -3935,18 +4027,19 @@ fpstore1:
src2L <<= 4;
temp = e1 - e2;
if (temp > 0) {
if (temp > 17) {
if (temp > 15) {
src2L = 0;
} else {
/* Shift src2 right if src1 larger expo - expo */
src2L >>= 4 * temp;
}
} else if (temp < 0) {
if (temp < -17) {
temp = -temp;
if (temp > 15) {
src1L = 0;
} else {
/* Shift src1 right if src2 larger expo - expo */
src1L >>= 4 * (-temp);
src1L >>= 4 * temp;
}
e1 = e2;
}
@@ -3981,22 +4074,29 @@ fpstore1:
/* Set condition codes */
cc = 0;
if ((op & 0xE) != 0xE) {
if (destL != 0)
if (destL != 0) {
cc = (fill & 2) ? 1 : 2;
else
e1 = fill = 0;
} else {
if ((pmsk & SIGMSK) == 0) {
e1 = 0;
}
fill = 0;
}
} else {
if ((destL & UMASKL) != 0)
if ((destL & UMASKL) != 0) {
cc = (fill & 2) ? 1 : 2;
else
destL = e1 = fill = 0;
} else {
if ((pmsk & SIGMSK) == 0) {
e1 = 0;
}
destL = 0;
fill = 0;
}
}
/* Check signifigance exception */
if (cc == 0 && pmsk & SIGMSK) {
storepsw(OPPSW, IRC_SIGNIF);
e1 = fill = 0;
destL = 0;
goto fpstore;
}
@@ -4063,11 +4163,14 @@ fpstore:
}
/* Compute exponent */
e1 = e1 + e2 - 64;
e1 = e1 + e2 - 65;
/* Add in guard digits */
src1L <<= 4;
src2L <<= 4;
destL = 0;
/* Do multiply */
for (temp = 0; temp < 56; temp++) {
for (temp = 0; temp < 60; temp++) {
/* Add if we need too */
if (src1L & 1)
destL += src2L;
@@ -4080,9 +4183,11 @@ fpnorm:
if (destL & EMASKL) {
destL >>= 4;
e1 ++;
if (e1 >= 128) {
storepsw(OPPSW, IRC_EXPOVR);
}
}
/* Check for overflow */
if (e1 >= 128) {
storepsw(OPPSW, IRC_EXPOVR);
}
/* Align the results */
if ((destL) != 0) {
@@ -4162,13 +4267,13 @@ fpnorm:
src2L++;
destL = 0;
/* Do divide */
for (temp = 56; temp > 0; temp--) {
for (temp = 57; temp > 0; temp--) {
t_uint64 t;
/* Shift left by one */
src1L <<= 1;
/* Subtract remainder to dividend */
t= src1L + src2L;
t = src1L + src2L;
/* Shift quotent left one bit */
destL <<= 1;
@@ -4178,18 +4283,13 @@ fpnorm:
src1L = t;
destL |= 1;
}
src1L &= XMASKL;
}
/* Compute one final set to see if rounding needed */
/* Shift left by one */
src1L <<= 1;
/* Subtract remainder to dividend */
src1L += src2L;
/* If .5 off, round */
if ((src1L & MSIGNL) != 0) {
if (destL == 0x01ffffffffffffff) {
destL++;
}
destL >>= 1;
goto fpnorm;
/* Decimal operations */
@@ -4788,20 +4888,23 @@ int dec_load(uint8 *data, uint32 addr, int len, int *sign)
if (ReadByte(addr, &temp))
return 1;
t = temp & 0xf;
if (j != 0 && t > 0x9)
if (j != 0 && t > 0x9) {
err = 1;
}
data[j++] = t;
t = (temp >> 4) & 0xf;
if (t > 0x9)
if (t > 0x9) {
err = 1;
}
data[j++] = t;
addr--;
}
/* Check if sign valid and return it */
if (data[0] == 0xB || data[0] == 0xD)
*sign = 1;
else if (data[0] < 0xA)
else if (data[0] < 0xA) {
err = 1;
}
else
*sign = 0;
if (err) {
@@ -4906,7 +5009,8 @@ dec_srp(int op, uint32 addr1, uint8 len1, uint32 addr2, uint8 len2)
cc = 0;
if (!zero) /* Really not zero */
cc = (sa)? 1: 2;
dec_store(a, addr1, (int)len1, sa);
if (dec_store(a, addr1, (int)len1, sa))
return;
if (ov)
cc = 3;
if (ov && pmsk & DECOVR)
@@ -5004,7 +5108,8 @@ dec_add(int op, uint32 addr1, uint8 len1, uint32 addr2, uint8 len2)
}
}
}
dec_store(a, addr1, (int)len1, sa);
if (dec_store(a, addr1, (int)len1, sa))
return;
if (ov)
cc = 3;
if (ov && pmsk & DECOVR)
@@ -5036,6 +5141,33 @@ dec_mul(int op, uint32 addr1, uint8 len1, uint32 addr2, uint8 len2)
}
if (dec_load(b, addr2, (int)len2, &sb))
return;
/* Check if we can store the result back in place */
if (st_key != 0 && (cpu_unit[0].flags & FEAT_PROT) != 0) {
uint8 k;
uint32 pa;
/* Validate address */
if (TransAddr(addr1 + len, &pa))
return;
k = key[pa >> 11];
if ((k & 0xf0) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return;
}
/* Check if start on another page */
if (((addr1 & 0x3ff) + len) > 0x3ff) {
/* Validate address */
if (TransAddr(addr1, &pa))
return;
k = key[pa >> 11];
if ((k & 0xf0) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return;
}
}
}
if (dec_load(a, addr1, (int)len1, &sa))
return;
len = (int)len1;
@@ -5066,7 +5198,7 @@ dec_mul(int op, uint32 addr1, uint8 len1, uint32 addr2, uint8 len2)
mul--;
}
}
dec_store(a, addr1, len, sa);
(void)dec_store(a, addr1, len, sa);
}
void
@@ -5090,6 +5222,33 @@ dec_div(int op, uint32 addr1, uint8 len1, uint32 addr2, uint8 len2)
}
if (dec_load(b, addr2, (int)len2, &sb))
return;
/* Check if we can store the result back in place */
if (st_key != 0 && (cpu_unit[0].flags & FEAT_PROT) != 0) {
uint8 k;
uint32 pa;
/* Validate address */
if (TransAddr(addr1 + len, &pa))
return;
k = key[pa >> 11];
if ((k & 0xf0) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return;
}
/* Check if start on another page */
if (((addr1 & 0x3ff) + len) > 0x3ff) {
/* Validate address */
if (TransAddr(addr1, &pa))
return;
k = key[pa >> 11];
if ((k & 0xf0) != 0 && (k & 0xf0) != st_key) {
storepsw(OPPSW, IRC_PROT);
return;
}
}
}
if (dec_load(a, addr1, (int)len1, &sa))
return;
memset(c, 0, 32);
@@ -5143,7 +5302,7 @@ dec_div(int op, uint32 addr1, uint8 len1, uint32 addr2, uint8 len2)
} else {
a[len2] = ((flags & ASCII)? 0xa : 0xc);
}
dec_store(a, addr1, len, sa);
(void)dec_store(a, addr1, len, sa);
}
@@ -5154,6 +5313,8 @@ cpu_reset (DEVICE *dptr)
{
int i;
/* Make sure devices are mapped correctly */
chan_set_devs();
sim_vm_fprint_stopped = &cpu_fprint_stopped;
/* Create memory array if it does not exist. */
if (M == NULL) { /* first time init? */
@@ -5197,8 +5358,8 @@ cpu_reset (DEVICE *dptr)
}
if (cpu_unit[0].flags & (FEAT_370|FEAT_TIMER)) {
sim_rtcn_init_unit (&cpu_unit[0], cpu_unit[0].wait, TMR_RTC);
sim_activate(&cpu_unit[0], 10000);
sim_rtcn_init_unit (&cpu_unit[0], 1000, TMR_RTC);
sim_activate(&cpu_unit[0], 100);
}
idle_stop_tm0 = 0;
return SCPE_OK;
@@ -5211,11 +5372,11 @@ rtc_srv(UNIT * uptr)
{
(void)sim_rtcn_calb (rtc_tps, TMR_RTC);
sim_activate_after(uptr, 1000000/rtc_tps);
M[0x50>>2] -= 0x100;
if ((M[0x50>>2] & 0xfffff00) == 0) {
sim_debug(DEBUG_INST, &cpu_dev, "TIMER IRQ %08x\n", M[0x50>>2]);
interval_irq = 1;
}
M[0x50>>2] -= 0x100;
key[0] |= 0x6;
sim_debug(DEBUG_INST, &cpu_dev, "TIMER = %08x\n", M[0x50>>2]);
/* Time of day clock and timer on IBM 370 */

View File

@@ -107,7 +107,8 @@ typedef struct dib {
#define FEAT_EFP (1 << (UNIT_V_UF + 6)) /* Extended floating point */
#define FEAT_370 (1 << (UNIT_V_UF + 7)) /* Is a 370 */
#define FEAT_VMA (1 << (UNIT_V_UF + 8)) /* Enable VM assists */
#define EXT_IRQ (1 << (UNIT_V_UF + 9)) /* External interrupt */
#define FEAT_FPROT (1 << (UNIT_V_UF + 9)) /* Fetch protection */
#define EXT_IRQ (1 << (UNIT_V_UF + 10)) /* External interrupt */
/* low addresses */
#define IPSW 0x00 /* IPSW */
@@ -358,7 +359,7 @@ int haltio(uint16 addr);
int testchan(uint16 channel);
uint16 scan_chan(uint16 mask, int irq_en);
t_stat chan_boot(uint16 addr, DEVICE *dptr);
t_stat chan_set_devs();
void chan_set_devs();
t_stat set_dev_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
t_stat show_dev_addr(FILE * st, UNIT * uptr, int32 v, CONST void *desc);
extern uint16 loading;

View File

@@ -122,7 +122,7 @@ MTAB lpr_mod[] = {
&lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"},
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr,
&show_dev_addr, NULL},
{MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "FCB", "FCB={LEGACY|STD1)",
{MTAB_XTD|MTAB_VUN|MTAB_VALR|MTAB_NC, 0, "FCB", "FCB={LEGACY|STD1|NONE)",
&lpr_setfcb, &lpr_getfcb, NULL, NULL },
{0}
};
@@ -137,7 +137,7 @@ DEVICE lpr_dev = {
NULL, NULL, &lpr_help, NULL, NULL, &lpr_description
};
static CONST char *fcb_name[] = { "legacy", "std1", NULL};
static CONST char *fcb_name[] = { "LEGACY", "STD1", "NONE", NULL};
static CONST uint16 legacy[] = {
/* 1 2 3 4 5 6 7 8 9 10 lines */
@@ -162,7 +162,16 @@ static CONST uint16 std1[] = {
0x000, 0x000, 0x000, 0x000, 0x004, 0x000, 0x000, 0x000, 0x000, 0x000, /* 51 - 60 */
0x002, 0x000, 0x001, 0x000, 0x000, 0x000, 0x1000 }; /* 61 - 66 */
static CONST uint16 *fcb_ptr[] = { legacy, std1, NULL, NULL};
static CONST uint16 none[] = {
/* 1 2 3 4 5 6 7 8 9 10 lines */
0x800, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1 - 10 */
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 11 - 20 */
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 21 - 30 */
0x040, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 31 - 40 */
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 41 - 50 */
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 51 - 60 */
0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1000 }; /* 61 - 66 */
static CONST uint16 *fcb_ptr[] = { legacy, std1, none, NULL};
/* Line printer routines
@@ -291,16 +300,18 @@ print_line(UNIT * uptr)
f = 1;
uptr->pos += 2;
if ((uptr->CMD & 03) == 0x1) {
if ((lpr_data[u].fcb[uptr->LINE] & (0x1000 >> 9)) != 0)
if ((lpr_data[u].fcb[uptr->LINE] & (0x1000 >> 9)) != 0) {
uptr->SNS |= SNS_CHN9;
if ((lpr_data[u].fcb[uptr->LINE] & (0x1000 >> 12)) != 0)
}
if ((lpr_data[u].fcb[uptr->LINE] & (0x1000 >> 12)) != 0) {
uptr->SNS |= SNS_CHN12;
}
}
if ((lpr_data[u].fcb[uptr->LINE] & 0x1000) != 0 ||
((uint32)uptr->LINE) >= uptr->capac) {
if (f)
sim_fwrite("\r\n", 1, 2, uptr->fileref);
sim_fwrite("\f", 1, 1, uptr->fileref);
sim_fwrite("\f\r\n", 1, 3, uptr->fileref);
uptr->LINE = 0;
} else {
uptr->LINE++;
@@ -319,7 +330,7 @@ print_line(UNIT * uptr)
l++;
if ((lpr_data[u].fcb[i] & 0x1000) != 0 ||
((uint32)i) >= uptr->capac) {
sim_fwrite("\r\n\f", 1, 3, uptr->fileref);
sim_fwrite("\r\n\f\r\n", 1, 5, uptr->fileref);
uptr->pos += 3;
f = 1;
l = 0;
@@ -445,7 +456,7 @@ lpr_srv(UNIT *uptr) {
/* Handle UCS Load */
if ((uptr->CMD & 0xf7) == 0xf3) {
for (l = 0; l < 240; l++) {
if(chan_read_byte(addr, &ch))
if(chan_read_byte(addr, &ch))
break;
}
uptr->CMD &= ~(LPR_CMDMSK);
@@ -454,12 +465,12 @@ lpr_srv(UNIT *uptr) {
}
/* Check if valid form motion */
if ((cmd == 1 || cmd == 3) &&
if ((cmd == 1 || cmd == 3) &&
((l > 3 && l < 0x10) || l > 0x1d)) {
uptr->SNS = SNS_CMDREJ;
uptr->CMD &= ~(LPR_CMDMSK);
sim_debug(DEBUG_DETAIL, &lpr_dev, "%d Invalid skip %x %d", u, l, l);
if (cmd == 3)
if (cmd == 3)
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
else
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);

View File

@@ -520,7 +520,7 @@ t_stat mt_srv(UNIT * uptr)
ch = 0x23; /* Model 3, Support dual density */
if ((uptr->flags & MTUF_9TR) == 0) {
ch |= 0x80; /* Indicate 7 track */
}
}
chan_write_byte(addr, &ch);
/* Sense byte 7 */
ch = 0;
@@ -885,7 +885,6 @@ t_stat mt_srv(UNIT * uptr)
unit, reclen);
/* We don't set EOF on BSR */
if (r == MTSE_TMK) {
uptr->POS++;
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
sim_activate(uptr, 50);
} else {

View File

@@ -190,7 +190,7 @@ DEVICE scoml_dev = {
/*
* Issue a scommand to the 3271 controller.
* Issue a command to the 3271 controller.
*/
uint8 scoml_startcmd(UNIT *uptr, uint8 cmd) {
DEVICE *dptr = find_dev_from_unit(uptr);
@@ -382,7 +382,7 @@ write:
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d send %02x '%c'\n",
unit, ch, isprint(data)? data: '^');
tmxr_putc_ln( &scom_ldsc[unit], ch);
if (ch == IAC)
if (ch == IAC)
tmxr_putc_ln( &scom_ldsc[unit], ch);
sim_activate(uptr, 200);
}
@@ -430,6 +430,7 @@ t_stat scom_scan(UNIT * uptr)
line->CMD |= ENAB|DATA|INIT1;
line->CMD &= ~(RECV|SEND);
line->SNS = 0;
set_devattn(GET_UADDR(line->CMD), SNS_ATTN);
sim_activate(line, 20000);
}

View File

@@ -100,7 +100,7 @@ const char *scon_description(DEVICE *d);
UNIT scon_unit[] = {
{UDATA(scon_srv, UNIT_ATTABLE|UNIT_DISABLE|UNIT_DIS|UNIT_IDLE, 0), 0, UNIT_ADDR(0x09)}, /* B */
{UDATA(scon_srv, UNIT_ATTABLE|UNIT_DISABLE|UNIT_DIS|UNIT_IDLE, 0), 0, UNIT_ADDR(0x2F)}, /* C */
{UDATA(scon_srvo, UNIT_DISABLE|UNIT_DIS|UNIT_IDLE, 0) },
{UDATA(scon_srvo, UNIT_DISABLE|UNIT_DIS|UNIT_IDLE, 0) },
};
MTAB scon_mod[] = {
@@ -319,7 +319,7 @@ scon_srv(UNIT *uptr) {
}
break;
}
/* Grab next character and send it to CPU */
data = scon_data[u].ibuff[uptr->IPTR++];
sim_debug(DEBUG_CMD, &scon_dev, "%d: rd %02x\n", u, data);