aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-09-20 00:04:32 -0700
committerH. Peter Anvin <hpa@zytor.com>2018-09-20 00:04:32 -0700
commit0a331bb8d9a34ab342acf3e1d709071bc83240b5 (patch)
tree176e2925f662fb9888f7ade6ad19d84a4e005c8b
parent51e90f82bbb41982d999fcbce8f5c334fdcf75a8 (diff)
downloadabc80sim-0a331bb8d9a34ab342acf3e1d709071bc83240b5.tar.gz
abc80sim-0a331bb8d9a34ab342acf3e1d709071bc83240b5.tar.xz
abc80sim-0a331bb8d9a34ab342acf3e1d709071bc83240b5.zip
tracing: allow trace output to be redirected to a file
This is convenient especially when running on Windows detached from a console, or some other environment where stdout can't be relied upon.
-rw-r--r--abc80.c73
-rw-r--r--abcio.c8
-rw-r--r--abcmem.c8
-rw-r--r--disk.c24
-rw-r--r--z80.c28
-rw-r--r--z80.h1
6 files changed, 84 insertions, 58 deletions
diff --git a/abc80.c b/abc80.c
index f2709f0..8b3a6a1 100644
--- a/abc80.c
+++ b/abc80.c
@@ -5,6 +5,7 @@
#include "z80.h"
#include "abcio.h"
#include "patchlevel.h"
+#include "abcprintd.h"
#include "hostfile.h"
#include <SDL_main.h>
@@ -83,32 +84,34 @@ static no_return help(void)
printf("Usage: %s [options] [ihex_files...]\n"
"Simulate a microcomputer from the Luxor ABC series.\n"
"\n"
- " --abc80 simulate an ABC80 (default)\n"
- " --abc802 simulate an ABC802\n"
- " -4, --40 start in 40-column mode\n"
- " -8, --80 start in 80-column mode\n"
- " -b, --no-basic no BASIC ROM (uninitialized RAM instead)\n"
- " -B, --basic reverts the --no-basic option\n"
- " -d, --no-device no device driver ROMs\n"
- " -D, --device reverts the --no-device option\n"
- " --old-basic ABC80 only: run BASIC 1.0 (checksum 11273)\n"
- " --11273 same as --old-basic\n"
- " --new-basic ABC80 only: run BASIC 1.2 (checksum 9913)\n"
- " --9913 same as --new-basic\n"
- " -t, --trace ... trace various events (see \"--trace help\")\n"
- " -v, --version print the version string\n"
- " -h, --help print this help message\n"
- " -k, --kb set the memory size in K (ABC80: 1-32 or 64)\n"
- " --diskdir set directory for disk images (default abcdisk)\n"
- " --filedir set directory for file sharing (default abcdir)\n"
- " --scrndir set directory for screen shots (default null)\n"
+ " --abc80 simulate an ABC80 (default)\n"
+ " --abc802 simulate an ABC802\n"
+ " -4, --40 start in 40-column mode\n"
+ " -8, --80 start in 80-column mode\n"
+ " -b, --no-basic no BASIC ROM (uninitialized RAM instead)\n"
+ " -B, --basic reverts the --no-basic option\n"
+ " -d, --no-device no device driver ROMs\n"
+ " -D, --device reverts the --no-device option\n"
+ " --old-basic ABC80 only: run BASIC 1.0 (checksum 11273)\n"
+ " --11273 same as --old-basic\n"
+ " --new-basic ABC80 only: run BASIC 1.2 (checksum 9913)\n"
+ " --9913 same as --new-basic\n"
+ " -t, --trace ... trace various events (see \"--trace help\")\n"
+ " -T, --tracefile ... redirect trace output to a file\n"
+ " -v, --version print the version string\n"
+ " -h, --help print this help message\n"
+ " -k, --kb # set the memory size in K (ABC80: 1-32 or 64)\n"
+ " --diskdir ... set directory for disk images (default abcdisk)\n"
+ " --filedir ... set directory for file sharing (default abcdir)\n"
+ " --scrndir ... set directory for screen shots (default null)\n"
+ " --printcmd ... set command to launch a print job (* = filename)\n"
"\n"
"The simulator supports the following hotkeys:\n"
- " Alt-q quit the simulator\n"
- " Alt-s take a screenshot\n"
- " Alt-r CPU reset\n"
- " Alt-n send NMI\n",
- program_name);
+ " Alt-q quit the simulator\n"
+ " Alt-s take a screenshot\n"
+ " Alt-r CPU reset\n"
+ " Alt-n send NMI\n"
+ , program_name);
exit(1);
}
@@ -194,6 +197,7 @@ int main(int argc, char **argv)
char **option;
const char *optstr;
char optchr;
+ const char *tracefile = NULL;
(void)argc;
program_name = argv[0];
@@ -242,12 +246,16 @@ int main(int argc, char **argv)
show_version();
} else if (!strcmp(optstr, "trace")) {
parse_trace(LONG_ARG());
+ } else if (!strcmp(optstr, "tracefile")) {
+ tracefile = LONG_ARG();
} else if (!strcmp(optstr, "diskdir")) {
disk_path = LONG_ARG();
} else if (!strcmp(optstr, "filedir")) {
fileop_path = LONG_ARG();
} else if (!strcmp(optstr, "scrndir")) {
screen_path = LONG_ARG();
+ } else if (!strcmp(optstr, "printcmd")) {
+ lpr_command = LONG_ARG();
} else {
fprintf(stderr, "%s: unknown option: --%s\n",
program_name, optstr);
@@ -260,6 +268,9 @@ int main(int argc, char **argv)
case 't':
parse_trace(SHORT_ARG());
break;
+ case 'T':
+ tracefile = SHORT_ARG();
+ break;
case 'b':
memflags |= MEMFL_NOBASIC;
break;
@@ -298,6 +309,20 @@ int main(int argc, char **argv)
}
}
+ if (tracing) {
+ if (!tracefile || !tracefile[0] ||
+ (tracefile[0] == '-' && !tracefile[1])) {
+ tracef = stdout;
+ } else {
+ tracef = fopen(tracefile, "wt");
+ if (!tracef) {
+ fprintf(stderr, "%s: Unable to open trace file %s: %s\n",
+ program_name, tracefile, strerror(errno));
+ tracing = 0;
+ }
+ }
+ }
+
hostfile_init();
screen_init(width40);
diff --git a/abcio.c b/abcio.c
index a987557..6e4a43e 100644
--- a/abcio.c
+++ b/abcio.c
@@ -240,8 +240,8 @@ static void (*do_out)(uint8_t, uint8_t);
void z80_out(int port, uint8_t value)
{
if (tracing & TRACE_IO) {
- printf("OUT: port 0x%02x (%3d) sel 0x%02x (%2d) data 0x%02x (%3d) PC=%04x\n",
- port, port, abcbus_select & 0xff, abcbus_select, value, value, REG_PC);
+ fprintf(tracef, "OUT: port 0x%02x (%3d) sel 0x%02x (%2d) data 0x%02x (%3d) PC=%04x\n",
+ port, port, abcbus_select & 0xff, abcbus_select, value, value, REG_PC);
}
do_out(port, value);
@@ -363,8 +363,8 @@ int z80_in(int port)
v = do_in(port);
if (tracing & TRACE_IO) {
- printf(" IN: port 0x%02x (%3d) sel 0x%02x (%2d) data 0x%02x (%3d) PC=%04x\n",
- port, port, sel, (int8_t)sel, v, v, REG_PC);
+ fprintf(tracef, " IN: port 0x%02x (%3d) sel 0x%02x (%2d) data 0x%02x (%3d) PC=%04x\n",
+ port, port, sel, (int8_t)sel, v, v, REG_PC);
}
return v;
}
diff --git a/abcmem.c b/abcmem.c
index 4207ab3..ace9094 100644
--- a/abcmem.c
+++ b/abcmem.c
@@ -89,16 +89,16 @@ void tracemem(void)
}
for (mtp = mem_traces; mtp < mem_trace_tail; mtp++) {
- putchar(' ');
+ fputc(' ', tracef);
if (mtp->addr != last_addr || mtp->written != last_written)
- printf("(%04X)%c", mtp->addr, mtp->written ? '=' : ':');
- printf("%0*X", mtp->size*2, mtp->data);
+ fprintf(tracef, "(%04X)%c", mtp->addr, mtp->written ? '=' : ':');
+ fprintf(tracef, "%0*X", mtp->size*2, mtp->data);
last_addr = mtp->addr + mtp->size;
last_written = mtp->written;
}
if (overflow)
- printf(" ...");
+ fputs(" ...", tracef);
mem_trace_tail = mem_traces;
}
diff --git a/disk.c b/disk.c
index bb8a846..6f7a761 100644
--- a/disk.c
+++ b/disk.c
@@ -208,11 +208,11 @@ void disk_out(int sel, int port, int value)
state->state = disk_k0;
if (tracing & TRACE_DISK) {
- printf("%s%d: command %02X %02X %02X %02X\n",
- state->name, state->k[1] & 7,
- state->k[0], state->k[1], state->k[2], state->k[3]);
- printf("PC = %04X BC = %04X DE = %04X HL = %04X\n",
- REG_PC, REG_BC, REG_DE, REG_HL);
+ fprintf(tracef, "%s%d: command %02X %02X %02X %02X\n",
+ state->name, state->k[1] & 7,
+ state->k[0], state->k[1], state->k[2], state->k[3]);
+ fprintf(tracef, "PC = %04X BC = %04X DE = %04X HL = %04X\n",
+ REG_PC, REG_BC, REG_DE, REG_HL);
}
/* Bad drive/sector? */
@@ -229,11 +229,11 @@ void disk_out(int sel, int port, int value)
case disk_upload:
state->buf[state->k[1] >> 6][state->out_ptr++] = value;
if (tracing & TRACE_DISK)
- printf("%02X", value);
+ fprintf(tracef, "%02X", value);
if ( state->out_ptr >= 256 ) {
if (tracing & TRACE_DISK)
- printf("\nPC = %04X BC = %04X DE = %04X HL = %04X\n",
- REG_PC, REG_BC, REG_DE, REG_HL);
+ fprintf(tracef, "\nPC = %04X BC = %04X DE = %04X HL = %04X\n",
+ REG_PC, REG_BC, REG_DE, REG_HL);
do_next_command(state);
}
break;
@@ -248,8 +248,8 @@ void disk_out(int sel, int port, int value)
case 2: /* Start command */
case 4: /* Reset */
if (tracing & TRACE_DISK) {
- printf("OUT %d/%d : ", sel, port);
- printf("PC = %04X BC = %04X DE = %04X HL = %04X\n",
+ fprintf(tracef, "OUT %d/%d : ", sel, port);
+ fprintf(tracef, "PC = %04X BC = %04X DE = %04X HL = %04X\n",
REG_PC, REG_BC, REG_DE, REG_HL);
}
disk_reset();
@@ -299,8 +299,8 @@ int disk_in(int sel, int port)
}
if (tracing & TRACE_DISK) {
- printf("IN %d/%d: %02X : ", sel, port, v);
- printf("PC = %04X BC = %04X DE = %04X HL = %04X\n",
+ fprintf(tracef, "IN %d/%d: %02X : ", sel, port, v);
+ fprintf(tracef, "PC = %04X BC = %04X DE = %04X HL = %04X\n",
REG_PC, REG_BC, REG_DE, REG_HL);
}
return v;
diff --git a/z80.c b/z80.c
index f4ac870..fb025cb 100644
--- a/z80.c
+++ b/z80.c
@@ -31,6 +31,7 @@
#include <setjmp.h>
unsigned int tracing;
+FILE *tracef;
/*
* The state of our Z-80 registers is kept in this structure:
@@ -1304,7 +1305,7 @@ static void do_nmi(void)
{
/* handle a non-maskable interrupt */
if (tracing & (TRACE_IO|TRACE_CPU)) {
- printf("NMI: PC=%02x\n", REG_PC);
+ fprintf(tracef, "NMI: PC=%02x\n", REG_PC);
}
REG_SP -= 2;
@@ -1320,9 +1321,9 @@ static void
do_int(void)
{
if (tracing & (TRACE_CPU | TRACE_IO)) {
- printf("INT: vector %02x (%3d) I=%02x PC=%04x\n",
- z80_state.i_vector, z80_state.i_vector,
- z80_state.i, REG_PC);
+ fprintf(tracef, "INT: vector %02x (%3d) I=%02x PC=%04x\n",
+ z80_state.i_vector, z80_state.i_vector,
+ z80_state.i, REG_PC);
}
switch (z80_state.interrupt_mode) {
@@ -2556,8 +2557,7 @@ int z80_run(bool continuous, bool halted)
if (tracing & TRACE_CPU) {
diffstate();
tracemem();
- putchar('\n');
- printf("PC=%04X ", z80_state.pc.word);
+ fprintf(tracef, "\nPC=%04X ", z80_state.pc.word);
disassemble(z80_state.pc.word);
}
@@ -3698,15 +3698,15 @@ z80_reset(void)
}
#define WREG(U,L) \
- if (z80_state.L.word != old_state.L.word) { \
- printf(" %s=%04X", #U, z80_state.L.word); \
- old_state.L.word = z80_state.L.word; \
+ if (z80_state.L.word != old_state.L.word) { \
+ fprintf(tracef, " %s=%04X", #U, z80_state.L.word); \
+ old_state.L.word = z80_state.L.word; \
}
-#define BREG(U,L) \
- if (z80_state.L != old_state.L) { \
- printf(" %s=%02X", #U, z80_state.L); \
- old_state.L= z80_state.L; \
- } \
+#define BREG(U,L) \
+ if (z80_state.L != old_state.L) { \
+ fprintf(tracef, " %s=%02X", #U, z80_state.L); \
+ old_state.L= z80_state.L; \
+ } \
static void diffstate(void)
{
diff --git a/z80.h b/z80.h
index 558e1dd..38cfd7c 100644
--- a/z80.h
+++ b/z80.h
@@ -189,6 +189,7 @@ extern int disassemble(int);
extern int DAsm(uint16_t pc, char *T, int *target);
extern unsigned int tracing;
+extern FILE *tracef;
#define TRACE_CPU 1
#define TRACE_IO 2