mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-13 13:50:59 +00:00
87d46ddd11
## 1.5.0 2020-09-28 * Drum note length expanding is now supported in real-time mode (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added support for OPNA chip with Neko Project II Kai YM2602 emulator usage (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added VGM file dumper which allows to output OPN2 commands into VGM file. (A new MIDI to VGM tool is now created with basing on libOPNMIDI) * Fixed an incorrect work of CC-121 (See https://github.com/Wohlstand/libADLMIDI/issues/227 for details) * Internality has been refactored and improved
217 lines
4.7 KiB
C++
217 lines
4.7 KiB
C++
// ---------------------------------------------------------------------------
|
|
// FM sound generator common timer module
|
|
// Copyright (C) cisc 1998, 2000.
|
|
// ---------------------------------------------------------------------------
|
|
// $Id: fmtimer.cpp,v 1.1 2000/09/08 13:45:56 cisc Exp $
|
|
|
|
#include "fmgen_headers.h"
|
|
#include "fmgen_fmtimer.h"
|
|
|
|
using namespace FM;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマー制御
|
|
//
|
|
void Timer::SetTimerControl(uint data)
|
|
{
|
|
uint tmp = regtc ^ data;
|
|
regtc = uint8(data);
|
|
|
|
if (data & 0x10)
|
|
ResetStatus(1);
|
|
if (data & 0x20)
|
|
ResetStatus(2);
|
|
|
|
if (tmp & 0x01)
|
|
timera_count = (data & 1) ? timera : 0;
|
|
if (tmp & 0x02)
|
|
timerb_count = (data & 2) ? timerb : 0;
|
|
}
|
|
|
|
#if 1
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマーA 周期設定
|
|
//
|
|
void Timer::SetTimerA(uint addr, uint data)
|
|
{
|
|
uint tmp;
|
|
regta[addr & 1] = uint8(data);
|
|
tmp = (regta[0] << 2) + (regta[1] & 3);
|
|
timera = (1024-tmp) * timer_step;
|
|
// LOG2("Timer A = %d %d us\n", tmp, timera >> 16);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマーB 周期設定
|
|
//
|
|
void Timer::SetTimerB(uint data)
|
|
{
|
|
timerb = (256-data) * timer_step;
|
|
// LOG2("Timer B = %d %d us\n", data, timerb >> 12);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマー時間処理
|
|
//
|
|
bool Timer::Count(int32 us)
|
|
{
|
|
bool event = false;
|
|
|
|
if (timera_count)
|
|
{
|
|
timera_count -= us << 16;
|
|
if (timera_count <= 0)
|
|
{
|
|
event = true;
|
|
TimerA();
|
|
|
|
while (timera_count <= 0)
|
|
timera_count += timera;
|
|
|
|
if (regtc & 4)
|
|
SetStatus(1);
|
|
}
|
|
}
|
|
if (timerb_count)
|
|
{
|
|
timerb_count -= us << 12;
|
|
if (timerb_count <= 0)
|
|
{
|
|
event = true;
|
|
while (timerb_count <= 0)
|
|
timerb_count += timerb;
|
|
|
|
if (regtc & 8)
|
|
SetStatus(2);
|
|
}
|
|
}
|
|
return event;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 次にタイマーが発生するまでの時間を求める
|
|
//
|
|
int32 Timer::GetNextEvent()
|
|
{
|
|
uint32 ta = ((timera_count + 0xffff) >> 16) - 1;
|
|
uint32 tb = ((timerb_count + 0xfff) >> 12) - 1;
|
|
return (ta < tb ? ta : tb) + 1;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
void Timer::DataSave(struct TimerData* data)
|
|
{
|
|
data->status = status;
|
|
data->regtc = regtc;
|
|
data->regta[0] = regta[0];
|
|
data->regta[1] = regta[1];
|
|
data->timera = timera;
|
|
data->timera_count = timera_count;
|
|
data->timerb = timerb;
|
|
data->timerb_count = timerb_count;
|
|
data->timer_step = timer_step;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
void Timer::DataLoad(struct TimerData* data)
|
|
{
|
|
status = data->status;
|
|
regtc = data->regtc;
|
|
regta[0] = data->regta[0];
|
|
regta[1] = data->regta[1];
|
|
timera = data->timera;
|
|
timera_count = data->timera_count;
|
|
timerb = data->timerb;
|
|
timerb_count = data->timerb_count;
|
|
timer_step = data->timer_step;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマー基準値設定
|
|
//
|
|
void Timer::SetTimerBase(uint clock)
|
|
{
|
|
timer_step = int32(1000000. * 65536 / clock);
|
|
}
|
|
|
|
#else
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマーA 周期設定
|
|
//
|
|
void Timer::SetTimerA(uint addr, uint data)
|
|
{
|
|
regta[addr & 1] = uint8(data);
|
|
timera = (1024 - ((regta[0] << 2) + (regta[1] & 3))) << 16;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマーB 周期設定
|
|
//
|
|
void Timer::SetTimerB(uint data)
|
|
{
|
|
timerb = (256-data) << (16 + 4);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマー時間処理
|
|
//
|
|
bool Timer::Count(int32 us)
|
|
{
|
|
bool event = false;
|
|
|
|
int tick = us * timer_step;
|
|
|
|
if (timera_count)
|
|
{
|
|
timera_count -= tick;
|
|
if (timera_count <= 0)
|
|
{
|
|
event = true;
|
|
TimerA();
|
|
|
|
while (timera_count <= 0)
|
|
timera_count += timera;
|
|
|
|
if (regtc & 4)
|
|
SetStatus(1);
|
|
}
|
|
}
|
|
if (timerb_count)
|
|
{
|
|
timerb_count -= tick;
|
|
if (timerb_count <= 0)
|
|
{
|
|
event = true;
|
|
while (timerb_count <= 0)
|
|
timerb_count += timerb;
|
|
|
|
if (regtc & 8)
|
|
SetStatus(2);
|
|
}
|
|
}
|
|
return event;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 次にタイマーが発生するまでの時間を求める
|
|
//
|
|
int32 Timer::GetNextEvent()
|
|
{
|
|
uint32 ta = timera_count - 1;
|
|
uint32 tb = timerb_count - 1;
|
|
uint32 t = (ta < tb ? ta : tb) + 1;
|
|
|
|
return (t+timer_step-1) / timer_step;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// タイマー基準値設定
|
|
//
|
|
void Timer::SetTimerBase(uint clock)
|
|
{
|
|
timer_step = clock * 1024 / 15625;
|
|
}
|
|
|
|
#endif
|