Top secrets sources NedoPC pentevo

Rev

Rev 783 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

#ifndef VS1001_H
#define VS1001_H
#include "util.h"

#undef SD_SEND

// S_CTRL bits
const u8 _MPNCS  = 2;
const u8 _MPXRS  = 4;
const u8 _MPHLF  = 8;

// S_STAT bits
const u8 _MPDRQ  = 1;

const u8 S_CTRL  = 0x11; // RW
const u8 S_STAT  = 0x12; // R

const u8 SD_SEND = 0x13; // W
const u8 SD_READ = 0x13; // R
const u8 SD_RSTR = 0x14; // R

const u8 MD_SEND = 0x14; // W same as SD_RSTR!!!

const u8 MC_SEND = 0x15; // W
const u8 MC_READ = 0x15; // R

class TRingBuffer
{
    TCriticalSection CritSect;
    TEvent NotEmpty;
    const u32 Size;
    u8 Buf[4*1024];
    u32 WrPos;
    u32 RdPos;
    u32 Count;
    bool Dreq;
    bool Cancelled;
public:
    TRingBuffer() : NotEmpty(FALSE), Size(4*1024)
    {
        Cancelled = false;
        Reset();
    }
    void Cancel()
    {
        CritSect.Lock();
        Cancelled = true;
        NotEmpty.Set();
        CritSect.Unlock();
    }
    void Reset();
    void Put(u8 Val);
    u32 Get(void *Data, u32 ReqLen);
    bool GetDreq() const { return Dreq; }
};

class TVs1001
{
    enum TRegs
    {
       MODE = 0,   // RW
       STATUS,     // RW
       INT_FCTLH,  // NA
       CLOCKF,     // RW
       DECODE_TIME,// R
       AUDATA,     // R
       WRAM_W,     // W
       WRAMADDR_W, // W
       HDAT0,      // R
       HDAT1,      // R
       AIADDR,     // RW
       VOL,        // RW
       RESERVED,   // NA
       AICTRL0,    // RW
       AICTRL1,    // RW
       REG_COUNT
    };

    static const u8 SM_RESET = 4;

    enum TState { ST_IDLE, ST_RD, ST_WR, ST_RD_IDX, ST_WR_IDX, ST_RD_MSB, ST_RD_LSB, ST_WR_MSB, ST_WR_LSB };
    enum TCmd { CMD_WR = 2, CMD_RD = 3 };
    u16 Regs[REG_COUNT];
    TState CurState;
    bool nCs;
    int Idx;
    u8 Msb, Lsb;
    TRingBuffer RingBuffer;
    TEvent EventStreamClose;
    HANDLE ThreadHandle;
    HSTREAM Mp3Stream;
    static BASS_FILEPROCS Procs;
public:
    TVs1001();
    void Reset();
    void ShutDown();
    void SetNcs(bool nCs);
    void Wr(u8 Val); // sdi mpeg data write
    void WrCmd(u8 Val); // sci write
    u8 Rd(); // sci read
    void Play(); // play buffered data
    bool GetDreq() const { return RingBuffer.GetDreq(); }
private:
    void Wr(int Idx, u16 Val); // sci write
    u16 Rd(int Idx); // sci read

    void SoftReset();
    void SetVol(u16 Vol);
    u16 GetDecodeTime();

    void Thread();
    void StreamClose();
    QWORD StreamLen();
    DWORD StreamRead(void *Buffer, DWORD Length);
    BOOL StreamSeek(QWORD offset);

    static unsigned CALLBACK Thread(void *This)
    {
        ((TVs1001 *)This)->Thread();
        return 0;
    }

    static void CALLBACK StreamClose(void *This)
    { ((TVs1001 *)This)->StreamClose(); }

    static QWORD CALLBACK StreamLen(void *This)
    { return ((TVs1001 *)This)->StreamLen(); }

    static DWORD CALLBACK StreamRead(void *Buffer, DWORD Length, void *This)
    { return ((TVs1001 *)This)->StreamRead(Buffer, Length); }

    static BOOL CALLBACK StreamSeek(QWORD offset, void *This)
    { return ((TVs1001 *)This)->StreamSeek(offset); }

    static const char *State2Str(TState State);
};

extern TVs1001 Vs1001;
#endif