OSDN Git Service

2c80c9be401211732566f439ac42ee985b244a91
[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 void FLOPPY::initialize()
17 {
18         drvreg = drvsel = 0;
19         irq = irqmsk = false;
20         changed[0] = changed[1] = changed[2] = changed[3] = false;
21 }
22
23 void FLOPPY::reset()
24 {
25         for(int i = 0; i < MAX_DRIVE; i++) {
26                 d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
27         }
28 }
29
30 void FLOPPY::write_io8(uint32_t addr, uint32_t data)
31 {
32         int nextdrv = drvsel;
33         
34         switch(addr & 0xffff) {
35         case 0x208:
36                 // drive control register
37                 irqmsk = ((data & 1) != 0);
38                 update_intr();
39                 // note: bit5 is CLKSEL, but 0 is set while seeking
40 /*
41                 for(int i = 0; i < MAX_DRIVE; i++) {
42                         if(data & 0x20) {
43                                 d_fdc->set_drive_type(i, DRIVE_TYPE_2DD);
44                         } else {
45                                 d_fdc->set_drive_type(i, DRIVE_TYPE_2HD);
46                         }
47                 }
48 */
49                 d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10);
50                 d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 4);
51                 break;
52         case 0x20c:
53                 // drive select register
54                 if(data & 0x0f) {
55                         if(data & 1) {
56                                 nextdrv = 0;
57                         } else if(data & 2) {
58                                 nextdrv = 1;
59                         } else if(data & 4) {
60                                 nextdrv = 2;
61                         } else if(data & 8) {
62                                 nextdrv = 3;
63                         }
64                         if(drvsel != nextdrv) {
65                                 d_fdc->write_signal(SIG_MB8877_DRIVEREG, drvsel = nextdrv, 3);
66                         }
67                         for(int i = 0; i < MAX_DRIVE; i++) {
68                                 if((data & 0xc0) == 0x00) {
69                                         d_fdc->set_drive_type(i, DRIVE_TYPE_2DD); // 300rpm
70                                 } else if((data & 0xc0) == 0x40) {
71                                         d_fdc->set_drive_type(i, DRIVE_TYPE_2HD); // 360rpm
72                                 }
73                         }
74                 }
75                 drvreg = data;
76                 break;
77         }
78 }
79
80 uint32_t FLOPPY::read_io8(uint32_t addr)
81 {
82         switch(addr & 0xffff) {
83         case 0x208:
84                 {
85                         int drvreg = d_fdc->read_signal(SIG_MB8877_DRIVEREG);
86                         uint32_t fdc_status = d_fdc->is_disk_inserted(drvreg) ? 2 : 0;
87                         
88                         if(changed[drvsel]) {
89                                 changed[drvsel] = false;
90                                 return fdc_status | 0xe1;       // fdd*2
91                         }
92 //                      return fdc_status | 0x60;       // fdd*1
93                         return fdc_status | 0xe0;       // fdd*2
94                 }
95         case 0x20c:
96                 return drvreg;
97         }
98         return 0xff;
99 }
100
101 void FLOPPY::write_signal(int id, uint32_t data, uint32_t mask)
102 {
103         if(id == SIG_FLOPPY_IRQ) {
104                 irq = ((data & mask) != 0);
105                 update_intr();
106         }
107 }
108
109 void FLOPPY::update_intr()
110 {
111         d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR6, irq && irqmsk ? 1 : 0, 1);
112 }
113
114 #define STATE_VERSION   1
115
116 #include "../../statesub.h"
117
118 void FLOPPY::decl_state()
119 {
120         enter_decl_state(STATE_VERSION);
121
122         DECL_STATE_ENTRY_INT32(drvreg);
123         DECL_STATE_ENTRY_INT32(drvsel);
124         DECL_STATE_ENTRY_BOOL(irq);
125         DECL_STATE_ENTRY_BOOL(irqmsk);
126         DECL_STATE_ENTRY_1D_ARRAY(changed, sizeof(changed) / sizeof(bool));
127
128         leave_decl_state();
129 }
130
131 void FLOPPY::save_state(FILEIO* state_fio)
132 {
133         if(state_entry != NULL) {
134                 state_entry->save_state(state_fio);
135         }
136
137 //      state_fio->FputUint32(STATE_VERSION);
138 //      state_fio->FputInt32(this_device_id);
139 //      
140 //      state_fio->FputInt32(drvreg);
141 //      state_fio->FputInt32(drvsel);
142 //      state_fio->FputBool(irq);
143 //      state_fio->FputBool(irqmsk);
144 //      state_fio->Fwrite(changed, sizeof(changed), 1);
145 }
146
147 bool FLOPPY::load_state(FILEIO* state_fio)
148 {
149         bool mb = false;
150         if(state_entry != NULL) {
151                 mb = state_entry->load_state(state_fio);
152         }
153         if(!mb) {
154                 return false;
155         }
156
157 //      if(state_fio->FgetUint32() != STATE_VERSION) {
158 //              return false;
159 //      }
160 //      if(state_fio->FgetInt32() != this_device_id) {
161 //              return false;
162 //      }
163 //      drvreg = state_fio->FgetInt32();
164 //      drvsel = state_fio->FgetInt32();
165 //      irq = state_fio->FgetBool();
166 //      irqmsk = state_fio->FgetBool();
167 //      state_fio->Fread(changed, sizeof(changed), 1);
168         return true;
169 }
170
171 bool FLOPPY::process_state(FILEIO* state_fio, bool loading)
172 {
173         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
174                 return false;
175         }
176         if(!state_fio->StateCheckInt32(this_device_id)) {
177                 return false;
178         }
179         state_fio->StateInt32(drvreg);
180         state_fio->StateInt32(drvsel);
181         state_fio->StateBool(irq);
182         state_fio->StateBool(irqmsk);
183         state_fio->StateBuffer(changed, sizeof(changed), 1);
184         return true;
185 }