OSDN Git Service

[General][Qt] Add prepare to build PC9801VM. Maybe still not working.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / floppy.cpp
1 /*
2         NEC PC-9801 Emulator 'ePC-9801'
3         NEC PC-9801E/F/M Emulator 'ePC-9801E'
4         NEC PC-98DO Emulator 'ePC-98DO'
5
6         Author : Takeda.Toshiya
7         Date   : 2010.09.15-
8
9         [ floppy ]
10 */
11
12 #include "floppy.h"
13 #include "../disk.h"
14 #include "../i8237.h"
15 #include "../i8259.h"
16 #include "../upd765a.h"
17 #include "../../fileio.h"
18
19 #define EVENT_TIMER     0
20
21 void FLOPPY::reset()
22 {
23 #if defined(SUPPORT_2HD_FDD_IF)
24         for(int i = 0; i < MAX_DRIVE; i++) {
25                 d_fdc_2hd->set_drive_type(i, DRIVE_TYPE_2HD);
26         }
27         ctrlreg_2hd = 0x80;
28 #endif
29 #if defined(SUPPORT_2DD_FDD_IF)
30         for(int i = 0; i < MAX_DRIVE; i++) {
31                 d_fdc_2dd->set_drive_type(i, DRIVE_TYPE_2DD);
32         }
33         ctrlreg_2dd = 0x80;
34 #endif
35 #if defined(SUPPORT_2HD_2DD_FDD_IF)
36         for(int i = 0; i < 4; i++) {
37                 d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
38         }
39         ctrlreg = 0x80;
40         modereg = 0x03;
41 #endif
42         timer_id = -1;
43 }
44
45 void FLOPPY::write_io8(uint32 addr, uint32 data)
46 {
47         switch(addr & 0xffff) {
48 #if defined(SUPPORT_2HD_FDD_IF)
49         case 0x90:
50                 d_fdc_2hd->write_io8(0, data);
51                 break;
52         case 0x92:
53                 d_fdc_2hd->write_io8(1, data);
54                 break;
55         case 0x94:
56                 if(!(ctrlreg_2hd & 0x80) && (data & 0x80)) {
57                         d_fdc_2hd->reset();
58                 }
59                 d_fdc_2hd->write_signal(SIG_UPD765A_FREADY, data, 0x40);
60                 ctrlreg_2hd = data;
61                 break;
62 #endif
63 #if defined(SUPPORT_2DD_FDD_IF)
64         case 0xc8:
65                 d_fdc_2dd->write_io8(0, data);
66                 break;
67         case 0xca:
68                 d_fdc_2dd->write_io8(1, data);
69                 break;
70         case 0xcc:
71                 if(!(ctrlreg_2dd & 0x80) && (data & 0x80)) {
72                         d_fdc_2dd->reset();
73                 }
74                 if(data & 1) {
75                         if(timer_id != -1) {
76                                 cancel_event(this, timer_id);
77                         }
78                         register_event(this, EVENT_TIMER, 100000, false, &timer_id);
79                 }
80                 d_fdc_2dd->write_signal(SIG_UPD765A_MOTOR, data, 0x08);
81                 ctrlreg_2dd = data;
82                 break;
83 #endif
84 #if defined(SUPPORT_2HD_2DD_FDD_IF)
85         case 0x90:
86         case 0xc8:
87                 if(((addr >> 4) & 1) == (modereg & 1)) {
88                         d_fdc->write_io8(0, data);
89                 }
90                 break;
91         case 0x92:
92         case 0xca:
93                 if(((addr >> 4) & 1) == (modereg & 1)) {
94                         d_fdc->write_io8(1, data);
95                 }
96                 break;
97         case 0x94:
98         case 0xcc:
99                 if(((addr >> 4) & 1) == (modereg & 1)) {
100                         if(!(ctrlreg & 0x80) && (data & 0x80)) {
101                                 d_fdc->reset();
102                         }
103                         if(!(addr == 0xcc && !(data & 0x20))) {
104                                 d_fdc->write_signal(SIG_UPD765A_FREADY, data, 0x40);
105                         }
106                         if(data & 1) {
107                                 if(timer_id != -1) {
108                                         cancel_event(this, timer_id);
109                                 }
110                                 register_event(this, EVENT_TIMER, 100000, false, &timer_id);
111                         }
112 //                      if(modereg & 4) {
113 //                              d_fdc->write_signal(SIG_UPD765A_MOTOR, data, 0x08);
114 //                      }
115                         ctrlreg = data;
116                 }
117                 break;
118         case 0xbe:
119                 if(!(modereg & 2) && (data & 2)) {
120                         d_fdc->set_drive_type(0, DRIVE_TYPE_2HD);
121                         d_fdc->set_drive_type(1, DRIVE_TYPE_2HD);
122                 } else if((modereg & 2) && !(data & 2)) {
123                         d_fdc->set_drive_type(0, DRIVE_TYPE_2DD);
124                         d_fdc->set_drive_type(1, DRIVE_TYPE_2DD);
125                 }
126                 modereg = data;
127                 break;
128 #endif
129         }
130 }
131
132 uint32 FLOPPY::read_io8(uint32 addr)
133 {
134         switch(addr & 0xffff) {
135 #if defined(SUPPORT_2HD_FDD_IF)
136         case 0x90:
137                 return d_fdc_2hd->read_io8(0);
138         case 0x92:
139                 return d_fdc_2hd->read_io8(1);
140 #if !defined(_PC9801)
141         case 0x94:
142                 return 0x5f;    // 0x40 ???
143 #endif
144 #endif
145 #if defined(SUPPORT_2DD_FDD_IF)
146         case 0xc8:
147                 return d_fdc_2dd->read_io8(0);
148         case 0xca:
149                 return d_fdc_2dd->read_io8(1);
150         case 0xcc:
151                 return (d_fdc_2dd->disk_inserted() ? 0x10 : 0) | 0x6f;  // 0x60 ???
152 #endif
153 #if defined(SUPPORT_2HD_2DD_FDD_IF)
154         case 0x90:
155         case 0xc8:
156                 if(((addr >> 4) & 1) == (modereg & 1)) {
157                         return d_fdc->read_io8(0);
158                 }
159                 break;
160         case 0x92:
161         case 0xca:
162                 if(((addr >> 4) & 1) == (modereg & 1)) {
163                         return d_fdc->read_io8(1);
164                 }
165                 break;
166         case 0x94:
167                 if(modereg & 1) {
168                         return 0x44;
169                 }
170                 break;
171         case 0xbe:
172                 return 0xf8 | (modereg & 3);
173         case 0xcc:
174                 if(!(modereg & 1)) {
175                         return (d_fdc->disk_inserted() ? 0x10 : 0) | 0x64;      // 0x60 ???
176                 }
177                 break;
178 #endif
179         }
180         return 0xff;//addr & 0xff;
181 }
182
183 void FLOPPY::write_signal(int id, uint32 data, uint32 mask)
184 {
185         switch(id) {
186 #if defined(SUPPORT_2HD_FDD_IF)
187         case SIG_FLOPPY_2HD_IRQ:
188                 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR3, data, mask);
189                 break;
190         case SIG_FLOPPY_2HD_DRQ:
191                 d_dma->write_signal(SIG_I8237_CH2, data, mask);
192                 break;
193 #endif
194 #if defined(SUPPORT_2DD_FDD_IF)
195         case SIG_FLOPPY_2DD_IRQ:
196                 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR2, data, mask);
197                 break;
198         case SIG_FLOPPY_2DD_DRQ:
199                 d_dma->write_signal(SIG_I8237_CH3, data, mask);
200                 break;
201 #endif
202 #if defined(SUPPORT_2HD_2DD_FDD_IF)
203         case SIG_FLOPPY_IRQ:
204                 if(modereg & 1) {
205                         d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR3, data, mask);
206                 } else {
207                         d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR2, data, mask);
208                 }
209                 break;
210         case SIG_FLOPPY_DRQ:
211                 if(modereg & 1) {
212                         d_dma->write_signal(SIG_I8237_CH2, data, mask);
213                 } else {
214                         d_dma->write_signal(SIG_I8237_CH3, data, mask);
215                 }
216                 break;
217 #endif
218         }
219 }
220
221 void FLOPPY::event_callback(int event_id, int err)
222 {
223 #if defined(SUPPORT_2DD_FDD_IF)
224         if(ctrlreg_2dd & 4) {
225                 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR2, 1, 1);
226         }
227 #endif
228 #if defined(SUPPORT_2HD_2DD_FDD_IF)
229         if(ctrlreg & 4) {
230                 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR2, 1, 1);
231         }
232 #endif
233         timer_id = -1;
234 }
235
236
237 #define STATE_VERSION   1
238
239 void FLOPPY::save_state(FILEIO* state_fio)
240 {
241         state_fio->FputUint32(STATE_VERSION);
242         state_fio->FputInt32(this_device_id);
243         
244 #if defined(SUPPORT_2HD_FDD_IF)
245         state_fio->FputUint8(ctrlreg_2hd);
246 #endif
247 #if defined(SUPPORT_2DD_FDD_IF)
248         state_fio->FputUint8(ctrlreg_2dd);
249 #endif
250 #if defined(SUPPORT_2HD_2DD_FDD_IF)
251         state_fio->FputUint8(ctrlreg);
252         state_fio->FputUint8(modereg);
253 #endif
254         state_fio->FputInt32(timer_id);
255 }
256
257 bool FLOPPY::load_state(FILEIO* state_fio)
258 {
259         if(state_fio->FgetUint32() != STATE_VERSION) {
260                 return false;
261         }
262         if(state_fio->FgetInt32() != this_device_id) {
263                 return false;
264         }
265 #if defined(SUPPORT_2HD_FDD_IF)
266         ctrlreg_2hd = state_fio->FgetUint8();
267 #endif
268 #if defined(SUPPORT_2DD_FDD_IF)
269         ctrlreg_2dd = state_fio->FgetUint8();
270 #endif
271 #if defined(SUPPORT_2HD_2DD_FDD_IF)
272         ctrlreg = state_fio->FgetUint8();
273         modereg = state_fio->FgetUint8();
274 #endif
275         timer_id = state_fio->FgetInt32();
276         return true;
277 }
278