fixed language card memory reads not being redirected to LC RAM, prodos 2.4 now gets to the directory listing before crashing

This commit is contained in:
Luigi Thirty 2017-08-10 00:05:14 -04:00
parent 92a77fc3d5
commit 181b98b95c
15 changed files with 297 additions and 55 deletions

View File

@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
2A044E2C1F37D65A000E8085 /* LanguageCard16K.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */; }; 2A044E2C1F37D65A000E8085 /* LanguageCard16K.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */; };
2A044E2E1F382CA9000E8085 /* AppleIIPlus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A044E2D1F382CA9000E8085 /* AppleIIPlus.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 */; }; 2A16ADBB1F33C341004A0333 /* DiskImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A16ADBA1F33C341004A0333 /* DiskImage.swift */; };
2A2126841F2A9FA300E43DC1 /* DebuggerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */; }; 2A2126841F2A9FA300E43DC1 /* DebuggerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */; };
2A22EBFB1F21A7A700A36A61 /* IntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */; }; 2A22EBFB1F21A7A700A36A61 /* IntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */; };
@ -60,6 +61,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageCard16K.swift; sourceTree = "<group>"; }; 2A044E2B1F37D65A000E8085 /* LanguageCard16K.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageCard16K.swift; sourceTree = "<group>"; };
2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleIIPlus.swift; sourceTree = "<group>"; }; 2A044E2D1F382CA9000E8085 /* AppleIIPlus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleIIPlus.swift; sourceTree = "<group>"; };
2A0D0C681F3C09990000913B /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; };
2A16ADBA1F33C341004A0333 /* DiskImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskImage.swift; sourceTree = "<group>"; }; 2A16ADBA1F33C341004A0333 /* DiskImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskImage.swift; sourceTree = "<group>"; };
2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerWindowController.swift; sourceTree = "<group>"; }; 2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerWindowController.swift; sourceTree = "<group>"; };
2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegerExtensions.swift; sourceTree = "<group>"; }; 2A22EBFA1F21A7A700A36A61 /* IntegerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegerExtensions.swift; sourceTree = "<group>"; };
@ -278,6 +280,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
2AE3BB961F32CEB100C11060 /* ROMManager.swift */, 2AE3BB961F32CEB100C11060 /* ROMManager.swift */,
2A0D0C681F3C09990000913B /* Types.swift */,
); );
path = Memory; path = Memory;
sourceTree = "<group>"; sourceTree = "<group>";
@ -435,6 +438,7 @@
2AB6CACD1F3041A200DECAC0 /* AppleII.swift in Sources */, 2AB6CACD1F3041A200DECAC0 /* AppleII.swift in Sources */,
2A63C2331F32C39300D4F4F8 /* TextMode.swift in Sources */, 2A63C2331F32C39300D4F4F8 /* TextMode.swift in Sources */,
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */, 2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */,
2A0D0C691F3C09990000913B /* Types.swift in Sources */,
2AE42E0A1F28521E00C4900E /* WriteOverride.swift in Sources */, 2AE42E0A1F28521E00C4900E /* WriteOverride.swift in Sources */,
2A6DC7ED1F30492C0066FE0D /* ScreenDelegate.swift in Sources */, 2A6DC7ED1F30492C0066FE0D /* ScreenDelegate.swift in Sources */,
2A044E2C1F37D65A000E8085 /* LanguageCard16K.swift in Sources */, 2A044E2C1F37D65A000E8085 /* LanguageCard16K.swift in Sources */,

View File

