1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Turned sim65 into a lightweight cc65 execution environment.

The sim65 source code has been a construction site for over a decade.
I was looking for a simple cc65 program execution environment for
regression tests. So I decided to re-purpose sim65 for that task by
removing about everything but the 6502 emulation.

There's no memory mapped i/o emulation whatsoever. Rather exit(),
open(), close(), read() and write() calls are supported by mapping
them through a thin paravirtualization layer to the corresponding
host os functions.

Note: The sim65 6502 emulation provides means to switch between
6502 and 65C02 emulation but currently there are no actual 65C02
opcodes implemented.
This commit is contained in:
Oliver Schmidt 2013-05-20 20:20:14 +02:00
parent 753aa29b15
commit 3a028fb621
42 changed files with 3316 additions and 9482 deletions

View File

@ -9,6 +9,7 @@ PROGS = ar65 \
grc65 \
ld65 \
od65 \
sim65 \
sp65
CA65_INC := $(abspath ../asminc)

View File

@ -53,6 +53,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sp65", "sp65.vcxproj", "{43
{71DC1F68-BFC4-478C-8655-C8E9C9654D2B} = {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sim65", "sim65.vcxproj", "{002A366E-2863-46A8-BDDE-DDF534AAEC73}"
ProjectSection(ProjectDependencies) = postProject
{71DC1F68-BFC4-478C-8655-C8E9C9654D2B} = {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -103,6 +108,10 @@ Global
{4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Debug|Win32.Build.0 = Debug|Win32
{4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|Win32.ActiveCfg = Release|Win32
{4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|Win32.Build.0 = Release|Win32
{002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|Win32.ActiveCfg = Debug|Win32
{002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|Win32.Build.0 = Debug|Win32
{002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.ActiveCfg = Release|Win32
{002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

96
src/sim65.vcxproj Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{002A366E-2863-46A8-BDDE-DDF534AAEC73}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>sim65</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)..\bin\</OutDir>
<IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)..\bin\</OutDir>
<IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions>
<AdditionalIncludeDirectories>common</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions>
<AdditionalIncludeDirectories>common</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="sim65\6502.h" />
<ClInclude Include="sim65\error.h" />
<ClInclude Include="sim65\memory.h" />
<ClInclude Include="sim65\paravirt.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="sim65\6502.c" />
<ClCompile Include="sim65\error.c" />
<ClCompile Include="sim65\main.c" />
<ClCompile Include="sim65\memory.c" />
<ClCompile Include="sim65\paravirt.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

2830
src/sim65/6502.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/*****************************************************************************/
/* */
/* addrspace.h */
/* 6502.h */
/* */
/* CPU address space for the 6502 simulator */
/* CPU core for the 6502 */
/* */
/* */
/* */
@ -33,8 +33,8 @@
#ifndef ADDRSPACE_H
#define ADDRSPACE_H
#ifndef _6502_H
#define _6502_H
@ -44,20 +44,36 @@
/* Forwards */
struct CPUData;
struct ChipInstance;
/* Supported CPUs */
typedef enum CPUType {
CPU_6502,
CPU_65C02
} CPUType;
/* Forwards */
typedef struct AddressSpace AddressSpace;
struct AddressSpace {
struct CPU* CPU; /* Backpointer to CPU */
unsigned Size; /* Address space size */
struct ChipInstance* Data[1]; /* Pointer to chips, dynamically! */
/* Current CPU */
extern CPUType CPU;
/* 6502 CPU registers */
typedef struct CPURegs CPURegs;
struct CPURegs {
unsigned AC; /* Accumulator */
unsigned XR; /* X register */
unsigned YR; /* Y register */
unsigned ZR; /* Z register */
unsigned SR; /* Status register */
unsigned SP; /* Stackpointer */
unsigned PC; /* Program counter */
};
/* Status register bits */
#define CF 0x01 /* Carry flag */
#define ZF 0x02 /* Zero flag */
#define IF 0x04 /* Interrupt flag */
#define DF 0x08 /* Decimal flag */
#define BF 0x10 /* Break flag */
#define OF 0x40 /* Overflow flag */
#define SF 0x80 /* Sign flag */
/*****************************************************************************/
@ -66,34 +82,25 @@ struct AddressSpace {
AddressSpace* NewAddressSpace (unsigned Size);
/* Allocate a new address space and return it */
void Reset (void);
/* Generate a CPU RESET */
void ASWrite (AddressSpace* AS, unsigned Addr, unsigned char Val);
/* Write a byte to a given location */
void IRQRequest (void);
/* Generate an IRQ */
unsigned char ASRead (AddressSpace* AS, unsigned Addr);
/* Read a byte from a location */
void NMIRequest (void);
/* Generate an NMI */
void ASWriteCtrl (AddressSpace* AS, unsigned Addr, unsigned char Val);
/* Write a byte to a given location */
unsigned ExecuteInsn (void);
/* Execute one CPU instruction. Return the number of clock cycles for the
* executed instruction.
*/
unsigned char ASReadCtrl (AddressSpace* AS, unsigned Addr);
/* Read a byte from a location */
void ASAssignChip (AddressSpace* AS, struct ChipInstance* CI,
unsigned Addr, unsigned Range);
/* Assign a chip instance to memory locations */
struct ChipInstance* ASGetChip (const AddressSpace* AS, unsigned Addr);
/* Get the chip that is located at the given address (may return NULL). */
unsigned long GetCycles (void);
/* Return the total number of clock cycles executed */
/* End of addrspace.h */
/* End of 6502.h */
#endif

View File

@ -1,190 +0,0 @@
/*****************************************************************************/
/* */
/* addrspace.c */
/* */
/* CPU address space for the 6502 simulator */
/* */
/* */
/* */
/* (C) 2002-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
/* common */
#include "check.h"
#include "xmalloc.h"
/* sim65 */
#include "chip.h"
#include "cpucore.h"
#include "error.h"
#include "addrspace.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
AddressSpace* NewAddressSpace (unsigned Size)
/* Allocate a new address space and return it */
{
unsigned I;
/* Allocate memory */
AddressSpace* AS = xmalloc (sizeof (AddressSpace) +
(Size - 1) * sizeof (ChipInstance*));
/* Initialize the struct */
AS->CPU = 0;
AS->Size = Size;
for (I = 0; I < Size; ++I) {
AS->Data[I] = 0;
}
/* Return the new struct */
return AS;
}
void ASWrite (AddressSpace* AS, unsigned Addr, unsigned char Val)
/* Write a byte to a given location */
{
const ChipInstance* CI;
/* Make sure, the addresses are in a valid range */
PRECONDITION (Addr < AS->Size);
/* Get the instance of the chip at this address */
CI = AS->Data[Addr];
/* Check if the memory is mapped */
if (CI == 0) {
Break ("Writing to unassigned memory at $%06X", Addr);
} else {
CI->C->Data->Write (CI->Data, Addr - CI->Addr, Val);
}
}
unsigned char ASRead (AddressSpace* AS, unsigned Addr)
/* Read a byte from a location */
{
const ChipInstance* CI;
/* Make sure, the addresses are in a valid range */
PRECONDITION (Addr < AS->Size);
/* Get the instance of the chip at this address */
CI = AS->Data[Addr];
/* Check if the memory is mapped */
if (CI == 0) {
Break ("Reading from unassigned memory at $%06X", Addr);
return 0xFF;
} else {
return CI->C->Data->Read (CI->Data, Addr - CI->Addr);
}
}
void ASWriteCtrl (AddressSpace* AS, unsigned Addr, unsigned char Val)
/* Write a byte to a given location */
{
const ChipInstance* CI;
/* Make sure, the addresses are in a valid range */
PRECONDITION (Addr < AS->Size);
/* Get the instance of the chip at this address */
CI = AS->Data[Addr];
/* Check if the memory is mapped */
if (CI == 0) {
Break ("Writing to unassigned memory at $%06X", Addr);
} else {
CI->C->Data->WriteCtrl (CI->Data, Addr - CI->Addr, Val);
}
}
unsigned char ASReadCtrl (AddressSpace* AS, unsigned Addr)
/* Read a byte from a location */
{
const ChipInstance* CI;
/* Make sure, the addresses are in a valid range */
PRECONDITION (Addr < AS->Size);
/* Get the instance of the chip at this address */
CI = AS->Data[Addr];
/* Check if the memory is mapped */
if (CI == 0) {
Break ("Reading from unassigned memory at $%06X", Addr);
return 0xFF;
} else {
return CI->C->Data->ReadCtrl (CI->Data, Addr - CI->Addr);
}
}
void ASAssignChip (AddressSpace* AS, ChipInstance* CI,
unsigned Addr, unsigned Range)
/* Assign a chip instance to memory locations */
{
/* Make sure, the addresses are in a valid range */
PRECONDITION (Addr + Range <= AS->Size);
/* Assign the chip instance */
while (Range--) {
CHECK (AS->Data[Addr] == 0);
AS->Data[Addr++] = CI;
}
/* Set the backpointer to us */
CI->AS = AS;
}
ChipInstance* ASGetChip (const AddressSpace* AS, unsigned Addr)
/* Get the chip that is located at the given address (may return NULL). */
{
/* Make sure, the addresses are in a valid range */
PRECONDITION (Addr < AS->Size);
/* Return the chip instance */
return AS->Data[Addr];
}

View File

@ -1,191 +0,0 @@
/*****************************************************************************/
/* */
/* callback.c */
/* */
/* Chip callbacks */
/* */
/* */
/* */
/* (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. */
/* */
/*****************************************************************************/
/* common */
#include "xmalloc.h"
/* sim65 */
#include "error.h"
#include "callback.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
struct Callback {
Callback* Next; /* Next entry in list */
unsigned Ticks; /* Remaining ticks */
CallbackFunc UserFunc; /* User function */
void* UserData; /* User data */
};
/* Delta list that keeps existing callbacks */
static Callback* List = 0;
/*****************************************************************************/
/* Routines that handle the delta list */
/*****************************************************************************/
static void InsertCallback (Callback* C, unsigned Ticks)
/* Insert the callback C into the delta list */
{
/* Search for the insertion point */
Callback* N;
Callback** L = &List;
while ((N = *L) != 0) {
/* Check if the next callback in the list has a higher wait time */
if (N->Ticks > Ticks) {
/* Insert before this callback */
N->Ticks -= Ticks;
break;
} else {
/* Insert behind this callback */
Ticks -= N->Ticks;
L = &N->Next;
}
}
/* Insert the new task */
C->Ticks = Ticks;
C->Next = N;
*L = C;
}
static void RemoveCallback (Callback* C)
/* Remove a callback from the list. If the callback is not in the list, this
* is a fatal error.
*/
{
Callback* N;
Callback** L = &List;
while ((N = *L) != 0) {
if (N == C) {
/* Found, remove it */
if (C->Next) {
/* Adjust the counter of the following callback */
C->Next->Ticks += C->Ticks;
}
*L = C->Next;
return;
} else {
L = &N->Next;
}
}
/* Callback was not found */
Internal ("RemoveCallback: Callback not found in list!");
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
Callback* NewCallback (unsigned Ticks, CallbackFunc Func, void* Data)
/* Create a callback for function F to be called in Ticks ticks. */
{
/* Allocate memory */
Callback* C = xmalloc (sizeof (Callback));
/* Initialize the fields */
C->UserFunc = Func;
C->UserData = Data;
/* Insert the callback into the delta list */
InsertCallback (C, Ticks);
/* Return the new callback */
return C;
}
void FreeCallback (Callback* C)
/* Delete a callback (remove from the queue) */
{
/* Remove the callback from the list */
RemoveCallback (C);
/* Delete it */
xfree (C);
}
void HandleCallbacks (unsigned TicksSinceLastCall)
/* Handle the callback queue */
{
while (List) {
/* Check if this one is due */
if (List->Ticks <= TicksSinceLastCall) {
/* Calclulate the tick offset */
int TickOffs = ((int) List->Ticks) - ((int) TicksSinceLastCall);
/* Retrieve the first callback from the list */
Callback* C = List;
List = C->Next;
/* Call the user function */
C->UserFunc (TickOffs, C->UserData);
/* Delete the callback */
xfree (C);
} else {
List->Ticks -= TicksSinceLastCall;
break;
}
}
}

View File

@ -1,77 +0,0 @@
/*****************************************************************************/
/* */
/* callback.h */
/* */
/* Chip callbacks */
/* */
/* */
/* */
/* (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. */
/* */
/*****************************************************************************/
#ifndef CALLBACK_H
#define CALLBACK_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Type of a callback function */
typedef void (*CallbackFunc) (int TickOffs, void* UserData);
/* Forward */
typedef struct Callback Callback;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
Callback* NewCallback (unsigned Ticks, CallbackFunc Func, void* Data);
/* Create a callback for function F to be called in Ticks ticks. */
void FreeCallback (Callback* C);
/* Delete a callback (remove from the queue) */
void HandleCallbacks (unsigned TicksSinceLastCall);
/* Handle the callback queue */
/* End of callback.h */
#endif

View File

@ -1,234 +0,0 @@
/*****************************************************************************/
/* */
/* cfgdata.c */
/* */
/* Config data structure */
/* */
/* */
/* */
/* (C) 2002-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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 <string.h>
/* common */
#include "strutil.h"
#include "xmalloc.h"
/* sim65 */
#include "error.h"
#include "scanner.h"
#include "cfgdata.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
CfgData* NewCfgData (void)
/* Create and intialize a new CfgData struct, then return it. The function
* uses the current output of the config scanner.
*/
{
/* Allocate memory */
CfgData* D = xmalloc (sizeof (CfgData) + SB_GetLen (&CfgSVal));
/* Initialize the fields */
D->Type = CfgDataInvalid;
D->Line = CfgErrorLine;
D->Col = CfgErrorCol;
memcpy (D->Attr, SB_GetConstBuf (&CfgSVal), SB_GetLen (&CfgSVal) + 1);
/* Return the new struct */
return D;
}
void FreeCfgData (CfgData* D)
/* Free a config data structure */
{
if (D->Type == CfgDataId || D->Type == CfgDataString) {
/* Free the string value */
xfree (D->V.SVal);
}
/* Free the structure */
xfree (D);
}
void CfgDataCheckType (const CfgData* D, unsigned Type)
/* Check the config data type and print an error message if it has the wrong
* type.
*/
{
if (D->Type != Type) {
Error ("%s(%u): Attribute `%s' has invalid type",
CfgGetName (), D->Line, D->Attr);
}
}
int CfgDataFind (const Collection* Attributes, const char* AttrName)
/* Find the attribute with the given name and return its index. Return -1 if
* the attribute was not found.
*/
{
unsigned I;
/* Walk through the attributes checking for a "mirror" attribute */
for (I = 0; I < CollCount (Attributes); ++I) {
/* Get the next attribute */
const CfgData* D = CollConstAt (Attributes, I);
/* Compare the name */
if (StrCaseCmp (D->Attr, AttrName) == 0) {
/* Found */
return I;
}
}
/* Not found */
return -1;
}
CfgData* CfgDataGetTyped (Collection* Attributes, const char* Name, unsigned Type)
/* Find the attribute with the given name and type. If found, remove it from
* Attributes and return it. If not found or wrong type, return NULL.
*/
{
CfgData* D;
/* Search for the attribute */
int I = CfgDataFind (Attributes, Name);
if (I < 0) {
/* Not found */
return 0;
}
/* Get the attribute */
D = CollAtUnchecked (Attributes, I);
/* Check the type */
if (D->Type != Type) {
/* Wrong type. ### Warn here? */
return 0;
}
/* Remove the attribute and return it */
CollDelete (Attributes, I);
return D;
}
int CfgDataGetId (Collection* Attributes, const char* Name, char** Id)
/* Search CfgInfo for an attribute with the given name and type "id". If
* found, remove it from the configuration, copy it into Buf and return
* true. If not found, return false.
*/
{
CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataId);
if (D == 0) {
/* Not found or wrong type */
return 0;
}
/* Use the string value and invalidate the type, so FreeCfgData won't
* delete the string.
*/
*Id = D->V.SVal;
D->Type = CfgDataInvalid;
/* Delete the config data struct */
FreeCfgData (D);
/* Success */
return 1;
}
int CfgDataGetStr (Collection* Attributes, const char* Name, char** S)
/* Search CfgInfo for an attribute with the given name and type "string".
* If found, remove it from the configuration, copy it into Buf and return
* true. If not found, return false.
*/
{
CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataString);
if (D == 0) {
/* Not found or wrong type */
return 0;
}
/* Use the string value and invalidate the type, so FreeCfgData won't
* delete the string.
*/
*S = D->V.SVal;
D->Type = CfgDataInvalid;
/* Delete the config data struct */
FreeCfgData (D);
/* Success */
return 1;
}
int CfgDataGetNum (Collection* Attributes, 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.
*/
{
CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataNumber);
if (D == 0) {
/* Not found or wrong type */
return 0;
}
/* Return the value to the caller */
*Val = D->V.IVal;
/* Delete the config data struct */
FreeCfgData (D);
/* Success */
return 1;
}

View File

@ -1,120 +0,0 @@
/*****************************************************************************/
/* */
/* cfgdata.h */
/* */
/* Config data structure */
/* */
/* */
/* */
/* (C) 2002-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef CFGDATA_H
#define CFGDATA_H
/* common */
#include "coll.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
typedef struct CfgData CfgData;
struct CfgData {
enum {
CfgDataInvalid,
CfgDataId,
CfgDataNumber,
CfgDataString
} Type; /* Type of the value */
union {
char* SVal; /* String or id value */
long IVal; /* Integer value */
} V;
unsigned Line; /* Line where the attribute was defined */
unsigned Col; /* Column of attribute definition */
char Attr[1]; /* The attribute name */
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
CfgData* NewCfgData (void);
/* Create and intialize a new CfgData struct, then return it. The function
* uses the current output of the config scanner.
*/
void FreeCfgData (CfgData* D);
/* Free a config data structure */
void CfgDataCheckType (const CfgData* D, unsigned Type);
/* Check the config data type and print an error message if it has the wrong
* type.
*/
int CfgDataFind (const Collection* Attributes, const char* AttrName);
/* Find the attribute with the given name and return its index. Return -1 if
* the attribute was not found.
*/
int CfgDataGetId (Collection* Attributes, const char* Name, char** Id);
/* Search CfgInfo for an attribute with the given name and type "id". If
* found, remove it from the configuration, copy it into Buf and return
* true. If not found, return false.
*/
int CfgDataGetStr (Collection* Attributes, const char* Name, char** S);
/* Search CfgInfo for an attribute with the given name and type "string".
* If found, remove it from the configuration, copy it into Buf and return
* true. If not found, return false.
*/
int CfgDataGetNum (Collection* Attributes, 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.
*/
/* End of cfgdata.h */
#endif

View File

@ -1,419 +0,0 @@
/*****************************************************************************/
/* */
/* chip.c */
/* */
/* Interface for the chip plugins */
/* */
/* */
/* */
/* (C) 2002-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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 <string.h>
#include <dlfcn.h>
/* common */
#include "coll.h"
#include "fname.h"
#include "print.h"
#include "xmalloc.h"
/* sim65 */
#include "cfgdata.h"
#include "chip.h"
#include "chipdata.h"
#include "cpucore.h"
#include "error.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 */
/*****************************************************************************/
/* Sorted list of all chip data structures */
static Collection Chips = STATIC_COLLECTION_INITIALIZER;
/* A collection containing all libraries */
static Collection ChipLibraries = STATIC_COLLECTION_INITIALIZER;
/* SimData instance */
static const SimData Sim65Data = {
1, /* MajorVersion */
1, /* MinorVersion */
xmalloc,
xfree,
Warning,
Error,
Internal,
GetCfgId,
GetCfgStr,
GetCfgNum,
0,
0,
Break,
IRQRequest,
NMIRequest,
};
/*****************************************************************************/
/* Helper functions */
/*****************************************************************************/
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 */
{
/* Cast the object pointers */
const Chip* Left = (const Chip*) rhs;
const Chip* Right = (const Chip*) lhs;
/* Do the compare */
return strcmp (Left->Data->ChipName, Right->Data->ChipName);
}
static Chip* FindChip (const char* Name)
/* Find a chip by name. Returns the Chip data structure or NULL if the chip
* 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 */
Chip* C = CollAt (&Chips, I);
/* Compare the name */
if (strcmp (Name, C->Data->ChipName) == 0) {
/* Found */
return C;
}
}
/* Not found */
return 0;
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static ChipLibrary* NewChipLibrary (const char* PathName)
/* Create, initialize and return a new ChipLibrary structure */
{
/* Allocate memory */
ChipLibrary* L = xmalloc (sizeof (ChipLibrary));
/* Initialize the fields */
L->LibName = xstrdup (FindName (PathName));
L->PathName = xstrdup (PathName);
L->Handle = 0;
L->Chips = EmptyCollection;
/* Return the allocated structure */
return L;
}
static void FreeChipLibrary (ChipLibrary* L)
/* Free a ChipLibrary structure */
{
/* Free the names */
xfree (L->LibName);
xfree (L->PathName);
/* If the library is open, close it. Discard any errors. */
if (L->Handle) {
dlclose (L->Handle);
(void) dlerror ();
}
/* We may have to handle the Chip pointers, but currently the function
* is never called with a non empty Chips collection, so we don't care
* for now.
*/
xfree (L);
}
static Chip* NewChip (ChipLibrary* Library, const ChipData* Data)
/* Allocate a new chip structure, initialize and return it */
{
/* Allocate memory */
Chip* C = xmalloc (sizeof (Chip));
/* Initialize the fields */
C->Lib = Library;
C->Data = Data;
C->Instances = EmptyCollection;
/* Insert the new chip into the collection of all chips */
CollAppend (&Chips, C);
/* Return the structure */
return C;
}
ChipInstance* NewChipInstance (const char* ChipName, unsigned Addr,
unsigned Size, Collection* Attributes)
{
ChipInstance* CI;
/* Find the chip with the given name */
Chip* C = FindChip (ChipName);
if (C == 0) {
Error ("No chip `%s' found for address $%06X", ChipName, Addr);
}
/* Allocate a new ChipInstance structure */
CI = xmalloc (sizeof (*CI));
/* Initialize the fields */
CI->C = C;
CI->AS = 0;
CI->Addr = Addr;
CI->Size = Size;
CI->Data = C->Data->CreateInstance (Addr, Size, Attributes);
/* Assign the chip instance to the chip */
CollAppend (&C->Instances, CI);
/* Return the new instance struct */
return CI;
}
ChipInstance* MirrorChipInstance (const ChipInstance* Orig, unsigned Addr)
/* Generate a chip instance mirror and return it. */
{
/* Allocate a new ChipInstance structure */
ChipInstance* CI = xmalloc (sizeof (*CI));
/* Initialize the fields */
CI->C = Orig->C;
CI->AS = 0;
CI->Addr = Addr;
CI->Size = Orig->Size;
CI->Data = Orig->Data;
/* Assign the chip instance to the chip */
CollAppend (&CI->C->Instances, CI);
/* Return the new instance struct */
return CI;
}
void SortChips (void)
/* Sort all chips by name. Called after loading */
{
/* Last act: Sort the chips by name */
CollSort (&Chips, CmpChips, 0);
}
void LoadChipLibrary (const char* LibName)
/* Load a chip library. This includes loading the shared libary, allocating
* and initializing the data structure, and loading all chip data from the
* library.
*/
{
const char* Msg;
int (*GetChipData) (const struct ChipData**, unsigned*);
int ErrorCode;
const ChipData* Data; /* Pointer to chip data */
unsigned ChipCount; /* Number of chips in this library */
unsigned I;
/* Allocate a new ChipLibrary structure */
ChipLibrary* L = NewChipLibrary (LibName);
/* Open the library */
L->Handle = dlopen (L->PathName, RTLD_GLOBAL | RTLD_LAZY);
/* Check for errors */
Msg = dlerror ();
if (Msg) {
Error ("Cannot open `%s': %s", L->PathName, Msg);
FreeChipLibrary (L);
return;
}
/* Locate the GetChipData function */
GetChipData = dlsym (L->Handle, "GetChipData");
/* Check the error message */
Msg = dlerror ();
if (Msg) {
/* We had an error */
Error ("Cannot find export `GetChipData' in `%s': %s", L->LibName, Msg);
FreeChipLibrary (L);
return;
}
/* Call the function to read the chip data */
ErrorCode = GetChipData (&Data, &ChipCount);
if (ErrorCode != 0) {
Error ("Function `GetChipData' in `%s' returned error %d", L->LibName, ErrorCode);
FreeChipLibrary (L);
return;
}
/* Remember the library */
CollAppend (&ChipLibraries, L);
/* Print some information */
Print (stderr, 1, "Opened chip library `%s'\n", L->PathName);
/* Create the chips */
for (I = 0; I < ChipCount; ++I) {
Chip* C;
/* Get a pointer to the chip data */
const ChipData* D = Data + I;
/* Check if the chip data has the correct version */
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);
/* Ignore this chip */
continue;
}
/* Initialize the chip passing the simulator data */
D->InitChip (&Sim65Data);
/* Generate a new chip */
C = NewChip (L, D);
/* Insert a reference to the chip into the library exporting it */
CollAppend (&L->Chips, C);
/* Output chip name and version to keep the user happy */
Print (stdout, 1,
" 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);
}
}

View File

@ -1,118 +0,0 @@
/*****************************************************************************/
/* */
/* chip.h */
/* */
/* Interface for the chip plugins */
/* */
/* */
/* */
/* (C) 2003-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef CHIP_H
#define CHIP_H
/* common.h */
#include "coll.h"
/* sim65 */
#include "chipdata.h"
#include "simdata.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Forwards */
struct AddressSpace;
struct CfgData;
typedef struct ChipInstance ChipInstance;
typedef struct Chip Chip;
typedef struct ChipLibrary ChipLibrary;
/* One instance of a chip */
struct ChipInstance {
Chip* C; /* Pointer to corresponding chip */
struct AddressSpace* AS; /* Pointer to address space */
unsigned Addr; /* Start address of range */
unsigned Size; /* Size of range */
void* Data; /* Chip instance data */
};
/* Chip structure */
struct Chip {
struct ChipLibrary* Lib; /* Pointer to library data structure */
const ChipData* Data; /* Chip data as given by the library */
Collection Instances; /* Pointer to chip instances */
};
/* ChipLibrary structure */
struct ChipLibrary {
char* LibName; /* Name of the library as given */
char* PathName; /* Name of library including path */
void* Handle; /* Pointer to libary handle */
Collection Chips; /* Chips in this library */
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
ChipInstance* NewChipInstance (const char* ChipName, unsigned Addr,
unsigned Size, Collection* Attributes);
/* Allocate a new chip instance for the chip. */
ChipInstance* MirrorChipInstance (const ChipInstance* Orig, unsigned Addr);
/* Generate a chip instance mirror and return it. */
void SortChips (void);
/* Sort all chips by name. Called after loading */
void LoadChipLibrary (const char* LibName);
/* Load a chip library. This includes loading the shared libary, allocating
* and initializing the data structure, and loading all chip data from the
* library.
*/
/* End of chip.h */
#endif

View File

@ -1,82 +0,0 @@
/*****************************************************************************/
/* */
/* chipdata.h */
/* */
/* Chip description data structure */
/* */
/* */
/* */
/* (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 */
/* 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 CHIPDATA_H
#define CHIPDATA_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* 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
/* Forwards */
struct CfgData;
struct SimData;
/* ChipDesc structure */
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;
/* -- Exported functions -- */
int (*InitChip) (const struct SimData* Data);
void* (*CreateInstance) (unsigned Addr, unsigned Range, void* CfgInfo);
void (*DestroyInstance) (void* Data);
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);
};
/* End of chipdata.h */
#endif

View File

@ -1,52 +0,0 @@
/*****************************************************************************/
/* */
/* chipif.h */
/* */
/* Interface header file for chip plugins - unused by sim65 */
/* */
/* */
/* */
/* (C) 2002-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef CHIPIF_H
#define CHIPIF_H
/* sim65 */
#include "chipdata.h"
#include "simdata.h"
/* End of chipif.h */
#endif

View File

@ -1,81 +0,0 @@
/*****************************************************************************/
/* */
/* chippath.h */
/* */
/* Chip path handling for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 2000-2010, Ullrich von Bassewitz */
/* Roemerstrasse 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 <stdio.h>
#include <string.h>
#if defined(_MSC_VER)
/* Microsoft compiler */
# include <io.h>
#else
/* Anyone else */
# include <unistd.h>
#endif
/* sim65 */
#include "chippath.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
SearchPath* ChipSearchPath; /* Search paths for chip libs */
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void InitChipPaths (void)
/* Initialize the chip search path list */
{
/* Create the search path list */
ChipSearchPath = NewSearchPath ();
/* Add the current directory to the search path */
AddSearchPath (ChipSearchPath, "");
}

View File

@ -1,72 +0,0 @@
/*****************************************************************************/
/* */
/* chippath.h */
/* */
/* Chip path handling for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 2000-2010, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef CHIPPATH_H
#define CHIPPATH_H
/* common */
#include "searchpath.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
extern SearchPath* ChipSearchPath; /* Search paths for chip libs */
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void InitChipPaths (void);
/* Initialize the chip search path list */
/* End of chippath.h */
#endif

View File

@ -1,659 +0,0 @@
/*****************************************************************************/
/* */
/* console.c */
/* */
/* Console plugin for the sim65 simulator */
/* */
/* */
/* */
/* (C) 2003-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
/* common */
#include "attrib.h"
/* sim65 */
#include "chipif.h"
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
static int ScreenInitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
static void* ScreenCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
/* Create a new chip instance */
static void ScreenDestroyInstance (void* Data);
/* Destroy a chip instance */
static void ScreenWrite (void* Data, unsigned Offs, unsigned char Val);
/* Write user data */
static unsigned char ScreenRead (void* Data, unsigned Offs);
/* Read user data */
static void ScreenDrawBorder (void);
/* Draw the complete border */
static void ScreenDrawChar (unsigned Offs);
/* Draw one character at the given position */
static void ScreenDrawAllChars (void);
/* Redraw the complete interior screen */
static void ScreenEventLoop (void);
/* Get all waiting events and handle them */
/*****************************************************************************/
/* Global data */
/*****************************************************************************/
/* The SimData pointer we get when InitChip is called */
static const SimData* Sim;
/* Control data passed to the main program */
static const struct ChipData CData[] = {
{
"VIDEOSCREEN", /* Name of the chip */
CHIPDATA_TYPE_CHIP, /* Type of the chip */
CHIPDATA_VER_MAJOR, /* Version information */
CHIPDATA_VER_MINOR,
/* -- Exported functions -- */
ScreenInitChip,
ScreenCreateInstance,
ScreenDestroyInstance,
ScreenWrite,
ScreenWrite,
ScreenRead,
ScreenRead
},
};
/* Defines for console screen */
static const XColor GreenColor = {
0, 32*256, 141*256, 32*256, 0, 0 /* green */
};
static const XColor AmberColor = {
0, 255*256, 204*256, 51*256, 0, 0 /* amber */
};
static const XColor WhiteColor = {
0, 224*256, 224*256, 224*256, 0, 0 /* white */
};
static const XColor BgColor = {
0, 0*256, 0*256, 0*256, 0, 0 /* black */
};
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Screen instance data */
typedef struct ScreenInstance ScreenInstance;
struct ScreenInstance {
/* Settings passed from the simulator */
unsigned Addr; /* Address of the chip */
unsigned Range; /* Memory range */
/* X variables */
Display* ScreenDisplay;
Window ScreenWindow;
int Screen;
GC ScreenGC;
/* Windows rows and columns */
unsigned Rows;
unsigned Cols;
/* Window dimensions, determined by char resolution and char set */
unsigned XTotal;
unsigned YTotal;
/* Usable area within the window */
unsigned XSize;
unsigned YSize;
/* Offset of the usable area */
unsigned XOffs;
unsigned YOffs;
/* Character height */
unsigned CharHeight;
/* Fore- and background color */
XColor FgColor;
XColor BgColor;
/* A list of 4 rectangles used to draw the border */
XRectangle Border[4];
/* The virtual screen we are writing to. */
unsigned MemSize;
unsigned char* Mem;
/* The font data */
unsigned FontDataSize;
unsigned char* FontData;
};
/* If we have a video ram window, place it's instance data here */
static ScreenInstance* VScreen = 0;
/*****************************************************************************/
/* Exported function */
/*****************************************************************************/
int GetChipData (const ChipData** Data, unsigned* Count)
{
/* Pass the control structure to the caller */
*Data = CData;
*Count = sizeof (CData) / sizeof (CData[0]);
/* Call was successful */
return 0;
}
/*****************************************************************************/
/* Helper functions */
/*****************************************************************************/
static long CfgGetNum (void* CfgInfo, const char* AttrName, long Min, long Max, long Def)
/* Read a number from the attributes. Check against Min/Max. Return the
* number or Def if it doesn't exist.
*/
{
long Val;
/* Read the attribute if it does exist */
if (Sim->GetCfgNum (CfgInfo, AttrName, &Val)) {
/* Check it */
if (Val < Min || Val > Max) {
Sim->Error ("Range error for attribute `%s'", AttrName);
}
/* Return it */
return Val;
} else {
/* Return the default */
return Def;
}
}
/*****************************************************************************/
/* Console screen */
/*****************************************************************************/
static int ScreenInitChip (const struct SimData* Data)
/* Initialize the chip, return an error code */
{
/* Remember the pointer */
Sim = Data;
/* Always successful */
return 0;
}
static void* ScreenCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
/* Create a new chip instance */
{
char* Name;
FILE* F;
unsigned ColorDepth;
Colormap CM;
XSizeHints SizeHints;
XWMHints WMHints;
Cursor C;
unsigned CharColor;
/* Allocate the instance data */
ScreenInstance* V = VScreen = Sim->Malloc (sizeof (ScreenInstance));
/* Remember a few settings */
V->Addr = Addr;
V->Range = Range;
/* Character height is 8 or given as attribute */
V->CharHeight = (unsigned) CfgGetNum (CfgInfo, "charheight", 8, 16, 8);
/* Allocate memory for the font */
V->FontDataSize = V->CharHeight * 256;
V->FontData = Sim->Malloc (V->FontDataSize);
/* We must have a "fontdata" attribute. Get it. */
if (Sim->GetCfgStr (CfgInfo, "fontdata", &Name) == 0) {
/* Attribute not found */
Sim->Error ("Attribute `fontdata' 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 (V->FontData, 1, V->FontDataSize, F) != V->FontDataSize) {
Sim->Warning ("Font data file `%s' seems to be corrupt", Name);
}
/* Close the file */
fclose (F);
/* Free the file name */
Sim->Free (Name);
/* Read screen rows and columns */
V->Rows = (unsigned) CfgGetNum (CfgInfo, "rows", 15, 75, 25);
V->Cols = (unsigned) CfgGetNum (CfgInfo, "cols", 32, 132, 80);
/* Allocate screen memory and clear it */
V->MemSize = V->Rows * V->Cols;
V->Mem = Sim->Malloc (V->MemSize);
memset (V->Mem, ' ', V->MemSize);
/* Setup the window geometry */
V->XSize = V->Cols * 8;
V->YSize = V->Rows * V->CharHeight;
V->XTotal = V->XSize + 20;
V->YTotal = V->YSize + 20;
V->XOffs = (V->XTotal - V->XSize) / 2;
V->YOffs = (V->YTotal - V->YSize) / 2;
/* Setup the rectanges used to draw the exterior */
V->Border[0].x = 0;
V->Border[0].y = 0;
V->Border[0].width = V->XTotal;
V->Border[0].height = V->YOffs;
V->Border[1].x = 0;
V->Border[1].y = V->YOffs + V->YSize;
V->Border[1].width = V->XTotal;
V->Border[1].height = V->YOffs;
V->Border[2].x = 0;
V->Border[2].y = V->YOffs;
V->Border[2].width = V->XOffs;
V->Border[2].height = V->YSize;
V->Border[3].x = V->XOffs + V->XSize;
V->Border[3].y = V->YOffs;
V->Border[3].width = V->XOffs;
V->Border[3].height = V->YSize;
/* Open the X display. */
V->ScreenDisplay = XOpenDisplay ("");
if (V->ScreenDisplay == NULL) {
Sim->Error ("Screen: Cannot open X display");
}
/* Get a screen */
V->Screen = DefaultScreen (V->ScreenDisplay);
/* Check the available colors. For now, we expect direct colors, so we
* will check for a color depth of at least 16.
*/
ColorDepth = XDefaultDepth (V->ScreenDisplay, V->Screen);
if (ColorDepth < 16) {
/* OOPS */
Sim->Error ("Screen: Need color display");
}
/* Determine the character color */
CharColor = (unsigned) CfgGetNum (CfgInfo, "charcolor", 0, 2, 0);
/* Get all needed colors */
switch (CharColor) {
case 1: V->FgColor = AmberColor; break;
case 2: V->FgColor = WhiteColor; break;
default: V->FgColor = GreenColor; break;
}
V->BgColor = BgColor;
CM = DefaultColormap (V->ScreenDisplay, V->Screen);
if (XAllocColor (V->ScreenDisplay, CM, &V->FgColor) == 0) {
Sim->Error ("Screen: Cannot allocate foreground color");
}
if (XAllocColor (V->ScreenDisplay, CM, &V->BgColor) == 0) {
Sim->Error ("Screen: Cannot allocate background color");
}
/* Set up the size hints structure */
SizeHints.x = 0;
SizeHints.y = 0;
SizeHints.flags = PPosition | PSize | PMinSize | PMaxSize | PResizeInc;
SizeHints.width = V->XTotal;
SizeHints.height = V->YTotal;
SizeHints.min_width = V->XTotal;
SizeHints.min_height = V->YTotal;
SizeHints.max_width = V->XTotal;
SizeHints.max_height = V->YTotal;
SizeHints.width_inc = 0;
SizeHints.height_inc = 0;
WMHints.flags = InputHint;
WMHints.input = True;
/* Create the window */
V->ScreenWindow = XCreateSimpleWindow (V->ScreenDisplay,
DefaultRootWindow (V->ScreenDisplay),
SizeHints.x,
SizeHints.y,
SizeHints.width,
SizeHints.height,
5,
V->FgColor.pixel,
V->BgColor.pixel);
/* Set the standard window properties */
XSetStandardProperties (V->ScreenDisplay, /* Display */
V->ScreenWindow, /* Window */
"sim65 console screen", /* Window name */
"sim65 console screen", /* Icon name */
None, /* Icon Pixmap */
0, /* argv */
0, /* argc */
&SizeHints); /* Hints */
XSetWMHints (V->ScreenDisplay, V->ScreenWindow, &WMHints);
/* GC creation and initialization */
V->ScreenGC = XCreateGC (V->ScreenDisplay, V->ScreenWindow, 0, 0);
/* Set the cursor to show over the console window */
C = XCreateFontCursor (V->ScreenDisplay, XC_pirate);
XDefineCursor (V->ScreenDisplay, V->ScreenWindow, C);
/* Select input events */
XSelectInput (V->ScreenDisplay, V->ScreenWindow, ExposureMask | StructureNotifyMask | KeyPressMask);
/* Show the window */
XMapRaised (V->ScreenDisplay, V->ScreenWindow);
/* Handle events */
ScreenEventLoop ();
/* Return the instance data */
return V;
}
static void ScreenDestroyInstance (void* Data)
/* Destroy a chip instance */
{
/* Cast the data pointer */
ScreenInstance* V = Data;
/* Free X resources */
XUndefineCursor (V->ScreenDisplay, V->ScreenWindow);
XFreeGC (V->ScreenDisplay, V->ScreenGC);
XDestroyWindow (V->ScreenDisplay, V->ScreenWindow);
XCloseDisplay (V->ScreenDisplay);
/* Clear the global pointer */
VScreen = 0;
/* Free the instance data */
Sim->Free (V->FontData);
Sim->Free (V->Mem);
Sim->Free (V);
}
static void ScreenWrite (void* Data, unsigned Offs, unsigned char Val)
/* Write user data */
{
/* Cast the data pointer */
ScreenInstance* V = Data;
/* Check the offset */
if (Offs >= V->MemSize) {
Sim->Break ("Screen: Accessing invalid memory at $%06X", V->Addr + Offs);
return;
}
/* Write the value */
V->Mem[Offs] = Val;
/* Schedule a redraw */
ScreenDrawChar (Offs);
/* Call the event loop */
ScreenEventLoop ();
}
static unsigned char ScreenRead (void* Data, unsigned Offs)
/* Read user data */
{
/* Cast the data pointer */
ScreenInstance* V = Data;
/* Check the offset */
if (Offs >= sizeof (V->Mem)) {
Sim->Break ("Screen: Accessing invalid memory at $%06X", V->Addr + Offs);
return 0xFF;
} else {
return V->Mem[Offs];
}
}
static void ScreenDrawBorder (void)
/* Draw the complete border */
{
if (VScreen) {
/* Set the border color */
XSetForeground (VScreen->ScreenDisplay, VScreen->ScreenGC, VScreen->BgColor.pixel);
/* Fill all rectangles that make the border */
XFillRectangles (VScreen->ScreenDisplay, VScreen->ScreenWindow, VScreen->ScreenGC,
VScreen->Border, sizeof (VScreen->Border) / sizeof (VScreen->Border[0]));
}
}
static void ScreenDrawChar (unsigned Offs)
/* Draw one character at the given position */
{
unsigned Row, Col;
XPoint Points[128];
unsigned PCount;
/* Get the character from the video RAM */
unsigned char C = VScreen->Mem[Offs];
/* Calculate the offset for the character data in the character ROM */
unsigned char* D = VScreen->FontData + (C * VScreen->CharHeight);
/* Calculate the coords for the output */
unsigned X = VScreen->XOffs + (Offs % VScreen->Cols) * 8;
unsigned Y = VScreen->YOffs + (Offs / VScreen->Cols) * VScreen->CharHeight;
/* Clear the character area with the background color */
XSetForeground (VScreen->ScreenDisplay, VScreen->ScreenGC, VScreen->BgColor.pixel);
XFillRectangle (VScreen->ScreenDisplay, VScreen->ScreenWindow, VScreen->ScreenGC, X, Y, 8, VScreen->CharHeight);
/* Prepare the foreground pixels */
PCount = 0;
for (Row = 0; Row < VScreen->CharHeight; ++Row) {
/* Get next byte from char rom */
unsigned Data = *D++;
/* Make pixels from this byte */
for (Col = 0; Col < 8; ++Col) {
if (Data & 0x80) {
/* Foreground pixel */
Points[PCount].x = X + Col;
Points[PCount].y = Y + Row;
++PCount;
}
Data <<= 1;
}
}
if (PCount) {
/* Set the character color */
XSetForeground (VScreen->ScreenDisplay, VScreen->ScreenGC, VScreen->FgColor.pixel);
/* Draw the pixels */
XDrawPoints (VScreen->ScreenDisplay, VScreen->ScreenWindow, VScreen->ScreenGC,
Points, PCount, CoordModeOrigin);
}
}
static void ScreenDrawArea (unsigned X1, unsigned Y1, unsigned X2, unsigned Y2)
/* Update an area of the interior screen */
{
unsigned X, Y;
/* Check if we have to draw anything */
if (X2 < VScreen->XOffs || Y2 < VScreen->YOffs ||
X1 >= VScreen->XOffs + VScreen->XSize ||
Y1 >= VScreen->YOffs + VScreen->YSize) {
/* Completely outside */
return;
}
/* Make the coordinates relative to the interior */
X1 -= VScreen->XOffs;
Y1 -= VScreen->YOffs;
X2 -= VScreen->XOffs;
Y2 -= VScreen->YOffs;
/* Loop updating characters */
for (Y = Y1; Y <= Y2; Y += 8) {
for (X = X1; X <= X2; X += 8) {
ScreenDrawChar ((Y / 8) * 40 + (X / 8));
}
}
}
static void ScreenDrawAllChars (void)
/* Redraw the complete interior screen */
{
unsigned I;
for (I = 0; I < 25*40; ++I) {
ScreenDrawChar (I);
}
}
static void ScreenEventLoop (void)
/* Get all waiting events and handle them */
{
unsigned X1, Y1, X2, Y2;
/* Read input events */
while (XEventsQueued (VScreen->ScreenDisplay, QueuedAfterFlush) != 0) {
/* Read an event */
XEvent Event;
XNextEvent (VScreen->ScreenDisplay, &Event);
switch (Event.type) {
case Expose:
/* Calculate the area to redraw, then update the screen */
X1 = Event.xexpose.x;
Y1 = Event.xexpose.y;
X2 = Event.xexpose.x + Event.xexpose.width - 1;
Y2 = Event.xexpose.y + Event.xexpose.height - 1;
if (X1 < VScreen->XOffs || X2 > VScreen->XOffs + VScreen->XSize ||
Y1 < VScreen->YOffs || Y2 > VScreen->YOffs + VScreen->YSize) {
/* Update the border */
ScreenDrawBorder ();
}
ScreenDrawArea (X1, Y1, X2, Y2);
break;
case MappingNotify:
XRefreshKeyboardMapping (&Event.xmapping);
break;
case KeyPress:
break;
default:
/* Ignore anything else */
break;
}
}
/* Flush the outgoing event queue */
XFlush (VScreen->ScreenDisplay);
}

View File

@ -1,266 +0,0 @@
/*****************************************************************************/
/* */
/* ram.c */
/* */
/* RAM plugin for the sim65 6502 simulator */
/* */
/* */
/* */
/* (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 */
/* 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 <stdlib.h>
#include <string.h>
/* sim65 */
#include "chipif.h"
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
static int InitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
/* Create a new chip instance */
static void DestroyInstance (void* Data);
/* Destroy a 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 CData[1] = {
{
"RAM", /* Name of the chip */
CHIPDATA_TYPE_CHIP, /* Type of the chip */
CHIPDATA_VER_MAJOR, /* Version information */
CHIPDATA_VER_MINOR,
/* -- Exported functions -- */
InitChip,
CreateInstance,
DestroyInstance,
WriteCtrl,
Write,
ReadCtrl,
Read
}
};
/* The SimData pointer we get when InitChip is called */
static const SimData* Sim;
/* Possible RAM attributes */
#define ATTR_INITIALIZED 0x01 /* RAM cell is intialized */
#define ATTR_WPROT 0x02 /* RAM cell is write protected */
/* Data for one RAM instance */
typedef struct InstanceData InstanceData;
struct InstanceData {
unsigned BaseAddr; /* Base address */
unsigned Range; /* Memory range */
unsigned char* MemAttr; /* Memory attributes */
unsigned char* Mem; /* The memory itself */
};
/*****************************************************************************/
/* Exported function */
/*****************************************************************************/
int GetChipData (const ChipData** Data, unsigned* Count)
{
/* Pass the control structure to the caller */
*Data = CData;
*Count = sizeof (CData) / sizeof (CData[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* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
/* Create a new chip instance */
{
long Val;
/* 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->MemAttr = Sim->Malloc (Range * sizeof (D->MemAttr[0]));
D->Mem = Sim->Malloc (Range * sizeof (D->Mem[0]));
/* Check if a value is given that should be used to clear the RAM.
* Otherwise use random values.
*/
if (Sim->GetCfgNum (CfgInfo, "fill", &Val) == 0) {
/* No "fill" attribute */
unsigned I;
for (I = 0; I < Range; ++I) {
D->Mem[I] = (unsigned char) rand ();
}
} else {
/* Got a "fill" attribute */
memset (D->Mem, (int) Val, Range);
}
/* Clear the attribute memory */
memset (D->MemAttr, 0, Range * sizeof (D->MemAttr[0]));
/* Done, return the instance data */
return D;
}
static void DestroyInstance (void* Data)
/* Destroy a chip instance */
{
/* Cast the data pointer */
InstanceData* D = (InstanceData*) Data;
/* Free memory and attributes */
Sim->Free (D->Mem);
Sim->Free (D->MemAttr);
/* Free the instance data itself */
free (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 and remember the cell as initialized */
D->Mem[Offs] = Val;
D->MemAttr[Offs] |= ATTR_INITIALIZED;
}
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[Offs] & ATTR_WPROT) {
Sim->Break ("Writing to write protected memory at $%04X", D->BaseAddr+Offs);
}
/* Do the write and remember the cell as initialized */
D->Mem[Offs] = Val;
D->MemAttr[Offs] |= ATTR_INITIALIZED;
}
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;
/* 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->Break ("Reading from uninitialized memory at $%04X", D->BaseAddr+Offs);
}
/* Read the cell and return the value */
return D->Mem[Offs];
}

View File

@ -1,255 +0,0 @@
/*****************************************************************************/
/* */
/* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* sim65 */
#include "chipif.h"
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
static int InitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
/* Create a new chip instance */
static void DestroyInstance (void* Data);
/* Destroy a 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 CData[1] = {
{
"ROM", /* Name of the chip */
CHIPDATA_TYPE_CHIP, /* Type of the chip */
CHIPDATA_VER_MAJOR, /* Version information */
CHIPDATA_VER_MINOR,
/* -- Exported functions -- */
InitChip,
CreateInstance,
DestroyInstance,
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 = CData;
*Count = sizeof (CData) / sizeof (CData[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* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
/* Create 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 DestroyInstance (void* Data)
/* Destroy a chip instance */
{
/* Cast the data pointer */
InstanceData* D = (InstanceData*) Data;
/* Free the ROM memory */
Sim->Free (D->Mem);
/* Free the instance data itself */
free (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];
}

View File

@ -1,289 +0,0 @@
/*****************************************************************************/
/* */
/* stdio.c */
/* */
/* STDIO plugin for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 2002-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
/* common */
#include "attrib.h"
/* sim65 */
#include "chipif.h"
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
static int InitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
/* Create a new chip instance */
static void DestroyInstance (void* Data);
/* Destroy a 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 */
/*****************************************************************************/
/* The SimData pointer we get when InitChip is called */
static const SimData* Sim;
/* Control data passed to the main program */
static const struct ChipData CData[1] = {
{
"STDIO", /* Name of the chip */
CHIPDATA_TYPE_CHIP, /* Type of the chip */
CHIPDATA_VER_MAJOR, /* Version information */
CHIPDATA_VER_MINOR,
/* -- Exported functions -- */
InitChip,
CreateInstance,
DestroyInstance,
WriteCtrl,
Write,
ReadCtrl,
Read
}
};
/* Screen instance data */
typedef struct InstanceData InstanceData;
struct InstanceData {
/* The memory area used for data */
unsigned char* Mem[32];
};
/* Function opcodes */
enum {
F_open,
F_close,
F_write,
F_read,
F_lseek,
F_unlink,
F_chdir,
F_getcwd,
F_mkdir,
F_rmdir,
};
/*****************************************************************************/
/* Exported function */
/*****************************************************************************/
int GetChipData (const ChipData** Data, unsigned* Count)
{
/* Pass the control structure to the caller */
*Data = CData;
*Count = sizeof (CData) / sizeof (CData[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* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
/* Initialize a new chip instance */
{
/* Allocate the instance data */
InstanceData* D = Sim->Malloc (sizeof (InstanceData));
/* Initialize the instance data */
memset (D->Mem, 0x00, sizeof (D->Mem));
/* Return the instance data */
return D;
}
static void DestroyInstance (void* Data)
/* Destroy a chip instance */
{
/* Cast the instance data pointer */
InstanceData* D = Data;
/* Free the instance data */
Sim->Free (D);
}
static void WriteCtrl (void* Data attribute, unsigned Offs, unsigned char Val)
/* Write user data */
{
/* Cast the instance data pointer */
InstanceData* D = Data;
/* Write to the memory */
D->Mem[Offs] = Val;
}
static void Write (void* Data, unsigned Offs, unsigned char Val)
/* Write user data */
{
/* Cast the instance data pointer */
InstanceData* D = Data;
/* Write to the memory */
D->Mem[Offs] = Val;
/* Now check the offset. Zero is special because it will trigger the
* action
*/
if (Offs == 0) {
/* The action is determined by the value that is written */
switch (Val) {
case F_open:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_close:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_write:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_read:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_lseek:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_unlink:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_chdir:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_getcwd:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_mkdir:
Sim->Break ("Unsupported function $%02X", Val);
break;
case F_rmdir:
Sim->Break ("Unsupported function $%02X", Val);
break;
}
}
}
static unsigned char ReadCtrl (void* Data, unsigned Offs)
/* Read user data */
{
/* Cast the instance data pointer */
InstanceData* D = 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 instance data pointer */
InstanceData* D = Data;
/* Read the cell and return the value */
return D->Mem[Offs];
}

View File

@ -1,897 +0,0 @@
/*****************************************************************************/
/* */
/* vic2.c */
/* */
/* VIC II 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
/* common */
#include "attrib.h"
/* sim65 */
#include "chipif.h"
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
static int VicInitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
static void* VicCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
/* Create a new chip instance */
static void VicDestroyInstance (void* Data);
/* Destroy a chip instance */
static void VicWrite (void* Data, unsigned Offs, unsigned char Val);
/* Write user data */
static unsigned char VicRead (void* Data, unsigned Offs);
/* Read user data */
static int VRamInitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
static void* VRamCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
/* Create a new chip instance */
static void VRamDestroyInstance (void* Data);
/* Destroy a chip instance */
static void VRamWrite (void* Data, unsigned Offs, unsigned char Val);
/* Write user data */
static unsigned char VRamRead (void* Data, unsigned Offs);
/* Read user data */
static void VRamDrawBorder (void);
/* Draw the complete border */
static void VRamDrawChar (unsigned Offs);
/* Draw one character at the given position */
static void VRamDrawAllChars (void);
/* Redraw the complete interior screen */
static void VRamEventLoop (void);
/* Get all waiting events and handle them */
static int CRamInitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
static void* CRamCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
/* Create a new chip instance */
static void CRamDestroyInstance (void* Data);
/* Destroy a chip instance */
static void CRamWrite (void* Data, unsigned Offs, unsigned char Val);
/* Write user data */
static unsigned char CRamRead (void* Data, unsigned Offs);
/* Read user data */
/*****************************************************************************/
/* Global data */
/*****************************************************************************/
/* The SimData pointer we get when InitChip is called */
static const SimData* Sim;
/* Control data passed to the main program */
static const struct ChipData CData[] = {
{
"VIC2", /* Name of the chip */
CHIPDATA_TYPE_CHIP, /* Type of the chip */
CHIPDATA_VER_MAJOR, /* Version information */
CHIPDATA_VER_MINOR,
/* -- Exported functions -- */
VicInitChip,
VicCreateInstance,
VicDestroyInstance,
VicWrite,
VicWrite,
VicRead,
VicRead
},
{
"VIC2-VIDEORAM", /* Name of the chip */
CHIPDATA_TYPE_CHIP, /* Type of the chip */
CHIPDATA_VER_MAJOR, /* Version information */
CHIPDATA_VER_MINOR,
/* -- Exported functions -- */
VRamInitChip,
VRamCreateInstance,
VRamDestroyInstance,
VRamWrite,
VRamWrite,
VRamRead,
VRamRead
},
{
"VIC2-COLORRAM", /* Name of the chip */
CHIPDATA_TYPE_CHIP, /* Type of the chip */
CHIPDATA_VER_MAJOR, /* Version information */
CHIPDATA_VER_MINOR,
/* -- Exported functions -- */
CRamInitChip,
CRamCreateInstance,
CRamDestroyInstance,
CRamWrite,
CRamWrite,
CRamRead,
CRamRead
}
};
/* Defines for the VIC chip */
#define VIC_COLOR_COUNT 16
#define VIC_BLACK 0
#define VIC_WHITE 1
/* The application color map. VIC II color values are taken from
* http://www.pepto.de/projects/colorvic/ (Philip "Pepto" Timmermann)
*/
static XColor VicColors [VIC_COLOR_COUNT] = {
{ 0, 0*256, 0*256, 0*256, 0, 0 }, /* black */
{ 0, 255*256, 255*256, 255*256, 0, 0 }, /* white */
{ 0, 104*256, 55*256, 43*256, 0, 0 }, /* red */
{ 0, 112*256, 163*256, 178*256, 0, 0 }, /* cyan */
{ 0, 111*256, 61*256, 134*256, 0, 0 }, /* purple */
{ 0, 88*256, 141*256, 67*256, 0, 0 }, /* green */
{ 0, 53*256, 40*256, 121*256, 0, 0 }, /* blue */
{ 0, 184*256, 199*256, 111*256, 0, 0 }, /* yellow */
{ 0, 111*256, 79*256, 37*256, 0, 0 }, /* orange */
{ 0, 67*256, 57*256, 0*256, 0, 0 }, /* brown */
{ 0, 154*256, 103*256, 89*256, 0, 0 }, /* light red */
{ 0, 68*256, 68*256, 68*256, 0, 0 }, /* dark grey */
{ 0, 108*256, 108*256, 108*256, 0, 0 }, /* grey */
{ 0, 154*256, 210*256, 132*256, 0, 0 }, /* light green */
{ 0, 108*256, 94*256, 181*256, 0, 0 }, /* light blue */
{ 0, 149*256, 149*256, 149*256, 0, 0 } /* light grey */
};
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* VIC II instance data */
typedef struct VicInstance VicInstance;
struct VicInstance {
unsigned Addr; /* Address of the chip */
unsigned Range; /* Memory range */
unsigned char Regs[47]; /* VIC registers */
};
/* Video RAM instance data */
typedef struct VRamInstance VRamInstance;
struct VRamInstance {
/* Settings passed from the simulator */
unsigned Addr; /* Address of the chip */
unsigned Range; /* Memory range */
/* X variables */
Display* VicDisplay;
Window VicWindow;
int VicScreen;
GC VicGC;
/* Window dimensions, 384*288 (PAL) */
unsigned XTotal;
unsigned YTotal;
/* Usable area within the window */
unsigned XSize;
unsigned YSize;
/* Offset of the usable area */
unsigned XOffs;
unsigned YOffs;
/* The window color map. */
XColor Colors [VIC_COLOR_COUNT];
/* A list of 4 rectangles used to draw the border */
XRectangle Border[4];
/* The virtual screen we are writing to. */
unsigned char Mem[0x400];
/* The character ROM data */
unsigned char CharRom[0x1000];
};
typedef struct CRamInstance CRamInstance;
struct CRamInstance {
/* Settings passed from the simulator */
unsigned Addr; /* Address of the chip */
unsigned Range; /* Memory range */
/* The memory we are writing to. */
unsigned char Mem[0x400];
};
/* If we have a video ram window, place it's instance data here */
static VicInstance* Vic = 0;
static VRamInstance* VRam = 0;
static CRamInstance* CRam = 0;
/*****************************************************************************/
/* Exported function */
/*****************************************************************************/
int GetChipData (const ChipData** Data, unsigned* Count)
{
/* Pass the control structure to the caller */
*Data = CData;
*Count = sizeof (CData) / sizeof (CData[0]);
/* Call was successful */
return 0;
}
/*****************************************************************************/
/* VIC II Chip */
/*****************************************************************************/
static int VicInitChip (const struct SimData* Data)
/* Initialize the chip, return an error code */
{
/* Remember the pointer */
Sim = Data;
/* Always successful */
return 0;
}
static void* VicCreateInstance (unsigned Addr, unsigned Range,
void* CfgInfo attribute ((unused)))
/* Initialize a new chip instance */
{
/* Allocate a new instance structure */
VicInstance* V = Vic = Sim->Malloc (sizeof (VicInstance));
/* Initialize the structure, allocate RAM and attribute memory */
V->Addr = Addr;
V->Range = Range;
memset (V->Regs, 0, sizeof (V->Regs));
/* Done, return the instance data */
return V;
}
static void VicDestroyInstance (void* Data)
/* Destroy a chip instance */
{
/* Cast the data pointer */
VicInstance* V = Data;
/* Free the instance data */
Sim->Free (V);
}
static void VicWrite (void* Data, unsigned Offs, unsigned char Val)
/* Write user data */
{
/* Cast the data pointer */
VicInstance* V = Data;
/* Check for a write outside our range */
if (Offs >= sizeof (V->Regs)) {
Sim->Break ("Writing to invalid VIC register at $%04X", V->Addr+Offs);
} else {
/* Do the write */
V->Regs[Offs] = Val;
/* Handle special registers */
switch (Offs) {
case 32:
/* Exterior color */
if (VRam) {
VRamDrawBorder ();
}
break;
case 33:
/* Background color #0 */
if (VRam) {
VRamDrawAllChars ();
}
break;
}
/* Handle the event queue */
if (VRam) {
VRamEventLoop ();
}
}
}
static unsigned char VicRead (void* Data, unsigned Offs)
/* Read user data */
{
/* Cast the data pointer */
VicInstance* V = Data;
/* Simulate the rasterline register */
if (V->Regs[17] & 0x80) {
if (++V->Regs[18] == (312 & 0xFF)) {
V->Regs[17] &= 0x7F;
V->Regs[18] = 0;
}
} else {
if (++V->Regs[18] == 0) {
V->Regs[17] |= 0x80;
}
}
/* Check for a read outside our range */
if (Offs >= sizeof (V->Regs)) {
Sim->Break ("Reading invalid VIC register at $%04X", V->Addr+Offs);
return 0xFF;
} else {
/* Do the read */
return V->Regs[Offs];
}
}
/*****************************************************************************/
/* Video RAM */
/*****************************************************************************/
static int VRamInitChip (const struct SimData* Data)
/* Initialize the chip, return an error code */
{
/* Remember the pointer */
Sim = Data;
/* Always successful */
return 0;
}
static void* VRamCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
/* Create a new chip instance */
{
char* Name;
FILE* F;
unsigned ColorDepth;
Colormap CM;
unsigned CIdx;
XSizeHints SizeHints;
XWMHints WMHints;
Cursor C;
/* Allocate the instance data */
VRamInstance* V = VRam = Sim->Malloc (sizeof (VRamInstance));
/* Remember a few settings */
V->Addr = Addr;
V->Range = Range;
/* Setup the window geometry */
V->XTotal = 384; /* PAL */
V->YTotal = 288;
V->XSize = 320;
V->YSize = 200;
V->XOffs = (V->XTotal - V->XSize) / 2;
V->YOffs = (V->YTotal - V->YSize) / 2;
/* Setup the rectanges used to draw the exterior */
V->Border[0].x = 0;
V->Border[0].y = 0;
V->Border[0].width = V->XTotal;
V->Border[0].height = V->YOffs;
V->Border[1].x = 0;
V->Border[1].y = V->YOffs + V->YSize;
V->Border[1].width = V->XTotal;
V->Border[1].height = V->YOffs;
V->Border[2].x = 0;
V->Border[2].y = V->YOffs;
V->Border[2].width = V->XOffs;
V->Border[2].height = V->YSize;
V->Border[3].x = V->XOffs + V->XSize;
V->Border[3].y = V->YOffs;
V->Border[3].width = V->XOffs;
V->Border[3].height = V->YSize;
/* 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 (V->CharRom, 1, sizeof (V->CharRom), F) != sizeof (V->CharRom)) {
Sim->Warning ("Char ROM `%s' seems to be corrupt", Name);
}
/* Close the file */
fclose (F);
/* Free the file name */
Sim->Free (Name);
/* Open the X display. */
V->VicDisplay = XOpenDisplay ("");
if (V->VicDisplay == NULL) {
Sim->Error ("VRAM: Cannot open X display");
}
/* Get a screen */
V->VicScreen = DefaultScreen (V->VicDisplay);
/* Check the available colors. For now, we expect direct colors, so we
* will check for a color depth of at least 16.
*/
ColorDepth = XDefaultDepth (V->VicDisplay, V->VicScreen);
if (ColorDepth < 16) {
/* OOPS */
Sim->Error ("VRAM: Need color display");
}
/* Get all needed colors */
memcpy (V->Colors, VicColors, sizeof (V->Colors));
CM = DefaultColormap (V->VicDisplay, V->VicScreen);
for (CIdx = 0; CIdx < VIC_COLOR_COUNT; CIdx++) {
if (XAllocColor (V->VicDisplay, CM, &V->Colors [CIdx]) == 0) {
Sim->Error ("VRAM: Cannot allocate color");
}
}
/* Set up the size hints structure */
SizeHints.x = 0;
SizeHints.y = 0;
SizeHints.flags = PPosition | PSize | PMinSize | PMaxSize | PResizeInc;
SizeHints.width = V->XTotal;
SizeHints.height = V->YTotal;
SizeHints.min_width = V->XTotal;
SizeHints.min_height = V->YTotal;
SizeHints.max_width = V->XTotal;
SizeHints.max_height = V->YTotal;
SizeHints.width_inc = 0;
SizeHints.height_inc = 0;
WMHints.flags = InputHint;
WMHints.input = True;
/* Create the window */
V->VicWindow = XCreateSimpleWindow (V->VicDisplay,
DefaultRootWindow (V->VicDisplay),
SizeHints.x,
SizeHints.y,
SizeHints.width,
SizeHints.height,
5,
V->Colors [VIC_WHITE].pixel,
V->Colors [VIC_BLACK].pixel);
/* Set the standard window properties */
XSetStandardProperties (V->VicDisplay, /* Display */
V->VicWindow, /* Window */
"sim65 VIC screen", /* Window name */
"sim65 VIC screen", /* Icon name */
None, /* Icon Pixmap */
0, /* argv */
0, /* argc */
&SizeHints); /* Hints */
XSetWMHints (V->VicDisplay, V->VicWindow, &WMHints);
/* GC creation and initialization */
V->VicGC = XCreateGC (V->VicDisplay, V->VicWindow, 0, 0);
/* Set the cursor to show over the Vic window */
C = XCreateFontCursor (V->VicDisplay, XC_pirate);
XDefineCursor (V->VicDisplay, V->VicWindow, C);
/* Select input events */
XSelectInput (V->VicDisplay, V->VicWindow, ExposureMask | StructureNotifyMask);
/* Show the window */
XMapRaised (V->VicDisplay, V->VicWindow);
/* Handle events */
VRamEventLoop ();
/* Return the instance data */
return V;
}
static void VRamDestroyInstance (void* Data)
/* Destroy a chip instance */
{
/* Cast the data pointer */
VRamInstance* V = Data;
/* Free X resources */
XUndefineCursor (V->VicDisplay, V->VicWindow);
XFreeGC (V->VicDisplay, V->VicGC);
XDestroyWindow (V->VicDisplay, V->VicWindow);
XCloseDisplay (V->VicDisplay);
/* Clear the global pointer */
VRam = 0;
/* Free the instance data */
Sim->Free (V);
}
static void VRamWrite (void* Data, unsigned Offs, unsigned char Val)
/* Write user data */
{
/* Cast the data pointer */
VRamInstance* V = Data;
/* Check the offset */
if (Offs >= sizeof (V->Mem)) {
Sim->Break ("VRAM: Accessing invalid memory at $%06X", V->Addr + Offs);
return;
}
/* Write the value */
V->Mem[Offs] = Val;
/* If this changes the visible part of the screen, schedule a redraw */
if (Offs < 40*25) {
/* Schedule a redraw */
VRamDrawChar (Offs);
/* Call the event loop */
VRamEventLoop ();
}
}
static unsigned char VRamRead (void* Data, unsigned Offs)
/* Read user data */
{
/* Cast the data pointer */
VRamInstance* V = Data;
/* Check the offset */
if (Offs >= sizeof (V->Mem)) {
Sim->Break ("VRAM: Accessing invalid memory at $%06X", V->Addr + Offs);
return 0xFF;
} else {
return V->Mem[Offs];
}
}
static void VRamDrawBorder (void)
/* Draw the complete border */
{
if (Vic) {
/* Set the border color */
XSetForeground (VRam->VicDisplay, VRam->VicGC, VRam->Colors[Vic->Regs[32]].pixel);
/* Fill all rectangles that make the border */
XFillRectangles (VRam->VicDisplay, VRam->VicWindow, VRam->VicGC,
VRam->Border, sizeof (VRam->Border) / sizeof (VRam->Border[0]));
}
}
static void VRamDrawChar (unsigned Offs)
/* Draw one character at the given position */
{
unsigned Row, Col;
XPoint Points[64];
unsigned PCount;
unsigned Color;
/* Get the character from the video RAM */
unsigned char C = VRam->Mem[Offs];
/* Calculate the offset for the character data in the character ROM */
unsigned char* D = VRam->CharRom + (C * 8);
/* Calculate the coords for the output */
unsigned X = VRam->XOffs + (Offs % 40) * 8;
unsigned Y = VRam->YOffs + (Offs / 40) * 8;
/* Clear the character area with the background color */
XSetForeground (VRam->VicDisplay, VRam->VicGC, VRam->Colors[Vic->Regs[33]].pixel);
XFillRectangle (VRam->VicDisplay, VRam->VicWindow, VRam->VicGC, X, Y, 8, 8);
/* Set the character color */
Color = CRam? CRam->Mem[Offs] & 0x0F : VIC_WHITE;
XSetForeground (VRam->VicDisplay, VRam->VicGC, VRam->Colors[Color].pixel);
/* Draw the foreground pixels */
PCount = 0;
for (Row = 0; Row < 8; ++Row) {
/* Get next byte from char rom */
unsigned Data = *D++;
/* Make pixels from this byte */
for (Col = 0; Col < 8; ++Col) {
if (Data & 0x80) {
/* Foreground pixel */
Points[PCount].x = X + Col;
Points[PCount].y = Y + Row;
++PCount;
}
Data <<= 1;
}
}
if (PCount) {
XDrawPoints (VRam->VicDisplay, VRam->VicWindow, VRam->VicGC,
Points, PCount, CoordModeOrigin);
}
}
static void VRamDrawArea (unsigned X1, unsigned Y1, unsigned X2, unsigned Y2)
/* Update an area of the interior screen */
{
unsigned X, Y;
/* Check if we have to draw anything */
if (X2 < VRam->XOffs || Y2 < VRam->YOffs ||
X1 >= VRam->XOffs + VRam->XSize ||
Y1 >= VRam->YOffs + VRam->YSize) {
/* Completely outside */
return;
}
/* Make the coordinates relative to the interior */
X1 -= VRam->XOffs;
Y1 -= VRam->YOffs;
X2 -= VRam->XOffs;
Y2 -= VRam->YOffs;
/* Loop updating characters */
for (Y = Y1; Y <= Y2; Y += 8) {
for (X = X1; X <= X2; X += 8) {
VRamDrawChar ((Y / 8) * 40 + (X / 8));
}
}
}
static void VRamDrawAllChars (void)
/* Redraw the complete interior screen */
{
unsigned I;
for (I = 0; I < 25*40; ++I) {
VRamDrawChar (I);
}
}
static void VRamEventLoop (void)
/* Get all waiting events and handle them */
{
unsigned X1, Y1, X2, Y2;
/* Read input events */
while (XEventsQueued (VRam->VicDisplay, QueuedAfterFlush) != 0) {
/* Read an event */
XEvent Event;
XNextEvent (VRam->VicDisplay, &Event);
switch (Event.type) {
case Expose:
/* Calculate the area to redraw, then update the screen */
X1 = Event.xexpose.x;
Y1 = Event.xexpose.y;
X2 = Event.xexpose.x + Event.xexpose.width - 1;
Y2 = Event.xexpose.y + Event.xexpose.height - 1;
if (X1 < VRam->XOffs || X2 > VRam->XOffs + VRam->XSize ||
Y1 < VRam->YOffs || Y2 > VRam->YOffs + VRam->YSize) {
/* Update the border */
VRamDrawBorder ();
}
VRamDrawArea (X1, Y1, X2, Y2);
break;
case MappingNotify:
XRefreshKeyboardMapping (&Event.xmapping);
break;
}
}
/* Flush the outgoing event queue */
XFlush (VRam->VicDisplay);
}
/*****************************************************************************/
/* Color RAM */
/*****************************************************************************/
static int CRamInitChip (const struct SimData* Data)
/* Initialize the chip, return an error code */
{
/* Remember the pointer */
Sim = Data;
/* Always successful */
return 0;
}
static void* CRamCreateInstance (unsigned Addr, unsigned Range,
void* CfgInfo attribute ((unused)))
/* Create a new chip instance */
{
/* Allocate the instance data */
CRamInstance* C = CRam = Sim->Malloc (sizeof (CRamInstance));
/* Remember a few settings */
C->Addr = Addr;
C->Range = Range;
/* Clear the color RAM memory */
memset (C->Mem, 0x00, sizeof (C->Mem));
/* Return the instance data */
return C;
}
static void CRamDestroyInstance (void* Data)
/* Destroy a chip instance */
{
/* Clear the global pointer */
CRam = 0;
/* Free the instance data */
Sim->Free (Data);
}
static void CRamWrite (void* Data, unsigned Offs, unsigned char Val)
/* Write user data */
{
/* Cast the data pointer */
CRamInstance* C = Data;
/* Check the offset */
if (Offs >= sizeof (C->Mem)) {
Sim->Break ("CRAM: Accessing invalid memory at $%06X", C->Addr + Offs);
return;
}
/* Write the value */
C->Mem[Offs] = Val & 0x0F;
/* If this changes the visible part of the screen, schedule a redraw */
if (Offs < 40*25) {
/* Schedule a redraw */
VRamDrawChar (Offs);
/* Call the event loop */
VRamEventLoop ();
}
}
static unsigned char CRamRead (void* Data, unsigned Offs)
/* Read user data */
{
/* Cast the data pointer */
CRamInstance* C = Data;
/* Check the offset */
if (Offs >= sizeof (C->Mem)) {
Sim->Break ("CRAM: Accessing invalid memory at $%06X", C->Addr + Offs);
return 0xFF;
} else {
return C->Mem[Offs] | 0xF0;
}
}

View File

@ -1,393 +0,0 @@
/*****************************************************************************/
/* */
/* config.c */
/* */
/* Configuration file parsing for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* common */
#include "check.h"
#include "bitops.h"
#include "print.h"
#include "strutil.h"
#include "xmalloc.h"
/* sim65 */
#include "addrspace.h"
#include "cfgdata.h"
#include "chip.h"
#include "error.h"
#include "global.h"
#include "location.h"
#include "scanner.h"
#include "config.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
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 ParseCPU (void)
/* Parse a CPU section */
{
static const IdentTok Attributes [] = {
{ "TYPE", CFGTOK_TYPE },
{ "ADDRSPACE", CFGTOK_ADDRSPACE },
};
enum {
atNone = 0x0000,
atType = 0x0001,
atAddrSpace = 0x0002
};
unsigned Attr = 0;
unsigned long Size = 0;
while (CfgTok == CFGTOK_IDENT) {
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_TYPE:
FlagAttr (&Attr, atType, "TYPE");
CfgAssureIdent ();
/* ### */
break;
case CFGTOK_ADDRSPACE:
FlagAttr (&Attr, atAddrSpace, "ADDRSPACE");
CfgAssureInt ();
CfgRangeCheck (0x1000, 0x1000000);
Size = CfgIVal;
break;
default:
FAIL ("Unexpected attribute token");
}
/* Skip the attribute value and an optional comma */
CfgNextTok ();
CfgOptionalComma ();
}
/* Must have some attributes */
AttrCheck (Attr, atType, "TYPE");
AttrCheck (Attr, atAddrSpace, "ADDRSPACE");
/* Create the system using the specified CPU */
System = NewSystem (NewCPU ("6502", Size));
/* Skip the semicolon */
CfgConsumeSemi ();
}
static void ParseAddrSpace (void)
/* Parse a ADDRSPACE section */
{
unsigned I;
/* CPU must be defined before the address space */
if (System == 0) {
CfgError ("CPU must be defined before address space definitions");
}
/* Parse addresses */
while (CfgTok == CFGTOK_INTCON) {
Location* L;
/* Remember the start address and skip it */
unsigned long Start = CfgIVal;
CfgNextTok ();
/* .. must follow */
CfgConsume (CFGTOK_DOTDOT, "`..' expected");
/* End address must follow and must be greater than start */
CfgAssureInt ();
if (CfgIVal < Start) {
CfgError ("Start address must be greater than end address");
}
/* Create a new location and add it to the list */
L = NewLocation (Start, CfgIVal);
CollAppend (&Locations, L);
/* Skip the end address and the following colon */
CfgNextTok ();
CfgConsumeColon ();
/* Parse attributes terminated by a semicolon */
while (CfgTok == CFGTOK_IDENT) {
/* Generate a new attribute with the given name, then skip it */
CfgData* D = NewCfgData ();
CfgNextTok ();
/* An optional assignment follows */
CfgOptionalAssign ();
/* Check and assign the attribute value */
switch (CfgTok) {
case CFGTOK_INTCON:
D->Type = CfgDataNumber;
D->V.IVal = CfgIVal;
break;
case CFGTOK_STRCON:
D->Type = CfgDataString;
D->V.SVal = xstrdup (CfgSVal);
break;
case CFGTOK_IDENT:
D->Type = CfgDataId;
D->V.SVal = xstrdup (CfgSVal);
break;
default:
CfgError ("Invalid attribute type");
}
/* Add the attribute to the location */
CollAppend (&L->Attributes, D);
/* Skip the attribute value and an optional comma */
CfgNextTok ();
CfgOptionalComma ();
}
/* Skip the semicolon */
CfgConsumeSemi ();
}
/* Sort all memory locations */
LocationSort (&Locations);
/* Check the locations for overlaps and other problems */
LocationCheck (&Locations);
/* Now create the chip instances. Since we can only mirror existing chips,
* we will first create all real chips and the mirrors in a second run.
*/
for (I = 0; I < CollCount (&Locations); ++I) {
int Index;
CfgData* D;
unsigned Range; /* Address range for this chip */
ChipInstance* CI;
/* Get this location */
Location* L = CollAtUnchecked (&Locations, I);
/* Skip mirrors */
if (LocationIsMirror (L)) {
continue;
}
/* The chip must have an attribute "name" of type string */
Index = LocationGetAttr (L, "name");
D = CollAt (&L->Attributes, Index);
CfgDataCheckType (D, CfgDataString);
/* Remove the "name" attribute from the attribute list */
CollDelete (&L->Attributes, Index);
/* Create the chip instance for the address range */
Range = L->End - L->Start + 1;
CI = NewChipInstance (D->V.SVal, L->Start, Range, &L->Attributes);
/* Delete the "name" attribute */
FreeCfgData (D);
/* Assign the chip instance to address space */
ASAssignChip (CPUInstance->AS, CI, L->Start, Range);
}
/* Create the mirrors */
for (I = 0; I < CollCount (&Locations); ++I) {
const CfgData* D;
unsigned MirrorAddr; /* Mirror address */
unsigned Range; /* Address range for this chip */
unsigned Offs; /* Offset of the mirror */
const ChipInstance* CI; /* Original chip instance */
ChipInstance* MCI; /* Mirrored chip instance */
/* Get this location */
const Location* L = CollAtUnchecked (&Locations, I);
/* Skip non mirrors */
if (!LocationIsMirror (L)) {
continue;
}
/* Calculate the address range */
Range = L->End - L->Start;
/* Get the mirror address */
D = CollConstAt (&L->Attributes, 0);
MirrorAddr = (unsigned) D->V.IVal;
/* For simplicity, get the chip instance we're mirroring from the
* memory, instead of searching for the range in the list.
*/
CI = ASGetChip (MirrorAddr);
if (CI == 0) {
/* We are mirroring an unassigned address */
Error ("%s(%u): Mirroring an unassigned address",
CfgGetName (), L->Line);
}
/* Make sure we're mirroring the correct chip */
CHECK (MirrorAddr >= CI->Addr && MirrorAddr < CI->Addr + CI->Size);
/* Calculate the offset of the mirror */
Offs = MirrorAddr - CI->Addr;
/* Check if the mirror range is ok */
if (Offs + Range > CI->Size) {
Error ("%s(%u): Mirror range is too large", CfgGetName (), L->Line);
}
/* Clone the chip instance for the new location */
MCI = MirrorChipInstance (CI, L->Start - Offs);
/* Assign the chip instance to address space */
ASAssignChip (CPUInstance->AS, MCI, L->Start, Range);
}
}
static void ParseConfig (void)
/* Parse the config file */
{
static const IdentTok BlockNames [] = {
{ "ADDRSPACE", CFGTOK_ADDRSPACE },
{ "CPU", CFGTOK_CPU },
};
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_ADDRSPACE:
ParseAddrSpace ();
break;
case CFGTOK_CPU:
ParseCPU ();
break;
default:
FAIL ("Unexpected block token");
}
/* Skip closing brace */
CfgConsumeRCurly ();
} while (CfgTok != CFGTOK_EOF);
}
void CfgRead (void)
/* Read the configuration */
{
/* If we have a config name given, open the file, otherwise we will read
* from a buffer.
*/
CfgOpenInput ();
/* Parse the file */
ParseConfig ();
/* Close the input file */
CfgCloseInput ();
}

View File

@ -1,75 +0,0 @@
/*****************************************************************************/
/* */
/* cpucore.c */
/* */
/* CPU definition for the simulator */
/* */
/* */
/* */
/* (C) 2003-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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 <string.h>
/* common */
#include "xmalloc.h"
/* sim65 */
#include "cpucore.h"
#include "error.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
CPUCore* NewCPUCore (const char* Name, unsigned AddrSpaceSize)
/* Create and return a new CPU including it's address space */
{
CPUCore* C;
/* Make sure this is a 6502 CPU for now */
if (strcmp (Name, "6502") != 0) {
Error ("Unknown CPU type `%s'", Name);
}
/* Allocate memory */
C = xmalloc (sizeof (*C));
/* Initialize the data */
C->Handle = 0; /* ### */
C->AddressSize = AddrSpaceSize;
/* Return the new CPU core */
return C;
}

View File

@ -1,83 +0,0 @@
/*****************************************************************************/
/* */
/* cpucore.h */
/* */
/* CPU definition for the simulator */
/* */
/* */
/* */
/* (C) 2003-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef CPUCORE_H
#define CPUCORE_H
/* sim65 */
#include "addrspace.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* CPU core structure */
typedef struct CPUCore CPUCore;
struct CPUCore {
void* Handle; /* Pointer to shared lib handle */
unsigned AddressSize; /* Size of the address space */
/* Callback functions */
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
CPUCore* NewCPUCore (const char* Name, unsigned AddrSpaceSize);
/* Create and return a new CPU including it's address space */
/* End of cpucore.h */
#endif

View File

@ -1,97 +0,0 @@
/*****************************************************************************/
/* */
/* cpudata.h */
/* */
/* CPU data passed from the CPU plugins */
/* */
/* */
/* */
/* (C) 2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef CPUDATA_H
#define CPUDATA_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Version defines */
#define CPUDATA_VER_MAJOR 1U
#define CPUDATA_VER_MINOR 0U
/* Forwards */
struct SimData;
/* CPUData structure */
typedef struct CPUData CPUData;
struct CPUData {
const char* CPUName; /* Name of the chip */
unsigned MajorVersion; /* Version information */
unsigned MinorVersion;
/* -- Exported functions -- */
void (*Init) (const struct SimData* Data);
/* Initialize the CPU module */
void* (*CreateInstance) (void* CfgInfo);
/* Create an instance of the CPU. Return the instance data pointer */
void (*DestroyInstance) (void* Data);
/* Destroy an instance of the CPU */
void (*Reset) (void* Data);
/* Generate a CPU RESET */
void (*IRQRequest) (void* Data);
/* Generate an IRQ */
void (*NMIRequest) (void* Data);
/* Generate an NMI */
unsigned (*ExecuteInsn) (void* Data);
/* Execute one CPU instruction. Return the number of clock cycles for the
* executed instruction.
*/
unsigned long (*GetCycles) (void* Data);
/* Return the total number of clock cycles executed */
};
/* End of cpudata.h */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
/*****************************************************************************/
/* */
/* cputype.h */
/* */
/* CPU type definitions */
/* */
/* */
/* */
/* (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 */
/* 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 "cputype.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Current CPU */
CPUType CPU = CPU_6502;

View File

@ -1,64 +0,0 @@
/*****************************************************************************/
/* */
/* cputype.h */
/* */
/* CPU type definitions */
/* */
/* */
/* */
/* (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 */
/* 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 CPUTYPE_H
#define CPUTYPE_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Supported CPUs */
typedef enum CPUType {
CPU_6502,
CPU_65C02
} CPUType;
/* Current CPU */
extern CPUType CPU;
/* End of cputype.h */
#endif

View File

@ -1,49 +0,0 @@
/*****************************************************************************/
/* */
/* global.c */
/* */
/* Global variables for the sim65 6502 simulator */
/* */
/* */
/* */
/* (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 */
/* 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 "global.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
unsigned char Debug = 0; /* Debug mode */

View File

@ -1,57 +0,0 @@
/*****************************************************************************/
/* */
/* global.h */
/* */
/* Global variables for the sim65 6502 simulator */
/* */
/* */
/* */
/* (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 */
/* 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 GLOBAL_H
#define GLOBAL_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
extern unsigned char Debug; /* Debug mode */
/* End of global.h */
#endif

View File

@ -1,174 +0,0 @@
/*****************************************************************************/
/* */
/* location.c */
/* */
/* Memory location description */
/* */
/* */
/* */
/* (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. */
/* */
/*****************************************************************************/
/* common.h */
#include "coll.h"
#include "xmalloc.h"
/* sim65 */
#include "cfgdata.h"
#include "error.h"
#include "scanner.h"
#include "location.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* List of all memory locations */
Collection Locations = STATIC_COLLECTION_INITIALIZER;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
Location* NewLocation (unsigned long Start, unsigned long End)
/* Create a new location, initialize and return it */
{
/* Allocate memory */
Location* L = xmalloc (sizeof (Location));
/* Initialize the fields */
L->Start = Start;
L->End = End;
L->Attributes = EmptyCollection;
L->Line = CfgErrorLine;
L->Col = CfgErrorCol;
/* Return the new struct */
return L;
}
static int CmpLocations (void* Data attribute ((unused)),
const void* lhs, const void* rhs)
/* Compare function for CollSort */
{
/* Cast the object pointers */
const Location* Left = (const Location*) rhs;
const Location* Right = (const Location*) lhs;
/* Do the compare */
if (Left->Start < Right->Start) {
return 1;
} else if (Left->Start > Right->Start) {
return -1;
} else {
return 0;
}
}
int LocationGetAttr (const Location* L, const char* AttrName)
/* Find the attribute with the given name and return it. Call Error() if the
* attribute was not found.
*/
{
int I = CfgDataFind (&L->Attributes, AttrName);
if (I < 0) {
Error ("%s(%u): Attribute `%s' missing", CfgGetName(), L->Line, AttrName);
}
return I;
}
int LocationIsMirror (const Location* L)
/* Return true if the given location is a mirror of another one. */
{
/* Find the "mirror" attribute */
return (CfgDataFind (&L->Attributes, "mirror") >= 0);
}
void LocationSort (Collection* Locations)
/* Sort all locations by address */
{
/* Sort all memory locations */
CollSort (Locations, CmpLocations, 0);
}
void LocationCheck (const Collection* Locations)
/* Check all locations for problems */
{
unsigned I;
/* Check for overlaps and other problems */
const Location* Last = 0;
for (I = 0; I < CollCount (Locations); ++I) {
/* Get this location */
const Location* L = CollConstAt (Locations, I);
/* Check for an overlap with the following location */
if (Last && Last->End >= L->Start) {
Error ("%s(%u): Address range overlap (overlapping entry is in line %u)",
CfgGetName(), L->Line, Last->Line);
}
/* If the location is a mirror, it must not have other attributes,
* and the mirror attribute must be an integer.
*/
if (LocationIsMirror (L)) {
const CfgData* D;
if (CollCount (&L->Attributes) > 1) {
Error ("%s(%u): Location at address $%06X is a mirror "
"but has attributes", CfgGetName(), L->Line, L->Start);
}
D = CollConstAt (&L->Attributes, 0);
CfgDataCheckType (D, CfgDataNumber);
}
/* Remember this entry */
Last = L;
}
}

View File

@ -1,97 +0,0 @@
/*****************************************************************************/
/* */
/* location.h */
/* */
/* Memory location description */
/* */
/* */
/* */
/* (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. */
/* */
/*****************************************************************************/
#ifndef LOCATION_H
#define LOCATION_H
/* common.h */
#include "coll.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* List of all memory locations */
extern Collection Locations;
/* One memory location */
typedef struct Location Location;
struct Location {
unsigned Start; /* Start of memory location */
unsigned End; /* End memory location */
Collection Attributes; /* Attributes given */
unsigned Line; /* Line in config file */
unsigned Col; /* Column in config file */
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
Location* NewLocation (unsigned long Start, unsigned long End);
/* Create a new location, initialize and return it */
int LocationGetAttr (const Location* L, const char* AttrName);
/* Find the attribute with the given name and return it. Call Error() if the
* attribute was not found.
*/
int LocationIsMirror (const Location* L);
/* Return true if the given location is a mirror of another one. */
void LocationSort (Collection* Locations);
/* Sort all locations by address */
void LocationCheck (const Collection* Locations);
/* Check all locations for problems */
/* End of location.h */
#endif

View File

@ -33,31 +33,31 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
/* common */
#include "abend.h"
#include "cmdline.h"
#include "filestat.h"
#include "print.h"
#include "version.h"
#include "xmalloc.h"
/* sim65 */
#include "chip.h"
#include "chippath.h"
#include "config.h"
#include "cpucore.h"
#include "cputype.h"
#include "6502.h"
#include "error.h"
#include "global.h"
#include "memory.h"
#include "scanner.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Name of program file */
const char* ProgramFile;
@ -71,18 +71,11 @@ static void Usage (void)
{
printf ("Usage: %s [options] file\n"
"Short options:\n"
" -C name\t\tUse simulator config file\n"
" -L dir\t\tSet a chip directory search path\n"
" -V\t\t\tPrint the simulator version number\n"
" -d\t\t\tDebug mode\n"
" -h\t\t\tHelp (this text)\n"
" -v\t\t\tIncrease verbosity\n"
" -V\t\t\tPrint the simulator version number\n"
"\n"
"Long options:\n"
" --chipdir dir\t\tSet a chip directory search path\n"
" --config name\t\tUse simulator config file\n"
" --cpu type\t\tSet cpu type\n"
" --debug\t\tDebug mode\n"
" --help\t\tHelp (this text)\n"
" --verbose\t\tIncrease verbosity\n"
" --version\t\tPrint the simulator version number\n",
@ -91,98 +84,6 @@ static void Usage (void)
static void OptChipDir (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --chipdir option */
{
struct dirent* E;
/* Get the length of the directory name */
unsigned DirLen = strlen (Arg);
/* Open the directory */
DIR* D = opendir (Arg);
if (D == 0) {
AbEnd ("Cannot read directory `%s': %s", Arg, strerror (errno));
}
/* Read in all files and treat them as libraries */
while ((E = readdir (D)) != 0) {
char* Name;
struct stat S;
/* ### Ignore anything but *.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 */
Name = xmalloc (DirLen + 1 + NameLen + 1);
strcpy (Name, Arg);
strcpy (Name + DirLen, "/");
strcpy (Name + DirLen + 1, E->d_name);
/* Stat the file */
if (FileStat (Name, &S) != 0) {
Warning ("Cannot stat `%s': %s", Name, strerror (errno));
xfree (Name);
continue;
}
/* Check if this is a regular file */
if (S_ISREG (S.st_mode)) {
/* Treat it as a library */
LoadChipLibrary (Name);
}
/* Free the name */
xfree (Name);
}
/* Close the directory */
closedir (D);
}
static void OptCPU (const char* Opt, const char* Arg)
/* Handle the --cpu option */
{
if (strcmp (Arg, "6502") == 0) {
CPU = CPU_6502;
} else if (strcmp (Arg, "65C02") == 0) {
CPU = CPU_65C02;
} else {
AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
}
}
static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
/* Define the config file */
{
if (CfgAvail ()) {
Error ("Cannot use -C twice");
}
CfgSetName (Arg);
}
static void OptDebug (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Simulator debug mode */
{
Debug = 1;
}
static void OptHelp (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Print usage information and exit */
@ -204,21 +105,58 @@ static void OptVerbose (const char* Opt attribute ((unused)),
static void OptVersion (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Print the assembler version */
/* Print the simulator version */
{
fprintf (stderr, "sim65 V%s\n", GetVersionAsString ());
}
static void ReadProgramFile (void)
/* Load program into memory */
{
int Val;
unsigned Addr = 0x0200;
/* Open the file */
FILE* F = fopen (ProgramFile, "rb");
if (F == 0) {
Error ("Cannot open `%s': %s", ProgramFile, strerror (errno));
}
/* Get the CPU type from the file header */
if ((Val = fgetc(F)) != EOF) {
if (Val != CPU_6502 && Val != CPU_65C02) {
Error ("`%s': Invalid CPU type", ProgramFile);
}
CPU = Val;
}
/* Read the file body into memory */
while ((Val = fgetc(F)) != EOF) {
if (Addr == 0xFF00) {
Error ("`%s': To large to fit into $0200-$FFF0", ProgramFile);
}
MemWriteByte (Addr++, (unsigned char) Val);
}
/* Check for errors */
if (ferror (F)) {
Error ("Error reading from `%s': %s", ProgramFile, strerror (errno));
}
/* Close the file */
fclose (F);
Print (stdout, 1, "Loaded `%s' at $0200-$%04X\n", ProgramFile, Addr - 1);
}
int main (int argc, char* argv[])
{
/* Program long options */
static const LongOpt OptTab[] = {
{ "--chipdir", 1, OptChipDir },
{ "--config", 1, OptConfig },
{ "--cpu", 1, OptCPU },
{ "--debug", 0, OptDebug },
{ "--help", 0, OptHelp },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
@ -226,15 +164,9 @@ int main (int argc, char* argv[])
unsigned I;
/* Initialize the output file name */
const char* InputFile = 0;
/* Initialize the cmdline module */
InitCmdLine (&argc, &argv, "sim65");
/* Initialize the chip library search paths */
InitChipPaths ();
/* Parse the command line */
I = 1;
while (I < ArgCount) {
@ -251,10 +183,6 @@ int main (int argc, char* argv[])
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
break;
case 'd':
OptDebug (Arg, 0);
break;
case 'h':
case '?':
OptHelp (Arg, 0);
@ -264,14 +192,6 @@ int main (int argc, char* argv[])
OptVerbose (Arg, 0);
break;
case 'C':
OptConfig (Arg, GetArg (&I, 2));
break;
case 'L':
OptChipDir (Arg, GetArg (&I, 2));
break;
case 'V':
OptVersion (Arg, 0);
break;
@ -281,10 +201,11 @@ int main (int argc, char* argv[])
break;
}
} else {
if (InputFile) {
fprintf (stderr, "additional file specs ignored\n");
/* Filename. Check if we already had one */
if (ProgramFile) {
AbEnd ("Don't know what to do with `%s'", Arg);
} else {
InputFile = Arg;
ProgramFile = Arg;
}
}
@ -292,29 +213,21 @@ int main (int argc, char* argv[])
++I;
}
/* Sort the already loaded chips */
SortChips ();
/* Check if we have a valid configuration */
if (!CfgAvail ()) {
Error ("Simulator configuration missing");
/* Do we have a program file? */
if (ProgramFile == 0) {
AbEnd ("No program file");
}
/* Initialize the simulated CPU memory */
MemInit ();
/* Read the config file */
CfgRead ();
ReadProgramFile ();
CPUInit ();
Reset ();
while (1) {
CPURun ();
ExecuteInsn ();
}
/* Return an apropriate exit code */
return EXIT_SUCCESS;
}

View File

@ -33,18 +33,8 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
/* common */
#include "coll.h"
#include "xmalloc.h"
/* sim65 */
#include "chip.h"
#include "cputype.h"
#include "error.h"
#include "memory.h"
@ -55,9 +45,8 @@
/* Pointer to our memory */
static const ChipInstance** MemData = 0;
unsigned MemSize = 0;
/* THE memory */
static unsigned char Mem[0x10000];
@ -70,15 +59,7 @@ unsigned MemSize = 0;
void MemWriteByte (unsigned Addr, unsigned char Val)
/* Write a byte to a memory location */
{
/* Get the instance of the chip at this address */
const ChipInstance* CI = MemData[Addr];
/* Check if the memory is mapped */
if (CI == 0) {
Warning ("Writing to unassigned memory at $%06X", Addr);
} else {
CI->C->Data->Write (CI->Data, Addr - CI->Addr, Val);
}
Mem[Addr] = Val;
}
@ -86,16 +67,7 @@ void MemWriteByte (unsigned Addr, unsigned char Val)
unsigned char MemReadByte (unsigned Addr)
/* Read a byte from a memory location */
{
/* Get the instance of the chip at this address */
const ChipInstance* CI = MemData[Addr];
/* Check if the memory is mapped */
if (CI == 0) {
Warning ("Reading from unassigned memory at $%06X", Addr);
return 0xFF;
} else {
return CI->C->Data->Read (CI->Data, Addr - CI->Addr);
}
return Mem[Addr];
}
@ -121,54 +93,13 @@ unsigned MemReadZPWord (unsigned char Addr)
void MemAssignChip (const ChipInstance* CI, unsigned Addr, unsigned Range)
/* Assign a chip instance to memory locations */
{
/* Make sure, the addresses are in a valid range */
PRECONDITION (Addr + Range <= MemSize);
/* Assign the chip instance */
while (Range--) {
CHECK (MemData[Addr] == 0);
MemData[Addr++] = CI;
}
}
const struct ChipInstance* MemGetChip (unsigned Addr)
/* Get the chip that is located at the given address (may return NULL). */
{
/* Make sure, the address is valid */
PRECONDITION (Addr < MemSize);
/* Return the chip instance */
return MemData[Addr];
}
void MemInit (void)
/* Initialize the memory subsystem */
{
unsigned I;
/* Fill momory with illegal opcode */
memset (Mem, 0xFF, sizeof (Mem));
/* Allocate memory depending on the CPU type */
switch (CPU) {
case CPU_6502:
case CPU_65C02:
MemSize = 0x10000;
break;
default:
Internal ("Unexpected CPU type: %d", CPU);
}
MemData = xmalloc (MemSize * sizeof (ChipInstance*));
/* Clear the memory */
for (I = 0; I < MemSize; ++I) {
MemData[I] = 0;
}
/* Set RESET vector to 0x0200 */
Mem[0xFFFC] = 0x00;
Mem[0xFFFD] = 0x02;
}

View File

@ -38,20 +38,6 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Forwards */
struct ChipInstance;
/* Memory size of the CPU */
extern unsigned MemSize;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -73,12 +59,6 @@ unsigned MemReadZPWord (unsigned char Addr);
* overflow.
*/
void MemAssignChip (const struct ChipInstance* CI, unsigned Addr, unsigned Range);
/* Assign a chip instance to memory locations */
const struct ChipInstance* MemGetChip (unsigned Addr);
/* Get the chip that is located at the given address (may return NULL). */
void MemInit (void);
/* Initialize the memory subsystem */

255
src/sim65/paravirt.c Normal file
View File

@ -0,0 +1,255 @@
/*****************************************************************************/
/* */
/* paravirt.c */
/* */
/* Paravirtualization for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 2013-2013 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 <stdlib.h>
#include <fcntl.h>
#if defined(_MSC_VER)
/* Microsoft compiler */
# include <io.h>
# pragma warning(disable : 4996)
# define O_INITIAL O_BINARY
#else
/* Anyone else */
# include <unistd.h>
# define O_INITIAL 0
#endif
/* common */
#include "print.h"
#include "xmalloc.h"
/* sim65 */
#include "6502.h"
#include "memory.h"
#include "paravirt.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
typedef void (*PVFunc) (CPURegs* Regs);
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static unsigned char Pop (CPURegs* Regs)
{
return MemReadByte (0x0100 + ++Regs->SP);
}
static unsigned PopParam (unsigned char Incr)
{
unsigned SP = MemReadZPWord (0x00);
unsigned Val = MemReadWord (SP);
SP += Incr;
MemWriteByte (0x00, SP);
SP >>= 8;
MemWriteByte (0x01, SP);
return Val;
}
static void PVExit (CPURegs* Regs)
{
Print (stdout, 1, "PVExit ($%02X)\n", Regs->AC);
exit (Regs->AC);
}
static void PVOpen (CPURegs* Regs)
{
char Path[1024];
int OFlag = O_INITIAL;
unsigned RetVal, I = 0;
unsigned Mode = PopParam (Regs->YR - 4);
unsigned Flags = PopParam (2);
unsigned Name = PopParam (2);
do {
Path[I] = MemReadByte (Name++);
}
while (Path[I++]);
Print (stdout, 2, "PVOpen (\"%s\", $%04X)\n", Path, Flags);
switch (Flags & 0x03) {
case 0x01:
OFlag |= O_RDONLY;
break;
case 0x02:
OFlag |= O_WRONLY;
break;
case 0x03:
OFlag |= O_RDWR;
break;
}
if (Flags & 0x10) {
OFlag |= O_CREAT;
}
if (Flags & 0x20) {
OFlag |= O_TRUNC;
}
if (Flags & 0x40) {
OFlag |= O_APPEND;
}
if (Flags & 0x80) {
OFlag |= O_EXCL;
}
/* Avoid gcc warning */
(void) Mode;
RetVal = open (Path, OFlag);
Regs->AC = RetVal & 0xFF;
RetVal >>= 8;
Regs->XR = RetVal & 0xFF;
}
static void PVClose (CPURegs* Regs)
{
unsigned RetVal;
unsigned FD = Regs->AC + (Regs->XR << 8);
Print (stdout, 2, "PVClose ($%04X)\n", FD);
RetVal = close (FD);
Regs->AC = RetVal & 0xFF;
RetVal >>= 8;
Regs->XR = RetVal & 0xFF;
}
static void PVRead (CPURegs* Regs)
{
unsigned char* Data;
unsigned RetVal, I = 0;
unsigned Count = Regs->AC + (Regs->XR << 8);
unsigned Buf = PopParam (2);
unsigned FD = PopParam (2);
Print (stdout, 2, "PVRead ($%04X, $%04X, $%04X)\n", FD, Buf, Count);
Data = xmalloc (Count);
RetVal = read (FD, Data, Count);
if (RetVal != (unsigned) -1) {
while (I < RetVal) {
MemWriteByte (Buf++, Data[I++]);
}
}
xfree (Data);
Regs->AC = RetVal & 0xFF;
RetVal >>= 8;
Regs->XR = RetVal & 0xFF;
}
static void PVWrite (CPURegs* Regs)
{
unsigned char* Data;
unsigned RetVal, I = 0;
unsigned Count = Regs->AC + (Regs->XR << 8);
unsigned Buf = PopParam (2);
unsigned FD = PopParam (2);
Print (stdout, 2, "PVWrite ($%04X, $%04X, $%04X)\n", FD, Buf, Count);
Data = xmalloc (Count);
while (I < Count) {
Data[I++] = MemReadByte (Buf++);
}
RetVal = write (FD, Data, Count);
xfree (Data);
Regs->AC = RetVal & 0xFF;
RetVal >>= 8;
Regs->XR = RetVal & 0xFF;
}
static const PVFunc Hooks[] = {
PVExit,
PVOpen,
PVClose,
PVRead,
PVWrite,
};
void ParaVirtualization (CPURegs* Regs)
/* Potentially execute paravirtualization hook */
{
/* Check for paravirtualization address range */
if (Regs->PC < 0xFFF0 ||
Regs->PC >= 0xFFF0 + sizeof (Hooks) / sizeof (Hooks[0])) {
return;
}
/* Call paravirtualization hook */
Hooks[Regs->PC - 0xFFF0] (Regs);
/* Simulate RTS */
Regs->PC = Pop(Regs) + (Pop(Regs) << 8) + 1;
}

View File

@ -1,12 +1,12 @@
/*****************************************************************************/
/* */
/* config.h */
/* paravirt.h */
/* */
/* Configuration file parsing for the sim65 6502 simulator */
/* Paravirtualization for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* (C) 2013-2013 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -33,8 +33,8 @@
#ifndef CONFIG_H
#define CONFIG_H
#ifndef PARAVIRT_H
#define PARAVIRT_H
@ -44,16 +44,11 @@
void CfgRead (void);
/* Read the configuration */
void ParaVirtualization (CPURegs* Regs);
/* Potentially execute paravirtualization hook */
/* End of config.h */
/* End of paravirt.h */
#endif

View File

@ -1,530 +0,0 @@
/*****************************************************************************/
/* */
/* scanner.c */
/* */
/* Configuration file scanner for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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 <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
/* common */
#include "chartype.h"
#include "xsprintf.h"
/* sim65 */
#include "error.h"
#include "scanner.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Current token and attributes */
cfgtok_t CfgTok;
StrBuf CfgSVal = STATIC_STRBUF_INITIALIZER;
unsigned long CfgIVal;
/* Error location */
unsigned CfgErrorLine;
unsigned CfgErrorCol;
/* Input sources for the configuration */
static const char* CfgName = 0;
static const char* CfgBuf = 0;
/* Other input stuff */
static int C = ' ';
static unsigned InputLine = 1;
static unsigned InputCol = 0;
static FILE* InputFile = 0;
/*****************************************************************************/
/* Error handling */
/*****************************************************************************/
void CfgWarning (const char* Format, ...)
/* Print a warning message adding file name and line number of the config file */
{
char Buf [512];
va_list ap;
va_start (ap, Format);
xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, Buf);
}
void CfgError (const char* Format, ...)
/* Print an error message adding file name and line number of the config file */
{
char Buf [512];
va_list ap;
va_start (ap, Format);
xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, Buf);
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static void NextChar (void)
/* Read the next character from the input file */
{
if (CfgBuf) {
/* Read from buffer */
C = (unsigned char)(*CfgBuf);
if (C == 0) {
C = EOF;
} else {
++CfgBuf;
}
} else {
/* Read from the file */
C = getc (InputFile);
}
/* Count columns */
if (C != EOF) {
++InputCol;
}
/* Count lines */
if (C == '\n') {
++InputLine;
InputCol = 0;
}
}
static unsigned DigitVal (int C)
/* Return the value for a numeric digit */
{
if (isdigit (C)) {
return C - '0';
} else {
return toupper (C) - 'A' + 10;
}
}
void CfgNextTok (void)
/* Read the next token from the input stream */
{
unsigned I;
Again:
/* Skip whitespace */
while (isspace (C)) {
NextChar ();
}
/* Remember the current position */
CfgErrorLine = InputLine;
CfgErrorCol = InputCol;
/* Identifier? */
if (C == '_' || IsAlpha (C)) {
/* Read the identifier */
I = 0;
while (C == '_' || IsAlNum (C)) {
if (I < CFG_MAX_IDENT_LEN) {
CfgSVal [I++] = C;
}
NextChar ();
}
CfgSVal [I] = '\0';
CfgTok = CFGTOK_IDENT;
return;
}
/* Hex number? */
if (C == '$') {
NextChar ();
if (!isxdigit (C)) {
Error ("%s(%u): Hex digit expected", CfgName, InputLine);
}
CfgIVal = 0;
while (isxdigit (C)) {
CfgIVal = CfgIVal * 16 + DigitVal (C);
NextChar ();
}
CfgTok = CFGTOK_INTCON;
return;
}
/* Decimal number? */
if (isdigit (C)) {
CfgIVal = 0;
while (isdigit (C)) {
CfgIVal = CfgIVal * 10 + DigitVal (C);
NextChar ();
}
CfgTok = CFGTOK_INTCON;
return;
}
/* Other characters */
switch (C) {
case '{':
NextChar ();
CfgTok = CFGTOK_LCURLY;
break;
case '}':
NextChar ();
CfgTok = CFGTOK_RCURLY;
break;
case ';':
NextChar ();
CfgTok = CFGTOK_SEMI;
break;
case '.':
NextChar ();
if (C == '.') {
NextChar ();
CfgTok = CFGTOK_DOTDOT;
} else {
CfgTok = CFGTOK_DOT;
}
break;
case ',':
NextChar ();
CfgTok = CFGTOK_COMMA;
break;
case '=':
NextChar ();
CfgTok = CFGTOK_EQ;
break;
case ':':
NextChar ();
CfgTok = CFGTOK_COLON;
break;
case '\"':
NextChar ();
I = 0;
while (C != '\"') {
if (C == EOF || C == '\n') {
Error ("%s(%u): Unterminated string", CfgName, InputLine);
}
if (I < CFG_MAX_IDENT_LEN) {
CfgSVal [I++] = C;
}
NextChar ();
}
NextChar ();
CfgSVal [I] = '\0';
CfgTok = CFGTOK_STRCON;
break;
case '#':
/* Comment */
while (C != '\n' && C != EOF) {
NextChar ();
}
if (C != EOF) {
goto Again;
}
CfgTok = CFGTOK_EOF;
break;
case EOF:
CfgTok = CFGTOK_EOF;
break;
default:
Error ("%s(%u): Invalid character `%c'", CfgName, InputLine, C);
}
}
void CfgConsume (cfgtok_t T, const char* Msg)
/* Skip a token, print an error message if not found */
{
if (CfgTok != T) {
CfgError ("%s", Msg);
}
CfgNextTok ();
}
void CfgConsumeSemi (void)
/* Consume a semicolon */
{
CfgConsume (CFGTOK_SEMI, "`;' expected");
}
void CfgConsumeColon (void)
/* Consume a colon */
{
CfgConsume (CFGTOK_COLON, "`:' expected");
}
void CfgConsumeRCurly (void)
/* Consume a right curly brace */
{
CfgConsume (CFGTOK_RCURLY, "`}' expected");
}
void CfgOptionalComma (void)
/* Consume a comma if there is one */
{
if (CfgTok == CFGTOK_COMMA) {
CfgNextTok ();
}
}
void CfgOptionalAssign (void)
/* Consume an equal sign if there is one */
{
if (CfgTok == CFGTOK_EQ) {
CfgNextTok ();
}
}
void CfgAssureInt (void)
/* Make sure the next token is an integer */
{
if (CfgTok != CFGTOK_INTCON) {
CfgError ("Integer constant expected");
}
}
void CfgAssureStr (void)
/* Make sure the next token is a string constant */
{
if (CfgTok != CFGTOK_STRCON) {
CfgError ("String constant expected");
}
}
void CfgAssureIdent (void)
/* Make sure the next token is an identifier */
{
if (CfgTok != CFGTOK_IDENT) {
CfgError ("Identifier expected");
}
}
void CfgRangeCheck (unsigned long Lo, unsigned long Hi)
/* Check the range of CfgIVal */
{
if (CfgIVal < Lo || CfgIVal > Hi) {
CfgError ("Range error");
}
}
void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
/* Map an identifier to one of the special tokens in the table */
{
unsigned I;
/* We need an identifier */
if (CfgTok == CFGTOK_IDENT) {
/* Make it upper case */
I = 0;
while (CfgSVal [I]) {
CfgSVal [I] = toupper (CfgSVal [I]);
++I;
}
/* Linear search */
for (I = 0; I < Size; ++I) {
if (strcmp (CfgSVal, Table [I].Ident) == 0) {
CfgTok = Table [I].Tok;
return;
}
}
}
/* Not found or no identifier */
Error ("%s(%u): %s expected", CfgName, InputLine, Name);
}
void CfgBoolToken (void)
/* Map an identifier or integer to a boolean token */
{
static const IdentTok Booleans [] = {
{ "YES", CFGTOK_TRUE },
{ "NO", CFGTOK_FALSE },
{ "TRUE", CFGTOK_TRUE },
{ "FALSE", CFGTOK_FALSE },
};
/* If we have an identifier, map it to a boolean token */
if (CfgTok == CFGTOK_IDENT) {
CfgSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
} else {
/* We expected an integer here */
if (CfgTok != CFGTOK_INTCON) {
CfgError ("Boolean value expected");
}
CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE;
}
}
void CfgSetName (const char* Name)
/* Set a name for a config file */
{
CfgName = Name;
}
const char* CfgGetName (void)
/* Get the name of the config file */
{
if (CfgName) {
return CfgName;
} else if (CfgBuf) {
return "[builtin config]";
} else {
return "";
}
}
void CfgSetBuf (const char* Buf)
/* Set a memory buffer for the config */
{
CfgBuf = Buf;
}
int CfgAvail (void)
/* Return true if we have a configuration available */
{
return CfgName != 0 || CfgBuf != 0;
}
void CfgOpenInput (void)
/* Open the input file if we have one */
{
/* If we have a config name given, open the file, otherwise we will read
* from a buffer.
*/
if (!CfgBuf) {
/* Open the file */
InputFile = fopen (CfgName, "r");
if (InputFile == 0) {
Error ("Cannot open `%s': %s", CfgName, strerror (errno));
}
}
/* Initialize variables */
C = ' ';
InputLine = 1;
InputCol = 0;
/* Start the ball rolling ... */
CfgNextTok ();
}
void CfgCloseInput (void)
/* Close the input file if we have one */
{
/* Close the input file if we had one */
if (InputFile) {
(void) fclose (InputFile);
InputFile = 0;
}
}

View File

@ -1,180 +0,0 @@
/*****************************************************************************/
/* */
/* scanner.h */
/* */
/* Configuration file scanner for the sim65 6502 simulator */
/* */
/* */
/* */
/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef SCANNER_H
#define SCANNER_H
/* common */
#include "attrib.h"
#include "strbuf.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Config file tokens */
typedef enum {
CFGTOK_NONE,
CFGTOK_INTCON,
CFGTOK_STRCON,
CFGTOK_IDENT,
CFGTOK_LCURLY,
CFGTOK_RCURLY,
CFGTOK_SEMI,
CFGTOK_COMMA,
CFGTOK_EQ,
CFGTOK_COLON,
CFGTOK_DOT,
CFGTOK_DOTDOT,
CFGTOK_EOF,
/* Primary blocks */
CFGTOK_CPU,
CFGTOK_ADDRSPACE,
/* Secondary stuff */
CFGTOK_TYPE,
/* Special identifiers */
CFGTOK_TRUE,
CFGTOK_FALSE
} cfgtok_t;
/* Mapping table entry, special identifier --> token */
typedef struct IdentTok IdentTok;
struct IdentTok {
const char* Ident; /* Identifier */
cfgtok_t Tok; /* Token for identifier */
};
#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0]))
/* Current token and attributes */
extern cfgtok_t CfgTok;
extern StrBuf CfgSVal;
extern unsigned long CfgIVal;
/* Error location */
extern unsigned CfgErrorLine;
extern unsigned CfgErrorCol;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void CfgWarning (const char* Format, ...) attribute((format(printf,1,2)));
/* Print a warning message adding file name and line number of the config file */
void CfgError (const char* Format, ...) attribute((format(printf,1,2)));
/* Print an error message adding file name and line number of the config file */
void CfgNextTok (void);
/* Read the next token from the input stream */
void CfgConsume (cfgtok_t T, const char* Msg);
/* Skip a token, print an error message if not found */
void CfgConsumeSemi (void);
/* Consume a semicolon */
void CfgConsumeColon (void);
/* Consume a colon */
void CfgConsumeRCurly (void);
/* Consume a right curly brace */
void CfgOptionalComma (void);
/* Consume a comma if there is one */
void CfgOptionalAssign (void);
/* Consume an equal sign if there is one */
void CfgAssureInt (void);
/* Make sure the next token is an integer */
void CfgAssureStr (void);
/* Make sure the next token is a string constant */
void CfgAssureIdent (void);
/* Make sure the next token is an identifier */
void CfgRangeCheck (unsigned long Lo, unsigned long Hi);
/* Check the range of CfgIVal */
void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name);
/* Map an identifier to one of the special tokens in the table */
void CfgBoolToken (void);
/* Map an identifier or integer to a boolean token */
void CfgSetName (const char* Name);
/* Set a name for a config file */
const char* CfgGetName (void);
/* Get the name of the config file */
void CfgSetBuf (const char* Buf);
/* Set a memory buffer for the config */
int CfgAvail (void);
/* Return true if we have a configuration available */
void CfgOpenInput (void);
/* Open the input file if we have one */
void CfgCloseInput (void);
/* Close the input file if we have one */
/* End of scanner.h */
#endif

View File

@ -1,118 +0,0 @@
/*****************************************************************************/
/* */
/* simdata.h */
/* */
/* Simulator data passed to the chip plugins */
/* */
/* */
/* */
/* (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 */
/* 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 SIMDATA_H
#define SIMDATA_H
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* SimData structure */
typedef struct SimData SimData;
struct SimData {
unsigned MajorVersion;
unsigned MinorVersion;
/* -- Callback functions -- */
void* (*Malloc) (size_t Size);
/* Allocate a memory block of the given size */
void (*Free) (void* Block);
/* Free an allocated memory block */
void (*Warning) (const char* Format, ...);
/* Print a warning */
void (*Error) (const char* Format, ...);
/* Print an error and terminate the program */
void (*Internal) (const char* Format, ...);
/* Print an internal program error and terminate */
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();
*/
int (*GetCfgStr) (void* CfgInfo, const char* Name, char** S);
/* 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);
/* 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.
*/
unsigned char (*ReadCtrl) (unsigned Addr);
/* Read from the given address without triggering any additional action */
void (*WriteCtrl) (unsigned Addr, unsigned char Val);
/* Write to the given address without triggering additional action */
void (*Break) (const char* Format, ...);
/* Stop the CPU and display the given message */
void (*IRQ) (void);
/* Issue an irq request */
void (*NMI) (void);
/* Issue an nmi request */
};
/* End of simdata.h */
#endif

View File

@ -1,70 +0,0 @@
/*****************************************************************************/
/* */
/* system.c */
/* */
/* Description of the simulated system */
/* */
/* */
/* */
/* (C) 2003-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
/* common.h */
#include "xmalloc.h"
/* sim65 */
#include "system.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
System* NewSystem (CPUCore* CPU)
/* Create and initialize a new System struct. The function will read the size
* of the address space from the CPU, and also create a new AddressSpace
* object. No chips are assigned, however.
*/
{
/* Allocate memory */
System* Sys = xmalloc (sizeof (System));
/* Initialize the fields */
Sys->CPU = CPU;
Sys->AS = NewAddressSpace (CPU->AddressSize);
Sys->ChipInstances = AUTO_COLLECTION_INITIALIZER;
/* Return the new system */
return Sys;
}

View File

@ -1,91 +0,0 @@
/*****************************************************************************/
/* */
/* system.h */
/* */
/* Description of the simulated system */
/* */
/* */
/* */
/* (C) 2003-2012, Ullrich von Bassewitz */
/* Roemerstrasse 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. */
/* */
/*****************************************************************************/
#ifndef SYSTEM_H
#define SYSTEM_H
/* common.h */
#include "coll.h"
/* sim65 */
#include "addrspace.h"
#include "cpucore.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Forwards */
struct CPUCore;
/* */
typedef struct System System;
struct System {
CPUCore* CPU; /* The CPU in the system */
AddressSpace* AS; /* The CPU address space */
Collection ChipInstances; /* Instances of all the chips */
};
/* Global pointer to simulated system */
extern System* System;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
System* NewSystem (CPUCore* CPU);
/* Create and initialize a new System struct. The function will read the size
* of the address space from the CPU, and also create a new AddressSpace
* object. No chips are assigned, however.
*/
/* End of system.h */
#endif