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"
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
34 void FM7_MAINIO::reset_fdc(void)
38 fdc_statreg = fdc->read_io8(0);
39 fdc_trackreg = fdc->read_io8(1);
40 fdc_sectreg = fdc->read_io8(2);
41 fdc_datareg = fdc->read_io8(3);
42 fdc_headreg = 0xfe | fdc->read_signal(SIG_MB8877_SIDEREG);
43 fdc_drvsel = 0x7c | fdc->read_signal(SIG_MB8877_DRIVEREG);
44 irqreg_fdc = 0x00; //0b00000000;
46 //fdc_motor = (fdc->read_signal(SIG_MB8877_MOTOR) != 0);
49 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
50 defined(_FM77AV20) || defined(_FM77AV20EX)
53 for(int i = 0; i < 4; i++) {
54 fdc_drive_table[i] = (uint8_t)i;
55 fdc->set_drive_type(i, DRIVE_TYPE_2D);
60 for(int i = 0; i < 4; i++) {
61 fdc->set_drive_type(i, DRIVE_TYPE_2D);
65 if(event_fdc_motor >= 0) cancel_event(this, event_fdc_motor);
70 set_fdc_motor(fdc_motor);
77 void FM7_MAINIO::set_fdc_cmd(uint8_t val)
79 if(!connect_fdc) return;
83 if(((fdc_cmdreg >= 0x80) && (fdc_cmdreg < 0xd0)) || (fdc_cmdreg >= 0xe0)) {
84 uint32_t words = dmac->read_signal(HD6844_WORDS_REG_0);
85 if((words != 0) && (words < 0xffff) && (dmac->read_signal(HD6844_IS_TRANSFER_0) == 0)) {
86 dmac->write_signal(HD6844_SRC_FIXED_ADDR_CH0, 3, 0xffffffff);
87 dmac->write_signal(HD6844_TRANSFER_START, 0, 0xffffffff);
88 //this->out_debug_log(_T("FDC: Start DMA CMDREG=%02x CHRN=%02x %02x %02x * DRVSEL=%08x\n"),
89 // fdc_cmdreg, fdc_trackreg, fdc_headreg & 0x01, fdc_sectreg, fdc_drvsel);
93 fdc->write_io8(0, val & 0x00ff);
94 //#ifdef _FM7_FDC_DEBUG
95 if(config.special_debug_fdc) out_debug_log(_T("FDC: CMD: $%02x"), fdc_cmdreg);
99 uint8_t FM7_MAINIO::get_fdc_stat(void)
101 //uint32_t stat_backup = fdc_statreg;
102 if(!connect_fdc) return 0xff;
103 fdc_statreg = fdc->read_io8(0);
104 #ifdef _FM7_FDC_DEBUG
105 if(stat_backup != fdc_statreg) this->out_debug_log(_T("FDC: \nGet Stat(not busy): $%02x"), fdc_statreg);
110 void FM7_MAINIO::set_fdc_track(uint8_t val)
112 if(!connect_fdc) return;
113 // if mode is 2DD and type-of-image = 2D then val >>= 1;
116 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
117 defined(_FM77AV20) || defined(_FM77AV20EX)
119 if((fdc_drvsel & 0x40) == 0) {
120 d = fdc_drive_table[fdc_drvsel & 0x03] & 0x03;
122 d = fdc_drvsel & 0x03;
125 DISK *disk = fdc->get_disk_handler(d);
126 if(disk->media_type != MEDIA_TYPE_2D){
127 if(config.special_debug_fdc) out_debug_log(_T("NOTE: MEDIA TYPE IS 2DD"));
128 //if(disk->drive_type == DRIVE_TYPE_2D) val <<= 1;
130 if(config.special_debug_fdc) out_debug_log(_T("NOTE: MEDIA TYPE IS 2D"));
131 //if(disk->drive_type != DRIVE_TYPE_2D) val >>= 1;
135 fdc->write_io8(1, val);
136 //#ifdef _FM7_FDC_DEBUG
137 if(config.special_debug_fdc) out_debug_log(_T("FDC : Set Track: %d"), val);
141 uint8_t FM7_MAINIO::get_fdc_track(void)
143 if(!connect_fdc) return 0xff;
144 fdc_trackreg = fdc->read_io8(1);
148 void FM7_MAINIO::set_fdc_sector(uint8_t val)
150 if(!connect_fdc) return;
152 fdc->write_io8(2, val);
153 //#ifdef _FM7_FDC_DEBUG
154 if(config.special_debug_fdc) out_debug_log(_T("FDC: Set Sector: $%02x"), val);
158 uint8_t FM7_MAINIO::get_fdc_sector(void)
160 if(!connect_fdc) return 0xff;
161 fdc_sectreg = fdc->read_io8(2);
165 void FM7_MAINIO::set_fdc_data(uint8_t val)
167 if(!connect_fdc) return;
169 fdc->write_io8(3, val & 0x00ff);
172 uint8_t FM7_MAINIO::get_fdc_data(void)
174 if(!connect_fdc) return 0xff;
175 fdc_datareg = fdc->read_io8(3);
180 uint8_t FM7_MAINIO::get_fdc_motor(void)
182 uint8_t val = 0x3c; //0b01111100;
186 if(!connect_fdc) return 0xff;
187 fdc_motor = (fdc->read_signal(SIG_MB8877_MOTOR) != 0) ? true : false;
188 //fdc_drvsel = fdc->read_signal(SIG_MB8877_READ_DRIVE_REG);
189 drv = fdc_drvsel & 0x03;
190 val = val | (fdc_drvsel & 0x03);
191 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
192 defined(_FM77AV20) || defined(_FM77AV20EX)
193 val = val | (fdc_drvsel & 0x40);
194 if((fdc_drvsel & 0x40) != 0) {
195 drv = fdc_drive_table[drv & 0x03];
198 fdc_motor = fdc_motor & (fdc->get_drive_type(drv) != DRIVE_TYPE_UNK);
199 if(fdc_motor) val |= 0x80;
200 //#ifdef _FM7_FDC_DEBUG
201 if(config.special_debug_fdc) out_debug_log(_T("FDC: Get motor/Drive: $%02x"), val);
206 void FM7_MAINIO::set_fdc_fd1c(uint8_t val)
208 if(!connect_fdc) return;
209 fdc_headreg = (val & 0x01) | 0xfe;
210 fdc->write_signal(SIG_MB8877_SIDEREG, val, 0x01);
211 //#ifdef _FM7_FDC_DEBUG
212 if(config.special_debug_fdc) out_debug_log(_T("FDC: Set side/head: $%02x"), val);
216 uint8_t FM7_MAINIO::get_fdc_fd1c(void)
218 if(!connect_fdc) return 0xff;
219 //fdc_headreg = fdc->read_signal(SIG_MB8877_SIDEREG);
223 void FM7_MAINIO::set_fdc_fd1d(uint8_t val)
225 bool backup_motor = fdc_motor;
227 if(!connect_fdc) return;
228 if((val & 0x80) != 0) {
234 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
235 defined(_FM77AV20) || defined(_FM77AV20EX)
236 if((val & 0x40) == 0) {
237 fdc->write_signal(SIG_MB8877_DRIVEREG, fdc_drive_table[val & 0x03], 0x03);
239 fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03);
243 fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03);
247 if(f != backup_motor) {
248 if(event_fdc_motor >= 0) cancel_event(this, event_fdc_motor);
250 register_event(this, EVENT_FD_MOTOR_ON, 1000.0 * 300.0, false, &event_fdc_motor); // Motor ON After 0.3Sec.
252 register_event(this, EVENT_FD_MOTOR_OFF, 1000.0 * 50.0, false, &event_fdc_motor); // Motor OFF After 0.05Sec.
255 //#ifdef _FM7_FDC_DEBUG
256 if(config.special_debug_fdc) out_debug_log(_T("FDC: Set Drive Select: $%02x"), val);
260 uint8_t FM7_MAINIO::get_fdc_fd1e(void)
262 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
263 defined(_FM77AV20) || defined(_FM77AV20EX)
265 val |= (fdc_reg_fd1e & 0x5f);
266 if(config.special_debug_fdc) out_debug_log(_T("FDC: GET $FD1E value=$%02x"), val);
269 //if(config.special_debug_fdc) out_debug_log(_T("FDC: GET $FD1E value=$%02x"), val);
274 void FM7_MAINIO::set_fdc_fd1e(uint8_t val)
276 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
277 defined(_FM77AV20) || defined(_FM77AV20EX)
279 if(!connect_fdc) return;
283 if((val & 0x10) != 0) {
284 fdc_drive_table[(val & 0x0c) >> 2] = val & 0x03;
285 if(((val & 0x0c) >> 2) == (fdc_drvsel & 0x03)) {
286 fdc->write_signal(SIG_MB8877_DRIVEREG, fdc_drive_table[(val & 0x0c) >> 2], 0x03);
289 if((val & 0x40) != 0) {
290 for(drive = 0; drive < MAX_DRIVE; drive++) fdc->set_drive_type(drive, DRIVE_TYPE_2D);
291 if(config.special_debug_fdc) out_debug_log(_T("SET DRIVE to 2D"));
293 for(drive = 0; drive < MAX_DRIVE; drive++) fdc->set_drive_type(drive, DRIVE_TYPE_2DD);
294 if(config.special_debug_fdc) out_debug_log(_T("SET DRIVE to 2DD"));
296 if(config.special_debug_fdc) out_debug_log(_T("FDC: SET $FD1E value=$%02x"), val);
300 void FM7_MAINIO::set_irq_mfd(bool flag)
302 bool backup = irqstat_fdc;
303 if(!connect_fdc) return;
305 irqreg_fdc |= 0x40; //0b01000000;
307 irqreg_fdc &= 0xbf; //0b10111111;
309 #if defined(_FM77_VARIANTS)
310 flag = flag & !(intmode_fdc);
312 //#if !defined(_FM8) // With FM8, $FD1F is alive and not do_irq(), Thanks to Anna_Wu.
313 irqstat_fdc = flag & !irqmask_mfd;
314 if(backup != irqstat_fdc) do_irq();
319 void FM7_MAINIO::set_drq_mfd(bool flag)
321 if(!connect_fdc) return;
323 irqreg_fdc |= 0x80;//0b10000000;
325 irqreg_fdc &= 0x7f; //0b01111111;
328 if((dmac->read_signal(HD6844_IS_TRANSFER_0) != 0) && (flag)) {
329 dmac->write_signal(HD6844_DO_TRANSFER, 0x0, 0xffffffff);
335 uint8_t FM7_MAINIO::fdc_getdrqirq(void)
337 uint8_t val = irqreg_fdc | 0x3f;
338 if(!connect_fdc) return 0xff;
342 void FM7_MAINIO::set_fdc_motor(bool flag)
344 if(!connect_fdc) return;
346 fdc->write_signal(SIG_MB8877_MOTOR, flag ? 0x01 : 0x00, 0x01);
347 val = fdc_drvsel & 0x03;
348 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
349 defined(_FM77AV20) || defined(_FM77AV20EX)
350 if((fdc_drvsel & 0x40) == 0) {
351 val = fdc_drive_table[val & 0x03];
354 fdc_motor = (fdc->read_signal(SIG_MB8877_MOTOR) != 0);
355 fdc_motor = fdc_motor & (fdc->get_drive_type(val) != DRIVE_TYPE_UNK);
356 if(config.special_debug_fdc) out_debug_log(_T("FDC: MOTOR=%d VAL=$%02x"), flag, val);