Skip to content

Commit

Permalink
wip property rework
Browse files Browse the repository at this point in the history
  • Loading branch information
gulrak committed Oct 10, 2024
1 parent da5bf60 commit 5c9d5ba
Show file tree
Hide file tree
Showing 10 changed files with 362 additions and 45 deletions.
1 change: 1 addition & 0 deletions src/emulation/chip8strict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ static bool registeredStrictC8 = CoreRegistry::registerFactory(PROP_CLASS, std::

bool Chip8StrictEmulator::updateProperties(Properties& props, Property& changed)
{
(void)registeredStrictC8;
if(fuzzyAnyOf(changed.getName(), {"TraceLog", "InstructionsPerFrame", "FrameRate"})) {
_options = Chip8StrictOptions::fromProperties(props);
return false;
Expand Down
19 changes: 7 additions & 12 deletions src/emulation/cosmacvip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
#include <fstream>
#include <memory>

#define VIDEO_FIRST_VISIBLE_LINE 80
#define VIDEO_FIRST_INVISIBLE_LINE 208

namespace emu {

static const std::string PROP_CLASS = "COSMAC-VIP";
Expand Down Expand Up @@ -751,7 +748,8 @@ uint16_t CosmacVIP::justPatchRAM(VIPChip8Interpreter interpreter, uint8_t* ram,
auto iter = g_patchSets.find(interpreter);
if(iter == g_patchSets.end())
return 0;
return iter->second.apply(ram, size);}
return iter->second.apply(ram, size);
}

std::string CosmacVIP::name() const
{
Expand Down Expand Up @@ -916,10 +914,7 @@ int64_t CosmacVIP::machineCycles() const

int CosmacVIP::frameRate() const
{
switch (_impl->_video.getType()) {
case Cdp186x::eCDP1864: return static_cast<int>(std::lround(_impl->_options.clockFrequency / 8.0 / 4368.0));
default: return static_cast<int>(std::lround(_impl->_options.clockFrequency / 8.0 / 3668.0));
}
return std::lround(_impl->_options.clockFrequency / 8.0 /_impl->_video.cyclesPerFrame());
}

bool CosmacVIP::executeCdp1802()
Expand Down Expand Up @@ -1010,7 +1005,7 @@ int CosmacVIP::executeInstruction()
}
//std::clog << "CHIP8: " << dumpStateLine() << std::endl;
const auto start = _impl->_cpu.cycles();
while(!executeCdp1802() && _execMode != ePAUSED && _impl->_cpu.cycles() - start < 3668*14);
while(!executeCdp1802() && _execMode != ePAUSED && _impl->_cpu.cycles() - start < _impl->_video.cyclesPerFrame()*14);
return static_cast<int>(_impl->_cpu.cycles() - start);
}

Expand All @@ -1027,12 +1022,12 @@ void CosmacVIP::executeInstructions(int numInstructions)

inline int CosmacVIP::frameCycle() const
{
return Cdp186x::frameCycle(_impl->_cpu.cycles()); // _impl->_irqStart ? ((_impl->_cpu.getCycles() >> 3) - _impl->_irqStart) : 0;
return _impl->_video.frameCycle(_impl->_cpu.cycles()); // _impl->_irqStart ? ((_impl->_cpu.getCycles() >> 3) - _impl->_irqStart) : 0;
}

inline int CosmacVIP::videoLine() const
{
return Cdp186x::videoLine(_impl->_cpu.cycles()); // (frameCycle() + (78*14)) % 3668) / 14;
return _impl->_video.videoLine(_impl->_cpu.cycles()); // (frameCycle() + (78*14)) % 3668) / 14;
}

void CosmacVIP::executeFrame()
Expand All @@ -1041,7 +1036,7 @@ void CosmacVIP::executeFrame()
setExecMode(ePAUSED);
return;
}
auto nextFrame = Cdp186x::nextFrame(_impl->_cpu.cycles());
auto nextFrame = _impl->_video.nextFrame(_impl->_cpu.cycles());
while(_execMode != ePAUSED && _impl->_cpu.cycles() < nextFrame) {
executeCdp1802();
}
Expand Down
19 changes: 13 additions & 6 deletions src/emulation/hardware/cdp186x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const uint32_t Cdp186x::_cdp1862BackgroundColors[4] = { 0x000080FF, 0x000000FF,
Cdp186x::Cdp186x(Type type, Cdp1802& cpu, bool traceLog)
: _cpu(cpu)
, _type(type)
, VIDEO_FIRST_VISIBLE_LINE(80)
, VIDEO_FIRST_INVISIBLE_LINE(type == eCDP1864 ? VIDEO_FIRST_VISIBLE_LINE + 192 : VIDEO_FIRST_VISIBLE_LINE + 128)
, VIDEO_CYCLES_PER_FRAME(type == eCDP1864 ? 4368 : 3668)
, _traceLog(traceLog)
{
static uint32_t foregroundColors[8] = { 0x181818FF, 0xFF0000FF, 0x0000FFFF, 0xFF00FFFF, 0x00FF00FF, 0xFFFF00FF, 0x00FFFFFF, 0xFFFFFFFF };
Expand Down Expand Up @@ -64,19 +67,23 @@ void Cdp186x::reset()
_screen.setPalette(_cdp1862Palette);
}
_frameCounter = 0;
_displayEnabledLatch = false;
_displayEnabledLatch = _displayEnabled = _type == eCDP1864;
disableDisplay();
}

void Cdp186x::enableDisplay()
{
_displayEnabled = true;
if(_type != eCDP1864) {
_displayEnabled = true;
}
}

void Cdp186x::disableDisplay()
{
_screen.setAll(0);
_displayEnabled = false;
if(_type != eCDP1864) {
_screen.setAll(0);
_displayEnabled = false;
}
}

bool Cdp186x::getNEFX() const
Expand All @@ -91,7 +98,7 @@ const Cdp186x::VideoType& Cdp186x::getScreen() const

std::pair<int,bool> Cdp186x::executeStep()
{
auto fc = static_cast<int>((_cpu.cycles() >> 3) % 3668);
auto fc = static_cast<int>((_cpu.cycles() >> 3) % VIDEO_CYCLES_PER_FRAME);
bool vsync = false;
if(fc < _frameCycle) {
vsync = true;
Expand Down Expand Up @@ -147,7 +154,7 @@ std::pair<int,bool> Cdp186x::executeStep()
}
}
}
return {(_cpu.cycles() >> 3) % 3668, vsync};
return {(_cpu.cycles() >> 3) % VIDEO_CYCLES_PER_FRAME, vsync};
}

