|
|
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.6 ! root 60: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
! 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:
! 86: // 選択周波数での 1フレームにかかる時間 [nsec]
! 87: uint64 guest_frame_nsec {};
! 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:
! 102: // ミキサー周波数での1フレームにかかる時間 [nsec]
! 103: uint64 mixer_frame_nsec {};
! 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.2 root 120: static inline ADPCMDevice *GetADPCMDevice() {
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.