]> git.sesse.net Git - pistorm/blob - memory_mapped.c
Add Meson build files.
[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 || cfg->map_type[i] == MAPTYPE_RAM_WTC)) {
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 (ovl && cfg->map_type[i] == MAPTYPE_RAM_WTC) {
91       if (cfg->map_mirror[i] != ((unsigned int)-1) && CHKRANGE(addr, cfg->map_mirror[i], cfg->map_size[i])) {
92         write_addr = cfg->map_data[i] + ((addr - cfg->map_mirror[i]) % cfg->rom_size[i]);
93         res = -1;
94         goto write_value;
95       }
96     }
97     else if (CHKRANGE_ABS(addr, cfg->map_offset[i], cfg->map_high[i])) {
98       switch(cfg->map_type[i]) {
99         case MAPTYPE_ROM:
100           return 1;
101           break;
102         case MAPTYPE_RAM:
103         case MAPTYPE_RAM_NOALLOC:
104           write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
105           res = 1;
106           goto write_value;
107           break;
108         case MAPTYPE_RAM_WTC:
109           //printf("Some write to WTC RAM.\n");
110           write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
111           res = -1;
112           goto write_value;
113           break;
114         case MAPTYPE_REGISTER:
115           if (cfg->platform && cfg->platform->register_write) {
116             return cfg->platform->register_write(addr, value, type);
117           }
118           break;
119       }
120     }
121   }
122
123   return res;
124
125 write_value:;
126   switch(type) {
127     case OP_TYPE_BYTE:
128       write_addr[0] = (unsigned char)value;
129       return res;
130       break;
131     case OP_TYPE_WORD:
132       ((short *)write_addr)[0] = htobe16(value);
133       return res;
134       break;
135     case OP_TYPE_LONGWORD:
136       ((int *)write_addr)[0] = htobe32(value);
137       return res;
138       break;
139     case OP_TYPE_MEM:
140       return -1;
141       break;
142   }
143
144   // This should never actually happen.
145   return res;
146 }