]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Shell execute custom event support. Joystick mode/autofire is stored correctly.
authorToni Wilen <twilen@winuae.net>
Sun, 14 Feb 2016 16:35:24 +0000 (18:35 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 14 Feb 2016 16:35:24 +0000 (18:35 +0200)
cfgfile.cpp
filesys.cpp
include/native2amiga_api.h
inputdevice.cpp
native2amiga.cpp

index 0fbe3e2231daddf3f7c2adc57a23c3c85de4091f..67bdb6aaee4608905eb35f85ae87cf24f24975bc 100644 (file)
@@ -36,6 +36,7 @@
 #include "gfxboard.h"
 #include "cpuboard.h"
 #include "luascript.h"
+#include "native2amiga_api.h"
 
 #define cfgfile_warning write_log
 #define cfgfile_warning_obsolete write_log
@@ -5874,7 +5875,9 @@ uae_u32 cfgfile_modify (uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR *
 
        for (i = 0; i < argv; i++) {
                if (i + 2 <= argv) {
-                       if (!_tcsicmp (argc[i], _T("dbg"))) {
+                       if (!_tcsicmp (argc[i], _T("shellexec"))) {
+                               uae_ShellExecute(argc[i + 1]);
+                       } else if (!_tcsicmp (argc[i], _T("dbg"))) {
                                debug_parser (argc[i + 1], out, outsize);
                        } else if (!inputdevice_uaelib (argc[i], argc[i + 1])) {
                                if (!cfgfile_parse_uaelib_option (&changed_prefs, argc[i], argc[i + 1], 0)) {
index 3f13c6306e5ae67611c1f0cc33272ebadd94123c..45e8658743623f4782d9fe1b2be424a7e979ece3 100644 (file)
@@ -95,8 +95,6 @@ int log_filesys = 0;
 
 #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)
@@ -139,6 +137,7 @@ static uaecptr bootrom_start;
 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;
@@ -148,6 +147,7 @@ static uaecptr ROM_filesys_doio, ROM_filesys_doio_original;
 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
@@ -5323,7 +5323,6 @@ static void action_write(TrapContext *ctx, Unit *unit, dpacket *packet)
        uae_u32 size = GET_PCK_ARG3 (packet);
        uae_u32 actual;
        uae_u8 *buf;
-       int i;
 
        if (k == 0) {
                PUT_PCK_RES1 (packet, DOS_FALSE);
@@ -6529,8 +6528,7 @@ static void action_free_record64(TrapContext *ctx, Unit *unit, dpacket *packet)
 * 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)
 {
@@ -6539,6 +6537,39 @@ 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
@@ -6599,6 +6630,12 @@ static uae_u32 REGPARAM2 exter_int_helper(TrapContext *ctx)
                /* 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));
@@ -6623,10 +6660,19 @@ static uae_u32 REGPARAM2 exter_int_helper(TrapContext *ctx)
                                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:
@@ -6668,152 +6714,6 @@ end:
        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);
@@ -7109,12 +7009,6 @@ void filesys_start_threads (void)
        }
 }
 
-void filesys_cleanup (void)
-{
-       filesys_free_handles ();
-       free_mountinfo ();
-}
-
 void filesys_free_handles (void)
 {
        Unit *u, *u1;
@@ -7167,6 +7061,9 @@ void filesys_reset (void)
        load_injected_icons();
        filesys_reset2 ();
        initialize_mountinfo ();
+
+       shell_execute_data = 0;
+       shell_execute_process = 0;
 }
 
 static void filesys_prepare_reset2 (void)
@@ -8764,6 +8661,15 @@ void filesys_vsync (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;
@@ -8771,7 +8677,7 @@ void filesys_install (void)
        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");
index f313ef6d6a11225feccd209215608633c660807a..c2969cbb222e1e933170e5cfcd748926bed8118f 100644 (file)
 #include "uae/types.h"
 
 #ifdef SUPPORT_THREADS
+typedef void(*UAE_PROCESSED)(int);
+
 void uae_Cause(uaecptr interrupt);
 void uae_ReplyMsg(uaecptr msg);
 void uae_PutMsg(uaecptr port, uaecptr msg);
 void uae_Signal(uaecptr task, uae_u32 mask);
+void uae_Signal_with_Func(uaecptr task, uae_u32 mask, UAE_PROCESSED state);
 void uae_NotificationHack(uaecptr, uaecptr);
+void uae_ShellExecute(TCHAR *command);
 #endif
 int native2amiga_isfree(void);
+void uae_nativesem_wait(void);
+void uae_nativesem_post(void);
 
 #endif /* UAE_NATIVE2AMIGA_API_H */
index 0f5a69ea3adaa02fd8b72bd9909ffe5259a908e6..6adb48a25abc6471b795ad0bcb36d7a598d9ddc2 100644 (file)
@@ -58,6 +58,7 @@
 #endif
 #include "tabletlibrary.h"
 #include "statusline.h"
+#include "native2amiga_api.h"
 
 #if SIZEOF_TCHAR != 1
 /* FIXME: replace strcasecmp with _tcsicmp in source code instead */
@@ -3436,8 +3437,10 @@ static int handle_custom_event (const TCHAR *custom)
                        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)) {
@@ -6716,7 +6719,7 @@ void inputdevice_devicechange (struct uae_prefs *prefs)
        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();
@@ -6730,8 +6733,6 @@ void inputdevice_devicechange (struct uae_prefs *prefs)
                                        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;
@@ -8320,6 +8321,7 @@ static void inputdevice_get_previous_joy(struct uae_prefs *p, int portnum)
 {
        bool found = false;
        int idx = 0;
+       struct jport *jpx = &p->jports[portnum];
        for (;;) {
                struct jport *jp = inputdevice_get_used_device(portnum, idx);
                if (!jp)
@@ -8329,10 +8331,12 @@ static void inputdevice_get_previous_joy(struct uae_prefs *p, int portnum)
                        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;
                }
index 74bfdb33b1829abf0d6874f522c13a93fa04ef49..4410945ccd3d6289a1f464e06ac2ddcfcc8f1174 100644 (file)
@@ -30,7 +30,7 @@ static uae_sem_t n2asem;
 
 void native2amiga_install (void)
 {
-       init_comm_pipe (&native2amiga_pending, 100, 2);
+       init_comm_pipe (&native2amiga_pending, 300, 2);
        uae_sem_init (&n2asem, 0, 1);
 }
 
@@ -56,52 +56,83 @@ int native2amiga_isfree (void)
 
 #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