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