diff --git a/Components/6821/6821.hpp b/Components/6821/6821.hpp new file mode 100644 index 000000000..334b40031 --- /dev/null +++ b/Components/6821/6821.hpp @@ -0,0 +1,32 @@ +// +// 6821.hpp +// Clock Signal +// +// Created by Thomas Harte on 19/03/2026. +// Copyright © 2026 Thomas Harte. All rights reserved. +// + +#ifndef _821_hpp +#define _821_hpp + +#include "Numeric/SizedInt.hpp" + +namespace Motorola::MC6821 { + +template +class MC6821 { +public: + void write(const Numeric::SizedInt<2> address, const uint8_t value) { + (void)address; + (void)value; + } + + uint8_t read(const Numeric::SizedInt<2> address) { + (void)address; + return 0; + } +}; + +}; + +#endif /* _821_hpp */ diff --git a/Machines/Thomson/MO5/MO5.cpp b/Machines/Thomson/MO5/MO5.cpp index f4725f040..f06776380 100644 --- a/Machines/Thomson/MO5/MO5.cpp +++ b/Machines/Thomson/MO5/MO5.cpp @@ -10,9 +10,19 @@ #include "Machines/MachineTypes.hpp" #include "Processors/6809/6809.hpp" +#include "Components/6821/6821.hpp" using namespace Thomson::MO5; +// Video timing, as far as auto-translate lets me figure it out: +// +// 64 cycles/line; +// 56 lines post signalled vsync, then 200 of video, then 56 more, for 312 total. +// +// Start of vsync is connected to CPU IRQ. +// +// Within a line: ??? Who knows ??? +// namespace { struct ConcreteMachine: @@ -33,6 +43,8 @@ struct ConcreteMachine: const auto &rom = roms.find(ROM::Name::ThomasonMO5v11)->second; std::copy_n(rom.begin(), rom.size(), rom_.begin()); + + page_lower(false); } void run_for(const Cycles cycles) final { @@ -49,21 +61,38 @@ struct ConcreteMachine: const AddressT address, CPU::M6809::data_t value ) { - if constexpr (read_write != CPU::M6809::ReadWrite::NoData) { - if constexpr (CPU::M6809::is_read(read_write)) { - if(address >= 0xc000) { - value = rom_[address - 0xc000]; - } else { - value = ram_[address]; + if constexpr (read_write == CPU::M6809::ReadWrite::NoData) { + return Cycles(0); + } else { + if(address >= 0xa7c0 && address < 0xa800) { + switch(address) { + case 0xa7c0: case 0xa7c1: case 0xa7c2: case 0xa7c3: + if constexpr (CPU::M6809::is_read(read_write)) { + value = system_pia_.read(+address); + } else { + system_pia_.write(+address, value); + } + break; } } else { - ram_[address] = value; - printf("%04x: RAM <- 0x%02x [S: %04x]\n", +address, value, m6809_.registers().s); + if constexpr (CPU::M6809::is_read(read_write)) { + if(address < 0x2000) { + value = start_pointer_[address]; + } else if(address >= 0xc000) { + value = rom_[address - 0xc000]; + } else { + value = ram_[address]; + } + } else { + if(address < 0x2000) { + start_pointer_[address] = value; + } else { + ram_[address] = value; + } + } } } - // TODO: the lowest 8kb of memory can actually be paged, so the linear representation above isn't accurate. - return Cycles(0); } @@ -75,8 +104,15 @@ private: }; CPU::M6809::Processor m6809_; - std::array ram_; + std::array ram_; std::array rom_; + uint8_t *start_pointer_ = nullptr; + + void page_lower(const bool attributes) { + start_pointer_ = &ram_[attributes ? 0 : 0xf000]; + } + + Motorola::MC6821::MC6821 system_pia_; // MARK: - ScanProducer. diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 53b1eb4ab..f9dbaef9e 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -2531,6 +2531,7 @@ 4BDACBEA22FFA5D20045EF7E /* ncr5380.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ncr5380.cpp; sourceTree = ""; }; 4BDACBEB22FFA5D20045EF7E /* ncr5380.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ncr5380.hpp; sourceTree = ""; }; 4BDB3D8522833321002D3CEE /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = ""; }; + 4BDB734F2F6CA1A200964D69 /* 6821.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = 6821.hpp; sourceTree = ""; }; 4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = ""; }; 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = ""; }; 4BE0151C286A8C8E00EA42E9 /* MemorySwitches.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MemorySwitches.hpp; sourceTree = ""; }; @@ -5276,6 +5277,7 @@ 4BC080DD26A481C100D03FD8 /* 6526 */, 4B1E85791D174DEC001EF87D /* 6532 */, 4BC9DF4C1D04691600F44158 /* 6560 */, + 4BDB73512F6CA1A200964D69 /* 6821 */, 4BE845221F2FF7F400A5EA22 /* 6845 */, 4BB307B8235001C300457D33 /* 6850 */, 4BD9137C1F3115AC009BCF85 /* 8255 */, @@ -5591,6 +5593,14 @@ path = 5380; sourceTree = ""; }; + 4BDB73512F6CA1A200964D69 /* 6821 */ = { + isa = PBXGroup; + children = ( + 4BDB734F2F6CA1A200964D69 /* 6821.hpp */, + ); + path = 6821; + sourceTree = ""; + }; 4BE211FB253FC80800435408 /* AppleIIgs */ = { isa = PBXGroup; children = (