bsnes/higan/sfc/coprocessor/sdd1/sdd1.cpp

144 lines
3.9 KiB
C++
Raw Normal View History

#include <sfc/sfc.hpp>
namespace SuperFamicom {
SDD1 sdd1;
#include "decompressor.cpp"
#include "serialization.cpp"
auto SDD1::unload() -> void {
rom.reset();
ram.reset();
Update to v075 release. byuu says: This release brings improved Super Game Boy emulation, the final SHA256 hashes for the DSP-(1,1B,2,3,4) and ST-(0010,0011) coprocessors, user interface improvements, and major internal code restructuring. Changelog (since v074): - completely rewrote memory sub-system to support 1-byte granularity in XML mapping - removed Memory inheritance and MMIO class completely, any address can be mapped to any function now - SuperFX: removed SuperFXBus : Bus, now implemented manually - SA-1: removed SA1Bus : Bus, now implemented manually - entire bus mapping is now static, happens once on cartridge load - as a result, read/write handlers now handle MMC mapping; slower average case, far faster worst case - namespace memory is no more, RAM arrays are stored inside the chips they are owned by now - GameBoy: improved CPU HALT emulation, fixes Zelda: Link's Awakening scrolling - GameBoy: added serial emulation (cannot connect to another GB yet), fixes Shin Megami Tensei - Devichil - GameBoy: improved LCD STAT emulation, fixes Sagaia - ui: added fullscreen support (F11 key), video settings allows for three scale settings - ui: fixed brightness, contrast, gamma, audio volume, input frequency values on program startup - ui: since Qt is dead, config file becomes bsnes.cfg once again - Super Game Boy: you can now load the BIOS without a game inserted to see a pretty white box - ui-gameboy: can be built without SNES components now - libsnes: now a UI target, compile with 'make ui=ui-libsnes' - libsnes: added WRAM, APURAM, VRAM, OAM, CGRAM access (cheat search, etc) - source: removed launcher/, as the Qt port is now gone - source: Makefile restructuring to better support new ui targets - source: lots of other internal code cleanup work
2011-01-27 08:52:34 +00:00
}
auto SDD1::power() -> void {
Update to v098r03 release. byuu says: It took several hours, but I've rebuilt much of the SNES' bus memory mapping architecture. The new design unifies the cartridge string-based mapping ("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function now has an accompanying unmap() function, and instead of a fixed 256 callbacks, it'll scan to find the first available slot. unmap() will free slots up when zero addresses reference a given slot. The controllers and expansion port are now both entirely dynamic. Instead of load/unload/power/reset, they only have the constructor (power/reset/load) and destructor (unload). What this means is you can now dynamically change even expansion port devices after the system is loaded. Note that this is incredibly dangerous and stupid, but ... oh well. The whole point of this was for 21fx. There's no way to change the expansion port device prior to loading a game, but if the 21fx isn't active, then the reset vector hijack won't work. Now you can load a 21fx game, change the expansion port device, and simply reset the system to active the device. The unification of design between controller port devices and expansion port devices is nice, and overall this results in a reduction of code (all of the Mapping stuff in Cartridge is gone, replaced with direct bus mapping.) And there's always the potential to expand this system more in the future now. The big missing feature right now is the ability to push/pop mappings. So if you look at how the 21fx does the reset vector, you might vomit a little bit. But ... it works. Also changed exit(0) to _exit(0) in the POSIX version of nall::execute. [The _exit(0) thing is an attempt to make higan not crash when it tries to launch icarus and it's not on $PATH. The theory is that higan forks, then the child tries to exec icarus and fails, so it exits, all the unique_ptrs clean up their resources and tell the X server to free things the parent process is still using. Calling _exit() prevents destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
//hook S-CPU DMA MMIO registers to gather information for struct dma[];
//buffer address and transfer size information for use in SDD1::mcu_read()
bus.map({&SDD1::dmaRead, &sdd1}, {&SDD1::dmaWrite, &sdd1}, "00-3f,80-bf:4300-437f");
Update to v098r03 release. byuu says: It took several hours, but I've rebuilt much of the SNES' bus memory mapping architecture. The new design unifies the cartridge string-based mapping ("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function now has an accompanying unmap() function, and instead of a fixed 256 callbacks, it'll scan to find the first available slot. unmap() will free slots up when zero addresses reference a given slot. The controllers and expansion port are now both entirely dynamic. Instead of load/unload/power/reset, they only have the constructor (power/reset/load) and destructor (unload). What this means is you can now dynamically change even expansion port devices after the system is loaded. Note that this is incredibly dangerous and stupid, but ... oh well. The whole point of this was for 21fx. There's no way to change the expansion port device prior to loading a game, but if the 21fx isn't active, then the reset vector hijack won't work. Now you can load a 21fx game, change the expansion port device, and simply reset the system to active the device. The unification of design between controller port devices and expansion port devices is nice, and overall this results in a reduction of code (all of the Mapping stuff in Cartridge is gone, replaced with direct bus mapping.) And there's always the potential to expand this system more in the future now. The big missing feature right now is the ability to push/pop mappings. So if you look at how the 21fx does the reset vector, you might vomit a little bit. But ... it works. Also changed exit(0) to _exit(0) in the POSIX version of nall::execute. [The _exit(0) thing is an attempt to make higan not crash when it tries to launch icarus and it's not on $PATH. The theory is that higan forks, then the child tries to exec icarus and fails, so it exits, all the unique_ptrs clean up their resources and tell the X server to free things the parent process is still using. Calling _exit() prevents destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
r4800 = 0x00;
r4801 = 0x00;
r4804 = 0x00;
r4805 = 0x01;
r4806 = 0x02;
r4807 = 0x03;
for(auto n : range(8)) {
dma[n].addr = 0;
dma[n].size = 0;
}
dmaReady = false;
}
auto SDD1::read(uint24 addr, uint8 data) -> uint8 {
addr = 0x4800 | addr.bits(0,3);
switch(addr) {
case 0x4800: return r4800;
case 0x4801: return r4801;
case 0x4804: return r4804;
case 0x4805: return r4805;
case 0x4806: return r4806;
case 0x4807: return r4807;
}
//00-3f,80-bf:4802-4803,4808-480f falls through to ROM
return rom.read(addr);
}
auto SDD1::write(uint24 addr, uint8 data) -> void {
addr = 0x4800 | addr.bits(0,3);
switch(addr) {
case 0x4800: r4800 = data; break;
case 0x4801: r4801 = data; break;
case 0x4804: r4804 = data & 0x8f; break;
case 0x4805: r4805 = data & 0x8f; break;
case 0x4806: r4806 = data & 0x8f; break;
case 0x4807: r4807 = data & 0x8f; break;
}
}
auto SDD1::dmaRead(uint24 addr, uint8 data) -> uint8 {
return cpu.readDMA(addr, data);
Update to higan and icarus v095r15 release. r13 and r14 weren't posted as individual releases, but their changelogs were posted. byuu says about r13: I'm not going to be posting WIPs for r13 and above for a while. The reason is that I'm working on the major manifest overhaul I've discussed previously on the icarus subforum. I'm recreating my boards database from scratch using the map files and the new map analyzer. The only games that will load are ones I've created board definitions for, and updated sfc/cartridge/markup.cpp to parse. Once I've finished all the boards, then I'll update the heuristics. Then finally, I'll sync the syntax changes over to the fc, gb, gba cores. Once that's done, I'll start posting WIPs again, along with a new build of icarus. But I'll still post changelogs as I work through things. Changelog (r13): - preservation: created new database-builder tool (merges region-specific databases with boards) - icarus: support new, external database format (~/.config/icarus/Database/(Super Famicom.bml, ...) - added 1A3B-(10,11,12); 1A3B-20 byuu says about r14: r14 work: I successfully created mappings for every board used in the US set. I also updated icarus' heuristics to use the new mappings, and created ones there for the boards that are only in the JP set. Then I patched icarus to support pulling games out of the database when it's used on a game folder to generate a manifest file. Then I updated a lot of code in higan/sfc to support the new mapping syntax. sfc/cartridge/markup.cpp is about half the size it used to be with the new mappings, and I was able to kill off both map/id and map/select entirely. Then I updated all four emulated systems (and both subsystems) to use "board" as the root node, and harmonized their syntax (made them all more consistent with each other.) Then I added a manifest viewer to the tools window+menu. It's kind of an advanced user feature, but oh well. No reason to coddle people when the feature is very useful for developers. The viewer will show all manifests in order when you load multi-cart games as well. Still not going to call any syntax 100% done right now, but thankfully with the new manifest-free folders, nobody will have to do anything to use the new format. Just download the new version and go. The Super Famicom Event stuff is currently broken (CC92/PF94 boards). That's gonna be fun to support. byuu says about r15: EDIT: small bug in icarus with heuristics. Edit core/super-famicom.cpp line 27: if(/*auto*/ markup = cartridge.markup) { Gotta remove that "auto" so that it returns valid markup. Resolved the final concerns I had with the new manifest format. Right now there are two things that are definitely broken: MCC (BS-X Town cart) and Event (CC '92 and PF'94). And there are a few things that are untested: SPC7110, EpsonRTC, SharpRTC, SDD1+RAM, SufamiTurbo, BS-X slotted carts.
2015-12-19 08:52:34 +00:00
}
auto SDD1::dmaWrite(uint24 addr, uint8 data) -> void {
uint channel = addr.bits(4,6);
switch(addr.bits(0,3)) {
case 2: dma[channel].addr.byte(0) = data; break;
case 3: dma[channel].addr.byte(1) = data; break;
case 4: dma[channel].addr.byte(2) = data; break;
case 5: dma[channel].size.byte(0) = data; break;
case 6: dma[channel].size.byte(1) = data; break;
Update to higan and icarus v095r15 release. r13 and r14 weren't posted as individual releases, but their changelogs were posted. byuu says about r13: I'm not going to be posting WIPs for r13 and above for a while. The reason is that I'm working on the major manifest overhaul I've discussed previously on the icarus subforum. I'm recreating my boards database from scratch using the map files and the new map analyzer. The only games that will load are ones I've created board definitions for, and updated sfc/cartridge/markup.cpp to parse. Once I've finished all the boards, then I'll update the heuristics. Then finally, I'll sync the syntax changes over to the fc, gb, gba cores. Once that's done, I'll start posting WIPs again, along with a new build of icarus. But I'll still post changelogs as I work through things. Changelog (r13): - preservation: created new database-builder tool (merges region-specific databases with boards) - icarus: support new, external database format (~/.config/icarus/Database/(Super Famicom.bml, ...) - added 1A3B-(10,11,12); 1A3B-20 byuu says about r14: r14 work: I successfully created mappings for every board used in the US set. I also updated icarus' heuristics to use the new mappings, and created ones there for the boards that are only in the JP set. Then I patched icarus to support pulling games out of the database when it's used on a game folder to generate a manifest file. Then I updated a lot of code in higan/sfc to support the new mapping syntax. sfc/cartridge/markup.cpp is about half the size it used to be with the new mappings, and I was able to kill off both map/id and map/select entirely. Then I updated all four emulated systems (and both subsystems) to use "board" as the root node, and harmonized their syntax (made them all more consistent with each other.) Then I added a manifest viewer to the tools window+menu. It's kind of an advanced user feature, but oh well. No reason to coddle people when the feature is very useful for developers. The viewer will show all manifests in order when you load multi-cart games as well. Still not going to call any syntax 100% done right now, but thankfully with the new manifest-free folders, nobody will have to do anything to use the new format. Just download the new version and go. The Super Famicom Event stuff is currently broken (CC92/PF94 boards). That's gonna be fun to support. byuu says about r15: EDIT: small bug in icarus with heuristics. Edit core/super-famicom.cpp line 27: if(/*auto*/ markup = cartridge.markup) { Gotta remove that "auto" so that it returns valid markup. Resolved the final concerns I had with the new manifest format. Right now there are two things that are definitely broken: MCC (BS-X Town cart) and Event (CC '92 and PF'94). And there are a few things that are untested: SPC7110, EpsonRTC, SharpRTC, SDD1+RAM, SufamiTurbo, BS-X slotted carts.
2015-12-19 08:52:34 +00:00
}
return cpu.writeDMA(addr, data);
Update to higan and icarus v095r15 release. r13 and r14 weren't posted as individual releases, but their changelogs were posted. byuu says about r13: I'm not going to be posting WIPs for r13 and above for a while. The reason is that I'm working on the major manifest overhaul I've discussed previously on the icarus subforum. I'm recreating my boards database from scratch using the map files and the new map analyzer. The only games that will load are ones I've created board definitions for, and updated sfc/cartridge/markup.cpp to parse. Once I've finished all the boards, then I'll update the heuristics. Then finally, I'll sync the syntax changes over to the fc, gb, gba cores. Once that's done, I'll start posting WIPs again, along with a new build of icarus. But I'll still post changelogs as I work through things. Changelog (r13): - preservation: created new database-builder tool (merges region-specific databases with boards) - icarus: support new, external database format (~/.config/icarus/Database/(Super Famicom.bml, ...) - added 1A3B-(10,11,12); 1A3B-20 byuu says about r14: r14 work: I successfully created mappings for every board used in the US set. I also updated icarus' heuristics to use the new mappings, and created ones there for the boards that are only in the JP set. Then I patched icarus to support pulling games out of the database when it's used on a game folder to generate a manifest file. Then I updated a lot of code in higan/sfc to support the new mapping syntax. sfc/cartridge/markup.cpp is about half the size it used to be with the new mappings, and I was able to kill off both map/id and map/select entirely. Then I updated all four emulated systems (and both subsystems) to use "board" as the root node, and harmonized their syntax (made them all more consistent with each other.) Then I added a manifest viewer to the tools window+menu. It's kind of an advanced user feature, but oh well. No reason to coddle people when the feature is very useful for developers. The viewer will show all manifests in order when you load multi-cart games as well. Still not going to call any syntax 100% done right now, but thankfully with the new manifest-free folders, nobody will have to do anything to use the new format. Just download the new version and go. The Super Famicom Event stuff is currently broken (CC92/PF94 boards). That's gonna be fun to support. byuu says about r15: EDIT: small bug in icarus with heuristics. Edit core/super-famicom.cpp line 27: if(/*auto*/ markup = cartridge.markup) { Gotta remove that "auto" so that it returns valid markup. Resolved the final concerns I had with the new manifest format. Right now there are two things that are definitely broken: MCC (BS-X Town cart) and Event (CC '92 and PF'94). And there are a few things that are untested: SPC7110, EpsonRTC, SharpRTC, SDD1+RAM, SufamiTurbo, BS-X slotted carts.
2015-12-19 08:52:34 +00:00
}
auto SDD1::mmcRead(uint24 addr) -> uint8 {
switch(addr.bits(20,21)) {
case 0: return rom.read(r4804.bits(0,3) << 20 | addr.bits(0,19)); //c0-cf:0000-ffff
case 1: return rom.read(r4805.bits(0,3) << 20 | addr.bits(0,19)); //d0-df:0000-ffff
case 2: return rom.read(r4806.bits(0,3) << 20 | addr.bits(0,19)); //e0-ef:0000-ffff
case 3: return rom.read(r4807.bits(0,3) << 20 | addr.bits(0,19)); //f0-ff:0000-ffff
}
unreachable;
Update to v080r01 release. byuu says: There was one unfortunate aspect of the S-DD1 module: you had to give it the DMA length and a target buffer, and it would do the entire decompression at once. Real hardware would work by streaming the data byte by byte. So with that, I went ahead and rewrote the code to handle byte-based streaming. This WIP is an important milestone for me personally. Up until now, bsnes has always had code that was directly copy-pasted from other authors. With all of the DSP and Cx4 chips rewritten in LLE, and the SPC7110 algorithm already ported over from C, and archive decompression code removed for a long time, the S-DD1 was the only module left like this. It's obviously not that big of a deal. The code is basically still a copy of the original. S-DD1 decomp from Andreas Naive, SPC7110 decomp from neviksti, and S-DSP from blargg. And the rest of the emulator is of course only possible because of code and research before it, although everything else has no resemblance at all to code before it. The main advantage, really, is absolute code consistency. I always use the same variant of K&R, for instance. I dunno, I guess I just never really liked the "Build-a-Bear Workshop" style of emulators, like is so prominent in the Genesis scene: "My new Genesis emu (uses Starscream/Musashi 68K core, Marat Fayzullin's Z80 core, YM2612 core from Game_Music_Emu, VDP core from Gens, SVP core from picodrive)", sorry, but you wrote a front-end, not an emulator :/ I also updated the SPC7110 decompression module: I merged the class inside the SPC7110 class (not sure why it was separate before), and replaced the morton lookup tables with for-loops. The morton tables were added to be a tiny bit faster when I was more interested in speed than code clarity. It may be a tiny bit slower (or faster due to less L2 cache usage), but you won't even notice an FPS drop, and it cuts out a good chunk of code and some tables. Lastly, I added pinput_poll() to video_refresh(). Forgot to remove Interface::input_poll() from the C++ side, will have to do that later.
2011-06-28 11:36:00 +00:00
}
//map address=00-3f,80-bf:8000-ffff
//map address=c0-ff:0000-ffff
auto SDD1::mcuromRead(uint24 addr, uint8 data) -> uint8 {
//map address=00-3f,80-bf:8000-ffff
if(!addr.bit(22)) {
if(!addr.bit(23) && addr.bit(21) && r4805.bit(7)) addr.bit(21) = 0; //20-3f:8000-ffff
if( addr.bit(23) && addr.bit(21) && r4807.bit(7)) addr.bit(21) = 0; //a0-bf:8000-ffff
addr = addr.bits(16,21) << 15 | addr.bits(0,14);
return rom.read(addr);
}
Update to higan and icarus v095r15 release. r13 and r14 weren't posted as individual releases, but their changelogs were posted. byuu says about r13: I'm not going to be posting WIPs for r13 and above for a while. The reason is that I'm working on the major manifest overhaul I've discussed previously on the icarus subforum. I'm recreating my boards database from scratch using the map files and the new map analyzer. The only games that will load are ones I've created board definitions for, and updated sfc/cartridge/markup.cpp to parse. Once I've finished all the boards, then I'll update the heuristics. Then finally, I'll sync the syntax changes over to the fc, gb, gba cores. Once that's done, I'll start posting WIPs again, along with a new build of icarus. But I'll still post changelogs as I work through things. Changelog (r13): - preservation: created new database-builder tool (merges region-specific databases with boards) - icarus: support new, external database format (~/.config/icarus/Database/(Super Famicom.bml, ...) - added 1A3B-(10,11,12); 1A3B-20 byuu says about r14: r14 work: I successfully created mappings for every board used in the US set. I also updated icarus' heuristics to use the new mappings, and created ones there for the boards that are only in the JP set. Then I patched icarus to support pulling games out of the database when it's used on a game folder to generate a manifest file. Then I updated a lot of code in higan/sfc to support the new mapping syntax. sfc/cartridge/markup.cpp is about half the size it used to be with the new mappings, and I was able to kill off both map/id and map/select entirely. Then I updated all four emulated systems (and both subsystems) to use "board" as the root node, and harmonized their syntax (made them all more consistent with each other.) Then I added a manifest viewer to the tools window+menu. It's kind of an advanced user feature, but oh well. No reason to coddle people when the feature is very useful for developers. The viewer will show all manifests in order when you load multi-cart games as well. Still not going to call any syntax 100% done right now, but thankfully with the new manifest-free folders, nobody will have to do anything to use the new format. Just download the new version and go. The Super Famicom Event stuff is currently broken (CC92/PF94 boards). That's gonna be fun to support. byuu says about r15: EDIT: small bug in icarus with heuristics. Edit core/super-famicom.cpp line 27: if(/*auto*/ markup = cartridge.markup) { Gotta remove that "auto" so that it returns valid markup. Resolved the final concerns I had with the new manifest format. Right now there are two things that are definitely broken: MCC (BS-X Town cart) and Event (CC '92 and PF'94). And there are a few things that are untested: SPC7110, EpsonRTC, SharpRTC, SDD1+RAM, SufamiTurbo, BS-X slotted carts.
2015-12-19 08:52:34 +00:00
//map address=c0-ff:0000-ffff
if(r4800 & r4801) {
//at least one channel has S-DD1 decompression enabled ...
for(auto n : range(8)) {
if(r4800.bit(n) && r4801.bit(n)) {
//S-DD1 always uses fixed transfer mode, so address will not change during transfer
if(addr == dma[n].addr) {
if(!dmaReady) {
Update to v080r01 release. byuu says: There was one unfortunate aspect of the S-DD1 module: you had to give it the DMA length and a target buffer, and it would do the entire decompression at once. Real hardware would work by streaming the data byte by byte. So with that, I went ahead and rewrote the code to handle byte-based streaming. This WIP is an important milestone for me personally. Up until now, bsnes has always had code that was directly copy-pasted from other authors. With all of the DSP and Cx4 chips rewritten in LLE, and the SPC7110 algorithm already ported over from C, and archive decompression code removed for a long time, the S-DD1 was the only module left like this. It's obviously not that big of a deal. The code is basically still a copy of the original. S-DD1 decomp from Andreas Naive, SPC7110 decomp from neviksti, and S-DSP from blargg. And the rest of the emulator is of course only possible because of code and research before it, although everything else has no resemblance at all to code before it. The main advantage, really, is absolute code consistency. I always use the same variant of K&R, for instance. I dunno, I guess I just never really liked the "Build-a-Bear Workshop" style of emulators, like is so prominent in the Genesis scene: "My new Genesis emu (uses Starscream/Musashi 68K core, Marat Fayzullin's Z80 core, YM2612 core from Game_Music_Emu, VDP core from Gens, SVP core from picodrive)", sorry, but you wrote a front-end, not an emulator :/ I also updated the SPC7110 decompression module: I merged the class inside the SPC7110 class (not sure why it was separate before), and replaced the morton lookup tables with for-loops. The morton tables were added to be a tiny bit faster when I was more interested in speed than code clarity. It may be a tiny bit slower (or faster due to less L2 cache usage), but you won't even notice an FPS drop, and it cuts out a good chunk of code and some tables. Lastly, I added pinput_poll() to video_refresh(). Forgot to remove Interface::input_poll() from the C++ side, will have to do that later.
2011-06-28 11:36:00 +00:00
//prepare streaming decompression
decompressor.init(addr);
dmaReady = true;
}
Update to v080r01 release. byuu says: There was one unfortunate aspect of the S-DD1 module: you had to give it the DMA length and a target buffer, and it would do the entire decompression at once. Real hardware would work by streaming the data byte by byte. So with that, I went ahead and rewrote the code to handle byte-based streaming. This WIP is an important milestone for me personally. Up until now, bsnes has always had code that was directly copy-pasted from other authors. With all of the DSP and Cx4 chips rewritten in LLE, and the SPC7110 algorithm already ported over from C, and archive decompression code removed for a long time, the S-DD1 was the only module left like this. It's obviously not that big of a deal. The code is basically still a copy of the original. S-DD1 decomp from Andreas Naive, SPC7110 decomp from neviksti, and S-DSP from blargg. And the rest of the emulator is of course only possible because of code and research before it, although everything else has no resemblance at all to code before it. The main advantage, really, is absolute code consistency. I always use the same variant of K&R, for instance. I dunno, I guess I just never really liked the "Build-a-Bear Workshop" style of emulators, like is so prominent in the Genesis scene: "My new Genesis emu (uses Starscream/Musashi 68K core, Marat Fayzullin's Z80 core, YM2612 core from Game_Music_Emu, VDP core from Gens, SVP core from picodrive)", sorry, but you wrote a front-end, not an emulator :/ I also updated the SPC7110 decompression module: I merged the class inside the SPC7110 class (not sure why it was separate before), and replaced the morton lookup tables with for-loops. The morton tables were added to be a tiny bit faster when I was more interested in speed than code clarity. It may be a tiny bit slower (or faster due to less L2 cache usage), but you won't even notice an FPS drop, and it cuts out a good chunk of code and some tables. Lastly, I added pinput_poll() to video_refresh(). Forgot to remove Interface::input_poll() from the C++ side, will have to do that later.
2011-06-28 11:36:00 +00:00
//fetch a decompressed byte; once finished, disable channel and invalidate buffer
data = decompressor.read();
if(--dma[n].size == 0) {
dmaReady = false;
r4801.bit(n) = 0;
}
return data;
} //address matched
} //channel enabled
} //channel loop
} //S-DD1 decompressor enabled
//S-DD1 decompression mode inactive; return ROM data
return mmcRead(addr);
}
auto SDD1::mcuromWrite(uint24 addr, uint8 data) -> void {
}
//map address=00-3f,80-bf:6000-7fff mask=0xe000
//map address=70-73:0000-ffff mask=0x8000
auto SDD1::mcuramRead(uint24 addr, uint8 data) -> uint8 {
return ram.read(addr.bits(0,12), data);
}
auto SDD1::mcuramWrite(uint24 addr, uint8 data) -> void {
return ram.write(addr.bits(0,12), data);
}
}