mirror of
https://github.com/Luigi30/FruitMachine-Swift.git
synced 2024-11-23 17:33:47 +00:00
more instructions, just need ADC/SBC and the shift instructions now
This commit is contained in:
parent
da828a5d36
commit
eb9f02758b
@ -155,7 +155,20 @@ let InstructionTable: [UInt8:CPUInstruction] = [
|
||||
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),
|
||||
|
||||
//Branch instructions
|
||||
0x10: CPUInstruction(mnemonic: "BPL", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BPL),
|
||||
0x30: CPUInstruction(mnemonic: "BMI", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BMI),
|
||||
0x50: CPUInstruction(mnemonic: "BVC", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BVC),
|
||||
0x70: CPUInstruction(mnemonic: "BVS", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BVS),
|
||||
0x90: CPUInstruction(mnemonic: "BCC", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BCC),
|
||||
0xB0: CPUInstruction(mnemonic: "BCS", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BCS),
|
||||
0xD0: CPUInstruction(mnemonic: "BNE", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BNE),
|
||||
0xF0: CPUInstruction(mnemonic: "BEQ", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BEQ),
|
||||
|
||||
0x20: CPUInstruction(mnemonic: "JSR", cycles: 6, bytes: 3, addressingMode: .absolute, action: Opcodes.JSR),
|
||||
0x60: CPUInstruction(mnemonic: "RTS", cycles: 6, bytes: 1, addressingMode: .implied, action: Opcodes.RTS),
|
||||
|
||||
0x00: CPUInstruction(mnemonic: "BRK", cycles: 7, bytes: 1, addressingMode: .implied, action: Opcodes.BRK),
|
||||
|
||||
0xEA: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP),
|
||||
]
|
||||
|
@ -123,6 +123,8 @@ class CPUState: NSObject {
|
||||
|
||||
var memoryInterface: MemoryInterface
|
||||
|
||||
var branch_was_taken: Bool
|
||||
|
||||
override init() {
|
||||
cycles = 0
|
||||
|
||||
@ -136,7 +138,11 @@ class CPUState: NSObject {
|
||||
status_register = StatusRegister(negative: false, overflow: false, brk: false, decimal: false, irq_disable: false, zero: false, carry: false)
|
||||
memoryInterface = MemoryInterface()
|
||||
|
||||
//Some instructions incur a 1-cycle penalty if crossing a page boundary.
|
||||
page_boundary_crossed = false
|
||||
//Branches incur a 1-cycle penalty if taken plus the page boundary penalty if necessary.
|
||||
branch_was_taken = false
|
||||
|
||||
}
|
||||
|
||||
func disassemble(fromAddress: UInt16, length: UInt16) -> [Disassembly] {
|
||||
@ -212,6 +218,10 @@ class CPUState: NSObject {
|
||||
self.cycles += 1
|
||||
self.page_boundary_crossed = false
|
||||
}
|
||||
if(self.branch_was_taken) {
|
||||
self.cycles += 1
|
||||
self.branch_was_taken = false
|
||||
}
|
||||
|
||||
if(operation!.mnemonic != "JMP") {
|
||||
self.program_counter = UInt16(Int(self.program_counter) + operation!.bytes)
|
||||
|
@ -10,6 +10,18 @@ import Cocoa
|
||||
|
||||
extension CPUState {
|
||||
|
||||
func popByte() -> UInt8 {
|
||||
stack_pointer = stack_pointer &+ 1
|
||||
return memoryInterface.readByte(offset: stackPointerAsUInt16())
|
||||
}
|
||||
|
||||
func popWord() -> UInt16 {
|
||||
let low = popByte()
|
||||
let high = popByte()
|
||||
|
||||
return (UInt16(high) << 8) | UInt16(low)
|
||||
}
|
||||
|
||||
func pushByte(data: UInt8) -> Void {
|
||||
memoryInterface.writeByte(offset: stackPointerAsUInt16(), value: data)
|
||||
stack_pointer = stack_pointer &- 1
|
||||
@ -27,6 +39,15 @@ extension CPUState {
|
||||
return 0x0100 | UInt16(stack_pointer);
|
||||
}
|
||||
|
||||
func doBranch() {
|
||||
let distance = getOperandByte()
|
||||
|
||||
if(((program_counter & 0x00FF) + distance) > 0x0100) {
|
||||
page_boundary_crossed = true
|
||||
}
|
||||
program_counter = program_counter + distance
|
||||
branch_was_taken = true
|
||||
}
|
||||
}
|
||||
|
||||
func getOperandByteForAddressingMode(state: CPUState, mode: AddressingMode) -> UInt8 {
|
||||
@ -391,16 +412,74 @@ class Opcodes: NSObject {
|
||||
state.status_register.fromByte(state: state.memoryInterface.readByte(offset: state.stackPointerAsUInt16()))
|
||||
}
|
||||
|
||||
static func BPL(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(!state.status_register.negative) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
static func BMI(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(state.status_register.negative) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
static func BVC(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(!state.status_register.overflow) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
static func BVS(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(state.status_register.overflow) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
static func BCC(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(!state.status_register.carry) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
static func BCS(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(state.status_register.carry) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
static func BNE(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(!state.status_register.zero) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
static func BEQ(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
if(state.status_register.zero) {
|
||||
state.doBranch()
|
||||
}
|
||||
}
|
||||
|
||||
//Misc
|
||||
static func JMP(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
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.pushWord(data: state.program_counter - 1)
|
||||
state.program_counter = state.getOperandWord()
|
||||
}
|
||||
|
||||
static func RTS(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
state.program_counter = state.popWord() + 1
|
||||
}
|
||||
|
||||
static func BRK(state: CPUState, addressingMode: AddressingMode) -> Void {
|
||||
state.status_register.brk = true
|
||||
state.pushWord(data: state.program_counter)
|
||||
state.pushByte(data: state.status_register.asByte())
|
||||
state.program_counter = state.memoryInterface.readWord(offset: 0xFFFE)
|
||||
}
|
||||
|
||||
static func NOP(state: CPUState, addressingMode: AddressingMode) -> Void {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user