OSDN Git Service

[VM] TRY:Use namespace {VMNAME} to separate around VMs. This feature still apply...
[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(fdc_2HD_motor);
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         fdc_2HD_motor = (fdc_2HD->read_signal(SIG_MB8877_MOTOR) != 0) ? true : false;
175         fdc_2HD_motor = fdc_2HD_motor & (fdc_2HD->get_drive_type(fdc_2HD_drvsel & 3) != DRIVE_TYPE_UNK);
176         if(fdc_2HD_motor) val |= 0x80;
177         val = val | (fdc_2HD_drvsel & 0x03);
178         // OK?
179 #ifdef _FM7_FDC_DEBUG   
180         this->out_debug_log(_T("FDC(2HD): Get motor/Drive: $%02x"), val);
181 #endif  
182         return val;
183 #else
184         return 0xff;
185 #endif
186 }
187   
188 void FM7_MAINIO::set_fdc_fd1c_2HD(uint8_t val)
189 {
190 #if defined(HAS_2HD)
191         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
192         fdc_2HD_headreg = (val & 0x01) | 0xfe;
193         fdc_2HD->write_signal(SIG_MB8877_SIDEREG, val, 0x01);
194 #ifdef _FM7_FDC_DEBUG   
195         this->out_debug_log(_T("FDC(2HD): Set side/head: $%02x"), val);
196 #endif
197 #endif
198 }
199
200 uint8_t FM7_MAINIO::get_fdc_fd1c_2HD(void)
201 {
202 #if defined(HAS_2HD)
203         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
204         //fdc_2HD_headreg = fdc_2HD->read_signal(SIG_MB8877_SIDEREG);
205         return fdc_2HD_headreg;
206 #else
207         return 0xff;
208 #endif
209 }
210
211 void FM7_MAINIO::set_fdc_fd1d_2HD(uint8_t val)
212 {
213 #if defined(HAS_2HD)
214         bool backup_motor = fdc_2HD_motor;
215         bool f;
216         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
217         if((val & 0x80) != 0) {
218                 f = true;
219         } else {
220                 f = false;
221         }
222
223         fdc_2HD->write_signal(SIG_MB8877_DRIVEREG, val, 0x03);
224         fdc_2HD_drvsel = val;
225
226         if(f != backup_motor) {
227                 if(event_fdc_motor_2HD >= 0) cancel_event(this, event_fdc_motor_2HD);
228                 // OK?
229                 if(f) {
230                         register_event(this, EVENT_FD_MOTOR_ON_2HD, 1000.0 * 300.0, false, &event_fdc_motor_2HD); // Motor ON After 0.3Sec.
231                 } else {
232                         register_event(this, EVENT_FD_MOTOR_OFF_2HD, 1000.0 * 50.0, false, &event_fdc_motor_2HD); // Motor OFF After 0.05Sec.
233                 }
234         }
235 #ifdef _FM7_FDC_DEBUG   
236         this->out_debug_log(_T("FDC(2HD): Set Drive Select: $%02x"), val);
237 #endif
238 #endif
239 }
240
241 uint8_t FM7_MAINIO::get_fdc_fd1e_2HD(void)
242 {
243         return 0xff;
244 }       
245
246 void FM7_MAINIO::set_fdc_fd1e_2HD(uint8_t val)
247 {
248 }
249
250 void FM7_MAINIO::set_irq_mfd_2HD(bool flag)
251 {
252 #if defined(HAS_2HD)
253         bool backup = irqstat_fdc_2hd;
254         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
255         if(flag) {
256                 irqreg_fdc_2HD |= 0x40; //0b01000000;
257         } else {
258                 irqreg_fdc_2HD &= 0xbf; //0b10111111;
259         }
260         if(intmode_fdc) { // Temporally implement.
261                 if(flag) {
262 #if 0                   
263                         double t;
264                         if(event_2hd_nmi >= 0) cancel_event(this, event_2hd_nmi);
265                         t = (double)nmi_delay;
266                         register_event(this, EVENT_FD_NMI_2HD, t, false, &event_2hd_nmi);
267                         irqstat_fdc_2hd = flag;
268 #else
269                         do_nmi(true);
270 #endif
271                 } else {
272                         //event_2hd_nmi = -1;
273                 }
274         } else {
275                 irqstat_fdc_2hd = flag & !irqmask_mfd;
276                 if(backup != irqstat_fdc_2hd) do_irq();
277         }
278 #endif
279         return;
280         
281 }
282
283 void FM7_MAINIO::set_drq_mfd_2HD(bool flag)
284 {
285 #if defined(HAS_2HD)
286         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
287         if(flag) {
288                 irqreg_fdc_2HD |= 0x80;//0b10000000;
289         } else {
290                 irqreg_fdc_2HD &= 0x7f; //0b01111111;
291         }
292         if(intmode_fdc) {
293                 //if(drqstat_fdc_2hd != flag) {
294                         drqstat_fdc_2hd = flag;
295                         do_firq();
296                         //}
297         }
298 # if defined(HAS_DMA)
299         if((dmac->read_signal(HD6844_IS_TRANSFER_0) != 0) && (flag)) {
300                 dmac->write_signal(HD6844_DO_TRANSFER, 0x0, 0xffffffff);
301         }
302 # endif
303 #endif
304         return;
305 }
306
307 uint8_t FM7_MAINIO::fdc_getdrqirq_2HD(void)
308 {
309 #if defined(HAS_2HD)
310         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return 0xff;
311         uint8_t val = irqreg_fdc_2HD | 0x3f;
312         return val;
313 #else
314         return 0xff;
315 #endif
316 }
317
318 void FM7_MAINIO::set_fdc_motor_2HD(bool flag)
319 {
320 #if defined(HAS_2HD)
321         if(!(connect_fdc_2HD) || (fdc_2HD == NULL)) return;
322         fdc_2HD->write_signal(SIG_MB8877_MOTOR, flag ? 0x01 : 0x00, 0x01);
323         fdc_2HD_motor = (fdc_2HD->read_signal(SIG_MB8877_MOTOR) != 0);
324         fdc_2HD_motor = fdc_2HD_motor & (fdc_2HD->get_drive_type(fdc_2HD_drvsel & 3) != DRIVE_TYPE_UNK);
325 #endif
326 }
327
328 }