void Cdp186x::incrementBackground()
Expand Down
18 changes: 10 additions & 8 deletions src/emulation/hardware/cdp186x.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@

namespace emu {

#define VIDEO_FIRST_VISIBLE_LINE 80
#define VIDEO_FIRST_INVISIBLE_LINE 208

class Cdp1802;

class Cdp186x
Expand All @@ -56,26 +53,28 @@ class Cdp186x
void setSubMode(SubMode subMode) { _subMode = subMode; }
void incrementBackground();
int frames() const { return _frameCounter; }
int cyclesPerFrame() const { return VIDEO_CYCLES_PER_FRAME; }
const VideoType& getScreen() const;

static int64_t machineCycle(cycles_t cycles)
{
return cycles >> 3;
}

static int frameCycle(cycles_t cycles)
int frameCycle(cycles_t cycles) const
{
return machineCycle(cycles) % 3668;
return int(machineCycle(cycles) % VIDEO_CYCLES_PER_FRAME);
}

static int videoLine(cycles_t cycles)
int videoLine(cycles_t cycles) const
{
return frameCycle(cycles) / 14;
}

static cycles_t nextFrame(cycles_t cycles)
cycles_t nextFrame(cycles_t cycles) const
{
return ((cycles + 8*3668) / (8*3668)) * (8*3668);
//return ((cycles + 8*VIDEO_CYCLES_PER_FRAME) / (8*VIDEO_CYCLES_PER_FRAME)) * (8*VIDEO_CYCLES_PER_FRAME);
return cycles + (8 * VIDEO_CYCLES_PER_FRAME - cycles % (8 * VIDEO_CYCLES_PER_FRAME));
}

private:
Expand All @@ -84,6 +83,9 @@ class Cdp186x
SubMode _subMode{eNONE};
std::array<uint32_t,256> _cdp1862Palette{};
VideoScreen<uint8_t,256,192> _screen;
const int VIDEO_FIRST_VISIBLE_LINE{0};
const int VIDEO_FIRST_INVISIBLE_LINE{0};
const int VIDEO_CYCLES_PER_FRAME{0};
int _frameCycle{0};
int _frameCounter{0};
int _backgroundColor{0};
Expand Down
Binary file added test-roms/bin/chromatophore-hp48-draw.ch8
Binary file not shown.
57 changes: 57 additions & 0 deletions test-roms/chromatophore-hp48-draw.8o
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Test by Chromatophore
# https://github.com/Chromatophore/HP48-Superchip/blob/master/investigations/quirk_display.md

:alias px v3
:alias py v4

: main
i := data
load v5
lores

i := tilea
sprite v0 v1 15

vf := key

hires

vf := key

i := tileb
sprite v2 v3 15

vf := key

sprite v4 v3 15
sprite v2 v5 15
sprite v4 v5 15

vf := key

lores

vf := key

i := tilea
sprite v0 v1 15

vf := key

clear

vf := key

jump main
;

: data
10 10 20 20 28 35

: tilea
0xFF 0xBD 0xFF 0xE7 0xFF 0xA5 0xDB 0xA5
0xDB 0xA5 0xD9 0xFF 0xFF 0xFF 0xFF

: tileb
0xCD 0xFE 0xCD 0xFE 0xCD 0xFE 0xCD 0xFE
0xCD 0xFE 0xCD 0xFE 0xCD 0xFE 0xCD
4 changes: 2 additions & 2 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ if(FALSE)
endif()

if(chip8testsuite_SOURCE_DIR)
add_executable(chip8_emulation_tests main.cpp basic_opcode_tests.cpp test_suite_tests.cpp chip8testhelper.hpp)
add_compile_definitions(chip8_emulation_tests PUBLIC CHIP8_TEST_SUITE="${chip8testsuite_SOURCE_DIR}")
add_executable(chip8_emulation_tests main.cpp basic_opcode_tests.cpp test_suite_tests.cpp superchip_tests.cpp chip8testhelper.hpp)
add_compile_definitions(chip8_emulation_tests PUBLIC CHIP8_TEST_SUITE="${chip8testsuite_SOURCE_DIR}" TEST_ROM_FOLDER="${PROJECT_SOURCE_DIR}/test-roms/bin")
else()
add_executable(chip8_emulation_tests main.cpp basic_opcode_tests.cpp chip8testhelper.hpp)
endif()
Expand Down
46 changes: 32 additions & 14 deletions test/basic_opcode_tests.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@
//
//---------------------------------------------------------------------------------------

#if QUIRKS & QUIRK_SCALE_X2
#define SCALE_X 2
#else
#define SCALE_X 1
#endif
#if QUIRKS & QUIRK_SCALE_Y4
#define SCALE_Y 4
#elif QUIRKS & QUIRK_SCALE_Y2
#define SCALE_Y 2
#else
#define SCALE_Y 1
#endif

TEST_SUITE_BEGIN(C8CORE "-Basic-Opcodes");

Expand Down Expand Up @@ -643,7 +655,7 @@ TEST_CASE(C8CORE ": Cxnn - vx := random nn")
CHECK(maskOr == 0xa5);
}

