diff --git a/GimliDS.nds b/GimliDS.nds index f14f2aa..183d2e7 100644 Binary files a/GimliDS.nds and b/GimliDS.nds differ diff --git a/Makefile b/Makefile index 5414d0a..0752ffc 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ include $(DEVKITARM)/ds_rules export TARGET := GimliDS export TOPDIR := $(CURDIR) -export VERSION := 0.8a +export VERSION := 0.8b ICON := -b $(CURDIR)/C64_icon.bmp "GimliDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/GimliDS" diff --git a/arm9/source/Display.cpp b/arm9/source/Display.cpp index 6d715d9..e581060 100644 --- a/arm9/source/Display.cpp +++ b/arm9/source/Display.cpp @@ -48,6 +48,7 @@ u8 floppy_sound_counter = 0; +u8 bDebugDisplay = 0; // "Colodore" palette uint8_t palette_red[16] = { @@ -449,15 +450,16 @@ int i = 0; int debug[8]={0,0,0,0,0,0,0,0}; void C64Display::Speedometer(int speed) { -#if 0 char tmp[34]; - sprintf(tmp, "%-8d", speed); - DSPrint(19, 1, 6, tmp); + if (bDebugDisplay) + { + sprintf(tmp, "%-8d", speed); + DSPrint(19, 1, 6, tmp); - sprintf(tmp, "%-8d %-8d %-6d %-6d", debug[0],debug[1],debug[2],debug[3]); - DSPrint(0, 0, 6, tmp); -#endif + sprintf(tmp, "%-8d %-8d %-6d %-6d", debug[0],debug[1],debug[2],debug[3]); + DSPrint(0, 0, 6, tmp); + } show_joysticks(); show_shift_key(); diff --git a/arm9/source/VIC.cpp b/arm9/source/VIC.cpp index 6e03310..471aeac 100644 --- a/arm9/source/VIC.cpp +++ b/arm9/source/VIC.cpp @@ -3,12 +3,12 @@ // // As GimliDS is a port of the Frodo emulator for the DS/DSi/XL/LL handhelds, // any copying or distribution of this emulator, its source code and associated -// readme files, with or without modification, are permitted per the original +// readme files, with or without modification, are permitted per the original // Frodo emulator license shown below. Hugest thanks to Christian Bauer for his // efforts to provide a clean open-source emulation base for the C64. // -// Numerous hacks and 'unsafe' optimizations have been performed on the original -// Frodo emulator codebase to get it running on the small handheld system. You +// Numerous hacks and 'unsafe' optimizations have been performed on the original +// Frodo emulator codebase to get it running on the small handheld system. You // are strongly encouraged to seek out the official Frodo sources if you're at // all interested in this emulator code. // @@ -358,7 +358,7 @@ void MOS6569::Reset(void) total_frames = 0; frame_skipped = false; raster_y = 0xffff; - + // Clear foreground mask memset(fore_mask_buf, 0, DISPLAY_X/8); } @@ -874,7 +874,7 @@ inline void MOS6569::vblank(void) if ((total_frames % 3) == 0) frame_skipped = 0; // But every so often toss in an odd frame } } - + the_c64->VBlank(!frame_skipped); } @@ -894,10 +894,10 @@ inline void MOS6569::el_std_text(uint8 *p, uint8 *q, uint8 *r) for (int i=0; i<40; i++) { uint8 data = r[i] = q[mp[i] << 3]; - + if (!data) { - *lp++ = b0c_color32; + *lp++ = b0c_color32; *lp++ = b0c_color32; } else @@ -968,12 +968,12 @@ inline void MOS6569::el_std_bitmap(uint8 *p, uint8 *q, uint8 *r) uint8 *mp = matrix_line; // Loop for 40 characters - for (int i=0; i<40; i++, q+=8) + for (int i=0; i<40; i++, q+=8) { uint8 data = r[i] = *q; uint8 color = mp[i] >> 4; uint8 bcolor = mp[i] & 15; - + *lp++ = TextColorTable[color][bcolor][data>>4].b; *lp++ = TextColorTable[color][bcolor][data&0xf].b; } @@ -995,13 +995,13 @@ inline void MOS6569::el_mc_bitmap(uint8 *p, uint8 *q, uint8 *r) uint32 bg32 = (b0c_color << 24) | (b0c_color << 16) | (b0c_color << 8) | b0c_color; // Loop for 40 characters - for (int i=0; i<40; i++, q+=8) + for (int i=0; i<40; i++, q+=8) { uint8 color, acolor, bcolor; uint8 data = *q; r[i] = (data & 0xaa) | (data & 0xaa) >> 1; - + if (!data) { *wp++ = bg32; @@ -1014,7 +1014,7 @@ inline void MOS6569::el_mc_bitmap(uint8 *p, uint8 *q, uint8 *r) bcolor = mp[i] & 0xf; lookup[2] = (bcolor << 8) | bcolor; acolor = cp[i] & 0xf; - lookup[3] = (acolor << 8) | acolor; + lookup[3] = (acolor << 8) | acolor; *wp++ = lookup[(data >> 6) & 3] | (lookup[(data >> 4) & 3] << 16); *wp++ = lookup[(data >> 2) & 3] | (lookup[(data >> 0) & 3] << 16); @@ -1035,7 +1035,7 @@ inline void MOS6569::el_ecm_text(uint8 *p, uint8 *q, uint8 *r) uint8 *bcp = &b0c; // Loop for 40 characters - for (int i=0; i<40; i++) + for (int i=0; i<40; i++) { uint8 data = r[i] = mp[i]; uint8 color = cp[i]; @@ -1097,11 +1097,13 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) unsigned spr_coll=0, gfx_coll=0; // Draw each active sprite - for (unsigned snum = 0; snum < 8; ++snum) { + for (unsigned snum = 0; snum < 8; ++snum) + { uint8_t sbit = 1 << snum; // Is sprite visible? - if ((sprite_on & sbit) && mx[snum] < DISPLAY_X-32) { + if ((sprite_on & sbit) && mx[snum] < DISPLAY_X-32) + { uint8_t *p = chunky_ptr + mx[snum] + 8; uint8_t *q = spr_coll_buf + mx[snum] + 8; @@ -1118,7 +1120,8 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) uint32_t fore_mask = (fmbp[0] << 24) | (fmbp[1] << 16) | (fmbp[2] << 8) | (fmbp[3] << 0); fore_mask = (fore_mask << sshift) | (fmbp[4] >> (8-sshift)); - if (mxe & sbit) { // X-expanded + if (mxe & sbit) // X-expanded + { if (mx[snum] >= DISPLAY_X-56) continue; @@ -1127,7 +1130,8 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) uint32_t fore_mask_r = (fmbp[4] << 24) | (fmbp[5] << 16) | (fmbp[6] << 8); fore_mask_r <<= sshift; - if (mmc & sbit) { // X-expanded multicolor mode + if (mmc & sbit) // X-expanded multicolor mode + { uint32_t plane0_l, plane0_r, plane1_l, plane1_r; // Expand sprite data @@ -1152,21 +1156,32 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } // Paint sprite - for (unsigned i = 0; i < 32; ++i, plane0_l <<= 1, plane1_l <<= 1, fore_mask <<= 1) { + for (unsigned i = 0; i < 32; ++i, plane0_l <<= 1, plane1_l <<= 1, fore_mask <<= 1) + { uint8_t col; - if (plane1_l & 0x80000000) { - if (plane0_l & 0x80000000) { + if (plane1_l & 0x80000000) + { + if (plane0_l & 0x80000000) + { col = mm1_color; - } else { + } + else + { col = color; } - } else { - if (plane0_l & 0x80000000) { + } + else + { + if (plane0_l & 0x80000000) + { col = mm0_color; - } else { + } + else + { continue; } } + if (q[i]) { // Obscured by higher-priority data? spr_coll |= q[i] | sbit; } else if ((fore_mask & 0x80000000) == 0) { @@ -1215,7 +1230,9 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } // Paint sprite - for (unsigned i = 0; i < 32; ++i, sdata_l <<= 1, fore_mask <<= 1) { + if (sdata_l) + for (unsigned i = 0; i < 32; ++i, sdata_l <<= 1, fore_mask <<= 1) + { if (sdata_l & 0x80000000) { if (q[i]) { // Obscured by higher-priority data? spr_coll |= q[i] | sbit; @@ -1225,8 +1242,12 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) q[i] |= sbit; } } - for (unsigned i = 32; i < 48; ++i, sdata_r <<= 1, fore_mask_r <<= 1) { - if (sdata_r & 0x80000000) { + + if (sdata_r) + for (unsigned i = 32; i < 48; ++i, sdata_r <<= 1, fore_mask_r <<= 1) + { + if (sdata_r & 0x80000000) + { if (q[i]) { // Obscured by higher-priority data? spr_coll |= q[i] | sbit; } else if ((fore_mask_r & 0x80000000) == 0) { @@ -1237,9 +1258,11 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } } - } else { // Unexpanded - - if (mmc & sbit) { // Unexpanded multicolor mode + } + else // Unexpanded + { + if (mmc & sbit) // Unexpanded multicolor mode + { uint32_t plane0, plane1; // Convert sprite chunky pixels to bitplanes @@ -1257,18 +1280,29 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } // Paint sprite - for (unsigned i = 0; i < 24; ++i, plane0 <<= 1, plane1 <<= 1, fore_mask <<= 1) { + if (plane0 || plane1) + for (unsigned i = 0; i < 24; ++i, plane0 <<= 1, plane1 <<= 1, fore_mask <<= 1) + { uint8_t col; - if (plane1 & 0x80000000) { - if (plane0 & 0x80000000) { + if (plane1 & 0x80000000) + { + if (plane0 & 0x80000000) + { col = mm1_color; - } else { + } + else + { col = color; } - } else { - if (plane0 & 0x80000000) { + } + else + { + if (plane0 & 0x80000000) + { col = mm0_color; - } else { + } + else + { continue; } } @@ -1279,9 +1313,9 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } q[i] |= sbit; } - - } else { // Unexpanded standard mode - + } + else // Unexpanded standard mode + { // Collision with graphics? if (fore_mask & sdata) { gfx_coll |= sbit; @@ -1293,8 +1327,11 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } // Paint sprite - for (unsigned i = 0; i < 24; ++i, sdata <<= 1, fore_mask <<= 1) { - if (sdata & 0x80000000) { + if (sdata) + for (unsigned i = 0; i < 24; ++i, sdata <<= 1, fore_mask <<= 1) + { + if (sdata & 0x80000000) + { if (q[i]) { // Obscured by higher-priority data? spr_coll |= q[i] | sbit; } else if ((fore_mask & 0x80000000) == 0) { @@ -1309,7 +1346,8 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } // Check sprite-sprite collisions - if (spr_coll) { + if (spr_coll) + { uint8_t old_clx_spr = clx_spr; clx_spr |= spr_coll; if (old_clx_spr == 0) { // Interrupt on first detected collision @@ -1322,7 +1360,8 @@ ITCM_CODE void el_sprites(uint8 *chunky_ptr) } // Check sprite-background collisions - if (gfx_coll) { + if (gfx_coll) + { uint8_t old_clx_bgr = clx_bgr; clx_bgr |= gfx_coll; if (old_clx_bgr == 0) { // Interrupt on first detected collision @@ -1350,13 +1389,13 @@ inline int MOS6569::el_update_mc(int raster) uint8 raster8bit = raster & 0xff; // Increment sprite data counters - for (i=0, j=1; i<8; i++, j<<=1) + for (i=0, j=1; i<8; i++, j<<=1) { // Sprite enabled? if (spren & j) { // Yes, activate if Y position matches raster counter - if (my[i] == raster8bit) + if (my[i] == raster8bit) { mc[i] = 0; spron |= j; @@ -1370,13 +1409,13 @@ spr_off: { if (sprye & j) // Y expansion { - if (!((my[i] ^ raster8bit) & 1)) + if (!((my[i] ^ raster8bit) & 1)) { cycles_used++; if (++mc[i] == 21) spron &= ~j; } - } - else + } + else { cycles_used++; if (++mc[i] == 21) spron &= ~j; @@ -1421,7 +1460,7 @@ int MOS6569::EmulateLine(void) bad_lines_enabled = ctrl1 & 0x10; // Skip frame? Only calculate Bad Lines then - if (frame_skipped) + if (frame_skipped) { if (raster >= FIRST_DMA_LINE && raster <= LAST_DMA_LINE && ((raster & 7) == y_scroll) && bad_lines_enabled) { is_bad_line = true; @@ -1431,7 +1470,7 @@ int MOS6569::EmulateLine(void) } // Within the visible range? - if (raster >= FIRST_DISP_LINE && raster <= LAST_DISP_LINE) + if (raster >= FIRST_DISP_LINE && raster <= LAST_DISP_LINE) { u8 bSkipDraw = 0; // Our output goes here @@ -1468,7 +1507,7 @@ int MOS6569::EmulateLine(void) if (raster == dy_start && (ctrl1 & 0x10)) // Don't turn off border if DEN bit cleared border_on = false; - if (!border_on) + if (!border_on) { // Display window contents uint8 *p = chunky_ptr + COL40_XSTART; // Pointer in chunky display buffer @@ -1485,11 +1524,12 @@ int MOS6569::EmulateLine(void) p++; } - if (display_state) { - switch (display_idx) { - + if (display_state) + { + switch (display_idx) + { case 0: // Standard text - if (x_scroll & 3) + if (x_scroll & 3) { el_std_text(text_chunky_buf, char_base + rc, r); // Experimentally, this is slightly faster than memcpy() @@ -1502,7 +1542,7 @@ int MOS6569::EmulateLine(void) break; case 1: // Multicolor text - if (x_scroll & 3) + if (x_scroll & 3) { el_mc_text(text_chunky_buf, char_base + rc, r); // Experimentally, this is slightly faster than memcpy() @@ -1515,7 +1555,7 @@ int MOS6569::EmulateLine(void) break; case 2: // Standard bitmap - if (x_scroll & 3) + if (x_scroll & 3) { el_std_bitmap(text_chunky_buf, bitmap_base + (vc << 3) + rc, r); // Experimentally, this is slightly faster than memcpy() @@ -1528,7 +1568,7 @@ int MOS6569::EmulateLine(void) break; case 3: // Multicolor bitmap - if (x_scroll & 3) + if (x_scroll & 3) { el_mc_bitmap(text_chunky_buf, bitmap_base + (vc << 3) + rc, r); // Experimentally, this is slightly faster than memcpy() @@ -1541,7 +1581,7 @@ int MOS6569::EmulateLine(void) break; case 4: // ECM text - if (x_scroll & 3) + if (x_scroll & 3) { el_ecm_text(text_chunky_buf, char_base + rc, r); // Experimentally, this is slightly faster than memcpy() @@ -1561,9 +1601,9 @@ int MOS6569::EmulateLine(void) vc += 40; } - else + else { // Idle state graphics - switch (display_idx) + switch (display_idx) { case 0: // Standard text case 1: // Multicolor text @@ -1612,7 +1652,7 @@ int MOS6569::EmulateLine(void) // Draw sprites // Clear sprite collision buffer - but only if we have spites to draw on this line - if (sprite_on) + if (sprite_on) { memset((uint32 *)spr_coll_buf, 0x00, sizeof(spr_coll_buf)); el_sprites(chunky_ptr); @@ -1637,7 +1677,7 @@ int MOS6569::EmulateLine(void) u16 *p16 = (u16 *) p; *p16++ = c16; *p16++ = c16; - *p16 = c16; + *p16 = c16; } else { @@ -1646,7 +1686,7 @@ int MOS6569::EmulateLine(void) *p16++ = c16; *p16++ = c16; p = (u8 *) p16; - *p = ec_color; + *p = ec_color; } // Get us onto an even alignment and do 32-bits for added speed @@ -1664,11 +1704,11 @@ int MOS6569::EmulateLine(void) *p32++ = c; *p32++ = c; p = (u8 *) p32; - *p = ec_color; + *p = ec_color; } } } - else + else { // Display border - directly to screen! bSkipDraw = 1; @@ -1687,7 +1727,7 @@ int MOS6569::EmulateLine(void) if (raster >= FIRST_DMA_LINE-1 && raster <= LAST_DMA_LINE-1 && (((raster+1) & 7) == y_scroll) && bad_lines_enabled) rc = 0; - + // Not end of screen... output the next scanline as it will be 'stale' and not cached... // This also helps with tearing as we'll be outputting the 'stale' (last frame) line while the new frame is drawing. if (!frame_skipped) @@ -1698,7 +1738,6 @@ int MOS6569::EmulateLine(void) } } } - VIC_nop: // Skip this if all sprites are off diff --git a/arm9/source/diskmenu.cpp b/arm9/source/diskmenu.cpp index 7b9adbf..8f08e7e 100644 --- a/arm9/source/diskmenu.cpp +++ b/arm9/source/diskmenu.cpp @@ -49,6 +49,8 @@ char strBuf[40]; #define WAITVBL swiWaitForVBlank();swiWaitForVBlank();swiWaitForVBlank(); +extern u8 bDebugDisplay; + /********************************************************************************* * Show The 14 games on the list to allow the user to choose a new game. ********************************************************************************/ @@ -113,7 +115,7 @@ int Filescmp (const void *c1, const void *c2) /********************************************************************************* * Find files (TAP/TZX/Z80/SNA) available - sort them for display. ********************************************************************************/ -void speccySEFindFiles(u8 bTapeOnly) +void gimliDSFindFiles(u8 bTapeOnly) { u32 uNbFile; DIR *dir; @@ -146,7 +148,7 @@ void speccySEFindFiles(u8 bTapeOnly) { if ( (strcasecmp(strrchr(szFile, '.'), ".D64") == 0) ) { strcpy(gpFic[uNbFile].szName,szFile); - gpFic[uNbFile].uType = SPECCY_FILE; + gpFic[uNbFile].uType = NORMALFILE; uNbFile++; countZX++; } @@ -167,7 +169,7 @@ void speccySEFindFiles(u8 bTapeOnly) // ---------------------------------------------------------------- // Let the user select a new game (rom) file and load it up! // ---------------------------------------------------------------- -u8 speccySELoadFile(u8 bTapeOnly) +u8 gimliDSLoadFile(u8 bTapeOnly) { bool bDone=false; u16 ucHaut=0x00, ucBas=0x00,ucSHaut=0x00, ucSBas=0x00, romSelected= 0, firstRomDisplay=0,nbRomPerPage, uNbRSPage; @@ -177,7 +179,7 @@ u8 speccySELoadFile(u8 bTapeOnly) // Show the menu... while ((keysCurrent() & (KEY_TOUCH | KEY_START | KEY_SELECT | KEY_A | KEY_B))!=0); - speccySEFindFiles(bTapeOnly); + gimliDSFindFiles(bTapeOnly); ucGameChoice = -1; @@ -333,13 +335,14 @@ u8 speccySELoadFile(u8 bTapeOnly) { bDone=true; if (keysCurrent() & KEY_X) retVal = 2; else retVal = 1; + if (keysCurrent() & KEY_Y) bDebugDisplay = 1; else bDebugDisplay = 0; ucGameChoice = ucGameAct; WAITVBL; } else { chdir(gpFic[ucGameAct].szName); - speccySEFindFiles(bTapeOnly); + gimliDSFindFiles(bTapeOnly); ucGameAct = 0; nbRomPerPage = (countZX>=14 ? 14 : countZX); uNbRSPage = (countZX>=5 ? 5 : countZX); @@ -597,7 +600,7 @@ u8 DisketteMenu(C64 *the_c64) case MENU_ACTION_DRIVE8: BottomScreenMainMenu(); - retVal = speccySELoadFile(0); + retVal = gimliDSLoadFile(0); if (ucGameChoice >= 0) { retVal = 1; @@ -609,7 +612,7 @@ u8 DisketteMenu(C64 *the_c64) case MENU_ACTION_DRIVE9: BottomScreenMainMenu(); - retVal = speccySELoadFile(0); + retVal = gimliDSLoadFile(0); if (ucGameChoice >= 0) { retVal = 1; diff --git a/arm9/source/diskmenu.h b/arm9/source/diskmenu.h index 6121001..acf7f15 100644 --- a/arm9/source/diskmenu.h +++ b/arm9/source/diskmenu.h @@ -1,7 +1,7 @@ #define MAX_FILES 2048 #define MAX_FILENAME_LEN 256 -#define SPECCY_FILE 0x01 +#define NORMALFILE 0x01 #define DIRECTORY 0x02 class C64; extern void DSPrint(int iX,int iY,int iScr,char *szMessage);