OSDN Git Service

4242a3ad607f54127cd024d50f1f943b7192d33a
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr50 / floppy.cpp
1 /*
2         FUJITSU FMR-50 Emulator 'eFMR-50'
3         FUJITSU FMR-60 Emulator 'eFMR-60'
4
5         Author : Takeda.Toshiya
6         Date   : 2008.04.30 -
7
8         [ floppy ]
9 */
10
11 #include "floppy.h"
12 #include "../disk.h"
13 #include "../i8259.h"
14 #include "../mb8877.h"
15
16 namespace FMR50 {
17
18 void FLOPPY::initialize()
19 {
20         drvreg = drvsel = 0;
21         irq = irqmsk = false;
22         changed[0] = changed[1] = changed[2] = changed[3] = false;
23 }
24
25 void FLOPPY::reset()
26 {
27         for(int i = 0; i < MAX_DRIVE; i++) {
28                 d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
29         }
30 }
31
32 void FLOPPY::write_io8(uint32_t addr, uint32_t data)
33 {
34         int nextdrv = drvsel;
35         
36         switch(addr & 0xffff) {
37         case 0x208:
38                 // drive control register
39                 irqmsk = ((data & 1) != 0);
40                 update_intr();
41                 // note: bit5 is CLKSEL, but 0 is set while seeking
42 /*
43                 for(int i = 0; i < MAX_DRIVE; i++) {
44                         if(data & 0x20) {
45                                 d_fdc->set_drive_type(i, DRIVE_TYPE_2DD);
46                         } else {
47                                 d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
48                         }
49                 }
50 */
51                 d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10);
52                 d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 4);
53                 break;
54         case 0x20c:
55                 // drive select register
56                 if(data & 0x0f) {
57                         if(data & 1) {
58                                 nextdrv = 0;
59                         } else if(data & 2) {
60                                 nextdrv = 1;
61                         } else if(data & 4) {
62                                 nextdrv = 2;
63                         } else if(data & 8) {
64                                 nextdrv = 3;
65                         }
66                         if(drvsel != nextdrv) {
67                                 d_fdc->write_signal(SIG_MB8877_DRIVEREG, drvsel = nextdrv, 3);
68                         }
69                         for(int i = 0; i < MAX_DRIVE; i++) {
70                                 if((data & 0xc0) == 0x00) {
71                                         d_fdc->set_drive_type(i, DRIVE_TYPE_2DD); // 300rpm
72                                 } else if((data & 0xc0) == 0x40) {
73                                         d_fdc->set_drive_type(i, DRIVE_TYPE_2HD); // 360rpm
74                                 }
75                         }
76                 }
77                 drvreg = data;
78                 break;
79         }
80 }
81
82 uint32_t FLOPPY::read_io8(uint32_t addr)
83 {
84         switch(addr & 0xffff) {
85         case 0x208:
86                 {
87                         int drvreg = d_fdc->read_signal(SIG_MB8877_DRIVEREG);
88                         uint32_t fdc_status = d_fdc->is_disk_inserted(drvreg) ? 2 : 0;
89                         
90                         if(changed[drvsel]) {
91                                 changed[drvsel] = false;
92                                 return fdc_status | 0xe1;       // fdd*2
93                         }
94 //                      return fdc_status | 0x60;       // fdd*1
95                         return fdc_status | 0xe0;       // fdd*2
96                 }
97         case 0x20c:
98                 return drvreg;
99         }
100         return 0xff;
101 }
102
103 void FLOPPY::write_signal(int id, uint32_t data, uint32_t mask)
104 {
105         if(id == SIG_FLOPPY_IRQ) {
106                 irq = ((data & mask) != 0);
107                 update_intr();
108         }
109 }
110
111 void FLOPPY::update_intr()
112 {
113         d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR6, irq && irqmsk ? 1 : 0, 1);
114 }
115
116 #define STATE_VERSION   1
117
118 bool FLOPPY::process_state(FILEIO* state_fio, bool loading)
119 {
120         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
121                 return false;
122         }
123         if(!state_fio->StateCheckInt32(this_device_id)) {
124                 return false;
125         }
126         state_fio->StateInt32(drvreg);
127         state_fio->StateInt32(drvsel);
128         state_fio->StateBool(irq);
129         state_fio->StateBool(irqmsk);
130         //state_fio->StateBuffer(changed, sizeof(changed), 1);
131         for(int i = 0; i < (sizeof(changed) / sizeof(bool)); i++) {
132                 state_fio->StateBool(changed[i]);
133         }
134         return true;
135 }
136
137 }