mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-09 00:37:27 +00:00
Merge pull request #1207 from TomHarte/PhoneyPC
Start sketching out a PC compatible machine.
This commit is contained in:
commit
3843102609
4
.github/workflows/ccpp.yml
vendored
4
.github/workflows/ccpp.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: SDL/Ubuntu
|
||||
|
||||
on: [push, pull_request]
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get --allow-releaseinfo-change update && sudo apt-get --fix-missing install libsdl2-dev scons
|
||||
run: sudo apt-get --allow-releaseinfo-change update && sudo apt-get --fix-missing install gcc-10 libsdl2-dev scons
|
||||
- name: Make
|
||||
working-directory: OSBindings/SDL
|
||||
run: scons -j$(nproc --all)
|
||||
|
@ -25,6 +25,7 @@ enum class Machine {
|
||||
MasterSystem,
|
||||
MSX,
|
||||
Oric,
|
||||
PCCompatible,
|
||||
Vic20,
|
||||
ZX8081,
|
||||
ZXSpectrum,
|
||||
|
@ -15,7 +15,7 @@
|
||||
using namespace InstructionSet::x86;
|
||||
|
||||
template <Model model>
|
||||
std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(const uint8_t *source, size_t length) {
|
||||
std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(const uint8_t *source, std::size_t length) {
|
||||
// Instruction length limits:
|
||||
//
|
||||
// 8086/80186: none*
|
||||
@ -26,8 +26,8 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
// be back to wherever it started, so it's safe to spit out a NOP and reset parsing
|
||||
// without any loss of context. This reduces the risk of the decoder tricking a caller into
|
||||
// an infinite loop.
|
||||
constexpr int max_instruction_length = model >= Model::i80386 ? 15 : (model == Model::i80286 ? 10 : 65536);
|
||||
const uint8_t *const end = source + std::min(length, size_t(max_instruction_length - consumed_));
|
||||
static constexpr std::size_t max_instruction_length = model >= Model::i80386 ? 15 : (model == Model::i80286 ? 10 : 65536);
|
||||
const uint8_t *const end = source + std::min(length, max_instruction_length - consumed_);
|
||||
|
||||
// MARK: - Prefixes (if present) and the opcode.
|
||||
|
||||
@ -58,14 +58,16 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
#define RegAddr(op, dest, op_size, addr_size) \
|
||||
SetOpSrcDestSize(op, DirectAddress, dest, op_size); \
|
||||
displacement_size_ = addr_size; \
|
||||
phase_ = Phase::DisplacementOrOperand
|
||||
phase_ = Phase::DisplacementOrOperand; \
|
||||
sign_extend_displacement_ = false
|
||||
|
||||
/// Handles instructions of the form jjkk, Ax where the former is implicitly an address.
|
||||
#define AddrReg(op, source, op_size, addr_size) \
|
||||
SetOpSrcDestSize(op, source, DirectAddress, op_size); \
|
||||
displacement_size_ = addr_size; \
|
||||
destination_ = Source::DirectAddress; \
|
||||
phase_ = Phase::DisplacementOrOperand
|
||||
phase_ = Phase::DisplacementOrOperand; \
|
||||
sign_extend_displacement_ = false
|
||||
|
||||
/// Covers both `mem/reg, reg` and `reg, mem/reg`.
|
||||
#define MemRegReg(op, format, size) \
|
||||
@ -1017,11 +1019,20 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
if(bytes_to_consume == outstanding_bytes) {
|
||||
phase_ = Phase::ReadyToPost;
|
||||
|
||||
switch(displacement_size_) {
|
||||
case DataSize::None: displacement_ = 0; break;
|
||||
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
|
||||
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
|
||||
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
|
||||
if(!sign_extend_displacement_) {
|
||||
switch(displacement_size_) {
|
||||
case DataSize::None: displacement_ = 0; break;
|
||||
case DataSize::Byte: displacement_ = uint8_t(inward_data_); break;
|
||||
case DataSize::Word: displacement_ = uint16_t(inward_data_); break;
|
||||
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
|
||||
}
|
||||
} else {
|
||||
switch(displacement_size_) {
|
||||
case DataSize::None: displacement_ = 0; break;
|
||||
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
|
||||
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
|
||||
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
|
||||
}
|
||||
}
|
||||
inward_data_ >>= bit_size(displacement_size_);
|
||||
|
||||
@ -1112,3 +1123,7 @@ template class InstructionSet::x86::Decoder<InstructionSet::x86::Model::i8086>;
|
||||
template class InstructionSet::x86::Decoder<InstructionSet::x86::Model::i80186>;
|
||||
template class InstructionSet::x86::Decoder<InstructionSet::x86::Model::i80286>;
|
||||
template class InstructionSet::x86::Decoder<InstructionSet::x86::Model::i80386>;
|
||||
|
||||
std::pair<int, Instruction<false>> Decoder8086::decode(const uint8_t *source, std::size_t length) {
|
||||
return decoder.decode(source, length);
|
||||
}
|
||||
|
@ -38,13 +38,12 @@ template <Model model> class Decoder {
|
||||
supplied cannot form a valid instruction.
|
||||
|
||||
@discussion although instructions also contain an indicator of their length, on chips prior
|
||||
to the 80286 there is no limit to instruction length and that could in theory overflow the available
|
||||
storage, which can describe instructions only up to 1kb in size.
|
||||
to the 80286 there is no limit to potential instruction length.
|
||||
|
||||
The 80286 and 80386 have instruction length limits of 10 and 15 bytes respectively, so
|
||||
cannot overflow the field.
|
||||
*/
|
||||
std::pair<int, InstructionT> decode(const uint8_t *source, size_t length);
|
||||
std::pair<int, InstructionT> decode(const uint8_t *source, std::size_t length);
|
||||
|
||||
/*!
|
||||
Enables or disables 32-bit protected mode. Meaningful only if the @c Model supports it.
|
||||
@ -173,7 +172,7 @@ template <Model model> class Decoder {
|
||||
|
||||
// Ephemeral decoding state.
|
||||
Operation operation_ = Operation::Invalid;
|
||||
int consumed_ = 0, operand_bytes_ = 0;
|
||||
uint32_t consumed_ = 0, operand_bytes_ = 0;
|
||||
|
||||
// Source and destination locations.
|
||||
Source source_ = Source::None;
|
||||
@ -193,6 +192,8 @@ template <Model model> class Decoder {
|
||||
DataSize operand_size_ = DataSize::None; // i.e. size of in-stream operand, if any.
|
||||
DataSize operation_size_ = DataSize::None; // i.e. size of data manipulated by the operation.
|
||||
|
||||
bool sign_extend_displacement_ = true; // If set then sign extend any displacement up to the address
|
||||
// size; otherwise it'll be zero-padded.
|
||||
bool sign_extend_operand_ = false; // If set then sign extend the operand up to the operation size;
|
||||
// otherwise it'll be zero-padded.
|
||||
|
||||
@ -223,9 +224,23 @@ template <Model model> class Decoder {
|
||||
next_inward_data_shift_ = 0;
|
||||
inward_data_ = 0;
|
||||
sign_extend_operand_ = false;
|
||||
sign_extend_displacement_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
// This is a temporary measure; for reasons as-yet unknown, GCC isn't picking up the
|
||||
// explicit instantiations of the template above at link time, even though is is
|
||||
// unambiguously building and linking in Decoder.cpp.
|
||||
//
|
||||
// So here's a thin non-templated shim to unblock initial PC Compatible development.
|
||||
class Decoder8086 {
|
||||
public:
|
||||
std::pair<int, Instruction<false>> decode(const uint8_t *source, std::size_t length);
|
||||
|
||||
private:
|
||||
Decoder<Model::i8086> decoder;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* InstructionSets_x86_Decoder_hpp */
|
||||
|
@ -82,8 +82,8 @@ class Flags {
|
||||
using FlagT = uint32_t;
|
||||
|
||||
// Flag getters.
|
||||
template <Flag flag> bool flag() const {
|
||||
switch(flag) {
|
||||
template <Flag flag_v> bool flag() const {
|
||||
switch(flag_v) {
|
||||
case Flag::Carry: return carry_;
|
||||
case Flag::AuxiliaryCarry: return auxiliary_carry_;
|
||||
case Flag::Sign: return sign_;
|
||||
@ -163,7 +163,7 @@ class Flags {
|
||||
set_from<Flag::Interrupt>(value & FlagValue::Interrupt);
|
||||
set_from<Flag::Direction>(value & FlagValue::Direction);
|
||||
|
||||
set_from<uint8_t, Flag::Sign>(value);
|
||||
set_from<uint8_t, Flag::Sign>(uint8_t(value));
|
||||
|
||||
set_from<Flag::Zero>((~value) & FlagValue::Zero);
|
||||
set_from<Flag::ParityOdd>((~value) & FlagValue::Parity);
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "Stack.hpp"
|
||||
#include "../AccessType.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace InstructionSet::x86::Primitive {
|
||||
|
||||
template <typename IntT, typename ContextT>
|
||||
@ -34,7 +36,7 @@ void jump(
|
||||
|
||||
// TODO: proper behaviour in 32-bit.
|
||||
if(condition) {
|
||||
context.flow_controller.jump(context.registers.ip() + displacement);
|
||||
context.flow_controller.jump(uint16_t(context.registers.ip() + displacement));
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +78,7 @@ void loopne(
|
||||
|
||||
template <typename IntT, typename ContextT>
|
||||
void call_relative(
|
||||
IntT offset,
|
||||
typename std::make_signed<IntT>::type offset,
|
||||
ContextT &context
|
||||
) {
|
||||
push<uint16_t, false>(context.registers.ip(), context);
|
||||
|
@ -175,8 +175,8 @@ template <
|
||||
case Operation::ESC:
|
||||
case Operation::NOP: return;
|
||||
|
||||
case Operation::AAM: Primitive::aam(context.registers.axp(), instruction.operand(), context); return;
|
||||
case Operation::AAD: Primitive::aad(context.registers.axp(), instruction.operand(), context); return;
|
||||
case Operation::AAM: Primitive::aam(context.registers.axp(), uint8_t(instruction.operand()), context); return;
|
||||
case Operation::AAD: Primitive::aad(context.registers.axp(), uint8_t(instruction.operand()), context); return;
|
||||
case Operation::AAA: Primitive::aaas<true>(context.registers.axp(), context); return;
|
||||
case Operation::AAS: Primitive::aaas<false>(context.registers.axp(), context); return;
|
||||
case Operation::DAA: Primitive::daas<true>(context.registers.al(), context); return;
|
||||
@ -232,7 +232,9 @@ template <
|
||||
case Operation::NEG: Primitive::neg<IntT>(source_rmw(), context); break; // TODO: should be a destination.
|
||||
case Operation::NOT: Primitive::not_<IntT>(source_rmw()); break; // TODO: should be a destination.
|
||||
|
||||
case Operation::CALLrel: Primitive::call_relative<AddressT>(instruction.displacement(), context); return;
|
||||
case Operation::CALLrel:
|
||||
Primitive::call_relative<AddressT>(instruction.displacement(), context);
|
||||
return;
|
||||
case Operation::CALLabs: Primitive::call_absolute<IntT>(destination_r(), context); return;
|
||||
case Operation::CALLfar: Primitive::call_far(instruction, context); return;
|
||||
|
||||
|
@ -162,7 +162,7 @@ typename Accessor<IntT, access>::type resolve(
|
||||
//
|
||||
// * if this is a memory access, set target_address and break;
|
||||
// * otherwise return the appropriate value.
|
||||
uint32_t target_address;
|
||||
uint32_t target_address = 0;
|
||||
switch(source) {
|
||||
// Defer all register accesses to the register-specific lookup.
|
||||
case Source::eAX: return *register_<IntT, access, Source::eAX>(context);
|
||||
@ -183,7 +183,7 @@ typename Accessor<IntT, access>::type resolve(
|
||||
case Source::None: return *none;
|
||||
|
||||
case Source::Immediate:
|
||||
*immediate = instruction.operand();
|
||||
*immediate = IntT(instruction.operand());
|
||||
return *immediate;
|
||||
|
||||
case Source::Indirect:
|
||||
|
438
Machines/PCCompatible/PCCompatible.cpp
Normal file
438
Machines/PCCompatible/PCCompatible.cpp
Normal file
@ -0,0 +1,438 @@
|
||||
//
|
||||
// PCCompatible.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 15/11/2023.
|
||||
// Copyright © 2023 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "PCCompatible.hpp"
|
||||
|
||||
#include "../../InstructionSets/x86/Decoder.hpp"
|
||||
#include "../../InstructionSets/x86/Flags.hpp"
|
||||
#include "../../InstructionSets/x86/Instruction.hpp"
|
||||
#include "../../InstructionSets/x86/Perform.hpp"
|
||||
|
||||
#include "../ScanProducer.hpp"
|
||||
#include "../TimedMachine.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace PCCompatible {
|
||||
|
||||
struct Registers {
|
||||
public:
|
||||
static constexpr bool is_32bit = false;
|
||||
|
||||
uint8_t &al() { return ax_.halves.low; }
|
||||
uint8_t &ah() { return ax_.halves.high; }
|
||||
uint16_t &ax() { return ax_.full; }
|
||||
|
||||
CPU::RegisterPair16 &axp() { return ax_; }
|
||||
|
||||
uint8_t &cl() { return cx_.halves.low; }
|
||||
uint8_t &ch() { return cx_.halves.high; }
|
||||
uint16_t &cx() { return cx_.full; }
|
||||
|
||||
uint8_t &dl() { return dx_.halves.low; }
|
||||
uint8_t &dh() { return dx_.halves.high; }
|
||||
uint16_t &dx() { return dx_.full; }
|
||||
|
||||
uint8_t &bl() { return bx_.halves.low; }
|
||||
uint8_t &bh() { return bx_.halves.high; }
|
||||
uint16_t &bx() { return bx_.full; }
|
||||
|
||||
uint16_t &sp() { return sp_; }
|
||||
uint16_t &bp() { return bp_; }
|
||||
uint16_t &si() { return si_; }
|
||||
uint16_t &di() { return di_; }
|
||||
|
||||
uint16_t &ip() { return ip_; }
|
||||
|
||||
uint16_t &es() { return es_; }
|
||||
uint16_t &cs() { return cs_; }
|
||||
uint16_t &ds() { return ds_; }
|
||||
uint16_t &ss() { return ss_; }
|
||||
uint16_t es() const { return es_; }
|
||||
uint16_t cs() const { return cs_; }
|
||||
uint16_t ds() const { return ds_; }
|
||||
uint16_t ss() const { return ss_; }
|
||||
|
||||
void reset() {
|
||||
cs_ = 0xffff;
|
||||
ip_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
CPU::RegisterPair16 ax_;
|
||||
CPU::RegisterPair16 cx_;
|
||||
CPU::RegisterPair16 dx_;
|
||||
CPU::RegisterPair16 bx_;
|
||||
|
||||
uint16_t sp_;
|
||||
uint16_t bp_;
|
||||
uint16_t si_;
|
||||
uint16_t di_;
|
||||
uint16_t es_, cs_, ds_, ss_;
|
||||
uint16_t ip_;
|
||||
};
|
||||
|
||||
class Segments {
|
||||
public:
|
||||
Segments(const Registers ®isters) : registers_(registers) {}
|
||||
|
||||
using Source = InstructionSet::x86::Source;
|
||||
|
||||
/// Posted by @c perform after any operation which *might* have affected a segment register.
|
||||
void did_update(Source segment) {
|
||||
switch(segment) {
|
||||
default: break;
|
||||
case Source::ES: es_base_ = uint32_t(registers_.es()) << 4; break;
|
||||
case Source::CS: cs_base_ = uint32_t(registers_.cs()) << 4; break;
|
||||
case Source::DS: ds_base_ = uint32_t(registers_.ds()) << 4; break;
|
||||
case Source::SS: ss_base_ = uint32_t(registers_.ss()) << 4; break;
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
did_update(Source::ES);
|
||||
did_update(Source::CS);
|
||||
did_update(Source::DS);
|
||||
did_update(Source::SS);
|
||||
}
|
||||
|
||||
uint32_t es_base_, cs_base_, ds_base_, ss_base_;
|
||||
|
||||
bool operator ==(const Segments &rhs) const {
|
||||
return
|
||||
es_base_ == rhs.es_base_ &&
|
||||
cs_base_ == rhs.cs_base_ &&
|
||||
ds_base_ == rhs.ds_base_ &&
|
||||
ss_base_ == rhs.ss_base_;
|
||||
}
|
||||
|
||||
private:
|
||||
const Registers ®isters_;
|
||||
};
|
||||
|
||||
// TODO: send writes to the ROM area off to nowhere.
|
||||
struct Memory {
|
||||
public:
|
||||
using AccessType = InstructionSet::x86::AccessType;
|
||||
|
||||
// Constructor.
|
||||
Memory(Registers ®isters, const Segments &segments) : registers_(registers), segments_(segments) {}
|
||||
|
||||
//
|
||||
// Preauthorisation call-ins. Since only an 8088 is currently modelled, all accesses are implicitly authorised.
|
||||
//
|
||||
void preauthorise_stack_write([[maybe_unused]] uint32_t length) {}
|
||||
void preauthorise_stack_read([[maybe_unused]] uint32_t length) {}
|
||||
void preauthorise_read([[maybe_unused]] InstructionSet::x86::Source segment, [[maybe_unused]] uint16_t start, [[maybe_unused]] uint32_t length) {}
|
||||
void preauthorise_read([[maybe_unused]] uint32_t start, [[maybe_unused]] uint32_t length) {}
|
||||
|
||||
//
|
||||
// Access call-ins.
|
||||
//
|
||||
|
||||
// Accesses an address based on segment:offset.
|
||||
template <typename IntT, AccessType type>
|
||||
typename InstructionSet::x86::Accessor<IntT, type>::type access(InstructionSet::x86::Source segment, uint16_t offset) {
|
||||
const uint32_t physical_address = address(segment, offset);
|
||||
|
||||
if constexpr (std::is_same_v<IntT, uint16_t>) {
|
||||
// If this is a 16-bit access that runs past the end of the segment, it'll wrap back
|
||||
// to the start. So the 16-bit value will need to be a local cache.
|
||||
if(offset == 0xffff) {
|
||||
return split_word<type>(physical_address, address(segment, 0));
|
||||
}
|
||||
}
|
||||
|
||||
return access<IntT, type>(physical_address);
|
||||
}
|
||||
|
||||
// Accesses an address based on physical location.
|
||||
template <typename IntT, AccessType type>
|
||||
typename InstructionSet::x86::Accessor<IntT, type>::type access(uint32_t address) {
|
||||
// Dispense with the single-byte case trivially.
|
||||
if constexpr (std::is_same_v<IntT, uint8_t>) {
|
||||
return memory[address];
|
||||
} else if(address != 0xf'ffff) {
|
||||
return *reinterpret_cast<IntT *>(&memory[address]);
|
||||
} else {
|
||||
return split_word<type>(address, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename IntT>
|
||||
void write_back() {
|
||||
if constexpr (std::is_same_v<IntT, uint16_t>) {
|
||||
if(write_back_address_[0] != NoWriteBack) {
|
||||
memory[write_back_address_[0]] = write_back_value_ & 0xff;
|
||||
memory[write_back_address_[1]] = write_back_value_ >> 8;
|
||||
write_back_address_[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Direct write.
|
||||
//
|
||||
template <typename IntT>
|
||||
void preauthorised_write(InstructionSet::x86::Source segment, uint16_t offset, IntT value) {
|
||||
// Bytes can be written without further ado.
|
||||
if constexpr (std::is_same_v<IntT, uint8_t>) {
|
||||
memory[address(segment, offset) & 0xf'ffff] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Words that straddle the segment end must be split in two.
|
||||
if(offset == 0xffff) {
|
||||
memory[address(segment, offset) & 0xf'ffff] = value & 0xff;
|
||||
memory[address(segment, 0x0000) & 0xf'ffff] = value >> 8;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t target = address(segment, offset) & 0xf'ffff;
|
||||
|
||||
// Words that straddle the end of physical RAM must also be split in two.
|
||||
if(target == 0xf'ffff) {
|
||||
memory[0xf'ffff] = value & 0xff;
|
||||
memory[0x0'0000] = value >> 8;
|
||||
return;
|
||||
}
|
||||
|
||||
// It's safe just to write then.
|
||||
*reinterpret_cast<uint16_t *>(&memory[target]) = value;
|
||||
}
|
||||
|
||||
//
|
||||
// Helper for instruction fetch.
|
||||
//
|
||||
std::pair<const uint8_t *, size_t> next_code() {
|
||||
const uint32_t start = segments_.cs_base_ + registers_.ip();
|
||||
return std::make_pair(&memory[start], 0x10'000 - start);
|
||||
}
|
||||
|
||||
std::pair<const uint8_t *, size_t> all() {
|
||||
return std::make_pair(memory.data(), 0x10'000);
|
||||
}
|
||||
|
||||
//
|
||||
// Population.
|
||||
//
|
||||
void install(size_t address, const uint8_t *data, size_t length) {
|
||||
std::copy(data, data + length, memory.begin() + std::vector<uint8_t>::difference_type(address));
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<uint8_t, 1024*1024> memory{0xff};
|
||||
Registers ®isters_;
|
||||
const Segments &segments_;
|
||||
|
||||
uint32_t segment_base(InstructionSet::x86::Source segment) {
|
||||
using Source = InstructionSet::x86::Source;
|
||||
switch(segment) {
|
||||
default: return segments_.ds_base_;
|
||||
case Source::ES: return segments_.es_base_;
|
||||
case Source::CS: return segments_.cs_base_;
|
||||
case Source::SS: return segments_.ss_base_;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t address(InstructionSet::x86::Source segment, uint16_t offset) {
|
||||
return (segment_base(segment) + offset) & 0xf'ffff;
|
||||
}
|
||||
|
||||
template <AccessType type>
|
||||
typename InstructionSet::x86::Accessor<uint16_t, type>::type
|
||||
split_word(uint32_t low_address, uint32_t high_address) {
|
||||
if constexpr (is_writeable(type)) {
|
||||
write_back_address_[0] = low_address;
|
||||
write_back_address_[1] = high_address;
|
||||
|
||||
// Prepopulate only if this is a modify.
|
||||
if constexpr (type == AccessType::ReadModifyWrite) {
|
||||
write_back_value_ = uint16_t(memory[write_back_address_[0]] | (memory[write_back_address_[1]] << 8));
|
||||
}
|
||||
|
||||
return write_back_value_;
|
||||
} else {
|
||||
return uint16_t(memory[low_address] | (memory[high_address] << 8));
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr uint32_t NoWriteBack = 0; // A low byte address of 0 can't require write-back.
|
||||
uint32_t write_back_address_[2] = {NoWriteBack, NoWriteBack};
|
||||
uint16_t write_back_value_;
|
||||
};
|
||||
|
||||
class IO {
|
||||
public:
|
||||
template <typename IntT> void out([[maybe_unused]] uint16_t port, [[maybe_unused]] IntT value) {
|
||||
switch(port) {
|
||||
default:
|
||||
if constexpr (std::is_same_v<IntT, uint8_t>) {
|
||||
printf("Unhandled out: %02x to %04x\n", value, port);
|
||||
} else {
|
||||
printf("Unhandled out: %04x to %04x\n", value, port);
|
||||
}
|
||||
break;
|
||||
|
||||
// On the XT the NMI can be masked by setting bit 7 on I/O port 0xA0.
|
||||
case 0x00a0:
|
||||
printf("TODO: NMIs %s\n", (value & 0x80) ? "masked" : "unmasked");
|
||||
break;
|
||||
}
|
||||
}
|
||||
template <typename IntT> IntT in([[maybe_unused]] uint16_t port) {
|
||||
printf("Unhandled in: %04x\n", port);
|
||||
return IntT(~0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class FlowController {
|
||||
public:
|
||||
FlowController(Registers ®isters, Segments &segments) :
|
||||
registers_(registers), segments_(segments) {}
|
||||
|
||||
// Requirements for perform.
|
||||
void jump(uint16_t address) {
|
||||
registers_.ip() = address;
|
||||
}
|
||||
|
||||
void jump(uint16_t segment, uint16_t address) {
|
||||
registers_.cs() = segment;
|
||||
segments_.did_update(Segments::Source::CS);
|
||||
registers_.ip() = address;
|
||||
}
|
||||
|
||||
void halt() {}
|
||||
void wait() {}
|
||||
|
||||
void repeat_last() {
|
||||
should_repeat_ = true;
|
||||
}
|
||||
|
||||
// Other actions.
|
||||
void begin_instruction() {
|
||||
should_repeat_ = false;
|
||||
}
|
||||
bool should_repeat() const {
|
||||
return should_repeat_;
|
||||
}
|
||||
|
||||
private:
|
||||
Registers ®isters_;
|
||||
Segments &segments_;
|
||||
bool should_repeat_ = false;
|
||||
};
|
||||
|
||||
class ConcreteMachine:
|
||||
public Machine,
|
||||
public MachineTypes::TimedMachine,
|
||||
public MachineTypes::ScanProducer
|
||||
{
|
||||
public:
|
||||
ConcreteMachine(
|
||||
[[maybe_unused]] const Analyser::Static::Target &target,
|
||||
[[maybe_unused]] const ROMMachine::ROMFetcher &rom_fetcher
|
||||
) {
|
||||
// This is actually a MIPS count; try 3 million.
|
||||
set_clock_rate(3'000'000);
|
||||
|
||||
// Fetch the BIOS. [8088 only, for now]
|
||||
const auto bios = ROM::Name::PCCompatibleGLaBIOS;
|
||||
|
||||
ROM::Request request = ROM::Request(bios);
|
||||
auto roms = rom_fetcher(request);
|
||||
if(!request.validate(roms)) {
|
||||
throw ROMMachine::Error::MissingROMs;
|
||||
}
|
||||
|
||||
const auto &bios_contents = roms.find(bios)->second;
|
||||
context.memory.install(0x10'0000 - bios_contents.size(), bios_contents.data(), bios_contents.size());
|
||||
}
|
||||
|
||||
// MARK: - TimedMachine.
|
||||
void run_for([[maybe_unused]] const Cycles cycles) override {
|
||||
auto instructions = cycles.as_integral();
|
||||
while(instructions--) {
|
||||
// Get the next thing to execute into decoded.
|
||||
if(!context.flow_controller.should_repeat()) {
|
||||
// Decode from the current IP.
|
||||
const auto remainder = context.memory.next_code();
|
||||
decoded = decoder.decode(remainder.first, remainder.second);
|
||||
|
||||
// If that didn't yield a whole instruction then the end of memory must have been hit;
|
||||
// continue from the beginning.
|
||||
if(decoded.first <= 0) {
|
||||
const auto all = context.memory.all();
|
||||
decoded = decoder.decode(all.first, all.second);
|
||||
}
|
||||
|
||||
context.registers.ip() += decoded.first;
|
||||
} else {
|
||||
context.flow_controller.begin_instruction();
|
||||
}
|
||||
|
||||
// Execute it.
|
||||
InstructionSet::x86::perform(
|
||||
decoded.second,
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ScanProducer.
|
||||
void set_scan_target([[maybe_unused]] Outputs::Display::ScanTarget *scan_target) override {}
|
||||
Outputs::Display::ScanStatus get_scaled_scan_status() const override {
|
||||
return Outputs::Display::ScanStatus();
|
||||
}
|
||||
|
||||
private:
|
||||
struct Context {
|
||||
Context() :
|
||||
segments(registers),
|
||||
memory(registers, segments),
|
||||
flow_controller(registers, segments)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
registers.reset();
|
||||
segments.reset();
|
||||
}
|
||||
|
||||
InstructionSet::x86::Flags flags;
|
||||
Registers registers;
|
||||
Segments segments;
|
||||
Memory memory;
|
||||
FlowController flow_controller;
|
||||
IO io;
|
||||
static constexpr auto model = InstructionSet::x86::Model::i8086;
|
||||
} context;
|
||||
|
||||
// TODO: eliminate use of Decoder8086 and Decoder8086 in gneral in favour of the templated version, as soon
|
||||
// as whatever error is preventing GCC from picking up Decoder's explicit instantiations becomes apparent.
|
||||
InstructionSet::x86::Decoder8086 decoder;
|
||||
// InstructionSet::x86::Decoder<InstructionSet::x86::Model::i8086> decoder;
|
||||
|
||||
std::pair<int, InstructionSet::x86::Instruction<false>> decoded;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
using namespace PCCompatible;
|
||||
|
||||
// See header; constructs and returns an instance of the Amstrad CPC.
|
||||
Machine *Machine::PCCompatible(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
||||
return new PCCompatible::ConcreteMachine(*target, rom_fetcher);
|
||||
}
|
||||
|
||||
Machine::~Machine() {}
|
33
Machines/PCCompatible/PCCompatible.hpp
Normal file
33
Machines/PCCompatible/PCCompatible.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// PCCompatible.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 15/11/2023.
|
||||
// Copyright © 2023 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef PCCompatible_hpp
|
||||
#define PCCompatible_hpp
|
||||
|
||||
#include "../../Analyser/Static/StaticAnalyser.hpp"
|
||||
#include "../ROMMachine.hpp"
|
||||
|
||||
namespace PCCompatible {
|
||||
|
||||
/*!
|
||||
Models a PC compatible.
|
||||
*/
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine();
|
||||
|
||||
/// Creates and returns a PC Compatible.
|
||||
static Machine *PCCompatible(
|
||||
const Analyser::Static::Target *target,
|
||||
const ROMMachine::ROMFetcher &rom_fetcher
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* PCCompatible_hpp */
|
@ -13,7 +13,6 @@
|
||||
#include "../ClockReceiver/TimeTypes.hpp"
|
||||
|
||||
#include "AudioProducer.hpp"
|
||||
#include "ScanProducer.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../MasterSystem/MasterSystem.hpp"
|
||||
#include "../MSX/MSX.hpp"
|
||||
#include "../Oric/Oric.hpp"
|
||||
#include "../PCCompatible/PCCompatible.hpp"
|
||||
#include "../Sinclair/ZX8081/ZX8081.hpp"
|
||||
#include "../Sinclair/ZXSpectrum/ZXSpectrum.hpp"
|
||||
|
||||
@ -69,6 +70,7 @@ Machine::DynamicMachine *Machine::MachineForTarget(const Analyser::Static::Targe
|
||||
Bind(Enterprise)
|
||||
Bind(MSX)
|
||||
Bind(Oric)
|
||||
Bind(PCCompatible)
|
||||
BindD(Sega::MasterSystem, MasterSystem)
|
||||
BindD(Sinclair::ZX8081, ZX8081)
|
||||
BindD(Sinclair::ZXSpectrum, ZXSpectrum)
|
||||
@ -139,6 +141,7 @@ std::string Machine::ShortNameForTargetMachine(const Analyser::Machine machine)
|
||||
case Analyser::Machine::MasterSystem: return "MasterSystem";
|
||||
case Analyser::Machine::MSX: return "MSX";
|
||||
case Analyser::Machine::Oric: return "Oric";
|
||||
case Analyser::Machine::PCCompatible: return "PCCompatible";
|
||||
case Analyser::Machine::Vic20: return "Vic20";
|
||||
case Analyser::Machine::ZX8081: return "ZX8081";
|
||||
case Analyser::Machine::ZXSpectrum: return "ZXSpectrum";
|
||||
@ -162,6 +165,7 @@ std::string Machine::LongNameForTargetMachine(Analyser::Machine machine) {
|
||||
case Analyser::Machine::MasterSystem: return "Sega Master System";
|
||||
case Analyser::Machine::MSX: return "MSX";
|
||||
case Analyser::Machine::Oric: return "Oric";
|
||||
case Analyser::Machine::PCCompatible: return "PC Compatible";
|
||||
case Analyser::Machine::Vic20: return "Vic 20";
|
||||
case Analyser::Machine::ZX8081: return "ZX80/81";
|
||||
case Analyser::Machine::ZXSpectrum: return "ZX Spectrum";
|
||||
@ -244,6 +248,7 @@ std::map<std::string, std::unique_ptr<Analyser::Static::Target>> Machine::Target
|
||||
Add(Macintosh);
|
||||
Add(MSX);
|
||||
Add(Oric);
|
||||
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::PCCompatible), new Analyser::Static::Target(Analyser::Machine::PCCompatible)));
|
||||
AddMapped(Vic20, Commodore);
|
||||
Add(ZX8081);
|
||||
Add(ZXSpectrum);
|
||||
|
@ -567,6 +567,8 @@ Description::Description(Name name) {
|
||||
case Name::OricMicrodisc: *this = Description(name, "Oric", "the Oric Microdisc ROM", "microdisc.rom", 8*1024, 0xa9664a9cu); break;
|
||||
case Name::Oric8DOSBoot: *this = Description(name, "Oric", "the 8DOS boot ROM", "8dos.rom", 512, 0x49a74c06u); break;
|
||||
|
||||
case Name::PCCompatibleGLaBIOS: *this = Description(name, "PCCompatible", "8088 GLaBIOS 0.2.5", "GLABIOS_0.2.5_8T.ROM", 8 * 1024, 0x9576944cu); break;
|
||||
|
||||
// TODO: CRCs below are incomplete, at best.
|
||||
case Name::MSXGenericBIOS: *this = Description(name, "MSX", "a generix MSX BIOS", "msx.rom", 32*1024, 0x94ee12f3u); break;
|
||||
case Name::MSXJapaneseBIOS: *this = Description(name, "MSX", "a Japanese MSX BIOS", "msx-japanese.rom", 32*1024, 0xee229390u); break;
|
||||
|
@ -132,6 +132,9 @@ enum Name {
|
||||
OricMicrodisc,
|
||||
Oric8DOSBoot,
|
||||
|
||||
// PCCompatible.
|
||||
PCCompatibleGLaBIOS,
|
||||
|
||||
// Sinclair QL.
|
||||
SinclairQLJS,
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
423BDC4A2AB24699008E37B6 /* 8088Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 423BDC492AB24699008E37B6 /* 8088Tests.mm */; };
|
||||
42437B332AC70833006DFED1 /* HDV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6FD0342923061300EC4760 /* HDV.cpp */; };
|
||||
425739382B051EA800B7D1E4 /* PCCompatible.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425739372B051EA800B7D1E4 /* PCCompatible.cpp */; };
|
||||
425739392B051EA800B7D1E4 /* PCCompatible.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425739372B051EA800B7D1E4 /* PCCompatible.cpp */; };
|
||||
4281683A2A37AFB4008ECD27 /* DispatcherTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 428168392A37AFB4008ECD27 /* DispatcherTests.mm */; };
|
||||
42A5E80C2ABBE04600A0DD5D /* NeskellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42A5E80B2ABBE04600A0DD5D /* NeskellTests.swift */; };
|
||||
42A5E8442ABBE16F00A0DD5D /* illegal_rmw_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 42A5E8332ABBE16F00A0DD5D /* illegal_rmw_test.bin */; };
|
||||
@ -1138,6 +1140,8 @@
|
||||
4257392E2AFBE2BC00B7D1E4 /* Repetition.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Repetition.hpp; sourceTree = "<group>"; };
|
||||
4257392F2AFBE36B00B7D1E4 /* LoadStore.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LoadStore.hpp; sourceTree = "<group>"; };
|
||||
425739302AFBE47700B7D1E4 /* InOut.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = InOut.hpp; sourceTree = "<group>"; };
|
||||
425739362B051EA800B7D1E4 /* PCCompatible.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PCCompatible.hpp; sourceTree = "<group>"; };
|
||||
425739372B051EA800B7D1E4 /* PCCompatible.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCCompatible.cpp; sourceTree = "<group>"; };
|
||||
4281572E2AA0334300E16AA1 /* Carry.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Carry.hpp; sourceTree = "<group>"; };
|
||||
428168372A16C25C008ECD27 /* LineLayout.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LineLayout.hpp; sourceTree = "<group>"; };
|
||||
428168392A37AFB4008ECD27 /* DispatcherTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatcherTests.mm; sourceTree = "<group>"; };
|
||||
@ -2353,6 +2357,15 @@
|
||||
path = Implementation;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
425739352B051EA800B7D1E4 /* PCCompatible */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
425739362B051EA800B7D1E4 /* PCCompatible.hpp */,
|
||||
425739372B051EA800B7D1E4 /* PCCompatible.cpp */,
|
||||
);
|
||||
path = PCCompatible;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
42A5E8322ABBE16F00A0DD5D /* Neskell Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4475,6 +4488,7 @@
|
||||
4B7F188B2154825D00388727 /* MasterSystem */,
|
||||
4B79A4FC1FC8FF9800EEDAD5 /* MSX */,
|
||||
4BCF1FA51DADC3E10039D2E7 /* Oric */,
|
||||
425739352B051EA800B7D1E4 /* PCCompatible */,
|
||||
4B0F1BC92602F17B00B85C66 /* Sinclair */,
|
||||
4B2B3A461F9B8FA70062DABF /* Utility */,
|
||||
);
|
||||
@ -5733,6 +5747,7 @@
|
||||
4BD424E62193B5830097291A /* Shader.cpp in Sources */,
|
||||
4BC080CB26A238CC00D03FD8 /* AmigaADF.cpp in Sources */,
|
||||
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
|
||||
425739392B051EA800B7D1E4 /* PCCompatible.cpp in Sources */,
|
||||
4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */,
|
||||
4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */,
|
||||
4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */,
|
||||
@ -5951,6 +5966,7 @@
|
||||
4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */,
|
||||
4BDA00E422E663B900AC3CD0 /* NSData+CRC32.m in Sources */,
|
||||
4B9EC0E626AA4A660060A31F /* Chipset.cpp in Sources */,
|
||||
425739382B051EA800B7D1E4 /* PCCompatible.cpp in Sources */,
|
||||
4BB8616E24E22DC500A00E03 /* BufferingScanTarget.cpp in Sources */,
|
||||
4BB4BFB022A42F290069048D /* MacintoshIMG.cpp in Sources */,
|
||||
4B05401E219D1618001BF69C /* ScanTarget.cpp in Sources */,
|
||||
|
@ -123,6 +123,10 @@ typedef NS_ENUM(NSInteger, CSMachineMSXRegion) {
|
||||
CSMachineMSXRegionJapanese,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, CSPCCompatibleModel) {
|
||||
CSPCCompatibleModelTurboXT,
|
||||
};
|
||||
|
||||
typedef int Kilobytes;
|
||||
|
||||
@interface CSStaticAnalyser : NSObject
|
||||
@ -143,6 +147,7 @@ typedef int Kilobytes;
|
||||
- (instancetype)initWithVic20Region:(CSMachineVic20Region)region memorySize:(Kilobytes)memorySize hasC1540:(BOOL)hasC1540;
|
||||
- (instancetype)initWithZX80MemorySize:(Kilobytes)memorySize useZX81ROM:(BOOL)useZX81ROM;
|
||||
- (instancetype)initWithZX81MemorySize:(Kilobytes)memorySize;
|
||||
- (instancetype)initWithPCCompatibleModel:(CSPCCompatibleModel)model;
|
||||
|
||||
@property(nonatomic, readonly, nullable) NSString *optionsNibName;
|
||||
@property(nonatomic, readonly) NSString *displayName;
|
||||
|
@ -272,6 +272,16 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPCCompatibleModel:(CSPCCompatibleModel)model {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::Target;
|
||||
auto target = std::make_unique<Target>(Analyser::Machine::PCCompatible);
|
||||
_targets.push_back(std::move(target));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithSpectrumModel:(CSMachineSpectrumModel)model {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@ -17,10 +17,10 @@
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titleVisibility="hidden" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" documentModal="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="590" height="353"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1800" height="1131"/>
|
||||
<rect key="contentRect" x="196" y="240" width="590" height="367"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1440"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="590" height="353"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="590" height="367"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hKn-1l-OSN">
|
||||
@ -49,7 +49,7 @@ Gw
|
||||
<action selector="cancelCreateMachine:" target="-2" id="lf8-PM-c0m"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="1" verticalHuggingPriority="1" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9YM-5x-pc0">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="1" verticalHuggingPriority="1" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9YM-5x-pc0">
|
||||
<rect key="frame" x="18" y="14" width="405" height="32"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" sendsActionOnEndEditing="YES" id="xTm-Oy-oz5">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -59,16 +59,16 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<tabView type="noTabsBezelBorder" translatesAutoresizingMaskIntoConstraints="NO" id="VUb-QG-x7c">
|
||||
<rect key="frame" x="154" y="57" width="420" height="242"/>
|
||||
<rect key="frame" x="154" y="57" width="420" height="256"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<tabViewItems>
|
||||
<tabViewItem label="Amiga" identifier="amiga" id="JmB-OF-xcM">
|
||||
<view key="view" id="5zS-Nj-Ynx">
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="236"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qfH-1l-GXp">
|
||||
<rect key="frame" x="110" y="178" width="80" height="25"/>
|
||||
<rect key="frame" x="110" y="192" width="80" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="512 kb" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="512" imageScaling="axesIndependently" inset="2" selectedItem="Zev-ku-jDG" id="vdO-VR-mUx">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -81,16 +81,16 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P6K-dt-stj">
|
||||
<rect key="frame" x="18" y="184" width="89" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P6K-dt-stj">
|
||||
<rect key="frame" x="18" y="198" width="89" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Chip Memory:" id="FIO-ZR-rsA">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YD0-OJ-2bY">
|
||||
<rect key="frame" x="18" y="154" width="87" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YD0-OJ-2bY">
|
||||
<rect key="frame" x="18" y="168" width="87" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Fast Memory:" id="Rpz-39-jyt">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -98,7 +98,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="af8-pF-qc9">
|
||||
<rect key="frame" x="108" y="148" width="72" height="25"/>
|
||||
<rect key="frame" x="108" y="162" width="72" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="None" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="zV7-V8-c7s" id="39D-ms-pf9">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -148,7 +148,7 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="c3g-96-b3x">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="c3g-96-b3x">
|
||||
<rect key="frame" x="18" y="184" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model:" id="53v-92-jmf">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -172,7 +172,7 @@ Gw
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5Z-dX-Ns4">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5Z-dX-Ns4">
|
||||
<rect key="frame" x="18" y="184" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model:" id="qV3-2P-3JW">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -180,7 +180,7 @@ Gw
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WnO-ef-IC6">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WnO-ef-IC6">
|
||||
<rect key="frame" x="18" y="154" width="96" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Disk controller:" id="kbf-rc-Y4M">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -235,19 +235,19 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Apple IIgs" identifier="appleiigs" id="u5E-8n-ghF">
|
||||
<view key="view" id="jOM-9f-vkk">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0d9-IG-gKU">
|
||||
<rect key="frame" x="18" y="185" width="46" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0d9-IG-gKU">
|
||||
<rect key="frame" x="18" y="184" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model:" id="kiv-1P-FWc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LES-76-Ovz">
|
||||
<rect key="frame" x="18" y="155" width="85" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LES-76-Ovz">
|
||||
<rect key="frame" x="18" y="154" width="85" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Memory size:" id="OLJ-nC-yyj">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -255,7 +255,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gcS-uy-mzl">
|
||||
<rect key="frame" x="67" y="179" width="89" height="25"/>
|
||||
<rect key="frame" x="67" y="178" width="89" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="ROM 03" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="2" imageScaling="axesIndependently" inset="2" selectedItem="0TS-DO-O9h" id="hjw-g8-e2f">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -269,7 +269,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nQa-YS-utT">
|
||||
<rect key="frame" x="106" y="149" width="82" height="25"/>
|
||||
<rect key="frame" x="106" y="148" width="82" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="8 mb" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="8192" imageScaling="axesIndependently" inset="2" selectedItem="UHg-gU-Xnn" id="dl3-cq-uWO">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -303,7 +303,7 @@ Gw
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dKg-qC-BBF">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dKg-qC-BBF">
|
||||
<rect key="frame" x="18" y="184" width="58" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Memory:" id="ZBF-0r-RNK">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -338,32 +338,32 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Electron" identifier="electron" id="muc-z9-Vqc">
|
||||
<view key="view" id="SRc-2D-95G">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JqM-IK-FMP">
|
||||
<rect key="frame" x="18" y="186" width="168" height="18"/>
|
||||
<rect key="frame" x="18" y="185" width="168" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="With Disk Filing System" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="tpW-5C-xKp">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="945-wU-JOH">
|
||||
<rect key="frame" x="18" y="164" width="232" height="18"/>
|
||||
<rect key="frame" x="18" y="163" width="232" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="With Advanced Disk Filing System" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="S0c-Jg-7Pu">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cG2-Ph-S3Z">
|
||||
<rect key="frame" x="18" y="142" width="231" height="18"/>
|
||||
<rect key="frame" x="18" y="141" width="231" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="With Advanced Plus 6 Utility ROM" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="yjF-XS-zx6">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lzo-8g-o4S">
|
||||
<rect key="frame" x="18" y="120" width="284" height="18"/>
|
||||
<rect key="frame" x="18" y="119" width="284" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Fill unused ROM banks with sideways RAM" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="JEz-eK-uWp">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -389,11 +389,11 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Enterprise" identifier="enterprise" id="zhO-EO-wUe">
|
||||
<view key="view" id="1cs-PX-RAH">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PhH-bu-pb5">
|
||||
<rect key="frame" x="80" y="179" width="129" height="25"/>
|
||||
<rect key="frame" x="80" y="178" width="129" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Enterprise 128" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="128" imageScaling="axesIndependently" inset="2" selectedItem="roH-nL-f8o" id="z9O-XC-XBv">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -407,7 +407,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Lfl-5c-b8j">
|
||||
<rect key="frame" x="67" y="149" width="77" height="25"/>
|
||||
<rect key="frame" x="67" y="148" width="77" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="4 Mhz" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="4" imageScaling="axesIndependently" inset="2" selectedItem="5N6-tD-uN7" id="BU2-NJ-Kii">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -420,7 +420,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nen-Za-7zH">
|
||||
<rect key="frame" x="64" y="119" width="107" height="25"/>
|
||||
<rect key="frame" x="64" y="118" width="107" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Version 2.1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="21" imageScaling="axesIndependently" inset="2" selectedItem="Qja-xZ-wVM" id="xGG-ri-8Sb">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -434,7 +434,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hIr-GH-7xi">
|
||||
<rect key="frame" x="67" y="89" width="105" height="25"/>
|
||||
<rect key="frame" x="67" y="88" width="105" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Version 2.1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="21" imageScaling="axesIndependently" inset="2" selectedItem="TME-cv-Jh1" id="9mQ-GW-lq9">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -449,7 +449,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="syE-e7-TjU">
|
||||
<rect key="frame" x="57" y="59" width="83" height="25"/>
|
||||
<rect key="frame" x="57" y="58" width="83" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="EXDOS" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="1" imageScaling="axesIndependently" inset="2" selectedItem="8rP-2w-PdU" id="NvO-Zm-2Rq">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -461,40 +461,40 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ykc-W1-YaS">
|
||||
<rect key="frame" x="18" y="125" width="43" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ykc-W1-YaS">
|
||||
<rect key="frame" x="18" y="124" width="43" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="EXOS:" id="gUC-PN-zVL">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="frx-nk-c3P">
|
||||
<rect key="frame" x="18" y="185" width="59" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="frx-nk-c3P">
|
||||
<rect key="frame" x="18" y="184" width="59" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Machine:" id="uTv-hH-mIC">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dzd-tH-BjX">
|
||||
<rect key="frame" x="18" y="95" width="46" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dzd-tH-BjX">
|
||||
<rect key="frame" x="18" y="94" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="BASIC:" id="ai1-oR-X6Y">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pxr-Bq-yh0">
|
||||
<rect key="frame" x="18" y="65" width="36" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pxr-Bq-yh0">
|
||||
<rect key="frame" x="18" y="64" width="36" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="DOS:" id="NFk-cp-DfS">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rHr-bh-QMV">
|
||||
<rect key="frame" x="17" y="155" width="47" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rHr-bh-QMV">
|
||||
<rect key="frame" x="17" y="154" width="47" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Speed:" id="sAw-C9-Sf7">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -536,11 +536,11 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Macintosh" identifier="mac" id="lmR-z3-xSm">
|
||||
<view key="view" id="7Yf-vi-Q0W">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZOY-4E-Cfl">
|
||||
<rect key="frame" x="18" y="185" width="46" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZOY-4E-Cfl">
|
||||
<rect key="frame" x="18" y="184" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model:" id="h9r-i6-66j">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -548,7 +548,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xa6-NA-JY5">
|
||||
<rect key="frame" x="67" y="179" width="75" height="25"/>
|
||||
<rect key="frame" x="67" y="178" width="75" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Plus" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="3" imageScaling="axesIndependently" inset="2" selectedItem="R6T-hg-rOF" id="1Kb-Q2-BGM">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -599,7 +599,7 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZaD-7v-rMS">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZaD-7v-rMS">
|
||||
<rect key="frame" x="18" y="154" width="50" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Region:" id="x4m-eh-Nif">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -607,7 +607,7 @@ Gw
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gFV-RB-7dB">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gFV-RB-7dB">
|
||||
<rect key="frame" x="18" y="184" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model:" id="r7C-zE-gyj">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -659,11 +659,11 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Oric" identifier="oric" id="NSx-DC-p4M">
|
||||
<view key="view" id="sOR-e0-8iZ">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0ct-tf-uRH">
|
||||
<rect key="frame" x="18" y="185" width="46" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0ct-tf-uRH">
|
||||
<rect key="frame" x="18" y="184" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model:" id="Xm1-7x-YVl">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -671,7 +671,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ENP-hI-BVZ">
|
||||
<rect key="frame" x="67" y="179" width="107" height="25"/>
|
||||
<rect key="frame" x="67" y="178" width="107" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Oric-1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="jGN-1a-biF" id="Jll-EJ-cMr">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -685,7 +685,7 @@ Gw
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fYL-p6-wyn">
|
||||
<rect key="frame" x="113" y="149" width="130" height="25"/>
|
||||
<rect key="frame" x="113" y="148" width="130" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="None" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="XhK-Jh-oTW" id="aYb-m1-H9X">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -700,8 +700,8 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="okM-ZI-NbF">
|
||||
<rect key="frame" x="18" y="155" width="92" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="okM-ZI-NbF">
|
||||
<rect key="frame" x="18" y="154" width="92" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Disk interface:" id="SFK-hS-tFC">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -724,6 +724,44 @@ Gw
|
||||
</constraints>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="PC Compatible" identifier="pc" id="8cB-MZ-g3U">
|
||||
<view key="view" id="gJD-vd-WWu">
|
||||
<rect key="frame" x="10" y="7" width="400" height="236"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="stw-i3-ikG">
|
||||
<rect key="frame" x="108" y="192" width="116" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Unexpanded" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="oIy-If-5bQ" id="xz8-mu-ynU">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="dju-ZY-2DH">
|
||||
<items>
|
||||
<menuItem title="Unexpanded" state="on" id="oIy-If-5bQ"/>
|
||||
<menuItem title="16 kb" tag="16" id="igW-oa-8YI"/>
|
||||
<menuItem title="64 kb" tag="64" hidden="YES" enabled="NO" id="Tcz-UB-hbn"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uhf-1k-ibT">
|
||||
<rect key="frame" x="18" y="198" width="87" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Memory Size:" id="ROV-EU-T3W">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="stw-i3-ikG" secondAttribute="trailing" constant="20" symbolic="YES" id="A0n-lr-LHf"/>
|
||||
<constraint firstItem="uhf-1k-ibT" firstAttribute="leading" secondItem="gJD-vd-WWu" secondAttribute="leading" constant="20" symbolic="YES" id="JNr-Tg-gDV"/>
|
||||
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="stw-i3-ikG" secondAttribute="bottom" constant="20" symbolic="YES" id="RSc-OQ-KNO"/>
|
||||
<constraint firstItem="uhf-1k-ibT" firstAttribute="centerY" secondItem="stw-i3-ikG" secondAttribute="centerY" id="bfD-kx-eOc"/>
|
||||
<constraint firstItem="stw-i3-ikG" firstAttribute="leading" secondItem="uhf-1k-ibT" secondAttribute="trailing" constant="8" symbolic="YES" id="f6l-B2-nBw"/>
|
||||
<constraint firstItem="stw-i3-ikG" firstAttribute="top" secondItem="gJD-vd-WWu" secondAttribute="top" constant="20" symbolic="YES" id="wjD-TM-5CL"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Vic-20" identifier="vic20" id="cyO-PU-hSU">
|
||||
<view key="view" id="fLI-XB-QCr">
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
@ -759,7 +797,7 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MTh-9p-FqC">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MTh-9p-FqC">
|
||||
<rect key="frame" x="18" y="184" width="50" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Region:" id="F3g-Ya-ypU">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -767,7 +805,7 @@ Gw
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gRS-DK-rIy">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gRS-DK-rIy">
|
||||
<rect key="frame" x="18" y="154" width="87" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Memory Size:" id="a4I-vG-yCp">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -803,11 +841,11 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="ZX80" identifier="zx80" id="tMH-kF-GUz">
|
||||
<view key="view" id="8hL-Vn-Hg0">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="I1a-Eu-5UB">
|
||||
<rect key="frame" x="108" y="179" width="116" height="25"/>
|
||||
<rect key="frame" x="108" y="178" width="116" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Unexpanded" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="4Sa-jR-xOd" id="B8M-do-Yod">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -820,8 +858,8 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NCX-4e-lSu">
|
||||
<rect key="frame" x="18" y="185" width="87" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NCX-4e-lSu">
|
||||
<rect key="frame" x="18" y="184" width="87" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Memory Size:" id="e6x-TE-OC5">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -829,7 +867,7 @@ Gw
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ReP-bV-Thu">
|
||||
<rect key="frame" x="18" y="158" width="118" height="18"/>
|
||||
<rect key="frame" x="18" y="157" width="118" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Use ZX81 ROM" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="VQH-nv-Pfm">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -851,11 +889,11 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="ZX81" identifier="zx81" id="Wnn-nQ-gZ6">
|
||||
<view key="view" id="bmd-gL-gzT">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5aO-UX-HnX">
|
||||
<rect key="frame" x="108" y="179" width="116" height="25"/>
|
||||
<rect key="frame" x="108" y="178" width="116" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Unexpanded" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="7QC-Ij-hES" id="d3W-Gl-3Mf">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -868,8 +906,8 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8tU-73-XEE">
|
||||
<rect key="frame" x="18" y="185" width="87" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8tU-73-XEE">
|
||||
<rect key="frame" x="18" y="184" width="87" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Memory Size:" id="z4b-oR-Yl2">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -889,11 +927,11 @@ Gw
|
||||
</tabViewItem>
|
||||
<tabViewItem label="ZX Spectrum" identifier="spectrum" id="HQv-oF-k8b">
|
||||
<view key="view" id="bMx-F6-JUb">
|
||||
<rect key="frame" x="10" y="7" width="400" height="223"/>
|
||||
<rect key="frame" x="10" y="7" width="400" height="222"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gFZ-d4-WFv">
|
||||
<rect key="frame" x="67" y="179" width="76" height="25"/>
|
||||
<rect key="frame" x="67" y="178" width="76" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="16kb" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="16" imageScaling="axesIndependently" inset="2" selectedItem="Fo7-NL-Kv5" id="tYs-sA-oek">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
@ -909,8 +947,8 @@ Gw
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fJ3-ma-Byy">
|
||||
<rect key="frame" x="18" y="185" width="46" height="16"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fJ3-ma-Byy">
|
||||
<rect key="frame" x="18" y="184" width="46" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Model:" id="JId-Tp-LrE">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -931,14 +969,14 @@ Gw
|
||||
</tabViewItems>
|
||||
</tabView>
|
||||
<scrollView borderType="line" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="10" verticalLineScroll="24" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="z5Q-Bs-hJj">
|
||||
<rect key="frame" x="20" y="60" width="130" height="238"/>
|
||||
<rect key="frame" x="20" y="60" width="130" height="252"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" id="O8s-Vw-9yQ">
|
||||
<rect key="frame" x="1" y="1" width="128" height="236"/>
|
||||
<rect key="frame" x="1" y="1" width="128" height="250"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="24" id="3go-Eb-GOy">
|
||||
<rect key="frame" x="0.0" y="0.0" width="128" height="236"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="128" height="250"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="17" height="0.0"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -974,8 +1012,8 @@ Gw
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VAc-6N-O7q">
|
||||
<rect key="frame" x="18" y="306" width="554" height="27"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VAc-6N-O7q">
|
||||
<rect key="frame" x="18" y="320" width="554" height="27"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Choose a machine" id="32m-Vs-dPO">
|
||||
<font key="font" textStyle="title2" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -84,9 +84,12 @@ class MachinePicker: NSObject, NSTableViewDataSource, NSTableViewDelegate {
|
||||
|
||||
// Set up data soure.
|
||||
|
||||
// TEMPORARY: remove the Apple IIgs option. It's not yet a fully-working machine; no need to publicise it.
|
||||
let appleIIgsTabIndex = machineSelector.indexOfTabViewItem(withIdentifier: "appleiigs")
|
||||
machineSelector.removeTabViewItem(machineSelector.tabViewItem(at: appleIIgsTabIndex))
|
||||
// TEMPORARY: remove the Apple IIgs and PC compatible options.
|
||||
// Neither is yet a fully-working machine.
|
||||
for hidden in ["appleiigs", "pc"] {
|
||||
let tabIndex = machineSelector.indexOfTabViewItem(withIdentifier: hidden)
|
||||
machineSelector.removeTabViewItem(machineSelector.tabViewItem(at: tabIndex))
|
||||
}
|
||||
machineNameTable.reloadData()
|
||||
|
||||
// Machine type
|
||||
@ -396,6 +399,9 @@ class MachinePicker: NSObject, NSTableViewDataSource, NSTableViewDelegate {
|
||||
|
||||
return CSStaticAnalyser(oricModel: model, diskInterface: diskInterface)
|
||||
|
||||
case "pc":
|
||||
return CSStaticAnalyser(pcCompatibleModel: .turboXT)
|
||||
|
||||
case "spectrum":
|
||||
var model: CSMachineSpectrumModel = .plus2a
|
||||
switch spectrumModelTypeButton.selectedTag() {
|
||||
|
@ -59,7 +59,6 @@ struct Registers {
|
||||
uint16_t &si() { return si_; }
|
||||
uint16_t &di() { return di_; }
|
||||
|
||||
uint16_t ip_;
|
||||
uint16_t &ip() { return ip_; }
|
||||
|
||||
uint16_t &es() { return es_; }
|
||||
@ -89,9 +88,7 @@ struct Registers {
|
||||
ip_ == rhs.ip_;
|
||||
}
|
||||
|
||||
// TODO: make the below private and use a friend class for test population, to ensure Perform
|
||||
// is free of direct accesses.
|
||||
// private:
|
||||
private:
|
||||
CPU::RegisterPair16 ax_;
|
||||
CPU::RegisterPair16 cx_;
|
||||
CPU::RegisterPair16 dx_;
|
||||
@ -102,6 +99,7 @@ struct Registers {
|
||||
uint16_t si_;
|
||||
uint16_t di_;
|
||||
uint16_t es_, cs_, ds_, ss_;
|
||||
uint16_t ip_;
|
||||
};
|
||||
class Segments {
|
||||
public:
|
||||
@ -369,18 +367,18 @@ struct IO {
|
||||
};
|
||||
class FlowController {
|
||||
public:
|
||||
FlowController(Memory &memory, Registers ®isters, Segments &segments, Flags &flags) :
|
||||
memory_(memory), registers_(registers), segments_(segments), flags_(flags) {}
|
||||
FlowController(Registers ®isters, Segments &segments) :
|
||||
registers_(registers), segments_(segments) {}
|
||||
|
||||
// Requirements for perform.
|
||||
void jump(uint16_t address) {
|
||||
registers_.ip_ = address;
|
||||
registers_.ip() = address;
|
||||
}
|
||||
|
||||
void jump(uint16_t segment, uint16_t address) {
|
||||
registers_.cs_ = segment;
|
||||
registers_.cs() = segment;
|
||||
segments_.did_update(Segments::Source::CS);
|
||||
registers_.ip_ = address;
|
||||
registers_.ip() = address;
|
||||
}
|
||||
|
||||
void halt() {}
|
||||
@ -399,10 +397,8 @@ class FlowController {
|
||||
}
|
||||
|
||||
private:
|
||||
Memory &memory_;
|
||||
Registers ®isters_;
|
||||
Segments &segments_;
|
||||
Flags &flags_;
|
||||
bool should_repeat_ = false;
|
||||
};
|
||||
|
||||
@ -418,7 +414,7 @@ struct ExecutionSupport {
|
||||
ExecutionSupport():
|
||||
memory(registers, segments),
|
||||
segments(registers),
|
||||
flow_controller(memory, registers, segments, flags) {}
|
||||
flow_controller(registers, segments) {}
|
||||
|
||||
void clear() {
|
||||
memory.clear();
|
||||
@ -580,20 +576,20 @@ struct FailedExecution {
|
||||
}
|
||||
|
||||
- (void)populate:(Registers &)registers flags:(Flags &)flags value:(NSDictionary *)value {
|
||||
registers.ax_.full = [value[@"ax"] intValue];
|
||||
registers.bx_.full = [value[@"bx"] intValue];
|
||||
registers.cx_.full = [value[@"cx"] intValue];
|
||||
registers.dx_.full = [value[@"dx"] intValue];
|
||||
registers.ax() = [value[@"ax"] intValue];
|
||||
registers.bx() = [value[@"bx"] intValue];
|
||||
registers.cx() = [value[@"cx"] intValue];
|
||||
registers.dx() = [value[@"dx"] intValue];
|
||||
|
||||
registers.bp_ = [value[@"bp"] intValue];
|
||||
registers.cs_ = [value[@"cs"] intValue];
|
||||
registers.di_ = [value[@"di"] intValue];
|
||||
registers.ds_ = [value[@"ds"] intValue];
|
||||
registers.es_ = [value[@"es"] intValue];
|
||||
registers.si_ = [value[@"si"] intValue];
|
||||
registers.sp_ = [value[@"sp"] intValue];
|
||||
registers.ss_ = [value[@"ss"] intValue];
|
||||
registers.ip_ = [value[@"ip"] intValue];
|
||||
registers.bp() = [value[@"bp"] intValue];
|
||||
registers.cs() = [value[@"cs"] intValue];
|
||||
registers.di() = [value[@"di"] intValue];
|
||||
registers.ds() = [value[@"ds"] intValue];
|
||||
registers.es() = [value[@"es"] intValue];
|
||||
registers.si() = [value[@"si"] intValue];
|
||||
registers.sp() = [value[@"sp"] intValue];
|
||||
registers.ss() = [value[@"ss"] intValue];
|
||||
registers.ip() = [value[@"ip"] intValue];
|
||||
|
||||
const uint16_t flags_value = [value[@"flags"] intValue];
|
||||
flags.set(flags_value);
|
||||
@ -646,7 +642,7 @@ struct FailedExecution {
|
||||
//
|
||||
// TODO: enquire of the actual mechanism of repetition; if it were stateful as below then
|
||||
// would it survive interrupts? So is it just IP adjustment?
|
||||
execution_support.registers.ip_ += decoded.first;
|
||||
execution_support.registers.ip() += decoded.first;
|
||||
do {
|
||||
execution_support.flow_controller.begin_instruction();
|
||||
InstructionSet::x86::perform(
|
||||
@ -718,7 +714,7 @@ struct FailedExecution {
|
||||
// More research required, but for now I'm not treating this as a roadblock.
|
||||
if(decoded.second.operation() == Operation::IDIV_REP) {
|
||||
Registers advanced_registers = intended_registers;
|
||||
advanced_registers.ip_ += decoded.first;
|
||||
advanced_registers.ip() += decoded.first;
|
||||
if(advanced_registers == execution_support.registers && ramEqual && flagsEqual) {
|
||||
failure_list = &permitted_failures;
|
||||
}
|
||||
|
@ -99,6 +99,7 @@ SOURCES += \
|
||||
$$SRC/Machines/MasterSystem/*.cpp \
|
||||
$$SRC/Machines/MSX/*.cpp \
|
||||
$$SRC/Machines/Oric/*.cpp \
|
||||
$$SRC/Machines/PCCompatible/*.cpp \
|
||||
$$SRC/Machines/Utility/*.cpp \
|
||||
$$SRC/Machines/Sinclair/Keyboard/*.cpp \
|
||||
$$SRC/Machines/Sinclair/ZX8081/*.cpp \
|
||||
@ -232,6 +233,7 @@ HEADERS += \
|
||||
$$SRC/Machines/MasterSystem/*.hpp \
|
||||
$$SRC/Machines/MSX/*.hpp \
|
||||
$$SRC/Machines/Oric/*.hpp \
|
||||
$$SRC/Machines/PCCompatible/*.hpp \
|
||||
$$SRC/Machines/Utility/*.hpp \
|
||||
$$SRC/Machines/Sinclair/Keyboard/*.hpp \
|
||||
$$SRC/Machines/Sinclair/ZX8081/*.hpp \
|
||||
|
@ -86,6 +86,7 @@ SOURCES += glob.glob('../../Machines/Enterprise/*.cpp')
|
||||
SOURCES += glob.glob('../../Machines/MasterSystem/*.cpp')
|
||||
SOURCES += glob.glob('../../Machines/MSX/*.cpp')
|
||||
SOURCES += glob.glob('../../Machines/Oric/*.cpp')
|
||||
SOURCES += glob.glob('../../Machines/PCCompatible/*.cpp')
|
||||
SOURCES += glob.glob('../../Machines/Utility/*.cpp')
|
||||
SOURCES += glob.glob('../../Machines/Sinclair/Keyboard/*.cpp')
|
||||
SOURCES += glob.glob('../../Machines/Sinclair/ZX8081/*.cpp')
|
||||
|
BIN
ROMImages/PCCompatible/GLABIOS_0.2.5_8T.ROM
Normal file
BIN
ROMImages/PCCompatible/GLABIOS_0.2.5_8T.ROM
Normal file
Binary file not shown.
5
ROMImages/PCCompatible/readme.txt
Normal file
5
ROMImages/PCCompatible/readme.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Expected files:
|
||||
|
||||
GLABIOS_0.2.5_8T.ROM — the 8088 GlaBIOS ROM.
|
||||
|
||||
GlaBIOS is an open-source GPLv3 alternative BIOS for XT clones, available from https://glabios.org/
|
Loading…
x
Reference in New Issue
Block a user