// // EmuTOSTests.m // Clock SignalTests // // Created by Thomas Harte on 10/03/2019. // Copyright © 2019 Thomas Harte. All rights reserved. // #import #include #include #include "68000.hpp" #include "CSROMFetcher.hpp" class EmuTOS: public CPU::MC68000::BusHandler { public: EmuTOS(const std::vector &emuTOS) : m68000_(*this) { assert(!(emuTOS.size() & 1)); emuTOS_.resize(emuTOS.size() / 2); for(size_t c = 0; c < emuTOS_.size(); ++c) { emuTOS_[c] = (emuTOS[c << 1] << 8) | emuTOS[(c << 1) + 1]; } } void run_for(HalfCycles cycles) { m68000_.run_for(cycles); } HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int is_supervisor) { uint32_t address = cycle.address ? (*cycle.address) & 0x00fffffe : 0; // 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_rom = address > 0xfc0000 || address < 8; uint16_t *const base = is_rom ? emuTOS_.data() : ram_.data(); if(is_rom) { address &= 0x1ffff; } else { address &= 0x7ffff; } // TODO: discern reads and writes (!) switch(cycle.operation & (CPU::MC68000::Microcycle::LowerData | CPU::MC68000::Microcycle::UpperData)) { case 0: break; case CPU::MC68000::Microcycle::LowerData: cycle.value->halves.low = base[address >> 1] >> 8; break; case CPU::MC68000::Microcycle::UpperData: cycle.value->halves.high = base[address >> 1] & 0xff; break; case CPU::MC68000::Microcycle::UpperData | CPU::MC68000::Microcycle::LowerData: cycle.value->full = base[address >> 1]; break; } return HalfCycles(0); } private: CPU::MC68000::Processor m68000_; std::vector emuTOS_; std::array ram_; }; @interface EmuTOSTests : XCTestCase @end @implementation EmuTOSTests { std::unique_ptr _machine; } - (void)setUp { // Put setup code here. This method is called before the invocation of each test method in the class. const auto roms = CSROMFetcher()("AtariST", {"etos192uk.img"}); _machine.reset(new EmuTOS(*roms[0])); } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. } - (void)testExample { // 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(400)); } @end