1 /*****************************************************************************/
5 /* Memory subsystem for the 6502 simulator */
9 /* (C) 2002 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
44 /*****************************************************************************/
46 /*****************************************************************************/
50 static void MemWrite (unsigned Addr, unsigned char Val);
51 /* Write one byte to the memory cell */
53 static unsigned char MemRead (unsigned Attr);
54 /* Read one memory cell */
58 /*****************************************************************************/
60 /*****************************************************************************/
65 #define RA_READFUNC_MASK 0x000F /* Up to 16 read functions */
66 #define RA_WRITEFUNC_MASK 0x00F0 /* Up to 16 write functions */
67 #define RA_INITIALIZED 0x0100 /* Memory cell is initialized */
68 #define RA_WPROT 0x0200 /* Memory cell is write protected */
70 /* Defines reader and writer functions */
71 #define RA_READFUNC_SHIFT 0
72 #define RA_WRITEFUNC_SHIFT 4
73 #define RA_READFUNC_MAX 16
74 #define RA_WRITEFUNC_MAX 16
76 /* Read/write function declarations */
77 typedef unsigned char (*ReadFunc) (unsigned Addr);
78 typedef void (*WriteFunc) (unsigned Addr, unsigned char Val);
79 static Collection ReadFuncs = STATIC_COLLECTION_INITIALIZER;
80 static Collection WriteFuncs = STATIC_COLLECTION_INITIALIZER;
82 /* Memory attributes and the memory */
83 static unsigned short MemAttr[0x10000];
84 static unsigned char Mem[0x10000];
88 /*****************************************************************************/
89 /* Internal functions */
90 /*****************************************************************************/
94 static void MemWrite (unsigned Addr, unsigned char Val)
95 /* Write one byte to the memory cell */
97 if (MemAttr[Addr] & RA_WPROT) {
101 MemAttr[Addr] |= RA_INITIALIZED;
106 static unsigned char MemRead (unsigned Addr)
107 /* Read one memory cell */
109 if ((MemAttr[Addr] & RA_INITIALIZED) == 0) {
110 /* We're reading a memory cell that was never written */
118 /*****************************************************************************/
120 /*****************************************************************************/
124 void MemWriteByte (unsigned Addr, unsigned char Val)
125 /* Write a byte to a memory location */
127 /* Get the writer function */
128 unsigned WI = (MemAttr[Addr] & RA_WRITEFUNC_MASK) >> RA_WRITEFUNC_SHIFT;
129 WriteFunc WF = CollAt (&WriteFuncs, WI);
131 /* Call the writer function */
137 unsigned char MemReadByte (unsigned Addr)
138 /* Read a byte from a memory location */
140 /* Get the reader function */
141 unsigned RI = (MemAttr[Addr] & RA_READFUNC_MASK) >> RA_READFUNC_SHIFT;
142 ReadFunc RF = CollAt (&WriteFuncs, RI);
144 /* Call the reader function */
150 unsigned MemReadWord (unsigned Addr)
151 /* Read a word from a memory location */
153 unsigned W = MemReadByte (Addr++);
154 return (W | (MemReadByte (Addr) << 8));
159 unsigned MemReadZPWord (unsigned char Addr)
160 /* Read a word from the zero page. This function differs from ReadMemW in that
161 * the read will always be in the zero page, even in case of an address
165 unsigned W = MemReadByte (Addr++);
166 return (W | (MemReadByte (Addr) << 8));
172 /* Initialize the memory subsystem */
176 /* Clear the memory and it's attributes. Writing zeroes to the
177 * attribute array will cause any special flags to be reset and
178 * the default read and write functions to be used.
180 for (I = 0; I < sizeof (Mem) / sizeof (Mem[0]); ++I) {
183 for (I = 0; I < sizeof (MemAttr) / sizeof (MemAttr[0]); ++I) {
187 /* Add the default reader and writer functions to the collection */
188 CollAppend (&ReadFuncs, MemRead);
189 CollAppend (&WriteFuncs, MemWrite);