memory.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <../base.hpp>
  2. #define MEMORY_CPP
  3. namespace memory {
  4. MMIOAccess mmio;
  5. StaticRAM wram(128 * 1024);
  6. StaticRAM apuram(64 * 1024);
  7. StaticRAM vram(64 * 1024);
  8. StaticRAM oam(544);
  9. StaticRAM cgram(512);
  10. UnmappedMemory memory_unmapped;
  11. UnmappedMMIO mmio_unmapped;
  12. };
  13. uint8 UnmappedMemory::read(unsigned) { return cpu.regs.mdr; }
  14. void UnmappedMemory::write(unsigned addr, uint8 val) {
  15. //printf("UnmappedMemory::write 0x%x 0x%x\n",addr,val);
  16. }
  17. uint8 UnmappedMMIO::mmio_read(unsigned) { return cpu.regs.mdr; }
  18. void UnmappedMMIO::mmio_write(unsigned addr, uint8 val) {
  19. //printf("UnmappedMemory::write 0x%x 0x%x\n",addr,val);
  20. }
  21. void MMIOAccess::map(unsigned addr, MMIO &access) {
  22. //printf("MMIOAccess::map 0x%x\n",addr);
  23. //MMIO: $[00-3f]:[2000-5fff]
  24. mmio[(addr - 0x2000) & 0x3fff] = &access;
  25. }
  26. MMIO* MMIOAccess::get(unsigned addr) {
  27. return mmio[(addr - 0x2000) & 0x3fff];
  28. }
  29. uint8 MMIOAccess::read(unsigned addr) {
  30. //printf("MMIOAccess::read 0x%x\n",addr);
  31. return mmio[(addr - 0x2000) & 0x3fff]->mmio_read(addr);
  32. }
  33. void MMIOAccess::write(unsigned addr, uint8 data) {
  34. //printf("MMIOAccess::write 0x%x %x\n",addr,data);
  35. mmio[(addr - 0x2000) & 0x3fff]->mmio_write(addr, data);
  36. }
  37. unsigned Bus::mirror(unsigned addr, unsigned size) {
  38. unsigned base = 0;
  39. if(size) {
  40. unsigned mask = 1 << 23;
  41. while(addr >= size) {
  42. while(!(addr & mask)) mask >>= 1;
  43. addr -= mask;
  44. if(size > mask) {
  45. size -= mask;
  46. base += mask;
  47. }
  48. mask >>= 1;
  49. }
  50. base += addr;
  51. }
  52. return base;
  53. }
  54. void Bus::map(unsigned addr, Memory &access, unsigned offset) {
  55. page[addr >> 8].access = &access;
  56. page[addr >> 8].offset = offset - addr;
  57. }
  58. void Bus::map(
  59. MapMode mode,
  60. uint8 bank_lo, uint8 bank_hi,
  61. uint16 addr_lo, uint16 addr_hi,
  62. Memory &access, unsigned offset, unsigned size
  63. ) {
  64. assert(bank_lo <= bank_hi);
  65. assert(addr_lo <= addr_hi);
  66. if(access.size() == -1U) return;
  67. uint8 page_lo = addr_lo >> 8;
  68. uint8 page_hi = addr_hi >> 8;
  69. unsigned index = 0;
  70. switch(mode) {
  71. case MapDirect: {
  72. printf("Bus::map MapDirect bank_lo=0x%02x bank_hi=0x%02x addr_lo=0x%04x addr_hi=0x%04x\n",
  73. bank_lo,bank_hi,addr_lo,addr_hi);
  74. for(unsigned bank = bank_lo; bank <= bank_hi; bank++) {
  75. for(unsigned page = page_lo; page <= page_hi; page++) {
  76. map((bank << 16) + (page << 8), access, (bank << 16) + (page << 8));
  77. }
  78. }
  79. } break;
  80. case MapLinear: {
  81. printf("Bus::map MapLinear bank_lo=0x%02x bank_hi=0x%02x addr_lo=0x%04x addr_hi=0x%04x\n",
  82. bank_lo,bank_hi,addr_lo,addr_hi);
  83. for(unsigned bank = bank_lo; bank <= bank_hi; bank++) {
  84. for(unsigned page = page_lo; page <= page_hi; page++) {
  85. map((bank << 16) + (page << 8), access, mirror(offset + index, access.size()));
  86. index += 256;
  87. if(size) index %= size;
  88. }
  89. }
  90. } break;
  91. case MapShadow: {
  92. printf("Bus::map MapShadow bank_lo=0x%02x bank_hi=0x%02x addr_lo=0x%04x addr_hi=0x%04x\n",
  93. bank_lo,bank_hi,addr_lo,addr_hi);
  94. for(unsigned bank = bank_lo; bank <= bank_hi; bank++) {
  95. index += page_lo * 256;
  96. if(size) index %= size;
  97. for(unsigned page = page_lo; page <= page_hi; page++) {
  98. map((bank << 16) + (page << 8), access, mirror(offset + index, access.size()));
  99. index += 256;
  100. if(size) index %= size;
  101. }
  102. index += (255 - page_hi) * 256;
  103. if(size) index %= size;
  104. }
  105. } break;
  106. }
  107. }