OSDN Git Service

[VM][FM7] Apply changes of MB8877:: to FM7 series.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / floppy_2HD.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 #if defined(HAS_DMA)
19 #include "hd6844.h"
20 #endif
21
22 namespace FM7 {
23
24 #define FDC_CMD_TYPE1           1
25 #define FDC_CMD_RD_SEC          2
26 #define FDC_CMD_RD_MSEC         3
27 #define FDC_CMD_WR_SEC          4
28 #define FDC_CMD_WR_MSEC         5
29 #define FDC_CMD_RD_ADDR         6
30 #define FDC_CMD_RD_TRK          7
31 #define FDC_CMD_WR_TRK          8
32 #define FDC_CMD_TYPE4           0x80
33
34
35
36 void FM7_MAINIO::reset_fdc_2HD(void)
37 {
38 #if defined(HAS_2HD)
39         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
40         fdc_2HD_cmdreg = 0;
41         fdc_2HD_statreg = fdc_2HD->read_io8(0);
42         fdc_2HD_trackreg = fdc_2HD->read_io8(1);
43         fdc_2HD_sectreg = fdc_2HD->read_io8(2);
44         fdc_2HD_datareg = fdc_2HD->read_io8(3);
45         fdc_2HD_headreg = 0xfe | fdc_2HD->read_signal(SIG_MB8877_SIDEREG);
46         fdc_2HD_drvsel = 0x7c | (fdc_2HD->read_signal(SIG_MB8877_DRIVEREG) & 0x03);
47         irqreg_fdc_2HD = 0x00; //0b00000000;
48         //fdc_2HD_motor = (fdc_2HD->read_signal(SIG_MB8877_MOTOR) != 0);
49         //fdc_2HD_motor = false;
50                 
51         if(event_fdc_motor_2HD >= 0) cancel_event(this, event_fdc_motor_2HD);
52         event_fdc_motor_2HD = -1;
53         //irqstat_2HD_fdc = false;
54         //irqmask_2HD_mfd = true;
55         if(connect_fdc_2HD) {
56                 set_fdc_motor_2HD(false);
57         }
58 #endif
59 }
60
61 void FM7_MAINIO::set_fdc_cmd_2HD(uint8_t val)
62 {
63 #if defined(HAS_2HD)
64         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
65         //irqreg_fdc = 0x00;
66         fdc_2HD_cmdreg = val;
67 #if 0
68 #if defined(HAS_DMA)
69         if(((fdc_2HD_cmdreg >= 0x80) && (fdc_2HD_cmdreg < 0xd0)) || (fdc_2HD_cmdreg >= 0xe0)) {
70                 uint32_t words = dmac->read_signal(HD6844_WORDS_REG_0);
71                 if((words != 0) && (words < 0xffff) && (dmac->read_signal(HD6844_IS_TRANSFER_0) == 0)) {
72                         dmac->write_signal(HD6844_SRC_FIXED_ADDR_CH0, 3, 0xffffffff);
73                         dmac->write_signal(HD6844_TRANSFER_START, 0, 0xffffffff);
74                         //this->out_debug_log(_T("FDC: Start DMA CMDREG=%02x CHRN=%02x %02x %02x * DRVSEL=%08x\n"),
75                         //                                       fdc_cmdreg, fdc_trackreg, fdc_headreg & 0x01, fdc_sectreg, fdc_drvsel);
76                 }
77         }
78 #endif
79 #endif
80         fdc_2HD->write_io8(0, val & 0x00ff);
81 #ifdef _FM7_FDC_DEBUG   
82         this->out_debug_log(_T("FDC(2HD): CMD: $%02x"), fdc_2HD_cmdreg);
83 #endif  
84 #endif
85 }
86
87 uint8_t FM7_MAINIO::get_fdc_stat_2HD(void)
88 {
89 #if defined(HAS_2HD)
90         uint32_t stat_backup = fdc_2HD_statreg;
91         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
92         fdc_2HD_statreg =  fdc_2HD->read_io8(0);
93 #ifdef _FM7_FDC_DEBUG   
94         if(stat_backup != fdc_2HD_statreg) this->out_debug_log(_T("FDC(2HD): \nGet Stat(not busy): $%02x"), fdc_2HD_statreg);
95 #endif  
96         return fdc_2HD_statreg;
97 #else
98         return 0xff;
99 #endif
100 }
101
102 void FM7_MAINIO::set_fdc_track_2HD(uint8_t val)
103 {
104 #if defined(HAS_2HD)
105         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
106         fdc_2HD_trackreg = val;
107         fdc_2HD->write_io8(1, val);
108 #ifdef _FM7_FDC_DEBUG   
109         this->out_debug_log(_T("FDC(2HD) : Set Track: %d"), val);
110 #endif
111 #endif
112 }
113
114 uint8_t FM7_MAINIO::get_fdc_track_2HD(void)
115 {
116 #if defined(HAS_2HD)
117         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
118         fdc_2HD_trackreg = fdc_2HD->read_io8(1);
119         return fdc_2HD_trackreg;
120 #else
121         return 0xff;
122 #endif
123 }
124
125 void FM7_MAINIO::set_fdc_sector_2HD(uint8_t val)
126 {
127 #if defined(HAS_2HD)
128         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
129         fdc_2HD_sectreg = val;
130         fdc_2HD->write_io8(2, val);
131 #ifdef _FM7_FDC_DEBUG   
132         this->out_debug_log(_T("FDC(2HD): Set Sector: $%02x"), val);
133 #endif
134 #endif
135 }
136
137 uint8_t FM7_MAINIO::get_fdc_sector_2HD(void)
138 {
139 #if defined(HAS_2HD)
140         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
141         fdc_2HD_sectreg = fdc_2HD->read_io8(2);
142         return fdc_2HD_sectreg;
143 #else
144         return 0xff;
145 #endif
146 }
147   
148 void FM7_MAINIO::set_fdc_data_2HD(uint8_t val)
149 {
150 #if defined(HAS_2HD)
151         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
152         fdc_2HD_datareg = val;
153         fdc_2HD->write_io8(3, val & 0x00ff);
154 #endif
155 }
156
157 uint8_t FM7_MAINIO::get_fdc_data_2HD(void)
158 {
159 #if defined(HAS_2HD)
160         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
161         fdc_2HD_datareg = fdc_2HD->read_io8(3);
162         
163         return fdc_2HD_datareg;
164 #else
165         return 0xff;
166 #endif
167 }
168
169 uint8_t FM7_MAINIO::get_fdc_motor_2HD(void)
170 {
171 #if defined(HAS_2HD)
172         uint8_t val = 0x7c; //0b01111100;
173         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
174         // 20221215 K.O OK?
175         if(fdc_2HD_motor) val |= 0x80;
176         val = val | (fdc_2HD_drvsel & 0x03);
177         // OK?
178 #ifdef _FM7_FDC_DEBUG   
179         this->out_debug_log(_T("FDC(2HD): Get motor/Drive: $%02x"), val);
180 #endif  
181         return val;
182 #else
183         return 0xff;
184 #endif
185 }
186   
187 void FM7_MAINIO::set_fdc_fd1c_2HD(uint8_t val)
188 {
189 #if defined(HAS_2HD)
190         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
191         fdc_2HD_headreg = (val & 0x01) | 0xfe;
192         fdc_2HD->write_signal(SIG_MB8877_SIDEREG, val, 0x01);
193 #ifdef _FM7_FDC_DEBUG   
194         this->out_debug_log(_T("FDC(2HD): Set side/head: $%02x"), val);
195 #endif
196 #endif
197 }
198
199 uint8_t FM7_MAINIO::get_fdc_fd1c_2HD(void)
200 {
201 #if defined(HAS_2HD)
202         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
203         //fdc_2HD_headreg = fdc_2HD->read_signal(SIG_MB8877_SIDEREG);
204         return fdc_2HD_headreg;
205 #else
206         return 0xff;
207 #endif
208 }
209
210 void FM7_MAINIO::set_fdc_fd1d_2HD(uint8_t val)
211 {
212 #if defined(HAS_2HD)
213         bool f;
214         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
215         if((val & 0x80) != 0) {
216                 f = true;
217         } else {
218                 f = false;
219         }
220         drv = val & 0x03;
221         bool mdrv_flag = fdc_2HD->is_drive_ready(drv);
222         fdc_2HD->write_signal(SIG_MB8877_DRIVEREG, drv, 0x03);
223         fdc_2HD_drvsel = val;
224
225         if(f != mdrv_flag) {
226                 if(event_fdc_motor_2HD >= 0) cancel_event(this, event_fdc_motor_2HD);
227                 // OK?
228                 if(f) {
229                         register_event(this, EVENT_FD_MOTOR_ON_2HD, 1000.0 * 300.0, false, &event_fdc_motor_2HD); // Motor ON After 0.3Sec.
230                 } else {
231                         register_event(this, EVENT_FD_MOTOR_OFF_2HD, 1000.0 * 50.0, false, &event_fdc_motor_2HD); // Motor OFF After 0.05Sec.
232                 }
233         }
234 #ifdef _FM7_FDC_DEBUG   
235         this->out_debug_log(_T("FDC(2HD): Set Drive Select: $%02x"), val);
236 #endif
237 #endif
238 }
239
240 uint8_t FM7_MAINIO::get_fdc_fd1e_2HD(void)
241 {
242         return 0xff;
243 }       
244
245 void FM7_MAINIO::set_fdc_fd1e_2HD(uint8_t val)
246 {
247 }
248
249 void FM7_MAINIO::set_irq_mfd_2HD(bool flag)
250 {
251 #if defined(HAS_2HD)
252         bool backup = irqstat_fdc_2hd;
253         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
254         if(flag) {
255                 irqreg_fdc_2HD |= 0x40; //0b01000000;
256         } else {
257                 irqreg_fdc_2HD &= 0xbf; //0b10111111;
258         }
259         if(intmode_fdc) { // Temporally implement.
260                 if(flag) {
261 #if 0                   
262                         double t;
263                         if(event_2hd_nmi >= 0) cancel_event(this, event_2hd_nmi);
264                         t = (double)nmi_delay;
265                         register_event(this, EVENT_FD_NMI_2HD, t, false, &event_2hd_nmi);
266                         irqstat_fdc_2hd = flag;
267 #else
268                         do_nmi(true);
269 #endif
270                 } else {
271                         //event_2hd_nmi = -1;
272                 }
273         } else {
274                 irqstat_fdc_2hd = flag & !irqmask_mfd;
275                 if(backup != irqstat_fdc_2hd) do_irq();
276         }
277 #endif
278         return;
279         
280 }
281
282 void FM7_MAINIO::set_drq_mfd_2HD(bool flag)
283 {
284 #if defined(HAS_2HD)
285         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
286         if(flag) {
287                 irqreg_fdc_2HD |= 0x80;//0b10000000;
288         } else {
289                 irqreg_fdc_2HD &= 0x7f; //0b01111111;
290         }
291         if(intmode_fdc) {
292                 //if(drqstat_fdc_2hd != flag) {
293                         drqstat_fdc_2hd = flag;
294                         do_firq();
295                         //}
296         }
297 # if defined(HAS_DMA)
298         if((dmac->read_signal(HD6844_IS_TRANSFER_0) != 0) && (flag)) {
299                 dmac->write_signal(HD6844_DO_TRANSFER, 0x0, 0xffffffff);
300         }
301 # endif
302 #endif
303         return;
304 }
305
306 uint8_t FM7_MAINIO::fdc_getdrqirq_2HD(void)
307 {
308 #if defined(HAS_2HD)
309         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
310         uint8_t val = irqreg_fdc_2HD | 0x3f;
311         return val;
312 #else
313         return 0xff;
314 #endif
315 }
316
317 void FM7_MAINIO::set_fdc_motor_2HD(bool flag)
318 {
319 #if defined(HAS_2HD)
320         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
321         // OK? 20221215 K.O
322         fdc_2HD->write_signal(SIG_MB8877_MOTOR, flag ? 0xffffffff : 0x00, 0xffffffff);
323 #endif
324 }
325
326 }