some more opcodes and refactoring

This commit is contained in:
Luigi Thirty 2017-07-23 01:29:09 -04:00
parent 780f722955
commit da828a5d36
4 changed files with 170 additions and 81 deletions

View File

@ -17,6 +17,7 @@
2AD458E31F20661300F05121 /* CPUInstructions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458E21F20661300F05121 /* CPUInstructions.swift */; };
2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458E41F2070DF00F05121 /* Opcodes.swift */; };
2AE5BA041F23DE4400FAA343 /* Disassembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE5BA031F23DE4400FAA343 /* Disassembly.swift */; };
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE5BA051F2469EB00FAA343 /* AddressConversions.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -33,6 +34,7 @@
2AD458E21F20661300F05121 /* CPUInstructions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPUInstructions.swift; sourceTree = "<group>"; };
2AD458E41F2070DF00F05121 /* Opcodes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Opcodes.swift; sourceTree = "<group>"; };
2AE5BA031F23DE4400FAA343 /* Disassembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disassembly.swift; sourceTree = "<group>"; };
2AE5BA051F2469EB00FAA343 /* AddressConversions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressConversions.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -83,6 +85,7 @@
2AD458E21F20661300F05121 /* CPUInstructions.swift */,
2AE5BA031F23DE4400FAA343 /* Disassembly.swift */,
2AD458E41F2070DF00F05121 /* Opcodes.swift */,
2AE5BA051F2469EB00FAA343 /* AddressConversions.swift */,
2AD458E01F2064CB00F05121 /* MemoryInterface.swift */,
2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */,
);
@ -165,6 +168,7 @@
2A22EBFB1F21A7A700A36A61 /* IntegerExtensions.swift in Sources */,
2AE5BA041F23DE4400FAA343 /* Disassembly.swift in Sources */,
2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */,
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */,
2AD458E11F2064CB00F05121 /* MemoryInterface.swift in Sources */,
2AD458DF1F205F4500F05121 /* CPUState.swift in Sources */,
);

View File

@ -0,0 +1,15 @@
//
// Conversions.swift
// FruitMachine
//
// Created by Christopher Rohl on 7/23/17.
// Copyright © 2017 Christopher Rohl. All rights reserved.
//
import Cocoa
class AddressConversions: NSObject {
static func zeroPageAsUInt16(address: UInt8) -> UInt16 {
return 0x0000 | UInt16(address)
}
}

View File

