2 * FM-7 Main I/O -> FDC [floppy.cpp]
4 * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
7 * Mar 19, 2015 : Initial, split from fm7_mainio.cpp .
11 #include "fm7_mainio.h"
13 #include "../mc6809.h"
16 #include "../mb8877.h"
22 #define FDC_CMD_TYPE1 1
23 #define FDC_CMD_RD_SEC 2
24 #define FDC_CMD_RD_MSEC 3
25 #define FDC_CMD_WR_SEC 4
26 #define FDC_CMD_WR_MSEC 5
27 #define FDC_CMD_RD_ADDR 6
28 #define FDC_CMD_RD_TRK 7
29 #define FDC_CMD_WR_TRK 8
30 #define FDC_CMD_TYPE4 0x80
32 void FM7_MAINIO::reset_fdc(void)
36 fdc_statreg = fdc->read_io8(0);
37 fdc_trackreg = fdc->read_io8(1);
38 fdc_sectreg = fdc->read_io8(2);
39 fdc_datareg = fdc->read_io8(3);
40 fdc_headreg = 0xfe | fdc->read_signal(SIG_MB8877_SIDEREG);
41 fdc_drvsel = 0x7c | fdc->read_signal(SIG_MB8877_DRIVEREG);
42 irqreg_fdc = 0x00; //0b00000000;
44 //fdc_motor = (fdc->read_signal(SIG_MB8877_MOTOR) != 0);
46 fdc_cmd_type1 = false;
48 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
49 defined(_FM77AV20) || defined(_FM77AV20EX)
52 for(int i = 0; i < 4; i++) {
53 fdc_drive_table[i] = (uint8_t)i;
54 fdc->set_drive_type(i, DRIVE_TYPE_2D);
59 for(int i = 0; i < 4; i++) {
60 fdc->set_drive_type(i, DRIVE_TYPE_2D);
64 if(event_fdc_motor >= 0) cancel_event(this, event_fdc_motor);
69 set_fdc_motor(fdc_motor);
75 void FM7_MAINIO::set_fdc_cmd(uint8_t val)
77 if(!connect_fdc) return;
80 fdc_cmd_type1 = ((val & 0x80) == 0);
82 if(((fdc_cmdreg >= 0x80) && (fdc_cmdreg < 0xd0)) || (fdc_cmdreg >= 0xe0)) {
83 uint32_t words = dmac->read_signal(HD6844_WORDS_REG_0);
84 if((words != 0) && (words < 0xffff) && (dmac->read_signal(HD6844_IS_TRANSFER_0) == 0)) {
85 dmac->write_signal(HD6844_SRC_FIXED_ADDR_CH0, 3, 0xffffffff);
86 dmac->write_signal(HD6844_TRANSFER_START, 0, 0xffffffff);
87 //this->out_debug_log(_T("FDC: Start DMA CMDREG=%02x CHRN=%02x %02x %02x * DRVSEL=%08x\n"),
88 // fdc_cmdreg, fdc_trackreg, fdc_headreg & 0x01, fdc_sectreg, fdc_drvsel);
92 fdc->write_io8(0, val & 0x00ff);
94 this->out_debug_log(_T("FDC: CMD: $%02x"), fdc_cmdreg);
98 uint8_t FM7_MAINIO::get_fdc_stat(void)
100 uint32_t stat_backup = fdc_statreg;
101 if(!connect_fdc) return 0xff;
102 fdc_statreg = fdc->read_io8(0);
103 #ifdef _FM7_FDC_DEBUG
104 if(stat_backup != fdc_statreg) this->out_debug_log(_T("FDC: \nGet Stat(not busy): $%02x"), fdc_statreg);
109 void FM7_MAINIO::set_fdc_track(uint8_t val)
111 if(!connect_fdc) return;
112 // if mode is 2DD and type-of-image = 2D then val >>= 1;
115 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
116 defined(_FM77AV20) || defined(_FM77AV20EX)
118 if((fdc_drvsel & 0x40) == 0) {
119 d = fdc_drive_table[fdc_drvsel & 0x03] & 0x03;
121 d = fdc_drvsel & 0x03;
123 DISK *disk = fdc->get_disk_handler(d);
124 if(disk->media_type != MEDIA_TYPE_2D){
125 if(disk->drive_type == DRIVE_TYPE_2D) val <<= 1;
127 //if(disk->drive_type != DRIVE_TYPE_2D) val >>= 1;
130 fdc->write_io8(1, val);
131 #ifdef _FM7_FDC_DEBUG
132 this->out_debug_log(_T("FDC : Set Track: %d"), val);
136 uint8_t FM7_MAINIO::get_fdc_track(void)
138 if(!connect_fdc) return 0xff;
139 fdc_trackreg = fdc->read_io8(1);
143 void FM7_MAINIO::set_fdc_sector(uint8_t val)
145 if(!connect_fdc) return;
147 fdc->write_io8(2, val);
148 #ifdef _FM7_FDC_DEBUG
149 this->out_debug_log(_T("FDC: Set Sector: $%02x"), val);
153 uint8_t FM7_MAINIO::get_fdc_sector(void)
155 if(!connect_fdc) return 0xff;
156 fdc_sectreg = fdc->read_io8(2);
160 void FM7_MAINIO::set_fdc_data(uint8_t val)
162 if(!connect_fdc) return;
164 fdc->write_io8(3, val & 0x00ff);
167 uint8_t FM7_MAINIO::get_fdc_data(void)
169 if(!connect_fdc) return 0xff;
170 fdc_datareg = fdc->read_io8(3);
175 uint8_t FM7_MAINIO::get_fdc_motor(void)
177 uint8_t val = 0x3c; //0b01111100;
178 if(!connect_fdc) return 0xff;
179 fdc_motor = (fdc->read_signal(SIG_MB8877_MOTOR) != 0) ? true : false;
180 if(fdc_motor) val |= 0x80;
181 //fdc_drvsel = fdc->read_signal(SIG_MB8877_READ_DRIVE_REG);
182 val = val | (fdc_drvsel & 0x03);
183 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
184 defined(_FM77AV20) || defined(_FM77AV20EX)
185 val = val | (fdc_drvsel & 0x40);
187 #ifdef _FM7_FDC_DEBUG
188 this->out_debug_log(_T("FDC: Get motor/Drive: $%02x"), val);
193 void FM7_MAINIO::set_fdc_fd1c(uint8_t val)
195 if(!connect_fdc) return;
196 fdc_headreg = (val & 0x01) | 0xfe;
197 fdc->write_signal(SIG_MB8877_SIDEREG, val, 0x01);
198 #ifdef _FM7_FDC_DEBUG
199 this->out_debug_log(_T("FDC: Set side/head: $%02x"), val);
203 uint8_t FM7_MAINIO::get_fdc_fd1c(void)
205 if(!connect_fdc) return 0xff;
206 //fdc_headreg = fdc->read_signal(SIG_MB8877_SIDEREG);
210 void FM7_MAINIO::set_fdc_fd1d(uint8_t val)
212 bool backup_motor = fdc_motor;
214 if(!connect_fdc) return;
215 if((val & 0x80) != 0) {
221 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
222 defined(_FM77AV20) || defined(_FM77AV20EX)
223 if((val & 0x40) == 0) {
224 fdc->write_signal(SIG_MB8877_DRIVEREG, fdc_drive_table[val & 0x03], 0x03);
226 fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03);
230 fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03);
234 if(f != backup_motor) {
235 if(event_fdc_motor >= 0) cancel_event(this, event_fdc_motor);
237 register_event(this, EVENT_FD_MOTOR_ON, 1000.0 * 300.0, false, &event_fdc_motor); // Motor ON After 0.3Sec.
239 register_event(this, EVENT_FD_MOTOR_OFF, 1000.0 * 50.0, false, &event_fdc_motor); // Motor OFF After 0.05Sec.
242 #ifdef _FM7_FDC_DEBUG
243 this->out_debug_log(_T("FDC: Set Drive Select: $%02x"), val);
247 uint8_t FM7_MAINIO::get_fdc_fd1e(void)
249 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
250 defined(_FM77AV20) || defined(_FM77AV20EX)
252 val |= (fdc_reg_fd1e & 0x5f);
259 void FM7_MAINIO::set_fdc_fd1e(uint8_t val)
261 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
262 defined(_FM77AV20) || defined(_FM77AV20EX)
264 if(!connect_fdc) return;
268 if((val & 0x10) != 0) {
269 fdc_drive_table[(val & 0x0c) >> 2] = val & 0x03;
270 if(((val & 0x0c) >> 2) == (fdc_drvsel & 0x03)) {
271 fdc->write_signal(SIG_MB8877_DRIVEREG, fdc_drive_table[(val & 0x0c) >> 2], 0x03);
274 if((val & 0x40) != 0) {
275 for(drive = 0; drive < MAX_DRIVE; drive++) fdc->set_drive_type(drive, DRIVE_TYPE_2D);
276 //this->out_debug_log(_T("2D\n"));
278 for(drive = 0; drive < MAX_DRIVE; drive++) fdc->set_drive_type(drive, DRIVE_TYPE_2DD);
279 //this->out_debug_log(_T("2DD\n"));
283 void FM7_MAINIO::set_irq_mfd(bool flag)
285 bool backup = irqstat_fdc;
286 if(!connect_fdc) return;
288 irqreg_fdc |= 0x40; //0b01000000;
290 irqreg_fdc &= 0xbf; //0b10111111;
292 #if !defined(_FM8) // With FM8, $FD1F is alive and not do_irq(), Thanks to Anna_Wu.
293 irqstat_fdc = flag & !irqmask_mfd;
294 if(backup != irqstat_fdc) do_irq();
299 void FM7_MAINIO::set_drq_mfd(bool flag)
301 if(!connect_fdc) return;
303 irqreg_fdc |= 0x80;//0b10000000;
305 irqreg_fdc &= 0x7f; //0b01111111;
308 if((dmac->read_signal(HD6844_IS_TRANSFER_0) != 0) && (flag)) {
309 dmac->write_signal(HD6844_DO_TRANSFER, 0x0, 0xffffffff);
315 uint8_t FM7_MAINIO::fdc_getdrqirq(void)
317 uint8_t val = irqreg_fdc | 0x3f;
318 if(!connect_fdc) return 0xff;
322 void FM7_MAINIO::set_fdc_motor(bool flag)
324 if(!connect_fdc) return;
325 fdc->write_signal(SIG_MB8877_MOTOR, flag ? 0x01 : 0x00, 0x01);
326 fdc_motor = (fdc->read_signal(SIG_MB8877_MOTOR) != 0);