]> git.sesse.net Git - pistorm/blob - memory_mapped.c
Add write-through cached RAM for Mac experiments
[pistorm] / memory_mapped.c
1 // SPDX-License-Identifier: MIT
2
3 #include "config_file/config_file.h"
4 #include "m68k.h"
5 #include "platforms/amiga/Gayle.h"
6 #include <endian.h>
7
8 #define CHKRANGE(a, b, c) a >= (unsigned int)b && a < (unsigned int)(b + c)
9 #define CHKRANGE_ABS(a, b, c) a >= (unsigned int)b && a < (unsigned int) c
10
11 static unsigned int target;
12 extern int ovl;
13
14 extern const char *map_type_names[MAPTYPE_NUM];
15 const char *op_type_names[OP_TYPE_NUM] = {
16   "BYTE",
17   "WORD",
18   "LONGWORD",
19   "MEM",
20 };
21
22 inline int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type) {
23   unsigned char *read_addr = NULL;
24
25   for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) {
26     if (cfg->map_type[i] == MAPTYPE_NONE)
27       continue;
28     else if (ovl && cfg->map_type[i] == MAPTYPE_ROM) {
29       if (cfg->map_mirror[i] != ((unsigned int)-1) && CHKRANGE(addr, cfg->map_mirror[i], cfg->map_size[i])) {
30         read_addr = cfg->map_data[i] + ((addr - cfg->map_mirror[i]) % cfg->rom_size[i]);
31         goto read_value;
32       }
33     }
34     if (CHKRANGE_ABS(addr, cfg->map_offset[i], cfg->map_high[i])) {
35       switch(cfg->map_type[i]) {
36         case MAPTYPE_ROM:
37           read_addr = cfg->map_data[i] + ((addr - cfg->map_offset[i]) % cfg->rom_size[i]);
38           goto read_value;
39           break;
40         case MAPTYPE_RAM:
41         case MAPTYPE_RAM_WTC:
42         case MAPTYPE_RAM_NOALLOC:
43           read_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
44           goto read_value;
45           break;
46         case MAPTYPE_REGISTER:
47           if (cfg->platform && cfg->platform->register_read) {
48             if (cfg->platform->register_read(addr, type, &target) != -1) {
49               *val = target;
50               return 1;
51             }
52           }
53           return -1;
54           break;
55       }
56     }
57   }
58
59   return -1;
60
61 read_value:;
62   switch(type) {
63     case OP_TYPE_BYTE:
64       *val = read_addr[0];
65       return 1;
66       break;
67     case OP_TYPE_WORD:
68       *val = be16toh(((unsigned short *)read_addr)[0]);
69       return 1;
70       break;
71     case OP_TYPE_LONGWORD:
72       *val = be32toh(((unsigned int *)read_addr)[0]);
73       return 1;
74       break;
75     case OP_TYPE_MEM:
76       return -1;
77       break;
78   }
79
80   return 1;
81 }
82
83 inline int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, unsigned int value, unsigned char type) {
84   int res = -1;
85   unsigned char *write_addr = NULL;
86
87   for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) {
88     if (cfg->map_type[i] == MAPTYPE_NONE)
89       continue;
90     else if (CHKRANGE_ABS(addr, cfg->map_offset[i], cfg->map_high[i])) {
91       switch(cfg->map_type[i]) {
92         case MAPTYPE_ROM:
93           res = 1;
94           break;
95         case MAPTYPE_RAM:
96         case MAPTYPE_RAM_NOALLOC:
97           write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
98           res = 1;
99           goto write_value;
100           break;
101         case MAPTYPE_RAM_WTC:
102           write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
103           res = -1;
104           goto write_value;
105           break;
106         case MAPTYPE_REGISTER:
107           if (cfg->platform && cfg->platform->register_write) {
108             return cfg->platform->register_write(addr, value, type);
109           }
110           break;
111       }
112     }
113   }
114
115   return res;
116
117 write_value:;
118   switch(type) {
119     case OP_TYPE_BYTE:
120       write_addr[0] = (unsigned char)value;
121       return res;
122       break;
123     case OP_TYPE_WORD:
124       ((short *)write_addr)[0] = htobe16(value);
125       return res;
126       break;
127     case OP_TYPE_LONGWORD:
128       ((int *)write_addr)[0] = htobe32(value);
129       return res;
130       break;
131     case OP_TYPE_MEM:
132       return -1;
133       break;
134   }
135
136   // This should never actually happen.
137   return res;
138 }