OSDN Git Service

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