]> Shamusworld >> Repos - thunder/blobdiff - src/v63701.cpp
Emulator working with YM2151 and V63701 emus in place.
[thunder] / src / v63701.cpp
index b76063fccc168a931ee92d83e1d8c63b620a0cf9..ea225bd0c6c7642bdfe3ec8df4d013322762ca1e 100644 (file)
@@ -37,7 +37,7 @@
 // conversion to macro style opcodes is completed. :-)
 // [DONE--remain to be seen if there is any performance increase]
 
-//#define __DEBUG__
+#define __DEBUG__
 #define TEST_DONT_BRANCH_OPTIMIZATION
 
 #include "v63701.h"
@@ -46,6 +46,7 @@
 #ifdef __DEBUG__
 #include "dis63701.h"
 //#include "log.h"
+#include <stdio.h>             // for printf()
 #define WriteLog printf
 #endif
 
 
 #define WRITE_BACK(d)          regs.WrMem(addr, (d))
 
-#define PULL                           regs.RdMem(regs.s++)
-#define PUSH(r)                                regs.WrMem(--regs.s, (r))
-#define PULL16                         RdMemW(regs.s);         regs.s += 2
-#define PUSH16(r)                      regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8)
+// This is correct; PUSH writes the location *then* decrements the stack
+// pointer, and PULL does the opposite. Verified from the data sheet.
+#define PULL                           regs.RdMem(++regs.s)
+#define PUSH(r)                                regs.WrMem(regs.s--, (r))
+#define PULL16                         RdMemW(++regs.s);       ++regs.s;
+#define PUSH16(r)                      regs.WrMem(regs.s--, (r) & 0xFF); regs.WrMem(regs.s--, (r) >> 8)
 
 #define PACK_FLAGS                     ((regs.cc & 0xC0) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
 #define UNPACK_FLAGS           flagH = (regs.cc & FLAG_H) >> 5; \
 // Private global variables
 
 static V63701REGS regs;
+//V63701REGS regs;
 static V63701REGS * regsPointer;
