]> localhost Git - WindEmu.git/commitdiff
hook up asic14 to gpio pin 10 and fix interrupt status clearing. when an interrupt...
authorGeorge Wright <gw@gwright.org.uk>
Sat, 7 Dec 2024 23:57:55 +0000 (15:57 -0800)
committerGeorge Wright <gw@gwright.org.uk>
Sat, 7 Dec 2024 23:57:55 +0000 (15:57 -0800)
WindCore/sa1100.cpp
WindCore/sa1100/asic14.cpp
WindCore/sa1100/asic14.h
WindCore/sa1100/gpio_controller.cpp
WindCore/sa1100/gpio_controller.h
WindCore/sa1100/interrupt_controller.h
WindCore/sa1100/os_timer.cpp
WindCore/sa1100/os_timer.h

index 1f7d235c4616a52f58045d0d6fe9952688bd33fe..5693bcb8204f7c2756c6a376cecd9f9e48f8e171 100644 (file)
@@ -13,13 +13,15 @@ Emulator::Emulator() : EmuBase(false) {
        resetController = new ResetController();
        rtc = new RTC();
        intController = new IntController(lcdController, osTimer, gpioController, serial3, rtc);
+       gpioController->setIntController(intController);
+       osTimer->setIntController(intController);
        powerManager = new PowerManager();
        MemoryBlockC0 = new uint8_t[memoryMask+1];
        MemoryBlockC8 = new uint8_t[memoryMask+1];
        // MemoryBlockD0 = new uint8_t[memoryMask+1];
        // MemoryBlockD8 = new uint8_t[memoryMask+1];
        ROM = new uint8_t[0x1000000];
-       asic14 = new ASIC14();
+       asic14 = new ASIC14(gpioController);
 }
 
 Emulator::~Emulator() {
@@ -130,10 +132,12 @@ uint32_t Emulator::readSCM32(uint32_t physAddr) {
                // GPIO
                printf("GPIO read at 0x%08x\n", physAddr);
                return gpioController->get_data(physAddr);
-       case 0x9005:
+       case 0x9005: {
                // Interrupt Controller
-               printf("Interrupt controller read at 0x%08x\n", physAddr);
-               return intController->get_data(physAddr);
+               auto value = intController->get_data(physAddr);
+               printf("Interrupt controller read at 0x%08x [0x%08x]\n", physAddr, value);
+               return value;
+       }
        default:
                printf("Read SCM32 at 0x%08x\n", physAddr);
                return 0x0;
@@ -1007,6 +1011,7 @@ bool Emulator::executeUntil(int64_t cycles) {
 
                        nextTickAt += TICK_INTERVAL;
                        pendingInterrupts |= (1<<TINT);
+                       asic14->tick();
                }
                if (passedCycles % TICKS_3_6864_MHZ == 0) {
                        osTimer->tick();
index f6bf18eb67c22784068dec3ee0dac66be110f864..cf23854e0ad8eed4b7b470db1ec5a2faeb6a100e 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace SA1100 {
 
-  ASIC14::ASIC14() {
+  ASIC14::ASIC14(GPIOController* const gpioController) : mGPIOController(gpioController) {
     init_register();
     mCurrPlace = 0;
     for (int i = 0; i < 0x80; i++)
@@ -65,7 +65,7 @@ namespace SA1100 {
       switch (address) {
           case CTRL0:
             printf("ASIC14 read register CTRL0: %04x\n", m_CTRL0);
-            return m_CTRL0;
+            return 0;
           case KBD_PADR:
             printf("ASIC14 read register KBD_PADR: %04x\n", m_KBD_PADR);
             return m_KBD_PADR;
@@ -129,7 +129,7 @@ namespace SA1100 {
             break;
           case CTRL_STATUS:
             printf("ASIC14 write %04x to register CTRL_STATUS\n", value);
-            m_CTRL_STATUS value;
+            m_CTRL_STATUS &= ~value;
             break;
           case POWER:
             printf("ASIC14 write %04x to register POWER\n", value);
index 7397e9d41a39fb01fdac29e4927a2f7a6c812bf0..f901774ae48d5cdadef5c1472b546f05a47f188b 100644 (file)
@@ -42,6 +42,7 @@ class ASIC14 {
   private:
     uint8_t prom[0x80] = {};
     int mCurrPlace = 0;
+    GPIOController* mGPIOController;
     enum
     {
         CTRL0       = 0x10000000,
@@ -99,7 +100,7 @@ class ASIC14 {
     }
 
   public:
-    ASIC14();
+    ASIC14(GPIOController* const gpioController);
 
     void run();
     void reset();
@@ -107,6 +108,14 @@ class ASIC14 {
     uint16_t get_data(uint32_t const address);
 
     void put_data(uint32_t const address, uint16_t const value);
+    void tick() {
+
+      //m_IRQ_STATUS = IRQ_CFCARD_CHANGE | IRQ_PCMCIA_CHANGE;
+      m_IRQ_STATUS = m_IRQ_MASK;
+      if (m_IRQ_STATUS != 0) {
+        mGPIOController->trigger_asic14_gpio();
+      }
+    }
 };
 
 } // namespace SA1100
index d3c20ba6d50269d6c453fba87a87a8d55a6ba30f..477d3283491ee08c5f798343b43fc4d6f64b29a6 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "gpio_controller.h"
 
+#include "interrupt_controller.h"
 namespace SA1100 {
   void GPIOController::reset() {
     m_GPLR &= 0xFFFFFFF;
@@ -126,6 +127,8 @@ namespace SA1100 {
       // GEDR status bits are cleared by writing a one to them.
       // Writing a zero to a GEDR status bit has no effect.
       m_GEDR &= ~(value & 0xFFFFFFF);
+      printf("GEDR write %08x [%08x]\n", value, m_GEDR);
+      mIntController->clear_interrupt(IntController::GPIO_0_10_EDGE_BIT_MASK);
       break;
       
     case GAFR:
index b2af1d1dcf01376b0e48aec94495672a4f5d6f25..d9668c53f2301400cc1a1e03d68cde23d2fd83ee 100644 (file)
@@ -23,6 +23,8 @@
 namespace SA1100
 {
 
+class IntController;
+
 class GPIOController {
   private:
     
@@ -42,6 +44,7 @@ class GPIOController {
     // Normal function
     
     enum {
+      GAFR_ASIC14 = (1 << 10),
       GAFR_ACTION_BUTTON = (1 << 18)
     };
     
@@ -85,6 +88,8 @@ class GPIOController {
       m_GEDR = 0;
       m_GAFR = 0;
     }
+
+    IntController* mIntController;
     
   public:
     
@@ -93,6 +98,10 @@ class GPIOController {
     GPIOController() {
       init_register();
     }
+
+    void setIntController(IntController* intController) {
+      mIntController = intController;
+    }
     
     // Operation
     
@@ -124,6 +133,23 @@ class GPIOController {
         m_GPLR &= ~GAFR_ACTION_BUTTON;
       }
     }
+
+    inline void trigger_asic14_gpio() {
+      printf("Triggering ASIC14 GPIO\n");
+      // :SA-1110 Developer's Manual: p.80: Wei 2004-Jul-1:
+      //
+      // A zero in GAFR indicates that the corresponding GPIO pin is to be used for its normal GPIO function.
+      if (0 == (m_GAFR & GAFR_ASIC14))
+      {
+        // if (high) {
+        //   m_GPLR |= GAFR_ASIC14;
+        // } else {
+        //   m_GPLR &= ~GAFR_ASIC14;
+        // }
+        m_GEDR |= GAFR_ASIC14;
+      }
+    }
+
     inline void flip_gpio() {
       if (m_GPLR & 0x400) {
         m_GPLR &= ~0x400;
index 06dd8ffcdd151e4c1e4dc12b2fbb682d1d75ed4f..cbb0fc265d77de15cc724bbf8f943c48cc60aaff 100644 (file)
@@ -78,6 +78,15 @@ class IntController {
     };
     typedef enum IntCtrlBitMaskEnum IntCtrlBitMaskEnum;
     
+    enum
+    {
+      ICIP = 0x90050000,
+      ICMR = 0x90050004,
+      ICLR = 0x90050008,
+      ICCR = 0x9005000C,
+      ICFP = 0x90050010,
+      ICPR = 0x90050020
+    };
   private:
     
     // Attribute
@@ -89,15 +98,6 @@ class IntController {
     
     // Register location
     
-    enum
-    {
-      ICIP = 0x90050000,
-      ICMR = 0x90050004,
-      ICLR = 0x90050008,
-      ICCR = 0x9005000C,
-      ICFP = 0x90050010,
-      ICPR = 0x90050020
-    };
     
     // Register
     
@@ -147,6 +147,12 @@ class IntController {
     
     void put_data(uint32_t const address, uint32_t const value);
     
+    void clear_interrupt(uint32_t const mask) {
+      m_ICIP = m_ICIP & ~mask;
+      m_ICFP = m_ICFP & ~mask;
+      m_ICPR = m_ICPR & ~mask;
+      printf("Clear interrupt %08x [%08x, %08x]\n", mask, m_ICIP, m_ICFP);
+    }
     inline bool have_pending_irq() const {
       return (0 == m_ICIP) ? false : true;
     }
index 10bc5e5494033c26153b61e43c1f2bfb3a166a42..d55ef7e75d57e04c5e8d8666f5ecc62d1f6b6fba 100644 (file)
@@ -16,6 +16,7 @@
 //
 
 #include "os_timer.h"
+#include "interrupt_controller.h"
 
 namespace SA1100 {
 
@@ -139,6 +140,7 @@ namespace SA1100 {
         break;
       default:
         m_OSSR &= ~(value & 0xF);
+        mIntController->clear_interrupt((value & 0xF) << 26);
         break;
       }
       break;
index 3e10a6b10bbcbc0605cf5c71bf672607156ceb0c..ac66ce68cdae2e0c8050f54b556df62b1c9d9cbb 100644 (file)
@@ -23,6 +23,8 @@
 
 namespace SA1100 {
 
+class IntController;
+
 class OsTimer {
   private:
 
@@ -51,16 +53,19 @@ class OsTimer {
     inline void compare_and_set_status(uint32_t osmrs) {
       if (osmrs & OSMR0_MASK) {
           if (m_OSCR == m_OSMR[0]) {
+              printf("OSMR0 triggered\n");
               m_OSSR |= OSMR0_MASK;
           }
       }
       if (osmrs & OSMR1_MASK) {
           if (m_OSCR == m_OSMR[1]) {
+              printf("OSMR1 triggered\n");
               m_OSSR |= OSMR1_MASK;
           }
       }
       if (osmrs & OSMR2_MASK) {
           if (m_OSCR == m_OSMR[2]) {
+              printf("OSMR2 triggered\n");
               m_OSSR |= OSMR2_MASK;
           }
       }
@@ -75,6 +80,8 @@ class OsTimer {
         }
       }
     }
+  
+  IntController* mIntController;
 
   public:
     enum {
@@ -97,6 +104,10 @@ class OsTimer {
 
     OsTimer();
 
+    void setIntController(IntController* intController) {
+      mIntController = intController;
+    }
+
     void reset();
     void tick();