2 * Main memory for FM-7 [FM7_MAINMEM/MAINMEM_MMR]
10 #include "fm7_mainmem.h"
14 int FM7_MAINMEM::window_convert(uint32_t addr, uint32_t *realaddr)
16 uint32_t raddr = addr;
18 if((addr < 0x8000) && (addr >= 0x7c00)) {
19 raddr = ((window_offset * 256) + addr) & 0x0ffff;
21 #ifdef _FM77AV_VARIANTS
22 //printf("TWR hit %04x -> %04x\n", addr, raddr);
23 return FM7_MAINMEM_AV_PAGE0; // 0x00000 - 0x0ffff
24 #else // FM77(L4 or others)
26 return FM7_MAINMEM_EXTRAM; // 0x20000 - 0x2ffff
34 void FM7_MAINMEM::update_mmr_jumptable(uint32_t pos)
37 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
38 if(pos >= 0x80) return;
40 if(pos >= 0x40) return;
42 uint32_t n_pos = pos * (0x1000 / 0x80);
44 uint8_t mmr_index = mmr_map_data[pos];
45 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
46 uint32_t r_pos_ext = mmr_index * (0x1000 / 0x80);
48 uint32_t r_pos_nor = (mmr_index & 0x3f) * (0x1000 / 0x80);
51 raddr_ext = (mmr_index << 12);
52 raddr_nor = ((mmr_index & 0x3f) << 12);
54 for(i = 0; i < (0x1000 / 0x80); i++) {
55 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
56 mmr_bank_table[n_pos] = mmr_index;
57 mmr_baseaddr_table_ext[i + n_pos] = raddr_ext;
58 if((mmr_index >= 0x40) && !(extram_connected)) {
59 mmr_update_table_ext[i + n_pos].read_data = NULL;
60 mmr_update_table_ext[i + n_pos].write_data = NULL;
61 mmr_update_table_ext[i + n_pos].read_func = NULL;
62 mmr_update_table_ext[i + n_pos].write_func = NULL;
64 if(mmr_index != 0x3f) {
65 mmr_update_table_ext[i + n_pos].read_data = data_table[r_pos_ext + i].read_data;
66 mmr_update_table_ext[i + n_pos].write_data = data_table[r_pos_ext + i].write_data;
67 mmr_update_table_ext[i + n_pos].read_func = data_table[r_pos_ext + i].read_func;
68 mmr_update_table_ext[i + n_pos].write_func = data_table[r_pos_ext + i].write_func;
70 mmr_update_table_ext[i + n_pos].read_data = NULL;
71 mmr_update_table_ext[i + n_pos].write_data = NULL;
72 mmr_update_table_ext[i + n_pos].read_func = &FM7_MAINMEM::read_segment_3f;
73 mmr_update_table_ext[i + n_pos].write_func = &FM7_MAINMEM::write_segment_3f;
77 mmr_baseaddr_table_nor[i + n_pos] = raddr_nor;
79 # if defined(_FM77_VARIANTS)
80 if(mmr_index < 0x30) {
81 if(!extram_connected) {
82 mmr_update_table_nor[i + n_pos].read_data = NULL;
83 mmr_update_table_nor[i + n_pos].write_data = NULL;
84 mmr_update_table_nor[i + n_pos].read_func = NULL;
85 mmr_update_table_nor[i + n_pos].write_func = NULL;
90 if(mmr_index != 0x3f) {
91 mmr_update_table_nor[i + n_pos].read_data = data_table[r_pos_nor + i].read_data;
92 mmr_update_table_nor[i + n_pos].write_data = data_table[r_pos_nor + i].write_data;
93 mmr_update_table_nor[i + n_pos].read_func = data_table[r_pos_nor + i].read_func;
94 mmr_update_table_nor[i + n_pos].write_func = data_table[r_pos_nor + i].write_func;
96 mmr_update_table_nor[i + n_pos].read_data = NULL;
97 mmr_update_table_nor[i + n_pos].write_data = NULL;
98 mmr_update_table_nor[i + n_pos].read_func = &FM7_MAINMEM::read_segment_3f;
99 mmr_update_table_nor[i + n_pos].write_func = &FM7_MAINMEM::write_segment_3f;
105 void FM7_MAINMEM::update_all_mmr_jumptable(void)
109 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
110 for(i = 0; i < 0x80; i++) {
111 update_mmr_jumptable(i);
114 for(i = 0; i < 0x40; i++) {
115 update_mmr_jumptable(i);
121 uint8_t FM7_MAINMEM::read_segment_3f(uint32_t addr, bool dmamode)
124 uint32_t raddr = addr & 0x0fff;
125 # ifdef _FM77AV_VARIANTS
126 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
129 raddr = raddr | 0x3f000;
130 return read_data_tbl(raddr, dmamode);
132 # elif defined(_FM77_VARIANTS)
133 if((raddr >= 0xc00) && (raddr < 0xe00)) {
137 raddr = raddr - 0xc00;
138 return fm77_shadowram[raddr];
140 } else if(raddr >= 0xe00) {
141 raddr = raddr - 0x0e00;
143 if(diag_load_bootrom_mmr) {
144 return fm7_bootroms[2][raddr];
146 return fm7_bootroms[0][raddr];
149 return fm7_bootram[raddr];
152 raddr = raddr | 0x3f000;
153 return read_data_tbl(raddr, dmamode);
161 void FM7_MAINMEM::write_segment_3f(uint32_t addr, uint32_t data, bool dmamode)
164 uint32_t raddr = addr & 0x0fff;
165 # ifdef _FM77AV_VARIANTS
166 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
169 raddr = raddr | 0x3f000;
170 write_data_tbl(raddr, data, dmamode);
173 # elif defined(_FM77_VARIANTS)
174 if((raddr >= 0xc00) && (raddr < 0xe00)) {
178 raddr = raddr - 0xc00;
179 fm77_shadowram[raddr] = (uint8_t)data;
182 } else if(raddr >= 0xe00) {
183 raddr = raddr - 0x0e00;
185 fm7_bootram[raddr] = (uint8_t)data;
188 raddr = raddr | 0x3f000;
189 write_data_tbl(raddr, data, dmamode);
197 uint8_t FM7_MAINMEM::read_with_mmr(uint32_t addr, uint32_t segment, uint32_t dmamode)
200 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
204 //n_pos = (segment & 0x03) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7);
205 n_pos = ((segment & 0x03) << 9) + ((addr & 0xffff) >> 7);
206 if(mmr_update_table_nor[n_pos].read_data != NULL) {
207 return mmr_update_table_nor[n_pos].read_data[addr & 0x7f];
208 } else if(mmr_update_table_nor[n_pos].read_func != NULL) {
209 uint8_t (FM7_MAINMEM::*read_func)(uint32_t, bool);
210 read_func = this->mmr_update_table_nor[n_pos].read_func;
211 raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
212 return (this->*read_func)(raddr, dmamode);
216 //n_pos = (segment & 0x0f) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7);
217 n_pos = ((segment & 0x0f) << 9) + ((addr & 0xffff) >> 7);
218 if(mmr_update_table_ext[n_pos].read_data != NULL) {
219 return mmr_update_table_ext[n_pos].read_data[addr & 0x7f];
220 } else if(mmr_update_table_ext[n_pos].read_func != NULL) {
221 uint8_t (FM7_MAINMEM::*read_func)(uint32_t, bool);
222 raddr = mmr_baseaddr_table_ext[n_pos] | (addr & 0xfff);
223 read_func = this->mmr_update_table_ext[n_pos].read_func;
224 return (this->*read_func)(raddr, dmamode);
231 //n_pos = (segment & 0x03) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7);
232 //n_pos = (((segment & 0x03) * 0x10) | ((addr >> 12) & 0x0f)) * (0x1000 / 0x80) + ((addr & 0xfff) >> 7);
233 n_pos = ((segment & 0x03) << 9) + ((addr & 0xffff) >> 7);
234 if(mmr_update_table_nor[n_pos].read_data != NULL) {
235 return mmr_update_table_nor[n_pos].read_data[addr & 0x7f];
236 } else if(mmr_update_table_nor[n_pos].read_func != NULL) {
237 uint8_t (FM7_MAINMEM::*read_func)(uint32_t, bool);
238 read_func = this->mmr_update_table_nor[n_pos].read_func;
239 raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
240 return (this->*read_func)(raddr, dmamode);
249 void FM7_MAINMEM::write_with_mmr(uint32_t addr, uint32_t segment, uint32_t data, uint32_t dmamode)
252 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
256 //n_pos = (segment & 0x03) * (0x10000 >> 7) + ((addr & 0xffff) >> 7);
257 n_pos = ((segment & 0x03) << 9) + ((addr & 0xffff) >> 7);
258 if(mmr_update_table_nor[n_pos].write_data != NULL) {
259 mmr_update_table_nor[n_pos].write_data[addr & 0x7f] = (uint8_t)data;
260 } else if(mmr_update_table_nor[n_pos].write_func != NULL) {
261 void (FM7_MAINMEM::*write_func)(uint32_t, uint32_t, bool);
262 write_func = this->mmr_update_table_nor[n_pos].write_func;
263 raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
264 (this->*write_func)(raddr, data, dmamode);
268 //n_pos = (segment & 0x0f) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7);
269 n_pos = ((segment & 0x0f) << 9) + ((addr & 0xffff) >> 7);
270 if(mmr_update_table_ext[n_pos].write_data != NULL) {
271 mmr_update_table_ext[n_pos].write_data[addr & 0x7f] = (uint8_t)data;
272 } else if(mmr_update_table_ext[n_pos].write_func != NULL) {
273 void (FM7_MAINMEM::*write_func)(uint32_t, uint32_t, bool);
274 write_func = this->mmr_update_table_ext[n_pos].write_func;
275 raddr = mmr_baseaddr_table_ext[n_pos] | (addr & 0xfff);
276 (this->*write_func)(raddr, data, dmamode);
283 //n_pos = (segment & 0x03) * (0x10 * 0x1000 / 0x80) + ((addr & 0xffff) >> 7);
284 //n_pos = (((segment & 0x03) * 0x10) | ((addr >> 12) & 0x0f)) * (0x1000 / 0x80) + ((addr & 0xfff) >> 7);
285 n_pos = ((segment & 0x03) << 9) + ((addr & 0xffff) >> 7);
286 if(mmr_update_table_nor[n_pos].write_data != NULL) {
287 mmr_update_table_nor[n_pos].write_data[addr & 0x7f] = (uint8_t)data;
288 } else if(mmr_update_table_nor[n_pos].write_func != NULL) {
289 void (FM7_MAINMEM::*write_func)(uint32_t, uint32_t, bool);
290 write_func = this->mmr_update_table_nor[n_pos].write_func;
291 raddr = mmr_baseaddr_table_nor[n_pos] | (addr & 0xfff);
292 //printf("%08x %08x %08x\n", addr, raddr, n_pos);
293 (this->*write_func)(raddr, data, dmamode);