@ -46,86 +46,116 @@ class CPUInstruction: NSObject {
let InstructionTable: [UInt8:CPUInstruction] = [
//INC/DEC
0xC6: CPUInstruction(mnemonic: "DEC", cycles: 5, bytes: 2, addressingMode: .zeropage, action: Opcodes.DEC),
0xD6: CPUInstruction(mnemonic: "DEC", cycles: 6, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.DEC),
0xCE: CPUInstruction(mnemonic: "DEC", cycles: 6, bytes: 3, addressingMode: .absolute, action: Opcodes.DEC),
0xDE: CPUInstruction(mnemonic: "DEC", cycles: 7, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.DEC),
//Boolean operators
0x09: CPUInstruction(mnemonic: "ORA", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.ORA),
0x05: CPUInstruction(mnemonic: "ORA", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.ORA),
0x15: CPUInstruction(mnemonic: "ORA", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.ORA),
0x0D: CPUInstruction(mnemonic: "ORA", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.ORA),
0x1D: CPUInstruction(mnemonic: "ORA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.ORA),
0x19: CPUInstruction(mnemonic: "ORA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.ORA),
0x01: CPUInstruction(mnemonic: "ORA", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.ORA),
0x11: CPUInstruction(mnemonic: "ORA", cycles: 5, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.ORA),
0xE6: CPUInstruction(mnemonic: "INC", cycles: 5, bytes: 2, addressingMode: .zeropage, action: Opcodes.INC),
0xF6: CPUInstruction(mnemonic: "INC", cycles: 6, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.INC),
0xEE: CPUInstruction(mnemonic: "INC", cycles: 6, bytes: 3, addressingMode: .absolute, action: Opcodes.INC),
0xFE: CPUInstruction(mnemonic: "INC", cycles: 7, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.INC),
0x49: CPUInstruction(mnemonic: "EOR", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.EOR),
0x45: CPUInstruction(mnemonic: "EOR", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.EOR),
0x55: CPUInstruction(mnemonic: "EOR", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.EOR),
0x4D: CPUInstruction(mnemonic: "EOR", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.EOR),
0x5D: CPUInstruction(mnemonic: "EOR", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.EOR),
0x59: CPUInstruction(mnemonic: "EOR", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.EOR),
0x41: CPUInstruction(mnemonic: "EOR", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.EOR),
0x51: CPUInstruction(mnemonic: "EOR", cycles: 5, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.EOR),
0x29: CPUInstruction(mnemonic: "AND", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.AND),
0x25: CPUInstruction(mnemonic: "AND", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.AND),
0x35: CPUInstruction(mnemonic: "AND", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.AND),
0x2D: CPUInstruction(mnemonic: "AND", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.AND),
0x3D: CPUInstruction(mnemonic: "AND", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.AND),
0x39: CPUInstruction(mnemonic: "AND", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.AND),
0x21: CPUInstruction(mnemonic: "AND", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.AND),
0x31: CPUInstruction(mnemonic: "AND", cycles: 5, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.AND),
//INC/DEC
0xC6: CPUInstruction(mnemonic: "DEC", cycles: 5, bytes: 2, addressingMode: .zeropage, action: Opcodes.DEC),
0xD6: CPUInstruction(mnemonic: "DEC", cycles: 6, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.DEC),
0xCE: CPUInstruction(mnemonic: "DEC", cycles: 6, bytes: 3, addressingMode: .absolute, action: Opcodes.DEC),
0xDE: CPUInstruction(mnemonic: "DEC", cycles: 7, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.DEC),
0xE6: CPUInstruction(mnemonic: "INC", cycles: 5, bytes: 2, addressingMode: .zeropage, action: Opcodes.INC),
0xF6: CPUInstruction(mnemonic: "INC", cycles: 6, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.INC),
0xEE: CPUInstruction(mnemonic: "INC", cycles: 6, bytes: 3, addressingMode: .absolute, action: Opcodes.INC),
0xFE: CPUInstruction(mnemonic: "INC", cycles: 7, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.INC),
//JMP
0x4C: CPUInstruction(mnemonic: "JMP", cycles: 3, bytes: 3, addressingMode: .absolute, action: Opcodes.JMP),
0x6C: CPUInstruction(mnemonic: "JMP", cycles: 5, bytes: 3, addressingMode: .indirect, action: Opcodes.JMP),
0x4C: CPUInstruction(mnemonic: "JMP", cycles: 3, bytes: 3, addressingMode: .absolute, action: Opcodes.JMP),
0x6C: CPUInstruction(mnemonic: "JMP", cycles: 5, bytes: 3, addressingMode: .indirect, action: Opcodes.JMP),
//LD instructions
0xA9: CPUInstruction(mnemonic: "LDA", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDA),
0xA5: CPUInstruction(mnemonic: "LDA", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDA),
0xB5: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDA),
0xAD: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDA),
0xBD: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDA),
0xB9: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDA),
0xA1: CPUInstruction(mnemonic: "LDA", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.LDA),
0xB1: CPUInstruction(mnemonic: "LDA", cycles: 5, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.LDA),
0xA9: CPUInstruction(mnemonic: "LDA", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDA),
0xA5: CPUInstruction(mnemonic: "LDA", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDA),
0xB5: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDA),
0xAD: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDA),
0xBD: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDA),
0xB9: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDA),
0xA1: CPUInstruction(mnemonic: "LDA", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.LDA),
0xB1: CPUInstruction(mnemonic: "LDA", cycles: 5, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.LDA),
0xA2: CPUInstruction(mnemonic: "LDX", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDX),
0xA6: CPUInstruction(mnemonic: "LDX", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDX),
0xB6: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_y, action: Opcodes.LDX),
0xAE: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDX),
0xBE: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDX),
0xA2: CPUInstruction(mnemonic: "LDX", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDX),
0xA6: CPUInstruction(mnemonic: "LDX", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDX),
0xB6: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_y, action: Opcodes.LDX),
0xAE: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDX),
0xBE: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDX),
0xA0: CPUInstruction(mnemonic: "LDY", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDY),
0xA4: CPUInstruction(mnemonic: "LDY", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDY),
0xB4: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDY),
0xAC: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDY),
0xBC: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDY),
0xA0: CPUInstruction(mnemonic: "LDY", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDY),
0xA4: CPUInstruction(mnemonic: "LDY", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDY),
0xB4: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDY),
0xAC: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDY),
0xBC: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDY),
//ST functions
0x85: CPUInstruction(mnemonic: "STA", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.STA),
0x95: CPUInstruction(mnemonic: "STA", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.STA),
0x8D: CPUInstruction(mnemonic: "STA", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.STA),
0x9D: CPUInstruction(mnemonic: "STA", cycles: 5, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.STA),
0x99: CPUInstruction(mnemonic: "STA", cycles: 5, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.STA),
0x81: CPUInstruction(mnemonic: "STA", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.STA),
0x91: CPUInstruction(mnemonic: "STA", cycles: 6, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.STA),
0x85: CPUInstruction(mnemonic: "STA", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.STA),
0x95: CPUInstruction(mnemonic: "STA", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.STA),
0x8D: CPUInstruction(mnemonic: "STA", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.STA),
0x9D: CPUInstruction(mnemonic: "STA", cycles: 5, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.STA),
0x99: CPUInstruction(mnemonic: "STA", cycles: 5, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.STA),
0x81: CPUInstruction(mnemonic: "STA", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.STA),
0x91: CPUInstruction(mnemonic: "STA", cycles: 6, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.STA),
0x86: CPUInstruction(mnemonic: "STX", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.STX),
0x96: CPUInstruction(mnemonic: "STX", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_y, action: Opcodes.STX),
0x8E: CPUInstruction(mnemonic: "STX", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.STX),
0x86: CPUInstruction(mnemonic: "STX", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.STX),
0x96: CPUInstruction(mnemonic: "STX", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_y, action: Opcodes.STX),
0x8E: CPUInstruction(mnemonic: "STX", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.STX),
0x84: CPUInstruction(mnemonic: "STY", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.STY),
0x94: CPUInstruction(mnemonic: "STY", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.STY),
0x8C: CPUInstruction(mnemonic: "STY", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.STY),
0x84: CPUInstruction(mnemonic: "STY", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.STY),
0x94: CPUInstruction(mnemonic: "STY", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.STY),
0x8C: CPUInstruction(mnemonic: "STY", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.STY),
//Register functions
0x88: CPUInstruction(mnemonic: "DEY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEY),
0x8A: CPUInstruction(mnemonic: "TXA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXA),
0x98: CPUInstruction(mnemonic: "TYA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TYA),
0xA8: CPUInstruction(mnemonic: "TAY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAY),
0xAA: CPUInstruction(mnemonic: "TAX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAX),
0xC8: CPUInstruction(mnemonic: "INY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INY),
0xCA: CPUInstruction(mnemonic: "DEX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEX),
0xE8: CPUInstruction(mnemonic: "INX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INX),
0x88: CPUInstruction(mnemonic: "DEY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEY),
0x8A: CPUInstruction(mnemonic: "TXA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXA),
0x98: CPUInstruction(mnemonic: "TYA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TYA),
0xA8: CPUInstruction(mnemonic: "TAY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAY),
0xAA: CPUInstruction(mnemonic: "TAX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAX),
0xC8: CPUInstruction(mnemonic: "INY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INY),
0xCA: CPUInstruction(mnemonic: "DEX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEX),
0xE8: CPUInstruction(mnemonic: "INX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INX),
//Processor flag instructions
0x18: CPUInstruction(mnemonic: "CLC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLC),
0x38: CPUInstruction(mnemonic: "SEC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEC),
0x58: CPUInstruction(mnemonic: "CLI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLI),
0x78: CPUInstruction(mnemonic: "SEI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEI),
0xB8: CPUInstruction(mnemonic: "CLV", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLV),
0xD8: CPUInstruction(mnemonic: "CLD", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLD),
0xF8: CPUInstruction(mnemonic: "SED", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SED),
0x18: CPUInstruction(mnemonic: "CLC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLC),
0x38: CPUInstruction(mnemonic: "SEC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEC),
0x58: CPUInstruction(mnemonic: "CLI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLI),
0x78: CPUInstruction(mnemonic: "SEI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEI),
0xB8: CPUInstruction(mnemonic: "CLV", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLV),
0xD8: CPUInstruction(mnemonic: "CLD", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLD),
0xF8: CPUInstruction(mnemonic: "SED", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SED),
//Stack instructions
0x9A: CPUInstruction(mnemonic: "TXS", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXS),
0xBA: CPUInstruction(mnemonic: "TSX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TSX),
0x48: CPUInstruction(mnemonic: "PHA", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHA),
0x68: CPUInstruction(mnemonic: "PLA", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLA),
0x08: CPUInstruction(mnemonic: "PHP", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHP),
0x28: CPUInstruction(mnemonic: "PLP", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLP),
0x9A: CPUInstruction(mnemonic: "TXS", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXS),
0xBA: CPUInstruction(mnemonic: "TSX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TSX),
0x48: CPUInstruction(mnemonic: "PHA", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHA),
0x68: CPUInstruction(mnemonic: "PLA", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLA),
0x08: CPUInstruction(mnemonic: "PHP", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHP),
0x28: CPUInstruction(mnemonic: "PLP", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLP),
0xEA: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP),
0x20: CPUInstruction(mnemonic: "JSR", cycles: 6, bytes: 3, addressingMode: .absolute, action: Opcodes.JSR),
0xEA: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP),
]

View File

@ -8,12 +8,25 @@
import Cocoa
func stackPointerAsUInt16(state: CPUState) -> UInt16 {
return 0x0100 | UInt16(state.stack_pointer);
}
extension CPUState {
func zpAsUInt16(address: UInt8) -> UInt16 {
return 0x0000 | UInt16(address)
func pushByte(data: UInt8) -> Void {
memoryInterface.writeByte(offset: stackPointerAsUInt16(), value: data)
stack_pointer = stack_pointer &- 1
}
func pushWord(data: UInt16) -> Void {
let low = UInt8(data & 0x00FF)
let high = UInt8(data & 0xFF00)
pushByte(data: low)
pushByte(data: high)
}
func stackPointerAsUInt16() -> UInt16 {
return 0x0100 | UInt16(stack_pointer);
}
}
func getOperandByteForAddressingMode(state: CPUState, mode: AddressingMode) -> UInt8 {
@ -110,7 +123,7 @@ class Opcodes: NSObject {
let address: UInt16
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_x) {
address = zpAsUInt16(address: state.getOperandByte())
address = AddressConversions.zeroPageAsUInt16(address: state.getOperandByte())
state.memoryInterface.writeByte(offset: address, value: state.accumulator)
}
@ -128,7 +141,7 @@ class Opcodes: NSObject {
let address: UInt16
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_y) {
address = zpAsUInt16(address: state.getOperandByte())
address = AddressConversions.zeroPageAsUInt16(address: state.getOperandByte())
state.memoryInterface.writeByte(offset: address, value: state.index_x)
}
@ -146,7 +159,7 @@ class Opcodes: NSObject {
let address: UInt16
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_x) {
address = zpAsUInt16(address: state.getOperandByte())
address = AddressConversions.zeroPageAsUInt16(address: state.getOperandByte())
state.memoryInterface.writeByte(offset: address, value: state.index_y)
}
@ -222,7 +235,7 @@ class Opcodes: NSObject {
var val: UInt8
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_x) {
address = zpAsUInt16(address: state.getOperandByte())
address = AddressConversions.zeroPageAsUInt16(address: state.getOperandByte())
val = state.memoryInterface.readByte(offset: address)
}
@ -247,7 +260,7 @@ class Opcodes: NSObject {
var val: UInt8
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_x) {
address = zpAsUInt16(address: state.getOperandByte())
address = AddressConversions.zeroPageAsUInt16(address: state.getOperandByte())
val = state.memoryInterface.readByte(offset: address)
}
@ -273,7 +286,7 @@ class Opcodes: NSObject {
state.updateZeroFlag(value: data)
state.updateNegativeFlag(value: data)
state.status_register.carry = !state.status_register.negative //? check this
state.status_register.carry = (data >= 0)
}
static func CPX(state: CPUState, addressingMode: AddressingMode) -> Void {
@ -281,7 +294,7 @@ class Opcodes: NSObject {
state.updateZeroFlag(value: data)
state.updateNegativeFlag(value: data)
state.status_register.carry = !state.status_register.negative //? check this
state.status_register.carry = (data >= 0)
}
static func CPY(state: CPUState, addressingMode: AddressingMode) -> Void {
@ -289,7 +302,29 @@ class Opcodes: NSObject {
state.updateZeroFlag(value: data)
state.updateNegativeFlag(value: data)
state.status_register.carry = !state.status_register.negative //? check this
state.status_register.carry = (data >= 0)
}
//Boolean operators
static func EOR(state: CPUState, addressingMode: AddressingMode) -> Void {
state.accumulator = state.accumulator ^ getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.accumulator)
state.updateNegativeFlag(value: state.accumulator)
}
static func AND(state: CPUState, addressingMode: AddressingMode) -> Void {
state.accumulator = state.accumulator & getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.accumulator)
state.updateNegativeFlag(value: state.accumulator)
}
static func ORA(state: CPUState, addressingMode: AddressingMode) -> Void {
state.accumulator = state.accumulator | getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.accumulator)
state.updateNegativeFlag(value: state.accumulator)
}
//Processor flag instructions
@ -334,26 +369,26 @@ class Opcodes: NSObject {
}
static func PHA(state: CPUState, addressingMode: AddressingMode) -> Void {
state.memoryInterface.writeByte(offset: stackPointerAsUInt16(state: state), value: state.accumulator)
state.memoryInterface.writeByte(offset: state.stackPointerAsUInt16(), value: state.accumulator)
state.stack_pointer = state.stack_pointer &- 1
}
static func PLA(state: CPUState, addressingMode: AddressingMode) -> Void {
state.stack_pointer = state.stack_pointer &+ 1
state.accumulator = state.memoryInterface.readByte(offset: stackPointerAsUInt16(state: state))
state.accumulator = state.memoryInterface.readByte(offset: state.stackPointerAsUInt16())
state.updateZeroFlag(value: state.accumulator);
state.updateNegativeFlag(value: state.accumulator);
}
static func PHP(state: CPUState, addressingMode: AddressingMode) -> Void {
state.memoryInterface.writeByte(offset: stackPointerAsUInt16(state: state), value: state.status_register.asByte())
state.memoryInterface.writeByte(offset: state.stackPointerAsUInt16(), value: state.status_register.asByte())
state.stack_pointer = state.stack_pointer &- 1
}
static func PLP(state: CPUState, addressingMode: AddressingMode) -> Void {
state.stack_pointer = state.stack_pointer &+ 1
state.status_register.fromByte(state: state.memoryInterface.readByte(offset: stackPointerAsUInt16(state: state)))
state.status_register.fromByte(state: state.memoryInterface.readByte(offset: state.stackPointerAsUInt16()))
}
//Misc
@ -361,6 +396,11 @@ class Opcodes: NSObject {
state.program_counter = getOperandWordForAddressingMode(state: state, mode: addressingMode)
}
static func JSR(state: CPUState, addressingMode: AddressingMode) -> Void {
//JSR pushes the address-1 of the next operation on to the stack before transferring program control to the following address
state.pushWord(data: state.program_counter + 3)
state.program_counter = state.getOperandWord()
}
static func NOP(state: CPUState, addressingMode: AddressingMode) -> Void {}
}