diff --git a/vimlac/memory.c b/vimlac/memory.c index d2c8ec9..3bfa084 100755 --- a/vimlac/memory.c +++ b/vimlac/memory.c @@ -74,18 +74,18 @@ mem_put(WORD address, bool indirect, WORD value) } void -mem_clear(void) +mem_clear(WORD value) { if (rom_readonly) { /* save the ROM contents */ WORD rom[ROM_SIZE]; memcpy(rom, &memory[ROM_START], sizeof(WORD)*ROM_SIZE); - memset(memory, 0, sizeof(WORD)*MEM_SIZE); + memset(memory, value, sizeof(WORD)*MEM_SIZE); memcpy(&memory[ROM_START], rom, sizeof(WORD)*ROM_SIZE); } else - memset(memory, 0, sizeof(WORD)*MEM_SIZE); + memset(memory, value, sizeof(WORD)*MEM_SIZE); } void diff --git a/vimlac/memory.h b/vimlac/memory.h index 181a20a..5f671f2 100755 --- a/vimlac/memory.h +++ b/vimlac/memory.h @@ -12,7 +12,7 @@ WORD mem_get(WORD address, bool indirect); void mem_put(WORD address, bool indirect, WORD value); -void mem_clear(void); +void mem_clear(WORD value); void mem_set_rom(WORD *rom); void mem_set_rom_readonly(bool readonly); void mem_load_core(char *filename); diff --git a/vimlac/plist.c b/vimlac/plist.c index 8588d75..2cf87b0 100644 --- a/vimlac/plist.c +++ b/vimlac/plist.c @@ -8,7 +8,7 @@ * * * PLIST PlistCreate(void); * * * - * void PListInsert(PLIST plist, char *name, char *value); * + * void PlistInsert(PLIST plist, char *name, char *value); * * * * void *PlistFind(PLIST plist, char *name); * * * @@ -92,7 +92,7 @@ Description : Function to insert new record into the property list. : New record placed in front of any existing equal record. ******************************************************************************/ void -PListInsert(PLIST plist, char *name, char *value) +PlistInsert(PLIST plist, char *name, char *value) { PList *hdr = (PList *) plist; @@ -164,7 +164,6 @@ PlistDestroy(PLIST plist) } -#ifdef DEBUG /****************************************************************************** Name : PlistDump() Description : Dump the plist to a specified open output FILE. @@ -192,4 +191,3 @@ PlistDump(PLIST plist, FILE *output) fprintf(output, " next: %p\n", hdr->next); } } -#endif diff --git a/vimlac/plist.h b/vimlac/plist.h index cafa530..e347f4a 100644 --- a/vimlac/plist.h +++ b/vimlac/plist.h @@ -23,12 +23,10 @@ typedef void *PLIST; ******/ PLIST PlistCreate(void); -void PListInsert(PLIST plist, char *name, char *value); +void PlistInsert(PLIST plist, char *name, char *value); char *PlistFind(PLIST plist, char *name); PLIST PlistDestroy(PLIST plist); -#ifdef DEBUG void PlistDump(PLIST plist, FILE *output); -#endif #endif diff --git a/vimlac/test_cpu.c b/vimlac/test_cpu.c index d34b93f..54a6418 100644 --- a/vimlac/test_cpu.c +++ b/vimlac/test_cpu.c @@ -62,6 +62,7 @@ #include "memory.h" #include "error.h" #include "log.h" +#include "plist.h" // string comparison macro @@ -71,6 +72,9 @@ const char *LstFilename = "_#TEST#_.lst"; // LST filename const char *AsmFilename = "_#TEST#_.asm"; // ASM filename +const int InitMemValue = 0; +const int InitRegValue = 0; + const int MaxLineSize = 4096; // max length of one script line // command structures @@ -100,14 +104,27 @@ bool DisplayOn = false; int UsedCycles = 0; WORD RegAllValue = 0; WORD MemAllValue = 0; -Assoc *RememberReg; +PLIST MemValues = NULL; +PLIST RegValues = NULL; +/****************************************************************************** +Description : Convert a string to upper case. + Parameters : str - address of string to convert + Returns : + Comments : The string is converted 'in situ'. + ******************************************************************************/ void -remember(Assoc *head, char *name, WORD value) +strupper(char *str) { + while (*str) + { + *str = toupper(*str); + ++str; + } } + /****************************************************************************** Description : Convert a string value into a WORD integer. Parameters : str - address of string holding [0-9] characters @@ -586,6 +603,9 @@ setmem(char *addr, char *fld2) mem_put(address, false, value); + PlistInsert(MemValues, addr, fld2); + PlistDump(MemValues, NULL); + return 0; } @@ -690,53 +710,68 @@ checkcycles(char *cycles, char *fld2) /****************************************************************************** Description : Check that a register contents is as expected. - Parameters : reg - string holding register name - : value - expected register value (string) + Parameters : reg - string holding register name + : expected - expected register value (string) Returns : The number of errors encountered (0 or 1). Comments : ******************************************************************************/ int -checkreg(char *reg, char *value) +checkreg(char *reg, char *expected) { - WORD val = str2word(value); + WORD exp = str2word(expected); + char buffer[32]; + + strupper(reg); - if (STREQ(reg, "ac")) + if (STREQ(reg, "AC")) { - remember(RememberReg, reg, cpu_get_AC()); - if (cpu_get_AC() != val) + WORD value = cpu_get_AC(); + + sprintf(buffer, "%d", value); + PlistInsert(RegValues, reg, buffer); + if (value != exp) { - vlog("AC is %07o, should be %07o", cpu_get_AC(), val); - printf("AC is %07o, should be %07o\n", cpu_get_AC(), val); + vlog("AC is %07o, should be %07o", value, exp); + printf("AC is %07o, should be %07o\n", value, exp); return 1; } } - else if (STREQ(reg, "l")) + else if (STREQ(reg, "L")) { - remember(RememberReg, reg, cpu_get_L()); - if (cpu_get_L() != val) + WORD value = cpu_get_L(); + + sprintf(buffer, "%d", value); + PlistInsert(RegValues, reg, buffer); + if (value != exp) { - vlog("L is %02o, should be %02o", cpu_get_L(), val); - printf("L is %02o, should be %02o\n", cpu_get_L(), val); + vlog("L is %02o, should be %02o", value, exp); + printf("L is %02o, should be %02o\n", value, exp); return 1; } } - else if (STREQ(reg, "pc")) + else if (STREQ(reg, "PC")) { - remember(RememberReg, reg, cpu_get_PC()); - if (cpu_get_PC() != val) + WORD value = cpu_get_PC(); + + sprintf(buffer, "%d", value); + PlistInsert(RegValues, reg, buffer); + if (value != exp) { - vlog("PC is %07o, should be %07o", cpu_get_PC(), val); - printf("PC is %07o, should be %07o\n", cpu_get_PC(), val); + vlog("PC is %07o, should be %07o", value, exp); + printf("PC is %07o, should be %07o\n", value, exp); return 1; } } - else if (STREQ(reg, "ds")) + else if (STREQ(reg, "DS")) { - remember(RememberReg, reg, cpu_get_DS()); - if (cpu_get_DS() != val) + WORD value = cpu_get_DS(); + + sprintf(buffer, "%d", value); + PlistInsert(RegValues, reg, buffer); + if (value != exp) { - vlog("DS is %07o, should be %07o", cpu_get_DS(), val); - printf("DS is %07o, should be %07o\n", cpu_get_DS(), val); + vlog("DS is %07o, should be %07o", value, exp); + printf("DS is %07o, should be %07o\n", value, exp); return 1; } } @@ -793,14 +828,35 @@ Description : Check that a memory address contents is as expected. Parameters : address - memory address to check (string) : value - expected memory value (string) Returns : The number of errors encountered (0 or 1). - Comments : + Comments : We check the MemValues plist first! ******************************************************************************/ int checkmem(char *address, char *value) { WORD adr = str2word(address); WORD val = str2word(value); - WORD memvalue = mem_get(adr, false); + WORD memvalue; + char *charvalue; + + printf("checkmem: address=%s, value=%s", address, value); + + // check the plist first + charvalue = PlistFind(MemValues, address); + if (charvalue) + { // in the plist, check value + memvalue = str2word(charvalue); + if (memvalue != val) + { + printf("Memory at address %07o is %07o, should be %07o\n", + adr, memvalue, val); + return 1; + } + + return 0; + } + + // now check actual memory + memvalue = mem_get(adr, false); if (memvalue != val) { @@ -853,10 +909,114 @@ checkrun(char *state, char *unused) } +/****************************************************************************** +Description : Check that memory values are as they should be. + Parameters : + Returns : The number of errors encountered. + Comments : Expected values shopuld be the global 'MemAllValue' or one of the + : values in the 'MemValues' plist. + ******************************************************************************/ +int +check_all_mem(void) +{ + int result = 0; + char buffer[32]; + + printf("check_all_mem: entered\n"); + + for (WORD adr = 0; adr < MEM_SIZE; ++adr) + { + WORD value = mem_get(adr, false); + sprintf(buffer, "%04o", adr); + char *expected = PlistFind(MemValues, buffer); + + if (adr == 0100) + { + printf("Checking %07o, PlistFind() returned %s for '%s'\n", + adr, expected, buffer); + PlistDump(MemValues, NULL); + } + + if (expected) + { + if (expected != buffer) + { + printf("Memory at %07o changed, is %07o, should be %07o\n", + adr, value, str2word(expected)); + result += 1; + } + } + else + { + if (value != MemAllValue) + { + printf("Memory at %07o changed, is %07o, should be %07o\n", + adr, value, MemAllValue); + result += 1; + } + } + } + + return result; +} + +/****************************************************************************** +Description : Check that a register value is as it should be. + Parameters : reg - register name + Returns : The number of errors encountered. + Comments : Expected values should be the value in 'RegValues' plist. + ******************************************************************************/ +int +check_reg(char *reg) +{ + char *expect_str = PlistFind(RegValues, reg); + WORD expect = str2word(expect_str); + WORD value; + + if (STREQ(reg, "AC")) value = cpu_get_AC(); + else if (STREQ(reg, "L")) value = cpu_get_L(); + else if (STREQ(reg, "PC")) value = cpu_get_PC(); + else if (STREQ(reg, "DS")) value = cpu_get_DS(); + else + { + printf("check_reg: bad register name '%s'\n", reg); + return 1; + } + + if (value != expect) + { + printf("Register %s has bad value, expected %07o got %07o\n", + reg, expect, value); + return 1; + } + + return 0; +} + + +/****************************************************************************** +Description : Check that register values are as they should be. + Parameters : + Returns : The number of errors encountered. + Comments : Expected values should be the value in 'RegValues' plist. + ******************************************************************************/ +int +check_all_regs(void) +{ + int result = 0; + + result += check_reg("AC"); + result += check_reg("L"); + result += check_reg("PC"); + result += check_reg("DS"); + + return result; +} + /****************************************************************************** Description : Run all commands in one test line. Parameters : test - pointer to a Test struct - Returns : The number of errors encountered (0 or 1). + Returns : The number of errors encountered. Comments : ******************************************************************************/ int @@ -865,6 +1025,20 @@ run_one_test(Test *test) int error = 0; char buffer[256]; + // set up memory/register value data structures + MemValues = PlistCreate(); + RegValues = PlistCreate(); + + // set memory and registers to known initial values + MemAllValue = InitMemValue; + mem_clear(InitMemValue); + + RegAllValue = InitRegValue; + cpu_set_AC(InitRegValue); + cpu_set_L(InitRegValue & 1); + cpu_set_PC(InitRegValue); + cpu_set_DS(InitRegValue); + for (Command *cmd = test->commands; cmd; cmd = cmd->next) { char *opcode = cmd->opcode; @@ -908,6 +1082,13 @@ run_one_test(Test *test) } } + // now check all memory and regs for changes + error += check_all_mem(); + error += check_all_regs(); + + // destroy any created data structures + MemValues = PlistDestroy(MemValues); + return error; } @@ -981,7 +1162,6 @@ execute(char *script) // get test commands into massaged form in memory test = parse_script(script); -#ifdef DEBUG // DEBUG - print contents of 'test' for (Test *tscan = test; tscan != NULL; tscan = tscan->next) { @@ -993,7 +1173,6 @@ execute(char *script) printf("\n"); fflush(stdout); } -#endif // execute tests return run(test); diff --git a/vimlac/test_memory.c b/vimlac/test_memory.c index 6ea694d..e69557b 100755 --- a/vimlac/test_memory.c +++ b/vimlac/test_memory.c @@ -17,7 +17,7 @@ main(int argc, char *argv[]) FILE *fd; // test the "memory clear" function - mem_clear(); + mem_clear(0); for (addr = 0; addr < MEM_SIZE; ++addr) assert(mem_get(addr, false) == 0); @@ -112,7 +112,7 @@ main(int argc, char *argv[]) // now save memory to a file mem_set_rom_readonly(false); - mem_clear(); + mem_clear(0); for (addr = 0; addr < MEM_SIZE; ++addr) mem_put(addr, false, addr); fd = fopen("imlac.core", "wb"); @@ -120,7 +120,7 @@ main(int argc, char *argv[]) fclose(fd); // clear memory and read core file back in - mem_clear(); + mem_clear(0); fd = fopen("imlac.core", "rb"); mem_load_core(fd); fclose(fd); diff --git a/vimlac/vimlac.c b/vimlac/vimlac.c index 9a8e76e..d8ccfa2 100755 --- a/vimlac/vimlac.c +++ b/vimlac/vimlac.c @@ -65,7 +65,7 @@ run(WORD pc) int main(void) { - mem_clear(); + mem_clear(0); mem_set_rom(PtrROMImage); ptr_mount("test_add.ptp"); run(040);