1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-03-10 12:29:26 +00:00

IBM360: Updated to DASD to run IBM 3330 disks.

This commit is contained in:
Richard Cornwell
2018-02-13 22:27:49 -05:00
parent c1e3b1935f
commit 9e48a862b4

View File

@@ -195,19 +195,20 @@ struct disk_t
unsigned int cyl; /* Number of cylinders */
unsigned int heads; /* Number of heads/cylinder */
unsigned int bpt; /* Max bytes per track */
uint8 sen_cnt; /* Number of sense bytes */
uint8 dev_type; /* Device type code */
}
disk_type[] =
{
{"2301", 1, 200, 20483, 0x01}, /* 4.1 M */
{"2302", 250, 46, 4984, 0x02}, /* 57.32 M 50ms, 120ms/10, 180ms> 10 */
{"2303", 80, 10, 4984, 0x03}, /* 4.00 M */
{"2305", 48, 8, 14568, 0x05}, /* 5.43 M */
{"2305-2",96, 8, 14858, 0x05}, /* 11.26 M */
{"2311", 202, 10, 3717, 0x11}, /* 7.32 M 156k/s 30 ms 145 full */
{"2314", 203, 20, 7294, 0x14}, /* 29.17 M */
{"3330", 411, 19, 13165, 0x30}, /* 100.00 M */
{"3330-2",815, 19, 13165, 0x30},
{"2301", 1, 200, 20483, 6, 0x01}, /* 4.1 M */
{"2302", 250, 46, 4984, 6, 0x02}, /* 57.32 M 50ms, 120ms/10, 180ms> 10 */
{"2303", 80, 10, 4984, 6, 0x03}, /* 4.00 M */
{"2305", 48, 8, 14568, 6, 0x05}, /* 5.43 M */
{"2305-2",96, 8, 14858, 6, 0x05}, /* 11.26 M */
{"2311", 202, 10, 3717, 6, 0x11}, /* 7.32 M 156k/s 30 ms 145 full */
{"2314", 203, 20, 7294, 6, 0x14}, /* 29.17 M */
{"3330", 411, 19, 13165, 24, 0x30}, /* 100.00 M */
{"3330-2",815, 19, 13165, 24, 0x30},
#if 0
{"3340", 349, 12, 8535}, /* 34.94 M */
{"3340-2",698, 12, 8535}, /* 69.89 M */
@@ -289,7 +290,7 @@ UNIT ddb_unit[] = {
{UDATA(&dasd_srv, UNIT_DASD, 0), 0, UNIT_ADDR(0x237)}, /* 7 */
};
struct dib ddb_dib = { 0xF8, NUM_UNITS_MT, dasd_startio, dasd_startcmd, NULL,
struct dib ddb_dib = { 0xF8, NUM_UNITS_MT, dasd_startio, dasd_startcmd, NULL,
ddb_unit, dasd_ini};
DEVICE ddb_dev = {
@@ -351,9 +352,9 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uptr->u5 = 0;
return SNS_CHNEND|SNS_DEVEND;
}
if (cmd == 0x0)
if (cmd == 0x0)
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
uptr->u5 = 0x48; //SNS_INTVENT|SNS_CMDREJ;
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
}
@@ -422,7 +423,7 @@ t_stat dasd_srv(UNIT * uptr)
if (state != DK_POS_SEEK && data->tpos >= data->tsize) {
sim_debug(DEBUG_POS, dptr, "state end unit=%d %d\n", unit, data->tpos);
state = DK_POS_INDEX;
}
}
switch(state) {
case DK_POS_INDEX: /* At Index Mark */
/* Read and multi-track advance to next head */
@@ -434,7 +435,7 @@ t_stat dasd_srv(UNIT * uptr)
uptr->u3 &= ~0xff;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
goto index;
}
}
uptr->u4 ++;
if ((uptr->u3 & 0x7) == 1 && (uptr->u3 & 0x60) != 0)
uptr->u3 &= ~DK_INDEX;
@@ -453,7 +454,7 @@ t_stat dasd_srv(UNIT * uptr)
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)
if ((data->filemsk & DK_MSK_SK) == DK_MSK_SKNONE)
uptr->u5 |= (SNS_WRP << 8);
else
uptr->u5 |= (SNS_NOREC << 8);
@@ -473,7 +474,7 @@ index:
data->tpos++;
if (data->count == 4) {
// sim_debug(DEBUG_DATA, dptr, "HA:unit=%d :", unit);
// for(i = 0; i < 40; i++)
// 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;
@@ -560,7 +561,7 @@ index:
/* Set next state = index */
i = (uptr->u4 >> 8) - data->cyl;
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d %d %d s=%x\n", unit, uptr->u4 >> 8, i,
data->state);
data->state);
if (i == 0) {
uptr->u3 &= ~DK_INDEX;
data->state = DK_POS_INDEX;
@@ -591,7 +592,7 @@ index:
case 0: /* No command, stop tape */
break;
case 0x4:
case 0x4: /* Sense */
ch = uptr->u5 & 0xff;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
@@ -601,12 +602,34 @@ index:
ch = 0;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 3 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
ch = unit;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
if (disk_type[type].sen_cnt > 6) {
ch = 0;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
ch = unit;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 5 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
ch = (uptr->u4 >> 8) & 0xff;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 6 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
ch = (uptr->u4 & 0x1f) | ((uptr->u4 & 0x10000) ? 0x40 : 0);
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 7 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
ch = 0; /* Compute message code */
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 8 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
i = 8;
} else {
ch = unit;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
i = 4;
}
ch = 0;
chan_write_byte(addr, &ch) ;
chan_write_byte(addr, &ch) ;
for (; i < disk_type[type].sen_cnt; i++) {
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d %d %x\n", unit, i, ch);
chan_write_byte(addr, &ch) ;
}
uptr->u3 &= ~(0xff|DK_INDEX);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
@@ -659,14 +682,14 @@ index:
break;
}
}
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_DETAIL, dptr,
"seek unit=%d %02x %02x %02x %02x %02x %02x\n", unit,
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
trk = (buf[2] << 8) | buf[3];
sim_debug(DEBUG_DETAIL, dptr, "seek unit=%d %d %d\n", unit, trk, buf[5]);
/* Check if seek valid */
if ((buf[0] | buf[1] | buf[4]) != 0 || trk > disk_type[type].cyl
if ((buf[0] | buf[1] | buf[4]) != 0 || trk > disk_type[type].cyl
|| buf[5] >= disk_type[type].heads) {
uptr->u6 = cmd;
uptr->u3 &= ~(0xff);
@@ -701,14 +724,14 @@ index:
return SCPE_OK;
case DK_RESTORE: /* Restore */
/* If we are waiting on seek to finish, check if there yet. */
if (uptr->u3 & DK_PARAM) {
if ((uptr->u4 >> 8) == data->cyl) {
uptr->u6 = cmd;
uptr->u3 &= ~(0xff);
set_devattn(addr, SNS_DEVEND);
sim_debug(DEBUG_DETAIL, dptr, "seek end unit=%d %d %d %x\n", unit,
sim_debug(DEBUG_DETAIL, dptr, "seek end unit=%d %d %d %x\n", unit,
uptr->u4 >> 8, data->cyl, data->state);
}
break;
@@ -743,21 +766,25 @@ index:
uptr->u6 = cmd;
uptr->u3 &= ~(0xff|DK_PARAM);
if (uptr->u3 & DK_MSET) {
sim_debug(DEBUG_DETAIL, dptr, "setmsk dup\n");
sim_debug(DEBUG_DETAIL, dptr, "setmsk dup\n");
uptr->u6 = 0;
uptr->u5 |= SNS_CMDREJ | (SNS_INVSEQ << 8);
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
}
/* Grab mask */
if (chan_read_byte(addr, &ch)) {
sim_debug(DEBUG_DETAIL, dptr, "setmsk rdr\n");
sim_debug(DEBUG_DETAIL, dptr, "setmsk rdr\n");
uptr->u6 = 0;
uptr->u5 |= SNS_CMDREJ;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
}
/* Save */
if (disk_type[type].dev_type >= 0x30) {
/* Clear bits which have no meaning in simulator */
ch &= 0xFC;
}
if ((ch & ~(DK_MSK_SK|DK_MSK_WRT)) != 0) {
sim_debug(DEBUG_DETAIL, dptr, "setmsk inv\n");
sim_debug(DEBUG_DETAIL, dptr, "setmsk inv\n");
uptr->u6 = 0;
uptr->u5 |= SNS_CMDREJ;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
@@ -773,7 +800,7 @@ index:
break;
case DK_SRCH_HAEQ: /* Search HA equal */
/* Wait until home address is found */
if (state == DK_POS_HA && count == 0) {
sim_debug(DEBUG_DETAIL, dptr, "search HA unit=%d %x %d %x\n",
@@ -791,7 +818,7 @@ index:
} else if (ch != *da) {
uptr->u3 |= DK_NOEQ;
}
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_DETAIL, dptr,
"search HA unit=%d %d %x %02x=%02x %d\n", unit,
count, state, ch, *da, data->tpos);
/* At end of count */
@@ -810,7 +837,7 @@ index:
case DK_RD_CNT: /* Read count */
/* Wait for next address mark */
if (state == DK_POS_AM)
if (state == DK_POS_AM)
// if (uptr->u3 & DK_PARAM) {
// uptr->u5 |= (SNS_NOREC << 8);
// uptr->u3 &= ~0xff;
@@ -839,7 +866,7 @@ index:
case DK_SRCH_IDGE: /* Search ID greater or equal */
/* Wait for beginning of count segment */
if (state == DK_POS_CNT && count == 0) {
sim_debug(DEBUG_DETAIL, dptr, "search ID unit=%d %x %d %x %d\n",
sim_debug(DEBUG_DETAIL, dptr, "search ID unit=%d %x %d %x %d\n",
unit, state, count, uptr->u4, data->rec);
uptr->u3 &= ~(DK_SRCOK|DK_SHORTSRC|DK_NOEQ|DK_HIGH);
uptr->u3 |= DK_PARAM;
@@ -857,7 +884,7 @@ index:
uptr->u3 |= DK_HIGH;
}
}
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_DETAIL, dptr,
"search ID unit=%d %d %x %02x=%02x %d %c %c\n", unit, count,
state, ch, *da, data->tpos,
((uptr->u3 & DK_NOEQ) ? '!' : '='),
@@ -886,7 +913,7 @@ index:
/* Check proper sequence */
sim_debug(DEBUG_DETAIL, dptr, "search Key cn unit=%d %x %d %x %d %x\n",
unit, state, count, uptr->u4, data->rec, uptr->u6);
if (uptr->u6 == DK_RD_CNT || uptr->u6 == 0x100
if (uptr->u6 == DK_RD_CNT || uptr->u6 == 0x100
|| ((uptr->u6 & 0x1F) == 0x11 && /* Search ID */
(uptr->u3 & (DK_SRCOK|DK_SHORTSRC)) == DK_SRCOK )) {
uptr->u3 &= ~(DK_SRCOK|DK_SHORTSRC|DK_NOEQ|DK_HIGH);
@@ -903,7 +930,7 @@ index:
uptr->u3 &= ~(0xff);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
}
}
}
/* If we hit address mark, see if over */
if (state == DK_POS_AM) {
@@ -930,7 +957,7 @@ index:
uptr->u3 |= DK_HIGH;
}
}
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_DETAIL, dptr,
"search Key unit=%d %d %x %02x=%02x %d %c %c\n", unit, count,
state, ch, *da, data->tpos,
((uptr->u3 & DK_NOEQ) ? '!' : '='),
@@ -981,7 +1008,7 @@ index:
}
/* Wait for seek to finish */
if (data->cyl != 0)
if (data->cyl != 0)
break;
/* Read in the first record on track zero */
@@ -1021,7 +1048,7 @@ index:
if (count == 0 && state == DK_POS_KEY) {
uptr->u3 |= DK_PARAM;
uptr->u3 &= ~DK_INDEX;
sim_debug(DEBUG_DETAIL, dptr, "RD KD unit=%d %d k=%d d=%d %02x %04x\n",
sim_debug(DEBUG_DETAIL, dptr, "RD KD unit=%d %d k=%d d=%d %02x %04x\n",
unit, data->rec, data->klen, data->dlen, data->state,
8 + data->klen + data->dlen);
}
@@ -1144,7 +1171,7 @@ rd:
state, count);
/* Check if command ok based on mask */
i = data->filemsk & DK_MSK_WRT;
if (i == DK_MSK_INHWRT || i == DK_MSK_ALLWRU) {
if (i == DK_MSK_INHWRT || i == DK_MSK_ALLWRU) {
sim_debug(DEBUG_DETAIL, dptr, "Wr CKD unit=%d mask\n", unit);
uptr->u5 |= SNS_CMDREJ;
uptr->u6 = 0;
@@ -1169,7 +1196,7 @@ rd:
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
}
}
goto wrckd;
goto wrckd;
case DK_WR_KD: /* Write key and data */
/* Wait for beginning of next key */
@@ -1260,9 +1287,9 @@ wrckd:
if (state == DK_POS_CNT && count == 7) {
data->klen = rec[5];
data->dlen = (rec[6] << 8) | rec[7];
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_DETAIL, dptr,
"WCKD count unit=%d %d k=%d d=%d %02x %04x\n",
unit, data->rec, data->klen, data->dlen, data->state,
unit, data->rec, data->klen, data->dlen, data->state,
8 + data->klen + data->dlen);
data->state = DK_POS_KEY;
if (data->klen == 0)
@@ -1276,7 +1303,7 @@ wrckd:
if (state == DK_POS_AM || state == DK_POS_END) {
/* Check if command ok based on mask */
i = data->filemsk & DK_MSK_WRT;
if (i == DK_MSK_INHWRT || i == DK_MSK_ALLWRU) {
if (i == DK_MSK_INHWRT || i == DK_MSK_ALLWRU) {
uptr->u5 |= SNS_CMDREJ;
uptr->u6 = 0;
uptr->u3 &= ~(0xff);
@@ -1478,7 +1505,7 @@ dasd_detach(UNIT * uptr)
if (uptr->u3 & DK_CYL_DIRTY) {
(void)sim_fseek(uptr->fileref, data->cpos, SEEK_SET);
(void)sim_fwrite(data->cbuf, 1,
(void)sim_fwrite(data->cbuf, 1,
data->tsize * disk_type[type].heads, uptr->fileref);
uptr->u3 &= ~DK_CYL_DIRTY;
}
@@ -1548,7 +1575,7 @@ t_stat dasd_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
for (i = 0; disk_type[i].name != 0; i++) {
fprintf(st, "%s", disk_type[i].name);
if (disk_type[i+1].name != 0)
fprintf(st, ", ");
fprintf(st, ", ");
}
fprintf (st, ".\nEach drive has the following storage capacity:\n\n");
for (i = 0; disk_type[i].name != 0; i++) {