Getting ready for the big 1.0 release!

This commit is contained in:
Dave Bernazzani 2025-05-07 07:51:30 -04:00
parent 77799f4952
commit 73b2e86c58
17 changed files with 111 additions and 58 deletions

View File

@ -9,7 +9,7 @@ include $(DEVKITARM)/ds_rules
export TARGET := GimliDS
export TOPDIR := $(CURDIR)
export VERSION := 0.9d
export VERSION := 1.0
ICON := -b $(CURDIR)/C64_icon.bmp "GimliDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/GimliDS"

View File

@ -124,6 +124,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
```
## Change Log
Version 1.0 release 08-May-2025 by wavemotion-dave
* Added TOGGLE ZOOM button map to scale screen 1:1 temporarily (to make text games readable)
* Another proper fix for CPU jump commands not handling the extra cycle it takes.
* A bit of polish and cleanup for the big first release!
Version 0.9d release 06-May-2025 by wavemotion-dave
* Added ability to remap the British Pound (£) symbol to one of the other rare missing keys (left arrow, up arrow, C=)
* Fix for CPU jump commands not handling the extra cycle it takes.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -72,8 +72,6 @@ u8 CompressBuffer[0x20000]; //128K more than enough
*/
C64::C64()
{
// The thread is not yet running
thread_running = false;
quit_thyself = false;
have_a_break = false;
@ -258,11 +256,14 @@ void C64::NewPrefs(Prefs *prefs)
TheDisplay->NewPrefs(prefs);
// Changed order of calls. If 1541 mode hasn't changed the order is insignificant.
if (prefs->TrueDrive) {
if (prefs->TrueDrive)
{
// New prefs have 1541 enabled ==> if old prefs had disabled free drives FIRST
TheIEC->NewPrefs(prefs);
TheJob1541->NewPrefs(prefs);
} else {
}
else
{
// New prefs has 1541 disabled ==> if old prefs had enabled free job FIRST
TheJob1541->NewPrefs(prefs);
TheIEC->NewPrefs(prefs);
@ -271,7 +272,8 @@ void C64::NewPrefs(Prefs *prefs)
TheSID->NewPrefs(prefs);
// Reset 1541 processor if turned on or off (to bring IEC lines back to sane state)
if (ThePrefs.TrueDrive != prefs->TrueDrive) {
if (ThePrefs.TrueDrive != prefs->TrueDrive)
{
TheCPU1541->AsyncReset();
}
}
@ -1103,6 +1105,13 @@ uint8 C64::poll_joystick(int port)
temp_offset = 24;
slide_dampen = 15;
break;
case KEY_MAP_ZOOM_SCR:
if (keysCurrent() & KEY_X)
{
toggle_zoom();
WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;
}
break;
// Handle all other keypresses... mark the key as pressed for the PollKeyboard() routine
default:

View File

@ -90,8 +90,7 @@ public:
void RemoveCart(void);
void LoadPRG(char *filename);
uint8 *RAM, *Basic, *Kernal,
*Char, *Color; // C64
uint8 *RAM, *Basic, *Kernal, *Char, *Color; // C64
uint8 *RAM1541, *ROM1541; // 1541
C64Display *TheDisplay;
@ -114,7 +113,6 @@ private:
uint8 poll_joystick(int port);
void main_loop(void);
bool thread_running; // Emulation thread is running
bool quit_thyself; // Emulation thread shall quit
bool have_a_break; // Emulation thread shall pause

View File

@ -703,7 +703,7 @@ void MOS6502_1541::illegal_op(uint8 op, uint16 at)
push_byte(tmp);
void MOS6502_1541::ext_opcode(void)
void MOS6502_1541::extended_opcode(void)
{
if (pc < 0xc000) {
illegal_op(0xf2, pc-1);
@ -737,6 +737,7 @@ int MOS6502_1541::EmulateLine(int cycles_left, int cpu_cycles)
uint8 tmp, tmp2;
uint16 adr;
int last_cycles = 0;
uint16 page_plus_cyc = 0;
// Any pending interrupts?
if (interrupt.intr_any) {

View File

@ -68,7 +68,7 @@ public:
MOS6502_1541(C64 *c64, Job1541 *job, C64Display *disp, uint8 *Ram, uint8 *Rom);
int EmulateLine(int cycles_left, int cpu_cycles); // Emulate until cycles_left underflows
void ext_opcode(void);
void extended_opcode(void);
void Reset(void);
void AsyncReset(void); // Reset the CPU asynchronously
void GetState(MOS6502State *s);
@ -84,7 +84,7 @@ public:
MOS6526_2 *TheCIA2; // Pointer to C64 CIA 2
uint8 IECLines; // State of IEC lines (bit 7 - DATA, bit 6 - CLK)
bool Idle; // true: 1541 is idle
uint8 Idle; // true: 1541 is idle
private:
uint8 read_byte(uint16 adr);
@ -120,8 +120,8 @@ private:
uint8 a, x, y, sp;
uint16_t pc;
uint32 cycle_counter;
int borrowed_cycles; // Borrowed cycles from next line
uint32 cycle_counter;// Track total cycles of 1541 emulation
int borrowed_cycles; // Borrowed cycles from next line
uint8 via1_pra; // PRA of VIA 1
uint8 via1_ddra; // DDRA of VIA 1

View File

@ -79,7 +79,8 @@
#include "Cartridge.h"
#include "mainmenu.h"
enum {
enum
{
INT_RESET = 3
};
@ -600,7 +601,7 @@ void MOS6510::illegal_op(uint8 op, uint16 at)
if (c_flag) tmp |= 0x01; \
push_byte(tmp);
void MOS6510::ext_opcode(void)
void MOS6510::extended_opcode(void)
{
if (pc < 0xe000) {
illegal_op(0xf2, pc-1);
@ -673,6 +674,7 @@ ITCM_CODE int MOS6510::EmulateLine(int cycles_left)
uint8 tmp, tmp2;
uint16 adr; // Used by read_adr_abs()!
int last_cycles = 0;
uint16 page_plus_cyc = 0;
// Any pending interrupts?
if (interrupt.intr_any)

View File

@ -40,13 +40,11 @@
#include "C64.h"
// Set this to 1 for more precise CPU cycle calculation
#ifndef PRECISE_CPU_CYCLES
#define PRECISE_CPU_CYCLES 0
#endif
// Interrupt types
enum {
INT_VICIRQ,
@ -55,7 +53,6 @@ enum {
// INT_RESET (private)
};
class MOS6569;
class MOS6581;
class MOS6526_1;
@ -85,8 +82,6 @@ public:
void ClearNMI(void);
void setCharVsIO(void);
int ExtConfig; // Memory configuration for ExtRead/WriteByte (0..7)
MOS6569 *TheVIC; // Pointer to VIC
MOS6581 *TheSID; // Pointer to SID
MOS6526_1 *TheCIA1; // Pointer to CIA 1
@ -95,7 +90,7 @@ public:
Cartridge *TheCart; // Pointer to cartridge object
private:
void ext_opcode(void);
void extended_opcode(void);
uint8 read_byte(uint16 adr);
uint8 read_byte_io(uint16 adr);
uint8 read_byte_io_cart(uint16 adr);

View File

@ -88,7 +88,7 @@
#if PRECISE_CPU_CYCLES
// Account for cyles due to crossing page boundaries
#define page_plus(exp, reg) \
(adr = exp, /*last_cycles -= (((adr & 0xff) + reg) & 0x100 ? 1:0),*/ adr + reg) // TODO: Fix last_cycles here...
(adr = exp, page_plus_cyc = ((adr & 0xff) + reg) & 0x100, adr + reg)
// Read absolute x-indexed operand
#define read_byte_abs_x() read_byte(page_plus(read_adr_abs(), x))
@ -134,6 +134,7 @@
while (true)
{
if (page_plus_cyc) {last_cycles++; page_plus_cyc=0;}
if ((cycles_left -= last_cycles) < 0)
{
borrowed_cycles = -cycles_left;
@ -142,6 +143,8 @@
#else // CPU is 1541
cpu_cycles += CycleDeltas[myConfig.cpuCycles];
MOS6510 *localCPU = the_c64->TheCPU;
if (page_plus_cyc) {last_cycles++; page_plus_cyc=0;}
cycle_counter += last_cycles; // In case we have any initial interrupt cycles
while ((cycles_left -= last_cycles) >= 0)
@ -1371,8 +1374,8 @@
illegal_op(read_byte(pc-1), pc-1);
break;
// Extension opcode
case 0xf2: ext_opcode(); break;
// Extension opcode - mostly for Kernal / 1541 hooks
case 0xf2: extended_opcode(); break;
}
#ifdef IS_CPU_1541

View File

@ -80,13 +80,14 @@ public:
u32 total_cart_size = 0;
u8 last_bank = 0;
u8 cart_type = 0;
// Memory mapping control lines
u8 notEXROM = true;
u8 notGAME = true;
u8 bank = 0; // Selected bank
u8 bTrueDriveRequired = false;
uint8 ram[256]; // Mostly for EasyFlash but can be used for any cart that maps some RAM
uint8_t * rom = nullptr; // Pointer to ROM contents
u8 notEXROM = true; // Cartridge /GAME control line
u8 notGAME = true; // Cartridge /GAME control line
u8 bank = 0; // Selected bank - only for cart types that support banking
u8 bTrueDriveRequired = false; // Magic Desk disk conversions need the scaffolding of True Drive to load the 'virtual disk'
uint8 ram[256]; // Mostly for EasyFlash but can be used for any cart that maps some RAM
uint8_t * rom = nullptr; // Pointer to ROM contents
};
@ -189,7 +190,7 @@ public:
};
// Ocean cartridge (banked 8K/16K ROM cartridge)
// Easy Flash cartridge (banked 16K ROM cartridge)
class CartridgeEasyFlash : public ROMCartridge {
public:
CartridgeEasyFlash(bool not_game, bool not_exrom);

View File

@ -299,6 +299,35 @@ ITCM_CODE void vblankIntr(void)
}
}
// Toggle full 320x256
static s16 last_xScale = 0;
static s16 last_yScale = 0;
static s16 last_xOffset = 0;
static s16 last_yOffset = 0;
__attribute__ ((noinline)) void toggle_zoom(void)
{
if (last_xScale == 0)
{
last_xScale = myConfig.scaleX;
last_yScale = myConfig.scaleY;
last_xOffset = myConfig.offsetX;
last_yOffset = myConfig.offsetY;
myConfig.scaleX = 320;
myConfig.scaleY = 200;
myConfig.offsetX = 60;
myConfig.offsetY = 24;
}
else
{
myConfig.scaleX = last_xScale;
myConfig.scaleY = last_yScale;
myConfig.offsetX = last_xOffset;
myConfig.offsetY = last_yOffset;
last_xScale = last_yScale = 0;
last_xOffset = last_yOffset = 0;
}
}
extern void InterruptHandler(void);
int init_graphics(void)
{
@ -313,7 +342,6 @@ int init_graphics(void)
REG_BLDCNT = BLEND_ALPHA | BLEND_SRC_BG2 | BLEND_DST_BG3;
REG_BLDALPHA = (8 << 8) | 8; // 50% / 50%
//set the first two banks as background memory and the third as sub background memory
//D is not used..if you need a bigger background then you will need to map
//more vram banks consecutivly (VRAM A-D are all 0x20000 bytes in size)
@ -621,7 +649,7 @@ void C64Display::PollKeyboard(uint8 *key_matrix, uint8 *rev_matrix, uint8 *joyst
tilex = m_tp.px;
tiley = m_tp.py;
if (tiley > 20) // We're in the keyboard area...
{
if (tiley < 44) // Big Key Row

View File

@ -70,5 +70,6 @@ public:
// Exported functions
extern long ShowRequester(const char *str, const char *button1, const char *button2 = NULL);
extern u8 issue_commodore_key;
extern void toggle_zoom(void);
#endif

View File

@ -55,13 +55,12 @@
#include "SID.h"
#include "Prefs.h"
#define FIXPOINT_PREC 16 // number of fractional bits used in fixpoint representation
#define PRECOMPUTE_RESONANCE
#define ldSINTAB 9 // size of sinus table (0 to 90 degrees)
#define FIXPOINT_PREC 16 // number of fractional bits used in fixpoint representation
#define PRECOMPUTE_RESONANCE // For a bit of added speed
#define ldSINTAB 9 // size of sinus table (0 to 90 degrees)
#include "FixPoint.h"
uint8 regs[32] __attribute__((section(".dtcm"))); // Copies of the 32 write-only SID registers
uint8 last_sid_byte __attribute__((section(".dtcm"))); // Last value written to SID
uint32_t sid_random_seed __attribute__((section(".dtcm"))); // Random seed - global so it's deterministic
@ -117,14 +116,18 @@ MOS6581::~MOS6581()
void MOS6581::Reset(void)
{
for (int i=0; i<32; i++)
{
regs[i] = 0;
}
last_sid_byte = 0;
fake_v3_count = 0x555555;
sid_random_seed = 1;
// Reset the renderer
if (the_renderer != NULL)
{
the_renderer->Reset();
}
}
@ -136,7 +139,9 @@ void MOS6581::NewPrefs(Prefs *prefs)
{
open_close_renderer(ThePrefs.SIDType, prefs->SIDType);
if (the_renderer != NULL)
{
the_renderer->NewPrefs(prefs);
}
}
@ -147,7 +152,9 @@ void MOS6581::NewPrefs(Prefs *prefs)
void MOS6581::PauseSound(void)
{
if (the_renderer != NULL)
{
the_renderer->Pause();
}
}
@ -158,7 +165,9 @@ void MOS6581::PauseSound(void)
void MOS6581::ResumeSound(void)
{
if (the_renderer != NULL)
{
the_renderer->Resume();
}
}
@ -260,11 +269,11 @@ void MOS6581::SetState(MOS6581State *ss)
** Renderer for digital SID emulation (SIDTYPE_DIGITAL)
**/
const uint32 SAMPLE_FREQ = 15600; // NDS Sample Rate - 50 frames x 312 scanlines = 15600 samples per second
const uint32 SID_FREQ = 985248; // SID frequency in Hz
const uint32 SID_CYCLES_FIX = ((SID_FREQ << 11)/SAMPLE_FREQ)<<5; // # of SID clocks per sample frame * 65536
const uint32 SID_CYCLES = SID_CYCLES_FIX << 16; // # of SID clocks per sample frame
const int SAMPLE_BUF_SIZE = 0x138*2;// Size of buffer for sampled voice (double buffered)
const uint32 SAMPLE_FREQ = 15600; // NDS Sample Rate - 50 frames x 312 scanlines = 15600 samples per second
const uint32 SID_FREQ = 985248; // SID frequency in Hz
const uint32 SID_CYCLES_FIX = ((SID_FREQ << 11)/SAMPLE_FREQ)<<5; // # of SID clocks per sample frame * 65536
const uint32 SID_CYCLES = SID_CYCLES_FIX << 16; // # of SID clocks per sample frame
const int SAMPLE_BUF_SIZE = 0x138*2; // Size of buffer for sampled voice (double buffered)
uint8 sample_vol_filt[SAMPLE_BUF_SIZE] __attribute__((section(".dtcm"))); // Buffer for sampled volumes and filter bits shifted up
int sample_in_ptr __attribute__((section(".dtcm"))); // Index in sample_vol_filt[] for writing
@ -297,8 +306,8 @@ enum {
// Structure for one voice
struct DRVoice {
int wave; // Selected waveform
int eg_state; // Current state of EG
int wave; // Selected waveform
int eg_state; // Current state of EG
DRVoice *mod_by; // Voice that modulates this one
DRVoice *mod_to; // Voice that is modulated by this one

View File

@ -1413,7 +1413,8 @@ int MOS6569::EmulateLine(void)
// Skip frame? Only calculate Bad Lines then
if (frame_skipped)
{
if (raster >= FIRST_DMA_LINE && raster <= LAST_DMA_LINE && ((raster & 7) == y_scroll) && bad_lines_enabled) {
if (raster >= FIRST_DMA_LINE && raster <= LAST_DMA_LINE && ((raster & 7) == y_scroll) && bad_lines_enabled)
{
is_bad_line = true;
cycles_left = BAD_CYCLES_PER_LINE;
}

View File

@ -565,7 +565,7 @@ void FindConfig(void)
struct options_t
{
const char *label;
const char *option[64];
const char *option[65];
u8 *option_val;
u8 option_max;
};
@ -578,7 +578,7 @@ struct options_t
"KEY A", "KEY B", "KEY C", "KEY D", "KEY E", "KEY F", "KEY G", "KEY H", "KEY I", "KEY J", "KEY K", "KEY L",\
"KEY M", "KEY N", "KEY O", "KEY P", "KEY Q", "KEY R", "KEY S", "KEY T", "KEY U", "KEY V", "KEY W", "KEY X",\
"KEY Y", "KEY Z", "KEY 1", "KEY 2", "KEY 3", "KEY 4", "KEY 5", "KEY 6", "KEY 7", "KEY 8", "KEY 9", "KEY 0",\
"PAN-UP 16", "PAN-UP 24", "PAN-DOWN 16", "PAN-DOWN 24"
"PAN-UP 16", "PAN-UP 24", "PAN-DOWN 16", "PAN-DOWN 24", "ZOOM TOGGLE"
const struct options_t Option_Table[1][20] =
@ -594,16 +594,15 @@ const struct options_t Option_Table[1][20] =
{"1541 CYCLES", {CYCLE_DELTA_STR}, &myConfig.flopCycles, 19},
{"POUND KEY", {"POUND", "LEFT ARROW", "UP ARROW", "C= COMMODORE"}, &myConfig.poundKey, 4},
{"D-PAD UP", {KEY_MAP_OPTIONS}, &myConfig.key_map[0], 64},
{"D-PAD DOWN", {KEY_MAP_OPTIONS}, &myConfig.key_map[1], 64},
{"D-PAD LEFT", {KEY_MAP_OPTIONS}, &myConfig.key_map[2], 64},
{"D-PAD RIGHT", {KEY_MAP_OPTIONS}, &myConfig.key_map[3], 64},
{"D-PAD UP", {KEY_MAP_OPTIONS}, &myConfig.key_map[0], 65},
{"D-PAD DOWN", {KEY_MAP_OPTIONS}, &myConfig.key_map[1], 65},
{"D-PAD LEFT", {KEY_MAP_OPTIONS}, &myConfig.key_map[2], 65},
{"D-PAD RIGHT", {KEY_MAP_OPTIONS}, &myConfig.key_map[3], 65},
{"A BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[4], 64},
{"B BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[5], 64},
{"X BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[6], 64},
{"Y BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[7], 64},
{"A BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[4], 65},
{"B BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[5], 65},
{"X BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[6], 65},
{"Y BUTTON", {KEY_MAP_OPTIONS}, &myConfig.key_map[7], 65},
{NULL, {"", ""}, NULL, 1},
}

View File

@ -98,8 +98,9 @@ extern struct Config_t myConfig;
#define KEY_MAP_PAN_UP24 61
#define KEY_MAP_PAN_DN16 62
#define KEY_MAP_PAN_DN24 63
#define KEY_MAP_ZOOM_SCR 64
#define KEY_MAP_MAX 64
#define KEY_MAP_MAX 65
#define JOYMODE_NORMAL 0
#define JOYMODE_SLIDE_N_GLIDE 1