OSDN Git Service

[VM] TRY:Use namespace {VMNAME} to separate around VMs. This feature still apply...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / mainmem_mmr.cpp
1 /*
2  * Main memory for FM-7 [FM7_MAINMEM/MAINMEM_MMR]
3  *  Author: K.Ohta
4  *  Date  : 2017.04.01-
5  *  License: GPLv2
6  *
7  */
8 #include "vm.h"
9 #include "emu.h"
10 #include "fm7_mainmem.h"
11
12 namespace FM7 {
13
14 int FM7_MAINMEM::window_convert(uint32_t addr, uint32_t *realaddr)
15 {
16         uint32_t raddr = addr;
17 #ifdef HAS_MMR
18         if((addr < 0x8000) && (addr >= 0x7c00)) {
19                 raddr = ((window_offset * 256) + addr) & 0x0ffff; 
20                 *realaddr = raddr;
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)
25                 *realaddr |= 0x20000;
26                 return FM7_MAINMEM_EXTRAM; // 0x20000 - 0x2ffff
27 #endif
28         }
29         // Window not hit.
30 #endif
31         return -1;
32 }
33
34 void FM7_MAINMEM::update_mmr_jumptable(uint32_t pos)
35 {
36 #if defined(HAS_MMR)
37 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) 
38         if(pos >= 0x80) return;
39 # else
40         if(pos >= 0x40) return;
41 # endif
42         uint32_t n_pos = pos * (0x1000 / 0x80);
43         uint32_t i;
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);
47 # endif
48         uint32_t r_pos_nor = (mmr_index & 0x3f) * (0x1000 / 0x80);
49         uint32_t raddr_nor;
50         uint32_t raddr_ext;
51         raddr_ext = (mmr_index << 12);
52         raddr_nor = ((mmr_index & 0x3f) << 12);
53         
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;
63                 } else {                        
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;
69                         } else {
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;
74                         }
75                 }
76 # endif
77                 mmr_baseaddr_table_nor[i + n_pos] = raddr_nor;
78                 
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;
86                                 return;
87                         }
88                 }
89 # endif
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;
95                 } else {
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;
100                 }
101         }
102 #endif
103 }
104
105 void FM7_MAINMEM::update_all_mmr_jumptable(void)
106 {
107 #if defined(HAS_MMR)
108         uint32_t i;
109 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) 
110         for(i = 0; i < 0x80; i++) {
111                 update_mmr_jumptable(i);
112         }
113 # else
114         for(i = 0; i < 0x40; i++) {
115                 update_mmr_jumptable(i);
116         }
117 # endif
118 #endif
119 }
120
121 uint8_t FM7_MAINMEM::read_segment_3f(uint32_t addr, bool dmamode)
122 {
123 #if defined(HAS_MMR)
124         uint32_t raddr = addr & 0x0fff;
125 # ifdef _FM77AV_VARIANTS
126         if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
127                 return 0xff;
128         } else {
129                 raddr = raddr | 0x3f000;
130                 return read_data_tbl(raddr, dmamode);
131         }
132 # elif defined(_FM77_VARIANTS)
133         if((raddr >= 0xc00) && (raddr < 0xe00)) {
134                 if(is_basicrom) {
135                         return 0x00;
136                 } else {
137                         raddr = raddr - 0xc00;
138                         return fm77_shadowram[raddr];
139                 }
140         } else if(raddr >= 0xe00) {
141                 raddr = raddr - 0x0e00;
142                 if(is_basicrom) {
143                         if(diag_load_bootrom_mmr) {
144                                 return fm7_bootroms[2][raddr];
145                         } else {
146                                 return fm7_bootroms[0][raddr];
147                         }
148                 } else {
149                         return fm7_bootram[raddr];
150                 }
151         } else {
152                 raddr = raddr | 0x3f000;
153                 return read_data_tbl(raddr, dmamode);
154         } 
155 # endif
156 #else
157         return 0xff;
158 #endif
159 }
160
161 void FM7_MAINMEM::write_segment_3f(uint32_t addr, uint32_t data, bool dmamode)
162 {
163 #if defined(HAS_MMR)
164         uint32_t raddr = addr & 0x0fff;
165 # ifdef _FM77AV_VARIANTS
166         if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
167                 return;
168         } else {
169                 raddr = raddr | 0x3f000;
170                 write_data_tbl(raddr, data, dmamode);
171                 return;
172         }
173 # elif defined(_FM77_VARIANTS)
174         if((raddr >= 0xc00) && (raddr < 0xe00)) {
175                 if(is_basicrom) {
176                         return;
177                 } else {
178                         raddr = raddr - 0xc00;
179                         fm77_shadowram[raddr] = (uint8_t)data;
180                         return;
181                 }
182         } else if(raddr >= 0xe00) {
183                 raddr = raddr - 0x0e00;
184                 if(!is_basicrom) {
185                         fm7_bootram[raddr] = (uint8_t)data;
186                 }
187         } else {
188                 raddr = raddr | 0x3f000;
189                 write_data_tbl(raddr, data, dmamode);
190         } 
191 # endif
192 #else
193         return;
194 #endif
195 }
196
197 uint8_t FM7_MAINMEM::read_with_mmr(uint32_t addr, uint32_t segment, uint32_t dmamode)
198 {
199 #if defined(HAS_MMR)
200 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
201         uint32_t raddr;
202         uint32_t n_pos;
203         if(!mmr_extend) {
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);
213                 }
214                 return 0xff;
215         } else {
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);
225                 }
226                 return 0xff;
227         }               
228 # else
229         uint32_t n_pos;
230         uint32_t raddr;
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);
241         }
242         return 0xff;
243 # endif
244 #else
245         return 0xff;
246 #endif
247 }
248
249 void FM7_MAINMEM::write_with_mmr(uint32_t addr, uint32_t segment, uint32_t data, uint32_t dmamode)
250 {
251 #if defined(HAS_MMR)
252 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
253         uint32_t n_pos;
254         uint32_t raddr;
255         if(!mmr_extend) {
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);
265                 }
266                 return;
267         } else {
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);
277                 }
278                 return;
279         }               
280 # else
281         uint32_t n_pos;
282         uint32_t raddr;
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);
294         }
295         return;
296 # endif
297 #else
298         return;
299 #endif
300 }
301
302 }