OSDN Git Service

[VM] Merge Updtream 2017-05-13. Still not build test.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mb8877.h
1 /*
2         Skelton for retropc emulator
3
4         Origin : XM7
5         Author : Takeda.Toshiya
6         Date   : 2006.12.06 -
7
8         [ MB8877 / MB8876 / MB8866 / MB89311 ]
9 */
10
11 #ifndef _MB8877_H_ 
12 #define _MB8877_H_
13
14 //#include "vm.h"
15 //#include "../emu.h"
16 #include "device.h"
17
18 #define SIG_MB8877_ACCESS       0
19 #define SIG_MB8877_DRIVEREG     1
20 #define SIG_MB8877_SIDEREG      2
21 #define SIG_MB8877_MOTOR        3
22
23 class DISK;
24 class NOISE;
25
26 class MB8877 : public DEVICE
27 {
28 private:
29         // output signals
30         outputs_t outputs_irq;
31         outputs_t outputs_drq;
32         
33         // drive noise
34         NOISE* d_noise_seek;
35         NOISE* d_noise_head_down;
36         NOISE* d_noise_head_up;
37         
38         // drive info
39         struct {
40                 int track;
41                 int index;
42                 bool access;
43                 bool head_load;
44                 // write track
45                 bool id_written;
46                 bool sector_found;
47                 int sector_length;
48                 int sector_index;
49                 int side;
50                 bool side_changed;
51                 // timing
52                 int cur_position;
53                 int next_trans_position;
54                 int bytes_before_2nd_drq;
55                 int next_am1_position;
56                 uint32_t prev_clock;
57         } fdc[16];
58         DISK* disk[16];
59         
60         // registor
61         uint8_t status, status_tmp;
62         uint8_t cmdreg, cmdreg_tmp;
63         uint8_t trkreg;
64         uint8_t secreg;
65         uint8_t datareg;
66         uint8_t drvreg;
67         uint8_t sidereg;
68         uint8_t cmdtype;
69         
70         // event
71         int register_id[8];
72         
73         void cancel_my_event(int event);
74         void register_my_event(int event, double usec);
75         void register_seek_event();
76         void register_drq_event(int bytes);
77         void register_lost_event(int bytes);
78         
79         // status
80         bool now_search;
81         bool now_seek;
82         bool sector_changed;
83         int no_command;
84         int seektrk;
85         bool seekvct;
86         bool motor_on;
87         bool drive_sel;
88         
89 //#ifdef HAS_MB89311
90         // MB89311
91         bool extended_mode;
92 //#endif
93         
94         // timing
95         uint32_t prev_drq_clock;
96         uint32_t seekend_clock;
97
98         // flags
99         bool fdc_debug_log;
100         bool invert_registers;
101         bool type_fm77av_2dd;
102         bool type_mb8866;
103         bool type_mb89311;
104         bool type_x1;
105         bool type_fm7;
106         bool type_fmr50;
107         bool type_fmr60;
108         bool mb8877_no_busy_after_seek;
109         int _max_drive;
110         int _drive_mask;
111         
112         int get_cur_position();
113         double get_usec_to_start_trans(bool first_sector);
114         double get_usec_to_next_trans_pos(bool delay);
115         double get_usec_to_detect_index_hole(int count, bool delay);
116         
117         // image handler
118         uint8_t search_track();
119         uint8_t search_sector();
120         uint8_t search_addr();
121         
122         // command
123         void process_cmd();
124         void cmd_restore();
125         void cmd_seek();
126         void cmd_step();
127         void cmd_stepin();
128         void cmd_stepout();
129         void cmd_readdata(bool first_sector);
130         void cmd_writedata(bool first_sector);
131         void cmd_readaddr();
132         void cmd_readtrack();
133         void cmd_writetrack();
134 //#ifdef HAS_MB89311
135         void cmd_format();
136 //#endif
137         void cmd_forceint();
138         void update_head_flag(int drv, bool head_load);
139         
140         // irq/dma
141         void set_irq(bool val);
142         void set_drq(bool val);
143         
144 public:
145         MB8877(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
146         {
147                 initialize_output_signals(&outputs_irq);
148                 initialize_output_signals(&outputs_drq);
149                 d_noise_seek = NULL;
150                 d_noise_head_down = NULL;
151                 d_noise_head_up = NULL;
152                 motor_on = false;
153                 //
154                 fdc_debug_log = invert_registers = type_fm77av_2dd = false;
155                 type_mb8866 = type_mb89311 = false;
156                 type_x1 = type_fm7 = type_fmr50 = type_fmr60 = false;
157                 mb8877_no_busy_after_seek = false;
158                 _max_drive = 4;
159                 _drive_mask = _max_drive - 1;
160 //#if defined(HAS_MB89311)
161 //              set_device_name(_T("MB89311 FDC"));
162 //#elif defined(HAS_MB8866)
163 //              set_device_name(_T("MB8866 FDC"));
164 //#elif defined(HAS_MB8876)
165 //              set_device_name(_T("MB8876 FDC"));
166 //#else
167 //              set_device_name(_T("MB8877 FDC"));
168 //#endif
169         }
170         ~MB8877() {}
171         
172         // common functions
173         void initialize();
174         void release();
175         void reset();
176         void write_io8(uint32_t addr, uint32_t data);
177         uint32_t read_io8(uint32_t addr);
178         void write_dma_io8(uint32_t addr, uint32_t data);
179         uint32_t read_dma_io8(uint32_t addr);
180         void write_signal(int id, uint32_t data, uint32_t mask);
181         uint32_t read_signal(int ch);
182         void event_callback(int event_id, int err);
183         void update_config();
184         void save_state(FILEIO* state_fio);
185         bool load_state(FILEIO* state_fio);
186         
187         // unique functions
188         void set_context_irq(DEVICE* device, int id, uint32_t mask)
189         {
190                 register_output_signal(&outputs_irq, device, id, mask);
191         }
192         void set_context_drq(DEVICE* device, int id, uint32_t mask)
193         {
194                 register_output_signal(&outputs_drq, device, id, mask);
195         }
196         void set_context_noise_seek(NOISE* device)
197         {
198                 d_noise_seek = device;
199         }
200         NOISE* get_context_noise_seek()
201         {
202                 return d_noise_seek;
203         }
204         void set_context_noise_head_down(NOISE* device)
205         {
206                 d_noise_head_down = device;
207         }
208         NOISE* get_context_noise_head_down()
209         {
210                 return d_noise_head_down;
211         }
212         void set_context_noise_head_up(NOISE* device)
213         {
214                 d_noise_head_up = device;
215         }
216         NOISE* get_context_noise_head_up()
217         {
218                 return d_noise_head_up;
219         }
220         DISK* get_disk_handler(int drv)
221         {
222                 return disk[drv];
223         }
224         void open_disk(int drv, const _TCHAR* file_path, int bank);
225         void close_disk(int drv);
226         bool is_disk_inserted(int drv);
227         void is_disk_protected(int drv, bool value);
228         bool is_disk_protected(int drv);
229         void set_drive_type(int drv, uint8_t type);
230         uint8_t get_drive_type(int drv);
231         void set_drive_rpm(int drv, int rpm);
232         void set_drive_mfm(int drv, bool mfm);
233         void set_track_size(int drv, int size);
234         uint8_t fdc_status();
235 };
236
237 #endif