diff --git a/vimlac/Makefile b/vimlac/Makefile index 7cc91a6..61fceaa 100755 --- a/vimlac/Makefile +++ b/vimlac/Makefile @@ -1,16 +1,16 @@ DEVFILES = cpu.o dcpu.o ptrptp.o memory.o kb.o ttyin.o ttyout.o trace.o error.o log.o plist.o bootstrap.o +HFILES = cpu.h dcpu.h ptrptp.h memory.h kb.h ttyin.h ttyout.h trace.h error.h log.h plist.h bootstrap.h OFILES = vimlac.o $(DEVFILES) -#CFLAGS=-fPIC -O2 -Wall -ansi -pedantic -std=c99 -g CFLAGS=-O2 -Wall -ansi -pedantic -std=c99 -g -test_cpu: test_cpu.c $(DEVFILES) Makefile - gcc -o test_cpu ${CFLAGS} $(DEVFILES) test_cpu.c - test: test_cpu rm -f vimlac.log ./test_cpu CPU.test +test_cpu: test_cpu.c $(DEVFILES) Makefile + gcc -o test_cpu ${CFLAGS} $(DEVFILES) test_cpu.c + vimlac: ${OFILES} Makefile gcc -o vimlac ${CFLAGS} ${OFILES} diff --git a/vimlac/error.c b/vimlac/error.c index 2669f99..341cea6 100644 --- a/vimlac/error.c +++ b/vimlac/error.c @@ -21,7 +21,7 @@ error(char *fmt, ...) va_start(ap, fmt); vsprintf(buff, fmt, ap); - fprintf(stderr, "%s\n", buff); + fprintf(stderr, "\n%s\n", buff); va_end(ap); exit(10); diff --git a/vimlac/ptrptp.c b/vimlac/ptrptp.c index af981f8..1699a5f 100755 --- a/vimlac/ptrptp.c +++ b/vimlac/ptrptp.c @@ -35,8 +35,6 @@ #define InUsePTR "PTR" #define InUsePTP "PTP" -#define STREQ(a, b) (strcmp((a), (b)) == 0) - /***** * State variables for the general device @@ -57,10 +55,21 @@ static bool ptr_at_eof = true; static BYTE ptr_value = PTR_EOF; +void ptrptp_reset(void) +{ + device_ready = false; + device_use = NULL; + device_motor_on = false; + device_open_file = NULL; + device_filename = NULL; + device_cycle_count = 0; +} + + int ptr_mount(char *fname) { - if (device_use && STREQ(device_use, InUsePTP)) + if (STREQ(device_use, InUsePTP)) error("ptr_mount: Can't mount PTR file, being used as PTP"); device_filename = fname; @@ -75,6 +84,7 @@ ptr_mount(char *fname) ptr_at_eof = false; ptr_value = PTR_EOF; device_cycle_count = PTR_NOT_PTR_READY_CYCLES; + device_use = InUsePTR; return 0; } @@ -83,7 +93,7 @@ ptr_mount(char *fname) void ptr_dismount(void) { - if (device_use && STREQ(device_use, InUsePTP)) + if (STREQ(device_use, InUsePTP)) error("ptr_mount: Can't dismount PTR file, being used as PTP"); if (device_open_file) @@ -94,14 +104,15 @@ ptr_dismount(void) device_ready = false; ptr_at_eof = true; ptr_value = PTR_EOF; + device_use = NULL; } void ptr_start(void) { - if (device_use && STREQ(device_use, InUsePTP)) - error("ptrptp_start: Can't start PTR motor, being used as PTP"); + if (STREQ(device_use, InUsePTP)) + error("ptrptp_start: Can't start PTR motor, being used as PTP, device_use=%s", device_use); device_motor_on = true; device_ready = false; @@ -112,7 +123,7 @@ ptr_start(void) void ptr_stop(void) { - if (device_use && STREQ(device_use, InUsePTP)) + if (STREQ(device_use, InUsePTP)) error("ptr_stop: Can't stop PTR motor, being used as PTP"); device_motor_on = false; @@ -124,7 +135,7 @@ ptr_stop(void) int ptr_read(void) { - if (device_use && STREQ(device_use, InUsePTP)) + if (STREQ(device_use, InUsePTP)) error("ptr_read: Can't read PTR, device being used as PTP"); return ptr_value; @@ -134,7 +145,6 @@ ptr_read(void) bool ptr_ready(void) { - vlog("ptr_ready: returning %s (%d)", (device_ready) ? "true" : "false", device_ready); return device_ready; } @@ -142,9 +152,8 @@ ptr_ready(void) void ptr_tick(long cycles) { - vlog("ptr_tick: (1) device_ready=%s (%d)", (device_ready) ? "true" : "false", device_ready); // if not being used as PTR, do nothing - if (device_use && !STREQ(device_use, InUsePTR)) + if (STREQ(device_use, InUsePTP)) return; /* if no state change */ @@ -155,27 +164,21 @@ ptr_tick(long cycles) device_cycle_count -= cycles; if (device_cycle_count <= 0L) { - vlog("ptr_tick: **** device_ready=%s (%d)", (device_ready) ? "true" : "false", device_ready); if (device_ready == true) { device_ready = false; device_cycle_count += PTR_NOT_PTR_READY_CYCLES; - ptr_value = 0; } else { device_ready = true; device_cycle_count += PTR_READY_CYCLES; if (fread(&ptr_value, sizeof(BYTE), 1, device_open_file) != 1) - { /* assume EOF on file, dismount tape */ -// fclose(device_open_file); -// device_open_file = NULL; + { /* EOF on file */ ptr_at_eof = true; ptr_value = PTR_EOF; } } - vlog("ptr_tick: device_cycle_count=%d, device_ready->%s (%d)", - device_cycle_count, (device_ready) ? "true" : "false", device_ready); } } @@ -184,8 +187,8 @@ ptr_tick(long cycles) int ptp_mount(char *fname) { - if (device_use && STREQ(device_use, InUsePTR)) - error("ptp_mount: Can't mount PTP, device being used as PTR"); + if (STREQ(device_use, InUsePTR)) + error("ptp_mount: Can't mount PTP, device being used as '%s'", device_use); device_use = InUsePTP; device_filename = fname; @@ -206,7 +209,7 @@ ptp_mount(char *fname) void ptp_dismount(void) { - if (device_use && STREQ(device_use, InUsePTR)) + if (STREQ(device_use, InUsePTR)) error("ptp_dismount: Can't dismount PTP, device being used as PTR"); if (device_open_file) @@ -221,6 +224,9 @@ ptp_dismount(void) void ptp_start(void) { + if (STREQ(device_use, InUsePTR)) + error("ptp_dismount: Can't start PTP, device being used as PTR"); + device_motor_on = true; device_ready = false; device_cycle_count = PTP_NOT_READY_CYCLES; @@ -230,6 +236,9 @@ ptp_start(void) void ptp_stop(void) { + if (STREQ(device_use, InUsePTR)) + error("ptp_stop: Can't stop PTP, device being used as PTR"); + device_motor_on = false; device_cycle_count = PTP_NOT_READY_CYCLES; } @@ -238,6 +247,9 @@ ptp_stop(void) void ptp_punch(BYTE value) { + if (STREQ(device_use, InUsePTR)) + error("ptp_punch: Can't punch PTP, device being used as PTR"); + if (device_motor_on && device_open_file != NULL) { putc(value, device_open_file); @@ -256,11 +268,14 @@ ptp_ready(void) void ptp_tick(long cycles) { - /* if no state change */ - if (!device_motor_on || device_open_file == NULL) + if (STREQ(device_use, InUsePTR)) + return; + + /* if no mounted file */ + if (device_open_file == NULL) return; - /* tape in, motor on */ + /* tape in */ device_cycle_count -= cycles; if (device_cycle_count <= 0L) { diff --git a/vimlac/ptrptp.h b/vimlac/ptrptp.h index 35c7deb..8c7ac31 100755 --- a/vimlac/ptrptp.h +++ b/vimlac/ptrptp.h @@ -5,6 +5,7 @@ #ifndef PTRPTP_H #define PTRPTP_H +void ptrptp_reset(void); int ptr_mount(char *fname); void ptr_dismount(void); void ptr_start(void); diff --git a/vimlac/test_cpu.c b/vimlac/test_cpu.c index b1c0df5..71cb16f 100644 --- a/vimlac/test_cpu.c +++ b/vimlac/test_cpu.c @@ -25,9 +25,6 @@ #include "trace.h" -// string comparison macro -#define STREQ(a, b) (strcmp((a), (b)) == 0) - // constants const char *LstFilename = "_#TEST#_.lst"; // LST filename const char *AsmFilename = "_#TEST#_.asm"; // ASM filename @@ -705,6 +702,59 @@ mount(char *device, char *filename) } +/****************************************************************************** +Description : Dismount a file on a device. + Parameters : device - a device name ("PTR", "PTP", "TTYIN" or "TTYOUT") + : ignore - unused + Returns : The number of errors encountered (0 or 1). + Comments : + ******************************************************************************/ +int +dismount(char *device, char *ignore) +{ +// strupper(device); + + if (STREQ(device, "PTR")) + ptr_dismount(); + else if (STREQ(device, "PTP")) + ptp_dismount(); + else + { + vlog("dismount: device name not recognized: %s", device); + return 1; + } + + return 0; +} + + +/****************************************************************************** +Description : Checkk that two files are identical. + Parameters : file1, file2 - files to check + Returns : The number of errors encountered (0 or 1). + Comments : + ******************************************************************************/ +int +checkfile(char *file1, char *file2) +{ + char buffer[1024]; + + strlower(file1); + strlower(file2); + + // assemble the file + sprintf(buffer, "cmp %s %s >/dev/null 2>&1", file1, file2); + printf("%s\n", buffer); + if (system(buffer) == -1) + { + vlog("checkfile: files '%s' and '%s' differ", file1, file2); + return 1; + } + + return 0; +} + + /****************************************************************************** Description : Check that a memory address contents is as expected. Parameters : address - memory address to check (string) @@ -862,20 +912,16 @@ assemble(WORD addr, char *opcodes) char *new_strcopy; int num_opcodes = 0; - vlog("assemble: addr=%07o, opcodes=%s", addr, opcodes); - // create the ASM file fd = fopen(AsmFilename, "wb"); fprintf(fd, "\torg\t%07o\n", addr); while ((new_strcopy = split(strcopy, '|'))) { - vlog("assemble: code=%s", strcopy); fprintf(fd, "\t%s\n", strcopy); ++num_opcodes; strcopy = new_strcopy; } // handle last opcode - vlog("assemble: code=%s", strcopy); fprintf(fd, "\t%s\n", strcopy); ++num_opcodes; @@ -883,8 +929,6 @@ assemble(WORD addr, char *opcodes) fclose(fd); free(old_strcopy); - vlog("assemble: num_opcodes=%d", num_opcodes); - // assemble the file sprintf(buffer, "../iasm/iasm -l %s %s", LstFilename, AsmFilename); if (system(buffer) == -1) @@ -910,7 +954,6 @@ assemble(WORD addr, char *opcodes) // read first word value if (sscanf(buffer, "%o", &new_opcode->opcode) != 1) error("Badly formatted assembler output: %s", buffer); - vlog("assemble: assembly output: %07o", new_opcode->opcode); // add binary opcode to end of result list if (result == NULL) @@ -1016,7 +1059,6 @@ parse_one_cmd(char *scan) v = v->next; } field2 = tmpbuff+1; - vlog("parse_one_cmd: field2=%s", field2); } else { @@ -1314,6 +1356,8 @@ run_one_test(Test *test) UsedCycles = 0; + ptrptp_reset(); + trace_open(); for (Command *cmd = test->commands; cmd; cmd = cmd->next) @@ -1357,6 +1401,10 @@ run_one_test(Test *test) error += checkcpu(fld1, fld2); else if (STREQ(opcode, "MOUNT")) error += mount(fld1, fld2); + else if (STREQ(opcode, "DISMOUNT")) + error += dismount(fld1, fld2); + else if (STREQ(opcode, "CHECKFILE")) + error += checkfile(fld1, fld2); else { printf("Unrecognized operation '%s' at line %d\n", @@ -1433,7 +1481,7 @@ run_tests(Test *test) test = test->next; } - printf("\r"); + printf("\n"); fflush(stdout); return errors; diff --git a/vimlac/vimlac.h b/vimlac/vimlac.h index 4c4174a..84b610c 100755 --- a/vimlac/vimlac.h +++ b/vimlac/vimlac.h @@ -12,6 +12,9 @@ #include #include +#include "error.h" + + typedef unsigned int WORD; typedef unsigned char BYTE; @@ -22,7 +25,11 @@ typedef unsigned char BYTE; #define OVERFLOWMASK 0x10000 #define LOWBITMASK 0x1 +// macro to convert a boolean value to a string +#define BOOL2STR(a) ((a) ? "true" : "false") + +// macro to more reliably compare strings +#define STREQ(a, b) ((a) && (strcmp((a), (b)) == 0)) -void error(char *msg, ...); #endif