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

IBM360: Updated to better run OS/360.

This commit is contained in:
Richard Cornwell
2018-10-05 13:06:18 -04:00
parent e65398a9a4
commit 42b9898ad2
2 changed files with 113 additions and 37 deletions

View File

@@ -543,6 +543,7 @@ sim_instr(void)
t_uint64 t64;
t_uint64 t64a;
uint16 ops[3];
uint16 dec_acc[8];
reason = SCPE_OK;
ilc = 0;
@@ -556,36 +557,37 @@ sim_instr(void)
wait_loop:
if (sim_interval <= 0) {
reason = sim_process_event();
if (reason != SCPE_OK)
return reason;
reason = sim_process_event();
if (reason != SCPE_OK)
return reason;
}
irq= scan_chan(sysmsk);
if (irq!= 0) {
ilc = 0;
if (loading) {
irqcode = irq;
(void)WriteHalf(0x2, irq);
loading = 0;
irqaddr = 0;
} else
storepsw(OIOPSW, irq);
goto supress;
sim_debug(DEBUG_DETAIL, &cpu_dev, "IRQ=%04x %08x ", irq, PC);
if (loading) {
irqcode = irq;
(void)WriteHalf(0x2, irq);
loading = 0;
irqaddr = 0;
} else
storepsw(OIOPSW, irq);
goto supress;
}
if ((cpu_unit.flags & EXT_IRQ) && (sysmsk & 01)) {
ilc = 0;
cpu_unit.flags &= ~EXT_IRQ;
storepsw(OEPSW, 0x40);
goto supress;
ilc = 0;
cpu_unit.flags &= ~EXT_IRQ;
storepsw(OEPSW, 0x40);
goto supress;
}
if (interval_irq && (sysmsk & 01)) {
ilc = 0;
interval_irq = 0;
storepsw(OEPSW, 0x80);
goto supress;
ilc = 0;
interval_irq = 0;
storepsw(OEPSW, 0x80);
goto supress;
}
if (loading || flags & WAIT) {
@@ -1954,10 +1956,11 @@ save_dbl:
case OP_SP:
case OP_ZAP:
case OP_AP:
/* Get sign of second operand */
/* If op & 1 flip sign */
/* Get sign of first operand */
/* Compute sign of result */
if ((cpu_unit.flags & FEAT_DEC) == 0) {
storepsw(OPPSW, IRC_OPR);
goto supress;
}
case OP_MP:
case OP_DP:
storepsw(OPPSW, IRC_OPR);
@@ -2019,6 +2022,7 @@ lpsw:
}
}
/* Reset */
t_stat cpu_reset (DEVICE *dptr)

View File

