bsx_flash.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #ifdef BSX_CPP
  2. void BSXFlash::init() {}
  3. void BSXFlash::enable() {}
  4. void BSXFlash::power() {
  5. reset();
  6. }
  7. void BSXFlash::reset() {
  8. regs.command = 0;
  9. regs.write_old = 0x00;
  10. regs.write_new = 0x00;
  11. regs.flash_enable = false;
  12. regs.read_enable = false;
  13. regs.write_enable = false;
  14. }
  15. unsigned BSXFlash::size() const {
  16. return memory::bscram.size();
  17. }
  18. uint8 BSXFlash::read(unsigned addr) {
  19. if(addr == 0x0002) {
  20. if(regs.flash_enable) return 0x80;
  21. }
  22. if(addr == 0x5555) {
  23. if(regs.flash_enable) return 0x80;
  24. }
  25. if(regs.read_enable && addr >= 0xff00 && addr <= 0xff13) {
  26. //read flash cartridge vendor information
  27. switch(addr - 0xff00) {
  28. case 0x00: return 0x4d;
  29. case 0x01: return 0x00;
  30. case 0x02: return 0x50;
  31. case 0x03: return 0x00;
  32. case 0x04: return 0x00;
  33. case 0x05: return 0x00;
  34. case 0x06: return 0x2a; //0x2a = 8mbit, 0x2b = 16mbit (not known to exist, though BIOS recognizes ID)
  35. case 0x07: return 0x00;
  36. default: return 0x00;
  37. }
  38. }
  39. return memory::bscram.read(addr);
  40. }
  41. void BSXFlash::write(unsigned addr, uint8 data) {
  42. //there exist both read-only and read-write BS-X flash cartridges ...
  43. //unfortunately, the vendor info is not stored inside memory dumps
  44. //of BS-X flashcarts, so it is impossible to determine whether a
  45. //given flashcart is writeable.
  46. //however, it has been observed that LoROM-mapped BS-X carts always
  47. //use read-write flashcarts, and HiROM-mapped BS-X carts always use
  48. //read-only flashcarts.
  49. //below is an unfortunately necessary workaround to this problem.
  50. if(cartridge.mapper() == Cartridge::BSCHiROM) return;
  51. if((addr & 0xff0000) == 0) {
  52. regs.write_old = regs.write_new;
  53. regs.write_new = data;
  54. if(regs.write_enable && regs.write_old == regs.write_new) {
  55. return memory::bscram.write(addr, data);
  56. }
  57. } else {
  58. if(regs.write_enable) {
  59. return memory::bscram.write(addr, data);
  60. }
  61. }
  62. if(addr == 0x0000) {
  63. regs.command <<= 8;
  64. regs.command |= data;
  65. if((regs.command & 0xffff) == 0x38d0) {
  66. regs.flash_enable = true;
  67. regs.read_enable = true;
  68. }
  69. }
  70. if(addr == 0x2aaa) {
  71. regs.command <<= 8;
  72. regs.command |= data;
  73. }
  74. if(addr == 0x5555) {
  75. regs.command <<= 8;
  76. regs.command |= data;
  77. if((regs.command & 0xffffff) == 0xaa5570) {
  78. regs.write_enable = false;
  79. }
  80. if((regs.command & 0xffffff) == 0xaa55a0) {
  81. regs.write_old = 0x00;
  82. regs.write_new = 0x00;
  83. regs.flash_enable = true;
  84. regs.write_enable = true;
  85. }
  86. if((regs.command & 0xffffff) == 0xaa55f0) {
  87. regs.flash_enable = false;
  88. regs.read_enable = false;
  89. regs.write_enable = false;
  90. }
  91. }
  92. }
  93. #endif