2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 #define EVENT_FM_TIMER 0
14 #ifdef SUPPORT_MAME_FM_DLL
15 static bool dont_create_multiple_chips = false;
18 void YM2151::initialize()
21 #ifdef SUPPORT_MAME_FM_DLL
22 // fmdll = new CFMDLL(_T("mamefm.dll"));
23 fmdll = new CFMDLL(config.fmgen_dll_path);
26 register_vline_event(this);
28 clock_prev = clock_accum = clock_busy = 0;
31 void YM2151::release()
34 #ifdef SUPPORT_MAME_FM_DLL
36 fmdll->Release(dllchip);
45 #ifdef SUPPORT_MAME_FM_DLL
47 fmdll->Reset(dllchip);
49 memset(port_log, 0, sizeof(port_log));
52 irq_prev = busy = false;
55 void YM2151::write_io8(uint32 addr, uint32 data)
64 clock_busy = current_clock();
71 uint32 YM2151::read_io8(uint32 addr)
76 uint32 status = opm->ReadStatus() & ~0x80;
78 // FIXME: we need to investigate the correct busy period
79 if(passed_usec(clock_busy) < 8) {
89 void YM2151::write_signal(int id, uint32 data, uint32 mask)
91 if(id == SIG_YM2151_MUTE) {
92 mute = ((data & mask) != 0);
96 void YM2151::event_vline(int v, int clock)
102 void YM2151::event_callback(int event_id, int error)
110 void YM2151::update_count()
112 clock_accum += clock_const * passed_clock(clock_prev);
113 uint32 count = clock_accum >> 20;
116 clock_accum -= count << 20;
118 clock_prev = current_clock();
121 void YM2151::update_event()
123 if(timer_event_id != -1) {
124 cancel_event(this, timer_event_id);
128 int count = opm->GetNextEvent();
130 register_event(this, EVENT_FM_TIMER, 1000000.0 / (double)chip_clock * (double)count, false, &timer_event_id);
134 void YM2151::update_interrupt()
136 bool irq = opm->ReadIRQ();
137 if(!irq_prev && irq) {
138 write_signals(&outputs_irq, 0xffffffff);
139 } else if(irq_prev && !irq) {
140 write_signals(&outputs_irq, 0);
145 void YM2151::mix(int32* buffer, int cnt)
147 if(cnt > 0 && !mute) {
148 opm->Mix(buffer, cnt);
149 #ifdef SUPPORT_MAME_FM_DLL
151 fmdll->Mix(dllchip, buffer, cnt);
157 void YM2151::init(int rate, int clock, int samples, int vol)
159 opm->Init(clock, rate, false);
161 #ifdef SUPPORT_MAME_FM_DLL
162 if(!dont_create_multiple_chips) {
163 fmdll->Create((LPVOID*)&dllchip, clock, rate);
165 fmdll->SetVolumeFM(dllchip, vol);
168 DWORD dwCaps = fmdll->GetCaps(dllchip);
169 if((dwCaps & SUPPORT_MULTIPLE) != SUPPORT_MULTIPLE) {
170 dont_create_multiple_chips = true;
172 if((dwCaps & SUPPORT_FM_A) == SUPPORT_FM_A) {
175 if((dwCaps & SUPPORT_FM_B) == SUPPORT_FM_B) {
178 if((dwCaps & SUPPORT_FM_C) == SUPPORT_FM_C) {
181 opm->SetChannelMask(mask);
182 fmdll->SetChannelMask(dllchip, ~mask);
190 void YM2151::SetReg(uint addr, uint data)
192 opm->SetReg(addr, data);
193 #ifdef SUPPORT_MAME_FM_DLL
195 fmdll->SetReg(dllchip, addr, data);
197 port_log[addr].written = true;
198 port_log[addr].data = data;
202 void YM2151::update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame)
204 clock_const = (uint32)((double)chip_clock * 1024.0 * 1024.0 / (double)new_clocks + 0.5);
207 #define STATE_VERSION 1
209 void YM2151::save_state(FILEIO* state_fio)
211 state_fio->FputUint32(STATE_VERSION);
212 state_fio->FputInt32(this_device_id);
214 opm->SaveState((void *)state_fio);
215 #ifdef SUPPORT_MAME_FM_DLL
216 state_fio->Fwrite(port_log, sizeof(port_log), 1);
218 state_fio->FputInt32(chip_clock);
219 state_fio->FputUint8(ch);
220 state_fio->FputBool(irq_prev);
221 state_fio->FputBool(mute);
222 state_fio->FputUint32(clock_prev);
223 state_fio->FputUint32(clock_accum);
224 state_fio->FputUint32(clock_const);
225 state_fio->FputUint32(clock_busy);
226 state_fio->FputBool(busy);
229 bool YM2151::load_state(FILEIO* state_fio)
231 if(state_fio->FgetUint32() != STATE_VERSION) {
234 if(state_fio->FgetInt32() != this_device_id) {
237 if(!opm->LoadState((void *)state_fio)) {
240 #ifdef SUPPORT_MAME_FM_DLL
241 state_fio->Fread(port_log, sizeof(port_log), 1);
243 chip_clock = state_fio->FgetInt32();
244 ch = state_fio->FgetUint8();
245 irq_prev = state_fio->FgetBool();
246 mute = state_fio->FgetBool();
247 clock_prev = state_fio->FgetUint32();
248 clock_accum = state_fio->FgetUint32();
249 clock_const = state_fio->FgetUint32();
250 clock_busy = state_fio->FgetUint32();
251 busy = state_fio->FgetBool();
253 #ifdef SUPPORT_MAME_FM_DLL
256 fmdll->Reset(dllchip);
257 for(int i = 0; i < 0x100; i++) {
258 if(port_log[i].written) {
259 fmdll->SetReg(dllchip, i, port_log[i].data);