OSDN Git Service

[VM][STATE_SAVE] Fix bug of loading [int64_t|uint64_t] .
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / fm8_mainio.cpp
1 /*
2  * FM-7 -> FM-8 Main I/O [fm8_mainio.h]
3  *
4  * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
5  * License: GPLv2
6  * History:
7  *   Jan 03, 2015 : Initial
8  *   Jan 25, 2018 : Move some routines from fm7_mainio.h
9  *
10  */
11
12 #include "fm7.h"
13 #include "fm8_mainio.h"
14
15 #include "../mc6809.h"
16 #include "../z80.h"
17
18 #include "../datarec.h"
19 #include "../i8251.h"
20 #if defined(HAS_DMA)
21 #include "hd6844.h"
22 #endif
23 #include "../ym2203.h"
24 #include "../ay_3_891x.h"
25 #include "../pcm1bit.h"
26
27 #include "./fm7_mainmem.h"
28 #include "bubblecasette.h"
29
30 FM8_MAINIO::FM8_MAINIO(VM* parent_vm, EMU* parent_emu) : FM7_MAINIO(parent_vm, parent_emu)
31 {
32     psg = NULL;
33         bubble_casette[0] = NULL;
34         bubble_casette[1] = NULL;
35
36         // FD15/ FD46 / FD51
37         connect_psg = false;
38         {
39                 opn_address[0] = 0x00;
40                 opn_data[0] = 0x00;
41                 opn_cmdreg[0] = 0;
42         }
43 #if defined(HAS_DMA)
44         dmac = NULL;
45 #endif  
46         set_device_name(_T("FM-8 MAIN I/O"));
47         
48 }
49
50 FM8_MAINIO::~FM8_MAINIO()
51 {
52 }
53
54
55 void FM8_MAINIO::initialize()
56 {
57         FM7_MAINIO::initialize();
58 }
59
60 void FM8_MAINIO::reset()
61 {
62         FM7_MAINIO::reset();
63         cancel_event(this, event_timerirq);
64 }
65
66 uint8_t FM8_MAINIO::get_port_fd00(void)
67 {
68         uint8_t ret = 0xfe;
69         if(clock_fast) ret |= 0x01; //0b00000001;
70         return ret;
71 }
72
73 void FM8_MAINIO::set_port_fd02(uint8_t val)
74 {
75         return;
76 }
77
78 uint8_t FM8_MAINIO::get_irqstat_fd03(void)
79 {
80         return 0xff;
81 }
82
83 uint8_t FM8_MAINIO::get_extirq_fd17(void)
84 {
85         uint8_t val = 0xff;
86         return val;
87 }
88
89 void FM8_MAINIO::set_ext_fd17(uint8_t data)
90 {
91 }
92
93 void FM8_MAINIO::set_irq_syndet(bool flag)
94 {
95         bool backup = intstat_syndet;
96         irqreq_syndet = flag;
97         intstat_syndet = flag;
98         if(backup != intstat_syndet) do_irq();
99 }
100
101 void FM8_MAINIO::set_irq_rxrdy(bool flag)
102 {
103         bool backup = intstat_rxrdy;
104         irqreq_rxrdy = flag;
105         intstat_rxrdy = flag;
106         if(backup != intstat_rxrdy) do_irq();
107 }
108
109 void FM8_MAINIO::set_irq_txrdy(bool flag)
110 {
111         bool backup = intstat_txrdy;
112         irqreq_txrdy = flag;
113         intstat_txrdy = flag;
114         if(backup != intstat_txrdy) do_irq();
115 }
116
117
118 void FM8_MAINIO::set_irq_timer(bool flag)
119 {
120 }
121
122 void FM8_MAINIO::set_irq_printer(bool flag)
123 {
124 }
125
126 void FM8_MAINIO::set_irq_mfd(bool flag)
127 {
128         //bool backup = irqstat_fdc;
129         if(!connect_fdc) return;
130         if(flag) {
131                 irqreg_fdc |= 0x40; //0b01000000;
132         } else {
133                 irqreg_fdc &= 0xbf; //0b10111111;
134         }
135         // With FM8, $FD1F is alive and not do_irq(), Thanks to Anna_Wu.
136 }
137
138 void FM8_MAINIO::do_irq(void)
139 {
140         bool intstat;
141         uint32_t nval;
142         intstat = intstat_txrdy | intstat_rxrdy | intstat_syndet;
143         nval = (intstat) ? 0xffffffff : 0;
144         write_signals(&irq_bus, nval);
145 }
146
147 void FM8_MAINIO::write_fd0f(void)
148 {
149         if((config.dipswitch & FM7_DIPSW_FM8_PROTECT_FD0F) != 0) {
150                 return;
151         }
152         bootmode = 1; // DOS : Where BUBBLE?
153         if(config.boot_mode >= 4) {
154                 bootmode = 5;
155         }
156         mainmem->write_signal(FM7_MAINIO_BOOTMODE, bootmode, 0xffffffff);
157         mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0, 0xffffffff);
158         mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0, 0xffffffff);
159 }
160
161 uint8_t FM8_MAINIO::read_fd0f(void)
162 {
163         if((config.dipswitch & FM7_DIPSW_FM8_PROTECT_FD0F) != 0) {
164                 return 0xff;
165         }
166         bootmode = 0; // BASIC
167         if(config.boot_mode >= 4) {
168                 bootmode = 4;
169         }
170         mainmem->write_signal(FM7_MAINIO_BOOTMODE, bootmode, 0xffffffff);
171         mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0xffffffff, 0xffffffff);
172         mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0xffffffff, 0xffffffff);
173         return 0xff;
174 }
175
176 void FM8_MAINIO::reset_sound(void)
177 {
178         if(psg != NULL) {
179                 psg->reset();
180         }
181         connect_psg = false;
182         if(config.sound_type == 0) {
183                 connect_psg = false;
184         } else {
185                 connect_psg = true;
186         }
187 # if defined(USE_AY_3_8910_AS_PSG)
188         psg->write_signal(SIG_AY_3_891X_MUTE, !connect_psg ? 0xffffffff : 0x00000000, 0xffffffff);
189 # else  
190         psg->write_signal(SIG_YM2203_MUTE, !connect_psg ? 0xffffffff : 0x00000000, 0xffffffff);
191 # endif
192         pcm1bit->write_signal(SIG_PCM1BIT_MUTE, 0x01, 0x01);
193         pcm1bit->write_signal(SIG_PCM1BIT_ON, 0x00, 0x01);
194
195 }
196
197 void FM8_MAINIO::set_psg(uint8_t val)
198 {
199         if(connect_psg) return set_opn(0, val);
200 }
201
202 uint8_t FM8_MAINIO::get_psg(void)
203 {
204         if(connect_psg) return get_opn(0);
205         return 0xff;
206 }
207 /*
208  * $fd0d : After 77AV, this is OPN.
209  */
210 void FM8_MAINIO::set_psg_cmd(uint8_t cmd)
211 {
212         cmd = cmd & 0x03;
213         if(connect_psg) set_opn_cmd(0, cmd);
214         return;
215 }
216 // OPN
217 // Write to FD16, same as 
218 void FM8_MAINIO::write_opn_reg(int index, uint32_t addr, uint32_t data)
219 {
220         if(connect_psg) {
221                 opn_regs[0][addr] = data;
222                 psg->write_io8(0, addr & 0x0f);
223                 psg->write_io8(1, data);
224                 return;
225         }
226 }
227
228 void FM8_MAINIO::set_opn(int index, uint8_t val)
229 {
230         if(!connect_psg) {
231                 return;
232         }
233         if(index != 0) return;
234         if(psg == NULL) return;
235         opn_data[index] = val;
236         switch(opn_cmdreg[index]){
237                 case 0: // High inpedance
238                 case 1: // Read Data
239                         break;
240                 case 2: // Write Data
241                         write_opn_reg(index, opn_address[index], opn_data[index]);
242                         break;
243                 case 3: // Register address
244                         if(index == 3) {
245                                 opn_address[index] = val & 0x0f;
246                         } else {
247                                 opn_address[index] = val;
248                         }
249                         break;
250                 default:
251                         break;
252         }
253 }
254
255 uint8_t FM8_MAINIO::get_opn(int index)
256 {
257         uint8_t val = 0xff;
258         if(!connect_psg) return val;
259         if(index != 0) return val;
260         if(psg == NULL) return val;
261         switch(opn_cmdreg[index]) {
262                 case 0:
263                 case 1:
264                 case 2:
265                 case 3:
266                         val = opn_data[index];
267                         break;
268                 default:
269                         break;
270                 }
271                 return val;
272 }
273   /*
274    * $fd16?
275    */
276 void FM8_MAINIO::set_opn_cmd(int index, uint8_t cmd)
277 {
278         if(!connect_psg) return;
279         if(index != 0) return;
280         if(psg == NULL) return;
281         uint32_t mask[16] = { // Parameter is related by XM7. Thanks Ryu.
282                 0xff, 0x0f, 0xff, 0x0f,
283                 0xff, 0x0f, 0x1f, 0xff,
284                 0x1f, 0x1f, 0x1f, 0xff,
285                 0xff, 0x0f, 0xff, 0xff
286         };
287         opn_cmdreg[index] = cmd & 0x0f;
288         uint8_t val = opn_data[index];
289         switch(opn_cmdreg[index]) {
290                 case 0:
291                         break;
292                 case 1:
293                         if(index == 0) {
294                                 psg->write_io8(0, opn_address[index]);
295                                 opn_data[index] = psg->read_io8(1);
296                         }
297                         if(opn_address[index] <= 0x0f) {
298                                 opn_data[index] &= mask[opn_address[index]];
299                         }
300                         break;
301                 case 2:
302                         write_opn_reg(index, opn_address[index], opn_data[index]);
303                         break;
304                 case 3: // Register address
305                         if(index == 3) {
306                                 opn_address[index] = val & 0x0f;
307                         } else {
308                                 opn_address[index] = val;
309                         }
310
311                         break;
312                 default:
313                         break;
314         }
315         return;
316 }
317 uint8_t FM8_MAINIO::get_extirq_whg(void)
318 {
319         uint8_t val = 0xff;
320         return val;
321 }
322 uint8_t FM8_MAINIO::get_extirq_thg(void)
323 {
324         uint8_t val = 0xff;
325         return val;
326 }
327 void FM8_MAINIO::opn_note_on(int index)
328 {
329 }
330
331 void FM8_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
332 {
333         bool val_b = ((data & mask) != 0);
334         switch(id) {
335                 case FM7_MAINIO_OPN_IRQ:
336                         return;
337                         break;
338                 case FM7_MAINIO_WHG_IRQ:
339                         return;
340                         break;
341                 case FM7_MAINIO_THG_IRQ:
342                         return;
343                         break;
344                 case FM7_MAINIO_FDC_IRQ:
345                         set_irq_mfd(val_b);
346                         return;
347                         break;
348                 default:
349                         break;
350         }
351         FM7_MAINIO::write_signal(id, data, mask);
352 }
353
354 uint32_t FM8_MAINIO::read_data8(uint32_t addr)
355 {
356         uint32_t retval = 0xff;
357         switch(addr) {
358         case 0x00:
359                 retval = (uint32_t)get_port_fd00();
360                 return retval;
361                 break;
362         case 0x01: // FD01
363                 retval = 0xff;
364                 return retval;
365                 break;
366         case 0x03: // FD03
367                 retval = 0xff;
368                 return retval;
369                 break;
370         case 0x0e: // PSG DATA
371                 retval = (uint32_t) get_psg();
372                 //printf("PSG DATA READ val=%02x\n", retval);
373                 return retval;
374                 break;
375         case 0x0f: // FD0F
376                 read_fd0f();
377                 retval = 0xff;
378                 break;
379         case 0x10:
380         case 0x11:
381         case 0x12:
382         case 0x13:
383         case 0x14:
384         case 0x15:
385         case 0x16:
386         case 0x17:
387                 retval = bubble_casette[0]->read_data8(addr);
388                 return retval;
389                 break;
390         case 0x37: // Multi page
391                 retval = 0xff;
392                 return;
393                 break;
394         default:
395                 break;
396         }
397         if((addr < 0x40) && (addr >= 0x38)) return 0xff; // Palette
398         if((addr < 0x54) && (addr >= 0x45)) return 0xff; // WHG, THG
399         if((addr >= 0x40) && (addr < 0x100)) return 0xff; // Another devices.
400                 
401         return FM7_MAINIO::read_data8(addr);
402 }
403
404 void FM8_MAINIO::write_data8(uint32_t addr, uint32_t data)
405 {
406         switch(addr) {
407         case 0x02:
408                 return set_port_fd02(data);
409                 break;
410         case 0x10:
411         case 0x11:
412         case 0x12:
413         case 0x13:
414         case 0x14:
415         case 0x15:
416         case 0x16:
417         case 0x17:
418                 bubble_casette[0]->write_data8(addr, data);
419                 return;
420                 break;
421         case 0x28:
422         case 0x29:
423         case 0x2a:
424         case 0x2b:
425         case 0x2c:
426         case 0x2d:
427         case 0x2e:
428                 return;
429                 break;
430         case 0x37: // Multi page
431                 return;
432                 break;
433         default:
434                 break;
435         }
436         if((addr < 0x40) && (addr >= 0x38)) return; // palette
437         if((addr < 0x54) && (addr >= 0x45)) return; // WHG, THG
438         if((addr < 0x100) && (addr >= 0x40)) return;
439         FM7_MAINIO::write_data8(addr, data);
440 }
441
442 void FM8_MAINIO::event_callback(int event_id, int err)
443 {
444         if(event_id == EVENT_TIMERIRQ_ON) {
445                 return;
446         }
447         FM7_MAINIO::event_callback(event_id, err);
448 }
449
450 void FM8_MAINIO::update_config()
451 {
452         FM7_MAINIO::update_config();
453         // BASIC
454         if(config.boot_mode == 0) {
455                 mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0xffffffff, 0xffffffff);
456         } else {
457                 mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0, 0xffffffff);
458         }
459         mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, ((config.boot_mode & 3) == 0) ? 1 : 0, 0x01);
460         mainmem->write_signal(FM7_MAINIO_BOOTMODE, bootmode, 0xffffffff);
461 }
462
463
464 #include "../../statesub.h"
465 void FM8_MAINIO::decl_state(void)
466 {
467         FM7_MAINIO::decl_state();
468         DECL_STATE_ENTRY_BOOL(connect_psg);
469 }
470
471 void FM8_MAINIO::save_state(FILEIO *state_fio)
472 {
473         FM7_MAINIO::save_state(state_fio);
474 }
475
476 bool FM8_MAINIO::load_state(FILEIO *state_fio)
477 {
478         bool mb = false;
479         mb = FM7_MAINIO::load_state(state_fio);
480         return mb;
481 }