diff --git a/core/core.cpp b/core/core.cpp index 38bc8be..2c05f87 100644 --- a/core/core.cpp +++ b/core/core.cpp @@ -171,59 +171,59 @@ LibretroCore::LibretroCore(retro_log_printf_t log_cb_, int machineDetailedType_, if (enhancedRom) { bootframes = 20*10; - config->memory.rom[0x00].file=romBasePath+"exos24uk.rom"; + config->memory.rom[0x00].file="exos24uk.rom"; config->memory.rom[0x00].offset=0; - config->memory.rom[0x01].file=romBasePath+"exos24uk.rom"; + config->memory.rom[0x01].file="exos24uk.rom"; config->memory.rom[0x01].offset=16384; - config->memory.rom[0x02].file=romBasePath+"exos24uk.rom"; + config->memory.rom[0x02].file="exos24uk.rom"; config->memory.rom[0x02].offset=32768; - config->memory.rom[0x03].file=romBasePath+"exos24uk.rom"; + config->memory.rom[0x03].file="exos24uk.rom"; config->memory.rom[0x03].offset=49152; } else if (is_EP64) { bootframes = 30*10; - config->memory.rom[0x00].file=romBasePath+"exos20.rom"; + config->memory.rom[0x00].file="exos20.rom"; config->memory.rom[0x00].offset=0; - config->memory.rom[0x01].file=romBasePath+"exos20.rom"; + config->memory.rom[0x01].file="exos20.rom"; config->memory.rom[0x01].offset=16384; } else { bootframes = 40*10; - config->memory.rom[0x00].file=romBasePath+"exos21.rom"; + config->memory.rom[0x00].file="exos21.rom"; config->memory.rom[0x00].offset=0; - config->memory.rom[0x01].file=romBasePath+"exos21.rom"; + config->memory.rom[0x01].file="exos21.rom"; config->memory.rom[0x01].offset=16384; } if(contentLocale == LOCALE_HUN) { // Locale support: HUN ROM goes to segment 4 and then Basic goes to segment 5 - config->memory.rom[0x04].file=romBasePath+"hun.rom"; + config->memory.rom[0x04].file="hun.rom"; config->memory.rom[0x04].offset=0; if (use_cartridge) { if (is_EP64) - config->memory.rom[0x05].file=romBasePath+"basic20.rom"; + config->memory.rom[0x05].file="basic20.rom"; else - config->memory.rom[0x05].file=romBasePath+"basic21.rom"; + config->memory.rom[0x05].file="basic21.rom"; config->memory.rom[0x05].offset=0; } // HFONT is used from epdos rom (and CLKOFF, as it is not present after this 1.6f version) - config->memory.rom[0x06].file=romBasePath+"epdos16f.rom"; + config->memory.rom[0x06].file="epdos16f.rom"; config->memory.rom[0x06].offset=0; - config->memory.rom[0x07].file=romBasePath+"epdos16f.rom"; + config->memory.rom[0x07].file="epdos16f.rom"; config->memory.rom[0x07].offset=16384; } else if(contentLocale == LOCALE_GER) { // Locale support: BRD ROM goes to segment 4 and then Basic goes to segment 5 - config->memory.rom[0x04].file=romBasePath+"brd.rom"; + config->memory.rom[0x04].file="brd.rom"; config->memory.rom[0x04].offset=0; if (use_cartridge) { if (is_EP64) - config->memory.rom[0x05].file=romBasePath+"basic20.rom"; + config->memory.rom[0x05].file="basic20.rom"; else - config->memory.rom[0x05].file=romBasePath+"basic21.rom"; + config->memory.rom[0x05].file="basic21.rom"; config->memory.rom[0x05].offset=0; } } @@ -231,38 +231,38 @@ LibretroCore::LibretroCore(retro_log_printf_t log_cb_, int machineDetailedType_, { if (use_cartridge) { if (is_EP64) - config->memory.rom[0x04].file=romBasePath+"basic20.rom"; + config->memory.rom[0x04].file="basic20.rom"; else - config->memory.rom[0x05].file=romBasePath+"basic21.rom"; + config->memory.rom[0x05].file="basic21.rom"; config->memory.rom[0x04].offset=0; } } if(use_file || use_dtf) { - config->memory.rom[0x10].file=romBasePath+"epfileio.rom"; + config->memory.rom[0x10].file="epfileio.rom"; config->memory.rom[0x10].offset=0; if(use_dtf) { - config->memory.rom[0x40].file=romBasePath+"zt19uk.rom"; + config->memory.rom[0x40].file="zt19uk.rom"; config->memory.rom[0x40].offset=0; - config->memory.rom[0x41].file=romBasePath+"zt19uk.rom"; + config->memory.rom[0x41].file="zt19uk.rom"; config->memory.rom[0x41].offset=16384; } } if(use_isdos) { - config->memory.rom[0x20].file=romBasePath+"exdos14isdos10uk.rom"; + config->memory.rom[0x20].file="exdos14isdos10uk.rom"; config->memory.rom[0x20].offset=0; - config->memory.rom[0x21].file=romBasePath+"exdos14isdos10uk.rom"; + config->memory.rom[0x21].file="exdos14isdos10uk.rom"; config->memory.rom[0x21].offset=16384; startSequence += " \xff\xff\xff\xff\xff\xff\xff\xff\xff\xff""\x27""isdos\r""\xff\xff\xff\xff\xff\xff\xff""dir\r"; } else if(use_file || use_disk) { - config->memory.rom[0x20].file=romBasePath+"exdos13.rom"; + config->memory.rom[0x20].file="exdos13.rom"; config->memory.rom[0x20].offset=0; - config->memory.rom[0x21].file=romBasePath+"exdos13.rom"; + config->memory.rom[0x21].file="exdos13.rom"; config->memory.rom[0x21].offset=16384; } } @@ -270,18 +270,18 @@ LibretroCore::LibretroCore(retro_log_printf_t log_cb_, int machineDetailedType_, { bootframes = 50*10; config->memory.ram.size=128; - config->memory.rom[0x00].file=romBasePath+"tvc22_sys.rom"; + config->memory.rom[0x00].file="tvc22_sys.rom"; config->memory.rom[0x00].offset=0; - config->memory.rom[0x02].file=romBasePath+"tvc22_ext.rom"; + config->memory.rom[0x02].file="tvc22_ext.rom"; config->memory.rom[0x02].offset=0; if(machineDetailedType == VM_config.at("TVC64_FILE")) { - config->memory.rom[0x04].file=romBasePath+"tvcfileio.rom"; + config->memory.rom[0x04].file="tvcfileio.rom"; config->memory.rom[0x04].offset=0; } if(machineDetailedType == VM_config.at("TVC64_DISK")) { - config->memory.rom[0x03].file=romBasePath+"tvc_dos12d.rom"; + config->memory.rom[0x03].file="tvc_dos12d.rom"; config->memory.rom[0x03].offset=0; } } @@ -292,31 +292,31 @@ LibretroCore::LibretroCore(retro_log_printf_t log_cb_, int machineDetailedType_, if(machineDetailedType == VM_config.at("CPC_464_TAPE")) { config->memory.ram.size=64; - config->memory.rom[0x10].file=romBasePath+"cpc464.rom"; + config->memory.rom[0x10].file="cpc464.rom"; config->memory.rom[0x10].offset=0; - config->memory.rom[0x00].file=romBasePath+"cpc464.rom"; + config->memory.rom[0x00].file="cpc464.rom"; config->memory.rom[0x00].offset=16384; } else if(machineDetailedType == VM_config.at("CPC_664_DISK")) { config->memory.ram.size=64; - config->memory.rom[0x10].file=romBasePath+"cpc664.rom"; + config->memory.rom[0x10].file="cpc664.rom"; config->memory.rom[0x10].offset=0; - config->memory.rom[0x00].file=romBasePath+"cpc664.rom"; + config->memory.rom[0x00].file="cpc664.rom"; config->memory.rom[0x00].offset=16384; } else { // 6128 as default config->memory.ram.size=128; - config->memory.rom[0x10].file=romBasePath+"cpc6128.rom"; + config->memory.rom[0x10].file="cpc6128.rom"; config->memory.rom[0x10].offset=0; - config->memory.rom[0x00].file=romBasePath+"cpc6128.rom"; + config->memory.rom[0x00].file="cpc6128.rom"; config->memory.rom[0x00].offset=16384; } if(machineDetailedType == VM_config.at("CPC_DISK") || machineDetailedType == VM_config.at("CPC_664_DISK")) { - config->memory.rom[0x07].file=romBasePath+"cpc_amsdos.rom"; + config->memory.rom[0x07].file="cpc_amsdos.rom"; config->memory.rom[0x07].offset=0; } @@ -339,23 +339,92 @@ LibretroCore::LibretroCore(retro_log_printf_t log_cb_, int machineDetailedType_, if(machineDetailedType == VM_config.at("ZX128_TAPE") || machineDetailedType == VM_config.at("ZX128_FILE")) { - config->memory.rom[0x00].file=romBasePath+"zx128.rom"; + config->memory.rom[0x00].file="zx128.rom"; config->memory.rom[0x00].offset=0; - config->memory.rom[0x01].file=romBasePath+"zx128.rom"; + config->memory.rom[0x01].file="zx128.rom"; config->memory.rom[0x01].offset=16384; } else { - config->memory.rom[0x00].file=romBasePath+"zx48.rom"; + config->memory.rom[0x00].file="zx48.rom"; config->memory.rom[0x00].offset=0; } } + + if(machineType == MACHINE_EP) + { + config->vm.cpuClockFrequency=4000000; + config->vm.enableMemoryTimingEmulation=true; + config->vm.soundClockFrequency=500000; + config->vm.videoClockFrequency=889846; + } + else if(machineType == MACHINE_TVC) + { + config->vm.cpuClockFrequency=3125000; + config->vm.enableMemoryTimingEmulation=true; + config->vm.soundClockFrequency=390625; + config->vm.videoClockFrequency=1562500; + } + else if(machineType == MACHINE_CPC) + { + config->vm.cpuClockFrequency=4000000; + config->vm.enableMemoryTimingEmulation=true; + config->vm.soundClockFrequency=125000; + config->vm.videoClockFrequency=1000000; + } + else if(machineType == MACHINE_ZX) + { + if(machineDetailedType == VM_config.at("ZX128_TAPE") || machineDetailedType == VM_config.at("ZX128_FILE")) + { + config->vm.cpuClockFrequency=3546896; + config->vm.soundClockFrequency=221681; + config->vm.videoClockFrequency=886724; + } + else + { + config->vm.cpuClockFrequency=3500000; + config->vm.soundClockFrequency=218750; + config->vm.videoClockFrequency=875000; + } + config->vm.enableMemoryTimingEmulation=true; + } + config->vmConfigurationChanged = true; + + config->sound.sampleRate = EP128EMU_SAMPLE_RATE_FLOAT; + config->sound.hwPeriods = 16; + //config->sound.swPeriods = 16; + //config->sound.enabled = false; + config->sound.highQuality = true; + config->soundSettingsChanged = true; + + // Reload config files to enforce priority of settings. + if(Ep128Emu::does_file_exist(configBaseFile.c_str())) + { + config->loadState(configBaseFile.c_str(),false); + } + // highest: content-specific file + if (cfgFile[0]) + { + config->loadState(cfgFile,false); + } + // ROM validity check: scan ROM definitions and check if files can be be found. // If not, try to use replacement file for(int i=0; i<68; i++) { if(config->memory.rom[i].file.length()>0) { + // Prepend romBasePath if the rom name is not a path already (useful for rom settings read from .ep128cfg) +#ifdef WIN32 + size_t idx = config->memory.rom[i].file.rfind('\\'); +#else + size_t idx = config->memory.rom[i].file.rfind('/'); +#endif + if(idx == std::string::npos) + { + config->memory.rom[i].file=romBasePath+config->memory.rom[i].file; + } + if(!Ep128Emu::does_file_exist(config->memory.rom[i].file.c_str())) { std::map< std::string, std::string >::const_iterator iter_altrom; @@ -422,65 +491,8 @@ LibretroCore::LibretroCore(retro_log_printf_t log_cb_, int machineDetailedType_, } } } - config->memoryConfigurationChanged = true; - - if(machineType == MACHINE_EP) - { - config->vm.cpuClockFrequency=4000000; - config->vm.enableMemoryTimingEmulation=true; - config->vm.soundClockFrequency=500000; - config->vm.videoClockFrequency=889846; - } - else if(machineType == MACHINE_TVC) - { - config->vm.cpuClockFrequency=3125000; - config->vm.enableMemoryTimingEmulation=true; - config->vm.soundClockFrequency=390625; - config->vm.videoClockFrequency=1562500; - } - else if(machineType == MACHINE_CPC) - { - config->vm.cpuClockFrequency=4000000; - config->vm.enableMemoryTimingEmulation=true; - config->vm.soundClockFrequency=125000; - config->vm.videoClockFrequency=1000000; - } - else if(machineType == MACHINE_ZX) - { - if(machineDetailedType == VM_config.at("ZX128_TAPE") || machineDetailedType == VM_config.at("ZX128_FILE")) - { - config->vm.cpuClockFrequency=3546896; - config->vm.soundClockFrequency=221681; - config->vm.videoClockFrequency=886724; - } - else - { - config->vm.cpuClockFrequency=3500000; - config->vm.soundClockFrequency=218750; - config->vm.videoClockFrequency=875000; - } - config->vm.enableMemoryTimingEmulation=true; - } - config->vmConfigurationChanged = true; - - config->sound.sampleRate = EP128EMU_SAMPLE_RATE_FLOAT; - config->sound.hwPeriods = 16; - //config->sound.swPeriods = 16; - //config->sound.enabled = false; - config->sound.highQuality = true; - config->soundSettingsChanged = true; - - // Reload config files to enforce priority of settings. - if(Ep128Emu::does_file_exist(configBaseFile.c_str())) - { - config->loadState(configBaseFile.c_str(),false); - } - // highest: content-specific file - if (cfgFile[0]) - { - config->loadState(cfgFile,false); - } - + config->memoryConfigurationChanged = true; + initialize_keyboard_map(); initialize_joystick_map(std::string(""),std::string(""),std::string(""),-1, joystick_type.at("DEFAULT"), joystick_type.at("DEFAULT"), joystick_type.at("DEFAULT"), diff --git a/core/main.cpp b/core/main.cpp index 16ff875..1f0a693 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -178,17 +178,22 @@ static void update_led_interface(void) unsigned int l = 0; // TODO: power LED should go off during reset (even though original machine had no such thing) - led_state[0] = 1; - if (core) - led_state[1] = core->vm->getFloppyDriveLEDState() ? 1 : 0; - else + // TODO: LED 0/1 could be used for red/green replication of load indicators. LED0 does not work yet. + if (core) { + led_state[1] = core->vm->getFloppyDriveLEDState() & 0xFFFFFFBF ? 1 : 0; + led_state[0] = core->vm->getFloppyDriveLEDState() & 0x00000040 ? 1 : 0; + } + else { led_state[1] = 0; + led_state[0] = 1; + } + for (l = 0; l < sizeof(led_state)/sizeof(led_state[0]); l++) { if (retro_led_state[l] != led_state[l]) { - log_cb(RETRO_LOG_DEBUG, "LED control: change LED nr. %d (%d)->(%d)\n",l,retro_led_state[l],led_state[l]); + /*log_cb(RETRO_LOG_DEBUG, "LED control: change LED nr. %d (%d)->(%d)\n",l,retro_led_state[l],led_state[l]);*/ retro_led_state[l] = led_state[l]; led_state_cb(l, led_state[l]); } @@ -620,7 +625,7 @@ void retro_get_system_info(struct retro_system_info *info) { memset(info, 0, sizeof(*info)); info->library_name = "ep128emu"; - info->library_version = "v1.2.7"; + info->library_version = "v1.2.8"; info->need_fullpath = true; #ifndef EXCLUDE_SOUND_LIBS info->valid_extensions = "img|dsk|tap|dtf|com|trn|128|bas|cas|cdt|tzx|wav|tvcwav|mp3|."; diff --git a/core/sample.ep128cfg b/core/sample.ep128cfg index ed7e274..9203faa 100644 --- a/core/sample.ep128cfg +++ b/core/sample.ep128cfg @@ -38,8 +38,8 @@ joypad.user6 "" # Joypad detailed configuration for user 1. Example: # joypad.x "1" -# This maps retropad button X to key 1 on emulated keyboard. -# Following values can be used (all lowercase): +# This maps retropad button X to pressing key 1 on emulated keyboard. +# Following keypress values can be used (all lowercase): # a-z 0-9 f1-f8 # \-^;:[],/.@ # esc, enter, space, tab, lshift, rshift, ctrl, alt @@ -100,3 +100,10 @@ machineDetailedType "" # sound.mono Yes # Other ep128emu options are also recognized, but not tested extensively. +# memory.ram.size 576 +# memory.rom.40.file "spemu128.rom" +# memory.rom.40.offset 0 +# memory.rom.41.file "spemu128.rom" +# memory.rom.41.offset 16384 +# memory.rom.42.file "spemu128.rom" +# memory.rom.42.offset 32768 diff --git a/src/dave.cpp b/src/dave.cpp index 124ffd5..52739d8 100644 --- a/src/dave.cpp +++ b/src/dave.cpp @@ -782,6 +782,12 @@ namespace Ep128 { tape_input_level = (level > 0 ? 1 : 0); } + uint8_t Dave::getTapeInput() + { + return uint8_t(tape_input ? 0x40 : 0x0 | tape_input_level ? 0x80 : 0x0); + /*(tape_input_level - 1) & 0x40) | ((tape_input - 1) & 0x80);*/ + } + void Dave::setKeyboardState(int keyCode, int state) { int row = (keyCode & 0x78) >> 3; diff --git a/src/dave.hpp b/src/dave.hpp index 99daf97..d9f3a7b 100644 --- a/src/dave.hpp +++ b/src/dave.hpp @@ -197,6 +197,10 @@ namespace Ep128 { * Set tape input state, and level (0: low, 1: high). */ void setTapeInput(int state, int level); + /*! + * Get tape input state, and level (same as port 0x16 read). + */ + uint8_t getTapeInput(); /*! * Set state of key 'keyCode' (0 to 127, see table below) to pressed * (state != 0) or released (state == 0). diff --git a/src/ep128vm.cpp b/src/ep128vm.cpp index 955114a..1cada24 100644 --- a/src/ep128vm.cpp +++ b/src/ep128vm.cpp @@ -2181,6 +2181,11 @@ namespace Ep128 { n = n << 8; n |= uint32_t(floppyDrives[i].getLEDState()); } + if (haveTape() && getIsTapeMotorOn()) { + // 0x00000080: tape red "LED" (input present) + // 0x00000040: tape green "LED" (level present) + n |= uint32_t(dave.getTapeInput()); + } #ifdef ENABLE_SDEXT n = n | sdext.getLEDState(); #endif diff --git a/src/vm.hpp b/src/vm.hpp index 894d804..ddf27d4 100644 --- a/src/vm.hpp +++ b/src/vm.hpp @@ -90,6 +90,8 @@ namespace Ep128Emu { // 0x00000002: floppy drive 0 green LED is on // 0x00000004: IDE drive 0 red LED is on (low priority) // 0x0000000C: IDE drive 0 red LED is on (high priority) + // 0x00000040: tape red "LED" (input present, negative) + // 0x00000080: tape green "LED" (input present, positive) // 0x00000100: floppy drive 1 red LED is on // 0x00000200: floppy drive 1 green LED is on // 0x00000400: IDE drive 1 red LED is on (low priority)