156 lines
2.4 KiB
C++
156 lines
2.4 KiB
C++
#ifndef __MDFN_SIMPLEFIFO_H
|
|
#define __MDFN_SIMPLEFIFO_H
|
|
|
|
#include <vector>
|
|
#include <assert.h>
|
|
|
|
#include "../math_ops.h"
|
|
|
|
template<typename T>
|
|
class SimpleFIFO
|
|
{
|
|
public:
|
|
|
|
// Constructor
|
|
SimpleFIFO(uint32 the_size) // Size should be a power of 2!
|
|
{
|
|
data.resize((unsigned long)round_up_pow2(the_size));
|
|
size = the_size;
|
|
read_pos = 0;
|
|
write_pos = 0;
|
|
in_count = 0;
|
|
}
|
|
|
|
// Destructor
|
|
INLINE ~SimpleFIFO()
|
|
{
|
|
|
|
}
|
|
|
|
INLINE void SaveStatePostLoad(void)
|
|
{
|
|
//I think this is crap about file format (buffer size) change recovery. screw it.
|
|
//read_pos %= data.size();
|
|
//write_pos %= data.size();
|
|
//in_count %= (data.size() + 1);
|
|
}
|
|
|
|
#if 0
|
|
INLINE int StateAction(StateMem *sm, int load, int data_only, const char* sname)
|
|
{
|
|
SFORMAT StateRegs[] =
|
|
{
|
|
std::vector<T> data;
|
|
uint32 size;
|
|
|
|
SFVAR(read_pos),
|
|
SFVAR(write_pos),
|
|
SFVAR(in_count),
|
|
SFEND;
|
|
}
|
|
int ret = MDFNSS_StateAction(sm, load, data_only, sname);
|
|
|
|
if(load)
|
|
{
|
|
read_pos %= data.size();
|
|
write_pos %= data.size();
|
|
in_count %= (data.size() + 1);
|
|
}
|
|
|
|
return(ret);
|
|
}
|
|
#endif
|
|
|
|
INLINE uint32 CanRead(void)
|
|
{
|
|
return(in_count);
|
|
}
|
|
|
|
INLINE uint32 CanWrite(void)
|
|
{
|
|
return(size - in_count);
|
|
}
|
|
|
|
INLINE T ReadUnit(bool peek = false)
|
|
{
|
|
T ret;
|
|
|
|
assert(in_count > 0);
|
|
|
|
ret = data[read_pos];
|
|
|
|
if(!peek)
|
|
{
|
|
read_pos = (read_pos + 1) & (data.size() - 1);
|
|
in_count--;
|
|
}
|
|
|
|
return(ret);
|
|
}
|
|
|
|
INLINE uint8 ReadByte(bool peek = false)
|
|
{
|
|
assert(sizeof(T) == 1);
|
|
|
|
return(ReadUnit(peek));
|
|
}
|
|
|
|
INLINE void Write(const T *happy_data, uint32 happy_count)
|
|
{
|
|
assert(CanWrite() >= happy_count);
|
|
|
|
while(happy_count)
|
|
{
|
|
data[write_pos] = *happy_data;
|
|
|
|
write_pos = (write_pos + 1) & (data.size() - 1);
|
|
in_count++;
|
|
happy_data++;
|
|
happy_count--;
|
|
}
|
|
}
|
|
|
|
INLINE void WriteUnit(const T& wr_data)
|
|
{
|
|
Write(&wr_data, 1);
|
|
}
|
|
|
|
INLINE void WriteByte(const T& wr_data)
|
|
{
|
|
assert(sizeof(T) == 1);
|
|
Write(&wr_data, 1);
|
|
}
|
|
|
|
|
|
INLINE void Flush(void)
|
|
{
|
|
read_pos = 0;
|
|
write_pos = 0;
|
|
in_count = 0;
|
|
}
|
|
|
|
//private:
|
|
std::vector<T> data;
|
|
uint32 size;
|
|
uint32 read_pos; // Read position
|
|
uint32 write_pos; // Write position
|
|
uint32 in_count; // Number of units in the FIFO
|
|
|
|
template<bool isReader> void SyncState(EW::NewState *ns)
|
|
{
|
|
//I dont like this class...
|
|
|
|
PSS(&data[0], data.capacity()*sizeof(T));
|
|
NSS(read_pos);
|
|
NSS(write_pos);
|
|
NSS(in_count);
|
|
|
|
|
|
SaveStatePostLoad();
|
|
}
|
|
|
|
};
|
|
|
|
|
|
#endif
|