1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-10 19:29:45 +00:00

Working on the plugin interface

git-svn-id: svn://svn.cc65.org/cc65/trunk@1220 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2002-04-06 22:11:09 +00:00
parent 438c8499e6
commit 9abe1e62e7
9 changed files with 641 additions and 29 deletions

213
src/sim65/chip.c Normal file
View File

@ -0,0 +1,213 @@
/*****************************************************************************/
/* */
/* chip.c */
/* */
/* Interface for the chip plugins */
/* */
/* */
/* */
/* (C) 2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#include <string.h>
#include <dlfcn.h>
/* common */
#include "coll.h"
#include "xmalloc.h"
/* sim65 */
#include "chippath.h"
#include "error.h"
#include "chip.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Sorted list of all chip data structures */
static Collection Chips = STATIC_COLLECTION_INITIALIZER;
/*****************************************************************************/
/* Helper functions */
/*****************************************************************************/
static int CmpChips (void* Data attribute ((unused)),
const void* lhs, const void* rhs)
/* Compare function for CollSort */
{
return strcmp (((const Chip*) lhs)->Name, ((const Chip*) rhs)->Name);
}
void* GetSym (const Chip* C, const char* SymName)
/* Locate a symbol in a module and return it. Abort on errors (may be modified
* later to return NULL).
*/
{
void* Val;
const char* Msg;
/* Fetch the error message and discard it - this will clear pending
* errors
*/
dlerror ();
/* Fetch the symbol value */
Val = dlsym (C->Handle, SymName);
/* Check the error message */
Msg = dlerror ();
if (Msg) {
/* We had an error */
Error ("Error loading `%s' from `%s': %s", SymName, C->LibName, Msg);
return 0;
}
/* Return the symbol value read */
return Val;
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static Chip* NewChip (void* Handle, const char* LibName)
/* Allocate a new chip structure, initialize and return it */
{
/* Allocate memory */
Chip* C = xmalloc (sizeof (Chip));
/* Initialize the fields */
C->Name = 0;
C->LibName = xstrdup (LibName);
C->Handle = Handle;
C->InitChip = 0;
C->GetVersion = 0;
C->WriteCtrl = 0;
C->Write = 0;
C->ReadCtrl = 0;
C->Read = 0;
/* Return the structure */
return C;
}
void FreeChip (Chip* C)
/* Free the given chip structure */
{
/* Free the strings */
xfree (C->Name);
xfree (C->LibName);
/* Free the structure itself */
xfree (C);
}
void LoadChip (const char* LibName)
/* Load a chip. This includes loading the shared libary, allocating and
* initializing the data structure.
*/
{
Chip* C;
void* H;
const char* Msg;
/* Locate the library */
char* PathName = FindChip (LibName);
if (PathName == 0) {
/* Library not found */
Error ("Cannot find chip plugin library `%s'", LibName);
return;
}
/* Open the library */
H = dlopen (PathName, RTLD_GLOBAL | RTLD_LAZY);
/* Check for errors */
Msg = dlerror ();
if (Msg) {
Error ("Error opening `%s': %s", PathName, Msg);
}
/* Free the path to the library since we don't need it any longer */
xfree (PathName);
/* Allocate the chip structure */
C = NewChip (H, LibName);
/* Read function pointers */
C->InitChip = GetSym (C, "InitChip");
C->GetName = GetSym (C, "GetName");
C->GetVersion = GetSym (C, "GetVersion");
C->WriteCtrl = GetSym (C, "WriteCtrl");
C->Write = GetSym (C, "Write");
C->ReadCtrl = GetSym (C, "ReadCtrl");
C->Read = GetSym (C, "Read");
/* Insert the structure into the list of all chips */
CollAppend (&Chips, C);
}
void InitChips (void)
/* Initialize the chips. Must be called *after* all chips are loaded */
{
/* Sort the chips by name */
CollSort (&Chips, CmpChips, 0);
}
const Chip* GetChip (const char* Name)
/* Find a chip by name. Returns the Chip data structure or NULL if the chip
* could not be found.
*/
{
return 0;
}

97
src/sim65/chip.h Normal file
View File

@ -0,0 +1,97 @@
/*****************************************************************************/
/* */
/* chip.h */
/* */
/* Interface for the chip plugins */
/* */
/* */
/* */
/* (C) 2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef CHIP_H
#define CHIP_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Forward */
struct SimData;
/* Chip structure */
typedef struct Chip Chip;
struct Chip {
char* Name; /* Name - must be unique */
char* LibName; /* Name of the associated library */
void* Handle; /* Library handle or pointer to it */
/* -- Exported functions -- */
unsigned (*InitChip) (const struct SimData* Data);
const char* (*GetName) (void);
unsigned (*GetVersion) (void);
void (*WriteCtrl) (unsigned Addr, unsigned char Val);
void (*Write) (unsigned Addr, unsigned char Val);
unsigned char (*ReadCtrl) (unsigned Addr);
unsigned char (*Read) (unsigned Addr);
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void LoadChip (const char* LibName);
/* Load a chip. This includes loading the shared libary, allocating and
* initializing the data structure.
*/
void InitChips (void);
/* Initialize the chips. Must be called *after* all chips are loaded */
const Chip* GetChip (const char* Name);
/* Find a chip by name. Returns the Chip data structure or NULL if the chip
* could not be found.
*/
/* End of chip.h */
#endif

179
src/sim65/chippath.c Normal file
View File

@ -0,0 +1,179 @@
/*****************************************************************************/
/* */
/* chippath.h */
/* */
/* Chip path handling for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 2000-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#include <stdio.h>
#include <string.h>
#if defined(_MSC_VER)
/* Microsoft compiler */
# include <io.h>
#else
/* Anyone else */
# include <unistd.h>
#endif
/* common */
#include "xmalloc.h"
/* sim65 */
#include "chippath.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
static char* ChipPath = 0;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static char* Add (char* Orig, const char* New)
/* Create a new path from Orig and New, delete Orig, return the result */
{
unsigned OrigLen, NewLen;
char* NewPath;
/* Get the length of the original string */
OrigLen = Orig? strlen (Orig) : 0;
/* Get the length of the new path */
NewLen = strlen (New);
/* Check for a trailing path separator and remove it */
if (NewLen > 0 && (New [NewLen-1] == '\\' || New [NewLen-1] == '/')) {
--NewLen;
}
/* Allocate memory for the new string */
NewPath = xmalloc (OrigLen + NewLen + 2);
/* Copy the strings */
memcpy (NewPath, Orig, OrigLen);
memcpy (NewPath+OrigLen, New, NewLen);
NewPath [OrigLen+NewLen+0] = ';';
NewPath [OrigLen+NewLen+1] = '\0';
/* Delete the original path */
xfree (Orig);
/* Return the new path */
return NewPath;
}
static char* Find (const char* Path, const char* File)
/* Search for a file in a list of directories. If found, return the complete
* name including the path in a malloced data area, if not found, return 0.
*/
{
const char* P;
int Max;
char PathName [FILENAME_MAX];
/* Initialize variables */
Max = sizeof (PathName) - strlen (File) - 2;
if (Max < 0) {
return 0;
}
P = Path;
/* Handle a NULL pointer as replacement for an empty string */
if (P == 0) {
P = "";
}
/* Start the search */
while (*P) {
/* Copy the next path element into the buffer */
int Count = 0;
while (*P != '\0' && *P != ';' && Count < Max) {
PathName [Count++] = *P++;
}
/* Add a path separator and the filename */
if (Count) {
PathName [Count++] = '/';
}
strcpy (PathName + Count, File);
/* Check if this file exists */
if (access (PathName, 0) == 0) {
/* The file exists */
return xstrdup (PathName);
}
/* Skip a list separator if we have one */
if (*P == ';') {
++P;
}
}
/* Not found */
return 0;
}
void AddChipPath (const char* NewPath)
/* Add a search path for chips */
{
/* Allow a NULL path */
if (NewPath) {
ChipPath = Add (ChipPath, NewPath);
}
}
char* FindChip (const char* LibName)
/* Find a chip library. Return a pointer to a malloced area that contains
* the complete path, if found, return 0 otherwise.
*/
{
/* Search in the include directories */
return Find (ChipPath, LibName);
}

62
src/sim65/chippath.h Normal file
View File

@ -0,0 +1,62 @@
/*****************************************************************************/
/* */
/* chippath.h */
/* */
/* Chip path handling for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 2000-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef CHIPPATH_H
#define CHIPPATH_H
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void AddChipPath (const char* NewPath);
/* Add a search path for chips */
char* FindChip (const char* LibName);
/* Find a chip library. Return a pointer to a malloced area that contains
* the complete path, if found, return 0 otherwise.
*/
/* End of chippath.h */
#endif

View File

@ -42,6 +42,7 @@
/* sim65 */
#include "cputype.h"
#include "error.h"
#include "global.h"
#include "memory.h"
#include "cpucore.h"
@ -74,7 +75,7 @@ static unsigned StackPage = 0x100;
#define ZF 0x02 /* Zero flag */
#define IF 0x04 /* Interrupt flag */
#define DF 0x08 /* Decimal flag */
#define BF 0x10 /* Break flag */
#define BF 0x10 /* Break flag */
#define OF 0x40 /* Overflow flag */
#define SF 0x80 /* Sign flag */
@ -84,7 +85,7 @@ int CPUHalted;
/*****************************************************************************/
/* Helper functions and macros */
/* Helper functions and macros */
/*****************************************************************************/
@ -117,7 +118,7 @@ int CPUHalted;
#define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0)
/* Program counter halves */
#define PCL (PC & 0xFF)
#define PCL (PC & 0xFF)
#define PCH ((PC >> 8) & 0xFF)
/* Stack operations */
@ -226,7 +227,7 @@ int CPUHalted;
/* ADC */
#define ADC(v) \
if (GET_DF ()) { \
NotImplemented (); \
Warning ("Decimal mode not available"); \
} else { \
unsigned Val; \
unsigned char rhs = v; \
@ -289,7 +290,7 @@ int CPUHalted;
/* SBC */
#define SBC(v) \
if (GET_DF ()) { \
NotImplemented (); \
Warning ("Decimal mode not available"); \
} else { \
unsigned Val; \
unsigned char rhs = v; \
@ -309,26 +310,15 @@ int CPUHalted;
static void OPC_Illegal (void) attribute ((noreturn));
static void OPC_Illegal (void)
{
fprintf (stderr, "Illegal: $%02X\n", MemReadByte (PC));
exit (EXIT_FAILURE);
}
static void NotImplemented (void) attribute ((noreturn));
static void NotImplemented (void)
{
fprintf (stderr, "Not implemented: $%02X\n", MemReadByte (PC));
exit (EXIT_FAILURE);
Warning ("Illegal opcode $%02X at address $%04X\n", MemReadByte (PC), PC);
}
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@ -344,6 +334,7 @@ static void OPC_6502_00 (void)
PUSH (SR);
SET_IF (1);
PC = MemReadWord (0xFFFE);
CPUHalted = 1;
}
@ -2505,10 +2496,20 @@ void CPURun (void)
while (!CPUHalted) {
/* Get the next opcode */
unsigned char B = MemReadByte (PC);
unsigned char OPC = MemReadByte (PC);
printf ("%6lu %04X %02X A=%02X X=%02X Y=%02X %c%c%c%c%c%c%c\n",
TotalCycles, PC, OPC, AC, XR, YR,
GET_SF()? 'S' : '-',
GET_ZF()? 'Z' : '-',
GET_CF()? 'C' : '-',
GET_IF()? 'I' : '-',
GET_BF()? 'B' : '-',
GET_DF()? 'D' : '-',
GET_OF()? 'V' : '-');
/* Execute it */
OPCTable[B] ();
OPCTable[OPC] ();
/* Count cycles */
TotalCycles += Cycles;

View File

@ -199,14 +199,11 @@ int main (int argc, char* argv[])
++I;
}
/* Did we have a file spec on the command line? */
if (InputFile == 0) {
AbEnd ("No input files");
}
/* Initialize modules */
MemInit ();
MemLoad ("uz.bin", 0x200, 0);
CPUInit ();
CPURun ();
/* Return an apropriate exit code */
return EXIT_SUCCESS;

View File

@ -10,7 +10,9 @@ CC = gcc
EBIND = emxbind
LDFLAGS =
OBJS = cpucore.o \
OBJS = chip.o \
chippath.o \
cpucore.o \
cputype.o \
error.o \
global.o \
@ -33,7 +35,7 @@ endif
sim65: $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) -ldl
@if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi
clean:

View File

@ -33,10 +33,14 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
/* common */
#include "coll.h"
/* sim65 */
/* sim65 */
#include "error.h"
#include "memory.h"
@ -140,7 +144,7 @@ unsigned char MemReadByte (unsigned Addr)
{
/* Get the reader function */
unsigned RI = (MemAttr[Addr] & RA_READFUNC_MASK) >> RA_READFUNC_SHIFT;
ReadFunc RF = CollAt (&WriteFuncs, RI);
ReadFunc RF = CollAt (&ReadFuncs, RI);
/* Call the reader function */
return RF (Addr);
@ -169,6 +173,50 @@ unsigned MemReadZPWord (unsigned char Addr)
void MemLoad (const char* Filename, unsigned Addr, unsigned Size)
/* Load the contents of the given file into the RAM at the given address.
* If Size is not zero, we will read exactly Size bytes from the file and
* consider it an error if this is not possible. The memory attributes
* for the range is set to initialized.
*/
{
unsigned BytesToRead;
unsigned BytesRead;
unsigned I;
/* Open the file */
FILE* F = fopen (Filename, "rb");
if (F == 0) {
Error ("Cannot open `%s': %s", Filename, strerror (errno));
}
/* Set the number of bytes to read */
BytesToRead = 0x10000 - Addr;
if (Size > 0) {
CHECK (Size <= BytesToRead); /* Must not exceed RAM */
BytesToRead = Size;
}
/* Read data from the file */
BytesRead = fread (Mem + Addr, 1, BytesToRead, F);
if (ferror (F)) {
Error ("Error reading from `%s': %s", Filename, strerror (errno));
}
if (Size > 0 && BytesRead != Size) {
Error ("Cannot read %u bytes from `%s'", Size, Filename);
}
/* Close the file. Ignore errors, we were just reading. */
fclose (F);
/* Set the memory attribute for the range to initialized */
for (I = 0; I < BytesRead; ++I) {
MemAttr[Addr+I] |= RA_INITIALIZED;
}
}
void MemInit (void)
/* Initialize the memory subsystem */
{
@ -188,4 +236,10 @@ void MemInit (void)
/* Add the default reader and writer functions to the collection */
CollAppend (&ReadFuncs, MemRead);
CollAppend (&WriteFuncs, MemWrite);
MemWriteByte (0xFFFC, 0x00);
MemWriteByte (0xFFFD, 0x02);
}

View File

@ -65,6 +65,13 @@ unsigned MemReadZPWord (unsigned char Addr);
* overflow.
*/
void MemLoad (const char* Filename, unsigned Addr, unsigned Size);
/* Load the contents of the given file into the RAM at the given address.
* If Size is not zero, we will read exactly Size bytes from the file and
* consider it an error if this is not possible. The memory attributes
* for the range is set to initialized.
*/
void MemInit (void);
/* Initialize the memory subsystem */