diff --git a/src/engine/fixedQueue.h b/src/engine/fixedQueue.h new file mode 100644 index 000000000..4b0d81290 --- /dev/null +++ b/src/engine/fixedQueue.h @@ -0,0 +1,81 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _FIXED_QUEUE_H +#define _FIXED_QUEUE_H + +#include +#include "../ta-log.h" + +template struct FixedQueue { + size_t readPos, writePos; + T data[items]; + + T& front(); + bool pop(); + bool push(const T& item); + void clear(); + bool empty(); + size_t size(); + FixedQueue(): + readPos(0), + writePos(0) {} +}; + +template T& FixedQueue::front() { + return data[readPos]; +} + +template bool FixedQueue::pop() { + if (readPos==writePos) return false; + if (++readPos>=items) readPos=0; + return true; +} + +template bool FixedQueue::push(const T& item) { + if (writePos==(readPos-1)) { + logW("queue overflow!"); + return false; + } + if (writePos==0 && readPos==items-1) { + logW("queue overflow!"); + return false; + } + data[writePos]=item; + if (++writePos>=items) writePos=0; + return true; +} + +template void FixedQueue::clear() { + readPos=0; + writePos=0; +} + +template bool FixedQueue::empty() { + return (readPos==writePos); +} + +template size_t FixedQueue::size() { + if (readPos>writePos) { + return items+writePos-readPos; + } + return writePos-readPos; +} + +#endif diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 47e5bbcdd..8066bff28 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -22,7 +22,7 @@ #include //#define rWrite(a,v) pendingWrites[a]=v; -#define rWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } +#define rWrite(a,v) if (!skipRegisterWrites) {writes.push(QueuedWrite(a,v)); if (dumpWrites) {addWrite(a,v);} } #define chWrite(c,a,v) \ if (!skipRegisterWrites) { \ if (curChan!=c) { \ diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 9b8c610c8..452791792 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -21,7 +21,7 @@ #define _PCE_H #include "../dispatch.h" -#include +#include "../fixedQueue.h" #include "../waveSynth.h" #include "sound/pce_psg.h" @@ -62,9 +62,10 @@ class DivPlatformPCE: public DivDispatch { struct QueuedWrite { unsigned char addr; unsigned char val; + QueuedWrite(): addr(0), val(9) {} QueuedWrite(unsigned char a, unsigned char v): addr(a), val(v) {} }; - std::queue writes; + FixedQueue writes; unsigned char lastPan; int cycles, curChan, delay;