diff --git a/vimlac/.gitignore b/vimlac/.gitignore deleted file mode 100644 index 9e1c672..0000000 --- a/vimlac/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -test_memory -test_cpu diff --git a/vimlac/Makefile b/vimlac/Makefile old mode 100644 new mode 100755 index 4bb3c53..6716369 --- a/vimlac/Makefile +++ b/vimlac/Makefile @@ -1,20 +1,15 @@ -OFILES=cpu.o dcpu.o ptr.o ptp.o memory.o kbd.o ttyin.o ttyout.o trace.o -CFILES=cpu.c dcpu.c ptr.c ptp.c memory.c kbd.c ttyin.c ttyout.c trace.c error.c -HFILES=cpu.h dcpu.h ptr.h ptp.h memory.h kbd.h ttyin.h ttyout.h trace.h error.h +OFILES = vimlac.o cpu.o dcpu.o ptr.o ptp.o memory.o kb.o ttyin.o ttyout.o trace.o 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} gcc -o vimlac ${OFILES} -test_cpu: test_cpu.c $(CFILES) $(HFILES) Makefile - gcc -o test_cpu test_cpu.c $(CFILES) - test_ptr: test_ptr.c ptr.c ptr.h Makefile gcc -o test_ptr ptr.c test_ptr.c diff --git a/vimlac/cpu.c b/vimlac/cpu.c index eae29d8..1aa63f5 100755 --- a/vimlac/cpu.c +++ b/vimlac/cpu.c @@ -6,11 +6,11 @@ * * \******************************************************************************/ -#include "imlac.h" +#include "vimlac.h" #include "cpu.h" #include "dcpu.h" #include "memory.h" -#include "kbd.h" +#include "kb.h" #include "ptr.h" #include "ptp.h" #include "ttyin.h" @@ -492,7 +492,7 @@ Description : Emulate the DSF instruction. static int i_DSF(void) { - if (dcpu_running()) + if (dcpu_on()) r_PC = (r_PC + 1) & WORD_MASK; trace("DSF\t"); @@ -529,7 +529,7 @@ Description : Emulate the DSN instruction. static int i_DSN(void) { - if (!dcpu_running()) + if (!dcpu_on()) r_PC = (r_PC + 1) & WORD_MASK; trace("DSN\t"); @@ -585,7 +585,7 @@ Description : Emulate the IMLAC KCF instruction. static int i_KCF(void) { - kbd_clear_flag(); + kb_clear_flag(); trace("KCF\t"); @@ -602,7 +602,7 @@ Description : Emulate the IMLAC KRB instruction. static int i_KRB(void) { - r_AC |= kbd_get_char(); + r_AC |= kb_get_char(); trace("KRB\t"); @@ -619,8 +619,8 @@ Description : Emulate the IMLAC KRC instruction. static int i_KRC(void) { - r_AC |= kbd_get_char(); - kbd_clear_flag(); + r_AC |= kb_get_char(); + kb_clear_flag(); trace("KRC\t"); @@ -637,7 +637,7 @@ Description : Emulate the IMLAC KSF instruction. static int i_KSF(void) { - if (kbd_ready()) + if (kb_ready()) r_PC = (r_PC + 1) & WORD_MASK; trace("KSF\t"); @@ -655,7 +655,7 @@ Description : Emulate the IMLAC KSN instruction. static int i_KSN(void) { - if (!kbd_ready()) + if (!kb_ready()) r_PC = (r_PC + 1) & WORD_MASK; trace("KSN\t"); @@ -673,9 +673,7 @@ Description : Emulate the IMLAC PUN instruction. static int i_PUN(void) { - char value = r_AC & 0xff; - - ptp_punch(value); + ptp_punch(r_AC & 0xff); trace("PUN\t"); @@ -939,9 +937,7 @@ Description : Emulate the IMLAC TPC instruction. static int i_TPC(void) { - BYTE value = r_AC & 0xff; - - ttyout_send(value); + ttyout_send(r_AC & 0xff); ttyout_clear_flag(); trace("TPC\t"); @@ -1120,7 +1116,7 @@ Description : Emulate the IMLAC DLA instruction. static int i_DLA(void) { - dcpu_set_DPC(r_AC); + dcpu_set_PC(r_AC); trace("DLA\t"); @@ -1489,7 +1485,7 @@ page00(WORD instruction) /****************************************************************************** Description : Function to execute one main processor instruction. Parameters : - Returns : The number of cycles the instruction took. + Returns : Comments : Perform initial decode of 5 bit opcode and either call : appropriate emulating function or call further decode function. ******************************************************************************/ diff --git a/vimlac/cpu.h b/vimlac/cpu.h index e532e06..93b34b2 100755 --- a/vimlac/cpu.h +++ b/vimlac/cpu.h @@ -1,15 +1,12 @@ /******************************************************************************\ * cpu.h * * ------- * - * * - * Implements all main CPU instructions. * - * * \******************************************************************************/ #ifndef CPU_H #define CPU_H -#include "imlac.h" +#include "vimlac.h" /****** * Exported functions. diff --git a/vimlac/dcpu.c b/vimlac/dcpu.c index 9ead4ed..e9c0ae4 100755 --- a/vimlac/dcpu.c +++ b/vimlac/dcpu.c @@ -1,105 +1,56 @@ /******************************************************************************\ - * dcpu.c * - * -------- * + * dcpu.c * + * ------- * * * * This file is used to decode and execute a display processor instruction. * * * \******************************************************************************/ -#include "imlac.h" +#include "vimlac.h" #include "dcpu.h" #include "memory.h" -#include "trace.h" /****** * Emulated registers, state, memory, etc. ******/ -static WORD r_DPC; -static WORD Prev_r_DPC; -static WORD DRSindex = 0; +static WORD r_PC; +static WORD Prev_r_PC; +static int r_DRSindex; -/* 40Hz sync stuff */ -static bool Sync40HzOn = false; /****** * Environment stuff. PTR and TTY in and out files, etc ******/ -static bool dcpu_on; /* true if display processor is running */ -static bool dcpu_sync_on; /* true if 40HZ flag set */ +static bool cpu_is_on; /* true if display processor is running */ /****************************************************************************** -Description : Function to get the display CPU status. - Parameters : - Returns : - Comments : - ******************************************************************************/ -bool -dcpu_running(void) -{ - return dcpu_on == true; -} - - -/****************************************************************************** -Description : Function to start the display CPU. - Parameters : - Returns : - Comments : - ******************************************************************************/ -void -dcpu_start(void) -{ - dcpu_on = true; -} - - -/****************************************************************************** -Description : Function to stop the display CPU. - Parameters : - Returns : - Comments : - ******************************************************************************/ -void -dcpu_stop(void) -{ - dcpu_on = false; -} - - -/****************************************************************************** -Description : Functions to get various registers. +Description : Functions to get/set various registers. Parameters : Returns : Comments : ******************************************************************************/ WORD -dcpu_get_DPC(void) +dcpu_get_PC(void) { - return r_DPC; -} - - -WORD -dcpu_get_prev_DPC(void) -{ - return Prev_r_DPC; + return r_PC; } void -dcpu_set_DPC(WORD new_dpc) +dcpu_set_PC(WORD value) { - r_DPC = new_dpc; + r_PC = value; } + void -dcpu_set_DRSindex(WORD drsindex) +dcpu_set_DRSindex(int value) { - DRSindex = drsindex; + r_DRSindex = value; } @@ -112,55 +63,44 @@ Description : Function to handle unrecognized instruction. static void illegal(void) { - WORD oldDPC = Prev_r_DPC & MEMMASK; + WORD oldPC = Prev_r_PC & MEMMASK; + +/* memdump(LogOut, oldPC - 8, 16); */ error("INTERNAL ERROR: " - "unexpected display processor opcode %06.6o at address %06.6o", - mem_get(oldDPC, false), oldDPC); -} - - -/****************************************************************************** -Description : - Parameters : - Returns : - Comments : - ******************************************************************************/ -static int -i_LAW_LWC(bool indirect, WORD address) -{ - return 1; + "unexpected main processor opcode %06.6o at address %06.6o", + mem_get(oldPC, false), oldPC); } /****************************************************************************** Description : Function to execute one display processor instruction. Parameters : - Returns : The number of cycles the instruction took. + Returns : Comments : ******************************************************************************/ int dcpu_execute_one(void) { - WORD instruction; - WORD opcode; - WORD address; - bool indirect; + WORD instruction = 0; + bool indirect = false; + WORD opcode = 0; + WORD address = 0; /****** - * If main processor not running, return immediately. + * If processor not running, return immediately. ******/ - if (!dcpu_on) + if (!cpu_is_on) return 0; /****** * Fetch the instruction. Split into initial opcode and address. ******/ - Prev_r_DPC = r_DPC; - instruction = mem_get(r_DPC++, false); - r_DPC = r_DPC & MEMMASK; + Prev_r_PC = r_PC; + instruction = mem_get(r_PC++, false); + r_PC = r_PC & MEMMASK; indirect = (bool) (instruction & 0100000); /* high bit set? */ opcode = (instruction >> 11) & 017; /* high 5 bits */ @@ -170,12 +110,70 @@ dcpu_execute_one(void) * Now decode it. ******/ +#ifdef JUNK switch (opcode) { - default: illegal(); } +#endif + ++instruction; + indirect = !indirect; + ++opcode; + ++address; + illegal(); - return 0; /* CAN'T REACH */ + return 0; +} + + +/****************************************************************************** +Description : Function to get CPU state. + Parameters : + Returns : + Comments : + ******************************************************************************/ +bool +dcpu_on(void) +{ + return cpu_is_on; +} + + +/****************************************************************************** +Description : Function to start the CPU. + Parameters : + Returns : + Comments : + ******************************************************************************/ +void +dcpu_start(void) +{ + cpu_is_on = true; +} + + +/****************************************************************************** +Description : Function to stop the CPU. + Parameters : + Returns : + Comments : + ******************************************************************************/ +void +dcpu_stop(void) +{ + cpu_is_on = false; +} + + +/****************************************************************************** +Description : Function to stop the CPU. + Parameters : + Returns : + Comments : + ******************************************************************************/ +void +dcpu_set_drsindex(int index) +{ + r_DRSindex = index; } diff --git a/vimlac/dcpu.h b/vimlac/dcpu.h index d602f2d..055441f 100755 --- a/vimlac/dcpu.h +++ b/vimlac/dcpu.h @@ -1,28 +1,24 @@ /******************************************************************************\ - * dcpu.h * - * -------- * - * * - * Implements all display CPU instructions. * - * * + * dcpu.h * + * -------- * \******************************************************************************/ #ifndef DCPU_H #define DCPU_H -#include "imlac.h" +#include "vimlac.h" /****** * Exported functions. ******/ -bool dcpu_running(void); void dcpu_start(void); void dcpu_stop(void); -void dcpu_set_DRSindex(WORD); int dcpu_execute_one(void); -WORD dcpu_get_AC(void); -WORD dcpu_get_DPC(void); -WORD dcpu_get_prev_DPC(void); -void dcpu_set_DPC(WORD dpc); +WORD dcpu_get_PC(void); +void dcpu_set_PC(WORD value); +void dcpu_set_DRSindex(int index); +bool dcpu_on(void); + #endif diff --git a/vimlac/error.c b/vimlac/error.c deleted file mode 100644 index d3b0bc8..0000000 --- a/vimlac/error.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Error routines for the imlac simulator. - */ - -#include -#include -#include - - -/****************************************************************************** -Description : printf()-style trace routine. - Parameters : like printf() - Returns : - Comments : - ******************************************************************************/ -void -error(char *fmt, ...) -{ - va_list ap; - char buff[1024]; - - va_start(ap, fmt); - vsprintf(buff, fmt, ap); - fprintf(stderr, "%s\n", buff); - va_end(ap); - - exit(10); -} - - diff --git a/vimlac/error.h b/vimlac/error.h deleted file mode 100644 index 36720ed..0000000 --- a/vimlac/error.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Error routines for the imlac simulation. - */ - -#ifndef ERROR_H -#define ERROR_H - -void error(char *fmt, ...); - -#endif diff --git a/vimlac/imlac.h b/vimlac/imlac.h deleted file mode 100644 index 973e915..0000000 --- a/vimlac/imlac.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Global definitions for the imlac simulator. - */ - -#ifndef IMLAC_H -#define IMLAC_H - -#include -#include -#include -#include -#include -#include -#include - -typedef unsigned int WORD; -typedef unsigned char BYTE; - -#define CPU_HERZ 1800000 -#define MEMMASK 0xffff -#define HIGHBITMASK 0x8000 -#define WORD_MASK 0xffff -#define OVERFLOWMASK 0x10000 -#define LOWBITMASK 0x1 - - -void error(char *msg, ...); - -#endif diff --git a/vimlac/kbd.c b/vimlac/kbd.c deleted file mode 100755 index a9f0304..0000000 --- a/vimlac/kbd.c +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************\ - * kbd.c * - * ------- * - * * - * This file is used to implement a KBD device (keyboard). * - * * -\******************************************************************************/ - -#include "imlac.h" -#include "kbd.h" -#include "trace.h" - - -/****** - * Emulated registers, state, memory, etc. - ******/ - -static WORD state_KBD; -static bool clear = false; - - -/****************************************************************************** -Description : Clear the KBD (keyboard) flag. - Parameters : - Returns : - Comments : - ******************************************************************************/ -void -kbd_clear_flag(void) -{ - clear = false; -} - -/****************************************************************************** -Description : Get the character in the keyboard buffer. - Parameters : - Returns : - Comments : - ******************************************************************************/ -WORD -kbd_get_char(void) -{ - return 'a'; -} - -/****************************************************************************** -Description : Test if the keyboard is ready with the next character. - Parameters : - Returns : - Comments : - ******************************************************************************/ -bool -kbd_ready(void) -{ - return !clear; -} - - diff --git a/vimlac/kbd.h b/vimlac/kbd.h deleted file mode 100755 index fa87a3a..0000000 --- a/vimlac/kbd.h +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************\ - * kbd.h * - * ------- * - * * - * Implements all display CPU instructions. * - * * -\******************************************************************************/ - -#ifndef KBD_H -#define KBD_H - -#include "imlac.h" - -/****** - * Exported functions. - ******/ - - -void kbd_clear_flag(void); -WORD kbd_get_char(void); -bool kbd_ready(void); - - -#endif diff --git a/vimlac/memory.c b/vimlac/memory.c old mode 100644 new mode 100755 index 76a9b34..d2c8ec9 --- a/vimlac/memory.c +++ b/vimlac/memory.c @@ -1,14 +1,13 @@ /* - * Implementation of memory for the imlac simulator. + * Implementation of vimlac memory. * * Memory size is a compile-time constant. - * The code here handles indirect memory references as well + * The code here handles indirect memory references as will * as the 8 auto-index registers at 010-017 in every 2K block. */ #include -#include "imlac.h" #include "memory.h" @@ -44,14 +43,6 @@ 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) { @@ -68,15 +59,6 @@ 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) { @@ -91,17 +73,11 @@ 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 and restore after clear */ + { /* save the ROM contents */ WORD rom[ROM_SIZE]; memcpy(rom, &memory[ROM_START], sizeof(WORD)*ROM_SIZE); @@ -112,12 +88,6 @@ 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) { @@ -125,24 +95,12 @@ 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) { @@ -164,12 +122,6 @@ 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 old mode 100644 new mode 100755 index f97622d..181a20a --- a/vimlac/memory.h +++ b/vimlac/memory.h @@ -1,11 +1,11 @@ /* - * Interface to the imlac memory routines. + * Interface for the vimlac memory. */ #ifndef MEMORY_H #define MEMORY_H -#include "imlac.h" +#include "vimlac.h" #define MEM_SIZE 0x4000 diff --git a/vimlac/ptp.c b/vimlac/ptp.c old mode 100644 new mode 100755 index 503ce76..191b784 --- a/vimlac/ptp.c +++ b/vimlac/ptp.c @@ -1,25 +1,23 @@ /* - * Implementation for the imlac PTP (papertape punch) device. + * Implementation for the vimlac PTP (papertape punch). */ -#include "imlac.h" +#include "vimlac.h" #include "ptp.h" /***** * constants for the PTP device * - * The device punches at 100 chars/second, so we work out how many imlac - * machine cycles data is ready/notready at a 30%/70% ready cycle. + * The device punches at 300 chars/second, so we work out how many + * machine cycles device is not ready after punch starts. ******/ -#define CHARS_PER_SECOND 100 -#define CYCLES_PER_CHAR (CPU_HERZ / CHARS_PER_SECOND) -#define READY_CYCLES (int)((3 * CYCLES_PER_CHAR) / 10) -#define NOT_READY_CYCLES (int)((7 * CYCLES_PER_CHAR) / 10) +#define CHARS_PER_SECOND 300 +#define NOT_READY_CYCLES (int) (CPU_HERZ / CHARS_PER_SECOND) /***** - * State variables for the PTP device + * State variables for the PTR device ******/ static bool motor_on = false; @@ -27,16 +25,8 @@ static bool device_ready = false; static FILE *open_file; static char *filename = NULL; static long cycle_count = 0; -static char value = 0; - -/****************************************************************************** -Description : Mount a papertape file on the PTP device - Parameters : fname - pathname of the file to mount - Returns : 0 if no error, else status code. - Comments : - ******************************************************************************/ int ptp_mount(char *fname) { filename = fname; @@ -54,12 +44,6 @@ int ptp_mount(char *fname) } -/****************************************************************************** -Description : Dismount papertape file from device. - Parameters : - Returns : - Comments : Turns motor off. - ******************************************************************************/ void ptp_dismount(void) { if (open_file) @@ -67,16 +51,10 @@ void ptp_dismount(void) filename = NULL; open_file = NULL; motor_on = false; - device_ready = false; + device_ready = true; } -/****************************************************************************** -Description : Start the papertape device motor. - Parameters : - Returns : - Comments : We don't check if papertape mounted as the real imlac doesn't. - ******************************************************************************/ void ptp_start(void) { motor_on = true; @@ -85,50 +63,29 @@ void ptp_start(void) } -/****************************************************************************** -Description : Turn the papertape device motor off. - Parameters : - Returns : - Comments : - ******************************************************************************/ void ptp_stop(void) { motor_on = false; - device_ready = false; cycle_count = NOT_READY_CYCLES; } -/****************************************************************************** -Description : Write the current value to the papertape punch file. - Parameters : - Returns : - Comments : - ******************************************************************************/ -int ptp_punch(BYTE value) +void ptp_punch(BYTE value) { - return value; + if (motor_on && open_file != NULL) + { + putc(value, open_file); + cycle_count = NOT_READY_CYCLES; + } } -/****************************************************************************** -Description : Get the papertape device status. - Parameters : - Returns : TRUE if device ready, else FALSE. - Comments : - ******************************************************************************/ bool ptp_ready(void) { return device_ready; } -/****************************************************************************** -Description : Tick the state machine along a bit. - Parameters : cycles - number of imlac cycles that have elapsed - Returns : - Comments : - ******************************************************************************/ void ptp_tick(long cycles) { /* if no state change */ @@ -139,21 +96,8 @@ void ptp_tick(long cycles) cycle_count -= cycles; if (cycle_count <= 0L) { - if (device_ready) - { - device_ready = false; - cycle_count += NOT_READY_CYCLES; - value = 0; - } - else - { + if (!device_ready) device_ready = true; - cycle_count += READY_CYCLES; - if (fread(&value, sizeof(BYTE), 1, open_file) != 1) - { /* assume EOF on file, dismount tape */ - fclose(open_file); - open_file = NULL; - } - } + cycle_count = 0; } } diff --git a/vimlac/ptp.h b/vimlac/ptp.h old mode 100644 new mode 100755 index 3c3c944..9443213 --- a/vimlac/ptp.h +++ b/vimlac/ptp.h @@ -1,5 +1,5 @@ /* - * Interface for the imlac PTP (papertape punch). + * Interface for the vimlac PTP (papertape punch). */ #ifndef PTP_H @@ -9,8 +9,8 @@ int ptp_mount(char *fname); void ptp_dismount(void); void ptp_start(void); void ptp_stop(void); -int ptp_punch(BYTE value); -bool ptp_ready(void); +void ptp_punch(BYTE byte); void ptp_tick(long cycles); +bool ptp_ready(void); #endif diff --git a/vimlac/ptr.c b/vimlac/ptr.c old mode 100644 new mode 100755 index a7ce533..41fb647 --- a/vimlac/ptr.c +++ b/vimlac/ptr.c @@ -1,15 +1,15 @@ /* - * Implementation for the imlac PTR (papertape reader) device. + * Implementation for the vimlac PTR (papertape reader). */ -#include "imlac.h" +#include "vimlac.h" #include "ptr.h" /***** * constants for the PTR device * - * The device reads at 300 chars/second, so we work out how many imlac + * The device reads at 300 chars/second, so we work out how many * machine cycles data is ready/notready at a 30%/70% ready cycle. ******/ @@ -33,13 +33,6 @@ static BYTE value = PTR_EOF; static long cycle_count = 0; - -/****************************************************************************** -Description : Mount a papertape file on the PTR device - Parameters : fname - pathname of the file to mount - Returns : 0 if no error, else status code. - Comments : - ******************************************************************************/ int ptr_mount(char *fname) { filename = fname; @@ -59,12 +52,6 @@ int ptr_mount(char *fname) } -/****************************************************************************** -Description : Dismount papertape file from device. - Parameters : - Returns : - Comments : Turns motor off. - ******************************************************************************/ void ptr_dismount(void) { if (open_file) @@ -78,12 +65,6 @@ void ptr_dismount(void) } -/****************************************************************************** -Description : Start the papertape device motor. - Parameters : - Returns : - Comments : We don't check if papertape mounted as the real imlac doesn't. - ******************************************************************************/ void ptr_start(void) { motor_on = true; @@ -92,12 +73,6 @@ void ptr_start(void) } -/****************************************************************************** -Description : Turn the papertape device motor off. - Parameters : - Returns : - Comments : - ******************************************************************************/ void ptr_stop(void) { motor_on = false; @@ -105,36 +80,18 @@ void ptr_stop(void) } -/****************************************************************************** -Description : Read the current value of the papertape device. - Parameters : - Returns : - Comments : - ******************************************************************************/ int ptr_read(void) { return value; } -/****************************************************************************** -Description : Get the papertape device status. - Parameters : - Returns : TRUE if device ready, else FALSE. - Comments : - ******************************************************************************/ bool ptr_ready(void) { return device_ready; } -/****************************************************************************** -Description : Tick the state machine along a bit. - Parameters : cycles - number of imlac cycles that have elapsed - Returns : - Comments : - ******************************************************************************/ void ptr_tick(long cycles) { /* if no state change */ diff --git a/vimlac/ptr.h b/vimlac/ptr.h old mode 100644 new mode 100755 index d3612a9..d555b8b --- a/vimlac/ptr.h +++ b/vimlac/ptr.h @@ -1,5 +1,5 @@ /* - * Interface for the imlac PTR (papertape reader). + * Interface for the vimlac PTR (papertape reader). */ #ifndef PTR_H diff --git a/vimlac/test_memory.c b/vimlac/test_memory.c old mode 100644 new mode 100755 index ed5caa3..6ea694d --- a/vimlac/test_memory.c +++ b/vimlac/test_memory.c @@ -5,7 +5,7 @@ #include #include -#include "imlac.h" +#include "vimlac.h" #include "memory.h" @@ -15,7 +15,6 @@ main(int argc, char *argv[]) WORD addr; WORD result; FILE *fd; - int errors = 0; // test the "memory clear" function mem_clear(); @@ -31,7 +30,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); - errors += 1; + return 1; } } @@ -45,7 +44,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); - errors += 1; + return 1; } } @@ -58,26 +57,26 @@ main(int argc, char *argv[]) if (result != 1) { printf("C: auto-index at address 010 not indirectly addressing\n"); - errors += 1; + return 1; } result = mem_get(010, false); if (result != 1) { printf("D: auto-index at address 010 not incrementing\n"); - errors += 1; + return 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"); - errors += 1; + return 1; } result = mem_get(010, false); if (result != 0) { printf("F: auto-index at address 010 not incrementing\n"); - errors += 1; + return 1; } // check 017, make sure address wrap-around works @@ -89,26 +88,26 @@ main(int argc, char *argv[]) if (result != 0) { printf("G: auto-index at address 017 not indirectly addressing\n"); - errors += 1; + return 1; } result = mem_get(017, false); if (result != 2) { printf("H: auto-index at address 017 not incrementing\n"); - errors += 1; + return 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"); - errors += 1; + return 1; } result = mem_get(017, false); if (result != 0x4000) { printf("J: auto-index at address 017 not incrementing\n"); - errors += 1; + return 1; } // now save memory to a file @@ -116,22 +115,24 @@ main(int argc, char *argv[]) mem_clear(); for (addr = 0; addr < MEM_SIZE; ++addr) mem_put(addr, false, addr); - mem_save_core("imlac.core"); + fd = fopen("imlac.core", "wb"); + mem_save_core(fd); + fclose(fd); // clear memory and read core file back in mem_clear(); - mem_load_core("imlac.core"); + fd = fopen("imlac.core", "rb"); + mem_load_core(fd); + fclose(fd); 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); - errors += 1; + return 1; } } - printf("%d errors found\n", errors); - return 0; } diff --git a/vimlac/test_ptr.c b/vimlac/test_ptr.c old mode 100644 new mode 100755 diff --git a/vimlac/trace.c b/vimlac/trace.c old mode 100644 new mode 100755 index c5dd175..768855c --- a/vimlac/trace.c +++ b/vimlac/trace.c @@ -1,27 +1,89 @@ /* - * Trace routines for the imlac simulator. + * Trace routines for vimlac. */ #include -#include + +#include "vimlac.h" +#include "cpu.h" + + +bool TraceFlag = false; + + +/****************************************************************************** + * Description : printf()-style output routine to RAW screen. + * Parameters : like printf() + * Returns : + * Comments : + ******************************************************************************/ +void +Emit(char *fmt, ...) +{ + va_list ap; + char buff[512]; + char *chptr; + + va_start(ap, fmt); + vsprintf(buff, fmt, ap); + va_end(ap); + + for (chptr = buff; *chptr != '\0'; ++chptr) + fprintf(stdout, "%c", *chptr); + + fflush(stdout); +} + + +void +DumpRegs(char *buff) +{ + sprintf(buff, "AC=0%6.6o\tL=%1.1o", cpu_get_AC(), cpu_get_L()); +} + + +/****************************************************************************** +Description : printf()-style trace routine to dump registers. + Parameters : + Returns : + Comments : + ******************************************************************************/ +void +traceRegs(void) +{ + static char outbuff[512]; + + if (TraceFlag != false) + { + char emitbuff[512]; + + DumpRegs(outbuff); + sprintf(emitbuff, "\t;%s", outbuff); + Emit(emitbuff); + } +} /****************************************************************************** Description : printf()-style trace routine. Parameters : like printf() Returns : - Comments : + Comments : ******************************************************************************/ void trace(char *fmt, ...) { - va_list ap; - char buff[1024]; + static char outbuff[512]; - va_start(ap, fmt); - vsprintf(buff, fmt, ap); - fprintf(stdout, "%s\n", buff); - va_end(ap); + if (TraceFlag != false) + { + va_list ap; + + va_start(ap, fmt); + vsprintf(outbuff, fmt, ap); + va_end(ap); + Emit("0%6.6o\t%s", cpu_get_prev_PC(), outbuff); + traceRegs(); + Emit("\n"); + } } - - diff --git a/vimlac/trace.h b/vimlac/trace.h old mode 100644 new mode 100755 index 646623d..c745788 --- a/vimlac/trace.h +++ b/vimlac/trace.h @@ -1,5 +1,5 @@ /* - * Interface for the imlac TRACE routine(s). + * Interface for the vimlac trace routines. */ #ifndef TRACE_H diff --git a/vimlac/ttyin.c b/vimlac/ttyin.c old mode 100644 new mode 100755 index 0b8ebc2..a745634 --- a/vimlac/ttyin.c +++ b/vimlac/ttyin.c @@ -1,149 +1,41 @@ /* - * Implementation for the imlac TTYIN (TTY input) device. + * Implementation for the vimlac TTY input device. */ -#include "imlac.h" +#include "vimlac.h" #include "ttyin.h" /***** * constants for the TTYIN device - * - * The device reads at 4800 chars/second, so we work out how many imlac - * machine cycles data is ready/notready at a 30%/70% ready cycle. ******/ -#define CHARS_PER_SECOND 4800 -#define CYCLES_PER_CHAR (CPU_HERZ / CHARS_PER_SECOND) -#define READY_CYCLES (int)((3 * CYCLES_PER_CHAR) / 10) -#define NOT_READY_CYCLES (int)((7 * CYCLES_PER_CHAR) / 10) - -#define TTYIN_EOF 0377 /***** * State variables for the TTYIN device ******/ -static bool device_ready = false; -static FILE *open_file; -static char *filename = NULL; -static bool at_eof = false; -static BYTE value = TTYIN_EOF; -static long cycle_count = 0; +static bool flag; /* true if char ready to read */ - -/****************************************************************************** -Description : Mount a papertape file on the TTYIN device - Parameters : fname - pathname of the file to mount - Returns : 0 if no error, else status code. - Comments : - ******************************************************************************/ -int ttyin_mount(char *fname) +void +ttyin_clear_flag(void) { - filename = fname; - open_file = fopen(fname, "rb"); - if (open_file == NULL) - { - ttyin_dismount(); - return errno; - } - device_ready = false; - at_eof = false; - value = TTYIN_EOF; - cycle_count = NOT_READY_CYCLES; - - return 0; + flag = false; } -/****************************************************************************** -Description : Dismount papertape file from device. - Parameters : - Returns : - Comments : Turns motor off. - ******************************************************************************/ -void ttyin_dismount(void) +BYTE +ttyin_get_char(void) { - if (open_file) - if (fclose(open_file) != 0) - filename = NULL; - open_file = NULL; - device_ready = true; - at_eof = true; - value = TTYIN_EOF; + return ' '; } -/****************************************************************************** -Description : Read the current value of the papertape device. - Parameters : - Returns : - Comments : - ******************************************************************************/ -int ttyin_get_char(void) +bool +ttyin_ready(void) { - return value; + return flag; } -/****************************************************************************** -Description : Get the papertape device status. - Parameters : - Returns : TRUE if device ready, else FALSE. - Comments : - ******************************************************************************/ -void ttyin_clear_flag(void) -{ - device_ready = false; -} - - -/****************************************************************************** -Description : Get the papertape device status. - Parameters : - Returns : TRUE if device ready, else FALSE. - Comments : - ******************************************************************************/ -bool ttyin_ready(void) -{ - return device_ready; -} - - -/****************************************************************************** -Description : Tick the state machine along a bit. - Parameters : cycles - number of imlac cycles that have elapsed - Returns : - Comments : - ******************************************************************************/ -void ttyin_tick(long cycles) -{ - /* if no state change */ - if (at_eof || open_file == NULL) - return; - - /* tape in, motor on */ - cycle_count -= cycles; - if (cycle_count <= 0L) - { - if (device_ready) - { - device_ready = false; - cycle_count += NOT_READY_CYCLES; - value = 0; - } - else - { - device_ready = true; - cycle_count += READY_CYCLES; - if (fread(&value, sizeof(BYTE), 1, open_file) != 1) - { /* assume EOF on file, dismount tape */ - fclose(open_file); - open_file = NULL; - at_eof = true; - value = TTYIN_EOF; - } - } - } -} diff --git a/vimlac/ttyin.h b/vimlac/ttyin.h old mode 100644 new mode 100755 index c4597a9..544f863 --- a/vimlac/ttyin.h +++ b/vimlac/ttyin.h @@ -1,15 +1,12 @@ /* - * Interface for the imlac TTYIN (TTY input). + * Interface for the vimlac TTY input device. */ #ifndef TTYIN_H #define TTYIN_H -int ttyin_mount(char *fname); -void ttyin_dismount(void); -int ttyin_get_char(void); -void ttyin_tick(long cycles); -bool ttyin_ready(void); void ttyin_clear_flag(void); +BYTE ttyin_get_char(void); +bool ttyin_ready(void); #endif diff --git a/vimlac/ttyout.c b/vimlac/ttyout.c old mode 100644 new mode 100755 index a0f6dd7..942af8a --- a/vimlac/ttyout.c +++ b/vimlac/ttyout.c @@ -1,136 +1,41 @@ /* - * Implementation for the imlac TTYOUT (TTY output) device. + * Implementation for the vimlac TTY output device. */ -#include "imlac.h" +#include "vimlac.h" #include "ttyout.h" /***** * constants for the TTYOUT device - * - * The device reads at 4800 chars/second, so we work out how many imlac - * machine cycles data is ready/notready at a 30%/70% ready cycle. ******/ -#define CHARS_PER_SECOND 4800 -#define CYCLES_PER_CHAR (CPU_HERZ / CHARS_PER_SECOND) -#define READY_CYCLES (int)((3 * CYCLES_PER_CHAR) / 10) -#define NOT_READY_CYCLES (int)((7 * CYCLES_PER_CHAR) / 10) - -#define TTYOUT_EOF 0377 /***** * State variables for the TTYOUT device ******/ -static bool device_ready = false; -static FILE *open_file; -static char *filename = NULL; -static long cycle_count = 0; +static bool flag; /* true if char ready to read */ - -/****************************************************************************** -Description : Mount a papertape file on the TTYOUT device - Parameters : fname - pathname of the file to mount - Returns : 0 if no error, else status code. - Comments : - ******************************************************************************/ -int ttyout_mount(char *fname) +void +ttyout_clear_flag(void) { - filename = fname; - open_file = fopen(fname, "wb"); - if (open_file == NULL) - { - ttyout_dismount(); - return errno; - } - device_ready = false; - cycle_count = NOT_READY_CYCLES; - - return 0; + flag = false; } -/****************************************************************************** -Description : Dismount papertape file from device. - Parameters : - Returns : - Comments : Turns motor off. - ******************************************************************************/ -void ttyout_dismount(void) +void +ttyout_send(BYTE ch) { - if (open_file) - if (fclose(open_file) != 0) - filename = NULL; - open_file = NULL; - device_ready = true; + return; } -/****************************************************************************** -Description : Write a byte value to the device. - Parameters : - Returns : - Comments : - ******************************************************************************/ -void ttyout_send(BYTE value) +bool +ttyout_ready(void) { - if (device_ready) - fwrite(&value, 1, 1, open_file); + return flag; } -/****************************************************************************** -Description : Get the papertape device status. - Parameters : - Returns : TRUE if device ready, else FALSE. - Comments : - ******************************************************************************/ -void ttyout_clear_flag(void) -{ - device_ready = false; -} - - -/****************************************************************************** -Description : Get the papertape device status. - Parameters : - Returns : TRUE if device ready, else FALSE. - Comments : - ******************************************************************************/ -bool ttyout_ready(void) -{ - return device_ready; -} - - -/****************************************************************************** -Description : Tick the state machine along a bit. - Parameters : cycles - number of imlac cycles that have elapsed - Returns : - Comments : - ******************************************************************************/ -void ttyout_tick(long cycles) -{ - /* if not open, no state change */ - if (open_file == NULL) - return; - - /* file mounted */ - cycle_count -= cycles; - if (cycle_count <= 0L) - { - if (device_ready) - { - device_ready = false; - cycle_count += NOT_READY_CYCLES; - } - else - { - device_ready = true; - cycle_count += READY_CYCLES; - } - } -} diff --git a/vimlac/ttyout.h b/vimlac/ttyout.h old mode 100644 new mode 100755 index 576dd64..9dfc14f --- a/vimlac/ttyout.h +++ b/vimlac/ttyout.h @@ -1,17 +1,12 @@ /* - * Interface for the imlac TTYOUT (TTY input). + * Interface for the vimlac TTY output device. */ #ifndef TTYOUT_H #define TTYOUT_H - -int ttyout_mount(char *fname); -void ttyout_dismount(void); -void ttyout_send(BYTE value); void ttyout_clear_flag(void); +void ttyout_send(BYTE); bool ttyout_ready(void); -void ttyout_tick(long cycles); - #endif