working on passing the klaus tests - works up to the JSR test

This commit is contained in:
Luigi Thirty 2017-07-25 03:56:31 -04:00
parent 3c04503525
commit a10296d118
7 changed files with 132 additions and 69 deletions

View File

@ -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"/>

View File

@ -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

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -17,3 +17,9 @@ extension UInt16 {
return String(format: "%04X", self)
}
}
extension UInt8 {
func asHexString() -> String {
return String(format: "%02X", self)
}
}

View File

@ -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)
}