mirror of
https://github.com/Luigi30/FruitMachine-Swift.git
synced 2025-02-10 13:31:17 +00:00
working on passing the klaus tests - works up to the JSR test
This commit is contained in:
parent
3c04503525
commit
a10296d118
@ -1035,7 +1035,6 @@
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="btn_CPU_restart" destination="ki7-hi-cZ9" id="PD7-dk-eNE"/>
|
||||
<outlet property="debuggerTableView" destination="MuT-J3-VZ6" id="TMx-Do-29u"/>
|
||||
<outlet property="text_CPU_A" destination="WjO-ue-iRg" id="kaI-Bh-Efs"/>
|
||||
<outlet property="text_CPU_Flags" destination="ecN-Ge-1hE" id="dDw-IG-xNd"/>
|
||||
|
@ -24,9 +24,18 @@ extension DebuggerViewController {
|
||||
{
|
||||
debugConsolePrint(str: DebuggerCommands.bpdel(state: cpuInstance, parameters: parameters), newline: true)
|
||||
}
|
||||
else if(commandSplit[0] == "bpadd")
|
||||
else if(commandSplit[0] == "bpset")
|
||||
{
|
||||
debugConsolePrint(str: DebuggerCommands.bpadd(state: cpuInstance, parameters: parameters), newline: true)
|
||||
debugConsolePrint(str: DebuggerCommands.bpset(state: cpuInstance, parameters: parameters), newline: true)
|
||||
}
|
||||
else if(commandSplit[0] == "bpclear")
|
||||
{
|
||||
debugConsolePrint(str: DebuggerCommands.bpclear(state: cpuInstance, parameters: parameters), newline: true)
|
||||
}
|
||||
|
||||
else if(commandSplit[0] == "memread")
|
||||
{
|
||||
debugConsolePrint(str: DebuggerCommands.memread(state: cpuInstance, parameters: parameters), newline: true)
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -46,7 +55,7 @@ class DebuggerCommands: NSObject {
|
||||
return output
|
||||
}
|
||||
|
||||
static func bpadd(state: CPU, parameters: [String]) -> String {
|
||||
static func bpset(state: CPU, parameters: [String]) -> String {
|
||||
var output = ""
|
||||
let val = UInt16(parameters[0])
|
||||
|
||||
@ -78,7 +87,30 @@ class DebuggerCommands: NSObject {
|
||||
}
|
||||
else
|
||||
{
|
||||
output += "Usage: bpdel <breakpoint-number>. Use bplist to find breakpoint numbers."
|
||||
output += "Usage: bpdel <breakpoint-number>\r\n Use bplist to find breakpoint numbers."
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
static func bpclear(state: CPU, parameters: [String]) -> String {
|
||||
var output = ""
|
||||
|
||||
state.breakpoints.removeAll()
|
||||
output += "All breakpoints deleted."
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
static func memread(state: CPU, parameters: [String]) -> String {
|
||||
var output = ""
|
||||
let val = UInt16(parameters[0], radix: 16)
|
||||
|
||||
if(val != nil) {
|
||||
output += "$\(val!.asHexString()) == $\(state.memoryInterface.readByte(offset: val!).asHexString())"
|
||||
}
|
||||
else {
|
||||
output += "Usage: memread <hex-address>"
|
||||
}
|
||||
|
||||
return output
|
||||
|
@ -46,7 +46,7 @@ class DebuggerViewController: NSViewController {
|
||||
text_CPU_SR.stringValue = String(format:"%02X", cpuInstance.stack_pointer)
|
||||
text_CPU_Flags.stringValue = String(cpuInstance.status_register.asString())
|
||||
|
||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 10000)
|
||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 40000)
|
||||
highlightCurrentInstruction()
|
||||
}
|
||||
|
||||
@ -60,10 +60,10 @@ class DebuggerViewController: NSViewController {
|
||||
cpuInstance.performReset()
|
||||
cpuInstance.program_counter = 0x400 //entry point for the test program
|
||||
updateCPUStatusFields()
|
||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 10000)
|
||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 40000)
|
||||
debuggerTableView.reloadData()
|
||||
|
||||
cpuInstance.breakpoints.append(0x0528)
|
||||
cpuInstance.breakpoints.append(0x94B) //failing at 0x36AC - JSR test. some stack problem
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
@ -89,7 +89,7 @@ class DebuggerViewController: NSViewController {
|
||||
isRunning = true
|
||||
|
||||
cpuInstance.cycles = 0
|
||||
cpuInstance.cyclesInBatch = 1000
|
||||
cpuInstance.cyclesInBatch = 50000
|
||||
|
||||
while(!cpuInstance.checkOutOfCycles() && isRunning) {
|
||||
cpuStep()
|
||||
@ -126,7 +126,7 @@ class DebuggerViewController: NSViewController {
|
||||
@IBAction func btn_CPU_Restart(_ sender: Any) {
|
||||
cpuInstance.performReset()
|
||||
cpuInstance.program_counter = 0x400
|
||||
debugConsolePrint(str: "CPU restarted from $0400", newline: true)
|
||||
debugConsolePrint(str: "CPU restarted from \(cpuInstance.program_counter)", newline: true)
|
||||
}
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ extension DebuggerViewController: NSTableViewDelegate {
|
||||
let operation = disassembly[row]
|
||||
|
||||
if(tableColumn == tableView.tableColumns[0]) {
|
||||
cellText = String(format: "%04X", operation.address)
|
||||
cellText = operation.getAddressString()
|
||||
cellIdentifier = CellIdentifiers.AddressCell
|
||||
}
|
||||
|
||||
@ -166,50 +166,13 @@ extension DebuggerViewController: NSTableViewDelegate {
|
||||
if(operation.instruction == nil) {
|
||||
cellText = "ILLEGAL"
|
||||
} else {
|
||||
switch(operation.instruction!.addressingMode) {
|
||||
case .accumulator:
|
||||
cellText = String(format: "%@ A", operation.instruction!.mnemonic)
|
||||
case .immediate:
|
||||
cellText = String(format: "%@ #$%02X", operation.instruction!.mnemonic, operation.data[1])
|
||||
case .implied:
|
||||
cellText = String(format: "%@", operation.instruction!.mnemonic)
|
||||
case .relative:
|
||||
var destination: UInt16 = operation.address
|
||||
if((operation.data[1] & 0x80) == 0x80) {
|
||||
destination = destination + 1 - UInt16(~operation.data[1])
|
||||
} else {
|
||||
destination = destination + 2 + UInt16(operation.data[1])
|
||||
}
|
||||
cellText = String(format: "%@ #$%04X", operation.instruction!.mnemonic, destination)
|
||||
case .absolute:
|
||||
cellText = String(format: "%@ $%02X%02X", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
|
||||
case .zeropage:
|
||||
cellText = String(format: "%@ $%02X", operation.instruction!.mnemonic, operation.data[1])
|
||||
case .indirect:
|
||||
cellText = String(format: "%@ ($%02X%02X)", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
|
||||
case .absolute_indexed_x:
|
||||
cellText = String(format: "%@ $%02X%02X,X", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
|
||||
case .absolute_indexed_y:
|
||||
cellText = String(format: "%@ $%02X%02X,Y", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
|
||||
case .zeropage_indexed_x:
|
||||
cellText = String(format: "%@ $%02X,X", operation.instruction!.mnemonic, operation.data[1])
|
||||
case .zeropage_indexed_y:
|
||||
cellText = String(format: "%@ $%02X,Y", operation.instruction!.mnemonic, operation.data[1])
|
||||
case .indexed_indirect:
|
||||
cellText = String(format: "%@ ($%02X,X)", operation.instruction!.mnemonic, operation.data[1])
|
||||
case .indirect_indexed:
|
||||
cellText = String(format: "%@ ($%02X),Y", operation.instruction!.mnemonic, operation.data[1])
|
||||
}
|
||||
cellText = operation.getInstructionString()
|
||||
}
|
||||
cellIdentifier = CellIdentifiers.DataCell
|
||||
}
|
||||
|
||||
if(tableColumn == tableView.tableColumns[2]) {
|
||||
cellText = ""
|
||||
for byte in operation.data {
|
||||
cellText += String(format: "%02X ", byte)
|
||||
}
|
||||
|
||||
cellText = operation.getDataString()
|
||||
cellIdentifier = CellIdentifiers.BytesCell
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ struct StatusRegister {
|
||||
str += "-"
|
||||
}
|
||||
|
||||
str += "-" //0x20 is unassigned
|
||||
str += "|" //0x20 is unassigned
|
||||
|
||||
if(brk) {
|
||||
str += "B"
|
||||
@ -63,6 +63,12 @@ struct StatusRegister {
|
||||
str += "-"
|
||||
}
|
||||
|
||||
if(carry) {
|
||||
str += "C"
|
||||
} else {
|
||||
str += "-"
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
@ -206,7 +212,7 @@ class CPU: NSObject {
|
||||
self.branch_was_taken = false
|
||||
}
|
||||
|
||||
if(operation!.mnemonic != "JMP") {
|
||||
if(operation!.mnemonic != "JMP" && operation!.mnemonic != "JSR") {
|
||||
self.program_counter = UInt16(Int(self.program_counter) + operation!.bytes)
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,55 @@ class Disassembly: NSObject {
|
||||
self.address = address
|
||||
self.data = data
|
||||
}
|
||||
|
||||
func getAddressString() -> String {
|
||||
return String(format: "%04X", address)
|
||||
}
|
||||
|
||||
func getInstructionString() -> String {
|
||||
switch(instruction!.addressingMode) {
|
||||
case .accumulator:
|
||||
return String(format: "%@ A", instruction!.mnemonic)
|
||||
case .immediate:
|
||||
return String(format: "%@ #$%02X", instruction!.mnemonic, data[1])
|
||||
case .implied:
|
||||
return String(format: "%@", instruction!.mnemonic)
|
||||
case .relative:
|
||||
var destination: UInt16 = address
|
||||
if((data[1] & 0x80) == 0x80) {
|
||||
destination = destination + 1 - UInt16(~data[1])
|
||||
} else {
|
||||
destination = destination + 2 + UInt16(data[1])
|
||||
}
|
||||
return String(format: "%@ #$%04X", instruction!.mnemonic, destination)
|
||||
case .absolute:
|
||||
return String(format: "%@ $%02X%02X", instruction!.mnemonic, data[2], data[1])
|
||||
case .zeropage:
|
||||
return String(format: "%@ $%02X", instruction!.mnemonic, data[1])
|
||||
case .indirect:
|
||||
return String(format: "%@ ($%02X%02X)", instruction!.mnemonic, data[2], data[1])
|
||||
case .absolute_indexed_x:
|
||||
return String(format: "%@ $%02X%02X,X", instruction!.mnemonic, data[2], data[1])
|
||||
case .absolute_indexed_y:
|
||||
return String(format: "%@ $%02X%02X,Y", instruction!.mnemonic, data[2], data[1])
|
||||
case .zeropage_indexed_x:
|
||||
return String(format: "%@ $%02X,X", instruction!.mnemonic, data[1])
|
||||
case .zeropage_indexed_y:
|
||||
return String(format: "%@ $%02X,Y", instruction!.mnemonic, data[1])
|
||||
case .indexed_indirect:
|
||||
return String(format: "%@ ($%02X,X)", instruction!.mnemonic, data[1])
|
||||
case .indirect_indexed:
|
||||
return String(format: "%@ ($%02X),Y", instruction!.mnemonic, data[1])
|
||||
}
|
||||
}
|
||||
|
||||
func getDataString() -> String {
|
||||
var dataStr = ""
|
||||
for byte in data {
|
||||
dataStr += String(format: "%02X ", byte)
|
||||
}
|
||||
return dataStr
|
||||
}
|
||||
}
|
||||
|
||||
extension CPU {
|
||||
|
@ -17,3 +17,9 @@ extension UInt16 {
|
||||
return String(format: "%04X", self)
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt8 {
|
||||
func asHexString() -> String {
|
||||
return String(format: "%02X", self)
|
||||
}
|
||||
}
|
||||
|
@ -369,27 +369,30 @@ class Opcodes: NSObject {
|
||||
|
||||
//CMP
|
||||
static func CMP(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
let data = state.accumulator - state.getOperandByte() //CMP is a subtract that doesn't affect memory
|
||||
let mem = getOperandByteForAddressingMode(state: state, mode: addressingMode)
|
||||
let t = state.accumulator &- mem //CMP is a subtract that doesn't affect memory
|
||||
|
||||
state.updateZeroFlag(value: data)
|
||||
state.updateNegativeFlag(value: data)
|
||||
state.status_register.carry = (data >= 0)
|
||||
state.status_register.zero = (t == 0) ? true : false
|
||||
state.status_register.negative = (t & 0x80) == 0x80 ? true : false
|
||||
state.status_register.carry = (state.accumulator >= mem)
|
||||
}
|
||||
|
||||
static func CPX(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
let data = state.index_x - state.getOperandByte() //CMP is a subtract that doesn't affect memory
|
||||
let mem = getOperandByteForAddressingMode(state: state, mode: addressingMode)
|
||||
let t = state.index_x &- mem //CMP is a subtract that doesn't affect memory
|
||||
|
||||
state.updateZeroFlag(value: data)
|
||||
state.updateNegativeFlag(value: data)
|
||||
state.status_register.carry = (data >= 0)
|
||||
state.status_register.zero = (t == 0) ? true : false
|
||||
state.status_register.negative = (t & 0x80) == 0x80 ? true : false
|
||||
state.status_register.carry = (state.index_x >= mem)
|
||||
}
|
||||
|
||||
static func CPY(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
let data = state.index_y - state.getOperandByte() //CMP is a subtract that doesn't affect memory
|
||||
let mem = getOperandByteForAddressingMode(state: state, mode: addressingMode)
|
||||
let t = state.index_y &- mem //CMP is a subtract that doesn't affect memory
|
||||
|
||||
state.updateZeroFlag(value: data)
|
||||
state.updateNegativeFlag(value: data)
|
||||
state.status_register.carry = (data >= 0)
|
||||
state.status_register.zero = (t == 0) ? true : false
|
||||
state.status_register.negative = (t & 0x80) == 0x80 ? true : false
|
||||
state.status_register.carry = (state.index_y >= mem)
|
||||
}
|
||||
|
||||
//Boolean operators
|
||||
@ -556,8 +559,7 @@ class Opcodes: NSObject {
|
||||
}
|
||||
|
||||
static func PHA(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
state.memoryInterface.writeByte(offset: state.stackPointerAsUInt16(), value: state.accumulator)
|
||||
state.stack_pointer = state.stack_pointer &- 1
|
||||
state.pushByte(data: state.accumulator)
|
||||
}
|
||||
|
||||
static func PLA(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
@ -569,13 +571,17 @@ class Opcodes: NSObject {
|
||||
}
|
||||
|
||||
static func PHP(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
state.memoryInterface.writeByte(offset: state.stackPointerAsUInt16(), value: state.status_register.asByte())
|
||||
var sr = state.status_register
|
||||
sr.brk = true //PHP pushes B as true
|
||||
|
||||
state.memoryInterface.writeByte(offset: state.stackPointerAsUInt16(), value: sr.asByte())
|
||||
state.stack_pointer = state.stack_pointer &- 1
|
||||
}
|
||||
|
||||
static func PLP(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
state.stack_pointer = state.stack_pointer &+ 1
|
||||
state.status_register.fromByte(state: state.memoryInterface.readByte(offset: state.stackPointerAsUInt16()))
|
||||
state.status_register.brk = false //PLP sets B to 0
|
||||
}
|
||||
|
||||
static func BPL(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
@ -643,12 +649,14 @@ class Opcodes: NSObject {
|
||||
static func RTI(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
state.status_register.fromByte(state: state.popByte())
|
||||
state.program_counter = state.popWord()
|
||||
state.status_register.brk = false //RTI sets B to 0
|
||||
}
|
||||
|
||||
static func BRK(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
state.status_register.brk = true
|
||||
var sr = state.status_register
|
||||
sr.brk = true //BRK pushes B as true
|
||||
state.pushWord(data: state.program_counter)
|
||||
state.pushByte(data: state.status_register.asByte())
|
||||
state.pushByte(data: sr.asByte())
|
||||
state.program_counter = state.memoryInterface.readWord(offset: 0xFFFE)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user