TEST_CASE(C8CORE ": Dxyn - sprite vx vy n")
TEST_CASE(C8CORE ": Dxyn - sprite vx vy n, simple draw")
{
std::string pacImage = "..####.\n.######\n##.###.\n#####..\n#####..\n######.\n.######\n..####.\n";
auto [host, core, start] = createChip8Instance(C8CORE);
Expand All @@ -658,21 +670,23 @@ TEST_CASE(C8CORE ": Dxyn - sprite vx vy n")
step(core);
}
CheckState(core, {.i = 0x400, .pc = start + 8, .sp = 0, .dt = TIMER_DEFAULT, .st = TIMER_DEFAULT, .v = {3,4,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}, .stack = {}}, "sprite v0 v1 8");
auto [rect, content] = host->chip8UsedScreen(SCALE_X, SCALE_Y);
CHECK(3 == rect.x);
CHECK(4 == rect.y);
CHECK(pacImage == content);
}

TEST_CASE(C8CORE ": Dxyn - sprite vx vy n, xor draw")
{
std::string pacImage = "..#...#.\n.#.....#\n#.##..#.\n#....#..\n#....#..\n#.....#.\n.#.....#\n..#...#.\n";
auto [host, core, start] = createChip8Instance(C8CORE);
core->reset();
write(core, start, {0x6003, 0x6104, 0xA400, 0xD018, 0x6004, 0xD018, uint16_t(0x1000 + start + 12)});
write(core, 0x400, {0x3c7e, 0xdcf8, 0xf8fc, 0x7e3c, 0x8000});
host->executeFrame();
host->executeFrame();
#if QUIRKS & QUIRK_SCALE_X2
auto scaleX = 2;
#else
auto scaleX = 1;
#endif
#if QUIRKS & QUIRK_SCALE_Y4
auto scaleY = 4;
#elif QUIRKS & QUIRK_SCALE_Y2
auto scaleY = 2;
#else
auto scaleY = 1;
#endif
auto [rect, content] = host->chip8UsedScreen(scaleX, scaleY);
auto [rect, content] = host->chip8UsedScreen(SCALE_X, SCALE_Y);
CHECK(core->getV(15) > 0);
CHECK(3 == rect.x);
CHECK(4 == rect.y);
CHECK(pacImage == content);
Expand Down Expand Up @@ -941,3 +955,7 @@ TEST_CASE(C8CORE ": Fx65 - load vx, checking i is unchanged")
#endif

TEST_SUITE_END();

#undef SCALE_X
#undef SCALE_Y

Loading

0 comments on commit 5c9d5ba

Please sign in to comment.