1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-26 10:29:31 +00:00

Extended analysis to spot IRQ and NMI vector changes, for titles that simply adjust those then exit. Ensured Oric emulator can type and load quickly on an Oric 1 just as well as on an Atmos.

This commit is contained in:
Thomas Harte 2016-11-15 11:05:53 +08:00
parent e2cdfae8a7
commit 8b40ae03ca
3 changed files with 38 additions and 15 deletions

View File

@ -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();

View File

@ -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> _videoOutput;

View File

@ -13,17 +13,13 @@
using namespace StaticAnalyser::Oric;
static int Score(const StaticAnalyser::MOS6502::Disassembly &disassembly, const std::set<uint16_t> &rom_functions)
static int Score(const StaticAnalyser::MOS6502::Disassembly &disassembly, const std::set<uint16_t> &rom_functions, const std::set<uint16_t> &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<uint16_t> 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<uint16_t> 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<uint16_t> 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<uint16_t> 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(