それではまず SIMH のコマンドをサポートする作業から始めましょう。
この段階でサポートするべきコマンドは RESET/ATTACH/DETACH の3つでしょう。 各々 tu_reset(), tu_attach(), tu_detach() を記述するとコマンドが動くようになります。
● tu_reset() を記述する
$ 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.10 diff -u -r1.10 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 06:13:29 -0000 1.10 +++ pdp11_tu.c 11 Dec 2003 07:41:11 -0000 @@ -9,7 +9,8 @@ extern int32 int_vec[IPL_HLVL][32]; #define TU_NUMDR 8 // #drives +#define USTAT u3 // unit status // TUCS1 (RW) 17772440 - control/status 1 @@ -200,6 +201,8 @@ int32 tuiff = 0; // INTR flip/flop int32 tu_stopioe = 1; // stop on error + +static uint8 *xbuf = NULL; // xfer buffer t_stat tu_rd(int32 *data, int32 PA, int32 access); t_stat tu_wr(int32 data, int32 PA, int32 access); @@ -344,6 +347,36 @@ t_stat tu_reset(DEVICE *dptr) { + int32 u; + UNIT *uptr; + + tucs1 = CS1_DVA | CS1_DONE; + tuba = 0; + tufc = 0; + tucs2 = CS2_IR | CS2_OR; + tufs = FS_FPR | FS_RDY; + tuer = 0; + tutc = 0; + + tuiff = 0; // clear CSTB INTR + + CLR_INT(TU); // clear intr req + + for (u = 0; u < TU_NUMDR; u++) { // loop thru units + uptr = tu_dev.units + u; + sim_tape_reset(uptr); // clear pos flag + sim_cancel(uptr); // cancel activity + uptr->USTAT = 0; + } + + if (xbuf == NULL) { + xbuf = calloc(MT_MAXFR + 4, sizeof (uint8)); + } + + if (xbuf == NULL) { + return(SCPE_MEM); + } + return(SCPE_OK); } $
● tu_attach() を記述する
$ 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.11 diff -u -r1.11 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 07:43:14 -0000 1.11 +++ pdp11_tu.c 11 Dec 2003 08:07:04 -0000 @@ -11,6 +11,8 @@ #define TU_NUMDR 8 // #drives #define USTAT u3 // unit status +#define UDENS u4 // unit density +#define UD_UNK 0 // unknown density // TUCS1 (RW) 17772440 - control/status 1 @@ -327,6 +329,12 @@ }; + + +void +update_tucs(int32 flag, int32 drv) +{ +} t_stat tu_rd(int32 *data, int32 PA, int32 access) { @@ -383,7 +391,27 @@ t_stat tu_attach(UNIT *uptr, char *cptr) { - return(SCPE_OK); + int32 drv = uptr - tu_dev.units; + t_stat r; + + r = sim_tape_attach(uptr, cptr); + if (r != SCPE_OK) { + return(r); + } + + uptr->USTAT = 0; // clear unit status + uptr->UDENS = UD_UNK; // unknown density + + tufs |= (FS_ATA | FS_SSC); // set attention + + if ((GET_FMTR(tucs2) == 0) && // selected drive? + (GET_DRV(tutc) == drv)) { + tufs |= FS_SAT; // set slave attn + } + + update_tucs(CS1_SC, drv); // update status + + return(r); } t_stat $
● tu_detach() を記述する
$ 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.12 diff -u -r1.12 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 08:09:34 -0000 1.12 +++ pdp11_tu.c 11 Dec 2003 08:15:43 -0000 @@ -417,7 +417,23 @@ t_stat tu_detach(UNIT *uptr) { - return(SCPE_OK); + int32 drv = uptr - tu_dev.units; + + if (sim_is_active(uptr)) { // unit active? + sim_cancel(uptr); // cancel operation + tuer |= ER_UNS; // set formatter error + if ((uptr->USTAT & FS_REW) == 0) { // data transfer? + tucs1 |= (CS1_DONE | CS1_TRE); // set done, err + } + } + + uptr->USTAT = 0; // clear status flags + + tufs |= (FS_ATA | FS_SSC); // set attention + + update_tucs(CS1_SC, drv); // update status + + return(sim_tape_detach(uptr)); } t_stat $
● update_tucs() を記述する
$ 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.13 diff -u -r1.13 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 08:19:26 -0000 1.13 +++ pdp11_tu.c 11 Dec 2003 08:22:28 -0000 @@ -332,6 +332,65 @@ void update_tucs(int32 flag, int32 drv) { + int32 act = sim_is_active(&tu_unit[drv]); + + if ((flag & ~tucs1) & CS1_DONE) { // DONE 0 to 1? + if (tucs1 & CS1_IE) { // CSTB INTR <- IE + tuiff = 1; + } else { + tuiff = 0; + } + } + + if (GET_FMTR(tucs2) == 0) { // formatter present? + tufs = (tufs & ~FS_DYN) | FS_FPR; + if (tu_unit[drv].flags & UNIT_ATT) { + tufs |= (FS_MOL | tu_unit[drv].USTAT); + + if (tu_unit[drv].UDENS == TC_1600) { + tufs |= FS_PE; + } + + if (sim_tape_wrp(&tu_unit[drv])) { + tufs |= FS_WRL; + } + + if (sim_tape_bot(&tu_unit[drv]) && !act) { + tufs |= FS_BOT; + } + } + + if (tuer) { + tufs |= FS_ERR; + } + } else { + tufs = 0; + } + + tucs1 = (tucs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ)) | CS1_DVA | flag; + + if (tucs2 & CS2_ERR) { + tucs1 |= (CS1_TRE | CS1_SC); + } else if (tucs1 & CS1_TRE) { + tucs1 |= CS1_SC; + } + + if (tufs & FS_ATA) { + tucs1 |= CS1_SC; + } + + if (tuiff || + ((tucs1 & CS1_SC) && (tucs1 & CS1_DONE) && (tucs1 & CS1_IE))) { + SET_INT(TU); + } else { + CLR_INT(TU); + } + + if ((tucs1 & CS1_DONE) && tufs && !act) { + tufs |= FS_RDY; + } + + return; } $
● RESET/ATTACH/DETACHコマンドを試してみる
$ 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.14 diff -u -r1.14 pdp11_tu.c --- pdp11_tu.c 11 Dec 2003 08:26:56 -0000 1.14 +++ pdp11_tu.c 11 Dec 2003 08:30:36 -0000 @@ -416,7 +416,9 @@ { int32 u; UNIT *uptr; - +#if 1 +printf("# tu_reset(dptr)\r\n"); +#endif tucs1 = CS1_DVA | CS1_DONE; tuba = 0; tufc = 0; @@ -452,7 +454,9 @@ { int32 drv = uptr - tu_dev.units; t_stat r; - +#if 1 +printf("# tu_attach(uptr, cptr =\"%s\")\r\n", cptr); +#endif r = sim_tape_attach(uptr, cptr); if (r != SCPE_OK) { return(r); @@ -477,7 +481,9 @@ tu_detach(UNIT *uptr) { int32 drv = uptr - tu_dev.units; - +#if 1 +printf("# tu_detach(uptr)\r\n"); +#endif if (sim_is_active(uptr)) { // unit active? sim_cancel(uptr); // cancel operation tuer |= ER_UNS; // set formatter error $ make cc -g -DVM_PDP11 -I./ -I../ -I../PDP11 -c -o pdp11_tu.o pdp11_tu.c cc -o pdp11e pdp11_fp.o pdp11_cpu.o pdp11_dz.o pdp11_cis.o pdp11_lp.o pdp11_rk.o pdp11_rl.o pdp11_rp.o pdp11_rx.o pdp11_stddev.o pdp11_sys.o pdp11_tc.o pdp11_tm.o pdp11_ts.o pdp11_io.o pdp11_rq.o pdp11_tq.o pdp11_pclk.o pdp11_ry.o pdp11_pt.o pdp11_hk.o pdp11_xq.o pdp11_xu.o pdp11_tu.o scp.o scp_tty.o sim_sock.o sim_tmxr.o sim_ether.o sim_tape.o -lm $ ./pdp11e # tu_reset(dptr) PDP-11 simulator V3.0-2 sim> reset tu # tu_reset(dptr) sim> attach tu0 HOGE # tu_attach(uptr, cptr ="HOGE") TU: creating new file sim> detach tu0 # tu_detach(uptr) sim> quit Goodbye # tu_detach(uptr) # tu_detach(uptr) # tu_detach(uptr) # tu_detach(uptr) # tu_detach(uptr) # tu_detach(uptr) # tu_detach(uptr) # tu_detach(uptr) $