+// SPDX-License-Identifier: MIT
+
#include "m68k.h"
#include "emulator.h"
#include "platforms/platforms.h"
#include "input/input.h"
#include "platforms/amiga/Gayle.h"
-#include "platforms/amiga/gayle-ide/ide.h"
#include "platforms/amiga/amiga-registers.h"
#include "platforms/amiga/rtg/rtg.h"
#include "platforms/amiga/hunk-reloc.h"
#include "platforms/amiga/piscsi/piscsi-enums.h"
#include "platforms/amiga/net/pi-net.h"
#include "platforms/amiga/net/pi-net-enums.h"
+#include "platforms/amiga/pistorm-dev/pistorm-dev.h"
+#include "platforms/amiga/pistorm-dev/pistorm-dev-enums.h"
#include "gpio/ps_protocol.h"
#include <assert.h>
extern volatile unsigned int *gpio;
extern volatile uint16_t srdata;
extern uint8_t realtime_graphics_debug;
+extern uint8_t rtg_on;
uint8_t realtime_disassembly, int2_enabled = 0;
uint32_t do_disasm = 0, old_level;
-char c = 0, c_code = 0, c_type = 0; // @todo temporary main/cpu_task scope workaround until input moved to a thread
uint32_t last_irq = 8, last_last_irq = 8;
+uint8_t end_signal = 0, load_new_config = 0;
+
char disasm_buf[4096];
#define KICKBASE 0xF80000
}*/
if (do_reset) {
cpu_pulse_reset();
- m68k_pulse_reset();
do_reset=0;
usleep(1000000); // 1sec
+ rtg_on=0;
// while(amiga_reset==0);
// printf("CPU emulation reset.\n");
}
-
if (mouse_hook_enabled && (mouse_extra != 0x00)) {
// mouse wheel events have occurred; unlike l/m/r buttons, these are queued as keypresses, so add to end of buffer
switch (mouse_extra) {
// dampen the scroll wheel until next while loop iteration
mouse_extra = 0x00;
}
+
+ if (load_new_config) {
+ printf("[CPU] Loading new config file.\n");
+ goto stop_cpu_emulation;
+ }
+
+ if (end_signal)
+ goto stop_cpu_emulation;
+
goto cpu_loop;
-//stop_cpu_emulation:
+stop_cpu_emulation:
printf("[CPU] End of CPU thread\n");
+ return (void *)NULL;
}
void *keyboard_task() {
- struct pollfd kbdfd[1];
- int kpoll;
+ struct pollfd kbdpoll[1];
+ int kpollrc;
+ char c = 0, c_code = 0, c_type = 0;
+ char grab_message[] = "[KBD] Grabbing keyboard from input layer\n",
+ ungrab_message[] = "[KBD] Ungrabbing keyboard\n";
printf("[KBD] Keyboard thread started\n");
- kbdfd[0].fd = keyboard_fd;
- kbdfd[0].events = POLLIN;
+ // because we permit the keyboard to be grabbed on startup, quickly check if we need to grab it
+ if (kb_hook_enabled && cfg->keyboard_grab) {
+ printf(grab_message);
+ grab_device(keyboard_fd);
+ }
+
+ kbdpoll[0].fd = keyboard_fd;
+ kbdpoll[0].events = POLLIN;
key_loop:
- kpoll = poll(kbdfd, 1, KEY_POLL_INTERVAL_MSEC);
- if ((kpoll > 0) && (kbdfd[0].revents & POLLHUP)) {
+ kpollrc = poll(kbdpoll, 1, KEY_POLL_INTERVAL_MSEC);
+ if ((kpollrc > 0) && (kbdpoll[0].revents & POLLHUP)) {
// in the event that a keyboard is unplugged, keyboard_task will whiz up to 100% utilisation
// this is undesired, so if the keyboard HUPs, end the thread without ending the emulation
printf("[KBD] Keyboard node returned HUP (unplugged?)\n");
goto key_end;
}
- // if kpoll > 0 then it contains number of events to pull, also check if POLLIN is set in revents
- if ((kpoll <= 0) || !(kbdfd[0].revents & POLLIN)) {
+ // if kpollrc > 0 then it contains number of events to pull, also check if POLLIN is set in revents
+ if ((kpollrc <= 0) || !(kbdpoll[0].revents & POLLIN)) {
goto key_loop;
}
while (get_key_char(&c, &c_code, &c_type)) {
if (c && c == cfg->keyboard_toggle_key && !kb_hook_enabled) {
kb_hook_enabled = 1;
- printf("Keyboard hook enabled.\n");
- }
- else if (kb_hook_enabled) {
+ printf("[KBD] Keyboard hook enabled.\n");
+ if (cfg->keyboard_grab) {
+ grab_device(keyboard_fd);
+ printf(grab_message);
+ }
+ } else if (kb_hook_enabled) {
if (c == 0x1B && c_type) {
kb_hook_enabled = 0;
- printf("Keyboard hook disabled.\n");
- }
- else {
+ printf("[KBD] Keyboard hook disabled.\n");
+ if (cfg->keyboard_grab) {
+ release_device(keyboard_fd);
+ printf(ungrab_message);
+ }
+ } else {
if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled && last_irq != 2) {
//last_irq = 0;
//M68K_SET_IRQ(2);
//m68k_pulse_reset();
printf("CPU emulation reset.\n");
}
- // @todo work out how to signal the main process that we want to quit
- // if (c == 'q') {
- // printf("Quitting and exiting emulator.\n");
- // goto stop_cpu_emulation;
- // }
+ if (c == 'q') {
+ printf("Quitting and exiting emulator.\n");
+ end_signal = 1;
+ goto key_end;
+ }
if (c == 'd') {
realtime_disassembly ^= 1;
do_disasm = 1;
key_end:
printf("[KBD] Keyboard thread ending\n");
+ if (cfg->keyboard_grab) {
+ printf(ungrab_message);
+ release_device(keyboard_fd);
+ }
return (void*)NULL;
}
int g;
//const struct sched_param priority = {99};
- if (argc > 1) {
- irq_delay = atoi(argv[1]);
- printf("Setting IRQ delay to %d loops (%s).\n", irq_delay, argv[1]);
- }
-
// Some command line switch stuffles
for (g = 1; g < argc; g++) {
if (strcmp(argv[g], "--cpu_type") == 0 || strcmp(argv[g], "--cpu") == 0) {
} else {
g++;
cfg = load_config_file(argv[g]);
+ if (cfg) {
+ set_pistorm_devcfg_filename(argv[g]);
+ }
}
}
else if (strcmp(argv[g], "--keyboard-file") == 0 || strcmp(argv[g], "--kbfile") == 0) {
}
}
+switch_config:
+ srand(clock());
+
+ if (load_new_config != 0) {
+ uint8_t config_action = load_new_config - 1;
+ load_new_config = 0;
+ free_config_file(cfg);
+ if (cfg) {
+ free(cfg);
+ cfg = NULL;
+ }
+
+ /*for(int i = 0; i < 2 * SIZE_MEGA; i++) {
+ write8(i, 0);
+ }*/
+
+ switch(config_action) {
+ case PICFG_LOAD:
+ case PICFG_RELOAD:
+ cfg = load_config_file(get_pistorm_devcfg_filename());
+ break;
+ case PICFG_DEFAULT:
+ cfg = load_config_file("default.cfg");
+ break;
+ }
+ }
+
if (!cfg) {
printf("No config file specified. Trying to load default.cfg...\n");
cfg = load_config_file("default.cfg");
printf("Failed to open keyboard event source.\n");
}
+ if (cfg->mouse_autoconnect)
+ mouse_hook_enabled = 1;
+
+ if (cfg->keyboard_autoconnect)
+ kb_hook_enabled = 1;
+
InitGayle();
signal(SIGINT, sigint_handler);
m68k_set_cpu_type(cpu_type);
cpu_pulse_reset();
- pthread_t ipl_tid, cpu_tid, kbd_tid;
+ pthread_t ipl_tid = 0, cpu_tid, kbd_tid;
int err;
- err = pthread_create(&ipl_tid, NULL, &ipl_task, NULL);
- if (err != 0)
- printf("[ERROR] Cannot create IPL thread: [%s]", strerror(err));
- else {
- pthread_setname_np(ipl_tid, "pistorm: ipl");
- printf("IPL thread created successfully\n");
+ if (ipl_tid == 0) {
+ err = pthread_create(&ipl_tid, NULL, &ipl_task, NULL);
+ if (err != 0)
+ printf("[ERROR] Cannot create IPL thread: [%s]", strerror(err));
+ else {
+ pthread_setname_np(ipl_tid, "pistorm: ipl");
+ printf("IPL thread created successfully\n");
+ }
}
// create keyboard task
// wait for cpu task to end before closing up and finishing
pthread_join(cpu_tid, NULL);
- printf("[MAIN] All threads appear to have concluded; ending process\n");
+
+ if (load_new_config == 0)
+ printf("[MAIN] All threads appear to have concluded; ending process\n");
if (mouse_fd != -1)
close(mouse_fd);
if (mem_fd)
close(mem_fd);
+ if (load_new_config != 0)
+ goto switch_config;
+
+ if (cfg->platform->shutdown) {
+ cfg->platform->shutdown(cfg);
+ }
+
return 0;
}