+//V63701REGS * regsPointer;
 static uint8_t flagH, flagI, flagN, flagZ, flagV, flagC;
 
 static uint8_t CPUCycles[256] = {
@@ -2591,10 +2596,11 @@ static void myMemcpy(void * dst, void * src, uint32_t size)
 
 #ifdef __DEBUG__
 //int instCount[256];
-//static bool logGo = false;
-static bool logGo = true;
+bool V63701LogGo = false;
+//static bool V63701LogGo = true;
 char instBuf[256];
-extern uint8_t memory[];
+extern uint8_t mcuMem[];
+uint8_t * memory = mcuMem;
 #endif
 //
 // Function to execute 63701 for "cycles" cycles
@@ -2618,8 +2624,14 @@ void Execute63701(V63701REGS * context, uint32_t cycles)
        while (regs.clock < endCycles)
 #endif
        {
+#if 0
+if (regs.pc == 0x8236)
+{
+       printf("V63701: $8236 called by $%04X...\n", RdMemW(regs.s));
+}
+#endif
 #ifdef __DEBUG__
-if (logGo)
+if (V63701LogGo)
 {
        Decode63701(memory, regs.pc, instBuf);
        WriteLog("%s\n", instBuf);
@@ -2674,7 +2686,7 @@ if (logGo)
                                }
                        }
 #ifdef __DEBUG__
-if (logGo)
+if (V63701LogGo)
 //     WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.d.acc.a, regs.d.acc.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (regs.cc & FLAG_H ? "H" : " "), (regs.cc & FLAG_I ? "I" : " "), (regs.cc & FLAG_N ? "N" : " "), (regs.cc & FLAG_Z ? "Z" : " "), (regs.cc & FLAG_V ? "V" : " "), (regs.cc & FLAG_C ? "C" : " "));
        WriteLog(" [PC=%04X S=%04X X=%04X A=%02X B=%02X CC=%s%s%s%s%s%s TCSR=%s%s%s%s%s%s%s%s CT=%04X OC=%04X]\n", regs.pc, regs.s, regs.x, regs.d.acc.a, regs.d.acc.b, (flagH ? "H" : "."), (flagI ? "I" : "."), (flagN ? "N" : "."), (flagZ ? "Z" : "."), (flagV ? "V" : "."), (flagC ? "C" : "."), (regs.tcsr.bit.icf ? "I" :"."), (regs.tcsr.bit.ocf ? "O" :"."), (regs.tcsr.bit.tof ? "T" :"."), (regs.tcsr.bit.eici ? "i" :"."), (regs.tcsr.bit.eoci ? "o" :"."), (regs.tcsr.bit.etoi ? "t" :"."), (regs.tcsr.bit.iedg ? "E" :"."), (regs.tcsr.bit.olvl ? "O" :"."), regs.counter.word, regs.outputCompare.word);
 #endif
@@ -2683,7 +2695,8 @@ if (logGo)
                if (regs.cpuFlags & V63701_ASSERT_LINE_RESET)
                {
 #ifdef __DEBUG__
-WriteLog("*** RESET LINE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** RESET LINE ASSERTED ***\n");
 #endif
                        regs.tcsr.byte = 0;
                        regs.tcsrWasRead = false;
@@ -2697,21 +2710,24 @@ WriteLog("*** RESET LINE ASSERTED ***\n");
                else if (regs.cpuFlags & V63701_ASSERT_LINE_NMI)
                {
 #ifdef __DEBUG__
-WriteLog("*** NMI LINE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** NMI LINE ASSERTED ***\n");
 #endif
                        HandleInterrupt(0xFFFC, V63701_ASSERT_LINE_NMI);
                }
                else if (regs.cpuFlags & V63701_ASSERT_LINE_IRQ)
                {
 #ifdef __DEBUG__
-WriteLog("*** IRQ LINE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** IRQ LINE ASSERTED ***\n");
 #endif
 //                     if (!(regs.cc & FLAG_I))                        // Process an interrupt (I=0)?
                        if (!flagI)                                                     // Process an interrupt (I=0)?
                        {
 #ifdef __DEBUG__
-WriteLog("    IRQ TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    IRQ TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF8, V63701_ASSERT_LINE_IRQ);
                        }
@@ -2719,14 +2735,16 @@ logGo = true;
                else if (regs.cpuFlags & V63701_ASSERT_INPUT_CAPTURE)
                {
 #ifdef __DEBUG__
-WriteLog("*** INPUT CAPTURE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** INPUT CAPTURE ASSERTED ***\n");
 #endif
                        // Process interrupt if no I inhibit set, & enable in TCSR is set
                        if (!flagI && regs.tcsr.bit.eici)
                        {
 #ifdef __DEBUG__
-WriteLog("    IC TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    IC TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF6, V63701_ASSERT_INPUT_CAPTURE);
                        }
@@ -2734,14 +2752,16 @@ logGo = true;
                else if (regs.cpuFlags & V63701_ASSERT_OUTPUT_COMPARE)
                {
 #ifdef __DEBUG__
-WriteLog("*** OUTPUT COMPARE ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** OUTPUT COMPARE ASSERTED ***\n");
 #endif
                        // Process interrupt if no I inhibit set, & enable in TCSR is set
                        if (!flagI && regs.tcsr.bit.eoci)
                        {
 #ifdef __DEBUG__
-WriteLog("    OC TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    OC TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF4, V63701_ASSERT_OUTPUT_COMPARE);
                        }
@@ -2749,14 +2769,16 @@ logGo = true;
                else if (regs.cpuFlags & V63701_ASSERT_TIMER_OVERFLOW)
                {
 #ifdef __DEBUG__
-WriteLog("*** TIMER OVER ASSERTED ***\n");
+if (V63701LogGo)
+       WriteLog("*** TIMER OVER ASSERTED ***\n");
 #endif
                        // Process interrupt if no I inhibit set, & enable in TCSR is set
                        if (!flagI && regs.tcsr.bit.etoi)
                        {
 #ifdef __DEBUG__
-WriteLog("    TO TAKEN!\n");
-logGo = true;
+if (V63701LogGo)
+       WriteLog("    TO TAKEN!\n");
+//V63701LogGo = true;
 #endif
                                HandleInterrupt(0xFFF2, V63701_ASSERT_TIMER_OVERFLOW);
                        }
@@ -2813,8 +2835,15 @@ uint8_t InternalRegisterRead(uint16_t address)
        {
        case 0x00:
                return regs.ddr1;
+       case 0x01:
+               return regs.ddr2;
        case 0x02:
-               return /*(regs.port1read & ~regs.ddr1) |*/ (regs.port1 & regs.ddr1);
+               return (V63701ReadPort1() & ~regs.ddr1) | (regs.port1data & regs.ddr1);
+//             return /*(regs.port1read & ~regs.ddr1) |*/ (regs.port1r & ~regs.ddr1);
+       case 0x03:
+               // Top 3 bits are MCU mode bits.
+               return (V63701ReadPort2() & ~regs.ddr2) | (regs.port2data & regs.ddr2);
+//             return /*(regs.port1read & ~regs.ddr1) |*/ (regs.port2r & ~regs.ddr2 & 0x1F);
        // Timer Control and Status Register
        case 0x08:
                regs.tcsrWasRead = true;
@@ -2855,6 +2884,8 @@ uint8_t InternalRegisterRead(uint16_t address)
 
 void InternalRegisterWrite(uint16_t address, uint8_t data)
 {
+       uint8_t writeData;
+
        switch (address & 0x1F)
        {
        case 0x00:
@@ -2864,10 +2895,13 @@ void InternalRegisterWrite(uint16_t address, uint8_t data)
                regs.ddr2 = data;
                break;
        case 0x02:
-               regs.port1 = data;
+               regs.port1data = data;
+               writeData = (V63701ReadPort1() & ~regs.ddr1) | (data & regs.ddr1);
+               V63701WritePort1(writeData);
                break;
        case 0x03:
-               regs.port2 = data;
+               // Port 2 only has 5 bits of output, top 3 are the MCU mode bits
+               regs.port2data = ((regs.port2data & ~regs.ddr2) | (data & regs.ddr2)) & 0x1F;
                break;
 //     case 0x05:
        // Timer Control and Status Register