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:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user