int ng_fetch(uint32 addr, uint16 *wp) { if (Map_ReadW(addr, 2, wp) == 0) return 0; *wp = 0; return 1; }
t_stat ts_wr (int32 data, int32 PA, int32 access) { int32 i, t; switch ((PA >> 1) & 01) { /* decode PA<1> */ case 0: /* TSDB */ if ((tssr & TSSR_SSR) == 0) { /* ready? */ tssr = tssr | TSSR_RMR; /* no, refuse */ break; } tsba = ((tsdbx & TSDBX_M_XA) << 18) | /* form pkt addr */ ((data & 03) << 16) | (data & 0177774); tsdbx = 0; /* clr tsdbx */ tssr = ts_updtssr (tssr & TSSR_NBA); /* clr ssr, err */ msgxs0 = ts_updxs0 (msgxs0 & ~XS0_ALLCLR); /* clr, upd xs0 */ msgrfc = msgxs1 = msgxs2 = msgxs3 = msgxs4 = 0; /* clr status */ CLR_INT (TS); /* clr int req */ t = Map_ReadW (tsba, CMD_PLNT << 1, cpy_buf); /* read cmd pkt */ tsba = tsba + ((CMD_PLNT << 1) - t); /* incr tsba */ if (t) { /* nxm? */ ts_endcmd (TSSR_NXM + TC5, 0, MSG_ACK|MSG_MNEF|MSG_CFAIL); return SCPE_OK; } for (i = 0; i < CMD_PLNT; i++) /* copy packet */ tscmdp[i] = cpy_buf[i]; ts_ownc = ts_ownm = 1; /* tape owns all */ sim_activate (&ts_unit, ts_time); /* activate */ break; case 1: /* TSSR */ if (PA & 1) { /* TSDBX */ if (UNIBUS) /* not in TS11 */ return SCPE_OK; if (tssr & TSSR_SSR) { /* ready? */ tsdbx = data; /* save */ if (data & TSDBX_BOOT) { ts_bcmd = 1; sim_activate (&ts_unit, ts_time); } } else tssr = tssr | TSSR_RMR; /* no, err */ } else if (access == WRITE) /* reset */ ts_reset (&ts_dev); break; } return SCPE_OK; }
/* fetch memory */ int vt_fetch(uint32 addr, vt11word *wp) { /* On PDP-11 Unibus 22-bit systems, the VT11/VS60 behaves as an 18-bit Unibus peripheral and must go through the I/O map. */ /* apply Unibus map, when appropriate */ if (Map_ReadW(addr, 2, wp) == 0) return 0; /* no problem */ /* else mapped address lies outside configured memory range */ *wp = 0164000; /* DNOP; just updates DPC if used */ /* which shouldn't happen */ return 1; /* used to set "time_out" flag */ }
t_stat ts_svc (UNIT *uptr) { int32 i, t, bc, fnc, mod, st0, st1; static const int32 fnc_mod[CMD_N_FNC] = { /* max mod+1 0 ill */ 0, 4, 0, 0, 1, 2, 1, 0, /* 00 - 07 */ 5, 3, 5, 1, 0, 0, 0, 1, /* 10 - 17 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 27 */ 0, 0, 0, 0, 0, 0, 0, 0 /* 30 - 37 */ }; static const int32 fnc_flg[CMD_N_FNC] = { 0, FLG_MO+FLG_AD, 0, 0, 0, FLG_MO+FLG_WR+FLG_AD, FLG_AD, 0, FLG_MO, FLG_MO+FLG_WR, FLG_MO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 27 */ 0, 0, 0, 0, 0, 0, 0, 0 /* 30 - 37 */ }; static const char *fnc_name[CMD_N_FNC] = { "0", "READ", "2", "3", "WCHR", "WRITE", "WSSM", "7", "POS", "FMT", "CTL", "INIT", "14", "15", "16", "GSTA", "20", "21", "22", "23", "24", "25", "26", "27", "30", "31", "32", "33", "34", "35", "36", "37" }; if (ts_bcmd) { /* boot? */ ts_bcmd = 0; /* clear flag */ sim_tape_rewind (uptr); /* rewind */ if (uptr->flags & UNIT_ATT) { /* attached? */ cmdlnt = cmdadh = cmdadl = 0; /* defang rd */ ts_spacef (uptr, 1, FALSE); /* space fwd */ ts_readf (uptr, 512); /* read blk */ tssr = ts_updtssr (tssr | TSSR_SSR); } else tssr = ts_updtssr (tssr | TSSR_SSR | TC3); if (cmdhdr & CMD_IE) SET_INT (TS); return SCPE_OK; } if (!(cmdhdr & CMD_ACK)) { /* no acknowledge? */ tssr = ts_updtssr (tssr | TSSR_SSR); /* set rdy, int */ if (cmdhdr & CMD_IE) SET_INT (TS); ts_ownc = ts_ownm = 0; /* CPU owns all */ return SCPE_OK; } fnc = GET_FNC (cmdhdr); /* get fnc+mode */ mod = GET_MOD (cmdhdr); if (DEBUG_PRS (ts_dev)) { fprintf (sim_deb, ">>TS: cmd=%s, mod=%o, buf=%o, lnt=%d, pos=", fnc_name[fnc], mod, cmdadl, cmdlnt); fprint_val (sim_deb, ts_unit.pos, 10, T_ADDR_W, PV_LEFT); fprintf (sim_deb, "\n"); } if ((fnc != FNC_WCHR) && (tssr & TSSR_NBA)) { /* ~wr chr & nba? */ ts_endcmd (TC3, 0, 0); /* error */ return SCPE_OK; } if (ts_qatn && (wchopt & WCH_EAI)) { /* attn pending? */ ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn msg */ SET_INT (TS); /* set interrupt */ ts_qatn = 0; /* not pending */ return SCPE_OK; } if (cmdhdr & CMD_CVC) /* cvc? clr vck */ msgxs0 = msgxs0 & ~XS0_VCK; if ((cmdhdr & CMD_MBZ) || (mod >= fnc_mod[fnc])) { /* test mbz */ ts_endcmd (TC3, XS0_ILC, MSG_ACK | MSG_MILL | MSG_CFAIL); return SCPE_OK; } if ((fnc_flg[fnc] & FLG_MO) && /* mot+(vck|!att)? */ ((msgxs0 & XS0_VCK) || !(uptr->flags & UNIT_ATT))) { ts_endcmd (TC3, XS0_NEF, MSG_ACK | MSG_MNEF | MSG_CFAIL); return SCPE_OK; } if ((fnc_flg[fnc] & FLG_WR) && /* write? */ sim_tape_wrp (uptr)) { /* write lck? */ ts_endcmd (TC3, XS0_WLE | XS0_NEF, MSG_ACK | MSG_MNEF | MSG_CFAIL); return SCPE_OK; } if ((((fnc == FNC_READ) && (mod == 1)) || /* read rev */ ((fnc == FNC_POS) && (mod & 1))) && /* space rev */ sim_tape_bot (uptr)) { /* BOT? */ ts_endcmd (TC3, XS0_NEF, MSG_ACK | MSG_MNEF | MSG_CFAIL); return SCPE_OK; } if ((fnc_flg[fnc] & FLG_AD) && (cmdadh & ADDRTEST)) { /* buf addr > 22b? */ ts_endcmd (TC3, XS0_ILA, MSG_ACK | MSG_MILL | MSG_CFAIL); return SCPE_OK; } st0 = st1 = 0; switch (fnc) { /* case on func */ case FNC_INIT: /* init */ if (!sim_tape_bot (uptr)) /* set if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); /* rewind */ case FNC_WSSM: /* write mem */ case FNC_GSTA: /* get status */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); /* send end packet */ return SCPE_OK; case FNC_WCHR: /* write char */ if ((cmdadh & ADDRTEST) || (cmdadl & 1) || (cmdlnt < 6)) { ts_endcmd (TSSR_NBA | TC3, XS0_ILA, 0); break; } tsba = (cmdadh << 16) | cmdadl; bc = ((WCH_PLNT << 1) > cmdlnt)? cmdlnt: WCH_PLNT << 1; t = Map_ReadW (tsba, bc, cpy_buf); /* fetch packet */ tsba = tsba + (bc - t); /* inc tsba */ if (t) { /* nxm? */ ts_endcmd (TSSR_NBA | TSSR_NXM | TC5, 0, 0); return SCPE_OK; } for (i = 0; i < (bc / 2); i++) /* copy packet */ tswchp[i] = cpy_buf[i]; if ((wchlnt < ((MSG_PLNT - 1) * 2)) || (wchadh & 0177700) || (wchadl & 1)) ts_endcmd (TSSR_NBA | TC3, 0, 0); else { msgxs2 = msgxs2 | XS2_XTF | 1; tssr = ts_updtssr (tssr & ~TSSR_NBA); ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); } return SCPE_OK; case FNC_CTL: /* control */ switch (mod) { /* case mode */ case 00: /* msg buf rls */ tssr = ts_updtssr (tssr | TSSR_SSR); /* set SSR */ if (wchopt & WCH_ERI) SET_INT (TS); ts_ownc = 0; ts_ownm = 1; /* keep msg */ break; case 01: /* rewind and unload */ if (!sim_tape_bot (uptr)) /* if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_detach (uptr); /* unload */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); break; case 02: /* clean */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); /* nop */ break; case 03: /* undefined */ ts_endcmd (TC3, XS0_ILC, MSG_ACK | MSG_MILL | MSG_CFAIL); return SCPE_OK; case 04: /* rewind */ if (!sim_tape_bot (uptr)) /* if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); ts_endcmd (TC0, XS0_BOT, MSG_ACK | MSG_CEND); break; } break; case FNC_READ: /* read */ switch (mod) { /* case mode */ case 00: /* fwd */ st0 = ts_readf (uptr, cmdlnt); /* read */ break; case 01: /* back */ st0 = ts_readr (uptr, cmdlnt); /* read */ break; case 02: /* reread fwd */ if (cmdhdr & CMD_OPP) { /* opposite? */ st0 = ts_readr (uptr, cmdlnt); st1 = ts_spacef (uptr, 1, FALSE); } else { st0 = ts_spacer (uptr, 1, FALSE); st1 = ts_readf (uptr, cmdlnt); } break; case 03: /* reread back */ if (cmdhdr & CMD_OPP) { /* opposite */ st0 = ts_readf (uptr, cmdlnt); st1 = ts_spacer (uptr, 1, FALSE); } else { st0 = ts_spacef (uptr, 1, FALSE); st1 = ts_readr (uptr, cmdlnt); } break; } ts_cmpendcmd (st0, st1); break; case FNC_WRIT: /* write */ switch (mod) { /* case mode */ case 00: /* write */ st0 = ts_write (uptr, cmdlnt); break; case 01: /* rewrite */ st0 = ts_spacer (uptr, 1, FALSE); st1 = ts_write (uptr, cmdlnt); break; } ts_cmpendcmd (st0, st1); break; case FNC_FMT: /* format */ switch (mod) { /* case mode */ case 00: /* write tmk */ st0 = ts_wtmk (uptr); break; case 01: /* erase */ break; case 02: /* retry tmk */ st0 = ts_spacer (uptr, 1, FALSE); st1 = ts_wtmk (uptr); break; } ts_cmpendcmd (st0, st1); break; case FNC_POS: /* position */ switch (mod) { /* case mode */ case 00: /* space fwd */ st0 = ts_spacef (uptr, cmdadl, TRUE); break; case 01: /* space rev */ st0 = ts_spacer (uptr, cmdadl, TRUE); break; case 02: /* space ffwd */ st0 = ts_skipf (uptr, cmdadl); break; case 03: /* space frev */ st0 = ts_skipr (uptr, cmdadl); break; case 04: /* rewind */ if (!sim_tape_bot (uptr)) /* if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); break; } ts_cmpendcmd (st0, 0); break; } return SCPE_OK; }