fifo: fixed length off-by-one error in implementation

This commit is contained in:
Jakub Czekański 2020-12-23 11:22:14 +01:00
parent 5cb5b057c8
commit 7d83097357
4 changed files with 21 additions and 17 deletions

View file

@ -18,7 +18,7 @@ CDROM::CDROM(System* sys) : sys(sys) {
void CDROM::step() {
status.transmissionBusy = 0;
if (!interruptQueue.empty()) {
if (!interruptQueue.is_empty()) {
if ((interruptEnable & 7) & (interruptQueue.peek() & 7)) {
sys->interrupt->trigger(interrupt::CDROM);
}
@ -152,10 +152,10 @@ uint8_t CDROM::read(uint32_t address) {
}
if (address == 1) { // CD Response
uint8_t response = 0;
if (!CDROM_response.empty()) {
if (!CDROM_response.is_empty()) {
response = CDROM_response.get();
if (CDROM_response.empty()) {
if (CDROM_response.is_empty()) {
status.responseFifoEmpty = 0;
}
}
@ -174,7 +174,7 @@ uint8_t CDROM::read(uint32_t address) {
}
if (status.index == 1 || status.index == 3) { // Interrupt flags
uint8_t _status = 0b11100000;
if (!interruptQueue.empty()) {
if (!interruptQueue.is_empty()) {
_status |= interruptQueue.peek() & 7;
}
if (verbose == 2) fmt::print("CDROM: R INTF: 0x{:02x}\n", _status);
@ -336,7 +336,7 @@ void CDROM::write(uint32_t address, uint8_t data) {
status.parameterFifoFull = 1;
}
if (!interruptQueue.empty()) {
if (!interruptQueue.is_empty()) {
interruptQueue.get();
}
if (verbose == 2) fmt::print("CDROM: W INTF: 0x{:02x}\n", data);

View file

@ -155,7 +155,7 @@ class CDROM {
void handleCommand(uint8_t cmd);
void writeResponse(uint8_t byte) {
if (CDROM_response.full()) {
if (CDROM_response.is_full()) {
return;
}
CDROM_response.add(byte);
@ -165,7 +165,7 @@ class CDROM {
uint8_t readParam() {
uint8_t param = CDROM_params.get();
status.parameterFifoEmpty = CDROM_params.empty();
status.parameterFifoEmpty = CDROM_params.is_empty();
status.parameterFifoFull = 1;
return param;

View file

@ -27,7 +27,7 @@ void CDROM::cmdSetloc() {
void CDROM::cmdPlay() {
// Play NOT IMPLEMENTED
disc::Position pos;
if (!CDROM_params.empty()) {
if (!CDROM_params.is_empty()) {
int track = readParam(); // param or setloc used
if (track >= (int)disc->getTrackCount()) {
fmt::print("CDROM: Invalid PLAY track parameter ({})\n", track);

View file

@ -7,6 +7,7 @@ class fifo {
T data[length] = {};
size_t write_ptr = 0;
size_t read_ptr = 0;
bool full = false;
public:
size_t size() const {
@ -17,34 +18,38 @@ class fifo {
}
}
bool empty() const { return size() == 0; }
bool is_empty() const { return write_ptr == read_ptr && !full; }
bool full() const { return size() == length - 1; }
bool is_full() const { return full; }
void clear() {
write_ptr = 0;
read_ptr = 0;
full = false;
}
bool add(const T t) {
if (full()) {
if (is_full()) {
return false;
}
data[write_ptr] = t;
write_ptr = ++write_ptr % length;
write_ptr = (write_ptr + 1) % length;
full = write_ptr == read_ptr;
return true;
}
T get() {
if (empty()) {
if (is_empty()) {
return 0;
// TODO ?
}
T t = data[read_ptr];
read_ptr = ++read_ptr % length;
read_ptr = (read_ptr + 1) % length;
full = false;
return t;
}
@ -52,7 +57,6 @@ class fifo {
T peek(const size_t ptr = 0) const {
if (ptr >= size()) {
return 0;
// TODO ?
}
return data[(read_ptr + ptr) % length];
@ -62,6 +66,6 @@ class fifo {
template <class Archive>
void serialize(Archive& ar) {
ar(data);
ar(data, write_ptr, read_ptr, full);
}
};