/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
/* Generate a new chip and insert it into the collection */
CollAppend (&Chips, NewChip (L, Data));
+
+ /* Output chip name and version to keep the user happy */
+ Print (stdout, 1,
+ "Found chip `%s' version %u.%u\n",
+ Data->ChipName,
+ Data->MajorVersion,
+ Data->MinorVersion);
}
}
* could not be found.
*/
{
+ unsigned I;
+
+ /* ## We do a linear search for now */
+ for (I = 0; I < CollCount (&Chips); ++I) {
+
+ /* Get the chip at this position */
+ const Chip* C = CollConstAt (&Chips, I);
+
+ /* Compare the name */
+ if (strcmp (Name, C->Data->ChipName) == 0) {
+ /* Found */
+ return C;
+ }
+ }
+
+ /* Not found */
return 0;
}
/* -- Exported functions -- */
int (*InitChip) (const struct SimData* Data);
void* (*InitInstance) (unsigned Addr, unsigned Range);
- void (*WriteCtrl) (void* Data, unsigned Addr, unsigned char Val);
- void (*Write) (void* Data, unsigned Addr, unsigned char Val);
- unsigned char (*ReadCtrl) (void* Data, unsigned Addr);
- unsigned char (*Read) (void* Data, unsigned Addr);
+ void (*WriteCtrl) (void* Data, unsigned Offs, unsigned char Val);
+ void (*Write) (void* Data, unsigned Offs, unsigned char Val);
+ unsigned char (*ReadCtrl) (void* Data, unsigned Offs);
+ unsigned char (*Read) (void* Data, unsigned Offs);
};
static void* InitInstance (unsigned Addr, unsigned Range);
/* Initialize a new chip instance */
-static void WriteCtrl (void* Data, unsigned Addr, unsigned char Val);
+static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val);
/* Write control data */
-static void Write (void* Data, unsigned Addr, unsigned char Val);
+static void Write (void* Data, unsigned Offs, unsigned char Val);
/* Write user data */
-static unsigned char ReadCtrl (void* Data, unsigned Addr);
+static unsigned char ReadCtrl (void* Data, unsigned Offs);
/* Read control data */
-static unsigned char Read (void* Data, unsigned Addr);
+static unsigned char Read (void* Data, unsigned Offs);
/* Read user data */
-static void WriteCtrl (void* Data, unsigned Addr, unsigned char Val)
+static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val)
/* Write control data */
{
/* Cast the data pointer */
InstanceData* D = (InstanceData*) Data;
/* Do the write and remember the cell as initialized */
- D->Mem[Addr] = Val;
- D->MemAttr[Addr] |= ATTR_INITIALIZED;
+ D->Mem[Offs] = Val;
+ D->MemAttr[Offs] |= ATTR_INITIALIZED;
}
-static void Write (void* Data, unsigned Addr, unsigned char Val)
+static void Write (void* Data, unsigned Offs, unsigned char Val)
/* Write user data */
{
/* Cast the data pointer */
InstanceData* D = (InstanceData*) Data;
/* Check for a write to a write protected cell */
- if (D->MemAttr[Addr] & ATTR_WPROT) {
- Sim->Warning ("Writing to write protected memory at $%04X", Addr);
+ if (D->MemAttr[Offs] & ATTR_WPROT) {
+ Sim->Warning ("Writing to write protected memory at $%04X", D->BaseAddr+Offs);
}
/* Do the write and remember the cell as initialized */
- D->Mem[Addr] = Val;
- D->MemAttr[Addr] |= ATTR_INITIALIZED;
+ D->Mem[Offs] = Val;
+ D->MemAttr[Offs] |= ATTR_INITIALIZED;
}
-static unsigned char ReadCtrl (void* Data, unsigned Addr)
+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[Addr];
+ return D->Mem[Offs];
}
-static unsigned char Read (void* Data, unsigned Addr)
+static unsigned char Read (void* Data, unsigned Offs)
/* Read user data */
{
/* Cast the data pointer */
InstanceData* D = (InstanceData*) Data;
/* Check for a read from an uninitialized cell */
- if ((D->MemAttr[Addr] & ATTR_INITIALIZED) == 0) {
+ 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", Addr);
+ Sim->Warning ("Reading from uninitialized memory at $%04X", D->BaseAddr+Offs);
}
/* Read the cell and return the value */
- return D->Mem[Addr];
+ return D->Mem[Offs];
}
/*****************************************************************************/
-
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void* InitInstance (unsigned Addr, unsigned Range);
/* Initialize a new chip instance */
-static void Write (void* Data, unsigned Addr, unsigned char Val);
+static void Write (void* Data, unsigned Offs, unsigned char Val);
/* Write user data */
-static unsigned char Read (void* Data, unsigned Addr);
+static unsigned char Read (void* Data, unsigned Offs);
/* Read user data */
static void Write (void* Data attribute ((unused)),
- unsigned Addr attribute ((unused)),
+ unsigned Offs attribute ((unused)),
unsigned char Val)
/* Write user data */
{
static unsigned char Read (void* Data attribute ((unused)),
- unsigned Addr attribute ((unused)))
+ unsigned Offs attribute ((unused)))
/* Read user data */
{
/* Read a character and return the value */
+
#include "print.h"
#include "xmalloc.h"
-/* ld65 */
+/* sim65 */
+#include "chip.h"
#include "error.h"
#include "global.h"
#include "scanner.h"
+static void FlagAttr (unsigned* Flags, unsigned Mask, const char* Name)
+/* Check if the item is already defined. Print an error if so. If not, set
+ * the marker that we have a definition now.
+ */
+{
+ if (*Flags & Mask) {
+ CfgError ("%s is already defined", Name);
+ }
+ *Flags |= Mask;
+}
+
+
+
+static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name)
+/* Check that a mandatory attribute was given */
+{
+ if ((Attr & Mask) == 0) {
+ CfgError ("%s attribute is missing", Name);
+ }
+}
+
+
+
+static void ParseChips (void)
+/* Parse a CHIPS section */
+{
+ static const IdentTok Attributes [] = {
+ { "ADDR", CFGTOK_ADDR },
+ { "RANGE", CFGTOK_RANGE },
+ };
+
+ /* Bits and stuff to remember which attributes we have read */
+ enum {
+ CA_ADDR = 0x01,
+ CA_RANGE = 0x02
+ };
+ unsigned Attr;
+
+ /* Attribute values. Initialize to make gcc happy. */
+ const Chip* C;
+ unsigned Addr = 0;
+ unsigned Range = 0;
+
+ while (CfgTok == CFGTOK_IDENT) {
+
+ /* Search the chip with the given name */
+ C = FindChip (CfgSVal);
+ if (C == 0) {
+ CfgError ("No such chip: `%s'", CfgSVal);
+ }
+
+ /* Skip the name plus the following colon */
+ CfgNextTok ();
+ CfgConsumeColon ();
+
+ /* Read the attributes */
+ Attr = 0;
+ while (CfgTok == CFGTOK_IDENT) {
+
+ /* Map the identifier to a token */
+ cfgtok_t AttrTok;
+ CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
+ AttrTok = CfgTok;
+
+ /* An optional assignment follows */
+ CfgNextTok ();
+ CfgOptionalAssign ();
+
+ /* Check which attribute was given */
+ switch (AttrTok) {
+
+ case CFGTOK_ADDR:
+ CfgAssureInt ();
+ CfgRangeCheck (0, 0xFFFF);
+ FlagAttr (&Attr, CA_ADDR, "ADDR");
+ Addr = (unsigned) CfgIVal;
+ break;
+
+ case CFGTOK_RANGE:
+ CfgAssureInt ();
+ CfgRangeCheck (0, 0xFFFF);
+ FlagAttr (&Attr, CA_RANGE, "RANGE");
+ Range = (unsigned) CfgIVal;
+ break;
+
+ default:
+ FAIL ("Unexpected attribute token");
+
+ }
+
+ /* Skip the attribute value and an optional comma */
+ CfgNextTok ();
+ CfgOptionalComma ();
+ }
+
+ /* Skip the semicolon */
+ CfgConsumeSemi ();
+
+ /* Check for mandatory parameters */
+ AttrCheck (Attr, CA_ADDR, "ADDR");
+ AttrCheck (Attr, CA_RANGE, "RANGE");
+
+ /* Address + Range may not exceed 16 bits */
+ if (((unsigned long) Range) > 0x10000UL - Addr) {
+ CfgError ("Range error");
+ }
+
+ /* Create the chip ## */
+
+ }
+}
+
+
+
static void ParseConfig (void)
/* Parse the config file */
{
+ static const IdentTok BlockNames [] = {
+ { "CHIPS", CFGTOK_CHIPS },
+ };
+ cfgtok_t BlockTok;
+
+ do {
+
+ /* Read the block ident */
+ CfgSpecialToken (BlockNames, ENTRY_COUNT (BlockNames), "Block identifier");
+ BlockTok = CfgTok;
+ CfgNextTok ();
+
+ /* Expected a curly brace */
+ CfgConsume (CFGTOK_LCURLY, "`{' expected");
+
+ /* Read the block */
+ switch (BlockTok) {
+
+ case CFGTOK_CHIPS:
+ ParseChips ();
+ break;
+
+ default:
+ FAIL ("Unexpected block token");
+
+ }
+
+ /* Skip closing brace */
+ CfgConsume (CFGTOK_RCURLY, "`}' expected");
+
+ } while (CfgTok != CFGTOK_EOF);
}
Error ("Simulator configuration missing");
}
- /* Read the config file */
- CfgRead ();
-
- /* Initialize modules */
+ /* Load the chips */
AddChipPath ("chips");
LoadChipLibrary ("ram.so");
LoadChips ();
+
+ /* Read the config file */
+ CfgRead ();
+
MemInit ();
- MemLoad ("uz.bin", 0x200, 0);
CPUInit ();
+#if 0
CPURun ();
+#endif
/* Return an apropriate exit code */
return EXIT_SUCCESS;
CFGTOK_DOT,
CFGTOK_EOF,
+ /* Primary blocks */
+ CFGTOK_CHIPS,
+
+ /* Chips section */
+ CFGTOK_NAME,
+ CFGTOK_ADDR,
+ CFGTOK_RANGE,
+
/* Special identifiers */
CFGTOK_TRUE,
CFGTOK_FALSE
-
+
} cfgtok_t;