]> git.sesse.net Git - pistorm/blobdiff - emulator.c
[WIP] IRQ experiments, revert Musashi speed hax for now
[pistorm] / emulator.c
index b4ca6b0cf779a2f15ec6a858d2a86b4a3bbd0e43..b1ac4bcc07bdfaece9805f4d1c8d5629078fe15c 100644 (file)
@@ -54,7 +54,7 @@ extern volatile unsigned int *gpio;
 extern volatile uint16_t srdata;
 extern uint8_t realtime_graphics_debug;
 uint8_t realtime_disassembly, int2_enabled = 0;
-uint32_t do_disasm = 0;
+uint32_t do_disasm = 0, old_level;
 
 char disasm_buf[4096];
 
@@ -66,39 +66,92 @@ int mem_fd_gpclk;
 int irq;
 int gayleirq;
 
+//#define MUSASHI_HAX
+
+#ifdef MUSASHI_HAX
+#include "m68kcpu.h"
+extern m68ki_cpu_core m68ki_cpu;
+extern int m68ki_initial_cycles;
+extern int m68ki_remaining_cycles;
+
+#define M68K_SET_IRQ(i) old_level = CPU_INT_LEVEL; \
+       CPU_INT_LEVEL = (i << 8); \
+       if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700) \
+               m68ki_cpu.nmi_pending = TRUE;
+#define M68K_END_TIMESLICE     m68ki_initial_cycles = GET_CYCLES(); \
+       SET_CYCLES(0);
+#else
+#define M68K_SET_IRQ m68k_set_irq
+#define M68K_END_TIMESLICE m68k_end_timeslice()
+#endif
+
+#define NOP asm("nop"); asm("nop"); asm("nop"); asm("nop");
+
+#define DEBUG_EMULATOR
+#ifdef DEBUG_EMULATOR
+#define DEBUG printf
+#else
+#define DEBUG(...)
+#endif
+
 // Configurable emulator options
 unsigned int cpu_type = M68K_CPU_TYPE_68000;
-unsigned int loop_cycles = 300;
+unsigned int loop_cycles = 300, irq_status = 0;
 struct emulator_config *cfg = NULL;
 char keyboard_file[256] = "/dev/input/event1";
 
