OSDN Git Service

[VM][FMTOWNS][MEMORY] Fix setup around memory banks by I/O 0404h and 0480h.
[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  DLL_PREFIX MB8877 : public DEVICE
27 {
28 private:
29         // output signals
30         outputs_t outputs_irq;
31         outputs_t outputs_drq;
32         outputs_t outputs_rdy;
33
34         // drive noise
35         NOISE* d_noise_seek;
36         NOISE* d_noise_head_down;
37         NOISE* d_noise_head_up;
38         
39         // drive info
40         struct {
41                 int track;
42                 int index;
43                 bool access;
44                 bool head_load;
45                 // write track
46                 bool id_written;
47                 bool sector_found;
48                 int sector_length;
49                 int sector_index;
50                 int side;
51                 bool side_changed;
52                 // timing
53                 int cur_position;
54                 int next_trans_position;
55                 int bytes_before_2nd_drq;
56                 int next_am1_position;
57                 uint32_t prev_clock;
58                 bool count_immediate; // Hack for FLEX.
59         } fdc[16];
60         DISK* disk[16];
61         
62         // registor
63         uint8_t status, status_tmp;
64         uint8_t cmdreg, cmdreg_tmp;
65         uint8_t trkreg;
66         uint8_t secreg;
67         uint8_t datareg;
68         uint8_t drvreg;
69         uint8_t sidereg;
70         uint8_t cmdtype;
71         
72         // event
73         int register_id[10];
74         
75         void cancel_my_event(int event);
76         void register_my_event(int event, double usec);
77         bool register_my_event_with_check(int event, double usec);
78         void register_seek_event(bool first);
79         void register_drq_event(int bytes);
80         void register_lost_event(int bytes);
81         
82         bool check_drive(void);
83         bool check_drive2(void);
84         
85         // status
86         bool now_search;
87         bool now_seek;
88         bool sector_changed;
89         int no_command;
90         int seektrk;
91         bool seekvct;
92         bool motor_on;
93         bool drive_sel;
94         
95 //#ifdef HAS_MB89311
96         // MB89311
97         bool extended_mode;
98 //#endif
99         
100         // timing
101         uint32_t prev_drq_clock;
102         uint32_t seekend_clock;
103
104         // flags
105         bool fdc_debug_log;
106         bool invert_registers;
107         bool type_fm77av_2dd;
108         bool type_mb8866;
109         bool type_mb89311;
110         bool type_x1;
111         bool type_fm7;
112         bool type_fmr50;
113         bool type_fmr60;
114         bool mb8877_no_busy_after_seek;
115         int  mb8877_delay_after_seek;
116         int _max_drive;
117         int _drive_mask;
118         
119         int __FASTCALL get_cur_position();
120         double __FASTCALL  get_usec_to_start_trans(bool first_sector);
121         double __FASTCALL get_usec_to_next_trans_pos(bool delay);
122         double __FASTCALL get_usec_to_detect_index_hole(int count, bool delay);
123         
124         // image handler
125         uint8_t search_track();
126         uint8_t search_sector();
127         uint8_t search_addr();
128         
129         // command
130         void process_cmd();
131         void cmd_restore();
132         void cmd_seek();
133         void cmd_step();
134         void cmd_stepin();
135         void cmd_stepout();
136         void cmd_readdata(bool first_sector);
137         void cmd_writedata(bool first_sector);
138         void cmd_readaddr();
139         void cmd_readtrack();
140         void cmd_writetrack();
141 //#ifdef HAS_MB89311
142         void cmd_format();
143 //#endif
144         void cmd_forceint();
145         void update_head_flag(int drv, bool head_load);
146         virtual void update_ready();
147         
148         // irq/dma
149         void __FASTCALL set_irq(bool val);
150         void __FASTCALL set_drq(bool val);
151
152 public:
153         MB8877(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
154         {
155                 initialize_output_signals(&outputs_irq);
156                 initialize_output_signals(&outputs_drq);
157                 initialize_output_signals(&outputs_rdy);
158                 d_noise_seek = NULL;
159                 d_noise_head_down = NULL;
160                 d_noise_head_up = NULL;
161                 // these parameters may be modified before calling initialize()
162                 drvreg = sidereg = 0;
163                 motor_on = drive_sel = false;
164                 //
165                 mb8877_delay_after_seek = 0;
166                 fdc_debug_log = invert_registers = type_fm77av_2dd = false;
167                 type_mb8866 = type_mb89311 = false;
168                 type_x1 = type_fm7 = type_fmr50 = type_fmr60 = false;
169                 mb8877_no_busy_after_seek = false;
170                 _max_drive = 4;
171                 _drive_mask = _max_drive - 1;
172                 for(int i = 0; i < 16; i++) {
173                         disk[i] = NULL;
174                 }
175 //#if defined(HAS_MB89311)
176 //              set_device_name(_T("MB89311 FDC"));
177 //#elif defined(HAS_MB8866)
178 //              set_device_name(_T("MB8866 FDC"));
179 //#elif defined(HAS_MB8876)
180 //              set_device_name(_T("MB8876 FDC"));
181 //#else
182 //              set_device_name(_T("MB8877 FDC"));
183 //#endif
184         }
185         ~MB8877() {}
186         
187         // common functions
188         void initialize() override;
189         void release() override;
190         void reset() override;
191         void __FASTCALL write_io8(uint32_t addr, uint32_t data) override;
192         uint32_t __FASTCALL read_io8(uint32_t addr) override;
193         void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data) override;
194         uint32_t __FASTCALL read_dma_io8(uint32_t addr) override;
195         void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask) override;
196         uint32_t __FASTCALL read_signal(int ch) override;
197         void __FASTCALL event_callback(int event_id, int err) override;
198         void update_config() override;
199         bool is_debugger_available() override
200         {
201                 return true;
202         }
203         bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) override;
204         bool process_state(FILEIO* state_fio, bool loading) override;
205         
206         // unique functions
207         void set_context_irq(DEVICE* device, int id, uint32_t mask)
208         {
209                 register_output_signal(&outputs_irq, device, id, mask);
210         }
211         void set_context_drq(DEVICE* device, int id, uint32_t mask)
212         {
213                 register_output_signal(&outputs_drq, device, id, mask);
214         }
215         void set_context_rdy(DEVICE* device, int id, uint32_t mask)
216         {
217                 register_output_signal(&outputs_rdy, device, id, mask);
218         }
219         void set_context_noise_seek(NOISE* device)
220         {
221                 d_noise_seek = device;
222         }
223         NOISE* get_context_noise_seek()
224         {
225                 return d_noise_seek;
226         }
227         void set_context_noise_head_down(NOISE* device)
228         {
229                 d_noise_head_down = device;
230         }
231         NOISE* get_context_noise_head_down()
232         {
233                 return d_noise_head_down;
234         }
235         void set_context_noise_head_up(NOISE* device)
236         {
237                 d_noise_head_up = device;
238         }
239         NOISE* get_context_noise_head_up()
240         {
241                 return d_noise_head_up;
242         }
243         DISK* get_disk_handler(int drv)
244         {
245                 return disk[drv];
246         }
247         void open_disk(int drv, const _TCHAR* file_path, int bank);
248         void close_disk(int drv);
249         bool is_disk_inserted(int drv);
250         bool is_disk_changed(int drv);
251         void is_disk_protected(int drv, bool value);
252         bool is_disk_protected(int drv);
253         bool is_drive_ready();
254         bool is_drive_ready(int drv);
255         uint8_t get_media_type(int drv);
256         void set_drive_type(int drv, uint8_t type);
257         uint8_t get_drive_type(int drv);
258         void set_drive_rpm(int drv, int rpm);
259         void set_drive_mfm(int drv, bool mfm);
260         void set_track_size(int drv, int size);
261         uint8_t fdc_status();
262 };
263
264 #endif