--- /dev/null
+/*****************************************************************************/
+/* */
+/* 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;
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* 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
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* 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);
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* 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
+
+
+
/* sim65 */
#include "cputype.h"
+#include "error.h"
#include "global.h"
#include "memory.h"
#include "cpucore.h"
#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 */
/*****************************************************************************/
-/* Helper functions and macros */
+/* Helper functions and macros */
/*****************************************************************************/
#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 */
/* ADC */
#define ADC(v) \
if (GET_DF ()) { \
- NotImplemented (); \
+ Warning ("Decimal mode not available"); \
} else { \
unsigned Val; \
unsigned char rhs = v; \
/* SBC */
#define SBC(v) \
if (GET_DF ()) { \
- NotImplemented (); \
+ Warning ("Decimal mode not available"); \
} else { \
unsigned Val; \
unsigned char rhs = v; \
-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 */
/*****************************************************************************/
PUSH (SR);
SET_IF (1);
PC = MemReadWord (0xFFFE);
+ CPUHalted = 1;
}
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;
++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;
EBIND = emxbind
LDFLAGS =
-OBJS = cpucore.o \
+OBJS = chip.o \
+ chippath.o \
+ cpucore.o \
cputype.o \
error.o \
global.o \
sim65: $(OBJS) $(LIBS)
- $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
+ $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) -ldl
@if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi
clean:
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
/* common */
#include "coll.h"
-/* sim65 */
+/* sim65 */
#include "error.h"
#include "memory.h"
{
/* 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);
+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 */
{
/* Add the default reader and writer functions to the collection */
CollAppend (&ReadFuncs, MemRead);
CollAppend (&WriteFuncs, MemWrite);
+
+ MemWriteByte (0xFFFC, 0x00);
+ MemWriteByte (0xFFFD, 0x02);
}
+
+
+
* 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 */