OSDN Git Service

d68eff705f538aabd21d00800a68aefe14ee3a2b
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc6001 / floppy.cpp
1 //
2 // PC-6001/6601 disk I/O
3 // This file is based on a disk I/O program in C++
4 // by Mr. Yumitaro and translated into C for Cocoa iP6
5 // by Koichi NISHIDA 2006
6 //
7
8 /*
9         NEC PC-6601 Emulator 'yaPC-6601'
10         NEC PC-6601SR Emulator 'yaPC-6801'
11
12         Author : tanam
13         Date   : 2013.12.04-
14
15         [ internal floppy drive ]
16 */
17
18 #include "floppy.h"
19 #include "../disk.h"
20 #include "../noise.h"
21
22 int FLOPPY::Seek88(int drvno, int trackno, int sectno)
23 {
24         if(drvno < 2) {
25                 if(cur_trk[drvno] != trackno) {
26                         if(d_noise_seek != NULL) d_noise_seek->play();
27                 }
28                 cur_trk[drvno] = trackno;
29                 cur_sct[drvno] = sectno;
30                 cur_pos[drvno] = 0;
31                 
32                 if(disk[drvno]->get_track(trackno >> 1, trackno & 1)) {
33                         for(int i = 0; i < disk[drvno]->sector_num.sd; i++) {
34                                 if(disk[drvno]->get_sector(trackno >> 1, 0/*trackno & 1*/, i)) {
35                                         if(disk[drvno]->id[2] == sectno) {
36                                                 return 1;
37                                         }
38                                 }
39                         }
40                 }
41         }
42         return 0;
43 }
44
45 unsigned char FLOPPY::Getc88(int drvno)
46 {
47         if(drvno < 2 && disk[drvno]->sector != NULL) {
48                 if(cur_pos[drvno] >= disk[drvno]->sector_size.sd) {
49                         cur_sct[drvno]++;
50                         if(!Seek88(drvno, cur_trk[drvno], cur_sct[drvno])) {
51 //                              cur_trk[drvno]++;
52                                 cur_trk[drvno] += 2;
53                                 cur_sct[drvno] = 1;
54                                 if(!Seek88(drvno, cur_trk[drvno], cur_sct[drvno])) {
55                                         return 0xff;
56                                 }
57                         }
58                 }
59                 access[drvno] = true;
60                 return disk[drvno]->sector[cur_pos[drvno]++];
61         }
62         return 0xff;
63 }
64
65 int FLOPPY::Putc88(int drvno, unsigned char dat)
66 {
67         if(drvno < 2 && disk[drvno]->sector != NULL) {
68                 if(cur_pos[drvno] >= disk[drvno]->sector_size.sd) {
69                         cur_sct[drvno]++;
70                         if(!Seek88(drvno, cur_trk[drvno], cur_sct[drvno])) {
71 //                              cur_trk[drvno]++;
72                                 cur_trk[drvno] += 2;
73                                 cur_sct[drvno] = 1;
74                                 if(!Seek88(drvno, cur_trk[drvno], cur_sct[drvno])) {
75                                         return 0xff;
76                                 }
77                         }
78                 }
79                 access[drvno] = true;
80                 disk[drvno]->sector[cur_pos[drvno]++] = dat;
81                 return 1;
82         }
83         return 0;
84 }
85
86 // push data to data buffer
87 void FLOPPY::Push(int part, unsigned char data)
88 {
89         if (part > 3) return;
90         
91         if(Index[part] < 256) Data[part][Index[part]++] = data;
92 }
93
94 // pop data from data buffer
95 unsigned char FLOPPY::Pop(int part)
96 {
97         if(part > 3) return 0xff;
98         
99         if(Index[part] > 0) return Data[part][--Index[part]];
100         else                return 0xff;
101 }
102
103 // clear data
104 void FLOPPY::Clear(int i)
105 {
106         Index[i] = 0;
107 }
108
109 // FDC Status
110 #define FDC_BUSY                        (0x10)
111 #define FDC_READY                       (0x00)
112 #define FDC_NON_DMA                     (0x20)
113 #define FDC_FD2PC                       (0x40)
114 #define FDC_PC2FD                       (0x00)
115 #define FDC_DATA_READY          (0x80)
116
117 // Result Status 0
118 #define ST0_NOT_READY           (0x08)
119 #define ST0_EQUIP_CHK           (0x10)
120 #define ST0_SEEK_END            (0x20)
121 #define ST0_IC_NT                       (0x00)
122 #define ST0_IC_AT                       (0x40)
123 #define ST0_IC_IC                       (0x80)
124 #define ST0_IC_AI                       (0xc0)
125
126 // Result Status 1
127 #define ST1_NOT_WRITABLE        (0x02)
128
129 // Result Status 2
130
131 // Result Status 3
132 #define ST3_TRACK0                      (0x10)
133 #define ST3_READY                       (0x20)
134 #define ST3_WRITE_PROTECT       (0x40)
135 #define ST3_FAULT                       (0x80)
136
137 // initialise
138 int FLOPPY::DiskInit66(void)
139 {
140         memset( &CmdIn,  0, sizeof( CmdBuffer ) );
141         memset( &CmdOut, 0, sizeof( CmdBuffer ) );
142         SeekST0 = 0;
143         LastCylinder = 0;
144         SeekEnd = 0;
145         SendSectors  = 0;
146         Status = FDC_DATA_READY | FDC_READY | FDC_PC2FD;
147         return 1;
148 }
149
150 // push data to status buffer
151 void FLOPPY::PushStatus(int data)
152 {
153         CmdOut.Data[CmdOut.Index++] = data;
154 }
155
156 // pop data from status buffer
157 unsigned char FLOPPY::PopStatus()
158 {
159         return CmdOut.Data[--CmdOut.Index];
160 }
161
162 // write to FDC
163 void FLOPPY::OutFDC(unsigned char data)
164 {
165         const int CmdLength[] = { 0,0,0,3,2,9,9,2,1,0,0,0,0,6,0,3 };
166         
167         CmdIn.Data[CmdIn.Index++] = data;
168         if (CmdLength[CmdIn.Data[0]&0xf] == CmdIn.Index) Exec();
169 }
170
171 // read from FDC
172 unsigned char FLOPPY::InFDC()
173 {
174         if (CmdOut.Index == 1) Status = FDC_DATA_READY | FDC_PC2FD;
175         return PopStatus();
176 }
177
178 // read
179 void FLOPPY::Read()
180 {
181         int Drv, C, H, R, N;
182         int i, j;
183         
184         Drv = CmdIn.Data[1]&3;          // drive number No.(0-3)
185         C   = CmdIn.Data[2];            // cylinder
186         H   = CmdIn.Data[3];            // head address
187         R   = CmdIn.Data[4];            // sector No.
188         N   = CmdIn.Data[5] ? CmdIn.Data[5]*256 : 256;  // sector size
189         
190         if (disk[Drv]->inserted) {
191                 // seek
192                 // double track number(1D->2D)
193                 Seek88(Drv, C*2+H, R);
194                 for (i = 0; i < SendSectors; i++) {
195                         Clear(i);
196                         for(j=0; j<N; j++)
197                                 Push(i, Getc88(Drv));
198                 }
199         }
200         PushStatus(N);  // N
201         PushStatus(R);  // R
202         PushStatus(H);  // H
203         PushStatus(C);  // C
204         PushStatus(0);  // st2
205         PushStatus(0);  // st1
206         PushStatus(disk[Drv]->inserted ? 0 : ST0_NOT_READY);    // st0  bit3 : media not ready
207         Status = FDC_DATA_READY | FDC_FD2PC;
208 }
209
210 // Write
211 void FLOPPY::Write(void)
212 {
213         int Drv, C, H, R, N;
214         int i, j;
215         
216         Drv = CmdIn.Data[1]&3;          // drive No.(0-3)
217         C   = CmdIn.Data[2];            // cylinder
218         H   = CmdIn.Data[3];            // head address
219         R   = CmdIn.Data[4];            // sector No.
220         N   = CmdIn.Data[5] ? CmdIn.Data[5]*256 : 256;  // sector size
221         
222         if (disk[Drv]->inserted) {
223                 // seek
224                 // double track number(1D->2D)
225                 Seek88(Drv, C*2+H, R);
226                 for (i=0; i<SendSectors; i++) {
227                         for(j=0; j<0x100; j++)
228                                 Putc88(Drv, Pop(i));    // write data
229                 }
230         }
231         
232         PushStatus(N);  // N
233         PushStatus(R);  // R
234         PushStatus(H);  // H
235         PushStatus(C);  // C
236         PushStatus(0);  // st2
237         PushStatus(0);  // st1
238         
239         PushStatus(disk[Drv]->inserted ? 0 : ST0_NOT_READY);    // st0  bit3 : media not ready
240         
241         Status = FDC_DATA_READY | FDC_FD2PC;
242 }
243
244 // seek
245 void FLOPPY::Seek(void)
246 {
247         int Drv,C,H;
248         
249         Drv = CmdIn.Data[1]&3;          // drive No.(0-3)
250         C   = CmdIn.Data[2];            // cylinder
251         H   = CmdIn.Data[3];            // head address
252         
253         if (!disk[Drv]->inserted) {     // disk unmounted ?
254                 SeekST0      = ST0_IC_AT | ST0_SEEK_END | ST0_NOT_READY | Drv;
255                 SeekEnd      = 0;
256                 LastCylinder = 0;
257         } else { // seek
258                 // double number(1D->2D)
259                 Seek88(Drv, C*2+H, 1);
260                 SeekST0      = ST0_IC_NT | ST0_SEEK_END | Drv;
261                 SeekEnd      = 1;
262                 LastCylinder = C;
263         }
264 }
265
266 // sense interrupt status
267 void FLOPPY::SenseInterruptStatus(void)
268 {
269         if (SeekEnd) {
270                 SeekEnd = 0;
271                 PushStatus(LastCylinder);
272                 PushStatus(SeekST0);
273         } else {
274                 PushStatus(0);
275                 PushStatus(ST0_IC_IC);
276         }
277         
278         Status = FDC_DATA_READY | FDC_FD2PC;
279 }
280
281 // execute FDC command
282 void FLOPPY::Exec()
283 {
284         CmdOut.Index = 0;
285         switch (CmdIn.Data[0] & 0xf) {
286         case 0x03:      // Specify
287                 break;
288         case 0x05:      // Write Data
289                 Write();
290                 break;
291         case 0x06:      // Read Data
292                 Read();
293                 break;
294         case 0x08:      // Sense Interrupt Status
295                 SenseInterruptStatus();
296                 break;
297         case 0x0d:      // Write ID
298                 // Format is Not Implimented
299                 break;
300         case 0x07:      // Recalibrate
301                 CmdIn.Data[2] = 0;      // Seek to TRACK0
302         case 0x0f:      // Seek
303                 Seek();
304                 break;
305         default: ;      // Invalid
306         }
307         CmdIn.Index = 0;
308 }
309
310 // I/O access functions
311 void FLOPPY::OutB1H_66(unsigned char data) { DIO = data&2 ? 1 : 0; }                    // FD mode
312 void FLOPPY::OutB2H_66(unsigned char data) {}                                                                   // FDC INT?
313 void FLOPPY::OutB3H_66(unsigned char data) {}                                                                   // in out of PortB2h
314 void FLOPPY::OutD0H_66(unsigned char data) { Push(0, data); }                                   // Buffer
315 void FLOPPY::OutD1H_66(unsigned char data) { Push(1, data); }                                   // Buffer
316 void FLOPPY::OutD2H_66(unsigned char data) { Push(2, data); }                                   // Buffer
317 void FLOPPY::OutD3H_66(unsigned char data) { Push(3, data); }                                   // Buffer
318 void FLOPPY::OutD6H_66(unsigned char data) {}                                                                   // select drive
319 void FLOPPY::OutD8H_66(unsigned char data) {}                                                                   //
320 void FLOPPY::OutDAH_66(unsigned char data) { SendSectors = ~(data - 0x10); }    // set transfer amount
321 void FLOPPY::OutDDH_66(unsigned char data) { OutFDC(data); }                                    // FDC data register
322 void FLOPPY::OutDEH_66(unsigned char data) {}                                                                   // ?
323         
324 unsigned char FLOPPY::InB2H_66() { return 3; }                                                                  // FDC INT
325 unsigned char FLOPPY::InD0H_66() { return Pop(0); }                                                             // Buffer
326 unsigned char FLOPPY::InD1H_66() { return Pop(1); }                                                             // Buffer
327 unsigned char FLOPPY::InD2H_66() { return Pop(2); }                                                             // Buffer
328 unsigned char FLOPPY::InD3H_66() { return Pop(3); }                                                             // Buffer
329 unsigned char FLOPPY::InD4H_66() { return 0; }                                                                  // Mortor(on 0/off 1)
330 unsigned char FLOPPY::InDCH_66() { return Status; }                                                             // FDC status register
331 unsigned char FLOPPY::InDDH_66() { return InFDC(); }                                                    // FDC data register
332
333 void FLOPPY::initialize()
334 {
335         for(int i = 0; i < 2; i++) {
336                 disk[i] = new DISK(emu);
337                 disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1);
338                 disk[i]->drive_type = DRIVE_TYPE_2D;
339         }
340         if(d_noise_seek != NULL) {
341                 d_noise_seek->set_device_name(_T("Noise Player (FDD Seek)"));
342                 if(!d_noise_seek->load_wav_file(_T("FDDSEEK.WAV"))) {
343                         if(!d_noise_seek->load_wav_file(_T("FDDSEEK1.WAV"))) {
344                                 d_noise_seek->load_wav_file(_T("SEEK.WAV"));
345                         }
346                 }
347                 d_noise_seek->set_mute(!config.sound_noise_fdd);
348         }
349 //      if(d_noise_head_down != NULL) {
350 //              d_noise_head_down->set_device_name(_T("Noise Player (FDD Head Load)"));
351 //              d_noise_head_down->load_wav_file(_T("HEADDOWN.WAV"));
352 //              d_noise_head_down->set_mute(!config.sound_noise_fdd);
353 //      }
354 //      if(d_noise_head_up != NULL) {
355 //              d_noise_head_up->set_device_name(_T("Noise Player (FDD Head Unload)"));
356 //              d_noise_head_up->load_wav_file(_T("HEADUP.WAV"));
357 //              d_noise_head_up->set_mute(!config.sound_noise_fdd);
358 //      }
359         DiskInit66();
360 }
361
362 void FLOPPY::release()
363 {
364         for(int i = 0; i < 2; i++) {
365                 if(disk[i]) {
366                         disk[i]->close();
367                         delete disk[i];
368                 }
369         }
370 }
371
372 void FLOPPY::reset()
373 {
374         io_B1H = 0;
375         memset(Index, 0, sizeof(Index));
376 }
377
378 void FLOPPY::write_io8(uint32_t addr, uint32_t data)
379 {
380         // disk I/O
381         uint16_t port=(addr & 0x00ff);
382         uint8_t Value=(data & 0xff);
383         
384         switch(port)
385         {
386         // disk I/O
387         case 0xB1:
388         case 0xB5:
389                 io_B1H = Value;
390                 break;
391         case 0xB2:
392         case 0xB6:
393                 OutB2H_66(Value);
394                 break;
395         case 0xB3:
396         case 0xB7:
397                 OutB3H_66(Value);
398                 break;
399         case 0xD0:
400                 if(io_B1H & 4) {
401                         d_ext->write_io8(0, data);
402                 } else {
403                         OutD0H_66(Value);
404                 }
405                 break;
406         case 0xD1:
407                 if(io_B1H & 4) {
408                         d_ext->write_io8(1, data);
409                 } else {
410                         OutD1H_66(Value);
411                 }
412                 break;
413         case 0xD2:
414                 if(io_B1H & 4) {
415                         d_ext->write_io8(2, data);
416                 } else {
417                         OutD2H_66(Value);
418                 }
419                 break;
420         case 0xD3:
421                 if(io_B1H & 4) {
422                         d_ext->write_io8(3, data);
423                 } else {
424                         OutD3H_66(Value);
425                 }
426                 break;
427         case 0xD4:
428                 if(io_B1H & 4) {
429                         d_ext->write_io8(0, data);
430                 }
431                 break;
432         case 0xD5:
433                 if(io_B1H & 4) {
434                         d_ext->write_io8(1, data);
435                 }
436                 break;
437         case 0xD6:
438                 if(io_B1H & 4) {
439                         d_ext->write_io8(2, data);
440                 } else {
441                         OutD6H_66(Value);
442                 }
443                 break;
444         case 0xD7:
445                 if(io_B1H & 4) {
446                         d_ext->write_io8(3, data);
447                 }
448                 break;
449         case 0xD8:
450                 OutD8H_66(Value);
451                 break;
452         case 0xDA:
453                 OutDAH_66(Value);
454                 break;
455         case 0xDD:
456                 OutDDH_66(Value);
457                 break;
458         case 0xDE:
459                 OutDEH_66(Value);
460                 break;
461         }
462         return;
463 }
464
465 uint32_t FLOPPY::read_io8(uint32_t addr)
466 {
467         // disk I/O
468         uint16_t port=(addr & 0x00ff);
469         uint8_t Value=0xff;
470         
471         switch(addr & 0xff) {
472         case 0xB2:
473         case 0xB6:
474                 Value=InB2H_66();
475                 break;
476         case 0xD0:
477                 if(io_B1H & 4) {
478                         Value=d_ext->read_io8(0);
479                 } else {
480                         Value=InD0H_66();
481                 }
482                 break;
483         case 0xD1:
484                 if(io_B1H & 4) {
485                         Value=d_ext->read_io8(1);
486                 } else {
487                         Value=InD1H_66();
488                 }
489                 break;
490         case 0xD2:
491                 if(io_B1H & 4) {
492                         Value=d_ext->read_io8(2);
493                 } else {
494                         Value=InD2H_66();
495                 }
496                 break;
497         case 0xD3:
498                 if(io_B1H & 4) {
499                         Value=d_ext->read_io8(3);
500                 } else {
501                         Value=InD3H_66();
502                 }
503                 break;
504         case 0xD4:
505                 if(io_B1H & 4) {
506                         Value=d_ext->read_io8(0);
507                 } else {
508                         Value=InD4H_66();
509                 }
510                 break;
511         case 0xD5:
512                 if(io_B1H & 4) {
513                         Value=d_ext->read_io8(1);
514                 }
515                 break;
516         case 0xD6:
517                 if(io_B1H & 4) {
518                         Value=d_ext->read_io8(2);
519                 }
520                 break;
521         case 0xD7:
522                 if(io_B1H & 4) {
523                         Value=d_ext->read_io8(3);
524                 }
525                 break;
526         case 0xDC:
527                 Value=InDCH_66();
528                 break;
529         case 0xDD:
530                 Value=InDDH_66();
531                 break;
532         }
533         return(Value);
534 }
535
536 uint32_t FLOPPY::read_signal(int ch)
537 {
538         // get access status
539         uint32_t stat = 0;
540         for(int drv = 0; drv < 2; drv++) {
541                 if(access[drv]) {
542                         stat |= 1 << drv;
543                 }
544                 access[drv] = false;
545         }
546         return stat;
547 }
548
549 void FLOPPY::open_disk(int drv, const _TCHAR* file_path, int bank)
550 {
551         if(drv < 2) {
552                 disk[drv]->open(file_path, bank);
553                 Seek88(drv, 0, 1);
554         }
555 }
556
557 void FLOPPY::close_disk(int drv)
558 {
559         if(drv < 2 && disk[drv]->inserted) {
560                 disk[drv]->close();
561         }
562 }
563
564 bool FLOPPY::is_disk_inserted(int drv)
565 {
566         if(drv < 2) {
567                 return disk[drv]->inserted;
568         }
569         return false;
570 }
571
572 void FLOPPY::is_disk_protected(int drv, bool value)
573 {
574         if(drv < 2) {
575                 disk[drv]->write_protected = value;
576         }
577 }
578
579 bool FLOPPY::is_disk_protected(int drv)
580 {
581         if(drv < 2) {
582                 return disk[drv]->write_protected;
583         }
584         return false;
585 }
586
587 void FLOPPY::update_config()
588 {
589         if(d_noise_seek != NULL) {
590                 d_noise_seek->set_mute(!config.sound_noise_fdd);
591         }
592 //      if(d_noise_head_down != NULL) {
593 //              d_noise_head_down->set_mute(!config.sound_noise_fdd);
594 //      }
595 //      if(d_noise_head_up != NULL) {
596 //              d_noise_head_up->set_mute(!config.sound_noise_fdd);
597 //      }
598 }
599
600 #define STATE_VERSION   1
601
602 #include "../../statesub.h"
603
604 void FLOPPY::decl_state()
605 {
606         enter_decl_state(STATE_VERSION);
607
608         DECL_STATE_ENTRY_UINT8(io_B1H);
609         DECL_STATE_ENTRY_1D_ARRAY(cur_trk, 2);
610         DECL_STATE_ENTRY_1D_ARRAY(cur_sct, 2);
611         DECL_STATE_ENTRY_1D_ARRAY(cur_pos, 2);
612         DECL_STATE_ENTRY_1D_ARRAY(access, 2);
613         DECL_STATE_ENTRY_2D_ARRAY(Data, 4, 256);
614         DECL_STATE_ENTRY_1D_ARRAY(Index, 4);
615         {
616                 DECL_STATE_ENTRY_1D_ARRAY((CmdIn.Data), 10 * sizeof(unsigned char));
617                 DECL_STATE_ENTRY_INT32((CmdIn.Index));
618         }
619         {
620                 DECL_STATE_ENTRY_1D_ARRAY((CmdOut.Data), 10 * sizeof(unsigned char));
621                 DECL_STATE_ENTRY_INT32((CmdOut.Index));
622         }
623
624         DECL_STATE_ENTRY_UINT8(SeekST0);
625         DECL_STATE_ENTRY_UINT8(LastCylinder);
626         DECL_STATE_ENTRY_INT32(SeekEnd);
627         DECL_STATE_ENTRY_UINT8(SendSectors);
628         DECL_STATE_ENTRY_INT32(DIO);
629         DECL_STATE_ENTRY_UINT8(Status);
630         leave_decl_state();
631
632         for(int i = 0; i < 2; i++) {
633                 disk[i]->decl_state(p_logger);
634         }
635
636 }
637
638
639 void FLOPPY::save_state(FILEIO* state_fio)
640 {
641         if(state_entry != NULL) {
642                 state_entry->save_state(state_fio);
643         }
644 //      state_fio->FputUint32(STATE_VERSION);
645 //      state_fio->FputInt32(this_device_id);
646         
647 //      state_fio->FputUint8(io_B1H);
648         for(int i = 0; i < 2; i++) {
649                 disk[i]->save_state(state_fio);
650         }
651 //      state_fio->Fwrite(cur_trk, sizeof(cur_trk), 1);
652 //      state_fio->Fwrite(cur_sct, sizeof(cur_sct), 1);
653 //      state_fio->Fwrite(cur_pos, sizeof(cur_pos), 1);
654 //      state_fio->Fwrite(access, sizeof(access), 1);
655 //      state_fio->Fwrite(Data, sizeof(Data), 1);
656 //      state_fio->Fwrite(Index, sizeof(Index), 1);
657 //      state_fio->Fwrite(&CmdIn, sizeof(CmdBuffer), 1);
658 //      state_fio->Fwrite(&CmdOut, sizeof(CmdBuffer), 1);
659
660 //      state_fio->FputUint8(SeekST0);
661 //      state_fio->FputUint8(LastCylinder);
662 //      state_fio->FputInt32(SeekEnd);
663 //      state_fio->FputUint8(SendSectors);
664 //      state_fio->FputInt32(DIO);
665 //      state_fio->FputUint8(Status);
666 }
667
668 bool FLOPPY::load_state(FILEIO* state_fio)
669 {
670         bool mb = false;
671         if(state_entry != NULL) {
672                 mb = state_entry->load_state(state_fio);
673         }
674         if(!mb) {
675                 return false;
676         }
677 //      if(state_fio->FgetUint32() != STATE_VERSION) {
678 //              return false;
679 //      }
680 //      if(state_fio->FgetInt32() != this_device_id) {
681 //              return false;
682 //      }
683 //      io_B1H = state_fio->FgetUint8();
684         for(int i = 0; i < 2; i++) {
685                 if(!disk[i]->load_state(state_fio)) {
686                         return false;
687                 }
688         }
689 //      state_fio->Fread(cur_trk, sizeof(cur_trk), 1);
690 //      state_fio->Fread(cur_sct, sizeof(cur_sct), 1);
691 //      state_fio->Fread(cur_pos, sizeof(cur_pos), 1);
692 //      state_fio->Fread(access, sizeof(access), 1);
693 //      state_fio->Fread(Data, sizeof(Data), 1);
694 //      state_fio->Fread(Index, sizeof(Index), 1);
695 //      state_fio->Fread(&CmdIn, sizeof(CmdBuffer), 1);
696 //      state_fio->Fread(&CmdOut, sizeof(CmdBuffer), 1);
697 //      SeekST0 = state_fio->FgetUint8();
698 //      LastCylinder = state_fio->FgetUint8();
699 //      SeekEnd = state_fio->FgetInt32();
700 //      SendSectors = state_fio->FgetUint8();
701 //      DIO = state_fio->FgetInt32();
702 //      Status = state_fio->FgetUint8();
703         return true;
704 }
705
706 bool FLOPPY::process_state(FILEIO* state_fio, bool loading)
707 {
708         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
709                 return false;
710         }
711         if(!state_fio->StateCheckInt32(this_device_id)) {
712                 return false;
713         }
714         state_fio->StateUint8(io_B1H);
715         for(int i = 0; i < 2; i++) {
716                 if(!disk[i]->process_state(state_fio, loading)) {
717                         return false;
718                 }
719         }
720         state_fio->StateBuffer(cur_trk, sizeof(cur_trk), 1);
721         state_fio->StateBuffer(cur_sct, sizeof(cur_sct), 1);
722         state_fio->StateBuffer(cur_pos, sizeof(cur_pos), 1);
723         state_fio->StateBuffer(access, sizeof(access), 1);
724         state_fio->StateBuffer(Data, sizeof(Data), 1);
725         state_fio->StateBuffer(Index, sizeof(Index), 1);
726         state_fio->StateBuffer(&CmdIn, sizeof(CmdBuffer), 1);
727         state_fio->StateBuffer(&CmdOut, sizeof(CmdBuffer), 1);
728         state_fio->StateUint8(SeekST0);
729         state_fio->StateUint8(LastCylinder);
730         state_fio->StateInt32(SeekEnd);
731         state_fio->StateUint8(SendSectors);
732         state_fio->StateInt32(DIO);
733         state_fio->StateUint8(Status);
734         return true;
735 }