mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-21 10:12:30 +00:00
IBM360: Added support for Channels 4-7. 4 being multiplexer.
This commit is contained in:
parent
6e654bde53
commit
e277497d88
@ -79,18 +79,21 @@ extern uint32 *M;
|
||||
extern uint8 key[MAXMEMSIZE / 2048];
|
||||
|
||||
#define MAX_DEV (MAX_CHAN * 256)
|
||||
|
||||
#define SEL_BASE (SUB_CHANS * MAX_MUX)
|
||||
#define CHAN_SZ (SEL_BASE + MAX_CHAN)
|
||||
int channels = MAX_CHAN;
|
||||
int subchannels = SUB_CHANS; /* Number of subchannels */
|
||||
int irq_pend = 0;
|
||||
uint32 caw[256]; /* Channel command address word */
|
||||
uint32 ccw_addr[256]; /* Channel address */
|
||||
uint16 ccw_count[256]; /* Channel count */
|
||||
uint8 ccw_cmd[256]; /* Channel command and flags */
|
||||
uint16 ccw_flags[256]; /* Channel flags */
|
||||
uint16 chan_status[256]; /* Channel status */
|
||||
uint16 chan_dev[256]; /* Device on channel */
|
||||
uint32 chan_buf[256]; /* Channel data buffer */
|
||||
uint8 chan_byte[256]; /* Current byte, dirty/full */
|
||||
uint32 caw[CHAN_SZ]; /* Channel command address word */
|
||||
uint32 ccw_addr[CHAN_SZ]; /* Channel address */
|
||||
uint16 ccw_count[CHAN_SZ]; /* Channel count */
|
||||
uint8 ccw_cmd[CHAN_SZ]; /* Channel command and flags */
|
||||
uint16 ccw_flags[CHAN_SZ]; /* Channel flags */
|
||||
uint16 chan_status[CHAN_SZ]; /* Channel status */
|
||||
uint16 chan_dev[CHAN_SZ]; /* Device on channel */
|
||||
uint32 chan_buf[CHAN_SZ]; /* Channel data buffer */
|
||||
uint8 chan_byte[CHAN_SZ]; /* Current byte, dirty/full */
|
||||
DIB *dev_unit[MAX_DEV]; /* Pointer to Device info block */
|
||||
uint8 dev_status[MAX_DEV]; /* last device status flags */
|
||||
|
||||
@ -128,17 +131,37 @@ find_chan_dev(uint16 addr) {
|
||||
int
|
||||
find_subchan(uint16 device) {
|
||||
int chan;
|
||||
int base = 0;
|
||||
if (device > MAX_DEV)
|
||||
return -1;
|
||||
if (device > 0xff) {
|
||||
chan = (device >> 8) & 0x7;
|
||||
if (chan > channels)
|
||||
return -1;
|
||||
return subchannels + chan;
|
||||
chan = (device >> 8) & 0xf;
|
||||
device &= 0xff;
|
||||
if (chan > channels)
|
||||
return -1;
|
||||
switch(chan) {
|
||||
case 4:
|
||||
base += subchannels;
|
||||
/* Fall through */
|
||||
|
||||
case 0: /* Multiplexer channel */
|
||||
if (device >= subchannels)
|
||||
device = ((device - subchannels) >> 4) & 0x7;
|
||||
return base + device;
|
||||
case 1: /* Selector channel */
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return SEL_BASE + chan;
|
||||
}
|
||||
if (device < subchannels)
|
||||
return device;
|
||||
return ((device - subchannels)>>4) & 0xf;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find a channel for a given index */
|
||||
int
|
||||
find_chan(int chan) {
|
||||
return (chan_dev[chan] >> 8);
|
||||
}
|
||||
|
||||
/* Read a full word into memory.
|
||||
@ -157,7 +180,7 @@ readfull(int chan, uint32 addr, uint32 *word) {
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
@ -192,7 +215,7 @@ readbuff(int chan) {
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
@ -241,7 +264,7 @@ writebuff(int chan) {
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
@ -647,7 +670,7 @@ startio(uint16 addr) {
|
||||
|
||||
/* Try to load first command */
|
||||
if (load_ccw(chan, 0)) {
|
||||
if (chan_status[chan] &
|
||||
if (chan_status[chan] &
|
||||
(STATUS_ATTN|STATUS_CHECK|STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) {
|
||||
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | (M[0x44 >> 2] & 0xffff);
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x cc=2\n", addr, chan,
|
||||
@ -692,11 +715,15 @@ int testio(uint16 addr) {
|
||||
uint16 status;
|
||||
|
||||
/* Find channel this device is on, if no none return cc=3 */
|
||||
if (chan < 0 || dibp == 0)
|
||||
if (chan < 0 || dibp == 0) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x cc=3\n", addr, chan);
|
||||
return 3;
|
||||
}
|
||||
uptr = find_chan_dev(addr);
|
||||
if (uptr == 0)
|
||||
if (uptr == 0) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x uptr cc=3\n", addr, chan);
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* If any error pending save csw and return cc=1 */
|
||||
if (chan_status[chan] & (STATUS_PCI|STATUS_ATTN|STATUS_CHECK|\
|
||||
@ -804,7 +831,7 @@ int testchan(uint16 channel) {
|
||||
return 0;
|
||||
if (channel > channels)
|
||||
return 3;
|
||||
st = chan_status[subchannels + channel];
|
||||
st = chan_status[SEL_BASE + channel];
|
||||
if (st & STATUS_BUSY)
|
||||
return 2;
|
||||
if (st & (STATUS_ATTN|STATUS_PCI|STATUS_EXPT|STATUS_CHECK|
|
||||
@ -859,7 +886,7 @@ t_stat chan_boot(uint16 addr, DEVICE *dptyr) {
|
||||
* interrupt pending.
|
||||
*/
|
||||
uint16
|
||||
scan_chan(uint16 mask) {
|
||||
scan_chan(uint16 mask, int irq_en) {
|
||||
int i;
|
||||
int ch;
|
||||
int pend = 0; /* No device */
|
||||
@ -870,14 +897,11 @@ scan_chan(uint16 mask) {
|
||||
return 0;
|
||||
irq_pend = 0;
|
||||
/* Start with channel 0 and work through all channels */
|
||||
for (i = 0; i < subchannels + channels; i++) {
|
||||
/* If onto channel 1 or above shift mask */
|
||||
if (i >= subchannels)
|
||||
imask = imask / 2;
|
||||
|
||||
for (i = 0; i < CHAN_SZ; i++) {
|
||||
/* Check if PCI pending */
|
||||
if (chan_status[i] & STATUS_PCI) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Scan PCI(%x %x %x %x) end\n", i,
|
||||
if (irq_en && (chan_status[i] & STATUS_PCI) != 0) {
|
||||
imask = 0x8000 >> find_chan(i);
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Scan PCI(%x %x %x %x) end\n", i,
|
||||
chan_status[i], imask, mask);
|
||||
if ((imask & mask) != 0) {
|
||||
pend = chan_dev[i];
|
||||
@ -892,10 +916,12 @@ scan_chan(uint16 mask) {
|
||||
(void)load_ccw(i, 1);
|
||||
else
|
||||
irq_pend = 1;
|
||||
} else {
|
||||
} else if (irq_en || loading) {
|
||||
imask = 0x8000 >> find_chan(i);
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Scan(%x %x %x %x) end\n", i,
|
||||
chan_status[i], imask, mask);
|
||||
if ((imask & mask) != 0 || loading != 0) {
|
||||
if ((chan_status[i] & STATUS_DEND) != 0 &&
|
||||
(imask & mask) != 0 || loading != 0) {
|
||||
pend = chan_dev[i];
|
||||
break;
|
||||
}
|
||||
@ -921,6 +947,8 @@ scan_chan(uint16 mask) {
|
||||
return pend;
|
||||
}
|
||||
} else {
|
||||
if (!irq_en)
|
||||
return 0;
|
||||
for (pend = 0; pend < MAX_DEV; pend++) {
|
||||
if (dev_status[pend] != 0) {
|
||||
ch = find_subchan(pend);
|
||||
@ -1048,7 +1076,7 @@ set_dev_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
uptr->u3 |= UNIT_ADDR(devaddr);
|
||||
fprintf(stderr, "Set dev %s %x\n\r", dptr->name, GET_UADDR(uptr->u3));
|
||||
} else {
|
||||
fprintf(stderr, "Set dev %s0 %x\n\r", dptr->name, GET_UADDR(uptr->u3));
|
||||
fprintf(stderr, "Set dev %s0 %x\n\r", dptr->name, devaddr);
|
||||
for (i = 0; i < dibp->numunits; i++) {
|
||||
dev_unit[devaddr + i] = dibp;
|
||||
uptr = &((dibp->units)[i]);
|
||||
@ -1073,7 +1101,7 @@ show_dev_addr(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
addr = GET_UADDR(uptr->u3);
|
||||
fprintf(st, "%03x", addr);
|
||||
fprintf(st, "DEV=%03x", addr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ UNIT coml_unit[] = {
|
||||
{UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03F)}, /* F */
|
||||
};
|
||||
|
||||
struct dib com_dib = { 0xF0, NUM_UNITS_COM, NULL, coml_startcmd,
|
||||
struct dib com_dib = { 0xF0, NUM_UNITS_COM, NULL, coml_startcmd,
|
||||
coml_haltio, coml_unit, coml_ini};
|
||||
|
||||
DEVICE com_dev = {
|
||||
@ -136,94 +136,94 @@ static const uint8 com_2741_in[128] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0-37*/
|
||||
/* 8 9 A B C D E F */
|
||||
/*BS HT LF VT FF CR SO SI */
|
||||
0xDD, 0xFA, 0xB5, 0x00, 0x00, 0x5b, 0x00, 0x00,
|
||||
0xDD, 0xFA, 0xB5, 0x00, 0x00, 0x5b, 0x00, 0x00,
|
||||
/*DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/*CAN EM SUB ESC FS GS RS US */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* sp ! " # $ % & ' */
|
||||
0x81, 0xD7, 0x00, 0x16, 0x57, 0x8B, 0x61, 0x8D, /* 40 - 77 */
|
||||
/* ( ) * + , - . / */
|
||||
0x93, 0x94, 0x00, 0xE1, 0x37, 0xC0, 0x00, 0x23,
|
||||
0x93, 0x94, 0x00, 0xE1, 0x37, 0xC0, 0x00, 0x23,
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
0x15, 0x02, 0x04, 0x07, 0x08, 0x0B, 0x0D, 0x0E,
|
||||
0x15, 0x02, 0x04, 0x07, 0x08, 0x0B, 0x0D, 0x0E,
|
||||
/* 8 9 : ; < = > ? */
|
||||
0x10, 0x13, 0x88, 0x87, 0x00, 0x82, 0x8E, 0xA3,
|
||||
0x10, 0x13, 0x88, 0x87, 0x00, 0x82, 0x8E, 0xA3,
|
||||
/* @ A B C D E F G */
|
||||
0x20, 0xE2, 0xE4, 0xE7, 0xE8, 0xEB, 0xED, 0xEE, /* 100 - 137 */
|
||||
/* H I J K L M N O */
|
||||
0xF0, 0xF3, 0xC3, 0xC5, 0xC6, 0xC9, 0xCA, 0xCC,
|
||||
0xF0, 0xF3, 0xC3, 0xC5, 0xC6, 0xC9, 0xCA, 0xCC,
|
||||
/* P Q R S T U V W */
|
||||
0xCF, 0xD1, 0xD2, 0xA5, 0xA6, 0xA9, 0xAA, 0xAC,
|
||||
0xCF, 0xD1, 0xD2, 0xA5, 0xA6, 0xA9, 0xAA, 0xAC,
|
||||
/* X Y Z [ \ ] ^ _ */
|
||||
0xAF, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xAF, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* ` a b c d e f g */
|
||||
0x00, 0x62, 0x64, 0x67, 0x68, 0x6B, 0x6D, 0x6E, /* 140 - 177 */
|
||||
/* h i j k l m n o */
|
||||
0x70, 0x73, 0x43, 0x45, 0x46, 0x49, 0x4A, 0x4C,
|
||||
0x70, 0x73, 0x43, 0x45, 0x46, 0x49, 0x4A, 0x4C,
|
||||
/* p q r s t u v w */
|
||||
0x4F, 0x51, 0x52, 0x25, 0x26, 0x29, 0x2A, 0x2C,
|
||||
0x4F, 0x51, 0x52, 0x25, 0x26, 0x29, 0x2A, 0x2C,
|
||||
/* x y z { | } ~ del*/
|
||||
0x2F, 0x31, 0x32, 0x00, 0xB7, 0x00, 0xF6, 0x00,
|
||||
0x2F, 0x31, 0x32, 0x00, 0xB7, 0x00, 0xF6, 0x00,
|
||||
};
|
||||
|
||||
static const uint8 com_2741_out[256] = {
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, ' ', '1', 0xff, '2', 0xff, 0xff, '3', /* 0x0x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
'4', 0xff, 0xff, '5', 0xff, '6', '7', 0xff,
|
||||
'4', 0xff, 0xff, '5', 0xff, '6', '7', 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
'8', 0xff, 0xff, '9', 0xff, '0', '#', 0xff, /* 0x1x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
'@', 0xff, 0xff, '/', 0xff, 's', 't', 0xff, /* 0x2x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 'u', 'v', 0xff, 'w', 0xff, 'x', 0xff,
|
||||
0xff, 'u', 'v', 0xff, 'w', 0xff, 'x', 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, 'y', 'z', 0xff, 0xff, 0xff, 0xff, ',', /* 0x3x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
'-', 0xff, 0xff, 'j', 0xff, 'k', 'l', 0xff, /* 0x4x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 'm', 'n', 0xff, 'o', 0xff, 0xff, 'p',
|
||||
0xff, 'm', 'n', 0xff, 'o', 0xff, 0xff, 'p',
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, 'q', 'r', 0xff, 0xff, 0xff, 0xff, '$', /* 0x5x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 0xff, 0xff, 0x0a, 0xff, 0x08, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x0a, 0xff, 0x08, 0xff, 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, '&', 'a', 0xff, 'b', 0xff, 0xff, 'c', /* 0x6x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
'd', 0xff, 0xff, 'e', 0xff, 'f', 'g', 0xff,
|
||||
'd', 0xff, 0xff, 'e', 0xff, 'f', 'g', 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
'h', 0xff, 0xff, 'i', 0xff, 0xff, 0xff, 0xff, /* 0x7x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 0xff, 0x09, 0xff, 0xff, 0xff, 0xff, 0x7f,
|
||||
0xff, 0xff, 0x09, 0xff, 0xff, 0xff, 0xff, 0x7f,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, ' ', '=', 0xff, '<', 0xff, 0xff, ';', /* 0x8x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
':', 0xff, 0xff, '%', 0xff, '\'', '>', 0xff,
|
||||
':', 0xff, 0xff, '%', 0xff, '\'', '>', 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
'*', 0xff, 0xff, '(', 0xff, ')', '"', 0xff, /* 0x9x */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, 0xff, 0xff, '?', 0xff, 'S', 'T', 0xff, /* 0xAx */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 'U', 'V', 0xff, 'W', 0xff, 0xff, 'X',
|
||||
0xff, 'U', 'V', 0xff, 'W', 0xff, 0xff, 'X',
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, 'Y', 'Z', 0xff, 0xff, 0xff, 0xff, '|', /* 0xBx */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, '-', 0xff, 'J', 0xff, 'K', 'L', 0xff, /* 0xCx */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 'M', 'N', 0xff, 'O', 0xff, 0xff, 'P',
|
||||
0xff, 'M', 'N', 0xff, 'O', 0xff, 0xff, 'P',
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, 'Q', 'R', 0xff, 0xff, 0xff, 0xff, '!', /* 0xDx */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
0xff, 0xff, 0xff, 0x0a, 0xff, 0x08, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x0a, 0xff, 0x08, 0xff, 0xff,
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, */
|
||||
0xff, '+', 'A', 0xff, 'B', 0xff, 0xff, 'C', /* 0xEx */
|
||||
/* 8, 9, A, B, C, D, E, F, */
|
||||
@ -331,7 +331,7 @@ t_stat coml_srv(UNIT * uptr)
|
||||
uptr->u5 = SNS_CMDREJ;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
break;
|
||||
|
||||
|
||||
case CMD_INH: /* Read data without timeout */
|
||||
case CMD_RD: /* Read in data from com line */
|
||||
if (uptr->u3 & ENAB) {
|
||||
@ -415,7 +415,7 @@ t_stat coml_srv(UNIT * uptr)
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
} else if ((uptr->u3 & POLL) == 0) {
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d enable\n", unit);
|
||||
(void)tmxr_set_get_modem_bits(&com_ldsc[unit], TMXR_MDM_DTR,
|
||||
(void)tmxr_set_get_modem_bits(&com_ldsc[unit], TMXR_MDM_DTR,
|
||||
0, NULL);
|
||||
uptr->u3 |= POLL;
|
||||
}
|
||||
|
||||
@ -23,19 +23,7 @@
|
||||
|
||||
#include "ibm360_defs.h" /* simulator defns */
|
||||
|
||||
#define FEAT_PROT (1 << (UNIT_V_UF + 8)) /* Storage protection feature */
|
||||
#define FEAT_DEC (1 << (UNIT_V_UF + 9)) /* Decimal instruction set */
|
||||
#define FEAT_FLOAT (1 << (UNIT_V_UF + 10)) /* Floating point instruction set */
|
||||
#define FEAT_UNIV (3 << (UNIT_V_UF + 9)) /* All instructions */
|
||||
#define FEAT_STOR (1 << (UNIT_V_UF + 11)) /* No alignment restrictions */
|
||||
#define FEAT_TIMER (1 << (UNIT_V_UF + 12)) /* Interval timer */
|
||||
#define FEAT_DAT (1 << (UNIT_V_UF + 13)) /* Dynamic address translation */
|
||||
#define FEAT_EFP (1 << (UNIT_V_UF + 14)) /* Extended floating point */
|
||||
#define EXT_IRQ (1 << (UNIT_V_UF_31)) /* External interrupt */
|
||||
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF + 0) /* dummy mask */
|
||||
#define UNIT_MSIZE (0xff << UNIT_V_MSIZE)
|
||||
#define MEMAMOUNT(x) (x << UNIT_V_MSIZE)
|
||||
#define MEMAMOUNT(x) (x)
|
||||
|
||||
#define TMR_RTC 0
|
||||
|
||||
@ -236,7 +224,7 @@ int32 rtc_tps = 300;
|
||||
cpu_mod CPU modifier list
|
||||
*/
|
||||
|
||||
UNIT cpu_unit = { UDATA (&rtc_srv, UNIT_BINK, MAXMEMSIZE) };
|
||||
UNIT cpu_unit[] = { { UDATA (&rtc_srv, UNIT_BINK|UNIT_FIX, MAXMEMSIZE)} };
|
||||
|
||||
REG cpu_reg[] = {
|
||||
{ HRDATA (PC, PC, 24) },
|
||||
@ -272,24 +260,25 @@ REG cpu_reg[] = {
|
||||
MTAB cpu_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(1), "16K", "16K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(2), "32K", "32K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(4), "64K", "64K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(8), "128K", "128K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(12), "196K", "196K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(16), "256K", "256K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(32), "512K", "512K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, MEMAMOUNT(128), "2M", "2M", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(1), NULL, "16K", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(2), NULL, "32K", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(4), NULL, "64K", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(8), NULL, "128K", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(12), NULL, "196K", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(16), NULL, "256K", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(32), NULL, "512K", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(64), NULL, "1M", &cpu_set_size },
|
||||
{ MTAB_VDV, MEMAMOUNT(128), NULL, "2M", &cpu_set_size },
|
||||
{ FEAT_PROT, 0, NULL, "NOPROT", NULL, NULL, NULL, "No Storage protection"},
|
||||
{ FEAT_PROT, FEAT_PROT, "PROT", "PROT", NULL, NULL, NULL, "Storage 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,
|
||||
{ FEAT_UNIV, FEAT_FLOAT, "FLOAT", "FLOAT", NULL, NULL, NULL,
|
||||
"Floating point instructions"},
|
||||
{ FEAT_FLOAT, 0, NULL, "NOFLOAT", NULL, NULL, NULL, "No floating point instructions"},
|
||||
{ FEAT_UNIV, FEAT_DEC, "DECIMAL", "DECIMAL", NULL, NULL, NULL, "Decimal instruction set"},
|
||||
{ FEAT_DEC, 0, NULL, "NODECIMAL", NULL, NULL, NULL, "No decimal instructions"},
|
||||
{ FEAT_EFP|FEAT_FLOAT, FEAT_EFP|FEAT_FLOAT, "EFLOAT", "EFLOAT", NULL, NULL, NULL,
|
||||
{ FEAT_EFP|FEAT_FLOAT, FEAT_EFP|FEAT_FLOAT, "EFLOAT", "EFLOAT", NULL, NULL, NULL,
|
||||
"Extended Floating point instruction"},
|
||||
{ FEAT_EFP, 0, NULL, "NOEFLOAT", NULL, NULL, NULL, "No extended floating point"},
|
||||
{ FEAT_STOR, FEAT_STOR, "STORE", "STORE", NULL, NULL, NULL, "No storage alignment"},
|
||||
@ -306,7 +295,7 @@ MTAB cpu_mod[] = {
|
||||
};
|
||||
|
||||
DEVICE cpu_dev = {
|
||||
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
||||
"CPU", cpu_unit, cpu_reg, cpu_mod,
|
||||
1, 16, 24, 1, 16, 8,
|
||||
&cpu_ex, &cpu_dep, &cpu_reset, NULL, NULL, NULL,
|
||||
NULL, DEV_DEBUG, 0, dev_debug,
|
||||
@ -333,7 +322,7 @@ ICM BF RS
|
||||
#endif
|
||||
|
||||
void post_extirq() {
|
||||
cpu_unit.flags |= EXT_IRQ;
|
||||
cpu_unit[0].flags |= EXT_IRQ;
|
||||
}
|
||||
|
||||
|
||||
@ -495,7 +484,7 @@ int ReadFull(uint32 addr, uint32 *data) {
|
||||
|
||||
/* Check storage key */
|
||||
if (st_key != 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
@ -508,7 +497,7 @@ int ReadFull(uint32 addr, uint32 *data) {
|
||||
|
||||
*data = M[addr];
|
||||
if (offset != 0) {
|
||||
if ((cpu_unit.flags & FEAT_STOR) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
@ -545,7 +534,7 @@ int ReadByte(uint32 addr, uint32 *data) {
|
||||
|
||||
int ReadHalf(uint32 addr, uint32 *data) {
|
||||
if (addr & 0x1) {
|
||||
if ((cpu_unit.flags & FEAT_STOR) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
@ -590,7 +579,7 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
|
||||
/* Check storage key */
|
||||
if (st_key != 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
@ -603,7 +592,7 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
|
||||
/* Check if we handle unaligned access */
|
||||
if (offset != 0) {
|
||||
if ((cpu_unit.flags & FEAT_STOR) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
@ -621,7 +610,7 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else
|
||||
pa2 = pa + 1;
|
||||
}
|
||||
|
||||
@ -666,7 +655,7 @@ int WriteByte(uint32 addr, uint32 data) {
|
||||
|
||||
/* Check storage key */
|
||||
if (st_key != 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
@ -702,14 +691,14 @@ int WriteHalf(uint32 addr, uint32 data) {
|
||||
pa >>= 2;
|
||||
|
||||
/* Check if we handle unaligned access */
|
||||
if ((offset & 1) != 0 && (cpu_unit.flags & FEAT_STOR) == 0) {
|
||||
if ((offset & 1) != 0 && (cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check storage key */
|
||||
if (st_key != 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
@ -734,7 +723,7 @@ int WriteHalf(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else
|
||||
pa2 = pa + 1;
|
||||
}
|
||||
|
||||
@ -797,8 +786,8 @@ sim_instr(void)
|
||||
reason = SCPE_OK;
|
||||
ilc = 0;
|
||||
/* Enable timer if option set */
|
||||
if (cpu_unit.flags & FEAT_TIMER) {
|
||||
sim_activate(&cpu_unit, 100);
|
||||
if (cpu_unit[0].flags & FEAT_TIMER) {
|
||||
sim_activate(&cpu_unit[0], 100);
|
||||
}
|
||||
interval_irq = 0;
|
||||
irq_en |= (loading != 0);
|
||||
@ -813,7 +802,7 @@ wait_loop:
|
||||
}
|
||||
|
||||
/* Check if we should see if an IRQ is pending */
|
||||
irq= scan_chan(sysmsk);
|
||||
irq= scan_chan(sysmsk, irq_en);
|
||||
if (irq!= 0) {
|
||||
ilc = 0;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "IRQ=%04x %08x\n", irq, PC);
|
||||
@ -829,9 +818,9 @@ wait_loop:
|
||||
|
||||
/* Check for external interrupts */
|
||||
if (ext_en) {
|
||||
if ((cpu_unit.flags & EXT_IRQ) && (cregs[4] & 0x40) != 0) {
|
||||
if ((cpu_unit[0].flags & EXT_IRQ) && (cregs[4] & 0x40) != 0) {
|
||||
ilc = 0;
|
||||
cpu_unit.flags &= ~EXT_IRQ;
|
||||
cpu_unit[0].flags &= ~EXT_IRQ;
|
||||
storepsw(OEPSW, 0x40);
|
||||
goto supress;
|
||||
}
|
||||
@ -957,7 +946,7 @@ opr:
|
||||
|
||||
/* Check if floating point */
|
||||
if ((op & 0xA0) == 0x20) {
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -1029,7 +1018,7 @@ opr:
|
||||
|
||||
case OP_BASR:
|
||||
case OP_BAS:
|
||||
if ((cpu_unit.flags & FEAT_DAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_DAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
} else {
|
||||
dest = PC;
|
||||
@ -1082,7 +1071,7 @@ opr:
|
||||
|
||||
case OP_SSK:
|
||||
dest = src1;
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
} else if (flags & PROBLEM) {
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
@ -1090,7 +1079,7 @@ opr:
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
} else if (addr1 >= MEMSIZE) {
|
||||
storepsw(OPPSW, IRC_ADDR);
|
||||
} else if (cpu_unit.flags & FEAT_PROT) {
|
||||
} else if (cpu_unit[0].flags & FEAT_PROT) {
|
||||
if (TransAddr(addr1, &addr2))
|
||||
break;
|
||||
key[addr2 >> 11] = src1 & 0xf8;
|
||||
@ -1099,7 +1088,7 @@ opr:
|
||||
|
||||
case OP_ISK:
|
||||
dest = src1;
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
} if (flags & PROBLEM) {
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
@ -1168,28 +1157,28 @@ opr:
|
||||
if (flags & PROBLEM)
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
else
|
||||
cc = startio(addr1);
|
||||
cc = startio(addr1 & 0xfff);
|
||||
break;
|
||||
|
||||
case OP_TIO:
|
||||
if (flags & PROBLEM)
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
else
|
||||
cc = testio(addr1);
|
||||
cc = testio(addr1 & 0xfff);
|
||||
break;
|
||||
|
||||
case OP_HIO:
|
||||
if (flags & PROBLEM)
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
else
|
||||
cc = haltio(addr1);
|
||||
cc = haltio(addr1 & 0xfff);
|
||||
break;
|
||||
|
||||
case OP_TCH:
|
||||
if (flags & PROBLEM)
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
else
|
||||
cc = testchan(addr1);
|
||||
cc = testchan(addr1 & 0xfff);
|
||||
break;
|
||||
|
||||
case OP_DIAG:
|
||||
@ -1307,7 +1296,7 @@ set_cc3:
|
||||
}
|
||||
#ifdef USE_64BIT
|
||||
src1L = ((t_uint64)src1) * ((t_uint64)src2);
|
||||
if (fill)
|
||||
if (fill)
|
||||
src1L = -src1L;
|
||||
if (op != OP_MH) {
|
||||
STDBL(reg1, src1L);
|
||||
@ -1720,7 +1709,7 @@ save_dbl:
|
||||
break;
|
||||
|
||||
case OP_STMC:
|
||||
if ((cpu_unit.flags & FEAT_DAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_DAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
} else if (flags & PROBLEM) {
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
@ -1765,7 +1754,7 @@ save_dbl:
|
||||
break;
|
||||
|
||||
case OP_LMC:
|
||||
if ((cpu_unit.flags & FEAT_DAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_DAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
} else if (flags & PROBLEM) {
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
@ -1787,7 +1776,7 @@ save_dbl:
|
||||
case 0x6: /* Maskes */
|
||||
sysmsk = (dest >> 16) & 0xfefe;
|
||||
cregs[reg] &= 0xfefe0000;
|
||||
if (sysmsk & 0xfe00)
|
||||
if (sysmsk & 0xfe00)
|
||||
cregs[reg] |= 0x1000000;
|
||||
if (sysmsk & 0x00fe)
|
||||
cregs[reg] |= 0x0010000;
|
||||
@ -1822,7 +1811,7 @@ save_dbl:
|
||||
break;
|
||||
|
||||
case OP_LRA:
|
||||
if ((cpu_unit.flags & FEAT_DAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_DAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
} else if (flags & PROBLEM) {
|
||||
storepsw(OPPSW, IRC_PRIV);
|
||||
@ -2279,7 +2268,7 @@ save_dbl:
|
||||
case OP_HDR:
|
||||
case OP_HER:
|
||||
//fprintf(stderr, "FP HD Op=%0x src2=%08x %08x %.12e\n\r", op, src2, src2h, cnvt_float(src2, src2h));
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2322,7 +2311,7 @@ save_dbl:
|
||||
case OP_LE:
|
||||
case OP_LD:
|
||||
//fprintf(stderr, "FP LD Op=%0x src1=%08x %08x\n\r", op, src1, src1h);
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2341,7 +2330,7 @@ save_dbl:
|
||||
case OP_LTER:
|
||||
case OP_LCER:
|
||||
//fprintf(stderr, "FP LD Op=%0x src1=%08x %08x\n\r", op, src1, src1h);
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2362,7 +2351,7 @@ save_dbl:
|
||||
|
||||
/* Floating Store register */
|
||||
case OP_STD:
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2372,7 +2361,7 @@ save_dbl:
|
||||
|
||||
case OP_STE:
|
||||
//fprintf(stderr, "FP STD Op=%0x src1=%08x %08x\n\r", op, src1, src1h);
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2382,7 +2371,7 @@ save_dbl:
|
||||
/* Floating Compare */
|
||||
case OP_CE: /* 79 */
|
||||
case OP_CER: /* 39 */
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2471,7 +2460,7 @@ save_dbl:
|
||||
case OP_AU: /* 7E */
|
||||
case OP_AER: /* 3A */
|
||||
case OP_AUR: /* 3E */
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2604,7 +2593,7 @@ save_dbl:
|
||||
/* Floating Compare */
|
||||
case OP_CD: /* 69 */
|
||||
case OP_CDR: /* 29 */
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -2766,7 +2755,7 @@ save_dbl:
|
||||
case OP_AW: /* 6E */
|
||||
case OP_ADR: /* 2A */
|
||||
case OP_AWR: /* 2E */
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3040,7 +3029,7 @@ fpstore:
|
||||
case OP_MER:
|
||||
case OP_ME:
|
||||
case OP_MD:
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3211,7 +3200,7 @@ fpnorm:
|
||||
case OP_DDR:
|
||||
case OP_DD:
|
||||
case OP_DE:
|
||||
if ((cpu_unit.flags & FEAT_FLOAT) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_FLOAT) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3393,7 +3382,7 @@ fpnorm:
|
||||
case OP_SP: /* 1011 */
|
||||
case OP_ZAP: /* 1000 */
|
||||
case OP_AP: /* 1010 */
|
||||
if ((cpu_unit.flags & FEAT_DEC) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_DEC) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3401,7 +3390,7 @@ fpnorm:
|
||||
break;
|
||||
|
||||
case OP_MP:
|
||||
if ((cpu_unit.flags & FEAT_DEC) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_DEC) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3409,7 +3398,7 @@ fpnorm:
|
||||
break;
|
||||
|
||||
case OP_DP:
|
||||
if ((cpu_unit.flags & FEAT_DEC) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_DEC) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3418,7 +3407,7 @@ fpnorm:
|
||||
|
||||
/* Extended precision load round */
|
||||
case OP_LRER:
|
||||
if ((cpu_unit.flags & FEAT_EFP) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_EFP) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3451,7 +3440,7 @@ fpnorm:
|
||||
break;
|
||||
|
||||
case OP_LRDR:
|
||||
if ((cpu_unit.flags & FEAT_EFP) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_EFP) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3472,7 +3461,7 @@ fpnorm:
|
||||
/* Add round */
|
||||
desth = src2h + 1;
|
||||
dest = src2;
|
||||
if (desth == 0)
|
||||
if (desth == 0)
|
||||
dest ++;
|
||||
|
||||
/* If overflow, shift right 4 bits */
|
||||
@ -3496,7 +3485,7 @@ fpnorm:
|
||||
|
||||
case OP_MXDR:
|
||||
case OP_MXD:
|
||||
if ((cpu_unit.flags & FEAT_EFP) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_EFP) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -3690,7 +3679,7 @@ fpnorm:
|
||||
src1 ^= MSIGN;
|
||||
/* Fall through */
|
||||
case OP_AXR:
|
||||
if ((cpu_unit.flags & FEAT_EFP) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_EFP) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -4090,7 +4079,7 @@ fpnorm:
|
||||
break;
|
||||
|
||||
case OP_MXR:
|
||||
if ((cpu_unit.flags & FEAT_EFP) == 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_EFP) == 0) {
|
||||
storepsw(OPPSW, IRC_OPR);
|
||||
goto supress;
|
||||
}
|
||||
@ -4486,6 +4475,7 @@ dec_div(int op, uint32 addr1, uint8 len1, uint32 addr2, uint8 len2)
|
||||
t_stat cpu_reset (DEVICE *dptr)
|
||||
{
|
||||
st_key = cc = pmsk = irqcode = flags = irqaddr = loading = 0;
|
||||
dat_en = irq_en = ext_en = 0;
|
||||
chan_set_devs();
|
||||
if (M == NULL) { /* first time init? */
|
||||
sim_brk_types = sim_brk_dflt = SWMASK ('E');
|
||||
@ -4502,7 +4492,7 @@ t_stat cpu_reset (DEVICE *dptr)
|
||||
t_stat
|
||||
rtc_srv(UNIT * uptr)
|
||||
{
|
||||
if (cpu_unit.flags & FEAT_TIMER) {
|
||||
if (cpu_unit[0].flags & FEAT_TIMER) {
|
||||
int32 t;
|
||||
t = sim_rtcn_calb (rtc_tps, TMR_RTC);
|
||||
sim_activate_after(uptr, 1000000/rtc_tps);
|
||||
@ -4569,7 +4559,7 @@ int32 i, clim;
|
||||
uint32 *nM = NULL;
|
||||
int32 max = MEMSIZE >> 2;
|
||||
|
||||
val = val >> UNIT_V_MSIZE;
|
||||
//val = val >> UNIT_V_MSIZE;
|
||||
val = 16 * 1024 * val;
|
||||
if ((val <= 0) || (val > MAXMEMSIZE))
|
||||
return SCPE_ARG;
|
||||
@ -4587,8 +4577,8 @@ free (M);
|
||||
M = nM;
|
||||
fprintf(stderr, "Mem size=%x\n\r", val);
|
||||
MEMSIZE = val;
|
||||
cpu_unit.flags &= ~UNIT_MSIZE;
|
||||
cpu_unit.flags |= val / (16 * 1024);
|
||||
//cpu_unit.flags &= ~UNIT_MSIZE;
|
||||
//cpu_unit.flags |= val / (16 * 1024);
|
||||
reset_all (0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@ -430,7 +430,7 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
return 0;
|
||||
|
||||
case 0x0: /* Status */
|
||||
if (cmd == 0x4) { /* Sense */
|
||||
if ((cmd & 0xF) == 0x4) { /* Sense */
|
||||
uptr->u3 |= cmd;
|
||||
return 0;
|
||||
}
|
||||
@ -724,7 +724,8 @@ index:
|
||||
switch (cmd) {
|
||||
case 0: /* No command, stop tape */
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
case 0x34:
|
||||
case 0x4: /* Sense */
|
||||
ch = uptr->u5 & 0xff;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch);
|
||||
@ -1558,6 +1559,7 @@ wrckd:
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case DK_WR_SCKD: /* Write special count, key and data */
|
||||
default:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "invalid command=%d %x\n", unit, cmd);
|
||||
|
||||
@ -30,9 +30,47 @@
|
||||
|
||||
#define MAXMEMSIZE (16*1024*1024) /* max memory size */
|
||||
#define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define MEMSIZE (cpu_unit[0].capac) /* actual memory size */
|
||||
#define MEM_ADDR_OK(x) (((x)) < MEMSIZE)
|
||||
|
||||
/* channel:
|
||||
|
||||
Channels 0 and 4 are multiplexer channels.
|
||||
subchannels = 128
|
||||
0 - 7 0x80-0xff
|
||||
8 - 127 0x00-0x7f
|
||||
256 - +6 0x1xx - 0x6xx
|
||||
|
||||
subchannels = 192
|
||||
0 - 3 0xd0-0xff
|
||||
4 - 192 0x00-0xcf
|
||||
384 - +6 0x1xx - 0x6xx
|
||||
|
||||
Channels 1,2,3,5,6 are selector channels.
|
||||
Devices on channel 0 below number of subchannels have there own
|
||||
virtual channel.
|
||||
Devices on channel 0 above the number of subchannels are mapped in
|
||||
groups of 16 into channels 0 to n.
|
||||
|
||||
Channels 1-n run on channels virtual channels above subchannels.
|
||||
*/
|
||||
|
||||
#define MAX_CHAN 6
|
||||
#define SUB_CHANS 192
|
||||
#define MAX_MUX 2
|
||||
|
||||
/* Define number of supported units for each device type */
|
||||
#define NUM_DEVS_CDP 1
|
||||
#define NUM_DEVS_CDR 1
|
||||
#define NUM_DEVS_CON 1
|
||||
#define NUM_DEVS_LPR 1
|
||||
#define NUM_DEVS_MT 1
|
||||
#define NUM_UNITS_MT 8
|
||||
#define NUM_DEVS_DASD 4
|
||||
#define NUM_UNITS_DASD 8
|
||||
#define NUM_DEVS_COM 1
|
||||
#define NUM_UNITS_COM 16
|
||||
|
||||
/* Device information block */
|
||||
typedef struct dib {
|
||||
uint8 mask; /* Device mask */
|
||||
@ -50,25 +88,27 @@ typedef struct dib {
|
||||
|
||||
#define DEV_V_ADDR DEV_V_UF /* Pointer to device address */
|
||||
#define DEV_ADDR_MASK (0x7ff << DEV_V_ADDR)
|
||||
#define DEV_V_UADDR (DEV_V_UF + 12) /* Device address in Unit */
|
||||
#define DEV_V_UADDR (DEV_V_UF + 10) /* Device address in Unit */
|
||||
#define DEV_UADDR (1 << DEV_V_UADDR)
|
||||
#define GET_DADDR(x) (0x7ff & ((x) >> DEV_V_ADDR))
|
||||
#define DEV_ADDR(x) ((x) << DEV_V_ADDR)
|
||||
|
||||
#define UNIT_V_ADDR 21
|
||||
#define UNIT_V_ADDR 20
|
||||
#define UNIT_ADDR_MASK (0x7ff << UNIT_V_ADDR)
|
||||
#define GET_UADDR(x) ((UNIT_ADDR_MASK & x) >> UNIT_V_ADDR)
|
||||
#define UNIT_ADDR(x) ((x) << UNIT_V_ADDR)
|
||||
|
||||
/* CPU options, needed by channel */
|
||||
#define FEAT_PROT (1 << (UNIT_V_UF + 8)) /* Storage protection feature */
|
||||
#define FEAT_DEC (1 << (UNIT_V_UF + 9)) /* Decimal instruction set */
|
||||
#define FEAT_FLOAT (1 << (UNIT_V_UF + 10)) /* Floating point instruction set */
|
||||
#define FEAT_UNIV (3 << (UNIT_V_UF + 9)) /* All instructions */
|
||||
#define FEAT_STOR (1 << (UNIT_V_UF + 11)) /* No alignment restrictions */
|
||||
#define FEAT_TIMER (1 << (UNIT_V_UF + 12)) /* Interval timer */
|
||||
#define FEAT_DAT (1 << (UNIT_V_UF + 13)) /* Dynamic address translation */
|
||||
#define EXT_IRQ (1 << (UNIT_V_UF_31)) /* External interrupt */
|
||||
/* CPU options */
|
||||
#define FEAT_PROT (1 << (UNIT_V_UF + 0)) /* Storage protection feature */
|
||||
#define FEAT_DEC (1 << (UNIT_V_UF + 1)) /* Decimal instruction set */
|
||||
#define FEAT_FLOAT (1 << (UNIT_V_UF + 2)) /* Floating point instruction set */
|
||||
#define FEAT_UNIV (3 << (UNIT_V_UF + 1)) /* All instructions */
|
||||
#define FEAT_STOR (1 << (UNIT_V_UF + 3)) /* No alignment restrictions */
|
||||
#define FEAT_TIMER (1 << (UNIT_V_UF + 4)) /* Interval timer */
|
||||
#define FEAT_DAT (1 << (UNIT_V_UF + 5)) /* Dynamic address translation */
|
||||
#define FEAT_EFP (1 << (UNIT_V_UF + 6)) /* Extended floating point */
|
||||
#define FEAT_370 (1 << (UNIT_V_UF + 7)) /* Is a 370 */
|
||||
#define EXT_IRQ (1 << (UNIT_V_UF + 8)) /* External interrupt */
|
||||
|
||||
/* low addresses */
|
||||
#define IPSW 0x00 /* IPSW */
|
||||
@ -98,6 +138,8 @@ typedef struct dib {
|
||||
#define OP_ISK 0x09
|
||||
#define OP_SVC 0x0A
|
||||
#define OP_BASR 0x0D
|
||||
#define OP_MVCL 0x0E /* 370 Move long */
|
||||
#define OP_CLCL 0x0F /* 370 Compare logical long */
|
||||
#define OP_LPR 0x10
|
||||
#define OP_LNR 0x11
|
||||
#define OP_LTR 0x12
|
||||
@ -220,9 +262,21 @@ typedef struct dib {
|
||||
#define OP_TIO 0x9D
|
||||
#define OP_HIO 0x9E
|
||||
#define OP_TCH 0x9F
|
||||
#define OP_STMC 0xB0
|
||||
#define OP_STNSM 0xAC /* 370 Store then and system mask */
|
||||
#define OP_STOSM 0xAD /* 370 Store then or system mask */
|
||||
#define OP_SIGP 0xAE /* 370 Signal processor */
|
||||
#define OP_MC 0xAF /* 370 Monitor call */
|
||||
#define OP_STMC 0xB0 /* 360/67 Store control */
|
||||
#define OP_LRA 0xB1
|
||||
#define OP_LMC 0xB8
|
||||
#define OP_370 0xB2 /* Misc 370 system instructions */
|
||||
#define OP_STCTL 0xB6 /* 370 Store control */
|
||||
#define OP_LCTL 0xB7 /* 370 Load control */
|
||||
#define OP_LMC 0xB8 /* 360/67 Load Control */
|
||||
#define OP_CS 0xBA /* 370 Compare and swap */
|
||||
#define OP_CDS 0xBB /* 370 Compare double and swap */
|
||||
#define OP_CLM 0xBD /* 370 Compare character under mask */
|
||||
#define OP_STCM 0xBE /* 370 Store character under mask */
|
||||
#define OP_ICM 0xBF /* 370 Insert character under mask */
|
||||
#define OP_MVN 0xD1
|
||||
#define OP_MVC 0xD2
|
||||
#define OP_MVZ 0xD3
|
||||
@ -234,6 +288,7 @@ typedef struct dib {
|
||||
#define OP_TRT 0xDD
|
||||
#define OP_ED 0xDE
|
||||
#define OP_EDMK 0xDF
|
||||
#define OP_SRP 0xF0 /* 370 Shift and round decimal */
|
||||
#define OP_MVO 0xF1
|
||||
#define OP_PACK 0xF2
|
||||
#define OP_UNPK 0xF3
|
||||
@ -281,23 +336,6 @@ typedef struct dib {
|
||||
#define STATUS_INTER 0x0002 /* Channel interface check */
|
||||
#define STATUS_CHAIN 0x0001 /* Channel chain check */
|
||||
|
||||
/* channel:
|
||||
subchannels = 128
|
||||
0 - 7 0x80-0xff
|
||||
8 - 127 0x00-0x7f
|
||||
128 - +6 0x1xx - 0x6xx
|
||||
|
||||
Devices on channel 0 below number of subchannels have there own
|
||||
virtual channel.
|
||||
Devices on channel 0 above the number of subchannels are mapped in
|
||||
groups of 16 into channels 0 to n.
|
||||
|
||||
Channels 1-n run on channels virtual channels above subchannels.
|
||||
*/
|
||||
|
||||
#define MAX_CHAN 3
|
||||
#define SUB_CHANS 192
|
||||
|
||||
void post_extirq();
|
||||
|
||||
/* look up device to find subchannel device is on */
|
||||
@ -310,7 +348,7 @@ int startio(uint16 addr) ;
|
||||
int testio(uint16 addr);
|
||||
int haltio(uint16 addr);
|
||||
int testchan(uint16 channel);
|
||||
uint16 scan_chan(uint16 mask);
|
||||
uint16 scan_chan(uint16 mask, int irq_en);
|
||||
t_stat chan_boot(uint16 addr, DEVICE *dptr);
|
||||
t_stat chan_set_devs();
|
||||
t_stat set_dev_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
|
||||
@ -347,17 +385,6 @@ extern DEVICE ddc_dev;
|
||||
extern DEVICE ddd_dev;
|
||||
extern DEVICE coml_dev;
|
||||
extern DEVICE com_dev;
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
#define NUM_DEVS_CDP 1
|
||||
#define NUM_DEVS_CDR 1
|
||||
#define NUM_DEVS_CON 1
|
||||
#define NUM_DEVS_LPR 1
|
||||
#define NUM_DEVS_MT 1
|
||||
#define NUM_UNITS_MT 8
|
||||
#define NUM_DEVS_DASD 4
|
||||
#define NUM_UNITS_DASD 8
|
||||
#define NUM_DEVS_COM 1
|
||||
#define NUM_UNITS_COM 16
|
||||
extern UNIT cpu_unit[];
|
||||
|
||||
extern void fprint_inst(FILE *, uint16 *);
|
||||
|
||||
@ -247,10 +247,19 @@ lpr_srv(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (cmd == 7) {
|
||||
uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->u6 = 0;
|
||||
chan_end(addr, SNS_DEVEND|SNS_CHNEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if ((uptr->u3 & LPR_FULL) || cmd == 0x3) {
|
||||
print_line(uptr);
|
||||
uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->u6 = 0;
|
||||
if (cmd == 0x3)
|
||||
chan_end(addr, SNS_CHNEND);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@ -855,6 +855,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Unload unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
r = sim_tape_detach(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
#include "sim_card.h"
|
||||
|
||||
extern DEVICE cpu_dev;
|
||||
extern UNIT cpu_unit;
|
||||
extern REG cpu_reg[];
|
||||
extern uint32 M[MAXMEMSIZE];
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user