Test initialisation of MUIA_List_AdjustWidth and MUIA_List_AdjustHeight, and
[AROS.git] / arch / .unmaintained / m68k-pp-native / xcopilotpatch / memory.c
blob1835a15800f8c6aae28d940e54b681ae604e8c50
1 /*****************************************************************************
3 XCopilot
5 This code is part of XCopilot, a port of copilot
7 Portions of this code are Copyright (C) 1997 Ivan A. Curtis
8 icurtis@radlogic.com.au
10 The original MS-Windows95 copilot emulator was written by Greg Hewgill.
11 The following copyright notice appeared on the original copilot sources:
13 Copyright (c) 1996 Greg Hewgill
15 MC68000 Emulation code is from Bernd Schmidt's Unix Amiga Emulator.
16 The following copyright notice appeared in those files:
18 Original UAE code Copyright (c) 1995 Bernd Schmidt
20 This code must not be distributed without these copyright notices intact.
22 *******************************************************************************
23 *******************************************************************************
25 Filename: memory.c
27 Description: Copilot Memory management
29 Update History: (most recent first)
30 Ian Goldberg 26-Jun-98 12:40 -- generalized memory mappings
31 Ian Goldberg 11-Sep-97 09:48 -- added bus error support
32 Brian Grossman 14-Jul-97 15:00 -- $XCOPILOTRAM is now a filename
33 Ian Goldberg 18-Apr-97 11:13 -- can now have multiple RAM files
34 Ian Goldberg 10-Apr-97 16:43 -- support for Palm Pilot ROM
35 I. Curtis 5-Mar-97 21:47 -- mmapped scratchmemory and pilotram
36 rom_wput() routine now actually does something
37 I. Curtis 26-Feb-97 14:59 -- modified from win95 version
39 ******************************************************************************/
40 #include <config.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <sys/mman.h>
45 #include <sys/ipc.h>
46 #include <sys/shm.h>
47 #include <fcntl.h>
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <string.h>
51 #include <netinet/in.h>
53 #include "sysdeps.h"
54 #include "shared.h"
55 #include "memory.h"
57 int ram_size;
58 int ram_size_mask;
59 int rom_size;
60 extern shared_img *Shptr;
62 int sram_protect = 1;
63 int buserr = 0;
64 addrbank *membanks;
66 /* Default memory access functions */
68 int default_check(CPTR a, ULONG b)
70 return 0;
73 UWORD *default_xlate(CPTR a)
75 /* fprintf(stderr, "Your Pilot program just did something terribly stupid\n"); */
76 return 0;
79 /* A dummy bank that only contains zeros */
81 static ULONG dummy_lget(CPTR);
82 static UWORD dummy_wget(CPTR);
83 static UBYTE dummy_bget(CPTR);
84 static void dummy_lput(CPTR, ULONG);
85 static void dummy_wput(CPTR, UWORD);
86 static void dummy_bput(CPTR, UBYTE);
87 static int dummy_check(CPTR addr, ULONG size);
88 static UWORD *dummy_xlate(CPTR addr);
90 ULONG dummy_lget(CPTR addr)
92 fprintf(stderr,
93 "Bus error: read a long from undefined memory address 0x%08lx\n",
94 addr);
95 buserr = 1;
96 return 0;
99 UWORD dummy_wget(CPTR addr)
101 if ((addr & 0xFF000000) != 0x10000000) {
102 fprintf(stderr,
103 "Bus error: read a word from undefined memory address 0x%08lx\n",
104 addr);
105 buserr = 1;
107 return 0;
110 UBYTE dummy_bget(CPTR addr)
112 fprintf(stderr,
113 "Bus error: read a byte from undefined memory address 0x%08lx\n",
114 addr);
115 buserr = 1;
116 return 0;
119 void dummy_lput(CPTR addr, ULONG l)
121 fprintf(stderr,
122 "Bus error: wrote a long to undefined memory address 0x%08lx (@ %x)\n",
123 addr,Shptr->regs.pc);
124 buserr = 1;
127 void dummy_wput(CPTR addr, UWORD w)
129 if ((addr & 0xFF000000) != 0x10000000) {
130 fprintf(stderr,
131 "Bus error: wrote a word to undefined memory address 0x%08lx (@ %x)\n",
132 addr,Shptr->regs.pc);
133 buserr = 1;
137 void dummy_bput(CPTR addr, UBYTE b)
139 fprintf(stderr,
140 "Bus error: wrote a byte to undefined memory address 0x%08lx (@ %x)\n",
141 addr,Shptr->regs.pc);
142 buserr = 1;
145 int dummy_check(CPTR addr, ULONG size)
147 return 0;
150 UWORD *dummy_xlate(CPTR addr)
152 return NULL;
155 /* stegerg: AROS: debug output bank */
157 ULONG debug_lget(CPTR addr)
159 fprintf(stderr,
160 "debug_bank: unexpected long read from memory address 0x%08lx\n",
161 addr);
162 return 0;
165 UWORD debug_wget(CPTR addr)
167 fprintf(stderr,
168 "debug_bank: unexpected word read from memory address 0x%08lx\n",
169 addr);
170 return 0;
173 UBYTE debug_bget(CPTR addr)
175 fprintf(stderr,
176 "debug_bank: unexpected byte read from memory address 0x%08lx\n",
177 addr);
178 return 0;
181 void debug_lput(CPTR addr, ULONG l)
183 fprintf(stderr,
184 "debug_bank: unexpected long write to memory address 0x%08lx (@ %x)\n",
185 addr,Shptr->regs.pc);
188 void debug_wput(CPTR addr, UWORD w)
190 fprintf(stderr,
191 "debug_bank: unexpected word write to memory address 0x%08lx (@ %x)\n",
192 addr,Shptr->regs.pc);
195 void debug_bput(CPTR addr, UBYTE b)
197 /* Debug output from AROS :-) */
199 if (addr == 0xdddddebc)
201 if (b) fprintf(stderr, "%c", b);
203 else
205 fprintf(stderr,
206 "debug_bank: unexpected byte write to memory address 0x%08lx (@ %x)\n",
207 addr,Shptr->regs.pc);
212 int debug_check(CPTR addr, ULONG size)
214 return 0;
217 UWORD *debug_xlate(CPTR addr)
219 return NULL;
222 /* RAM */
224 UWORD *rammemory;
226 static ULONG ram_lget(CPTR);
227 static UWORD ram_wget(CPTR);
228 static UBYTE ram_bget(CPTR);
229 static void ram_lput(CPTR, ULONG);
230 static void ram_wput(CPTR, UWORD);
231 static void ram_bput(CPTR, UBYTE);
232 static int ram_check(CPTR addr, ULONG size);
233 static UWORD *ram_xlate(CPTR addr);
235 ULONG ram_lget(CPTR addr)
237 addr -= ram_start & (ram_size_mask);
238 addr &= ram_size_mask;
239 return ((ULONG)rammemory[addr >> 1] << 16) | rammemory[(addr >> 1)+1];
242 UWORD ram_wget(CPTR addr)
244 addr -= ram_start & (ram_size_mask);
245 addr &= ram_size_mask;
246 return rammemory[addr >> 1];
249 UBYTE ram_bget(CPTR addr)
251 addr -= ram_start & (ram_size_mask);
252 addr &= ram_size_mask;
253 if (addr & 1)
254 return rammemory[addr >> 1];
255 else
256 return rammemory[addr >> 1] >> 8;
259 void ram_lput(CPTR addr, ULONG l)
261 addr -= ram_start & (ram_size_mask);
262 addr &= ram_size_mask;
263 rammemory[addr >> 1] = l >> 16;
264 rammemory[(addr >> 1)+1] = (UWORD)l;
267 void sram_lput(CPTR addr, ULONG l)
269 if (sram_protect) {
270 fprintf(stderr,
271 "Bus error: wrote a long to database RAM address 0x%08lx\n", addr);
272 buserr = 1;
273 } else {
274 ram_lput(addr, l);
278 void ram_wput(CPTR addr, UWORD w)
280 addr -= ram_start & (ram_size_mask);
281 addr &= ram_size_mask;
282 rammemory[addr >> 1] = w;
285 void sram_wput(CPTR addr, UWORD w)
287 if (sram_protect) {
288 fprintf(stderr,
289 "Bus error: wrote a word to database RAM address 0x%08lx\n", addr);
290 buserr = 1;
291 } else {
292 ram_wput(addr, w);
296 void ram_bput(CPTR addr, UBYTE b)
298 addr -= ram_start & (ram_size_mask);
299 addr &= ram_size_mask;
300 if (!(addr & 1)) {
301 rammemory[addr>>1] = (rammemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
302 } else {
303 rammemory[addr>>1] = (rammemory[addr>>1] & 0xff00) | b;
307 void sram_bput(CPTR addr, UBYTE b)
309 if (sram_protect) {
310 fprintf(stderr,
311 "Bus error: wrote a byte to database RAM address 0x%08lx\n", addr);
312 buserr = 1;
313 } else {
314 ram_bput(addr, b);
318 int ram_check(CPTR addr, ULONG size)
320 addr -= ram_start & (ram_size_mask);
321 addr &= ram_size_mask;
322 return (addr + size) <= (ULONG)ram_size;
325 UWORD *ram_xlate(CPTR addr)
327 addr -= ram_start & (ram_size_mask);
328 addr &= ram_size_mask;
329 return rammemory + (addr >> 1);
332 /* ROM */
334 static UWORD *rommemory;
336 static ULONG rom_lget(CPTR);
337 static UWORD rom_wget(CPTR);
338 static UBYTE rom_bget(CPTR);
339 static void rom_lput(CPTR, ULONG);
340 static void rom_wput(CPTR, UWORD);
341 static void rom_bput(CPTR, UBYTE);
342 static int rom_check(CPTR addr, ULONG size);
343 static UWORD *rom_xlate(CPTR addr);
345 ULONG rom_lget(CPTR addr)
347 addr -= rom_start & (rom_size-1);
348 addr &= rom_size-1;
349 return ((ULONG)rommemory[addr >> 1] << 16) | rommemory[(addr >> 1)+1];
352 UWORD rom_wget(CPTR addr)
354 addr -= rom_start & (rom_size-1);
355 addr &= rom_size-1;
356 return rommemory[addr >> 1];
359 UBYTE rom_bget(CPTR addr)
361 addr -= rom_start & (rom_size-1);
362 addr &= rom_size-1;
363 return rommemory[addr >> 1] >> (addr & 1 ? 0 : 8);
366 void rom_lput(CPTR addr, ULONG b)
368 fprintf(stderr,
369 "Bus error: wrote a long to ROM address 0x%08lx (@ %x)\n", addr,
370 Shptr->regs.pc);
371 buserr = 1;
374 void rom_wput(CPTR addr, UWORD w)
376 if (Shptr->allowromwrites) {
377 addr -= rom_start & (rom_size - 1);
378 addr &= rom_size - 1;
379 rommemory[addr >> 1] = w;
380 } else {
381 fprintf(stderr,
382 "Bus error: wrote a word to ROM address 0x%08lx\n", addr);
383 buserr = 1;
387 void rom_bput(CPTR addr, UBYTE b)
389 fprintf(stderr,
390 "Bus error: wrote a byte to ROM address 0x%08lx\n", addr);
391 buserr = 1;
394 int rom_check(CPTR addr, ULONG size)
396 addr -= rom_start & (rom_size-1);
397 addr &= rom_size-1;
398 return (addr + size) <= rom_size;
401 UWORD *rom_xlate(CPTR addr)
403 addr -= rom_start & (rom_size-1);
404 addr &= rom_size-1;
405 return rommemory + (addr >> 1);
408 static int
409 verify_entrypoint(const void *rom)
411 const unsigned char _bootsign[] = { 0x4e, 0xfa, 0x00, 0x00, 'b', 'o', 'o', 't',
412 0x27, 0x10, 0xff };
413 const unsigned char _bootmask[] = { 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
414 0xff, 0xff, 0x00 };
416 const unsigned char *bootsign = _bootsign, *bootmask = _bootmask;
418 while ((*bootsign & *bootmask) == *bootsign)
419 if ((*((char *)rom)++ & *bootmask++) != *bootsign++)
420 return 0;
422 return 1;
425 static const char *
426 find_entrypoint(const char *rom)
428 const char *entry = rom;
430 while (entry - rom < rom_size)
432 if (verify_entrypoint(entry))
433 return entry;
434 else
435 entry += 2; /* Instructions must be word aligned */
438 return NULL;
441 /* This routine replaces the win_load_rom routine */
442 /* It was grabbed from copilot-linux sources */
443 static int load_rom(const char *dir, const char *romfile, int nocheck)
445 int i;
446 char *rombuf;
447 char *resetv;
448 int f;
449 struct stat st;
451 if (romfile[0] != '/' && dir) {
452 rombuf = alloca(strlen(dir)+strlen(romfile)+2);
453 if (!rombuf) {
454 printf("%d\n",__LINE__);
455 return PILOTCPU_ERROR_LOADING_ROM;
457 sprintf(rombuf, "%s/%s", dir, romfile);
458 romfile = rombuf;
460 f = open(romfile, O_RDONLY);
461 if (f == -1) {
462 printf("%d (%s)\n",__LINE__,romfile);
463 return PILOTCPU_ROM_NOT_FOUND;
465 if (fstat(f, &st)) {
466 close(f);
467 printf("%d\n",__LINE__);
468 return PILOTCPU_ROM_NOT_FOUND;
470 rom_size = st.st_size;
471 /* Round up to the next power of two */
472 if (rom_size & (rom_size-1)) {
473 /* It is not already a power of two */
474 int pow_of_2;
475 for(pow_of_2 = 1; pow_of_2 < rom_size; pow_of_2 <<= 1) ;
476 rom_size = pow_of_2;
479 rommemory = (UWORD*)mmap(0, rom_size, PROT_READ|PROT_WRITE,
480 MAP_FILE|MAP_PRIVATE, f, 0);
481 if (rommemory == (UWORD *)-1) {
482 printf("%d\n",__LINE__);
483 return PILOTCPU_ERROR_LOADING_ROM;
486 if (!nocheck) {
487 /* Check if the reset vector looks plausible */
488 printf("%d\n",__LINE__);
489 resetv = (char *)rommemory +
490 (ntohl(*(CPTR *)(((char *)rommemory)+4)) - rom_start);
491 printf("resetv: %x, rom_start: %x, rommemory: %x\n",
492 resetv,rom_start,rommemory);
494 if (!verify_entrypoint(resetv)) {
495 int offset;
496 int pageoffset;
497 void *newrom;
498 printf("%d\n",__LINE__);
500 /* It didn't - we need to find it */
501 if (1 != ntohs(*(UWORD *)(((char *)rommemory)+0x0c))) {
502 offset = ntohl(*(CPTR *)(((char *)rommemory)+0x68)) +
503 sram_start - rom_start;
505 else {
506 printf("%d\n",__LINE__);
507 offset = resetv - find_entrypoint((char *)rommemory);
510 /* Did we find it? If not, lets go with the original. */
511 if ((char *)offset != resetv) {
512 /* It may not always be page aligned... */
513 pageoffset = ((offset-1) & ~(getpagesize() - 1)) + getpagesize();
515 if ((st.st_size + offset) > rom_size)
516 rom_size <<= 1;
518 rommemory = (UWORD *)mmap((void*)(rommemory + pageoffset),
519 rom_size - pageoffset,
520 PROT_READ | PROT_WRITE,
521 MAP_FILE | MAP_PRIVATE | MAP_FIXED, f, 0);
522 if (rommemory == (UWORD *)-1) {
523 printf("%d\n",__LINE__);
524 return PILOTCPU_ERROR_LOADING_ROM;
527 memcpy(((char *)rommemory) - offset, rommemory, 256);
528 ((char *)rommemory) -= offset;
531 printf("%d\n",__LINE__);
534 #ifndef WORDS_BIGENDIAN
535 for (i = 0; i < rom_size/2; i++) {
536 UWORD *p;
537 UBYTE *bp;
538 p = rommemory + i;
539 bp = (UBYTE *)p;
540 *p = (*bp << 8) | *(bp + 1);
542 #endif
544 close(f);
545 return 0;
548 /* Scratch area */
550 UBYTE *scratchmemory = NULL;
552 static ULONG scratch_lget(CPTR);
553 static UWORD scratch_wget(CPTR);
554 static UBYTE scratch_bget(CPTR);
555 static void scratch_lput(CPTR, ULONG);
556 static void scratch_wput(CPTR, UWORD);
557 static void scratch_bput(CPTR, UBYTE);
558 static int scratch_check(CPTR addr, ULONG size);
559 static UWORD *scratch_xlate(CPTR addr);
561 ULONG scratch_lget(CPTR addr)
563 if (scratchmemory == NULL) return dummy_lget(addr);
564 addr -= scratch_start;
565 return ((ULONG)scratchmemory[addr] << 24)
566 | ((ULONG)scratchmemory[addr+1] << 16)
567 | ((ULONG)scratchmemory[addr+2] << 8)
568 | scratchmemory[addr+3];
571 UWORD scratch_wget(CPTR addr)
573 if (scratchmemory == NULL) return dummy_wget(addr);
574 addr -= scratch_start;
575 return ((UWORD)scratchmemory[addr] << 8) | scratchmemory[addr+1];
578 UBYTE scratch_bget(CPTR addr)
580 if (scratchmemory == NULL) return dummy_lget(addr);
581 addr -= scratch_start;
582 return scratchmemory[addr];
585 void scratch_lput(CPTR addr, ULONG l)
587 if (scratchmemory == NULL) return;
588 addr -= scratch_start;
589 scratchmemory[addr] = l >> 24;
590 scratchmemory[addr+1] = l >> 16;
591 scratchmemory[addr+2] = l >> 8;
592 scratchmemory[addr+3] = l;
595 void scratch_wput(CPTR addr, UWORD w)
597 if (scratchmemory == NULL) return;
598 addr -= scratch_start;
599 scratchmemory[addr] = w >> 8;
600 scratchmemory[addr+1] = w;
603 void scratch_bput(CPTR addr, UBYTE b)
605 if (scratchmemory == NULL) return;
606 addr -= scratch_start;
607 scratchmemory[addr] = b;
610 int scratch_check(CPTR addr, ULONG size)
612 if (scratchmemory == NULL) return 0;
613 return 1;
616 UWORD *scratch_xlate(CPTR addr)
618 return NULL; /* anything that calls this will assume swapped byte order! */
621 /* Address banks */
623 addrbank dummy_bank = {
624 dummy_lget, dummy_wget, dummy_bget,
625 dummy_lput, dummy_wput, dummy_bput,
626 dummy_xlate, dummy_check
629 addrbank ram_bank = {
630 ram_lget, ram_wget, ram_bget,
631 ram_lput, ram_wput, ram_bput,
632 ram_xlate, ram_check
635 addrbank sram_bank = {
636 ram_lget, ram_wget, ram_bget,
637 sram_lput, sram_wput, sram_bput,
638 ram_xlate, ram_check
641 addrbank rom_bank = {
642 rom_lget, rom_wget, rom_bget,
643 rom_lput, rom_wput, rom_bput,
644 rom_xlate, rom_check
647 addrbank scratch_bank = {
648 scratch_lget, scratch_wget, scratch_bget,
649 scratch_lput, scratch_wput, scratch_bput,
650 scratch_xlate, scratch_check
653 addrbank debug_bank = {
654 debug_lget, debug_wget, debug_bget,
655 debug_lput, debug_wput, debug_bput,
656 debug_xlate, debug_check
659 void map_banks(addrbank bank, int start, int size)
661 int bnr;
662 for (bnr = start; bnr < start+size; bnr++)
663 membanks[bnr] = bank;
666 #ifdef NEED_FTRUNCATE
668 /* -*-Mode: C;-*-
670 * MODULE: ftruncate.c
672 * AUTHORS: HO Harry Ohlsen harryo@ise.com.au
673 * RF Rick Flower rick.flower@trw.com
675 * PURPOSE: Supplementary library function for ftruncate();
677 * USAGE:
679 * This routine is used to augment systems which don't have access
680 * to the ftruncate() system library function (such as SunOS).
681 * This routine tries to mimic as closely as possible the regular
682 * behavior that the standard library function performs, including
683 * the same return error codes where applicable.
685 * This routine will return zero on success and non-zero (-1) on
686 * failure. If it fails, it will also set errno appropriately.
688 * HISTORY:
690 * This routine was snitched from some code originally written by
691 * Harry Ohlsen (see Authors above) and adapted by Rick Flower
692 * for this specific purpose.
694 #include <sys/types.h>
695 #include <unistd.h>
696 #include <errno.h>
698 int ftruncate(int fd, off_t createSize)
700 int bytesToGo = createSize;
701 char *crap;
703 /* We will get problems when we try to write stuff
704 * to the memory segment (it won't end up on disk,
705 * since mmap()-ed things don't extend).
707 crap = (char *)malloc(createSize);
708 errno = 0; /* Reset errno value */
710 (void)memset(crap, 0x00, createSize);
711 while (bytesToGo > 0)
713 int bytesToWrite;
715 if (bytesToGo < createSize)
716 bytesToWrite = bytesToGo;
717 else
718 bytesToWrite = createSize;
720 if (write(fd, crap, bytesToWrite) != bytesToWrite)
722 free(crap); /* Free buffer space used up.. */
723 errno = EIO; /* Set error to indicate I/O error */
724 return(-1); /* Return bad status to caller */
726 bytesToGo -= bytesToWrite;
728 free(crap); /* Free buffer space used up.. */
729 return(0); /* Return valid status to caller */
731 #endif
734 * This routine replaces the original memory_init
735 * It was taken from copilot-linux sources with minor changes
737 int memory_init(int ramsize, const char *dir, const char *romfile,
738 const char *ramfile, const char *scratchfile, int reset,
739 int check_entrypoint)
741 int i;
742 int f;
743 int res;
744 char *rambuf, *scratchbuf;
746 buserr = 0;
747 if (ramsize & (ramsize-1)) {
748 return PILOTCPU_ERROR_LOADING_RAM;
750 ram_size = ramsize * 1024;
751 ram_size_mask = ram_size - 1;
752 if (ramfile[0] != '/' && dir) {
753 rambuf = alloca(strlen(dir)+strlen(ramfile)+2);
754 if (!rambuf) {
755 return PILOTCPU_ERROR_LOADING_RAM;
757 sprintf(rambuf, "%s/%s", dir, ramfile);
758 ramfile = rambuf;
760 if (reset)
761 f = open(ramfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
762 else
763 f = open(ramfile, O_RDWR|O_CREAT, 0666);
764 if (f == -1) {
765 return PILOTCPU_ERROR_LOADING_RAM;
767 ftruncate(f, ram_size);
768 rammemory = (UWORD*)mmap(0, ram_size, PROT_READ|PROT_WRITE,
769 MAP_FILE|MAP_SHARED, f, 0);
770 if (rammemory == (UWORD*)-1) {
771 return PILOTCPU_ERROR_LOADING_RAM;
773 close(f);
775 if (scratchfile[0] != '/' && dir) {
776 scratchbuf = alloca(strlen(dir)+strlen(scratchfile)+2);
777 if (!scratchbuf) {
778 return PILOTCPU_ERROR_LOADING_RAM;
780 sprintf(scratchbuf, "%s/%s", dir, scratchfile);
781 scratchfile = scratchbuf;
783 f = open(scratchfile, O_RDWR|O_CREAT|O_TRUNC,0666);
784 if (f == -1) {
785 return PILOTCPU_ERROR_LOADING_RAM;
787 ftruncate(f, SCRATCH_SIZE);
788 scratchmemory = (unsigned char*)mmap(0, SCRATCH_SIZE, PROT_READ|PROT_WRITE,
789 MAP_FILE|MAP_SHARED, f, 0);
790 close(f);
792 /* f = open("cpustate", O_RDWR|O_CREAT|O_TRUNC,0666); */
793 /* if (f == -1) { */
794 /* return PILOTCPU_ERROR_LOADING_RAM; */
795 /* } */
796 /* ftruncate(f, state_size); */
798 /* statememory = (char*)mmap(0, state_size, PROT_READ|PROT_WRITE, */
799 /* MAP_FILE|MAP_SHARED, f, 0); */
800 /* close(f); */
802 /* sharedstate = (struct state*)statememory; */
804 /* CpuState = (int*)(sharedstate+1); */
805 /* ExceptionFlags = (int*)(CpuState+1); */
807 membanks = (addrbank *)malloc(65536 * sizeof(addrbank));
808 if (membanks == NULL) {
809 perror("memory_init");
810 exit(1);
813 for(i = 0; i < 65536; i++) {
814 membanks[i] = dummy_bank;
817 #define NUM_BANKS(s) ((s)>>16 + (((s)&0xFFFF) ? 1 : 0))
818 map_banks(ram_bank, ram_start>>16, 16);
819 map_banks(sram_bank, sram_start>>16, NUM_BANKS(ram_size));
820 map_banks(scratch_bank, scratch_start>>16, NUM_BANKS(SCRATCH_SIZE));
821 map_banks(custom_bank, custom_start>>16, 1);
822 res = load_rom(dir, romfile, check_entrypoint);
823 map_banks(rom_bank, rom_start>>16, NUM_BANKS(rom_size));
825 map_banks(debug_bank, 0xDDDD, 1);
827 return res;
830 void mem_setscratchaddr(UBYTE *addr)
832 scratchmemory = addr;
835 unsigned int bankindex(CPTR a)
837 return a>>16;
840 ULONG longget(CPTR addr)
842 return membanks[bankindex(addr)].lget(addr);
845 UWORD wordget(CPTR addr)
847 return membanks[bankindex(addr)].wget(addr);
849 UBYTE byteget(CPTR addr)
851 return membanks[bankindex(addr)].bget(addr);
853 void longput(CPTR addr, ULONG l)
855 membanks[bankindex(addr)].lput(addr, l);
857 void wordput(CPTR addr, UWORD w)
859 membanks[bankindex(addr)].wput(addr, w);
861 void byteput(CPTR addr, UBYTE b)
863 membanks[bankindex(addr)].bput(addr, b);
865 int check_addr(CPTR a)
867 #ifdef NO_EXCEPTION_3
868 return 1;
869 #else
870 return (a & 1) == 0;
871 #endif
874 ULONG get_long(CPTR addr)
876 if (check_addr(addr))
877 return longget(addr);
878 fprintf(stderr,
879 "Bus error: read a long from odd address 0x%08lx (@ %x)\n", addr,
880 Shptr->regs.pc);
881 buserr = 1;
882 return 0;
885 UWORD get_word(CPTR addr)
887 if (check_addr(addr))
888 return wordget(addr);
889 fprintf(stderr,
890 "Bus error: read a word from odd address 0x%08lx (@ %x)\n", addr,Shptr->regs.pc);
891 buserr = 1;
892 return 0;
895 UBYTE get_byte(CPTR addr)
897 return byteget(addr);
900 void put_long(CPTR addr, ULONG l)
902 if (!check_addr(addr)) {
903 fprintf(stderr,
904 "Bus error: wrote a long to odd address 0x%08lx (@ %x)\n", addr,
905 Shptr->regs.pc);
906 buserr = 1;
908 longput(addr, l);
911 void put_word(CPTR addr, UWORD w)
913 if (!check_addr(addr)) {
914 fprintf(stderr,
915 "Bus error: wrote a word to odd address 0x%08lx (@ %x)\n", addr,Shptr->regs.pc);
916 buserr = 1;
918 wordput(addr, w);
921 void put_byte(CPTR addr, UBYTE b)
923 byteput(addr, b);
926 UWORD *get_real_address(CPTR addr)
928 if (!check_addr(addr)) {
929 fprintf(stderr,
930 "Bus error: attempted translation of odd address 0x%08lx (pc = %x, a7 = %x)\n", addr,Shptr->regs.pc,Shptr->regs.a[7]);
931 buserr = 1;
933 return membanks[bankindex(addr)].xlateaddr(addr);
936 int valid_address(CPTR addr, ULONG size)
938 if (!check_addr(addr)) {
939 fprintf(stderr,
940 "Bus error: attempted validation of odd address 0x%08lx (@ %x)\n", addr,Shptr->regs.pc);
941 buserr = 1;
943 return membanks[bankindex(addr)].check(addr, size);