From 181b98b95ced26bf748bfe0a7681af4075c770bd Mon Sep 17 00:00:00 2001 From: Luigi Thirty Date: Thu, 10 Aug 2017 00:05:14 -0400 Subject: [PATCH] fixed language card memory reads not being redirected to LC RAM, prodos 2.4 now gets to the directory listing before crashing --- FruitMachine.xcodeproj/project.pbxproj | 4 + FruitMachine/AppleII/AppleIIBase.swift | 12 +- .../AppleII/Peripherals/DiskII/DiskII.swift | 2 +- .../Peripherals/DiskII/DiskImage.swift | 32 ++- .../AppleII/Peripherals/LanguageCard16K.swift | 194 +++++++++++++++++- FruitMachine/Common/Memory/Types.swift | 11 + FruitMachine/FruitMachine.storyboard | 4 +- FruitMachine/M6502/CPU.swift | 38 +++- .../Debugger/Base.lproj/Debugger.storyboard | 16 +- .../Debugger/DebuggerViewController.swift | 3 +- FruitMachine/M6502/Debugger/Disassembly.swift | 4 +- .../M6502/Memory/MemoryInterface.swift | 4 +- .../M6502/Opcodes/CPUInstructions.swift | 5 + FruitMachine/M6502/Opcodes/Opcodes.swift | 17 ++ FruitMachine/PreferencesWindow.xib | 6 +- 15 files changed, 297 insertions(+), 55 deletions(-) create mode 100644 FruitMachine/Common/Memory/Types.swift diff --git a/FruitMachine.xcodeproj/project.pbxproj b/FruitMachine.xcodeproj/project.pbxproj index 4bd83a4..4662b08 100644 --- a/FruitMachine.xcodeproj/project.pbxproj +++ b/FruitMachine.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 2A044E2C1F37D65A000E8085 /* LanguageCard16K.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */; }; 2A044E2E1F382CA9000E8085 /* AppleIIPlus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */; }; + 2A0D0C691F3C09990000913B /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A0D0C681F3C09990000913B /* Types.swift */; }; 2A16ADBB1F33C341004A0333 /* DiskImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A16ADBA1F33C341004A0333 /* DiskImage.swift */; }; 2A2126841F2A9FA300E43DC1 /* DebuggerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */; }; 2A22EBFB1F21A7A700A36A61 /* IntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */; }; @@ -60,6 +61,7 @@ /* Begin PBXFileReference section */ 2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageCard16K.swift; sourceTree = ""; }; 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleIIPlus.swift; sourceTree = ""; }; + 2A0D0C681F3C09990000913B /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = ""; }; 2A16ADBA1F33C341004A0333 /* DiskImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskImage.swift; sourceTree = ""; }; 2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerWindowController.swift; sourceTree = ""; }; 2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegerExtensions.swift; sourceTree = ""; }; @@ -278,6 +280,7 @@ isa = PBXGroup; children = ( 2AE3BB961F32CEB100C11060 /* ROMManager.swift */, + 2A0D0C681F3C09990000913B /* Types.swift */, ); path = Memory; sourceTree = ""; @@ -435,6 +438,7 @@ 2AB6CACD1F3041A200DECAC0 /* AppleII.swift in Sources */, 2A63C2331F32C39300D4F4F8 /* TextMode.swift in Sources */, 2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */, + 2A0D0C691F3C09990000913B /* Types.swift in Sources */, 2AE42E0A1F28521E00C4900E /* WriteOverride.swift in Sources */, 2A6DC7ED1F30492C0066FE0D /* ScreenDelegate.swift in Sources */, 2A044E2C1F37D65A000E8085 /* LanguageCard16K.swift in Sources */, diff --git a/FruitMachine/AppleII/AppleIIBase.swift b/FruitMachine/AppleII/AppleIIBase.swift index c3ca3db..42ee388 100644 --- a/FruitMachine/AppleII/AppleIIBase.swift +++ b/FruitMachine/AppleII/AppleIIBase.swift @@ -91,19 +91,17 @@ class AppleIIBase: NSObject, EmulatedSystem { CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.null //not connected } for page in 208 ..< 256 { - CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.ro //ROM + CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.rw //Bankswitching area } } func setupPeripherals() { let defaults = UserDefaults.standard - /* let slot0 = defaults.string(forKey: "a2_Peripherals_Slot0") if(slot0 == "Language Card (16K)") { backplane[0] = LanguageCard16K(slot: 0, romPath: "/Users/luigi/apple2/341-0020-00.f8") } - */ let slot6 = defaults.string(forKey: "a2_Peripherals_Slot6") if(slot6 == "Disk II") { @@ -133,8 +131,11 @@ class AppleIIBase: NSObject, EmulatedSystem { CPU.sharedInstance.cycles = 0 CPU.sharedInstance.cyclesInBatch = CYCLES_PER_BATCH CPU.sharedInstance.runCyclesBatch() - - //update the video display + + updateScreen() + } + + func updateScreen() { CVPixelBufferLockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0)) let pixelBase = CVPixelBufferGetBaseAddress(emulatorViewDelegate.pixels!) let buf = pixelBase?.assumingMemoryBound(to: BitmapPixelsLE555.PixelData.self) @@ -171,6 +172,7 @@ class AppleIIBase: NSObject, EmulatedSystem { CVPixelBufferUnlockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0)) emulatorView.setNeedsDisplay(emulatorView.frame) + } /* Video */ diff --git a/FruitMachine/AppleII/Peripherals/DiskII/DiskII.swift b/FruitMachine/AppleII/Peripherals/DiskII/DiskII.swift index 7856088..ad12fe1 100644 --- a/FruitMachine/AppleII/Peripherals/DiskII/DiskII.swift +++ b/FruitMachine/AppleII/Peripherals/DiskII/DiskII.swift @@ -35,7 +35,7 @@ import Cocoa */ class DiskII: NSObject, Peripheral, HasROM { - let debug = true + let debug = false enum MotorPhase { case Phase0 diff --git a/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift b/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift index d407b7f..4c0892a 100644 --- a/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift +++ b/FruitMachine/AppleII/Peripherals/DiskII/DiskImage.swift @@ -77,28 +77,28 @@ class ProdosImage: DiskImageFormat { switch blockOffset8 { case 0: sector1 = 0 - sector2 = 0xE + sector2 = 0x1 case 1: - sector1 = 0xD - sector2 = 0xC + sector1 = 0x2 + sector2 = 0x3 case 2: - sector1 = 0xB - sector2 = 0xA + sector1 = 0x4 + sector2 = 0x5 case 3: - sector1 = 0x9 - sector2 = 0x8 + sector1 = 0x6 + sector2 = 0x7 case 4: - sector1 = 0x7 - sector2 = 0x6 + sector1 = 0x8 + sector2 = 0x9 case 5: - sector1 = 0x5 - sector2 = 0x4 + sector1 = 0xA + sector2 = 0xB case 6: - sector1 = 0x3 - sector2 = 0x2 + sector1 = 0xC + sector2 = 0xD case 7: - sector1 = 0x1 + sector1 = 0xE sector2 = 0xF default: print("should never happen") @@ -161,7 +161,7 @@ class DiskImage: NSObject { nbls.append(contentsOf: track) } - blks.append(contentsOf: ProdosImage.readBlock(imageData: rawData!, blockNum: 7)) + blks.append(contentsOf: ProdosImage.readBlock(imageData: rawData!, blockNum: 0)) var ptr = UnsafeBufferPointer(start: blks, count: blks.count) var data = Data(buffer: ptr) @@ -259,8 +259,6 @@ class DiskImage: NSObject { encodedData.append(contentsOf: EncodeSectorSixAndTwo(sector: Dos33Image.readTrackAndSector(imageData: imageData, trackNum: index, sectorNum: sectorNum))) } else if(image is ProdosImage){ - /* TODO: A .PO image is stored by 512-blocks which are not contiguous on the disk. Need to adapt this to handle blocks. */ - /* Find the 256 bytes corresponding to this sector. */ switch(sectorNum) { diff --git a/FruitMachine/AppleII/Peripherals/LanguageCard16K.swift b/FruitMachine/AppleII/Peripherals/LanguageCard16K.swift index 700bfe8..1cd8ad1 100644 --- a/FruitMachine/AppleII/Peripherals/LanguageCard16K.swift +++ b/FruitMachine/AppleII/Peripherals/LanguageCard16K.swift @@ -12,12 +12,29 @@ class LanguageCard16K: NSObject, Peripheral, HasROM { var slotNumber: Int var romManager: ROMManager + /* Off: $D000-$DFFF -> RAM bank 2. On: $D000-$DFFF -> RAM bank 1 */ + var LCBNK: Bool = false + + /* Off: Reads of $D000-$FFFF -> ROM. On: Reads of $D000-$FFFF -> RAM */ + var LCRAM: Bool = false + + /* Off: Writes of $D000-$FFFF do nothing. On: Writes of $D000-$FFFF -> RAM */ + var LCWRITE: Bool = false + + var lastReadSwitch: UInt8 = 0x00 + //16KB of RAM on the Language Card. var ram = [UInt8](repeating: 0xCC, count: 16384) var readIOOverride: ReadOverride? = nil var writeIOOverride: WriteOverride? = nil + var RDLCBNKOverride: ReadOverride? = nil + var RDLCRAMOverride: ReadOverride? = nil + + var readLanguageCardAddressingOverride: ReadOverride? = nil + var writeLanguageCardAddressingOverride: WriteOverride? = nil + func installOverrides() { func installOverrides() { CPU.sharedInstance.memoryInterface.read_overrides.append(readIOOverride!) @@ -31,15 +48,92 @@ class LanguageCard16K: NSObject, Peripheral, HasROM { super.init() + RDLCBNKOverride = ReadOverride(start: UInt16(0xC011 + (0x10 * slotNumber)), + end: UInt16(0xC012 + (0x10 * slotNumber)), + readAnyway: false, + action: actionRDLCBNK) + + RDLCRAMOverride = ReadOverride(start: UInt16(0xC011 + (0x10 * slotNumber)), + end: UInt16(0xC012 + (0x10 * slotNumber)), + readAnyway: false, + action: actionRDLCRAM) + readIOOverride = ReadOverride(start: UInt16(0xC080 + (0x10 * slotNumber)), end: UInt16(0xC08F + (0x10 * slotNumber)), readAnyway: false, action: actionDispatchOperation) - writeIOOverride = WriteOverride(start: UInt16(0xC080 + (0x10 * slotNumber)), - end: UInt16(0xC08F + (0x10 * slotNumber)), - writeAnyway: false, - action: actionDispatchOperation) + readLanguageCardAddressingOverride = ReadOverride(start: UInt16(0xD000), + end: UInt16(0xFFFF), + readAnyway: false, + action: actionReadLanguageCard) + + writeLanguageCardAddressingOverride = WriteOverride(start: UInt16(0xD000), + end: UInt16(0xFFFF), + writeAnyway: false, + action: actionWriteLanguageCard) + + CPU.sharedInstance.memoryInterface.read_overrides.append(RDLCBNKOverride!) + CPU.sharedInstance.memoryInterface.read_overrides.append(RDLCRAMOverride!) + CPU.sharedInstance.memoryInterface.read_overrides.append(readIOOverride!) + CPU.sharedInstance.memoryInterface.read_overrides.append(readLanguageCardAddressingOverride!) + CPU.sharedInstance.memoryInterface.write_overrides.append(writeLanguageCardAddressingOverride!) + } + + private func actionRDLCBNK(something: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? + { + return (LCBNK ? 0x80 : 0x00) + } + + private func actionRDLCRAM(something: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? + { + return (LCRAM ? 0x80 : 0x00) + } + + private func actionReadLanguageCard(something: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? + { + /* Redirect reads according to the language card switches. */ + if(address >= 0xE000) { + if(LCRAM) { + /* Map to language card RAM. */ + return ram[Int(address - UInt16(0xC000))] + } else { + /* Map $E000-$FFFF to ROM. */ + return CPU.sharedInstance.memoryInterface.readByte(offset: address, bypassOverrides: true) + } + } + else { + if(LCRAM && LCBNK) { + /* Bank 1 */ + return ram[Int(address - UInt16(0xD000))] + } else if(LCRAM && !LCBNK) { + /* Bank 2 */ + return ram[Int(address - UInt16(0xC000))] + } else { + return CPU.sharedInstance.memoryInterface.readByte(offset: address, bypassOverrides: true) + } + } + } + + private func actionWriteLanguageCard(something: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? + { + if(LCWRITE) { + if(address <= 0xDFFF) { + if(LCBNK) { + /* Bank 1 */ + ram[Int(address - UInt16(0xD000))] = byte! + } + else { + /* Bank 2 */ + ram[Int(address - UInt16(0xC000))] = byte! + } + } else { + /* High 8K is written. */ + ram[Int(address - UInt16(0xC000))] = byte! + } + } + + return nil } private func actionDispatchOperation(something: AnyObject, address: UInt16, byte: UInt8?) -> UInt8? @@ -49,12 +143,98 @@ class LanguageCard16K: NSObject, Peripheral, HasROM { if(byte == nil) { isRead = true } + + switch operationNumber { + case 0: + LCRAM = true + LCBNK = false + LCWRITE = false + case 1: + LCRAM = false + LCBNK = false + if(lastReadSwitch == 0x01) { + LCWRITE = true + } + case 2: + LCRAM = false + LCBNK = false + LCWRITE = false + case 3: + LCRAM = true + LCBNK = false + if(lastReadSwitch == 0x03) { + LCWRITE = true + } + case 4: + LCRAM = true + LCBNK = false + LCWRITE = false + case 5: + LCRAM = false + LCBNK = true + if(lastReadSwitch == 0x05) { + LCWRITE = true + } + case 6: + LCRAM = false + LCBNK = false + LCWRITE = false + case 7: + LCRAM = true + LCBNK = false + if(lastReadSwitch == 0x07) { + LCWRITE = true + } + case 8: + LCRAM = true + LCBNK = true + LCWRITE = false + case 9: + LCRAM = false + LCBNK = true + if(lastReadSwitch == 0x09) { + LCWRITE = true + } + case 0xA: + LCRAM = false + LCBNK = true + LCWRITE = false + case 0xB: + LCRAM = true + LCBNK = true + if(lastReadSwitch == 0x0B) { + LCWRITE = true + } + case 0xC: + LCRAM = true + LCBNK = true + LCWRITE = false + case 0xD: + LCRAM = false + LCBNK = true + if(lastReadSwitch == 0x0D) { + LCWRITE = true + } + case 0xE: + LCRAM = false + LCBNK = true + LCWRITE = false + case 0xF: + LCRAM = true + LCBNK = true + if(lastReadSwitch == 0x0F) { + LCWRITE = true + } + default: + print("shouldn't happen") + } - print("Language Card command: \(isRead == false ? "Read" : "Write") $\(operationNumber.asHexString())") + lastReadSwitch = operationNumber + + //print("Language Card command: \(isRead == false ? "Read" : "Write") $\(operationNumber.asHexString()). LCRAM \(LCRAM) LCBNK \(LCBNK) LCWRITE \(LCWRITE)") + print("LC: offset \(operationNumber.asHexString()) | new state \(LCRAM ? "R" : "x")\(LCWRITE ? "W" : "x") dxxx=\(LCBNK ? "0000" : "1000")") return 0x00 } - - } diff --git a/FruitMachine/Common/Memory/Types.swift b/FruitMachine/Common/Memory/Types.swift new file mode 100644 index 0000000..30cb30b --- /dev/null +++ b/FruitMachine/Common/Memory/Types.swift @@ -0,0 +1,11 @@ +// +// Types.swift +// FruitMachine +// +// Created by Christopher Rohl on 8/9/17. +// Copyright © 2017 Christopher Rohl. All rights reserved. +// + +import Cocoa + +typealias Address = UInt16 diff --git a/FruitMachine/FruitMachine.storyboard b/FruitMachine/FruitMachine.storyboard index af9d6c0..2f53cee 100644 --- a/FruitMachine/FruitMachine.storyboard +++ b/FruitMachine/FruitMachine.storyboard @@ -1,8 +1,8 @@ - + - + diff --git a/FruitMachine/M6502/CPU.swift b/FruitMachine/M6502/CPU.swift index 600cbb9..ab1abcd 100644 --- a/FruitMachine/M6502/CPU.swift +++ b/FruitMachine/M6502/CPU.swift @@ -12,6 +12,11 @@ enum CPUExceptions : Error { case invalidInstruction } +enum CPUModel { + case M6502 + case M65C02 +} + struct StatusRegister { var negative: Bool //N - 0x80 var overflow: Bool //V - 0x40 @@ -132,7 +137,7 @@ final class CPU: NSObject { let RESET_VECTOR: UInt16 = 0xFFFC let IRQ_VECTOR: UInt16 = 0xFFFE - static let sharedInstance = CPU() + static let sharedInstance = CPU(cpuModel: .M6502) var isRunning: Bool @@ -148,6 +153,9 @@ final class CPU: NSObject { var program_counter: UInt16 var status_register: StatusRegister + //Debugging + var old_program_counter: UInt16 + var page_boundary_crossed: Bool var branch_was_taken: Bool @@ -155,9 +163,13 @@ final class CPU: NSObject { var breakpoints: [UInt16] - override init() { + var model: CPUModel + + init(cpuModel: CPUModel) { isRunning = false + model = cpuModel + cycles = 0 cyclesInBatch = 0 @@ -168,6 +180,7 @@ final class CPU: NSObject { index_y = 0 stack_pointer = 0 program_counter = 0 + old_program_counter = 0 status_register = StatusRegister(negative: false, overflow: false, brk: false, decimal: false, irq_disable: false, zero: false, carry: false) memoryInterface = MemoryInterface() @@ -176,7 +189,7 @@ final class CPU: NSObject { //Branches incur a 1-cycle penalty if taken plus the page boundary penalty if necessary. branch_was_taken = false - breakpoints = [UInt16]() + breakpoints = [UInt16]() } func coldReset() { @@ -201,15 +214,20 @@ final class CPU: NSObject { } } + func changeModel(cpuModel: CPUModel) { + model = cpuModel + coldReset() + } + func getOperandByte() -> UInt8 { //Returns the operand byte after the current instruction byte. - return memoryInterface.readByte(offset: program_counter + 1) + return memoryInterface.readByte(offset: program_counter &+ 1) } func getOperandWord() -> UInt16 { var word: UInt16 - let low = memoryInterface.readByte(offset: program_counter + 1) - let high = memoryInterface.readByte(offset: program_counter + 2) + let low = memoryInterface.readByte(offset: program_counter &+ 1) + let high = memoryInterface.readByte(offset: program_counter &+ 2) word = UInt16(high) word = word << 8 @@ -241,6 +259,11 @@ final class CPU: NSObject { throw CPUExceptions.invalidInstruction } + if(program_counter == 0x102F) { + print("$102F") + } + + self.old_program_counter = self.program_counter operation!.action(CPU.sharedInstance, operation!.addressingMode) self.cycles += operation!.cycles @@ -253,7 +276,8 @@ final class CPU: NSObject { self.branch_was_taken = false } - self.program_counter = UInt16(self.program_counter &+ UInt16(operation!.bytes)) + + self.program_counter = Address(self.program_counter &+ UInt16(operation!.bytes)) } func outOfCycles() -> Bool { diff --git a/FruitMachine/M6502/Debugger/Base.lproj/Debugger.storyboard b/FruitMachine/M6502/Debugger/Base.lproj/Debugger.storyboard index 759613a..442362c 100644 --- a/FruitMachine/M6502/Debugger/Base.lproj/Debugger.storyboard +++ b/FruitMachine/M6502/Debugger/Base.lproj/Debugger.storyboard @@ -1,8 +1,8 @@ - + - + @@ -47,7 +47,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -119,7 +119,7 @@ - + @@ -137,7 +137,7 @@ - + diff --git a/FruitMachine/M6502/Debugger/DebuggerViewController.swift b/FruitMachine/M6502/Debugger/DebuggerViewController.swift index 387f7c7..d6c3206 100644 --- a/FruitMachine/M6502/Debugger/DebuggerViewController.swift +++ b/FruitMachine/M6502/Debugger/DebuggerViewController.swift @@ -78,7 +78,7 @@ class DebuggerViewController: NSViewController { isRunning = true cpuInstance.cycles = 0 - cpuInstance.cyclesInBatch = 1000000 + cpuInstance.cyclesInBatch = 10000 while(!cpuInstance.outOfCycles() && isRunning) { cpuInstance.cpuStep() @@ -101,6 +101,7 @@ class DebuggerViewController: NSViewController { @IBAction func btn_CPUStep(_ sender: Any) { cpuInstance.cpuStep() updateCPUStatusFields() + EmulatedSystemInstance!.updateScreen() } @IBAction func btn_Break(_ sender: Any) { diff --git a/FruitMachine/M6502/Debugger/Disassembly.swift b/FruitMachine/M6502/Debugger/Disassembly.swift index 7fd5e5d..eb52182 100644 --- a/FruitMachine/M6502/Debugger/Disassembly.swift +++ b/FruitMachine/M6502/Debugger/Disassembly.swift @@ -87,9 +87,9 @@ extension CPU { } disassembly.append(Disassembly(instruction: operation, address: currentAddress, data: data)) - currentAddress = currentAddress + UInt16(operation!.bytes) + currentAddress = currentAddress &+ UInt16(operation!.bytes) } else { - currentAddress = currentAddress + 1 + currentAddress = currentAddress &+ 1 } } diff --git a/FruitMachine/M6502/Memory/MemoryInterface.swift b/FruitMachine/M6502/Memory/MemoryInterface.swift index ab2eb6b..93d7018 100644 --- a/FruitMachine/M6502/Memory/MemoryInterface.swift +++ b/FruitMachine/M6502/Memory/MemoryInterface.swift @@ -76,8 +76,8 @@ final class MemoryInterface: NSObject { } func readWord(offset: UInt16) -> UInt16 { - let low: UInt8 = memory[Int(offset)] - let high: UInt8 = memory[Int(offset+1)] + let low = readByte(offset: offset) + let high = readByte(offset: offset+1) return (UInt16(high) << 8) | UInt16(low) } diff --git a/FruitMachine/M6502/Opcodes/CPUInstructions.swift b/FruitMachine/M6502/Opcodes/CPUInstructions.swift index 4756465..54f750c 100644 --- a/FruitMachine/M6502/Opcodes/CPUInstructions.swift +++ b/FruitMachine/M6502/Opcodes/CPUInstructions.swift @@ -229,4 +229,9 @@ let InstructionTable: [UInt8:CPUInstruction] = [ 0x7A: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP), 0xDA: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP), 0xFA: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP), + 0x82: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 2, addressingMode: .implied, action: Opcodes.NOP), + 0xC2: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 2, addressingMode: .implied, action: Opcodes.NOP), + 0xE2: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 2, addressingMode: .implied, action: Opcodes.NOP), + + //0x07: CPUInstruction(mnemonic: "SLO", cycles: 5, bytes: 2, addressingMode: .zeropage, action: Opcodes.SLO), ] diff --git a/FruitMachine/M6502/Opcodes/Opcodes.swift b/FruitMachine/M6502/Opcodes/Opcodes.swift index 6237706..ba976f9 100644 --- a/FruitMachine/M6502/Opcodes/Opcodes.swift +++ b/FruitMachine/M6502/Opcodes/Opcodes.swift @@ -570,6 +570,21 @@ final class Opcodes: NSObject { } } + //Illegal + static func SLO(state: CPU, addressingMode: CPU.AddressingMode) -> Void { + let address = getOperandAddressForAddressingMode(state: state, mode: addressingMode) + var data = state.memoryInterface.readByte(offset: address) + let t = (data & 0x80) == 0x80 ? true : false + + data = data << 1 + data = state.accumulator | data + state.memoryInterface.writeByte(offset: address, value: data) + + state.status_register.carry = t + state.updateZeroFlag(value: data) + state.updateNegativeFlag(value: data) + } + //Misc static func JMP(state: CPU, addressingMode: CPU.AddressingMode) -> Void { state.program_counter = getOperandAddressForAddressingMode(state: state, mode: addressingMode) &- 3 @@ -591,6 +606,8 @@ final class Opcodes: NSObject { } static func BRK(state: CPU, addressingMode: CPU.AddressingMode) -> Void { + print("*** BRK at \(state.program_counter.asHexString())! ***") + var sr = state.status_register sr.brk = true //BRK pushes B as true state.pushWord(data: state.program_counter + 2) diff --git a/FruitMachine/PreferencesWindow.xib b/FruitMachine/PreferencesWindow.xib index f97dd74..6c49214 100644 --- a/FruitMachine/PreferencesWindow.xib +++ b/FruitMachine/PreferencesWindow.xib @@ -34,12 +34,12 @@ - + - + @@ -140,7 +140,7 @@ - +