#define UNIT_LED(unit) ((unit)->ui.unit_type == UNIT_CDFS ? LED_CD : LED_HD)
-static uae_sem_t test_sem;
-
static int bootrom_header;
static uae_u32 dlg (uae_u32 a)
static uae_u32 fsdevname, fshandlername, filesys_configdev;
static uae_u32 cdfs_devname, cdfs_handlername;
static uaecptr afterdos_name, afterdos_id, afterdos_initcode;
+static uaecptr shell_execute_data, shell_execute_process;
static int filesys_in_interrupt;
static uae_u32 mountertask;
static int automountunit = -1;
static uaecptr ROM_filesys_putmsg, ROM_filesys_putmsg_original;
static uaecptr ROM_filesys_putmsg_return;
static uaecptr ROM_filesys_hack_remove;
+static smp_comm_pipe shellexecute_pipe;
#define FS_STARTUP 0
#define FS_GO_DOWN 1
uae_u32 size = GET_PCK_ARG3 (packet);
uae_u32 actual;
uae_u8 *buf;
- int i;
if (k == 0) {
PUT_PCK_RES1 (packet, DOS_FALSE);
* know whether AmigaOS takes care of that, but this does. */
static uae_sem_t singlethread_int_sem;
-#if 1
-
+#define SHELLEXEC_MAX_CMD_LEN 512
static uae_u32 REGPARAM2 exter_int_helper(TrapContext *ctx)
{
int n = trap_get_dreg(ctx, 0);
static int unit_no;
+ if (n == 20) {
+ // d1 = shellexec process
+ shell_execute_process = trap_get_dreg(ctx, 1);
+ return 0;
+ } else if (n == 21) {
+ trap_set_areg(ctx, 0, 0);
+ if (comm_pipe_has_data(&shellexecute_pipe)) {
+ TCHAR *p = (TCHAR*)read_comm_pipe_pvoid_blocking(&shellexecute_pipe);
+ if (p) {
+ int maxsize = SHELLEXEC_MAX_CMD_LEN - 1;
+ if (shell_execute_data) {
+ uae_char *src = ua(p);
+ uae_u8 *dst = uaeboard_map_ram(shell_execute_data);
+ uae_char *srcp = src;
+ while (maxsize-- > 0) {
+ uae_u8 v = *srcp++;
+ *dst++ = v;
+ if (!v)
+ break;
+ }
+ *dst = 0;
+ xfree(src);
+ }
+ trap_set_areg(ctx, 0, shell_execute_data);
+ }
+ xfree(p);
+ }
+ return 0;
+ } else if (n == 22) {
+ // ack
+ return 0;
+ }
+
if (n == 1) {
/* Release a message_lock. This is called as soon as the message is
* received by the assembly code. We use the opportunity to check
/* First, check signals/messages */
while (comm_pipe_has_data(&native2amiga_pending)) {
int cmd = read_comm_pipe_int_blocking(&native2amiga_pending);
+ if (cmd & 0x80) {
+ cmd &= ~0x80;
+ // tell the sender that message was processed
+ UAE_PROCESSED func = (UAE_PROCESSED)read_comm_pipe_pvoid_blocking(&native2amiga_pending);
+ func(cmd);
+ }
switch (cmd) {
case 0: /* Signal() */
trap_set_areg(ctx, 1, read_comm_pipe_u32_blocking(&native2amiga_pending));
trap_set_areg(ctx, 1, read_comm_pipe_u32_blocking(&native2amiga_pending));
return 5;
- case 5: /* CallLib() */
+ case 5: /* shell execute */
{
- int num = read_comm_pipe_u32_blocking(&native2amiga_pending);
- return 6;
+ TCHAR *p = (TCHAR*)read_comm_pipe_pvoid_blocking(&native2amiga_pending);
+ write_comm_pipe_pvoid(&shellexecute_pipe, p, 0);
+ if (shell_execute_data) {
+ if (!shell_execute_process)
+ break;
+ trap_set_areg(ctx, 1, shell_execute_process - 92);
+ trap_set_dreg(ctx, 1, 1 << 13);
+ return 2; // signal process
+ }
+ shell_execute_data = uaeboard_alloc_ram(SHELLEXEC_MAX_CMD_LEN);
+ return 6; // create process
}
default:
return 0;
}
-#else
-
-static uae_u32 REGPARAM2 exter_int_helper(TrapContext *ctx)
-{
- UnitInfo *uip = mountinfo.ui;
- uaecptr port;
- int n = trap_get_dreg (ctx, 0);
- static int unit_no;
-
- switch (n) {
- case 0:
- /* Determine whether a given EXTER interrupt is for us. */
- if (uae_int_requested & 1) {
- if (uae_sem_trywait (&singlethread_int_sem) != 0)
- /* Pretend it isn't for us. We might get it again later. */
- return 0;
- /* Clear the interrupt flag _before_ we do any processing.
- * That way, we can get too many interrupts, but never not
- * enough. */
- filesys_in_interrupt++;
- atomic_and(&uae_int_requested, ~1);
- unit_no = 0;
- return 1;
- }
- return 0;
- case 1:
- /* Release a message_lock. This is called as soon as the message is
- * received by the assembly code. We use the opportunity to check
- * whether we have some locks that we can give back to the assembler
- * code.
- * Note that this is called from the main loop, unlike the other cases
- * in this switch statement which are called from the interrupt handler.
- */
-#ifdef UAE_FILESYS_THREADS
- {
- Unit *unit = find_unit (trap_get_areg (ctx, 5));
- uaecptr msg = trap_get_areg (ctx, 4);
- unit->cmds_complete = unit->cmds_acked;
- while (comm_pipe_has_data (unit->ui.back_pipe)) {
- uaecptr locks, lockend;
- int cnt = 0;
- locks = read_comm_pipe_int_blocking (unit->ui.back_pipe);
- lockend = locks;
- while (trap_get_long(ctx, lockend) != 0) {
- if (trap_get_long(ctx, lockend) == lockend) {
- write_log (_T("filesystem lock queue corrupted!\n"));
- break;
- }
- lockend = trap_get_long(ctx, lockend);
- cnt++;
- }
- TRACE3((_T("message_lock: %d %x %x %x\n"), cnt, locks, lockend, trap_get_areg (ctx, 3)));
- trap_put_long(ctx, lockend, trap_get_long(ctx, trap_get_areg (ctx, 3)));
- trap_put_long(ctx, trap_get_areg (ctx, 3), locks);
- }
- }
-#else
- write_log (_T("exter_int_helper should not be called with arg 1!\n"));
-#endif
- break;
- case 2:
- /* Find work that needs to be done:
- * return d0 = 0: none
- * d0 = 1: PutMsg(), port in a0, message in a1
- * d0 = 2: Signal(), task in a1, signal set in d1
- * d0 = 3: ReplyMsg(), message in a1
- * d0 = 4: Cause(), interrupt in a1
- * d0 = 5: Send FileNofication message, port in a0, notifystruct in a1
- */
-
-#ifdef SUPPORT_THREADS
- /* First, check signals/messages */
- while (comm_pipe_has_data (&native2amiga_pending)) {
- int cmd = read_comm_pipe_int_blocking (&native2amiga_pending);
- switch (cmd) {
- case 0: /* Signal() */
- trap_set_areg(ctx, 1, read_comm_pipe_u32_blocking (&native2amiga_pending));
- trap_set_dreg(ctx, 1, read_comm_pipe_u32_blocking (&native2amiga_pending));
- return 2;
-
- case 1: /* PutMsg() */
- trap_set_areg(ctx, 0, read_comm_pipe_u32_blocking(&native2amiga_pending));
- trap_set_areg(ctx, 1, read_comm_pipe_u32_blocking(&native2amiga_pending));
- return 1;
-
- case 2: /* ReplyMsg() */
- trap_set_areg(ctx, 1, read_comm_pipe_u32_blocking(&native2amiga_pending));
- return 3;
-
- case 3: /* Cause() */
- trap_set_areg(ctx, 1, read_comm_pipe_u32_blocking(&native2amiga_pending));
- return 4;
-
- case 4: /* NotifyHack() */
- trap_set_areg(ctx, 0, read_comm_pipe_u32_blocking(&native2amiga_pending));
- trap_set_areg(ctx, 1, read_comm_pipe_u32_blocking(&native2amiga_pending));
- return 5;
-
- default:
- write_log (_T("exter_int_helper: unknown native action %X\n"), cmd);
- break;
- }
- }
-#endif
-
- /* Find some unit that needs a message sent, and return its port,
- * or zero if all are done.
- * Take care not to dereference self for units that didn't have their
- * startup packet sent. */
- for (;;) {
- if (unit_no >= MAX_FILESYSTEM_UNITS)
- return 0;
-
- if (uip[unit_no].open > 0 && uip[unit_no].self != 0
- && uip[unit_no].self->cmds_acked == uip[unit_no].self->cmds_complete
- && uip[unit_no].self->cmds_acked != uip[unit_no].self->cmds_sent)
- break;
- unit_no++;
- }
- uip[unit_no].self->cmds_acked = uip[unit_no].self->cmds_sent;
- port = uip[unit_no].self->port;
- if (port) {
- trap_set_areg (ctx, 0, port);
- trap_set_areg (ctx, 1, find_unit (port)->dummy_message);
- unit_no++;
- return 1;
- }
- break;
- case 3:
- uae_sem_wait (&singlethread_int_sem);
- break;
- case 4:
- /* Exit the interrupt, and release the single-threading lock. */
- filesys_in_interrupt--;
- uae_sem_post (&singlethread_int_sem);
- break;
-
- default:
- write_log (_T("Shouldn't happen in exter_int_helper.\n"));
- break;
- }
- return 0;
-}
-
-#endif
-
static int handle_packet(TrapContext *ctx, Unit *unit, dpacket *pck, uae_u32 msg, int isvolume)
{
uae_s32 type = GET_PCK_TYPE (pck);
}
}
-void filesys_cleanup (void)
-{
- filesys_free_handles ();
- free_mountinfo ();
-}
-
void filesys_free_handles (void)
{
Unit *u, *u1;
load_injected_icons();
filesys_reset2 ();
initialize_mountinfo ();
+
+ shell_execute_data = 0;
+ shell_execute_process = 0;
}
static void filesys_prepare_reset2 (void)
}
}
+void filesys_cleanup(void)
+{
+ filesys_free_handles();
+ free_mountinfo();
+ destroy_comm_pipe(&shellexecute_pipe);
+ uae_sem_destroy(&singlethread_int_sem);
+ shell_execute_data = 0;
+}
+
void filesys_install (void)
{
uaecptr loop;
TRACEI ((_T("Installing filesystem\n")));
uae_sem_init (&singlethread_int_sem, 0, 1);
- uae_sem_init (&test_sem, 0, 1);
+ init_comm_pipe(&shellexecute_pipe, 100, 1);
ROM_filesys_resname = ds_ansi ("UAEunixfs.resource");
ROM_filesys_resid = ds_ansi ("UAE unixfs 0.4");
#endif
#include "tabletlibrary.h"
#include "statusline.h"
+#include "native2amiga_api.h"
#if SIZEOF_TCHAR != 1
/* FIXME: replace strcasecmp with _tcsicmp in source code instead */
config_changed = 0;
} else if (!_tcsicmp (p, _T("do_config_check"))) {
set_config_changed ();
- } else if (!_tcsnicmp (p, _T("dbg "), 4)) {
- debug_parser (p + 4, NULL, -1);
+ } else if (!_tcsnicmp(p, _T("shellexec "), 10)) {
+ uae_ShellExecute(p + 10);
+ } else if (!_tcsnicmp(p, _T("dbg "), 4)) {
+ debug_parser(p + 4, NULL, -1);
} else if (!_tcsnicmp (p, _T("kbr "), 4)) {
inject_events (p + 4);
} else if (!_tcsnicmp (p, _T("evt "), 4)) {
matchdevices (&idev[IDTYPE_JOYSTICK], joysticks);
matchdevices (&idev[IDTYPE_KEYBOARD], keyboards);
- // find which one was remove or inserted
+ // find out which one was removed or inserted
for (int j = 0; j <= IDTYPE_KEYBOARD; j++) {
struct inputdevice_functions *inf = &idev[j];
int num = inf->get_num();
TCHAR *un = inf->get_uniquename(k);
TCHAR *fn = inf->get_friendlyname(k);
if (!_tcscmp(fn2, fn) && !_tcscmp(un2, un)) {
- xfree(fn2);
- xfree(un2);
devcfg[i][j].name[0] = 0;
devcfg[i][j].configname[0] = 0;
df[k] = true;
{
bool found = false;
int idx = 0;
+ struct jport *jpx = &p->jports[portnum];
for (;;) {
struct jport *jp = inputdevice_get_used_device(portnum, idx);
if (!jp)
if (!found && jp->id == -2)
found = inputdevice_joyport_config(p, jp->idc.name, NULL, portnum, jp->mode, 1, true) != 0;
} else if (jp->id < JSEM_JOYS && jp->id >= 0) {
- p->jports[portnum].id = jp->id;
+ jpx->id = jp->id;
found = true;
}
if (found) {
+ jpx->mode = jp->mode;
+ jpx->autofire = jp->autofire;
inputdevice_set_newest_used_device(portnum, jp);
break;
}
void native2amiga_install (void)
{
- init_comm_pipe (&native2amiga_pending, 100, 2);
+ init_comm_pipe (&native2amiga_pending, 300, 2);
uae_sem_init (&n2asem, 0, 1);
}
#ifdef SUPPORT_THREADS
+void uae_nativesem_wait(void)
+{
+ uae_sem_wait(&n2asem);
+}
+void uae_nativesem_post(void)
+{
+ uae_sem_post(&n2asem);
+}
+
void uae_Cause (uaecptr interrupt)
{
- uae_sem_wait (&n2asem);
+ uae_nativesem_wait();
write_comm_pipe_int (&native2amiga_pending, 3, 0);
write_comm_pipe_u32 (&native2amiga_pending, interrupt, 1);
do_uae_int_requested ();
- uae_sem_post (&n2asem);
+ uae_nativesem_post();
}
void uae_ReplyMsg (uaecptr msg)
{
- uae_sem_wait (&n2asem);
+ uae_nativesem_wait();
write_comm_pipe_int (&native2amiga_pending, 2, 0);
write_comm_pipe_u32 (&native2amiga_pending, msg, 1);
do_uae_int_requested ();
- uae_sem_post (&n2asem);
+ uae_nativesem_post();
}
void uae_PutMsg (uaecptr port, uaecptr msg)
{
- uae_sem_wait (&n2asem);
+ uae_nativesem_wait();
write_comm_pipe_int (&native2amiga_pending, 1, 0);
write_comm_pipe_u32 (&native2amiga_pending, port, 0);
write_comm_pipe_u32 (&native2amiga_pending, msg, 1);
do_uae_int_requested ();
- uae_sem_post (&n2asem);
+ uae_nativesem_post();
}
void uae_Signal (uaecptr task, uae_u32 mask)
{
- uae_sem_wait (&n2asem);
+ uae_nativesem_wait();
write_comm_pipe_int (&native2amiga_pending, 0, 0);
write_comm_pipe_u32 (&native2amiga_pending, task, 0);
write_comm_pipe_int (&native2amiga_pending, mask, 1);
do_uae_int_requested ();
- uae_sem_post (&n2asem);
+ uae_nativesem_post();
+}
+
+void uae_Signal_with_Func(uaecptr task, uae_u32 mask, UAE_PROCESSED state)
+{
+ uae_nativesem_wait();
+ write_comm_pipe_int(&native2amiga_pending, 0 | 0x80, 0);
+ write_comm_pipe_pvoid(&native2amiga_pending, state, 0);
+ write_comm_pipe_u32(&native2amiga_pending, task, 0);
+ write_comm_pipe_int(&native2amiga_pending, mask, 1);
+ do_uae_int_requested();
+ uae_nativesem_post();
}
+
void uae_NotificationHack (uaecptr port, uaecptr nr)
{
- uae_sem_wait (&n2asem);
+ uae_nativesem_wait();
write_comm_pipe_int (&native2amiga_pending, 4, 0);
write_comm_pipe_int (&native2amiga_pending, port, 0);
write_comm_pipe_int (&native2amiga_pending, nr, 1);
do_uae_int_requested ();
- uae_sem_post (&n2asem);
+ uae_nativesem_post();
+}
+
+void uae_ShellExecute(TCHAR *command)
+{
+ TCHAR *cmd = my_strdup(command);
+ uae_nativesem_wait();
+ write_comm_pipe_int(&native2amiga_pending, 5, 0);
+ write_comm_pipe_pvoid(&native2amiga_pending, cmd, 1);
+ do_uae_int_requested();
+ uae_nativesem_post();
}
#endif