From 84efde070959e4c09b74187baa7cece3ba7bcd63 Mon Sep 17 00:00:00 2001 From: Ross Wilson Date: Thu, 15 Oct 2015 13:06:05 +0700 Subject: [PATCH] Working on C imlac simulator --- vimlac/Makefile | 6 ++-- vimlac/cpu.c | 2 +- vimlac/{vimlac.h => imlac.h} | 7 +++-- vimlac/memory.c | 54 ++++++++++++++++++++++++++++++++++-- vimlac/memory.h | 4 +-- vimlac/test_memory.c | 35 ++++++++++++----------- 6 files changed, 78 insertions(+), 30 deletions(-) rename vimlac/{vimlac.h => imlac.h} (79%) diff --git a/vimlac/Makefile b/vimlac/Makefile index 75e7a23..ecdad67 100644 --- a/vimlac/Makefile +++ b/vimlac/Makefile @@ -2,9 +2,9 @@ OFILES = vimlac.o cpu.o dcpu.o ptr.o ptp.o memory.o kb.o ttyin.o ttyout.o trace. CFLAGS=-shared -fPIC -O2 -Wall -ansi -pedantic -std=c99 -g -test: vimlac.py vimlac - #python vimlac.py -ptr test_add.ptp -r 040 -r 0100 - vimlac +#test: vimlac.py vimlac +# #python vimlac.py -ptr test_add.ptp -r 040 -r 0100 +# vimlac vimlac: ${OFILES} Makefile #gcc -o vimlac.so -shared -fPIC ${OFILES} diff --git a/vimlac/cpu.c b/vimlac/cpu.c index 1aa63f5..d0fd949 100755 --- a/vimlac/cpu.c +++ b/vimlac/cpu.c @@ -1485,7 +1485,7 @@ page00(WORD instruction) /****************************************************************************** Description : Function to execute one main processor instruction. Parameters : - Returns : + Returns : The number of cycles the instruction took. Comments : Perform initial decode of 5 bit opcode and either call : appropriate emulating function or call further decode function. ******************************************************************************/ diff --git a/vimlac/vimlac.h b/vimlac/imlac.h similarity index 79% rename from vimlac/vimlac.h rename to vimlac/imlac.h index 4c4174a..973e915 100644 --- a/vimlac/vimlac.h +++ b/vimlac/imlac.h @@ -1,12 +1,13 @@ /* - * Interface for the vimlac emulator. + * Global definitions for the imlac simulator. */ -#ifndef VIMLAC_H -#define VIMLAC_H +#ifndef IMLAC_H +#define IMLAC_H #include #include +#include #include #include #include diff --git a/vimlac/memory.c b/vimlac/memory.c index d2c8ec9..76a9b34 100644 --- a/vimlac/memory.c +++ b/vimlac/memory.c @@ -1,13 +1,14 @@ /* - * Implementation of vimlac memory. + * Implementation of memory for the imlac simulator. * * Memory size is a compile-time constant. - * The code here handles indirect memory references as will + * The code here handles indirect memory references as well * as the 8 auto-index registers at 010-017 in every 2K block. */ #include +#include "imlac.h" #include "memory.h" @@ -43,6 +44,14 @@ static WORD memory[MEM_SIZE]; #define AUTO_INDEX(a) (((a & INDEX_MASK) >= LOWER_INDEX) && ((a & INDEX_MASK) <= HIGHER_INDEX)) +/****************************************************************************** +Description : Get a word value from memory. + Parameters : address - the address to fetch from + : indirect - TRUE if the fetch is to be indirect + Returns : The word from memory. + Comments : If 'indirect' is TRUE 'address' is the address of a pointer to + : the word to fetch. + ******************************************************************************/ WORD mem_get(WORD address, bool indirect) { @@ -59,6 +68,15 @@ mem_get(WORD address, bool indirect) return result; } +/****************************************************************************** +Description : Put a word value into memory. + Parameters : address - the address to store to + : indirect - TRUE if the store is to be indirect + : value - the word value to place into memory + Returns : + Comments : If 'indirect' is TRUE 'address' is the address of a pointer to + : the word to store into. + ******************************************************************************/ void mem_put(WORD address, bool indirect, WORD value) { @@ -73,11 +91,17 @@ mem_put(WORD address, bool indirect, WORD value) memory[a & ADDR_MASK] = value; } +/****************************************************************************** +Description : Clear memory to zero words. + Parameters : + Returns : + Comments : If the ROM addresses are read-only, don't clear them. + ******************************************************************************/ void mem_clear(void) { if (rom_readonly) - { /* save the ROM contents */ + { /* save the ROM contents and restore after clear */ WORD rom[ROM_SIZE]; memcpy(rom, &memory[ROM_START], sizeof(WORD)*ROM_SIZE); @@ -88,6 +112,12 @@ mem_clear(void) memset(memory, 0, sizeof(WORD)*MEM_SIZE); } +/****************************************************************************** +Description : Set the ROM addresses to a particular ROM setting. + Parameters : rom - pointer to ROM_SIZE words of OM values + Returns : + Comments : Sets the ROM area as read-only. + ******************************************************************************/ void mem_set_rom(WORD *rom) { @@ -95,12 +125,24 @@ mem_set_rom(WORD *rom) memcpy(&memory[ROM_START], rom, sizeof(WORD)*ROM_SIZE); } +/****************************************************************************** +Description : Sets the ROM area to be protected or not. + Parameters : readonly - if TRUE the ROM area is protected + Returns : + Comments : + ******************************************************************************/ void mem_set_rom_readonly(bool readonly) { rom_readonly = readonly; } +/****************************************************************************** +Description : Load memory from a core save file. + Parameters : filename - pathname of file to load + Returns : + Comments : + ******************************************************************************/ void mem_load_core(char *filename) { @@ -122,6 +164,12 @@ mem_load_core(char *filename) fclose(fd); } +/****************************************************************************** +Description : Save memory to a core save file. + Parameters : filename - pathname of file to save to + Returns : + Comments : + ******************************************************************************/ void mem_save_core(char *filename) { diff --git a/vimlac/memory.h b/vimlac/memory.h index 181a20a..f97622d 100644 --- a/vimlac/memory.h +++ b/vimlac/memory.h @@ -1,11 +1,11 @@ /* - * Interface for the vimlac memory. + * Interface to the imlac memory routines. */ #ifndef MEMORY_H #define MEMORY_H -#include "vimlac.h" +#include "imlac.h" #define MEM_SIZE 0x4000 diff --git a/vimlac/test_memory.c b/vimlac/test_memory.c index 6ea694d..ed5caa3 100644 --- a/vimlac/test_memory.c +++ b/vimlac/test_memory.c @@ -5,7 +5,7 @@ #include #include -#include "vimlac.h" +#include "imlac.h" #include "memory.h" @@ -15,6 +15,7 @@ main(int argc, char *argv[]) WORD addr; WORD result; FILE *fd; + int errors = 0; // test the "memory clear" function mem_clear(); @@ -30,7 +31,7 @@ main(int argc, char *argv[]) { printf("A: mem_get(0x%04x) was 0x%04x, should be 0x%04x\n", addr, mem_get(addr, false), addr); - return 1; + errors += 1; } } @@ -44,7 +45,7 @@ main(int argc, char *argv[]) { printf("B: mem_get(0x%04x) was 0x%04x, should be 0x%04x\n", addr, mem_get(addr, false), addr); - return 1; + errors += 1; } } @@ -57,26 +58,26 @@ main(int argc, char *argv[]) if (result != 1) { printf("C: auto-index at address 010 not indirectly addressing\n"); - return 1; + errors += 1; } result = mem_get(010, false); if (result != 1) { printf("D: auto-index at address 010 not incrementing\n"); - return 1; + errors += 1; } mem_put(010, false, 0xffff); result = mem_get(010, true); if (result != 0) { printf("E: auto-index at address 010 not indirectly addressing\n"); - return 1; + errors += 1; } result = mem_get(010, false); if (result != 0) { printf("F: auto-index at address 010 not incrementing\n"); - return 1; + errors += 1; } // check 017, make sure address wrap-around works @@ -88,26 +89,26 @@ main(int argc, char *argv[]) if (result != 0) { printf("G: auto-index at address 017 not indirectly addressing\n"); - return 1; + errors += 1; } result = mem_get(017, false); if (result != 2) { printf("H: auto-index at address 017 not incrementing\n"); - return 1; + errors += 1; } mem_put(017, false, 0x3fff); result = mem_get(017, true); if (result != 2) { printf("I: auto-index at address 017 not indirectly addressing\n"); - return 1; + errors += 1; } result = mem_get(017, false); if (result != 0x4000) { printf("J: auto-index at address 017 not incrementing\n"); - return 1; + errors += 1; } // now save memory to a file @@ -115,24 +116,22 @@ main(int argc, char *argv[]) mem_clear(); for (addr = 0; addr < MEM_SIZE; ++addr) mem_put(addr, false, addr); - fd = fopen("imlac.core", "wb"); - mem_save_core(fd); - fclose(fd); + mem_save_core("imlac.core"); // clear memory and read core file back in mem_clear(); - fd = fopen("imlac.core", "rb"); - mem_load_core(fd); - fclose(fd); + mem_load_core("imlac.core"); for (addr = 0; addr < MEM_SIZE; ++addr) { if (mem_get(addr, false) != addr) { printf("K: mem_get(0x%04x) was 0x%04x, should be 0x%04x\n", addr, mem_get(addr, false), addr); - return 1; + errors += 1; } } + printf("%d errors found\n", errors); + return 0; }