2015-07-17 00:15:30 +00:00
|
|
|
//
|
|
|
|
// Machine.m
|
2015-07-26 19:25:11 +00:00
|
|
|
// CLK
|
2015-07-17 00:15:30 +00:00
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 29/06/2015.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2015 Thomas Harte. All rights reserved.
|
2015-07-17 00:15:30 +00:00
|
|
|
//
|
|
|
|
|
2017-05-15 12:18:57 +00:00
|
|
|
#import "TestMachine6502.h"
|
2015-07-17 00:15:30 +00:00
|
|
|
#include <stdint.h>
|
2018-08-07 01:15:13 +00:00
|
|
|
#include "../../../../Processors/6502/AllRAM/6502AllRAM.hpp"
|
2017-06-04 01:22:16 +00:00
|
|
|
#import "TestMachine+ForSubclassEyesOnly.h"
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2017-07-24 02:22:50 +00:00
|
|
|
const uint8_t CSTestMachine6502JamOpcode = CPU::MOS6502::JamOpcode;
|
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
#pragma mark - Register enum map
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
static CPU::MOS6502::Register registerForRegister(CSTestMachine6502Register reg) {
|
2015-07-17 00:15:30 +00:00
|
|
|
switch (reg) {
|
2017-05-15 12:18:57 +00:00
|
|
|
case CSTestMachine6502RegisterProgramCounter: return CPU::MOS6502::Register::ProgramCounter;
|
|
|
|
case CSTestMachine6502RegisterLastOperationAddress: return CPU::MOS6502::Register::LastOperationAddress;
|
|
|
|
case CSTestMachine6502RegisterFlags: return CPU::MOS6502::Register::Flags;
|
|
|
|
case CSTestMachine6502RegisterA: return CPU::MOS6502::Register::A;
|
|
|
|
case CSTestMachine6502RegisterX: return CPU::MOS6502::Register::X;
|
|
|
|
case CSTestMachine6502RegisterY: return CPU::MOS6502::Register::Y;
|
2020-04-15 03:51:45 +00:00
|
|
|
case CSTestMachine6502RegisterStackPointer: return CPU::MOS6502::Register::StackPointer;
|
2020-10-14 01:38:30 +00:00
|
|
|
case CSTestMachine6502RegisterEmulationFlag: return CPU::MOS6502::Register::EmulationFlag;
|
|
|
|
case CSTestMachine6502RegisterDataBank: return CPU::MOS6502::Register::DataBank;
|
|
|
|
case CSTestMachine6502RegisterProgramBank: return CPU::MOS6502::Register::ProgramBank;
|
|
|
|
case CSTestMachine6502RegisterDirect: return CPU::MOS6502::Register::Direct;
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
#pragma mark - Test class
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
@implementation CSTestMachine6502 {
|
2017-06-04 01:22:16 +00:00
|
|
|
CPU::MOS6502::AllRAMProcessor *_processor;
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
#pragma mark - Lifecycle
|
2015-07-17 00:15:30 +00:00
|
|
|
|
2021-07-31 01:21:16 +00:00
|
|
|
- (instancetype)initWithProcessor:(CSTestMachine6502Processor)processor hasCIAs:(BOOL)hasCIAs {
|
2015-07-17 00:15:30 +00:00
|
|
|
self = [super init];
|
|
|
|
|
2016-04-25 02:32:24 +00:00
|
|
|
if(self) {
|
2020-09-27 02:31:50 +00:00
|
|
|
switch(processor) {
|
2023-09-21 13:47:29 +00:00
|
|
|
case CSTestMachine6502ProcessorNES6502:
|
|
|
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502Esque::Type::TNES6502, hasCIAs);
|
|
|
|
break;
|
2020-09-27 02:31:50 +00:00
|
|
|
case CSTestMachine6502Processor6502:
|
2021-07-31 01:21:16 +00:00
|
|
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502Esque::Type::T6502, hasCIAs);
|
2020-09-27 02:31:50 +00:00
|
|
|
break;
|
|
|
|
case CSTestMachine6502Processor65C02:
|
2021-07-31 01:21:16 +00:00
|
|
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502Esque::Type::TWDC65C02, hasCIAs);
|
2020-09-27 02:31:50 +00:00
|
|
|
break;
|
2020-09-29 01:35:46 +00:00
|
|
|
case CSTestMachine6502Processor65816:
|
2021-07-31 01:21:16 +00:00
|
|
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor(CPU::MOS6502Esque::Type::TWDC65816, hasCIAs);
|
2020-09-27 02:31:50 +00:00
|
|
|
}
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2021-07-31 01:21:16 +00:00
|
|
|
- (nonnull instancetype)initWithProcessor:(CSTestMachine6502Processor)processor {
|
|
|
|
return [self initWithProcessor:processor hasCIAs:NO];
|
|
|
|
}
|
|
|
|
|
2015-07-17 00:15:30 +00:00
|
|
|
- (void)dealloc {
|
2017-06-04 01:22:16 +00:00
|
|
|
delete _processor;
|
2015-07-17 00:15:30 +00:00
|
|
|
}
|
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
#pragma mark - Accessors
|
|
|
|
|
2020-10-14 01:38:30 +00:00
|
|
|
- (uint8_t)valueForAddress:(uint32_t)address {
|
2017-05-17 02:05:42 +00:00
|
|
|
uint8_t value;
|
2017-06-04 01:22:16 +00:00
|
|
|
_processor->get_data_at_address(address, 1, &value);
|
2017-05-17 02:05:42 +00:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-10-14 01:38:30 +00:00
|
|
|
- (void)setValue:(uint8_t)value forAddress:(uint32_t)address {
|
2017-06-04 01:22:16 +00:00
|
|
|
_processor->set_data_at_address(address, 1, &value);
|
2017-05-17 02:05:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setValue:(uint16_t)value forRegister:(CSTestMachine6502Register)reg {
|
2023-05-10 23:53:38 +00:00
|
|
|
_processor->set_value_of(registerForRegister(reg), value);
|
2017-05-17 02:05:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (uint16_t)valueForRegister:(CSTestMachine6502Register)reg {
|
2023-05-10 23:53:38 +00:00
|
|
|
return _processor->value_of(registerForRegister(reg));
|
2017-05-17 02:05:42 +00:00
|
|
|
}
|
|
|
|
|
2020-10-14 01:38:30 +00:00
|
|
|
- (void)setData:(NSData *)data atAddress:(uint32_t)startAddress {
|
2017-06-04 01:22:16 +00:00
|
|
|
_processor->set_data_at_address(startAddress, data.length, (const uint8_t *)data.bytes);
|
2017-05-17 02:05:42 +00:00
|
|
|
}
|
|
|
|
|
2023-09-21 14:00:26 +00:00
|
|
|
- (nonnull NSData *)dataAtAddress:(uint32_t)address length:(uint32_t)length {
|
|
|
|
NSMutableData *data = [[NSMutableData alloc] initWithLength:length];
|
|
|
|
_processor->get_data_at_address(address, length, (uint8_t *)data.mutableBytes);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
- (BOOL)isJammed {
|
2017-06-04 01:22:16 +00:00
|
|
|
return _processor->is_jammed();
|
2017-05-17 02:05:42 +00:00
|
|
|
}
|
|
|
|
|
2015-08-13 00:06:56 +00:00
|
|
|
- (uint32_t)timestamp {
|
2019-10-30 02:36:29 +00:00
|
|
|
return uint32_t(_processor->get_timestamp().as_integral());
|
2015-08-13 00:06:56 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 01:29:43 +00:00
|
|
|
- (void)setIrqLine:(BOOL)irqLine {
|
|
|
|
_irqLine = irqLine;
|
2017-06-04 01:22:16 +00:00
|
|
|
_processor->set_irq_line(irqLine);
|
2016-06-29 01:29:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setNmiLine:(BOOL)nmiLine {
|
|
|
|
_nmiLine = nmiLine;
|
2017-06-04 01:22:16 +00:00
|
|
|
_processor->set_nmi_line(nmiLine);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (CPU::AllRAMProcessor *)processor {
|
|
|
|
return _processor;
|
2016-06-29 01:29:43 +00:00
|
|
|
}
|
|
|
|
|
2017-05-17 02:05:42 +00:00
|
|
|
#pragma mark - Actions
|
|
|
|
|
|
|
|
- (void)runForNumberOfCycles:(int)cycles {
|
2017-07-23 02:21:26 +00:00
|
|
|
_processor->run_for(Cycles(cycles));
|
2017-05-17 02:05:42 +00:00
|
|
|
}
|
|
|
|
|
2020-11-03 02:09:32 +00:00
|
|
|
- (void)runForNumberOfInstructions:(int)instructions {
|
|
|
|
_processor->run_for_instructions(instructions);
|
|
|
|
}
|
|
|
|
|
2015-07-17 00:15:30 +00:00
|
|
|
@end
|