Added basic keyboard functionality

Added Soft Reset support
Fixed few minor bugs
This commit is contained in:
Tamas Rudnai 2019-09-09 00:27:31 -07:00
parent f5ea13eb86
commit d644057a13
5 changed files with 217 additions and 86 deletions

View File

@ -13,6 +13,9 @@
#include "common.h"
#include "Apple2_mmio.h"
#define SOFTRESET_VECTOR 0x3F2
/**
Instruction Implementations
!!!! `his has to be here!!!
@ -25,7 +28,7 @@
/////
unsigned long long int clktime = 0;
m6502_s m6502 = {0};
m6502_t m6502 = {0};
static inline int m6502_step() {
@ -327,8 +330,28 @@ static inline void m6502_run() {
// unsigned long long s = rdtsc();
unsigned long long e = (unsigned long long)-1LL;
for ( unsigned long long int i = 0; i < iterations ; i++ ) {
// for ( unsigned long long int i = 0; i < iterations ; i++ ) {
// for ( ; m6502.pc ; ) {
for ( ; ; ) {
if ( m6502.interrupt_flag ) {
switch (m6502.interrupt) {
case NMI:
break;
case HARDRESET:
break;
case SOFTRESET:
m6502.pc = memread16(SOFTRESET_VECTOR);
break;
default:
break;
}
m6502.interrupt_flag = 0;
}
dbgPrintf("%04u %04X: ", clktime, m6502.pc);
clk = m6502_step();
clktime += clk;

View File

@ -17,6 +17,11 @@
#define dbgPrintf(format, ...)
#endif
typedef enum {
NMI,
HARDRESET,
SOFTRESET,
} interrupt_t;
typedef struct m6502_s {
uint8_t A; // Accumulator
@ -45,10 +50,15 @@ typedef struct m6502_s {
uint16_t pc; // Program Counter
uint16_t sp; // Stack Pointer
unsigned clk; // Clock Counter
} m6502_s;
union {
int interrupt_flag;
interrupt_t interrupt;
};
} m6502_t;
extern m6502_s m6502;
extern m6502_t m6502;
extern uint8_t RAM[ 64 * 1024 ];
extern void tst6502();

View File

@ -14,51 +14,51 @@
enum mmio {
ioSomething = 0xC000,
io_KBD = 0xC000,
io_KBDSTRB = 0xC010,
};
uint8_t RAM[ 64 * KB ] = {0};
#define PAGESIZE 256
#define PAGES 16
uint8_t ram_0[PAGESIZE];
uint8_t ram_1[PAGESIZE];
uint8_t ram_2[PAGESIZE];
uint8_t ram_3[PAGESIZE];
uint8_t ram_4[PAGESIZE];
uint8_t ram_5[PAGESIZE];
uint8_t ram_6[PAGESIZE];
uint8_t ram_7[PAGESIZE];
uint8_t ram_8[PAGESIZE];
uint8_t ram_9[PAGESIZE];
uint8_t ram_A[PAGESIZE];
uint8_t ram_B[PAGESIZE];
uint8_t aui_C[PAGESIZE];
uint8_t rom_D[PAGESIZE];
uint8_t rom_E[PAGESIZE];
uint8_t rom_F[PAGESIZE];
uint8_t * ram[PAGES] = {
ram_0,
ram_1,
ram_2,
ram_3,
ram_4,
ram_5,
ram_6,
ram_7,
ram_8,
ram_9,
ram_A,
ram_B,
aui_C,
rom_D,
rom_E,
rom_F,
};
//uint8_t ram_0[PAGESIZE];
//uint8_t ram_1[PAGESIZE];
//uint8_t ram_2[PAGESIZE];
//uint8_t ram_3[PAGESIZE];
//uint8_t ram_4[PAGESIZE];
//uint8_t ram_5[PAGESIZE];
//uint8_t ram_6[PAGESIZE];
//uint8_t ram_7[PAGESIZE];
//uint8_t ram_8[PAGESIZE];
//uint8_t ram_9[PAGESIZE];
//uint8_t ram_A[PAGESIZE];
//uint8_t ram_B[PAGESIZE];
//uint8_t aui_C[PAGESIZE];
//uint8_t rom_D[PAGESIZE];
//uint8_t rom_E[PAGESIZE];
//uint8_t rom_F[PAGESIZE];
//
//uint8_t * ram[PAGES] = {
// ram_0,
// ram_1,
// ram_2,
// ram_3,
// ram_4,
// ram_5,
// ram_6,
// ram_7,
// ram_8,
// ram_9,
// ram_A,
// ram_B,
// aui_C,
// rom_D,
// rom_E,
// rom_F,
//};
//uint8_t ( * mmio_read [ 64 * KB ] )( uint16_t addr );
@ -74,9 +74,12 @@ typedef union address16_u {
static inline uint8_t ioRead( uint16_t addr ) {
// printf("mmio:%04X\n", addr);
switch (addr) {
case ioSomething:
return 123;
case io_KBD:
return RAM[addr];
case io_KBDSTRB:
return RAM[io_KBD] &= 0x7F;
default:
break;
}
@ -86,7 +89,7 @@ static inline uint8_t ioRead( uint16_t addr ) {
static inline void ioWrite( uint16_t addr ) {
// printf("mmio:%04X\n", addr);
switch (addr) {
case ioSomething:
case io_KBD:
return;
default:

View File

@ -686,7 +686,7 @@
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="440"/>
<rect key="contentRect" x="196" y="240" width="810" height="440"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
@ -705,19 +705,60 @@
<objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="A2Mac" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="480" height="440"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<rect key="frame" x="0.0" y="0.0" width="810" height="440"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uza-t6-XSw">
<rect key="frame" x="10" y="10" width="460" height="420"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" enabled="NO" refusesFirstResponder="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" state="on" borderStyle="border" alignment="center" placeholderString="Apple ][ Emulator Virtual Monitor" drawsBackground="YES" allowsEditingTextAttributes="YES" id="5AO-Gd-Lzo">
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uza-t6-XSw">
<rect key="frame" x="10" y="10" width="700" height="420"/>
<constraints>
<constraint firstAttribute="width" constant="700" id="YGY-gy-pSn"/>
<constraint firstAttribute="height" constant="420" id="dWL-EL-ab7"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" enabled="NO" allowsUndo="NO" sendsActionOnEndEditing="YES" state="on" borderStyle="border" alignment="center" placeholderString="Apple ][ Emulator Virtual Monitor" drawsBackground="YES" id="5AO-Gd-Lzo">
<font key="font" size="14" name="Courier-Bold"/>
<color key="textColor" name="systemGreenColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" red="0.12549019607843137" green="0.17933968321917809" blue="0.12549019607843137" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mfd-12-bcR">
<rect key="frame" x="714" y="402" width="92" height="32"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="t2i-0h-wau"/>
</constraints>
<buttonCell key="cell" type="push" title="Power" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="hmD-vF-EXJ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="Power:" target="XfG-lQ-9wD" id="IvK-jh-tRI"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rR3-9T-NFu">
<rect key="frame" x="714" y="371" width="92" height="32"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="sbX-nh-SV3"/>
</constraints>
<buttonCell key="cell" type="push" title="Reset" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="LHj-7W-LwD">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<connections>
<action selector="Reset:" target="XfG-lQ-9wD" id="1Q2-mr-CEh"/>
</connections>
</buttonCell>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="mfd-12-bcR" secondAttribute="trailing" constant="10" id="3NC-0i-OPC"/>
<constraint firstAttribute="trailing" secondItem="rR3-9T-NFu" secondAttribute="trailing" constant="10" id="68s-0C-BVZ"/>
<constraint firstItem="mfd-12-bcR" firstAttribute="leading" secondItem="Uza-t6-XSw" secondAttribute="trailing" constant="10" id="CFN-hq-O5V"/>
<constraint firstItem="Uza-t6-XSw" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="10" id="Dmb-dB-rhg"/>
<constraint firstAttribute="trailing" secondItem="Uza-t6-XSw" secondAttribute="trailing" constant="100" id="UBG-e6-psp"/>
<constraint firstAttribute="bottom" secondItem="Uza-t6-XSw" secondAttribute="bottom" constant="10" id="agC-TV-DPy"/>
<constraint firstItem="Uza-t6-XSw" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" constant="10" id="kDF-dq-M0E"/>
<constraint firstItem="rR3-9T-NFu" firstAttribute="leading" secondItem="Uza-t6-XSw" secondAttribute="trailing" constant="10" id="kOZ-D6-JaQ"/>
<constraint firstItem="rR3-9T-NFu" firstAttribute="top" secondItem="mfd-12-bcR" secondAttribute="bottom" constant="10" id="ycb-iY-X4I"/>
<constraint firstItem="mfd-12-bcR" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="10" id="zDl-Cs-xmz"/>
</constraints>
</view>
<connections>
<outlet property="display" destination="5AO-Gd-Lzo" id="Khc-vv-2HB"/>

View File

@ -25,6 +25,92 @@ class ViewController: NSViewController {
0x228, 0x2A8, 0x328, 0x3A8, 0x050, 0x0D0, 0x150, 0x1D0, 0x250, 0x2D0, 0x350, 0x3D0
]
@IBAction func Power(_ sender: Any) {
DispatchQueue.global(qos: .userInitiated).async {
tst6502()
}
}
@IBAction func Reset(_ sender: Any) {
// let resetPointer = UnsafeRawBufferPointer(start: &RAM + 0x3F2, count: 2)
// let ral = UInt16(resetPointer[0])
// let rah = UInt16(resetPointer[1])
// let resetAddr = rah << 8 + ral
//
// let hex = String(resetAddr, radix: 16, uppercase: true)
// print("reset to:\(hex)\n")
// m6502.pc = resetAddr
m6502.interrupt = SOFTRESET;
}
override func keyDown(with event: NSEvent) {
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.command] where event.characters == "l",
[.command, .shift] where event.characters == "l":
print("command-l or command-shift-l")
default:
break
}
print( "key = " + (event.charactersIgnoringModifiers ?? ""))
print( "\ncharacter = " + (event.characters ?? ""))
if let chars = event.characters {
let char = chars[chars.startIndex]
if let code = char.asciiValue {
var A2code = code + 0x60
if ( code == 13 ) {
A2code = 141
}
print("keycode: \(code) --> \(A2code)")
let resetPointer = UnsafeMutableRawBufferPointer(start: &RAM + 0xC000, count: 1)
resetPointer[0] = A2code
}
}
}
override func flagsChanged(with event: NSEvent) {
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.shift]:
print("shift key is pressed")
case [.control]:
print("control key is pressed")
case [.option] :
print("option key is pressed")
case [.command]:
print("Command key is pressed")
case [.control, .shift]:
print("control-shift keys are pressed")
case [.option, .shift]:
print("option-shift keys are pressed")
case [.command, .shift]:
print("command-shift keys are pressed")
case [.control, .option]:
print("control-option keys are pressed")
case [.control, .command]:
print("control-command keys are pressed")
case [.option, .command]:
print("option-command keys are pressed")
case [.shift, .control, .option]:
print("shift-control-option keys are pressed")
case [.shift, .control, .command]:
print("shift-control-command keys are pressed")
case [.control, .option, .command]:
print("control-option-command keys are pressed")
case [.shift, .command, .option]:
print("shift-command-option keys are pressed")
case [.shift, .control, .option, .command]:
print("shift-control-option-command keys are pressed")
default:
print("no modifier keys are pressed")
}
}
func update() {
while true {
@ -34,7 +120,7 @@ class ViewController: NSViewController {
let textLines = 24
let textCols = 40
var txt : String = "|"
var txt : String = ""
for y in 0...textLines-1 {
let textAddr = textBaseAddr + textLineOfs[y]
@ -44,10 +130,10 @@ class ViewController: NSViewController {
let idx = Int(byte);
let chr = ViewController.charConvTbl[idx]
// print("byte \(index): \(chr)")
txt = txt + [chr]
txt = txt + " \(chr)"
}
txt = txt + "|\n|"
txt = txt + " |\n"
}
@ -74,38 +160,6 @@ class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
display.stringValue = "lll"
// emulate in he background
// DispatchQueue.global(qos: .background).async {
DispatchQueue.global(qos: .userInitiated).async {
tst6502()
}
// let r = RAM.1
// let r = UnsafeMutablePointer<UInt8>(RAM)
// let r = withUnsafeBytes(of: &RAM) { (rawPtr) -> Array<uint8> in
// let ptr = rawPtr.baseAddress!.assumingMemoryBound(to: uint8.self)
// return Array(ptr)
// }
// This seem to work:
// var ram: [UInt8] = []
// withUnsafeBytes(of: &RAM) {
// ram.append(contentsOf: $0)
// }
// let string = String(bytes: ram, encoding: .utf8)
// ...but this does not:
// let text = ""
// while(true) {
// for i in 0x400...0x7FF {
// text += screenBuffer[i]
// }
// }
// DispatchQueue.main.asyncAfter(deadline: .now() + 1/30, execute: {
// self.update()