OSDN Git Service

[VM][FM7][SUB] (MAYBE) Fixed bugs around sub attention firq.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / floppy.cpp
1 /*
2  * FM-7 Main I/O -> FDC [floppy.cpp]
3  *
4  * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
5  * License: GPLv2
6  * History:
7  *   Mar 19, 2015 : Initial, split from fm7_mainio.cpp .
8  *
9  */
10
11 #include "fm7_mainio.h"
12
13 #include "../mc6809.h"
14 #include "../z80.h"
15
16 #include "../mb8877.h"
17 #include "../disk.h"
18
19 void FM7_MAINIO::reset_fdc(void)
20 {
21   
22         fdc_statreg = 0x00;
23         fdc_cmdreg = 0x00;
24         fdc_trackreg = 0x00;
25         fdc_sectreg = 0x00;
26         fdc_datareg = 0x00;
27         fdc_headreg = 0xfe;
28         fdc_drvsel = 0x00;
29         fdc_motor = false;
30         irqreg_fdc = 0xff; //0b11111111;
31         if(connect_fdc) {
32                 extdet_neg = true;
33                 irqreg_fdc = 0x1f; //0b00011111;
34         }
35         irqstat_fdc = false;
36         irqmask_mfd = true;
37 }
38
39 /* FDD */
40
41 void FM7_MAINIO::set_fdc_cmd(uint8 val)
42 {
43         if(!connect_fdc) return;
44         irqreg_fdc = 0x00;
45         fdc_cmdreg = val;
46         fdc->write_io8(0, val & 0x00ff);
47 }
48
49 uint8 FM7_MAINIO::get_fdc_stat(void)
50 {
51         if(!connect_fdc) return 0xff;
52         fdc_statreg =  fdc->read_io8(0);
53         return fdc_statreg;
54 }
55
56 void FM7_MAINIO::set_fdc_track(uint8 val)
57 {
58         if(!connect_fdc) return;
59         // if mode is 2DD and type-of-image = 2D then val >>= 1;
60         fdc_trackreg = val;
61         fdc->write_io8(1, val & 0x00ff);
62 }
63
64 uint8 FM7_MAINIO::get_fdc_track(void)
65 {
66         if(!connect_fdc) return 0xff;
67         fdc_trackreg = fdc->read_io8(1);
68         return fdc_trackreg;
69 }
70
71 void FM7_MAINIO::set_fdc_sector(uint8 val)
72 {
73         if(!connect_fdc) return;
74         fdc_sectreg = val;
75         fdc->write_io8(2, val & 0x00ff);
76 }
77
78 uint8 FM7_MAINIO::get_fdc_sector(void)
79 {
80         if(!connect_fdc) return 0xff;
81         fdc_sectreg = fdc->read_io8(2);
82         return fdc_sectreg;
83 }
84   
85 void FM7_MAINIO::set_fdc_data(uint8 val)
86 {
87         if(!connect_fdc) return;
88         fdc_datareg = val;
89         fdc->write_io8(3, val & 0x00ff);
90 }
91
92 uint8 FM7_MAINIO::get_fdc_data(void)
93 {
94         if(!connect_fdc) return 0xff;
95         fdc_datareg = fdc->read_io8(3);
96         return fdc_datareg;
97 }
98
99 uint8 FM7_MAINIO::get_fdc_motor(void)
100 {
101   uint8 val = 0x3c; //0b00111100;
102         if(!connect_fdc) return 0xff;
103         if(fdc_motor) val |= 0x80;
104         val = val | (fdc_drvsel & 0x03);
105         return val;
106 }
107   
108 void FM7_MAINIO::set_fdc_fd1c(uint8 val)
109 {
110         if(!connect_fdc) return;
111         fdc_headreg = (val & 0x01) | 0xfe;
112         fdc->write_signal(SIG_MB8877_SIDEREG, val, 0x01);
113 }
114
115 uint8 FM7_MAINIO::get_fdc_fd1c(void)
116 {
117         if(!connect_fdc) return 0xff;
118         return fdc_headreg;
119 }
120
121 void FM7_MAINIO::set_fdc_fd1d(uint8 val)
122 {
123         bool backup_motor = fdc_motor;
124         if(!connect_fdc) return;
125         if((val & 0x80) != 0) {
126                 fdc_motor = true;
127         } else {
128                 fdc_motor = false;
129         }
130         //      fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x07);
131         fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03);
132         if(fdc_motor != backup_motor) {
133                 if(fdc_motor) {
134                         register_event(this, EVENT_FD_MOTOR_ON, 1000.0 * 1000.0, false, NULL); // Motor ON After 1.0Sec.
135                 } else {
136                         register_event(this, EVENT_FD_MOTOR_OFF, 1000.0 * 300.0, false, NULL); // Motor ON After 0.3Sec.
137                 }
138         }
139         fdc_drvsel = val;
140 }
141
142 void FM7_MAINIO::set_irq_mfd(bool flag)
143 {
144         uint8 backup = irqreg_fdc;
145
146         if(!connect_fdc) return;
147         if(flag) {
148                 irqreg_fdc |= 0x40; //0b01000000;
149                 if(!(irqmask_mfd)) irqstat_fdc = true;
150         } else {
151                 irqreg_fdc &= 0xbf; //0b10111111;
152                 irqstat_fdc = false;
153         }
154         if(backup != irqreg_fdc) do_irq();
155         return;
156 }
157
158 void FM7_MAINIO::set_drq_mfd(bool flag)
159 {
160         if(!connect_fdc) return;
161         if(flag) {
162                 irqreg_fdc |= 0x80;//0b10000000;
163         } else {
164           irqreg_fdc &= 0x7f; //0b01111111;
165         }
166         return;
167 }
168
169 uint8 FM7_MAINIO::fdc_getdrqirq(void)
170 {
171         uint8 val = irqreg_fdc | 0x3f;
172         if((fdc->read_io8(0) & 0x01) == 0) val |= 0x40; // Workaround of 太陽の神殿
173         irqreg_fdc |= 0x20; //0b00100000;
174         return val;
175 }
176
177 void FM7_MAINIO::set_fdc_motor(bool flag)
178 {
179         fdc->write_signal(SIG_MB8877_MOTOR, flag ? 0x01 : 0x00, 0x01);
180 }