1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00

Working on C imlac simulator

This commit is contained in:
Ross Wilson
2015-10-15 13:06:05 +07:00
parent 1ad3cbffe6
commit 84efde0709
6 changed files with 78 additions and 30 deletions

View File

@@ -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}

View File

@@ -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.
******************************************************************************/

View File

@@ -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 <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>

View File

@@ -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 <stdio.h>
#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)
{

View File

@@ -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

View File

@@ -5,7 +5,7 @@
#include <stdio.h>
#include <assert.h>
#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;
}