istvan-v / plus4emu

IstvanV's great Commodore +4 emulator imported to github
http://plus4emu.sourceforge.net/
GNU General Public License v2.0
23 stars 1 forks source link

Banking EPROM cartridge support #4

Open zzarko opened 3 years ago

zzarko commented 3 years ago

I have managed to hack-in a support for banked EPROM cartridge that can have up to 4MB. Banking address is $FDFE and only $8000-$BFFF is used in the cartridge. There is a signature right after CBM chars, so it can be easily recognized. This was done to speed-up the development of real cartridge, as I haven't found that something like that is supported in this or other emulators. Plus4Emu had a clean structure that was relatively easy to follow and make changes. Now, those changes probably aren't in accordance with the overall architecture of the emulator, but I'll gladly send them if there is a interest for something like that.

zzarko commented 3 years ago

Here is a patch created with diff:

diff -Naur plus4emu-master-original/src/memory.cpp plus4emu-master-changed/src/memory.cpp
--- plus4emu-master-original/src/memory.cpp 2020-04-02 08:12:32.000000000 +0200
+++ plus4emu-master-changed/src/memory.cpp  2021-01-16 16:33:47.000000000 +0100
@@ -234,6 +234,20 @@
     ted.tedBitmapReadMap = (ted.tedBitmapReadMap & 0x07F8U) | tmp;
   }

