/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher * Copyright (C) 2011-2016 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef MT32EMU_MEMORY_REGION_H #define MT32EMU_MEMORY_REGION_H #include #include "globals.h" #include "Types.h" #include "Structures.h" namespace MT32Emu { enum MemoryRegionType { MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset }; class Synth; class MemoryRegion { private: Synth *synth; Bit8u *realMemory; Bit8u *maxTable; public: MemoryRegionType type; Bit32u startAddr, entrySize, entries; MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) { synth = useSynth; realMemory = useRealMemory; maxTable = useMaxTable; type = useType; startAddr = useStartAddr; entrySize = useEntrySize; entries = useEntries; } int lastTouched(Bit32u addr, Bit32u len) const { return (offset(addr) + len - 1) / entrySize; } int firstTouchedOffset(Bit32u addr) const { return offset(addr) % entrySize; } int firstTouched(Bit32u addr) const { return offset(addr) / entrySize; } Bit32u regionEnd() const { return startAddr + entrySize * entries; } bool contains(Bit32u addr) const { return addr >= startAddr && addr < regionEnd(); } int offset(Bit32u addr) const { return addr - startAddr; } Bit32u getClampedLen(Bit32u addr, Bit32u len) const { if (addr + len > regionEnd()) return regionEnd() - addr; return len; } Bit32u next(Bit32u addr, Bit32u len) const { if (addr + len > regionEnd()) { return regionEnd() - addr; } return 0; } Bit8u getMaxValue(int off) const { if (maxTable == NULL) return 0xFF; return maxTable[off % entrySize]; } Bit8u *getRealMemory() const { return realMemory; } bool isReadable() const { return getRealMemory() != NULL; } void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const; void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const; }; // class MemoryRegion class PatchTempMemoryRegion : public MemoryRegion { public: PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {} }; class RhythmTempMemoryRegion : public MemoryRegion { public: RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {} }; class TimbreTempMemoryRegion : public MemoryRegion { public: TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {} }; class PatchesMemoryRegion : public MemoryRegion { public: PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {} }; class TimbresMemoryRegion : public MemoryRegion { public: TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {} }; class SystemMemoryRegion : public MemoryRegion { public: SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {} }; class DisplayMemoryRegion : public MemoryRegion { public: DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), SYSEX_BUFFER_SIZE - 1, 1) {} }; class ResetMemoryRegion : public MemoryRegion { public: ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {} }; } // namespace MT32Emu #endif // #ifndef MT32EMU_MEMORY_REGION_H