2 * FM-7 Main I/O [fm7_mainio.h]
4 * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
7 * Jan 03, 2015 : Initial
11 #ifndef _VM_FM7_MAINIO_H_
12 #define _VM_FM7_MAINIO_H_
15 #include "fm7_common.h"
17 #include "../device.h"
23 #if defined(USE_AY_3_8910_AS_PSG) && !defined(_FM77AV_VARIANTS)
39 #if defined(CAPABLE_JCOMMCARD)
45 class FM7_MAINIO : public DEVICE {
51 int event_beep_oneshot;
54 int event_fdc_motor_2HD;
58 outputs_t clock_status;
59 outputs_t printer_reset_bus;
60 outputs_t printer_strobe_bus;
61 outputs_t printer_select_bus;
66 uint8_t io_w_latch[0x100];
69 bool clock_fast; // bit0
71 bool lpt_strobe; // bit6
72 bool lpt_slctin; // bit7
74 uint8_t lpt_outdata; //
77 bool cmt_indat; // bit7 : Data of casette.
78 bool cmt_invert; // Invert signal
79 bool lpt_det2; // bit5 : DET2(Normally high).
80 bool lpt_det1; // bit4 : DET1(Normally high).
81 bool lpt_pe; // bit3 : PAPER EMPTY.
82 bool lpt_ackng_inv; // bit2 : ACK
83 bool lpt_error_inv; // bit1 : ERROR
84 bool lpt_busy; // bit0 : BUSY.
88 uint8_t irqmask_reg0; // bit7-4, bit2-0 , '1' is enable. '0' is disable.
89 // 7-4 : RS232C / SYNDET,RXRDY,TXRDY,MFD
93 bool irqmask_syndet; // bit7: "0" = mask.
94 bool irqmask_rxrdy; // bit6: "0" = mask.
95 bool irqmask_txrdy; // bit5: "0" = mask.
96 bool irqmask_mfd; // bit4: "0" = mask.
97 bool irqmask_timer; // bit2: "0" = mask.
98 bool irqmask_printer; // bit1: "0" = mask.
99 bool irqmask_keyboard; // bit0: "0" = mask.
102 uint8_t irqstat_reg0; // bit 3-0, '0' is happened, '1' is not happened.
103 // bit3 : extended interrupt
104 // bit2-0: Same as FD02 : W .
105 /* FD03 : W , '1' = ON*/
107 bool irqstat_printer;
108 bool irqstat_keyboard;
111 bool irqreq_keyboard;
114 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
115 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
116 bool stat_kanjirom; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
117 bool stat_400linemode; // R/W : bit3, '0' = 400line, '1' = 200line.
118 #elif defined(_FM77_VARIANTS)
119 bool stat_kanjirom; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
120 bool stat_400linecard;// R/W : bit4, '0' = connected. FM-77 Only.
121 //bool stat_400linemode; // R/W : bit3, '0' = 400line, '1' = 200line.
125 bool drqstat_fdc_2hd;
126 bool irqstat_fdc_2hd;
127 bool stat_fdmode_2hd; // R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
129 bool firq_break_key; // bit1, ON = '0'.
130 bool firq_sub_attention; // bit0, ON = '0'.
132 bool intmode_fdc; // bit2, '0' = normal, '1' = SFD.
133 #if defined(_FM77AV_VARIANTS)
137 bool extdet_neg; // bit0 : '1' = none , '0' = exists.
139 bool sub_halt; // bit7 : '1' Halt req.
140 bool sub_cancel; // bit6 : '1' Cancel req.
141 bool sub_halt_bak; // bit7 : shadow.
142 bool sub_cancel_bak; // bit6 : shadow.
143 bool req_z80run; // bit0 : '1' = Z80. Maybe only FM-7/77.
146 /* FD06 : R/W : RS-232C */
147 /* FD07 : R/W : RS-232C */
153 bool irqreq_txrdy; /* FD08 : Grafic pen, not implemented */
154 /* FD09 : Grafic pen, not implemented */
155 /* FD0A : Grafic pen, not implemented */
162 #if defined(_FM77AV_VARIANTS)
166 uint8_t sub_monitor_type; // bit 2 - 0: default = 0.
169 /* FD15 / FD46 / FD51 : W */
171 bool connect_psg; // [0]
173 bool connect_opn; // [0]
174 bool connect_whg; // [1]
175 bool connect_thg; // [2]
177 uint8_t opn_address[4];
180 uint8_t opn_cmdreg[4]; // OPN register, bit 3-0, maybe dummy.
181 uint8_t opn_ch3mode[4];
182 uint8_t opn_prescaler_type[4];
185 bool intstat_whg; // bit3 : OPN interrupt. '0' = happened.
187 bool intstat_thg; // bit3 : OPN interrupt. '0' = happened.
191 bool intstat_opn; // bit3 : OPN interrupt. '0' = happened.
192 bool intstat_mouse; // bit2 : Mouse interrupt (not OPN-Mouse?), '0' = happened.
194 bool mouse_enable; // bit2 : '1' = enable.
203 uint8_t fdc_trackreg;
212 uint8_t fdc_headreg; // bit0, '0' = side0, '1' = side1
215 bool fdc_motor; // bit7 : '1' = ON, '0' = OFF
216 uint8_t fdc_drvsel; // bit 1-0
217 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
218 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
221 uint8_t fdc_drive_table[4];
222 uint8_t fdc_reg_fd1e;
229 uint8_t irqreg_fdc_2HD;
232 bool connect_kanjiroml1;
233 #ifdef _FM77AV_VARIANTS
234 bool connect_kanjiroml2;
238 /* FD30 - FD36 : RW */
240 bool connect_fdc_2HD;
243 uint8_t fdc_2HD_statreg;
245 uint8_t fdc_2HD_cmdreg;
248 uint8_t fdc_2HD_trackreg;
251 uint8_t fdc_2HD_sectreg;
254 uint8_t fdc_2HD_datareg;
257 uint8_t fdc_2HD_headreg; // bit0, '0' = side0, '1' = side1
260 bool fdc_2HD_motor; // bit7 : '1' = ON, '0' = OFF
261 uint8_t fdc_2HD_drvsel; // bit 1-0
263 //uint8_t irqreg_2HD_fdc;
264 //bool irqstat_2HD_fdc;
265 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
269 bool enable_initiator;
275 void set_clockmode(uint8_t flags);
276 uint8_t get_clockmode(void);
277 void set_cmt_motor(uint8_t flag);
278 bool get_cmt_motor(void);
280 virtual uint8_t get_port_fd00(void);
281 virtual void set_port_fd00(uint8_t data);
282 virtual uint8_t get_port_fd02(void);
283 virtual void set_port_fd02(uint8_t val);
284 virtual uint8_t get_irqstat_fd03(void);
285 virtual uint8_t get_extirq_fd17(void);
286 virtual void set_ext_fd17(uint8_t data);
288 void set_beep(uint32_t data); // fd03
289 virtual void reset_sound(void);
290 void reset_printer(void);
292 void reset_fdc(void);
293 void set_fdc_motor(bool flag);
295 void reset_fdc_2HD(void);
296 void set_fdc_motor_2HD(bool flag);
298 virtual void do_irq(void);
299 virtual void set_irq_syndet(bool flag);
300 virtual void set_irq_rxrdy(bool flag);
301 virtual void set_irq_txrdy(bool flag);
303 virtual void set_irq_timer(bool flag);
304 virtual void set_irq_printer(bool flag);
305 virtual void set_irq_keyboard(bool flag);
306 //virtual void set_irq_opn(bool flag);
307 virtual void set_irq_mfd(bool flag);
308 virtual void set_drq_mfd(bool flag);
310 virtual void set_irq_mfd_2HD(bool flag);
311 virtual void set_drq_mfd_2HD(bool flag);
314 virtual void do_firq(void);
315 virtual void do_nmi(bool flag);
317 void set_break_key(bool pressed);
318 void set_sub_attention(bool flag);
320 uint8_t get_fd04(void);
321 void set_fd04(uint8_t val);
322 uint8_t get_fd05(void);
323 void set_fd05(uint8_t val);
325 void set_extdet(bool flag);
327 virtual void set_psg(uint8_t val);
328 virtual uint8_t get_psg(void);
330 virtual void set_psg_cmd(uint8_t cmd);
332 virtual void write_fd0f(void);
333 virtual uint8_t read_fd0f(void);
334 bool get_rommode_fd0f(void);
335 #if defined(_FM77AV_VARIANTS)
337 uint8_t subsystem_read_status(void);
340 virtual void set_opn(int index, uint8_t val);
341 virtual uint8_t get_opn(int index);
342 virtual void set_opn_cmd(int index, uint8_t cmd);
343 virtual void write_opn_reg(int index, uint32_t addr, uint32_t data);
345 virtual uint8_t get_extirq_whg(void);
346 virtual uint8_t get_extirq_thg(void);
348 void write_kanjiaddr_lo(uint8_t addr);
349 void write_kanjiaddr_hi(uint8_t addr);
350 uint8_t read_kanjidata_left(void);
351 uint8_t read_kanjidata_right(void);
352 #if defined(CAPABLE_KANJI_CLASS2)
353 void write_kanjiaddr_lo_l2(uint8_t addr);
354 void write_kanjiaddr_hi_l2(uint8_t addr);
355 uint8_t read_kanjidata_left_l2(void);
356 uint8_t read_kanjidata_right_l2(void);
359 uint8_t get_fdc_fd1c(void);
360 void set_fdc_fd1c(uint8_t val);
361 void set_fdc_fd1d(uint8_t val);
363 uint8_t get_fdc_fd1e(void);
364 void set_fdc_fd1e(uint8_t val);
366 uint8_t get_fdc_stat(void);
367 void set_fdc_cmd(uint8_t val);
368 uint8_t fdc_getdrqirq(void);
370 void set_fdc_track(uint8_t val);
371 uint8_t get_fdc_track(void);
373 uint8_t get_fdc_motor(void);
374 void set_fdc_sector(uint8_t val);
375 uint8_t get_fdc_sector(void);
377 void set_fdc_data(uint8_t val);
378 uint8_t get_fdc_data(void);
380 void set_fdc_misc(uint8_t val);
381 uint8_t get_fdc_misc(void);
383 uint8_t get_fdc_fd1c_2HD(void);
384 void set_fdc_fd1c_2HD(uint8_t val);
385 void set_fdc_fd1d_2HD(uint8_t val);
387 uint8_t get_fdc_fd1e_2HD(void);
388 void set_fdc_fd1e_2HD(uint8_t val);
390 uint8_t get_fdc_stat_2HD(void);
391 void set_fdc_cmd_2HD(uint8_t val);
392 uint8_t fdc_getdrqirq_2HD(void);
394 void set_fdc_track_2HD(uint8_t val);
395 uint8_t get_fdc_track_2HD(void);
397 uint8_t get_fdc_motor_2HD(void);
398 void set_fdc_sector_2HD(uint8_t val);
399 uint8_t get_fdc_sector_2HD(void);
401 void set_fdc_data_2HD(uint8_t val);
402 uint8_t get_fdc_data_2HD(void);
404 void set_fdc_misc_2HD(uint8_t val);
405 uint8_t get_fdc_misc_2HD(void);
407 /* Signal Handlers */
408 void set_beep_oneshot(void);
411 void event_beep_off(void);
412 void event_beep_cycle(void);
415 YM2203* opn[3]; // 0=OPN 1=WHG 2=THG
416 # if !defined(_FM77AV_VARIANTS)
417 # if defined(USE_AY_3_8910_AS_PSG)
420 YM2203* psg; // Optional PSG.
429 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
432 bool uart_enabled[3];
436 bool modem_irqmask_rxrdy;
437 bool modem_irqmask_txrdy;
442 bool midi_uart_irqmask;
455 //FM7_RS232C *rs232c;
457 FM7::KANJIROM *kanjiclass1;
458 FM7::KANJIROM *kanjiclass2;
459 FM7::DISPLAY *display;
460 FM7::KEYBOARD *keyboard;
461 FM7::FM7_MAINMEM *mainmem;
468 #if defined(CAPABLE_JCOMMCARD)
469 FM7::FM7_JCOMMCARD *jcommcard;
472 void call_write_signal(T *np, int id, uint32_t data, uint32_t mask)
474 //T *nnp = static_cast<T *>(np);
475 static_cast<T *>(np)->write_signal(id, data, mask);
478 void call_write_data8(T *np, uint32_t addr, uint32_t data)
480 //T *nnp = static_cast<T *>(np);
481 static_cast<T *>(np)->write_data8(addr, data);
484 uint32_t call_read_data8(T *np, uint32_t addr)
486 //T *nnp = static_cast<T *>(np);
487 return static_cast<T *>(np)->read_data8(addr);
490 void call_write_dma_data8(T *np, uint32_t addr, uint32_t data)
492 //T *nnp = static_cast<T *>(np);
493 static_cast<T *>(np)->write_dma_data8(addr, data);
496 uint32_t call_read_dma_data8(T *np, uint32_t addr)
498 //T *nnp = static_cast<T *>(np);
499 return static_cast<T *>(np)->read_dma_data8(addr);
502 bool decl_state_opn(FILEIO *state_fio, bool loading);
505 FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu);
507 void event_vline(int v, int clock);
509 uint8_t opn_regs[4][0x100];
510 uint32_t read_io8(uint32_t addr); // This is only for debug.
512 virtual void initialize();
514 virtual void write_data8(uint32_t addr, uint32_t data);
515 void write_dma_data8(uint32_t addr, uint32_t data);
516 void write_dma_io8(uint32_t addr, uint32_t data);
518 virtual uint32_t read_data8(uint32_t addr);
519 uint32_t read_dma_data8(uint32_t addr);
520 uint32_t read_dma_io8(uint32_t addr);
522 virtual void write_signal(int id, uint32_t data, uint32_t mask);
523 virtual uint32_t read_signal(int id);
525 virtual void event_callback(int event_id, int err);
526 virtual void reset();
527 virtual void update_config();
528 virtual void save_state(FILEIO *state_fio);
529 virtual bool load_state(FILEIO *state_fio);
530 virtual bool decl_state(FILEIO *state_fio, bool loading);
532 void set_context_printer(DEVICE *p)
536 void set_context_kanjirom_class1(DEVICE *p)
538 kanjiclass1 = (FM7::KANJIROM *)p;
539 if(p != NULL) connect_kanjiroml1 = true;
541 virtual void set_context_kanjirom_class2(DEVICE *p)
543 #if defined(_FM77AV_VARIANTS)
544 kanjiclass2 = (FM7::KANJIROM *)p;
545 if(p != NULL) connect_kanjiroml2 = true;
548 void set_context_beep(DEVICE *p)
550 pcm1bit = (PCM1BIT *)p;
553 void set_context_datarec(DATAREC *p)
558 void set_context_opn(YM2203 *p, int ch)
560 if((ch < 0) || (ch > 2)) return;
578 #if !defined(_FM77AV_VARIANTS)
579 # if defined(USE_AY_3_8910_AS_PSG)
580 virtual void set_context_psg(AY_3_891X *p)
585 virtual void set_context_psg(YM2203 *p)
591 void set_context_fdc(MB8877 *p){
594 irqreg_fdc = 0xff; //0b11111111;
598 irqreg_fdc = 0x3f; //0b00111111;
600 this->out_debug_log(_T("FDC: connect=%d"), connect_fdc);
604 void set_context_fdc_2HD(MB8877 *p){
606 connect_fdc_2HD = false;
607 irqreg_fdc_2HD = 0xff; //0b11111111;
609 connect_fdc_2HD = true;
611 irqreg_fdc_2HD = 0x3f; //0b00111111;
613 this->out_debug_log(_T("FDC(2HD): connect=%d"), connect_fdc);
617 void set_context_maincpu(MC6809 *p){
620 void set_context_mainmem(DEVICE *p){
621 mainmem = (FM7_MAINMEM *)p;
623 void set_context_subcpu(MC6809 *p){
626 void set_context_display(DEVICE *p){
627 display = (DISPLAY *)p;
629 void set_context_keyboard(DEVICE *p){
630 keyboard = (FM7::KEYBOARD *)p;
632 void set_context_joystick(DEVICE *p){
633 joystick = (FM7::JOYSTICK *)p;
635 void set_context_clock_status(DEVICE *p, int id, uint32_t mask) {
636 register_output_signal(&clock_status, p, id, mask);
638 void set_context_printer_reset(DEVICE *p, int id, uint32_t mask) {
639 register_output_signal(&printer_reset_bus, p, id, mask);
641 void set_context_printer_strobe(DEVICE *p, int id, uint32_t mask) {
642 register_output_signal(&printer_strobe_bus, p, id, mask);
644 void set_context_printer_select(DEVICE *p, int id, uint32_t mask) {
645 register_output_signal(&printer_select_bus, p, id, mask);
647 void set_context_irq(DEVICE *p, int id, uint32_t mask) {
648 register_output_signal(&irq_bus, p, id, mask);
650 void set_context_firq(DEVICE *p, int id, uint32_t mask) {
651 register_output_signal(&firq_bus, p, id, mask);
653 void set_context_nmi(DEVICE *p, int id, uint32_t mask) {
654 register_output_signal(&nmi_bus, p, id, mask);
657 void set_context_z80cpu(Z80 *p) {
662 void set_context_jcommcard(DEVICE *p) {
663 #if defined(CAPABLE_JCOMMCARD)
664 jcommcard = (FM7::FM7_JCOMMCARD *)p;
667 void set_context_uart(int num, I8251 *p) {
672 uart_enabled[num] = true;
674 uart_enabled[num] = false;
677 void set_context_rs232c_dtr(AND *p) {
678 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
683 void set_context_dmac(HD6844 *p) {