diff --git a/Machines/Thomson/MO5/CD90-640.cpp b/Machines/Thomson/MO5/CD90-640.cpp index 12620498c..174660555 100644 --- a/Machines/Thomson/MO5/CD90-640.cpp +++ b/Machines/Thomson/MO5/CD90-640.cpp @@ -11,97 +11,7 @@ using namespace Thomson; CD90_640::CD90_640() : WD::WD1770(P1770) { - // 325 is a peculiar RPM, but seems to match a spin-up test in the disk ROM that polls the WD1770's status register - // index hole bit and counts time. Furthermore there are other machines with unusual RPMs. Could definitely - // still just imply an issue elsewhere in the emulator though. - emplace_drives(2, 8'000'000, 325, 2); - - // - // On "325 RPM": - // - // Faulty reasoning was: - // --------------------- - // - // The DOS ROM verifies that a disk is present and spinning before proceeding. - // Part of that test is of spin speed. - // - // Specifically, with X = 0xa7d0 it performs: - // - // ; - // ; Wait for index hole set. - // ; - // a29b LDA ,X ; 4 µs - // a29d ANDA #$02 ; 2 µs - // a29f BEQ ZA29B ; 3 µs - // - // ; - // ; i.e. start of track falls about here - // ; - // - // ; - // ; Fixed delay... - // ; - // a2a1 LDY #M09C4 ; 4 µs - // a2a5 DEY ; 5 µs - // a2a7 BNE ZA2A5 ; 3 µs = net delay of 4 + 9C4*7 = 17,504 µs - // - // a2a9 PSHS CC ; 6 µs - // a2ab SEIF ; 3 µs - // - // ; - // ; Count time until index hole is set again - // ; - // a2ad LDA ,X ; 4 µs, read WD status - // a2af INY ; 5 µs - // a2b1 ANDA #$02 ; 2 µs - // a2b3 BEQ ZA2AD ; 3 µs - // - // a2b5 PULS CC - // - // ; - // ; Check whether rotation speed was within bounds - // ; - // a2b7 CMPY #M311B - // a2bb BMI ZA2C7 - // a2bd CMPY #M3357 - // a2c1 BPL ZA2C7 - // - // [test passed code here, test failed code from a2c7] - // - // If I've disassembled that correctly, then the process is: - // - // (1) wait for index hole, with up to 9 µs of latency; - // (2) spin in a loop for 17,504 µs; - // (3) do minor stack/flag work for 9 µs; - // (4) count time from here until next index hole, ending with Y = time/13; - // (5) test that that is within the bounds 0x311b, 0x3357. - // - // Ignoring minor potential latencies in loop exits, that's: - // - // (1) wait for index hole; - // (2) spend 17,513 µs doing something else; - // (3) get Y = [µs from there to next index hole] / 13. - // - // i.e. it's a test that the rotation it samples takes n µs, where: - // - // 14 * 0x311b < n - 17,513 < 14 * 0x3357 - // 14 * 12,571 + 20,009 < n < 14 * 13,143 + 20,009 - // 196,003 < n < 204,011 - // - // i.e. - // - // ~331 >= RPM >= ~319 RPM. - // - // So 325 RPM is a really weird number but I can't currently say why it should be - // wrong rather than merely unexpected. So here it is. - // - // Correct reasoning is: - // --------------------- - // - // The LEAYs that constitute INY and DEY above should be _five_ cycles long, not four. - // My 6809 timing is adrift. - // If loops were properly timed then 300 RPM looks appropriate. - // Cf. https://forum.system-cfg.com/viewtopic.php?f=1&t=17137 + emplace_drives(2, 8'000'000, 300, 2); } uint8_t CD90_640::control() { diff --git a/OSBindings/Mac/Clock SignalTests/6809Tests.mm b/OSBindings/Mac/Clock SignalTests/6809Tests.mm index f3a4ff8be..be2514c89 100644 --- a/OSBindings/Mac/Clock SignalTests/6809Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/6809Tests.mm @@ -824,7 +824,8 @@ struct M6809Traits { sequence(0xbf); // STY } - // Omitted entirely: LEAS, LEAU, LEAX, LEAY that come only in indexed mode. Maybe use those as the indexed test? + // Omitted entirely: LEAS, LEAU, LEAX, LEAY that come only in indexed mode. LEAS is the subject of the indexed + // timing tests, and I _assume_ the rest conform. // MARK: - JMP @@ -1087,35 +1088,35 @@ struct M6809Traits { test( {0x32, NoOffset | RegX}, // ,R { - RW::Read, RW::Read, RW::NoData + RW::Read, RW::Read, RW::NoData, RW::NoData, } ); test( {0x32, NoOffset | RegX | Indirect}, // [,R] { - RW::Read, RW::Read, RW::NoData, RW::Read, RW::Read, RW::NoData + RW::Read, RW::Read, RW::NoData, RW::Read, RW::Read, RW::NoData, RW::NoData, } ); test( {0x32, Offset5bit | RegX}, // [5n,R] { - RW::Read, RW::Read, RW::NoData, RW::NoData + RW::Read, RW::Read, RW::NoData, RW::NoData, RW::NoData, } ); test( {0x32, Offset8bit | RegX, 0x00}, // 8n,R { - RW::Read, RW::Read, RW::Read, RW::NoData + RW::Read, RW::Read, RW::Read, RW::NoData, RW::NoData, } ); test( {0x32, Offset8bit | RegX | Indirect, 0x00}, // [8n,R] { - RW::Read, RW::Read, RW::Read, RW::NoData, RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::Read, RW::NoData, RW::Read, RW::Read, RW::NoData, RW::NoData, } ); @@ -1124,7 +1125,7 @@ struct M6809Traits { { RW::Read, RW::Read, RW::Read, RW::Read, - RW::NoData, RW::NoData, RW::NoData, + RW::NoData, RW::NoData, RW::NoData, RW::NoData, } ); @@ -1132,7 +1133,7 @@ struct M6809Traits { {0x32, ARegisterOffset | RegX}, // A,R { RW::Read, RW::Read, - RW::NoData, RW::NoData, + RW::NoData, RW::NoData, RW::NoData, } ); @@ -1141,7 +1142,7 @@ struct M6809Traits { { RW::Read, RW::Read, RW::NoData, RW::NoData, - RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::NoData, RW::NoData, } ); @@ -1152,7 +1153,7 @@ struct M6809Traits { {0x32, DRegisterOffset | RegX}, // D,R { RW::Read, RW::Read, - RW::NoData, RW::NoData, RW::NoData, RW::NoData, RW::NoData, + RW::NoData, RW::NoData, RW::NoData, RW::NoData, RW::NoData, RW::NoData, } ); @@ -1161,7 +1162,7 @@ struct M6809Traits { { RW::Read, RW::Read, RW::NoData, RW::NoData, RW::NoData, RW::NoData, RW::NoData, - RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::NoData, RW::NoData, } ); @@ -1169,7 +1170,7 @@ struct M6809Traits { {0x32, PostInc1 | RegX}, // R+ { RW::Read, RW::Read, - RW::NoData, RW::NoData, RW::NoData, + RW::NoData, RW::NoData, RW::NoData, RW::NoData, } ); @@ -1177,7 +1178,7 @@ struct M6809Traits { {0x32, PreDec1 | RegX}, // -R { RW::Read, RW::Read, - RW::NoData, RW::NoData, RW::NoData, + RW::NoData, RW::NoData, RW::NoData, RW::NoData, } ); @@ -1185,7 +1186,7 @@ struct M6809Traits { {0x32, PostInc2 | RegX}, // R++ { RW::Read, RW::Read, - RW::NoData, RW::NoData, RW::NoData, RW::NoData, + RW::NoData, RW::NoData, RW::NoData, RW::NoData, RW::NoData, } ); @@ -1194,14 +1195,14 @@ struct M6809Traits { { RW::Read, RW::Read, RW::NoData, RW::NoData, RW::NoData, RW::NoData, - RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::NoData, RW::NoData, } ); test( {0x32, PCOffset8bit | RegX, 0x00}, // 8n, PC { - RW::Read, RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::Read, RW::NoData, RW::NoData, } ); @@ -1209,7 +1210,7 @@ struct M6809Traits { {0x32, PCOffset8bit | RegX | Indirect, 0x00, 0x00, 0x00}, // [8n, PC] { RW::Read, RW::Read, RW::Read, RW::NoData, - RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::NoData, RW::NoData, } ); @@ -1217,7 +1218,7 @@ struct M6809Traits { {0x32, PCOffset16bit | RegX, 0x00, 0x00}, // 16n, PC { RW::Read, RW::Read, RW::Read, RW::Read, - RW::NoData, RW::NoData, RW::NoData, RW::NoData, + RW::NoData, RW::NoData, RW::NoData, RW::NoData, RW::NoData, } ); @@ -1226,7 +1227,7 @@ struct M6809Traits { { RW::Read, RW::Read, RW::Read, RW::Read, RW::NoData, RW::NoData, RW::NoData, RW::NoData, - RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::NoData, RW::NoData, } ); @@ -1235,7 +1236,7 @@ struct M6809Traits { { RW::Read, RW::Read, RW::Read, RW::Read, RW::NoData, - RW::Read, RW::Read, RW::NoData, + RW::Read, RW::Read, RW::NoData, RW::NoData, } ); } diff --git a/Processors/6809/6809.hpp b/Processors/6809/6809.hpp index ddf328ea2..ea1b7b674 100644 --- a/Processors/6809/6809.hpp +++ b/Processors/6809/6809.hpp @@ -666,7 +666,7 @@ struct Processor { ); address_.halves.high = registers_.reg(); - if(operation_.type == AccessType::LEA) { + if(operation_.operation == Operation::JMP) { goto internal_lic_break; } internal_cycle(LIC::Inactive); @@ -694,7 +694,7 @@ struct Processor { ++registers_.pc.full ); - if(operation_.type == AccessType::LEA) { + if(operation_.operation == Operation::JMP) { goto internal_lic_break; } internal_cycle(LIC::Inactive); @@ -766,7 +766,7 @@ struct Processor { read(BusState::Normal, LIC::Inactive, Literal(address_.full), operand_.halves.low, ++address_.full); address_ = operand_; - if(operation_.type == AccessType::LEA) { + if(operation_.operation == Operation::JMP) { goto internal_lic_break; } internal_cycle(LIC::Inactive); diff --git a/Processors/6809/Perform.hpp b/Processors/6809/Perform.hpp index 77cc86d87..0310b106d 100644 --- a/Processors/6809/Perform.hpp +++ b/Processors/6809/Perform.hpp @@ -545,10 +545,10 @@ Cycles perform( case STY: st(registers, word); return 0; case STS: st(registers, word); return 0; - case LEAU: lea(registers, word); return 0; - case LEAX: lea(registers, word); return 0; - case LEAY: lea(registers, word); return 0; - case LEAS: lea(registers, word); return 0; + case LEAU: lea(registers, word); return 1; + case LEAX: lea(registers, word); return 1; + case LEAY: lea(registers, word); return 1; + case LEAS: lea(registers, word); return 1; case MUL: mul(registers); return 9; // Per 6809cyc.txt; might need more research. @@ -606,8 +606,7 @@ inline bool is_zero_costed(const InstructionSet::M6809::Operation operation) { case CLR: case LDA: case LDB: case STA: case STB: case LDD: case LDU: case LDX: case LDY: case LDS: case STD: case STU: case STX: case STY: case STS: - case LEAU: case LEAX: case LEAY: case LEAS: case SEX: - case TSTA: case TSTB: case JMP: + case SEX: case TSTA: case TSTB: case JMP: return true; } } diff --git a/Processors/6809/Registers.hpp b/Processors/6809/Registers.hpp index 8dcf75180..470e06f04 100644 --- a/Processors/6809/Registers.hpp +++ b/Processors/6809/Registers.hpp @@ -9,6 +9,7 @@ #pragma once #include +#include #include #include "Numeric/RegisterSizes.hpp"