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:
@@ -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}
|
||||
|
||||
@@ -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.
|
||||
******************************************************************************/
|
||||
|
||||
@@ -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>
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user