1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-13 15:27:04 +00:00

I7000: Fix some bugs in card reader and magnetic tape controller.

This commit is contained in:
Richard Cornwell 2023-11-27 16:29:21 -05:00
parent 4d62c0f755
commit eaf766e7ff
2 changed files with 66 additions and 32 deletions

View File

@ -122,8 +122,10 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
uptr->u5 &= ~0xF0000;
uptr->u5 |= stk << 16;
#endif
if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR))
if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR)) {
uptr->u5 &= ~(URCSTA_EOF|URCSTA_ERR);
return SCPE_IOERR;
}
/* Process commands */
switch(cmd) {
@ -141,15 +143,19 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
#endif
break;
default:
sim_debug(DEBUG_CMD, &cdr_dev, "%d: CMD none %02o\n", u, cmd);
chan_set_attn(chan);
return SCPE_IOERR;
}
/* If at eof, just return EOF */
if (uptr->u5 & URCSTA_EOF) {
if (sim_card_eof(uptr)) {
uint16 *image = (uint16 *)(uptr->up7);
chan_set_eof(chan);
chan_set_attn(chan);
return SCPE_OK;
uptr->u5 &= ~(URCSTA_EOF|URCSTA_ERR);
(void)sim_read_card(uptr, image);
return SCPE_IOERR;
}
uptr->u5 |= URCSTA_READ;
@ -256,6 +262,10 @@ cdr_srv(UNIT *uptr) {
#endif
ch = sim_hol_to_bcd(image[uptr->u4]);
/* Handle 7-9 to generate 20 */
if (ch == 012 && image[uptr->u4] == 0202) {
ch = 020;
}
/* Handle invalid punch */
if (ch == 0x7f) {
@ -288,7 +298,7 @@ cdr_srv(UNIT *uptr) {
uptr->u4++;
break;
}
sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %02o\n", u, ch);
sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %04o %02o\n", u, image[uptr->u4-1], ch);
sim_activate(uptr, 10);
}
return SCPE_OK;

View File

@ -78,6 +78,8 @@
#define MT_EOR 002000 /* Set EOR on next record */
#define MT_UNLOAD 004000 /* Unload when rewind done */
#define MT_EGAP 010000 /* Write extended gap on next write */
#define MT_LWR 020000 /* Last command was a write */
#define MT_CLRIND 040000 /* On I7010 flag for SKR to clear indicator */
/* u6 holds the current buffer position */
@ -238,9 +240,9 @@ UNIT mta_unit[] = {
};
MTAB mt_mod[] = {
{ MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED",
{ MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED",
&set_writelock, &show_writelock, NULL, "Write ring in place" },
{ MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED",
{ MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED",
&set_writelock, NULL, NULL, "no Write ring in place" },
{MTUF_LDN, 0, "high density", "HIGH", &mt_tape_density, NULL, NULL,
"556 BPI"},
@ -393,7 +395,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
/* If drive is offline or not attached return not ready */
if ((uptr->flags & (UNIT_ATT | MTUF_ONLINE)) !=
(UNIT_ATT | MTUF_ONLINE)) {
sim_printf("Attempt to access offline unit %s%d\n\r", dptr->name, unit);
sim_messagef(SCPE_OK, "Attempt to access offline unit %s%d\n\r", dptr->name, unit);
return SCPE_IOERR;
}
/* Check if drive is ready to recieve a command */
@ -798,7 +800,7 @@ t_stat mt_srv(UNIT * uptr)
switch (cmd) {
case 0: /* No command, stop tape */
uptr->u5 |= MT_RDY; /* Ready since command is done */
mt_chan[chan] &= ~MTC_BSY;
mt_chan[chan] &= ~MTC_BSY;
sim_debug(DEBUG_DETAIL, dptr, "Idle unit=%d\n", unit);
return SCPE_OK;
@ -821,6 +823,7 @@ t_stat mt_srv(UNIT * uptr)
/* Fall through */
case MT_RDSB:
uptr->u5 &= ~MT_LWR; /* Not write command */
/* Post EOR */
if (uptr->u5 & MT_EOR) {
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post EOR\n", unit);
@ -901,13 +904,14 @@ t_stat mt_srv(UNIT * uptr)
uptr->u3++;
/* Do BCD translation */
if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) {
sim_debug(DEBUG_DETAIL, dptr, "%s parity error %d %03o\n",
(cmd == MT_RDS) ? "BCD" : "Binary", uptr->u3-1, ch);
#ifdef I7010
if (astmode)
ch = 054;
#else
chan_set_attn(chan);
#endif
chan_set_error(chan);
}
#if I7090 | I704 | I701
/* Not needed on decimal machines */
@ -973,6 +977,7 @@ t_stat mt_srv(UNIT * uptr)
mode = 0100;
/* fall through */
case MT_WRSB:
uptr->u5 |= MT_LWR; /* write command */
if (uptr->u5 & MT_EGAP) {
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
uptr->u5 &= ~MT_EGAP;
@ -985,6 +990,8 @@ t_stat mt_srv(UNIT * uptr)
(uptr->u6 > BUFFSIZE) ? DEV_WEOR : 0)) {
case TIME_ERROR:
#if I7090 | I701 | I704
uptr->u5 &= ~MT_CMDMSK;
uptr->u5 |= MT_SKIP;
/* If no data was written, simulate a write gap */
if (uptr->u6 == 0) {
r = sim_tape_wrgap(uptr, 35);
@ -994,7 +1001,6 @@ t_stat mt_srv(UNIT * uptr)
}
}
#endif
chan_set_attn(chan);
/* fall through */
case END_RECORD:
@ -1035,6 +1041,7 @@ t_stat mt_srv(UNIT * uptr)
return SCPE_OK;
case MT_RDB:
uptr->u5 &= ~MT_LWR; /* not write command */
/* If tape mark pending, return it */
if (chan_test(chan, DEV_FULL) == 0 && uptr->u5 & MT_MARK) {
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post ", unit);
@ -1117,6 +1124,7 @@ t_stat mt_srv(UNIT * uptr)
return SCPE_OK;
case MT_WEF:
uptr->u5 &= ~MT_LWR; /* not write command */
if (uptr->u5 & MT_EGAP) {
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
uptr->u5 &= ~MT_EGAP;
@ -1138,8 +1146,17 @@ t_stat mt_srv(UNIT * uptr)
case MT_BSR:
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
/* If last command was a write, put extended gap on tape */
if (uptr->u5 & MT_LWR) {
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d bsr\n", unit);
r = sim_tape_wrgap(uptr, 35);
uptr->u5 &= ~MT_LWR;
sim_activate(uptr, 10*T3_us);
return SCPE_OK;
}
/* Clear tape mark, command, idle since we will need to change dir */
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY);
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY | MT_LWR);
r = sim_tape_sprecr(uptr, &reclen);
if (r != MTSE_BOT)
uptr->u3 -= GAP_LEN;
@ -1147,8 +1164,6 @@ t_stat mt_srv(UNIT * uptr)
if (r == MTSE_TMK) {
#ifdef I7080
chan_set_eof(chan);
#else
/* We don't set EOF on BSR */
#endif
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
sim_activate(uptr, T2_us);
@ -1160,7 +1175,7 @@ t_stat mt_srv(UNIT * uptr)
return SCPE_OK;
case MT_BSF:
uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT);
uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT | MT_LWR);
r = sim_tape_sprecr(uptr, &reclen);
if (r != MTSE_BOT)
uptr->u3 -= GAP_LEN;
@ -1179,39 +1194,47 @@ t_stat mt_srv(UNIT * uptr)
case MT_SKR:
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
/* Clear tape mark, command, idle since we will need to change dir */
uptr->u5 &= ~(MT_CMDMSK | MT_EOT);
uptr->u5 |= (MT_RDY | MT_IDLE);
if (uptr->u5 & MT_CLRIND) {
sim_debug(DEBUG_DETAIL, dptr, "clear ind\n");
#if I7010
if ((uptr->u5 & MT_MARK) == 0) {
chan_clear(chan, STA_PEND);
}
#endif
chan_clear(chan, STA_TWAIT);
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_LWR | MT_MARK | MT_CLRIND);
uptr->u5 |= (MT_RDY | MT_IDLE);
mt_chan[chan] &= ~MTC_BSY;
sim_activate(uptr, (uptr->u6 * T1_us) + T2_us);
return SCPE_OK;
}
uptr->u5 |= (MT_CLRIND);
r = sim_tape_sprecf(uptr, &reclen);
uptr->u3 += GAP_LEN;
mt_chan[chan] &= ~MTC_BSY;
#if I7010 | I7080
uptr->u6 = reclen;
#if I7080
chan_clear(chan, STA_TWAIT);
#endif
#ifdef I7010
chan_set(chan, STA_PEND);
#else
#endif
/* We are like read that transfers nothing */
chan_set(chan, DEV_REOR);
#endif
/* We don't set EOF on SKR */
if (r == MTSE_TMK) {
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
sim_activate(uptr, T1_us);
uptr->u5 |= MT_MARK;
uptr->u6 = 1;
sim_activate(uptr, 2*T1_us);
return SCPE_OK;
#ifdef I7010
} else if (r == MTSE_EOM) {
chan_set(chan, STA_PEND);
#endif
}
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
uptr->u3 += reclen;
sim_activate(uptr, (reclen * T1_us));
sim_activate(uptr, 2*T1_us);
break;
case MT_ERG:
sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit);
uptr->u5 &= ~(MT_CMDMSK|MT_MARK);
uptr->u5 &= ~(MT_CMDMSK|MT_MARK|MT_LWR);
uptr->u5 |= (MT_RDY | MT_IDLE);
#if I7010 | I7080
chan_clear(chan, STA_TWAIT);
@ -1225,7 +1248,7 @@ t_stat mt_srv(UNIT * uptr)
case MT_REW:
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d %d %d\n", unit, uptr->u3,
uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200);
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY);
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY | MT_LWR);
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
uptr->u5 |= MT_HREW;
sim_activate(uptr, us_to_ticks(5000000));
@ -1238,7 +1261,7 @@ t_stat mt_srv(UNIT * uptr)
case MT_RUN:
sim_debug(DEBUG_DETAIL, dptr, "Unload unit=%d\n", unit);
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY);
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY | MT_LWR);
uptr->u5 |= MT_UNLOAD;
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
uptr->u5 |= MT_HREW;
@ -1350,6 +1373,7 @@ mt_attach(UNIT * uptr, CONST char *file)
if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK)
return r;
sim_tape_set_dens(uptr, (uptr->flags == MTUF_LDN) ? MT_DENS_200 : MT_DENS_556, NULL, NULL);
uptr->u3 = 0;
uptr->u5 |= MT_RDY;
uptr->flags |= MTUF_ONLINE;