From 9ca9fdcea5e23cf437d98cc97ba2f2cc07de58ad Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sun, 24 Jul 2016 22:09:46 -0400 Subject: [PATCH] KA10: Added Card Reader and Card Punch. Some fixes to KI10. Card reader and Card Punch now work. KI10 will refresh disk structures and load backup from tape. --- PDP10/Makefile | 10 +-- PDP10/ka10_cp.c | 206 ++++++++++++++++++++++------------------------ PDP10/ka10_cpu.c | 146 +++++++++++++++++--------------- PDP10/ka10_cr.c | 169 ++++++++++++++++++++----------------- PDP10/ka10_defs.h | 13 ++- PDP10/ka10_sys.c | 19 +++++ 6 files changed, 304 insertions(+), 259 deletions(-) diff --git a/PDP10/Makefile b/PDP10/Makefile index a258668..fd39303 100644 --- a/PDP10/Makefile +++ b/PDP10/Makefile @@ -35,7 +35,7 @@ LDFLAGS = -lm -lrt BIN = ./ SIM = ../scp.c ../sim_console.c ../sim_fio.c ../sim_timer.c ../sim_tape.c \ ../sim_sock.c ../sim_tmxr.c ../sim_ether.c ../sim_video.c ../sim_serial.c \ - ../sim_disk.c + ../sim_disk.c ../sim_card.c # @@ -46,16 +46,16 @@ KA10 = ${KA10D}ka10_cpu.c ${KA10D}ka10_sys.c ${KA10D}ka10_df.c \ ${KA10D}ka10_dp.c ${KA10D}ka10_mt.c ${KA10D}ka10_cty.c \ ${KA10D}ka10_lp.c ${KA10D}ka10_pt.c ${KA10D}ka10_dc.c \ ${KA10D}ka10_rp.c ${KA10D}ka10_rc.c ${KA10D}ka10_dt.c \ - ${KA10D}ka10_dk.c -KA10_OPT = -I.. -DUSE_INT64 -DKA=1 + ${KA10D}ka10_dk.c ${KA10D}ka10_cr.c ${KA10D}ka10_cp.c +KA10_OPT = -I.. -DUSE_INT64 -DKA=1 -DUSE_SIM_CARD KI10D = ./ KI10 = ${KA10D}ka10_cpu.c ${KA10D}ka10_sys.c ${KA10D}ka10_df.c \ ${KA10D}ka10_dp.c ${KA10D}ka10_mt.c ${KA10D}ka10_cty.c \ ${KA10D}ka10_lp.c ${KA10D}ka10_pt.c ${KA10D}ka10_dc.c \ ${KA10D}ka10_rp.c ${KA10D}ka10_rc.c ${KA10D}ka10_dt.c \ - ${KA10D}ka10_dk.c -KI10_OPT = -I.. -DUSE_INT64 -DKI=1 + ${KA10D}ka10_dk.c ${KA10D}ka10_cr.c ${KA10D}ka10_cp.c +KI10_OPT = -I.. -DUSE_INT64 -DKI=1 -DUSE_SIM_CARD # # Build everything diff --git a/PDP10/ka10_cp.c b/PDP10/ka10_cp.c index 96617ee..7c0b595 100644 --- a/PDP10/ka10_cp.c +++ b/PDP10/ka10_cp.c @@ -1,4 +1,4 @@ -/* ka10_cdp.c: PDP10 Card Punch +/* ka10_cp.c: PDP10 Card Punch Copyright (c) 2016, Richard Cornwell @@ -32,19 +32,19 @@ #include "ka10_defs.h" #include "sim_card.h" #include "sim_defs.h" -#ifdef NUM_DEVS_CDP +#if (NUM_DEVS_CP > 0) -#define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE | MODE_026 +#define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE | MODE_029 -#define CDP_DEVNUM 0110 +#define CP_DEVNUM 0110 /* std devices. data structures - cdp_dev Card Punch device descriptor - cdp_unit Card Punch unit descriptor - cdp_reg Card Punch register list - cdp_mod Card Punch modifiers list + cp_dev Card Punch device descriptor + cp_unit Card Punch unit descriptor + cp_reg Card Punch register list + cp_mod Card Punch modifiers list */ /* CONO Bits */ @@ -77,41 +77,31 @@ #define HOPPER_LOW 0100000 /* less 200 cards 20 */ #define TEST 0400000 /* In test mode 18 */ -/* Device status information stored in u5 */ -#define URCSTA_EOF 0001 /* Hit end of file */ -#define URCSTA_ERR 0002 /* Error reading record */ -#define URCSTA_CARD 0004 /* Unit has card in buffer */ -#define URCSTA_FULL 0004 /* Unit has full buffer */ -#define URCSTA_BUSY 0010 /* Device is busy */ - -t_stat cdp_devio(uint32 dev, uint64 *data); -void cdp_ini(UNIT *, t_bool); -t_stat cdp_srv(UNIT *); -t_stat cdp_reset(DEVICE *); -t_stat cdp_attach(UNIT *, CONST char *); -t_stat cdp_detach(UNIT *); -t_stat cdp_help(FILE *, DEVICE *, UNIT *, int32, const char *); -const char *cdp_description(DEVICE *dptr); +t_stat cp_devio(uint32 dev, uint64 *data); +t_stat cp_srv(UNIT *); +t_stat cp_reset(DEVICE *); +t_stat cp_attach(UNIT *, CONST char *); +t_stat cp_detach(UNIT *); +t_stat cp_help(FILE *, DEVICE *, UNIT *, int32, const char *); +const char *cp_description(DEVICE *dptr); -DIB cdp_dib = { CDP_DEVNUM, 1, cdp_devio, NULL}; +DIB cp_dib = { CP_DEVNUM, 1, cp_devio, NULL}; -UNIT cdp_unit[] = { - {UDATA(cdp_srv, UNIT_S_CHAN(CHAN_CHUREC) | UNIT_CDP, 0), 600}, /* A */ -}; +UNIT cp_unit = {UDATA(cp_srv, UNIT_CDP, 0), 600 }; -MTAB cdp_mod[] = { +MTAB cp_mod[] = { {MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", &sim_card_set_fmt, &sim_card_show_fmt, NULL}, {0} }; -DEVICE cdp_dev = { - "CP", cdp_unit, NULL, cdp_mod, - NUM_DEVS_CDP, 8, 15, 1, 8, 8, - NULL, NULL, NULL, NULL, &cdp_attach, &cdp_detach, - &cdp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, - NULL, NULL, &cdp_help, NULL, NULL, &cdp_description +DEVICE cp_dev = { + "CP", &cp_unit, NULL, cp_mod, + NUM_DEVS_CP, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, &cp_attach, &cp_detach, + &cp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, + NULL, NULL, &cp_help, NULL, NULL, &cp_description }; @@ -120,51 +110,52 @@ DEVICE cdp_dev = { /* Card punch routine */ -t_stat cdp_devio(uint32 dev, uint64 *data) { +t_stat cp_devio(uint32 dev, uint64 *data) { uint64 res; - DEVICE *dptr = &cdp_dev[0]; - UNIT *uptr = &cdp_unit[0]; + UNIT *uptr = &cp_unit; struct _card_data *dp; -#define PIA 0000007 -#define DATA_REQ 0000010 -#define PUNCH_ON 0000040 -#define END_CARD 0000100 /* Eject or column 80 */ -#define END_CARD_EN 0000200 -#define CARD_IN_PUNCH 0000400 /* Card ready to punch */ -#define ERROR 0001000 /* Punch error */ -#define TROUBLE_EN 0002000 -#define TROUBLE 0004000 /* Bit 18,22,23, or 21 */ -#define EJECT_FAIL 0010000 /* Could not eject card 23 */ -#define PICK_FAIL 0020000 /* Could not pick up card 22 */ -#define NEED_OPR 0040000 /* Hopper empty, chip full 21 */ -#define HOPPER_LOW 0100000 /* less 200 cards 20 */ -#define TEST 0400000 /* In test mode 18 */ switch(dev & 3) { case CONI: *data = uptr->u3; + sim_debug(DEBUG_CONI, &cp_dev, "CP: CONI %012llo\n", *data); break; case CONO: - uptr->u3 &= ~7; - uptr->u3 |= *data & (PUNCH_ON|07); clr_interrupt(dev); + sim_debug(DEBUG_CONO, &cp_dev, "CP: CONO %012llo\n", *data); + uptr->u3 &= ~PIA; + uptr->u3 |= *data & PIA; if (*data & CLR_PUNCH) { uptr->u3 &= ~(TROUBLE|ERROR|END_CARD|END_CARD_EN|TROUBLE_EN); + break; } - if ( -#define SET_DATA_REQ 0000010 -#define CLR_DATA_REQ 0000020 -#define SET_PUNCH_ON 0000040 -#define CLR_END_CARD 0000100 -#define EN_END_CARD 0000200 -#define DIS_END_CARD 0000400 -#define CLR_ERROR 0001000 -#define EN_TROUBLE 0002000 -#define DIS_TROUBLE 0004000 -#define EJECT 0010000 /* Finish punch and eject */ -#define OFFSET_CARD 0040000 /* Offset card stack */ -#define CLR_PUNCH 0100000 /* Clear Trouble, Error, End */ - if (uptr->u3 & PUNCH_ON) { + if (*data & SET_DATA_REQ) { + uptr->u3 |= DATA_REQ; + set_interrupt(dev, uptr->u3); + } + if (*data & CLR_DATA_REQ) + uptr->u3 &= ~DATA_REQ; + if (*data & CLR_END_CARD) + uptr->u3 &= ~END_CARD; + if (*data & EN_END_CARD) + uptr->u3 |= END_CARD_EN; + if (*data & DIS_END_CARD) + uptr->u3 &= ~END_CARD_EN; + if (*data & EN_TROUBLE) + uptr->u3 |= TROUBLE_EN; + if (*data & DIS_TROUBLE) + uptr->u3 &= ~TROUBLE_EN; + if (*data & EJECT && uptr->u3 & CARD_IN_PUNCH) { + uptr->u4 = 80; + uptr->u3 &= ~DATA_REQ; + sim_activate(uptr, uptr->wait); + } + if ((uptr->u3 & (TROUBLE|TROUBLE_EN)) == (TROUBLE|TROUBLE_EN)) + set_interrupt(CP_DEVNUM, uptr->u3); + if ((uptr->u3 & (END_CARD|END_CARD_EN)) == (END_CARD|END_CARD_EN)) + set_interrupt(CP_DEVNUM, uptr->u3); + if (*data & PUNCH_ON) { + uptr->u3 |= PUNCH_ON; sim_activate(uptr, uptr->wait); } break; @@ -176,6 +167,8 @@ t_stat cdp_devio(uint32 dev, uint64 *data) { dp->image[uptr->u4++] = *data & 0xfff; uptr->u3 &= ~DATA_REQ; clr_interrupt(dev); + sim_debug(DEBUG_DATAIO, &cp_dev, "CP: DATAO %012llo %d\n", *data, + uptr->u4); sim_activate(uptr, uptr->wait); break; } @@ -184,68 +177,69 @@ t_stat cdp_devio(uint32 dev, uint64 *data) { /* Handle transfer of data for card punch */ t_stat -cdp_srv(UNIT *uptr) { - int u = (uptr - cdp_unit); +cp_srv(UNIT *uptr) { - - if (uptr->u5 & URCSTA_BUSY) { - /* Done waiting, punch card */ - if (uptr->u5 & URCSTA_FULL) { - switch(sim_punch_card(uptr, NULL)) { - case SCPE_EOF: - case SCPE_UNATT: - chan_set_eof(chan); - break; - /* If we get here, something is wrong */ - case SCPE_IOERR: - chan_set_error(chan); - break; - case SCPE_OK: - break; - } - uptr->u5 &= ~URCSTA_FULL; + if (uptr->u3 & PUNCH_ON) { + uptr->u3 |= CARD_IN_PUNCH; + if (uptr->u3 & DATA_REQ) { + sim_activate(uptr, uptr->wait); + return SCPE_OK; + } + if (uptr->u4 < 80) { + if ((uptr->u3 & DATA_REQ) == 0) { + uptr->u3 |= DATA_REQ; + set_interrupt(CP_DEVNUM, uptr->u3); + } + sim_activate(uptr, uptr->wait); + return SCPE_OK; + } + uptr->u4 = 0; + uptr->u3 &= ~(PUNCH_ON|CARD_IN_PUNCH); + uptr->u3 |= END_CARD; + switch(sim_punch_card(uptr, NULL)) { + case SCPE_EOF: + case SCPE_UNATT: + uptr->u3 |= PICK_FAIL|TROUBLE; + break; + /* If we get here, something is wrong */ + case SCPE_IOERR: + uptr->u3 |= EJECT_FAIL|TROUBLE; + break; + case SCPE_OK: + break; } - uptr->u5 &= ~URCSTA_BUSY; + if ((uptr->u3 & (TROUBLE|TROUBLE_EN)) == (TROUBLE|TROUBLE_EN)) + set_interrupt(CP_DEVNUM, uptr->u3); + if (uptr->u3 & END_CARD_EN) + set_interrupt(CP_DEVNUM, uptr->u3); } - /* Copy next column over */ - if (uptr->u5 & URCSTA_WRITE && uptr->u4 < 80) { - struct _card_data *data; - uint8 ch = 0; - - data = (struct _card_data *)uptr->up7; - - sim_activate(uptr, uptr->wait); - } return SCPE_OK; } -void -cdp_ini(UNIT *uptr, t_bool f) { -} - t_stat -cdp_attach(UNIT * uptr, CONST char *file) +cp_attach(UNIT * uptr, CONST char *file) { t_stat r; if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; - uptr->u5 = 0; + uptr->u3 = 0; + uptr->u4 = 0; return SCPE_OK; } t_stat -cdp_detach(UNIT * uptr) +cp_detach(UNIT * uptr) { - if (uptr->u5 & URCSTA_FULL) + if (uptr->u3 & CARD_IN_PUNCH) sim_punch_card(uptr, NULL); return sim_card_detach(uptr); } t_stat -cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +cp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) { fprintf (st, "Card Punch\n\n"); fprint_set_help(st, dptr); @@ -254,7 +248,7 @@ cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) } const char * -cdp_description(DEVICE *dptr) +cp_description(DEVICE *dptr) { return "Card Punch"; } diff --git a/PDP10/ka10_cpu.c b/PDP10/ka10_cpu.c index 350424d..12a436e 100644 --- a/PDP10/ka10_cpu.c +++ b/PDP10/ka10_cpu.c @@ -374,9 +374,9 @@ int opflags[] = { 0, 0, 0, 0, #endif /* UFA */ /* DFN */ /* FSC */ /* IBP */ - FCE|FBR, FCE|FAC|SAC, FAC|SAC, FCEPSE, + FCE|FBR, FCE|FAC|SAC, FAC|SAC, 0, /* ILDB */ /* LDB */ /* IDPB */ /* DPB */ - FCEPSE, FCE, FCEPSE, FCE, + 0, 0, 0, 0, /* FAD */ /* FADL */ /* FADM */ /* FADB */ SAC|FBR|FCE, SAC|SAC2|FBR|FCE, FCEPSE|FBR, SAC|FBR|FCEPSE, /* FADR */ /* FADRI */ /* FADRM */ /* FADRB */ @@ -984,7 +984,7 @@ t_stat null_dev(uint32 dev, uint64 *data) { /* * Handle page lookup on KI10 */ -int page_lookup(int addr, int flag, int *loc, int wr, int fetch) { +int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { uint64 data; int base; int page = addr >> 9; @@ -995,7 +995,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int fetch) { if (page_fault) return 0; - if (uf || ((xct_flag & 1) && !fetch && ((wr == 0) || modify)) || + if (uf || ((xct_flag & 1) && !cur_context && ((wr == 0) || modify)) || ((xct_flag & 2) && wr)) { base = ub_ptr; uf = 1; @@ -1039,7 +1039,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int fetch) { private_page = 1; // fprintf(stderr, " public"); } - if (fetch && ((data & 0200000) != 0)) + if (cur_context && ((data & 0200000) != 0)) FLAGS |= PUBLIC; if ((data & LSIGN) == 0 || (wr & ((data & 0100000) == 0))) { fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 28) | 020LL; @@ -1123,7 +1123,7 @@ int Mem_write_nopage() { /* * Translation logic for KA10 */ -int page_lookup(int addr, int flag, int *loc, int wr, int fetch) { +int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) { if (!flag && (FLAGS & USER) != 0) { if (addr <= ((Pl << 10) + 01777)) *loc = (AB + (Rl << 10)) & RMASK; @@ -1152,7 +1152,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int fetch) { * * Return of 0 if successful, 1 if there was an error. */ -int Mem_read(int flag, int fetch) { +int Mem_read(int flag, int cur_context) { int addr; if (AB < 020) { @@ -1160,7 +1160,7 @@ int Mem_read(int flag, int fetch) { if (FLAGS & USER) { MB = get_reg(AB); return 0; - } else if (xct_flag & 1 && !fetch) { + } else if (xct_flag & 1 && !cur_context) { if (FLAGS & USERIO) { if (fm_sel == 0) goto read; @@ -1175,7 +1175,7 @@ int Mem_read(int flag, int fetch) { } else { read: sim_interval--; - if (!page_lookup(AB, flag, &addr, 0, fetch)) + if (!page_lookup(AB, flag, &addr, 0, cur_context)) return 1; if (addr >= (int)MEMSIZE) { nxm_flag = 1; @@ -1192,7 +1192,7 @@ read: * * Return of 0 if successful, 1 if there was an error. */ -int Mem_write(int flag) { +int Mem_write(int flag, int cur_context) { int addr; if (AB < 020) { @@ -1200,7 +1200,8 @@ int Mem_write(int flag) { if (FLAGS & USER) { set_reg(AB, MB); return 0; - } else if (((xct_flag & 1) && modify) || (xct_flag & 2)) { + } else if (!cur_context && + ((xct_flag & 1) && modify) || (xct_flag & 2)) { if (FLAGS & USERIO) { if (fm_sel == 0) goto write; @@ -1216,7 +1217,7 @@ int Mem_write(int flag) { } else { write: sim_interval--; - if (!page_lookup(AB, flag, &addr, 1, 0)) + if (!page_lookup(AB, flag, &addr, 1, cur_context)) return 1; #if KI | KL if (private_page) @@ -1279,6 +1280,10 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ pi_rq = 0; pi_ov = 0; BYF5 = 0; +#if KI | KL + private_page = 0; + page_fault = 0; +#endif while ( reason == 0) { /* loop until ABORT */ if (sim_interval <= 0) { /* check clock queue */ @@ -1293,6 +1298,26 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ break; } +#if KI | KL + /* Handle page fault and traps */ + if (page_enable && (page_fault || private_page || (FLAGS & (TRP1|TRP2)))) { + if (page_fault || private_page) { + page_fault = private_page = 0; + AB = ub_ptr + (FLAGS & USER) ? 0427 : 0426; + MB = fault_data; + Mem_write_nopage(); + AB = 0420; + } else { + AB = 0420 + ((FLAGS & (TRP1|TRP2)) >> 2); + FLAGS &= ~(TRP1|TRP2); + } + f_pc_inh = 1; + trap_flag = 1; + AB += (FLAGS & USER) ? ub_ptr : eb_ptr; + Mem_read_nopage(); + goto no_fetch; + } +#endif /* Normal instruction */ if (f_load_pc) { @@ -1306,18 +1331,11 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */ if (f_inst_fetch) { fetch: -#if KI | KL - private_page = 0; - page_fault = 0; -#endif Mem_read(pi_cycle | uuo_cycle, 1); no_fetch: IR = (MB >> 27) & 0777; AC = (MB >> 23) & 017; i_flags = opflags[IR]; -#if KI | KL - FLAGS &= ~(TRP1|TRP2); -#endif BYF5 = 0; } @@ -1361,7 +1379,7 @@ no_fetch: if (IR != 0254) AR &= RMASK; if (ind & !pi_rq) - if (Mem_read(pi_cycle | uuo_cycle, 0)) + if (Mem_read(pi_cycle | uuo_cycle, 1)) goto last; /* Handle events during a indirect loop */ if (sim_interval-- <= 0) { @@ -1418,12 +1436,14 @@ fetch_opr: /* Set up to execute instruction */ f_inst_fetch = 1; f_load_pc = 1; - f_pc_inh = 0; nrf = 0; fxu_hold_set = 0; sac_inh = 0; #if KI | KL modify = 0; + f_pc_inh = trap_flag; +#else + f_pc_inh = 0; #endif /* Load pseudo registers based on flags */ if (i_flags & (FCEPSE|FCE)) { @@ -1525,7 +1545,7 @@ unasign: } #endif AB = 040; - Mem_write(uuo_cycle); + Mem_write(uuo_cycle, 0); AB += 1; f_load_pc = 0; f_pc_inh = 1; @@ -1739,7 +1759,7 @@ dpnorm: /* Handle each half as seperate instruction */ if ((FLAGS & BYTI) == 0) { MB = AR; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; FLAGS |= BYTI; #if KI /* KL does this in one shot */ @@ -1750,7 +1770,7 @@ dpnorm: if ((FLAGS & BYTI)) { AB = (AB + 1) & RMASK; MB = MQ; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; FLAGS &= ~BYTI; } @@ -1766,7 +1786,7 @@ dpnorm: AR = BR; AR &= FMASK; MB = AR; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; FLAGS |= BYTI; #if KI @@ -1778,7 +1798,7 @@ dpnorm: MQ = (CM(MQ) + 1) & CMASK; AB = (AB + 1) & RMASK; MB = MQ; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; FLAGS &= ~BYTI; } @@ -1840,7 +1860,7 @@ unasign: MB = ((uint64)(IR) << 27) | ((uint64)(AC) << 23) | (uint64)(AB); AB = 060; uuo_cycle = 1; - Mem_write(uuo_cycle); + Mem_write(uuo_cycle, 0); AB += 1; f_load_pc = 0; f_pc_inh = 1; @@ -1851,6 +1871,12 @@ unasign: case 0134: /* ILDB */ case 0136: /* IDPB */ if ((FLAGS & BYTI) == 0) { /* BYF6 */ + if (Mem_read(0, 1)) + goto last; + AR = MB; +#if KI | KL + modify = 1; +#endif SC = (AR >> 24) & 077; SCAD = (((AR >> 30) & 077) + (0777 ^ SC) + 1) & 0777; if (SCAD & 0400) { @@ -1864,6 +1890,9 @@ unasign: SC = SCAD; AR &= PMASK; AR |= (uint64)(SC & 077) << 30; + MB = AR; + if (Mem_write(0, 1)) + goto last; if ((IR & 04) == 0) break; } @@ -1871,6 +1900,9 @@ unasign: case 0135:/* LDB */ case 0137:/* DPB */ if (((FLAGS & BYTI) == 0) | !BYF5) { + if (Mem_read(0, 1)) + goto last; + AR = MB; SC = (AR >> 30) & 077; MQ = (uint64)(1) << ( 077 & (AR >> 24)); MQ -= 1; @@ -1902,7 +1934,7 @@ unasign: AR &= FMASK; BR |= AR & MQ; MB = BR; - Mem_write(0); + Mem_write(0, 0); } FLAGS &= ~BYTI; /* BYF6 */ BYF5 = 0; @@ -1920,7 +1952,7 @@ unasign: BR = AR; AR = AD; MB = BR; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; break; #endif @@ -2665,7 +2697,7 @@ fxnorm: if (Mem_read(0, 0)) break; AB = (AR & RMASK); - if (Mem_write(0)) + if (Mem_write(0, 0)) break; AD = (AR & RMASK) + CM(BR) + 1; AR = AOB(AR); @@ -2811,7 +2843,7 @@ fxnorm: if (uuo_cycle | pi_cycle) { FLAGS &= ~(USER|PUBLIC); /* Clear USER */ } - Mem_write(uuo_cycle | pi_cycle); + Mem_write(uuo_cycle | pi_cycle, 0); PC = BR & RMASK; f_pc_inh = 1; break; @@ -2830,7 +2862,7 @@ fxnorm: } AR &= FMASK; MB = BR; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; break; @@ -2840,7 +2872,7 @@ fxnorm: goto last; AR = SOB(AR); AB = BR & RMASK; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; if ((AR & C1) == 0) { #if KI | KL @@ -3434,7 +3466,7 @@ test_op: } AR &= FMASK; MB = AR; - if (Mem_write(pi_cycle)) + if (Mem_write(pi_cycle, 0)) break; AB = AR & RMASK; goto fetch_opr; @@ -3442,7 +3474,7 @@ test_op: case 1: /* 04 DATAI */ dev_tab[d](DATAI|(d<<2), &AR); MB = AR; - Mem_write(pi_cycle); + Mem_write(pi_cycle, 0); break; case 3: /* 14 DATAO */ if (Mem_read(pi_cycle, 0)) @@ -3456,7 +3488,7 @@ test_op: case 5: /* 24 CONI */ dev_tab[d](CONI|(d<<2), &AR); MB = AR; - Mem_write(pi_cycle); + Mem_write(pi_cycle, 0); break; case 6: /* 30 CONSZ */ dev_tab[d](CONI|(d<<2), &AR); @@ -3474,9 +3506,10 @@ test_op: } break; } + if (!sac_inh && (i_flags & (SCE|FCEPSE))) { MB = AR; - if (Mem_write(0)) + if (Mem_write(0, 0)) goto last; } if (!sac_inh && ((i_flags & SAC) || ((i_flags & SACZ) && AC != 0))) @@ -3492,42 +3525,19 @@ test_op: last: -#if KI | KL - /* Handle page fault and traps */ - if (page_enable && (page_fault || private_page || (FLAGS & (TRP1|TRP2)))) { - if (page_fault || private_page) { - page_fault = private_page = 0; - if (pi_cycle) { - inout_fail = 1; - fprintf (stderr, "I/O Page fault PC=%06o\n", PC); - goto last2; - } - AB = ub_ptr + (FLAGS & USER) ? 0427 : 0426; - MB = fault_data; - Mem_write_nopage(); - AB = 0420; - } else { - AB = 0420 + ((FLAGS & (TRP1|TRP2)) >> 2); - } - f_pc_inh = 1; - f_load_pc = 0; - f_inst_fetch = 0; - trap_flag = 1; - AB += (FLAGS & USER) ? ub_ptr : eb_ptr; - Mem_read_nopage(); - goto no_fetch; - } - -last2: - check_apr_irq(); -#endif - - if (!f_pc_inh & !pi_cycle) { + if (!f_pc_inh && !pi_cycle) { PC = (PC + 1) & RMASK; } /* Dismiss an interrupt */ if (pi_cycle) { +#if KI | KL + if (page_enable && (page_fault || private_page)) { + page_fault = private_page = 0; + inout_fail = 1; + } +#endif + if ((IR & 0700) == 0700 && ((AC & 04) == 0)) { pi_hold = pi_ov; if (!pi_hold & f_inst_fetch) { diff --git a/PDP10/ka10_cr.c b/PDP10/ka10_cr.c index 0df15b8..a0f2b56 100644 --- a/PDP10/ka10_cr.c +++ b/PDP10/ka10_cr.c @@ -1,4 +1,4 @@ -/* ka10_cdr.c: PDP10 Card reader. +/* ka10_cr.c: PDP10 Card reader. Copyright (c) 2016, Richard Cornwell @@ -32,20 +32,20 @@ #include "ka10_defs.h" #include "sim_card.h" #include "sim_defs.h" -#ifdef NUM_DEVS_CDR +#if (NUM_DEVS_CR > 0) #define UNIT_CDR UNIT_ATTABLE | UNIT_RO | UNIT_DISABLE | \ - UNIT_ROABLE | MODE_026 + UNIT_ROABLE | MODE_029 -#define CDR_DEVNUM 0150 +#define CR_DEVNUM 0150 /* std devices. data structures - cdr_dev Card Reader device descriptor - cdr_unit Card Reader unit descriptor - cdr_reg Card Reader register list - cdr_mod Card Reader modifiers list + cr_dev Card Reader device descriptor + cr_unit Card Reader unit descriptor + cr_reg Card Reader register list + cr_mod Card Reader modifiers list */ /* CONO Bits */ @@ -56,7 +56,7 @@ #define EN_READY 0000100 /* Enable ready irq */ #define CLR_DATA_MISS 0000200 /* Clear data miss */ #define EN_TROUBLE 0000400 /* Enable trouble IRQ */ -#define READ_CARD 0001000 /* Read in card */ +#define READ_CARD 0001000 /* Read card */ #define OFFSET_CARD 0004000 #define CLR_READER 0010000 /* Clear reader */ /* CONI Bits */ @@ -68,87 +68,98 @@ #define TROUBLE 00000400 /* Trouble */ #define READING 00001000 /* Reading card */ #define HOPPER_EMPTY 00002000 -#define CARD_READ 00004000 /* Card in reader */ +#define CARD_IN_READ 00004000 /* Card in reader */ #define STOP 00010000 #define MOTION_ERROR 00020000 #define CELL_ERROR 00040000 #define PICK_ERROR 00100000 #define RDY_READ_EN 00200000 #define TROUBLE_EN 00400000 -#define READ_CARD 01000000 +t_stat cr_devio(uint32 dev, uint64 *data); +t_stat cr_srv(UNIT *); +t_stat cr_reset(DEVICE *); +t_stat cr_attach(UNIT *, CONST char *); +t_stat cr_detach(UNIT *); +t_stat cr_help(FILE *, DEVICE *, UNIT *, int32, const char *); +const char *cr_description(DEVICE *dptr); -/* Device status information stored in u5 */ -#define URCSTA_EOF 0001 /* Hit end of file */ -#define URCSTA_ERR 0002 /* Error reading record */ -#define URCSTA_CARD 0004 /* Unit has card in buffer */ -#define URCSTA_FULL 0004 /* Unit has full buffer */ -#define URCSTA_BUSY 0010 /* Device is busy */ +DIB cr_dib = { CR_DEVNUM, 1, cr_devio, NULL}; -t_stat cdr_devio(uint32 dev, uint64 *data); -t_stat cdr_srv(UNIT *); -t_stat cdr_reset(DEVICE *); -t_stat cdr_attach(UNIT *, CONST char *); -t_stat cdr_detach(UNIT *); -t_stat cdr_help(FILE *, DEVICE *, UNIT *, int32, const char *); -const char *cdr_description(DEVICE *dptr); - -DIB cdr_dib = { CDR_DEVNUM, 1, cdr_devio, NULL}; - -UNIT cdr_unit[] = { - {UDATA(cdr_srv, UNIT_S_CHAN(CHAN_CHUREC) | UNIT_CDR, 0), 300}, /* A */ +UNIT cr_unit = { + UDATA(cr_srv, UNIT_CDR, 0), 300, }; -MTAB cdr_mod[] = { +MTAB cr_mod[] = { {MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", &sim_card_set_fmt, &sim_card_show_fmt, NULL}, {0} }; -DEVICE cdr_dev = { - "CR", cdr_unit, NULL, cdr_mod, - NUM_DEVS_CDR, 8, 15, 1, 8, 8, - NULL, NULL, NULL, NULL, &cdr_attach, &sim_card_detach, - &cdr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, - NULL, NULL, &cdr_help, NULL, NULL, &cdr_description +DEVICE cr_dev = { + "CR", &cr_unit, NULL, cr_mod, + NUM_DEVS_CR, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, &cr_attach, &sim_card_detach, + &cr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, + NULL, NULL, &cr_help, NULL, NULL, &cr_description }; /* * Device entry points for card reader. */ -t_stat cdr_devio(uint32 dev, uint64 *data) { - UNIT *uptr = &cdr_unit; +t_stat cr_devio(uint32 dev, uint64 *data) { + UNIT *uptr = &cr_unit; switch(dev & 3) { case CONI: - *data = uptr->STATUS; + if (uptr->flags & UNIT_ATT && + (uptr->u3 & (READING|CARD_IN_READ|END_CARD)) == 0) + uptr->u3 |= RDY_READ; + *data = uptr->u3; + if (uptr->u3 & RDY_READ_EN && uptr->u3 & RDY_READ) + set_interrupt(dev, uptr->u3); + sim_debug(DEBUG_CONI, &cr_dev, "CR: CONI %012llo\n", *data); break; case CONO: clr_interrupt(dev); - fprintf(stderr, "PT: CONO %012llo\n\r", *data); - uptr->STATUS = (PI_DONE|DONE_FLG|BUSY_FLG|BIN_FLG) & *data; - if ((uptr->flags & UNIT_ATT)) - uptr->STATUS |= TAPE_PR; - if (uptr->STATUS & BUSY_FLG) { - uptr->CHR = 0; - uptr->CHL = 0; - sim_activate (&ptr_unit, ptr_unit.wait); + sim_debug(DEBUG_CONO, &cr_dev, "CR: CONO %012llo\n", *data); + if (*data & CLR_READER) { + uptr->u3 = 0; + sim_cancel(uptr); + break; } - if (uptr->STATUS & DONE_FLG) - set_interrupt(dev, uptr->STATUS); + uptr->u3 &= ~(PIA); + uptr->u3 |= *data & PIA; + uptr->u3 &= ~(*data & (CLR_DRDY|CLR_END_CARD|CLR_EOF|CLR_DATA_MISS)); + if (*data & EN_TROUBLE) + uptr->u3 |= TROUBLE_EN; + if (*data & EN_READY) + uptr->u3 |= RDY_READ_EN; + if (*data & READ_CARD) { + uptr->u3 |= READING; + uptr->u3 &= ~(CARD_IN_READ|RDY_READ|DATA_RDY); + uptr->u4 = 0; + sim_activate(uptr, uptr->wait); + } + if (uptr->flags & UNIT_ATT && + (uptr->u3 & (READING|CARD_IN_READ|END_CARD)) == 0) + uptr->u3 |= RDY_READ; + if (uptr->u3 & RDY_READ_EN && uptr->u3 & RDY_READ) + set_interrupt(dev, uptr->u3); + if (uptr->u3 & TROUBLE_EN && + (uptr->u3 & (END_CARD|END_FILE|DATA_MISS|TROUBLE)) != 0) + set_interrupt(dev, uptr->u3); break; case DATAI: - if ((uptr->STATUS & DONE_FLG)) { - *data = ((uint64)uptr->CHL) << 18; - *data |= ((uint64)uptr->CHR); - fprintf(stderr, "PT: DATAI %012llo\n\r", *data); - uptr->STATUS |= BUSY_FLG; - uptr->STATUS &= ~DONE_FLG; - clr_interrupt(dev); - sim_activate (&ptr_unit, ptr_unit.wait); - } + clr_interrupt(dev); + if (uptr->u3 & DATA_RDY) { + *data = uptr->u5; + sim_debug(DEBUG_DATAIO, &cr_dev, "CR: DATAI %012llo\n", *data); + uptr->u3 &= ~DATA_RDY; + } else + *data = 0; break; case DATAO: break; @@ -158,63 +169,69 @@ t_stat cdr_devio(uint32 dev, uint64 *data) { /* Handle transfer of data for card reader */ t_stat -cdr_srv(UNIT *uptr) { - int u = (uptr - cdr_unit); +cr_srv(UNIT *uptr) { struct _card_data *data; data = (struct _card_data *)uptr->up7; - if (uptr->u3 & URCSTA_BUSY) { - uptr->u3 &= ~URCSTA_BUSY; - } - /* Check if new card requested. */ - if (uptr->u4 == 0 && - (uptr->u3 & (READ_CARD|CARD_READ)) == READ_CARD) { + if ((uptr->u3 & (READING|CARD_IN_READ)) == READING) { switch(sim_read_card(uptr)) { case SCPE_EOF: uptr->u3 |= END_FILE; + if (uptr->u3 & TROUBLE_EN) + set_interrupt(CR_DEVNUM, uptr->u3); return SCPE_OK; case SCPE_UNATT: return SCPE_OK; case SCPE_IOERR: uptr->u3 |= TROUBLE; + if (uptr->u3 & TROUBLE_EN) + set_interrupt(CR_DEVNUM, uptr->u3); return SCPE_OK; case SCPE_OK: - uptr->u3 |= CARD_READ; - uptr->u3 &= ~READ_CARD; + uptr->u3 |= CARD_IN_READ; break; } + uptr->u4 = 0; + sim_activate(uptr, uptr->wait); + return SCPE_OK; } /* Copy next column over */ - if (uptr->u3 & CARD_READ) { + if (uptr->u3 & CARD_IN_READ) { if (uptr->u4 >= 80) { + uptr->u3 &= ~(CARD_IN_READ|READING); uptr->u3 |= END_CARD; + set_interrupt(CR_DEVNUM, uptr->u3); + sim_activate(uptr, uptr->wait); + return SCPE_OK; } uptr->u5 = data->image[uptr->u4++]; + if (uptr->u3 & DATA_RDY) { + uptr->u3 |= DATA_MISS; + } uptr->u3 |= DATA_RDY; - sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %03x\n", u, uptr->u5); + sim_debug(DEBUG_DATA, &cr_dev, "CR Char > %d %03x\n", uptr->u4, uptr->u5); + set_interrupt(CR_DEVNUM, uptr->u3); sim_activate(uptr, uptr->wait); } return SCPE_OK; } t_stat -cdr_attach(UNIT * uptr, CONST char *file) +cr_attach(UNIT * uptr, CONST char *file) { t_stat r; if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; - uptr->u3 &= URCSTA_BUSY; - uptr->u4 = 0; - uptr->u6 = 0; + uptr->u3 |= RDY_READ; return SCPE_OK; } t_stat -cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +cr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) { fprintf (st, "Card Reader\n\n"); fprintf (st, "The system supports one card reader.\n"); @@ -224,7 +241,7 @@ cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) } const char * -cdr_description(DEVICE *dptr) +cr_description(DEVICE *dptr) { return "Card Reader"; } diff --git a/PDP10/ka10_defs.h b/PDP10/ka10_defs.h index 9e8d395..a3b838c 100644 --- a/PDP10/ka10_defs.h +++ b/PDP10/ka10_defs.h @@ -104,12 +104,13 @@ #define DEBUG_DATA 0x0000002 /* Show data transfers */ #define DEBUG_DETAIL 0x0000004 /* Show details */ #define DEBUG_EXP 0x0000008 /* Show error conditions */ -#define DEBUG_CONI 0x0000010 /* Show CONI instructions */ -#define DEBUG_CONO 0x0000020 /* Show CONO instructions */ -#define DEBUG_DATAIO 0x0000040 /* Show DATAI/O instructions */ -#define DEBUG_IRQ 0x0000080 /* Show IRQ requests */ +#define DEBUG_CONI 0x0000020 /* Show CONI instructions */ +#define DEBUG_CONO 0x0000040 /* Show CONO instructions */ +#define DEBUG_DATAIO 0x0000080 /* Show DATAI/O instructions */ +#define DEBUG_IRQ 0x0000100 /* Show IRQ requests */ extern DEBTAB dev_debug[]; +extern DEBTAB crd_debug[]; /* Operating system flags, kept in cpu_unit.flags */ @@ -253,6 +254,8 @@ extern DEVICE rpd_dev; extern DEVICE lpt_dev; extern DEVICE ptp_dev; extern DEVICE ptr_dev; +extern DEVICE cr_dev; +extern DEVICE cp_dev; extern DEVICE rca_dev; extern DEVICE rcb_dev; extern DEVICE dc_dev; @@ -301,6 +304,8 @@ int df10_write(struct df10 *df); #define NUM_DEVS_DP 2 #define NUM_DEVS_LP 1 #define NUM_DEVS_PT 1 +#define NUM_DEVS_CR 1 +#define NUM_DEVS_CP 1 #define NUM_DEVS_DC 1 #define NUM_DEVS_RC 1 #define NUM_DEVS_DT 0 diff --git a/PDP10/ka10_sys.c b/PDP10/ka10_sys.c index 701489e..156fb34 100644 --- a/PDP10/ka10_sys.c +++ b/PDP10/ka10_sys.c @@ -25,6 +25,7 @@ */ #include "ka10_defs.h" +#include "sim_card.h" #include @@ -66,6 +67,12 @@ DEVICE *sim_devices[] = { #if (NUM_DEVS_LP > 0) &lpt_dev, #endif +#if (NUM_DEVS_CR > 0) + &cr_dev, +#endif +#if (NUM_DEVS_CP > 0) + &cp_dev, +#endif #if (NUM_DEVS_MT > 0) &mt_dev, #endif @@ -130,6 +137,18 @@ DEBTAB dev_debug[] = { {0, 0} }; +/* Simulator debug controls */ +DEBTAB crd_debug[] = { + {"CMD", DEBUG_CMD, "Show command execution to devices"}, + {"DATA", DEBUG_DATA, "Show data transfers"}, + {"DETAIL", DEBUG_DETAIL, "Show details about device"}, + {"EXP", DEBUG_EXP, "Show exception information"}, + {"CONI", DEBUG_CONI, "Show coni instructions"}, + {"CONO", DEBUG_CONO, "Show coni instructions"}, + {"DATAIO", DEBUG_DATAIO, "Show datai and datao instructions"}, + {"CARD", DEBUG_CARD, "Show Card read/punches"}, + {0, 0} +}; /* Binary loader, supports RIM10, SAV, EXE */