OPM.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.util.*;
16:
17: public class OPM {
18:
19: public static final boolean OPM_ON = true;
20:
21: public static final int OPM_OSC_FREQ = 4000000;
22: public static final int OPM_SAMPLE_FREQ = OPM_OSC_FREQ / 64;
23: public static final long OPM_SAMPLE_TIME = XEiJ.TMR_FREQ / OPM_SAMPLE_FREQ;
24: public static final int OPM_BLOCK_SAMPLES = OPM_SAMPLE_FREQ / SoundSource.SND_BLOCK_FREQ;
25:
26: public static int opmOutputMask;
27:
28:
29: public static YM2151 opmYM2151;
30: public static TickerQueue.Ticker opmTimerATicker;
31: public static TickerQueue.Ticker opmTimerBTicker;
32: public static int[] opmRegister;
33: public static int[] opmBuffer;
34: public static int opmPointer;
35: public static long opmBusyClock;
36:
37:
38:
39: public static void opmInit () {
40:
41: opmYM2151 = new YM2151 ();
42: opmTimerATicker = new TickerQueue.Ticker () {
43: @Override protected void tick () {
44: opmYM2151.timerAExpired ();
45: }
46: };
47: opmTimerBTicker = new TickerQueue.Ticker () {
48: @Override protected void tick () {
49: opmYM2151.timerBExpired ();
50: }
51: };
52: opmRegister = new int[266];
53: opmYM2151.setListener (new YM2151.Listener () {
54: @Override public void timerA (int clocks) {
55: if (clocks != -1) {
56: TickerQueue.tkqAdd (opmTimerATicker, XEiJ.mpuClockTime + (XEiJ.TMR_FREQ / (long) OPM_OSC_FREQ) * (long) clocks);
57: } else {
58: TickerQueue.tkqRemove (opmTimerATicker);
59: }
60: }
61: @Override public void timerB (int clocks) {
62: if (clocks != -1) {
63: TickerQueue.tkqAdd (opmTimerBTicker, XEiJ.mpuClockTime + (XEiJ.TMR_FREQ / (long) OPM_OSC_FREQ) * (long) clocks);
64: } else {
65: TickerQueue.tkqRemove (opmTimerBTicker);
66: }
67: }
68: @Override public void busy (int clocks) {
69: opmBusyClock = XEiJ.mpuClockTime + (XEiJ.TMR_FREQ / (long) OPM_OSC_FREQ) * (long) clocks;
70: }
71: @Override public boolean isBusy () {
72: return XEiJ.mpuClockTime < opmBusyClock;
73: }
74: @Override public void irq (boolean asserted) {
75: if (asserted) {
76: MC68901.mfpOpmirqFall ();
77: } else {
78: MC68901.mfpOpmirqRise ();
79: }
80: }
81: @Override public void control (int data) {
82: FDC.fdcSetEnforcedReady ((data & 1) != 0);
83: ADPCM.pcmOscillator = (data >> 1) & 1;
84: ADPCM.pcmUpdateRepeatInterval ();
85: }
86: @Override public void written (int pointer, int address, int data) {
87: if (address == 0x08) {
88: opmRegister[256 + (data & 7)] = (data >> 3) & 15;
89: } else if (address == 0x19) {
90: opmRegister[264 + (data >> 7)] = data & 127;
91: } else {
92: opmRegister[address] = data;
93: }
94: if (OPMLog.OLG_ON) {
95: OPMLog.olgSetData (address, data);
96: }
97: }
98: });
99: opmYM2151.allocate (SoundSource.SND_CHANNELS * (OPM_BLOCK_SAMPLES + 1));
100: opmReset ();
101: }
102:
103:
104:
105: public static void opmReset () {
106: opmYM2151.reset ();
107: opmYM2151.clear ();
108: opmBuffer = opmYM2151.getBuffer ();
109: opmPointer = opmYM2151.getPointer ();
110: opmBusyClock = 0L;
111: }
112:
113:
114:
115: public static void opmSetOutputOn (boolean on) {
116: opmOutputMask = on ? -1 : 0;
117: opmYM2151.setChannelMask (opmOutputMask & 0xff);
118: }
119:
120: }