JMP works now yay
This commit is contained in:
parent
944f51a186
commit
e1a6a0c1b3
|
@ -2,9 +2,9 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.app-sandbox</key>
|
<key>com.apple.security.app-sandbox</key>
|
||||||
<true/>
|
<false/>
|
||||||
<key>com.apple.security.files.user-selected.read-only</key>
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -46,54 +46,58 @@ class CPUInstruction: NSObject {
|
||||||
|
|
||||||
let InstructionTable: [UInt8:CPUInstruction] = [
|
let InstructionTable: [UInt8:CPUInstruction] = [
|
||||||
|
|
||||||
|
//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
|
//LD instructions
|
||||||
0xA9: CPUInstruction.init(mnemonic: "LDA", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDA),
|
0xA9: CPUInstruction(mnemonic: "LDA", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDA),
|
||||||
0xA5: CPUInstruction.init(mnemonic: "LDA", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDA),
|
0xA5: CPUInstruction(mnemonic: "LDA", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDA),
|
||||||
0xB5: CPUInstruction.init(mnemonic: "LDA", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDA),
|
0xB5: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDA),
|
||||||
0xAD: CPUInstruction.init(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDA),
|
0xAD: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDA),
|
||||||
0xBD: CPUInstruction.init(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDA),
|
0xBD: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDA),
|
||||||
0xB9: CPUInstruction.init(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDA),
|
0xB9: CPUInstruction(mnemonic: "LDA", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDA),
|
||||||
0xA1: CPUInstruction.init(mnemonic: "LDA", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.LDA),
|
0xA1: CPUInstruction(mnemonic: "LDA", cycles: 6, bytes: 2, addressingMode: .indexed_indirect, action: Opcodes.LDA),
|
||||||
0xB1: CPUInstruction.init(mnemonic: "LDA", cycles: 5, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.LDA),
|
0xB1: CPUInstruction(mnemonic: "LDA", cycles: 5, bytes: 2, addressingMode: .indirect_indexed, action: Opcodes.LDA),
|
||||||
|
|
||||||
0xA2: CPUInstruction.init(mnemonic: "LDX", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDX),
|
0xA2: CPUInstruction(mnemonic: "LDX", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDX),
|
||||||
0xA6: CPUInstruction.init(mnemonic: "LDX", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDX),
|
0xA6: CPUInstruction(mnemonic: "LDX", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDX),
|
||||||
0xB6: CPUInstruction.init(mnemonic: "LDX", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_y, action: Opcodes.LDX),
|
0xB6: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_y, action: Opcodes.LDX),
|
||||||
0xAE: CPUInstruction.init(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDX),
|
0xAE: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDX),
|
||||||
0xBE: CPUInstruction.init(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDX),
|
0xBE: CPUInstruction(mnemonic: "LDX", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_y, action: Opcodes.LDX),
|
||||||
|
|
||||||
0xA0: CPUInstruction.init(mnemonic: "LDY", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDY),
|
0xA0: CPUInstruction(mnemonic: "LDY", cycles: 2, bytes: 2, addressingMode: .immediate, action: Opcodes.LDY),
|
||||||
0xA4: CPUInstruction.init(mnemonic: "LDY", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDY),
|
0xA4: CPUInstruction(mnemonic: "LDY", cycles: 3, bytes: 2, addressingMode: .zeropage, action: Opcodes.LDY),
|
||||||
0xB4: CPUInstruction.init(mnemonic: "LDY", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDY),
|
0xB4: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 2, addressingMode: .zeropage_indexed_x, action: Opcodes.LDY),
|
||||||
0xAC: CPUInstruction.init(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDY),
|
0xAC: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute, action: Opcodes.LDY),
|
||||||
0xBC: CPUInstruction.init(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDY),
|
0xBC: CPUInstruction(mnemonic: "LDY", cycles: 4, bytes: 3, addressingMode: .absolute_indexed_x, action: Opcodes.LDY),
|
||||||
|
|
||||||
//Register functions
|
//Register functions
|
||||||
0x88: CPUInstruction.init(mnemonic: "DEY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEY),
|
0x88: CPUInstruction(mnemonic: "DEY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEY),
|
||||||
0x8A: CPUInstruction.init(mnemonic: "TXA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXA),
|
0x8A: CPUInstruction(mnemonic: "TXA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXA),
|
||||||
0x98: CPUInstruction.init(mnemonic: "TYA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TYA),
|
0x98: CPUInstruction(mnemonic: "TYA", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TYA),
|
||||||
0xA8: CPUInstruction.init(mnemonic: "TAY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAY),
|
0xA8: CPUInstruction(mnemonic: "TAY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAY),
|
||||||
0xAA: CPUInstruction.init(mnemonic: "TAX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAX),
|
0xAA: CPUInstruction(mnemonic: "TAX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TAX),
|
||||||
0xC8: CPUInstruction.init(mnemonic: "INY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INY),
|
0xC8: CPUInstruction(mnemonic: "INY", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INY),
|
||||||
0xCA: CPUInstruction.init(mnemonic: "DEX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEX),
|
0xCA: CPUInstruction(mnemonic: "DEX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.DEX),
|
||||||
0xE8: CPUInstruction.init(mnemonic: "INX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INX),
|
0xE8: CPUInstruction(mnemonic: "INX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.INX),
|
||||||
|
|
||||||
//Processor flag instructions
|
//Processor flag instructions
|
||||||
0x18: CPUInstruction.init(mnemonic: "CLC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLC),
|
0x18: CPUInstruction(mnemonic: "CLC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLC),
|
||||||
0x38: CPUInstruction.init(mnemonic: "SEC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEC),
|
0x38: CPUInstruction(mnemonic: "SEC", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEC),
|
||||||
0x58: CPUInstruction.init(mnemonic: "CLI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLI),
|
0x58: CPUInstruction(mnemonic: "CLI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLI),
|
||||||
0x78: CPUInstruction.init(mnemonic: "SEI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEI),
|
0x78: CPUInstruction(mnemonic: "SEI", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SEI),
|
||||||
0xB8: CPUInstruction.init(mnemonic: "CLV", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLV),
|
0xB8: CPUInstruction(mnemonic: "CLV", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLV),
|
||||||
0xD8: CPUInstruction.init(mnemonic: "CLD", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLD),
|
0xD8: CPUInstruction(mnemonic: "CLD", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.CLD),
|
||||||
0xF8: CPUInstruction.init(mnemonic: "SED", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SED),
|
0xF8: CPUInstruction(mnemonic: "SED", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.SED),
|
||||||
|
|
||||||
//Stack instructions
|
//Stack instructions
|
||||||
0x9A: CPUInstruction.init(mnemonic: "TXS", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXS),
|
0x9A: CPUInstruction(mnemonic: "TXS", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TXS),
|
||||||
0xBA: CPUInstruction.init(mnemonic: "TSX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TSX),
|
0xBA: CPUInstruction(mnemonic: "TSX", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.TSX),
|
||||||
0x48: CPUInstruction.init(mnemonic: "PHA", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHA),
|
0x48: CPUInstruction(mnemonic: "PHA", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHA),
|
||||||
0x68: CPUInstruction.init(mnemonic: "PLA", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLA),
|
0x68: CPUInstruction(mnemonic: "PLA", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLA),
|
||||||
0x08: CPUInstruction.init(mnemonic: "PHP", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHP),
|
0x08: CPUInstruction(mnemonic: "PHP", cycles: 3, bytes: 1, addressingMode: .implied, action: Opcodes.PHP),
|
||||||
0x28: CPUInstruction.init(mnemonic: "PLP", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLP),
|
0x28: CPUInstruction(mnemonic: "PLP", cycles: 4, bytes: 1, addressingMode: .implied, action: Opcodes.PLP),
|
||||||
|
|
||||||
0xEA: CPUInstruction.init(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP),
|
0xEA: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP),
|
||||||
]
|
]
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct StatusRegister {
|
||||||
var zero: Bool //Z - 0x02
|
var zero: Bool //Z - 0x02
|
||||||
var carry: Bool //C - 0x01
|
var carry: Bool //C - 0x01
|
||||||
|
|
||||||
mutating func setState(state: UInt8) {
|
mutating func fromByte(state: UInt8) {
|
||||||
negative = (state & 0x80 == 0x80)
|
negative = (state & 0x80 == 0x80)
|
||||||
overflow = (state & 0x40 == 0x40)
|
overflow = (state & 0x40 == 0x40)
|
||||||
brk = (state & 0x10 == 0x10)
|
brk = (state & 0x10 == 0x10)
|
||||||
|
@ -113,7 +113,7 @@ class CPUState: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeNextInstruction() throws {
|
func executeNextInstruction() throws {
|
||||||
instruction_register = memoryInterface.memory[Int(program_counter)]
|
instruction_register = memoryInterface.readByte(offset: program_counter)
|
||||||
let operation = InstructionTable[instruction_register]
|
let operation = InstructionTable[instruction_register]
|
||||||
if(operation == nil) {
|
if(operation == nil) {
|
||||||
throw CPUExceptions.invalidInstruction
|
throw CPUExceptions.invalidInstruction
|
||||||
|
@ -127,15 +127,17 @@ class CPUState: NSObject {
|
||||||
self.page_boundary_crossed = false
|
self.page_boundary_crossed = false
|
||||||
}
|
}
|
||||||
|
|
||||||
self.program_counter = UInt16(Int(self.program_counter) + operation!.bytes)
|
if(operation!.mnemonic != "JMP") {
|
||||||
|
self.program_counter = UInt16(Int(self.program_counter) + operation!.bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateNegativeFlag() {
|
func updateNegativeFlag(value: UInt8) {
|
||||||
status_register.negative = (accumulator & 0x80 == 0x80)
|
status_register.negative = (value & 0x80 == 0x80)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateZeroFlag() {
|
func updateZeroFlag(value: UInt8) {
|
||||||
status_register.zero = (accumulator == 0)
|
status_register.zero = (value == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
class MemoryInterface: NSObject {
|
class MemoryInterface: NSObject {
|
||||||
var memory: [UInt8]
|
|
||||||
|
fileprivate var memory: [UInt8]
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
memory = [UInt8](repeating: 0x00, count: 65536)
|
memory = [UInt8](repeating: 0x00, count: 65536)
|
||||||
|
@ -26,4 +27,13 @@ class MemoryInterface: NSObject {
|
||||||
func readWord(offset: UInt16) -> UInt16 {
|
func readWord(offset: UInt16) -> UInt16 {
|
||||||
return UInt16(memory[Int(offset)] | (memory[Int(offset+1)] << 8))
|
return UInt16(memory[Int(offset)] | (memory[Int(offset+1)] << 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadBinary(path: String) {
|
||||||
|
do {
|
||||||
|
let fileContent: NSData = try NSData(contentsOfFile: path)
|
||||||
|
fileContent.getBytes(&memory, range: NSRange(location: 0, length: 65536))
|
||||||
|
} catch {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
|
func stackPointerAsUInt16(state: CPUState) -> UInt16 {
|
||||||
|
return 0x0100 | UInt16(state.stack_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
func getOperand(state: CPUState, mode: AddressingMode) -> UInt8 {
|
func getOperand(state: CPUState, mode: AddressingMode) -> UInt8 {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|
||||||
|
@ -33,22 +37,35 @@ func getOperand(state: CPUState, mode: AddressingMode) -> UInt8 {
|
||||||
let zp: UInt8 = state.memoryInterface.readByte(offset: UInt16(state.getOperandByte() + state.index_x))
|
let zp: UInt8 = state.memoryInterface.readByte(offset: UInt16(state.getOperandByte() + state.index_x))
|
||||||
//read from (ZP)
|
//read from (ZP)
|
||||||
let pointer: UInt16 = state.memoryInterface.readWord(offset: UInt16(zp))
|
let pointer: UInt16 = state.memoryInterface.readWord(offset: UInt16(zp))
|
||||||
state.accumulator = state.memoryInterface.readByte(offset: pointer)
|
return state.memoryInterface.readByte(offset: pointer)
|
||||||
case .indirect_indexed:
|
case .indirect_indexed:
|
||||||
let zp: UInt8 = state.memoryInterface.readByte(offset: UInt16(state.getOperandByte()))
|
let zp: UInt8 = state.memoryInterface.readByte(offset: UInt16(state.getOperandByte()))
|
||||||
let pointer: UInt16 = state.memoryInterface.readWord(offset: UInt16(zp)) + UInt16(state.index_y)
|
let pointer: UInt16 = state.memoryInterface.readWord(offset: UInt16(zp)) + UInt16(state.index_y)
|
||||||
state.accumulator = state.memoryInterface.readByte(offset: pointer)
|
return state.memoryInterface.readByte(offset: pointer)
|
||||||
|
|
||||||
case .indirect:
|
|
||||||
//JMP is the only instruction that does this - handle it specially since it's a UInt16
|
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
print("Called getOperand on an instruction in addressing mode \(mode)")
|
print("Called getOperand: UInt8 on an instruction that expects a UInt16.")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOperand(state: CPUState, mode: AddressingMode) -> UInt16 {
|
||||||
|
//Function that will provide a 16-bit operand to instructions.
|
||||||
|
//All instructions have 2 data bytes, little-endian.
|
||||||
|
|
||||||
|
switch(mode) {
|
||||||
|
case .absolute:
|
||||||
|
return state.getOperandWord()
|
||||||
|
case .absolute_indexed_x:
|
||||||
|
return state.getOperandWord() + state.index_x
|
||||||
|
case .absolute_indexed_y:
|
||||||
|
return state.getOperandWord() + state.index_y
|
||||||
|
case .indirect:
|
||||||
|
return state.memoryInterface.readWord(offset: state.getOperandWord())
|
||||||
|
default:
|
||||||
|
print("Called getOperand: UInt16 on an instruction that expects a UInt8")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0 //never gets here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
@ -58,79 +75,79 @@ class Opcodes: NSObject {
|
||||||
static func LDA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func LDA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.accumulator = getOperand(state: state, mode: addressingMode)
|
state.accumulator = getOperand(state: state, mode: addressingMode)
|
||||||
|
|
||||||
state.updateZeroFlag()
|
state.updateZeroFlag(value: state.accumulator)
|
||||||
state.updateNegativeFlag()
|
state.updateNegativeFlag(value: state.accumulator)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func LDX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func LDX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_x = getOperand(state: state, mode: addressingMode)
|
state.index_x = getOperand(state: state, mode: addressingMode)
|
||||||
|
|
||||||
state.updateZeroFlag()
|
state.updateZeroFlag(value: state.index_x)
|
||||||
state.updateNegativeFlag()
|
state.updateNegativeFlag(value: state.index_x)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func LDY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func LDY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_y = getOperand(state: state, mode: addressingMode)
|
state.index_y = getOperand(state: state, mode: addressingMode)
|
||||||
|
|
||||||
state.updateZeroFlag()
|
state.updateZeroFlag(value: state.index_y)
|
||||||
state.updateNegativeFlag()
|
state.updateNegativeFlag(value: state.index_y)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Register instructions
|
//Register instructions
|
||||||
static func TAX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func TAX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_x = state.accumulator
|
state.index_x = state.accumulator
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.index_x);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.index_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func TXA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func TXA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.accumulator = state.index_x
|
state.accumulator = state.index_x
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.accumulator);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.accumulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func DEX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func DEX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_x = state.index_x &- 1
|
state.index_x = state.index_x &- 1
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.index_x);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.index_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func INX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func INX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_x = state.index_x &+ 1
|
state.index_x = state.index_x &+ 1
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.index_x);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.index_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func TAY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func TAY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_y = state.accumulator
|
state.index_y = state.accumulator
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.index_y);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.index_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func TYA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func TYA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.accumulator = state.index_y
|
state.accumulator = state.index_y
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.accumulator);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.accumulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func DEY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func DEY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_y = state.index_x &- 1
|
state.index_y = state.index_x &- 1
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.index_y);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.index_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func INY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func INY(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_y = state.index_x &+ 1
|
state.index_y = state.index_x &+ 1
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.index_y);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.index_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Processor flag instructions
|
//Processor flag instructions
|
||||||
|
@ -170,31 +187,35 @@ class Opcodes: NSObject {
|
||||||
static func TSX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func TSX(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.index_x = state.stack_pointer
|
state.index_x = state.stack_pointer
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.index_x);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.index_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func PHA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func PHA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.memoryInterface.writeByte(offset: 0x0100 | UInt16(state.stack_pointer), value: state.accumulator)
|
state.memoryInterface.writeByte(offset: stackPointerAsUInt16(state: state), value: state.accumulator)
|
||||||
state.stack_pointer = state.stack_pointer &- 1
|
state.stack_pointer = state.stack_pointer &- 1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func PLA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func PLA(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.stack_pointer = state.stack_pointer &+ 1
|
state.stack_pointer = state.stack_pointer &+ 1
|
||||||
state.accumulator = state.memoryInterface.readByte(offset: 0x0100 | UInt16(state.stack_pointer))
|
state.accumulator = state.memoryInterface.readByte(offset: stackPointerAsUInt16(state: state))
|
||||||
|
|
||||||
state.updateZeroFlag();
|
state.updateZeroFlag(value: state.accumulator);
|
||||||
state.updateNegativeFlag();
|
state.updateNegativeFlag(value: state.accumulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static func PHP(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func PHP(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.memoryInterface.writeByte(offset: 0x0100 | UInt16(state.stack_pointer), value: state.status_register.asByte())
|
state.memoryInterface.writeByte(offset: stackPointerAsUInt16(state: state), value: state.status_register.asByte())
|
||||||
state.stack_pointer = state.stack_pointer &- 1
|
state.stack_pointer = state.stack_pointer &- 1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func PLP(state: CPUState, addressingMode: AddressingMode) -> Void {
|
static func PLP(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
state.stack_pointer = state.stack_pointer &+ 1
|
state.stack_pointer = state.stack_pointer &+ 1
|
||||||
state.status_register.setState(state: state.memoryInterface.readByte(offset: 0x0100 | UInt16(state.stack_pointer)))
|
state.status_register.fromByte(state: state.memoryInterface.readByte(offset: stackPointerAsUInt16(state: state)))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func JMP(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||||
|
state.program_counter = getOperand(state: state, mode: addressingMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func NOP(state: CPUState, addressingMode: AddressingMode) -> Void {}
|
static func NOP(state: CPUState, addressingMode: AddressingMode) -> Void {}
|
||||||
|
|
|
@ -14,12 +14,7 @@ class ViewController: NSViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
CPU.memoryInterface.memory[0] = 0xAD
|
CPU.memoryInterface.loadBinary(path: "/Users/luigi/6502/test.bin")
|
||||||
|
|
||||||
CPU.memoryInterface.memory[1] = 0x34
|
|
||||||
CPU.memoryInterface.memory[2] = 0x12
|
|
||||||
|
|
||||||
CPU.memoryInterface.memory[0x1234] = 0xAA
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try CPU.executeNextInstruction()
|
try CPU.executeNextInstruction()
|
||||||
|
|
Loading…
Reference in New Issue