diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 52d7d437a..ee93adf30 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -14,7 +14,8 @@ using namespace Oric; Machine::Machine() : _cycles_since_video_update(0), _use_fast_tape_hack(false), - _typer_delay(2500000) + _typer_delay(2500000), + _keyboard_read_count(0) { set_clock_rate(1000000); _via.set_interrupt_delegate(this); @@ -40,10 +41,20 @@ void Machine::configure_as_target(const StaticAnalyser::Target &target) if(target.oric.use_atmos_rom) { memcpy(_rom, _basic11.data(), std::min(_basic11.size(), sizeof(_rom))); + + _is_using_basic11 = true; + _tape_get_byte_address = 0xe6c9; + _scan_keyboard_address = 0xf495; + _tape_speed_address = 0x024d; } else { memcpy(_rom, _basic10.data(), std::min(_basic10.size(), sizeof(_rom))); + + _is_using_basic11 = false; + _tape_get_byte_address = 0xe630; + _scan_keyboard_address = 0xf43c; + _tape_speed_address = 0x67; } } @@ -60,9 +71,9 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin // 024D = 0 => fast; otherwise slow // E6C9 = read byte: return byte in A - if(address == 0xe6c9 && _use_fast_tape_hack && operation == CPU6502::BusOperation::ReadOpcode && _via.tape->has_tape() && !_via.tape->get_tape()->is_at_end()) + if(address == _tape_get_byte_address && _use_fast_tape_hack && operation == CPU6502::BusOperation::ReadOpcode && _via.tape->has_tape() && !_via.tape->get_tape()->is_at_end()) { - uint8_t next_byte = _via.tape->get_next_byte(!_ram[0x024d]); + uint8_t next_byte = _via.tape->get_next_byte(!_ram[_tape_speed_address]); set_value_of_register(CPU6502::A, next_byte); set_value_of_register(CPU6502::Flags, next_byte ? 0 : CPU6502::Flag::Zero); *value = 0x60; // i.e. RTS @@ -87,9 +98,12 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin } } - if(_typer && operation == CPU6502::BusOperation::ReadOpcode && address == 0xF495) + if(_typer && address == _scan_keyboard_address && operation == CPU6502::BusOperation::ReadOpcode) { - if(!_typer->type_next_character()) + // the Oric 1 misses any key pressed on the very first entry into the read keyboard routine, so don't + // do anything until at least the second, regardless of machine + if(!_keyboard_read_count) _keyboard_read_count++; + else if(!_typer->type_next_character()) { clear_all_keys(); _typer.reset(); diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index 000a024b0..f469d7fba 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -102,6 +102,11 @@ class Machine: int _cycles_since_video_update; inline void update_video(); + // ROM bookkeeping + bool _is_using_basic11; + uint16_t _tape_get_byte_address, _scan_keyboard_address, _tape_speed_address; + int _keyboard_read_count; + // Outputs std::unique_ptr _videoOutput; diff --git a/StaticAnalyser/Oric/StaticAnalyser.cpp b/StaticAnalyser/Oric/StaticAnalyser.cpp index ae1bd0815..e21b16052 100644 --- a/StaticAnalyser/Oric/StaticAnalyser.cpp +++ b/StaticAnalyser/Oric/StaticAnalyser.cpp @@ -13,17 +13,13 @@ using namespace StaticAnalyser::Oric; -static int Score(const StaticAnalyser::MOS6502::Disassembly &disassembly, const std::set &rom_functions) +static int Score(const StaticAnalyser::MOS6502::Disassembly &disassembly, const std::set &rom_functions, const std::set &variable_locations) { int score = 0; - for(auto address : disassembly.outward_calls) - { - if(rom_functions.find(address) != rom_functions.end()) - score++; - else - score--; - } + for(auto address : disassembly.outward_calls) score += (rom_functions.find(address) != rom_functions.end()) ? 1 : -1; + for(auto address : disassembly.external_stores) score += (variable_locations.find(address) != variable_locations.end()) ? 1 : -1; + for(auto address : disassembly.external_loads) score += (variable_locations.find(address) != variable_locations.end()) ? 1 : -1; return score; } @@ -31,6 +27,7 @@ static int Score(const StaticAnalyser::MOS6502::Disassembly &disassembly, const static int Basic10Score(const StaticAnalyser::MOS6502::Disassembly &disassembly) { std::set rom_functions = { + 0x0228, 0x022b, 0xc3ca, 0xc3f8, 0xc448, 0xc47c, 0xc4b5, 0xc4e3, 0xc4e0, 0xc524, 0xc56f, 0xc5a2, 0xc5f8, 0xc60a, 0xc6a5, 0xc6de, 0xc719, 0xc738, 0xc773, 0xc824, 0xc832, 0xc841, 0xc8c1, 0xc8fe, 0xc91f, 0xc93f, 0xc941, 0xc91e, 0xc98b, 0xc996, 0xc9b3, 0xc9e0, 0xca0a, 0xca1c, 0xca1f, 0xca3e, 0xca61, 0xca78, 0xca98, 0xcad2, 0xcb61, 0xcb9f, 0xcc59, 0xcbed, 0xcc0a, 0xcc8c, 0xcc8f, 0xccba, 0xccc9, 0xccfd, @@ -45,13 +42,17 @@ static int Basic10Score(const StaticAnalyser::MOS6502::Disassembly &disassembly) 0xf43c, 0xf4ef, 0xf523, 0xf561, 0xf535, 0xf57b, 0xf5d3, 0xf71a, 0xf73f, 0xf7e4, 0xf7e0, 0xf82f, 0xf88f, 0xf8af, 0xf8b5, 0xf920, 0xf967, 0xf960, 0xf9c9, 0xfa14, 0xfa85, 0xfa9b, 0xfab1, 0xfac7, 0xfafa, 0xfb10, 0xfb26, 0xfbb6, 0xfbfe }; + std::set variable_locations = { + 0x0228, 0x0229, 0x022a, 0x022b, 0x022c, 0x022d, 0x0230 + }; - return Score(disassembly, rom_functions); + return Score(disassembly, rom_functions, variable_locations); } static int Basic11Score(const StaticAnalyser::MOS6502::Disassembly &disassembly) { std::set rom_functions = { + 0x0238, 0x023b, 0x023e, 0x0241, 0x0244, 0x0247, 0xc3c6, 0xc3f4, 0xc444, 0xc47c, 0xc4a8, 0xc4d3, 0xc4e0, 0xc524, 0xc55f, 0xc592, 0xc5e8, 0xc5fa, 0xc692, 0xc6b3, 0xc6ee, 0xc70d, 0xc748, 0xc7fd, 0xc809, 0xc816, 0xc82f, 0xc855, 0xc8c1, 0xc915, 0xc952, 0xc971, 0xc973, 0xc9a0, 0xc9bd, 0xc9c8, 0xc9e5, 0xca12, 0xca3c, 0xca4e, 0xca51, 0xca70, 0xca99, 0xcac2, 0xcae2, 0xcb1c, 0xcbab, 0xcbf0, 0xcc59, 0xccb0, 0xccce, 0xcd16, 0xcd19, 0xcd46, @@ -67,8 +68,11 @@ static int Basic11Score(const StaticAnalyser::MOS6502::Disassembly &disassembly) 0xf88f, 0xf8af, 0xf8b5, 0xf920, 0xf967, 0xf9aa, 0xf9c9, 0xfa14, 0xfa9f, 0xfab5, 0xfacb, 0xfae1, 0xfb14, 0xfb2a, 0xfb40, 0xfbd0, 0xfc18 }; + std::set variable_locations = { + 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x024a, 0x024b, 0x024c + }; - return Score(disassembly, rom_functions); + return Score(disassembly, rom_functions, variable_locations); } void StaticAnalyser::Oric::AddTargets(