@ -91,19 +91,17 @@ class AppleIIBase: NSObject, EmulatedSystem {
CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.null //not connected CPU.sharedInstance.memoryInterface.pages[page] = MemoryInterface.pageMode.null //not connected
} }
for page in 208 ..< 256 { 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() { func setupPeripherals() {
let defaults = UserDefaults.standard let defaults = UserDefaults.standard
/*
let slot0 = defaults.string(forKey: "a2_Peripherals_Slot0") let slot0 = defaults.string(forKey: "a2_Peripherals_Slot0")
if(slot0 == "Language Card (16K)") { if(slot0 == "Language Card (16K)") {
backplane[0] = LanguageCard16K(slot: 0, romPath: "/Users/luigi/apple2/341-0020-00.f8") backplane[0] = LanguageCard16K(slot: 0, romPath: "/Users/luigi/apple2/341-0020-00.f8")
} }
*/
let slot6 = defaults.string(forKey: "a2_Peripherals_Slot6") let slot6 = defaults.string(forKey: "a2_Peripherals_Slot6")
if(slot6 == "Disk II") { if(slot6 == "Disk II") {
@ -133,8 +131,11 @@ class AppleIIBase: NSObject, EmulatedSystem {
CPU.sharedInstance.cycles = 0 CPU.sharedInstance.cycles = 0
CPU.sharedInstance.cyclesInBatch = CYCLES_PER_BATCH CPU.sharedInstance.cyclesInBatch = CYCLES_PER_BATCH
CPU.sharedInstance.runCyclesBatch() CPU.sharedInstance.runCyclesBatch()
//update the video display updateScreen()
}
func updateScreen() {
CVPixelBufferLockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0)) CVPixelBufferLockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0))
let pixelBase = CVPixelBufferGetBaseAddress(emulatorViewDelegate.pixels!) let pixelBase = CVPixelBufferGetBaseAddress(emulatorViewDelegate.pixels!)
let buf = pixelBase?.assumingMemoryBound(to: BitmapPixelsLE555.PixelData.self) let buf = pixelBase?.assumingMemoryBound(to: BitmapPixelsLE555.PixelData.self)
@ -171,6 +172,7 @@ class AppleIIBase: NSObject, EmulatedSystem {
CVPixelBufferUnlockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0)) CVPixelBufferUnlockBaseAddress(emulatorViewDelegate.pixels!, CVPixelBufferLockFlags(rawValue: 0))
emulatorView.setNeedsDisplay(emulatorView.frame) emulatorView.setNeedsDisplay(emulatorView.frame)
} }
/* Video */ /* Video */

View File

