mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-13 15:27:04 +00:00
IBM360: Changed storage protection, and misc cleanup.
This commit is contained in:
parent
81f824681b
commit
5ae42ddddd
@ -825,6 +825,7 @@ int haltio(uint16 addr) {
|
||||
int chan = find_subchan(addr);
|
||||
DIB *dibp = dev_unit[addr];
|
||||
UNIT *uptr;
|
||||
int cc;
|
||||
|
||||
/* Find channel this device is on, if no none return cc=3 */
|
||||
if (chan < 0 || dibp == 0) {
|
||||
@ -839,16 +840,35 @@ int haltio(uint16 addr) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x %x %x\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
|
||||
/* If channel busy, set end of buffer, return cc=2 */
|
||||
if (ccw_cmd[chan]) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
return 2;
|
||||
/* Generic halt I/O, tell device to stop and
|
||||
/* If any error pending save csw and return cc=1 */
|
||||
if (chan_status[chan] & (STATUS_PCI|STATUS_ATTN|STATUS_CHECK|\
|
||||
STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x %x cc=0\n", addr, chan,
|
||||
chan_status[chan]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Not executing a command, issue halt if available */
|
||||
if (dibp->halt_io != NULL)
|
||||
chan_status[chan] = dibp->halt_io(uptr) << 8;
|
||||
return 0;
|
||||
/* Ask device to halt if it knows how to */
|
||||
if (dibp->halt_io != NULL) {
|
||||
/* Let device do it's thing */
|
||||
cc = dibp->halt_io(uptr);
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x cc=%d\n", addr, chan, cc);
|
||||
if (cc == 1)
|
||||
M[0x44 >> 2] = (((uint32)chan_status[chan]) << 16) |
|
||||
(M[0x44 >> 2] & 0xffff);
|
||||
return cc;
|
||||
}
|
||||
|
||||
/* If channel busy, set end of buffer, return cc=2 */
|
||||
if (ccw_cmd[chan])
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
|
||||
/* Store CSW and return 1. */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x cc=1\n", addr, chan);
|
||||
M[0x44 >> 2] = (((uint32)chan_status[chan]) << 16) |
|
||||
(M[0x44 >> 2] & 0xffff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -275,14 +275,16 @@ uint8 coml_haltio(UNIT *uptr) {
|
||||
int cmd = uptr->u3 & 0xff;
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "HLTIO unit=%d %x\n", unit, cmd);
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||
return 3;
|
||||
|
||||
switch (cmd) {
|
||||
case 0:
|
||||
case CMD_DIS: /* Disable line */
|
||||
case CMD_DIAL: /* Dial call */
|
||||
case 0x4:
|
||||
/* Short commands nothing to do */
|
||||
return 0;
|
||||
/* Short commands nothing to do */
|
||||
break;
|
||||
|
||||
case CMD_INH: /* Read data without timeout */
|
||||
case CMD_RD: /* Read in data from com line */
|
||||
@ -300,7 +302,7 @@ uint8 coml_haltio(UNIT *uptr) {
|
||||
uptr->u3 &= ~0xffff;
|
||||
break;
|
||||
}
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Handle per unit commands */
|
||||
|
||||
@ -116,7 +116,6 @@ con_ini(UNIT *uptr, t_bool f) {
|
||||
|
||||
uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
int u = (uptr - con_unit);
|
||||
uint8 ch;
|
||||
|
||||
if ((uptr->u3 & CON_MSK) != 0)
|
||||
return SNS_BSY;
|
||||
@ -171,11 +170,8 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
break;
|
||||
|
||||
case 4: /* Sense */
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd SNS %02x\n", u, uptr->u5);
|
||||
/* Check if request pending */
|
||||
ch = uptr->u5;
|
||||
chan_write_byte(GET_UADDR(uptr->u3), &ch);
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
uptr->u3 |= cmd & CON_MSK;
|
||||
return 0;
|
||||
|
||||
default: /* invalid command */
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
@ -199,6 +195,15 @@ con_srv(UNIT *uptr) {
|
||||
|
||||
|
||||
switch (cmd) {
|
||||
case 0x4:
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd SNS %02x\n", u, uptr->u5);
|
||||
/* Check if request pending */
|
||||
ch = uptr->u5;
|
||||
chan_write_byte(addr, &ch);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
uptr->u3 &= ~(CON_MSK);
|
||||
break;
|
||||
|
||||
case CON_WR:
|
||||
case CON_ACR:
|
||||
if (chan_read_byte(addr, &ch)) {
|
||||
|
||||
@ -472,50 +472,53 @@ int TransAddr(uint32 va, uint32 *pa) {
|
||||
* success.
|
||||
*/
|
||||
int ReadFull(uint32 addr, uint32 *data) {
|
||||
uint32 temp;
|
||||
uint32 pa;
|
||||
int offset;
|
||||
uint8 k;
|
||||
|
||||
/* Validate address */
|
||||
if (TransAddr(addr, &addr))
|
||||
if (TransAddr(addr, &pa))
|
||||
return 1;
|
||||
|
||||
offset = addr & 0x3;
|
||||
addr >>= 2;
|
||||
|
||||
/* Check storage key */
|
||||
if (st_key != 0) {
|
||||
uint8 k;
|
||||
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
k = key[addr >> 9];
|
||||
k = key[pa >> 11];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
*data = M[addr];
|
||||
offset = pa & 0x3;
|
||||
if (offset != 0 && (cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
pa >>= 2;
|
||||
*data = M[pa];
|
||||
if (offset != 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
temp = addr + 1;
|
||||
/* Check if possible next page */
|
||||
if ((temp & 0x3ff) == 0) {
|
||||
if (TransAddr(temp << 2, &temp))
|
||||
return 1;
|
||||
temp >>= 2;
|
||||
}
|
||||
if ((temp & 0x1ff) == 0 && st_key != 0) {
|
||||
k = key[temp >> 9];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
uint32 temp;
|
||||
uint8 k;
|
||||
|
||||
temp = pa + 4;
|
||||
if ((temp & 0x7FC) == 0) {
|
||||
/* Check if possible next page */
|
||||
if (TransAddr(addr + 4, &temp))
|
||||
return 1;
|
||||
if (st_key != 0) {
|
||||
k = key[temp >> 11];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
temp >>= 2;
|
||||
temp = M[temp];
|
||||
*data <<= 8 * offset;
|
||||
temp >>= 8 * (4 - offset);
|
||||
@ -576,7 +579,10 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
|
||||
offset = pa & 0x3;
|
||||
pa >>= 2;
|
||||
if (offset != 0 && (cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check storage key */
|
||||
if (st_key != 0) {
|
||||
@ -584,36 +590,29 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
k = key[pa >> 9];
|
||||
k = key[pa >> 11];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
pa2 = pa + 4;
|
||||
/* Check if we handle unaligned access */
|
||||
if (offset != 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
if (offset != 0 && (pa2 & 0x7FC) == 0) {
|
||||
/* Validate address */
|
||||
if (TransAddr(addr + 4, &pa2))
|
||||
return 1;
|
||||
if (st_key != 0) {
|
||||
k = key[(pa2) >> 11];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if new page or new protection zone */
|
||||
if ((pa & 0x1ff) == 0x1ff) {
|
||||
/* Validate address */
|
||||
if (TransAddr(addr + 4, &pa2))
|
||||
return 1;
|
||||
pa2 >>= 2;
|
||||
if (st_key != 0) {
|
||||
k = key[(pa2) >> 9];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else
|
||||
pa2 = pa + 1;
|
||||
}
|
||||
pa >>= 2;
|
||||
pa2 >>= 2;
|
||||
|
||||
switch (offset) {
|
||||
case 0:
|
||||
@ -651,22 +650,21 @@ int WriteByte(uint32 addr, uint32 data) {
|
||||
if (TransAddr(addr, &pa))
|
||||
return 1;
|
||||
|
||||
offset = 8 * (3 - (pa & 0x3));
|
||||
pa >>= 2;
|
||||
|
||||
/* Check storage key */
|
||||
if (st_key != 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
k = key[pa >> 9];
|
||||
k = key[pa >> 11];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
offset = 8 * (3 - (pa & 0x3));
|
||||
pa >>= 2;
|
||||
mask = 0xff;
|
||||
data &= mask;
|
||||
data <<= offset;
|
||||
@ -688,44 +686,40 @@ int WriteHalf(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
|
||||
offset = pa & 0x3;
|
||||
pa >>= 2;
|
||||
|
||||
/* Check if we handle unaligned access */
|
||||
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[0].flags & FEAT_PROT) == 0) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
k = key[pa >> 9];
|
||||
k = key[pa >> 11];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset == 3) {
|
||||
/* Check if new page or new protection zone */
|
||||
if ((pa & 0x1ff) == 0x1ff) {
|
||||
/* Validate address */
|
||||
if (TransAddr(addr + 4, &pa2))
|
||||
return 1;
|
||||
pa2 >>= 2;
|
||||
if (st_key != 0) {
|
||||
k = key[(pa2) >> 9];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else
|
||||
pa2 = pa + 1;
|
||||
pa2 = pa + 4;
|
||||
if (offset == 3 && (pa2 & 0x7FC) == 0) {
|
||||
/* Validate address */
|
||||
if (TransAddr(addr + 4, &pa2))
|
||||
return 1;
|
||||
if (st_key != 0) {
|
||||
k = key[(pa2) >> 11];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
pa >>= 2;
|
||||
pa2 >>= 2;
|
||||
|
||||
mask = 0xffff;
|
||||
data &= mask;
|
||||
|
||||
@ -185,7 +185,7 @@ struct dasd_t
|
||||
uint16 tpos; /* Track position */
|
||||
uint16 rpos; /* Start of current record */
|
||||
uint16 dlen; /* remaining in data */
|
||||
uint16 tsize; /* Size of one track include rounding */
|
||||
uint32 tsize; /* Size of one track include rounding */
|
||||
uint8 state; /* Current state */
|
||||
uint8 klen; /* remaining in key */
|
||||
uint8 filemsk; /* Current file mask */
|
||||
@ -723,7 +723,7 @@ index:
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 0: /* No command, stop tape */
|
||||
case 0: /* No command */
|
||||
break;
|
||||
case 0x14:
|
||||
case 0x34:
|
||||
@ -1560,6 +1560,13 @@ wrckd:
|
||||
|
||||
break;
|
||||
|
||||
case DK_NOP:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "NOP=%d %x\n", unit, cmd);
|
||||
(void)chan_read_byte(addr, &ch);
|
||||
uptr->u6 = 0;
|
||||
uptr->u3 &= ~(0xff);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case DK_WR_SCKD: /* Write special count, key and data */
|
||||
default:
|
||||
|
||||
@ -256,8 +256,6 @@ lpr_srv(UNIT *uptr) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -386,7 +386,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||
}
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
switch (cmd & 0xf) {
|
||||
case 0: /* No command, stop tape */
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Idle unit=%d\n", unit);
|
||||
break;
|
||||
@ -631,232 +631,234 @@ t_stat mt_srv(UNIT * uptr)
|
||||
sim_activate(uptr, 20);
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_WTM:
|
||||
if (uptr->u4 == 0) {
|
||||
if (sim_tape_wrp(uptr)) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
r = sim_tape_wrtmk(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_BSR:
|
||||
switch (uptr->u4 ) {
|
||||
case 0:
|
||||
if (sim_tape_bot(uptr)) {
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
/* We don't set EOF on BSR */
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
case 0x7:
|
||||
case 0xf:
|
||||
switch (cmd) {
|
||||
case MT_WTM:
|
||||
if (uptr->u4 == 0) {
|
||||
if (sim_tape_wrp(uptr)) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d \n", reclen);
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
r = sim_tape_wrtmk(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_BSF:
|
||||
switch(uptr->u4) {
|
||||
case 0:
|
||||
if (sim_tape_bot(uptr)) {
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
break;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d\n", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_BOT) {
|
||||
uptr->u4+= 2;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_FSR:
|
||||
switch(uptr->u4) {
|
||||
case 0:
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4 = 3;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_EOM) {
|
||||
uptr->u4 = 4;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
case MT_BSR:
|
||||
switch (uptr->u4 ) {
|
||||
case 0:
|
||||
if (sim_tape_bot(uptr)) {
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
/* We don't set EOF on BSR */
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d \n", reclen);
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 4:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_FSF:
|
||||
switch(uptr->u4) {
|
||||
case 0:
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_EOM) {
|
||||
uptr->u4+= 2;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
case MT_BSF:
|
||||
switch(uptr->u4) {
|
||||
case 0:
|
||||
if (sim_tape_bot(uptr)) {
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
break;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d\n", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_BOT) {
|
||||
uptr->u4+= 2;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip done unit=%d\n", unit);
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_FSR:
|
||||
switch(uptr->u4) {
|
||||
case 0:
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4 = 3;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_EOM) {
|
||||
uptr->u4 = 4;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 4:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_ERG:
|
||||
switch (uptr->u4) {
|
||||
case 0:
|
||||
if (sim_tape_wrp(uptr)) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
} else {
|
||||
case MT_FSF:
|
||||
switch(uptr->u4) {
|
||||
case 0:
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_EOM) {
|
||||
uptr->u4+= 2;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip done unit=%d\n", unit);
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_ERG:
|
||||
switch (uptr->u4) {
|
||||
case 0:
|
||||
if (sim_tape_wrp(uptr)) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
} else {
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit);
|
||||
r = sim_tape_wrgap(uptr, 35);
|
||||
sim_activate(uptr, 5000);
|
||||
uptr->u4++;
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_REW:
|
||||
if (uptr->u4 == 0) {
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 500);
|
||||
sim_activate(uptr, 30000);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
r = sim_tape_rewind(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit);
|
||||
r = sim_tape_wrgap(uptr, 35);
|
||||
sim_activate(uptr, 5000);
|
||||
uptr->u4++;
|
||||
|
||||
case MT_RUN:
|
||||
if (uptr->u4 == 0) {
|
||||
uptr->u4 ++;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
sim_activate(uptr, 30000);
|
||||
} else {
|
||||
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;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_REW:
|
||||
if (uptr->u4 == 0) {
|
||||
uptr->u4 ++;
|
||||
sim_activate(uptr, 30000);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
r = sim_tape_rewind(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_RUN:
|
||||
if (uptr->u4 == 0) {
|
||||
uptr->u4 ++;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
sim_activate(uptr, 30000);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user