mirror of
https://github.com/rcornwell/sims.git
synced 2026-04-12 15:07:12 +00:00
SCP: Updated to current.
This commit is contained in:
19
scp.c
19
scp.c
@@ -4095,7 +4095,7 @@ return ap;
|
||||
|
||||
Token "%0" represents the command file name.
|
||||
|
||||
The input sequence "\%" represents a literal "%", and "\\" represents a
|
||||
The input sequence "%%" represents a literal "%", and "\\" represents a
|
||||
literal "\". All other character combinations are rendered literally.
|
||||
|
||||
Omitted parameters result in null-string substitutions.
|
||||
@@ -4202,11 +4202,16 @@ for (; *ip && (op < oend); ) {
|
||||
++ip;
|
||||
}
|
||||
else {
|
||||
get_glyph_nc (ip, gbuf, '%'); /* get the literal name */
|
||||
ap = _sim_get_env_special (gbuf, rbuf, sizeof (rbuf));
|
||||
ip += strlen (gbuf);
|
||||
if (*ip == '%')
|
||||
++ip;
|
||||
if (*ip == '\0') { /* is this a bare % at end of line? */
|
||||
*op++ = '%'; /* leave it there as a literal percent sign */
|
||||
}
|
||||
else {
|
||||
get_glyph_nc (ip, gbuf, '%'); /* get the literal name */
|
||||
ap = _sim_get_env_special (gbuf, rbuf, sizeof (rbuf));
|
||||
ip += strlen (gbuf);
|
||||
if (*ip == '%')
|
||||
++ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ap) { /* non-null arg? */
|
||||
@@ -7281,6 +7286,7 @@ for (i = 0; i < (device_count + sim_internal_device_count); i++) {/* loop thru d
|
||||
WRITE_I (uptr->wait);
|
||||
WRITE_I (uptr->buf);
|
||||
WRITE_I (uptr->recsize);
|
||||
WRITE_I (uptr->tape_eom);
|
||||
WRITE_I (uptr->capac); /* [V3.5] capacity */
|
||||
fprintf (sfile, "%.0f\n", uptr->usecs_remaining);/* [V4.0] remaining wait */
|
||||
WRITE_I (uptr->pos);
|
||||
@@ -7532,6 +7538,7 @@ for ( ;; ) { /* device loop */
|
||||
READ_I (uptr->wait);
|
||||
READ_I (uptr->buf);
|
||||
READ_I (uptr->recsize);
|
||||
READ_I (uptr->tape_eom);
|
||||
}
|
||||
old_capac = uptr->capac; /* save current capacity */
|
||||
if (v35) { /* [V3.5+] capacity */
|
||||
|
||||
@@ -45,6 +45,7 @@ struct ROM_File_Descriptor {
|
||||
{"VAX/ka610.bin", "VAX/vax_ka610_bin.h", 16384, 0xFFEF3312, "vax_ka610_bin"},
|
||||
{"VAX/ka750_new.bin", "VAX/vax_ka750_bin_new.h", 1024, 0xFFFE7BE5, "vax_ka750_bin_new", "From ROM set: E40A9, E41A9, E42A9, E43A9 (Boots: A=DD, B=DB, C=DU"},
|
||||
{"VAX/ka750_old.bin", "VAX/vax_ka750_bin_old.h", 1024, 0xFFFEBAA5, "vax_ka750_bin_old", "From ROM set: 990A9, 948A9, 906A9, 905A9 (Boots: A=DD, B=DM, C=DL, D=DU"},
|
||||
{"VAX/vcb02.bin", "VAX/vax_vcb02_bin.h", 16384, 0xFFF1D2AD, "vax_vcb02_bin"},
|
||||
{"VAX/vmb.exe", "VAX/vax_vmb_exe.h", 44544, 0xFFC014BB, "vax_vmb_exe"},
|
||||
{"PDP11/lunar11/lunar.lda", "PDP11/pdp11_vt_lunar_rom.h", 13824 , 0xFFF15D00, "lunar_lda"},
|
||||
{"PDP11/dazzledart/dazzle.lda", "PDP11/pdp11_dazzle_dart_rom.h", 6096, 0xFFF83848, "dazzle_lda"},
|
||||
|
||||
@@ -591,7 +591,8 @@ struct UNIT {
|
||||
uint16 us9; /* device specific */
|
||||
uint16 us10; /* device specific */
|
||||
void *tmxr; /* TMXR linkage */
|
||||
uint32 recsize; /* Tape info */
|
||||
uint32 recsize; /* Tape specific info */
|
||||
t_addr tape_eom; /* Tape specific info */
|
||||
t_bool (*cancel)(UNIT *);
|
||||
double usecs_remaining; /* time balance for long delays */
|
||||
char *uname; /* Unit name */
|
||||
|
||||
152
sim_ether.c
152
sim_ether.c
@@ -1202,7 +1202,7 @@ int load_pcap(void) {
|
||||
|
||||
/* define functions with dynamic revectoring */
|
||||
void pcap_close(pcap_t* a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
p_pcap_close(a);
|
||||
}
|
||||
}
|
||||
@@ -1213,7 +1213,7 @@ int pcap_compile(pcap_t* a, struct bpf_program* b, char* c, int d, bpf_u_int32 e
|
||||
#else
|
||||
int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_int32 e) {
|
||||
#endif
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_compile(a, b, c, d, e);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -1221,7 +1221,7 @@ int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_i
|
||||
}
|
||||
|
||||
int pcap_datalink(pcap_t* a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_datalink(a);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -1229,7 +1229,7 @@ int pcap_datalink(pcap_t* a) {
|
||||
}
|
||||
|
||||
int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_dispatch(a, b, c, d);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -1237,7 +1237,7 @@ int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) {
|
||||
}
|
||||
|
||||
int pcap_findalldevs(pcap_if_t** a, char* b) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_findalldevs(a, b);
|
||||
} else {
|
||||
*a = 0;
|
||||
@@ -1247,22 +1247,22 @@ int pcap_findalldevs(pcap_if_t** a, char* b) {
|
||||
}
|
||||
|
||||
void pcap_freealldevs(pcap_if_t* a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
p_pcap_freealldevs(a);
|
||||
}
|
||||
}
|
||||
|
||||
void pcap_freecode(struct bpf_program* a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
p_pcap_freecode(a);
|
||||
}
|
||||
}
|
||||
|
||||
char* pcap_geterr(pcap_t* a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_geterr(a);
|
||||
} else {
|
||||
return (char*) 0;
|
||||
return (char*) "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1284,15 +1284,15 @@ pcap_t* pcap_open_live(const char* a, int b, int c, int d, char* e) {
|
||||
|
||||
#ifdef _WIN32
|
||||
int pcap_setmintocopy(pcap_t* a, int b) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_setmintocopy(a, b);
|
||||
} else {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE pcap_getevent(pcap_t* a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_getevent(a);
|
||||
} else {
|
||||
return (HANDLE) 0;
|
||||
@@ -1302,7 +1302,7 @@ HANDLE pcap_getevent(pcap_t* a) {
|
||||
#else
|
||||
#ifdef MUST_DO_SELECT
|
||||
int pcap_get_selectable_fd(pcap_t* a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_get_selectable_fd(a);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -1311,7 +1311,7 @@ int pcap_get_selectable_fd(pcap_t* a) {
|
||||
#endif
|
||||
|
||||
int pcap_fileno(pcap_t * a) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_fileno(a);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -1320,7 +1320,7 @@ int pcap_fileno(pcap_t * a) {
|
||||
#endif
|
||||
|
||||
int pcap_sendpacket(pcap_t* a, const u_char* b, int c) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_sendpacket(a, b, c);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -1328,7 +1328,7 @@ int pcap_sendpacket(pcap_t* a, const u_char* b, int c) {
|
||||
}
|
||||
|
||||
int pcap_setfilter(pcap_t* a, struct bpf_program* b) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_setfilter(a, b);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -1336,7 +1336,7 @@ int pcap_setfilter(pcap_t* a, struct bpf_program* b) {
|
||||
}
|
||||
|
||||
int pcap_setnonblock(pcap_t* a, int nonblock, char *errbuf) {
|
||||
if (load_pcap() != 0) {
|
||||
if (a && (load_pcap() != 0)) {
|
||||
return p_pcap_setnonblock(a, nonblock, errbuf);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -2182,7 +2182,13 @@ else { /* !tap: */
|
||||
}
|
||||
#endif /* xBSD */
|
||||
#if defined(_WIN32)
|
||||
pcap_setmintocopy ((pcap_t*)(*handle), 0);
|
||||
if ((pcap_setmintocopy ((pcap_t*)(*handle), 0) == -1) ||
|
||||
(pcap_getevent ((pcap_t*)(*handle)) == NULL)) {
|
||||
pcap_close ((pcap_t*)(*handle));
|
||||
errbuf[PCAP_ERRBUF_SIZE-1] = '\0';
|
||||
snprintf (errbuf, PCAP_ERRBUF_SIZE-1, "pcap can't initialize API for interface: %s", savname);
|
||||
return SCPE_OPENERR;
|
||||
}
|
||||
#endif
|
||||
#if !defined (USE_READER_THREAD)
|
||||
#ifdef USE_SETNONBLOCK
|
||||
@@ -4170,6 +4176,10 @@ int errors = 0;
|
||||
t_stat r;
|
||||
DEVICE eth_tst;
|
||||
ETH_DEV dev;
|
||||
int eth_num;
|
||||
int eth_opened;
|
||||
ETH_LIST eth_list[ETH_MAX_DEVICE];
|
||||
int eth_device_count;
|
||||
int reflections, all_multicast, promiscuous;
|
||||
char buf[116+66*ETH_FILTER_MAX];
|
||||
char mac[20];
|
||||
@@ -4215,59 +4225,83 @@ int bpf_compile_skip_count = 0;
|
||||
|
||||
|
||||
memset (ð_tst, 0, sizeof(eth_tst));
|
||||
eth_open(&dev, "eth0", ð_tst, 1);
|
||||
for (reflections=0; reflections<=1; reflections++) {
|
||||
for (all_multicast=0; all_multicast<=1; all_multicast++) {
|
||||
for (promiscuous=0; promiscuous<=1; promiscuous++) {
|
||||
for (addr_count=1; addr_count<=2; addr_count++) {
|
||||
for (hash_listindex=0; hash_listindex<=1; hash_listindex++) {
|
||||
for (host_phy_addr_listindex=0; host_phy_addr_listindex<=1; host_phy_addr_listindex++) {
|
||||
int i;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
eth_device_count = eth_devices(ETH_MAX_DEVICE, eth_list);
|
||||
eth_opened = 0;
|
||||
for (eth_num=0; eth_num<eth_device_count; eth_num++) {
|
||||
char eth_name[32];
|
||||
|
||||
++bpf_count;
|
||||
r = eth_bpf_filter (&dev, addr_count, &filter_address[0],
|
||||
all_multicast, promiscuous, reflections,
|
||||
&filter_address[0],
|
||||
host_phy_addr_list[host_phy_addr_listindex],
|
||||
hash_list[hash_listindex],
|
||||
buf);
|
||||
if (r != SCPE_OK) {
|
||||
++bpf_construct_error_count;
|
||||
sim_printf ("Eth: Error producing a BPF filter for:\n");
|
||||
SIM_PRINT_BPF_ARGUMENTS;
|
||||
}
|
||||
else {
|
||||
if (sim_switches & SWMASK('D')) {
|
||||
if ((0 == memcmp (eth_list[eth_num].name, "nat:", 4)) ||
|
||||
(0 == memcmp (eth_list[eth_num].name, "tap:", 4)) ||
|
||||
(0 == memcmp (eth_list[eth_num].name, "vde:", 4)) ||
|
||||
(0 == memcmp (eth_list[eth_num].name, "udp:", 4)))
|
||||
continue;
|
||||
eth_name[sizeof (eth_name)-1] = '\0';
|
||||
snprintf (eth_name, sizeof (eth_name)-1, "eth%d", eth_num);
|
||||
r = eth_open(&dev, eth_name, ð_tst, 1);
|
||||
if (r != SCPE_OK) {
|
||||
sim_printf ("%s: Eth: Error opening eth%d: %s\n", dptr->name, eth_num, sim_error_text (r));
|
||||
continue;
|
||||
}
|
||||
++eth_opened;
|
||||
for (reflections=0; reflections<=1; reflections++) {
|
||||
for (all_multicast=0; all_multicast<=1; all_multicast++) {
|
||||
for (promiscuous=0; promiscuous<=1; promiscuous++) {
|
||||
for (addr_count=1; addr_count<=2; addr_count++) {
|
||||
for (hash_listindex=0; hash_listindex<=1; hash_listindex++) {
|
||||
for (host_phy_addr_listindex=0; host_phy_addr_listindex<=1; host_phy_addr_listindex++) {
|
||||
int i;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
++bpf_count;
|
||||
r = eth_bpf_filter (&dev, addr_count, &filter_address[0],
|
||||
all_multicast, promiscuous, reflections,
|
||||
&filter_address[0],
|
||||
host_phy_addr_list[host_phy_addr_listindex],
|
||||
hash_list[hash_listindex],
|
||||
buf);
|
||||
if (r != SCPE_OK) {
|
||||
++bpf_construct_error_count;
|
||||
sim_printf ("Eth: Error producing a BPF filter for:\n");
|
||||
SIM_PRINT_BPF_ARGUMENTS;
|
||||
sim_printf ("Eth: BPF string is: |%s|\n", buf);
|
||||
}
|
||||
if (dev.eth_api == ETH_API_PCAP) {
|
||||
struct bpf_program bpf;
|
||||
|
||||
if (pcap_compile ((pcap_t*)dev.handle, &bpf, buf, 1, (bpf_u_int32)0) < 0) {
|
||||
++bpf_compile_error_count;
|
||||
sprintf(errbuf, "%s", pcap_geterr((pcap_t*)dev.handle));
|
||||
sim_printf("Eth: pcap_compile error: %s\n", errbuf);
|
||||
if (!(sim_switches & SWMASK('D'))) {
|
||||
/* show erroneous BPF string */
|
||||
SIM_PRINT_BPF_ARGUMENTS;
|
||||
sim_printf ("Eth: BPF string is: |%s|\n", buf);
|
||||
}
|
||||
else {
|
||||
if (sim_switches & SWMASK('D')) {
|
||||
SIM_PRINT_BPF_ARGUMENTS;
|
||||
sim_printf ("Eth: BPF string is: |%s|\n", buf);
|
||||
}
|
||||
pcap_freecode(&bpf);
|
||||
if (dev.eth_api == ETH_API_PCAP) {
|
||||
struct bpf_program bpf;
|
||||
|
||||
if (pcap_compile ((pcap_t*)dev.handle, &bpf, buf, 1, (bpf_u_int32)0) < 0) {
|
||||
++bpf_compile_error_count;
|
||||
sprintf(errbuf, "%s", pcap_geterr((pcap_t*)dev.handle));
|
||||
sim_printf("Eth: pcap_compile error: %s\n", errbuf);
|
||||
if (!(sim_switches & SWMASK('D'))) {
|
||||
/* show erroneous BPF string */
|
||||
SIM_PRINT_BPF_ARGUMENTS;
|
||||
sim_printf ("Eth: BPF string is: |%s|\n", buf);
|
||||
}
|
||||
}
|
||||
pcap_freecode(&bpf);
|
||||
}
|
||||
else
|
||||
++bpf_compile_skip_count;
|
||||
}
|
||||
else
|
||||
++bpf_compile_skip_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
eth_close(&dev);
|
||||
}
|
||||
eth_close(&dev);
|
||||
sim_printf ("BPF Filter Count: %d\n", bpf_count);
|
||||
|
||||
if (eth_opened == 0) {
|
||||
errors = 1;
|
||||
sim_printf ("%s: No testable LAN interfaces found\n", dptr->name);
|
||||
}
|
||||
if (bpf_count)
|
||||
sim_printf ("BPF Filter Count: %d\n", bpf_count);
|
||||
if (bpf_construct_error_count)
|
||||
sim_printf ("BPF Construct Errors: %d\n", bpf_construct_error_count);
|
||||
if (bpf_compile_error_count)
|
||||
|
||||
@@ -811,7 +811,7 @@ if (bits_to_clear&TMXR_MDM_RTS)
|
||||
}
|
||||
if (incoming_bits) {
|
||||
DWORD ModemStat;
|
||||
if (GetCommModemStatus (port->hPort, &ModemStat)) {
|
||||
if (!GetCommModemStatus (port->hPort, &ModemStat)) {
|
||||
sim_error_serial ("GetCommModemStatus", (int) GetLastError ());
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
@@ -90,8 +90,10 @@ extern "C" {
|
||||
#endif
|
||||
#define WSAEACCES EACCES
|
||||
#define WSAEINTR EINTR
|
||||
#define INVALID_SOCKET ((SOCKET)-1)
|
||||
#define SOCKET_ERROR -1
|
||||
#define INVALID_SOCKET ((SOCKET)-1)
|
||||
#if !defined(SOCKET_ERROR)
|
||||
#define SOCKET_ERROR (-1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (VMS) /* VMS unique */
|
||||
|
||||
384
sim_tape.c
384
sim_tape.c
@@ -102,7 +102,7 @@
|
||||
|
||||
struct sim_tape_fmt {
|
||||
const char *name; /* name */
|
||||
int32 uflags; /* unit flags */
|
||||
int32 uflags; /* unit flags */
|
||||
t_addr bot; /* bot test */
|
||||
t_addr eom_remnant; /* potentially unprocessed data */
|
||||
};
|
||||
@@ -113,7 +113,7 @@ static struct sim_tape_fmt fmts[MTUF_N_FMT] = {
|
||||
{ "TPC", UNIT_RO, sizeof (t_tpclnt) - 1, sizeof (t_tpclnt) },
|
||||
{ "P7B", 0, 0, 0 },
|
||||
{ "AWS", 0, 0, 0 },
|
||||
/* { "TPF", UNIT_RO, 0 }, */
|
||||
{ "TAR", 0, 0, 0 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ static t_stat sim_tape_ioerr (UNIT *uptr);
|
||||
static t_stat sim_tape_wrdata (UNIT *uptr, uint32 dat);
|
||||
static t_stat sim_tape_aws_wrdata (UNIT *uptr, uint8 *buf, t_mtrlnt bc);
|
||||
static uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map, uint32 mapsize);
|
||||
static t_stat sim_tape_scan_tape (UNIT *uptr);
|
||||
static t_stat sim_tape_validate_tape (UNIT *uptr);
|
||||
static t_addr sim_tape_tpc_fnd (UNIT *uptr, t_addr *map);
|
||||
static void sim_tape_data_trace (UNIT *uptr, const uint8 *data, size_t len, const char* txt, int detail, uint32 reason);
|
||||
static t_stat tape_erase_fwd (UNIT *uptr, t_mtrlnt gap_size);
|
||||
@@ -479,14 +479,31 @@ if ((dptr = find_dev_from_unit (uptr)) == NULL)
|
||||
if (sim_switches & SWMASK ('F')) { /* format spec? */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get spec */
|
||||
if (*cptr == 0) /* must be more */
|
||||
return SCPE_2FARG;
|
||||
return sim_messagef (SCPE_2FARG, "Missing Format specifier and filename to attach\n");
|
||||
if (sim_tape_set_fmt (uptr, 0, gbuf, NULL) != SCPE_OK)
|
||||
return sim_messagef (SCPE_ARG, "Invalid Tape Format: %s\n", gbuf);
|
||||
sim_switches = sim_switches & ~(SWMASK ('F')); /* Record Format specifier already processed */
|
||||
auto_format = TRUE;
|
||||
}
|
||||
if (MT_GET_FMT (uptr) == MTUF_F_TPC)
|
||||
sim_switches |= SWMASK ('R'); /* Force ReadOnly attach for TPC tapes */
|
||||
if (MT_GET_FMT (uptr) == MTUF_F_TAR) {
|
||||
if (sim_switches & SWMASK ('B')) { /* Record Size (blocking factor)? */
|
||||
uint32 recsize;
|
||||
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get spec */
|
||||
if (*cptr == 0) /* must be more */
|
||||
return sim_messagef (SCPE_2FARG, "Missing Record Size and filename to attach\n");
|
||||
recsize = (uint32) get_uint (gbuf, 10, 65536, &r);
|
||||
if ((r != SCPE_OK) || (recsize == 0))
|
||||
return sim_messagef (SCPE_ARG, "Invalid Tape Record Size: %s\n", gbuf);
|
||||
uptr->recsize = recsize;
|
||||
sim_switches = sim_switches & ~(SWMASK ('B')); /* Record Blocking Factor */
|
||||
}
|
||||
if (uptr->recsize == 0)
|
||||
uptr->recsize = TAR_DFLT_RECSIZE;
|
||||
}
|
||||
if ((MT_GET_FMT (uptr) == MTUF_F_TPC) ||
|
||||
(MT_GET_FMT (uptr) == MTUF_F_TAR))
|
||||
sim_switches |= SWMASK ('R'); /* Force ReadOnly attach for TPC and TAR tapes */
|
||||
r = attach_unit (uptr, (CONST char *)cptr); /* attach unit */
|
||||
if (r != SCPE_OK) /* error? */
|
||||
return sim_messagef (r, "Can't open tape image: %s\n", cptr);
|
||||
@@ -522,12 +539,17 @@ switch (MT_GET_FMT (uptr)) { /* case on format */
|
||||
sim_tape_tpc_map (uptr, (t_addr *) uptr->filebuf, objc);/* fill map */
|
||||
break;
|
||||
|
||||
case MTUF_F_TAR: /* TAR */
|
||||
uptr->hwmark = (t_addr)sim_fsize (uptr->fileref);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (r == SCPE_OK) {
|
||||
sim_tape_scan_tape (uptr);
|
||||
|
||||
sim_tape_validate_tape (uptr);
|
||||
|
||||
sim_tape_rewind (uptr);
|
||||
|
||||
@@ -568,7 +590,7 @@ if (ctx)
|
||||
|
||||
sim_tape_clr_async (uptr);
|
||||
|
||||
MT_CLR_INMRK (uptr); /* Not within an AWS tapemark */
|
||||
MT_CLR_INMRK (uptr); /* Not within an AWS or TAR tapemark */
|
||||
r = detach_unit (uptr); /* detach unit */
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
@@ -578,12 +600,14 @@ switch (f) { /* case on format */
|
||||
if (uptr->filebuf) /* free map */
|
||||
free (uptr->filebuf);
|
||||
uptr->filebuf = NULL;
|
||||
uptr->hwmark = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uptr->hwmark = 0;
|
||||
uptr->recsize = 0;
|
||||
uptr->tape_eom = 0;
|
||||
|
||||
sim_tape_rewind (uptr);
|
||||
free (uptr->tape_ctx);
|
||||
@@ -615,9 +639,16 @@ fprintf (st, " -R Attach Read Only.\n");
|
||||
fprintf (st, " -E Must Exist (if not specified an attempt to create the indicated\n");
|
||||
fprintf (st, " virtual tape will be attempted).\n");
|
||||
fprintf (st, " -F Open the indicated tape container in a specific format (default\n");
|
||||
fprintf (st, " is SIMH, alternatives are E11, TPC and P7B)\n");
|
||||
fprintf (st, " is SIMH, alternatives are E11, TPC, P7B, AWS and TAR)\n");
|
||||
fprintf (st, " -B For TAR format tapes, the record size for data read from the\n");
|
||||
fprintf (st, " specified file. This record size will be used for all but\n");
|
||||
fprintf (st, " possibly the last record which will be what remains unread.\n");
|
||||
fprintf (st, " The default TAR record size is 10240.\n");
|
||||
fprintf (st, " -V Display some summary information about the record structure\n");
|
||||
fprintf (st, " contained in the tape structure.\n");
|
||||
fprintf (st, " contained in the tape image scan performed when it is attached.\n");
|
||||
fprintf (st, " -L Display detailed record size counts observed during attach\n");
|
||||
fprintf (st, " validation pass\n");
|
||||
fprintf (st, " contained in the tape image scan performed when it is attached.\n");
|
||||
fprintf (st, " -D Causes the internal tape structure information to be displayed\n");
|
||||
fprintf (st, " while the tape image is scanned.\n");
|
||||
return SCPE_OK;
|
||||
@@ -638,6 +669,7 @@ if (sim_deb && ((uptr->dctrl | ctx->dptr->dctrl) & reason))
|
||||
Inputs:
|
||||
uptr = pointer to tape unit
|
||||
bc = pointer to returned record length
|
||||
|
||||
Outputs:
|
||||
status = operation status
|
||||
|
||||
@@ -733,21 +765,29 @@ t_tpclnt tpcbc;
|
||||
t_awshdr awshdr;
|
||||
size_t rdcnt;
|
||||
t_mtrlnt buffer [256]; /* local tape buffer */
|
||||
t_addr saved_pos;
|
||||
uint32 bufcntr, bufcap; /* buffer counter and capacity */
|
||||
int32 runaway_counter, sizeof_gap; /* bytes remaining before runaway and bytes per gap */
|
||||
t_stat status = MTSE_OK;
|
||||
|
||||
MT_CLR_PNU (uptr); /* clear the position-not-updated flag */
|
||||
*bc = 0;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* if the unit is not attached */
|
||||
return MTSE_UNATT; /* then quit with an error */
|
||||
|
||||
if (sim_fseek (uptr->fileref, uptr->pos, SEEK_SET)) { /* set the initial tape position; if it fails */
|
||||
if ((uptr->tape_eom) &&
|
||||
(uptr->pos >= uptr->tape_eom)) {
|
||||
MT_SET_PNU (uptr); /* then set position not updated */
|
||||
status = sim_tape_ioerr (uptr); /* and quit with I/O error status */
|
||||
return MTSE_EOM; /* and quit with I/O error status */
|
||||
}
|
||||
|
||||
else switch (f) { /* otherwise the read method depends on the tape format */
|
||||
if (sim_fseek (uptr->fileref, uptr->pos, SEEK_SET)) { /* set the initial tape position; if it fails */
|
||||
MT_SET_PNU (uptr); /* then set position not updated */
|
||||
return sim_tape_ioerr (uptr); /* and quit with I/O error status */
|
||||
}
|
||||
|
||||
switch (f) { /* otherwise the read method depends on the tape format */
|
||||
|
||||
case MTUF_F_STD:
|
||||
case MTUF_F_E11:
|
||||
@@ -799,6 +839,7 @@ else switch (f) { /* otherwise the read me
|
||||
if (bufcntr == 0) { /* then if this is the initial read */
|
||||
MT_SET_PNU (uptr); /* then set position not updated */
|
||||
status = MTSE_EOM; /* and report the end-of-medium and quit */
|
||||
uptr->tape_eom = uptr->pos;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -844,17 +885,12 @@ else switch (f) { /* otherwise the read me
|
||||
|
||||
bufcntr = bufcap; /* mark the buffer as invalid to force a read */
|
||||
|
||||
*bc = MTR_GAP; /* reset the marker */
|
||||
*bc = (t_mtrlnt)MTR_GAP; /* reset the marker */
|
||||
runaway_counter -= sizeof_gap / 2; /* and decrement the gap counter */
|
||||
}
|
||||
|
||||
else { /* otherwise it's a record marker */
|
||||
if (bufcntr < bufcap /* if the position is within the buffer */
|
||||
&& sim_fseek (uptr->fileref, uptr->pos, SEEK_SET)) { /* then seek to the data area; if it fails */
|
||||
status = sim_tape_ioerr (uptr); /* then quit with I/O error status */
|
||||
break;
|
||||
}
|
||||
|
||||
saved_pos = uptr->pos; /* Save data position */
|
||||
sbc = MTR_L (*bc); /* extract the record length */
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt) /* position to the start */
|
||||
+ (f == MTUF_F_STD ? (sbc + 1) & ~1 : sbc); /* of the record */
|
||||
@@ -865,8 +901,7 @@ else switch (f) { /* otherwise the read me
|
||||
if (runaway_counter <= 0) /* if a tape runaway occurred */
|
||||
status = MTSE_RUNAWAY; /* then report it */
|
||||
|
||||
if (status == MTSE_OK) { /* Validate the reverse record size */
|
||||
t_addr saved_pos = (t_addr)sim_ftell(uptr->fileref);
|
||||
if (status == MTSE_OK) { /* Validate the reverse record size for data records */
|
||||
t_mtrlnt rev_lnt;
|
||||
|
||||
if (sim_fseek (uptr->fileref, uptr->pos - sizeof (t_mtrlnt), SEEK_SET)){ /* then seek to the end of record size; if it fails */
|
||||
@@ -883,21 +918,20 @@ else switch (f) { /* otherwise the read me
|
||||
status = sim_tape_ioerr (uptr); /* report the error and quit */
|
||||
break;
|
||||
}
|
||||
if (sim_fseek (uptr->fileref, saved_pos, SEEK_SET)){ /* then seek back to the beginning of the data; if it fails */
|
||||
status = sim_tape_ioerr (uptr); /* then quit with I/O error status */
|
||||
break;
|
||||
}
|
||||
if (rev_lnt != *bc) { /* size mismatch? */
|
||||
status = MTSE_INVRL;
|
||||
uptr->pos -= (sizeof (t_mtrlnt) + *bc + sizeof (t_mtrlnt));
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
break;
|
||||
}
|
||||
if (sim_fseek (uptr->fileref, saved_pos, SEEK_SET)) /* then seek back to the beginning of the data; if it fails */
|
||||
status = sim_tape_ioerr (uptr); /* then quit with I/O error status */
|
||||
}
|
||||
break; /* otherwise the operation succeeded */
|
||||
|
||||
case MTUF_F_TPC:
|
||||
(void)sim_fread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
*bc = tpcbc; /* save rec lnt */
|
||||
*bc = (t_mtrlnt)tpcbc; /* save rec lnt */
|
||||
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
@@ -911,7 +945,7 @@ else switch (f) { /* otherwise the read me
|
||||
status = MTSE_EOM;
|
||||
}
|
||||
else {
|
||||
uptr->pos = uptr->pos + sizeof (t_tpclnt); /* spc over reclnt */
|
||||
uptr->pos += sizeof (t_tpclnt); /* spc over reclnt */
|
||||
if (tpcbc == TPC_TMK) /* tape mark? */
|
||||
status = MTSE_TMK;
|
||||
else
|
||||
@@ -955,7 +989,6 @@ else switch (f) { /* otherwise the read me
|
||||
MT_CLR_INMRK (uptr); /* Not within an AWS tapemark */
|
||||
memset (&awshdr, 0, sizeof (awshdr));
|
||||
rdcnt = sim_fread (&awshdr, sizeof (t_awslnt), 3, uptr->fileref);
|
||||
*bc = 0;
|
||||
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
@@ -981,7 +1014,7 @@ else switch (f) { /* otherwise the read me
|
||||
else { /* tape data record */
|
||||
t_addr saved_pos;
|
||||
|
||||
*bc = awshdr.nxtlen; /* save rec lnt */
|
||||
*bc = (t_mtrlnt)awshdr.nxtlen; /* save rec lnt */
|
||||
uptr->pos += awshdr.nxtlen; /* spc over record */
|
||||
memset (&awshdr, 0, sizeof (t_awslnt));
|
||||
saved_pos = (t_addr)sim_ftell (uptr->fileref);
|
||||
@@ -999,6 +1032,26 @@ else switch (f) { /* otherwise the read me
|
||||
}
|
||||
break;
|
||||
|
||||
case MTUF_F_TAR:
|
||||
if (uptr->pos < uptr->hwmark) {
|
||||
if ((uptr->hwmark - uptr->pos) >= uptr->recsize)
|
||||
*bc = (t_mtrlnt)uptr->recsize; /* TAR record size */
|
||||
else
|
||||
*bc = (t_mtrlnt)(uptr->hwmark - uptr->pos); /* TAR remnant last record */
|
||||
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET);
|
||||
uptr->pos += *bc;
|
||||
MT_CLR_INMRK (uptr);
|
||||
}
|
||||
else {
|
||||
if (MT_TST_INMRK (uptr))
|
||||
status = MTSE_EOM;
|
||||
else {
|
||||
status = MTSE_TMK;
|
||||
MT_SET_INMRK (uptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
status = MTSE_FMT;
|
||||
}
|
||||
@@ -1075,6 +1128,7 @@ int32 runaway_counter, sizeof_gap; /* bytes remaining befor
|
||||
t_stat status = MTSE_OK;
|
||||
|
||||
MT_CLR_PNU (uptr); /* clear the position-not-updated flag */
|
||||
*bc = 0;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* if the unit is not attached */
|
||||
return MTSE_UNATT; /* then quit with an error */
|
||||
@@ -1150,7 +1204,7 @@ else switch (f) { /* otherwise the read me
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt) / 2; /* then position forward to resync */
|
||||
bufcntr = 0; /* mark the buffer as invalid to force a read */
|
||||
|
||||
*bc = MTR_GAP; /* reset the marker */
|
||||
*bc = (t_mtrlnt)MTR_GAP; /* reset the marker */
|
||||
runaway_counter -= sizeof_gap / 2; /* and decrement the gap counter */
|
||||
}
|
||||
|
||||
@@ -1178,7 +1232,7 @@ else switch (f) { /* otherwise the read me
|
||||
ppos = sim_tape_tpc_fnd (uptr, (t_addr *) uptr->filebuf); /* find prev rec */
|
||||
(void)sim_fseek (uptr->fileref, ppos, SEEK_SET);/* position */
|
||||
(void)sim_fread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
*bc = tpcbc; /* save rec lnt */
|
||||
*bc = (t_mtrlnt)tpcbc; /* save rec lnt */
|
||||
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
status = sim_tape_ioerr (uptr);
|
||||
@@ -1194,34 +1248,50 @@ else switch (f) { /* otherwise the read me
|
||||
break;
|
||||
|
||||
case MTUF_F_P7B:
|
||||
for (sbc = 1, all_eof = 1; (t_addr) sbc <= uptr->pos ; sbc++) {
|
||||
(void)sim_fseek (uptr->fileref, uptr->pos - sbc, SEEK_SET);
|
||||
(void)sim_fread (&c, sizeof (uint8), 1, uptr->fileref);
|
||||
if (1) {
|
||||
#define BUF_SZ 512
|
||||
uint8 buf[BUF_SZ];
|
||||
t_addr buf_offset;
|
||||
size_t bytes_in_buf = 0;
|
||||
size_t read_size;
|
||||
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
status = sim_tape_ioerr (uptr);
|
||||
break;
|
||||
}
|
||||
else if (feof (uptr->fileref)) { /* eof? */
|
||||
status = MTSE_EOM;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
for (sbc = 1, all_eof = 1; (t_addr) sbc <= uptr->pos ; sbc++) {
|
||||
if (bytes_in_buf == 0) { /* Need to Fill Buffer */
|
||||
if (uptr->pos < BUF_SZ) {
|
||||
buf_offset = 0;
|
||||
read_size = (size_t)uptr->pos;
|
||||
}
|
||||
else {
|
||||
buf_offset = uptr->pos - (sbc - 1 + BUF_SZ);
|
||||
read_size = BUF_SZ;
|
||||
}
|
||||
(void)sim_fseek (uptr->fileref, buf_offset, SEEK_SET);
|
||||
bytes_in_buf = sim_fread (buf, sizeof (uint8), read_size, uptr->fileref);
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
status = sim_tape_ioerr (uptr);
|
||||
break;
|
||||
}
|
||||
if (feof (uptr->fileref)) { /* eof? */
|
||||
status = MTSE_EOM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = buf[--bytes_in_buf];
|
||||
if ((c & P7B_DPAR) != P7B_EOF)
|
||||
all_eof = 0;
|
||||
if (c & P7B_SOR) /* start of record? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == MTSE_OK) {
|
||||
uptr->pos = uptr->pos - sbc; /* update position */
|
||||
*bc = sbc; /* save rec lnt */
|
||||
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for next read */
|
||||
if (all_eof) /* tape mark? */
|
||||
status = MTSE_TMK;
|
||||
if (status == MTSE_OK) {
|
||||
uptr->pos = uptr->pos - sbc; /* update position */
|
||||
*bc = sbc; /* save rec lnt */
|
||||
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for next read */
|
||||
if (all_eof) /* tape mark? */
|
||||
status = MTSE_TMK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTUF_F_AWS:
|
||||
*bc = sbc = 0;
|
||||
@@ -1259,7 +1329,7 @@ else switch (f) { /* otherwise the read me
|
||||
if (MT_TST_INMRK (uptr)) /* already in a tapemark? */
|
||||
awshdr.rectyp = AWS_REC;
|
||||
MT_CLR_INMRK (uptr); /* No longer in a tapemark */
|
||||
*bc = (awshdr.rectyp == AWS_REC) ? awshdr.prelen : 0;/* save rec lnt */
|
||||
*bc = (t_mtrlnt)((awshdr.rectyp == AWS_REC) ? awshdr.prelen : 0);/* save rec lnt */
|
||||
sbc = *bc; /* extract the record length */
|
||||
if ((awshdr.rectyp != AWS_TMK) ||
|
||||
(awshdr.prelen == 0)) {
|
||||
@@ -1281,7 +1351,28 @@ else switch (f) { /* otherwise the read me
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case MTUF_F_TAR:
|
||||
if (uptr->pos == uptr->hwmark) {
|
||||
if (MT_TST_INMRK (uptr)) {
|
||||
status = MTSE_TMK;
|
||||
MT_CLR_INMRK (uptr);
|
||||
}
|
||||
else {
|
||||
if (uptr->hwmark % uptr->recsize)
|
||||
*bc = (t_mtrlnt)(uptr->hwmark % uptr->recsize);
|
||||
else
|
||||
*bc = (t_mtrlnt)uptr->recsize;
|
||||
}
|
||||
}
|
||||
else
|
||||
*bc = (t_mtrlnt)uptr->recsize;
|
||||
if (*bc) {
|
||||
uptr->pos -= *bc;
|
||||
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
status = MTSE_FMT;
|
||||
}
|
||||
|
||||
@@ -1504,6 +1595,8 @@ switch (f) { /* case on format */
|
||||
return status;
|
||||
break;
|
||||
}
|
||||
if (uptr->pos > uptr->tape_eom)
|
||||
uptr->tape_eom = uptr->pos; /* update EOM as needed */
|
||||
sim_tape_data_trace(uptr, buf, sbc, "Record Written", (uptr->dctrl | ctx->dptr->dctrl) & MTSE_DBG_DAT, MTSE_DBG_STR);
|
||||
return MTSE_OK;
|
||||
}
|
||||
@@ -1556,6 +1649,8 @@ if ((!replacing_record) || (bc == 0)) {
|
||||
if (!replacing_record)
|
||||
sim_set_fsize (uptr->fileref, uptr->pos + sizeof (awshdr));
|
||||
}
|
||||
if (uptr->pos > uptr->tape_eom)
|
||||
uptr->tape_eom = uptr->pos; /* Update EOM if we're there */
|
||||
return MTSE_OK;
|
||||
}
|
||||
|
||||
@@ -1580,6 +1675,8 @@ if (ferror (uptr->fileref)) { /* error? */
|
||||
}
|
||||
sim_debug_unit (MTSE_DBG_STR, uptr, "wr_lnt: lnt: %d, pos: %" T_ADDR_FMT "u\n", dat, uptr->pos);
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* move tape */
|
||||
if (uptr->pos > uptr->tape_eom)
|
||||
uptr->tape_eom = uptr->pos; /* update EOM */
|
||||
return MTSE_OK;
|
||||
}
|
||||
|
||||
@@ -2568,7 +2665,10 @@ if (uptr->flags & UNIT_ATT) {
|
||||
sim_debug_unit (ctx->dbit, uptr, "sim_tape_rewind(unit=%d)\n", (int)(uptr-ctx->dptr->units));
|
||||
}
|
||||
uptr->pos = 0;
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET);
|
||||
MT_CLR_PNU (uptr);
|
||||
MT_CLR_INMRK (uptr); /* Not within an AWS or TAR tapemark */
|
||||
return MTSE_OK;
|
||||
}
|
||||
|
||||
@@ -2841,7 +2941,7 @@ sprintf(msgbuf, "Error %d", stat);
|
||||
return msgbuf;
|
||||
}
|
||||
|
||||
static t_stat sim_tape_scan_tape (UNIT *uptr)
|
||||
static t_stat sim_tape_validate_tape (UNIT *uptr)
|
||||
{
|
||||
t_addr saved_pos = uptr->pos;
|
||||
uint32 record_in_file = 0;
|
||||
@@ -2849,13 +2949,14 @@ uint32 data_total = 0;
|
||||
uint32 tapemark_total = 0;
|
||||
uint32 record_total = 0;
|
||||
uint32 unique_record_sizes = 0;
|
||||
uint32 remaining_data = 0;
|
||||
uint32 *rec_sizes = NULL;
|
||||
t_stat r = SCPE_OK;
|
||||
t_stat r_f;
|
||||
t_stat r_r;
|
||||
t_stat r_s;
|
||||
uint8 *buf_f = NULL;
|
||||
uint8 *buf_r = NULL;
|
||||
uint32 *rec_sizes = NULL;
|
||||
t_mtrlnt bc_f;
|
||||
t_mtrlnt bc_r;
|
||||
t_mtrlnt bc_s;
|
||||
@@ -2866,10 +2967,10 @@ t_mtrlnt max = MTR_MAXLEN;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT))
|
||||
return SCPE_UNATT;
|
||||
buf_f = (uint8 *)malloc (max);
|
||||
buf_f = (uint8 *)calloc (1, max);
|
||||
if (buf_f == NULL)
|
||||
return SCPE_MEM;
|
||||
buf_r = (uint8 *)malloc (max);
|
||||
buf_r = (uint8 *)calloc (1, max);
|
||||
if (buf_r == NULL) {
|
||||
free (buf_f);
|
||||
return SCPE_MEM;
|
||||
@@ -2882,6 +2983,8 @@ if (rec_sizes == NULL) {
|
||||
}
|
||||
r = sim_tape_rewind (uptr);
|
||||
while (r == SCPE_OK) {
|
||||
if (stop_cpu) /* SIGINT? */
|
||||
break;
|
||||
pos_f = uptr->pos;
|
||||
r_f = sim_tape_rdrecf (uptr, buf_f, &bc_f, max);
|
||||
switch (r_f) {
|
||||
@@ -2904,13 +3007,15 @@ while (r == SCPE_OK) {
|
||||
break;
|
||||
}
|
||||
if (bc_f != bc_r) {
|
||||
sim_printf ("Forward Record Read record lemgtj: %d, Reverse read record length: %d\n", bc_f, bc_r);
|
||||
sim_printf ("Forward Record Read record length: %d, Reverse read record length: %d\n", bc_f, bc_r);
|
||||
break;
|
||||
}
|
||||
if (0 != memcmp (buf_f, buf_r, bc_f)) {
|
||||
sim_printf ("%d byte record contents differ when read forward amd backwards start from position %" T_ADDR_FMT "u\n", bc_f, pos_f);
|
||||
break;
|
||||
}
|
||||
memset (buf_f, 0, bc_f);
|
||||
memset (buf_r, 0, bc_f);
|
||||
if (pos_f != pos_r) {
|
||||
sim_printf ("Unexpected tape file position between forward and reverse record read: (%" T_ADDR_FMT "u, %" T_ADDR_FMT "u\n", pos_f, pos_r);
|
||||
break;
|
||||
@@ -2941,11 +3046,12 @@ while (r == SCPE_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) ||
|
||||
((uint32)(sim_fsize_ex (uptr->fileref) - (t_offset)uptr->pos) > fmts[MT_GET_FMT (uptr)].eom_remnant) ||
|
||||
(unique_record_sizes > 2 * tapemark_total)) {
|
||||
uint32 remaining_data = (uint32)(sim_fsize_ex (uptr->fileref) - (t_offset)uptr->pos);
|
||||
|
||||
uptr->tape_eom = uptr->pos;
|
||||
if ((!stop_cpu) &&
|
||||
((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) || (sim_switches & SWMASK ('L')) ||
|
||||
((uint32)(sim_fsize_ex (uptr->fileref) - (t_offset)uptr->pos) > fmts[MT_GET_FMT (uptr)].eom_remnant) ||
|
||||
(unique_record_sizes > 2 * tapemark_total))) {
|
||||
remaining_data = (uint32)(sim_fsize_ex (uptr->fileref) - (t_offset)uptr->tape_eom);
|
||||
sim_printf ("Tape Image '%s' scanned as %s format.\n", uptr->filename, fmts[MT_GET_FMT (uptr)].name);
|
||||
if (r != MTSE_EOM)
|
||||
sim_printf ("After processing ");
|
||||
@@ -2953,8 +3059,8 @@ if ((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) ||
|
||||
sim_printf ("contains ");
|
||||
sim_printf ("%u bytes of tape data (%u records, %u tapemarks)\n",
|
||||
data_total, record_total, tapemark_total);
|
||||
if (record_total > 0) {
|
||||
sim_printf ("Comprising (in record size order):\n");
|
||||
if ((record_total > 0) && (sim_switches & SWMASK ('L'))) {
|
||||
sim_printf ("Comprising %d different sized records (in record size order):\n", unique_record_sizes);
|
||||
for (bc = 0; bc <= max; bc++) {
|
||||
if (rec_sizes[bc])
|
||||
sim_printf ("%8u %u byte records\n", rec_sizes[bc], (uint32)bc);
|
||||
@@ -2965,8 +3071,8 @@ if ((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) ||
|
||||
if (remaining_data > fmts[MT_GET_FMT (uptr)].eom_remnant)
|
||||
sim_printf ("%u bytes of unexamined data remain in the tape image file\n", remaining_data);
|
||||
}
|
||||
/* Try again reading backwards */
|
||||
if (unique_record_sizes > 2 * tapemark_total) {
|
||||
if ((!stop_cpu) &&
|
||||
(unique_record_sizes > 2 * tapemark_total)) {
|
||||
sim_printf ("An unreasonable number of record sizes(%u) vs tape marks (%u) have been found\n", unique_record_sizes, tapemark_total);
|
||||
sim_printf ("The tape format (%s) might not be correct for the '%s' tape image\n", fmts[MT_GET_FMT (uptr)].name, uptr->filename);
|
||||
}
|
||||
@@ -2975,6 +3081,7 @@ free (buf_f);
|
||||
free (buf_r);
|
||||
free (rec_sizes);
|
||||
uptr->pos = saved_pos;
|
||||
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -3116,6 +3223,45 @@ else { /* otherwise get the den
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* list supported densities
|
||||
|
||||
translates the mask of supported densities to a string list in the form:
|
||||
|
||||
"(800|1600|6250)"
|
||||
|
||||
this string may be useful to construct a MTAB help string for a
|
||||
SET <unit> DENSITY= command.
|
||||
|
||||
*/
|
||||
|
||||
t_stat sim_tape_density_supported (char *string, size_t string_size, int32 valid_bits)
|
||||
{
|
||||
uint32 density;
|
||||
int32 count;
|
||||
|
||||
strlcpy (string, "", string_size);
|
||||
if ((!valid_bits) || (valid_bits >> BPI_COUNT))
|
||||
return SCPE_ARG;
|
||||
for (density = count = 0; density < BPI_COUNT; density++) {
|
||||
if (valid_bits & (1 << density)) {
|
||||
char density_str[20];
|
||||
|
||||
++count;
|
||||
if (count == 1)
|
||||
strlcat (string, "{", string_size);
|
||||
else
|
||||
strlcat (string, "|", string_size);
|
||||
sprintf (density_str, "%d", bpi[density]);
|
||||
strlcat (string, density_str, string_size);
|
||||
}
|
||||
}
|
||||
if ((count == 1) && (string_size > 1))
|
||||
memmove (string, string + 1, strlen (string));
|
||||
else
|
||||
strlcat (string, "}", string_size);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static DEBTAB tape_debug[] = {
|
||||
{"TRACE", MTSE_DBG_API, "API Trace"},
|
||||
{"DATA", MTSE_DBG_DAT, "Tape Data"},
|
||||
@@ -3135,13 +3281,15 @@ static t_bool p7b_parity_inited = FALSE;
|
||||
static uint8 p7b_odd_parity[64];
|
||||
static uint8 p7b_even_parity[64];
|
||||
|
||||
static t_stat create_tape_files (UNIT *uptr, const char *filename, int files, int records, int max_size)
|
||||
static t_stat sim_tape_test_create_tape_files (UNIT *uptr, const char *filename, int files, int records, int max_size)
|
||||
{
|
||||
FILE *fSIMH = NULL;
|
||||
FILE *fE11 = NULL;
|
||||
FILE *fTPC = NULL;
|
||||
FILE *fP7B = NULL;
|
||||
FILE *fAWS = NULL;
|
||||
FILE *fTAR = NULL;
|
||||
FILE *fTAR2 = NULL;
|
||||
int i, j, k;
|
||||
t_tpclnt tpclnt;
|
||||
t_mtrlnt mtrlnt;
|
||||
@@ -3189,6 +3337,14 @@ sprintf (name, "%s.p7b", filename);
|
||||
fP7B = fopen (name, "wb");
|
||||
if (fP7B == NULL)
|
||||
goto Done_Files;
|
||||
sprintf (name, "%s.tar", filename);
|
||||
fTAR = fopen (name, "wb");
|
||||
if (fTAR == NULL)
|
||||
goto Done_Files;
|
||||
sprintf (name, "%s.2.tar", filename);
|
||||
fTAR2 = fopen (name, "wb");
|
||||
if (fTAR2 == NULL)
|
||||
goto Done_Files;
|
||||
sprintf (name, "%s.aws", filename);
|
||||
fAWS = fopen (name, "wb");
|
||||
if (fAWS == NULL)
|
||||
@@ -3267,6 +3423,24 @@ tpclnt = 0xffff;
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fE11);
|
||||
(void)sim_fwrite (&tpclnt, sizeof (tpclnt), 1, fTPC);
|
||||
(void)sim_fwrite (buf, 1, 1, fP7B);
|
||||
/* Write an unmatched record delimiter (aka garbage) at
|
||||
the end of the SIMH, E11 and AWS files */
|
||||
mtrlnt = 25;
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fSIMH);
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fE11);
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fAWS);
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fAWS);
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fAWS);
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, uptr->fileref);
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, uptr->fileref);
|
||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, uptr->fileref);
|
||||
for (j=0; j<records; j++) {
|
||||
memset (buf, j, 10240);
|
||||
(void)sim_fwrite (buf, 1, 10240, fTAR);
|
||||
(void)sim_fwrite (buf, 1, 10240, fTAR2);
|
||||
}
|
||||
memset (buf, j, 10240);
|
||||
(void)sim_fwrite (buf, 1, 5120, fTAR2);
|
||||
Done_Files:
|
||||
if (fSIMH)
|
||||
fclose (fSIMH);
|
||||
@@ -3278,6 +3452,10 @@ if (fP7B)
|
||||
fclose (fP7B);
|
||||
if (fAWS)
|
||||
fclose (fAWS);
|
||||
if (fTAR)
|
||||
fclose (fTAR);
|
||||
if (fTAR2)
|
||||
fclose (fTAR2);
|
||||
free (buf);
|
||||
sim_tape_detach (uptr);
|
||||
if (stat == SCPE_OK) {
|
||||
@@ -3293,14 +3471,14 @@ sim_switches = saved_switches;
|
||||
return stat;
|
||||
}
|
||||
|
||||
static t_stat process_tape_file (UNIT *uptr, const char *filename, const char *format)
|
||||
static t_stat sim_tape_test_process_tape_file (UNIT *uptr, const char *filename, const char *format)
|
||||
{
|
||||
char args[256];
|
||||
t_stat stat;
|
||||
|
||||
sprintf (args, "%s %s.%s", format, filename, format);
|
||||
sim_tape_detach (uptr);
|
||||
sim_switches |= SWMASK ('F') | SWMASK ('V');
|
||||
sim_switches |= SWMASK ('F') | SWMASK ('L'); /* specific-format and detailed record report */
|
||||
stat = sim_tape_attach_ex (uptr, args, 0, 0);
|
||||
if (stat != SCPE_OK)
|
||||
return stat;
|
||||
@@ -3309,7 +3487,7 @@ sim_switches = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat remove_tape_files (UNIT *uptr, const char *filename)
|
||||
static t_stat sim_tape_test_remove_tape_files (UNIT *uptr, const char *filename)
|
||||
{
|
||||
char name[256];
|
||||
|
||||
@@ -3323,6 +3501,42 @@ sprintf (name, "%s.p7b", filename);
|
||||
(void)remove (name);
|
||||
sprintf (name, "%s.aws", filename);
|
||||
(void)remove (name);
|
||||
sprintf (name, "%s.tar", filename);
|
||||
(void)remove (name);
|
||||
sprintf (name, "%s.2.tar", filename);
|
||||
(void)remove (name);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_tape_test_density_string (void)
|
||||
{
|
||||
char buf[128];
|
||||
int32 valid_bits = 0;
|
||||
t_stat stat;
|
||||
|
||||
if ((SCPE_ARG != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||
(strcmp (buf, "")))
|
||||
return stat;
|
||||
valid_bits = MT_556_VALID;
|
||||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||
(strcmp (buf, "556")))
|
||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||
valid_bits = MT_800_VALID | MT_1600_VALID;
|
||||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||
(strcmp (buf, "{800|1600}")))
|
||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||
valid_bits = MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
|
||||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||
(strcmp (buf, "{800|1600|6250}")))
|
||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||
valid_bits = MT_200_VALID | MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
|
||||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||
(strcmp (buf, "{200|800|1600|6250}")))
|
||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||
valid_bits = MT_NONE_VALID | MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
|
||||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||
(strcmp (buf, "{0|800|1600|6250}")))
|
||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -3335,26 +3549,34 @@ SIM_TEST_INIT;
|
||||
|
||||
sim_printf ("\nTesting %s device sim_tape APIs\n", sim_uname(dptr->units));
|
||||
|
||||
SIM_TEST(remove_tape_files (dptr->units, "TapeTestFile1"));
|
||||
SIM_TEST(sim_tape_test_density_string ());
|
||||
|
||||
SIM_TEST(create_tape_files (dptr->units, "TapeTestFile1", 2, 4, 4096));
|
||||
SIM_TEST(sim_tape_test_remove_tape_files (dptr->units, "TapeTestFile1"));
|
||||
|
||||
SIM_TEST(sim_tape_test_create_tape_files (dptr->units, "TapeTestFile1", 2, 5, 4096));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "aws"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "tar"));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "p7b"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1.2", "tar"));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "tpc"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "aws"));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "e11"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "p7b"));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "simh"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "tpc"));
|
||||
|
||||
SIM_TEST(remove_tape_files (dptr->units, "TapeTestFile1"));
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "e11"));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "simh"));
|
||||
|
||||
SIM_TEST(sim_tape_test_remove_tape_files (dptr->units, "TapeTestFile1"));
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ typedef uint32 t_mtrlnt; /* magtape rec lnt */
|
||||
#define MTR_MAXLEN 0x00FFFFFF /* max len is 24b */
|
||||
#define MTR_ERF 0x80000000 /* error flag */
|
||||
#define MTR_F(x) ((x) & MTR_ERF) /* record error flg */
|
||||
#define MTR_L(x) ((x) & ~MTR_ERF) /* record length */
|
||||
#define MTR_L(x) ((t_mtrlnt)((x) & ~MTR_ERF)) /* record length */
|
||||
|
||||
/* TPC tape format */
|
||||
|
||||
@@ -85,6 +85,9 @@ typedef struct {
|
||||
#define AWS_REC 0x00A0
|
||||
} t_awshdr;
|
||||
|
||||
/* TAR tape format */
|
||||
#define TAR_DFLT_RECSIZE 10240 /* Default Fixed record size */
|
||||
|
||||
/* Unit flags */
|
||||
|
||||
#define MTUF_V_PNU (UNIT_V_UF + 0) /* position not upd */
|
||||
@@ -98,6 +101,7 @@ typedef struct {
|
||||
#define MTUF_F_TPC 2 /* TPC format */
|
||||
#define MTUF_F_P7B 3 /* P7B format */
|
||||
#define MTUF_F_AWS 4 /* AWS format */
|
||||
#define MTUF_F_TAR 5 /* TAR format */
|
||||
#define MTUF_V_UF (MTUF_V_FMT + MTUF_W_FMT)
|
||||
#define MTUF_PNU (1u << MTUF_V_PNU)
|
||||
#define MTUF_WLK (1u << MTUF_V_WLK)
|
||||
@@ -109,6 +113,7 @@ typedef struct {
|
||||
#define MT_F_TPC (MTUF_F_TPC << MTUF_V_FMT)
|
||||
#define MT_F_P7B (MTUF_F_P7B << MTUF_V_FMT)
|
||||
#define MT_F_AWS (MTUF_F_AWS << MTUF_V_FMT)
|
||||
#define MT_F_TAR (MTUF_F_TAR << MTUF_V_FMT)
|
||||
|
||||
#define MT_SET_PNU(u) (u)->flags = (u)->flags | MTUF_PNU
|
||||
#define MT_CLR_PNU(u) (u)->flags = (u)->flags & ~MTUF_PNU
|
||||
@@ -224,6 +229,7 @@ t_stat sim_tape_set_capac (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat sim_tape_show_capac (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat sim_tape_set_dens (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat sim_tape_show_dens (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat sim_tape_density_supported (char *string, size_t string_size, int32 valid_bits);
|
||||
t_stat sim_tape_set_asynch (UNIT *uptr, int latency);
|
||||
t_stat sim_tape_clr_asynch (UNIT *uptr);
|
||||
t_stat sim_tape_test (DEVICE *dptr);
|
||||
|
||||
24
sim_video.c
24
sim_video.c
@@ -361,13 +361,12 @@ t_bool vid_key_state[SDL_NUM_SCANCODES];
|
||||
SDL_Texture *vid_texture; /* video buffer in GPU */
|
||||
SDL_Renderer *vid_renderer;
|
||||
SDL_Window *vid_window; /* window handle */
|
||||
SDL_PixelFormat *vid_format;
|
||||
uint32 vid_windowID;
|
||||
#endif
|
||||
SDL_Thread *vid_thread_handle = NULL; /* event thread handle */
|
||||
SDL_Cursor *vid_cursor = NULL; /* current cursor */
|
||||
t_bool vid_cursor_visible = FALSE; /* cursor visibility state */
|
||||
uint32 vid_mono_palette[2]; /* Monochrome Color Map */
|
||||
SDL_Color vid_colors[256];
|
||||
KEY_EVENT_QUEUE vid_key_events; /* keyboard events */
|
||||
MOUSE_EVENT_QUEUE vid_mouse_events; /* mouse events */
|
||||
DEVICE *vid_dev;
|
||||
@@ -631,6 +630,15 @@ if (SDL_SemTryWait (vid_mouse_events.sem) == 0) {
|
||||
return stat;
|
||||
}
|
||||
|
||||
uint32 vid_map_rgb (uint8 r, uint8 g, uint8 b)
|
||||
{
|
||||
#if SDL_MAJOR_VERSION == 1
|
||||
return SDL_MapRGB (vid_image->format, r, g, b);
|
||||
#else
|
||||
return SDL_MapRGB (vid_format, r, g, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf)
|
||||
{
|
||||
#if SDL_MAJOR_VERSION == 1
|
||||
@@ -1604,9 +1612,6 @@ if (!initialized) {
|
||||
|
||||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_thread() - Starting\n");
|
||||
|
||||
vid_mono_palette[0] = sim_end ? 0xFF000000 : 0x000000FF; /* Black */
|
||||
vid_mono_palette[1] = 0xFFFFFFFF; /* White */
|
||||
|
||||
memset (&vid_key_state, 0, sizeof(vid_key_state));
|
||||
|
||||
#if SDL_MAJOR_VERSION == 1
|
||||
@@ -1646,6 +1651,8 @@ if (!vid_texture) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
vid_format = SDL_AllocFormat (SDL_PIXELFORMAT_ARGB8888);
|
||||
|
||||
SDL_StopTextInput ();
|
||||
|
||||
vid_windowID = SDL_GetWindowID (vid_window);
|
||||
@@ -2317,8 +2324,6 @@ SDL_Delay (vid_beep_duration + 100);/* Wait for sound to finnish */
|
||||
#else /* !(defined(USE_SIM_VIDEO) && defined(HAVE_LIBSDL)) */
|
||||
/* Non-implemented versions */
|
||||
|
||||
uint32 vid_mono_palette[2]; /* Monochrome Color Map */
|
||||
|
||||
t_stat vid_open (DEVICE *dptr, const char *title, uint32 width, uint32 height, int flags)
|
||||
{
|
||||
return SCPE_NOFNC;
|
||||
@@ -2339,6 +2344,11 @@ t_stat vid_poll_mouse (SIM_MOUSE_EVENT *ev)
|
||||
return SCPE_EOF;
|
||||
}
|
||||
|
||||
uint32 vid_map_rgb (uint8 r, uint8 g, uint8 b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -183,6 +183,7 @@ t_stat vid_register_quit_callback (VID_QUIT_CALLBACK callback);
|
||||
t_stat vid_close (void);
|
||||
t_stat vid_poll_kb (SIM_KEY_EVENT *ev);
|
||||
t_stat vid_poll_mouse (SIM_MOUSE_EVENT *ev);
|
||||
uint32 vid_map_rgb (uint8 r, uint8 g, uint8 b);
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf);
|
||||
void vid_beep (void);
|
||||
void vid_refresh (void);
|
||||
@@ -196,7 +197,6 @@ t_stat vid_show (FILE* st, DEVICE *dptr, UNIT* uptr, int32 val, CONST char* des
|
||||
t_stat vid_screenshot (const char *filename);
|
||||
|
||||
extern t_bool vid_active;
|
||||
extern uint32 vid_mono_palette[2];
|
||||
void vid_set_cursor_position (int32 x, int32 y); /* cursor position (set by calling code) */
|
||||
|
||||
/* A device simulator can optionally set the vid_display_kb_event_process
|
||||
|
||||
Reference in New Issue
Block a user