@ -35,7 +35,7 @@ import Cocoa
*/ */
class DiskII: NSObject, Peripheral, HasROM { class DiskII: NSObject, Peripheral, HasROM {
let debug = true let debug = false
enum MotorPhase { enum MotorPhase {
case Phase0 case Phase0

View File

@ -77,28 +77,28 @@ class ProdosImage: DiskImageFormat {
switch blockOffset8 { switch blockOffset8 {
case 0: case 0:
sector1 = 0 sector1 = 0
sector2 = 0xE sector2 = 0x1
case 1: case 1:
sector1 = 0xD sector1 = 0x2
sector2 = 0xC sector2 = 0x3
case 2: case 2:
sector1 = 0xB sector1 = 0x4
sector2 = 0xA sector2 = 0x5
case 3: case 3:
sector1 = 0x9 sector1 = 0x6
sector2 = 0x8 sector2 = 0x7
case 4: case 4:
sector1 = 0x7 sector1 = 0x8
sector2 = 0x6 sector2 = 0x9
case 5: case 5:
sector1 = 0x5 sector1 = 0xA
sector2 = 0x4 sector2 = 0xB
case 6: case 6:
sector1 = 0x3 sector1 = 0xC
sector2 = 0x2 sector2 = 0xD
case 7: case 7:
sector1 = 0x1 sector1 = 0xE
sector2 = 0xF sector2 = 0xF
default: default:
print("should never happen") print("should never happen")
@ -161,7 +161,7 @@ class DiskImage: NSObject {
nbls.append(contentsOf: track) 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 ptr = UnsafeBufferPointer(start: blks, count: blks.count)
var data = Data(buffer: ptr) 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))) encodedData.append(contentsOf: EncodeSectorSixAndTwo(sector: Dos33Image.readTrackAndSector(imageData: imageData, trackNum: index, sectorNum: sectorNum)))
} }
else if(image is ProdosImage){ 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. */ /* Find the 256 bytes corresponding to this sector. */
switch(sectorNum) switch(sectorNum)
{ {

View File

@ -12,12 +12,29 @@ class LanguageCard16K: NSObject, Peripheral, HasROM {
var slotNumber: Int var slotNumber: Int
var romManager: ROMManager 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. //16KB of RAM on the Language Card.
var ram = [UInt8](repeating: 0xCC, count: 16384) var ram = [UInt8](repeating: 0xCC, count: 16384)
var readIOOverride: ReadOverride? = nil var readIOOverride: ReadOverride? = nil
var writeIOOverride: WriteOverride? = 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() {
func installOverrides() { func installOverrides() {
CPU.sharedInstance.memoryInterface.read_overrides.append(readIOOverride!) CPU.sharedInstance.memoryInterface.read_overrides.append(readIOOverride!)
@ -31,15 +48,92 @@ class LanguageCard16K: NSObject, Peripheral, HasROM {
super.init() 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)), readIOOverride = ReadOverride(start: UInt16(0xC080 + (0x10 * slotNumber)),
end: UInt16(0xC08F + (0x10 * slotNumber)), end: UInt16(0xC08F + (0x10 * slotNumber)),
readAnyway: false, readAnyway: false,
action: actionDispatchOperation) action: actionDispatchOperation)
writeIOOverride = WriteOverride(start: UInt16(0xC080 + (0x10 * slotNumber)), readLanguageCardAddressingOverride = ReadOverride(start: UInt16(0xD000),
end: UInt16(0xC08F + (0x10 * slotNumber)), end: UInt16(0xFFFF),
writeAnyway: false, readAnyway: false,
action: actionDispatchOperation) 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? private func actionDispatchOperation(something: AnyObject, address: UInt16, byte: UInt8?) -> UInt8?
@ -49,12 +143,98 @@ class LanguageCard16K: NSObject, Peripheral, HasROM {
if(byte == nil) { if(byte == nil) {
isRead = true 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 return 0x00
} }
} }

View File

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

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="13168.3" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="0Wh-dg-gsU"> <document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="13178.6" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="0Wh-dg-gsU">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13168.3"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13178.6"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>

View File

@ -12,6 +12,11 @@ enum CPUExceptions : Error {
case invalidInstruction case invalidInstruction
} }
enum CPUModel {
case M6502
case M65C02
}
struct StatusRegister { struct StatusRegister {
var negative: Bool //N - 0x80 var negative: Bool //N - 0x80
var overflow: Bool //V - 0x40 var overflow: Bool //V - 0x40
@ -132,7 +137,7 @@ final class CPU: NSObject {
let RESET_VECTOR: UInt16 = 0xFFFC let RESET_VECTOR: UInt16 = 0xFFFC
let IRQ_VECTOR: UInt16 = 0xFFFE let IRQ_VECTOR: UInt16 = 0xFFFE
static let sharedInstance = CPU() static let sharedInstance = CPU(cpuModel: .M6502)
var isRunning: Bool var isRunning: Bool
@ -148,6 +153,9 @@ final class CPU: NSObject {
var program_counter: UInt16 var program_counter: UInt16
var status_register: StatusRegister var status_register: StatusRegister
//Debugging
var old_program_counter: UInt16
var page_boundary_crossed: Bool var page_boundary_crossed: Bool
var branch_was_taken: Bool var branch_was_taken: Bool
@ -155,9 +163,13 @@ final class CPU: NSObject {
var breakpoints: [UInt16] var breakpoints: [UInt16]
override init() { var model: CPUModel
init(cpuModel: CPUModel) {
isRunning = false isRunning = false
model = cpuModel
cycles = 0 cycles = 0
cyclesInBatch = 0 cyclesInBatch = 0
@ -168,6 +180,7 @@ final class CPU: NSObject {
index_y = 0 index_y = 0
stack_pointer = 0 stack_pointer = 0
program_counter = 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) status_register = StatusRegister(negative: false, overflow: false, brk: false, decimal: false, irq_disable: false, zero: false, carry: false)
memoryInterface = MemoryInterface() 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. //Branches incur a 1-cycle penalty if taken plus the page boundary penalty if necessary.
branch_was_taken = false branch_was_taken = false
breakpoints = [UInt16]() breakpoints = [UInt16]()
} }
func coldReset() { func coldReset() {
@ -201,15 +214,20 @@ final class CPU: NSObject {
} }
} }
func changeModel(cpuModel: CPUModel) {
model = cpuModel
coldReset()
}
func getOperandByte() -> UInt8 { func getOperandByte() -> UInt8 {
//Returns the operand byte after the current instruction byte. //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 { func getOperandWord() -> UInt16 {
var word: UInt16 var word: UInt16
let low = memoryInterface.readByte(offset: program_counter + 1) let low = memoryInterface.readByte(offset: program_counter &+ 1)
let high = memoryInterface.readByte(offset: program_counter + 2) let high = memoryInterface.readByte(offset: program_counter &+ 2)
word = UInt16(high) word = UInt16(high)
word = word << 8 word = word << 8
@ -241,6 +259,11 @@ final class CPU: NSObject {
throw CPUExceptions.invalidInstruction throw CPUExceptions.invalidInstruction
} }
if(program_counter == 0x102F) {
print("$102F")
}
self.old_program_counter = self.program_counter
operation!.action(CPU.sharedInstance, operation!.addressingMode) operation!.action(CPU.sharedInstance, operation!.addressingMode)
self.cycles += operation!.cycles self.cycles += operation!.cycles
@ -253,7 +276,8 @@ final class CPU: NSObject {
self.branch_was_taken = false 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 { func outOfCycles() -> Bool {

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="13168.3" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS"> <document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="13178.6" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13168.3"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13178.6"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
@ -47,7 +47,7 @@
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WjO-ue-iRg"> <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WjO-ue-iRg">
<rect key="frame" x="42" y="510" width="96" height="22"/> <rect key="frame" x="42" y="510" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="tFR-bO-ncf"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="tFR-bO-ncf">
<font key="font" metaFont="fixedUser" size="11"/> <font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -65,7 +65,7 @@
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nOs-8C-MbH"> <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nOs-8C-MbH">
<rect key="frame" x="42" y="480" width="96" height="22"/> <rect key="frame" x="42" y="480" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="rbk-9r-h0r"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="rbk-9r-h0r">
<font key="font" metaFont="fixedUser" size="11"/> <font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -83,7 +83,7 @@
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eqA-qk-YQy"> <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eqA-qk-YQy">
<rect key="frame" x="42" y="450" width="96" height="22"/> <rect key="frame" x="42" y="450" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="TpP-00-jRa"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="TpP-00-jRa">
<font key="font" metaFont="fixedUser" size="11"/> <font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -101,7 +101,7 @@
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XbV-5m-dd0"> <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XbV-5m-dd0">
<rect key="frame" x="42" y="420" width="96" height="22"/> <rect key="frame" x="42" y="420" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="tiL-Qj-d0G"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="tiL-Qj-d0G">
<font key="font" metaFont="fixedUser" size="11"/> <font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -119,7 +119,7 @@
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5TT-BA-Iw1"> <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5TT-BA-Iw1">
<rect key="frame" x="42" y="390" width="96" height="22"/> <rect key="frame" x="42" y="390" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="wzs-zZ-PQs"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="wzs-zZ-PQs">
<font key="font" metaFont="fixedUser" size="11"/> <font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -137,7 +137,7 @@
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ecN-Ge-1hE"> <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ecN-Ge-1hE">
<rect key="frame" x="42" y="360" width="96" height="22"/> <rect key="frame" x="42" y="360" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="4dD-B8-JHv"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="4dD-B8-JHv">
<font key="font" metaFont="fixedUser" size="11"/> <font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>

View File

@ -78,7 +78,7 @@ class DebuggerViewController: NSViewController {
isRunning = true isRunning = true
cpuInstance.cycles = 0 cpuInstance.cycles = 0
cpuInstance.cyclesInBatch = 1000000 cpuInstance.cyclesInBatch = 10000
while(!cpuInstance.outOfCycles() && isRunning) { while(!cpuInstance.outOfCycles() && isRunning) {
cpuInstance.cpuStep() cpuInstance.cpuStep()
@ -101,6 +101,7 @@ class DebuggerViewController: NSViewController {
@IBAction func btn_CPUStep(_ sender: Any) { @IBAction func btn_CPUStep(_ sender: Any) {
cpuInstance.cpuStep() cpuInstance.cpuStep()
updateCPUStatusFields() updateCPUStatusFields()
EmulatedSystemInstance!.updateScreen()
} }
@IBAction func btn_Break(_ sender: Any) { @IBAction func btn_Break(_ sender: Any) {

View File

@ -87,9 +87,9 @@ extension CPU {
} }
disassembly.append(Disassembly(instruction: operation, address: currentAddress, data: data)) disassembly.append(Disassembly(instruction: operation, address: currentAddress, data: data))
currentAddress = currentAddress + UInt16(operation!.bytes) currentAddress = currentAddress &+ UInt16(operation!.bytes)
} else { } else {
currentAddress = currentAddress + 1 currentAddress = currentAddress &+ 1
} }
} }

View File

@ -76,8 +76,8 @@ final class MemoryInterface: NSObject {
} }
func readWord(offset: UInt16) -> UInt16 { func readWord(offset: UInt16) -> UInt16 {
let low: UInt8 = memory[Int(offset)] let low = readByte(offset: offset)
let high: UInt8 = memory[Int(offset+1)] let high = readByte(offset: offset+1)
return (UInt16(high) << 8) | UInt16(low) return (UInt16(high) << 8) | UInt16(low)
} }

View File

@ -229,4 +229,9 @@ let InstructionTable: [UInt8:CPUInstruction] = [
0x7A: CPUInstruction(mnemonic: "NOP", cycles: 2, bytes: 1, addressingMode: .implied, action: Opcodes.NOP), 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), 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), 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),
] ]

View File

@ -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 //Misc
static func JMP(state: CPU, addressingMode: CPU.AddressingMode) -> Void { static func JMP(state: CPU, addressingMode: CPU.AddressingMode) -> Void {
state.program_counter = getOperandAddressForAddressingMode(state: state, mode: addressingMode) &- 3 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 { static func BRK(state: CPU, addressingMode: CPU.AddressingMode) -> Void {
print("*** BRK at \(state.program_counter.asHexString())! ***")
var sr = state.status_register var sr = state.status_register
sr.brk = true //BRK pushes B as true sr.brk = true //BRK pushes B as true
state.pushWord(data: state.program_counter + 2) state.pushWord(data: state.program_counter + 2)

View File

@ -34,12 +34,12 @@
<tabViewItems> <tabViewItems>
<tabViewItem label="General" identifier="1" id="nQU-pA-pvF"> <tabViewItem label="General" identifier="1" id="nQU-pA-pvF">
<view key="view" id="iK8-x4-ay0"> <view key="view" id="iK8-x4-ay0">
<rect key="frame" x="10" y="33" width="554" height="338"/> <rect key="frame" x="10" y="33" width="259" height="0.0"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view> </view>
</tabViewItem> </tabViewItem>
<tabViewItem label="Paths" identifier="2" id="zXY-01-Th8"> <tabViewItem label="Paths" identifier="2" id="zXY-01-Th8">
<view key="view" id="tiQ-eh-pdD"> <view key="view" ambiguous="YES" id="tiQ-eh-pdD">
<rect key="frame" x="10" y="33" width="554" height="338"/> <rect key="frame" x="10" y="33" width="554" height="338"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
@ -140,7 +140,7 @@
</view> </view>
</tabViewItem> </tabViewItem>
<tabViewItem label="Apple II" identifier="" id="aVa-m9-VEl"> <tabViewItem label="Apple II" identifier="" id="aVa-m9-VEl">
<view key="view" ambiguous="YES" id="mjS-Jn-KXO"> <view key="view" id="mjS-Jn-KXO">
<rect key="frame" x="10" y="33" width="554" height="338"/> <rect key="frame" x="10" y="33" width="554" height="338"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>