From: <m97...@us...> - 2007-09-29 13:23:48
|
Revision: 7100 http://openmsx.svn.sourceforge.net/openmsx/?rev=7100&view=rev Author: m9710797 Date: 2007-09-29 06:23:48 -0700 (Sat, 29 Sep 2007) Log Message: ----------- updated Halnote mapper (based on implementation in blueMSX) Modified Paths: -------------- openmsx/branches/branch_0_6_3/ChangeLog openmsx/branches/branch_0_6_3/src/memory/RomHalnote.cc openmsx/branches/branch_0_6_3/src/memory/RomHalnote.hh Modified: openmsx/branches/branch_0_6_3/ChangeLog =================================================================== --- openmsx/branches/branch_0_6_3/ChangeLog 2007-09-29 12:06:38 UTC (rev 7099) +++ openmsx/branches/branch_0_6_3/ChangeLog 2007-09-29 13:23:48 UTC (rev 7100) @@ -1,5 +1,8 @@ $Id$ +2007-09-29 Wouter Vermaelen <wou...@sc...> + * Fixed Halnote mapper, based on info from blueMSX + 2007-09-19 Wouter Vermaelen <wou...@sc...> * Fixed bug in stereo blip resampler: in case only one of the two channels was active, we left the other Modified: openmsx/branches/branch_0_6_3/src/memory/RomHalnote.cc =================================================================== --- openmsx/branches/branch_0_6_3/src/memory/RomHalnote.cc 2007-09-29 12:06:38 UTC (rev 7099) +++ openmsx/branches/branch_0_6_3/src/memory/RomHalnote.cc 2007-09-29 13:23:48 UTC (rev 7100) @@ -1,20 +1,56 @@ // $Id$ +/* + * HALNOTE mapper + * + * This info is extracted from the romMapperHalnote.c source in blueMSX, + * implemented by white_cat. + * + * This is a 1024kB mapper, it's divided in 128 pages of 8kB. The last 512kB + * can also be mapped as 256 pages of 2kB. There is 16kB SRAM. + * + * Main bankswitch registers: + * bank 0, region: [0x4000-0x5FFF], switch addr: 0x4FFF + * bank 1, region: [0x6000-0x7FFF], switch addr: 0x6FFF + * bank 2, region: [0x8000-0x9FFF], switch addr: 0x8FFF + * bank 3, region: [0xA000-0xBFFF], switch addr: 0xAFFF + * Sub-bankswitch registers: + * bank 0, region: [0x7000-0x77FF], switch addr: 0x77FF + * bank 1, region: [0x7800-0x7FFF], switch addr: 0x7FFF + * Note that the two sub-banks overlap with main bank 1! + * + * The upper bit (0x80) of the first two main bankswitch registers are special: + * bank 0, bit7 SRAM enabled in [0x0000-0x3FFF] (1=enabled) + * bank 1, bit7 submapper enabled in [0x7000-0x7FFF] (1=enabled) + * If enabled, the submapper shadows (part of) main bank 1. + */ + #include "RomHalnote.hh" #include "CacheLine.hh" +#include "MSXCPU.hh" #include "Rom.hh" +#include "SRAM.hh" namespace openmsx { RomHalnote::RomHalnote(MSXMotherBoard& motherBoard, const XMLElement& config, const EmuTime& time, std::auto_ptr<Rom> rom) : Rom8kBBlocks(motherBoard, config, time, rom) + , sram(new SRAM(motherBoard, getName() + " SRAM", 0x4000, config)) { reset(time); } +RomHalnote::~RomHalnote() +{ +} + void RomHalnote::reset(const EmuTime& /*time*/) { + subBanks[0] = subBanks[1] = 0; + sramEnabled = false; + subMapperEnabled = false; + setBank(0, unmappedRead); setBank(1, unmappedRead); for (int i = 2; i < 6; i++) { @@ -24,23 +60,89 @@ setBank(7, unmappedRead); } +const byte* RomHalnote::getReadCacheLine(word address) const +{ + if (subMapperEnabled && (0x7000 <= address) && (address < 0x8000)) { + // sub-mapper + int subBank = address < 0x7800 ? 0 : 1; + return &(*rom)[0x80000 + subBanks[subBank] * 0x800 + (address & 0x7FF)]; + } else { + // default mapper implementation + return Rom8kBBlocks::getReadCacheLine(address); + } +} +byte RomHalnote::readMem(word address, const EmuTime& /*time*/) +{ + // all reads are cacheable, reuse that implementation + return *getReadCacheLine(address); +} + void RomHalnote::writeMem(word address, byte value, const EmuTime& /*time*/) { - if ((0x4000 <= address) && (address < 0xC000)) { - if ((address & 0x1FFF) == 0x0FFF) { - setRom(address >> 13, value); + if (address < 0x4000) { + // SRAM region + if (sramEnabled) { + sram->write(address, value); } + } else if (address < 0xC000) { + if ((address == 0x77FF) || (address == 0x7FFF)) { + // sub-mapper bank switch region + int subBank = address < 0x7800 ? 0 : 1; + if (subBanks[subBank] != value) { + subBanks[subBank] = value; + if (subMapperEnabled) { + cpu.invalidateMemCache( + 0x7000 + subBank * 0x800, 0x800); + } + } + } else if ((address & 0x1FFF) == 0x0FFF) { + // normal bank switch region + int bank = address >> 13; // 2-5 + setRom(bank, value); + if (bank == 2) { + // sram enable/disable + bool newSramEnabled = value & 0x80; + if (newSramEnabled != sramEnabled) { + sramEnabled = newSramEnabled; + if (sramEnabled) { + setBank(0, &(*sram)[0x0000]); + setBank(1, &(*sram)[0x2000]); + } else { + setBank(0, unmappedRead); + setBank(1, unmappedRead); + } + } + } else if (bank == 3) { + // sub-mapper enable/disable + bool newSubMapperEnabled = value & 0x80; + if (newSubMapperEnabled != subMapperEnabled) { + subMapperEnabled = newSubMapperEnabled; + cpu.invalidateMemCache(0x7000, 0x1000); + } + } + } } } byte* RomHalnote::getWriteCacheLine(word address) const { - if ((0x4000 <= address) && (address < 0xC000) && - ((address & 0x1FFF) == (0x0FFF & CacheLine::HIGH))) { - return NULL; - } else { - return unmappedWrite; + if (address < 0x4000) { + // SRAM region + if (sramEnabled) { + return NULL; + } + } else if (address < 0xC000) { + if (((address & CacheLine::HIGH) == (0x77FF & CacheLine::HIGH)) || + ((address & CacheLine::HIGH) == (0x7FFF & CacheLine::HIGH))) { + // sub-mapper bank switch region + return NULL; + } else if ((address & 0x1FFF & CacheLine::HIGH) == + (0x0FFF & CacheLine::HIGH)) { + // normal bank switch region + return NULL; + } } + return unmappedWrite; } } // namespace openmsx Modified: openmsx/branches/branch_0_6_3/src/memory/RomHalnote.hh =================================================================== --- openmsx/branches/branch_0_6_3/src/memory/RomHalnote.hh 2007-09-29 12:06:38 UTC (rev 7099) +++ openmsx/branches/branch_0_6_3/src/memory/RomHalnote.hh 2007-09-29 13:23:48 UTC (rev 7100) @@ -7,15 +7,26 @@ namespace openmsx { +class SRAM; + class RomHalnote : public Rom8kBBlocks { public: RomHalnote(MSXMotherBoard& motherBoard, const XMLElement& config, const EmuTime& time, std::auto_ptr<Rom> rom); + virtual ~RomHalnote(); virtual void reset(const EmuTime& time); + virtual byte readMem(word address, const EmuTime& time); + virtual const byte* getReadCacheLine(word address) const; virtual void writeMem(word address, byte value, const EmuTime& time); virtual byte* getWriteCacheLine(word address) const; + +private: + const std::auto_ptr<SRAM> sram; + byte subBanks[2]; + bool sramEnabled; + bool subMapperEnabled; }; } // namespace openmsx This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |