1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Added two, extraordinarily simple tests.

This commit is contained in:
Thomas Harte 2017-02-12 20:32:53 -05:00
parent 25776de59d
commit cd90118a0f
4 changed files with 112 additions and 18 deletions

View File

@ -19,7 +19,7 @@ namespace {
uint8_t reverse_table[256];
}
TIA::TIA() :
TIA::TIA(bool create_crt) :
horizontal_counter_(0),
pixels_start_location_(0),
output_mode_(0),
@ -33,9 +33,12 @@ TIA::TIA() :
horizontal_move_start_time_(0),
collision_flags_(0)
{
crt_.reset(new Outputs::CRT::CRT(cycles_per_line * 2 + 1, 1, Outputs::CRT::DisplayType::NTSC60, 1));
crt_->set_output_device(Outputs::CRT::Television);
set_output_mode(OutputMode::NTSC);
if(create_crt)
{
crt_.reset(new Outputs::CRT::CRT(cycles_per_line * 2 + 1, 1, Outputs::CRT::DisplayType::NTSC60, 1));
crt_->set_output_device(Outputs::CRT::Television);
set_output_mode(OutputMode::NTSC);
}
for(int c = 0; c < 256; c++)
{
@ -132,7 +135,9 @@ TIA::TIA() :
collision_buffer_.resize(160);
}
TIA::TIA(std::function<void(uint8_t *output_buffer)> line_end_function) : TIA()
TIA::TIA() : TIA(true) {}
TIA::TIA(std::function<void(uint8_t *output_buffer)> line_end_function) : TIA(false)
{
line_end_function_ = line_end_function;
}
@ -424,13 +429,13 @@ void TIA::output_for_cycles(int number_of_cycles)
{ \
if(horizontal_counter_ <= target) \
{ \
crt_->function((unsigned int)((horizontal_counter_ - output_cursor) * 2)); \
if(crt_) crt_->function((unsigned int)((horizontal_counter_ - output_cursor) * 2)); \
horizontal_counter_ %= cycles_per_line; \
return; \
} \
else \
{ \
crt_->function((unsigned int)((target - output_cursor) * 2)); \
if(crt_) crt_->function((unsigned int)((target - output_cursor) * 2)); \
output_cursor = target; \
} \
}
@ -459,16 +464,16 @@ void TIA::output_for_cycles(int number_of_cycles)
if(pixel_target_)
{
output_pixels(pixels_start_location_, output_cursor);
crt_->output_data((unsigned int)(output_cursor - pixels_start_location_) * 2, 2);
if(crt_) crt_->output_data((unsigned int)(output_cursor - pixels_start_location_) * 2, 2);
pixel_target_ = nullptr;
pixels_start_location_ = 0;
}
int duration = std::min(228, horizontal_counter_) - output_cursor;
crt_->output_blank((unsigned int)(duration * 2));
if(crt_) crt_->output_blank((unsigned int)(duration * 2));
}
else
{
if(!pixels_start_location_)
if(!pixels_start_location_ && crt_)
{
pixels_start_location_ = output_cursor;
pixel_target_ = crt_->allocate_write_area(160);
@ -484,7 +489,7 @@ void TIA::output_for_cycles(int number_of_cycles)
output_cursor++;
}
if(horizontal_counter_ == cycles_per_line)
if(horizontal_counter_ == cycles_per_line && crt_)
{
crt_->output_data((unsigned int)(output_cursor - pixels_start_location_) * 2, 2);
pixel_target_ = nullptr;
@ -549,16 +554,22 @@ void TIA::output_line()
break;
case sync_flag:
case sync_flag | blank_flag:
crt_->output_sync(32);
crt_->output_blank(32);
crt_->output_sync(392);
if(crt_)
{
crt_->output_sync(32);
crt_->output_blank(32);
crt_->output_sync(392);
}
horizontal_blank_extend_ = false;
break;
case blank_flag:
crt_->output_blank(32);
crt_->output_sync(32);
crt_->output_default_colour_burst(32);
crt_->output_blank(360);
if(crt_)
{
crt_->output_blank(32);
crt_->output_sync(32);
crt_->output_default_colour_burst(32);
crt_->output_blank(360);
}
horizontal_blank_extend_ = false;
break;
}

View File

@ -23,6 +23,7 @@ class TIA {
// be called with the latest collision buffer upon the conclusion of each line. What's a collision
// buffer? It's an implementation detail. If you're not writing a unit test, leave it alone.
TIA(std::function<void(uint8_t *output_buffer)> line_end_function);
TIA(bool create_crt);
enum class OutputMode {
NTSC, PAL

View File

@ -30,6 +30,7 @@
4B2A53A11D117D36003C6002 /* CSAtari2600.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539A1D117D36003C6002 /* CSAtari2600.mm */; };
4B2A53A21D117D36003C6002 /* CSElectron.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539C1D117D36003C6002 /* CSElectron.mm */; };
4B2A53A31D117D36003C6002 /* CSVic20.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539E1D117D36003C6002 /* CSVic20.mm */; };
4B2AF8691E513FC20027EE29 /* TIATests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2AF8681E513FC20027EE29 /* TIATests.mm */; };
4B2BFC5F1D613E0200BA3AA9 /* TapePRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */; };
4B2BFDB21DAEF5FF001A68B8 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2BFDB01DAEF5FF001A68B8 /* Video.cpp */; };
4B2C45421E3C3896002A2389 /* cartridge.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B2C45411E3C3896002A2389 /* cartridge.png */; };
@ -474,6 +475,7 @@
4B2A539C1D117D36003C6002 /* CSElectron.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CSElectron.mm; sourceTree = "<group>"; };
4B2A539D1D117D36003C6002 /* CSVic20.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSVic20.h; sourceTree = "<group>"; };
4B2A539E1D117D36003C6002 /* CSVic20.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CSVic20.mm; sourceTree = "<group>"; };
4B2AF8681E513FC20027EE29 /* TIATests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TIATests.mm; sourceTree = "<group>"; };
4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TapePRG.cpp; sourceTree = "<group>"; };
4B2BFC5E1D613E0200BA3AA9 /* TapePRG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TapePRG.hpp; sourceTree = "<group>"; };
4B2BFDB01DAEF5FF001A68B8 /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Video.cpp; path = Oric/Video.cpp; sourceTree = "<group>"; };
@ -1724,6 +1726,7 @@
4B121F941E05E66800BFDA12 /* PCMPatchedTrackTests.mm */,
4B121F9A1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm */,
4BD4A8CF1E077FD20020D856 /* PCMTrackTests.mm */,
4B2AF8681E513FC20027EE29 /* TIATests.mm */,
4B1D08051E0F7A1100763741 /* TimeTests.mm */,
4BB73EB81B587A5100552FC2 /* Info.plist */,
4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */,
@ -2494,6 +2497,7 @@
4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */,
4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */,
4B50730A1DDFCFDF00C48FBD /* ArrayBuilderTests.mm in Sources */,
4B2AF8691E513FC20027EE29 /* TIATests.mm in Sources */,
4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */,
4B3BA0D11D318B44005DD7A7 /* TestMachine.mm in Sources */,
4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */,

