OSDN Git Service

[VM][FMTOWNS] Add FONT ROMS, MSDOS ROM, SYSTEM ROM and SERIAL ROM.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / towns_dictionary.cpp
1 /*
2         FUJITSU FM Towns Emulator 'eFMTowns'
3
4         Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2019.01.09-
6
7         [ dictionary rom/ram & cmos & RAM area 0x000d0000 - 0x000effff]
8 */
9
10 #include "./towns_common.h"
11 #include "./towns_dictrom.h"
12 #include "./towns_sysrom.h"
13 #include "../../fileio.h"
14
15 namespace FMTOWNS {
16 void DICTIONARY::initialize()
17 {
18         cmos_dirty = false;
19         
20         memset(dict_rom, 0xff, sizeof(dict_rom));
21         memset(dict_ram, 0x00, sizeof(dict_ram));
22         memset(ram_0d0, 0x00, sizeof(ram_0d0));
23         
24         FILEIO* fio = new FILEIO();
25         if(fio->Fopen(create_local_path(_T("FMT_DIC.ROM")), FILEIO_READ_BINARY)) { // DICTIONARIES
26                 fio->Fread(dict_rom, sizeof(dict_rom), 1);
27                 fio->Fclose();
28         }
29         
30         if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_READ_BINARY)) {
31                 fio->Fread(dict_ram, sizeof(dict_ram), 1);
32                 fio->Fclose();
33         } else {
34                 cmos_dirty = true;
35         }
36         delete fio;
37
38         wait_val = 3;
39         dict_bank = 0;
40         bankd0_dict = false;
41 }
42
43 void DICTIONARY::release()
44 {
45         if(cmos_dirty) {
46                 FILEIO* fio = new FILEIO();
47                 if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_WRITE_BINARY)) {
48                         fio->Fwrite(dict_ram, sizeof(dict_ram), 1);
49                         fio->Fclose();
50                 }
51                 delete fio;
52         }
53 }
54
55 void DICTIONARY::reset()
56 {
57         //wait_val = 6; // OK?
58         dict_bank = 0;
59         bankd0_dict = false;
60         
61 }
62 uint32_t DICTIONARY::read_data8(uint32_t addr)
63 {
64         uint8_t n_data = 0xff;
65         if((addr < 0x000f0000) && (addr >= 0x000d0000)) {
66                 if(bankd0_dict) {
67                         if(addr < 0x000d8000) {
68                                 n_data = dict_rom[(addr & 0x7fff) + (((uint32_t)(dict_bank & 0x0f)) << 15)];
69                         } else if(addr < 0x000da000) {
70                                 n_data = dict_ram[addr & 0x1fff];
71                         }/* else { // ToDo: Check correctness
72                                 n_data = 0xff;
73                         }*/
74                 } else {
75                         n_data = ram_0d0[addr & 0x1ffff];
76                 }
77         } else if((addr >= 0xc20800000) && (addr < 0xc2100000)) {
78                 n_data = dict_rom[addr & 0x7ffff];
79         } else if((addr >= 0xc21400000) && (addr < 0xc2142000)) {
80                 n_data = dict_ram[addr & 0x1fff];
81         }
82         return n_data;
83 }
84
85 void DICTIONARY::write_data8(uint32_t addr, uint32_t data)
86 {
87         if((addr < 0x000f0000) && (addr >= 0x000d0000)) {
88                 if(bankd0_dict) {
89                         if((addr >= 0x000d8000) && (addr < 0x000da000)) {
90                                 cmos_dirty = true;
91                                 dict_ram[addr & 0x1fff] = data; // ToDo: Check correctness
92                         } /* else { // ToDo: Check correctness
93                         
94                         }*/
95                 } else {
96                         ram_0d0[addr & 0x1ffff] = (uint8_t)data;
97                 }
98         } else if((addr >= 0xc21400000) && (addr < 0xc2142000)) {
99                 dict_ram[addr & 0x1fff] = (uint8_t)data;
100         }
101 }
102
103 uint32_t DICTIONARY::read_data16(uint32_t addr)
104 {
105         pair16_t n;
106         addr = addr & 0xfffffffe;
107         n.l = (uint8_t)read_data8(addr + 0);
108         n.h = (uint8_t)read_data8(addr + 1);
109         return (uint32_t)(n.u16);
110 }
111
112 uint32_t DICTIONARY::read_data32(uint32_t addr)
113 {
114         pair32_t n;
115         addr = addr & 0xfffffffc;
116         n.l  = (uint8_t)read_data8(addr + 0);
117         n.h  = (uint8_t)read_data8(addr + 1);
118         n.h2 = (uint8_t)read_data8(addr + 2);
119         n.h3 = (uint8_t)read_data8(addr + 3);
120         return n.u32;
121 }
122
123 void DICTIONARY::write_data16(uint32_t addr, uint32_t data)
124 {
125         pair16_t n;
126         addr = addr & 0xfffffffe;
127         n.u16 = (uint16_t)data;
128         write_data8(addr + 0, n.l);
129         write_data8(addr + 1, n.h);
130 }
131
132 void DICTIONARY::write_data32(uint32_t addr, uint32_t data)
133 {
134         pair32_t n;
135         addr = addr & 0xfffffffc;
136         n.u32 = data;
137         write_data8(addr + 0, n.l);
138         write_data8(addr + 1, n.h);
139         write_data8(addr + 2, n.h2);
140         write_data8(addr + 3, n.h3);
141 }
142
143 uint32_t DICTIONARY::read_data8w(uint32_t addr, int *wait)
144 {
145         if(wait != NULL) *wait = wait_val;
146         return read_data8(addr, data);
147 }
148
149 uint32_t DICTIONARY::read_data16w(uint32_t addr, int *wait)
150 {
151         if(wait != NULL) *wait = wait_val * 2;
152         return read_data16(addr, data);
153 }
154
155 uint32_t DICTIONARY::read_data32w(uint32_t addr, int *wait)
156 {
157         if(wait != NULL) *wait = wait_val * 4;
158         return read_data32(addr, data);
159 }
160
161
162 void DICTIONARY::write_data8w(uint32_t addr, uint32_t data, int *wait)
163 {
164         if(wait != NULL) *wait = wait_val;
165         write_data8(addr, data);
166 }
167
168 void DICTIONARY::write_data16w(uint32_t addr, uint32_t data, int *wait)
169 {
170         if(wait != NULL) *wait = wait_val * 2;
171         write_data16(addr, data);
172 }
173
174 void DICTIONARY::write_data32w(uint32_t addr, uint32_t data, int *wait)
175 {
176         if(wait != NULL) *wait = wait_val * 4;
177         write_data32(addr, data);
178 }
179
180 void DICTIONARY::write_io8(uint32_t addr, uint32_t data)
181 {
182         if(addr == 0x0480) {
183                 bankd0_dict = ((data & 0x01) != 0);
184                 d_sysrom->write_signal(SIG_FMTONWS_SYSROMSEL, data, 0x02);
185         } else if(addr == 0x0484) {
186                 dict_bank = data & 0x0f;
187         } else if((addr >= 0x3000) && (addr < 0x4000)) {
188                 if((addr & 0x0001) == 0) { // OK?
189                         uint32_t naddr = (addr >> 1) & 0x7ff;
190                         cmos_dirty = true;
191                         dict_ram[naddr] = (uint8_t)data;
192                 }
193         }
194 }
195
196 uint32_t DICTIONARY::read_io8(uint32_t addr)
197 {
198         uint32_t data;
199         if(addr == 0x0480) {
200                 data = ((bank0_dict) ? 0x01 : 0x00) | ((d_sysrom->read_signal(SIG_FMTOWNS_SYSROMSEL) == 0) ? 0x02 : 0x00);
201         } else if(addr == 0x0484) {
202                 data = dict_bank & 0x0f;
203         } else if((addr >= 0x3000) && (addr < 0x4000)) {
204                 if((addr & 0x0001) == 0) { // OK?
205                         uint32_t naddr = (addr >> 1) & 0x7ff;
206                         data = dict_ram[naddr];
207                 } else {
208                         data = 0xff;
209                 }
210         } else {
211                 data = 0xff;
212         }
213         return data;
214 }
215
216 void DICTIONARY::write_signal(int ch, uint32_t data, uint32_t mask)
217 {
218         switch(ch) {
219         case SIG_FMTOWNS_DICTSEL:
220                 bankd0_dict = ((data & mask) != 0);
221                 break;
222         case SIG_FMTOWNS_DICTBANK:
223                 dict_bank = (uint8_t)(data & 0x0f);
224                 break;
225         case SIG_FMTOWNS_SET_MEMWAIT:
226                 wait_val = (int)data;
227                 break;
228         }
229 }
230
231 uint32_t DICTIONARY::read_signal(int ch)
232 {
233         switch(ch) {
234         case SIG_FMTOWNS_DICTSEL:
235                 return ((bankd0_dict) ? 0xffffffff : 0x00000000);
236                 break;
237         case SIG_FMTOWNS_DICTBANK:
238                 return (uint32_t)(dict_bank & 0x0f);
239                 break;
240         case SIG_FMTOWNS_SET_MEMWAIT:
241                 return (uinrt32_t)wait_val;
242                 break;
243         }
244         return 0x00;
245 }
246         
247 #define STATE_VERSION   1
248
249 bool DICTIONARY::process_state(FILEIO* state_fio, bool loading)
250 {
251         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
252                 return false;
253         }
254         if(!state_fio->StateCheckInt32(this_device_id)) {
255                 return false;
256         }
257         state_fio->StateValue(wait_val);
258         state_fio->StateValue(dict_bank);
259         state_fio->StateValue(bankd0_dict);
260         state_fio->StateArray(dict_ram, sizeof(dict_ram), 1);
261         state_fio->StateArray(ram_0d0, sizeof(ram_0d0), 1);
262         
263         if(loading) {
264                 cmos_dirty = true;
265         }/* else {
266                 FILEIO* fio = new FILEIO();
267                 if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_WRITE_BINARY)) {
268                         fio->Fwrite(dict_ram, sizeof(dict_ram), 1);
269                         fio->Fclose();
270                 }
271                 delete fio;
272                 cmos_dirty = false;
273         } */
274         return true;
275 }       
276 }