2016-10-12 02:20:13 +00:00
|
|
|
//
|
|
|
|
// CSOric.m
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 11/10/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "CSOric.h"
|
|
|
|
|
|
|
|
#include "Oric.hpp"
|
|
|
|
#include "StaticAnalyser.hpp"
|
|
|
|
|
|
|
|
#import "CSMachine+Subclassing.h"
|
|
|
|
#import "NSData+StdVector.h"
|
|
|
|
#import "NSBundle+DataResource.h"
|
|
|
|
|
2017-07-23 02:17:29 +00:00
|
|
|
@implementation CSOric {
|
2017-08-16 18:35:53 +00:00
|
|
|
std::unique_ptr<Oric::Machine> _oric;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (CRTMachine::Machine * const)machine {
|
|
|
|
if(!_oric) {
|
|
|
|
_oric.reset(Oric::Machine::Oric());
|
|
|
|
}
|
|
|
|
return _oric.get();
|
2016-10-12 02:20:13 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 02:17:29 +00:00
|
|
|
- (instancetype)init {
|
2016-10-12 22:51:02 +00:00
|
|
|
self = [super init];
|
2017-07-23 02:17:29 +00:00
|
|
|
if(self) {
|
2016-11-15 02:39:16 +00:00
|
|
|
NSData *basic10 = [self rom:@"basic10"];
|
2016-11-21 12:59:25 +00:00
|
|
|
NSData *basic11 = [self rom:@"basic11"];
|
2016-12-10 03:17:10 +00:00
|
|
|
NSData *colour = [self rom:@"colour"];
|
2016-11-21 12:59:25 +00:00
|
|
|
NSData *microdisc = [self rom:@"microdisc"];
|
2016-11-15 02:39:16 +00:00
|
|
|
|
2017-08-16 18:35:53 +00:00
|
|
|
if(basic10) _oric->set_rom(Oric::BASIC10, basic10.stdVector8);
|
|
|
|
if(basic11) _oric->set_rom(Oric::BASIC11, basic11.stdVector8);
|
|
|
|
if(colour) _oric->set_rom(Oric::Colour, colour.stdVector8);
|
|
|
|
if(microdisc) _oric->set_rom(Oric::Microdisc, microdisc.stdVector8);
|
2016-10-12 22:51:02 +00:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2017-07-23 02:17:29 +00:00
|
|
|
- (NSData *)rom:(NSString *)name {
|
2016-10-12 22:51:02 +00:00
|
|
|
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Oric"];
|
|
|
|
}
|
|
|
|
|
2016-10-13 22:56:55 +00:00
|
|
|
#pragma mark - CSKeyboardMachine
|
|
|
|
|
2017-07-23 02:17:29 +00:00
|
|
|
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
|
2016-10-15 01:18:03 +00:00
|
|
|
@synchronized(self) {
|
2017-07-23 02:17:29 +00:00
|
|
|
switch(key) {
|
2017-08-16 18:35:53 +00:00
|
|
|
case VK_ANSI_0: _oric->set_key_state(Oric::Key::Key0, isPressed); break;
|
|
|
|
case VK_ANSI_1: _oric->set_key_state(Oric::Key::Key1, isPressed); break;
|
|
|
|
case VK_ANSI_2: _oric->set_key_state(Oric::Key::Key2, isPressed); break;
|
|
|
|
case VK_ANSI_3: _oric->set_key_state(Oric::Key::Key3, isPressed); break;
|
|
|
|
case VK_ANSI_4: _oric->set_key_state(Oric::Key::Key4, isPressed); break;
|
|
|
|
case VK_ANSI_5: _oric->set_key_state(Oric::Key::Key5, isPressed); break;
|
|
|
|
case VK_ANSI_6: _oric->set_key_state(Oric::Key::Key6, isPressed); break;
|
|
|
|
case VK_ANSI_7: _oric->set_key_state(Oric::Key::Key7, isPressed); break;
|
|
|
|
case VK_ANSI_8: _oric->set_key_state(Oric::Key::Key8, isPressed); break;
|
|
|
|
case VK_ANSI_9: _oric->set_key_state(Oric::Key::Key9, isPressed); break;
|
|
|
|
|
|
|
|
case VK_ANSI_Q: _oric->set_key_state(Oric::Key::KeyQ, isPressed); break;
|
|
|
|
case VK_ANSI_W: _oric->set_key_state(Oric::Key::KeyW, isPressed); break;
|
|
|
|
case VK_ANSI_E: _oric->set_key_state(Oric::Key::KeyE, isPressed); break;
|
|
|
|
case VK_ANSI_R: _oric->set_key_state(Oric::Key::KeyR, isPressed); break;
|
|
|
|
case VK_ANSI_T: _oric->set_key_state(Oric::Key::KeyT, isPressed); break;
|
|
|
|
case VK_ANSI_Y: _oric->set_key_state(Oric::Key::KeyY, isPressed); break;
|
|
|
|
case VK_ANSI_U: _oric->set_key_state(Oric::Key::KeyU, isPressed); break;
|
|
|
|
case VK_ANSI_I: _oric->set_key_state(Oric::Key::KeyI, isPressed); break;
|
|
|
|
case VK_ANSI_O: _oric->set_key_state(Oric::Key::KeyO, isPressed); break;
|
|
|
|
case VK_ANSI_P: _oric->set_key_state(Oric::Key::KeyP, isPressed); break;
|
|
|
|
case VK_ANSI_A: _oric->set_key_state(Oric::Key::KeyA, isPressed); break;
|
|
|
|
case VK_ANSI_S: _oric->set_key_state(Oric::Key::KeyS, isPressed); break;
|
|
|
|
case VK_ANSI_D: _oric->set_key_state(Oric::Key::KeyD, isPressed); break;
|
|
|
|
case VK_ANSI_F: _oric->set_key_state(Oric::Key::KeyF, isPressed); break;
|
|
|
|
case VK_ANSI_G: _oric->set_key_state(Oric::Key::KeyG, isPressed); break;
|
|
|
|
case VK_ANSI_H: _oric->set_key_state(Oric::Key::KeyH, isPressed); break;
|
|
|
|
case VK_ANSI_J: _oric->set_key_state(Oric::Key::KeyJ, isPressed); break;
|
|
|
|
case VK_ANSI_K: _oric->set_key_state(Oric::Key::KeyK, isPressed); break;
|
|
|
|
case VK_ANSI_L: _oric->set_key_state(Oric::Key::KeyL, isPressed); break;
|
|
|
|
case VK_ANSI_Z: _oric->set_key_state(Oric::Key::KeyZ, isPressed); break;
|
|
|
|
case VK_ANSI_X: _oric->set_key_state(Oric::Key::KeyX, isPressed); break;
|
|
|
|
case VK_ANSI_C: _oric->set_key_state(Oric::Key::KeyC, isPressed); break;
|
|
|
|
case VK_ANSI_V: _oric->set_key_state(Oric::Key::KeyV, isPressed); break;
|
|
|
|
case VK_ANSI_B: _oric->set_key_state(Oric::Key::KeyB, isPressed); break;
|
|
|
|
case VK_ANSI_N: _oric->set_key_state(Oric::Key::KeyN, isPressed); break;
|
|
|
|
case VK_ANSI_M: _oric->set_key_state(Oric::Key::KeyM, isPressed); break;
|
|
|
|
|
|
|
|
case VK_Space: _oric->set_key_state(Oric::Key::KeySpace, isPressed); break;
|
|
|
|
case VK_Return: _oric->set_key_state(Oric::Key::KeyReturn, isPressed); break;
|
|
|
|
case VK_ANSI_Minus: _oric->set_key_state(Oric::Key::KeyMinus, isPressed); break;
|
|
|
|
case VK_ANSI_Equal: _oric->set_key_state(Oric::Key::KeyEquals, isPressed); break;
|
2016-10-15 02:39:27 +00:00
|
|
|
case VK_ANSI_Backslash:
|
2017-08-16 18:35:53 +00:00
|
|
|
_oric->set_key_state(Oric::Key::KeyBackSlash, isPressed); break;
|
|
|
|
case VK_ANSI_Slash: _oric->set_key_state(Oric::Key::KeyForwardSlash, isPressed); break;
|
2016-10-15 02:39:27 +00:00
|
|
|
|
|
|
|
case VK_ANSI_LeftBracket:
|
2017-08-16 18:35:53 +00:00
|
|
|
_oric->set_key_state(Oric::Key::KeyOpenSquare, isPressed); break;
|
2016-10-15 02:39:27 +00:00
|
|
|
case VK_ANSI_RightBracket:
|
2017-08-16 18:35:53 +00:00
|
|
|
_oric->set_key_state(Oric::Key::KeyCloseSquare, isPressed); break;
|
|
|
|
case VK_ANSI_Quote: _oric->set_key_state(Oric::Key::KeyQuote, isPressed); break;
|
2016-10-15 01:18:03 +00:00
|
|
|
|
2017-08-16 18:35:53 +00:00
|
|
|
case VK_RightArrow: _oric->set_key_state(Oric::Key::KeyRight, isPressed); break;
|
|
|
|
case VK_LeftArrow: _oric->set_key_state(Oric::Key::KeyLeft, isPressed); break;
|
|
|
|
case VK_DownArrow: _oric->set_key_state(Oric::Key::KeyDown, isPressed); break;
|
|
|
|
case VK_UpArrow: _oric->set_key_state(Oric::Key::KeyUp, isPressed); break;
|
2016-10-15 01:18:03 +00:00
|
|
|
|
2017-08-16 18:35:53 +00:00
|
|
|
case VK_Delete: _oric->set_key_state(Oric::Key::KeyDelete, isPressed); break;
|
|
|
|
case VK_Escape: _oric->set_key_state(Oric::Key::KeyEscape, isPressed); break;
|
2016-10-15 01:18:03 +00:00
|
|
|
|
2017-08-16 18:35:53 +00:00
|
|
|
case VK_ANSI_Comma: _oric->set_key_state(Oric::Key::KeyComma, isPressed); break;
|
|
|
|
case VK_ANSI_Period: _oric->set_key_state(Oric::Key::KeyFullStop, isPressed); break;
|
2016-10-15 01:18:03 +00:00
|
|
|
|
2017-08-16 18:35:53 +00:00
|
|
|
case VK_ANSI_Semicolon: _oric->set_key_state(Oric::Key::KeySemiColon, isPressed); break;
|
2016-10-15 01:18:03 +00:00
|
|
|
|
2017-05-19 02:25:59 +00:00
|
|
|
case VK_Shift:
|
2017-08-16 18:35:53 +00:00
|
|
|
_oric->set_key_state(Oric::Key::KeyLeftShift, isPressed);
|
|
|
|
_oric->set_key_state(Oric::Key::KeyRightShift, isPressed);
|
2017-05-19 02:25:59 +00:00
|
|
|
break;
|
2017-08-16 18:35:53 +00:00
|
|
|
case VK_RightShift: _oric->set_key_state(Oric::Key::KeyRightShift, isPressed); break;
|
|
|
|
case VK_Control: _oric->set_key_state(Oric::Key::KeyControl, isPressed); break;
|
2016-10-15 01:18:03 +00:00
|
|
|
|
|
|
|
case VK_ANSI_Grave:
|
2017-08-16 18:35:53 +00:00
|
|
|
case VK_F12: _oric->set_key_state(Oric::Key::KeyNMI, isPressed); break;
|
2016-10-15 01:18:03 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
printf("%02x\n", key);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-10-13 22:56:55 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 02:17:29 +00:00
|
|
|
- (void)clearAllKeys {
|
2017-08-16 18:35:53 +00:00
|
|
|
@synchronized(self) {
|
|
|
|
_oric->clear_all_keys();
|
|
|
|
}
|
2016-10-20 02:56:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - Options
|
|
|
|
|
2016-11-03 11:59:30 +00:00
|
|
|
- (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack {
|
|
|
|
@synchronized(self) {
|
|
|
|
_useFastLoadingHack = useFastLoadingHack;
|
2017-08-16 18:35:53 +00:00
|
|
|
_oric->set_use_fast_tape_hack(useFastLoadingHack ? true : false);
|
2016-11-03 11:59:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-20 02:56:14 +00:00
|
|
|
- (void)setUseCompositeOutput:(BOOL)useCompositeOutput {
|
|
|
|
@synchronized(self) {
|
|
|
|
_useCompositeOutput = useCompositeOutput;
|
2017-08-16 18:35:53 +00:00
|
|
|
_oric->set_output_device(useCompositeOutput ? Outputs::CRT::Television : Outputs::CRT::Monitor);
|
2016-10-20 02:56:14 +00:00
|
|
|
}
|
2016-10-13 22:56:55 +00:00
|
|
|
}
|
|
|
|
|
2016-10-12 02:20:13 +00:00
|
|
|
@end
|