]> git.sesse.net Git - pistorm/blob - memory_mapped.c
Some minor optimizations, hopefully fewer jumps and such
[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 inline 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]) % cfg->rom_size[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]) % cfg->rom_size[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 (cfg->platform && cfg->platform->register_read) {
49         if (cfg->platform->register_read(addr, type, &target) != -1) {
50           *val = target;
51           return 1;
52         }
53       }
54       return -1;
55     }
56     else if (read_addr) {
57       //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);
58       //printf("Readaddr: %.8lX (Base %.8lX\n", (uint64_t)(read_addr), (uint64_t)cfg->map_data[i]);
59       switch(type) {
60         case OP_TYPE_BYTE:
61           *val = read_addr[0];
62           //printf("Read val: %.8lX (%d)\n", (uint64_t)val, *val);
63           return 1;
64           break;
65         case OP_TYPE_WORD:
66           *val = be16toh(((unsigned short *)read_addr)[0]);
67           //printf("Read val: %.8lX (%d)\n", (uint64_t)val, *val);
68           return 1;
69           break;
70         case OP_TYPE_LONGWORD:
71           *val = be32toh(((unsigned int *)read_addr)[0]);
72           //printf("Read val: %.8lX (%d)\n", (uint64_t)val, *val);
73           return 1;
74           break;
75         case OP_TYPE_MEM:
76           return -1;
77           break;
78       }
79     }
80   }
81
82   return -1;
83 }
84
85 inline int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, unsigned int value, unsigned char type, unsigned char mirror) {
86   unsigned char *write_addr = NULL;
87   char handle_regs = 0;
88
89   //printf("Mapped write: %.8x\n", addr);
90   if (mirror) { }
91
92   for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) {
93     if (cfg->map_type[i] == MAPTYPE_NONE)
94       continue;
95     switch(cfg->map_type[i]) {
96       case MAPTYPE_ROM:
97         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
98           return 1;
99         break;
100       case MAPTYPE_RAM:
101         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
102           write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
103         break;
104       case MAPTYPE_REGISTER:
105         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
106           handle_regs = 1;
107         break;
108     }
109
110     if (!write_addr && !handle_regs)
111       continue;
112     
113     if (handle_regs) {
114       if (cfg->platform && cfg->platform->register_write) {
115         return cfg->platform->register_write(addr, value, type);
116       }
117     }
118     else if (write_addr) {
119       //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);
120       //printf("Writeaddr: %.8lX (Base %.8lX\n", (uint64_t)(write_addr), (uint64_t)cfg->map_data[i]);
121       switch(type) {
122         case OP_TYPE_BYTE:
123           write_addr[0] = (unsigned char)value;
124           //printf("Write val: %.8X (%d)\n", (uint32_t)value, value);
125           return 1;
126           break;
127         case OP_TYPE_WORD:
128           ((short *)write_addr)[0] = htobe16(value);
129           //printf("Write val: %.8X (%d)\n", (uint32_t)value, value);
130           return 1;
131           break;
132         case OP_TYPE_LONGWORD:
133           ((int *)write_addr)[0] = htobe32(value);
134           //printf("Write val: %.8X (%d)\n", (uint32_t)value, value);
135           return 1;
136           break;
137         case OP_TYPE_MEM:
138           return -1;
139           break;
140       }
141     }
142   }
143
144   return -1;
145 }