diff --git a/B5500/b5500_cpu.c b/B5500/b5500_cpu.c index 6dcb50d4..e0e7b8f3 100644 --- a/B5500/b5500_cpu.c +++ b/B5500/b5500_cpu.c @@ -213,7 +213,7 @@ uint16 l_reg[2]; /* L current syllable pointer */ uint8 ncsf_reg[2]; /* True if normal state */ uint8 salf_reg[2]; /* True if subrogram mode */ uint8 cwmf_reg[2]; /* True if character mode */ -uint8 hltf[2]; /* True if processor halted */ +uint16 hltf[2]; /* True if processor halted */ uint8 msff_reg[2]; /* Mark stack flag Word mode */ #define TFFF MSFF /* True state in Char mode */ uint8 varf_reg[2]; /* Variant Flag */ @@ -926,7 +926,7 @@ void initiate() { /* Save processor state in case of error or halt */ void storeInterrupt(int forced, int test) { int f; - t_uint64 temp; + uint16 temp; if (forced || test) NCSF = 0; @@ -946,7 +946,7 @@ void storeInterrupt(int forced, int test) { } /* Make ILCW */ B = X | ((i)? PRESENT : 0) | FLAG | DFLAG; - next_addr(S); /* Save B */ + next_addr(S); /* Save B */ memory_cycle(11); } else { if (BROF || test) { /* Push B First */ @@ -959,11 +959,11 @@ void storeInterrupt(int forced, int test) { } } AROF = 0; - B = ICW; /* Set ICW into B */ - next_addr(S); /* Save B */ + B = ICW; /* Set ICW into B */ + next_addr(S); /* Save B */ memory_cycle(11); - B = RCW(f); /* Save IRCW */ - next_addr(S); /* Save B */ + B = RCW(f); /* Save IRCW */ + next_addr(S); /* Save B */ memory_cycle(11); if (CWMF) { /* Get the correct value of R */ @@ -1985,7 +1985,7 @@ sim_instr(void) int i; int j; - reason = 0; + reason = SCPE_OK; hltf[0] = 0; hltf[1] = 0; P1_run = 1; @@ -1993,18 +1993,17 @@ sim_instr(void) while (reason == 0) { /* loop until halted */ if (P1_run == 0) return SCPE_STOP; + /* System is booting, wait until finished loading */ while (loading) { - sim_interval = -1; reason = sim_process_event(); - if (reason != SCPE_OK) { + if (reason != SCPE_OK) break; /* process */ - } } + /* Passed time quantum */ if (sim_interval <= 0) { /* event queue? */ reason = sim_process_event(); - if (reason != SCPE_OK) { + if (reason != SCPE_OK) break; /* process */ - } } if (sim_brk_summ) { @@ -2027,20 +2026,15 @@ sim_instr(void) } /* Toggle between two CPU's. */ + if (TROF == 0 && NCSF) { + if (Q != 0 || ((cpu_index)? HLTF : IAR) != 0) + storeInterrupt(1,0); + } + if (cpu_index == 0 && P2_run == 1) { cpu_index = 1; - /* Check if interrupt pending. */ - if (TROF == 0 && NCSF && ((Q != 0) || HLTF)) - /* Force a SFI */ - storeInterrupt(1,0); } else { cpu_index = 0; - - /* Check if interrupt pending. */ - if (TROF == 0 && NCSF && ((Q != 0) || - (IAR != 0))) - /* Force a SFI */ - storeInterrupt(1,0); } if (TROF == 0) next_prog(); @@ -2184,17 +2178,12 @@ crf_loop: Ma = (F - field) & CORE; memory_cycle(4); AROF = 0; - if (A & FLAG) { - if ((A & PRESENT) == 0) { - if (NCSF) - Q |= PRES_BIT; - break; - } - GH = 0; - } else { - GH = (A >> 12) & 070; - } Ma = CF(A); + GH = 0; + if ((A & FLAG) == 0) + GH = (A >> 12) & 070; + else if ((A & PRESENT) == 0 && NCSF) + Q |= PRES_BIT; break; case CMOP_RDA: /* Recall Destination Address */ @@ -2203,34 +2192,29 @@ crf_loop: S = (F - field) & CORE; memory_cycle(3); BROF = 0; - if (B & FLAG) { - if ((B & PRESENT) == 0) { - if (NCSF) - Q |= PRES_BIT; - break; - } - KV = 0; - } else { - KV = (B >> 12) & 070; - } S = CF(B); + KV = 0; + if ((B & FLAG) == 0) + KV = (B >> 12) & 070; + else if ((B & PRESENT) == 0 && NCSF) + Q |= PRES_BIT; break; case CMOP_RCA: /* Recall Control Address */ AROF = BROF; - A = B; /* Save B temporarly */ + A = B; /* Save B temporarly */ atemp = S; /* Save S */ S = (F - field) & CORE; - memory_cycle(3); /* Load word in B */ + memory_cycle(3);/* Load word in B */ S = atemp; /* Restore S */ if (B & FLAG) { if ((B & PRESENT) == 0) { if (NCSF) Q |= PRES_BIT; - break; + } else { + C = CF(B); + L = 0; } - C = CF(B); - L = 0; } else { C = CF(B); L = LF(B) + 1; @@ -2318,9 +2302,10 @@ crf_loop: A = B; AROF = BROF; B = ((t_uint64)(KV & 070) << (FFIELD_V - 3)) | toC(S); + atemp = S; S = (F - field) & CORE; memory_cycle(013); /* Store B in S */ - S = CF(B); + S = atemp; B = A; BROF = AROF; AROF = 0; @@ -2331,9 +2316,10 @@ crf_loop: A = B; AROF = BROF; B = ((t_uint64)(GH & 070) << (FFIELD_V - 3)) | toC(Ma); + atemp = Ma; Ma = (F - field) & CORE; memory_cycle(015); /* Store B in Ma */ - Ma = CF(B); + Ma = atemp; B = A; BROF = AROF; AROF = 0; @@ -3652,6 +3638,12 @@ control: do { Ma = CF(B); memory_cycle(5); + if (sim_interval <= 0) { /* event queue? */ + reason = sim_process_event(); + if (reason != SCPE_OK) { + break; /* process */ + } + } temp = (B & MANT) + (A & MANT); } while ((temp & EXPO) == 0); A = FLAG | PRESENT | toC(Ma); @@ -3672,17 +3664,12 @@ control: R = 0; F = S; /* Set F and X */ X = toF(S); - if (B & FLAG) { - if ((B & PRESENT) == 0) { - if (NCSF) - Q |= PRES_BIT; - break; - } - KV = 0; - } else { - KV = (uint8)((B >> (FFIELD_V - 3)) & 070); - } S = CF(B); + KV = 0; + if ((B & FLAG) == 0) + KV = (uint8)((B >> (FFIELD_V - 3)) & 070); + else if ((B & PRESENT) == 0 && NCSF) + Q |= PRES_BIT; break; case VARIANT(WMOP_MKS): /* Mark Stack */ @@ -3846,6 +3833,8 @@ cpu_reset(DEVICE * dptr) GH = KV = Q = 0; hltf[0] = 0; P1_run = 0; + IAR = 0; + HALT = 0; idle_addr = 0; sim_brk_types = sim_brk_dflt = SWMASK('E') | SWMASK('A') | SWMASK('B'); @@ -3958,7 +3947,7 @@ cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc) t_stat r; t_value sim_eval; struct InstHistory *h; - static const char flags[] = "ABCNSMV"; + CONST static char flags[] = "ABCNSMV"; if (hst_lnt == 0) return SCPE_NOFNC; /* enabled? */ @@ -4008,8 +3997,7 @@ cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc) fputc(' ', st); fprint_val(st, h->op, 8, 12, PV_RZRO); fputc(' ', st); - print_opcode(st, h->op, - ((h->flags & F_CWMF) ? char_ops : word_ops)); + print_opcode(st, h->op, ((h->flags & F_CWMF) != 0)); fputc(' ', st); fprint_val(st, h->iar, 8, 16, PV_RZRO); fputc('\n', st); /* end line */ diff --git a/B5500/b5500_defs.h b/B5500/b5500_defs.h index 7877be01..707b62af 100644 --- a/B5500/b5500_defs.h +++ b/B5500/b5500_defs.h @@ -72,8 +72,7 @@ typedef struct _opcode } t_opcode; -extern void print_opcode(FILE * ofile, t_value val, t_opcode *); -extern t_opcode word_ops[], char_ops[]; +void print_opcode(FILE * ofile, t_value val, int chr_mode); t_stat chan_reset(DEVICE *); t_stat chan_boot(t_uint64); diff --git a/B5500/b5500_dk.c b/B5500/b5500_dk.c index 1e0f67bf..ec9c48bf 100644 --- a/B5500/b5500_dk.c +++ b/B5500/b5500_dk.c @@ -280,7 +280,7 @@ t_stat dsk_srv(UNIT * uptr) chan_set_end(chan); } else uptr->u5 &= ~(DK_RDCK|DK_RD|DK_WR); - sim_activate(eptr, 500); + sim_activate(eptr, 8000); return SCPE_OK; } sim_activate(uptr, 100); @@ -432,7 +432,7 @@ t_stat esu_srv(UNIT * uptr) uptr->u5 -= DK_SECT; } } - sim_activate(uptr, (uptr->flags & MODIB) ? 200 :100); + sim_activate(uptr, (uptr->flags & MODIB) ? 500 :300); return SCPE_OK; } @@ -456,8 +456,14 @@ dsk_boot(int32 unit_num, DEVICE * dptr) t_uint64 desc; int i; - for(i = 0; i < 20; i++) + for(i = 0; i < 20; i++) { esu_unit[i].u5 = 0; + sim_cancel(&esu_unit[i]); + } + dsk_unit[0].u5 = 0; + dsk_unit[1].u5 = 0; + sim_cancel(&dsk_unit[0]); + sim_cancel(&dsk_unit[1]); desc = (((t_uint64)dev)<u5 & DTC_WR) { - if (line > dtc_desc.lines || line == -1) { + if (line > dtc_desc.lines || line == -1 || dtc_lstatus[line] & BufDisco) { sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm write invalid %d\n", line); chan_set_notrdy(chan); @@ -434,7 +435,7 @@ t_stat dtc_srv(UNIT * uptr) } if (uptr->u5 & DTC_RD) { - if (line > dtc_desc.lines || line == -1) { + if (line > dtc_desc.lines || line == -1 || dtc_lstatus[line] & BufDisco) { sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm read nothing %d\n", line); chan_set_notrdy(chan); @@ -489,7 +490,7 @@ t_stat dtc_srv(UNIT * uptr) if (dtc_lstatus[line] & BufAbnormal) chan_set_wcflg(chan); if (dtc_ldsc[line].conn == 0) /* connected? */ - dtc_lstatus[line] = BufIRQ|BufNotReady; + dtc_lstatus[line] = BufIRQ|BufAbnormal|BufIRQ|BufIdle; else dtc_lstatus[line] = BufIRQ|BufIdle; dtc_bsize[line] = 0; @@ -524,6 +525,7 @@ dtco_srv(UNIT * uptr) sim_clock_coschedule(uptr, tmxr_poll); ln = tmxr_poll_conn(&dtc_desc); /* look for connect */ if (ln >= 0) { /* got one? */ + dtc_ldsc[ln].rcve = 1; dtc_blimit[ln] = dtc_bufsize-1; dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufWriteRdy; IAR |= IRQ_12; @@ -532,32 +534,43 @@ dtco_srv(UNIT * uptr) /* For each line that is in idle state enable recieve */ for (ln = 0; ln < dtc_desc.lines; ln++) { - if (dtc_ldsc[ln].conn && - (dtc_lstatus[ln] & BufSMASK) == BufIdle) { + dtc_ldsc[ln].rcve = 0; + if (dtc_ldsc[ln].conn && + (dtc_lstatus[ln] & BufSMASK) < BufWrite) { dtc_ldsc[ln].rcve = 1; } } tmxr_poll_rx(&dtc_desc); /* poll for input */ for (ln = 0; ln < DTC_MLINES; ln++) { /* loop thru mux */ /* Check for disconnect */ - if (dtc_ldsc[ln].conn == 0) { /* connected? */ + if (dtc_ldsc[ln].conn == 0 && (dtc_lstatus[ln] & BufDisco) == 0) { /* connected? */ + dtc_ldsc[ln].rcve = 0; switch(dtc_lstatus[ln] & BufSMASK) { - case BufIdle: /* Idle, throw in EOT */ - /* Fall through */ + case BufIdle: /* Idle Flag as disconnected */ + dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufIdle|BufDisco; + dtc_bsize[ln] = 0; + IAR |= IRQ_12; + sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d idle\n", ln); + break; + case BufWriteRdy: /* Awaiting output, terminate */ dtc_bufptr[ln] = 0; /* Fall through */ case BufInputBusy: /* reading, terminate with EOT */ dtc_buf[ln][dtc_bufptr[ln]++] = 017; - dtc_bsize[ln] = dtc_bufptr[ln]; + dtc_bsize[ln] = dtc_bufptr[ln]+1; dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufReadRdy; IAR |= IRQ_12; + sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d write\n", ln); break; + case BufOutBusy: /* Terminate Output */ - dtc_lstatus[ln] = BufIRQ|BufIdle; + dtc_lstatus[ln] = BufIRQ|BufIdle|BufAbnormal; dtc_bsize[ln] = 0; IAR |= IRQ_12; + sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d out\n", ln); break; + default: /* Other cases, ignore until in better state */ break; @@ -568,23 +581,29 @@ dtco_srv(UNIT * uptr) switch(dtc_lstatus[ln] & BufSMASK) { case BufIdle: /* If we have any data to receive */ - if (tmxr_rqln(&dtc_ldsc[ln]) > 0) - dtc_lstatus[ln] = BufInputBusy; - else + if (tmxr_rqln(&dtc_ldsc[ln]) > 0) { + dtc_lstatus[ln] &= ~(BufSMASK); + dtc_lstatus[ln] |= BufInputBusy; + } else break; /* Nothing to do */ sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm recieve %d idle\n", ln); dtc_bufptr[ln] = 0; dtc_bsize[ln] = 0; - case BufInputBusy: - t = 1; - while (t && tmxr_rqln(&dtc_ldsc[ln]) != 0) { - c = tmxr_getc_ln(&dtc_ldsc[ln]) & 0x7f; /* get char */ + /* Fall through */ + + case BufInputBusy: + t = 1; + while (t) { + c = tmxr_getc_ln(&dtc_ldsc[ln]); /* get char */ + if (c == 0) + break; + c &= 0x7f; c1 = ascii_to_con[c]; switch(c) { case '\005': /* ^E ENQ who-are-you */ dtc_lstatus[ln] &= ~(BufSMASK); - dtc_lstatus[ln] |= BufIRQ|BufAbnormal|BufWriteRdy; + dtc_lstatus[ln] |= BufIRQ|BufWriteRdy|BufAbnormal; IAR |= IRQ_12; sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm recieve ENQ %d\n", ln); @@ -786,15 +805,14 @@ t_stat dtc_setnl (UNIT *uptr, int32 val, CONST char *cptr, void *desc) newln = (int32) get_uint (cptr, 10, DTC_MLINES, &r); if ((r != SCPE_OK) || (newln == dtc_desc.lines)) return r; - if ((newln == 0) || (newln >= DTC_MLINES)) + if ((newln == 0) || (newln > DTC_MLINES)) return SCPE_ARG; - newln--; if (newln < dtc_desc.lines) { - for (i = newln, t = 0; i < dtc_desc.lines; i++) + for (i = newln-1, t = 0; i < dtc_desc.lines; i++) t = t | dtc_ldsc[i].conn; if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE)) return SCPE_OK; - for (i = newln; i < dtc_desc.lines; i++) { + for (i = newln-1; i < dtc_desc.lines; i++) { if (dtc_ldsc[i].conn) { tmxr_linemsg (&dtc_ldsc[i], "\r\nOperator disconnected line\r\n"); tmxr_send_buffered_data (&dtc_ldsc[i]); diff --git a/B5500/b5500_mt.c b/B5500/b5500_mt.c index e6e98865..55471c77 100644 --- a/B5500/b5500_mt.c +++ b/B5500/b5500_mt.c @@ -570,7 +570,7 @@ mt_attach(UNIT * uptr, CONST char *file) { t_stat r; - if ((r = sim_tape_attach(uptr, file)) != SCPE_OK) + if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK) return r; uptr->u5 |= MT_LOADED|MT_BOT; sim_activate(uptr, 50000); diff --git a/B5500/b5500_sys.c b/B5500/b5500_sys.c index 28dfc65e..3eda2654 100644 --- a/B5500/b5500_sys.c +++ b/B5500/b5500_sys.c @@ -136,7 +136,7 @@ const char ascii_to_con[128] = { /* Control */ -1, -1, -1, -1, -1, -1, -1, -1, /*sp ! " # $ % & ' */ - 020, 032, 037, 013, 053, 017, 060, 014, /* 40 - 77 */ + 020, 032, 037, 013, 053, 034, 060, 014, /* 40 - 77 */ /* ( ) * + , - . / */ 075, 055, 054, 072, 033, 040, 073, 021, /* 0 1 2 3 4 5 6 7 */ @@ -150,7 +150,7 @@ const char ascii_to_con[128] = { /* P Q R S T U V W */ 047, 050, 051, 022, 023, 024, 025, 026, /* X Y Z [ \ ] ^ _ */ - 027, 030, 031, 075, 036, 055, 057, 000, + 027, 030, 031, 074, 036, 036, 057, 000, /* ` a b c d e f g */ 035, 061, 062, 063, 064, 065, 066, 067, /* 140 - 177 */ /* h i j k l m n o */ @@ -158,7 +158,7 @@ const char ascii_to_con[128] = { /* p q r s t u v w */ 047, 050, 051, 022, 023, 024, 025, 026, /* x y z { | } ~ del*/ - 027, 030, 031, 057, 077, 017, -1, -1 + 027, 030, 031, 057, 052, 017, -1, -1 }; @@ -341,9 +341,10 @@ t_opcode char_ops[] = { /* Print out an instruction */ void -print_opcode(FILE * of, t_value val, t_opcode * tab) +print_opcode(FILE * of, t_value val, int chr_mode) { uint16 op; + t_opcode *tab = (chr_mode) ? char_ops: word_ops; op = val; while (tab->name != NULL) { @@ -410,14 +411,14 @@ fprint_sym(FILE * of, t_addr addr, t_value * val, UNIT * uptr, int32 sw) fputs(" ", of); for (i = 36; i >= 0; i-=12) { int op = (int)(inst >> i) & 07777; - print_opcode(of, op, word_ops); + print_opcode(of, op, 0); } } if (sw & SWMASK('C')) { /* Char mode opcodes */ fputs(" ", of); for (i = 36; i >= 0; i-=12) { int op = (int)(inst >> i) & 07777; - print_opcode(of, op, char_ops); + print_opcode(of, op, 1); } } if (sw & SWMASK('B')) { /* BCD mode */ diff --git a/B5500/b5500_urec.c b/B5500/b5500_urec.c index 89da43fa..22bda957 100644 --- a/B5500/b5500_urec.c +++ b/B5500/b5500_urec.c @@ -35,10 +35,6 @@ #define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE | MODE_029 #define UNIT_LPR UNIT_ATTABLE | UNIT_DISABLE -/* For Card reader, when set returns end of file at end of deck. */ -/* Reset after sent to system */ -#define MODE_EOF (0x40 << UNIT_V_CARD_MODE) - #define TMR_RTC 0 @@ -84,6 +80,7 @@ DEBTAB cdr_debug[] = { #if NUM_DEVS_CDR > 0 t_stat cdr_boot(int32, DEVICE *); +t_stat cdr_ini(DEVICE *); t_stat cdr_srv(UNIT *); t_stat cdr_attach(UNIT *, CONST char *); t_stat cdr_detach(UNIT *); @@ -92,6 +89,7 @@ const char *cdr_description(DEVICE *dptr); #endif #if NUM_DEVS_CDP > 0 +t_stat cdp_ini(DEVICE *); t_stat cdp_srv(UNIT *); t_stat cdp_attach(UNIT *, CONST char *); t_stat cdp_detach(UNIT *); @@ -106,6 +104,7 @@ struct _lpr_data } lpr_data[NUM_DEVS_LPR]; +t_stat lpr_ini(DEVICE *); t_stat lpr_srv(UNIT *); t_stat lpr_attach(UNIT *, CONST char *); t_stat lpr_detach(UNIT *); @@ -146,16 +145,14 @@ MTAB cdr_mod[] = { {MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", &sim_card_set_fmt, &sim_card_show_fmt, NULL, "Sets card format"}, - {MODE_EOF, MODE_EOF, "EOF", "EOF", NULL, NULL, NULL, - "Causes EOF to be set when reader empty"}, {0} }; DEVICE cdr_dev = { "CR", cdr_unit, NULL, cdr_mod, NUM_DEVS_CDR, 8, 15, 1, 8, 8, - NULL, NULL, NULL, &cdr_boot, &cdr_attach, &cdr_detach, - NULL, DEV_DISABLE | DEV_DEBUG, 0, cdr_debug, + NULL, NULL, &cdr_ini, &cdr_boot, &cdr_attach, &cdr_detach, + NULL, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, cdr_debug, NULL, NULL, &cdr_help, NULL, NULL, &cdr_description }; @@ -176,8 +173,8 @@ MTAB cdp_mod[] = { 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, - NULL, DEV_DISABLE | DEV_DEBUG, 0, cdr_debug, + NULL, NULL, &cdp_ini, NULL, &cdp_attach, &cdp_detach, + NULL, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, cdr_debug, NULL, NULL, &cdp_help, NULL, NULL, &cdp_description }; @@ -202,7 +199,7 @@ MTAB lpr_mod[] = { DEVICE lpr_dev = { "LP", lpr_unit, NULL, lpr_mod, NUM_DEVS_LPR, 8, 15, 1, 8, 8, - NULL, NULL, NULL, NULL, &lpr_attach, &lpr_detach, + NULL, NULL, &lpr_ini, NULL, &lpr_attach, &lpr_detach, NULL, DEV_DISABLE | DEV_DEBUG, 0, dev_debug, NULL, NULL, &lpr_help, NULL, NULL, &lpr_description @@ -217,7 +214,7 @@ UNIT con_unit[] = { DEVICE con_dev = { "CON", con_unit, NULL, NULL, NUM_DEVS_CON, 8, 15, 1, 8, 8, - NULL, NULL, con_ini, NULL, NULL, NULL, + NULL, NULL, &con_ini, NULL, NULL, NULL, NULL, DEV_DISABLE | DEV_DEBUG, 0, dev_debug, NULL, NULL, &con_help, NULL, NULL, &con_description @@ -227,6 +224,17 @@ DEVICE con_dev = { #if ((NUM_DEVS_CDR > 0) | (NUM_DEVS_CDP > 0)) +t_stat +cdr_ini(DEVICE *dptr) { + int i; + + for(i = 0; i < NUM_DEVS_CDR; i++) { + cdr_unit[i].u5 = 0; + sim_cancel(&cdr_unit[i]); + } + return SCPE_OK; +} + /* * Device entry points for card reader. * And Card punch. @@ -255,15 +263,13 @@ t_stat card_cmd(uint16 cmd, uint16 dev, uint8 chan, uint16 *wc) /* Check if we ran out of cards */ if (uptr->u5 & URCSTA_EOF) { /* If end of file, return to system */ - if (uptr->flags & MODE_EOF) { - sim_debug(DEBUG_DETAIL, &cdr_dev, "cdr %d %d report eof\n", u, - chan); - chan_set_eof(chan); - uptr->flags &= ~MODE_EOF; + if (sim_card_input_hopper_count(uptr) != 0) + uptr->u5 &= ~URCSTA_EOF; + else { + /* Clear unit ready */ + iostatus &= ~(CARD1_FLAG << u); + return SCPE_UNATT; } - /* Clear unit ready */ - iostatus &= ~(CARD1_FLAG << u); - return SCPE_UNATT; } if (cmd & URCSTA_BINARY) { @@ -307,6 +313,7 @@ t_stat cdr_srv(UNIT *uptr) { int chan = URCSTA_CHMASK & uptr->u5; int u = (uptr - cdr_unit); + uint16 *image = (uint16 *)(uptr->up7); if (uptr->u5 & URCSTA_EOF) { sim_debug(DEBUG_DETAIL, &cdr_dev, "cdr %d %d unready\n", u, chan); @@ -319,32 +326,27 @@ cdr_srv(UNIT *uptr) { /* Check if new card requested. */ if (uptr->u4 == 0 && uptr->u5 & URCSTA_ACTIVE && (uptr->u5 & URCSTA_CARD) == 0) { - switch(sim_read_card(uptr)) { - case SCPE_UNATT: + switch(sim_read_card(uptr, image)) { + case CDSE_EMPTY: iostatus &= ~(CARD1_FLAG << u); uptr->u5 &= ~(URCSTA_ACTIVE); iostatus &= ~(CARD1_FLAG << u); chan_set_notrdy(chan); break; - case SCPE_EOF: + case CDSE_EOF: /* If end of file, return to system */ - if (uptr->flags & MODE_EOF) { - sim_debug(DEBUG_DETAIL, &cdr_dev, "cdr %d %d set eof\n", u, chan); - chan_set_eof(chan); - uptr->flags &= ~MODE_EOF; - } uptr->u5 &= ~(URCSTA_ACTIVE); uptr->u5 |= URCSTA_EOF; chan_set_notrdy(chan); sim_activate(uptr, 500); break; - case SCPE_IOERR: + case CDSE_ERROR: chan_set_error(chan); uptr->u5 &= ~(URCSTA_ACTIVE); uptr->u5 |= URCSTA_EOF; chan_set_end(chan); break; - case SCPE_OK: + case CDSE_OK: uptr->u5 |= URCSTA_CARD; sim_activate(uptr, 500); break; @@ -356,22 +358,18 @@ cdr_srv(UNIT *uptr) { /* Copy next column over */ if (uptr->u5 & URCSTA_CARD && uptr->u4 < ((uptr->u5 & URCSTA_BIN) ? 160 : 80)) { - struct _card_data *data; uint8 ch = 0; int u = (uptr - cdr_unit); - data = (struct _card_data *)uptr->up7; - if (uptr->u5 & URCSTA_BIN) { - ch = (data->image[uptr->u4 >> 1] >> - ((uptr->u4 & 1)? 0 : 6)) & 077; + ch = (image[uptr->u4 >> 1] >> ((uptr->u4 & 1)? 0 : 6)) & 077; } else { - ch = sim_hol_to_bcd(data->image[uptr->u4]); + ch = sim_hol_to_bcd(image[uptr->u4]); /* Remap some characters from 029 to BCL */ switch(ch) { case 0: ch = 020; break; /* Translate blanks */ case 10: /* Check if 0 punch of 82 punch */ - if (data->image[uptr->u4] != 0x200) { + if (image[uptr->u4] != 0x200) { ch = 0; if (uptr->u4 == 0) chan_set_parity(chan); @@ -439,6 +437,8 @@ cdr_attach(UNIT * uptr, CONST char *file) if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; + if (uptr->up7 == 0) + uptr->up7 = malloc(sizeof(uint16)*80); uptr->u5 &= URCSTA_BUSY; uptr->u4 = 0; uptr->u6 = 0; @@ -451,6 +451,9 @@ cdr_detach(UNIT * uptr) { int u = uptr-cdr_unit; + if (uptr->up7 != 0) + free(uptr->up7); + uptr->up7 = 0; iostatus &= ~(CARD1_FLAG << u); return sim_card_detach(uptr); } @@ -462,10 +465,6 @@ cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) fprintf (st, "The system supports up to two card readers, the second one is disabled\n"); fprintf (st, "by default. To have the card reader return the EOF flag when the deck\n"); fprintf (st, "has finished reading do:\n"); - fprintf (st, " sim> SET CRn EOF\n"); - fprintf (st, "This flag is cleared each time a deck has been read, so it must be set\n"); - fprintf (st, "again after each deck. MCP does not require this to be set as long as\n"); - fprintf (st, "the deck includes a ?END card\n"); fprint_set_help(st, dptr); fprint_show_help(st, dptr); return SCPE_OK; @@ -484,27 +483,39 @@ cdr_description(DEVICE *dptr) #if NUM_DEVS_CDR > 0 | NUM_DEVS_CDP > 0 /* Handle transfer of data for card punch */ +t_stat +cdp_ini(DEVICE *dptr) { + int i; + + for(i = 0; i < NUM_DEVS_CDP; i++) { + cdp_unit[i].u5 = 0; + sim_cancel(&cdp_unit[i]); + } + return SCPE_OK; +} + t_stat cdp_srv(UNIT *uptr) { int chan = URCSTA_CHMASK & uptr->u5; int u = (uptr - cdp_unit); + uint16 *image = (uint16 *)(uptr->up7); if (uptr->u5 & URCSTA_BUSY) { /* Done waiting, punch card */ if (uptr->u5 & URCSTA_FULL) { sim_debug(DEBUG_DETAIL, &cdp_dev, "cdp %d %d punch\n", u, chan); - switch(sim_punch_card(uptr, NULL)) { - case SCPE_EOF: - case SCPE_UNATT: + switch(sim_punch_card(uptr, image)) { + case CDSE_EOF: + case CDSE_EMPTY: sim_debug(DEBUG_DETAIL, &cdp_dev, "cdp %d %d set eof\n", u, chan); chan_set_eof(chan); break; /* If we get here, something is wrong */ - case SCPE_IOERR: + case CDSE_ERROR: chan_set_error(chan); break; - case SCPE_OK: + case CDSE_OK: break; } uptr->u5 &= ~URCSTA_FULL; @@ -515,18 +526,15 @@ cdp_srv(UNIT *uptr) { /* Copy next column over */ if (uptr->u5 & URCSTA_ACTIVE && uptr->u4 < 80) { - struct _card_data *data; uint8 ch = 0; - data = (struct _card_data *)uptr->up7; - if(chan_read_char(chan, &ch, 0)) { uptr->u5 |= URCSTA_BUSY|URCSTA_FULL; uptr->u5 &= ~URCSTA_ACTIVE; } else { sim_debug(DEBUG_DATA, &cdp_dev, "cdp %d: Char %d < %02o\n", u, uptr->u4, ch); - data->image[uptr->u4++] = sim_bcd_to_hol(ch & 077); + image[uptr->u4++] = sim_bcd_to_hol(ch & 077); } sim_activate(uptr, 10); } @@ -547,16 +555,24 @@ cdp_attach(UNIT * uptr, CONST char *file) if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; - uptr->u5 = 0; - iostatus |= PUNCH_FLAG; + if (uptr->up7 == 0) { + uptr->up7 = calloc(80, sizeof(uint16)); + uptr->u5 = 0; + iostatus |= PUNCH_FLAG; + } return SCPE_OK; } t_stat cdp_detach(UNIT * uptr) { + uint16 *image = (uint16 *)(uptr->up7); + if (uptr->u5 & URCSTA_FULL) - sim_punch_card(uptr, NULL); + sim_punch_card(uptr, image); + if (uptr->up7 != 0) + free(uptr->up7); + uptr->up7 = 0; iostatus &= ~PUNCH_FLAG; return sim_card_detach(uptr); } @@ -583,6 +599,16 @@ cdp_description(DEVICE *dptr) /* Line printer routines */ +t_stat +lpr_ini(DEVICE *dptr) { + int i; + + for(i = 0; i < NUM_DEVS_LPR; i++) { + lpr_unit[i].u5 = 0; + sim_cancel(&lpr_unit[i]); + } + return SCPE_OK; +} #if NUM_DEVS_LPR > 0 t_stat diff --git a/doc/b5500_doc.doc b/doc/b5500_doc.doc index fa1cd387..46818d72 100644 Binary files a/doc/b5500_doc.doc and b/doc/b5500_doc.doc differ