OSDN Git Service

[VM][Z80][DEBUGGER] Call debugger even BUSREQ.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Thu, 7 Dec 2017 09:45:25 +0000 (18:45 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Thu, 7 Dec 2017 09:45:25 +0000 (18:45 +0900)
[VM][Z80] Fix crash without setting PIC.

source/src/vm/z80.cpp
source/src/vm/z80.h
source/src/vm/z80_base.cpp

index 03ad068..81a12fa 100644 (file)
@@ -171,6 +171,39 @@ void Z80::reset()
        icount = extra_icount = 0;
 }
 
+void Z80::debugger_hook(void)
+{
+#ifdef USE_DEBUGGER
+       bool now_debugging = d_debugger->now_debugging;
+       if(now_debugging) {
+               d_debugger->check_break_points(PC);
+               if(d_debugger->now_suspended) {
+                       osd->mute_sound();
+                       d_debugger->now_waiting = true;
+                       while(d_debugger->now_debugging && d_debugger->now_suspended) {
+                               osd->sleep(10);
+                       }
+                       d_debugger->now_waiting = false;
+               }
+               if(d_debugger->now_debugging) {
+                       d_mem = d_debugger;
+               } else {
+                       now_debugging = false;
+               }
+               
+               //d_debugger->add_cpu_trace(PC);
+               int first_icount = icount;
+               //pPPC = pPC;
+               if(now_debugging) {
+                       if(!d_debugger->now_going) {
+                               d_debugger->now_suspended = true;
+                       }
+                       d_mem = d_mem_stored;
+               }
+       }
+#endif
+}
+
 int Z80::run(int clock)
 {
        if(clock == -1) {
@@ -187,6 +220,7 @@ int Z80::run(int clock)
                        /*icount = */extra_icount = 0;
                        #ifdef USE_DEBUGGER
                                total_icount += passed_icount;
+                               debugger_hook();
                        #endif
                        return passed_icount;
                } else {
@@ -210,6 +244,9 @@ int Z80::run(int clock)
                
                if(busreq) {
                        // run dma once
+                       #ifdef USE_DEBUGGER
+                               debugger_hook();
+                       #endif
                        #ifdef SINGLE_MODE_DMA
                                if(d_dma) {
                                        d_dma->do_dma();
@@ -232,6 +269,7 @@ int Z80::run(int clock)
        }
 }
 
+
 void Z80::run_one_opecode()
 {
        // rune one opecode
@@ -343,7 +381,7 @@ void Z80::run_one_opecode()
                                d_dma->do_dma();
                        }
 #endif
-                       d_pic->notify_intr_ei();
+                       if(d_pic != NULL) d_pic->notify_intr_ei();
                        check_interrupt();
                        
                        if(now_debugging) {
@@ -375,7 +413,7 @@ void Z80::run_one_opecode()
                                d_dma->do_dma();
                        }
 #endif
-                       d_pic->notify_intr_ei();
+                       if(d_pic != NULL) d_pic->notify_intr_ei();
                        check_interrupt();
 #ifdef USE_DEBUGGER
                }
@@ -408,7 +446,11 @@ void Z80::check_interrupt()
                                // INTR
                                LEAVE_HALT();
                                PUSH(pc);
-                               PCD = WZ = d_pic->get_intr_ack() & 0xffff;
+                               if(d_pic != NULL) { // OK?
+                                       PCD = WZ = d_pic->get_intr_ack() & 0xffff;
+                               } else {
+                                       PCD = WZ = (PCD & 0xff00) | 0xcd;
+                               }
                                icount -= cc_op[0xcd] + cc_ex[0xff];
                                iff1 = iff2 = 0;
                                intr_req_bit &= ~1;
@@ -442,7 +484,8 @@ void Z80::check_interrupt()
                                // interrupt
                                LEAVE_HALT();
                                
-                               uint32_t vector = d_pic->get_intr_ack();
+                               uint32_t vector = 0xcd;
+                               if(d_pic != NULL) vector = d_pic->get_intr_ack();
                                if(im == 0) {
                                        // mode 0 (support NOP/JMP/CALL/RST only)
                                        switch(vector & 0xff) {
index 2387e9a..62ae114 100644 (file)
@@ -108,6 +108,7 @@ protected:
        void OP_ED(uint8_t code);
        void OP(uint8_t code);
        virtual void run_one_opecode();
+       virtual void debugger_hook(void);
        
        uint8_t SZ[256];                /* zero and sign flags */
        uint8_t SZ_BIT[256];    /* zero, sign and parity/overflow (=zero) flags for BIT opcode */
@@ -250,7 +251,7 @@ public:
                d_debugger = NULL;
                d_mem_stored = NULL;
                d_io_stored = NULL;
-               
+               d_pic = NULL;
                has_nsc800 = false;
                has_io_wait = false;
                has_memory_wait = false;
@@ -339,6 +340,7 @@ class Z80 : public Z80_BASE
 protected:
        void check_interrupt();
        void run_one_opecode() override;
+       void debugger_hook(void) override;
 public:
        Z80(VM* parent_vm, EMU* parent_emu);
        ~Z80();
index 9fad23e..c1685d0 100644 (file)
@@ -290,7 +290,7 @@ Z80_INLINE void Z80_BASE::OUT8(uint32_t addr, uint8_t val)
        POP(pc); \
        WZ = PC; \
        iff1 = iff2; \
-       d_pic->notify_intr_reti(); \
+       if(d_pic != NULL) d_pic->notify_intr_reti();    \
 } while(0)
 
 #define LD_R_A() do { \
@@ -2006,6 +2006,10 @@ int Z80_BASE::run(int clock)
                
                if(busreq) {
                        // run dma once
+                       // run dma once
+                       #ifdef USE_DEBUGGER
+                               debugger_hook();
+                       #endif
                        //#ifdef SINGLE_MODE_DMA
                                if(d_dma) {
                                        d_dma->do_dma();
@@ -2025,6 +2029,10 @@ int Z80_BASE::run(int clock)
        }
 }
 
+void Z80_BASE::debugger_hook(void)
+{
+}
+
 void Z80_BASE::run_one_opecode()
 {
        // rune one opecode
@@ -2040,7 +2048,7 @@ void Z80_BASE::run_one_opecode()
 #if HAS_LDAIR_QUIRK
                if(after_ldair) F &= ~PF;       // reset parity flag after LD A,I or LD A,R
 #endif
-               d_pic->notify_intr_ei();
+               if(d_pic != NULL) d_pic->notify_intr_ei();
        }
        
        // check interrupt
@@ -2059,7 +2067,11 @@ void Z80_BASE::run_one_opecode()
                                // INTR
                                LEAVE_HALT();
                                PUSH(pc);
-                               PCD = WZ = d_pic->get_intr_ack() & 0xffff;
+                               if(d_pic != NULL) { // OK?
+                                       PCD = WZ = d_pic->get_intr_ack() & 0xffff;
+                               } else {
+                                       PCD = WZ = (PCD & 0xff00) | 0xcd;
+                               }
                                icount -= cc_op[0xcd] + cc_ex[0xff];
                                iff1 = iff2 = 0;
                                intr_req_bit &= ~1;
@@ -2093,7 +2105,8 @@ void Z80_BASE::run_one_opecode()
                                // interrupt
                                LEAVE_HALT();
                                
-                               uint32_t vector = d_pic->get_intr_ack();
+                               uint32_t vector = 0xcd; // Default
+                               if(d_pic != NULL) vector = d_pic->get_intr_ack();
                                if(im == 0) {
                                        // mode 0 (support NOP/JMP/CALL/RST only)
                                        switch(vector & 0xff) {