mirror of
https://github.com/wavemotion-dave/SpeccySE.git
synced 2025-06-18 13:55:33 -04:00
Version 1.0 released! See readme.md file.
This commit is contained in:
parent
bdde6bed8c
commit
28d72d5ddb
BIN
SpeccySE.nds
BIN
SpeccySE.nds
Binary file not shown.
Binary file not shown.
1595
arm7/build/.map
1595
arm7/build/.map
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -198,6 +198,10 @@ u16 mixer_read __attribute__((section(".dtcm"))) = 0;
|
|||||||
u16 mixer_write __attribute__((section(".dtcm"))) = 0;
|
u16 mixer_write __attribute__((section(".dtcm"))) = 0;
|
||||||
s16 mixer[WAVE_DIRECT_BUF_SIZE+1];
|
s16 mixer[WAVE_DIRECT_BUF_SIZE+1];
|
||||||
|
|
||||||
|
|
||||||
|
// The games normally run at the proper 100% speed, but user can override from 80% to 120%
|
||||||
|
u16 GAME_SPEED_PAL[] __attribute__((section(".dtcm"))) = {655, 596, 547, 728, 818 };
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
// maxmod will call this routine when the buffer is half-empty and requests that
|
// maxmod will call this routine when the buffer is half-empty and requests that
|
||||||
// we fill the sound buffer with more samples. They will request 'len' samples and
|
// we fill the sound buffer with more samples. They will request 'len' samples and
|
||||||
@ -270,6 +274,32 @@ ITCM_CODE void processDirectAudio(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
// The user can override the core emulation speed from 80% to 120% to make games play faster/slow
|
||||||
|
// than normal. We must adjust the MaxMode sample frequency to match or else we will not have the
|
||||||
|
// proper number of samples in our sound buffer... this isn't perfect but it's reasonably good!
|
||||||
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
static u8 last_game_speed = 0;
|
||||||
|
static u32 sample_rate_adjust[] = {100, 110, 120, 90, 80};
|
||||||
|
void newStreamSampleRate(void)
|
||||||
|
{
|
||||||
|
if (last_game_speed != myConfig.gameSpeed)
|
||||||
|
{
|
||||||
|
last_game_speed = myConfig.gameSpeed;
|
||||||
|
mmStreamClose();
|
||||||
|
|
||||||
|
// Adjust the sample rate to match the core emulation speed... user can override from 80% to 120%
|
||||||
|
int new_sample_rate = (sample_rate * sample_rate_adjust[myConfig.gameSpeed]) / 100;
|
||||||
|
myStream.sampling_rate = new_sample_rate; // sample_rate for the ZX to match the AY/Beeper drivers
|
||||||
|
myStream.buffer_length = buffer_size; // buffer length = (512+16)
|
||||||
|
myStream.callback = OurSoundMixer; // set callback function
|
||||||
|
myStream.format = MM_STREAM_16BIT_STEREO; // format = stereo 16-bit
|
||||||
|
myStream.timer = MM_TIMER0; // use hardware timer 0
|
||||||
|
myStream.manual = false; // use automatic filling
|
||||||
|
mmStreamOpen(&myStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
// Setup the maxmod audio stream - this will be a 16-bit Stereo PCM output at 55KHz which
|
// Setup the maxmod audio stream - this will be a 16-bit Stereo PCM output at 55KHz which
|
||||||
// sounds about right for the ZX Spectrum AY chip (we mix in beeper tones as well)
|
// sounds about right for the ZX Spectrum AY chip (we mix in beeper tones as well)
|
||||||
@ -957,7 +987,7 @@ u8 __attribute__((noinline)) handle_meta_key(u8 meta_key)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_CHOICE_CASSETTE:
|
case MENU_CHOICE_CASSETTE:
|
||||||
if (speccy_mode <= MODE_SNA) // Only show if we have a tape loaded
|
if ((speccy_mode <= MODE_SNA) || (speccy_mode == MODE_BIOS)) // Only show if we have a tape loaded
|
||||||
{
|
{
|
||||||
CassetteMenu();
|
CassetteMenu();
|
||||||
}
|
}
|
||||||
@ -1110,6 +1140,8 @@ void SpeccySE_main(void)
|
|||||||
timingFrames = 0;
|
timingFrames = 0;
|
||||||
emuFps=0;
|
emuFps=0;
|
||||||
|
|
||||||
|
newStreamSampleRate();
|
||||||
|
|
||||||
// Force the sound engine to turn on when we start emulation
|
// Force the sound engine to turn on when we start emulation
|
||||||
bStartSoundEngine = 10;
|
bStartSoundEngine = 10;
|
||||||
|
|
||||||
@ -1160,7 +1192,19 @@ void SpeccySE_main(void)
|
|||||||
{
|
{
|
||||||
if (--bStartIn == 0)
|
if (--bStartIn == 0)
|
||||||
{
|
{
|
||||||
tape_play();
|
// ---------------------------------------------------------
|
||||||
|
// If we are running in ZX81 mode, we now copy the .P file
|
||||||
|
// into memory and the ZX81 emulation will take over...
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
if (speccy_mode == MODE_ZX81)
|
||||||
|
{
|
||||||
|
u8 *ptr = MemoryMap[16393>>14] + (16393&0x3FFF);
|
||||||
|
memcpy(ptr, ROM_Memory+0x4000, last_file_size-0x4000);
|
||||||
|
}
|
||||||
|
else // Otherwise, play the ZX Spectrum tape!
|
||||||
|
{
|
||||||
|
tape_play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,9 +1225,15 @@ void SpeccySE_main(void)
|
|||||||
{
|
{
|
||||||
BufferKey('J'); BufferKey(KBD_KEY_SYMBOL); BufferKey('P'); BufferKey(KBD_KEY_SYMBOL); BufferKey('P'); BufferKey(KBD_KEY_RET);
|
BufferKey('J'); BufferKey(KBD_KEY_SYMBOL); BufferKey('P'); BufferKey(KBD_KEY_SYMBOL); BufferKey('P'); BufferKey(KBD_KEY_RET);
|
||||||
}
|
}
|
||||||
if (myConfig.autoLoad && (myConfig.tapeSpeed == 0)) bStartIn = 2; // Start tape in 2 frames...
|
if (myConfig.autoLoad && (myConfig.tapeSpeed == 0)) bStartIn = 2; // Start tape in 2 seconds...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (speccy_mode == MODE_ZX81)
|
||||||
|
{
|
||||||
|
BufferKey('6'); BufferKey(254); BufferKey('6'); BufferKey(254); BufferKey('6'); BufferKey(254); BufferKey(KBD_KEY_RET); BufferKey(255); BufferKey(255); BufferKey(255); BufferKey(255); BufferKey(255);
|
||||||
|
BufferKey('M'); BufferKey(255); BufferKey('5'); BufferKey(254); BufferKey('0'); BufferKey(254); BufferKey('0'); BufferKey(254); BufferKey('0'); BufferKey(254); BufferKey(KBD_KEY_RET); BufferKey(255);
|
||||||
|
bStartIn = 10; // Start P-File in 10 seconds... (it takes 6-7 seconds to process those keys above... slow processing on the ZX81 emulation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1206,7 +1256,7 @@ void SpeccySE_main(void)
|
|||||||
//
|
//
|
||||||
// This is how we time frame-to frame to keep the game running at 50FPS
|
// This is how we time frame-to frame to keep the game running at 50FPS
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
while (TIMER2_DATA < 655*(timingFrames+1))
|
while (TIMER2_DATA < GAME_SPEED_PAL[myConfig.gameSpeed]*(timingFrames+1))
|
||||||
{
|
{
|
||||||
if (myGlobalConfig.showFPS == 2) break; // If Full Speed, break out...
|
if (myGlobalConfig.showFPS == 2) break; // If Full Speed, break out...
|
||||||
if (tape_is_playing())
|
if (tape_is_playing())
|
||||||
|
@ -106,6 +106,7 @@ extern u32 DX, DY;
|
|||||||
#define MODE_SNA 5
|
#define MODE_SNA 5
|
||||||
#define MODE_Z80 6
|
#define MODE_Z80 6
|
||||||
#define MODE_BIOS 7
|
#define MODE_BIOS 7
|
||||||
|
#define MODE_ZX81 8
|
||||||
|
|
||||||
#define WAITVBL swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank();
|
#define WAITVBL swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank();
|
||||||
|
|
||||||
|
@ -344,39 +344,57 @@ void speccySEFindFiles(u8 bTapeOnly)
|
|||||||
else {
|
else {
|
||||||
if ((strlen(szFile)>4) && (strlen(szFile)<(MAX_FILENAME_LEN-4)) && (szFile[0] != '.') && (szFile[0] != '_')) // For MAC don't allow files starting with an underscore
|
if ((strlen(szFile)>4) && (strlen(szFile)<(MAX_FILENAME_LEN-4)) && (szFile[0] != '.') && (szFile[0] != '_')) // For MAC don't allow files starting with an underscore
|
||||||
{
|
{
|
||||||
if (!bTapeOnly) // If we're loading tape files only, exclude .z80 and .sna snapshots
|
if (bTapeOnly == 2) // Load P files only
|
||||||
{
|
{
|
||||||
if ( (strcasecmp(strrchr(szFile, '.'), ".z80") == 0) ) {
|
if ( (strcasecmp(strrchr(szFile, '.'), ".p") == 0) ) {
|
||||||
strcpy(gpFic[uNbFile].szName,szFile);
|
strcpy(gpFic[uNbFile].szName,szFile);
|
||||||
gpFic[uNbFile].uType = SPECCY_FILE;
|
gpFic[uNbFile].uType = SPECCY_FILE;
|
||||||
uNbFile++;
|
uNbFile++;
|
||||||
countZX++;
|
countZX++;
|
||||||
}
|
}
|
||||||
if ( (strcasecmp(strrchr(szFile, '.'), ".sna") == 0) ) {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!bTapeOnly) // If we're loading tape files only, exclude .z80 and .sna snapshots
|
||||||
|
{
|
||||||
|
if ( (strcasecmp(strrchr(szFile, '.'), ".z80") == 0) ) {
|
||||||
|
strcpy(gpFic[uNbFile].szName,szFile);
|
||||||
|
gpFic[uNbFile].uType = SPECCY_FILE;
|
||||||
|
uNbFile++;
|
||||||
|
countZX++;
|
||||||
|
}
|
||||||
|
if ( (strcasecmp(strrchr(szFile, '.'), ".sna") == 0) ) {
|
||||||
|
strcpy(gpFic[uNbFile].szName,szFile);
|
||||||
|
gpFic[uNbFile].uType = SPECCY_FILE;
|
||||||
|
uNbFile++;
|
||||||
|
countZX++;
|
||||||
|
}
|
||||||
|
if ( (strcasecmp(strrchr(szFile, '.'), ".rom") == 0) ) {
|
||||||
|
strcpy(gpFic[uNbFile].szName,szFile);
|
||||||
|
gpFic[uNbFile].uType = SPECCY_FILE;
|
||||||
|
uNbFile++;
|
||||||
|
countZX++;
|
||||||
|
}
|
||||||
|
if ( (strcasecmp(strrchr(szFile, '.'), ".z81") == 0) ) {
|
||||||
|
strcpy(gpFic[uNbFile].szName,szFile);
|
||||||
|
gpFic[uNbFile].uType = SPECCY_FILE;
|
||||||
|
uNbFile++;
|
||||||
|
countZX++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( (strcasecmp(strrchr(szFile, '.'), ".tap") == 0) ) {
|
||||||
strcpy(gpFic[uNbFile].szName,szFile);
|
strcpy(gpFic[uNbFile].szName,szFile);
|
||||||
gpFic[uNbFile].uType = SPECCY_FILE;
|
gpFic[uNbFile].uType = SPECCY_FILE;
|
||||||
uNbFile++;
|
uNbFile++;
|
||||||
countZX++;
|
countZX++;
|
||||||
}
|
}
|
||||||
if ( (strcasecmp(strrchr(szFile, '.'), ".rom") == 0) ) {
|
if ( (strcasecmp(strrchr(szFile, '.'), ".tzx") == 0) ) {
|
||||||
strcpy(gpFic[uNbFile].szName,szFile);
|
strcpy(gpFic[uNbFile].szName,szFile);
|
||||||
gpFic[uNbFile].uType = SPECCY_FILE;
|
gpFic[uNbFile].uType = SPECCY_FILE;
|
||||||
uNbFile++;
|
uNbFile++;
|
||||||
countZX++;
|
countZX++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( (strcasecmp(strrchr(szFile, '.'), ".tap") == 0) ) {
|
|
||||||
strcpy(gpFic[uNbFile].szName,szFile);
|
|
||||||
gpFic[uNbFile].uType = SPECCY_FILE;
|
|
||||||
uNbFile++;
|
|
||||||
countZX++;
|
|
||||||
}
|
|
||||||
if ( (strcasecmp(strrchr(szFile, '.'), ".tzx") == 0) ) {
|
|
||||||
strcpy(gpFic[uNbFile].szName,szFile);
|
|
||||||
gpFic[uNbFile].uType = SPECCY_FILE;
|
|
||||||
uNbFile++;
|
|
||||||
countZX++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -781,6 +799,23 @@ void Sinclair1(void)
|
|||||||
myConfig.keymap[11] = 31; // NDS SELECT mapped to '1'
|
myConfig.keymap[11] = 31; // NDS SELECT mapped to '1'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5 (left), 6 (down), 7 (up), 8 (right)
|
||||||
|
void Cursors(void)
|
||||||
|
{
|
||||||
|
myConfig.keymap[0] = 37; // UP
|
||||||
|
myConfig.keymap[1] = 36; // DOWN
|
||||||
|
myConfig.keymap[2] = 35; // LEFT
|
||||||
|
myConfig.keymap[3] = 38; // RIGHT
|
||||||
|
myConfig.keymap[4] = 44; // Return
|
||||||
|
myConfig.keymap[5] = 43; // Space
|
||||||
|
myConfig.keymap[6] = 43; // Space
|
||||||
|
myConfig.keymap[7] = 43; // Space
|
||||||
|
myConfig.keymap[8] = 41; // NDS R Button mapped to SHIFT
|
||||||
|
myConfig.keymap[9] = 42; // NDS L Button mapped to SYMBOL
|
||||||
|
myConfig.keymap[10] = 40; // NDS START mapped to '0'
|
||||||
|
myConfig.keymap[11] = 31; // NDS SELECT mapped to '1'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetDefaultGlobalConfig(void)
|
void SetDefaultGlobalConfig(void)
|
||||||
{
|
{
|
||||||
@ -803,7 +838,7 @@ void SetDefaultGameConfig(void)
|
|||||||
myConfig.dpad = DPAD_NORMAL; // Normal DPAD use - mapped to joystick
|
myConfig.dpad = DPAD_NORMAL; // Normal DPAD use - mapped to joystick
|
||||||
myConfig.autoLoad = 1; // Default is to to auto-load TAP and TZX games
|
myConfig.autoLoad = 1; // Default is to to auto-load TAP and TZX games
|
||||||
myConfig.loadAs = 0; // Default load is 48K
|
myConfig.loadAs = 0; // Default load is 48K
|
||||||
myConfig.reserved2 = 0;
|
myConfig.gameSpeed = 0; // Default is 100% game speed
|
||||||
myConfig.reserved3 = 0;
|
myConfig.reserved3 = 0;
|
||||||
myConfig.reserved4 = 0;
|
myConfig.reserved4 = 0;
|
||||||
myConfig.reserved5 = 0;
|
myConfig.reserved5 = 0;
|
||||||
@ -891,8 +926,10 @@ const struct options_t Option_Table[2][20] =
|
|||||||
{"AUTO STOP", {"NO", "YES"}, &myConfig.autoStop, 2},
|
{"AUTO STOP", {"NO", "YES"}, &myConfig.autoStop, 2},
|
||||||
{"AUTO FIRE", {"OFF", "ON"}, &myConfig.autoFire, 2},
|
{"AUTO FIRE", {"OFF", "ON"}, &myConfig.autoFire, 2},
|
||||||
{"TAPE SPEED", {"NORMAL", "ACCELERATED"}, &myConfig.tapeSpeed, 2},
|
{"TAPE SPEED", {"NORMAL", "ACCELERATED"}, &myConfig.tapeSpeed, 2},
|
||||||
|
{"GAME SPEED", {"100%", "110%", "120%", "90%", "80%"}, &myConfig.gameSpeed, 5},
|
||||||
{"BUS CONTEND", {"NORMAL", "LIGHT", "HEAVY"}, &myConfig.contention, 3},
|
{"BUS CONTEND", {"NORMAL", "LIGHT", "HEAVY"}, &myConfig.contention, 3},
|
||||||
{"NDS D-PAD", {"NORMAL", "DIAGONALS", "CHUCKIE"}, &myConfig.dpad, 3},
|
{"NDS D-PAD", {"NORMAL", "DIAGONALS", "CHUCKIE"}, &myConfig.dpad, 3},
|
||||||
|
|
||||||
{NULL, {"", ""}, NULL, 1},
|
{NULL, {"", ""}, NULL, 1},
|
||||||
},
|
},
|
||||||
// Global Options
|
// Global Options
|
||||||
@ -1058,14 +1095,15 @@ void DisplayKeymapName(u32 uY)
|
|||||||
u8 keyMapType = 0;
|
u8 keyMapType = 0;
|
||||||
void SwapKeymap(void)
|
void SwapKeymap(void)
|
||||||
{
|
{
|
||||||
keyMapType = (keyMapType+1) % 5;
|
keyMapType = (keyMapType+1) % 6;
|
||||||
switch (keyMapType)
|
switch (keyMapType)
|
||||||
{
|
{
|
||||||
case 0: MapPlayer1(); DSPrint(10,3,0,("KEMPSTON P1")); break;
|
case 0: MapPlayer1(); DSPrint(10,3,0,("KEMPSTON P1")); break;
|
||||||
case 1: Sinclair1(); DSPrint(10,3,0,("SINCLAIR P1")); break;
|
case 1: Sinclair1(); DSPrint(10,3,0,("SINCLAIR P1")); break;
|
||||||
case 2: MapQAOP(); DSPrint(10,3,0,(" QAOP ")); break;
|
case 2: Cursors(); DSPrint(10,3,0,(" CURSORS ")); break;
|
||||||
case 3: MapWASD(); DSPrint(10,3,0,(" WASD ")); break;
|
case 3: MapQAOP(); DSPrint(10,3,0,(" QAOP ")); break;
|
||||||
case 4: MapZXSpace(); DSPrint(10,3,0,(" ZX SPACE ")); break;
|
case 4: MapWASD(); DSPrint(10,3,0,(" WASD ")); break;
|
||||||
|
case 5: MapZXSpace(); DSPrint(10,3,0,(" ZX SPACE ")); break;
|
||||||
}
|
}
|
||||||
WAITVBL;WAITVBL;WAITVBL;WAITVBL;
|
WAITVBL;WAITVBL;WAITVBL;WAITVBL;
|
||||||
DSPrint(10,3,0,(" "));
|
DSPrint(10,3,0,(" "));
|
||||||
@ -1306,6 +1344,8 @@ void ReadFileCRCAndConfig(void)
|
|||||||
if (strstr(gpFic[ucGameChoice].szName, ".TZX") != 0) speccy_mode = MODE_TZX;
|
if (strstr(gpFic[ucGameChoice].szName, ".TZX") != 0) speccy_mode = MODE_TZX;
|
||||||
if (strstr(gpFic[ucGameChoice].szName, ".rom") != 0) speccy_mode = MODE_BIOS;
|
if (strstr(gpFic[ucGameChoice].szName, ".rom") != 0) speccy_mode = MODE_BIOS;
|
||||||
if (strstr(gpFic[ucGameChoice].szName, ".ROM") != 0) speccy_mode = MODE_BIOS;
|
if (strstr(gpFic[ucGameChoice].szName, ".ROM") != 0) speccy_mode = MODE_BIOS;
|
||||||
|
if (strstr(gpFic[ucGameChoice].szName, ".z81") != 0) speccy_mode = MODE_ZX81;
|
||||||
|
if (strstr(gpFic[ucGameChoice].szName, ".Z81") != 0) speccy_mode = MODE_ZX81;
|
||||||
|
|
||||||
FindConfig(); // Try to find keymap and config for this file...
|
FindConfig(); // Try to find keymap and config for this file...
|
||||||
}
|
}
|
||||||
@ -1589,7 +1629,9 @@ void ProcessBufferedKeys(void)
|
|||||||
{
|
{
|
||||||
buf_held = BufferedKeys[BufferedKeysReadIdx];
|
buf_held = BufferedKeys[BufferedKeysReadIdx];
|
||||||
BufferedKeysReadIdx = (BufferedKeysReadIdx+1) % 32;
|
BufferedKeysReadIdx = (BufferedKeysReadIdx+1) % 32;
|
||||||
if (buf_held == 255) {buf_held = 0; next_dampen_time=60;} else next_dampen_time = 10;
|
if (buf_held == 255) {buf_held = 0; next_dampen_time=30;}
|
||||||
|
else if (buf_held == 254) {buf_held = 0; next_dampen_time=20;}
|
||||||
|
else next_dampen_time = 10;
|
||||||
} else buf_held = 0;
|
} else buf_held = 0;
|
||||||
dampen = 0;
|
dampen = 0;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ struct __attribute__((__packed__)) Config_t
|
|||||||
u8 dpad;
|
u8 dpad;
|
||||||
u8 autoLoad;
|
u8 autoLoad;
|
||||||
u8 loadAs;
|
u8 loadAs;
|
||||||
u8 reserved2;
|
u8 gameSpeed;
|
||||||
u8 reserved3;
|
u8 reserved3;
|
||||||
u8 reserved4;
|
u8 reserved4;
|
||||||
u8 reserved5;
|
u8 reserved5;
|
||||||
|
@ -263,7 +263,7 @@ void zx_bank(u8 new_bank)
|
|||||||
if (portFD & 0x20) return; // Lock out - no more bank swaps allowed
|
if (portFD & 0x20) return; // Lock out - no more bank swaps allowed
|
||||||
|
|
||||||
// Map in the correct bios segment... make sure this isn't a diagnostic ROM
|
// Map in the correct bios segment... make sure this isn't a diagnostic ROM
|
||||||
if (speccy_mode != MODE_BIOS)
|
if ((speccy_mode != MODE_BIOS) && (speccy_mode != MODE_ZX81))
|
||||||
{
|
{
|
||||||
MemoryMap[0] = SpectrumBios128 + ((new_bank & 0x10) ? 0x4000 : 0x0000);
|
MemoryMap[0] = SpectrumBios128 + ((new_bank & 0x10) ? 0x4000 : 0x0000);
|
||||||
}
|
}
|
||||||
@ -670,6 +670,20 @@ void speccy_reset(void)
|
|||||||
MemoryMap[3] = RAM_Memory128 + (0 * 0x4000) + 0x0000; // Bank 0
|
MemoryMap[3] = RAM_Memory128 + (0 * 0x4000) + 0x0000; // Bank 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (speccy_mode == MODE_ZX81)
|
||||||
|
{
|
||||||
|
// Move the BIOS/Diagnostic ROM into memory...
|
||||||
|
memcpy(RAM_Memory, ROM_Memory, 0x4000); // Load diagnostics ROM into place - the rest of the file is the P-File
|
||||||
|
|
||||||
|
// And force 128K mode needed for ZX81 emulation
|
||||||
|
zx_128k_mode = 1;
|
||||||
|
myConfig.loadAs = 1;
|
||||||
|
|
||||||
|
// Now set the memory map to point to the right banks...
|
||||||
|
MemoryMap[1] = RAM_Memory128 + (5 * 0x4000) + 0x0000; // Bank 5
|
||||||
|
MemoryMap[2] = RAM_Memory128 + (2 * 0x4000) + 0x0000; // Bank 2
|
||||||
|
MemoryMap[3] = RAM_Memory128 + (0 * 0x4000) + 0x0000; // Bank 0
|
||||||
|
}
|
||||||
else if (speccy_mode < MODE_SNA) // TAP or TZX file - 48K or 128K
|
else if (speccy_mode < MODE_SNA) // TAP or TZX file - 48K or 128K
|
||||||
{
|
{
|
||||||
// BIOS will be loaded further below...
|
// BIOS will be loaded further below...
|
||||||
@ -765,7 +779,7 @@ void speccy_reset(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (speccy_mode != MODE_BIOS)
|
if ((speccy_mode != MODE_BIOS) && (speccy_mode != MODE_ZX81))
|
||||||
{
|
{
|
||||||
// Load the correct BIOS into place... either 48K Spectrum or 128K
|
// Load the correct BIOS into place... either 48K Spectrum or 128K
|
||||||
if (zx_128k_mode) memcpy(RAM_Memory, SpectrumBios128, 0x4000); // Load ZX 128K BIOS into place
|
if (zx_128k_mode) memcpy(RAM_Memory, SpectrumBios128, 0x4000); // Load ZX 128K BIOS into place
|
||||||
|
35
readme.md
35
readme.md
@ -13,6 +13,7 @@ Features :
|
|||||||
* Loads .TZX files up to 640K total length (can swap tapes mid-game)
|
* Loads .TZX files up to 640K total length (can swap tapes mid-game)
|
||||||
* Loads .SNA snapshots (48K only)
|
* Loads .SNA snapshots (48K only)
|
||||||
* Loads .Z80 snapshots (V1, V2 and V3 formats, 48K or 128K)
|
* Loads .Z80 snapshots (V1, V2 and V3 formats, 48K or 128K)
|
||||||
|
* Loads .Z81 files for ZX81 emulation (see below)
|
||||||
* Loads .ROM files up to 16K in place of standard BIOS (diagnostics, etc)
|
* Loads .ROM files up to 16K in place of standard BIOS (diagnostics, etc)
|
||||||
* Supports .POK files (same name as base game and stored in POK subdir)
|
* Supports .POK files (same name as base game and stored in POK subdir)
|
||||||
* Kempston and Sinclair joystick support
|
* Kempston and Sinclair joystick support
|
||||||
@ -150,7 +151,16 @@ under that as you wish. The emulator can support a file listing of up
|
|||||||
to 2000 files with names no longer than 160 characters (so please keep
|
to 2000 files with names no longer than 160 characters (so please keep
|
||||||
your filenames on the shorter side... although the emulator can scroll
|
your filenames on the shorter side... although the emulator can scroll
|
||||||
the filename, there only about 30 characters can be shown on the screen
|
the filename, there only about 30 characters can be shown on the screen
|
||||||
at a time).
|
at a time).
|
||||||
|
|
||||||
|
One option that is of particular note is the ability to run the game
|
||||||
|
at a speed other than normal 100%. Some games were designed to run
|
||||||
|
a bit too fast to be enjoyable. Other games were a bit too slow. Using
|
||||||
|
this optional adjustment, you can run a game anywhere from 80% of full
|
||||||
|
speed (slower than normal) to 120% (faster than normal). The sound driver
|
||||||
|
should auto-adjust and while the music / sounds will sound faster/slower,
|
||||||
|
it should match the core emulation speed perfectly. This can be adjusted
|
||||||
|
on a per-game basis.
|
||||||
|
|
||||||
As for the per-game options, you can set things like the auto fire
|
As for the per-game options, you can set things like the auto fire
|
||||||
for the joystick and the aforementioned CHUCKIE mode of joystick d-pad
|
for the joystick and the aforementioned CHUCKIE mode of joystick d-pad
|
||||||
@ -192,7 +202,6 @@ an alternate "[a]" version will load. Usually one tape image dump is
|
|||||||
as good as any other - but keep searching and put yourself together a
|
as good as any other - but keep searching and put yourself together a
|
||||||
library of known good working images for Speccy-SE.
|
library of known good working images for Speccy-SE.
|
||||||
|
|
||||||
|
|
||||||
ROM Support :
|
ROM Support :
|
||||||
-----------------------
|
-----------------------
|
||||||
The emulator allows you to load a .ROM file directly into the same memory
|
The emulator allows you to load a .ROM file directly into the same memory
|
||||||
@ -200,6 +209,28 @@ location as the BIOS (+0000 to +4000). Only up to 16K can be loaded in this
|
|||||||
way. This is mainly used to load diagnostic test programs such as the
|
way. This is mainly used to load diagnostic test programs such as the
|
||||||
amazing RETROLEUM DIAGROM.
|
amazing RETROLEUM DIAGROM.
|
||||||
|
|
||||||
|
ZX81 Support :
|
||||||
|
-----------------------
|
||||||
|
The emulator supports the Paul Farrow ZX81 emulator for the ZX 128k machines.
|
||||||
|
|
||||||
|
http://www.fruitcake.plus.com/Sinclair/Interface2/Cartridges/Interface2_RC_New_ZX81.htm
|
||||||
|
|
||||||
|
To make this work, download the 16K Interface 2 ROM for the emulator - either Edition 2
|
||||||
|
or Edition 3 (do not use Edition 1 or the 'bugfix version'). Take this ROM file
|
||||||
|
and concatenate it with a ZX81 .p file for the game you want to play.
|
||||||
|
|
||||||
|
So let's say you want to play the original ZX81 Mazogs. Obtain the mazogs.p file and the
|
||||||
|
aforementioned ZX81 emulator ROM and do the following:
|
||||||
|
|
||||||
|
Linux: cat S128_ZX81_ED2_ROM.bin mazogs.p > mazogs.z81
|
||||||
|
Windows: copy /b S128_ZX81_ED2_ROM.bin mazogs.p mazogs.z81
|
||||||
|
|
||||||
|
|
||||||
|
This will produce a .z81 file that is roughly 25K in size... it contains the emulator + the game .p file
|
||||||
|
in one binary image. This .z81 file is now loadable directly into Speccy-SE - when you pick the game, it
|
||||||
|
will automatically insert the keystrokes needed to get the emulator running. This takes about 10 seconds...
|
||||||
|
don't touch any virtual keys until the ZX81 game is fully loaded.
|
||||||
|
|
||||||
POK Support :
|
POK Support :
|
||||||
-----------------------
|
-----------------------
|
||||||
The emulator supports .pok files. The .pok file should have the same base
|
The emulator supports .pok files. The .pok file should have the same base
|
||||||
|
Loading…
Reference in New Issue
Block a user