+  // BANKCART-BEGIN
+  PLUS4EMU_REGPARM3 void TED7360::write_register_FDFE(
+      void *userData, uint16_t addr, uint8_t value)
+  {
+    (void) addr;
+    TED7360&  ted = *(reinterpret_cast<TED7360 *>(userData));
+    ted.dataBusState = value;
+    ted.BankCartCurrent = value;
+    uint32_t cartOffset = (value & ted.BankCartMask) << 14;
+    //printf("FDFE bank %d(%x), offset %d(%x)\n", value, value, cartOffset, cartOffset);
+    ted.loadROM(2, 0, 16384, ted.BankCart + cartOffset);
+  }
+  // BANKCART-END
+
   PLUS4EMU_REGPARM3 void TED7360::write_register_FF3E(
       void *userData, uint16_t addr, uint8_t value)
   {
@@ -313,6 +327,10 @@
   {
     int   i = offs, j, k;

+  // BANKCART-BEGIN
+  //printf("loadROM bankNum %d(%x)  offs %d(%x)  cnt %d(%x)\n", bankNum, bankNum, offs, offs, cnt, cnt);
+  // BANKCART-END
+
     if (buf) {
       for (j = 0, k = cnt; k > 0; i++, j++, k--) {
         uint8_t segment = uint8_t(((bankNum & 3) << 1) + ((i & 0x4000) >> 14));
diff -Naur plus4emu-master-original/src/plus4vm.cpp plus4emu-master-changed/src/plus4vm.cpp
--- plus4emu-master-original/src/plus4vm.cpp    2020-04-02 08:12:32.000000000 +0200
+++ plus4emu-master-changed/src/plus4vm.cpp 2021-01-16 16:34:48.000000000 +0100
@@ -1083,6 +1083,9 @@
     }
     // clear segment first
     if (floppyROMSegment < 0) {
+      // BANKCART-BEGIN
+      //printf("Clearing ROM image %s\n", fileName);
+      // BANKCART-END
       ted->loadROM(int(n >> 1), int(n & 1) << 14, 0, (uint8_t *) 0);
     }
     else {
@@ -1108,8 +1111,29 @@
     }
     std::fseek(f, long(offs), SEEK_SET);
     std::fread(&(buf.front()), 1, nBytes, f);
+
+    // BANKCART-BEGIN
+    if ( !strncmp("8BITCHIP", (char*)(&(buf.front()) + 10), 8) ) {
+        //printf("Loading CART image %s\n", fileName);
+        std::fseek(f, 0, SEEK_SET);
+        ted->BankCartLen = std::fread(ted->BankCart, 1, 1024*1024*4, f);
+        ted->BankCartCurrent = 0;
+
+        ted->BankCartMask = 0x00;
+        uint32_t len  = ted->BankCartLen >> 15;
+        while (len) {
+            ted->BankCartMask = (ted->BankCartMask << 1) | 1;
+            len >>= 1;
+        }
+        //printf("Bank mask: %02X\n", ted->BankCartMask);
+    }
+    // BANKCART-END
+
     std::fclose(f);
     if (floppyROMSegment < 0) {
+      // BANKCART-BEGIN
+      //printf("Loading ROM image %s\n", fileName);
+      // BANKCART-END
       ted->loadROM(int(n) >> 1, int(n & 1) << 14, int(nBytes), &(buf.front()));
     }
     else {
diff -Naur plus4emu-master-original/src/ted_api.cpp plus4emu-master-changed/src/ted_api.cpp
--- plus4emu-master-original/src/ted_api.cpp    2020-04-02 08:12:32.000000000 +0200
+++ plus4emu-master-changed/src/ted_api.cpp 2021-01-16 16:35:38.000000000 +0100
@@ -414,6 +414,10 @@
       }
       // load ROM segments
       for (uint8_t i = 0x00; i < 0x08; i++) {
+        // BANKCART-BEGIN
+        //printf("Load State ROM # %d\n", i);
+        // BANKCART-BEGIN
+
         if (!(romBitmap & (uint8_t(1) << i)))
           loadROM(int(i >> 1), int(i & 1) << 14, 0, (uint8_t *) 0);
         else {
diff -Naur plus4emu-master-original/src/ted.hpp plus4emu-master-changed/src/ted.hpp
--- plus4emu-master-original/src/ted.hpp    2020-04-02 08:12:32.000000000 +0200
+++ plus4emu-master-changed/src/ted.hpp 2021-01-16 16:09:15.000000000 +0100
@@ -317,6 +317,10 @@
         void *userData, uint16_t addr, uint8_t value);
     static PLUS4EMU_REGPARM3 void write_register_FDDx(
         void *userData, uint16_t addr, uint8_t value);
+    // BANKCART-BEGIN
+    static PLUS4EMU_REGPARM3 void write_register_FDFE(
+        void *userData, uint16_t addr, uint8_t value);
+    // BANKCART-END
     static PLUS4EMU_REGPARM3 void write_register_FFxx(
         void *userData, uint16_t addr, uint8_t value);
     static PLUS4EMU_REGPARM3 void write_register_FF00(
@@ -850,6 +854,13 @@
     // and 'f' is set to NULL.
     static uint16_t readPRGFileHeader(std::FILE*& f, const char *fileName);
     void registerChunkTypes(Plus4Emu::File&);
+
+    // BANKCART-BEGIN
+    uint32_t BankCartLen;
+    uint8_t BankCartMask;
+    uint8_t BankCartCurrent;
+    uint8_t BankCart[1024*1024*4];
+    // BANKCART-END
   };

 }       // namespace Plus4
diff -Naur plus4emu-master-original/src/ted_init.cpp plus4emu-master-changed/src/ted_init.cpp
--- plus4emu-master-original/src/ted_init.cpp   2020-04-02 08:12:32.000000000 +0200
+++ plus4emu-master-changed/src/ted_init.cpp    2021-01-16 16:35:24.000000000 +0100
@@ -140,6 +140,12 @@
       setMemoryWriteCallback(i, &write_register_FD3x);
     for (uint16_t i = 0xFDD0; i <= 0xFDDF; i++)
       setMemoryWriteCallback(i, &write_register_FDDx);
+
+    // BANKCART-BEGIN
+    setMemoryWriteCallback(0xFDFE, &write_register_FDFE);
+    //printf("CALLBACK SET\n");
+    // BANKCART-END
+
     setMemoryWriteCallback(0xFF00, &write_register_FF00);
     setMemoryWriteCallback(0xFF01, &write_register_FF01);
     setMemoryWriteCallback(0xFF02, &write_register_FF02);
@@ -321,6 +327,9 @@
     writeMemory(0x0000, 0x00);
     writeMemory(0x0001, 0x00);
     M7501::reset(cold_reset);
+    // BANKCART-BEGIN
+    write_register_FDFE(this, 0xFDFE, 0);
+    // BANKCART-BEGIN
   }

   TED7360::~TED7360()