X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fv63701.cpp;fp=src%2Fv63701.cpp;h=ea225bd0c6c7642bdfe3ec8df4d013322762ca1e;hb=be67039a7ed493081dd1503f94cdfae4dd4d965e;hp=b76063fccc168a931ee92d83e1d8c63b620a0cf9;hpb=44a4bdffcaf520bc1681fcc0fd330460cd49129f;p=thunder diff --git a/src/v63701.cpp b/src/v63701.cpp index b76063f..ea225bd 100644 --- a/src/v63701.cpp +++ b/src/v63701.cpp @@ -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 // for printf() #define WriteLog printf #endif @@ -94,10 +95,12 @@ #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; \ @@ -110,7 +113,9 @@ // 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