1 /*****************************************************************************
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 *******************************************************************************
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 ******************************************************************************/
42 #include <sys/types.h>
51 #include <netinet/in.h>
60 extern shared_img
*Shptr
;
66 /* Default memory access functions */
68 int default_check(CPTR a
, ULONG b
)
73 UWORD
*default_xlate(CPTR a
)
75 /* fprintf(stderr, "Your Pilot program just did something terribly stupid\n"); */
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
)
93 "Bus error: read a long from undefined memory address 0x%08lx\n",
99 UWORD
dummy_wget(CPTR addr
)
101 if ((addr
& 0xFF000000) != 0x10000000) {
103 "Bus error: read a word from undefined memory address 0x%08lx\n",
110 UBYTE
dummy_bget(CPTR addr
)
113 "Bus error: read a byte from undefined memory address 0x%08lx\n",
119 void dummy_lput(CPTR addr
, ULONG l
)
122 "Bus error: wrote a long to undefined memory address 0x%08lx (@ %x)\n",
123 addr
,Shptr
->regs
.pc
);
127 void dummy_wput(CPTR addr
, UWORD w
)
129 if ((addr
& 0xFF000000) != 0x10000000) {
131 "Bus error: wrote a word to undefined memory address 0x%08lx (@ %x)\n",
132 addr
,Shptr
->regs
.pc
);
137 void dummy_bput(CPTR addr
, UBYTE b
)
140 "Bus error: wrote a byte to undefined memory address 0x%08lx (@ %x)\n",
141 addr
,Shptr
->regs
.pc
);
145 int dummy_check(CPTR addr
, ULONG size
)
150 UWORD
*dummy_xlate(CPTR addr
)
155 /* stegerg: AROS: debug output bank */
157 ULONG
debug_lget(CPTR addr
)
160 "debug_bank: unexpected long read from memory address 0x%08lx\n",
165 UWORD
debug_wget(CPTR addr
)
168 "debug_bank: unexpected word read from memory address 0x%08lx\n",
173 UBYTE
debug_bget(CPTR addr
)
176 "debug_bank: unexpected byte read from memory address 0x%08lx\n",
181 void debug_lput(CPTR addr
, ULONG l
)
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
)
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
);
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
)
217 UWORD
*debug_xlate(CPTR addr
)
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
;
254 return rammemory
[addr
>> 1];
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
)
271 "Bus error: wrote a long to database RAM address 0x%08lx\n", addr
);
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
)
289 "Bus error: wrote a word to database RAM address 0x%08lx\n", addr
);
296 void ram_bput(CPTR addr
, UBYTE b
)
298 addr
-= ram_start
& (ram_size_mask
);
299 addr
&= ram_size_mask
;
301 rammemory
[addr
>>1] = (rammemory
[addr
>>1] & 0xff) | (((UWORD
)b
) << 8);
303 rammemory
[addr
>>1] = (rammemory
[addr
>>1] & 0xff00) | b
;
307 void sram_bput(CPTR addr
, UBYTE b
)
311 "Bus error: wrote a byte to database RAM address 0x%08lx\n", addr
);
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);
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);
349 return ((ULONG
)rommemory
[addr
>> 1] << 16) | rommemory
[(addr
>> 1)+1];
352 UWORD
rom_wget(CPTR addr
)
354 addr
-= rom_start
& (rom_size
-1);
356 return rommemory
[addr
>> 1];
359 UBYTE
rom_bget(CPTR addr
)
361 addr
-= rom_start
& (rom_size
-1);
363 return rommemory
[addr
>> 1] >> (addr
& 1 ? 0 : 8);
366 void rom_lput(CPTR addr
, ULONG b
)
369 "Bus error: wrote a long to ROM address 0x%08lx (@ %x)\n", addr
,
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
;
382 "Bus error: wrote a word to ROM address 0x%08lx\n", addr
);
387 void rom_bput(CPTR addr
, UBYTE b
)
390 "Bus error: wrote a byte to ROM address 0x%08lx\n", addr
);
394 int rom_check(CPTR addr
, ULONG size
)
396 addr
-= rom_start
& (rom_size
-1);
398 return (addr
+ size
) <= rom_size
;
401 UWORD
*rom_xlate(CPTR addr
)
403 addr
-= rom_start
& (rom_size
-1);
405 return rommemory
+ (addr
>> 1);
409 verify_entrypoint(const void *rom
)
411 const unsigned char _bootsign
[] = { 0x4e, 0xfa, 0x00, 0x00, 'b', 'o', 'o', 't',
413 const unsigned char _bootmask
[] = { 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
416 const unsigned char *bootsign
= _bootsign
, *bootmask
= _bootmask
;
418 while ((*bootsign
& *bootmask
) == *bootsign
)
419 if ((*((char *)rom
)++ & *bootmask
++) != *bootsign
++)
426 find_entrypoint(const char *rom
)
428 const char *entry
= rom
;
430 while (entry
- rom
< rom_size
)
432 if (verify_entrypoint(entry
))
435 entry
+= 2; /* Instructions must be word aligned */
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
)
451 if (romfile
[0] != '/' && dir
) {
452 rombuf
= alloca(strlen(dir
)+strlen(romfile
)+2);
454 printf("%d\n",__LINE__
);
455 return PILOTCPU_ERROR_LOADING_ROM
;
457 sprintf(rombuf
, "%s/%s", dir
, romfile
);
460 f
= open(romfile
, O_RDONLY
);
462 printf("%d (%s)\n",__LINE__
,romfile
);
463 return PILOTCPU_ROM_NOT_FOUND
;
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 */
475 for(pow_of_2
= 1; pow_of_2
< rom_size
; pow_of_2
<<= 1) ;
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
;
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
)) {
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
;
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
)
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
++) {
540 *p
= (*bp
<< 8) | *(bp
+ 1);
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;
616 UWORD
*scratch_xlate(CPTR addr
)
618 return NULL
; /* anything that calls this will assume swapped byte order! */
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
,
635 addrbank sram_bank
= {
636 ram_lget
, ram_wget
, ram_bget
,
637 sram_lput
, sram_wput
, sram_bput
,
641 addrbank rom_bank
= {
642 rom_lget
, rom_wget
, rom_bget
,
643 rom_lput
, rom_wput
, rom_bput
,
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
)
662 for (bnr
= start
; bnr
< start
+size
; bnr
++)
663 membanks
[bnr
] = bank
;
666 #ifdef NEED_FTRUNCATE
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();
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.
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>
698 int ftruncate(int fd
, off_t createSize
)
700 int bytesToGo
= createSize
;
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)
715 if (bytesToGo
< createSize
)
716 bytesToWrite
= bytesToGo
;
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 */
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
)
744 char *rambuf
, *scratchbuf
;
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);
755 return PILOTCPU_ERROR_LOADING_RAM
;
757 sprintf(rambuf
, "%s/%s", dir
, ramfile
);
761 f
= open(ramfile
, O_RDWR
|O_CREAT
|O_TRUNC
, 0666);
763 f
= open(ramfile
, O_RDWR
|O_CREAT
, 0666);
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
;
775 if (scratchfile
[0] != '/' && dir
) {
776 scratchbuf
= alloca(strlen(dir
)+strlen(scratchfile
)+2);
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);
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);
792 /* f = open("cpustate", O_RDWR|O_CREAT|O_TRUNC,0666); */
794 /* return PILOTCPU_ERROR_LOADING_RAM; */
796 /* ftruncate(f, state_size); */
798 /* statememory = (char*)mmap(0, state_size, PROT_READ|PROT_WRITE, */
799 /* MAP_FILE|MAP_SHARED, f, 0); */
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");
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);
830 void mem_setscratchaddr(UBYTE
*addr
)
832 scratchmemory
= addr
;
835 unsigned int bankindex(CPTR a
)
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
874 ULONG
get_long(CPTR addr
)
876 if (check_addr(addr
))
877 return longget(addr
);
879 "Bus error: read a long from odd address 0x%08lx (@ %x)\n", addr
,
885 UWORD
get_word(CPTR addr
)
887 if (check_addr(addr
))
888 return wordget(addr
);
890 "Bus error: read a word from odd address 0x%08lx (@ %x)\n", addr
,Shptr
->regs
.pc
);
895 UBYTE
get_byte(CPTR addr
)
897 return byteget(addr
);
900 void put_long(CPTR addr
, ULONG l
)
902 if (!check_addr(addr
)) {
904 "Bus error: wrote a long to odd address 0x%08lx (@ %x)\n", addr
,
911 void put_word(CPTR addr
, UWORD w
)
913 if (!check_addr(addr
)) {
915 "Bus error: wrote a word to odd address 0x%08lx (@ %x)\n", addr
,Shptr
->regs
.pc
);
921 void put_byte(CPTR addr
, UBYTE b
)
926 UWORD
*get_real_address(CPTR addr
)
928 if (!check_addr(addr
)) {
930 "Bus error: attempted translation of odd address 0x%08lx (pc = %x, a7 = %x)\n", addr
,Shptr
->regs
.pc
,Shptr
->regs
.a
[7]);
933 return membanks
[bankindex(addr
)].xlateaddr(addr
);
936 int valid_address(CPTR addr
, ULONG size
)
938 if (!check_addr(addr
)) {
940 "Bus error: attempted validation of odd address 0x%08lx (@ %x)\n", addr
,Shptr
->regs
.pc
);
943 return membanks
[bankindex(addr
)].check(addr
, size
);