1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-04-17 00:35:52 +00:00

IBM360: Major update. MVT now can be built.

CDR:  Clean up to return correct status on EOF and empty deck.
   CHAN: Fixed problems with storage key support.
   CHAN: Proper handling of error on initial connect to device.
   CPU:  Fixed errors in handling of storage key protection.
   CPU:  Added aligned data access.
   CPU:  Floating point code starting to work. Still some errors.
   DASD: Corrected sense data for 2311 and 2314 drives for CP/67.
   MT:   Cleaned up proper handling of unattached units.
   SYS:  Fixed bug in deposit.
This commit is contained in:
Richard Cornwell
2019-01-21 22:57:36 -05:00
parent 2f2c0bfa0d
commit 883dd27f9f
8 changed files with 537 additions and 297 deletions

View File

@@ -3,24 +3,20 @@ Current status:
Operating Systems:
TOS/360: Will IPL, and read IPL deck. Will run some jobs.
DOS/360: Will initialize disk.
Will restore disk.
Will run basic commands.
Assembly aborts with invalid instruction.
DOS/360: Will restore and run supervisor gen job on 2314.
OS/360: Will initialize disk.
Will restore disk.
Can run some jobs.
OS/360: MVT can be generated. Fortran, Algol working.
ibm360_cpu.c:
Need to complete floating point and decimal instructions.
Floating point starting to work.
Decimal instructions need test.
Complete /67 support.
ibm360_chan.c
More debugging required.
Mostly working.
ibm360_cdp.c:
Add support for binary mode.
Fix translation table.
ibm360_cdr.c:
Add support for binary mode.
@@ -32,15 +28,15 @@ ibm360_con.c:
Appears to be working.
ibm360_dasd.c:
Possibly working.
Mostly working.
ibm360_lpr.c:
Need to add in support for line skip and skip control.
ibm360_mt.c:
Possibly working.
Mostly working.
ibm360_sys.c:
Need to add in deposit function.
Working.

View File

