|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // ADPCM (MSM6258V)
9: //
10:
11: #pragma once
12:
13: #include "device.h"
14:
1.1.1.2 root 15: class DMACDevice;
1.1.1.6 root 16: class SoundRenderer;
17: class SoundTrack;
1.1.1.2 root 18:
1.1 root 19: class ADPCMDevice : public IODevice
20: {
21: using inherited = IODevice;
22:
1.1.1.4 root 23: static const uint32 baseaddr = 0xe92000;
1.1 root 24:
25: static const uint8 STAT_PLAY = 0x80;
26:
27: static const uint8 REC_START = 0x04;
28: static const uint8 PLAY_START = 0x02;
29: static const uint8 STOP = 0x01;
30:
31: public:
32: ADPCMDevice();
1.1.1.3 root 33: ~ADPCMDevice() override;
1.1 root 34:
1.1.1.2 root 35: bool Init() override;
1.1 root 36: void ResetHard(bool poweron) override;
37:
38: // CT1 によるクロック切り替え。OPM から呼ばれる。
39: void SetClock(bool);
40:
41: // DMAC から呼ばれる。
1.1.1.6 root 42: void AssertDACK();
43:
44: // PPI
45: bool GetPanOutL() const { return panout_L; }
46: bool GetPanOutR() const { return panout_R; }
47: void SetPanOutL(bool on);
48: void SetPanOutR(bool on);
49: void SetRate(uint32 idx);
1.1 root 50:
51: protected:
52: // BusIO インタフェース
53: static const uint32 NPORT = 2;
1.1.1.4 root 54: busdata ReadPort(uint32 offset);
55: busdata WritePort(uint32 offset, uint32 data);
56: busdata PeekPort(uint32 offset);
57: bool PokePort(uint32 offset, uint32 data);
1.1 root 58:
59: private:
1.1.1.7 ! root 60: DECLARE_MONITOR_SCREEN(MonitorScreen);
1.1.1.6 root 61:
62: uint32 GetSTAT() const;
1.1 root 63: void StartPlay();
1.1.1.6 root 64: void StopPlay();
65: void WriteData(uint32 data);
66: void CalcRate();
1.1 root 67:
1.1.1.5 root 68: void EventCallback(Event *);
1.1 root 69:
1.1.1.6 root 70: void DecodeADPCM(uint32 data);
71: void WritePCM(uint64 vtime, int16 target);
72:
73: uint32 pcm2adpcm_step(int16 pcm);
74: int16 adpcm2pcm_step(uint32 data);
75: inline uint32 adpcm_encode(int32 dn);
76: inline int32 adpcm_decode(uint32 data, int32 xn);
77: inline void adpcm_calcstep(uint32 data);
78:
1.1 root 79: bool playing {};
1.1.1.6 root 80: int clkMHz {}; // 入力クロック[MHz] (4 or 8)
81: int div {}; // 512, 768, 1024
82:
83: bool panout_L {};
84: bool panout_R {};
85:
1.1.1.7 ! root 86: // 選択周波数での 1フレームにかかる時間 [tsec]
! 87: uint64 guest_frame_tsec {};
1.1.1.6 root 88:
89: // 周波数
90: uint32 freq {};
91:
92: // データバッファ(1バイト)
93: uint8 databuf {};
94:
95: // ADPCM<->PCM 変換
96: int32 xprev {};
97: int stepidx {};
98:
99: // 最後に書き込んだサンプル値 (線形補間用)
100: int16 pcm0 {};
101:
1.1.1.7 ! root 102: // ミキサー周波数での1フレームにかかる時間 [tsec]
! 103: uint64 mixer_frame_tsec {};
1.1.1.6 root 104:
105: // ミキサー周波数にアップスキャンするための倍率。
106: // 15625 Hz なら 4(倍)。
107: uint scale_factor {};
1.1 root 108:
1.1.1.2 root 109: DMACDevice *dmac {};
1.1.1.6 root 110: SoundRenderer *sound {};
111: SoundTrack *track {};
1.1.1.2 root 112:
1.1.1.5 root 113: Event *event {};
1.1.1.6 root 114: Monitor *monitor {};
115:
116: static const int adpcm_stepadj[16];
117: static const int32 adpcm_stepsize[49];
1.1 root 118: };
119:
1.1.1.7 ! root 120: inline ADPCMDevice *GetADPCMDevice() {
1.1.1.2 root 121: return Object::GetObject<ADPCMDevice>(OBJ_ADPCM);
122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.