mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-09 02:31:22 +00:00
Makes Jasmin autoboot optional, adds a Jasmin reset key, adds the Jasmin to File -> New... .
Also finally implements KeyNMI.
This commit is contained in:
parent
7361e7ec34
commit
3ced31043a
@ -167,8 +167,8 @@ Analyser::Static::TargetList Analyser::Static::Oric::GetTargets(const Media &med
|
|||||||
target->media.disks.push_back(disk);
|
target->media.disks.push_back(disk);
|
||||||
} else if(IsJasmin(parser)) {
|
} else if(IsJasmin(parser)) {
|
||||||
target->disk_interface = Target::DiskInterface::Jasmin;
|
target->disk_interface = Target::DiskInterface::Jasmin;
|
||||||
|
target->should_start_jasmin = true;
|
||||||
target->media.disks.push_back(disk);
|
target->media.disks.push_back(disk);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ struct Target: public ::Analyser::Static::Target {
|
|||||||
ROM rom = ROM::BASIC11;
|
ROM rom = ROM::BASIC11;
|
||||||
DiskInterface disk_interface = DiskInterface::None;
|
DiskInterface disk_interface = DiskInterface::None;
|
||||||
std::string loading_command;
|
std::string loading_command;
|
||||||
|
bool should_start_jasmin = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,9 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
|
|||||||
|
|
||||||
BIND(Space, KeySpace);
|
BIND(Space, KeySpace);
|
||||||
BIND(Enter, KeyReturn);
|
BIND(Enter, KeyReturn);
|
||||||
|
|
||||||
|
BIND(F12, KeyNMI);
|
||||||
|
BIND(F1, KeyJasminReset);
|
||||||
}
|
}
|
||||||
#undef BIND
|
#undef BIND
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ enum Key: uint16_t {
|
|||||||
KeyForwardSlash = 0x0700 | 0x08, Key0 = 0x0700 | 0x04, KeyL = 0x0700 | 0x02, Key8 = 0x0700 | 0x01,
|
KeyForwardSlash = 0x0700 | 0x08, Key0 = 0x0700 | 0x04, KeyL = 0x0700 | 0x02, Key8 = 0x0700 | 0x01,
|
||||||
|
|
||||||
KeyNMI = 0xfffd,
|
KeyNMI = 0xfffd,
|
||||||
|
KeyJasminReset = 0xfffc,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KeyboardMapper: public KeyboardMachine::MappedMachine::KeyboardMapper {
|
struct KeyboardMapper: public KeyboardMachine::MappedMachine::KeyboardMapper {
|
||||||
|
@ -66,17 +66,32 @@ std::vector<std::unique_ptr<Configurable::Option>> get_options() {
|
|||||||
*/
|
*/
|
||||||
class Keyboard {
|
class Keyboard {
|
||||||
public:
|
public:
|
||||||
Keyboard() {
|
struct SpecialKeyHandler {
|
||||||
|
virtual void perform_special_key(Oric::Key key) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Keyboard(SpecialKeyHandler *handler) : special_key_handler_(handler) {
|
||||||
clear_all_keys();
|
clear_all_keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets whether @c key is or is not pressed, per @c is_pressed.
|
/// Sets whether @c key is or is not pressed, per @c is_pressed.
|
||||||
void set_key_state(uint16_t key, bool is_pressed) {
|
void set_key_state(uint16_t key, bool is_pressed) {
|
||||||
const uint8_t mask = key & 0xff;
|
switch(key) {
|
||||||
const int line = key >> 8;
|
default: {
|
||||||
|
const uint8_t mask = key & 0xff;
|
||||||
|
const int line = key >> 8;
|
||||||
|
|
||||||
if(is_pressed) rows_[line] |= mask;
|
if(is_pressed) rows_[line] |= mask;
|
||||||
else rows_[line] &= ~mask;
|
else rows_[line] &= ~mask;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case KeyNMI:
|
||||||
|
case KeyJasminReset:
|
||||||
|
if(is_pressed) {
|
||||||
|
special_key_handler_->perform_special_key(Oric::Key(key));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets all keys as unpressed.
|
/// Sets all keys as unpressed.
|
||||||
@ -97,6 +112,7 @@ class Keyboard {
|
|||||||
private:
|
private:
|
||||||
uint8_t row_ = 0;
|
uint8_t row_ = 0;
|
||||||
uint8_t rows_[8];
|
uint8_t rows_[8];
|
||||||
|
SpecialKeyHandler *const special_key_handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -211,7 +227,8 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
public Jasmin::Delegate,
|
public Jasmin::Delegate,
|
||||||
public ClockingHint::Observer,
|
public ClockingHint::Observer,
|
||||||
public Activity::Source,
|
public Activity::Source,
|
||||||
public Machine {
|
public Machine,
|
||||||
|
public Keyboard::SpecialKeyHandler {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConcreteMachine(const Analyser::Static::Oric::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
|
ConcreteMachine(const Analyser::Static::Oric::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
|
||||||
@ -221,6 +238,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
speaker_(ay8910_),
|
speaker_(ay8910_),
|
||||||
via_port_handler_(audio_queue_, ay8910_, speaker_, tape_player_, keyboard_),
|
via_port_handler_(audio_queue_, ay8910_, speaker_, tape_player_, keyboard_),
|
||||||
via_(via_port_handler_),
|
via_(via_port_handler_),
|
||||||
|
keyboard_(this),
|
||||||
diskii_(2000000) {
|
diskii_(2000000) {
|
||||||
set_clock_rate(1000000);
|
set_clock_rate(1000000);
|
||||||
speaker_.set_input_rate(1000000.0f);
|
speaker_.set_input_rate(1000000.0f);
|
||||||
@ -310,6 +328,12 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
type_string(target.loading_command);
|
type_string(target.loading_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(target.should_start_jasmin) {
|
||||||
|
// If Jasmin autostart is requested then plan to do so in 3 seconds; empirically long enough
|
||||||
|
// for the Oric to boot normally, before the Jasmin intercedes.
|
||||||
|
jasmin_reset_counter_ = 3000000;
|
||||||
|
}
|
||||||
|
|
||||||
switch(target.rom) {
|
switch(target.rom) {
|
||||||
case Analyser::Static::Oric::Target::ROM::BASIC10:
|
case Analyser::Static::Oric::Target::ROM::BASIC10:
|
||||||
tape_get_byte_address_ = 0xe630;
|
tape_get_byte_address_ = 0xe630;
|
||||||
@ -482,9 +506,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
if(jasmin_reset_counter_) {
|
if(jasmin_reset_counter_) {
|
||||||
--jasmin_reset_counter_;
|
--jasmin_reset_counter_;
|
||||||
if(!jasmin_reset_counter_) {
|
if(!jasmin_reset_counter_) {
|
||||||
jasmin_.write(0x3fa, 0);
|
perform_special_key(KeyJasminReset);
|
||||||
jasmin_.write(0x3fb, 1);
|
|
||||||
m6502_.set_power_on(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -681,8 +703,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
|
|
||||||
// the Jasmin, if in use.
|
// the Jasmin, if in use.
|
||||||
Jasmin jasmin_;
|
Jasmin jasmin_;
|
||||||
int jasmin_reset_counter_ = 3000000; // i.e. 3 seconds; empirically long enough for the Oric to boot normally,
|
int jasmin_reset_counter_ = 0;
|
||||||
// before the Jasmin intercedes.
|
|
||||||
|
|
||||||
// the Pravetz/Disk II, if in use.
|
// the Pravetz/Disk II, if in use.
|
||||||
Apple::DiskII diskii_;
|
Apple::DiskII diskii_;
|
||||||
@ -715,6 +736,26 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
m6502_.set_irq_line(irq_line);
|
m6502_.set_irq_line(irq_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keys that aren't read by polling.
|
||||||
|
void perform_special_key(Oric::Key key) override {
|
||||||
|
switch(key) {
|
||||||
|
default: break;
|
||||||
|
|
||||||
|
case KeyJasminReset:
|
||||||
|
jasmin_.write(0x3fa, 0);
|
||||||
|
jasmin_.write(0x3fb, 1);
|
||||||
|
m6502_.set_power_on(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyNMI:
|
||||||
|
// As luck would have it, the 6502's NMI line is edge triggered.
|
||||||
|
// So just forcing through an edge will work here.
|
||||||
|
m6502_.set_nmi_line(true);
|
||||||
|
m6502_.set_nmi_line(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK - typing
|
// MARK - typing
|
||||||
std::unique_ptr<Utility::StringSerialiser> string_serialiser_;
|
std::unique_ptr<Utility::StringSerialiser> string_serialiser_;
|
||||||
};
|
};
|
||||||
|
@ -49,7 +49,8 @@ typedef NS_ENUM(NSInteger, CSMachineOricModel) {
|
|||||||
typedef NS_ENUM(NSInteger, CSMachineOricDiskInterface) {
|
typedef NS_ENUM(NSInteger, CSMachineOricDiskInterface) {
|
||||||
CSMachineOricDiskInterfaceNone,
|
CSMachineOricDiskInterfaceNone,
|
||||||
CSMachineOricDiskInterfaceMicrodisc,
|
CSMachineOricDiskInterfaceMicrodisc,
|
||||||
CSMachineOricDiskInterfacePravetz
|
CSMachineOricDiskInterfacePravetz,
|
||||||
|
CSMachineOricDiskInterfaceJasmin
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, CSMachineVic20Region) {
|
typedef NS_ENUM(NSInteger, CSMachineVic20Region) {
|
||||||
|
@ -102,6 +102,7 @@
|
|||||||
case CSMachineOricDiskInterfaceNone: target->disk_interface = Target::DiskInterface::None; break;
|
case CSMachineOricDiskInterfaceNone: target->disk_interface = Target::DiskInterface::None; break;
|
||||||
case CSMachineOricDiskInterfaceMicrodisc: target->disk_interface = Target::DiskInterface::Microdisc; break;
|
case CSMachineOricDiskInterfaceMicrodisc: target->disk_interface = Target::DiskInterface::Microdisc; break;
|
||||||
case CSMachineOricDiskInterfacePravetz: target->disk_interface = Target::DiskInterface::Pravetz; break;
|
case CSMachineOricDiskInterfacePravetz: target->disk_interface = Target::DiskInterface::Pravetz; break;
|
||||||
|
case CSMachineOricDiskInterfaceJasmin: target->disk_interface = Target::DiskInterface::Jasmin; break;
|
||||||
}
|
}
|
||||||
_targets.push_back(std::move(target));
|
_targets.push_back(std::move(target));
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<windowStyleMask key="styleMask" titled="YES" documentModal="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" documentModal="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="196" y="240" width="720" height="205"/>
|
<rect key="contentRect" x="196" y="240" width="720" height="205"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="3840" height="2137"/>
|
||||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="720" height="205"/>
|
<rect key="frame" x="0.0" y="0.0" width="720" height="205"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
@ -64,7 +64,7 @@ Gw
|
|||||||
<tabViewItems>
|
<tabViewItems>
|
||||||
<tabViewItem label="Apple II" identifier="appleii" id="P59-QG-LOa">
|
<tabViewItem label="Apple II" identifier="appleii" id="P59-QG-LOa">
|
||||||
<view key="view" id="dHz-Yv-GNq">
|
<view key="view" id="dHz-Yv-GNq">
|
||||||
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
<rect key="frame" x="10" y="33" width="674" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5Z-dX-Ns4">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5Z-dX-Ns4">
|
||||||
@ -305,7 +305,7 @@ Gw
|
|||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Oric" identifier="oric" id="NSx-DC-p4M">
|
<tabViewItem label="Oric" identifier="oric" id="NSx-DC-p4M">
|
||||||
<view key="view" id="sOR-e0-8iZ">
|
<view key="view" id="sOR-e0-8iZ">
|
||||||
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
<rect key="frame" x="10" y="33" width="674" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0ct-tf-uRH">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0ct-tf-uRH">
|
||||||
@ -339,6 +339,7 @@ Gw
|
|||||||
<items>
|
<items>
|
||||||
<menuItem title="None" state="on" id="XhK-Jh-oTW"/>
|
<menuItem title="None" state="on" id="XhK-Jh-oTW"/>
|
||||||
<menuItem title="Microdisc" tag="1" id="1jS-Lz-FRj"/>
|
<menuItem title="Microdisc" tag="1" id="1jS-Lz-FRj"/>
|
||||||
|
<menuItem title="Jasmin" tag="3" id="CGU-gd-xov"/>
|
||||||
<menuItem title="8DOS" tag="2" id="edb-fl-C8Y"/>
|
<menuItem title="8DOS" tag="2" id="edb-fl-C8Y"/>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
@ -370,7 +371,7 @@ Gw
|
|||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Vic-20" identifier="vic20" id="cyO-PU-hSU">
|
<tabViewItem label="Vic-20" identifier="vic20" id="cyO-PU-hSU">
|
||||||
<view key="view" id="fLI-XB-QCr">
|
<view key="view" id="fLI-XB-QCr">
|
||||||
<rect key="frame" x="10" y="33" width="604" height="94"/>
|
<rect key="frame" x="10" y="33" width="674" height="94"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ueK-gq-gaF">
|
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ueK-gq-gaF">
|
||||||
|
@ -195,6 +195,7 @@ class MachinePicker: NSObject {
|
|||||||
switch oricDiskInterfaceButton!.selectedTag() {
|
switch oricDiskInterfaceButton!.selectedTag() {
|
||||||
case 1: diskInterface = .microdisc
|
case 1: diskInterface = .microdisc
|
||||||
case 2: diskInterface = .pravetz
|
case 2: diskInterface = .pravetz
|
||||||
|
case 3: diskInterface = .jasmin
|
||||||
default: break;
|
default: break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user