mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-21 21:33:54 +00:00
Merge pull request #928 from TomHarte/ContentionTests
Add timing tests, fix +3 discrepancy.
This commit is contained in:
commit
17f11a3be3
@ -80,7 +80,7 @@ template <VideoTiming timing> class Video {
|
||||
static constexpr Timings get_timings() {
|
||||
if constexpr (timing == VideoTiming::Plus3) {
|
||||
constexpr int delays[] = {1, 0, 7, 6, 5, 4, 3, 2};
|
||||
return Timings(228, 311, 6, 129, 14365, delays);
|
||||
return Timings(228, 311, 6, 129, 14361, delays);
|
||||
}
|
||||
|
||||
if constexpr (timing == VideoTiming::OneTwoEightK) {
|
||||
@ -94,8 +94,8 @@ template <VideoTiming timing> class Video {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: how long is the interrupt line held for?
|
||||
static constexpr int interrupt_duration = 48;
|
||||
// Interrupt should be held for 32 cycles.
|
||||
static constexpr int interrupt_duration = 64;
|
||||
|
||||
public:
|
||||
void run_for(HalfCycles duration) {
|
||||
|
@ -478,6 +478,7 @@
|
||||
4B89453D201967B4007DE474 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B894516201967B4007DE474 /* StaticAnalyser.cpp */; };
|
||||
4B89453E201967B4007DE474 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B894517201967B4007DE474 /* StaticAnalyser.cpp */; };
|
||||
4B89453F201967B4007DE474 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B894517201967B4007DE474 /* StaticAnalyser.cpp */; };
|
||||
4B8DD3682633B2D400B3C866 /* SpectrumVideoContentionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DD3672633B2D400B3C866 /* SpectrumVideoContentionTests.mm */; };
|
||||
4B8DF4D825465B7500F3433C /* IIgsMemoryMapTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF4D725465B7500F3433C /* IIgsMemoryMapTests.mm */; };
|
||||
4B8DF4F9254E36AE00F3433C /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF4F7254E36AD00F3433C /* Video.cpp */; };
|
||||
4B8DF4FA254E36AE00F3433C /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF4F7254E36AD00F3433C /* Video.cpp */; };
|
||||
@ -1427,6 +1428,7 @@
|
||||
4B894540201967D6007DE474 /* Machines.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Machines.hpp; sourceTree = "<group>"; };
|
||||
4B8A7E85212F988200F2BBC6 /* DeferredQueue.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DeferredQueue.hpp; sourceTree = "<group>"; };
|
||||
4B8D287E1F77207100645199 /* TrackSerialiser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TrackSerialiser.hpp; sourceTree = "<group>"; };
|
||||
4B8DD3672633B2D400B3C866 /* SpectrumVideoContentionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SpectrumVideoContentionTests.mm; sourceTree = "<group>"; };
|
||||
4B8DF4D62546561300F3433C /* MemoryMap.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MemoryMap.hpp; sourceTree = "<group>"; };
|
||||
4B8DF4D725465B7500F3433C /* IIgsMemoryMapTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = IIgsMemoryMapTests.mm; sourceTree = "<group>"; };
|
||||
4B8DF4ED254B840B00F3433C /* AppleClock.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AppleClock.hpp; sourceTree = "<group>"; };
|
||||
@ -3939,8 +3941,12 @@
|
||||
4BB73EB51B587A5100552FC2 /* Clock SignalTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B85322922778E4200F26553 /* Comparative68000.hpp */,
|
||||
4B90467222C6FA31000E2074 /* TestRunner68000.hpp */,
|
||||
4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */,
|
||||
4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */,
|
||||
4BC751B11D157E61006C31D9 /* 6522Tests.swift */,
|
||||
4B1E85801D176468001EF87D /* 6532Tests.swift */,
|
||||
4B4F478925367EDC004245B8 /* 65816AddressingTests.swift */,
|
||||
4B8DF5132550D62900F3433C /* 65816kromTests.swift */,
|
||||
4B90467522C6FD6E000E2074 /* 68000ArithmeticTests.mm */,
|
||||
4B9D0C4A22C7D70900DE1AD3 /* 68000BCDTests.mm */,
|
||||
4B90467322C6FADD000E2074 /* 68000BitwiseTests.mm */,
|
||||
@ -3949,46 +3955,43 @@
|
||||
4BC5C3DF22C994CC00795658 /* 68000MoveTests.mm */,
|
||||
4B9D0C4E22C7E0CF00DE1AD3 /* 68000RollShiftTests.mm */,
|
||||
4BD388872239E198002D14B5 /* 68000Tests.mm */,
|
||||
4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */,
|
||||
4B924E981E74D22700B76AF1 /* AtariStaticAnalyserTests.mm */,
|
||||
4BE34437238389E10058E78F /* AtariSTVideoTests.mm */,
|
||||
4B049CDC1DA3C82F00322067 /* BCDTest.swift */,
|
||||
4B3BA0C41D318B44005DD7A7 /* Bridges */,
|
||||
4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */,
|
||||
4B85322922778E4200F26553 /* Comparative68000.hpp */,
|
||||
4BB2A9AE1E13367E001A5C23 /* CRCTests.mm */,
|
||||
4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */,
|
||||
4BFF1D3C2235C3C100838EA1 /* EmuTOSTests.mm */,
|
||||
4BBF49AE1ED2880200AB3669 /* FUSETests.swift */,
|
||||
4B8DF4D725465B7500F3433C /* IIgsMemoryMapTests.mm */,
|
||||
4BB73EB81B587A5100552FC2 /* Info.plist */,
|
||||
4B4F477B253530B7004245B8 /* Jeek816Tests.swift */,
|
||||
4B1414611B58888700E04248 /* KlausDormannTests.swift */,
|
||||
4BEE1EBF22B5E236000A26A6 /* MacGCRTests.mm */,
|
||||
4BE90FFC22D5864800FB464D /* MacintoshVideoTests.mm */,
|
||||
4BA91E1C216D85BA00F79557 /* MasterSystemVDPTests.mm */,
|
||||
4B98A0601FFADCDE00ADF63B /* MSXStaticAnalyserTests.mm */,
|
||||
4BC0CB272446BC7B00A79DBB /* OPLTests.mm */,
|
||||
4BD91D762401C2B8007BDC91 /* PatrikRakTests.swift */,
|
||||
4B121F9A1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm */,
|
||||
4BD4A8CF1E077FD20020D856 /* PCMTrackTests.mm */,
|
||||
4B3F76B825A1635300178AEC /* PowerPCDecoderTests.mm */,
|
||||
4BE76CF822641ED300ACD6FA /* QLTests.mm */,
|
||||
4B8DD3672633B2D400B3C866 /* SpectrumVideoContentionTests.mm */,
|
||||
4B1414631B588A1100E04248 /* Test Binaries */,
|
||||
4B90467222C6FA31000E2074 /* TestRunner68000.hpp */,
|
||||
4B2AF8681E513FC20027EE29 /* TIATests.mm */,
|
||||
4B1D08051E0F7A1100763741 /* TimeTests.mm */,
|
||||
4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */,
|
||||
4BEE4BD325A26E2B00011BD2 /* x86DecoderTests.mm */,
|
||||
4BDA8234261E8E000021AA19 /* Z80ContentionTests.mm */,
|
||||
4BB73EB81B587A5100552FC2 /* Info.plist */,
|
||||
4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */,
|
||||
4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */,
|
||||
4BC751B11D157E61006C31D9 /* 6522Tests.swift */,
|
||||
4B1E85801D176468001EF87D /* 6532Tests.swift */,
|
||||
4B4F478925367EDC004245B8 /* 65816AddressingTests.swift */,
|
||||
4B8DF5132550D62900F3433C /* 65816kromTests.swift */,
|
||||
4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */,
|
||||
4B049CDC1DA3C82F00322067 /* BCDTest.swift */,
|
||||
4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */,
|
||||
4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */,
|
||||
4BBF49AE1ED2880200AB3669 /* FUSETests.swift */,
|
||||
4B4F477B253530B7004245B8 /* Jeek816Tests.swift */,
|
||||
4B1414611B58888700E04248 /* KlausDormannTests.swift */,
|
||||
4BD91D762401C2B8007BDC91 /* PatrikRakTests.swift */,
|
||||
4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */,
|
||||
4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */,
|
||||
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */,
|
||||
4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */,
|
||||
4BFCA12A1ECBE7C400AC40C1 /* ZexallTests.swift */,
|
||||
4B3BA0C41D318B44005DD7A7 /* Bridges */,
|
||||
4B1414631B588A1100E04248 /* Test Binaries */,
|
||||
);
|
||||
path = "Clock SignalTests";
|
||||
sourceTree = "<group>";
|
||||
@ -5643,6 +5646,7 @@
|
||||
4B4DEC07252BFA56004583AC /* 65816Base.cpp in Sources */,
|
||||
4B778F2323A5EDE40000D260 /* Tape.cpp in Sources */,
|
||||
4B778F4F23A5F21C0000D260 /* StaticAnalyser.cpp in Sources */,
|
||||
4B8DD3682633B2D400B3C866 /* SpectrumVideoContentionTests.mm in Sources */,
|
||||
4B778EEF23A5D6680000D260 /* AsyncTaskQueue.cpp in Sources */,
|
||||
4B778F1223A5EC720000D260 /* CRT.cpp in Sources */,
|
||||
4B778EF423A5DB3A0000D260 /* C1540.cpp in Sources */,
|
||||
|
156
OSBindings/Mac/Clock SignalTests/SpectrumVideoContentionTests.mm
Normal file
156
OSBindings/Mac/Clock SignalTests/SpectrumVideoContentionTests.mm
Normal file
@ -0,0 +1,156 @@
|
||||
//
|
||||
// SpectrumVideoContentionTests.cpp
|
||||
// Clock SignalTests
|
||||
//
|
||||
// Created by Thomas Harte on 23/4/2021.
|
||||
// Copyright © 2021 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#include "../../../Machines/Sinclair/ZXSpectrum/Video.hpp"
|
||||
|
||||
@interface SpectrumVideoContentionTests : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation SpectrumVideoContentionTests
|
||||
|
||||
struct ContentionAnalysis {
|
||||
int time_after_interrupt = 0;
|
||||
int contended_lines = 0;
|
||||
int contention_length = 0;
|
||||
int line_length = 0;
|
||||
int total_lines = 0;
|
||||
HalfCycles pattern[8];
|
||||
};
|
||||
|
||||
template <Sinclair::ZXSpectrum::VideoTiming video_timing> ContentionAnalysis analyse() {
|
||||
Sinclair::ZXSpectrum::Video<video_timing> video;
|
||||
ContentionAnalysis analysis;
|
||||
|
||||
// Advance to the start of the first interrupt.
|
||||
while(video.get_interrupt_line()) {
|
||||
video.run_for(HalfCycles(1));
|
||||
}
|
||||
while(!video.get_interrupt_line()) {
|
||||
video.run_for(HalfCycles(1));
|
||||
}
|
||||
|
||||
// Count half cycles until first non-zero contended time.
|
||||
while(video.access_delay(HalfCycles(0)) == HalfCycles(0)) {
|
||||
video.run_for(HalfCycles(2));
|
||||
analysis.time_after_interrupt += 2;
|
||||
}
|
||||
|
||||
// Grab the contention pattern.
|
||||
for(int c = 0; c < 8; c++) {
|
||||
analysis.pattern[c] = video.access_delay(HalfCycles(0));
|
||||
video.run_for(HalfCycles(2));
|
||||
}
|
||||
|
||||
// Figure out how long contention goes on for.
|
||||
int c = 0;
|
||||
analysis.contention_length = 16; // For the 16 just skipped.
|
||||
do {
|
||||
analysis.contention_length += 2;
|
||||
video.run_for(HalfCycles(2));
|
||||
c++;
|
||||
} while(analysis.pattern[c&7] == video.access_delay(HalfCycles(0)));
|
||||
|
||||
// Look for next start of contention to determine line length.
|
||||
analysis.line_length = analysis.contention_length;
|
||||
while(video.access_delay(HalfCycles(0)) == HalfCycles(0)) {
|
||||
video.run_for(HalfCycles(2));
|
||||
analysis.line_length += 2;
|
||||
}
|
||||
|
||||
// Count contended lines.
|
||||
analysis.contended_lines = 1;
|
||||
while(video.access_delay(HalfCycles(0)) == analysis.pattern[0]) {
|
||||
video.run_for(HalfCycles(analysis.line_length));
|
||||
++analysis.contended_lines;
|
||||
}
|
||||
|
||||
// Count total lines.
|
||||
analysis.total_lines = analysis.contended_lines;
|
||||
while(video.access_delay(HalfCycles(0)) != analysis.pattern[0]) {
|
||||
video.run_for(HalfCycles(analysis.line_length));
|
||||
++analysis.total_lines;
|
||||
}
|
||||
|
||||
return analysis;
|
||||
}
|
||||
|
||||
- (void)test48k {
|
||||
const auto analysis = analyse<Sinclair::ZXSpectrum::VideoTiming::FortyEightK>();
|
||||
|
||||
// Check time from interrupt.
|
||||
XCTAssertEqual(analysis.time_after_interrupt, 14335*2);
|
||||
|
||||
// Check contention pattern.
|
||||
XCTAssertEqual(analysis.pattern[0], HalfCycles(6 * 2));
|
||||
XCTAssertEqual(analysis.pattern[1], HalfCycles(5 * 2));
|
||||
XCTAssertEqual(analysis.pattern[2], HalfCycles(4 * 2));
|
||||
XCTAssertEqual(analysis.pattern[3], HalfCycles(3 * 2));
|
||||
XCTAssertEqual(analysis.pattern[4], HalfCycles(2 * 2));
|
||||
XCTAssertEqual(analysis.pattern[5], HalfCycles(1 * 2));
|
||||
XCTAssertEqual(analysis.pattern[6], HalfCycles(0 * 2));
|
||||
XCTAssertEqual(analysis.pattern[7], HalfCycles(0 * 2));
|
||||
|
||||
// Check line length and count.
|
||||
XCTAssertEqual(analysis.contention_length, 128*2);
|
||||
XCTAssertEqual(analysis.line_length, 224*2);
|
||||
XCTAssertEqual(analysis.contended_lines, 192);
|
||||
XCTAssertEqual(analysis.total_lines, 312);
|
||||
}
|
||||
|
||||
- (void)test128k {
|
||||
const auto analysis = analyse<Sinclair::ZXSpectrum::VideoTiming::OneTwoEightK>();
|
||||
|
||||
// Check time from interrupt.
|
||||
XCTAssertEqual(analysis.time_after_interrupt, 14361*2);
|
||||
|
||||
// Check contention pattern.
|
||||
XCTAssertEqual(analysis.pattern[0], HalfCycles(6 * 2));
|
||||
XCTAssertEqual(analysis.pattern[1], HalfCycles(5 * 2));
|
||||
XCTAssertEqual(analysis.pattern[2], HalfCycles(4 * 2));
|
||||
XCTAssertEqual(analysis.pattern[3], HalfCycles(3 * 2));
|
||||
XCTAssertEqual(analysis.pattern[4], HalfCycles(2 * 2));
|
||||
XCTAssertEqual(analysis.pattern[5], HalfCycles(1 * 2));
|
||||
XCTAssertEqual(analysis.pattern[6], HalfCycles(0 * 2));
|
||||
XCTAssertEqual(analysis.pattern[7], HalfCycles(0 * 2));
|
||||
|
||||
// Check line length and count.
|
||||
XCTAssertEqual(analysis.contention_length, 128*2);
|
||||
XCTAssertEqual(analysis.line_length, 228*2);
|
||||
XCTAssertEqual(analysis.contended_lines, 192);
|
||||
XCTAssertEqual(analysis.total_lines, 311);
|
||||
}
|
||||
|
||||
- (void)testPlus3 {
|
||||
const auto analysis = analyse<Sinclair::ZXSpectrum::VideoTiming::Plus3>();
|
||||
|
||||
// Check time from interrupt.
|
||||
XCTAssertEqual(analysis.time_after_interrupt, 14361*2);
|
||||
|
||||
// Check contention pattern.
|
||||
XCTAssertEqual(analysis.pattern[0], HalfCycles(1 * 2));
|
||||
XCTAssertEqual(analysis.pattern[1], HalfCycles(0 * 2));
|
||||
XCTAssertEqual(analysis.pattern[2], HalfCycles(7 * 2));
|
||||
XCTAssertEqual(analysis.pattern[3], HalfCycles(6 * 2));
|
||||
XCTAssertEqual(analysis.pattern[4], HalfCycles(5 * 2));
|
||||
XCTAssertEqual(analysis.pattern[5], HalfCycles(4 * 2));
|
||||
XCTAssertEqual(analysis.pattern[6], HalfCycles(3 * 2));
|
||||
XCTAssertEqual(analysis.pattern[7], HalfCycles(2 * 2));
|
||||
|
||||
// Check line length and count.
|
||||
XCTAssertEqual(analysis.contention_length, 130*2); // By the manner used for detection above,
|
||||
// the first obviously missing contention spot
|
||||
// will be after 130 cycles, not the textbook 129,
|
||||
// because cycle 130 is a delay of 0 either way.
|
||||
XCTAssertEqual(analysis.line_length, 228*2);
|
||||
XCTAssertEqual(analysis.contended_lines, 192);
|
||||
XCTAssertEqual(analysis.total_lines, 311);
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue
Block a user