|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Memory management
5: *
6: * (c) 1995 Bernd Schmidt
7: */
8:
9: #include <stdio.h>
10: #include <string.h>
11:
12: #include "config.h"
13: #include "amiga.h"
14: #include "options.h"
15: #include "memory.h"
16: #include "custom.h"
17: #include "cia.h"
18: #include "ersatz.h"
19:
20: bool buserr;
21:
22: const char romfile[] = "kick.rom";
23:
24: lget_func do_lget[256];
25: wget_func do_wget[256];
26: bget_func do_bget[256];
27: lput_func do_lput[256];
28: wput_func do_wput[256];
29: bput_func do_bput[256];
30: xlate_func do_xlateaddr[256];
31: check_func do_check[256];
32:
33: /* Default memory access functions */
34:
35: bool default_check(CPTR a, ULONG b)
36: {
37: return false;
38: }
39:
40: UWORD *default_xlate(CPTR a)
41: {
42: fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
43: return 0;
44: }
45:
46: /* Chip memory */
47:
48: static UWORD chipmemory[chipmem_size/2];
49:
50: static ULONG chipmem_lget(CPTR) REGPARAM;
51: static UWORD chipmem_wget(CPTR) REGPARAM;
52: static UBYTE chipmem_bget(CPTR) REGPARAM;
53: static void chipmem_lput(CPTR, ULONG) REGPARAM;
54: static void chipmem_wput(CPTR, UWORD) REGPARAM;
55: static void chipmem_bput(CPTR, UBYTE) REGPARAM;
56: static bool chipmem_check(CPTR addr, ULONG size) REGPARAM;
57: static UWORD *chipmem_xlate(CPTR addr) REGPARAM;
58:
59: ULONG chipmem_lget(CPTR addr)
60: {
61: addr -= chipmem_start & (chipmem_size-1);
62: addr &= chipmem_size-1;
63: return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1];
64: }
65:
66: UWORD chipmem_wget(CPTR addr)
67: {
68: addr -= chipmem_start & (chipmem_size-1);
69: addr &= chipmem_size-1;
70: return chipmemory[addr >> 1];
71: }
72:
73: UBYTE chipmem_bget(CPTR addr)
74: {
75: addr -= chipmem_start & (chipmem_size-1);
76: addr &= chipmem_size-1;
77: return chipmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
78: }
79:
80: void chipmem_lput(CPTR addr, ULONG l)
81: {
82: addr -= chipmem_start & (chipmem_size-1);
83: addr &= chipmem_size-1;
84: chipmemory[addr >> 1] = l >> 16;
85: chipmemory[(addr >> 1)+1] = (UWORD)l;
86: }
87:
88: void chipmem_wput(CPTR addr, UWORD w)
89: {
90: addr -= chipmem_start & (chipmem_size-1);
91: addr &= chipmem_size-1;
92: chipmemory[addr >> 1] = w;
93: }
94:
95: void chipmem_bput(CPTR addr, UBYTE b)
96: {
97: addr -= chipmem_start & (chipmem_size-1);
98: addr &= chipmem_size-1;
99: if (!(addr & 1)) {
100: chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
101: } else {
102: chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b;
103: }
104: }
105:
106: bool chipmem_check(CPTR addr, ULONG size)
107: {
108: addr -= chipmem_start & (chipmem_size-1);
109: addr &= chipmem_size-1;
110: return (addr + size) < chipmem_size;
111: }
112:
113: UWORD *chipmem_xlate(CPTR addr)
114: {
115: addr -= chipmem_start & (chipmem_size-1);
116: addr &= chipmem_size-1;
117: return chipmemory + (addr >> 1);
118: }
119:
120: /* Slow memory */
121:
122: static UWORD bogomemory[bogomem_size/2];
123:
124: static ULONG bogomem_lget(CPTR) REGPARAM;
125: static UWORD bogomem_wget(CPTR) REGPARAM;
126: static UBYTE bogomem_bget(CPTR) REGPARAM;
127: static void bogomem_lput(CPTR, ULONG) REGPARAM;
128: static void bogomem_wput(CPTR, UWORD) REGPARAM;
129: static void bogomem_bput(CPTR, UBYTE) REGPARAM;
130: static bool bogomem_check(CPTR addr, ULONG size) REGPARAM;
131: static UWORD *bogomem_xlate(CPTR addr) REGPARAM;
132:
133: ULONG bogomem_lget(CPTR addr)
134: {
135: addr -= bogomem_start & (bogomem_size-1);
136: addr &= bogomem_size-1;
137: return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1];
138: }
139:
140: UWORD bogomem_wget(CPTR addr)
141: {
142: addr -= bogomem_start & (bogomem_size-1);
143: addr &= bogomem_size-1;
144: return bogomemory[addr >> 1];
145: }
146:
147: UBYTE bogomem_bget(CPTR addr)
148: {
149: addr -= bogomem_start & (bogomem_size-1);
150: addr &= bogomem_size-1;
151: return bogomemory[addr >> 1] >> (addr & 1 ? 0 : 8);
152: }
153:
154: void bogomem_lput(CPTR addr, ULONG l)
155: {
156: addr -= bogomem_start & (bogomem_size-1);
157: addr &= bogomem_size-1;
158: bogomemory[addr >> 1] = l >> 16;
159: bogomemory[(addr >> 1)+1] = (UWORD)l;
160: }
161:
162: void bogomem_wput(CPTR addr, UWORD w)
163: {
164: addr -= bogomem_start & (bogomem_size-1);
165: addr &= bogomem_size-1;
166: bogomemory[addr >> 1] = w;
167: }
168:
169: void bogomem_bput(CPTR addr, UBYTE b)
170: {
171: addr -= bogomem_start & (bogomem_size-1);
172: addr &= bogomem_size-1;
173: if (!(addr & 1)) {
174: bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
175: } else {
176: bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b;
177: }
178: }
179:
180: bool bogomem_check(CPTR addr, ULONG size)
181: {
182: addr -= bogomem_start & (bogomem_size-1);
183: addr &= bogomem_size-1;
184: return (addr + size) < bogomem_size;
185: }
186:
187: UWORD *bogomem_xlate(CPTR addr)
188: {
189: addr -= bogomem_start & (bogomem_size-1);
190: addr &= bogomem_size-1;
191: return bogomemory + (addr >> 1);
192: }
193:
194: /* Kick memory */
195:
196: static UWORD kickmemory[kickmem_size/2];
197:
198: static ULONG kickmem_lget(CPTR) REGPARAM;
199: static UWORD kickmem_wget(CPTR) REGPARAM;
200: static UBYTE kickmem_bget(CPTR) REGPARAM;
201: static void kickmem_lput(CPTR, ULONG) REGPARAM;
202: static void kickmem_wput(CPTR, UWORD) REGPARAM;
203: static void kickmem_bput(CPTR, UBYTE) REGPARAM;
204: static bool kickmem_check(CPTR addr, ULONG size) REGPARAM;
205: static UWORD *kickmem_xlate(CPTR addr) REGPARAM;
206:
207: ULONG kickmem_lget(CPTR addr)
208: {
209: addr -= kickmem_start & (kickmem_size-1);
210: addr &= kickmem_size-1;
211: return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1];
212: }
213:
214: UWORD kickmem_wget(CPTR addr)
215: {
216: addr -= kickmem_start & (kickmem_size-1);
217: addr &= kickmem_size-1;
218: return kickmemory[addr >> 1];
219: }
220:
221: UBYTE kickmem_bget(CPTR addr)
222: {
223: addr -= kickmem_start & (kickmem_size-1);
224: addr &= kickmem_size-1;
225: return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
226: }
227:
228: void kickmem_lput(CPTR a, ULONG b)
229: {
230: }
231:
232: void kickmem_wput(CPTR a, UWORD b)
233: {
234: }
235:
236: void kickmem_bput(CPTR a, UBYTE b)
237: {
238: }
239:
240: bool kickmem_check(CPTR addr, ULONG size)
241: {
242: addr -= kickmem_start & (kickmem_size-1);
243: addr &= kickmem_size-1;
244: return (addr + size) < kickmem_size;
245: }
246:
247: UWORD *kickmem_xlate(CPTR addr)
248: {
249: addr -= kickmem_start & (kickmem_size-1);
250: addr &= kickmem_size-1;
251: return kickmemory + (addr >> 1);
252: }
253:
254: static bool load_kickstart(void)
255: {
256: int i;
257: ULONG cksum = 0, prevck = 0;
258:
259: FILE *f = fopen(romfile, "rb");
260:
261: if (f == NULL) {
262: fprintf(stderr, "No Kickstart ROM found.\n");
263: return false;
264: }
265:
266: for(i = 0; i < kickmem_size/2; i++) {
267: unsigned char buffer[2];
268: if (fread(buffer, 1, 2, f) < 2) {
269: if (feof(f) && i == kickmem_size/4) {
270: fprintf(stderr, "Warning: Kickstart is only 256K.\n");
271: #ifndef __mac__
272: memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/4);
273: #else
274: memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/2);
275: #endif
276: break;
277: } else {
278: fprintf(stderr, "Error while reading Kickstart.\n");
279: return false;
280: }
281: }
282: kickmemory[i] = buffer[0]*256 + buffer[1];
283: }
284: fclose (f);
285:
286: for (i = 0; i < kickmem_size/4; i++) {
287: ULONG data = kickmemory[i*2]*65536 + kickmemory[i*2+1];
288: cksum += data;
289: if (cksum < prevck)
290: cksum++;
291: prevck = cksum;
292: }
293: if (cksum != 0xFFFFFFFF) {
294: fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
295: }
296: return true;
297: }
298:
299: /* Address banks */
300:
301: addrbank chipmem_bank = {
302: chipmem_lget, chipmem_wget, chipmem_bget,
303: chipmem_lput, chipmem_wput, chipmem_bput,
304: chipmem_xlate, chipmem_check
305: };
306:
307: addrbank bogomem_bank = {
308: bogomem_lget, bogomem_wget, bogomem_bget,
309: bogomem_lput, bogomem_wput, bogomem_bput,
310: bogomem_xlate, bogomem_check
311: };
312:
313: addrbank kickmem_bank = {
314: kickmem_lget, kickmem_wget, kickmem_bget,
315: kickmem_lput, kickmem_wput, kickmem_bput,
316: kickmem_xlate, kickmem_check
317: };
318:
319:
320: #ifdef DUALCPU
321: ULONG mempattern;
322: bool incpu;
323: struct memreads {
324: CPTR addr;
325: ULONG value;
326: } readlog[200];
327:
328: int memlogptr = 0;
329:
330: ULONG get_long(CPTR addr)
331: {
332: ULONG result;
333: mempattern ^= addr ^ 0x99999999;
334: if (allowmem || !incpu) {
335: result = longget(addr);
336: if (incpu) {
337: readlog[memlogptr].addr = addr;
338: readlog[memlogptr++].value = result;
339: }
340: } else {
341: for(int i=0;i<memlogptr;i++) {
342: if (readlog[i].addr == addr) {
343: result = readlog[i].value;
344: }
345: }
346: }
347: return result;
348: }
349:
350: UWORD get_word(CPTR addr)
351: {
352: UWORD result;
353: mempattern ^= addr ^ 0xAAAAAAAA;
354: if (allowmem || !incpu) {
355: result = wordget(addr);
356: if (incpu) {
357: readlog[memlogptr].addr = addr;
358: readlog[memlogptr++].value = result;
359: }
360: } else {
361: for(int i=0;i<memlogptr;i++) {
362: if (readlog[i].addr == addr) {
363: result = readlog[i].value;
364: }
365: }
366: }
367: return result;
368: }
369:
370: UBYTE get_byte(CPTR addr)
371: {
372: UBYTE result;
373: mempattern ^= addr ^ 0x55555555;
374: if (allowmem || !incpu) {
375: result = byteget(addr);
376: if (incpu) {
377: readlog[memlogptr].addr = addr;
378: readlog[memlogptr++].value = result;
379: }
380: } else {
381: for(int i=0;i<memlogptr;i++) {
382: if (readlog[i].addr == addr) {
383: result = readlog[i].value;
384: }
385: }
386: }
387: return result;
388: }
389:
390: void put_long(CPTR addr, ULONG l)
391: {
392: mempattern ^= addr ^ l ^ 0x09090909;
393: longput(addr,l);
394: }
395:
396: void put_word(CPTR addr, UWORD w)
397: {
398: mempattern ^= addr ^ w ^ 0x0A0A0A0A;
399: wordput(addr,w);
400: }
401:
402: void put_byte(CPTR addr, UBYTE b)
403: {
404: mempattern ^= addr ^ b ^ 0x05050505;
405: byteput(addr,b);
406: }
407:
408: #endif
409:
410: void memory_init(void)
411: {
412: #ifdef DUALCPU
413: allowmem = true;
414: #endif
415: buserr = false;
416:
417: map_banks(chipmem_bank, 0, 256);
418:
419: map_banks(custom_bank, 0xC0, 0x20);
420:
421: if (use_slow_mem && bogomem_size > 0) {
422: map_banks(bogomem_bank, 0xC0, bogomem_size >> 16);
423: }
424: #if 0
425: if (fastmem_size > 0)
426: map_banks(expmem_config_bank, 0xE8, 1);
427: #endif
428: map_banks(kickmem_bank, 0xF8, 8);
429: map_banks(rtarea_bank, 0xF0, 1); rtarea_init ();
430: map_banks(cia_bank, 0xBF, 1);
431: map_banks(clock_bank, 0xDC, 1);
432:
433: if (!load_kickstart()) {
434: init_ersatz_rom(kickmemory);
435: }
436: }
437:
438: void map_banks(addrbank bank, int start, int size)
439: {
440: int bnr;
441: for(bnr=start; bnr < start+size; bnr++) {
442: do_lget[bnr] = bank.lget;
443: do_wget[bnr] = bank.wget;
444: do_bget[bnr] = bank.bget;
445: do_lput[bnr] = bank.lput;
446: do_wput[bnr] = bank.wput;
447: do_bput[bnr] = bank.bput;
448: do_xlateaddr[bnr] = bank.xlateaddr;
449: do_check[bnr] = bank.check;
450: }
451: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.