@@ -384,6 +384,82 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
return SNS_CHNEND|SNS_DEVEND;
}
/* Compute position on new track. */
void dasd_adjpos(UNIT * uptr)
{
uint16 addr = GET_UADDR(uptr->u3);
struct dasd_t *data = (struct dasd_t *)(uptr->up7);
uint8 *rec;
int pos;
/* Save current position */
pos = data->tpos;
/* Set ourselves to start of track */
data->state = DK_POS_HA;
data->rpos = data->rec = data->count = data->klen = data->dlen = 0;
data->tstart = (uptr->u4 & 0xff) * data->tsize;
rec = &data->cbuf[data->rpos + data->tstart];
/* Skip forward until we reach pos */
for (data->tpos = 0; data->tpos < pos; data->tpos++) {
switch(data->state) {
case DK_POS_HA: /* In home address (c) */
if (data->count == 4) {
data->tpos = data->rpos = 5;
data->state = DK_POS_CNT;
rec = &data->cbuf[data->rpos + data->tstart];
/* Check for end of track */
if ((rec[0] & rec[1] & rec[2] & rec[3]) == 0xff)
data->state = DK_POS_END;
}
break;
case DK_POS_CNT: /* In count (c) */
if (data->count == 0) {
/* Check for end of track */
if ((rec[0] & rec[1] & rec[2] & rec[3]) == 0xff) {
data->state = DK_POS_END;
}
data->klen = rec[5];
data->dlen = (rec[6] << 8) | rec[7];
}
if (data->count == 7) {
data->state = DK_POS_KEY;
if (data->klen == 0)
data->state = DK_POS_DATA;
}
break;
case DK_POS_KEY: /* In Key area */
if (data->count == data->klen) {
data->state = DK_POS_DATA;
data->count = 0;
}
break;
case DK_POS_DATA: /* In Data area */
if (data->count == data->dlen) {
data->state = DK_POS_AM;
}
break;
case DK_POS_AM: /* Beginning of record */
data->rpos += data->dlen + data->klen + 8;
data->tpos = data->rpos;
data->rec++;
data->state = DK_POS_CNT;
data->count = 0;
rec = &data->cbuf[data->rpos + data->tstart];
/* Check for end of track */
if ((rec[0] & rec[1] & rec[2] & rec[3]) == 0xff)
data->state = DK_POS_END;
break;
case DK_POS_END: /* Past end of data */
data->tpos+=10;
data->count = 0;
data->klen = 0;
data->dlen = 0;
return;
}
}
}
/* Handle processing of disk requests. */
t_stat dasd_srv(UNIT * uptr)
{
@@ -430,11 +506,11 @@ t_stat dasd_srv(UNIT * uptr)
/* Read and multi-track advance to next head */
if ((uptr->u3 & 0x83) == 0x82 || (uptr->u3 & 0x83) == 0x81) {
uptr->u4 ++;
sim_debug(DEBUG_DETAIL, dptr, "adv head unit=%d %02x %d %d %02x\n", unit, state,
data->tpos, uptr->u4 & 0xff, data->filemsk);
sim_debug(DEBUG_DETAIL, dptr, "adv head unit=%d %02x %d %d %02x\n",
unit, state, data->tpos, uptr->u4 & 0xff, data->filemsk);
if ((uptr->u4 & 0xff) >= disk_type[type].heads) {
sim_debug(DEBUG_DETAIL, dptr, "end cyl unit=%d %02x %d\n", unit, state,
data->tpos);
sim_debug(DEBUG_DETAIL, dptr, "end cyl unit=%d %02x %d\n",
unit, state, data->tpos);
uptr->u5 = (SNS_ENDCYL << 8);
data->tstart = 0;
uptr->u4 &= ~0xff;
@@ -452,8 +528,8 @@ t_stat dasd_srv(UNIT * uptr)
uptr->u3 &= ~DK_INDEX;
}
if ((uptr->u4 & 0xff) >= disk_type[type].heads) {
sim_debug(DEBUG_DETAIL, dptr, "end cyl unit=%d %02x %d\n", unit, state,
data->tpos);
sim_debug(DEBUG_DETAIL, dptr, "end cyl unit=%d %02x %d\n",
unit, state, data->tpos);
uptr->u5 = (SNS_ENDCYL << 8);
data->tstart = 0;
uptr->u4 &= ~0xff;
@@ -462,8 +538,8 @@ t_stat dasd_srv(UNIT * uptr)
}
/* If INDEX set signal no record if read */
if ((cmd & 0x03) == 0x01 && uptr->u3 & DK_INDEX) {
sim_debug(DEBUG_DETAIL, dptr, "index unit=%d %02x %d\n", unit, state,
data->tpos);
sim_debug(DEBUG_DETAIL, dptr, "index unit=%d %02x %d\n",
unit, state, data->tpos);
/* No seeks allowed, error out */
if ((data->filemsk & DK_MSK_SK) == DK_MSK_SKNONE)
uptr->u5 |= (SNS_WRP << 8);
@@ -484,10 +560,6 @@ index:
case DK_POS_HA: /* In home address (c) */
data->tpos++;
if (data->count == 4) {
// sim_debug(DEBUG_DATA, dptr, "HA:unit=%d :", unit);
// for(i = 0; i < 40; i++)
// sim_debug(DEBUG_DATA, dptr, "%d:%02x ", i, rec[i]);
// sim_debug(DEBUG_DATA, dptr, "\n");
data->tpos = data->rpos = 5;
data->state = DK_POS_CNT;
sim_debug(DEBUG_POS, dptr, "state HA unit=%d %d %d\n", unit, data->count,
@@ -751,10 +823,10 @@ index:
/* Do seek */
uptr->u3 |= DK_PARAM;
data->state = DK_POS_SEEK;
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d doing\n", unit);
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d doing\n", unit);
chan_end(addr, SNS_CHNEND);
} else {
data->tstart = buf[5] * data->tsize; /* Point to start of record */
dasd_adjpos(uptr);
uptr->u6 = cmd;
uptr->u3 &= ~(0xff);
chan_end(addr, SNS_DEVEND|SNS_CHNEND);