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