diff --git a/I7000/i7000_cdp.c b/I7000/i7000_cdp.c index c1e2cc0..f4c63a7 100644 --- a/I7000/i7000_cdp.c +++ b/I7000/i7000_cdp.c @@ -40,6 +40,12 @@ /* Flags for punch and reader. */ #define ATTENA (1 << (UNIT_V_UF+7)) #define ATTENB (1 << (UNIT_V_UF+14)) +#define INPUT_V (UNIT_V_UF+7) +#define INPUT_FULL (1 << INPUT_V) +#define INPUT_EMPTY (2 << INPUT_V) +#define INPUT_DECK (3 << INPUT_V) +#define INPUT_BLANK (4 << INPUT_V) +#define INPUT_MASK (7 << INPUT_V) /* std devices. data structures @@ -56,6 +62,8 @@ 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_get_input(FILE *, UNIT *, int32, CONST void *); +t_stat cdp_set_input(UNIT *, int32, CONST char *, void *); t_stat cdp_help(FILE *, DEVICE *, UNIT *, int32, const char *); const char *cdp_description(DEVICE *dptr); t_stat stk_help(FILE *, DEVICE *, UNIT *, int32, const char *); @@ -68,6 +76,13 @@ UNIT cdp_unit[] = { #endif }; +UNIT cdp_input_unit[] = { + {UDATA(NULL, UNIT_ATTABLE | INPUT_FULL | UNIT_RO, 0), 600}, /* A */ +#if NUM_DEVS_CDP > 1 + {UDATA(NULL, UNIT_ATTABLE | INPUT_FULL | UNIT_RO, 0), 600}, /* B */ +#endif +}; + MTAB cdp_mod[] = { {MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", &sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"}, @@ -80,17 +95,27 @@ MTAB cdp_mod[] = { {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan, &get_chan, NULL, "Set device channel"}, #endif + {MTAB_XTD | MTAB_VUN | MTAB_VALR | MTAB_NC, 0, "INPUT", "INPUT", &cdp_set_input, &cdp_get_input, + NULL, "Set input to card punch"}, {0} }; DEVICE cdp_dev = { "CDP", cdp_unit, NULL, cdp_mod, NUM_DEVS_CDP, 8, 15, 1, 8, 8, - NULL, NULL, NULL, NULL, &cdp_attach, &cdp_detach, + NULL, NULL, &cdp_reset, NULL, &cdp_attach, &cdp_detach, &cdp_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug, NULL, NULL, &cdp_help, NULL, NULL, &cdp_description }; +DEVICE cdp_input_dev = { + "INPUT", cdp_input_unit, NULL, NULL, + NUM_DEVS_CDP, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, DEV_DISABLE | DEV_DIS, 0, NULL, + NULL, NULL, NULL, NULL, NULL, NULL +}; + #ifdef STACK_DEV UNIT stack_unit[] = { { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }, @@ -140,10 +165,15 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev) int chan = UNIT_G_CHAN(uptr->flags); int u = (uptr - cdp_unit); int stk = dev & 017; + UNIT *iuptr = &cdp_input_unit[u]; + uint16 *image = (uint16 *)(uptr->up7); + int i; /* Are we currently tranfering? */ - if (uptr->u5 & URCSTA_WRITE) + if (uptr->u5 & URCSTA_WRITE) { + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Busy\n", u); return SCPE_BUSY; + } if (stk == 10) stk = 0; @@ -173,6 +203,37 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->u5 |= stk << 16; #endif sim_debug(DEBUG_CMD, &cdp_dev, "%d: Cmd WRS\n", u); + + switch((iuptr->flags & INPUT_MASK) >> INPUT_V) { + case INPUT_EMPTY >> INPUT_V: + case INPUT_BLANK >> INPUT_V: + if (iuptr->u3 == 0) { + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Empty\n", u); + return SCPE_IOERR; + } + iuptr->u3--; + /* Fall through */ + + case INPUT_FULL >> INPUT_V: + for (i = 0; i < 80; image[i++] = 0); + break; + case INPUT_DECK >> INPUT_V: + switch(sim_read_card(iuptr, image)) { + case CDSE_ERROR: + uptr->u5 |= URCSTA_ERR; + /* Fall through */ + + case CDSE_EOF: + case CDSE_EMPTY: + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Empty deck\n", u); + return SCPE_IOERR; + case CDSE_OK: + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: left %d\n", u, + sim_card_input_hopper_count(iuptr)); + break; + } + break; + } chan_set_sel(chan, 1); uptr->u5 |= URCSTA_WRITE; uptr->u4 = 0; @@ -180,7 +241,6 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev) sim_activate(uptr, 50); return SCPE_OK; } - chan_set_attn(chan); return SCPE_IOERR; } @@ -257,9 +317,12 @@ cdp_srv(UNIT *uptr) { ch = 020; else if (ch == 020) ch = 0; - sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch); - image[uptr->u4++] = sim_bcd_to_hol(ch); - if (uptr->u4 == 80) { + image[uptr->u4] |= sim_bcd_to_hol(ch); + if (sim_hol_to_bcd(image[uptr->u4]) == 0x7f) { + chan_set_eof(chan); + } + sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o %04o\n", u, ch, image[uptr->u4]); + if (++uptr->u4 == 80) { chan_set(chan, DEV_REOR); uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL; uptr->u5 &= ~URCSTA_WRITE; @@ -271,6 +334,10 @@ cdp_srv(UNIT *uptr) { return SCPE_OK; } +t_stat +cdp_reset(DEVICE *dptr) { + return sim_register_internal_device (&cdp_input_dev); +} void cdp_ini(UNIT *uptr, t_bool f) { @@ -285,7 +352,7 @@ cdp_attach(UNIT * uptr, CONST char *file) if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; if (uptr->up7 == 0) { - uptr->up7 = calloc(80, sizeof(uint16)); + uptr->up7 = calloc(80, sizeof(uint16)); uptr->u5 = 0; } return SCPE_OK; @@ -306,12 +373,119 @@ cdp_detach(UNIT * uptr) sim_punch_card(uptr, image); #endif } - if (uptr->up7 == 0) + if (uptr->up7 == 0) free(uptr->up7); uptr->up7 = 0; return sim_card_detach(uptr); } +t_stat +cdp_set_input(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int nflag = 1; + int num = 0; + char gbuf[30]; + char *p; + int u = (uptr - cdp_unit); + UNIT *iuptr = &cdp_input_unit[u]; + t_stat r = SCPE_ARG; + + if (cptr == NULL) + return SCPE_ARG; + if (uptr == NULL) + return SCPE_IERR; + + /* Clear existing input */ + sim_card_detach(iuptr); + iuptr->u3 = 0; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_EMPTY; + + /* Get first argument */ + cptr = get_glyph(cptr, gbuf, ';'); + + /* Check if it is a number */ + for (p = gbuf; *p != '\0'; p++) { + if (*p < '0' || *p > '9') { + nflag = 0; + break; + } + num = (num * 10) + (*p) - '0'; + } + + /* If valid number, set to number of blank cards */ + if (nflag) { + iuptr->u3 = num; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_BLANK; + return SCPE_OK; + } + + /* Check for given format */ + if (sim_strcasecmp(gbuf, "EMPTY") == 0) { + iuptr->u3 = 0; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_EMPTY; + return SCPE_OK; + } + + if (sim_strcasecmp(gbuf, "FULL") == 0) { + iuptr->u3 = 0; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_FULL; + return SCPE_OK; + } + + /* If deck attach it to input */ + if (sim_strcasecmp(gbuf, "DECK") == 0) { + int32 saved_switches = sim_switches; + + sim_switches = SWMASK('E') | SWMASK('R'); + if ((saved_switches & SWMASK('F')) != 0) { + cptr = get_glyph(cptr, gbuf, ';'); + sim_card_set_fmt(iuptr, 0, gbuf, NULL); + } + r = sim_card_attach(iuptr, cptr); + if (r == SCPE_OK) { + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_DECK; + } + sim_switches = saved_switches; + } + /* Error, set to empty */ + return r; +} + +t_stat +cdp_get_input(FILE *st, UNIT *uptr, int32 v, CONST void *desc) +{ + int u = (uptr - cdp_unit); + UNIT *iuptr = &cdp_input_unit[u]; + int i; + + if (uptr == NULL) + return SCPE_IERR; + + i = (iuptr->flags & INPUT_MASK) >> INPUT_V; + switch((iuptr->flags & INPUT_MASK) >> INPUT_V) { + case INPUT_BLANK >> INPUT_V: + fprintf(st, "%d blanks", iuptr->u3); + break; + case INPUT_FULL >> INPUT_V: + fprintf(st, "full"); + break; + case INPUT_EMPTY >> INPUT_V: + fprintf(st, "empty"); + break; + case INPUT_DECK >> INPUT_V: + fprintf(st, "deck %s", iuptr->filename); + break; + } + return SCPE_OK; +} + + + #ifdef STACK_DEV t_stat stk_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)