mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-22 15:29:58 +00:00
Add support for the CUDA_RESTART_SYSTEM command
There are cases where when it's necessary (e.g. given uninitialized NVRAM, the Beige G3 with the 10.2 install CD inserted will update the boot device and restart to boot from it). Restart support was done by wrapping the ppc_exec function in a loop and checking for a restart power off reason. We also need to disconnect all event listeners, since they will be recreated when the machine is re-initialized.
This commit is contained in:
parent
c7d2eb87ac
commit
57e6e90002
@ -58,6 +58,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void disconnect(int id) {
|
||||
_slots.erase(id);
|
||||
}
|
||||
|
||||
void disconnect_all() {
|
||||
_slots.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::map<int, std::function<void(Args...)>> _slots;
|
||||
mutable unsigned int _current_id { 0 };
|
||||
|
@ -94,6 +94,13 @@ public:
|
||||
_post_signal.connect_method(inst, func);
|
||||
}
|
||||
|
||||
void disconnect_handlers() {
|
||||
_window_signal.disconnect_all();
|
||||
_mouse_signal.disconnect_all();
|
||||
_keyboard_signal.disconnect_all();
|
||||
_post_signal.disconnect_all();
|
||||
}
|
||||
|
||||
private:
|
||||
static EventManager* event_manager;
|
||||
EventManager() {}; // private constructor to implement a singleton
|
||||
|
@ -322,6 +322,8 @@ enum Po_Cause : int {
|
||||
po_starting_up,
|
||||
po_shut_down,
|
||||
po_shutting_down,
|
||||
po_restarting,
|
||||
po_restart,
|
||||
po_disassemble_on,
|
||||
po_disassemble_off,
|
||||
po_enter_debugger,
|
||||
|
@ -458,6 +458,10 @@ void enter_debugger() {
|
||||
power_off_reason = po_shutting_down;
|
||||
break;
|
||||
}
|
||||
if (power_off_reason == po_restart) {
|
||||
power_off_reason = po_restarting;
|
||||
break;
|
||||
}
|
||||
power_on = true;
|
||||
|
||||
if (power_off_reason == po_starting_up) {
|
||||
|
@ -25,6 +25,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <core/hostevents.h>
|
||||
#include <core/timermanager.h>
|
||||
#include <devices/common/adb/adbbus.h>
|
||||
#include <cpu/ppc/ppcemu.h>
|
||||
#include <devices/common/hwinterrupt.h>
|
||||
#include <devices/common/viacuda.h>
|
||||
#include <devices/deviceregistry.h>
|
||||
@ -654,10 +655,14 @@ void ViaCuda::pseudo_command(int cmd, int data_count) {
|
||||
LOG_F(INFO, "Cuda: send %d to PB0", (int)(this->in_buf[2]));
|
||||
response_header(CUDA_PKT_PSEUDO, 0);
|
||||
break;
|
||||
case CUDA_RESTART_SYSTEM:
|
||||
LOG_F(INFO, "Cuda: system restart");
|
||||
power_on = false;
|
||||
power_off_reason = po_restart;
|
||||
break;
|
||||
case CUDA_WARM_START:
|
||||
case CUDA_POWER_DOWN:
|
||||
case CUDA_MONO_STABLE_RESET:
|
||||
case CUDA_RESTART_SYSTEM:
|
||||
/* really kludge temp code */
|
||||
LOG_F(INFO, "Cuda: Restart/Shutdown signal sent with command 0x%x!", cmd);
|
||||
//exit(0);
|
||||
|
38
main.cpp
38
main.cpp
@ -61,6 +61,8 @@ static string appDescription = string(
|
||||
"\n"
|
||||
);
|
||||
|
||||
void run_machine(std::string machine_str, std::string bootrom_path, uint32_t execution_mode);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
uint32_t execution_mode = interpreter;
|
||||
@ -166,10 +168,6 @@ int main(int argc, char** argv) {
|
||||
// initialize global profiler object
|
||||
gProfilerObj.reset(new Profiler());
|
||||
|
||||
if (MachineFactory::create_machine_for_id(machine_str, bootrom_path) < 0) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// graceful handling of fatal errors
|
||||
loguru::set_fatal_handler([](const loguru::Message& message) {
|
||||
// Make sure the reason for the failure is visible (it may have been
|
||||
@ -187,9 +185,29 @@ int main(int argc, char** argv) {
|
||||
// redirect SIGABRT to our own handler
|
||||
signal(SIGABRT, sigabrt_handler);
|
||||
|
||||
while (true) {
|
||||
run_machine(machine_str, bootrom_path, execution_mode);
|
||||
if (power_off_reason == po_restarting) {
|
||||
LOG_F(INFO, "Restarting...");
|
||||
power_on = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void run_machine(std::string machine_str, std::string bootrom_path, uint32_t execution_mode) {
|
||||
if (MachineFactory::create_machine_for_id(machine_str, bootrom_path) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set up system wide event polling using
|
||||
// default Macintosh polling rate of 11 ms
|
||||
TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(11), [] {
|
||||
uint32_t event_timer = TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(11), [] {
|
||||
EventManager::get_instance()->poll_events();
|
||||
});
|
||||
|
||||
@ -204,15 +222,11 @@ int main(int argc, char** argv) {
|
||||
break;
|
||||
default:
|
||||
LOG_F(ERROR, "Invalid EXECUTION MODE");
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
bail:
|
||||
LOG_F(INFO, "Cleaning up...");
|
||||
|
||||
TimerManager::get_instance()->cancel_timer(event_timer);
|
||||
EventManager::get_instance()->disconnect_handlers();
|
||||
delete gMachineObj.release();
|
||||
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user