Working
git-svn-id: svn://svn.cc65.org/cc65/trunk@2139 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -278,7 +278,7 @@ ChipInstance* NewChipInstance (const char* ChipName, unsigned Addr,
|
|||||||
CI->AS = 0;
|
CI->AS = 0;
|
||||||
CI->Addr = Addr;
|
CI->Addr = Addr;
|
||||||
CI->Size = Size;
|
CI->Size = Size;
|
||||||
CI->Data = C->Data->InitInstance (Addr, Size, Attributes);
|
CI->Data = C->Data->CreateInstance (Addr, Size, Attributes);
|
||||||
|
|
||||||
/* Assign the chip instance to the chip */
|
/* Assign the chip instance to the chip */
|
||||||
CollAppend (&C->Instances, CI);
|
CollAppend (&C->Instances, CI);
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ struct ChipData {
|
|||||||
|
|
||||||
/* -- Exported functions -- */
|
/* -- Exported functions -- */
|
||||||
int (*InitChip) (const struct SimData* Data);
|
int (*InitChip) (const struct SimData* Data);
|
||||||
void* (*InitInstance) (unsigned Addr, unsigned Range, void* CfgInfo);
|
void* (*CreateInstance) (unsigned Addr, unsigned Range, void* CfgInfo);
|
||||||
|
void (*DestroyInstance) (void* Data);
|
||||||
void (*WriteCtrl) (void* Data, unsigned Offs, unsigned char Val);
|
void (*WriteCtrl) (void* Data, unsigned Offs, unsigned char Val);
|
||||||
void (*Write) (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 (*ReadCtrl) (void* Data, unsigned Offs);
|
||||||
|
|||||||
@@ -11,14 +11,27 @@ CC = gcc
|
|||||||
EBIND = emxbind
|
EBIND = emxbind
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
LIBS = $(COMMON)/common.a
|
#LIBS = $(COMMON)/common.a
|
||||||
|
|
||||||
CHIPS = ram.so \
|
CHIPS = ram.so \
|
||||||
rom.so \
|
rom.so \
|
||||||
stdio.so
|
stdio.so \
|
||||||
|
vic2.so
|
||||||
|
|
||||||
OBJS = $(CHIPS:.so=.o)
|
OBJS = $(CHIPS:.so=.o)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Build rules
|
||||||
|
|
||||||
|
%.obj: %.c
|
||||||
|
$(CC) $(CFLAGS) $^
|
||||||
|
|
||||||
|
%.so: %.o
|
||||||
|
$(CC) $(CFLAGS) -shared -o $@ $(LIBS) $^ -L /usr/X11R6/lib -lX11
|
||||||
|
@if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
ifeq (.depend,$(wildcard .depend))
|
ifeq (.depend,$(wildcard .depend))
|
||||||
all: $(CHIPS)
|
all: $(CHIPS)
|
||||||
@@ -29,20 +42,6 @@ all: depend
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
# Rules to make chips
|
|
||||||
|
|
||||||
ram.so: ram.o
|
|
||||||
$(CC) $(CFLAGS) -shared -o $@ $(LIBS) $^
|
|
||||||
@if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi
|
|
||||||
|
|
||||||
rom.so: rom.o
|
|
||||||
$(CC) $(CFLAGS) -shared -o $@ $(LIBS) $^
|
|
||||||
@if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi
|
|
||||||
|
|
||||||
stdio.so: stdio.o
|
|
||||||
$(CC) $(CFLAGS) -shared -o $@ $(LIBS) $^
|
|
||||||
@if [ $(OS2_SHELL) ] ; then $(EBIND) $@ ; fi
|
|
||||||
|
|
||||||
# Admin stuff
|
# Admin stuff
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
static int InitChip (const struct SimData* Data);
|
static int InitChip (const struct SimData* Data);
|
||||||
/* Initialize the chip, return an error code */
|
/* Initialize the chip, return an error code */
|
||||||
|
|
||||||
static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo);
|
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
|
||||||
/* Initialize a new chip instance */
|
/* Create a new chip instance */
|
||||||
|
|
||||||
|
static void DestroyInstance (void* Data);
|
||||||
|
/* Destroy a chip instance */
|
||||||
|
|
||||||
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val);
|
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val);
|
||||||
/* Write control data */
|
/* Write control data */
|
||||||
@@ -74,7 +77,7 @@ static unsigned char Read (void* Data, unsigned Offs);
|
|||||||
|
|
||||||
|
|
||||||
/* Control data passed to the main program */
|
/* Control data passed to the main program */
|
||||||
static const struct ChipData RAMData[1] = {
|
static const struct ChipData CData[1] = {
|
||||||
{
|
{
|
||||||
"RAM", /* Name of the chip */
|
"RAM", /* Name of the chip */
|
||||||
CHIPDATA_TYPE_CHIP, /* Type of the chip */
|
CHIPDATA_TYPE_CHIP, /* Type of the chip */
|
||||||
@@ -83,7 +86,8 @@ static const struct ChipData RAMData[1] = {
|
|||||||
|
|
||||||
/* -- Exported functions -- */
|
/* -- Exported functions -- */
|
||||||
InitChip,
|
InitChip,
|
||||||
InitInstance,
|
CreateInstance,
|
||||||
|
DestroyInstance,
|
||||||
WriteCtrl,
|
WriteCtrl,
|
||||||
Write,
|
Write,
|
||||||
ReadCtrl,
|
ReadCtrl,
|
||||||
@@ -118,8 +122,8 @@ struct InstanceData {
|
|||||||
int GetChipData (const ChipData** Data, unsigned* Count)
|
int GetChipData (const ChipData** Data, unsigned* Count)
|
||||||
{
|
{
|
||||||
/* Pass the control structure to the caller */
|
/* Pass the control structure to the caller */
|
||||||
*Data = RAMData;
|
*Data = CData;
|
||||||
*Count = sizeof (Data) / sizeof (Data[0]);
|
*Count = sizeof (CData) / sizeof (CData[0]);
|
||||||
|
|
||||||
/* Call was successful */
|
/* Call was successful */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -145,8 +149,8 @@ static int InitChip (const struct SimData* Data)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
||||||
/* Initialize a new chip instance */
|
/* Create a new chip instance */
|
||||||
{
|
{
|
||||||
long Val;
|
long Val;
|
||||||
|
|
||||||
@@ -182,6 +186,22 @@ static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val)
|
||||||
/* Write control data */
|
/* Write control data */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,8 +52,11 @@
|
|||||||
static int InitChip (const struct SimData* Data);
|
static int InitChip (const struct SimData* Data);
|
||||||
/* Initialize the chip, return an error code */
|
/* Initialize the chip, return an error code */
|
||||||
|
|
||||||
static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo);
|
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
|
||||||
/* Initialize a new chip instance */
|
/* Create a new chip instance */
|
||||||
|
|
||||||
|
static void DestroyInstance (void* Data);
|
||||||
|
/* Destroy a chip instance */
|
||||||
|
|
||||||
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val);
|
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val);
|
||||||
/* Write control data */
|
/* Write control data */
|
||||||
@@ -76,7 +79,7 @@ static unsigned char Read (void* Data, unsigned Offs);
|
|||||||
|
|
||||||
|
|
||||||
/* Control data passed to the main program */
|
/* Control data passed to the main program */
|
||||||
static const struct ChipData ROMData[1] = {
|
static const struct ChipData CData[1] = {
|
||||||
{
|
{
|
||||||
"ROM", /* Name of the chip */
|
"ROM", /* Name of the chip */
|
||||||
CHIPDATA_TYPE_CHIP, /* Type of the chip */
|
CHIPDATA_TYPE_CHIP, /* Type of the chip */
|
||||||
@@ -85,7 +88,8 @@ static const struct ChipData ROMData[1] = {
|
|||||||
|
|
||||||
/* -- Exported functions -- */
|
/* -- Exported functions -- */
|
||||||
InitChip,
|
InitChip,
|
||||||
InitInstance,
|
CreateInstance,
|
||||||
|
DestroyInstance,
|
||||||
WriteCtrl,
|
WriteCtrl,
|
||||||
Write,
|
Write,
|
||||||
ReadCtrl,
|
ReadCtrl,
|
||||||
@@ -115,8 +119,8 @@ struct InstanceData {
|
|||||||
int GetChipData (const ChipData** Data, unsigned* Count)
|
int GetChipData (const ChipData** Data, unsigned* Count)
|
||||||
{
|
{
|
||||||
/* Pass the control structure to the caller */
|
/* Pass the control structure to the caller */
|
||||||
*Data = ROMData;
|
*Data = CData;
|
||||||
*Count = sizeof (Data) / sizeof (Data[0]);
|
*Count = sizeof (CData) / sizeof (CData[0]);
|
||||||
|
|
||||||
/* Call was successful */
|
/* Call was successful */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -142,8 +146,8 @@ static int InitChip (const struct SimData* Data)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
||||||
/* Initialize a new chip instance */
|
/* Create a new chip instance */
|
||||||
{
|
{
|
||||||
char* Name;
|
char* Name;
|
||||||
FILE* F;
|
FILE* F;
|
||||||
@@ -185,6 +189,21 @@ static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val)
|
||||||
/* Write control data */
|
/* Write control data */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,8 +54,11 @@
|
|||||||
static int InitChip (const struct SimData* Data);
|
static int InitChip (const struct SimData* Data);
|
||||||
/* Initialize the chip, return an error code */
|
/* Initialize the chip, return an error code */
|
||||||
|
|
||||||
static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo);
|
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo);
|
||||||
/* Initialize a new chip instance */
|
/* Create a new chip instance */
|
||||||
|
|
||||||
|
static void DestroyInstance (void* Data);
|
||||||
|
/* Destroy a chip instance */
|
||||||
|
|
||||||
static void Write (void* Data, unsigned Offs, unsigned char Val);
|
static void Write (void* Data, unsigned Offs, unsigned char Val);
|
||||||
/* Write user data */
|
/* Write user data */
|
||||||
@@ -72,7 +75,7 @@ static unsigned char Read (void* Data, unsigned Offs);
|
|||||||
|
|
||||||
|
|
||||||
/* Control data passed to the main program */
|
/* Control data passed to the main program */
|
||||||
static const struct ChipData STDIOData[1] = {
|
static const struct ChipData CData[1] = {
|
||||||
{
|
{
|
||||||
"STDIO", /* Name of the chip */
|
"STDIO", /* Name of the chip */
|
||||||
CHIPDATA_TYPE_CHIP, /* Type of the chip */
|
CHIPDATA_TYPE_CHIP, /* Type of the chip */
|
||||||
@@ -81,7 +84,8 @@ static const struct ChipData STDIOData[1] = {
|
|||||||
|
|
||||||
/* -- Exported functions -- */
|
/* -- Exported functions -- */
|
||||||
InitChip,
|
InitChip,
|
||||||
InitInstance,
|
CreateInstance,
|
||||||
|
DestroyInstance,
|
||||||
Write,
|
Write,
|
||||||
Write,
|
Write,
|
||||||
Read,
|
Read,
|
||||||
@@ -103,8 +107,8 @@ static const SimData* Sim;
|
|||||||
int GetChipData (const ChipData** Data, unsigned* Count)
|
int GetChipData (const ChipData** Data, unsigned* Count)
|
||||||
{
|
{
|
||||||
/* Pass the control structure to the caller */
|
/* Pass the control structure to the caller */
|
||||||
*Data = STDIOData;
|
*Data = CData;
|
||||||
*Count = sizeof (Data) / sizeof (Data[0]);
|
*Count = sizeof (CData) / sizeof (CData[0]);
|
||||||
|
|
||||||
/* Call was successful */
|
/* Call was successful */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -130,7 +134,7 @@ static int InitChip (const struct SimData* Data)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
||||||
/* Initialize a new chip instance */
|
/* Initialize a new chip instance */
|
||||||
{
|
{
|
||||||
/* We don't need any instance data */
|
/* We don't need any instance data */
|
||||||
@@ -139,6 +143,13 @@ static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void DestroyInstance (void* Data)
|
||||||
|
/* Destroy a chip instance */
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void Write (void* Data attribute ((unused)),
|
static void Write (void* Data attribute ((unused)),
|
||||||
unsigned Offs attribute ((unused)),
|
unsigned Offs attribute ((unused)),
|
||||||
unsigned char Val)
|
unsigned char Val)
|
||||||
|
|||||||
897
src/sim65/chips/vic2.c
Normal file
897
src/sim65/chips/vic2.c
Normal file
@@ -0,0 +1,897 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2498,10 +2498,12 @@ void NMI (void)
|
|||||||
void Break (const char* Format, ...)
|
void Break (const char* Format, ...)
|
||||||
/* Stop running and display the given message */
|
/* Stop running and display the given message */
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
xvsprintf (BreakMsg, sizeof (BreakMsg), Format, ap);
|
xvsprintf (BreakMsg, sizeof (BreakMsg), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2509,11 +2511,16 @@ void Break (const char* Format, ...)
|
|||||||
void CPURun (void)
|
void CPURun (void)
|
||||||
/* Run the CPU */
|
/* Run the CPU */
|
||||||
{
|
{
|
||||||
|
unsigned long I = 0;
|
||||||
|
|
||||||
|
|
||||||
while (!CPUHalted) {
|
while (!CPUHalted) {
|
||||||
|
|
||||||
/* Get the next opcode */
|
/* Get the next opcode */
|
||||||
unsigned char OPC = MemReadByte (PC);
|
unsigned char OPC = MemReadByte (PC);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if ((++I & 0xFF) == 0)
|
||||||
printf ("%9lu %06X %02X A=%02X X=%02X Y=%02X %c%c%c%c%c%c%c\n",
|
printf ("%9lu %06X %02X A=%02X X=%02X Y=%02X %c%c%c%c%c%c%c\n",
|
||||||
TotalCycles, PC, OPC, AC, XR, YR,
|
TotalCycles, PC, OPC, AC, XR, YR,
|
||||||
GET_SF()? 'S' : '-',
|
GET_SF()? 'S' : '-',
|
||||||
@@ -2523,6 +2530,7 @@ void CPURun (void)
|
|||||||
GET_BF()? 'B' : '-',
|
GET_BF()? 'B' : '-',
|
||||||
GET_DF()? 'D' : '-',
|
GET_DF()? 'D' : '-',
|
||||||
GET_OF()? 'V' : '-');
|
GET_OF()? 'V' : '-');
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Execute it */
|
/* Execute it */
|
||||||
OPCTable[OPC] ();
|
OPCTable[OPC] ();
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ OBJS = addrspace.o \
|
|||||||
location.o \
|
location.o \
|
||||||
main.o \
|
main.o \
|
||||||
memory.o \
|
memory.o \
|
||||||
scanner.o
|
scanner.o \
|
||||||
|
system.o
|
||||||
|
|
||||||
LIBS = $(COMMON)/common.a
|
LIBS = $(COMMON)/common.a
|
||||||
|
|
||||||
|
|||||||
71
src/sim65/system.c
Normal file
71
src/sim65/system.c
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* system.c */
|
||||||
|
/* */
|
||||||
|
/* Description of the simulated system */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (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 "xmalloc.h"
|
||||||
|
|
||||||
|
/* sim65 */
|
||||||
|
#include "addrspace.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
System* NewSystem (struct CPUData* 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 = 0; /* ### */
|
||||||
|
Sys->ChipInstances = AUTO_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
/* Return the new system */
|
||||||
|
return Sys;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
86
src/sim65/system.h
Normal file
86
src/sim65/system.h
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* system.h */
|
||||||
|
/* */
|
||||||
|
/* Description of the simulated system */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (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 SYSTEM_H
|
||||||
|
#define SYSTEM_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common.h */
|
||||||
|
#include "coll.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Forwards */
|
||||||
|
struct CPUData;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
typedef struct System System;
|
||||||
|
struct System {
|
||||||
|
|
||||||
|
struct CPUData* CPU; /* The CPU in the system */
|
||||||
|
struct AddressSpace* AS; /* The CPU address space */
|
||||||
|
Collection ChipInstances;/* Instances of all the chips */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
System* NewSystem (struct CPUData* 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user