+uint64_t trig_irq = 0, serv_irq = 0;
+uint16_t irq_delay = 0;
+
 void *iplThread(void *args) {
   printf("IPL thread running\n");
+  uint16_t old_irq = 0;
+  uint32_t value;
 
   while (1) {
-    if (!gpio_get_irq()) {
+    value = *(gpio + 13);
+
+    if (!(value & (1 << PIN_IPL_ZERO))) {
       irq = 1;
-      m68k_end_timeslice();
+      old_irq = irq_delay;
+      NOP
+      M68K_END_TIMESLICE;
+    }
+    else {
+      if (irq) {
+        if (old_irq) {
+          old_irq--;
+        }
+        else {
+          irq = 0;
+        }
+        NOP
+        M68K_END_TIMESLICE;
+      }
     }
-    else
-      irq = 0;
 
     if (gayle_ide_enabled) {
       if (((gayle_int & 0x80) || gayle_a4k_int) && (get_ide(0)->drive[0].intrq || get_ide(0)->drive[1].intrq)) {
         //get_ide(0)->drive[0].intrq = 0;
         gayleirq = 1;
-        m68k_end_timeslice();
+        M68K_END_TIMESLICE;
       }
       else
         gayleirq = 0;
     }
-    usleep(0);
+    //usleep(0);
+    NOP NOP NOP NOP NOP NOP NOP NOP
+    NOP NOP NOP NOP NOP NOP NOP NOP
+    NOP NOP NOP NOP NOP NOP NOP NOP
+    /*NOP NOP NOP NOP NOP NOP NOP NOP
+    NOP NOP NOP NOP NOP NOP NOP NOP
+    NOP NOP NOP NOP NOP NOP NOP NOP*/
   }
   return args;
 }
 
 void stop_cpu_emulation(uint8_t disasm_cur) {
-  m68k_end_timeslice();
+  M68K_END_TIMESLICE;
   if (disasm_cur) {
     m68k_disassemble(disasm_buf, m68k_get_reg(NULL, M68K_REG_PC), cpu_type);
     printf("REGA: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1), m68k_get_reg(NULL, M68K_REG_A2), m68k_get_reg(NULL, M68K_REG_A3), \
@@ -113,7 +166,7 @@ void stop_cpu_emulation(uint8_t disasm_cur) {
   do_disasm = 0;
 }
 
-int ovl;
+unsigned int ovl;
 static volatile unsigned char maprom;
 
 void sigint_handler(int sig_num) {
@@ -131,12 +184,20 @@ void sigint_handler(int sig_num) {
     cfg->platform->shutdown(cfg);
   }
 
+  printf("IRQs triggered: %lld\n", trig_irq);
+  printf("IRQs serviced: %lld\n", serv_irq);
+
   exit(0);
 }
 
 int main(int argc, char *argv[]) {
   int g;
-  const struct sched_param priority = {99};
+  //const struct sched_param priority = {99};
+
+  if (argc > 1) {
+    irq_delay = atoi(argv[1]);
+    printf("Setting IRQ delay to %d loops (%s).\n", irq_delay, argv[1]);
+  }
 
   // Some command line switch stuffles
   for (g = 1; g < argc; g++) {
@@ -248,6 +309,7 @@ int main(int argc, char *argv[]) {
   cpu_pulse_reset();
 
   char c = 0, c_code = 0, c_type = 0;
+  uint32_t last_irq = 0, last_last_irq = 0;
 
   pthread_t id;
   int err;
@@ -280,15 +342,29 @@ int main(int argc, char *argv[]) {
     }
 
     if (irq) {
-      unsigned int status = read_reg();
-      m68k_set_irq((status & 0xe000) >> 13);
-    }
-    else if (gayleirq && int2_enabled) {
-      write16(0xdff09c, 0x8000 | (1 << 3));
-      m68k_set_irq(2);
+      while (irq) {
+        last_irq = ((read_reg() & 0xe000) >> 13);
+        if (last_irq != last_last_irq) {
+          last_last_irq = last_irq;
+          M68K_SET_IRQ(last_irq);
+        }
+        m68k_execute(5);
+      }
+      if (gayleirq && int2_enabled) {
+        write16(0xdff09c, 0x8000 | (1 << 3) && last_irq != 2);
+        last_last_irq = last_irq;
+        last_irq = 2;
+        M68K_SET_IRQ(2);
+      }
+      M68K_SET_IRQ(0);
+      last_last_irq = 0;
     }
     /*else {
-      m68k_set_irq(0);
+      if (last_irq != 0) {
+        M68K_SET_IRQ(0);
+        last_last_irq = last_irq;
+        last_irq = 0;
+      }
     }*/
 
     while (get_key_char(&c, &c_code, &c_type)) {
@@ -317,8 +393,9 @@ int main(int argc, char *argv[]) {
               printf("unknown.\n");
               break;
           }*/
-          if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled) {
-            m68k_set_irq(2);
+          if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled && last_irq != 2) {
+            //last_irq = 0;
+            //M68K_SET_IRQ(2);
           }
         }
       }
@@ -390,6 +467,8 @@ void cpu_pulse_reset(void) {
   if (cfg->platform->handle_reset)
     cfg->platform->handle_reset(cfg);
 
+  
+  m68k_write_memory_16(INTENA, 0x7FFF);
   ovl = 1;
   m68k_write_memory_8(0xbfe201, 0x0001);  // AMIGA OVL
   m68k_write_memory_8(0xbfe001, 0x0001);  // AMIGA OVL high (ROM@0x0)
@@ -445,7 +524,7 @@ unsigned int m68k_read_memory_8(unsigned int address) {
     printf("BYTE read from DMAC @%.8X:", address);
     uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_BYTE);
     printf("%.2X\n", v);
-    m68k_end_timeslice();
+    M68K_END_TIMESLICE;
     cpu_emulation_running = 0;
     return v;
   }*/
@@ -478,19 +557,20 @@ unsigned int m68k_read_memory_8(unsigned int address) {
           send_keypress = 1;
       }
       if (send_keypress == 2) {
-        result |= 0x02;
+        //result |= 0x02;
         send_keypress = 0;
       }
       return result;
     }
     if (address == CIAADAT) {
-      if (send_keypress) {
+      //if (send_keypress) {
         uint8_t c = 0, t = 0;
         pop_queued_key(&c, &t);
         t ^= 0x01;
         result = ((c << 1) | t) ^ 0xFF;
         send_keypress = 2;
-      }
+        //M68K_SET_IRQ(0);
+      //}
       return result;
     }
   }
@@ -509,7 +589,7 @@ unsigned int m68k_read_memory_16(unsigned int address) {
     printf("WORD read from DMAC @%.8X:", address);
     uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_WORD);
     printf("%.2X\n", v);
-    m68k_end_timeslice();
+    M68K_END_TIMESLICE;
     cpu_emulation_running = 0;
     return v;
   }*/
@@ -558,7 +638,7 @@ unsigned int m68k_read_memory_32(unsigned int address) {
     printf("LONGWORD read from DMAC @%.8X:", address);
     uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_LONGWORD);
     printf("%.2X\n", v);
-    m68k_end_timeslice();
+    M68K_END_TIMESLICE;
     cpu_emulation_running = 0;
     return v;
   }*/
@@ -611,7 +691,7 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) {
   /*if (address >= 0xE90000 && address < 0xF00000) {
     printf("BYTE write to DMAC @%.8X: %.2X\n", address, value);
     cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_BYTE);
-    m68k_end_timeslice();
+    M68K_END_TIMESLICE;
     cpu_emulation_running = 0;
     return;
   }*/
@@ -636,7 +716,7 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) {
   /*if (address >= 0xE90000 && address < 0xF00000) {
     printf("WORD write to DMAC @%.8X: %.4X\n", address, value);
     cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_WORD);
-    m68k_end_timeslice();
+    M68K_END_TIMESLICE;
     cpu_emulation_running = 0;
     return;
   }*/
@@ -672,7 +752,7 @@ void m68k_write_memory_32(unsigned int address, unsigned int value) {
   /*if (address >= 0xE90000 && address < 0xF00000) {
     printf("LONGWORD write to DMAC @%.8X: %.8X\n", address, value);
     cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_LONGWORD);
-    m68k_end_timeslice();
+    M68K_END_TIMESLICE;
     cpu_emulation_running = 0;
     return;
   }*/