次にエミュレータエンジンから呼び出される、 入出力操作を司るルーチン tu_rd() と tu_wr() を実装します。
この2つのルーチンは原則として、 レジスタの内容を読み書きすることを目的としています。 が、 いわゆるコマンドレジスタ(TUCS1)などへ書き込みがされた場合、 実際のデバイスでは何らかの動作を始めるのですが、 それをエミュレートするため tu_go(), tu_svc(), tu_inta() も実装する必要があります。
● tu_rd() を記述する
$ cvs diff -u cvs diff: Diffing . Index: pdp11_tu.c =================================================================== RCS file: /wrk/simh/cvs/src/simh/pdp11e/pdp11_tu.c,v retrieving revision 1.15 diff -u -r1.15 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 08:34:41 -0000 1.15 +++ pdp11_tu.c 11 Dec 2003 09:09:25 -0000 @@ -203,6 +203,26 @@ int32 tuiff = 0; // INTR flip/flop int32 tu_stopioe = 1; // stop on error +int32 reg_in_fmtr[] = { // reg in formatter + 0, // CS1 + 0, // WC + 0, // BA + 1, // FC + 0, // CS2 + 1, // FS + 1, // ER + 0, // AS + 1, // CC + 0, // DB + 1, // MR + 1, // DT + 1, // SN + 1, // TC + 1, // BAE + 1, // CS3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + static uint8 *xbuf = NULL; // xfer buffer @@ -397,6 +417,90 @@ t_stat tu_rd(int32 *data, int32 PA, int32 access) { + int32 fmtr, drv, j; + + fmtr = GET_FMTR(tucs2); // get current fmtr + drv = GET_DRV(tutc); // get current drive + j = (PA >> 1) & 017; // get reg offset + + if (reg_in_fmtr[j] && (fmtr != 0)) { // nx formatter + tucs2 |= CS2_NEF; // set error flag + update_tucs(CS1_SC, drv); // request intr + *data = 0; + return(SCPE_OK); + } + + update_tucs(0, drv); // update status + + switch (j) { // decode PA<4:1> + case 000: // MTCS1 + if (fmtr != 0) { + *data = tucs1 & ~CS1_DRV; + } else { + *data = tucs1; + } + break; + case 001: // TUWC + *data = tuwc; + break; + case 002: // MTBA + tuba &= ~BA_MBZ; + *data = tuba; + break; + case 003: // TUFC + *data = tufc; + break; + case 004: // TUCS2 + tucs2 = (tucs2 & ~CS2_MBZ) | CS2_IR | CS2_OR; + *data = tucs2; + break; + case 005: // TUFS + *data = tufs & 0177777; // mask off rewind + break; + case 006: // TUER + *data = tuer; + break; + case 007: // TUAS + if (tufs & FS_ATA) { + *data = AS_U0; + } else { + *data = 0; + } + break; + case 010: // TUCC + tucc &= ~CC_MBZ; + *data = tucc; + break; + case 011: // TUDB + *data = tudb; + break; + case 012: // TUMR + *data = tumr; + break; + case 013: // TUDT + if (tu_unit[drv].flags & UNIT_DIS) { + *data = DT_TAPE | DT_TM03 | DT_OFF; + } else { + *data = DT_TAPE | DT_TM03 | DT_PRES | DT_TE16; + } + break; + case 014: // TUSN + if (tu_unit[drv].flags & UNIT_DIS) { + *data = 0; + } else { + *data = 040 | (drv + 1); + } + break; + case 015: // TUTC + tutc &= ~TC_MBZ; + *data = tutc; + break; + default: // all others + tuer |= ER_ILR; + update_tucs(0, drv); + break; + } + return(SCPE_OK); } $
● tu_wr() を記述する
$ cvs diff -u cvs diff: Diffing . Index: pdp11_tu.c =================================================================== RCS file: /wrk/simh/cvs/src/simh/pdp11e/pdp11_tu.c,v retrieving revision 1.16 diff -u -r1.16 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 09:13:29 -0000 1.16 +++ pdp11_tu.c 11 Dec 2003 10:10:21 -0000 @@ -222,6 +222,25 @@ 1, // CS3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +int32 reg_in_fmtr1[32] = { // rmr if write + go + 0, // CS1 + 0, // WC + 0, // BA + 1, // FC + 0, // CS2 + 1, // FS + 1, // ER + 0, // AS + 1, // CC + 0, // DB + 0, // MR + 1, // DT + 1, // SN + 1, // TC + 1, // BAE + 1, // CS3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; static uint8 *xbuf = NULL; // xfer buffer @@ -413,6 +432,11 @@ return; } +void +tu_go (int32 drv) +{ +} + t_stat tu_rd(int32 *data, int32 PA, int32 access) @@ -507,6 +531,161 @@ t_stat tu_wr(int32 data, int32 PA, int32 access) { + int32 cs1f, fmtr, drv, j; + + cs1f = 0; // no int on cs1 upd + fmtr = GET_FMTR (tucs2); // get formatter + drv = GET_DRV (tutc); // get current unit + j = (PA >> 1) & 017; // get reg offset + if (reg_in_fmtr[j] && (fmtr != 0)) { // nx formatter + tucs2 = tucs2 | CS2_NEF; // set error flag + update_tucs (CS1_SC, drv); // request intr + return SCPE_OK; } + if (reg_in_fmtr1[j] && // formatter busy? + ((tucs1 & CS1_DONE) == 0)) { + tuer = tuer | ER_RMR; // won't write + update_tucs (0, drv); + return SCPE_OK; } + + switch (j) { // decode PA<4:1> + case 000: // MTCS1 + if ((access == WRITEB) && (PA & 1)) { + data <<= 8; + } + if (data & CS1_TRE) { // error clear? + tucs1 &= ~CS1_TRE; // clr CS1+ tucs2 &= ~CS2_ERR; // clr CS2<15:8> + } + if ((access == WRITE) || (PA & 1)) { // hi byte write? + if (tucs1 & CS1_DONE) { // done set? + tucs1 = (tucs1 & ~CS1_UAE) | (data & CS1_UAE); + } + } + if ((access == WRITE) || !(PA & 1)) { // lo byte write? + if ((data & CS1_DONE) && // to DONE+IE? + (data & CS1_IE)) { + tuiff = 1; // set CSTB INTR + } + tucs1 = (tucs1 & ~CS1_IE) | (data & CS1_IE); + if (fmtr != 0) { // nx formatter? + tucs2 |= CS2_NEF; // set error flag + cs1f = CS1_SC; // req interrupt + } else if (tucs1 & CS1_GO) { // busy? + if (tucs1 & CS1_DONE) { + tuer |= ER_RMR; + } else { + tucs2 |= CS2_PGE; + } + } else { + tucs1 = (tucs1 & ~CS1_DRV) | (data & CS1_DRV); + if (tucs1 & CS1_GO) { + tu_go(drv); + } + } + } + break; + case 001: // MTWC + if (access == WRITEB) { + if (PA & 1) { + data = (tuwc & 0377) | (data << 8); + } else { + data = (tuwc & ~0377) | data; + } + } + tuwc = data; + break; + case 002: // MTBA + if (access == WRITEB) { + if (PA & 1) { + data = (tuba & 0377) | (data << 8); + } else { + data = (tuba & ~0377) | data; + } + } + tuba = data & ~BA_MBZ; + break; + case 003: // TUFC + if (access == WRITEB) { + if (PA & 1) { + data = (tufc & 0377) | (data << 8); + } else { + data = (tufc & ~0377) | data; + } + } + tufc = data; + tutc |= TC_FCS; // set fc flag + break; + case 004: // TUCS2 + if ((access == WRITEB) && (PA & 1)) { + data <<= 8; + } + if (data & CS2_CLR) { + tu_reset(&tu_dev); // init? + } else { + if ((data & ~tucs2) & (CS2_PE | CS2_MXF)) { + cs1f = CS1_SC; // diagn intr + } + if (access == WRITEB) { // merge data + if (PA & 1) { + data = (tucs2 & 0377) | data; + } else { + data = (tucs2 & 0177400) | data; + } + tucs2 = (tucs2 & ~CS2_RW) + | (data & CS2_RW) | CS2_IR | CS2_OR; + } + } + break; + case 007: // TUAS + if ((access == WRITEB) && (PA & 1)) break; + if (data & AS_U0) { + tufs &= ~FS_ATA; + } + break; + case 011: // MTDB + if (access == WRITEB) { + if (PA & 1) { + data = (tudb & 0377) | (data << 8); + } else { + data = (tudb & ~0377) | data; + } + } + tudb = data; + break; + case 012: // TUMR + if (access == WRITEB) { + if (PA & 1) { + data = (tumr & 0377) | (data << 8); + } else { + data = (tumr & ~0377) | data; + } + } + tumr = (tumr & ~MR_RW) | (data & MR_RW); + break; + case 015: // TUTC + if (access == WRITEB) { + if (PA & 1) { + data = (tutc & 0377) | (data << 8); + } else { + data = (tutc & ~0377) | data; + } + } + tutc = (tutc & ~TC_RW) | (data & TC_RW) | TC_SAC; + drv = GET_DRV(tutc); + break; + case 005: // TUFS + case 006: // TUER + case 010: // TUCC + case 013: // TUDT + case 014: // TUSN + break; // read only + default: // all others + tuer |= ER_ILR; + break; + } // end switch + + update_tucs(cs1f, drv); // update status + return(SCPE_OK); } $
● tu_go() を記述する
$ cvs diff -u > ~/public_html/COOKIES/SIMH/TE16/diff cvs diff: Diffing . Index: pdp11_tu.c =================================================================== RCS file: /wrk/simh/cvs/src/simh/pdp11e/pdp11_tu.c,v retrieving revision 1.17 diff -u -r1.17 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 10:12:01 -0000 1.17 +++ pdp11_tu.c 11 Dec 2003 10:48:18 -0000 @@ -201,9 +201,10 @@ int32 tucs3 = 0; // control/status 3 int32 tuiff = 0; // INTR flip/flop +int32 tu_time = 10; // record latency int32 tu_stopioe = 1; // stop on error int32 reg_in_fmtr[32] = { // reg in formatter 0, // CS1 0, // WC 0, // BA @@ -241,6 +242,34 @@ 1, // CS3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +int32 fmt_test[16] = { // fmt bytes/10 wd + 5, // 00 PDP-10:10-Core Dump + 0, // 01 PDP-15:15-Core Dump + 5, // 02 + 4, // 03 PDP-10:10-Compatible + 0, // 04 + 0, // 05 + 0, // 06 + 0, // 07 + 0, // 10 + 0, // 11 + 0, // 12 + 0, // 13 + 5, // 14 PDP-11:11-Normal + 5, // 15 PDP-11:11-Core Dump + 0, // 16 PDP-15:15-Normal + 0 // 17 PDP-11:Reserved +}; +int32 den_test[8] = { // valid densities + 0, // 00 + 0, // 01 + 0, // 02 + 1, // 03 800:NRZI + 1, // 04 1600:PE + 0, // 05 Reserved + 0, // 06 Reserved + 0 // 07 Reserved +}; static uint8 *xbuf = NULL; // xfer buffer @@ -286,6 +315,7 @@ { FLDATA(DONE, tucs1, CSR_V_DONE) }, { FLDATA(IE, tucs1, CSR_V_IE) }, { FLDATA(STOP_IOE, tu_stopioe, 0) }, + { DRDATA(TIME, tu_time, 24), PV_LEFT }, { NULL } }; @@ -435,6 +465,141 @@ void tu_go (int32 drv) { + int32 fnc, den, space_test = FS_BOT; + UNIT *uptr; + + fnc = GET_FNC(tucs1); // get function + den = GET_DEN(tutc); // get density + uptr = tu_dev.units + drv; // get unit + + if ((fnc != FNC_FCLR) && // not clear + ((tufs & FS_ERR) || // and error + sim_is_active(uptr))) { // or in motion? + tuer |= ER_ILF; // set error flag + tufs |= FS_ATA; // exception + tucs1 &= ~CS1_GO; // clear go */ + update_tucs(CS1_SC, drv); // request intr + return; + } + + tufs &= ~FS_ATA; // clear attention + tutc &= ~TC_SAC; // clear addr change + + switch (fnc) { // case on function + case FNC_FCLR: // drive clear + tuer = 0; // clear errors + tutc &= ~TC_FCS; // clear fc status + tufs &= ~(FS_SAT | FS_SSC | FS_ID | FS_TMK | FS_ERR); + sim_cancel(uptr); // reset drive + uptr->USTAT = 0; + case FNC_NOP: + tucs1 &= ~CS1_GO; // no operation + return; + case FNC_RIP: // read-in preset + tutc = TC_800; // density = 800 + sim_tape_rewind(&tu_unit[0]); // rewind unit 0 + tu_unit[0].USTAT = 0; + tucs1 &= ~CS1_GO; + return; + + case FNC_UNLOAD: // unload + if ((uptr->flags & UNIT_ATT) == 0) { // unattached? + tuer |= ER_UNS; + break; + } + detach_unit(uptr); + uptr->USTAT = FS_REW; + sim_activate(uptr, tu_time); + tucs1 &= ~CS1_GO; + return; + case FNC_REWIND: + if ((uptr->flags & UNIT_ATT) == 0) { // unattached? + tuer |= ER_UNS; + break; + } + uptr->USTAT = FS_PIP | FS_REW; + sim_activate(uptr, tu_time); + tucs1 &= ~CS1_GO; + return; + + case FNC_SPACEF: + space_test = FS_EOT; + case FNC_SPACER: + if ((uptr->flags & UNIT_ATT) == 0) { // unattached? + tuer |= ER_UNS; + break; + } + if ((tufs & space_test) || ((tutc & TC_FCS) == 0)) { + tuer |= ER_NXF; + break; + } + uptr->USTAT = FS_PIP; + goto GO_XFER; + + case FNC_WCHKR: // wchk = read + case FNC_READR: // read rev + if (tufs & FS_BOT) { // beginning of tape? + tuer |= ER_NXF; + break; + } + goto DATA_XFER; + + case FNC_WRITE: // write + if (((tutc & TC_FCS) == 0) || // frame cnt = 0? + ((den == TC_800) && // NRZI, + (tufc > 0777765))) { // fc < 13? + tuer |= ER_NXF; + break; + } + case FNC_WREOF: // write tape mark + case FNC_ERASE: // erase + if (sim_tape_wrp(uptr)) { // write locked? + tuer |= ER_NXF; + break; + } + case FNC_WCHKF: // wchk = read + case FNC_READF: // read + DATA_XFER: + if ((uptr->flags & UNIT_ATT) == 0) { // unattached? + tuer |= ER_UNS; + break; + } + if (fmt_test[GET_FMT(tutc)] == 0) { // invalid format? + tuer |= ER_FER; + break; + } + if (den_test[den] == 0) { // invalid density? + tuer |= ER_NXF; + break; + } + if (uptr->UDENS == UD_UNK) { + uptr->UDENS = den; // set dens +#if 0 + } else if (uptr->UDENS != den) { // density mismatch? + tuer |= ER_NXF; + break; +#endif + } + uptr->USTAT = 0; + tucs1 &= ~CS1_DONE; // clear done + GO_XFER: + tucs2 &= ~CS2_ERR; // clear errors + tucs1 &= ~(CS1_TRE | CS1_MCPE); + tufs &= ~(FS_TMK | FS_ID); // clear eof, id + sim_activate(uptr, tu_time); + return; + + default: // all others + tuer |= ER_ILF; // not supported + break; + } // end case function + + tucs1 &= ~CS1_GO; // clear go + tufs |= FS_ATA; // set attn + + update_tucs(CS1_SC, drv); // set intr + + return; } $
● BAE,CS3 の入出力操作を追加する
$ cvs diff -u cvs diff: Diffing . Index: pdp11_tu.c =================================================================== RCS file: /wrk/simh/cvs/src/simh/pdp11e/pdp11_tu.c,v retrieving revision 1.18 diff -u -r1.18 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 10:53:01 -0000 1.18 +++ pdp11_tu.c 11 Dec 2003 11:36:11 -0000 @@ -5,6 +5,9 @@ #include "pdp11_defs.h" #include "sim_tape.h" +#define RH (cpu_18b || (cpu_ubm && cpu_rh11)) +#define RH11 (RH) +extern int32 cpu_18b, cpu_ubm, cpu_rh11; extern int32 int_req[IPL_HLVL]; extern int32 int_vec[IPL_HLVL][32]; @@ -684,6 +687,16 @@ tutc &= ~TC_MBZ; *data = tutc; break; + case 016: // TUBAE + if (RH11) return SCPE_NXM; // not in RH11 + tubae &= ~AE_MBZ; + *data = tubae; + break; + case 017: // TUCS3 + if (RH11) return SCPE_NXM; // not in RH11 + tucs3 = (tucs3 & ~(CS3_IE | CS3_MBZ)) | (tucs1 & CS1_IE); + *data = tucs3; + break; default: // all others tuer |= ER_ILR; update_tucs(0, drv); @@ -837,6 +850,18 @@ } tutc = (tutc & ~TC_RW) | (data & TC_RW) | TC_SAC; drv = GET_DRV(tutc); break; + case 016: // TUBAE + if (RH11) return SCPE_NXM; // not in RH11 + if ((access == WRITEB) && (PA & 1)) break; + tubae = data & ~AE_MBZ; + tucs1 = (tucs1 & ~CS1_UAE) | ((tubae << CS1_V_UAE) & CS1_UAE); + break; + case 017: // RPCS3 + if (RH11) return SCPE_NXM; // not in RH11 + if ((access == WRITEB) && (PA & 1)) break; + tucs3 = data & ~CS3_MBZ; + tucs1 = (tucs1 & ~CS1_IE) | (tucs3 & CS3_IE); + break; case 005: // TUFS case 006: // TUER $
● tu_svc() を記述する
$ cvs diff -u cvs diff: Diffing . Index: pdp11_tu.c =================================================================== RCS file: /wrk/simh/cvs/src/simh/pdp11e/pdp11_tu.c,v retrieving revision 1.19 diff -u -r1.19 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 12:30:20 -0000 1.19 +++ pdp11_tu.c 12 Dec 2003 05:37:29 -0000 @@ -465,6 +465,211 @@ return; } + +t_stat +tu_map_err (UNIT *uptr, t_stat st) +{ + switch (st) { + case MTSE_FMT: // illegal fmt + case MTSE_UNATT: // not attached + tuer = tuer | ER_NXF; // can't execute + case MTSE_OK: // no error + return SCPE_IERR; + case MTSE_TMK: // end of file + tufs = tufs | FS_TMK; + break; + case MTSE_IOERR: // IO error + tuer = tuer | ER_VPE; // flag error + if (tu_stopioe) { + return(SCPE_IOERR); + } + break; + case MTSE_INVRL: // invalid rec lnt + tuer = tuer | ER_VPE; // flag error + return SCPE_MTRLNT; + case MTSE_RECE: // record in error + tuer = tuer | ER_CRC; // set crc err + break; + case MTSE_EOM: // end of medium + tuer = tuer | ER_OPI; // incomplete + break; + case MTSE_BOT: // reverse into BOT + break; + case MTSE_WRP: // write protect + tuer = tuer | ER_NXF; // can't execute + break; + } + + return(SCPE_OK); +} + + +t_stat +tu_svc(UNIT *uptr) +{ + int32 i; + int32 f; + int32 t; + int32 fc; + int32 wc; + int32 fmt; + int32 drv; + uint32 ba; + t_mtrlnt tbc; + t_stat st; + t_stat r = SCPE_OK; + + drv = uptr - tu_dev.units; // get drive # + if (uptr->USTAT & FS_REW) { // rewind or unload? + sim_tape_rewind(uptr); // rewind tape + uptr->USTAT = 0; // clear status + tufs |= FS_ATA | FS_SSC; + update_tucs(CS1_SC, drv); // update status + return(SCPE_OK); + } + + f = GET_FNC(tucs1); // get command + fmt = GET_FMT(tutc); // get format + ba = (tubae << 16) | tuba; // get byte addr + wc = 0200000 - tuwc; // get word count + fc = 0200000 - tufc; // get frame count + + uptr->USTAT = 0; // clear status + + switch (f) { // case on function + + case FNC_SPACEF: // space forward + do { + tufc = (tufc + 1) & 0177777; // incr fc + st = sim_tape_sprecf(uptr, &tbc); + if (st) { // space rec fwd, err? + r = tu_map_err(uptr, st); // map error + break; + } + } while (tufc != 0); + + if (tufc) { + tuer |= ER_FCE; + } else { + tutc &= ~TC_FCS; + } + tufs |= FS_ATA; + break; + + case FNC_SPACER: // space reverse + do { + tufc = (tufc + 1) & 0177777; // incr wc + st = sim_tape_sprecr(uptr, &tbc); + if (st) { // space rec rev, err? + r = tu_map_err(uptr, st); // map error + break; + } + } while (tufc != 0); + + if (tufc) { + tuer |= ER_FCE; + } else { + tutc &= ~TC_FCS; + } + tufs |= FS_ATA; + break; + + case FNC_WREOF: // write end of file + if (st = sim_tape_wrtmk(uptr)) { // write tmk, err? + r = tu_map_err(uptr, st); // map error + } + tufs |= FS_ATA; + break; + + case FNC_ERASE: + if (sim_tape_wrp(uptr)) { // write protected? + r = tu_map_err(uptr, MTSE_WRP); // map error + } + tufs |= FS_ATA; + break; + + case FNC_READF: // read + case FNC_WCHKF: // wcheck = read + tufc = 0; // clear frame count + if (uptr->UDENS == TC_1600 && + sim_tape_bot(uptr)) { + tufs |= FS_ID; // PE BOT? ID burst + } + + // read fwd + st = sim_tape_rdrecf(uptr, xbuf, &tbc, MT_MAXFR); + if (st) { + r = tu_map_err(uptr, st); // map error + break; // done + } + + t = Map_WriteB(ba, tbc, xbuf, RH); // copy buf to mem + if (t) { + tucs2 |= CS2_NEM; // set nxm err + } + + tufc = tbc & 0177777; + tuwc = (tuwc + (wc << 1)) & 0177777; + ba += (wc << 1); + break; + + case FNC_WRITE: // write + fc = wc << 1; + t = Map_ReadB(ba, fc, xbuf, RH); // copy mem to buf + if (t) { + tucs2 |= CS2_NEM; // set nxm err + } + + st = sim_tape_wrrecf(uptr, xbuf, fc); // write rec + if (st) { // err? + r = tu_map_err(uptr, st); // map error + break; + } + + tufc = (tufc + fc) & 0177777; + if (tufc == 0) { + tutc &= ~TC_FCS; + } + tuwc = (tuwc + (wc << 1)) & 0177777; + ba += (wc << 1); + break; + + case FNC_READR: // read reverse + case FNC_WCHKR: // wcheck = read + tufc = 0; // clear frame count + // read rev + st = sim_tape_rdrecr(uptr, xbuf, &tbc, MT_MAXFR); + if (st) { + r = tu_map_err(uptr, st); // map error + break; // done + } + + for (i = 0; i < 4; i++) { + xbuf[i] = 0; + } + + t = Map_WriteB(ba, tbc, xbuf, RH); // copy buf to mem + if (t) { + tucs2 |= CS2_NEM; // set nxm err + } + + tufc = tbc & 0177777; + tuwc = (tuwc + (wc << 1)) & 0177777; + ba -= (wc << 1); + break; + } // end case + + tucs1 = (tucs1 & ~CS1_UAE) | ((ba >> (16 - CS1_V_UAE)) & CS1_UAE); + tuba = (ba & 0177777) & ~BA_MBZ; // lower 16b + tubae = (ba >> 16) & ~AE_MBZ; // upper 6b + tucs1 &= ~CS1_GO; // clear go + + update_tucs(CS1_DONE, drv); + + return(SCPE_OK); +} + + void tu_go (int32 drv) { $
● tu_inta() を追加する
$ cvs diff -u cvs diff: Diffing . Index: pdp11_tu.c =================================================================== RCS file: /wrk/simh/cvs/src/simh/pdp11e/pdp11_tu.c,v retrieving revision 1.20 diff -u -r1.20 pdp11_tu.c --- pdp11_tu.c 12 Dec 2003 05:41:29 -0000 1.20 +++ pdp11_tu.c 12 Dec 2003 05:45:41 -0000 @@ -279,6 +279,7 @@ t_stat tu_rd(int32 *data, int32 PA, int32 access); t_stat tu_wr(int32 data, int32 PA, int32 access); +int32 tu_inta(void); t_stat tu_svc(UNIT *uptr); t_stat tu_reset(DEVICE *dptr); t_stat tu_boot(int32 unitno, DEVICE *dptr); @@ -375,7 +376,7 @@ 1, // vectors: number IVCL(TU), // locator VEC_TU, // value - { NULL } // ack routines + { &tu_inta } // ack routines }; DEVICE tu_dev = { @@ -463,6 +464,15 @@ } return; } + + +int32 +tu_inta(void) +{ + tucs1 &= ~CS1_IE; // clear int enable + tuiff = 0; // clear CSTB INTR + return(VEC_TU); // acknowledge +} $
これでデバイスのエミュレーションに関する一通りの実装は終りました。