@@ -119,6 +119,16 @@ uint8 cdr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
}
sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x\n", unit, cmd);
if (cmd != 4 && sim_card_eof(uptr) == 1) {
uint16 *image = (uint16 *)(uptr->up7);
uptr->u5 = SNS_INTVENT;
sim_read_card(uptr, image); /* Read in the EOF */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
}
if (cmd != 4 && (uptr->flags & UNIT_ATT) == 0) {
uptr->u5 = SNS_INTVENT;
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
}
switch (cmd & 0x7) {
case 2: /* Read command */
if ((cmd & 0xc0) != 0xc0)
@@ -171,6 +181,8 @@ cdr_srv(UNIT *uptr) {
if ((uptr->u3 & CDR_CMDMSK) == CHN_SNS) {
uint8 ch = uptr->u5;
if (ch == 0 && (uptr->flags & UNIT_ATT) == 0)
ch = SNS_INTVENT;
chan_write_byte(addr, &ch);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
uptr->u3 &= ~(CDR_CMDMSK);
@@ -180,16 +192,16 @@ cdr_srv(UNIT *uptr) {
/* Check if new card requested. */
if ((uptr->u3 & CDR_CARD) == 0) {
switch(sim_read_card(uptr, image)) {
case CDSE_EOF:
case CDSE_EMPTY:
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
uptr->u5 = SNS_INTVENT;
case CDSE_EOF:
uptr->u3 &= ~CDR_CMDMSK;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
return SCPE_OK;
case CDSE_ERROR:
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
uptr->u5 = SNS_INTVENT;
uptr->u3 &= ~CDR_CMDMSK;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
case CDSE_OK:
uptr->u3 |= CDR_CARD;

View File

@@ -150,22 +150,26 @@ readfull(int chan, uint32 addr, uint32 *word) {
int sk, k;
if ((addr & AMASK) > MEMSIZE) {
chan_status[chan] |= STATUS_PCHK;
irq_pend = 1;
return 1;
}
sk = (addr >> 24) & 0xff;
sk = (addr >> 24) & 0xf0;
addr &= AMASK;
addr >>= 2;
if (sk != 0) {
if ((cpu_dev.flags & PROTECT) == 0) {
if ((cpu_unit.flags & FEAT_PROT) == 0) {
chan_status[chan] |= STATUS_PROT;
irq_pend = 1;
return 1;
}
k = key[(addr & 0xfffc00) >> 10];
k = key[addr >> 9];
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
chan_status[chan] |= STATUS_PROT;
irq_pend = 1;
return 1;
}
}
addr &= AMASK;
addr >>= 2;
*word = M[addr];
return 0;
}
@@ -184,24 +188,25 @@ readbuff(int chan) {
irq_pend = 1;
return 1;
}
sk = (addr >> 24) & 0xff;
sk = (addr >> 24) & 0xf0;
addr &= AMASK;
addr >>= 2;
if (sk != 0) {
if ((cpu_dev.flags & PROTECT) == 0) {
if ((cpu_unit.flags & FEAT_PROT) == 0) {
chan_status[chan] |= STATUS_PROT;
chan_byte[chan] = BUFF_CHNEND;
irq_pend = 1;
return 1;
}
k = key[(addr & 0xfffc00) >> 10];
k = key[addr >> 9];
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
chan_status[chan] |= STATUS_PROT;
chan_byte[chan] = BUFF_CHNEND;
irq_pend = 1;
return 1;
}
}
addr &= AMASK;
addr >>= 2;
chan_buf[chan] = M[addr];
if ((ccw_cmd[chan] & CMD_TYPE) == CMD_WRITE) {
sim_debug(DEBUG_CDATA, &cpu_dev, "Channel write %02x %06x %08x %08x '",
@@ -233,23 +238,24 @@ writebuff(int chan) {
return 1;
}
sk = (addr >> 24) & 0xff;
addr &= AMASK;
addr >>= 2;
if (sk != 0) {
if ((cpu_dev.flags & PROTECT) == 0) {
if ((cpu_unit.flags & FEAT_PROT) == 0) {
chan_status[chan] |= STATUS_PROT;
chan_byte[chan] = BUFF_CHNEND;
irq_pend = 1;
return 1;
}
k = key[(addr & 0xfffc00) >> 10];
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
k = key[addr >> 9];
if ((k & 0xf0) != sk) {
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
chan_status[chan] |= STATUS_PROT;
chan_byte[chan] = BUFF_CHNEND;
irq_pend = 1;
return 1;
}
}
addr &= AMASK;
addr >>= 2;
M[addr] = chan_buf[chan];
sim_debug(DEBUG_CDATA, &cpu_dev, "Channel readf %02x %06x %08x %08x '",
chan, ccw_addr[chan] & 0xFFFFFC, chan_buf[chan], ccw_count[chan]);
@@ -575,8 +581,6 @@ int startio(uint16 addr) {
uptr = find_chan_dev(addr);
if (uptr == 0)
return 3;
if ((uptr->flags & UNIT_ATT) == 0)
return 3;
if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0 || chan_status[chan] != 0)
return 2;
sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x\n", addr, chan,
@@ -595,13 +599,24 @@ int startio(uint16 addr) {
return 1;
}
}
if (load_ccw(chan, 0) || (chan_status[chan] & (STATUS_PCI))) {
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff;
sim_debug(DEBUG_EXP, &cpu_dev, "Channel store csw %02x %08x\n",
chan, M[0x44 >> 2]);
chan_status[chan] &= ~STATUS_PCI;
dev_status[addr] = 0;
return 1;
if (load_ccw(chan, 0)) {
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,
ccw_cmd[chan], ccw_flags[chan]);
chan_status[chan] = 0;
dev_status[addr] = 0;
ccw_cmd[chan] = 0;
return 1;
}
if (chan_status[chan] & (STATUS_PCI)) {
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff;
sim_debug(DEBUG_EXP, &cpu_dev, "Channel store csw %02x %08x\n",
chan, M[0x44 >> 2]);
chan_status[chan] &= ~STATUS_PCI;
dev_status[addr] = 0;
return 1;
}
}
if (chan_status[chan] & STATUS_BUSY) {
M[0x40 >> 2] = 0;
@@ -628,34 +643,32 @@ int testio(uint16 addr) {
uptr = find_chan_dev(addr);
if (uptr == 0)
return 3;
if ((uptr->flags & UNIT_ATT) == 0)
return 3;
if (chan_status[chan] & (STATUS_PCI|STATUS_ATTN|STATUS_CHECK|\
STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) {
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1\n", addr, chan,
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
store_csw(chan);
return 1;
}
if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2\n", addr, chan,
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
return 2;
}
}
if (chan_dev[chan] != 0 && chan_dev[chan] != addr) {
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2a\n", addr, chan,
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2a\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
return 2;
}
}
if (ccw_cmd[chan] == 0 && chan_status[chan] != 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1a\n", addr, chan,
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1a\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
store_csw(chan);
chan_dev[chan] = 0;
return 1;
}
if (dev_status[addr] != 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1b\n", addr, chan,
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1b\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
M[0x40 >> 2] = 0;
M[0x44 >> 2] = ((uint32)dev_status[addr]) << 24;
@@ -663,18 +676,21 @@ int testio(uint16 addr) {
return 1;
}
chan_status[chan] = dibp->start_cmd(uptr, chan, 0) << 8;
if (chan_status[chan] & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) {
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1c\n", addr, chan,
status = dibp->start_cmd(uptr, chan, 0) << 8;
if (status == 0 && (uptr->flags & UNIT_ATT) == 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1c\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
return 3;
}
if (status & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) {
M[0x44 >> 2] = ((uint32)status<<24) | M[0x44 >> 2] & 0xffff;
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1d\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff;
chan_status[chan] = 0;
dev_status[addr] = 0;
return 1;
}
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=0\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
chan_status[chan] = 0;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -386,7 +386,7 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %02x\n", unit, cmd);
if ((uptr->flags & UNIT_ATT) == 0) {
if (cmd == 0x4) { /* Sense */
sim_debug(DEBUG_CMD, dptr, "CMD sense\n");
sim_debug(DEBUG_CMD, dptr, "CMD sense\n");
ch = uptr->u5 & 0xff;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
@@ -406,9 +406,9 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
return SNS_CHNEND|SNS_DEVEND;
}
if (cmd == 0x0)
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
return 0;
uptr->u5 = 0x48; /*SNS_INTVENT|SNS_CMDREJ; */
uptr->u5 = SNS_INTVENT|SNS_CMDREJ;
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
}
@@ -734,7 +734,7 @@ index:
if (chan_write_byte(addr, &ch))
goto sense_end;
if (disk_type[type].sen_cnt > 6) {
ch = 0;
ch = (unit & 07) | ((~unit & 07) << 3);
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
if (chan_write_byte(addr, &ch))
goto sense_end;
@@ -756,11 +756,20 @@ index:
goto sense_end;
i = 8;
} else {
ch = unit;
if (disk_type[type].dev_type == 0x11)
ch = 0xc8;
else
ch = 0x40;
if ((uptr->u4 >> 8) & SNS_ENDCYL)
ch |= 4;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
if (chan_write_byte(addr, &ch))
goto sense_end;
i = 4;
ch = unit;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 5 %x\n", unit, ch);
if (chan_write_byte(addr, &ch))
goto sense_end;
i = 5;
}
ch = 0;
for (; i < disk_type[type].sen_cnt; i++) {

View File

@@ -76,17 +76,15 @@ typedef struct dib {
#define GET_UADDR(x) ((UNIT_ADDR_MASK & x) >> UNIT_V_ADDR)
#define UNIT_ADDR(x) ((x) << UNIT_V_ADDR)
#define PROTECT_V UNIT_V_UF+12
#define PROTECT (1 << PROTECT_V)
/* Arithmetic */
/* Instruction format */
/* Globally visible flags */
/* I/O routine functions */
/* 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 */
/* low addresses */
#define IPSW 0x00 /* IPSW */

View File

@@ -268,6 +268,10 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
case 0x3: /* Control */
case 0xb: /* Control */
if ((uptr->flags & UNIT_ATT) == 0) {
uptr->u5 |= SNS_INTVENT;
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
}
if ((uptr->flags & MTUF_9TR) == 0) {
uptr->u5 |= (SNS_7TRACK << 8);
if ((cmd & 0xc0) == 0xc0) {
@@ -375,8 +379,12 @@ t_stat mt_srv(UNIT * uptr)
if ((uptr->flags & UNIT_ATT) == 0) {
uptr->u5 |= SNS_INTVENT;
if (cmd != MT_SENSE)
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
if (cmd != MT_SENSE) {
uptr->u3 &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
}
switch (cmd) {

View File

@@ -918,7 +918,7 @@ if (sw & SWMASK ('M')) {
}
num = get_uint(cptr, rdx, max[l], &r);
for (i = 0; i < l && i < 4; i++)
val[i] = (num >> (i * 8)) & 0xff;
val[i] = (num >> (((l - 1) - i) * 8)) & 0xff;
return -(l-1);
}