openMSX
YM2413OriginalNukeYKT.cc
Go to the documentation of this file.
2 #include "ranges.hh"
3 #include "serialize.hh"
4 #include "xrange.hh"
5 #include <cassert>
6 
7 namespace openmsx {
8 namespace YM2413OriginalNukeYKT {
9 
11 {
12  reset();
13 }
14 
16 {
18  ranges::fill(regs, 0);
19 }
20 
21 void YM2413::generateChannels(float* out_[9 + 5], uint32_t n)
22 {
23  float* out[9 + 5];
24  std::copy_n(out_, 9 + 5, out);
25 
26  auto f = [&] {
27  int32_t buf[2];
28  OPLL_Clock(&opll, buf);
29  switch (opll.cycles) {
30  case 0: *out[ 9]++ += buf[1] * 2; break;
31  case 1: *out[10]++ += buf[1] * 2; break;
32  case 2: *out[ 6]++ += buf[0];
33  *out[11]++ += buf[1] * 2; break;
34  case 3: *out[ 7]++ += buf[0];
35  *out[12]++ += buf[1] * 2; break;
36  case 4: *out[ 8]++ += buf[0];
37  *out[13]++ += buf[1] * 2; break;
38  case 8: *out[ 0]++ += buf[0]; break;
39  case 9: *out[ 1]++ += buf[0]; break;
40  case 10: *out[ 2]++ += buf[0]; break;
41  case 14: *out[ 3]++ += buf[0]; break;
42  case 15: *out[ 4]++ += buf[0]; break;
43  case 16: *out[ 5]++ += buf[0]; break;
44  }
45  };
46 
47  assert(n != 0);
48  for (auto& write : writes) {
49  if (write.port != uint8_t(-1)) {
50  OPLL_Write(&opll, write.port, write.value);
51  write.port = uint8_t(-1);
52  }
53  f();
54  }
55  repeat((n - 1) * 18, f);
56 
57  allowed_offset = std::max<int>(0, allowed_offset - 18); // see writePort()
58 }
59 
60 void YM2413::writePort(bool port, uint8_t value, int cycle_offset)
61 {
62  // see comments in YM2413NukeYKT.cc
63  while (unlikely(cycle_offset < allowed_offset)) {
64  float d = 0.0f;
65  float* dummy[9 + 5] = {
66  &d, &d, &d, &d, &d, &d, &d, &d, &d,
67  &d, &d, &d, &d, &d,
68  };
69  generateChannels(dummy, 1);
70  }
71  allowed_offset = ((port ? 84 : 12) / 4) + cycle_offset;
72 
73  writes[cycle_offset] = {port, value};
74 
75  // only needed for peekReg()
76  if (port == 0) {
77  latch = value & 63;
78  } else {
79  regs[latch] = value;
80  }
81 }
82 
83 void YM2413::pokeReg(uint8_t /*reg*/, uint8_t /*value*/)
84 {
85  // not supported
86 }
87 
88 uint8_t YM2413::peekReg(uint8_t reg) const
89 {
90  return regs[reg & 63];
91 }
92 
94 {
95  return 1.0f / 256.0f;
96 }
97 
98 template<typename Archive>
99 void YM2413::serialize(Archive& /*ar*/, unsigned /*version*/)
100 {
101  // Not implemented
102 }
103 
104 } // namespace OriginalNuke
105 
109 
110 } // namespace openmsx
Abstract interface for the YM2413 core.
Definition: YM2413Core.hh:27
void serialize(Archive &ar, unsigned version)
void writePort(bool port, uint8_t value, int cycle_offset) override
Write to the YM2413 register/data port.
void pokeReg(uint8_t reg, uint8_t value) override
Write to a YM2413 register (for debug).
float getAmplificationFactor() const override
Returns normalization factor.
void generateChannels(float *out[9+5], uint32_t n) override
uint8_t peekReg(uint8_t reg) const override
Read from a YM2413 register (for debug).
void reset() override
Reset this YM2413 core.
#define unlikely(x)
Definition: likely.hh:15
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:226
void OPLL_Reset(opll_t *chip, uint32_t chip_type)
Definition: opll.cc:293
void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data)
Definition: opll.cc:1101
void OPLL_Clock(opll_t *chip, int32_t *buffer)
Definition: opll.cc:1062
@ opll_type_ym2413b
Definition: opll.hh:31
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:998
uint32_t cycles
Definition: opll.hh:82
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.
Definition: xrange.hh:170