]> git.sesse.net Git - pistorm/blob - memory_mapped.c
Rework some emulator stuff, update sample X68000 config for OVL
[pistorm] / memory_mapped.c
1 #include "config_file/config_file.h"
2 #include "m68k.h"
3 #include "Gayle.h"
4 #include <endian.h>
5
6 #define CHKRANGE(a, b, c) a >= (unsigned int)b && a < (unsigned int)(b + c)
7
8 static unsigned int target;
9
10 extern const char *map_type_names[MAPTYPE_NUM];
11 const char *op_type_names[OP_TYPE_NUM] = {
12   "BYTE",
13   "WORD",
14   "LONGWORD",
15   "MEM",
16 };
17
18 int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type, unsigned char mirror) {
19   unsigned char *read_addr = NULL;
20   char handle_regs = 0;
21
22   //printf("Mapped read: %.8x\n", addr);
23
24   for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) {
25     if (cfg->map_type[i] == MAPTYPE_NONE)
26       continue;
27     switch(cfg->map_type[i]) {
28       case MAPTYPE_ROM:
29         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
30           read_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
31         else if (cfg->map_mirror[i] != -1 && mirror && CHKRANGE(addr, cfg->map_mirror[i], cfg->map_size[i]))
32           read_addr = cfg->map_data[i] + (addr - cfg->map_mirror[i]);
33         break;
34       case MAPTYPE_RAM:
35         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
36           read_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
37         break;
38       case MAPTYPE_REGISTER:
39         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
40           handle_regs = 1;
41         break;
42     }
43
44     if (!read_addr && !handle_regs)
45       continue;
46     
47     if (handle_regs) {
48       if (handle_register_read(addr, type, &target) != -1) {
49         *val = target;
50         return 1;
51       }
52       return -1;
53     }
54     else if (read_addr) {
55       //printf("[PC: %.8X] Read %s from %s (%.8X) (%d)\n", m68k_get_reg(NULL, M68K_REG_PC), op_type_names[type], map_type_names[cfg->map_type[i]], addr, mirror);
56       //printf("Readaddr: %.8lX (Base %.8lX\n", (uint64_t)(read_addr), (uint64_t)cfg->map_data[i]);
57       switch(type) {
58         case OP_TYPE_BYTE:
59           *val = read_addr[0];
60           //printf("Read val: %.8lX (%d)\n", (uint64_t)val, *val);
61           return 1;
62           break;
63         case OP_TYPE_WORD:
64           *val = be16toh(((unsigned short *)read_addr)[0]);
65           //printf("Read val: %.8lX (%d)\n", (uint64_t)val, *val);
66           return 1;
67           break;
68         case OP_TYPE_LONGWORD:
69           *val = be32toh(((unsigned int *)read_addr)[0]);
70           //printf("Read val: %.8lX (%d)\n", (uint64_t)val, *val);
71           return 1;
72           break;
73         case OP_TYPE_MEM:
74           return -1;
75           break;
76       }
77     }
78   }
79
80   return -1;
81 }
82
83 int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, unsigned int value, unsigned char type, unsigned char mirror) {
84   unsigned char *write_addr = NULL;
85   char handle_regs = 0;
86
87   //printf("Mapped write: %.8x\n", addr);
88   if (mirror) { }
89
90   for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) {
91     if (cfg->map_type[i] == MAPTYPE_NONE)
92       continue;
93     switch(cfg->map_type[i]) {
94       case MAPTYPE_ROM:
95         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
96           return 1;
97         break;
98       case MAPTYPE_RAM:
99         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
100           write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
101         break;
102       case MAPTYPE_REGISTER:
103         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
104           handle_regs = 1;
105         break;
106     }
107
108     if (!write_addr && !handle_regs)
109       continue;
110     
111     if (handle_regs) {
112       return handle_register_write(addr, value, type);
113     }
114     else if (write_addr) {
115       //printf("[PC: %.8X] Write %s to %s (%.8X) (%d)\n", m68k_get_reg(NULL, M68K_REG_PC), op_type_names[type], map_type_names[cfg->map_type[i]], addr, mirror);
116       //printf("Writeaddr: %.8lX (Base %.8lX\n", (uint64_t)(write_addr), (uint64_t)cfg->map_data[i]);
117       switch(type) {
118         case OP_TYPE_BYTE:
119           write_addr[0] = (unsigned char)value;
120           //printf("Write val: %.8X (%d)\n", (uint32_t)value, value);
121           return 1;
122           break;
123         case OP_TYPE_WORD:
124           ((short *)write_addr)[0] = htobe16(value);
125           //printf("Write val: %.8X (%d)\n", (uint32_t)value, value);
126           return 1;
127           break;
128         case OP_TYPE_LONGWORD:
129           ((int *)write_addr)[0] = htobe32(value);
130           //printf("Write val: %.8X (%d)\n", (uint32_t)value, value);
131           return 1;
132           break;
133         case OP_TYPE_MEM:
134           return -1;
135           break;
136       }
137     }
138   }
139
140   return -1;
141 }