Develop and Download Open Source Software

Browse CVS Repository

Contents of /mame32jp/mame32jp/src/memory.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Tue May 7 00:17:30 2002 UTC (21 years, 11 months ago) by zero
Branch: MAIN
CVS Tags: ver_0_60_1, ver0_60_2, ver0_60_3, ver0_60_4, ver0_60_5, HEAD
Changes since 1.5: +28 -14 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /***************************************************************************
2
3 memory.c
4
5 Functions which handle the CPU memory and I/O port access.
6
7 Caveats:
8
9 * The install_mem/port_*_handler functions are only intended to be
10 called at driver init time. Do not call them after this time.
11
12 * If your driver executes an opcode which crosses a bank-switched
13 boundary, it will pull the wrong data out of memory. Although not
14 a common case, you may need to revert to memcpy to work around this.
15 See machine/tnzs.c for an example.
16
17 ***************************************************************************/
18
19 #include "driver.h"
20 #include "osd_cpu.h"
21 #include "state.h"
22
23 #include <stdarg.h>
24
25
26 //#define MEM_DUMP
27 //#define CHECK_MASKS
28
29
30
31 /***************************************************************************
32
33 Basic theory of memory handling:
34
35 An address with up to 32 bits is passed to a memory handler. First,
36 the non-significant bits are removed from the bottom; for example,
37 a 16-bit memory handler doesn't care about the low bit, so that is
38 removed.
39
40 Next, the address is broken into two halves, an upper half and a
41 lower half. The number of bits in each half varies based on the
42 total number of address bits. The upper half is then used as an
43 index into the base_lookup table.
44
45 If the value pulled from the table is within the range 192-255, then
46 the lower half of the address is needed to resolve the final handler.
47 The value from the table (192-255) is combined with the lower address
48 bits to form an index into a subtable.
49
50 Table values in the range 0-31 are reserved for internal handling
51 (such as RAM, ROM, NOP, and banking). Table values between 32 and 192
52 are assigned dynamically at startup.
53
54 ***************************************************************************/
55
56 /* macros for the profiler */
57 #define MEMREADSTART profiler_mark(PROFILER_MEMREAD);
58 #define MEMREADEND(ret) { profiler_mark(PROFILER_END); return ret; }
59 #define MEMWRITESTART profiler_mark(PROFILER_MEMWRITE);
60 #define MEMWRITEEND(ret) { (ret); profiler_mark(PROFILER_END); return; }
61
62 #define DATABITS_TO_SHIFT(d) (((d) == 32) ? 2 : ((d) == 16) ? 1 : 0)
63
64 /* helper macros */
65 #define HANDLER_IS_RAM(h) ((FPTR)(h) == STATIC_RAM)
66 #define HANDLER_IS_ROM(h) ((FPTR)(h) == STATIC_ROM)
67 #define HANDLER_IS_RAMROM(h) ((FPTR)(h) == STATIC_RAMROM)
68 #define HANDLER_IS_NOP(h) ((FPTR)(h) == STATIC_NOP)
69 #define HANDLER_IS_BANK(h) ((FPTR)(h) >= STATIC_BANK1 && (FPTR)(h) <= STATIC_BANKMAX)
70 #define HANDLER_IS_STATIC(h) ((FPTR)(h) < STATIC_COUNT)
71
72 #define HANDLER_TO_BANK(h) ((FPTR)(h))
73 #define BANK_TO_HANDLER(b) ((void *)(b))
74
75
76 /*-------------------------------------------------
77 TYPE DEFINITIONS
78 -------------------------------------------------*/
79
80 struct bank_data
81 {
82 UINT8 used; /* is this bank used? */
83 UINT8 cpunum; /* the CPU it is used for */
84 offs_t base; /* the base offset */
85 offs_t readoffset; /* original base offset for reads */
86 offs_t writeoffset; /* original base offset for writes */
87 };
88
89 struct handler_data
90 {
91 void * handler; /* function pointer for handler */
92 offs_t offset; /* base offset for handler */
93 };
94
95 struct table_data
96 {
97 UINT8 * table; /* pointer to base of table */
98 UINT8 subtable_count; /* number of subtables used */
99 UINT8 subtable_alloc; /* number of subtables allocated */
100 struct handler_data *handlers; /* pointer to which set of handlers */
101 };
102
103 struct memport_data
104 {
105 int cpunum; /* CPU index */
106 int abits; /* address bits */
107 int dbits; /* data bits */
108 int ebits; /* effective address bits */
109 offs_t mask; /* address mask */
110 struct table_data read; /* memory read lookup table */
111 struct table_data write; /* memory write lookup table */
112 };
113
114 struct cpu_data
115 {
116 void * rambase; /* RAM base pointer */
117 opbase_handler opbase; /* opcode base handler */
118
119 void * op_ram; /* dynamic ROM base pointer */
120 void * op_rom; /* dynamic RAM base pointer */
121 UINT8 opcode_entry; /* opcode base handler */
122
123 struct memport_data mem; /* memory tables */
124 struct memport_data port; /* port tables */
125 };
126
127 struct memory_address_table
128 {
129 int bits; /* address bits */
130 read8_handler handler; /* handler associated with that */
131 };
132
133
134
135 /*-------------------------------------------------
136 GLOBAL VARIABLES
137 -------------------------------------------------*/
138
139 static int cur_context; /* current CPU context */
140
141 UINT8 * OP_ROM; /* opcode ROM base */
142 UINT8 * OP_RAM; /* opcode RAM base */
143 UINT8 opcode_entry; /* opcode readmem entry */
144
145 UINT8 * readmem_lookup; /* memory read lookup table */
146 static UINT8 * writemem_lookup; /* memory write lookup table */
147 static UINT8 * readport_lookup; /* port read lookup table */
148 static UINT8 * writeport_lookup; /* port write lookup table */
149
150 offs_t mem_amask; /* memory address mask */
151 static offs_t port_amask; /* port address mask */
152
153 UINT8 * cpu_bankbase[STATIC_COUNT]; /* array of bank bases */
154 struct ExtMemory ext_memory[MAX_EXT_MEMORY]; /* externally-allocated memory */
155
156 static data32_t unmap_value; /* unmapped memory value */
157
158 static opbase_handler opbasefunc; /* opcode base override */
159
160 static struct handler_data rmemhandler8[ENTRY_COUNT]; /* 8-bit memory read handlers */
161 static struct handler_data rmemhandler16[ENTRY_COUNT]; /* 16-bit memory read handlers */
162 static struct handler_data rmemhandler32[ENTRY_COUNT]; /* 32-bit memory read handlers */
163 static struct handler_data wmemhandler8[ENTRY_COUNT]; /* 8-bit memory write handlers */
164 static struct handler_data wmemhandler16[ENTRY_COUNT]; /* 16-bit memory write handlers */
165 static struct handler_data wmemhandler32[ENTRY_COUNT]; /* 32-bit memory write handlers */
166
167 static struct handler_data rporthandler8[ENTRY_COUNT]; /* 8-bit port read handlers */
168 static struct handler_data rporthandler16[ENTRY_COUNT]; /* 16-bit port read handlers */
169 static struct handler_data rporthandler32[ENTRY_COUNT]; /* 32-bit port read handlers */
170 static struct handler_data wporthandler8[ENTRY_COUNT]; /* 8-bit port write handlers */
171 static struct handler_data wporthandler16[ENTRY_COUNT]; /* 16-bit port write handlers */
172 static struct handler_data wporthandler32[ENTRY_COUNT]; /* 32-bit port write handlers */
173
174 static read8_handler rmemhandler8s[STATIC_COUNT]; /* copy of 8-bit static read memory handlers */
175 static write8_handler wmemhandler8s[STATIC_COUNT]; /* copy of 8-bit static write memory handlers */
176
177 static struct cpu_data cpudata[MAX_CPU]; /* data gathered for each CPU */
178 static struct bank_data bankdata[MAX_BANKS]; /* data gathered for each bank */
179
180 offs_t encrypted_opcode_start[MAX_CPU],encrypted_opcode_end[MAX_CPU];
181
182
183 /*-------------------------------------------------
184 PROTOTYPES
185 -------------------------------------------------*/
186
187 static int CLIB_DECL fatalerror(const char *string, ...);
188 static UINT8 get_handler_index(struct handler_data *table, void *handler, offs_t start);
189 static UINT8 alloc_new_subtable(const struct memport_data *memport, struct table_data *tabledata, UINT8 previous_value);
190 static void populate_table(struct memport_data *memport, int iswrite, offs_t start, offs_t stop, UINT8 handler);
191 static void *assign_dynamic_bank(int cpunum, offs_t start);
192 static void install_mem_handler(struct memport_data *memport, int iswrite, offs_t start, offs_t end, void *handler);
193 static void install_port_handler(struct memport_data *memport, int iswrite, offs_t start, offs_t end, void *handler);
194 static void set_static_handler(int idx,
195 read8_handler r8handler, read16_handler r16handler, read32_handler r32handler,
196 write8_handler w8handler, write16_handler w16handler, write32_handler w32handler);
197 static int init_cpudata(void);
198 static int init_memport(int cpunum, struct memport_data *data, int abits, int dbits, int ismemory);
199 static int verify_memory(void);
200 static int verify_ports(void);
201 static int allocate_memory(void);
202 static int populate_memory(void);
203 static int populate_ports(void);
204 static void register_banks(void);
205 static int mem_address_bits_of_cpu(int cpunum);
206 static int port_address_bits_of_cpu(int cpunum);
207 static int init_static(void);
208
209 #ifdef MEM_DUMP
210 static void mem_dump(void);
211 #endif
212 #ifdef CHECK_MASKS
213 static void verify_masks(void);
214 #endif
215
216
217
218 /*-------------------------------------------------
219 memory_init - initialize the memory system
220 -------------------------------------------------*/
221
222 int memory_init(void)
223 {
224 #ifdef CHECK_MASKS
225 verify_masks();
226 #endif
227
228 /* no current context to start */
229 cur_context = -1;
230 unmap_value = 0;
231
232 /* init the static handlers */
233 if (!init_static())
234 return 0;
235
236 /* init the CPUs */
237 if (!init_cpudata())
238 return 0;
239
240 /* verify the memory handlers and check banks */
241 if (!verify_memory())
242 return 0;
243 if (!verify_ports())
244 return 0;
245
246 /* allocate memory for sparse address spaces */
247 if (!allocate_memory())
248 return 0;
249
250 /* then fill in the tables */
251 if (!populate_memory())
252 return 0;
253 if (!populate_ports())
254 return 0;
255
256 #ifdef MAME32JP
257 if (!Machine->gamedrv->rom == 0)
258 #endif
259 register_banks();
260
261 #ifdef MEM_DUMP
262 /* dump the final memory configuration */
263 mem_dump();
264 #endif
265
266 return 1;
267 }
268
269
270 /*-------------------------------------------------
271 memory_shutdown - free memory
272 -------------------------------------------------*/
273
274 void memory_shutdown(void)
275 {
276 struct ExtMemory *ext;
277 int cpunum;
278
279 /* free all the tables */
280 for (cpunum = 0; cpunum < MAX_CPU; cpunum++ )
281 {
282 if (cpudata[cpunum].mem.read.table)
283 free(cpudata[cpunum].mem.read.table);
284 if (cpudata[cpunum].mem.write.table)
285 free(cpudata[cpunum].mem.write.table);
286 if (cpudata[cpunum].port.read.table)
287 free(cpudata[cpunum].port.read.table);
288 if (cpudata[cpunum].port.write.table)
289 free(cpudata[cpunum].port.write.table);
290 }
291 memset(&cpudata, 0, sizeof(cpudata));
292
293 /* free all the external memory */
294 for (ext = ext_memory; ext->data; ext++)
295 free(ext->data);
296 memset(ext_memory, 0, sizeof(ext_memory));
297 }
298
299
300 /*-------------------------------------------------
301 memory_set_opcode_base - set the base of
302 ROM
303 -------------------------------------------------*/
304
305 void memory_set_opcode_base(int cpunum, void *base)
306 {
307 if (cur_context == cpunum)
308 OP_ROM = base;
309 else
310 cpudata[cpunum].op_rom = base;
311 }
312
313
314 void memory_set_encrypted_opcode_range(int cpunum,offs_t min_address,offs_t max_address)
315 {
316 encrypted_opcode_start[cpunum] = min_address;
317 encrypted_opcode_end[cpunum] = max_address;
318 }
319
320
321 /*-------------------------------------------------
322 memory_set_context - set the memory context
323 -------------------------------------------------*/
324
325 void memory_set_context(int activecpu)
326 {
327 /* remember dynamic RAM/ROM */
328 if (cur_context != -1)
329 {
330 cpudata[cur_context].op_ram = OP_RAM;
331 cpudata[cur_context].op_rom = OP_ROM;
332 cpudata[cur_context].opcode_entry = opcode_entry;
333 }
334 cur_context = activecpu;
335
336 cpu_bankbase[STATIC_RAM] = cpudata[activecpu].rambase;
337 OP_RAM = cpudata[activecpu].op_ram;
338 OP_ROM = cpudata[activecpu].op_rom;
339 opcode_entry = opcode_entry;
340
341 readmem_lookup = cpudata[activecpu].mem.read.table;
342 writemem_lookup = cpudata[activecpu].mem.write.table;
343 readport_lookup = cpudata[activecpu].port.read.table;
344 writeport_lookup = cpudata[activecpu].port.write.table;
345
346 mem_amask = cpudata[activecpu].mem.mask;
347 port_amask = cpudata[activecpu].port.mask;
348
349 opbasefunc = cpudata[activecpu].opbase;
350 }
351
352
353 /*-------------------------------------------------
354 memory_set_unmap_value - set the unmapped
355 memory value
356 -------------------------------------------------*/
357
358 void memory_set_unmap_value(data32_t value)
359 {
360 unmap_value = value;
361 }
362
363
364 /*-------------------------------------------------
365 memory_set_bankhandler_r - set readmemory
366 handler for bank memory (8-bit only!)
367 -------------------------------------------------*/
368
369 void memory_set_bankhandler_r(int bank, offs_t offset, mem_read_handler handler)
370 {
371 /* determine the new offset */
372 if (HANDLER_IS_RAM(handler) || HANDLER_IS_ROM(handler))
373 rmemhandler8[bank].offset = 0 - offset, handler = (mem_read_handler)STATIC_RAM;
374 else if (HANDLER_IS_BANK(handler))
375 rmemhandler8[bank].offset = bankdata[HANDLER_TO_BANK(handler)].readoffset - offset;
376 else
377 rmemhandler8[bank].offset = bankdata[bank].readoffset - offset;
378
379 /* set the new handler */
380 if (HANDLER_IS_STATIC(handler))
381 handler = rmemhandler8s[(FPTR)handler];
382 rmemhandler8[bank].handler = (void *)handler;
383 }
384
385
386 /*-------------------------------------------------
387 memory_set_bankhandler_w - set writememory
388 handler for bank memory (8-bit only!)
389 -------------------------------------------------*/
390
391 void memory_set_bankhandler_w(int bank, offs_t offset, mem_write_handler handler)
392 {
393 /* determine the new offset */
394 if (HANDLER_IS_RAM(handler) || HANDLER_IS_ROM(handler) || HANDLER_IS_RAMROM(handler))
395 wmemhandler8[bank].offset = 0 - offset;
396 else if (HANDLER_IS_BANK(handler))
397 wmemhandler8[bank].offset = bankdata[HANDLER_TO_BANK(handler)].writeoffset - offset;
398 else
399 wmemhandler8[bank].offset = bankdata[bank].writeoffset - offset;
400
401 /* set the new handler */
402 if (HANDLER_IS_STATIC(handler))
403 handler = wmemhandler8s[(FPTR)handler];
404 wmemhandler8[bank].handler = (void *)handler;
405 }
406
407
408 /*-------------------------------------------------
409 memory_set_opbase_handler - change op-code
410 memory base
411 -------------------------------------------------*/
412
413 opbase_handler memory_set_opbase_handler(int cpunum, opbase_handler function)
414 {
415 opbase_handler old = cpudata[cpunum].opbase;
416 cpudata[cpunum].opbase = function;
417 if (cpunum == cpu_getactivecpu())
418 opbasefunc = function;
419 return old;
420 }
421
422
423 /*-------------------------------------------------
424 install_mem_read_handler - install dynamic
425 read handler for 8-bit case
426 -------------------------------------------------*/
427
428 data8_t *install_mem_read_handler(int cpunum, offs_t start, offs_t end, mem_read_handler handler)
429 {
430 /* sanity check */
431 if (cpudata[cpunum].mem.dbits != 8)
432 {
433 printf("fatal: install_mem_read_handler called on %d-bit cpu\n",cpudata[cpunum].mem.dbits);
434 exit(1);
435 }
436
437 /* install the handler */
438 install_mem_handler(&cpudata[cpunum].mem, 0, start, end, (void *)handler);
439 #ifdef MEM_DUMP
440 /* dump the new memory configuration */
441 mem_dump();
442 #endif
443 return memory_find_base(cpunum, start);
444 }
445
446
447 /*-------------------------------------------------
448 install_mem_read16_handler - install dynamic
449 read handler for 16-bit case
450 -------------------------------------------------*/
451
452 data16_t *install_mem_read16_handler(int cpunum, offs_t start, offs_t end, mem_read16_handler handler)
453 {
454 /* sanity check */
455 if (cpudata[cpunum].mem.dbits != 16)
456 {
457 printf("fatal: install_mem_read16_handler called on %d-bit cpu\n",cpudata[cpunum].mem.dbits);
458 exit(1);
459 }
460
461 /* install the handler */
462 install_mem_handler(&cpudata[cpunum].mem, 0, start, end, (void *)handler);
463 #ifdef MEM_DUMP
464 /* dump the new memory configuration */
465 mem_dump();
466 #endif
467 return memory_find_base(cpunum, start);
468 }
469
470
471 /*-------------------------------------------------
472 install_mem_read32_handler - install dynamic
473 read handler for 32-bit case
474 -------------------------------------------------*/
475
476 data32_t *install_mem_read32_handler(int cpunum, offs_t start, offs_t end, mem_read32_handler handler)
477 {
478 /* sanity check */
479 if (cpudata[cpunum].mem.dbits != 32)
480 {
481 printf("fatal: install_mem_read32_handler called on %d-bit cpu\n",cpudata[cpunum].mem.dbits);
482 exit(1);
483 }
484
485 /* install the handler */
486 install_mem_handler(&cpudata[cpunum].mem, 0, start, end, (void *)handler);
487 #ifdef MEM_DUMP
488 /* dump the new memory configuration */
489 mem_dump();
490 #endif
491 return memory_find_base(cpunum, start);
492 }
493
494
495 /*-------------------------------------------------
496 install_mem_write_handler - install dynamic
497 read handler for 8-bit case
498 -------------------------------------------------*/
499
500 data8_t *install_mem_write_handler(int cpunum, offs_t start, offs_t end, mem_write_handler handler)
501 {
502 /* sanity check */
503 if (cpudata[cpunum].mem.dbits != 8)
504 {
505 printf("fatal: install_mem_write_handler called on %d-bit cpu\n",cpudata[cpunum].mem.dbits);
506 exit(1);
507 }
508
509 /* install the handler */
510 install_mem_handler(&cpudata[cpunum].mem, 1, start, end, (void *)handler);
511 #ifdef MEM_DUMP
512 /* dump the new memory configuration */
513 mem_dump();
514 #endif
515 return memory_find_base(cpunum, start);
516 }
517
518
519 /*-------------------------------------------------
520 install_mem_write16_handler - install dynamic
521 read handler for 16-bit case
522 -------------------------------------------------*/
523
524 data16_t *install_mem_write16_handler(int cpunum, offs_t start, offs_t end, mem_write16_handler handler)
525 {
526 /* sanity check */
527 if (cpudata[cpunum].mem.dbits != 16)
528 {
529 printf("fatal: install_mem_write16_handler called on %d-bit cpu\n",cpudata[cpunum].mem.dbits);
530 exit(1);
531 }
532
533 /* install the handler */
534 install_mem_handler(&cpudata[cpunum].mem, 1, start, end, (void *)handler);
535 #ifdef MEM_DUMP
536 /* dump the new memory configuration */
537 mem_dump();
538 #endif
539 return memory_find_base(cpunum, start);
540 }
541
542
543 /*-------------------------------------------------
544 install_mem_write32_handler - install dynamic
545 read handler for 32-bit case
546 -------------------------------------------------*/
547
548 data32_t *install_mem_write32_handler(int cpunum, offs_t start, offs_t end, mem_write32_handler handler)
549 {
550 /* sanity check */
551 if (cpudata[cpunum].mem.dbits != 32)
552 {
553 printf("fatal: install_mem_write32_handler called on %d-bit cpu\n",cpudata[cpunum].mem.dbits);
554 exit(1);
555 }
556
557 /* install the handler */
558 install_mem_handler(&cpudata[cpunum].mem, 1, start, end, (void *)handler);
559 #ifdef MEM_DUMP
560 /* dump the new memory configuration */
561 mem_dump();
562 #endif
563 return memory_find_base(cpunum, start);
564 }
565
566
567 /*-------------------------------------------------
568 install_port_read_handler - install dynamic
569 read handler for 8-bit case
570 -------------------------------------------------*/
571
572 void install_port_read_handler(int cpunum, offs_t start, offs_t end, port_read_handler handler)
573 {
574 /* sanity check */
575 if (cpudata[cpunum].port.dbits != 8)
576 {
577 printf("fatal: install_port_read_handler called on %d-bit cpu\n",cpudata[cpunum].port.dbits);
578 exit(1);
579 }
580
581 /* install the handler */
582 install_port_handler(&cpudata[cpunum].port, 0, start, end, (void *)handler);
583 #ifdef MEM_DUMP
584 /* dump the new memory configuration */
585 mem_dump();
586 #endif
587 }
588
589
590 /*-------------------------------------------------
591 install_port_read16_handler - install dynamic
592 read handler for 16-bit case
593 -------------------------------------------------*/
594
595 void install_port_read16_handler(int cpunum, offs_t start, offs_t end, port_read16_handler handler)
596 {
597 /* sanity check */
598 if (cpudata[cpunum].port.dbits != 16)
599 {
600 printf("fatal: install_port_read16_handler called on %d-bit cpu\n",cpudata[cpunum].port.dbits);
601 exit(1);
602 }
603
604 /* install the handler */
605 install_port_handler(&cpudata[cpunum].port, 0, start, end, (void *)handler);
606 #ifdef MEM_DUMP
607 /* dump the new memory configuration */
608 mem_dump();
609 #endif
610 }
611
612
613 /*-------------------------------------------------
614 install_port_read32_handler - install dynamic
615 read handler for 32-bit case
616 -------------------------------------------------*/
617
618 void install_port_read32_handler(int cpunum, offs_t start, offs_t end, port_read32_handler handler)
619 {
620 /* sanity check */
621 if (cpudata[cpunum].port.dbits != 32)
622 {
623 printf("fatal: install_port_read32_handler called on %d-bit cpu\n",cpudata[cpunum].port.dbits);
624 exit(1);
625 }
626
627 /* install the handler */
628 install_port_handler(&cpudata[cpunum].port, 0, start, end, (void *)handler);
629 #ifdef MEM_DUMP
630 /* dump the new memory configuration */
631 mem_dump();
632 #endif
633 }
634
635
636 /*-------------------------------------------------
637 install_port_write_handler - install dynamic
638 read handler for 8-bit case
639 -------------------------------------------------*/
640
641 void install_port_write_handler(int cpunum, offs_t start, offs_t end, port_write_handler handler)
642 {
643 /* sanity check */
644 if (cpudata[cpunum].port.dbits != 8)
645 {
646 printf("fatal: install_port_write_handler called on %d-bit cpu\n",cpudata[cpunum].port.dbits);
647 exit(1);
648 }
649
650 /* install the handler */
651 install_port_handler(&cpudata[cpunum].port, 1, start, end, (void *)handler);
652 #ifdef MEM_DUMP
653 /* dump the new memory configuration */
654 mem_dump();
655 #endif
656 }
657
658
659 /*-------------------------------------------------
660 install_port_write16_handler - install dynamic
661 read handler for 16-bit case
662 -------------------------------------------------*/
663
664 void install_port_write16_handler(int cpunum, offs_t start, offs_t end, port_write16_handler handler)
665 {
666 /* sanity check */
667 if (cpudata[cpunum].port.dbits != 16)
668 {
669 printf("fatal: install_port_write16_handler called on %d-bit cpu\n",cpudata[cpunum].port.dbits);
670 exit(1);
671 }
672
673 /* install the handler */
674 install_port_handler(&cpudata[cpunum].port, 1, start, end, (void *)handler);
675 #ifdef MEM_DUMP
676 /* dump the new memory configuration */
677 mem_dump();
678 #endif
679 }
680
681
682 /*-------------------------------------------------
683 install_port_write32_handler - install dynamic
684 read handler for 32-bit case
685 -------------------------------------------------*/
686
687 void install_port_write32_handler(int cpunum, offs_t start, offs_t end, port_write32_handler handler)
688 {
689 /* sanity check */
690 if (cpudata[cpunum].port.dbits != 32)
691 {
692 printf("fatal: install_port_write32_handler called on %d-bit cpu\n",cpudata[cpunum].port.dbits);
693 exit(1);
694 }
695
696 /* install the handler */
697 install_port_handler(&cpudata[cpunum].port, 1, start, end, (void *)handler);
698 #ifdef MEM_DUMP
699 /* dump the new memory configuration */
700 mem_dump();
701 #endif
702 }
703
704
705 /*-------------------------------------------------
706 fatalerror - display an error message and
707 exit immediately
708 -------------------------------------------------*/
709
710 int CLIB_DECL fatalerror(const char *string, ...)
711 {
712 va_list arg;
713 va_start(arg, string);
714 vprintf(string, arg);
715 va_end(arg);
716 return 0;
717 }
718
719
720 /*-------------------------------------------------
721 memory_find_base - return a pointer to the
722 base of RAM associated with the given CPU
723 and offset
724 -------------------------------------------------*/
725
726 void *memory_find_base(int cpunum, offs_t offset)
727 {
728 int region = REGION_CPU1 + cpunum;
729 struct ExtMemory *ext;
730
731 /* look in external memory first */
732 for (ext = ext_memory; ext->data; ext++)
733 if (ext->region == region && ext->start <= offset && ext->end >= offset)
734 return (void *)((UINT8 *)ext->data + (offset - ext->start));
735
736 return (UINT8 *)cpudata[cpunum].rambase + offset;
737 }
738
739
740 /*-------------------------------------------------
741 get_handler_index - finds the index of a
742 handler, or allocates a new one as necessary
743 -------------------------------------------------*/
744
745 UINT8 get_handler_index(struct handler_data *table, void *handler, offs_t start)
746 {
747 int i;
748
749 /* all static handlers are hardcoded */
750 if (HANDLER_IS_STATIC(handler))
751 return (FPTR)handler;
752
753 /* otherwise, we have to search */
754 for (i = STATIC_COUNT; i < SUBTABLE_BASE; i++)
755 {
756 if (table[i].handler == NULL)
757 {
758 table[i].handler = handler;
759 table[i].offset = start;
760 }
761 if (table[i].handler == handler && table[i].offset == start)
762 return i;
763 }
764 return 0;
765 }
766
767
768 /*-------------------------------------------------
769 alloc_new_subtable - allocates more space
770 for a new subtable
771 -------------------------------------------------*/
772
773 UINT8 alloc_new_subtable(const struct memport_data *memport, struct table_data *tabledata, UINT8 previous_value)
774 {
775 int l1bits = LEVEL1_BITS(memport->ebits);
776 int l2bits = LEVEL2_BITS(memport->ebits);
777
778 /* make sure we don't run out */
779 if (tabledata->subtable_count + 1 == SUBTABLE_COUNT)
780 fatalerror("error: ran out of memory subtables\n");
781
782 /* allocate more memory if we need to */
783 if (tabledata->subtable_count <= tabledata->subtable_alloc)
784 {
785 tabledata->subtable_alloc += SUBTABLE_ALLOC;
786 tabledata->table = realloc(tabledata->table, (1 << l1bits) + (tabledata->subtable_alloc << l2bits));
787 if (!tabledata->table)
788 fatalerror("error: ran out of memory allocating memory subtable\n");
789 }
790
791 /* initialize the table entries */
792 memset(&tabledata->table[(1 << l1bits) + (tabledata->subtable_count << l2bits)], previous_value, 1 << l2bits);
793
794 /* return the new index */
795 return SUBTABLE_BASE + tabledata->subtable_count++;
796 }
797
798
799 /*-------------------------------------------------
800 populate_table - assign a memory handler to
801 a range of addresses
802 -------------------------------------------------*/
803
804 void populate_table(struct memport_data *memport, int iswrite, offs_t start, offs_t stop, UINT8 handler)
805 {
806 struct table_data *tabledata = iswrite ? &memport->write : &memport->read;
807 int minbits = DATABITS_TO_SHIFT(memport->dbits);
808 int l1bits = LEVEL1_BITS(memport->ebits);
809 int l2bits = LEVEL2_BITS(memport->ebits);
810 offs_t l2mask = LEVEL2_MASK(memport->ebits);
811 offs_t l1start = start >> (l2bits + minbits);
812 offs_t l2start = (start >> minbits) & l2mask;
813 offs_t l1stop = stop >> (l2bits + minbits);
814 offs_t l2stop = (stop >> minbits) & l2mask;
815 UINT8 subindex;
816
817 /* sanity check */
818 if (start > stop)
819 return;
820
821 /* set the base for non RAM/ROM cases */
822 if (handler != STATIC_RAM && handler != STATIC_ROM && handler != STATIC_RAMROM)
823 tabledata->handlers[handler].offset = start;
824
825 /* remember the base for banks */
826 if (handler >= STATIC_BANK1 && handler <= STATIC_BANKMAX)
827 {
828 if (iswrite)
829 bankdata[handler].writeoffset = start;
830 else
831 bankdata[handler].readoffset = start;
832 }
833
834 /* handle the starting edge if it's not on a block boundary */
835 if (l2start != 0)
836 {
837 /* get the subtable index */
838 subindex = tabledata->table[l1start];
839 if (subindex < SUBTABLE_BASE)
840 subindex = tabledata->table[l1start] = alloc_new_subtable(memport, tabledata, subindex);
841 subindex &= SUBTABLE_MASK;
842
843 /* if the start and stop end within the same block, handle that */
844 if (l1start == l1stop)
845 {
846 memset(&tabledata->table[(1 << l1bits) + (subindex << l2bits) + l2start], handler, l2stop - l2start + 1);
847 return;
848 }
849
850 /* otherwise, fill until the end */
851 memset(&tabledata->table[(1 << l1bits) + (subindex << l2bits) + l2start], handler, (1 << l2bits) - l2start);
852 if (l1start != (offs_t)~0) l1start++;
853 }
854
855 /* handle the trailing edge if it's not on a block boundary */
856 if (l2stop != l2mask)
857 {
858 /* get the subtable index */
859 subindex = tabledata->table[l1stop];
860 if (subindex < SUBTABLE_BASE)
861 subindex = tabledata->table[l1stop] = alloc_new_subtable(memport, tabledata, subindex);
862 subindex &= SUBTABLE_MASK;
863
864 /* fill from the beginning */
865 memset(&tabledata->table[(1 << l1bits) + (subindex << l2bits)], handler, l2stop + 1);
866
867 /* if the start and stop end within the same block, handle that */
868 if (l1start == l1stop)
869 return;
870 if (l1stop != 0) l1stop--;
871 }
872
873 /* now fill in the middle tables */
874 if (l1start <= l1stop)
875 memset(&tabledata->table[l1start], handler, l1stop - l1start + 1);
876 }
877
878
879 /*-------------------------------------------------
880 assign_dynamic_bank - finds a free or exact
881 matching bank
882 -------------------------------------------------*/
883
884 void *assign_dynamic_bank(int cpunum, offs_t start)
885 {
886 int bank;
887
888 /* special case: never assign a dynamic bank to an offset that */
889 /* intersects the CPU's region; always use RAM for that */
890 if (start < memory_region_length(REGION_CPU1 + cpunum))
891 return (void *)STATIC_RAM;
892
893 /* loop over banks, searching for an exact match or an empty */
894 for (bank = 1; bank <= MAX_BANKS; bank++)
895 if (!bankdata[bank].used || (bankdata[bank].cpunum == cpunum && bankdata[bank].base == start))
896 {
897 bankdata[bank].used = 1;
898 bankdata[bank].cpunum = cpunum;
899 bankdata[bank].base = start;
900 return BANK_TO_HANDLER(bank);
901 }
902
903 /* if we got here, we failed */
904 fatalerror("cpu #%d: ran out of banks for sparse memory regions!\n", cpunum);
905 return NULL;
906 }
907
908
909 /*-------------------------------------------------
910 install_mem_handler - installs a handler for
911 memory operatinos
912 -------------------------------------------------*/
913
914 void install_mem_handler(struct memport_data *memport, int iswrite, offs_t start, offs_t end, void *handler)
915 {
916 struct table_data *tabledata = iswrite ? &memport->write : &memport->read;
917 UINT8 idx;
918
919 /* translate ROM and RAMROM to RAM here for read cases */
920 if (!iswrite)
921 if (HANDLER_IS_ROM(handler) || HANDLER_IS_RAMROM(handler))
922 handler = (void *)MRA_RAM;
923
924 /* assign banks for sparse memory spaces */
925 if (IS_SPARSE(memport->abits) && HANDLER_IS_RAM(handler))
926 handler = (void *)assign_dynamic_bank(memport->cpunum, start);
927
928 /* set the handler */
929 idx = get_handler_index(tabledata->handlers, handler, start);
930 populate_table(memport, iswrite, start, end, idx);
931
932 /* if this is a bank, set the bankbase as well */
933 if (HANDLER_IS_BANK(handler))
934 cpu_bankbase[HANDLER_TO_BANK(handler)] = memory_find_base(memport->cpunum, start);
935 }
936
937
938 /*-------------------------------------------------
939 install_port_handler - installs a handler for
940 port operatinos
941 -------------------------------------------------*/
942
943 void install_port_handler(struct memport_data *memport, int iswrite, offs_t start, offs_t end, void *handler)
944 {
945 struct table_data *tabledata = iswrite ? &memport->write : &memport->read;
946 UINT8 idx = get_handler_index(tabledata->handlers, handler, start);
947 populate_table(memport, iswrite, start, end, idx);
948 }
949
950
951 /*-------------------------------------------------
952 set_static_handler - handy shortcut for
953 setting all 6 handlers for a given index
954 -------------------------------------------------*/
955
956 static void set_static_handler(int idx,
957 read8_handler r8handler, read16_handler r16handler, read32_handler r32handler,
958 write8_handler w8handler, write16_handler w16handler, write32_handler w32handler)
959 {
960 rmemhandler8s[idx] = r8handler;
961 wmemhandler8s[idx] = w8handler;
962
963 rmemhandler8[idx].handler = (void *)r8handler;
964 rmemhandler16[idx].handler = (void *)r16handler;
965 rmemhandler32[idx].handler = (void *)r32handler;
966 wmemhandler8[idx].handler = (void *)w8handler;
967 wmemhandler16[idx].handler = (void *)w16handler;
968 wmemhandler32[idx].handler = (void *)w32handler;
969
970 rporthandler8[idx].handler = (void *)r8handler;
971 rporthandler16[idx].handler = (void *)r16handler;
972 rporthandler32[idx].handler = (void *)r32handler;
973 wporthandler8[idx].handler = (void *)w8handler;
974 wporthandler16[idx].handler = (void *)w16handler;
975 wporthandler32[idx].handler = (void *)w32handler;
976 }
977
978
979 /*-------------------------------------------------
980 init_cpudata - initialize the cpudata
981 structure for each CPU
982 -------------------------------------------------*/
983
984 static int init_cpudata(void)
985 {
986 int cpunum;
987
988 /* zap the cpudata structure */
989 memset(&cpudata, 0, sizeof(cpudata));
990
991 /* loop over CPUs */
992 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
993 {
994 int cputype = Machine->drv->cpu[cpunum].cpu_type & ~CPU_FLAGS_MASK;
995
996 /* set the RAM/ROM base */
997 cpudata[cpunum].rambase = cpudata[cpunum].op_ram = cpudata[cpunum].op_rom = memory_region(REGION_CPU1 + cpunum);
998 cpudata[cpunum].opcode_entry = STATIC_ROM;
999 cpudata[cpunum].opbase = NULL;
1000 encrypted_opcode_start[cpunum] = 0;
1001 encrypted_opcode_end[cpunum] = 0;
1002
1003 /* initialize the readmem and writemem tables */
1004 if (!init_memport(cpunum, &cpudata[cpunum].mem, mem_address_bits_of_cpu(cputype), cpunum_databus_width(cpunum), 1))
1005 return 0;
1006
1007 /* initialize the readport and writeport tables */
1008 if (!init_memport(cpunum, &cpudata[cpunum].port, port_address_bits_of_cpu(cputype), cpunum_databus_width(cpunum), 0))
1009 return 0;
1010
1011 #if HAS_Z80
1012 /* Z80 port mask kludge */
1013 if (cputype == CPU_Z80)
1014 if (!(Machine->drv->cpu[cpunum].cpu_type & CPU_16BIT_PORT))
1015 cpudata[cpunum].port.mask = 0xff;
1016 #endif
1017 #ifdef MESS
1018 #if HAS_Z80_MSX
1019 /* Z80_MSX port mask kludge */
1020 if (cputype == CPU_Z80_MSX)
1021 if (!(Machine->drv->cpu[cpunum].cpu_type & CPU_16BIT_PORT))
1022 cpudata[cpunum].port.mask = 0xff;
1023 #endif
1024 #endif
1025 #if HAS_Z180
1026 /* Z180 port mask kludge */
1027 if (cputype == CPU_Z180)
1028 if (!(Machine->drv->cpu[cpunum].cpu_type & CPU_16BIT_PORT))
1029 cpudata[cpunum].port.mask = 0xff;
1030 #endif
1031 }
1032 return 1;
1033 }
1034
1035
1036 /*-------------------------------------------------
1037 init_memport - initialize the mem/port data
1038 structure
1039 -------------------------------------------------*/
1040
1041 static int init_memport(int cpunum, struct memport_data *data, int abits, int dbits, int ismemory)
1042 {
1043 /* determine the address and data bits */
1044 data->cpunum = cpunum;
1045 data->abits = abits;
1046 data->dbits = dbits;
1047 data->ebits = abits - DATABITS_TO_SHIFT(dbits);
1048 data->mask = 0xffffffffUL >> (32 - abits);
1049
1050 /* allocate memory */
1051 data->read.table = malloc(1 << LEVEL1_BITS(data->ebits));
1052 data->write.table = malloc(1 << LEVEL1_BITS(data->ebits));
1053 if (!data->read.table)
1054 return fatalerror("cpu #%d couldn't allocate read table\n", cpunum);
1055 if (!data->write.table)
1056 return fatalerror("cpu #%d couldn't allocate write table\n", cpunum);
1057
1058 /* initialize everything to unmapped */
1059 memset(data->read.table, STATIC_UNMAP, 1 << LEVEL1_BITS(data->ebits));
1060 memset(data->write.table, STATIC_UNMAP, 1 << LEVEL1_BITS(data->ebits));
1061
1062 /* initialize the pointers to the handlers */
1063 if (ismemory)
1064 {
1065 data->read.handlers = (dbits == 32) ? rmemhandler32 : (dbits == 16) ? rmemhandler16 : rmemhandler8;
1066 data->write.handlers = (dbits == 32) ? wmemhandler32 : (dbits == 16) ? wmemhandler16 : wmemhandler8;
1067 }
1068 else
1069 {
1070 data->read.handlers = (dbits == 32) ? rporthandler32 : (dbits == 16) ? rporthandler16 : rporthandler8;
1071 data->write.handlers = (dbits == 32) ? wporthandler32 : (dbits == 16) ? wporthandler16 : wporthandler8;
1072 }
1073 return 1;
1074 }
1075
1076
1077 /*-------------------------------------------------
1078 verify_memory - verify the memory structs
1079 and track which banks are referenced
1080 -------------------------------------------------*/
1081
1082 static int verify_memory(void)
1083 {
1084 int cpunum;
1085
1086 /* zap the bank data */
1087 memset(&bankdata, 0, sizeof(bankdata));
1088
1089 /* loop over CPUs */
1090 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
1091 {
1092 const struct Memory_ReadAddress *mra = Machine->drv->cpu[cpunum].memory_read;
1093 const struct Memory_WriteAddress *mwa = Machine->drv->cpu[cpunum].memory_write;
1094 UINT32 width;
1095 int bank;
1096
1097 /* determine the desired width */
1098 switch (cpunum_databus_width(cpunum))
1099 {
1100 case 8: width = MEMPORT_WIDTH_8; break;
1101 case 16: width = MEMPORT_WIDTH_16; break;
1102 case 32: width = MEMPORT_WIDTH_32; break;
1103 default: return fatalerror("cpu #%d has invalid memory width!\n", cpunum);
1104 }
1105
1106 /* verify the read handlers */
1107 if (mra)
1108 {
1109 /* verify the MEMPORT_READ_START header */
1110 if (mra->start == MEMPORT_MARKER && mra->end != 0)
1111 {
1112 if ((mra->end & MEMPORT_TYPE_MASK) != MEMPORT_TYPE_MEM)
1113 return fatalerror("cpu #%d has port handlers in place of memory read handlers!\n", cpunum);
1114 if ((mra->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_READ)
1115 return fatalerror("cpu #%d has memory write handlers in place of memory read handlers!\n", cpunum);
1116 if ((mra->end & MEMPORT_WIDTH_MASK) != width)
1117 return fatalerror("cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n", cpunum,cpunum_databus_width(cpunum),mra->end);
1118 mra++;
1119 }
1120
1121 /* track banks used */
1122 for ( ; !IS_MEMPORT_END(mra); mra++)
1123 if (!IS_MEMPORT_MARKER(mra) && HANDLER_IS_BANK(mra->handler))
1124 {
1125 bank = HANDLER_TO_BANK(mra->handler);
1126 bankdata[bank].used = 1;
1127 bankdata[bank].cpunum = -1;
1128 }
1129 }
1130
1131 /* verify the write handlers */
1132 if (mwa)
1133 {
1134 /* verify the MEMPORT_WRITE_START header */
1135 if (mwa->start == MEMPORT_MARKER && mwa->end != 0)
1136 {
1137 if ((mwa->end & MEMPORT_TYPE_MASK) != MEMPORT_TYPE_MEM)
1138 return fatalerror("cpu #%d has port handlers in place of memory write handlers!\n", cpunum);
1139 if ((mwa->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_WRITE)
1140 return fatalerror("cpu #%d has memory read handlers in place of memory write handlers!\n", cpunum);
1141 if ((mwa->end & MEMPORT_WIDTH_MASK) != width)
1142 return fatalerror("cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n", cpunum,cpunum_databus_width(cpunum),mwa->end);
1143 mwa++;
1144 }
1145
1146 /* track banks used */
1147 for (; !IS_MEMPORT_END(mwa); mwa++)
1148 if (!IS_MEMPORT_MARKER(mwa) && HANDLER_IS_BANK(mwa->handler))
1149 {
1150 bank = HANDLER_TO_BANK(mwa->handler);
1151 bankdata[bank].used = 1;
1152 bankdata[bank].cpunum = -1;
1153 }
1154 mwa++;
1155 }
1156 }
1157 return 1;
1158 }
1159
1160
1161 /*-------------------------------------------------
1162 verify_ports - verify the port structs
1163 -------------------------------------------------*/
1164
1165 static int verify_ports(void)
1166 {
1167 int cpunum;
1168
1169 /* loop over CPUs */
1170 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
1171 {
1172 const struct IO_ReadPort *mra = Machine->drv->cpu[cpunum].port_read;
1173 const struct IO_WritePort *mwa = Machine->drv->cpu[cpunum].port_write;
1174 UINT32 width;
1175
1176 /* determine the desired width */
1177 switch (cpunum_databus_width(cpunum))
1178 {
1179 case 8: width = MEMPORT_WIDTH_8; break;
1180 case 16: width = MEMPORT_WIDTH_16; break;
1181 case 32: width = MEMPORT_WIDTH_32; break;
1182 default: return fatalerror("cpu #%d has invalid memory width!\n", cpunum);
1183 }
1184
1185 /* verify the read handlers */
1186 if (mra)
1187 {
1188 /* verify the PORT_READ_START header */
1189 if (mra->start == MEMPORT_MARKER && mra->end != 0)
1190 {
1191 if ((mra->end & MEMPORT_TYPE_MASK) != MEMPORT_TYPE_IO)
1192 return fatalerror("cpu #%d has memory handlers in place of I/O read handlers!\n", cpunum);
1193 if ((mra->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_READ)
1194 return fatalerror("cpu #%d has port write handlers in place of port read handlers!\n", cpunum);
1195 if ((mra->end & MEMPORT_WIDTH_MASK) != width)
1196 return fatalerror("cpu #%d uses wrong data width port handlers! (width = %d, memory = %08x)\n", cpunum,cpunum_databus_width(cpunum),mra->end);
1197 }
1198 }
1199
1200 /* verify the write handlers */
1201 if (mwa)
1202 {
1203 /* verify the PORT_WRITE_START header */
1204 if (mwa->start == MEMPORT_MARKER && mwa->end != 0)
1205 {
1206 if ((mwa->end & MEMPORT_TYPE_MASK) != MEMPORT_TYPE_IO)
1207 return fatalerror("cpu #%d has memory handlers in place of I/O write handlers!\n", cpunum);
1208 if ((mwa->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_WRITE)
1209 return fatalerror("cpu #%d has port read handlers in place of port write handlers!\n", cpunum);
1210 if ((mwa->end & MEMPORT_WIDTH_MASK) != width)
1211 return fatalerror("cpu #%d uses wrong data width port handlers! (width = %d, memory = %08x)\n", cpunum,cpunum_databus_width(cpunum),mwa->end);
1212 }
1213 }
1214 }
1215 return 1;
1216 }
1217
1218
1219 /*-------------------------------------------------
1220 needs_ram - returns true if a given type
1221 of memory needs RAM backing it
1222 -------------------------------------------------*/
1223
1224 static int needs_ram(int cpunum, void *handler)
1225 {
1226 /* RAM, ROM, and banks always need RAM */
1227 if (HANDLER_IS_RAM(handler) || HANDLER_IS_ROM(handler) || HANDLER_IS_RAMROM(handler) || HANDLER_IS_BANK(handler))
1228 return 1;
1229
1230 /* NOPs never need RAM */
1231 else if (HANDLER_IS_NOP(handler))
1232 return 0;
1233
1234 /* otherwise, we only need RAM for sparse memory spaces */
1235 else
1236 return IS_SPARSE(cpudata[cpunum].mem.abits);
1237 }
1238
1239
1240 /*-------------------------------------------------
1241 allocate_memory - allocate memory for
1242 sparse CPU address spaces
1243 -------------------------------------------------*/
1244
1245 static int allocate_memory(void)
1246 {
1247 struct ExtMemory *ext = ext_memory;
1248 int cpunum;
1249
1250 /* don't do it for drivers that don't have ROM (MESS needs this) */
1251 if (Machine->gamedrv->rom == 0)
1252 return 1;
1253
1254 /* loop over all CPUs */
1255 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
1256 {
1257 int region = REGION_CPU1 + cpunum;
1258 int region_length = memory_region(region) ? memory_region_length(region) : 0;
1259 int size = region_length;
1260
1261 /* keep going until we break out */
1262 while (1)
1263 {
1264 const struct Memory_ReadAddress *mra = Machine->drv->cpu[cpunum].memory_read;
1265 const struct Memory_WriteAddress *mwa = Machine->drv->cpu[cpunum].memory_write;
1266 offs_t lowest = ~0, end, lastend;
1267
1268 /* find the base of the lowest memory region that extends past the end */
1269 for (mra = Machine->drv->cpu[cpunum].memory_read; !IS_MEMPORT_END(mra); mra++)
1270 if (!IS_MEMPORT_MARKER(mra))
1271 if (mra->end >= size && mra->start < lowest && needs_ram(cpunum, (void *)mra->handler))
1272 lowest = mra->start;
1273
1274 for (mwa = Machine->drv->cpu[cpunum].memory_write; !IS_MEMPORT_END(mwa); mwa++)
1275 if (!IS_MEMPORT_MARKER(mwa))
1276 if (mwa->end >= size && mwa->start < lowest && (mwa->base || needs_ram(cpunum, (void *)mwa->handler)))
1277 lowest = mwa->start;
1278
1279 /* done if nothing found */
1280 if (lowest == ~0)
1281 break;
1282
1283 /* now loop until we find the end of this contiguous block of memory */
1284 lastend = ~0;
1285 end = lowest;
1286 while (end != lastend)
1287 {
1288 lastend = end;
1289
1290 /* find the end of the contiguous block of memory */
1291 for (mra = Machine->drv->cpu[cpunum].memory_read; !IS_MEMPORT_END(mra); mra++)
1292 if (!IS_MEMPORT_MARKER(mra))
1293 if (mra->start <= end+1 && mra->end > end && needs_ram(cpunum, (void *)mra->handler))
1294 end = mra->end;
1295
1296 for (mwa = Machine->drv->cpu[cpunum].memory_write; !IS_MEMPORT_END(mwa); mwa++)
1297 if (!IS_MEMPORT_MARKER(mwa))
1298 if (mwa->start <= end+1 && mwa->end > end && (mwa->base || needs_ram(cpunum, (void *)mwa->handler)))
1299 end = mwa->end;
1300 }
1301
1302 /* fill in the data structure */
1303 ext->start = lowest;
1304 ext->end = end;
1305 ext->region = region;
1306
1307 /* allocate memory */
1308 ext->data = malloc(end+1 - lowest);
1309 if (!ext->data)
1310 fatalerror("malloc(%d) failed (lowest: %x - end: %x)\n", end + 1 - lowest, lowest, end);
1311
1312 /* reset the memory */
1313 memset(ext->data, 0, end+1 - lowest);
1314
1315 /* prepare for the next loop */
1316 size = ext->end + 1;
1317 ext++;
1318 }
1319 }
1320 return 1;
1321 }
1322
1323
1324 /*-------------------------------------------------
1325 populate_memory - populate the memory mapping
1326 tables with entries
1327 -------------------------------------------------*/
1328
1329 static int populate_memory(void)
1330 {
1331 int cpunum;
1332
1333 /* loop over CPUs */
1334 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
1335 {
1336 const struct Memory_ReadAddress *mra, *mra_start = Machine->drv->cpu[cpunum].memory_read;
1337 const struct Memory_WriteAddress *mwa, *mwa_start = Machine->drv->cpu[cpunum].memory_write;
1338
1339 /* install the read handlers */
1340 if (mra_start)
1341 {
1342 /* first find the end and check for address bits */
1343 for (mra = mra_start; !IS_MEMPORT_END(mra); mra++)
1344 if (IS_MEMPORT_MARKER(mra) && (mra->end & MEMPORT_ABITS_MASK))
1345 cpudata[cpunum].mem.mask = 0xffffffffUL >> (32 - (mra->end & MEMPORT_ABITS_VAL_MASK));
1346
1347 /* then work backwards */
1348 for (mra--; mra >= mra_start; mra--)
1349 if (!IS_MEMPORT_MARKER(mra))
1350 install_mem_handler(&cpudata[cpunum].mem, 0, mra->start, mra->end, (void *)mra->handler);
1351 }
1352
1353 /* install the write handlers */
1354 if (mwa_start)
1355 {
1356 /* first find the end and check for address bits */
1357 for (mwa = mwa_start; !IS_MEMPORT_END(mwa); mwa++)
1358 if (IS_MEMPORT_MARKER(mwa) && (mwa->end & MEMPORT_ABITS_MASK))
1359 cpudata[cpunum].mem.mask = 0xffffffffUL >> (32 - (mwa->end & MEMPORT_ABITS_VAL_MASK));
1360
1361 /* then work backwards */
1362 for (mwa--; mwa >= mwa_start; mwa--)
1363 if (!IS_MEMPORT_MARKER(mwa))
1364 {
1365 install_mem_handler(&cpudata[cpunum].mem, 1, mwa->start, mwa->end, (void *)mwa->handler);
1366 if (mwa->base) *mwa->base = memory_find_base(cpunum, mwa->start);
1367 if (mwa->size) *mwa->size = mwa->end - mwa->start + 1;
1368 }
1369 }
1370 }
1371 return 1;
1372 }
1373
1374
1375 /*-------------------------------------------------
1376 populate_ports - populate the port mapping
1377 tables with entries
1378 -------------------------------------------------*/
1379
1380 static int populate_ports(void)
1381 {
1382 int cpunum;
1383
1384 /* loop over CPUs */
1385 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
1386 {
1387 const struct IO_ReadPort *mra, *mra_start = Machine->drv->cpu[cpunum].port_read;
1388 const struct IO_WritePort *mwa, *mwa_start = Machine->drv->cpu[cpunum].port_write;
1389
1390 /* install the read handlers */
1391 if (mra_start)
1392 {
1393 /* first find the end and check for address bits */
1394 for (mra = mra_start; !IS_MEMPORT_END(mra); mra++)
1395 if (IS_MEMPORT_MARKER(mra) && (mra->end & MEMPORT_ABITS_MASK))
1396 cpudata[cpunum].port.mask = 0xffffffffUL >> (32 - (mra->end & MEMPORT_ABITS_VAL_MASK));
1397
1398 /* then work backwards */
1399 for (mra--; mra != mra_start; mra--)
1400 if (!IS_MEMPORT_MARKER(mra))
1401 install_port_handler(&cpudata[cpunum].port, 0, mra->start, mra->end, (void *)mra->handler);
1402 }
1403
1404 /* install the write handlers */
1405 if (mwa_start)
1406 {
1407 /* first find the end and check for address bits */
1408 for (mwa = mwa_start; !IS_MEMPORT_END(mwa); mwa++)
1409 if (IS_MEMPORT_MARKER(mwa) && (mwa->end & MEMPORT_ABITS_MASK))
1410 cpudata[cpunum].port.mask = 0xffffffffUL >> (32 - (mwa->end & MEMPORT_ABITS_VAL_MASK));
1411
1412 /* then work backwards */
1413 for (mwa--; mwa != mwa_start; mwa--)
1414 if (!IS_MEMPORT_MARKER(mwa))
1415 install_port_handler(&cpudata[cpunum].port, 1, mwa->start, mwa->end, (void *)mwa->handler);
1416 }
1417 }
1418 return 1;
1419 }
1420
1421
1422 /*-------------------------------------------------
1423 register_banks - Registers all memory banks
1424 into the state save system
1425 -------------------------------------------------*/
1426 typedef struct rg_map_entry {
1427 struct rg_map_entry *next;
1428 UINT32 start;
1429 UINT32 end;
1430 int flags;
1431 } rg_map_entry;
1432
1433 static rg_map_entry *rg_map = 0;
1434
1435 enum {
1436 RG_SAVE_READ = 0x0001,
1437 RG_DROP_READ = 0x0002,
1438 RG_READ_MASK = 0x00ff,
1439
1440 RG_SAVE_WRITE = 0x0100,
1441 RG_DROP_WRITE = 0x0200,
1442 RG_WRITE_MASK = 0xff00
1443 };
1444
1445 static void rg_add_entry(UINT32 start, UINT32 end, int mode)
1446 {
1447 rg_map_entry **cur;
1448 cur = &rg_map;
1449 while(*cur && ((*cur)->end < start))
1450 cur = &(*cur)->next;
1451
1452 while(start <= end)
1453 {
1454 int mask;
1455 if(!*cur || ((*cur)->start > start))
1456 {
1457 rg_map_entry *e = malloc(sizeof(rg_map_entry));
1458 e->start = start;
1459 e->end = *cur && (*cur)->start <= end ? (*cur)->start - 1 : end;
1460 e->flags = mode;
1461 e->next = *cur;
1462 *cur = e;
1463 cur = &(*cur)->next;
1464 start = e->end + 1;
1465 if(start > end)
1466 return;
1467 }
1468
1469 if((*cur)->start < start)
1470 {
1471 rg_map_entry *e = malloc(sizeof(rg_map_entry));
1472 e->start = (*cur)->start;
1473 e->end = start - 1;
1474 e->flags = (*cur)->flags;
1475 e->next = *cur;
1476 (*cur)->start = start;
1477 *cur = e;
1478 cur = &(*cur)->next;
1479 }
1480
1481 if((*cur)->end > end)
1482 {
1483 rg_map_entry *e = malloc(sizeof(rg_map_entry));
1484 e->start = start;
1485 e->end = end;
1486 e->flags = (*cur)->flags;
1487 e->next = *cur;
1488 (*cur)->start = end+1;
1489 *cur = e;
1490 }
1491
1492 mask = 0;
1493
1494 if (mode & RG_READ_MASK)
1495 mask |= RG_READ_MASK;
1496 if (mode & RG_WRITE_MASK)
1497 mask |= RG_WRITE_MASK;
1498
1499 (*cur)->flags = ((*cur)->flags & ~mask) | mode;
1500 start = (*cur)->end + 1;
1501 cur = &(*cur)->next;
1502 }
1503 }
1504
1505 static void rg_map_clear(void)
1506 {
1507 rg_map_entry *e = rg_map;
1508 while(e)
1509 {
1510 rg_map_entry *n = e->next;
1511 free(e);
1512 e = n;
1513 }
1514 rg_map = 0;
1515 }
1516
1517 static void register_zone(int cpunum, UINT32 start, UINT32 end)
1518 {
1519 char name[256];
1520 sprintf (name, "%08x-%08x", start, end);
1521 switch (cpunum_databus_width(cpunum))
1522 {
1523 case 8:
1524 state_save_register_UINT8 ("memory", cpunum, name, memory_find_base(cpunum, start), end-start+1);
1525 break;
1526 case 16:
1527 state_save_register_UINT16("memory", cpunum, name, memory_find_base(cpunum, start), (end-start+1)/2);
1528 break;
1529 case 32:
1530 state_save_register_UINT32("memory", cpunum, name, memory_find_base(cpunum, start), (end-start+1)/4);
1531 break;
1532 }
1533 }
1534
1535 void register_banks(void)
1536 {
1537 int cpunum, i;
1538 int banksize[MAX_BANKS];
1539 int bankcpu[MAX_BANKS];
1540
1541 for (i=0; i<MAX_BANKS; i++)
1542 {
1543 banksize[i] = 0;
1544 bankcpu[i] = -1;
1545 }
1546
1547 /* loop over CPUs */
1548 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
1549 {
1550 const struct Memory_ReadAddress *mra, *mra_start = Machine->drv->cpu[cpunum].memory_read;
1551 const struct Memory_WriteAddress *mwa, *mwa_start = Machine->drv->cpu[cpunum].memory_write;
1552 int bits = cpudata[cpunum].mem.abits;
1553 // int width = cpunum_databus_width(cpunum);
1554
1555 if (!IS_SPARSE(bits))
1556 {
1557 UINT32 size = memory_region_length(REGION_CPU1 + cpunum);
1558 if (size > (1<<bits))
1559 size = 1 << bits;
1560 rg_add_entry(0, size-1, RG_SAVE_READ|RG_SAVE_WRITE);
1561 }
1562
1563
1564 if (mra_start)
1565 {
1566 for (mra = mra_start; !IS_MEMPORT_END(mra); mra++);
1567 mra--;
1568 for (;mra != mra_start; mra--)
1569 {
1570 if (!IS_MEMPORT_MARKER (mra))
1571 {
1572 int mode;
1573 mem_read_handler h = mra->handler;
1574 if (!HANDLER_IS_STATIC (h))
1575 mode = RG_DROP_READ;
1576 else if (HANDLER_IS_RAM(h))
1577 mode = RG_SAVE_READ;
1578 else if (HANDLER_IS_ROM(h))
1579 mode = RG_DROP_READ;
1580 else if (HANDLER_IS_RAMROM(h))
1581 mode = RG_SAVE_READ;
1582 else if (HANDLER_IS_NOP(h))
1583 mode = RG_DROP_READ;
1584 else if (HANDLER_IS_BANK(h))
1585 {
1586 int size = mra->end-mra->start+1;
1587 if (banksize[HANDLER_TO_BANK(h)] < size)
1588 banksize[HANDLER_TO_BANK(h)] = size;
1589 bankcpu[HANDLER_TO_BANK(h)] = cpunum;
1590 mode = RG_DROP_READ;
1591 }
1592 else
1593 abort();
1594 rg_add_entry(mra->start, mra->end, mode);
1595 }
1596 }
1597 }
1598 if (mwa_start)
1599 {
1600 for (mwa = mwa_start; !IS_MEMPORT_END(mwa); mwa++);
1601 mwa--;
1602 for (;mwa != mwa_start; mwa--)
1603 {
1604 if (!IS_MEMPORT_MARKER (mwa))
1605 {
1606 int mode;
1607 mem_write_handler h = mwa->handler;
1608 if (!HANDLER_IS_STATIC (h))
1609 mode = mwa->base ? RG_SAVE_WRITE : RG_DROP_WRITE;
1610 else if (HANDLER_IS_RAM(h))
1611 mode = RG_SAVE_WRITE;
1612 else if (HANDLER_IS_ROM(h))
1613 mode = RG_DROP_WRITE;
1614 else if (HANDLER_IS_RAMROM(h))
1615 mode = RG_SAVE_WRITE;
1616 else if (HANDLER_IS_NOP(h))
1617 mode = RG_DROP_WRITE;
1618 else if (HANDLER_IS_BANK(h))
1619 {
1620 int size = mwa->end-mwa->start+1;
1621 if (banksize[HANDLER_TO_BANK(h)] < size)
1622 banksize[HANDLER_TO_BANK(h)] = size;
1623 bankcpu[HANDLER_TO_BANK(h)] = cpunum;
1624 mode = RG_DROP_WRITE;;
1625 }
1626 else
1627 abort();
1628 rg_add_entry(mwa->start, mwa->end, mode);
1629 }
1630 }
1631 }
1632
1633 {
1634 rg_map_entry *e = rg_map;
1635 UINT32 start = 0, end = 0;
1636 int active = 0;
1637 while (e)
1638 {
1639 if(e && (e->flags & (RG_SAVE_READ|RG_SAVE_WRITE)))
1640 {
1641 if (!active)
1642 {
1643 active = 1;
1644 start = e->start;
1645 }
1646 end = e->end;
1647 }
1648 else if (active)
1649 {
1650 register_zone (cpunum, start, end);
1651 active = 0;
1652 }
1653
1654 if (active && (!e->next || (e->end+1 != e->next->start)))
1655 {
1656 register_zone (cpunum, start, end);
1657 active = 0;
1658 }
1659 e = e->next;
1660 }
1661 }
1662
1663 rg_map_clear();
1664 }
1665
1666 for (i=0; i<MAX_BANKS; i++)
1667 if (banksize[i])
1668 switch (cpunum_databus_width(bankcpu[i]))
1669 {
1670 case 8:
1671 state_save_register_UINT8 ("bank", i, "ram", cpu_bankbase[i], banksize[i]);
1672 break;
1673 case 16:
1674 state_save_register_UINT16("bank", i, "ram", (UINT16 *)cpu_bankbase[i], banksize[i]/2);
1675 break;
1676 case 32:
1677 state_save_register_UINT32("bank", i, "ram", (UINT32 *)cpu_bankbase[i], banksize[i]/4);
1678 break;
1679 }
1680
1681 }
1682
1683 /*-------------------------------------------------
1684 READBYTE - generic byte-sized read handler
1685 -------------------------------------------------*/
1686
1687 #define READBYTE8(name,abits,lookup,handlist,mask) \
1688 data8_t name(offs_t address) \
1689 { \
1690 UINT8 entry; \
1691 MEMREADSTART \
1692 \
1693 /* perform lookup */ \
1694 address &= mask; \
1695 entry = lookup[LEVEL1_INDEX(address,abits,0)]; \
1696 if (entry >= SUBTABLE_BASE) \
1697 entry = lookup[LEVEL2_INDEX(entry,address,abits,0)]; \
1698 \
1699 /* for compatibility with setbankhandler, 8-bit systems */ \
1700 /* must call handlers for banks */ \
1701 if (entry == STATIC_RAM) \
1702 MEMREADEND(cpu_bankbase[STATIC_RAM][address]) \
1703 \
1704 /* fall back to the handler */ \
1705 else \
1706 { \
1707 read8_handler handler = (read8_handler)handlist[entry].handler; \
1708 MEMREADEND((*handler)(address - handlist[entry].offset)) \
1709 } \
1710 return 0; \
1711 } \
1712
1713 #define READBYTE16BE(name,abits,lookup,handlist,mask) \
1714 data8_t name(offs_t address) \
1715 { \
1716 UINT8 entry; \
1717 MEMREADSTART \
1718 \
1719 /* perform lookup */ \
1720 address &= mask; \
1721 entry = lookup[LEVEL1_INDEX(address,abits,1)]; \
1722 if (entry >= SUBTABLE_BASE) \
1723 entry = lookup[LEVEL2_INDEX(entry,address,abits,1)]; \
1724 \
1725 /* handle banks inline */ \
1726 address -= handlist[entry].offset; \
1727 if (entry <= STATIC_RAM) \
1728 MEMREADEND(cpu_bankbase[entry][BYTE_XOR_BE(address)]) \
1729 \
1730 /* fall back to the handler */ \
1731 else \
1732 { \
1733 int shift = 8 * (~address & 1); \
1734 read16_handler handler = (read16_handler)handlist[entry].handler; \
1735 MEMREADEND((*handler)(address >> 1, ~(0xff << shift)) >> shift) \
1736 } \
1737 return 0; \
1738 } \
1739
1740 #define READBYTE16LE(name,abits,lookup,handlist,mask) \
1741 data8_t name(offs_t address) \
1742 { \
1743 UINT8 entry; \
1744 MEMREADSTART \
1745 \
1746 /* perform lookup */ \
1747 address &= mask; \
1748 entry = lookup[LEVEL1_INDEX(address,abits,1)]; \
1749 if (entry >= SUBTABLE_BASE) \
1750 entry = lookup[LEVEL2_INDEX(entry,address,abits,1)]; \
1751 \
1752 /* handle banks inline */ \
1753 address -= handlist[entry].offset; \
1754 if (entry <= STATIC_RAM) \
1755 MEMREADEND(cpu_bankbase[entry][BYTE_XOR_LE(address)]) \
1756 \
1757 /* fall back to the handler */ \
1758 else \
1759 { \
1760 int shift = 8 * (address & 1); \
1761 read16_handler handler = (read16_handler)handlist[entry].handler; \
1762 MEMREADEND((*handler)(address >> 1, ~(0xff << shift)) >> shift) \
1763 } \
1764 return 0; \
1765 } \
1766
1767 #define READBYTE32BE(name,abits,lookup,handlist,mask) \
1768 data8_t name(offs_t address) \
1769 { \
1770 UINT8 entry; \
1771 MEMREADSTART \
1772 \
1773 /* perform lookup */ \
1774 address &= mask; \
1775 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
1776 if (entry >= SUBTABLE_BASE) \
1777 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
1778 \
1779 /* handle banks inline */ \
1780 address -= handlist[entry].offset; \
1781 if (entry <= STATIC_RAM) \
1782 MEMREADEND(cpu_bankbase[entry][BYTE4_XOR_BE(address)]) \
1783 \
1784 /* fall back to the handler */ \
1785 else \
1786 { \
1787 int shift = 8 * (~address & 3); \
1788 read32_handler handler = (read32_handler)handlist[entry].handler; \
1789 MEMREADEND((*handler)(address >> 2, ~(0xff << shift)) >> shift) \
1790 } \
1791 return 0; \
1792 } \
1793
1794 #define READBYTE32LE(name,abits,lookup,handlist,mask) \
1795 data8_t name(offs_t address) \
1796 { \
1797 UINT8 entry; \
1798 MEMREADSTART \
1799 \
1800 /* perform lookup */ \
1801 address &= mask; \
1802 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
1803 if (entry >= SUBTABLE_BASE) \
1804 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
1805 \
1806 /* handle banks inline */ \
1807 address -= handlist[entry].offset; \
1808 if (entry <= STATIC_RAM) \
1809 MEMREADEND(cpu_bankbase[entry][BYTE4_XOR_LE(address)]) \
1810 \
1811 /* fall back to the handler */ \
1812 else \
1813 { \
1814 int shift = 8 * (address & 3); \
1815 read32_handler handler = (read32_handler)handlist[entry].handler; \
1816 MEMREADEND((*handler)(address >> 2, ~(0xff << shift)) >> shift) \
1817 } \
1818 return 0; \
1819 } \
1820
1821
1822 /*-------------------------------------------------
1823 READWORD - generic word-sized read handler
1824 (16-bit and 32-bit aligned only!)
1825 -------------------------------------------------*/
1826
1827 #define READWORD16(name,abits,lookup,handlist,mask) \
1828 data16_t name(offs_t address) \
1829 { \
1830 UINT8 entry; \
1831 MEMREADSTART \
1832 \
1833 /* perform lookup */ \
1834 address &= mask & ~1; \
1835 entry = lookup[LEVEL1_INDEX(address,abits,1)]; \
1836 if (entry >= SUBTABLE_BASE) \
1837 entry = lookup[LEVEL2_INDEX(entry,address,abits,1)]; \
1838 \
1839 /* handle banks inline */ \
1840 address -= handlist[entry].offset; \
1841 if (entry <= STATIC_RAM) \
1842 MEMREADEND(*(data16_t *)&cpu_bankbase[entry][address]) \
1843 \
1844 /* fall back to the handler */ \
1845 else \
1846 { \
1847 read16_handler handler = (read16_handler)handlist[entry].handler; \
1848 MEMREADEND((*handler)(address >> 1,0)) \
1849 } \
1850 return 0; \
1851 } \
1852
1853 #define READWORD32BE(name,abits,lookup,handlist,mask) \
1854 data16_t name(offs_t address) \
1855 { \
1856 UINT8 entry; \
1857 MEMREADSTART \
1858 \
1859 /* perform lookup */ \
1860 address &= mask & ~1; \
1861 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
1862 if (entry >= SUBTABLE_BASE) \
1863 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
1864 \
1865 /* handle banks inline */ \
1866 address -= handlist[entry].offset; \
1867 if (entry <= STATIC_RAM) \
1868 MEMREADEND(*(data16_t *)&cpu_bankbase[entry][WORD_XOR_BE(address)]) \
1869 \
1870 /* fall back to the handler */ \
1871 else \
1872 { \
1873 int shift = 8 * (~address & 2); \
1874 read32_handler handler = (read32_handler)handlist[entry].handler; \
1875 MEMREADEND((*handler)(address >> 2, ~(0xffff << shift)) >> shift) \
1876 } \
1877 return 0; \
1878 } \
1879
1880 #define READWORD32LE(name,abits,lookup,handlist,mask) \
1881 data16_t name(offs_t address) \
1882 { \
1883 UINT8 entry; \
1884 MEMREADSTART \
1885 \
1886 /* perform lookup */ \
1887 address &= mask & ~1; \
1888 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
1889 if (entry >= SUBTABLE_BASE) \
1890 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
1891 \
1892 /* handle banks inline */ \
1893 address -= handlist[entry].offset; \
1894 if (entry <= STATIC_RAM) \
1895 MEMREADEND(*(data16_t *)&cpu_bankbase[entry][WORD_XOR_LE(address)]) \
1896 \
1897 /* fall back to the handler */ \
1898 else \
1899 { \
1900 int shift = 8 * (address & 2); \
1901 read32_handler handler = (read32_handler)handlist[entry].handler; \
1902 MEMREADEND((*handler)(address >> 2, ~(0xffff << shift)) >> shift) \
1903 } \
1904 return 0; \
1905 } \
1906
1907
1908 /*-------------------------------------------------
1909 READLONG - generic dword-sized read handler
1910 (32-bit aligned only!)
1911 -------------------------------------------------*/
1912
1913 #define READLONG32(name,abits,lookup,handlist,mask) \
1914 data32_t name(offs_t address) \
1915 { \
1916 UINT8 entry; \
1917 MEMREADSTART \
1918 \
1919 /* perform lookup */ \
1920 address &= mask & ~3; \
1921 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
1922 if (entry >= SUBTABLE_BASE) \
1923 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
1924 \
1925 /* handle banks inline */ \
1926 address -= handlist[entry].offset; \
1927 if (entry <= STATIC_RAM) \
1928 MEMREADEND(*(data32_t *)&cpu_bankbase[entry][address]) \
1929 \
1930 /* fall back to the handler */ \
1931 else \
1932 { \
1933 read32_handler handler = (read32_handler)handlist[entry].handler; \
1934 MEMREADEND((*handler)(address >> 2,0)) \
1935 } \
1936 return 0; \
1937 } \
1938
1939
1940 /*-------------------------------------------------
1941 WRITEBYTE - generic byte-sized write handler
1942 -------------------------------------------------*/
1943
1944 #define WRITEBYTE8(name,abits,lookup,handlist,mask) \
1945 void name(offs_t address, data8_t data) \
1946 { \
1947 UINT8 entry; \
1948 MEMWRITESTART \
1949 \
1950 /* perform lookup */ \
1951 address &= mask; \
1952 entry = lookup[LEVEL1_INDEX(address,abits,0)]; \
1953 if (entry >= SUBTABLE_BASE) \
1954 entry = lookup[LEVEL2_INDEX(entry,address,abits,0)]; \
1955 \
1956 /* for compatibility with setbankhandler, 8-bit systems */ \
1957 /* must call handlers for banks */ \
1958 if (entry == (FPTR)MRA_RAM) \
1959 MEMWRITEEND(cpu_bankbase[STATIC_RAM][address] = data) \
1960 \
1961 /* fall back to the handler */ \
1962 else \
1963 { \
1964 write8_handler handler = (write8_handler)handlist[entry].handler; \
1965 MEMWRITEEND((*handler)(address - handlist[entry].offset, data)) \
1966 } \
1967 } \
1968
1969 #define WRITEBYTE16BE(name,abits,lookup,handlist,mask) \
1970 void name(offs_t address, data8_t data) \
1971 { \
1972 UINT8 entry; \
1973 MEMWRITESTART \
1974 \
1975 /* perform lookup */ \
1976 address &= mask; \
1977 entry = lookup[LEVEL1_INDEX(address,abits,1)]; \
1978 if (entry >= SUBTABLE_BASE) \
1979 entry = lookup[LEVEL2_INDEX(entry,address,abits,1)]; \
1980 \
1981 /* handle banks inline */ \
1982 address -= handlist[entry].offset; \
1983 if (entry <= STATIC_RAM) \
1984 MEMWRITEEND(cpu_bankbase[entry][BYTE_XOR_BE(address)] = data) \
1985 \
1986 /* fall back to the handler */ \
1987 else \
1988 { \
1989 int shift = 8 * (~address & 1); \
1990 write16_handler handler = (write16_handler)handlist[entry].handler; \
1991 MEMWRITEEND((*handler)(address >> 1, data << shift, ~(0xff << shift))) \
1992 } \
1993 } \
1994
1995 #define WRITEBYTE16LE(name,abits,lookup,handlist,mask) \
1996 void name(offs_t address, data8_t data) \
1997 { \
1998 UINT8 entry; \
1999 MEMWRITESTART \
2000 \
2001 /* perform lookup */ \
2002 address &= mask; \
2003 entry = lookup[LEVEL1_INDEX(address,abits,1)]; \
2004 if (entry >= SUBTABLE_BASE) \
2005 entry = lookup[LEVEL2_INDEX(entry,address,abits,1)]; \
2006 \
2007 /* handle banks inline */ \
2008 address -= handlist[entry].offset; \
2009 if (entry <= STATIC_RAM) \
2010 MEMWRITEEND(cpu_bankbase[entry][BYTE_XOR_LE(address)] = data) \
2011 \
2012 /* fall back to the handler */ \
2013 else \
2014 { \
2015 int shift = 8 * (address & 1); \
2016 write16_handler handler = (write16_handler)handlist[entry].handler; \
2017 MEMWRITEEND((*handler)(address >> 1, data << shift, ~(0xff << shift))) \
2018 } \
2019 } \
2020
2021 #define WRITEBYTE32BE(name,abits,lookup,handlist,mask) \
2022 void name(offs_t address, data8_t data) \
2023 { \
2024 UINT8 entry; \
2025 MEMWRITESTART \
2026 \
2027 /* perform lookup */ \
2028 address &= mask; \
2029 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
2030 if (entry >= SUBTABLE_BASE) \
2031 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
2032 \
2033 /* handle banks inline */ \
2034 address -= handlist[entry].offset; \
2035 if (entry <= STATIC_RAM) \
2036 MEMWRITEEND(cpu_bankbase[entry][BYTE4_XOR_BE(address)] = data) \
2037 \
2038 /* fall back to the handler */ \
2039 else \
2040 { \
2041 int shift = 8 * (~address & 3); \
2042 write32_handler handler = (write32_handler)handlist[entry].handler; \
2043 MEMWRITEEND((*handler)(address >> 2, data << shift, ~(0xff << shift))) \
2044 } \
2045 } \
2046
2047 #define WRITEBYTE32LE(name,abits,lookup,handlist,mask) \
2048 void name(offs_t address, data8_t data) \
2049 { \
2050 UINT8 entry; \
2051 MEMWRITESTART \
2052 \
2053 /* perform lookup */ \
2054 address &= mask; \
2055 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
2056 if (entry >= SUBTABLE_BASE) \
2057 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
2058 \
2059 /* handle banks inline */ \
2060 address -= handlist[entry].offset; \
2061 if (entry <= STATIC_RAM) \
2062 MEMWRITEEND(cpu_bankbase[entry][BYTE4_XOR_LE(address)] = data) \
2063 \
2064 /* fall back to the handler */ \
2065 else \
2066 { \
2067 int shift = 8 * (address & 3); \
2068 write32_handler handler = (write32_handler)handlist[entry].handler; \
2069 MEMWRITEEND((*handler)(address >> 2, data << shift, ~(0xff << shift))) \
2070 } \
2071 } \
2072
2073
2074 /*-------------------------------------------------
2075 WRITEWORD - generic word-sized write handler
2076 (16-bit and 32-bit aligned only!)
2077 -------------------------------------------------*/
2078
2079 #define WRITEWORD16(name,abits,lookup,handlist,mask) \
2080 void name(offs_t address, data16_t data) \
2081 { \
2082 UINT8 entry; \
2083 MEMWRITESTART \
2084 \
2085 /* perform lookup */ \
2086 address &= mask & ~1; \
2087 entry = lookup[LEVEL1_INDEX(address,abits,1)]; \
2088 if (entry >= SUBTABLE_BASE) \
2089 entry = lookup[LEVEL2_INDEX(entry,address,abits,1)]; \
2090 \
2091 /* handle banks inline */ \
2092 address -= handlist[entry].offset; \
2093 if (entry <= STATIC_RAM) \
2094 MEMWRITEEND(*(data16_t *)&cpu_bankbase[entry][address] = data) \
2095 \
2096 /* fall back to the handler */ \
2097 else \
2098 { \
2099 write16_handler handler = (write16_handler)handlist[entry].handler; \
2100 MEMWRITEEND((*handler)(address >> 1, data, 0)) \
2101 } \
2102 } \
2103
2104 #define WRITEWORD32BE(name,abits,lookup,handlist,mask) \
2105 void name(offs_t address, data16_t data) \
2106 { \
2107 UINT8 entry; \
2108 MEMWRITESTART \
2109 \
2110 /* perform lookup */ \
2111 address &= mask & ~1; \
2112 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
2113 if (entry >= SUBTABLE_BASE) \
2114 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
2115 \
2116 /* handle banks inline */ \
2117 address -= handlist[entry].offset; \
2118 if (entry <= STATIC_RAM) \
2119 MEMWRITEEND(*(data16_t *)&cpu_bankbase[entry][WORD_XOR_BE(address)] = data) \
2120 \
2121 /* fall back to the handler */ \
2122 else \
2123 { \
2124 int shift = 8 * (~address & 2); \
2125 write32_handler handler = (write32_handler)handlist[entry].handler; \
2126 MEMWRITEEND((*handler)(address >> 2, data << shift, ~(0xffff << shift))) \
2127 } \
2128 } \
2129
2130 #define WRITEWORD32LE(name,abits,lookup,handlist,mask) \
2131 void name(offs_t address, data16_t data) \
2132 { \
2133 UINT8 entry; \
2134 MEMWRITESTART \
2135 \
2136 /* perform lookup */ \
2137 address &= mask & ~1; \
2138 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
2139 if (entry >= SUBTABLE_BASE) \
2140 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
2141 \
2142 /* handle banks inline */ \
2143 address -= handlist[entry].offset; \
2144 if (entry <= STATIC_RAM) \
2145 MEMWRITEEND(*(data16_t *)&cpu_bankbase[entry][WORD_XOR_LE(address)] = data) \
2146 \
2147 /* fall back to the handler */ \
2148 else \
2149 { \
2150 int shift = 8 * (address & 2); \
2151 write32_handler handler = (write32_handler)handlist[entry].handler; \
2152 MEMWRITEEND((*handler)(address >> 2, data << shift, ~(0xffff << shift))) \
2153 } \
2154 } \
2155
2156
2157 /*-------------------------------------------------
2158 WRITELONG - dword-sized write handler
2159 (32-bit aligned only!)
2160 -------------------------------------------------*/
2161
2162 #define WRITELONG32(name,abits,lookup,handlist,mask) \
2163 void name(offs_t address, data32_t data) \
2164 { \
2165 UINT8 entry; \
2166 MEMWRITESTART \
2167 \
2168 /* perform lookup */ \
2169 address &= mask & ~3; \
2170 entry = lookup[LEVEL1_INDEX(address,abits,2)]; \
2171 if (entry >= SUBTABLE_BASE) \
2172 entry = lookup[LEVEL2_INDEX(entry,address,abits,2)]; \
2173 \
2174 /* handle banks inline */ \
2175 address -= handlist[entry].offset; \
2176 if (entry <= STATIC_RAM) \
2177 MEMWRITEEND(*(data32_t *)&cpu_bankbase[entry][address] = data) \
2178 \
2179 /* fall back to the handler */ \
2180 else \
2181 { \
2182 write32_handler handler = (write32_handler)handlist[entry].handler; \
2183 MEMWRITEEND((*handler)(address >> 2, data, 0)) \
2184 } \
2185 } \
2186
2187
2188 /*-------------------------------------------------
2189 SETOPBASE - generic opcode base changer
2190 -------------------------------------------------*/
2191
2192 #define SETOPBASE(name,abits,minbits,table) \
2193 void name(offs_t pc) \
2194 { \
2195 UINT8 *base; \
2196 UINT8 entry; \
2197 \
2198 /* allow overrides */ \
2199 if (opbasefunc) \
2200 { \
2201 pc = (*opbasefunc)(pc); \
2202 if (pc == ~0) \
2203 return; \
2204 } \
2205 \
2206 /* perform the lookup */ \
2207 pc &= mem_amask; \
2208 entry = readmem_lookup[LEVEL1_INDEX(pc,abits,minbits)]; \
2209 if (entry >= SUBTABLE_BASE) \
2210 entry = readmem_lookup[LEVEL2_INDEX(entry,pc,abits,minbits)]; \
2211 opcode_entry = entry; \
2212 \
2213 /* RAM/ROM/RAMROM */ \
2214 if (entry >= STATIC_RAM && entry <= STATIC_RAMROM) \
2215 base = cpu_bankbase[STATIC_RAM]; \
2216 \
2217 /* banked memory */ \
2218 else if (entry >= STATIC_BANK1 && entry <= STATIC_RAM) \
2219 base = cpu_bankbase[entry]; \
2220 \
2221 /* other memory -- could be very slow! */ \
2222 else \
2223 { \
2224 logerror("cpu #%d (PC=%08X): warning - op-code execute on mapped I/O\n", \
2225 cpu_getactivecpu(), activecpu_get_pc()); \
2226 /*base = memory_find_base(cpu_getactivecpu(), pc);*/ \
2227 return; \
2228 } \
2229 \
2230 /* compute the adjusted base */ \
2231 OP_ROM = base - table[entry].offset + (OP_ROM - OP_RAM); \
2232 OP_RAM = base - table[entry].offset; \
2233 }
2234
2235
2236 /*-------------------------------------------------
2237 GENERATE_HANDLERS - macros to spew out all
2238 the handlers needed for a given memory type
2239 -------------------------------------------------*/
2240
2241 #define GENERATE_HANDLERS_8BIT(type, abits) \
2242 READBYTE8(cpu_read##type##abits, abits, read##type##_lookup, r##type##handler8, type##_amask) \
2243 WRITEBYTE8(cpu_write##type##abits, abits, write##type##_lookup, w##type##handler8, type##_amask)
2244
2245 #define GENERATE_HANDLERS_16BIT_BE(type, abits) \
2246 READBYTE16BE(cpu_read##type##abits##bew, abits, read##type##_lookup, r##type##handler16, type##_amask) \
2247 READWORD16(cpu_read##type##abits##bew_word, abits, read##type##_lookup, r##type##handler16, type##_amask) \
2248 WRITEBYTE16BE(cpu_write##type##abits##bew, abits, write##type##_lookup, w##type##handler16, type##_amask) \
2249 WRITEWORD16(cpu_write##type##abits##bew_word, abits, write##type##_lookup, w##type##handler16, type##_amask)
2250
2251 #define GENERATE_HANDLERS_16BIT_LE(type, abits) \
2252 READBYTE16LE(cpu_read##type##abits##lew, abits, read##type##_lookup, r##type##handler16, type##_amask) \
2253 READWORD16(cpu_read##type##abits##lew_word, abits, read##type##_lookup, r##type##handler16, type##_amask) \
2254 WRITEBYTE16LE(cpu_write##type##abits##lew, abits, write##type##_lookup, w##type##handler16, type##_amask) \
2255 WRITEWORD16(cpu_write##type##abits##lew_word, abits, write##type##_lookup, w##type##handler16, type##_amask)
2256
2257 #define GENERATE_HANDLERS_32BIT_BE(type, abits) \
2258 READBYTE32BE(cpu_read##type##abits##bedw, abits, read##type##_lookup, r##type##handler32, type##_amask) \
2259 READWORD32BE(cpu_read##type##abits##bedw_word, abits, read##type##_lookup, r##type##handler32, type##_amask) \
2260 READLONG32(cpu_read##type##abits##bedw_dword, abits, read##type##_lookup, r##type##handler32, type##_amask) \
2261 WRITEBYTE32BE(cpu_write##type##abits##bedw, abits, write##type##_lookup, w##type##handler32, type##_amask) \
2262 WRITEWORD32BE(cpu_write##type##abits##bedw_word, abits, write##type##_lookup, w##type##handler32, type##_amask) \
2263 WRITELONG32(cpu_write##type##abits##bedw_dword,abits, write##type##_lookup, w##type##handler32, type##_amask)
2264
2265 #define GENERATE_HANDLERS_32BIT_LE(type, abits) \
2266 READBYTE32LE(cpu_read##type##abits##ledw, abits, read##type##_lookup, r##type##handler32, type##_amask) \
2267 READWORD32LE(cpu_read##type##abits##ledw_word, abits, read##type##_lookup, r##type##handler32, type##_amask) \
2268 READLONG32(cpu_read##type##abits##ledw_dword, abits, read##type##_lookup, r##type##handler32, type##_amask) \
2269 WRITEBYTE32LE(cpu_write##type##abits##ledw, abits, write##type##_lookup, w##type##handler32, type##_amask) \
2270 WRITEWORD32LE(cpu_write##type##abits##ledw_word, abits, write##type##_lookup, w##type##handler32, type##_amask) \
2271 WRITELONG32(cpu_write##type##abits##ledw_dword,abits, write##type##_lookup, w##type##handler32, type##_amask)
2272
2273
2274 /*-------------------------------------------------
2275 GENERATE_MEM_HANDLERS - memory handler
2276 variants of the GENERATE_HANDLERS
2277 -------------------------------------------------*/
2278
2279 #define GENERATE_MEM_HANDLERS_8BIT(abits) \
2280 GENERATE_HANDLERS_8BIT(mem, abits) \
2281 SETOPBASE(cpu_setopbase##abits, abits, 0, rmemhandler8)
2282
2283 #define GENERATE_MEM_HANDLERS_16BIT_BE(abits) \
2284 GENERATE_HANDLERS_16BIT_BE(mem, abits) \
2285 SETOPBASE(cpu_setopbase##abits##bew, abits, 1, rmemhandler16)
2286
2287 #define GENERATE_MEM_HANDLERS_16BIT_LE(abits) \
2288 GENERATE_HANDLERS_16BIT_LE(mem, abits) \
2289 SETOPBASE(cpu_setopbase##abits##lew, abits, 1, rmemhandler16)
2290
2291 #define GENERATE_MEM_HANDLERS_32BIT_BE(abits) \
2292 GENERATE_HANDLERS_32BIT_BE(mem, abits) \
2293 SETOPBASE(cpu_setopbase##abits##bedw, abits, 2, rmemhandler32)
2294
2295 #define GENERATE_MEM_HANDLERS_32BIT_LE(abits) \
2296 GENERATE_HANDLERS_32BIT_LE(mem, abits) \
2297 SETOPBASE(cpu_setopbase##abits##ledw, abits, 2, rmemhandler32)
2298
2299
2300 /*-------------------------------------------------
2301 GENERATE_PORT_HANDLERS - port handler
2302 variants of the GENERATE_HANDLERS
2303 -------------------------------------------------*/
2304
2305 #define GENERATE_PORT_HANDLERS_8BIT(abits) \
2306 GENERATE_HANDLERS_8BIT(port, abits)
2307
2308 #define GENERATE_PORT_HANDLERS_16BIT_BE(abits) \
2309 GENERATE_HANDLERS_16BIT_BE(port, abits)
2310
2311 #define GENERATE_PORT_HANDLERS_16BIT_LE(abits) \
2312 GENERATE_HANDLERS_16BIT_LE(port, abits)
2313
2314 #define GENERATE_PORT_HANDLERS_32BIT_BE(abits) \
2315 GENERATE_HANDLERS_32BIT_BE(port, abits)
2316
2317 #define GENERATE_PORT_HANDLERS_32BIT_LE(abits) \
2318 GENERATE_HANDLERS_32BIT_LE(port, abits)
2319
2320
2321 /*-------------------------------------------------
2322 the memory handlers we need to generate
2323 -------------------------------------------------*/
2324
2325 GENERATE_MEM_HANDLERS_8BIT(16)
2326 GENERATE_MEM_HANDLERS_8BIT(20)
2327 GENERATE_MEM_HANDLERS_8BIT(21)
2328 GENERATE_MEM_HANDLERS_8BIT(24)
2329
2330 GENERATE_MEM_HANDLERS_16BIT_BE(16)
2331 GENERATE_MEM_HANDLERS_16BIT_BE(24)
2332 GENERATE_MEM_HANDLERS_16BIT_BE(32)
2333
2334 GENERATE_MEM_HANDLERS_16BIT_LE(16)
2335 GENERATE_MEM_HANDLERS_16BIT_LE(17)
2336 GENERATE_MEM_HANDLERS_16BIT_LE(24)
2337 GENERATE_MEM_HANDLERS_16BIT_LE(29)
2338 GENERATE_MEM_HANDLERS_16BIT_LE(32)
2339
2340 GENERATE_MEM_HANDLERS_32BIT_BE(24)
2341 GENERATE_MEM_HANDLERS_32BIT_BE(29)
2342 GENERATE_MEM_HANDLERS_32BIT_BE(32)
2343
2344 GENERATE_MEM_HANDLERS_32BIT_LE(26)
2345 GENERATE_MEM_HANDLERS_32BIT_LE(29)
2346 GENERATE_MEM_HANDLERS_32BIT_LE(32)
2347
2348 GENERATE_MEM_HANDLERS_32BIT_BE(18) /* HACK -- used for pdp-1 */
2349
2350 /* make sure you add an entry to this list whenever you add a set of handlers */
2351 static const struct memory_address_table readmem_to_bits[] =
2352 {
2353 { 16, cpu_readmem16 },
2354 { 20, cpu_readmem20 },
2355 { 21, cpu_readmem21 },
2356 { 24, cpu_readmem24 },
2357
2358 { 16, cpu_readmem16bew },
2359 { 24, cpu_readmem24bew },
2360 { 32, cpu_readmem32bew },
2361
2362 { 16, cpu_readmem16lew },
2363 { 17, cpu_readmem17lew },
2364 { 24, cpu_readmem24lew },
2365 { 29, cpu_readmem29lew },
2366 { 32, cpu_readmem32lew },
2367
2368 { 24, cpu_readmem24bedw },
2369 { 29, cpu_readmem29bedw },
2370 { 32, cpu_readmem32bedw },
2371
2372 { 26, cpu_readmem26ledw },
2373 { 29, cpu_readmem29ledw },
2374 { 32, cpu_readmem32ledw },
2375
2376 { 18, cpu_readmem18bedw }
2377 };
2378
2379
2380 /*-------------------------------------------------
2381 the port handlers we need to generate
2382 -------------------------------------------------*/
2383
2384 GENERATE_PORT_HANDLERS_8BIT(16)
2385
2386 GENERATE_PORT_HANDLERS_16BIT_BE(16)
2387
2388 GENERATE_PORT_HANDLERS_16BIT_LE(16)
2389 GENERATE_PORT_HANDLERS_16BIT_LE(24)
2390
2391 GENERATE_PORT_HANDLERS_32BIT_BE(16)
2392
2393 GENERATE_PORT_HANDLERS_32BIT_LE(16)
2394 GENERATE_PORT_HANDLERS_32BIT_LE(24)
2395
2396
2397 /*-------------------------------------------------
2398 get address bits from a read handler
2399 -------------------------------------------------*/
2400
2401 int mem_address_bits_of_cpu(int cputype)
2402 {
2403 read8_handler handler = cputype_get_interface(cputype)->memory_read;
2404 int idx;
2405
2406 /* scan the table */
2407 for (idx = 0; idx < sizeof(readmem_to_bits) / sizeof(readmem_to_bits[0]); idx++)
2408 if (readmem_to_bits[idx].handler == handler)
2409 return readmem_to_bits[idx].bits;
2410
2411 /* this is a fatal error */
2412 fatalerror("CPU #%d memory handlers don't have a table entry in readmem_to_bits!\n");
2413 exit(1);
2414 return 0;
2415 }
2416
2417
2418 /*-------------------------------------------------
2419 get address bits from a read handler
2420 -------------------------------------------------*/
2421
2422 int port_address_bits_of_cpu(int cputype)
2423 {
2424 #if (HAS_V60)
2425 return cputype == CPU_V60 ? 24 : 16;
2426 #else
2427 return 16;
2428 #endif
2429 }
2430
2431
2432 /*-------------------------------------------------
2433 basic static handlers
2434 -------------------------------------------------*/
2435
2436 static READ_HANDLER( mrh8_bad )
2437 {
2438 logerror("cpu #%d (PC=%08X): unmapped memory byte read from %08X\n", cpu_getactivecpu(), activecpu_get_pc(), offset);
2439 if (activecpu_address_bits() <= SPARSE_THRESH) return cpu_bankbase[STATIC_RAM][offset];
2440 return unmap_value;
2441 }
2442 static READ16_HANDLER( mrh16_bad )
2443 {
2444 logerror("cpu #%d (PC=%08X): unmapped memory word read from %08X & %04X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*2, mem_mask ^ 0xffff);
2445 if (activecpu_address_bits() <= SPARSE_THRESH) return ((data16_t *)cpu_bankbase[STATIC_RAM])[offset];
2446 return unmap_value;
2447 }
2448 static READ32_HANDLER( mrh32_bad )
2449 {
2450 logerror("cpu #%d (PC=%08X): unmapped memory dword read from %08X & %08X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*4, mem_mask ^ 0xffffffff);
2451 if (activecpu_address_bits() <= SPARSE_THRESH) return ((data32_t *)cpu_bankbase[STATIC_RAM])[offset];
2452 return unmap_value;
2453 }
2454
2455 static WRITE_HANDLER( mwh8_bad )
2456 {
2457 logerror("cpu #%d (PC=%08X): unmapped memory byte write to %08X = %02X\n", cpu_getactivecpu(), activecpu_get_pc(), offset, data);
2458 if (activecpu_address_bits() <= SPARSE_THRESH) cpu_bankbase[STATIC_RAM][offset] = data;
2459 }
2460 static WRITE16_HANDLER( mwh16_bad )
2461 {
2462 logerror("cpu #%d (PC=%08X): unmapped memory word write to %08X = %04X & %04X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*2, data, mem_mask ^ 0xffff);
2463 if (activecpu_address_bits() <= SPARSE_THRESH) COMBINE_DATA(&((data16_t *)cpu_bankbase[STATIC_RAM])[offset]);
2464 }
2465 static WRITE32_HANDLER( mwh32_bad )
2466 {
2467 logerror("cpu #%d (PC=%08X): unmapped memory dword write to %08X = %08X & %08X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*4, data, mem_mask ^ 0xffffffff);
2468 if (activecpu_address_bits() <= SPARSE_THRESH) COMBINE_DATA(&((data32_t *)cpu_bankbase[STATIC_RAM])[offset]);
2469 }
2470
2471 static READ_HANDLER( prh8_bad )
2472 {
2473 logerror("cpu #%d (PC=%08X): unmapped port byte read from %08X\n", cpu_getactivecpu(), activecpu_get_pc(), offset);
2474 return unmap_value;
2475 }
2476 static READ16_HANDLER( prh16_bad )
2477 {
2478 logerror("cpu #%d (PC=%08X): unmapped port word read from %08X & %04X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*2, mem_mask ^ 0xffff);
2479 return unmap_value;
2480 }
2481 static READ32_HANDLER( prh32_bad )
2482 {
2483 logerror("cpu #%d (PC=%08X): unmapped port dword read from %08X & %08X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*4, mem_mask ^ 0xffffffff);
2484 return unmap_value;
2485 }
2486
2487 static WRITE_HANDLER( pwh8_bad )
2488 {
2489 logerror("cpu #%d (PC=%08X): unmapped port byte write to %08X = %02X\n", cpu_getactivecpu(), activecpu_get_pc(), offset, data);
2490 }
2491 static WRITE16_HANDLER( pwh16_bad )
2492 {
2493 logerror("cpu #%d (PC=%08X): unmapped port word write to %08X = %04X & %04X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*2, data, mem_mask ^ 0xffff);
2494 }
2495 static WRITE32_HANDLER( pwh32_bad )
2496 {
2497 logerror("cpu #%d (PC=%08X): unmapped port dword write to %08X = %08X & %08X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*4, data, mem_mask ^ 0xffffffff);
2498 }
2499
2500 static WRITE_HANDLER( mwh8_rom ) { logerror("cpu #%d (PC=%08X): byte write to ROM %08X = %02X\n", cpu_getactivecpu(), activecpu_get_pc(), offset, data); }
2501 static WRITE16_HANDLER( mwh16_rom ) { logerror("cpu #%d (PC=%08X): word write to %08X = %04X & %04X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*2, data, mem_mask ^ 0xffff); }
2502 static WRITE32_HANDLER( mwh32_rom ) { logerror("cpu #%d (PC=%08X): dword write to %08X = %08X & %08X\n", cpu_getactivecpu(), activecpu_get_pc(), offset*4, data, mem_mask ^ 0xffffffff); }
2503
2504 static READ_HANDLER( mrh8_nop ) { return 0; }
2505 static READ16_HANDLER( mrh16_nop ) { return 0; }
2506 static READ32_HANDLER( mrh32_nop ) { return 0; }
2507
2508 static WRITE_HANDLER( mwh8_nop ) { }
2509 static WRITE16_HANDLER( mwh16_nop ) { }
2510 static WRITE32_HANDLER( mwh32_nop ) { }
2511
2512 static READ_HANDLER( mrh8_ram ) { return cpu_bankbase[STATIC_RAM][offset]; }
2513 static WRITE_HANDLER( mwh8_ram ) { cpu_bankbase[STATIC_RAM][offset] = data; }
2514
2515 static WRITE_HANDLER( mwh8_ramrom ) { cpu_bankbase[STATIC_RAM][offset] = cpu_bankbase[STATIC_RAM][offset + (OP_ROM - OP_RAM)] = data; }
2516 static WRITE16_HANDLER( mwh16_ramrom ) { COMBINE_DATA(&cpu_bankbase[STATIC_RAM][offset*2]); COMBINE_DATA(&cpu_bankbase[0][offset*2 + (OP_ROM - OP_RAM)]); }
2517 static WRITE32_HANDLER( mwh32_ramrom ) { COMBINE_DATA(&cpu_bankbase[STATIC_RAM][offset*4]); COMBINE_DATA(&cpu_bankbase[0][offset*4 + (OP_ROM - OP_RAM)]); }
2518
2519 static READ_HANDLER( mrh8_bank1 ) { return cpu_bankbase[1][offset]; }
2520 static READ_HANDLER( mrh8_bank2 ) { return cpu_bankbase[2][offset]; }
2521 static READ_HANDLER( mrh8_bank3 ) { return cpu_bankbase[3][offset]; }
2522 static READ_HANDLER( mrh8_bank4 ) { return cpu_bankbase[4][offset]; }
2523 static READ_HANDLER( mrh8_bank5 ) { return cpu_bankbase[5][offset]; }
2524 static READ_HANDLER( mrh8_bank6 ) { return cpu_bankbase[6][offset]; }
2525 static READ_HANDLER( mrh8_bank7 ) { return cpu_bankbase[7][offset]; }
2526 static READ_HANDLER( mrh8_bank8 ) { return cpu_bankbase[8][offset]; }
2527 static READ_HANDLER( mrh8_bank9 ) { return cpu_bankbase[9][offset]; }
2528 static READ_HANDLER( mrh8_bank10 ) { return cpu_bankbase[10][offset]; }
2529 static READ_HANDLER( mrh8_bank11 ) { return cpu_bankbase[11][offset]; }
2530 static READ_HANDLER( mrh8_bank12 ) { return cpu_bankbase[12][offset]; }
2531 static READ_HANDLER( mrh8_bank13 ) { return cpu_bankbase[13][offset]; }
2532 static READ_HANDLER( mrh8_bank14 ) { return cpu_bankbase[14][offset]; }
2533 static READ_HANDLER( mrh8_bank15 ) { return cpu_bankbase[15][offset]; }
2534 static READ_HANDLER( mrh8_bank16 ) { return cpu_bankbase[16][offset]; }
2535 static READ_HANDLER( mrh8_bank17 ) { return cpu_bankbase[17][offset]; }
2536 static READ_HANDLER( mrh8_bank18 ) { return cpu_bankbase[18][offset]; }
2537 static READ_HANDLER( mrh8_bank19 ) { return cpu_bankbase[19][offset]; }
2538 static READ_HANDLER( mrh8_bank20 ) { return cpu_bankbase[20][offset]; }
2539 static READ_HANDLER( mrh8_bank21 ) { return cpu_bankbase[21][offset]; }
2540 static READ_HANDLER( mrh8_bank22 ) { return cpu_bankbase[22][offset]; }
2541 static READ_HANDLER( mrh8_bank23 ) { return cpu_bankbase[23][offset]; }
2542 static READ_HANDLER( mrh8_bank24 ) { return cpu_bankbase[24][offset]; }
2543
2544 static WRITE_HANDLER( mwh8_bank1 ) { cpu_bankbase[1][offset] = data; }
2545 static WRITE_HANDLER( mwh8_bank2 ) { cpu_bankbase[2][offset] = data; }
2546 static WRITE_HANDLER( mwh8_bank3 ) { cpu_bankbase[3][offset] = data; }
2547 static WRITE_HANDLER( mwh8_bank4 ) { cpu_bankbase[4][offset] = data; }
2548 static WRITE_HANDLER( mwh8_bank5 ) { cpu_bankbase[5][offset] = data; }
2549 static WRITE_HANDLER( mwh8_bank6 ) { cpu_bankbase[6][offset] = data; }
2550 static WRITE_HANDLER( mwh8_bank7 ) { cpu_bankbase[7][offset] = data; }
2551 static WRITE_HANDLER( mwh8_bank8 ) { cpu_bankbase[8][offset] = data; }
2552 static WRITE_HANDLER( mwh8_bank9 ) { cpu_bankbase[9][offset] = data; }
2553 static WRITE_HANDLER( mwh8_bank10 ) { cpu_bankbase[10][offset] = data; }
2554 static WRITE_HANDLER( mwh8_bank11 ) { cpu_bankbase[11][offset] = data; }
2555 static WRITE_HANDLER( mwh8_bank12 ) { cpu_bankbase[12][offset] = data; }
2556 static WRITE_HANDLER( mwh8_bank13 ) { cpu_bankbase[13][offset] = data; }
2557 static WRITE_HANDLER( mwh8_bank14 ) { cpu_bankbase[14][offset] = data; }
2558 static WRITE_HANDLER( mwh8_bank15 ) { cpu_bankbase[15][offset] = data; }
2559 static WRITE_HANDLER( mwh8_bank16 ) { cpu_bankbase[16][offset] = data; }
2560 static WRITE_HANDLER( mwh8_bank17 ) { cpu_bankbase[17][offset] = data; }
2561 static WRITE_HANDLER( mwh8_bank18 ) { cpu_bankbase[18][offset] = data; }
2562 static WRITE_HANDLER( mwh8_bank19 ) { cpu_bankbase[19][offset] = data; }
2563 static WRITE_HANDLER( mwh8_bank20 ) { cpu_bankbase[20][offset] = data; }
2564 static WRITE_HANDLER( mwh8_bank21 ) { cpu_bankbase[21][offset] = data; }
2565 static WRITE_HANDLER( mwh8_bank22 ) { cpu_bankbase[22][offset] = data; }
2566 static WRITE_HANDLER( mwh8_bank23 ) { cpu_bankbase[23][offset] = data; }
2567 static WRITE_HANDLER( mwh8_bank24 ) { cpu_bankbase[24][offset] = data; }
2568
2569
2570 /*-------------------------------------------------
2571 init_static - sets up the static memory
2572 handlers
2573 -------------------------------------------------*/
2574
2575 static int init_static(void)
2576 {
2577 memset(rmemhandler8, 0, sizeof(rmemhandler8));
2578 memset(rmemhandler8s, 0, sizeof(rmemhandler8s));
2579 memset(rmemhandler16, 0, sizeof(rmemhandler16));
2580 memset(rmemhandler32, 0, sizeof(rmemhandler32));
2581 memset(wmemhandler8, 0, sizeof(wmemhandler8));
2582 memset(wmemhandler8s, 0, sizeof(wmemhandler8s));
2583 memset(wmemhandler16, 0, sizeof(wmemhandler16));
2584 memset(wmemhandler32, 0, sizeof(wmemhandler32));
2585
2586 memset(rporthandler8, 0, sizeof(rporthandler8));
2587 memset(rporthandler16, 0, sizeof(rporthandler16));
2588 memset(rporthandler32, 0, sizeof(rporthandler32));
2589 memset(wporthandler8, 0, sizeof(wporthandler8));
2590 memset(wporthandler16, 0, sizeof(wporthandler16));
2591 memset(wporthandler32, 0, sizeof(wporthandler32));
2592
2593 set_static_handler(STATIC_BANK1, mrh8_bank1, NULL, NULL, mwh8_bank1, NULL, NULL);
2594 set_static_handler(STATIC_BANK2, mrh8_bank2, NULL, NULL, mwh8_bank2, NULL, NULL);
2595 set_static_handler(STATIC_BANK3, mrh8_bank3, NULL, NULL, mwh8_bank3, NULL, NULL);
2596 set_static_handler(STATIC_BANK4, mrh8_bank4, NULL, NULL, mwh8_bank4, NULL, NULL);
2597 set_static_handler(STATIC_BANK5, mrh8_bank5, NULL, NULL, mwh8_bank5, NULL, NULL);
2598 set_static_handler(STATIC_BANK6, mrh8_bank6, NULL, NULL, mwh8_bank6, NULL, NULL);
2599 set_static_handler(STATIC_BANK7, mrh8_bank7, NULL, NULL, mwh8_bank7, NULL, NULL);
2600 set_static_handler(STATIC_BANK8, mrh8_bank8, NULL, NULL, mwh8_bank8, NULL, NULL);
2601 set_static_handler(STATIC_BANK9, mrh8_bank9, NULL, NULL, mwh8_bank9, NULL, NULL);
2602 set_static_handler(STATIC_BANK10, mrh8_bank10, NULL, NULL, mwh8_bank10, NULL, NULL);
2603 set_static_handler(STATIC_BANK11, mrh8_bank11, NULL, NULL, mwh8_bank11, NULL, NULL);
2604 set_static_handler(STATIC_BANK12, mrh8_bank12, NULL, NULL, mwh8_bank12, NULL, NULL);
2605 set_static_handler(STATIC_BANK13, mrh8_bank13, NULL, NULL, mwh8_bank13, NULL, NULL);
2606 set_static_handler(STATIC_BANK14, mrh8_bank14, NULL, NULL, mwh8_bank14, NULL, NULL);
2607 set_static_handler(STATIC_BANK15, mrh8_bank15, NULL, NULL, mwh8_bank15, NULL, NULL);
2608 set_static_handler(STATIC_BANK16, mrh8_bank16, NULL, NULL, mwh8_bank16, NULL, NULL);
2609 set_static_handler(STATIC_BANK17, mrh8_bank17, NULL, NULL, mwh8_bank17, NULL, NULL);
2610 set_static_handler(STATIC_BANK18, mrh8_bank18, NULL, NULL, mwh8_bank18, NULL, NULL);
2611 set_static_handler(STATIC_BANK19, mrh8_bank19, NULL, NULL, mwh8_bank19, NULL, NULL);
2612 set_static_handler(STATIC_BANK20, mrh8_bank20, NULL, NULL, mwh8_bank20, NULL, NULL);
2613 set_static_handler(STATIC_BANK21, mrh8_bank21, NULL, NULL, mwh8_bank21, NULL, NULL);
2614 set_static_handler(STATIC_BANK22, mrh8_bank22, NULL, NULL, mwh8_bank22, NULL, NULL);
2615 set_static_handler(STATIC_BANK23, mrh8_bank23, NULL, NULL, mwh8_bank23, NULL, NULL);
2616 set_static_handler(STATIC_BANK24, mrh8_bank24, NULL, NULL, mwh8_bank24, NULL, NULL);
2617 set_static_handler(STATIC_UNMAP, mrh8_bad, mrh16_bad, mrh32_bad, mwh8_bad, mwh16_bad, mwh32_bad);
2618 set_static_handler(STATIC_NOP, mrh8_nop, mrh16_nop, mrh32_nop, mwh8_nop, mwh16_nop, mwh32_nop);
2619 set_static_handler(STATIC_RAM, mrh8_ram, NULL, NULL, mwh8_ram, NULL, NULL);
2620 set_static_handler(STATIC_ROM, NULL, NULL, NULL, mwh8_rom, mwh16_rom, mwh32_rom);
2621 set_static_handler(STATIC_RAMROM, NULL, NULL, NULL, mwh8_ramrom, mwh16_ramrom, mwh32_ramrom);
2622
2623 /* override port unmapped handlers */
2624 rporthandler8 [STATIC_UNMAP].handler = (void *)prh8_bad;
2625 rporthandler16[STATIC_UNMAP].handler = (void *)prh16_bad;
2626 rporthandler32[STATIC_UNMAP].handler = (void *)prh32_bad;
2627 wporthandler8 [STATIC_UNMAP].handler = (void *)pwh8_bad;
2628 wporthandler16[STATIC_UNMAP].handler = (void *)pwh16_bad;
2629 wporthandler32[STATIC_UNMAP].handler = (void *)pwh32_bad;
2630
2631 return 1;
2632 }
2633
2634
2635 /*-------------------------------------------------
2636 debugging
2637 -------------------------------------------------*/
2638
2639 #ifdef MEM_DUMP
2640
2641 static void dump_map(FILE *file, const struct memport_data *memport, const struct table_data *table)
2642 {
2643 static const char *strings[] =
2644 {
2645 "invalid", "bank 1", "bank 2", "bank 3",
2646 "bank 4", "bank 5", "bank 6", "bank 7",
2647 "bank 8", "bank 9", "bank 10", "bank 11",
2648 "bank 12", "bank 13", "bank 14", "bank 15",
2649 "bank 16", "bank 17", "bank 18", "bank 19",
2650 "bank 20", "bank 21", "bank 22", "bank 23",
2651 "bank 24", "RAM", "ROM", "RAMROM",
2652 "nop", "unused 1", "unused 2", "unmapped"
2653 };
2654
2655 int minbits = DATABITS_TO_SHIFT(memport->dbits);
2656 int l1bits = LEVEL1_BITS(memport->ebits);
2657 int l2bits = LEVEL2_BITS(memport->ebits);
2658 int l1count = 1 << l1bits;
2659 int l2count = 1 << l2bits;
2660 int i, j;
2661
2662 fprintf(file, " Address bits = %d\n", memport->abits);
2663 fprintf(file, " Data bits = %d\n", memport->dbits);
2664 fprintf(file, "Effective bits = %d\n", memport->ebits);
2665 fprintf(file, " L1 bits = %d\n", l1bits);
2666 fprintf(file, " L2 bits = %d\n", l2bits);
2667 fprintf(file, " Address mask = %X\n", memport->mask);
2668 fprintf(file, "\n");
2669
2670 for (i = 0; i < l1count; i++)
2671 {
2672 UINT8 entry = table->table[i];
2673 if (entry != STATIC_UNMAP)
2674 {
2675 fprintf(file, "%05X %08X-%08X = %02X: ", i,
2676 i << (l2bits + minbits),
2677 ((i+1) << (l2bits + minbits)) - 1, entry);
2678 if (entry < STATIC_COUNT)
2679 fprintf(file, "%s [offset=%08X]\n", strings[entry], table->handlers[entry].offset);
2680 else if (entry < SUBTABLE_BASE)
2681 fprintf(file, "handler(%08X) [offset=%08X]\n", (UINT32)table->handlers[entry].handler, table->handlers[entry].offset);
2682 else
2683 {
2684 fprintf(file, "subtable %d\n", entry & SUBTABLE_MASK);
2685 entry &= SUBTABLE_MASK;
2686
2687 for (j = 0; j < l2count; j++)
2688 {
2689 UINT8 entry2 = table->table[(1 << l1bits) + (entry << l2bits) + j];
2690 if (entry2 != STATIC_UNMAP)
2691 {
2692 fprintf(file, " %05X %08X-%08X = %02X: ", j,
2693 (i << (l2bits + minbits)) | (j << minbits),
2694 ((i << (l2bits + minbits)) | ((j+1) << minbits)) - 1, entry2);
2695 if (entry2 < STATIC_COUNT)
2696 fprintf(file, "%s [offset=%08X]\n", strings[entry2], table->handlers[entry2].offset);
2697 else if (entry2 < SUBTABLE_BASE)
2698 fprintf(file, "handler(%08X) [offset=%08X]\n", (UINT32)table->handlers[entry2].handler, table->handlers[entry2].offset);
2699 else
2700 fprintf(file, "subtable %d???????????\n", entry2 & SUBTABLE_MASK);
2701 }
2702 }
2703 }
2704 }
2705 }
2706 }
2707
2708 static void mem_dump(void)
2709 {
2710 FILE *file = fopen("memdump.log", "w");
2711 int cpunum;
2712
2713 /* skip if we can't open the file */
2714 if (!file)
2715 return;
2716
2717 /* loop over CPUs */
2718 for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
2719 {
2720 /* memory handlers */
2721 if (cpudata[cpunum].mem.abits)
2722 {
2723 fprintf(file, "\n\n"
2724 "===============================\n"
2725 "CPU %d read memory handler dump\n"
2726 "===============================\n", cpunum);
2727 dump_map(file, &cpudata[cpunum].mem, &cpudata[cpunum].mem.read);
2728
2729 fprintf(file, "\n\n"
2730 "================================\n"
2731 "CPU %d write memory handler dump\n"
2732 "================================\n", cpunum);
2733 dump_map(file, &cpudata[cpunum].mem, &cpudata[cpunum].mem.write);
2734 }
2735
2736 /* port handlers */
2737 if (cpudata[cpunum].port.abits)
2738 {
2739 fprintf(file, "\n\n"
2740 "=============================\n"
2741 "CPU %d read port handler dump\n"
2742 "=============================\n", cpunum);
2743 dump_map(file, &cpudata[cpunum].port, &cpudata[cpunum].port.read);
2744
2745 fprintf(file, "\n\n"
2746 "==============================\n"
2747 "CPU %d write port handler dump\n"
2748 "==============================\n", cpunum);
2749 dump_map(file, &cpudata[cpunum].port, &cpudata[cpunum].port.write);
2750 }
2751 }
2752 fclose(file);
2753 }
2754 #endif
2755
2756 #ifdef CHECK_MASKS
2757 static void *track_buffer[65536];
2758 static int track_count;
2759 static int static_count;
2760 static int track_entry(void *entry, void *handler)
2761 {
2762 int i;
2763 for (i = 0; i < track_count; i++)
2764 if (track_buffer[i] == entry)
2765 return 1;
2766 track_buffer[track_count++] = entry;
2767 if (HANDLER_IS_STATIC(handler))
2768 static_count++;
2769 return 0;
2770 }
2771
2772 static void verify_masks(void)
2773 {
2774 int i, cpunum;
2775
2776 for (i = 0;drivers[i];i++)
2777 {
2778 const struct RomModule *romp = drivers[i]->rom;
2779 if (romp)
2780 {
2781 for (cpunum = 0;cpunum < MAX_CPU;cpunum++)
2782 {
2783 if (drivers[i]->drv->cpu[cpunum].cpu_type)
2784 {
2785 const struct Memory_ReadAddress *mra = drivers[i]->drv->cpu[cpunum].memory_read;
2786 const struct Memory_WriteAddress *mwa = drivers[i]->drv->cpu[cpunum].memory_write;
2787 const struct IO_ReadPort *iora = drivers[i]->drv->cpu[cpunum].port_read;
2788 const struct IO_WritePort *iowa = drivers[i]->drv->cpu[cpunum].port_write;
2789
2790 if (mra)
2791 for ( ; !IS_MEMPORT_END(mra); mra++)
2792 if (!IS_MEMPORT_MARKER(mra))
2793 {
2794 size_t size = mra->end - mra->start + 1;
2795 if (size)
2796 {
2797 while (!(size & 1)) size >>= 1;
2798 if (size != 1)
2799 {
2800 if (!track_entry((void *)mra, (void *)mra->handler))
2801 printf("%s: %s cpu %d readmem inval size { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, mra->start, mra->end);
2802 }
2803 }
2804 size--;
2805 if ((mra->start & size) != 0)
2806 {
2807 if (!track_entry((void *)mra, (void *)mra->handler))
2808 printf("%s: %s cpu %d readmem inval start { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, mra->start, mra->end);
2809 }
2810 if ((mra->end & size) != size)
2811 {
2812 if (!track_entry((void *)mra, (void *)mra->handler))
2813 printf("%s: %s cpu %d readmem inval end { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, mra->start, mra->end);
2814 }
2815 }
2816
2817 if (mwa)
2818 for ( ; !IS_MEMPORT_END(mwa); mwa++)
2819 if (!IS_MEMPORT_MARKER(mwa))
2820 {
2821 size_t size = mwa->end - mwa->start + 1;
2822 if (size)
2823 {
2824 while (!(size & 1)) size >>= 1;
2825 if (size != 1)
2826 {
2827 if (!track_entry((void *)mwa, (void *)mwa->handler))
2828 printf("%s: %s cpu %d writemem inval size { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, mwa->start, mwa->end);
2829 }
2830 }
2831 size--;
2832 if ((mwa->start & size) != 0)
2833 {
2834 if (!track_entry((void *)mwa, (void *)mwa->handler))
2835 printf("%s: %s cpu %d writemem inval start { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, mwa->start, mwa->end);
2836 }
2837 if ((mwa->end & size) != size)
2838 {
2839 if (!track_entry((void *)mwa, (void *)mwa->handler))
2840 printf("%s: %s cpu %d writemem inval end { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, mwa->start, mwa->end);
2841 }
2842 }
2843
2844 if (iora)
2845 for ( ; !IS_MEMPORT_END(iora); iora++)
2846 if (!IS_MEMPORT_MARKER(iora))
2847 {
2848 size_t size = iora->end - iora->start + 1;
2849 if (size)
2850 {
2851 while (!(size & 1)) size >>= 1;
2852 if (size != 1)
2853 {
2854 if (!track_entry((void *)iora, (void *)iora->handler))
2855 printf("%s: %s cpu %d readmem inval size { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, iora->start, iora->end);
2856 }
2857 }
2858 size--;
2859 if ((iora->start & size) != 0)
2860 {
2861 if (!track_entry((void *)iora, (void *)iora->handler))
2862 printf("%s: %s cpu %d readmem inval start { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, iora->start, iora->end);
2863 }
2864 if ((iora->end & size) != size)
2865 {
2866 if (!track_entry((void *)iora, (void *)iora->handler))
2867 printf("%s: %s cpu %d readmem inval end { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, iora->start, iora->end);
2868 }
2869 }
2870
2871 if (iowa)
2872 for ( ; !IS_MEMPORT_END(iowa); iowa++)
2873 if (!IS_MEMPORT_MARKER(iowa))
2874 {
2875 size_t size = iowa->end - iowa->start + 1;
2876 if (size)
2877 {
2878 while (!(size & 1)) size >>= 1;
2879 if (size != 1)
2880 {
2881 if (!track_entry((void *)iowa, (void *)iowa->handler))
2882 printf("%s: %s cpu %d writemem inval size { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, iowa->start, iowa->end);
2883 }
2884 }
2885 size--;
2886 if ((iowa->start & size) != 0)
2887 {
2888 if (!track_entry((void *)iowa, (void *)iowa->handler))
2889 printf("%s: %s cpu %d writemem inval start { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, iowa->start, iowa->end);
2890 }
2891 if ((iowa->end & size) != size)
2892 {
2893 if (!track_entry((void *)iowa, (void *)iowa->handler))
2894 printf("%s: %s cpu %d writemem inval end { %08X, %08X }\n", drivers[i]->source_file, drivers[i]->name, cpunum, iowa->start, iowa->end);
2895 }
2896 }
2897 }
2898 }
2899 }
2900 }
2901 printf("Total busted entries = %d\n", track_count);
2902 printf("Busted entries that are static = %d\n", static_count);
2903 }
2904 #endif

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26