OSDN Git Service

[VM][FM7][MAINMEM] MMR: Use jump tables.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / mainmem_readseq.cpp
1 /*
2  * Main memory for FM-7 [FM7_MAINMEM/MAINMEM_READSEQ]
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 uint8_t FM7_MAINMEM::read_data_tbl(uint32_t addr, bool dmamode)
13 {
14         uint32_t paddr = addr >> 7;
15         if(data_table[paddr].read_data != NULL) {
16                 return data_table[paddr].read_data[addr & 0x7f];
17         } else if(data_table[paddr].read_func != NULL) {
18                 uint8_t (FM7_MAINMEM::*read_func)(uint32_t, bool);
19                 read_func = this->data_table[paddr].read_func;
20                 return (this->*read_func)(addr, dmamode);
21         }
22         return 0xff;
23 }               
24
25 uint8_t FM7_MAINMEM::read_data(uint32_t addr, bool dmamode)
26 {
27 #ifdef HAS_MMR
28         int stat;
29         if(window_enabled) {
30                 uint32_t raddr;
31                 stat = window_convert(addr, &raddr);
32 #if defined(_FM77AV_VARIANTS)
33                 if(stat >= 0) {
34                         return fm7_mainmem_mmrbank_0[raddr & 0xffff];
35                 }
36 #elif defined(_FM77_VARIANTS)
37                 if(stat >= 0) {
38                         if((extram_pages >= 3) && (fm7_mainmem_extram != NULL)) {
39                                 return fm7_mainmem_extram[raddr];
40                         } else {
41                                 return 0xff;
42                         }
43                 }
44 #endif
45         }
46         if(mmr_enabled) {
47                 uint32_t segment = 0x00;
48                 uint32_t raddr = (addr & 0x0fff);
49                 uint32_t mmr_bank;
50                 if(addr < 0xfc00) {
51                         if(!dmamode) segment = mmr_segment;
52 #if 1
53                         return read_with_mmr(addr, segment, dmamode);
54 #else
55                         if(!mmr_extend) {
56                                 mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((segment & 0x03) << 4)] & 0x003f;
57                         } else {
58                                 mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((segment & 0x07) << 4)];
59                         }               
60                         // Reallocated by MMR
61                         // Bank 3x : Standard memories.
62                         if(mmr_bank != 0x3f){
63                                 raddr = (mmr_bank << 12) | raddr;
64                                 return read_data_tbl(raddr, dmamode);
65                         }
66 # ifdef _FM77AV_VARIANTS
67                         else if(mmr_bank == 0x3f) {
68                                 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
69                                         return 0xff;
70                                 } else {
71                                         raddr = raddr | 0x3f000;
72                                         return read_data_tbl(raddr, dmamode);
73                                 }
74                         }
75 # elif defined(_FM77_VARIANTS)
76                         else if(mmr_bank == 0x3f) {
77                                 if((raddr >= 0xc00) && (raddr < 0xe00)) {
78                                         if(is_basicrom) {
79                                                 return 0x00;
80                                         } else {
81                                                 raddr = raddr - 0xc00;
82                                                 return fm77_shadowram[raddr];
83                                         }
84                                 } else if(raddr >= 0xe00) {
85                                         raddr = raddr - 0x0e00;
86                                         if(is_basicrom) {
87                                                 if(diag_load_bootrom_mmr) {
88                                                         return fm7_bootroms[2][raddr];
89                                                 } else {
90                                                         return fm7_bootroms[0][raddr];
91                                                 }
92                                         } else {
93                                                 return fm7_bootram[raddr];
94                                         }
95                                 } else {
96                                         raddr = raddr | 0x3f000;
97                                         return read_data_tbl(raddr, dmamode);
98                                 } 
99                         }
100 # endif
101 #endif
102                 } else {
103                         raddr = 0x30000 | (addr & 0xffff);
104                         return read_data_tbl(raddr, dmamode);
105                 }
106         }
107 #endif
108         
109 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77_VARIANTS)
110         uint32_t raddr = (addr & 0xffff);
111         return read_data_tbl(raddr, dmamode);
112 #else
113         uint32_t raddr = (addr & 0xffff) | 0x30000;
114         return read_data_tbl(raddr, dmamode);
115 #endif
116 }
117
118 uint32_t FM7_MAINMEM::read_data8_main(uint32_t addr, bool dmamode)
119 {
120         uint32_t realaddr;
121         int bank;
122 #ifdef _FM77AV_VARIANTS
123         if(initiator_enabled) {
124                 if((addr >= 0x6000) && (addr < 0x8000)) {
125                         uint32_t raddr = addr - 0x6000;
126                         return fm7_mainmem_initrom[raddr];
127                 }
128                 if((addr >= 0xfffe) && (addr < 0x10000)) {
129                         uint32_t raddr = addr - 0xe000;
130                         //printf("%04x %02x\n", raddr, fm7_mainmem_initrom[raddr]);
131                         return fm7_mainmem_initrom[raddr];
132                 }
133         }
134 #endif
135         return read_data(addr, dmamode);
136 }       
137
138
139 uint8_t FM7_MAINMEM::read_shared_ram(uint32_t realaddr, bool dmamode)
140 {
141         realaddr = realaddr & 0x7f;
142         if(!sub_halted) return 0xff; // Not halt
143         return display->read_data8(realaddr  + 0xd380); // Okay?
144 }
145
146 uint8_t FM7_MAINMEM::read_direct_access(uint32_t realaddr, bool dmamode)
147 {
148 #if defined(_FM77AV_VARIANTS)
149         if(!sub_halted) return 0xff; // Not halt
150         if(dmamode) {
151                 return display->read_dma_data8(realaddr & 0xffff); // Okay?
152         } else {
153                 return display->read_data8(realaddr & 0xffff); // Okay?
154         }
155 #else
156         return 0xff;
157 #endif  
158 }
159
160 uint8_t FM7_MAINMEM::read_ura_basicrom(uint32_t addr, bool dmamode)
161 {
162         addr = addr & 0x7fff;
163         if (basicrom_fd0f) {
164                 return fm7_mainmem_basicrom[addr];
165         }
166         return fm7_mainmem_ura[addr];
167 }
168
169 uint8_t FM7_MAINMEM::read_mmio(uint32_t addr, bool dmamode)
170 {
171         addr &= 0xff;
172         wait();
173         if(mainio != NULL) {
174                 return mainio->read_data8(addr);
175         }
176         return 0xff;
177 }
178
179 uint8_t FM7_MAINMEM::read_bootrom(uint32_t addr, bool dmamode)
180 {
181         addr = addr & 0x1ff;
182         if(addr <  0x1e0) {
183                 wait();
184 #if defined(_FM77AV_VARIANTS)
185                 return fm7_bootram[addr];
186 #else
187                 switch(bootmode) {
188                 case 0:
189                 case 1:
190                 case 2:
191                 case 3:
192                         return fm7_bootroms[bootmode][addr];
193                         break;
194 # if defined(_FM77_VARIANTS)
195                 case 4:
196                         return fm7_bootram[addr];
197                         break;
198 # endif                         
199                 default:
200                         return fm7_bootroms[0][addr];
201                         break;
202                 }
203 #endif
204         } else if (addr < 0x1fe) { // VECTOR
205                 return fm7_mainmem_bootrom_vector[addr - 0x1e0];
206         }
207 #if defined(_FM77AV_VARIANTS)
208         else {
209                 wait();
210                 return fm7_bootram[addr];
211         }
212 #else
213         else {
214                 return fm7_mainmem_reset_vector[addr & 1];
215         }
216 #endif
217         return 0xff;
218 }