mirror of
https://github.com/Luigi30/FruitMachine-Swift.git
synced 2024-11-23 02:33:00 +00:00
graphics... sort of
This commit is contained in:
parent
dd8301ccab
commit
0c75e6f75e
@ -7,10 +7,14 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
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 */; };
|
||||||
2A5BC5191F29A28D008C03BE /* AppleScreenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5BC5181F29A28D008C03BE /* AppleScreenView.swift */; };
|
2A5BC5191F29A28D008C03BE /* AppleScreenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5BC5181F29A28D008C03BE /* AppleScreenView.swift */; };
|
||||||
2A5BC51C1F29A2EB008C03BE /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A5BC51B1F29A2EB008C03BE /* QuartzCore.framework */; };
|
2A5BC51C1F29A2EB008C03BE /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A5BC51B1F29A2EB008C03BE /* QuartzCore.framework */; };
|
||||||
2A5BC51E1F29A4C3008C03BE /* AppleScreenViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5BC51D1F29A4C3008C03BE /* AppleScreenViewDelegate.swift */; };
|
2A5BC51E1F29A4C3008C03BE /* AppleScreenViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5BC51D1F29A4C3008C03BE /* AppleScreenViewDelegate.swift */; };
|
||||||
|
2AA8B5F81F2A8889002B350F /* AppleI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA8B5F71F2A8889002B350F /* AppleI.swift */; };
|
||||||
|
2AA8B5FC1F2A8EAD002B350F /* Terminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA8B5FB1F2A8EAD002B350F /* Terminal.swift */; };
|
||||||
|
2AA8B5FE1F2A942C002B350F /* PIAOverrides.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA8B5FD1F2A942C002B350F /* PIAOverrides.swift */; };
|
||||||
2AD458CE1F205EB700F05121 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458CD1F205EB700F05121 /* AppDelegate.swift */; };
|
2AD458CE1F205EB700F05121 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458CD1F205EB700F05121 /* AppDelegate.swift */; };
|
||||||
2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */; };
|
2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */; };
|
||||||
2AD458D21F205EB700F05121 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AD458D11F205EB700F05121 /* Assets.xcassets */; };
|
2AD458D21F205EB700F05121 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AD458D11F205EB700F05121 /* Assets.xcassets */; };
|
||||||
@ -31,10 +35,14 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
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>"; };
|
||||||
2A5BC5181F29A28D008C03BE /* AppleScreenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleScreenView.swift; sourceTree = "<group>"; };
|
2A5BC5181F29A28D008C03BE /* AppleScreenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleScreenView.swift; sourceTree = "<group>"; };
|
||||||
2A5BC51B1F29A2EB008C03BE /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
2A5BC51B1F29A2EB008C03BE /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||||
2A5BC51D1F29A4C3008C03BE /* AppleScreenViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleScreenViewDelegate.swift; sourceTree = "<group>"; };
|
2A5BC51D1F29A4C3008C03BE /* AppleScreenViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleScreenViewDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
2AA8B5F71F2A8889002B350F /* AppleI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleI.swift; sourceTree = "<group>"; };
|
||||||
|
2AA8B5FB1F2A8EAD002B350F /* Terminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Terminal.swift; sourceTree = "<group>"; };
|
||||||
|
2AA8B5FD1F2A942C002B350F /* PIAOverrides.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAOverrides.swift; sourceTree = "<group>"; };
|
||||||
2AD458CA1F205EB700F05121 /* FruitMachine.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FruitMachine.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
2AD458CA1F205EB700F05121 /* FruitMachine.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FruitMachine.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
2AD458CD1F205EB700F05121 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
2AD458CD1F205EB700F05121 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerViewController.swift; sourceTree = "<group>"; };
|
2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerViewController.swift; sourceTree = "<group>"; };
|
||||||
@ -77,6 +85,17 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
2AA8B5F61F2A8844002B350F /* AppleI */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2AE42E411F28663600C4900E /* Video */,
|
||||||
|
2A5BC5181F29A28D008C03BE /* AppleScreenView.swift */,
|
||||||
|
2A5BC51D1F29A4C3008C03BE /* AppleScreenViewDelegate.swift */,
|
||||||
|
2AA8B5F71F2A8889002B350F /* AppleI.swift */,
|
||||||
|
);
|
||||||
|
path = AppleI;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
2AD458C11F205EB700F05121 = {
|
2AD458C11F205EB700F05121 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -97,11 +116,9 @@
|
|||||||
2AD458CC1F205EB700F05121 /* FruitMachine */ = {
|
2AD458CC1F205EB700F05121 /* FruitMachine */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
2AA8B5F61F2A8844002B350F /* AppleI */,
|
||||||
2AD458DD1F205F0D00F05121 /* M6502 */,
|
2AD458DD1F205F0D00F05121 /* M6502 */,
|
||||||
2AE42E411F28663600C4900E /* Video */,
|
|
||||||
2AD458CD1F205EB700F05121 /* AppDelegate.swift */,
|
2AD458CD1F205EB700F05121 /* AppDelegate.swift */,
|
||||||
2A5BC5181F29A28D008C03BE /* AppleScreenView.swift */,
|
|
||||||
2A5BC51D1F29A4C3008C03BE /* AppleScreenViewDelegate.swift */,
|
|
||||||
2AE42E381F28628300C4900E /* MainViewController.swift */,
|
2AE42E381F28628300C4900E /* MainViewController.swift */,
|
||||||
2AE42E3F1F28638100C4900E /* FruitMachine.storyboard */,
|
2AE42E3F1F28638100C4900E /* FruitMachine.storyboard */,
|
||||||
2AD458D11F205EB700F05121 /* Assets.xcassets */,
|
2AD458D11F205EB700F05121 /* Assets.xcassets */,
|
||||||
@ -139,6 +156,7 @@
|
|||||||
children = (
|
children = (
|
||||||
2AD458D31F205EB700F05121 /* Debugger.storyboard */,
|
2AD458D31F205EB700F05121 /* Debugger.storyboard */,
|
||||||
2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */,
|
2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */,
|
||||||
|
2A2126831F2A9FA300E43DC1 /* DebuggerWindowController.swift */,
|
||||||
2AD6D5831F26E6BF008F3CF5 /* DebuggerCommands.swift */,
|
2AD6D5831F26E6BF008F3CF5 /* DebuggerCommands.swift */,
|
||||||
2AE5BA031F23DE4400FAA343 /* Disassembly.swift */,
|
2AE5BA031F23DE4400FAA343 /* Disassembly.swift */,
|
||||||
);
|
);
|
||||||
@ -167,6 +185,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
2AE42E421F28665300C4900E /* CharacterGenerator.swift */,
|
2AE42E421F28665300C4900E /* CharacterGenerator.swift */,
|
||||||
|
2AA8B5FB1F2A8EAD002B350F /* Terminal.swift */,
|
||||||
|
2AA8B5FD1F2A942C002B350F /* PIAOverrides.swift */,
|
||||||
);
|
);
|
||||||
path = Video;
|
path = Video;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -242,8 +262,10 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
2A2126841F2A9FA300E43DC1 /* DebuggerWindowController.swift in Sources */,
|
||||||
2AD458E31F20661300F05121 /* CPUInstructions.swift in Sources */,
|
2AD458E31F20661300F05121 /* CPUInstructions.swift in Sources */,
|
||||||
2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */,
|
2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */,
|
||||||
|
2AA8B5FC1F2A8EAD002B350F /* Terminal.swift in Sources */,
|
||||||
2A5BC51E1F29A4C3008C03BE /* AppleScreenViewDelegate.swift in Sources */,
|
2A5BC51E1F29A4C3008C03BE /* AppleScreenViewDelegate.swift in Sources */,
|
||||||
2AD458CE1F205EB700F05121 /* AppDelegate.swift in Sources */,
|
2AD458CE1F205EB700F05121 /* AppDelegate.swift in Sources */,
|
||||||
2AE42E431F28665300C4900E /* CharacterGenerator.swift in Sources */,
|
2AE42E431F28665300C4900E /* CharacterGenerator.swift in Sources */,
|
||||||
@ -254,10 +276,12 @@
|
|||||||
2AE42E3A1F28628300C4900E /* MainViewController.swift in Sources */,
|
2AE42E3A1F28628300C4900E /* MainViewController.swift in Sources */,
|
||||||
2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */,
|
2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */,
|
||||||
2AE42E081F2850F400C4900E /* ReadOverride.swift in Sources */,
|
2AE42E081F2850F400C4900E /* ReadOverride.swift in Sources */,
|
||||||
|
2AA8B5FE1F2A942C002B350F /* PIAOverrides.swift in Sources */,
|
||||||
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */,
|
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */,
|
||||||
2AE42E0A1F28521E00C4900E /* WriteOverride.swift in Sources */,
|
2AE42E0A1F28521E00C4900E /* WriteOverride.swift in Sources */,
|
||||||
2A5BC5191F29A28D008C03BE /* AppleScreenView.swift in Sources */,
|
2A5BC5191F29A28D008C03BE /* AppleScreenView.swift in Sources */,
|
||||||
2AD458E11F2064CB00F05121 /* MemoryInterface.swift in Sources */,
|
2AD458E11F2064CB00F05121 /* MemoryInterface.swift in Sources */,
|
||||||
|
2AA8B5F81F2A8889002B350F /* AppleI.swift in Sources */,
|
||||||
2AD458DF1F205F4500F05121 /* CPU.swift in Sources */,
|
2AD458DF1F205F4500F05121 /* CPU.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -10,6 +10,7 @@ import Cocoa
|
|||||||
|
|
||||||
@NSApplicationMain
|
@NSApplicationMain
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
let AppleScreenNotifications = Notification.Name("com.luigithirty.appleScreenNotifications")
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||||
// Insert code here to initialize your application
|
// Insert code here to initialize your application
|
||||||
@ -19,5 +20,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
// Insert code here to tear down your application
|
// Insert code here to tear down your application
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func view_scale_1x(_ sender: Any) {
|
||||||
|
NotificationCenter.default.post(Notification(name: AppleScreenNotifications, object: "scaleFactor", userInfo: ["scaleFactor": 1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func view_scale_2x(_ sender: Any) {
|
||||||
|
NotificationCenter.default.post(Notification(name: AppleScreenNotifications, object: "scaleFactor", userInfo: ["scaleFactor": 2]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
67
FruitMachine/AppleI/AppleI.swift
Normal file
67
FruitMachine/AppleI/AppleI.swift
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// AppleI.swift
|
||||||
|
// FruitMachine
|
||||||
|
//
|
||||||
|
// Created by Christopher Rohl on 7/27/17.
|
||||||
|
// Copyright © 2017 Christopher Rohl. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class AppleI: NSObject {
|
||||||
|
static let sharedInstance = AppleI()
|
||||||
|
|
||||||
|
let cg = CharacterGenerator(romPath: "/Users/luigi/apple1/apple1.vid");
|
||||||
|
let terminal = Terminal()
|
||||||
|
|
||||||
|
let emulatorViewDelegate = AppleScreenViewDelegate()
|
||||||
|
let emulatorView = AppleScreenView(frame: NSMakeRect(0, 0, 400, 384))
|
||||||
|
let emuScreenLayer = CALayer()
|
||||||
|
|
||||||
|
static let CPU_FREQUENCY = 1000000
|
||||||
|
static let FRAMES_PER_SECOND = 60
|
||||||
|
static let CYCLES_PER_BATCH = CPU_FREQUENCY / FRAMES_PER_SECOND
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
emulatorView.wantsLayer = true
|
||||||
|
emuScreenLayer.delegate = emulatorViewDelegate
|
||||||
|
emuScreenLayer.frame = emulatorView.bounds
|
||||||
|
emuScreenLayer.setNeedsDisplay()
|
||||||
|
emulatorView.layer?.addSublayer(emuScreenLayer)
|
||||||
|
|
||||||
|
installOverrides()
|
||||||
|
|
||||||
|
for (cellNum, character) in terminal.characters.enumerated() {
|
||||||
|
emulatorViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: character), pixelPosition: emulatorViewDelegate.getPixelOffset(charCellIndex: cellNum))
|
||||||
|
}
|
||||||
|
|
||||||
|
CPU.sharedInstance.memoryInterface.loadBinary(path: "/Users/luigi/apple1/apple1.rom", offset: 0xFF00)
|
||||||
|
CPU.sharedInstance.performReset()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func installOverrides() {
|
||||||
|
CPU.sharedInstance.memoryInterface.write_overrides.append(PIAOverrides.writeDSP)
|
||||||
|
CPU.sharedInstance.memoryInterface.read_overrides.append(PIAOverrides.readDSP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runFrame() {
|
||||||
|
CPU.sharedInstance.cycles = 0
|
||||||
|
CPU.sharedInstance.cyclesInBatch = AppleI.CYCLES_PER_BATCH
|
||||||
|
CPU.sharedInstance.runCyclesBatch()
|
||||||
|
|
||||||
|
//update the video display
|
||||||
|
for (cellNum, character) in terminal.characters.enumerated() {
|
||||||
|
if(character == 0x8D) //CR
|
||||||
|
{
|
||||||
|
continue //ignore for now
|
||||||
|
}
|
||||||
|
|
||||||
|
emulatorViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: character), pixelPosition: emulatorViewDelegate.getPixelOffset(charCellIndex: cellNum))
|
||||||
|
}
|
||||||
|
|
||||||
|
emulatorView.display()
|
||||||
|
}
|
||||||
|
}
|
@ -10,10 +10,6 @@ import Cocoa
|
|||||||
|
|
||||||
class AppleScreenView: NSView {
|
class AppleScreenView: NSView {
|
||||||
|
|
||||||
//In characters
|
|
||||||
static let TERMINAL_WIDTH = 40
|
|
||||||
static let TERMINAL_HEIGHT = 24
|
|
||||||
|
|
||||||
override func draw(_ dirtyRect: NSRect) {
|
override func draw(_ dirtyRect: NSRect) {
|
||||||
super.draw(dirtyRect)
|
super.draw(dirtyRect)
|
||||||
// Drawing code here.
|
// Drawing code here.
|
@ -52,7 +52,7 @@ class AppleScreenViewDelegate: NSObject, CALayerDelegate {
|
|||||||
|
|
||||||
for charY in 0..<CharacterGenerator.CHAR_HEIGHT {
|
for charY in 0..<CharacterGenerator.CHAR_HEIGHT {
|
||||||
for charX in 0..<CharacterGenerator.CHAR_WIDTH {
|
for charX in 0..<CharacterGenerator.CHAR_WIDTH {
|
||||||
indexedPixels[baseOffset + (PIXEL_WIDTH * charY) + CharacterGenerator.CHAR_WIDTH - charX] = (charPixels[charY] & UInt8(1 << charX)) > 0 ? 1 : 0
|
indexedPixels[baseOffset + (PIXEL_WIDTH * charY) + CharacterGenerator.CHAR_WIDTH - charX - 1] = (charPixels[charY] & UInt8(1 << charX)) > 0 ? 1 : 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,6 +61,10 @@ class AppleScreenViewDelegate: NSObject, CALayerDelegate {
|
|||||||
return CGPoint(x: charCellX * 5, y: charCellY * 8)
|
return CGPoint(x: charCellX * 5, y: charCellY * 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPixelOffset(charCellIndex: Int) -> CGPoint {
|
||||||
|
return getPixelOffset(charCellX: charCellIndex % Terminal.CELLS_WIDTH, charCellY: charCellIndex / Terminal.CELLS_WIDTH)
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw the screen. */
|
/* Draw the screen. */
|
||||||
func draw(_ layer: CALayer, in ctx: CGContext) {
|
func draw(_ layer: CALayer, in ctx: CGContext) {
|
||||||
let bounds = layer.bounds
|
let bounds = layer.bounds
|
||||||
@ -70,8 +74,8 @@ class AppleScreenViewDelegate: NSObject, CALayerDelegate {
|
|||||||
let pixelProvider = CGDataProvider(data: NSData(bytes: &pixels, length: pixels.count * MemoryLayout<PixelData>.size))
|
let pixelProvider = CGDataProvider(data: NSData(bytes: &pixels, length: pixels.count * MemoryLayout<PixelData>.size))
|
||||||
|
|
||||||
let renderedImage = CGImage(width: PIXEL_WIDTH, height: PIXEL_HEIGHT, bitsPerComponent: Int(bitsPerComponent), bitsPerPixel: Int(bitsPerPixel), bytesPerRow: PIXEL_WIDTH * Int(MemoryLayout<PixelData>.size), space: colorSpace, bitmapInfo: bitmapInfo, provider: pixelProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
|
let renderedImage = CGImage(width: PIXEL_WIDTH, height: PIXEL_HEIGHT, bitsPerComponent: Int(bitsPerComponent), bitsPerPixel: Int(bitsPerPixel), bytesPerRow: PIXEL_WIDTH * Int(MemoryLayout<PixelData>.size), space: colorSpace, bitmapInfo: bitmapInfo, provider: pixelProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
|
||||||
|
|
||||||
ctx.draw(renderedImage!, in: bounds)
|
ctx.draw(renderedImage!, in: bounds)
|
||||||
//draw stuff here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -35,8 +35,26 @@ class CharacterGenerator: NSObject {
|
|||||||
func getCharacterPixels(charIndex: UInt8) -> [UInt8] {
|
func getCharacterPixels(charIndex: UInt8) -> [UInt8] {
|
||||||
var pixelArray = [UInt8](repeating: 0x00, count: CharacterGenerator.CHAR_HEIGHT)
|
var pixelArray = [UInt8](repeating: 0x00, count: CharacterGenerator.CHAR_HEIGHT)
|
||||||
|
|
||||||
|
/* Instead of ignoring ASCII bit b6, we ignore bit b5. At the same time ASCII bit b6 must be inverted before it is fed to the character ROM. This way the entire character range from $40 to $7F will end up in the range $00 to $1F (twice of course). Now lower case characters are automatically translated into their corresponding upper case bit maps.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var convertedCharIndex = charIndex & 0x7F
|
||||||
|
convertedCharIndex = convertedCharIndex & ~(0x20)
|
||||||
|
convertedCharIndex = convertedCharIndex & ~(0x40)
|
||||||
|
|
||||||
|
/*
|
||||||
|
if((convertedCharIndex & 0x40) == 0x40)
|
||||||
|
{
|
||||||
|
convertedCharIndex = convertedCharIndex & ~(0x40)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
convertedCharIndex = convertedCharIndex | 0x40
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
for scanlineIndex in 0..<CharacterGenerator.CHAR_HEIGHT {
|
for scanlineIndex in 0..<CharacterGenerator.CHAR_HEIGHT {
|
||||||
pixelArray[scanlineIndex] = ROM[scanlineIndex + (Int(charIndex) * CharacterGenerator.CHAR_HEIGHT)]
|
pixelArray[scanlineIndex] = ROM[scanlineIndex + (Int(convertedCharIndex) * CharacterGenerator.CHAR_HEIGHT)]
|
||||||
}
|
}
|
||||||
|
|
||||||
return pixelArray
|
return pixelArray
|
23
FruitMachine/AppleI/Video/PIAOverrides.swift
Normal file
23
FruitMachine/AppleI/Video/PIAOverrides.swift
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Overrides.swift
|
||||||
|
// FruitMachine
|
||||||
|
//
|
||||||
|
// Created by Christopher Rohl on 7/27/17.
|
||||||
|
// Copyright © 2017 Christopher Rohl. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class PIAOverrides: NSObject {
|
||||||
|
static let writeDSP = WriteOverride(start: 0xD012, end: 0xD012, writeValue: false, action: PIAOverrides.actionWriteDSP)
|
||||||
|
static func actionWriteDSP(terminal: AnyObject, byte: UInt8?) -> Void {
|
||||||
|
//(terminal as! Terminal).putCharacter(charIndex: byte!)
|
||||||
|
AppleI.sharedInstance.terminal.putCharacter(charIndex: byte!)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let readDSP = ReadOverride(start: 0xD012, end: 0xD012, writeValue: false, action: PIAOverrides.actionReadDSP)
|
||||||
|
static func actionReadDSP(terminal: AnyObject, byte: UInt8?) -> Void {
|
||||||
|
CPU.sharedInstance.memoryInterface.writeByte(offset: 0xD012, value: CPU.sharedInstance.memoryInterface.readByte(offset: 0xD012, bypassOverrides: true) & 0x7F, bypassOverrides: true) //the display is always ready
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
FruitMachine/AppleI/Video/Terminal.swift
Normal file
47
FruitMachine/AppleI/Video/Terminal.swift
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Terminal.swift
|
||||||
|
// FruitMachine
|
||||||
|
//
|
||||||
|
// Created by Christopher Rohl on 7/27/17.
|
||||||
|
// Copyright © 2017 Christopher Rohl. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
struct Cell {
|
||||||
|
var x: Int
|
||||||
|
var y: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
class Terminal: NSObject {
|
||||||
|
static let CELLS_WIDTH = 40
|
||||||
|
static let CELLS_HEIGHT = 24
|
||||||
|
|
||||||
|
var cursorPosition: Cell
|
||||||
|
var characters: [UInt8]
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
cursorPosition = Cell(x: 0, y: 0)
|
||||||
|
characters = [UInt8](repeating: 0x40, count: Terminal.CELLS_WIDTH * Terminal.CELLS_HEIGHT)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cellToIndex(cell: Cell) -> Int {
|
||||||
|
return (cell.y * Terminal.CELLS_WIDTH) + (cell.x % Terminal.CELLS_WIDTH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func putCharacter(charIndex: UInt8) {
|
||||||
|
characters[cellToIndex(cell: cursorPosition)] = charIndex
|
||||||
|
advanceCursor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func advanceCursor() {
|
||||||
|
cursorPosition.x += 1
|
||||||
|
if(cursorPosition.x == Terminal.CELLS_WIDTH) {
|
||||||
|
cursorPosition.x = 0
|
||||||
|
cursorPosition.y += 1
|
||||||
|
if(cursorPosition.y == Terminal.CELLS_HEIGHT) {
|
||||||
|
cursorPosition.y = 0 //TODO: scrolling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -629,6 +629,17 @@
|
|||||||
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
|
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="Lvb-d5-deQ"/>
|
||||||
|
<menuItem title="Scale 1x" keyEquivalent="1" id="nfL-VA-aet">
|
||||||
|
<connections>
|
||||||
|
<action selector="view_scale_1x:" target="Voe-Tx-rLC" id="QA5-yc-5zm"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Scale 2x" keyEquivalent="2" id="FYi-S6-fCx">
|
||||||
|
<connections>
|
||||||
|
<action selector="view_scale_2x:" target="Voe-Tx-rLC" id="rxd-VR-X3F"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
@ -116,7 +116,9 @@ class CPU: NSObject {
|
|||||||
let RESET_VECTOR: UInt16 = 0xFFFC
|
let RESET_VECTOR: UInt16 = 0xFFFC
|
||||||
let IRQ_VECTOR: UInt16 = 0xFFFE
|
let IRQ_VECTOR: UInt16 = 0xFFFE
|
||||||
|
|
||||||
static var sharedInstance = CPU()
|
static let sharedInstance = CPU()
|
||||||
|
|
||||||
|
var isRunning: Bool
|
||||||
|
|
||||||
var cycles: Int
|
var cycles: Int
|
||||||
var cyclesInBatch: Int
|
var cyclesInBatch: Int
|
||||||
@ -138,6 +140,8 @@ class CPU: NSObject {
|
|||||||
var breakpoints: [UInt16]
|
var breakpoints: [UInt16]
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
|
isRunning = false
|
||||||
|
|
||||||
cycles = 0
|
cycles = 0
|
||||||
cyclesInBatch = 0
|
cyclesInBatch = 0
|
||||||
|
|
||||||
@ -216,7 +220,7 @@ class CPU: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkOutOfCycles() -> Bool {
|
func outOfCycles() -> Bool {
|
||||||
if(cycles > cyclesInBatch) {
|
if(cycles > cyclesInBatch) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@ -238,4 +242,28 @@ class CPU: NSObject {
|
|||||||
status_register.zero = (value == 0)
|
status_register.zero = (value == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Running */
|
||||||
|
func cpuStep() {
|
||||||
|
do {
|
||||||
|
try executeNextInstruction()
|
||||||
|
} catch CPUExceptions.invalidInstruction {
|
||||||
|
isRunning = false
|
||||||
|
} catch {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCyclesBatch() {
|
||||||
|
isRunning = true
|
||||||
|
|
||||||
|
while(!outOfCycles() && isRunning) {
|
||||||
|
cpuStep()
|
||||||
|
|
||||||
|
if (breakpoints.contains(program_counter)) {
|
||||||
|
isRunning = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<!--Window Controller-->
|
<!--Window Controller-->
|
||||||
<scene sceneID="R2V-B0-nI4">
|
<scene sceneID="R2V-B0-nI4">
|
||||||
<objects>
|
<objects>
|
||||||
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
|
<windowController id="B8D-0N-5wS" customClass="DebuggerWindowController" customModule="FruitMachine" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<window key="window" title="Debugger" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
|
<window key="window" title="Debugger" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
@ -46,7 +46,7 @@ class DebuggerViewController: NSViewController {
|
|||||||
text_CPU_SR.stringValue = String(format:"%02X", cpuInstance.stack_pointer)
|
text_CPU_SR.stringValue = String(format:"%02X", cpuInstance.stack_pointer)
|
||||||
text_CPU_Flags.stringValue = String(cpuInstance.status_register.asString())
|
text_CPU_Flags.stringValue = String(cpuInstance.status_register.asString())
|
||||||
|
|
||||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 65535)
|
disassembly = cpuInstance.disassemble(fromAddress: CPU.sharedInstance.program_counter, length: 256)
|
||||||
highlightCurrentInstruction()
|
highlightCurrentInstruction()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,15 +56,10 @@ class DebuggerViewController: NSViewController {
|
|||||||
debuggerTableView.delegate = self
|
debuggerTableView.delegate = self
|
||||||
debuggerTableView.dataSource = self
|
debuggerTableView.dataSource = self
|
||||||
|
|
||||||
cpuInstance.memoryInterface.loadBinary(path: "/Users/luigi/6502/test.bin")
|
|
||||||
cpuInstance.performReset()
|
|
||||||
cpuInstance.program_counter = 0x400 //entry point for the test program
|
|
||||||
updateCPUStatusFields()
|
updateCPUStatusFields()
|
||||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 65535)
|
disassembly = cpuInstance.disassemble(fromAddress: CPU.sharedInstance.program_counter, length: 256)
|
||||||
debuggerTableView.reloadData()
|
debuggerTableView.reloadData()
|
||||||
|
|
||||||
cpuInstance.breakpoints.append(0x34E8) //failing at $34FD SBC test
|
|
||||||
|
|
||||||
// Do any additional setup after loading the view.
|
// Do any additional setup after loading the view.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,25 +69,14 @@ class DebuggerViewController: NSViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cpuStep() {
|
func debugRun() {
|
||||||
do {
|
|
||||||
try cpuInstance.executeNextInstruction()
|
|
||||||
} catch CPUExceptions.invalidInstruction {
|
|
||||||
isRunning = false
|
|
||||||
|
|
||||||
} catch {
|
|
||||||
print(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func cpuRun() {
|
|
||||||
isRunning = true
|
isRunning = true
|
||||||
|
|
||||||
cpuInstance.cycles = 0
|
cpuInstance.cycles = 0
|
||||||
cpuInstance.cyclesInBatch = 1000000
|
cpuInstance.cyclesInBatch = 1000000
|
||||||
|
|
||||||
while(!cpuInstance.checkOutOfCycles() && isRunning) {
|
while(!cpuInstance.outOfCycles() && isRunning) {
|
||||||
cpuStep()
|
cpuInstance.cpuStep()
|
||||||
|
|
||||||
if (cpuInstance.breakpoints.contains(cpuInstance.program_counter)) {
|
if (cpuInstance.breakpoints.contains(cpuInstance.program_counter)) {
|
||||||
isRunning = false
|
isRunning = false
|
||||||
@ -105,12 +89,12 @@ class DebuggerViewController: NSViewController {
|
|||||||
|
|
||||||
func queueCPUStep(queue: DispatchQueue) {
|
func queueCPUStep(queue: DispatchQueue) {
|
||||||
queue.async {
|
queue.async {
|
||||||
self.cpuStep()
|
self.cpuInstance.cpuStep()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func btn_CPUStep(_ sender: Any) {
|
@IBAction func btn_CPUStep(_ sender: Any) {
|
||||||
cpuStep()
|
cpuInstance.cpuStep()
|
||||||
updateCPUStatusFields()
|
updateCPUStatusFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +104,7 @@ class DebuggerViewController: NSViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func btn_CPURun(_ sender: Any) {
|
@IBAction func btn_CPURun(_ sender: Any) {
|
||||||
cpuRun()
|
debugRun()
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func btn_CPU_Restart(_ sender: Any) {
|
@IBAction func btn_CPU_Restart(_ sender: Any) {
|
||||||
@ -155,6 +139,11 @@ extension DebuggerViewController: NSTableViewDelegate {
|
|||||||
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
||||||
var cellText: String = ""
|
var cellText: String = ""
|
||||||
var cellIdentifier: String = ""
|
var cellIdentifier: String = ""
|
||||||
|
|
||||||
|
if(row >= disassembly.count) {
|
||||||
|
return nil //no cell
|
||||||
|
}
|
||||||
|
|
||||||
let operation = disassembly[row]
|
let operation = disassembly[row]
|
||||||
|
|
||||||
if(tableColumn == tableView.tableColumns[0]) {
|
if(tableColumn == tableView.tableColumns[0]) {
|
||||||
|
19
FruitMachine/M6502/Debugger/DebuggerWindowController.swift
Normal file
19
FruitMachine/M6502/Debugger/DebuggerWindowController.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// DebuggerWindowController.swift
|
||||||
|
// FruitMachine
|
||||||
|
//
|
||||||
|
// Created by Christopher Rohl on 7/27/17.
|
||||||
|
// Copyright © 2017 Christopher Rohl. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class DebuggerWindowController: NSWindowController {
|
||||||
|
|
||||||
|
override func windowDidLoad() {
|
||||||
|
super.windowDidLoad()
|
||||||
|
|
||||||
|
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -74,7 +74,7 @@ extension CPU {
|
|||||||
var disassembly: [Disassembly] = [Disassembly]()
|
var disassembly: [Disassembly] = [Disassembly]()
|
||||||
|
|
||||||
var currentAddress: UInt16 = fromAddress
|
var currentAddress: UInt16 = fromAddress
|
||||||
let endAddress: UInt16 = fromAddress + length
|
let endAddress: UInt16 = max(fromAddress &+ length, 0xFFFF)
|
||||||
|
|
||||||
while(currentAddress < endAddress) {
|
while(currentAddress < endAddress) {
|
||||||
let instruction = memoryInterface.readByte(offset: currentAddress)
|
let instruction = memoryInterface.readByte(offset: currentAddress)
|
||||||
|
@ -21,21 +21,30 @@ class MemoryInterface: NSObject {
|
|||||||
write_overrides = [WriteOverride]()
|
write_overrides = [WriteOverride]()
|
||||||
}
|
}
|
||||||
|
|
||||||
func readByte(offset: UInt16) -> UInt8 {
|
func readByte(offset: UInt16, bypassOverrides: Bool = false) -> UInt8 {
|
||||||
|
|
||||||
|
if(!bypassOverrides) {
|
||||||
for override in read_overrides {
|
for override in read_overrides {
|
||||||
if case override.rangeStart ... override.rangeEnd = offset {
|
if case override.rangeStart ... override.rangeEnd = offset {
|
||||||
override.action(CPU.sharedInstance, nil)
|
override.action(CPU.sharedInstance, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//No match.
|
//No match.
|
||||||
return memory[Int(offset)]
|
return memory[Int(offset)]
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeByte(offset: UInt16, value: UInt8) {
|
func writeByte(offset: UInt16, value: UInt8, bypassOverrides: Bool = false) {
|
||||||
for override in read_overrides {
|
|
||||||
|
if(!bypassOverrides) {
|
||||||
|
for override in write_overrides {
|
||||||
if case override.rangeStart ... override.rangeEnd = offset {
|
if case override.rangeStart ... override.rangeEnd = offset {
|
||||||
override.action(CPU.sharedInstance, value)
|
override.action(CPU.sharedInstance, value)
|
||||||
|
if(!override.writeValue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +57,10 @@ class MemoryInterface: NSObject {
|
|||||||
return (UInt16(high) << 8) | UInt16(low)
|
return (UInt16(high) << 8) | UInt16(low)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadBinary(path: String) {
|
func loadBinary(path: String, offset: UInt16) {
|
||||||
do {
|
do {
|
||||||
let fileContent: NSData = try NSData(contentsOfFile: path)
|
let fileContent: NSData = try NSData(contentsOfFile: path)
|
||||||
fileContent.getBytes(&memory, range: NSRange(location: 0, length: 65536))
|
fileContent.getBytes(&memory[Int(offset)], range: NSRange(location: 0, length: 256))
|
||||||
} catch {
|
} catch {
|
||||||
print(error)
|
print(error)
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,14 @@ import Cocoa
|
|||||||
class MemoryOverride: NSObject {
|
class MemoryOverride: NSObject {
|
||||||
let rangeStart: UInt16
|
let rangeStart: UInt16
|
||||||
let rangeEnd: UInt16
|
let rangeEnd: UInt16
|
||||||
|
let writeValue: Bool
|
||||||
|
|
||||||
let action: (CPU, UInt8?) -> Void
|
let action: (CPU, UInt8?) -> Void
|
||||||
|
|
||||||
init(start: UInt16, end: UInt16, action: @escaping (CPU, UInt8?) -> Void) {
|
init(start: UInt16, end: UInt16, writeValue: Bool, action: @escaping (AnyObject, UInt8?) -> Void) {
|
||||||
rangeStart = start
|
rangeStart = start
|
||||||
rangeEnd = end
|
rangeEnd = end
|
||||||
|
self.writeValue = writeValue
|
||||||
|
|
||||||
self.action = action
|
self.action = action
|
||||||
}
|
}
|
||||||
|
@ -10,36 +10,23 @@ import Cocoa
|
|||||||
import CoreGraphics
|
import CoreGraphics
|
||||||
|
|
||||||
class MainViewController: NSViewController {
|
class MainViewController: NSViewController {
|
||||||
var windowController: NSWindowController?
|
|
||||||
var debuggerViewController = DebuggerViewController()
|
|
||||||
let emuScreenLayer = CALayer()
|
|
||||||
|
|
||||||
let cg = CharacterGenerator(romPath: "/Users/luigi/apple1/apple1.vid");
|
let computer = AppleI.sharedInstance
|
||||||
var appleScreenView: AppleScreenView = AppleScreenView(frame: NSMakeRect(0, 0, 400, 384))
|
|
||||||
let appleScreenViewDelegate = AppleScreenViewDelegate()
|
var debuggerWindowController: DebuggerWindowController!
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
let debuggerStoryboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Debugger"), bundle: nil)
|
||||||
|
debuggerWindowController = debuggerStoryboard.instantiateInitialController() as! DebuggerWindowController
|
||||||
|
debuggerWindowController.showWindow(self)
|
||||||
|
|
||||||
// Do view setup here.
|
// Do view setup here.
|
||||||
self.view.addSubview(appleScreenView)
|
self.view.addSubview(computer.emulatorView)
|
||||||
|
computer.emulatorView.display()
|
||||||
|
|
||||||
appleScreenView.wantsLayer = true
|
computer.runFrame()
|
||||||
|
|
||||||
emuScreenLayer.delegate = appleScreenViewDelegate
|
|
||||||
emuScreenLayer.frame = appleScreenView.bounds
|
|
||||||
emuScreenLayer.setNeedsDisplay()
|
|
||||||
appleScreenView.layer?.addSublayer(emuScreenLayer)
|
|
||||||
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x00), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 0, charCellY: 0))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x01), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 1, charCellY: 1))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x02), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 2, charCellY: 2))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x03), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 3, charCellY: 3))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x04), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 4, charCellY: 4))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x05), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 5, charCellY: 5))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x06), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 6, charCellY: 6))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x07), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 7, charCellY: 7))
|
|
||||||
appleScreenViewDelegate.putCharacterPixels(charPixels: cg.getCharacterPixels(charIndex: 0x08), pixelPosition: appleScreenViewDelegate.getPixelOffset(charCellX: 8, charCellY: 8))
|
|
||||||
|
|
||||||
appleScreenView.display()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
8
FruitMachine/MainViewStoryboard.storyboard
Normal file
8
FruitMachine/MainViewStoryboard.storyboard
Normal file
@ -0,0 +1,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">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13168.3"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes/>
|
||||||
|
</document>
|
Loading…
Reference in New Issue
Block a user