From e68c334af31779da826f7876a3af487c2e96c3f6 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Wed, 13 Feb 2013 12:23:03 -0600 Subject: [PATCH] Fixed limits on cartridge space from 4MB to 6MB. Also fixed setting zoom levels in fullscreen (thanks to partycle for reporting!) and preliminary fixes to the M68K disassembler. Changed documentation to reflect next official release. --- docs/INSTALL | 2 +- docs/README | 2 +- docs/WHATSNEW | 8 ++ src/gui/mainwin.cpp | 12 +- src/jaguar.cpp | 22 ++-- src/m68000/m68kdasm.c | 257 +++++++++++++++++++++++++++++++----------- 6 files changed, 225 insertions(+), 78 deletions(-) diff --git a/docs/INSTALL b/docs/INSTALL index 0fb9032..751e06d 100644 --- a/docs/INSTALL +++ b/docs/INSTALL @@ -1,5 +1,5 @@ ---------------------------------------- -Virtual Jaguar v2.1.0 Qt release INSTALL +Virtual Jaguar v2.1.1 Qt release INSTALL ---------------------------------------- diff --git a/docs/README b/docs/README index 3d05119..63e1f19 100644 --- a/docs/README +++ b/docs/README @@ -1,5 +1,5 @@ ------------------------------------------- -Virtual Jaguar v2.1.0 GCC/Qt release README +Virtual Jaguar v2.1.1 GCC/Qt release README ------------------------------------------- -------------- diff --git a/docs/WHATSNEW b/docs/WHATSNEW index ab6d28b..b6ff928 100644 --- a/docs/WHATSNEW +++ b/docs/WHATSNEW @@ -1,3 +1,11 @@ +Virtual Jaguar v2.1.1 GCC/Qt +---------------------------- + +* Fixed 6MB cartridge space access limitation. 6MB carts should work now. + [Shamus] +* Fixed problem with JERRY interrupts corrupting the M68K core. [Shamus] + + Virtual Jaguar v2.1.0 GCC/Qt ---------------------------- diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index 85a94da..b17ef8d 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -24,7 +24,7 @@ // - Remove SDL dependencies (sound, mainly) from Jaguar core lib // - Fix inconsistency with trailing slashes in paths (eeproms needs one, software doesn't) // -// SFDX CODE: 9XF9TUHFM2359 +// SFDX CODE: S1E9T8H5M23YS // Uncomment this for debugging... //#define DEBUG @@ -875,8 +875,13 @@ void MainWin::SetFullScreen(bool state/*= true*/) // mainWinSize = size(); menuBar()->hide(); statusBar()->hide(); + x1Act->setDisabled(true); + x2Act->setDisabled(true); + x3Act->setDisabled(true); showFullScreen(); - int screenNum = QApplication::desktop()->screenNumber(videoWidget); + // This is needed because the fullscreen may happen on a different + // screen than screen 0: + int screenNum = QApplication::desktop()->screenNumber(videoWidget); QRect r = QApplication::desktop()->availableGeometry(screenNum); // double targetWidth = 320.0, targetHeight = (vjs.hardwareTypeNTSC ? 240.0 : 256.0); double targetWidth = (double)VIRTUAL_SCREEN_WIDTH, @@ -898,6 +903,9 @@ void MainWin::SetFullScreen(bool state/*= true*/) // Reset the video widget to windowed mode videoWidget->offset = 0; videoWidget->fullscreen = false; + x1Act->setDisabled(false); + x2Act->setDisabled(false); + x3Act->setDisabled(false); menuBar()->show(); statusBar()->show(); showNormal(); diff --git a/src/jaguar.cpp b/src/jaguar.cpp index 5f23f1b..9365b01 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -1496,11 +1496,12 @@ void JaguarDasm(uint32 offset, uint32 qt) uint8 JaguarReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) { uint8 data = 0x00; - offset &= 0xFFFFFF; - if (offset < 0x200000) - data = jaguarMainRAM[offset & 0x3FFFFF]; - else if ((offset >= 0x800000) && (offset < 0xC00000)) + + // First 2M is mirrored in the $0 - $7FFFFF range + if (offset < 0x800000) + data = jaguarMainRAM[offset & 0x1FFFFF]; + else if ((offset >= 0x800000) && (offset < 0xDFFF00)) data = jaguarMainROM[offset - 0x800000]; else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF)) data = CDROMReadByte(offset, who); @@ -1521,11 +1522,13 @@ uint8 JaguarReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) uint16 JaguarReadWord(uint32 offset, uint32 who/*=UNKNOWN*/) { offset &= 0xFFFFFF; - if (offset <= 0x1FFFFE) + + // First 2M is mirrored in the $0 - $7FFFFF range + if (offset < 0x800000) { return (jaguarMainRAM[(offset+0) & 0x1FFFFF] << 8) | jaguarMainRAM[(offset+1) & 0x1FFFFF]; } - else if ((offset >= 0x800000) && (offset <= 0xBFFFFE)) + else if ((offset >= 0x800000) && (offset < 0xDFFF00)) { offset -= 0x800000; return (jaguarMainROM[offset+0] << 8) | jaguarMainROM[offset+1]; @@ -1555,7 +1558,9 @@ void JaguarWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) WriteLog("JWB: Byte %02X written at %08X by %s\n", data, offset, whoName[who]);//*/ offset &= 0xFFFFFF; - if (offset < 0x200000) + + // First 2M is mirrored in the $0 - $7FFFFF range + if (offset < 0x800000) { jaguarMainRAM[offset & 0x1FFFFF] = data; return; @@ -1599,7 +1604,8 @@ if (offset == 0x0102)//64*4) offset &= 0xFFFFFF; - if (offset <= 0x1FFFFE) + // First 2M is mirrored in the $0 - $7FFFFF range + if (offset <= 0x7FFFFE) { /* GPU Table (CD BIOS) diff --git a/src/m68000/m68kdasm.c b/src/m68000/m68kdasm.c index 0720c40..74ee546 100644 --- a/src/m68000/m68kdasm.c +++ b/src/m68000/m68kdasm.c @@ -21,6 +21,9 @@ extern unsigned long IllegalOpcode(uint32_t opcode); extern cpuop_func * cpuFunctionTable[65536]; +// Prototypes +void HandleMovem(char * output, uint16_t data, int direction); + // Local "global" variables static long int m68kpc_offset; @@ -35,7 +38,8 @@ static long int m68kpc_offset; #endif -int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) +//int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) +int32_t ShowEA(int mnemonic, int reg, amodes mode, wordsizes size, char * buf) { uint16_t dp; int8_t disp8; @@ -66,7 +70,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) case Ad16: disp16 = get_iword_1(m68kpc_offset); m68kpc_offset += 2; addr = m68k_areg(regs,reg) + (int16_t)disp16; - sprintf(buffer,"(A%d,$%04X) == $%08lX", reg, disp16 & 0xFFFF, + sprintf(buffer,"(A%d,$%X) == $%lX", reg, disp16 & 0xFFFF, (unsigned long)addr); break; case Ad8r: @@ -100,7 +104,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) if (dp & 4) base += dispreg; addr = base + outer; - sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%08lX", name, + sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%lX", name, dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), (long)disp, (long)outer, (unsigned long)addr); @@ -108,7 +112,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) else { addr = m68k_areg(regs,reg) + (int32_t)((int8_t)disp8) + dispreg; - sprintf (buffer,"(A%d, %c%d.%c*%d, $%02X) == $%08lX", reg, + sprintf (buffer,"(A%d, %c%d.%c*%d, $%X) == $%lX", reg, dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp8, (unsigned long)addr); } @@ -117,7 +121,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) addr = m68k_getpc() + m68kpc_offset; disp16 = get_iword_1(m68kpc_offset); m68kpc_offset += 2; addr += (int16_t)disp16; - sprintf(buffer,"(PC,$%04X) == $%08lX", disp16 & 0xffff,(unsigned long)addr); + sprintf(buffer,"(PC, $%X) == $%lX", disp16 & 0xFFFF, (unsigned long)addr); break; case PC8r: addr = m68k_getpc() + m68kpc_offset; @@ -160,39 +164,39 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) if (dp & 4) base += dispreg; addr = base + outer; - sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%08lX", name, + sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%lX", name, dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), (long)disp, (long)outer, (unsigned long)addr); } else { addr += (int32_t)((int8_t)disp8) + dispreg; - sprintf(buffer,"(PC, %c%d.%c*%d, $%02X) == $%08lX", dp & 0x8000 ? 'A' : 'D', + sprintf(buffer,"(PC, %c%d.%c*%d, $%X) == $%lX", dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp8, (unsigned long)addr); } break; case absw: - sprintf(buffer,"$%08lX", (unsigned long)(int32_t)(int16_t)get_iword_1(m68kpc_offset)); + sprintf(buffer,"$%lX", (unsigned long)(int32_t)(int16_t)get_iword_1(m68kpc_offset)); m68kpc_offset += 2; break; case absl: - sprintf(buffer,"$%08lX", (unsigned long)get_ilong_1(m68kpc_offset)); + sprintf(buffer,"$%lX", (unsigned long)get_ilong_1(m68kpc_offset)); m68kpc_offset += 4; break; case imm: switch (size) { case sz_byte: - sprintf(buffer,"#$%02X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFF)); + sprintf(buffer,"#$%X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFF)); m68kpc_offset += 2; break; case sz_word: - sprintf(buffer,"#$%04X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFFFF)); + sprintf(buffer,"#$%X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFFFF)); m68kpc_offset += 2; break; case sz_long: - sprintf(buffer,"#$%08lX", (unsigned long)(get_ilong_1(m68kpc_offset))); + sprintf(buffer,"#$%lX", (unsigned long)(get_ilong_1(m68kpc_offset))); m68kpc_offset += 4; break; default: @@ -202,36 +206,185 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) case imm0: offset = (int32_t)(int8_t)get_iword_1(m68kpc_offset); m68kpc_offset += 2; - sprintf (buffer,"#$%02X", (unsigned int)(offset & 0xFF)); + sprintf(buffer,"#$%X", (unsigned int)(offset & 0xFF)); break; case imm1: offset = (int32_t)(int16_t)get_iword_1(m68kpc_offset); m68kpc_offset += 2; - sprintf (buffer,"#$%04X", (unsigned int)(offset & 0xFFFF)); + + if (mnemonic == i_MVMEL) + { + HandleMovem(buffer, offset, 0); + } + else if (mnemonic == i_MVMLE) + { + HandleMovem(buffer, offset, 1); + } + else + sprintf(buffer,"#$%X", (unsigned int)(offset & 0xFFFF)); + break; case imm2: offset = (int32_t)get_ilong_1(m68kpc_offset); m68kpc_offset += 4; - sprintf(buffer,"#$%08lX", (unsigned long)offset); + sprintf(buffer,"#$%lX", (unsigned long)(offset & 0xFFFFFFFF)); break; case immi: offset = (int32_t)(int8_t)(reg & 0xFF); - sprintf(buffer,"#$%08lX", (unsigned long)offset); + sprintf(buffer,"#$%lX", (unsigned long)(offset & 0xFFFFFFFF)); break; default: break; } - if (buf == 0) - fprintf(f, "%s", buffer); - else - strcat(buf, buffer); +// if (buf == 0) +// fprintf(f, "%s", buffer); +// else + strcat(buf, buffer); return offset; } -//void m68k_disasm(FILE * f, uint32_t addr, uint32_t * nextpc, int cnt) +void HandleMovem(char * output, uint16_t data, int direction) +{ +#if 0 +static void d68000_movem_re_32(void) +{ + uint data = read_imm_16(); + char buffer[40]; + uint first; + uint run_length; + uint i; + + buffer[0] = 0; + + for(i=0; i<8; i++) + { + if (data & (1 << i)) // (15 - i) for pre-decr + { + first = i; + run_length = 0; + + for(i++; i<8; i++) + if (data & (1 << i)) // 15 - i + run_length++; + + if (buffer[0] != 0) + strcat(buffer, "/"); + + sprintf(buffer+strlen(buffer), "D%d", first); + + if (run_length > 0) + sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + } + } + + for(i=0; i<8; i++) + { + if (data & (1 << (i + 8))) // (7 - i) for pre-decr + { + first = i; + run_length = 0; + + for(i++; i<8; i++) + if (data & (1 << (i + 8))) // 7 - i + run_length++; + + if (buffer[0] != 0) + strcat(buffer, "/"); + + sprintf(buffer+strlen(buffer), "A%d", first); + + if (run_length > 0) + sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + } + } + + sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); +} +#else + uint16_t ascending[16] = { + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 }; + uint16_t descending[16] = { + 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100, + 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001 }; + + int i, j, first, runLength, firstPrint = 1; + char buf[16]; + uint16_t * bitMask; + + bitMask = (direction ? descending : ascending); + output[0] = 0; + +//printf("HM: data = $%X\n", data); +//$42E0 + // Handle D0-D7... + for(i=0; i<8; i++) + { +//printf(" D: i=%d\n", i); + if (data & bitMask[i]) + { + first = i; + runLength = 0; + +// while ((++i < 8) && (data & bitMask[i])) + for(j=i+1; j<8 && (data & bitMask[j]); j++) + runLength++; + + i += runLength; + + if (firstPrint) + firstPrint = 0; + else + strcat(output, "/"); + + sprintf(buf, "D%d", first); + strcat(output, buf); + + if (runLength > 0) + { + sprintf(buf, "-D%d", first + runLength); + strcat(output, buf); + } + } + } + + // Handle A0-A7... + for(i=0; i<8; i++) + { +//printf(" A: i=%d\n", i); + if (data & bitMask[i + 8]) + { + first = i; + runLength = 0; + +// while ((++i < 8) && (data & bitMask[i + 8])) + for(j=i+1; j<8 && (data & bitMask[j+8]); j++) + runLength++; + + i += runLength; + + if (firstPrint) + firstPrint = 0; + else + strcat(output, "/"); + + sprintf(buf, "A%d", first); + strcat(output, buf); + + if (runLength > 0) + { + sprintf(buf, "-A%d", first + runLength); + strcat(output, buf); + } + } + } +#endif +} + + unsigned int m68k_disasm(char * output, uint32_t addr, uint32_t * nextpc, int cnt) { char f[256], str[256]; @@ -252,24 +405,12 @@ unsigned int m68k_disasm(char * output, uint32_t addr, uint32_t * nextpc, int cn uint32_t opcode; const struct mnemolookup * lookup; struct instr * dp; -// sprintf(f, "%06lX: ", m68k_getpc() + m68kpc_offset); -// strcat(str, f); - -#if 0 - for(opwords=0; opwords<5; opwords++) - { - sprintf(f, "%04X ", get_iword_1(m68kpc_offset + opwords * 2)); - strcat(str, f); - } -#endif opcode = get_iword_1(m68kpc_offset); m68kpc_offset += 2; if (cpuFunctionTable[opcode] == IllegalOpcode) - { opcode = 0x4AFC; - } dp = table68k + opcode; @@ -279,24 +420,12 @@ unsigned int m68k_disasm(char * output, uint32_t addr, uint32_t * nextpc, int cn strcpy(instrname, lookup->name); ccpt = strstr(instrname, "cc"); - if (ccpt != 0) - { + if (ccpt) strncpy(ccpt, ccnames[dp->cc], 2); - } sprintf(f, "%s", instrname); strcat(str, f); -#if 0 - switch (dp->size) - { - case sz_byte: sprintf(f, ".B "); break; - case sz_word: sprintf(f, ".W "); break; - case sz_long: sprintf(f, ".L "); break; - default: sprintf(f, " "); break; - } - strcat(str, f); -#else switch (dp->size) { case sz_byte: strcat(str, ".B\t"); break; @@ -304,54 +433,50 @@ unsigned int m68k_disasm(char * output, uint32_t addr, uint32_t * nextpc, int cn case sz_long: strcat(str, ".L\t"); break; default: strcat(str, "\t"); break; } -#endif if (dp->suse) { f[0] = 0; newpc = m68k_getpc() + m68kpc_offset; - newpc += ShowEA(0, dp->sreg, dp->smode, dp->size, f); - strcat(str, f); + newpc += ShowEA(dp->mnemo, dp->sreg, dp->smode, dp->size, f); + + // Don't display if branch or BSR or MVMLE, but DO let this go + // if it's a DBRcc... +//This is still not right... !!! FIX !!! + if (!(ccpt && dp->mnemo == i_DBcc) && !((opcode & 0xFF00) == 0x6100)) +// && (ccpt && dp->mnemo == i_DBcc) + strcat(str, f); } -#if 1 if (dp->suse && dp->duse) - { -// sprintf(f, ","); -// strcat(str, f); strcat(str, ", "); - } -#endif if (dp->duse) { f[0] = 0; newpc = m68k_getpc() + m68kpc_offset; - newpc += ShowEA(0, dp->dreg, dp->dmode, dp->size, f); - strcat(str, f); + newpc += ShowEA(dp->mnemo, dp->dreg, dp->dmode, dp->size, f); + + if (!ccpt && !((opcode & 0xFF00) == 0x6100)) + strcat(str, f); } - if (ccpt != 0) + if (ccpt) { if (cctrue(dp->cc)) - sprintf(f, " == %08lX (TRUE)", (long)newpc); + sprintf(f, "$%lX (TRUE)", (long)newpc); else - sprintf(f, " == %08lX (FALSE)", (long)newpc); + sprintf(f, "$%lX (FALSE)", (long)newpc); strcat(str, f); } else if ((opcode & 0xFF00) == 0x6100) // BSR { - sprintf(f, " == %08lX", (long)newpc); + sprintf(f, "$%lX", (long)newpc); strcat(str, f); } - -// fprintf(f, "\n"); } -// if (nextpc) -// *nextpc = m68k_getpc() + m68kpc_offset; - long int numberOfBytes = m68kpc_offset - pcOffsetSave; for(opwords=0; opwords<5; opwords++) -- 2.37.2