View File

@ -0,0 +1,78 @@
//
// TIATests.m
// Clock Signal
//
// Created by Thomas Harte on 12/02/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#import <XCTest/XCTest.h>
#include "TIA.hpp"
static uint8_t *line;
static void receive_line(uint8_t *next_line)
{
line = next_line;
}
@interface TIATests : XCTestCase
@end
@implementation TIATests {
std::unique_ptr<Atari2600::TIA> _tia;
}
- (void)setUp
{
[super setUp];
std::function<void(uint8_t *)> function = receive_line;
_tia.reset(new Atari2600::TIA(function));
line = nullptr;
}
- (void)testReflectedPlayfield
{
// set reflected, bit pattern 1000
_tia->set_playfield_control_and_ball_size(1);
_tia->set_playfield(0, 0x10);
_tia->set_playfield(1, 0xf0);
_tia->set_playfield(2, 0x0e);
_tia->run_for_cycles(228);
XCTAssert(line != nullptr, @"228 cycles should have ended the line");
uint8_t expected_line[] = {
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1
};
XCTAssert(!memcmp(expected_line, line, sizeof(expected_line)));
}
- (void)testRepeatedPlayfield
{
// set reflected, bit pattern 1000
_tia->set_playfield_control_and_ball_size(0);
_tia->set_playfield(0, 0x10);
_tia->set_playfield(1, 0xf0);
_tia->set_playfield(2, 0x0e);
_tia->run_for_cycles(228);
XCTAssert(line != nullptr, @"228 cycles should have ended the line");
uint8_t expected_line[] = {
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
XCTAssert(!memcmp(expected_line, line, sizeof(expected_line)));
}
@end