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 "common.h"
#include "Apple2_mmio.h" #include "Apple2_mmio.h"
#define SOFTRESET_VECTOR 0x3F2
/** /**
Instruction Implementations Instruction Implementations
!!!! `his has to be here!!! !!!! `his has to be here!!!
@ -25,7 +28,7 @@
///// /////
unsigned long long int clktime = 0; unsigned long long int clktime = 0;
m6502_s m6502 = {0}; m6502_t m6502 = {0};
static inline int m6502_step() { static inline int m6502_step() {
@ -327,8 +330,28 @@ static inline void m6502_run() {
// unsigned long long s = rdtsc(); // unsigned long long s = rdtsc();
unsigned long long e = (unsigned long long)-1LL; 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 ( ; 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); dbgPrintf("%04u %04X: ", clktime, m6502.pc);
clk = m6502_step(); clk = m6502_step();
clktime += clk; clktime += clk;

View File

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

View File

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

View File

@ -686,7 +686,7 @@
<windowController id="B8D-0N-5wS" sceneMemberID="viewController"> <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"> <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"/> <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"/> <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<connections> <connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/> <outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
@ -705,19 +705,60 @@
<objects> <objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="A2Mac" customModuleProvider="target" sceneMemberID="viewController"> <viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="A2Mac" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="m2S-Jp-Qdl"> <view key="view" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="480" height="440"/> <rect key="frame" x="0.0" y="0.0" width="810" height="440"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uza-t6-XSw"> <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uza-t6-XSw">
<rect key="frame" x="10" y="10" width="460" height="420"/> <rect key="frame" x="10" y="10" width="700" height="420"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <constraints>
<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"> <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"/> <font key="font" size="14" name="Courier-Bold"/>
<color key="textColor" name="systemGreenColor" catalog="System" colorSpace="catalog"/> <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"/> <color key="backgroundColor" red="0.12549019607843137" green="0.17933968321917809" blue="0.12549019607843137" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</textFieldCell> </textFieldCell>
</textField> </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> </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> </view>
<connections> <connections>
<outlet property="display" destination="5AO-Gd-Lzo" id="Khc-vv-2HB"/> <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 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() { func update() {
while true { while true {
@ -34,7 +120,7 @@ class ViewController: NSViewController {
let textLines = 24 let textLines = 24
let textCols = 40 let textCols = 40
var txt : String = "|" var txt : String = ""
for y in 0...textLines-1 { for y in 0...textLines-1 {
let textAddr = textBaseAddr + textLineOfs[y] let textAddr = textBaseAddr + textLineOfs[y]
@ -44,10 +130,10 @@ class ViewController: NSViewController {
let idx = Int(byte); let idx = Int(byte);
let chr = ViewController.charConvTbl[idx] let chr = ViewController.charConvTbl[idx]
// print("byte \(index): \(chr)") // 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() { override func viewDidLoad() {
super.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: { // DispatchQueue.main.asyncAfter(deadline: .now() + 1/30, execute: {
// self.update() // self.update()