]> git.sur5r.net Git - cc65/blob - src/sim65/memory.c
Cosmetic change
[cc65] / src / sim65 / memory.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 memory.h                                  */
4 /*                                                                           */
5 /*                  Memory subsystem for the 6502 simulator                  */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2002      Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
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.                                    */
18 /*                                                                           */
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:                            */
22 /*                                                                           */
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              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <errno.h>
39
40 /* common */
41 #include "coll.h"
42
43 /* sim65 */
44 #include "error.h"
45 #include "memory.h"
46
47
48
49 /*****************************************************************************/
50 /*                                   Forwards                                */
51 /*****************************************************************************/
52
53
54
55 static void MemWrite (unsigned Addr, unsigned char Val);
56 /* Write one byte to the memory cell */
57
58 static unsigned char MemRead (unsigned Attr);
59 /* Read one memory cell */
60
61
62
63 /*****************************************************************************/
64 /*                                   Data                                    */
65 /*****************************************************************************/
66
67
68
69 /* RAM attributes */
70 #define RA_READFUNC_MASK        0x000F  /* Up to 16 read functions */
71 #define RA_WRITEFUNC_MASK       0x00F0  /* Up to 16 write functions */
72 #define RA_INITIALIZED          0x0100  /* Memory cell is initialized */
73 #define RA_WPROT                0x0200  /* Memory cell is write protected */
74
75 /* Defines reader and writer functions */
76 #define RA_READFUNC_SHIFT       0
77 #define RA_WRITEFUNC_SHIFT      4
78 #define RA_READFUNC_MAX         16
79 #define RA_WRITEFUNC_MAX        16
80
81 /* Read/write function declarations */
82 typedef unsigned char (*ReadFunc) (unsigned Addr);
83 typedef void (*WriteFunc) (unsigned Addr, unsigned char Val);
84 static Collection ReadFuncs  = STATIC_COLLECTION_INITIALIZER;
85 static Collection WriteFuncs = STATIC_COLLECTION_INITIALIZER;
86
87 /* Memory attributes and the memory */
88 static unsigned short MemAttr[0x10000];
89 static unsigned char Mem[0x10000];
90
91
92
93 /*****************************************************************************/
94 /*                              Internal functions                           */
95 /*****************************************************************************/
96
97
98
99 static void MemWrite (unsigned Addr, unsigned char Val)
100 /* Write one byte to the memory cell */
101 {
102     if (MemAttr[Addr] & RA_WPROT) {
103         Warning ("Writing to write protected memory at $%04X", Addr);
104     }
105     Mem[Addr] = Val;
106     MemAttr[Addr] |= RA_INITIALIZED;
107 }
108
109
110
111 static unsigned char MemRead (unsigned Addr)
112 /* Read one memory cell */
113 {
114     if ((MemAttr[Addr] & RA_INITIALIZED) == 0) {
115         /* We're reading a memory cell that was never written */
116         Warning ("Reading from uninitialized memory at $%04X", Addr);
117     }
118     return Mem[Addr];
119 }
120
121
122
123 /*****************************************************************************/
124 /*                                   Code                                    */
125 /*****************************************************************************/
126
127
128
129 void MemWriteByte (unsigned Addr, unsigned char Val)
130 /* Write a byte to a memory location */
131 {
132     /* Get the writer function */
133     unsigned  WI = (MemAttr[Addr] & RA_WRITEFUNC_MASK) >> RA_WRITEFUNC_SHIFT;
134     WriteFunc WF = CollAt (&WriteFuncs, WI);
135
136     /* Call the writer function */
137     WF (Addr, Val);
138 }
139
140
141
142 unsigned char MemReadByte (unsigned Addr)
143 /* Read a byte from a memory location */
144 {
145     /* Get the reader function */
146     unsigned  RI = (MemAttr[Addr] & RA_READFUNC_MASK) >> RA_READFUNC_SHIFT;
147     ReadFunc RF = CollAt (&ReadFuncs, RI);
148
149     /* Call the reader function */
150     return RF (Addr);
151 }
152
153
154
155 unsigned MemReadWord (unsigned Addr)
156 /* Read a word from a memory location */
157 {
158     unsigned W = MemReadByte (Addr++);
159     return (W | (MemReadByte (Addr) << 8));
160 }
161
162
163
164 unsigned MemReadZPWord (unsigned char Addr)
165 /* Read a word from the zero page. This function differs from ReadMemW in that
166 * the read will always be in the zero page, even in case of an address
167 * overflow.
168 */
169 {
170     unsigned W = MemReadByte (Addr++);
171     return (W | (MemReadByte (Addr) << 8));
172 }
173
174
175
176 void MemLoad (const char* Filename, unsigned Addr, unsigned Size)
177 /* Load the contents of the given file into the RAM at the given address.
178  * If Size is not zero, we will read exactly Size bytes from the file and
179  * consider it an error if this is not possible. The memory attributes
180  * for the range is set to initialized.
181  */
182 {
183     unsigned BytesToRead;
184     unsigned BytesRead;
185     unsigned I;
186
187     /* Open the file */
188     FILE* F = fopen (Filename, "rb");
189     if (F == 0) {
190         Error ("Cannot open `%s': %s", Filename, strerror (errno));
191     }
192
193     /* Set the number of bytes to read */
194     BytesToRead = 0x10000 - Addr;
195     if (Size > 0) {
196         CHECK (Size <= BytesToRead);    /* Must not exceed RAM */
197         BytesToRead = Size;
198     }
199
200     /* Read data from the file */
201     BytesRead = fread (Mem + Addr, 1, BytesToRead, F);
202     if (ferror (F)) {
203         Error ("Error reading from `%s': %s", Filename, strerror (errno));
204     }
205     if (Size > 0 && BytesRead != Size) {
206         Error ("Cannot read %u bytes from `%s'", Size, Filename);
207     }
208
209     /* Close the file. Ignore errors, we were just reading. */
210     fclose (F);
211
212     /* Set the memory attribute for the range to initialized */
213     for (I = 0; I < BytesRead; ++I) {
214         MemAttr[Addr+I] |= RA_INITIALIZED;
215     }
216 }
217
218
219
220 void MemInit (void)
221 /* Initialize the memory subsystem */
222 {
223     unsigned I;
224
225     /* Clear the memory and it's attributes. Writing zeroes to the
226      * attribute array will cause any special flags to be reset and
227      * the default read and write functions to be used.
228      */
229     for (I = 0; I < sizeof (Mem) / sizeof (Mem[0]); ++I) {
230         Mem[I] = 0;
231     }
232     for (I = 0; I < sizeof (MemAttr) / sizeof (MemAttr[0]); ++I) {
233         MemAttr[I] = 0;
234     }
235
236     /* Add the default reader and writer functions to the collection */
237     CollAppend (&ReadFuncs, MemRead);
238     CollAppend (&WriteFuncs, MemWrite);
239
240     MemWriteByte (0xFFFC, 0x00);
241     MemWriteByte (0xFFFD, 0x02);
242 }
243
244
245