From 9abe1e62e7f63244ef968d298620189751374bd0 Mon Sep 17 00:00:00 2001 From: cuz Date: Sat, 6 Apr 2002 22:11:09 +0000 Subject: [PATCH] Working on the plugin interface git-svn-id: svn://svn.cc65.org/cc65/trunk@1220 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/sim65/chip.c | 213 +++++++++++++++++++++++++++++++++++++++++ src/sim65/chip.h | 97 +++++++++++++++++++ src/sim65/chippath.c | 179 ++++++++++++++++++++++++++++++++++ src/sim65/chippath.h | 62 ++++++++++++ src/sim65/cpucore.c | 41 ++++---- src/sim65/main.c | 7 +- src/sim65/make/gcc.mak | 6 +- src/sim65/memory.c | 58 ++++++++++- src/sim65/memory.h | 7 ++ 9 files changed, 641 insertions(+), 29 deletions(-) create mode 100644 src/sim65/chip.c create mode 100644 src/sim65/chip.h create mode 100644 src/sim65/chippath.c create mode 100644 src/sim65/chippath.h diff --git a/src/sim65/chip.c b/src/sim65/chip.c new file mode 100644 index 000000000..b73b7f0e7 --- /dev/null +++ b/src/sim65/chip.c @@ -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 +#include + +/* 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; +} + + + diff --git a/src/sim65/chip.h b/src/sim65/chip.h new file mode 100644 index 000000000..6b594638d --- /dev/null +++ b/src/sim65/chip.h @@ -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 + + + diff --git a/src/sim65/chippath.c b/src/sim65/chippath.c new file mode 100644 index 000000000..0e983fece --- /dev/null +++ b/src/sim65/chippath.c @@ -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 +#include +#if defined(_MSC_VER) +/* Microsoft compiler */ +# include +#else +/* Anyone else */ +# include +#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); +} + + + diff --git a/src/sim65/chippath.h b/src/sim65/chippath.h new file mode 100644 index 000000000..5bf28e4a7 --- /dev/null +++ b/src/sim65/chippath.h @@ -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 + + + diff --git a/src/sim65/cpucore.c b/src/sim65/cpucore.c index 2058ebda6..814085c1e 100644 --- a/src/sim65/cpucore.c +++ b/src/sim65/cpucore.c @@ -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; diff --git a/src/sim65/main.c b/src/sim65/main.c index 0adf81828..58ffd7686 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -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; diff --git a/src/sim65/make/gcc.mak b/src/sim65/make/gcc.mak index 0cfc23ee4..37aa8cd1b 100644 --- a/src/sim65/make/gcc.mak +++ b/src/sim65/make/gcc.mak @@ -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: diff --git a/src/sim65/memory.c b/src/sim65/memory.c index d4e7554f3..6454c75d3 100644 --- a/src/sim65/memory.c +++ b/src/sim65/memory.c @@ -33,10 +33,14 @@ +#include +#include +#include + /* 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); } + + + diff --git a/src/sim65/memory.h b/src/sim65/memory.h index d080c9a8f..43ac5f9df 100644 --- a/src/sim65/memory.h +++ b/src/sim65/memory.h @@ -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 */ -- 2.39.5