From 780f722955158725712990c030c832251cdf7659 Mon Sep 17 00:00:00 2001 From: Luigi Thirty Date: Sat, 22 Jul 2017 21:46:26 -0400 Subject: [PATCH] added STA/STX/STY, CMP/CPX/CPY (todo: check if CMP works) --- FruitMachine/Base.lproj/Main.storyboard | 80 ++++++++++++++++------- FruitMachine/DebuggerViewController.swift | 15 +++-- FruitMachine/M6502/CPUInstructions.swift | 8 +++ FruitMachine/M6502/CPUState.swift | 44 +++++++++++++ FruitMachine/M6502/Opcodes.swift | 61 +++++++++++++++++ 5 files changed, 178 insertions(+), 30 deletions(-) diff --git a/FruitMachine/Base.lproj/Main.storyboard b/FruitMachine/Base.lproj/Main.storyboard index ce5c2cd..915ca2b 100644 --- a/FruitMachine/Base.lproj/Main.storyboard +++ b/FruitMachine/Base.lproj/Main.storyboard @@ -688,7 +688,7 @@ - + @@ -707,11 +707,11 @@ - + - + @@ -720,16 +720,16 @@ - + - + - + @@ -738,16 +738,16 @@ - + - + - + @@ -756,16 +756,16 @@ - + - + - + @@ -774,16 +774,16 @@ - + - + - + @@ -792,16 +792,16 @@ - + - + - + - + - + @@ -858,7 +858,7 @@ - + @@ -872,11 +872,11 @@ - + - + @@ -904,15 +904,45 @@ - + + + + + + + + + + + + + + + + + + + + + diff --git a/FruitMachine/DebuggerViewController.swift b/FruitMachine/DebuggerViewController.swift index 997315f..b3a9b48 100644 --- a/FruitMachine/DebuggerViewController.swift +++ b/FruitMachine/DebuggerViewController.swift @@ -14,6 +14,7 @@ class DebuggerViewController: NSViewController { @IBOutlet weak var text_CPU_Y: NSTextField! @IBOutlet weak var text_CPU_IP: NSTextField! @IBOutlet weak var text_CPU_SR: NSTextField! + @IBOutlet weak var text_CPU_Flags: NSTextField! @IBOutlet weak var debuggerTableView: NSTableView! @@ -26,6 +27,7 @@ class DebuggerViewController: NSViewController { text_CPU_Y.stringValue = String(format:"%02X", CPU.index_y) text_CPU_IP.stringValue = String(format:"%04X", CPU.program_counter) text_CPU_SR.stringValue = String(format:"%02X", CPU.stack_pointer) + text_CPU_Flags.stringValue = String(CPU.status_register.asString()) } override func viewDidLoad() { @@ -63,6 +65,9 @@ class DebuggerViewController: NSViewController { cpuStep() } + @IBAction func btn_Break(_ sender: Any) { + _ = 0 + } } extension DebuggerViewController: NSTableViewDelegate { @@ -90,21 +95,21 @@ extension DebuggerViewController: NSTableViewDelegate { case .accumulator: cellText = String(format: "%@ A", operation.instruction!.mnemonic) case .immediate: - cellText = String(format: "%@ #%02X", operation.instruction!.mnemonic, operation.data[0]) + cellText = String(format: "%@ #$%02X", operation.instruction!.mnemonic, operation.data[0]) case .implied: cellText = String(format: "%@", operation.instruction!.mnemonic) case .relative: - cellText = String(format: "%@ #%04X", operation.instruction!.mnemonic, UInt16(operation.data[0]) + operation.address) + cellText = String(format: "%@ #$%04X", operation.instruction!.mnemonic, UInt16(operation.data[0]) + operation.address) case .absolute: - cellText = String(format: "%@ #%02X%02X", operation.instruction!.mnemonic, operation.data[1], operation.data[0]) + cellText = String(format: "%@ $%02X%02X", operation.instruction!.mnemonic, operation.data[1], operation.data[0]) case .zeropage: cellText = String(format: "%@ $%02X", operation.instruction!.mnemonic, operation.data[0]) case .indirect: cellText = String(format: "%@ ($%02X%02X)", operation.instruction!.mnemonic, operation.data[1], operation.data[0]) case .absolute_indexed_x: - cellText = String(format: "%@ #%02X%02X,X", operation.instruction!.mnemonic, operation.data[1], operation.data[0]) + cellText = String(format: "%@ $%02X%02X,X", operation.instruction!.mnemonic, operation.data[1], operation.data[0]) case .absolute_indexed_y: - cellText = String(format: "%@ #%02X%02X,Y", operation.instruction!.mnemonic, operation.data[1], operation.data[0]) + cellText = String(format: "%@ $%02X%02X,Y", operation.instruction!.mnemonic, operation.data[1], operation.data[0]) case .zeropage_indexed_x: cellText = String(format: "%@ $%02X,X", operation.instruction!.mnemonic, operation.data[0]) case .zeropage_indexed_y: diff --git a/FruitMachine/M6502/CPUInstructions.swift b/FruitMachine/M6502/CPUInstructions.swift index 4921e34..39d54b0 100644 --- a/FruitMachine/M6502/CPUInstructions.swift +++ b/FruitMachine/M6502/CPUInstructions.swift @@ -92,6 +92,14 @@ let InstructionTable: [UInt8:CPUInstruction] = [ 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), + + 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), diff --git a/FruitMachine/M6502/CPUState.swift b/FruitMachine/M6502/CPUState.swift index 2d12c77..1d0c1e8 100644 --- a/FruitMachine/M6502/CPUState.swift +++ b/FruitMachine/M6502/CPUState.swift @@ -22,6 +22,50 @@ struct StatusRegister { var zero: Bool //Z - 0x02 var carry: Bool //C - 0x01 + func asString() -> String { + var str = "" + + if(negative) { + str += "N" + } else { + str += "-" + } + + if(overflow) { + str += "V" + } else { + str += "-" + } + + str += "-" //0x20 is unassigned + + if(brk) { + str += "B" + } else { + str += "-" + } + + if(decimal) { + str += "D" + } else { + str += "-" + } + + if(irq_disable) { + str += "I" + } else { + str += "-" + } + + if(zero) { + str += "Z" + } else { + str += "-" + } + + return str + } + mutating func fromByte(state: UInt8) { negative = (state & 0x80 == 0x80) overflow = (state & 0x40 == 0x40) diff --git a/FruitMachine/M6502/Opcodes.swift b/FruitMachine/M6502/Opcodes.swift index 2f91d6d..a365c01 100644 --- a/FruitMachine/M6502/Opcodes.swift +++ b/FruitMachine/M6502/Opcodes.swift @@ -124,6 +124,42 @@ class Opcodes: NSObject { } } + static func STX(state: CPUState, addressingMode: AddressingMode) -> Void { + let address: UInt16 + + if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_y) { + address = zpAsUInt16(address: state.getOperandByte()) + state.memoryInterface.writeByte(offset: address, value: state.index_x) + + } + else if (addressingMode == .absolute) { + address = state.getOperandWord() + state.memoryInterface.writeByte(offset: address, value: state.index_x) + } + else { + print("Illegal addressing mode for STX") + return + } + } + + static func STY(state: CPUState, addressingMode: AddressingMode) -> Void { + let address: UInt16 + + if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_x) { + address = zpAsUInt16(address: state.getOperandByte()) + state.memoryInterface.writeByte(offset: address, value: state.index_y) + + } + else if (addressingMode == .absolute) { + address = state.getOperandWord() + state.memoryInterface.writeByte(offset: address, value: state.index_y) + } + else { + print("Illegal addressing mode for STY") + return + } + } + //Register instructions static func TAX(state: CPUState, addressingMode: AddressingMode) -> Void { state.index_x = state.accumulator @@ -231,6 +267,31 @@ class Opcodes: NSObject { state.updateNegativeFlag(value: val); } + //CMP + static func CMP(state: CPUState, addressingMode: AddressingMode) -> Void { + let data = state.accumulator - state.getOperandByte() //CMP is a subtract that doesn't affect memory + + state.updateZeroFlag(value: data) + state.updateNegativeFlag(value: data) + state.status_register.carry = !state.status_register.negative //? check this + } + + static func CPX(state: CPUState, addressingMode: AddressingMode) -> Void { + let data = state.index_x - state.getOperandByte() //CMP is a subtract that doesn't affect memory + + state.updateZeroFlag(value: data) + state.updateNegativeFlag(value: data) + state.status_register.carry = !state.status_register.negative //? check this + } + + static func CPY(state: CPUState, addressingMode: AddressingMode) -> Void { + let data = state.index_y - state.getOperandByte() //CMP is a subtract that doesn't affect memory + + state.updateZeroFlag(value: data) + state.updateNegativeFlag(value: data) + state.status_register.carry = !state.status_register.negative //? check this + } + //Processor flag instructions static func CLC(state: CPUState, addressingMode: AddressingMode) -> Void { state.status_register.carry = false