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)
38 #if defined(CAPABLE_JCOMMCARD)
42 class FM7_MAINIO : public DEVICE {
48 int event_beep_oneshot;
51 int event_fdc_motor_2HD;
55 outputs_t clock_status;
56 outputs_t printer_reset_bus;
57 outputs_t printer_strobe_bus;
58 outputs_t printer_select_bus;
63 uint8_t io_w_latch[0x100];
66 bool clock_fast; // bit0
68 bool lpt_strobe; // bit6
69 bool lpt_slctin; // bit7
71 uint8_t lpt_outdata; //
74 bool cmt_indat; // bit7 : Data of casette.
75 bool cmt_invert; // Invert signal
76 bool lpt_det2; // bit5 : DET2(Normally high).
77 bool lpt_det1; // bit4 : DET1(Normally high).
78 bool lpt_pe; // bit3 : PAPER EMPTY.
79 bool lpt_ackng_inv; // bit2 : ACK
80 bool lpt_error_inv; // bit1 : ERROR
81 bool lpt_busy; // bit0 : BUSY.
85 uint8_t irqmask_reg0; // bit7-4, bit2-0 , '1' is enable. '0' is disable.
86 // 7-4 : RS232C / SYNDET,RXRDY,TXRDY,MFD
90 bool irqmask_syndet; // bit7: "0" = mask.
91 bool irqmask_rxrdy; // bit6: "0" = mask.
92 bool irqmask_txrdy; // bit5: "0" = mask.
93 bool irqmask_mfd; // bit4: "0" = mask.
94 bool irqmask_timer; // bit2: "0" = mask.
95 bool irqmask_printer; // bit1: "0" = mask.
96 bool irqmask_keyboard; // bit0: "0" = mask.
99 uint8_t irqstat_reg0; // bit 3-0, '0' is happened, '1' is not happened.
100 // bit3 : extended interrupt
101 // bit2-0: Same as FD02 : W .
102 /* FD03 : W , '1' = ON*/
104 bool irqstat_printer;
105 bool irqstat_keyboard;
108 bool irqreq_keyboard;
111 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
112 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
113 bool stat_kanjirom; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
114 bool stat_400linemode; // R/W : bit3, '0' = 400line, '1' = 200line.
115 #elif defined(_FM77_VARIANTS)
116 bool stat_kanjirom; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
117 bool stat_400linecard;// R/W : bit4, '0' = connected. FM-77 Only.
118 //bool stat_400linemode; // R/W : bit3, '0' = 400line, '1' = 200line.
122 bool drqstat_fdc_2hd;
123 bool irqstat_fdc_2hd;
124 bool stat_fdmode_2hd; // R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
126 bool firq_break_key; // bit1, ON = '0'.
127 bool firq_sub_attention; // bit0, ON = '0'.
129 bool intmode_fdc; // bit2, '0' = normal, '1' = SFD.
130 #if defined(_FM77AV_VARIANTS)
134 bool extdet_neg; // bit0 : '1' = none , '0' = exists.
136 bool sub_halt; // bit7 : '1' Halt req.
137 bool sub_cancel; // bit6 : '1' Cancel req.
138 bool sub_halt_bak; // bit7 : shadow.
139 bool sub_cancel_bak; // bit6 : shadow.
140 bool req_z80run; // bit0 : '1' = Z80. Maybe only FM-7/77.
143 /* FD06 : R/W : RS-232C */
144 /* FD07 : R/W : RS-232C */
150 bool irqreq_txrdy; /* FD08 : Grafic pen, not implemented */
151 /* FD09 : Grafic pen, not implemented */
152 /* FD0A : Grafic pen, not implemented */
159 #if defined(_FM77AV_VARIANTS)
163 uint8_t sub_monitor_type; // bit 2 - 0: default = 0.
166 /* FD15 / FD46 / FD51 : W */
168 bool connect_psg; // [0]
170 bool connect_opn; // [0]
171 bool connect_whg; // [1]
172 bool connect_thg; // [2]
174 uint8_t opn_address[4];
177 uint8_t opn_cmdreg[4]; // OPN register, bit 3-0, maybe dummy.
178 uint8_t opn_ch3mode[4];
179 uint8_t opn_prescaler_type[4];
182 bool intstat_whg; // bit3 : OPN interrupt. '0' = happened.
184 bool intstat_thg; // bit3 : OPN interrupt. '0' = happened.
188 bool intstat_opn; // bit3 : OPN interrupt. '0' = happened.
189 bool intstat_mouse; // bit2 : Mouse interrupt (not OPN-Mouse?), '0' = happened.
191 bool mouse_enable; // bit2 : '1' = enable.
200 uint8_t fdc_trackreg;
209 uint8_t fdc_headreg; // bit0, '0' = side0, '1' = side1
212 bool fdc_motor; // bit7 : '1' = ON, '0' = OFF
213 uint8_t fdc_drvsel; // bit 1-0
214 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
215 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
218 uint8_t fdc_drive_table[4];
219 uint8_t fdc_reg_fd1e;
226 uint8_t irqreg_fdc_2HD;
229 bool connect_kanjiroml1;
230 #ifdef _FM77AV_VARIANTS
231 bool connect_kanjiroml2;
235 /* FD30 - FD36 : RW */
237 bool connect_fdc_2HD;
240 uint8_t fdc_2HD_statreg;
242 uint8_t fdc_2HD_cmdreg;
245 uint8_t fdc_2HD_trackreg;
248 uint8_t fdc_2HD_sectreg;
251 uint8_t fdc_2HD_datareg;
254 uint8_t fdc_2HD_headreg; // bit0, '0' = side0, '1' = side1
257 bool fdc_2HD_motor; // bit7 : '1' = ON, '0' = OFF
258 uint8_t fdc_2HD_drvsel; // bit 1-0
260 //uint8_t irqreg_2HD_fdc;
261 //bool irqstat_2HD_fdc;
262 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
266 bool enable_initiator;
272 void set_clockmode(uint8_t flags);
273 uint8_t get_clockmode(void);
274 void set_cmt_motor(uint8_t flag);
275 bool get_cmt_motor(void);
277 virtual uint8_t get_port_fd00(void);
278 virtual void set_port_fd00(uint8_t data);
279 virtual uint8_t get_port_fd02(void);
280 virtual void set_port_fd02(uint8_t val);
281 virtual uint8_t get_irqstat_fd03(void);
282 virtual uint8_t get_extirq_fd17(void);
283 virtual void set_ext_fd17(uint8_t data);
285 void set_beep(uint32_t data); // fd03
286 virtual void reset_sound(void);
287 void reset_printer(void);
289 void reset_fdc(void);
290 void set_fdc_motor(bool flag);
292 void reset_fdc_2HD(void);
293 void set_fdc_motor_2HD(bool flag);
295 virtual void do_irq(void);
296 virtual void set_irq_syndet(bool flag);
297 virtual void set_irq_rxrdy(bool flag);
298 virtual void set_irq_txrdy(bool flag);
300 virtual void set_irq_timer(bool flag);
301 virtual void set_irq_printer(bool flag);
302 virtual void set_irq_keyboard(bool flag);
303 //virtual void set_irq_opn(bool flag);
304 virtual void set_irq_mfd(bool flag);
305 virtual void set_drq_mfd(bool flag);
307 virtual void set_irq_mfd_2HD(bool flag);
308 virtual void set_drq_mfd_2HD(bool flag);
311 virtual void do_firq(void);
312 virtual void do_nmi(bool flag);
314 void set_break_key(bool pressed);
315 void set_sub_attention(bool flag);
317 uint8_t get_fd04(void);
318 void set_fd04(uint8_t val);
319 uint8_t get_fd05(void);
320 void set_fd05(uint8_t val);
322 void set_extdet(bool flag);
324 virtual void set_psg(uint8_t val);
325 virtual uint8_t get_psg(void);
327 virtual void set_psg_cmd(uint8_t cmd);
329 virtual void write_fd0f(void);
330 virtual uint8_t read_fd0f(void);
331 bool get_rommode_fd0f(void);
332 #if defined(_FM77AV_VARIANTS)
334 uint8_t subsystem_read_status(void);
337 virtual void set_opn(int index, uint8_t val);
338 virtual uint8_t get_opn(int index);
339 virtual void set_opn_cmd(int index, uint8_t cmd);
340 virtual void write_opn_reg(int index, uint32_t addr, uint32_t data);
342 virtual uint8_t get_extirq_whg(void);
343 virtual uint8_t get_extirq_thg(void);
345 void write_kanjiaddr_lo(uint8_t addr);
346 void write_kanjiaddr_hi(uint8_t addr);
347 uint8_t read_kanjidata_left(void);
348 uint8_t read_kanjidata_right(void);
349 #if defined(CAPABLE_KANJI_CLASS2)
350 void write_kanjiaddr_lo_l2(uint8_t addr);
351 void write_kanjiaddr_hi_l2(uint8_t addr);
352 uint8_t read_kanjidata_left_l2(void);
353 uint8_t read_kanjidata_right_l2(void);
356 uint8_t get_fdc_fd1c(void);
357 void set_fdc_fd1c(uint8_t val);
358 void set_fdc_fd1d(uint8_t val);
360 uint8_t get_fdc_fd1e(void);
361 void set_fdc_fd1e(uint8_t val);
363 uint8_t get_fdc_stat(void);
364 void set_fdc_cmd(uint8_t val);
365 uint8_t fdc_getdrqirq(void);
367 void set_fdc_track(uint8_t val);
368 uint8_t get_fdc_track(void);
370 uint8_t get_fdc_motor(void);
371 void set_fdc_sector(uint8_t val);
372 uint8_t get_fdc_sector(void);
374 void set_fdc_data(uint8_t val);
375 uint8_t get_fdc_data(void);
377 void set_fdc_misc(uint8_t val);
378 uint8_t get_fdc_misc(void);
380 uint8_t get_fdc_fd1c_2HD(void);
381 void set_fdc_fd1c_2HD(uint8_t val);
382 void set_fdc_fd1d_2HD(uint8_t val);
384 uint8_t get_fdc_fd1e_2HD(void);
385 void set_fdc_fd1e_2HD(uint8_t val);
387 uint8_t get_fdc_stat_2HD(void);
388 void set_fdc_cmd_2HD(uint8_t val);
389 uint8_t fdc_getdrqirq_2HD(void);
391 void set_fdc_track_2HD(uint8_t val);
392 uint8_t get_fdc_track_2HD(void);
394 uint8_t get_fdc_motor_2HD(void);
395 void set_fdc_sector_2HD(uint8_t val);
396 uint8_t get_fdc_sector_2HD(void);
398 void set_fdc_data_2HD(uint8_t val);
399 uint8_t get_fdc_data_2HD(void);
401 void set_fdc_misc_2HD(uint8_t val);
402 uint8_t get_fdc_misc_2HD(void);
404 /* Signal Handlers */
405 void set_beep_oneshot(void);
408 void event_beep_off(void);
409 void event_beep_cycle(void);
412 YM2203* opn[3]; // 0=OPN 1=WHG 2=THG
413 # if !defined(_FM77AV_VARIANTS)
414 # if defined(USE_AY_3_8910_AS_PSG)
417 YM2203* psg; // Optional PSG.
426 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
429 bool uart_enabled[3];
433 bool modem_irqmask_rxrdy;
434 bool modem_irqmask_txrdy;
439 bool midi_uart_irqmask;
452 //FM7_RS232C *rs232c;
454 KANJIROM *kanjiclass1;
455 KANJIROM *kanjiclass2;
459 FM7_MAINMEM *mainmem;
464 #if defined(CAPABLE_JCOMMCARD)
465 FM7_JCOMMCARD *jcommcard;
468 void call_write_signal(T *np, int id, uint32_t data, uint32_t mask)
470 //T *nnp = static_cast<T *>(np);
471 static_cast<T *>(np)->write_signal(id, data, mask);
474 void call_write_data8(T *np, uint32_t addr, uint32_t data)
476 //T *nnp = static_cast<T *>(np);
477 static_cast<T *>(np)->write_data8(addr, data);
480 uint32_t call_read_data8(T *np, uint32_t addr)
482 //T *nnp = static_cast<T *>(np);
483 return static_cast<T *>(np)->read_data8(addr);
486 void call_write_dma_data8(T *np, uint32_t addr, uint32_t data)
488 //T *nnp = static_cast<T *>(np);
489 static_cast<T *>(np)->write_dma_data8(addr, data);
492 uint32_t call_read_dma_data8(T *np, uint32_t addr)
494 //T *nnp = static_cast<T *>(np);
495 return static_cast<T *>(np)->read_dma_data8(addr);
498 void decl_state_opn(void);
500 FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu);
502 void event_vline(int v, int clock);
504 uint8_t opn_regs[4][0x100];
505 uint32_t read_io8(uint32_t addr); // This is only for debug.
507 virtual void initialize();
509 virtual void write_data8(uint32_t addr, uint32_t data);
510 void write_dma_data8(uint32_t addr, uint32_t data);
511 void write_dma_io8(uint32_t addr, uint32_t data);
513 virtual uint32_t read_data8(uint32_t addr);
514 uint32_t read_dma_data8(uint32_t addr);
515 uint32_t read_dma_io8(uint32_t addr);
517 virtual void write_signal(int id, uint32_t data, uint32_t mask);
518 virtual uint32_t read_signal(int id);
520 virtual void event_callback(int event_id, int err);
521 virtual void reset();
522 virtual void update_config();
523 virtual void save_state(FILEIO *state_fio);
524 virtual bool load_state(FILEIO *state_fio);
525 virtual void decl_state(void);
527 void set_context_printer(DEVICE *p)
531 void set_context_kanjirom_class1(DEVICE *p)
533 kanjiclass1 = (KANJIROM *)p;
534 if(p != NULL) connect_kanjiroml1 = true;
536 virtual void set_context_kanjirom_class2(DEVICE *p)
538 #if defined(_FM77AV_VARIANTS)
539 kanjiclass2 = (KANJIROM *)p;
540 if(p != NULL) connect_kanjiroml2 = true;
543 void set_context_beep(DEVICE *p)
545 pcm1bit = (PCM1BIT *)p;
548 void set_context_datarec(DATAREC *p)
553 void set_context_opn(YM2203 *p, int ch)
555 if((ch < 0) || (ch > 2)) return;
573 #if !defined(_FM77AV_VARIANTS)
574 # if defined(USE_AY_3_8910_AS_PSG)
575 virtual void set_context_psg(AY_3_891X *p)
580 virtual void set_context_psg(YM2203 *p)
586 void set_context_fdc(MB8877 *p){
589 irqreg_fdc = 0xff; //0b11111111;
593 irqreg_fdc = 0x3f; //0b00111111;
595 this->out_debug_log(_T("FDC: connect=%d"), connect_fdc);
599 void set_context_fdc_2HD(MB8877 *p){
601 connect_fdc_2HD = false;
602 irqreg_fdc_2HD = 0xff; //0b11111111;
604 connect_fdc_2HD = true;
606 irqreg_fdc_2HD = 0x3f; //0b00111111;
608 this->out_debug_log(_T("FDC(2HD): connect=%d"), connect_fdc);
612 void set_context_maincpu(MC6809 *p){
615 void set_context_mainmem(DEVICE *p){
616 mainmem = (FM7_MAINMEM *)p;
618 void set_context_subcpu(MC6809 *p){
621 void set_context_display(DEVICE *p){
622 display = (DISPLAY *)p;
624 void set_context_keyboard(DEVICE *p){
625 keyboard = (KEYBOARD *)p;
627 void set_context_joystick(DEVICE *p){
628 joystick = (JOYSTICK *)p;
630 void set_context_clock_status(DEVICE *p, int id, uint32_t mask) {
631 register_output_signal(&clock_status, p, id, mask);
633 void set_context_printer_reset(DEVICE *p, int id, uint32_t mask) {
634 register_output_signal(&printer_reset_bus, p, id, mask);
636 void set_context_printer_strobe(DEVICE *p, int id, uint32_t mask) {
637 register_output_signal(&printer_strobe_bus, p, id, mask);
639 void set_context_printer_select(DEVICE *p, int id, uint32_t mask) {
640 register_output_signal(&printer_select_bus, p, id, mask);
642 void set_context_irq(DEVICE *p, int id, uint32_t mask) {
643 register_output_signal(&irq_bus, p, id, mask);
645 void set_context_firq(DEVICE *p, int id, uint32_t mask) {
646 register_output_signal(&firq_bus, p, id, mask);
648 void set_context_nmi(DEVICE *p, int id, uint32_t mask) {
649 register_output_signal(&nmi_bus, p, id, mask);
652 void set_context_z80cpu(Z80 *p) {
657 void set_context_jcommcard(DEVICE *p) {
658 #if defined(CAPABLE_JCOMMCARD)
659 jcommcard = (FM7_JCOMMCARD *)p;
662 void set_context_uart(int num, I8251 *p) {
667 uart_enabled[num] = true;
669 uart_enabled[num] = false;
672 void set_context_rs232c_dtr(AND *p) {
673 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
678 void set_context_dmac(HD6844 *p) {