diff --git a/src/sim65/chip.c b/src/sim65/chip.c index 57e920616..80dd42cb8 100644 --- a/src/sim65/chip.c +++ b/src/sim65/chip.c @@ -45,11 +45,42 @@ /* sim65 */ #include "cfgdata.h" #include "chipdata.h" +#include "cpucore.h" #include "error.h" #include "chip.h" +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +static int GetCfgId (void* CfgInfo, const char* Name, char** Id); +/* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, pass a pointer to a dynamically + * allocated string containing the value to Id, and return true. If not + * found, return false. The memory passed in Id must be free by a call to + * Free(); + */ + +static int GetCfgStr (void* CfgInfo, const char* Name, char** S); +/* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, pass a pointer to a dynamically + * allocated string containing the value to Id, and return true. If not + * found, return false. The memory passed in S must be free by a call to + * Free(); + */ + +static int GetCfgNum (void* CfgInfo, const char* Name, long* Val); +/* Search CfgInfo for an attribute with the given name and type "number". + * If found, remove it from the configuration, copy it into Val and return + * true. If not found, return false. + */ + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -71,9 +102,10 @@ static const SimData Sim65Data = { Warning, Error, Internal, - CfgDataGetId, - CfgDataGetStr, - CfgDataGetNum + Break, + GetCfgId, + GetCfgStr, + GetCfgNum }; @@ -84,6 +116,43 @@ static const SimData Sim65Data = { +static int GetCfgId (void* CfgInfo, const char* Name, char** Id) +/* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, pass a pointer to a dynamically + * allocated string containing the value to Id, and return true. If not + * found, return false. The memory passed in Id must be free by a call to + * Free(); + */ +{ + return CfgDataGetId (CfgInfo, Name, Id); +} + + + +static int GetCfgStr (void* CfgInfo, const char* Name, char** S) +/* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, pass a pointer to a dynamically + * allocated string containing the value to Id, and return true. If not + * found, return false. The memory passed in S must be free by a call to + * Free(); + */ +{ + return CfgDataGetStr (CfgInfo, Name, S); +} + + + +static int GetCfgNum (void* CfgInfo, const char* Name, long* Val) +/* Search CfgInfo for an attribute with the given name and type "number". + * If found, remove it from the configuration, copy it into Val and return + * true. If not found, return false. + */ +{ + return CfgDataGetNum (CfgInfo, Name, Val); +} + + + static int CmpChips (void* Data attribute ((unused)), const void* lhs, const void* rhs) /* Compare function for CollSort */ @@ -312,7 +381,7 @@ void LoadChipLibrary (const char* LibName) const ChipData* D = Data + I; /* Check if the chip data has the correct version */ - if (Data->MajorVersion != CHIPDATA_VER_MAJOR) { + if (D->MajorVersion != CHIPDATA_VER_MAJOR) { Warning ("Version mismatch for `%s' (%s), expected %u, got %u", D->ChipName, L->LibName, CHIPDATA_VER_MAJOR, D->MajorVersion); @@ -320,6 +389,9 @@ void LoadChipLibrary (const char* LibName) continue; } + /* Initialize the chip passing the simulator data */ + D->InitChip (&Sim65Data); + /* Generate a new chip */ C = NewChip (L, D); @@ -328,10 +400,11 @@ void LoadChipLibrary (const char* LibName) /* Output chip name and version to keep the user happy */ Print (stdout, 1, - " Found `%s', version %u.%u in library `%s'\n", - Data->ChipName, - Data->MajorVersion, - Data->MinorVersion, + " Found %s `%s', version %u.%u in library `%s'\n", + (D->Type == CHIPDATA_TYPE_CHIP)? "chip" : "cpu", + D->ChipName, + D->MajorVersion, + D->MinorVersion, L->LibName); } } diff --git a/src/sim65/chipdata.h b/src/sim65/chipdata.h index e9cd81278..ad7b061a6 100644 --- a/src/sim65/chipdata.h +++ b/src/sim65/chipdata.h @@ -44,7 +44,9 @@ -/* Version information. */ +/* Chip type and version information. */ +#define CHIPDATA_TYPE_CHIP 0U +#define CHIPDATA_TYPE_CPU 1U #define CHIPDATA_VER_MAJOR 1U #define CHIPDATA_VER_MINOR 0U @@ -56,6 +58,7 @@ struct SimData; typedef struct ChipData ChipData; struct ChipData { const char* ChipName; /* Name of the chip */ + unsigned Type; /* Type of the chip */ unsigned MajorVersion; /* Version information */ unsigned MinorVersion; diff --git a/src/sim65/chips/make/gcc.mak b/src/sim65/chips/make/gcc.mak index dd1b2e1bd..004cfc201 100644 --- a/src/sim65/chips/make/gcc.mak +++ b/src/sim65/chips/make/gcc.mak @@ -14,6 +14,7 @@ LDFLAGS = LIBS = $(COMMON)/common.a CHIPS = ram.so \ + rom.so \ stdio.so OBJS = $(CHIPS:.so=.o) @@ -34,6 +35,10 @@ ram.so: ram.o $(CC) $(CFLAGS) -shared -o $@ $(LIBS) $^ @if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi +rom.so: rom.o + $(CC) $(CFLAGS) -shared -o $@ $(LIBS) $^ + @if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi + stdio.so: stdio.o $(CC) $(CFLAGS) -shared -o $@ $(LIBS) $^ @if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi diff --git a/src/sim65/chips/ram.c b/src/sim65/chips/ram.c index 639b05bfa..5a77bc744 100644 --- a/src/sim65/chips/ram.c +++ b/src/sim65/chips/ram.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -47,7 +47,7 @@ -int InitChip (const struct SimData* Data); +static int InitChip (const struct SimData* Data); /* Initialize the chip, return an error code */ static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo); @@ -77,6 +77,7 @@ static unsigned char Read (void* Data, unsigned Offs); static const struct ChipData RAMData[1] = { { "RAM", /* Name of the chip */ + CHIPDATA_TYPE_CHIP, /* Type of the chip */ CHIPDATA_VER_MAJOR, /* Version information */ CHIPDATA_VER_MINOR, @@ -132,7 +133,7 @@ int GetChipData (const ChipData** Data, unsigned* Count) -int InitChip (const struct SimData* Data) +static int InitChip (const struct SimData* Data) /* Initialize the chip, return an error code */ { /* Remember the pointer */ @@ -187,7 +188,7 @@ static void Write (void* Data, unsigned Offs, unsigned char Val) /* Check for a write to a write protected cell */ if (D->MemAttr[Offs] & ATTR_WPROT) { - Sim->Warning ("Writing to write protected memory at $%04X", D->BaseAddr+Offs); + Sim->Break ("Writing to write protected memory at $%04X", D->BaseAddr+Offs); } /* Do the write and remember the cell as initialized */ @@ -218,7 +219,7 @@ static unsigned char Read (void* Data, unsigned Offs) /* Check for a read from an uninitialized cell */ if ((D->MemAttr[Offs] & ATTR_INITIALIZED) == 0) { /* We're reading a memory cell that was never written to */ - Sim->Warning ("Reading from uninitialized memory at $%04X", D->BaseAddr+Offs); + Sim->Break ("Reading from uninitialized memory at $%04X", D->BaseAddr+Offs); } /* Read the cell and return the value */ diff --git a/src/sim65/chips/rom.c b/src/sim65/chips/rom.c new file mode 100644 index 000000000..eebfc7482 --- /dev/null +++ b/src/sim65/chips/rom.c @@ -0,0 +1,236 @@ +/*****************************************************************************/ +/* */ +/* rom.c */ +/* */ +/* ROM plugin for the sim65 6502 simulator */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* 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 +#include +#include + +/* sim65 */ +#include "chipif.h" + + + +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +static int InitChip (const struct SimData* Data); +/* Initialize the chip, return an error code */ + +static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo); +/* Initialize a new chip instance */ + +static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val); +/* Write control data */ + +static void Write (void* Data, unsigned Offs, unsigned char Val); +/* Write user data */ + +static unsigned char ReadCtrl (void* Data, unsigned Offs); +/* Read control data */ + +static unsigned char Read (void* Data, unsigned Offs); +/* Read user data */ + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Control data passed to the main program */ +static const struct ChipData ROMData[1] = { + { + "ROM", /* Name of the chip */ + CHIPDATA_TYPE_CHIP, /* Type of the chip */ + CHIPDATA_VER_MAJOR, /* Version information */ + CHIPDATA_VER_MINOR, + + /* -- Exported functions -- */ + InitChip, + InitInstance, + WriteCtrl, + Write, + ReadCtrl, + Read + } +}; + +/* The SimData pointer we get when InitChip is called */ +static const SimData* Sim; + +/* Data for one ROM instance */ +typedef struct InstanceData InstanceData; +struct InstanceData { + unsigned BaseAddr; /* Base address */ + unsigned Range; /* Memory range */ + unsigned char* Mem; /* The memory itself */ +}; + + + +/*****************************************************************************/ +/* Exported function */ +/*****************************************************************************/ + + + +int GetChipData (const ChipData** Data, unsigned* Count) +{ + /* Pass the control structure to the caller */ + *Data = ROMData; + *Count = sizeof (Data) / sizeof (Data[0]); + + /* Call was successful */ + return 0; +} + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static int InitChip (const struct SimData* Data) +/* Initialize the chip, return an error code */ +{ + /* Remember the pointer */ + Sim = Data; + + /* Always successful */ + return 0; +} + + + +static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo) +/* Initialize a new chip instance */ +{ + char* Name; + FILE* F; + + /* Allocate a new instance structure */ + InstanceData* D = Sim->Malloc (sizeof (InstanceData)); + + /* Initialize the structure, allocate RAM and attribute memory */ + D->BaseAddr = Addr; + D->Range = Range; + D->Mem = Sim->Malloc (Range); + + /* We must have a "file" attribute. Get it. */ + if (Sim->GetCfgStr (CfgInfo, "file", &Name) == 0) { + /* Attribute not found */ + Sim->Error ("Attribute `file' missing"); /* ### */ + } + + /* Open the file with the given name */ + F = fopen (Name, "rb"); + if (F == 0) { + Sim->Error ("Cannot open `%s': %s", Name, strerror (errno)); + } + + /* Read the file into the memory */ + if (fread (D->Mem, 1, D->Range, F) != D->Range) { + Sim->Warning ("Cannot read %u bytes from file `%s'", D->Range, Name); + } + + /* Close the file */ + fclose (F); + + /* Free the file name */ + Sim->Free (Name); + + /* Done, return the instance data */ + return D; +} + + + +static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val) +/* Write control data */ +{ + /* Cast the data pointer */ + InstanceData* D = (InstanceData*) Data; + + /* Do the write */ + D->Mem[Offs] = Val; +} + + + +static void Write (void* Data, unsigned Offs, unsigned char Val) +/* Write user data */ +{ + /* Cast the data pointer */ + InstanceData* D = (InstanceData*) Data; + + /* Print a warning */ + Sim->Break ("Writing to write protected memory at $%04X (value = $%02X)", + D->BaseAddr+Offs, Val); +} + + + +static unsigned char ReadCtrl (void* Data, unsigned Offs) +/* Read control data */ +{ + /* Cast the data pointer */ + InstanceData* D = (InstanceData*) Data; + + /* Read the cell and return the value */ + return D->Mem[Offs]; +} + + + +static unsigned char Read (void* Data, unsigned Offs) +/* Read user data */ +{ + /* Cast the data pointer */ + InstanceData* D = (InstanceData*) Data; + + /* Read the cell and return the value */ + return D->Mem[Offs]; +} + + + diff --git a/src/sim65/chips/stdio.c b/src/sim65/chips/stdio.c index 5eddd3ca2..d5d1bcd66 100644 --- a/src/sim65/chips/stdio.c +++ b/src/sim65/chips/stdio.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -51,7 +51,7 @@ -int InitChip (const struct SimData* Data); +static int InitChip (const struct SimData* Data); /* Initialize the chip, return an error code */ static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo); @@ -72,9 +72,10 @@ static unsigned char Read (void* Data, unsigned Offs); /* Control data passed to the main program */ -static const struct ChipData RAMData[1] = { +static const struct ChipData STDIOData[1] = { { "STDIO", /* Name of the chip */ + CHIPDATA_TYPE_CHIP, /* Type of the chip */ CHIPDATA_VER_MAJOR, /* Version information */ CHIPDATA_VER_MINOR, @@ -102,7 +103,7 @@ static const SimData* Sim; int GetChipData (const ChipData** Data, unsigned* Count) { /* Pass the control structure to the caller */ - *Data = RAMData; + *Data = STDIOData; *Count = sizeof (Data) / sizeof (Data[0]); /* Call was successful */ @@ -117,7 +118,7 @@ int GetChipData (const ChipData** Data, unsigned* Count) -int InitChip (const struct SimData* Data) +static int InitChip (const struct SimData* Data) /* Initialize the chip, return an error code */ { /* Remember the pointer */ diff --git a/src/sim65/config.c b/src/sim65/config.c index afb5d719b..ce1a272f8 100644 --- a/src/sim65/config.c +++ b/src/sim65/config.c @@ -304,7 +304,7 @@ static void ParseMemory (void) CollDelete (&L->Attributes, Index); /* Create the chip instance for the address range */ - Range = L->End - L->Start; + Range = L->End - L->Start + 1; CI = NewChipInstance (D->V.SVal, L->Start, Range, &L->Attributes); /* Delete the "name" attribute */ diff --git a/src/sim65/cpucore.c b/src/sim65/cpucore.c index 8f7e35f80..55802ed4c 100644 --- a/src/sim65/cpucore.c +++ b/src/sim65/cpucore.c @@ -33,12 +33,15 @@ +#include #include +#include /* common */ #include "abend.h" #include "attrib.h" #include "print.h" +#include "xsprintf.h" /* sim65 */ #include "cputype.h" @@ -82,6 +85,9 @@ static unsigned StackPage = 0x100; /* */ int CPUHalted; +/* Break message */ +static char BreakMsg[1024]; + /*****************************************************************************/ @@ -2489,6 +2495,17 @@ void NMI (void) +void Break (const char* Format, ...) +/* Stop running and display the given message */ +{ + va_list ap; + va_start (ap, Format); + xvsprintf (BreakMsg, sizeof (BreakMsg), Format, ap); + va_end (ap); +} + + + void CPURun (void) /* Run the CPU */ { @@ -2497,7 +2514,7 @@ void CPURun (void) /* Get the next opcode */ unsigned char OPC = MemReadByte (PC); - printf ("%6lu %04X %02X A=%02X X=%02X Y=%02X %c%c%c%c%c%c%c\n", + printf ("%9lu %06X %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' : '-', @@ -2512,6 +2529,11 @@ void CPURun (void) /* Count cycles */ TotalCycles += Cycles; + + if (BreakMsg[0]) { + printf ("%s\n", BreakMsg); + BreakMsg[0] = '\0'; + } } } diff --git a/src/sim65/cpucore.h b/src/sim65/cpucore.h index 09867fd28..f44431199 100644 --- a/src/sim65/cpucore.h +++ b/src/sim65/cpucore.h @@ -81,6 +81,9 @@ void IRQ (void); void NMI (void); /* Generate an NMI */ +void Break (const char* Format, ...); +/* Stop running and display the given message */ + void CPURun (void); /* Run the CPU */ diff --git a/src/sim65/main.c b/src/sim65/main.c index 2fa57a4e0..486e0f960 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -110,10 +110,20 @@ static void OptChipDir (const char* Opt attribute ((unused)), const char* Arg) /* Read in all files and treat them as libraries */ while ((E = readdir (D)) != 0) { + char* Name; struct stat S; + /* ### Ignore anything buy *.so files */ + unsigned NameLen = strlen (E->d_name); + if (NameLen <= 3) { + continue; + } + if (strcmp (E->d_name + NameLen - 3, ".so") != 0) { + continue; + } + /* Create the full file name */ - char* Name = xmalloc (DirLen + 1 + strlen (E->d_name) + 1); + Name = xmalloc (DirLen + 1 + NameLen + 1); strcpy (Name, Arg); strcpy (Name + DirLen, "/"); strcpy (Name + DirLen + 1, E->d_name); @@ -298,7 +308,7 @@ int main (int argc, char* argv[]) CfgRead (); CPUInit (); -#if 0 +#if 1 CPURun (); #endif diff --git a/src/sim65/memory.c b/src/sim65/memory.c index 727ba1ca6..dac80a450 100644 --- a/src/sim65/memory.c +++ b/src/sim65/memory.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -162,7 +162,7 @@ void MemInit (void) default: Internal ("Unexpected CPU type: %d", CPU); } - MemData = xmalloc (MemSize); + MemData = xmalloc (MemSize * sizeof (ChipInstance*)); /* Clear the memory */ for (I = 0; I < MemSize; ++I) { diff --git a/src/sim65/memory.h b/src/sim65/memory.h index 55e828607..6874e6411 100644 --- a/src/sim65/memory.h +++ b/src/sim65/memory.h @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ diff --git a/src/sim65/simdata.h b/src/sim65/simdata.h index 915c31c7c..c4d80ccb1 100644 --- a/src/sim65/simdata.h +++ b/src/sim65/simdata.h @@ -67,6 +67,9 @@ struct SimData { void (*Internal) (const char* Format, ...); /* Print an internal program error and terminate */ + void (*Break) (const char* Format, ...); + /* Stop the CPU and display the given message */ + int (*GetCfgId) (void* CfgInfo, const char* Name, char** Id); /* Search CfgInfo for an attribute with the given name and type "id". If * found, remove it from the configuration, pass a pointer to a dynamically @@ -76,11 +79,11 @@ struct SimData { */ int (*GetCfgStr) (void* CfgInfo, const char* Name, char** S); - /* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, pass a pointer to a dynamically - * allocated string containing the value to Id, and return true. If not - * found, return false. The memory passed in S must be free by a call to - * Free(); + /* Search CfgInfo for an attribute with the given name and type "string". + * If found, remove it from the configuration, pass a pointer to a + * dynamically allocated string containing the value to S, and return + * true. If not found, return false. The memory passed in S must be free + * by a call to Free(); */ int (*GetCfgNum) (void* CfgInfo, const char* Name, long* Val);