mirror of
https://github.com/cc65/cc65.git
synced 2024-09-29 17:56:21 +00:00
Working
git-svn-id: svn://svn.cc65.org/cc65/trunk@1240 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
b07ea7d699
commit
3dcb7dba3b
@ -89,7 +89,7 @@ static int CmpChips (void* Data attribute ((unused)),
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@ -150,6 +150,13 @@ void LoadChips (void)
|
|||||||
|
|
||||||
/* Generate a new chip and insert it into the collection */
|
/* Generate a new chip and insert it into the collection */
|
||||||
CollAppend (&Chips, NewChip (L, Data));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +171,22 @@ const Chip* FindChip (const char* Name)
|
|||||||
* could not be found.
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,10 +61,10 @@ struct ChipData {
|
|||||||
/* -- Exported functions -- */
|
/* -- Exported functions -- */
|
||||||
int (*InitChip) (const struct SimData* Data);
|
int (*InitChip) (const struct SimData* Data);
|
||||||
void* (*InitInstance) (unsigned Addr, unsigned Range);
|
void* (*InitInstance) (unsigned Addr, unsigned Range);
|
||||||
void (*WriteCtrl) (void* Data, unsigned Addr, unsigned char Val);
|
void (*WriteCtrl) (void* Data, unsigned Offs, unsigned char Val);
|
||||||
void (*Write) (void* Data, unsigned Addr, unsigned char Val);
|
void (*Write) (void* Data, unsigned Offs, unsigned char Val);
|
||||||
unsigned char (*ReadCtrl) (void* Data, unsigned Addr);
|
unsigned char (*ReadCtrl) (void* Data, unsigned Offs);
|
||||||
unsigned char (*Read) (void* Data, unsigned Addr);
|
unsigned char (*Read) (void* Data, unsigned Offs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,16 +53,16 @@ int InitChip (const struct SimData* Data);
|
|||||||
static void* InitInstance (unsigned Addr, unsigned Range);
|
static void* InitInstance (unsigned Addr, unsigned Range);
|
||||||
/* Initialize a new chip instance */
|
/* 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 */
|
/* 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 */
|
/* Write user data */
|
||||||
|
|
||||||
static unsigned char ReadCtrl (void* Data, unsigned Addr);
|
static unsigned char ReadCtrl (void* Data, unsigned Offs);
|
||||||
/* Read control data */
|
/* Read control data */
|
||||||
|
|
||||||
static unsigned char Read (void* Data, unsigned Addr);
|
static unsigned char Read (void* Data, unsigned Offs);
|
||||||
/* Read user data */
|
/* Read user data */
|
||||||
|
|
||||||
|
|
||||||
@ -166,63 +166,63 @@ static void* InitInstance (unsigned Addr, unsigned Range)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void WriteCtrl (void* Data, unsigned Addr, unsigned char Val)
|
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val)
|
||||||
/* Write control data */
|
/* Write control data */
|
||||||
{
|
{
|
||||||
/* Cast the data pointer */
|
/* Cast the data pointer */
|
||||||
InstanceData* D = (InstanceData*) Data;
|
InstanceData* D = (InstanceData*) Data;
|
||||||
|
|
||||||
/* Do the write and remember the cell as initialized */
|
/* Do the write and remember the cell as initialized */
|
||||||
D->Mem[Addr] = Val;
|
D->Mem[Offs] = Val;
|
||||||
D->MemAttr[Addr] |= ATTR_INITIALIZED;
|
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 */
|
/* Write user data */
|
||||||
{
|
{
|
||||||
/* Cast the data pointer */
|
/* Cast the data pointer */
|
||||||
InstanceData* D = (InstanceData*) Data;
|
InstanceData* D = (InstanceData*) Data;
|
||||||
|
|
||||||
/* Check for a write to a write protected cell */
|
/* Check for a write to a write protected cell */
|
||||||
if (D->MemAttr[Addr] & ATTR_WPROT) {
|
if (D->MemAttr[Offs] & ATTR_WPROT) {
|
||||||
Sim->Warning ("Writing to write protected memory at $%04X", Addr);
|
Sim->Warning ("Writing to write protected memory at $%04X", D->BaseAddr+Offs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the write and remember the cell as initialized */
|
/* Do the write and remember the cell as initialized */
|
||||||
D->Mem[Addr] = Val;
|
D->Mem[Offs] = Val;
|
||||||
D->MemAttr[Addr] |= ATTR_INITIALIZED;
|
D->MemAttr[Offs] |= ATTR_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned char ReadCtrl (void* Data, unsigned Addr)
|
static unsigned char ReadCtrl (void* Data, unsigned Offs)
|
||||||
/* Read control data */
|
/* Read control data */
|
||||||
{
|
{
|
||||||
/* Cast the data pointer */
|
/* Cast the data pointer */
|
||||||
InstanceData* D = (InstanceData*) Data;
|
InstanceData* D = (InstanceData*) Data;
|
||||||
|
|
||||||
/* Read the cell and return the value */
|
/* 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 */
|
/* Read user data */
|
||||||
{
|
{
|
||||||
/* Cast the data pointer */
|
/* Cast the data pointer */
|
||||||
InstanceData* D = (InstanceData*) Data;
|
InstanceData* D = (InstanceData*) Data;
|
||||||
|
|
||||||
/* Check for a read from an uninitialized cell */
|
/* 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 */
|
/* 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 */
|
/* Read the cell and return the value */
|
||||||
return D->Mem[Addr];
|
return D->Mem[Offs];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -57,10 +57,10 @@ int InitChip (const struct SimData* Data);
|
|||||||
static void* InitInstance (unsigned Addr, unsigned Range);
|
static void* InitInstance (unsigned Addr, unsigned Range);
|
||||||
/* Initialize a new chip instance */
|
/* 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 */
|
/* Write user data */
|
||||||
|
|
||||||
static unsigned char Read (void* Data, unsigned Addr);
|
static unsigned char Read (void* Data, unsigned Offs);
|
||||||
/* Read user data */
|
/* Read user data */
|
||||||
|
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ static void* InitInstance (unsigned Addr attribute ((unused)),
|
|||||||
|
|
||||||
|
|
||||||
static void Write (void* Data attribute ((unused)),
|
static void Write (void* Data attribute ((unused)),
|
||||||
unsigned Addr attribute ((unused)),
|
unsigned Offs attribute ((unused)),
|
||||||
unsigned char Val)
|
unsigned char Val)
|
||||||
/* Write user data */
|
/* Write user data */
|
||||||
{
|
{
|
||||||
@ -150,7 +150,7 @@ static void Write (void* Data attribute ((unused)),
|
|||||||
|
|
||||||
|
|
||||||
static unsigned char Read (void* Data attribute ((unused)),
|
static unsigned char Read (void* Data attribute ((unused)),
|
||||||
unsigned Addr attribute ((unused)))
|
unsigned Offs attribute ((unused)))
|
||||||
/* Read user data */
|
/* Read user data */
|
||||||
{
|
{
|
||||||
/* Read a character and return the value */
|
/* Read a character and return the value */
|
||||||
@ -159,3 +159,4 @@ static unsigned char Read (void* Data attribute ((unused)),
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* ld65 */
|
/* sim65 */
|
||||||
|
#include "chip.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
@ -58,9 +59,154 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
static void ParseConfig (void)
|
||||||
/* Parse the config file */
|
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,17 +244,19 @@ int main (int argc, char* argv[])
|
|||||||
Error ("Simulator configuration missing");
|
Error ("Simulator configuration missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the config file */
|
/* Load the chips */
|
||||||
CfgRead ();
|
|
||||||
|
|
||||||
/* Initialize modules */
|
|
||||||
AddChipPath ("chips");
|
AddChipPath ("chips");
|
||||||
LoadChipLibrary ("ram.so");
|
LoadChipLibrary ("ram.so");
|
||||||
LoadChips ();
|
LoadChips ();
|
||||||
|
|
||||||
|
/* Read the config file */
|
||||||
|
CfgRead ();
|
||||||
|
|
||||||
MemInit ();
|
MemInit ();
|
||||||
MemLoad ("uz.bin", 0x200, 0);
|
|
||||||
CPUInit ();
|
CPUInit ();
|
||||||
|
#if 0
|
||||||
CPURun ();
|
CPURun ();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Return an apropriate exit code */
|
/* Return an apropriate exit code */
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -59,10 +59,18 @@ typedef enum {
|
|||||||
CFGTOK_DOT,
|
CFGTOK_DOT,
|
||||||
CFGTOK_EOF,
|
CFGTOK_EOF,
|
||||||
|
|
||||||
|
/* Primary blocks */
|
||||||
|
CFGTOK_CHIPS,
|
||||||
|
|
||||||
|
/* Chips section */
|
||||||
|
CFGTOK_NAME,
|
||||||
|
CFGTOK_ADDR,
|
||||||
|
CFGTOK_RANGE,
|
||||||
|
|
||||||
/* Special identifiers */
|
/* Special identifiers */
|
||||||
CFGTOK_TRUE,
|
CFGTOK_TRUE,
|
||||||
CFGTOK_FALSE
|
CFGTOK_FALSE
|
||||||
|
|
||||||
} cfgtok_t;
|
} cfgtok_t;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user