From 5d1c01fcc989b04c9278211381df22228973f792 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sun, 16 Aug 2020 10:16:17 -0400 Subject: [PATCH] SCP: Updated to current. --- scp.c | 16 +++++------- scp.h | 16 +++++++++--- sim_card.c | 24 +++++++++++++----- sim_console.c | 44 +++++++++++++++++++++++++++++--- sim_console.h | 5 +++- sim_disk.c | 69 ++++++++++++++++++++++++++++++++++++++------------- sim_ether.c | 10 ++++++-- sim_tape.c | 13 ++++++++-- 8 files changed, 152 insertions(+), 45 deletions(-) diff --git a/scp.c b/scp.c index 0fe2165..7c3b425 100644 --- a/scp.c +++ b/scp.c @@ -314,14 +314,6 @@ else if (sz == sizeof (uint16)) *(((uint16 *) mb) + ((uint32) j)) = (uint16) v; \ else *(((uint32 *) mb) + ((uint32) j)) = v; #endif -#define GET_SWITCHES(cp) \ - if ((cp = get_sim_sw (cp)) == NULL) return SCPE_INVSW -#define GET_RADIX(val,dft) \ - if (sim_switches & SWMASK ('O')) val = 8; \ - else if (sim_switches & SWMASK ('D')) val = 10; \ - else if (sim_switches & SWMASK ('H')) val = 16; \ - else if ((sim_switch_number >= 2) && (sim_switch_number <= 36)) val = sim_switch_number; \ - else val = dft; #define SIM_DBG_EVENT 0x02000000 /* event dispatch activities */ #define SIM_DBG_ACTIVATE 0x04000000 /* queue insertion activities */ @@ -15517,6 +15509,10 @@ int32 saved_switches = sim_switches & ~SWMASK ('T'); t_stat stat = SCPE_OK; char gbuf[CBUFSIZE]; +if (sim_time != 0.0) + return sim_messagef (SCPE_UNK, "Library tests can not be performed after instructions have been executed.\n"); +detach_all (0, 0); /* Assure that all units are unattached */ + cptr = get_glyph (cptr, gbuf, 0); if (gbuf[0] == '\0') strcpy (gbuf, "ALL"); @@ -15571,9 +15567,9 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { tstat = SCPE_OK; /* can't enable, just skip device */ if (tstat != SCPE_OK) { stat = tstat; - sim_printf ("%s device tests returned: %d - %s\n", dptr->name, tstat, sim_error_text (tstat)); + sim_printf ("%s device tests returned: %d - %s\n", dptr->name, SCPE_BARE_STATUS (tstat), sim_error_text (tstat)); if (sim_ttisatty()) { - if (get_yn ("Continue with additional tests? [N]", SCPE_STOP) == SCPE_STOP) + if (get_yn ("Continue with additional tests? [N] ", SCPE_STOP) == SCPE_STOP) break; } else diff --git a/scp.h b/scp.h index 7d795fd..d21f76f 100644 --- a/scp.h +++ b/scp.h @@ -365,6 +365,14 @@ extern UNIT *sim_dfunit; extern int32 sim_interval; extern int32 sim_switches; extern int32 sim_switch_number; +#define GET_SWITCHES(cp) \ + if ((cp = get_sim_sw (cp)) == NULL) return SCPE_INVSW +#define GET_RADIX(val,dft) \ + if (sim_switches & SWMASK ('O')) val = 8; \ + else if (sim_switches & SWMASK ('D')) val = 10; \ + else if (sim_switches & SWMASK ('H')) val = 16; \ + else if ((sim_switch_number >= 2) && (sim_switch_number <= 36)) val = sim_switch_number; \ + else val = dft; extern int32 sim_show_message; extern int32 sim_quiet; extern int32 sim_step; @@ -448,13 +456,13 @@ extern const char *sim_vm_step_unit; /* Simulator can change These defines help implement consistent unit test functionality */ #define SIM_TEST_INIT \ - int test_stat; \ - const char *sim_test; \ + volatile int test_stat; \ + const char *volatile sim_test; \ jmp_buf sim_test_env; \ if ((test_stat = setjmp (sim_test_env))) { \ sim_printf ("Error: %d - '%s' processing: %s\n", \ - test_stat, sim_error_text(test_stat), \ - sim_test); \ + SCPE_BARE_STATUS(test_stat), \ + sim_error_text(test_stat), sim_test); \ return test_stat; \ } #define SIM_TEST(_stat) \ diff --git a/sim_card.c b/sim_card.c index fcb2af2..9dfd1c2 100644 --- a/sim_card.c +++ b/sim_card.c @@ -1353,27 +1353,39 @@ sim_card_detach(UNIT * uptr) t_stat sim_card_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) { - fprintf (st, "%s Card %sAttach Help\n\n", dptr->name, (uptr->flags & UNIT_RO) ? "Reader " : "Punch "); + uint32 i, readers = 0, punches = 0; + + for (i=0; i < dptr->numunits; ++i) + if (dptr->units[i].flags & UNIT_ATTABLE) { + readers += ((dptr->units[i].flags & UNIT_RO) != 0); + punches += ((dptr->units[i].flags & UNIT_RO) == 0); + } + if (uptr == NULL) + uptr = dptr->units; + fprintf (st, "%s Card %s%s%sAttach Help\n\n", dptr->name, + readers ? "Reader " : "", readers & punches ? "& " : "", punches ? "Punch ": ""); if (0 == (uptr-dptr->units)) { if (dptr->numunits > 1) { uint32 i; for (i=0; i < dptr->numunits; ++i) if (dptr->units[i].flags & UNIT_ATTABLE) - fprintf (st, " sim> ATTACH {switches} %s%d carddeck\n\n", dptr->name, i); + fprintf (st, " sim> ATTACH {switches} %s carddeck\n", sim_uname (&dptr->units[i])); + fprintf (st, "\n"); } else - fprintf (st, " sim> ATTACH {switches} %s carddeck\n\n", dptr->name); + fprintf (st, " sim> ATTACH {switches} %s carddeck\n\n", sim_uname (uptr)); } else - fprintf (st, " sim> ATTACH {switches} %s carddeck\n\n", dptr->name); + fprintf (st, " sim> ATTACH {switches} %s carddeck\n\n", sim_uname (uptr)); fprintf (st, "Attach command switches\n"); fprintf (st, " -F Open the indicated card deck in a specific format (default\n"); fprintf (st, " is AUTO, alternatives are BIN, TEXT, BCD and CBN)\n"); - if ((uptr->flags & UNIT_RO) == 0) { + if (punches != 0) { fprintf (st, " -N Create a new punch output file (default is to append to\n"); fprintf (st, " an existing file if it exists)\n"); - } else { + } + if (readers != 0) { fprintf (st, " -E Return EOF after deck read\n"); fprintf (st, " -S Append deck to cards currently waiting to be read\n"); } diff --git a/sim_console.c b/sim_console.c index 8e256a8..069eac0 100644 --- a/sim_console.c +++ b/sim_console.c @@ -2950,14 +2950,14 @@ uint32 md = mode & TTUF_M_MODE; if (md != TTUF_MODE_8B) { uint32 par_mode = (mode >> TTUF_W_MODE) & TTUF_M_PAR; - static int32 nibble_even_parity = 0x699600; /* bit array indicating the even parity for each index (offset by 8) */ + static int32 nibble_even_parity = 0x699600; /* bit array indicating the even parity for each index (offset by 8) */ c = c & 0177; if (md == TTUF_MODE_UC) { if (islower (c)) c = toupper (c); if (mode & TTUF_KSR) - c = c | 0200; + c = c | 0200; /* Force MARK parity */ } switch (par_mode) { case TTUF_PAR_EVEN: @@ -2971,7 +2971,8 @@ if (md != TTUF_MODE_8B) { break; } } -else c = c & 0377; +else + c = c & 0377; return c; } @@ -3051,6 +3052,43 @@ fprintf (st, (any? "\n": "no tabs set\n")); return SCPE_OK; } +t_stat sim_tt_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ +uint32 par_mode = (TT_GET_MODE (uptr->flags) >> TTUF_W_MODE) & TTUF_M_PAR; + +uptr->flags = uptr->flags & ~((TTUF_M_MODE << TTUF_V_MODE) | (TTUF_M_PAR << TTUF_V_PAR) | TTUF_KSR); +uptr->flags |= val; +if (val != TT_MODE_8B) + uptr->flags |= (par_mode << TTUF_V_PAR); +return SCPE_OK; +} + +t_stat sim_tt_set_parity (UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ +uptr->flags = uptr->flags & ~(TTUF_M_MODE | TTUF_M_PAR); +uptr->flags |= TT_MODE_7B | val; +return SCPE_OK; +} + +t_stat sim_tt_show_modepar (FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ +uint32 md = (TT_GET_MODE (uptr->flags) & TTUF_M_MODE); +static const char *modes[] = {"7b", "8b", "UC", "7p"}; +uint32 par_mode = (TT_GET_MODE (uptr->flags) >> TTUF_W_MODE) & TTUF_M_PAR; +static const char *parity[] = {"SPACE", "MARK", "EVEN", "ODD"}; + +if ((md == TTUF_MODE_UC) && (par_mode == TTUF_PAR_MARK)) + fprintf (st, "KSR (UC, MARK parity)"); +else + fprintf (st, "%s", modes[md]); +if ((md != TTUF_MODE_8B) && + ((md != TTUF_MODE_UC) || (par_mode != TTUF_PAR_MARK))) { + if (par_mode != 0) + fprintf (st, ", %s parity", parity[par_mode]); + } +return SCPE_OK; +} + #if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX) extern pthread_mutex_t sim_tmxr_poll_lock; diff --git a/sim_console.h b/sim_console.h index ae0ab86..aa0c594 100644 --- a/sim_console.h +++ b/sim_console.h @@ -60,7 +60,7 @@ extern "C" { #define TT_MODE_8B (TTUF_MODE_8B << TTUF_V_MODE) #define TT_MODE_UC (TTUF_MODE_UC << TTUF_V_MODE) #define TT_MODE_7P (TTUF_MODE_7P << TTUF_V_MODE) -#define TT_MODE_KSR (TT_MODE_UC) +#define TT_MODE_KSR (TT_MODE_UC|TT_PAR_MARK) /* 7 bit modes allow for an 8th bit parity mode */ #define TT_PAR (TTUF_M_PAR << TTUF_V_PAR) #define TT_PAR_SPACE (TTUF_PAR_SPACE << TTUF_V_PAR) @@ -124,6 +124,9 @@ t_stat sim_ttclose (void); t_bool sim_ttisatty (void); int32 sim_tt_inpcvt (int32 c, uint32 mode); int32 sim_tt_outcvt (int32 c, uint32 mode); +t_stat sim_tt_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat sim_tt_set_parity (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat sim_tt_show_modepar (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat sim_tt_settabs (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat sim_tt_showtabs (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_bool sim_is_remote_console_master_line (void *lp); diff --git a/sim_disk.c b/sim_disk.c index b05b103..8f54ba7 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -5891,22 +5891,38 @@ return WriteVirtualDiskSectors(hVHD, buf, sects, sectswritten, ctx->sector_size, * may have been recorded at the end of a disk container file */ -t_stat sim_disk_info_cmd (int32 flag, CONST char *cptr) +typedef struct { + t_stat stat; + int32 flag; + } DISK_INFO_CTX; + +static void sim_disk_info_entry (const char *directory, + const char *filename, + t_offset FileSize, + const struct stat *filestat, + void *context) { +DISK_INFO_CTX *info = (DISK_INFO_CTX *)context; +char FullPath[PATH_MAX + 1]; struct simh_disk_footer footer; struct simh_disk_footer *f = &footer; FILE *container; t_offset container_size; -if (flag) { /* zap type */ - container = sim_vhd_disk_open (cptr, "r"); +sprintf (FullPath, "%s%s", directory, filename); + +if (info->flag) { /* zap type */ + container = sim_vhd_disk_open (FullPath, "r"); if (container != NULL) { sim_vhd_disk_close (container); - return sim_messagef (SCPE_OPENERR, "Can't change the disk type of a VHD container file\n"); + info->stat = sim_messagef (SCPE_OPENERR, "Can't change the disk type of a VHD container file\n"); + return; + } + container = sim_fopen (FullPath, "r+"); + if (container == NULL) { + info->stat = sim_messagef (SCPE_OPENERR, "Can't open container file '%s' - %s\n", FullPath, strerror (errno)); + return; } - container = sim_fopen (cptr, "r+"); - if (container == NULL) - return sim_messagef (SCPE_OPENERR, "Can't open container file '%s' - %s\n", cptr, strerror (errno)); container_size = sim_fsize_ex (container); if ((container_size != (t_offset)-1) && (container_size > sizeof (*f)) && (sim_fseeko (container, container_size - sizeof (*f), SEEK_SET) == 0) && @@ -5915,13 +5931,15 @@ if (flag) { /* zap type */ (f->Checksum == NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum))))) { (void)sim_set_fsize (container, (t_addr)(container_size - sizeof (*f))); fclose (container); - return sim_messagef (SCPE_OK, "Disk Type Removed from container '%s'\n", cptr); + info->stat = sim_messagef (SCPE_OK, "Disk Type Removed from container '%s'\n", FullPath); + return; } } fclose (container); - return sim_messagef (SCPE_ARG, "No footer found on disk container '%s'.\n", cptr); + info->stat = sim_messagef (SCPE_ARG, "No footer found on disk container '%s'.\n", FullPath); + return; } -if (flag == 0) { +if (info->flag == 0) { UNIT unit, *uptr = &unit; struct disk_context disk_ctx; struct disk_context *ctx = &disk_ctx; @@ -5936,10 +5954,10 @@ if (flag == 0) { uptr->flags |= UNIT_ATTABLE; uptr->disk_ctx = &disk_ctx; sim_disk_set_fmt (uptr, 0, "VHD", NULL); - container = sim_vhd_disk_open (cptr, "r"); + container = sim_vhd_disk_open (FullPath, "r"); if (container == NULL) { sim_disk_set_fmt (uptr, 0, "SIMH", NULL); - container = sim_fopen (cptr, "r+"); + container = sim_fopen (FullPath, "r+"); close_function = fclose; size_function = sim_fsize_ex; } @@ -5949,7 +5967,7 @@ if (flag == 0) { } if (container) { container_size = size_function (container); - uptr->filename = strdup (cptr); + uptr->filename = strdup (FullPath); uptr->fileref = container; uptr->flags |= UNIT_ATT; get_disk_footer (uptr); @@ -5975,14 +5993,31 @@ if (flag == 0) { free (f); free (uptr->filename); close_function (container); - return SCPE_OK; + info->stat = SCPE_OK; + return; + } + else { + info->stat = sim_messagef (SCPE_OPENERR, "Can't open container file '%s' - %s\n", FullPath, strerror (errno)); + return; } - else - return sim_messagef (SCPE_OPENERR, "Can't open container file '%s' - %s\n", cptr, strerror (errno)); } -return SCPE_NOFNC; } +t_stat sim_disk_info_cmd (int32 flag, CONST char *cptr) +{ +DISK_INFO_CTX disk_info_state; +t_stat stat; + +if ((!cptr) || (*cptr == 0)) + return SCPE_2FARG; +GET_SWITCHES (cptr); /* get switches */ +memset (&disk_info_state, 0, sizeof (disk_info_state)); +disk_info_state.flag = flag; +stat = sim_dir_scan (cptr, sim_disk_info_entry, &disk_info_state); +if (stat == SCPE_OK) + return disk_info_state.stat; +return sim_messagef (SCPE_OK, "No such file or directory: %s\n", cptr); +} /* disk testing */ diff --git a/sim_ether.c b/sim_ether.c index 5bdbb10..bad6951 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -1687,7 +1687,7 @@ if (f) { read_size = fread (buf, 1, buf_size - 1, f); buf[read_size] = '\0'; - fclose (f); + pclose (f); } while ((strlen (buf) > 0) && sim_isspace(buf[strlen (buf) - 1])) buf[strlen (buf) - 1] = '\0'; @@ -3440,7 +3440,7 @@ response.msg[15] = (offset >> 8) & 0xFF; /* send response packet */ eth_write(dev, &response, NULL); -eth_packet_trace(dev, response.msg, response.len, ((function == 1) ? "loopbackreply" : "loopbackforward")); +eth_packet_trace(dev, response.msg, response.len, "loopbackforward"); ++dev->loopback_packets_processed; @@ -3887,6 +3887,9 @@ if (dev->dptr->dctrl & dev->dbit) { sim_debug(dev->dbit, dev->dptr, "Promiscuous\n"); } } +#ifdef USE_READER_THREAD + pthread_mutex_lock (&dev->self_lock); +#endif /* Set the desired physical address */ memset(dev->physical_addr, 0, sizeof(ETH_MAC)); dev->loopback_self_sent = 0; @@ -3900,6 +3903,9 @@ for (i = 0; i < addr_count; i++) { break; } } +#ifdef USE_READER_THREAD + pthread_mutex_unlock (&dev->self_lock); +#endif /* setup BPF filters and other fields to minimize packet delivery */ eth_bpf_filter (dev, dev->addr_count, dev->filter_address, diff --git a/sim_tape.c b/sim_tape.c index ea2af08..8170f1e 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -3830,7 +3830,7 @@ t_awslnt awsrec_typ = AWS_REC; char name[256]; t_stat stat = SCPE_OPENERR; uint8 *buf = NULL; -t_stat aws_stat; +t_stat aws_stat = MTSE_UNATT; int32 saved_switches = sim_switches; srand (0); /* All devices use the same random sequence for file data */ @@ -3894,6 +3894,10 @@ sim_switches = SWMASK ('F') | (sim_switches & SWMASK ('D')) | SWMASK ('N'); if (sim_switches & SWMASK ('D')) uptr->dctrl = MTSE_DBG_STR | MTSE_DBG_DAT; aws_stat = sim_tape_attach_ex (uptr, name, (saved_switches & SWMASK ('D')) ? MTSE_DBG_STR | MTSE_DBG_DAT: 0, 0); +if (aws_stat != MTSE_OK) { + stat = aws_stat; + goto Done_Files; + } sim_switches = saved_switches; stat = SCPE_OK; for (i=0; iunits->flags & UNIT_ATT) + return sim_messagef (SCPE_ALATT, "The %s device must be detached to run the tests\n", + sim_uname(dptr->units)); + sim_printf ("\nTesting %s device sim_tape APIs\n", sim_uname(dptr->units)); SIM_TEST(sim_tape_test_density_string ());