From e277497d882d04d17711d78a75d758eb97debfe3 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sun, 2 Feb 2020 21:05:30 -0500 Subject: [PATCH] IBM360: Added support for Channels 4-7. 4 being multiplexer. --- IBM360/ibm360_chan.c | 100 ++++++++++++++++++----------- IBM360/ibm360_com.c | 58 ++++++++--------- IBM360/ibm360_cpu.c | 148 ++++++++++++++++++++----------------------- IBM360/ibm360_dasd.c | 6 +- IBM360/ibm360_defs.h | 115 ++++++++++++++++++++------------- IBM360/ibm360_lpr.c | 9 +++ IBM360/ibm360_mt.c | 1 + IBM360/ibm360_sys.c | 1 - 8 files changed, 247 insertions(+), 191 deletions(-) diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index cd9cb69..eb5ff2f 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -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; } diff --git a/IBM360/ibm360_com.c b/IBM360/ibm360_com.c index 7a41a25..9b8e235 100644 --- a/IBM360/ibm360_com.c +++ b/IBM360/ibm360_com.c @@ -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; } diff --git a/IBM360/ibm360_cpu.c b/IBM360/ibm360_cpu.c index 9237638..1b2e96a 100644 --- a/IBM360/ibm360_cpu.c +++ b/IBM360/ibm360_cpu.c @@ -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; } diff --git a/IBM360/ibm360_dasd.c b/IBM360/ibm360_dasd.c index 635b83d..68545c9 100644 --- a/IBM360/ibm360_dasd.c +++ b/IBM360/ibm360_dasd.c @@ -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); diff --git a/IBM360/ibm360_defs.h b/IBM360/ibm360_defs.h index 10bd5c7..8c61cb7 100644 --- a/IBM360/ibm360_defs.h +++ b/IBM360/ibm360_defs.h @@ -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 *); diff --git a/IBM360/ibm360_lpr.c b/IBM360/ibm360_lpr.c index 84d6090..01031c9 100644 --- a/IBM360/ibm360_lpr.c +++ b/IBM360/ibm360_lpr.c @@ -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; } diff --git a/IBM360/ibm360_mt.c b/IBM360/ibm360_mt.c index 7c9d601..56c1177 100644 --- a/IBM360/ibm360_mt.c +++ b/IBM360/ibm360_mt.c @@ -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; } diff --git a/IBM360/ibm360_sys.c b/IBM360/ibm360_sys.c index 8ebac38..2d50bfa 100644 --- a/IBM360/ibm360_sys.c +++ b/IBM360/ibm360_sys.c @@ -26,7 +26,6 @@ #include "sim_card.h" extern DEVICE cpu_dev; -extern UNIT cpu_unit; extern REG cpu_reg[]; extern uint32 M[MAXMEMSIZE];