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

Starts to introduce the QL as a second source for 68000 testing.

It's advantageous over the ST in that a commented disassembly of the ROM is available.
This commit is contained in:
Thomas Harte 2019-04-14 22:15:09 -04:00
parent 75d8824e6b
commit 52e33e861c
2 changed files with 122 additions and 0 deletions

View File

@ -637,6 +637,7 @@
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539A1D117D36003C6002 /* CSAtari2600.mm */; };
4BDB61EC203285AE0048AF91 /* Atari2600OptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */; };
4BDDBA991EF3451200347E61 /* Z80MachineCycleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */; };
4BE76CF922641ED400ACD6FA /* QLTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BE76CF822641ED300ACD6FA /* QLTests.mm */; };
4BE7C9181E3D397100A5496D /* TIA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE7C9161E3D397100A5496D /* TIA.cpp */; };
4BE9A6B11EDE293000CBCB47 /* zexdoc.com in Resources */ = {isa = PBXBuildFile; fileRef = 4BE9A6B01EDE293000CBCB47 /* zexdoc.com */; };
4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; };
@ -1406,6 +1407,7 @@
4BE3231520532AA7006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
4BE3231620532BED006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
4BE3231720532CC0006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
4BE76CF822641ED300ACD6FA /* QLTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QLTests.mm; sourceTree = "<group>"; };
4BE7C9161E3D397100A5496D /* TIA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TIA.cpp; sourceTree = "<group>"; };
4BE7C9171E3D397100A5496D /* TIA.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TIA.hpp; sourceTree = "<group>"; };
4BE845201F2FF7F100A5EA22 /* CRTC6845.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRTC6845.hpp; path = 6845/CRTC6845.hpp; sourceTree = "<group>"; };
@ -2832,6 +2834,7 @@
4B98A0601FFADCDE00ADF63B /* MSXStaticAnalyserTests.mm */,
4B121F9A1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm */,
4BD4A8CF1E077FD20020D856 /* PCMTrackTests.mm */,
4BE76CF822641ED300ACD6FA /* QLTests.mm */,
4B2AF8681E513FC20027EE29 /* TIATests.mm */,
4B1D08051E0F7A1100763741 /* TimeTests.mm */,
4BB73EB81B587A5100552FC2 /* Info.plist */,
@ -4031,6 +4034,7 @@
4BA91E1D216D85BA00F79557 /* MasterSystemVDPTests.mm in Sources */,
4B98A0611FFADCDE00ADF63B /* MSXStaticAnalyserTests.mm in Sources */,
4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */,
4BE76CF922641ED400ACD6FA /* QLTests.mm in Sources */,
4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */,
4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */,
4BFCA12B1ECBE7C400AC40C1 /* ZexallTests.swift in Sources */,

View File

@ -0,0 +1,118 @@
//
// EmuTOSTests.m
// Clock SignalTests
//
// Created by Thomas Harte on 10/03/2019.
// Copyright © 2019 Thomas Harte. All rights reserved.
//
#import <XCTest/XCTest.h>
#include <array>
#include <cassert>
#include "68000.hpp"
#include "CSROMFetcher.hpp"
class QL: public CPU::MC68000::BusHandler {
public:
QL(const std::vector<uint8_t> &rom) : m68000_(*this) {
assert(!(rom.size() & 1));
rom_.resize(rom.size() / 2);
for(size_t c = 0; c < rom_.size(); ++c) {
rom_[c] = (rom[c << 1] << 8) | rom[(c << 1) + 1];
}
}
void run_for(HalfCycles cycles) {
m68000_.run_for(cycles);
}
HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int is_supervisor) {
const uint32_t address = cycle.word_address();
uint32_t word_address = address;
// As much about the Atari ST's memory map as is relevant here: the ROM begins
// at 0xfc0000, and the first eight bytes are mirrored to the first four memory
// addresses in order for /RESET to work properly. RAM otherwise fills the first
// 512kb of the address space. Trying to write to ROM raises a bus error.
const bool is_peripheral = false;//word_address > (0xff0000 >> 1);
const bool is_rom = word_address < (0xc000 >> 1);
uint16_t *const base = is_rom ? rom_.data() : ram_.data();
if(is_rom) {
word_address &= 0xbfff;
} else {
word_address &= 0x3ffff;
}
using Microcycle = CPU::MC68000::Microcycle;
if(cycle.data_select_active()) {
uint16_t peripheral_result = 0xffff;
/* if(is_peripheral) {
switch(address & 0x7ff) {
// A hard-coded value for TIMER B.
case (0xa21 >> 1):
peripheral_result = 0x00000001;
break;
}
printf("Peripheral: %c %08x", (cycle.operation & Microcycle::Read) ? 'r' : 'w', *cycle.address);
if(!(cycle.operation & Microcycle::Read)) {
if(cycle.operation & Microcycle::SelectByte)
printf(" %02x", cycle.value->halves.low);
else
printf(" %04x", cycle.value->full);
}
printf("\n");
}*/
switch(cycle.operation & (Microcycle::SelectWord | Microcycle::SelectByte | Microcycle::Read)) {
default: break;
case Microcycle::SelectWord | Microcycle::Read:
cycle.value->full = is_peripheral ? peripheral_result : base[word_address];
break;
case Microcycle::SelectByte | Microcycle::Read:
cycle.value->halves.low = (is_peripheral ? peripheral_result : base[word_address]) >> cycle.byte_shift();
break;
case Microcycle::SelectWord:
assert(!(is_rom && !is_peripheral));
base[word_address] = cycle.value->full;
break;
case Microcycle::SelectByte:
assert(!(is_rom && !is_peripheral));
base[word_address] = (cycle.value->full & cycle.byte_mask()) | (base[word_address] & (0xffff ^ cycle.byte_mask()));
break;
}
}
return HalfCycles(0);
}
private:
CPU::MC68000::Processor<QL, true> m68000_;
std::vector<uint16_t> rom_;
std::array<uint16_t, 256*1024> ram_;
};
@interface QLTests : XCTestCase
@end
@implementation QLTests {
std::unique_ptr<QL> _machine;
}
- (void)setUp {
const auto roms = CSROMFetcher()("SinclairQL", {"js.rom"});
_machine.reset(new QL(*roms[0]));
}
- (void)testStartup {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
_machine->run_for(HalfCycles(400000));
}
@end