From 4efe09ad307e9954f8469b4276eaf6892af7640c Mon Sep 17 00:00:00 2001 From: Luigi Thirty Date: Wed, 2 Aug 2017 04:01:06 -0400 Subject: [PATCH] carry flag problem --- FruitMachine.xcodeproj/project.pbxproj | 4 ++ FruitMachine/AppleII/AppleII.swift | 38 +++++++++++++ FruitMachine/AppleII/KeyboardController.swift | 14 +++++ .../AppleII/SoftswitchOverrides.swift | 17 +++--- FruitMachine/AppleIIViewController.swift | 14 ++++- FruitMachine/FruitMachine.storyboard | 55 +------------------ .../Debugger/DebuggerViewController.swift | 4 +- .../M6502/Memory/MemoryInterface.swift | 23 +++++++- FruitMachine/M6502/Opcodes/Opcodes.swift | 3 +- 9 files changed, 105 insertions(+), 67 deletions(-) create mode 100644 FruitMachine/AppleII/KeyboardController.swift diff --git a/FruitMachine.xcodeproj/project.pbxproj b/FruitMachine.xcodeproj/project.pbxproj index 7e5aeb5..9b9d077 100644 --- a/FruitMachine.xcodeproj/project.pbxproj +++ b/FruitMachine.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ 2A6DC7F01F30495D0066FE0D /* ScreenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6DC7EF1F30495D0066FE0D /* ScreenView.swift */; }; 2A7665781F2F05F600135518 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7665761F2F05F600135518 /* PreferencesWindowController.swift */; }; 2A7665791F2F05F600135518 /* PreferencesWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A7665771F2F05F600135518 /* PreferencesWindow.xib */; }; + 2A86FB971F316CB500AD0C68 /* KeyboardController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A86FB961F316CB500AD0C68 /* KeyboardController.swift */; }; 2A91852A1F2EA84D00A9E5BE /* BitmapPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A9185291F2EA84D00A9E5BE /* BitmapPixels.swift */; }; 2AA8B5F81F2A8889002B350F /* AppleI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA8B5F71F2A8889002B350F /* AppleI.swift */; }; 2AA8B5FC1F2A8EAD002B350F /* Terminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA8B5FB1F2A8EAD002B350F /* Terminal.swift */; }; @@ -62,6 +63,7 @@ 2A6DC7EF1F30495D0066FE0D /* ScreenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenView.swift; sourceTree = ""; }; 2A7665761F2F05F600135518 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; 2A7665771F2F05F600135518 /* PreferencesWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PreferencesWindow.xib; sourceTree = ""; }; + 2A86FB961F316CB500AD0C68 /* KeyboardController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardController.swift; sourceTree = ""; }; 2A9185291F2EA84D00A9E5BE /* BitmapPixels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitmapPixels.swift; sourceTree = ""; }; 2AA8B5F71F2A8889002B350F /* AppleI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleI.swift; sourceTree = ""; }; 2AA8B5FB1F2A8EAD002B350F /* Terminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Terminal.swift; sourceTree = ""; }; @@ -163,6 +165,7 @@ children = ( 2A6DC7EE1F30492E0066FE0D /* Video */, 2AB6CACC1F3041A200DECAC0 /* AppleII.swift */, + 2A86FB961F316CB500AD0C68 /* KeyboardController.swift */, 2A6C2D161F31216700B8DC60 /* SoftswitchOverrides.swift */, ); path = AppleII; @@ -358,6 +361,7 @@ 2AD6D5841F26E6BF008F3CF5 /* DebuggerCommands.swift in Sources */, 2AE5BA041F23DE4400FAA343 /* Disassembly.swift in Sources */, 2A6DC7EB1F3045C90066FE0D /* EmulatedSystem.swift in Sources */, + 2A86FB971F316CB500AD0C68 /* KeyboardController.swift in Sources */, 2AE42E3A1F28628300C4900E /* AppleIViewController.swift in Sources */, 2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */, 2AE42E081F2850F400C4900E /* ReadOverride.swift in Sources */, diff --git a/FruitMachine/AppleII/AppleII.swift b/FruitMachine/AppleII/AppleII.swift index f2c5570..76f6a79 100644 --- a/FruitMachine/AppleII/AppleII.swift +++ b/FruitMachine/AppleII/AppleII.swift @@ -14,6 +14,7 @@ class AppleII: NSObject, EmulatedSystem { var frameCounter: Int = 0 let cg = A2CharacterGenerator(romPath: "/Users/luigi/apple2/a2.chr"); + let keyboardController = KeyboardController() var CPU_FREQUENCY: Double var FRAMES_PER_SECOND: Double @@ -30,6 +31,7 @@ class AppleII: NSObject, EmulatedSystem { super.init() loadROMs() + setupMemory(ramConfig: .sixteenK) emuScreenLayer.shouldRasterize = true emuScreenLayer.delegate = emulatorViewDelegate @@ -42,14 +44,21 @@ class AppleII: NSObject, EmulatedSystem { installOverrides() + doReset() + } + + func doReset() { CPU.sharedInstance.performReset() } func loadROMs() { + /* CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0001-00.e0", offset: 0xE000, length: 0x800) CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0002-00.e8", offset: 0xE800, length: 0x800) CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0003-00.f0", offset: 0xF000, length: 0x800) CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple2/341-0004-00.f8", offset: 0xF800, length: 0x800) + */ + CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/6502/test.bin", offset: 0x0000, length: 0x10000) } func installOverrides() { @@ -89,4 +98,33 @@ class AppleII: NSObject, EmulatedSystem { emulatorView.setNeedsDisplay(emulatorView.frame) } + enum MemoryConfiguration { + case fourK + case sixteenK + case fortyeightK + } + + func setupMemory(ramConfig: MemoryConfiguration) { + let ramPages: Int + + switch ramConfig { + case .fourK: + ramPages = 4096 / 256 + case .sixteenK: + ramPages = 16384 / 256 + case .fortyeightK: + ramPages = 49152 / 256 + } + + for page in 0 ..< ramPages { + CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.rw //RAM + } + for page in ramPages ..< 192 { + CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.null //not connected + } + for page in 224 ..< 256 { + CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.ro //not connected + } + } + } diff --git a/FruitMachine/AppleII/KeyboardController.swift b/FruitMachine/AppleII/KeyboardController.swift new file mode 100644 index 0000000..45e27af --- /dev/null +++ b/FruitMachine/AppleII/KeyboardController.swift @@ -0,0 +1,14 @@ +// +// KeyboardController.swift +// FruitMachine +// +// Created by Christopher Rohl on 8/1/17. +// Copyright © 2017 Christopher Rohl. All rights reserved. +// + +import Cocoa + +class KeyboardController: NSObject { + var KEYBOARD: UInt8 = 0x00 + var STROBE: UInt8 = 0x00 +} diff --git a/FruitMachine/AppleII/SoftswitchOverrides.swift b/FruitMachine/AppleII/SoftswitchOverrides.swift index c50040d..156b487 100644 --- a/FruitMachine/AppleII/SoftswitchOverrides.swift +++ b/FruitMachine/AppleII/SoftswitchOverrides.swift @@ -13,11 +13,10 @@ extension AppleII { class SoftswitchOverrides: NSObject { static let readKeyboard = ReadOverride(start: 0xC000, end: 0xC000, readAnyway: false, action: SoftswitchOverrides.actionReadKeyboard) static func actionReadKeyboard(dummy: AnyObject, byte: UInt8?) -> UInt8? { - let b = CPU.sharedInstance.memoryInterface.readByte(offset: 0xC000, bypassOverrides: true) - - CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC000, value: b) - - return b + //let b = CPU.sharedInstance.memoryInterface.readByte(offset: 0xC000, bypassOverrides: true) + //CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC000, value: b) + //return b + return AppleII.sharedInstance.keyboardController.KEYBOARD } static let clearKeypressStrobeR = ReadOverride(start: 0xC010, end: 0xC010, readAnyway: false, action: SoftswitchOverrides.actionClearKeypressStrobe) @@ -25,10 +24,14 @@ extension AppleII { static func actionClearKeypressStrobe(dummy: AnyObject, byte: UInt8?) -> UInt8? { //Clears b7 of $C000 on write. - let b = CPU.sharedInstance.memoryInterface.readByte(offset: 0xC000, bypassOverrides: true) - CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC000, value: b & 0x7F, bypassOverrides: true) + //let b = CPU.sharedInstance.memoryInterface.readByte(offset: 0xC000, bypassOverrides: true) + //CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC000, value: b & 0x7F, bypassOverrides: true) //CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC010, value: b & 0x7F, bypassOverrides: true) + //return b + let b = AppleII.sharedInstance.keyboardController.KEYBOARD + AppleII.sharedInstance.keyboardController.KEYBOARD = b & 0x7F + AppleII.sharedInstance.keyboardController.STROBE = b & 0x7F return b } } diff --git a/FruitMachine/AppleIIViewController.swift b/FruitMachine/AppleIIViewController.swift index 46f22d2..1b1dd4b 100644 --- a/FruitMachine/AppleIIViewController.swift +++ b/FruitMachine/AppleIIViewController.swift @@ -25,11 +25,15 @@ class AppleIIViewController: NSViewController { self.view.addSubview(computer.emulatorView) + /* self.frameTimer = Timer.scheduledTimer(timeInterval: 1.0/60.0, target: self, selector: #selector(runEmulation), userInfo: nil, repeats: true) + */ + + CPU.sharedInstance.program_counter = 0x400 } @objc func runEmulation() { @@ -39,7 +43,7 @@ class AppleIIViewController: NSViewController { } } - @IBAction func showDebugger(_ sender: Any) { + @IBAction func showDebugger(_ sender: Any) { let debuggerStoryboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Debugger"), bundle: nil) debuggerWindowController = debuggerStoryboard.instantiateInitialController() as! DebuggerWindowController debuggerWindowController.showWindow(self) @@ -49,6 +53,10 @@ class AppleIIViewController: NSViewController { preferencesWindowController.loadWindow() } + @IBAction func doReset(_ sender: Any) { + computer.doReset() + } + override func keyDown(with event: NSEvent) { let c = returnChar(theEvent: event) @@ -56,8 +64,8 @@ class AppleIIViewController: NSViewController { return } - //Poke the ASCII byte into $C000. - CPU.sharedInstance.memoryInterface.writeByte(offset: 0xC000, value: UInt8((ascii32 | 0x80) & 0x000000FF)) + //Set the keyboard input register accordingly. Set b7 so the OS knows there's a keypress waiting + computer.keyboardController.KEYBOARD = UInt8((ascii32 | 0x80) & 0x000000FF) } private func returnChar(theEvent: NSEvent) -> Character?{ diff --git a/FruitMachine/FruitMachine.storyboard b/FruitMachine/FruitMachine.storyboard index cccddf0..7354b21 100644 --- a/FruitMachine/FruitMachine.storyboard +++ b/FruitMachine/FruitMachine.storyboard @@ -64,60 +64,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/FruitMachine/M6502/Debugger/DebuggerViewController.swift b/FruitMachine/M6502/Debugger/DebuggerViewController.swift index d762b65..5a66c96 100644 --- a/FruitMachine/M6502/Debugger/DebuggerViewController.swift +++ b/FruitMachine/M6502/Debugger/DebuggerViewController.swift @@ -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: CPU.sharedInstance.program_counter, length: 256) + disassembly = cpuInstance.disassemble(fromAddress: CPU.sharedInstance.program_counter &- 16, length: 256) debuggerTableView.reloadData() highlightCurrentInstruction() } @@ -58,7 +58,7 @@ class DebuggerViewController: NSViewController { debuggerTableView.dataSource = self updateCPUStatusFields() - disassembly = cpuInstance.disassemble(fromAddress: CPU.sharedInstance.program_counter, length: 256) + disassembly = cpuInstance.disassemble(fromAddress: CPU.sharedInstance.program_counter &- 16, length: 256) debuggerTableView.reloadData() // Do any additional setup after loading the view. diff --git a/FruitMachine/M6502/Memory/MemoryInterface.swift b/FruitMachine/M6502/Memory/MemoryInterface.swift index ec2a2ac..ec3ffc8 100644 --- a/FruitMachine/M6502/Memory/MemoryInterface.swift +++ b/FruitMachine/M6502/Memory/MemoryInterface.swift @@ -9,20 +9,31 @@ import Cocoa final class MemoryInterface: NSObject { + enum pageMode { + case ro + case rw + case null + } + fileprivate var memory: [UInt8] var read_overrides: [ReadOverride] var write_overrides: [WriteOverride] + var pages: [pageMode] = [pageMode](repeating: .null, count: 256) + override init() { memory = [UInt8](repeating: 0x00, count: 65536) read_overrides = [ReadOverride]() write_overrides = [WriteOverride]() } + func getPage(offset: UInt16) -> UInt8 { + return UInt8(offset >> 8) + } + func readByte(offset: UInt16, bypassOverrides: Bool = false) -> UInt8 { - if(!bypassOverrides) { for override in read_overrides { if case override.rangeStart ... override.rangeEnd = offset { @@ -34,6 +45,11 @@ final class MemoryInterface: NSObject { } } + //If no override, check if there's memory here. + if(pages[Int(getPage(offset: offset))] == pageMode.null) { + return 0x00 + } + //No match. return memory[Int(offset)] } @@ -51,6 +67,11 @@ final class MemoryInterface: NSObject { } } + //If no override, check if there's memory here to write. + if(pages[Int(getPage(offset: offset))] != pageMode.rw) { + return + } + memory[Int(offset)] = value } diff --git a/FruitMachine/M6502/Opcodes/Opcodes.swift b/FruitMachine/M6502/Opcodes/Opcodes.swift index cc6e879..16656da 100644 --- a/FruitMachine/M6502/Opcodes/Opcodes.swift +++ b/FruitMachine/M6502/Opcodes/Opcodes.swift @@ -175,7 +175,8 @@ final class Opcodes: NSObject { if(state.status_register.decimal == true) { t16 = UInt16(hex2bcd(hex: state.accumulator) + hex2bcd(hex: operand) + (state.status_register.carry ? UInt8(1) : UInt8(0))) } else { - state.status_register.carry = t8 <= 127 ? true : false + //carry flag isn't being set properly + state.status_register.carry = (t8 >= 127) ? true : false } state.accumulator = t8