mirror of
https://github.com/trudnai/Steve2.git
synced 2024-12-30 14:29:56 +00:00
Added basic keyboard functionality
Added Soft Reset support Fixed few minor bugs
This commit is contained in:
parent
f5ea13eb86
commit
d644057a13
27
A2Mac/6502.c
27
A2Mac/6502.c
@ -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;
|
||||
|
14
A2Mac/6502.h
14
A2Mac/6502.h
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -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"/>
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user