Пример #1
0
/*
 * Set up extended trap context and call handler function
 */
static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
{
    struct ExtendedTrapContext *context = (struct ExtendedTrapContext *) calloc (1, sizeof (ExtendedTrapContext));

    if (context) {
	uae_sem_init (&context->switch_to_trap_sem, 0, 0);
	uae_sem_init (&context->switch_to_emu_sem, 0, 0);

	context->trap_handler    = handler_func;
	context->trap_has_retval = has_retval;

	context->regs = regs;       /* Working copy of regs */

	context->saved_regs = regs; /* Copy of regs to be restored when trap is done */

	/* Start thread to handle new trap context. */
	uae_start_thread_fast (trap_thread, (void *)context, &context->thread);

	/* Switch to trap context to begin execution of
	 * trap handler function.
	 */
	uae_sem_post (&context->switch_to_trap_sem);

	/* Wait for trap context to switch back to us.
	 *
	 * It'll do this when the trap handler is done - or when
	 * the handler wants to call 68k code. */
	uae_sem_wait (&context->switch_to_emu_sem);

	/* Use trap's modified 68k state. This will reset the PC, so that
	 * execution will resume at either the m68k call handler or the
	 * the exit handler. */
	regs = context->regs;
    }
}
Пример #2
0
int32_t uaenet_open (struct uaenetdata *sd, struct netdriverdata *tc, struct s2devstruct *user,
				uaenet_gotfunc *gotfunc, uaenet_getfunc *getfunc, int32_t promiscuous)
{
	char *s;

	s = ua (tc->name);
	sd->fp = pcap_open_live (s, 65536, promiscuous, 100, sd->errbuf);
	xfree (s);
	if (sd->fp == NULL) {
		TCHAR *ss = au (sd->errbuf);
		write_log ("'%s' failed to open: %s\n", tc->name, ss);
		xfree (ss);
		return 0;
	}
	sd->tc = tc;
	sd->user = user;
	sd->mtu = tc->mtu;
	sd->readbuffer = xmalloc (uint8_t, sd->mtu);
	sd->writebuffer = xmalloc (uint8_t, sd->mtu);
	sd->gotfunc = gotfunc;
	sd->getfunc = getfunc;

	uae_sem_init (&sd->change_sem, 0, 1);
	uae_sem_init (&sd->sync_semr, 0, 0);
	uae_start_thread ("uaenet_r", uaenet_trap_threadr, sd, &sd->tidr);
	uae_sem_wait (&sd->sync_semr);
	uae_sem_init (&sd->sync_semw, 0, 0);
	uae_start_thread ("uaenet_w", uaenet_trap_threadw, sd, &sd->tidw);
	uae_sem_wait (&sd->sync_semw);
	write_log ("uaenet initialized\n");
	return 1;
}
Пример #3
0
/*
 * Set up extended trap context and call handler function
 */
static void trap_HandleExtendedTrap (TrapHandler handler_func, int has_retval)
{
	struct TrapContext *context = xcalloc (TrapContext, 1);

	if (context) {
		uae_sem_init (&context->switch_to_trap_sem, 0, 0);
		uae_sem_init (&context->switch_to_emu_sem, 0, 0);

		context->trap_handler = handler_func;
		context->trap_has_retval = has_retval;

		context->saved_regs = regs; /* Copy of regs to be restored when trap is done */

		/* Start thread to handle new trap context. */
		uae_start_thread ("Trap", trap_thread, (void *)context, &context->thread);

		/* Switch to trap context to begin execution of
		 * trap handler function.
		 */
		uae_sem_post (&context->switch_to_trap_sem);

		/* Wait for trap context to switch back to us.
		 *
		 * It'll do this when the trap handler is done - or when
		 * the handler wants to call 68k code. */
		uae_sem_wait (&context->switch_to_emu_sem);
	}
}
Пример #4
0
void netdev_start_threads (void)
{
	if (!currprefs.sana2)
		return;
	if (log_net)
		write_log (_T("netdev_start_threads()\n"));
	uae_sem_init (&change_sem, 0, 1);
	uae_sem_init (&async_sem, 0, 1);
}
Пример #5
0
/* We need a thread for this, since communication between finish_sound_buffer
 * and the callback works through semaphores.  In theory, this is unnecessary,
 * since SDL uses a sound thread internally, and the callback runs in its
 * context.  But we don't want to depend on SDL's internals too much.  */
static void init_sound_thread(void) {
    write_log("init_sound_thread\n");
	uae_thread_id tid;

	init_comm_pipe (&to_sound_pipe, 20, 1);
	uae_sem_init (&data_available_sem, 0, 0);
	uae_sem_init (&callback_done_sem, 0, 0);
	uae_sem_init (&sound_init_sem, 0, 0);
	uae_start_thread ("Sound", sound_thread, NULL, &tid);
}
Пример #6
0
/*
 * gui_init()
 *
 * This is called from the main UAE thread to tell the GUI to initialize.
 * To indicate failure to initialize, return -1.
 */
int32_t gui_init (void)
{
    init_comm_pipe (&from_gui_pipe, 8192 /* size */, 1 /* chunks */);
    uae_sem_init (&gui_sem, 0, 1);
    gui_initialized = 1;
    return 0;
}
Пример #7
0
static int32_t start_thread (struct devstruct *dev)
{
	init_comm_pipe (&dev->requests, 100, 1);
	uae_sem_init (&dev->sync_sem, 0, 0);
	uae_start_thread (_T("uaeserial"), dev_thread, dev, NULL);
	uae_sem_wait (&dev->sync_sem);
	return dev->thread_running;
}
Пример #8
0
void scsidev_start_threads (void)
{
    if (!currprefs.scsi) /* quite useless.. */
	return;
    if (log_scsi)
	write_log ("scsidev_start_threads()\n");
    uae_sem_init (&change_sem, 0, 1);
}
Пример #9
0
int uaenet_open (void *vsd, struct netdriverdata *tc, void *user, uaenet_gotfunc *gotfunc, uaenet_getfunc *getfunc, int promiscuous, const uae_u8 *mac)
{
	struct uaenetdatawin32 *sd = (struct uaenetdatawin32*)vsd;
	char *s;

	s = ua (tc->name);
	if (mac)
		memcpy(tc->mac, mac, 6);
	if (memcmp(tc->mac, tc->originalmac, 6)) {
		promiscuous = 1;
	}
	sd->fp = ppcap_open(s, 65536, (promiscuous ? PCAP_OPENFLAG_PROMISCUOUS : 0) | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, NULL, sd->errbuf);
	xfree (s);
	if (sd->fp == NULL) {
		TCHAR *ss = au (sd->errbuf);
		write_log (_T("'%s' failed to open: %s\n"), tc->name, ss);
		xfree (ss);
		return 0;
	}
	sd->tc = tc;
	sd->user = user;
	sd->evttw = CreateEvent (NULL, FALSE, FALSE, NULL);

	if (!sd->evttw)
		goto end;
	sd->mtu = tc->mtu;
	sd->readbuffer = xmalloc (uae_u8, sd->mtu);
	sd->writebuffer = xmalloc (uae_u8, sd->mtu);
	sd->gotfunc = gotfunc;
	sd->getfunc = getfunc;

	uae_sem_init (&sd->change_sem, 0, 1);
	uae_sem_init (&sd->sync_semr, 0, 0);
	uae_start_thread (_T("uaenet_win32r"), uaenet_trap_threadr, sd, &sd->tidr);
	uae_sem_wait (&sd->sync_semr);
	uae_sem_init (&sd->sync_semw, 0, 0);
	uae_start_thread (_T("uaenet_win32w"), uaenet_trap_threadw, sd, &sd->tidw);
	uae_sem_wait (&sd->sync_semw);
	write_log (_T("uaenet_win32 initialized\n"));
	return 1;

end:
	uaenet_close (sd);
	return 0;
}
Пример #10
0
void native2amiga_install (void)
{
  if(native2amiga_pending.size != 300)
    init_comm_pipe (&native2amiga_pending, 300, 2);
  if(n2asem != 0)
    uae_sem_destroy(&n2asem);
  n2asem = 0;
  uae_sem_init (&n2asem, 0, 1);
}
Пример #11
0
static int start_thread (struct s2devstruct *dev)
{
	if (dev->thread_running)
		return 1;
	init_comm_pipe (&dev->requests, 100, 1);
	uae_sem_init (&dev->sync_sem, 0, 0);
	uae_start_thread (SANA2NAME, dev_thread, dev, NULL);
	uae_sem_wait (&dev->sync_sem);
	return dev->thread_running;
}
Пример #12
0
/*
 * Initialize the extended trap mechanism.
 */
void init_extended_traps (void)
{
	m68k_call_trapaddr = here ();
	calltrap (deftrap2 (m68k_call_handler, TRAPFLAG_NO_RETVAL, _T("m68k_call")));

	m68k_return_trapaddr = here();
	calltrap (deftrap2 (m68k_return_handler, TRAPFLAG_NO_RETVAL, _T("m68k_return")));

	exit_trap_trapaddr = here();
	calltrap (deftrap2 (exit_trap_handler, TRAPFLAG_NO_RETVAL, _T("exit_trap")));

	uae_sem_init (&trap_mutex, 0, 1);
}
Пример #13
0
static int open_scsi_bus (int flags)
{
	if (bus_open) {
		write_log (L"SPTI open_bus() more than once!\n");
		return 1;
	}
	total_devices = 0;
	uae_sem_init (&scgp_sem, 0, 1);
	rescan ();
	bus_open = 1;
	write_log (L"SPTI driver open, %d devices.\n", total_devices);
	return total_devices;
}
Пример #14
0
static int start_thread (struct scsidevdata *sdd)
{
#ifdef UAE_SCSIDEV_THREADS
    if (sdd->thread_running)
	return 1;
    init_comm_pipe (&sdd->requests, 10, 1);
    uae_sem_init (&sdd->sync_sem, 0, 0);
    uae_start_thread (scsidev_thread, sdd, &sdd->tid);
    uae_sem_wait (&sdd->sync_sem);
    return sdd->thread_running;
#else
    return 1;
#endif
}
Пример #15
0
/*
 * Initialize the extended trap mechanism.
 */
void init_extended_traps (void)
{
    m68k_call_trapaddr = here ();
    calltrap (deftrap2 ((TrapHandler)m68k_call_handler, TRAPFLAG_NO_RETVAL, "m68k_call"));

    m68k_return_trapaddr = here();
    calltrap (deftrap2 ((TrapHandler)m68k_return_handler, TRAPFLAG_NO_RETVAL, "m68k_return"));

    exit_trap_trapaddr = here();
    calltrap (deftrap2 ((TrapHandler)exit_trap_handler, TRAPFLAG_NO_RETVAL, "exit_trap"));

    if(trap_mutex != 0)
      uae_sem_destroy(&trap_mutex);
    trap_mutex = 0;
    uae_sem_init (&trap_mutex, 0, 1);
}
Пример #16
0
int graphics_init (void)
{
	int i,j;

	uae_sem_init (&vsync_wait_sem, 0, 1);

	graphics_subinit ();


	if (!init_colors ())
		return 0;

	buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
	keyboard_init();
  
	return 1;
}
Пример #17
0
int graphics_setup(void)
{
#ifdef PICASSO96
	picasso_InitResolutions();
	InitPicasso96();
#endif
  VCHI_INSTANCE_T vchi_instance;
  VCHI_CONNECTION_T *vchi_connection;
  TV_DISPLAY_STATE_T tvstate;

  if(vchi_initialise(&vchi_instance) == 0) {
    if(vchi_connect(NULL, 0, vchi_instance) == 0) {
      vc_vchi_tv_init(vchi_instance, &vchi_connection, 1);
      if(vc_tv_get_display_state(&tvstate) == 0) {
        HDMI_PROPERTY_PARAM_T property;
        property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE;
        vc_tv_hdmi_get_property(&property);
        float frame_rate = property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tvstate.display.hdmi.frame_rate * (1000.0f/1001.0f) : tvstate.display.hdmi.frame_rate;
        host_hz = (int)frame_rate;
        time_per_host_frame = time_for_host_hz_frames / host_hz;
      }
      vc_vchi_tv_stop();
      vchi_disconnect(vchi_instance);
    }
  }

  if(display_pipe == 0) {
    display_pipe = xmalloc (smp_comm_pipe, 1);
    init_comm_pipe(display_pipe, 20, 1);
  }
  if(display_sem == 0) {
    uae_sem_init (&display_sem, 0, 0);
  }
  if(display_tid == 0 && display_pipe != 0 && display_sem != 0) {
    uae_start_thread(_T("render"), display_thread, NULL, &display_tid);
  }
	write_comm_pipe_u32(display_pipe, DISPLAY_SIGNAL_SETUP, 1);
	
	return 1;
}
Пример #18
0
static int open_scsi_bus (int flags)
{
    int   result = 0;
    int   debug, verbose;
    SCSI *scgp_scan;
    char *device;
    char  errstr[128];
    static int init = 0;

    DEBUG_LOG ("SCSIDEV: open_scsi_bus\n");

    if (!init) {
	init = 1;
	uae_sem_init (&scgp_sem, 0, 1);
	/* TODO: replace global lock with per-device locks */
    }

    debug   = getenvint ("UAE_SCSI_DEBUG", 0);
    verbose = getenvint ("UAE_SCSI_VERBOSE", 0);
    device  = getenv    ("UAE_SCSI_DEVICE");

    if (!device || (strlen (device) == 0))
	device = currprefs.scsi_device;

    if ((scgp_scan = scg_open (device, errstr, sizeof (errstr),
					       debug, verbose)) != (SCSI *)0) {
	scanscsi (scgp_scan);
	result = 1;
	scg_close (scgp_scan);
    } else {
	write_log ("SCSIDEV: can't open bus: %s\n", errstr);
    }

    write_log ("SCSIDEV: %d devices found\n", total_drives);
    return result;
}
Пример #19
0
int ethernet_open (struct netdriverdata *ndd, void *vsd, void *user, ethernet_gotfunc *gotfunc, ethernet_getfunc *getfunc, int promiscuous)
{
	switch (ndd->type)
	{
		case UAENET_SLIRP:
		case UAENET_SLIRP_INBOUND:
		{
			struct ethernet_data *ed = (struct ethernet_data*)vsd;
			ed->gotfunc = gotfunc;
			ed->getfunc = getfunc;
			ed->userdata = user;
			slirp_data = ed;
			uae_sem_init (&slirp_sem1, 0, 1);
			uae_sem_init (&slirp_sem2, 0, 1);
			slirp_init ();
			for (int i = 0; i < MAX_SLIRP_REDIRS; i++) {
				struct slirp_redir *sr = &currprefs.slirp_redirs[i];
				if (sr->proto) {
					struct in_addr a;
					if (sr->srcport == 0) {
					    inet_aton("10.0.2.15", &a);
						slirp_redir (0, sr->dstport, a, sr->dstport);
					} else {
#ifdef HAVE_STRUCT_IN_ADDR_S_UN
						a.S_un.S_addr = sr->addr;
#else
						a.s_addr = sr->addr;
#endif
						slirp_redir (sr->proto == 1 ? 0 : 1, sr->dstport, a, sr->srcport);
					}
				}
			}
			if (ndd->type == UAENET_SLIRP_INBOUND) {
				struct in_addr a;
			    inet_aton("10.0.2.15", &a);
				for (int i = 0; slirp_ports[i]; i++) {
					int port = slirp_ports[i];
					int j;
					for (j = 0; j < MAX_SLIRP_REDIRS; j++) {
						struct slirp_redir *sr = &currprefs.slirp_redirs[j];
						if (sr->proto && sr->dstport == port)
							break;
					}
					if (j == MAX_SLIRP_REDIRS)
						slirp_redir (0, port + SLIRP_PORT_OFFSET, a, port);
				}
			}
			netmode = ndd->type;
			slirp_start ();
		}
		return 1;
#ifdef WITH_UAENET_PCAP
		case UAENET_PCAP:
		if (uaenet_open (vsd, ndd, user, gotfunc, getfunc, promiscuous)) {
			netmode = ndd->type;
			return 1;
		}
		return 0;
#endif
	}
	return 0;
}
Пример #20
0
void uaeserialdev_start_threads (void)
{
	uae_sem_init (&change_sem, 0, 1);
	uae_sem_init (&async_sem, 0, 1);
}
Пример #21
0
/* open device level access to cd rom drive */
static int sys_cddev_open (struct dev_info_ioctl *ciw, int unitnum)
{

	ciw->cdda_volume[0] = 0x7fff;
	ciw->cdda_volume[1] = 0x7fff;
	/* buffer must be page aligned for device access */
	ciw->tempbuffer = (uae_u8*)VirtualAlloc (NULL, IOCTL_DATA_BUFFER, MEM_COMMIT, PAGE_READWRITE);
	if (!ciw->tempbuffer) {
		write_log (_T("IOCTL: failed to allocate buffer"));
		return 1;
	}

	memset (ciw->di.vendorid, 0, sizeof ciw->di.vendorid);
	memset (ciw->di.productid, 0, sizeof ciw->di.productid);
	memset (ciw->di.revision, 0, sizeof ciw->di.revision);
	_tcscpy (ciw->di.vendorid, _T("UAE"));
	_stprintf (ciw->di.productid, _T("SCSI CD%d IMG"), unitnum);
	_tcscpy (ciw->di.revision, _T("0.2"));

#if 0
	uae_u8 inquiry[256];
	int datalen;
	memset (inquiry, 0, sizeof inquiry);
	if (spti_inquiry (ciw, unitnum, inquiry, &datalen)) {
		// check also that device type is non-zero and it is removable
		if (datalen >= 36 && (inquiry[0] & 31) && (inquiry[1] & 0x80) && inquiry[8]) {
			char tmp[20];
			TCHAR *s;
			memcpy (tmp, inquiry + 8, 8);
			tmp[8] = 0;
			s = au (tmp);
			trim (s);
			_tcscpy (ciw->di.vendorid, s);
			xfree (s);
			memcpy (tmp, inquiry + 16, 16);
			tmp[16] = 0;
			s = au (tmp);
			trim (s);
			_tcscpy (ciw->di.productid, s);
			xfree (s);
			memcpy (tmp, inquiry + 32, 4);
			tmp[4] = 0;
			s = au (tmp);
			trim (s);
			_tcscpy (ciw->di.revision, s);
			xfree (s);
		}
		close_createfile (ciw);
	}
#endif

	if (!open_createfile (ciw, 0)) {
		write_log (_T("IOCTL: failed to open '%s', err=%d\n"), ciw->devname, GetLastError ());
		goto error;
	}

	STORAGE_PROPERTY_QUERY query;
	UCHAR outBuf[20000];
	ULONG returnedLength;
	memset (&query, 0, sizeof query);
	query.PropertyId = StorageDeviceProperty;
	query.QueryType = PropertyStandardQuery;
	if (DeviceIoControl(
		ciw->h,
		IOCTL_STORAGE_QUERY_PROPERTY,
		&query,
		sizeof (STORAGE_PROPERTY_QUERY),
		&outBuf,
		sizeof (outBuf),
		&returnedLength,
		NULL
	)) {
		PSTORAGE_DEVICE_DESCRIPTOR devDesc;
		devDesc = (PSTORAGE_DEVICE_DESCRIPTOR) outBuf;
		int size = devDesc->Version;
		PUCHAR p = (PUCHAR) outBuf;
		for (;;) {
			if (offsetof(STORAGE_DEVICE_DESCRIPTOR, CommandQueueing) > size)
				break;
			if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, VendorIdOffset) && devDesc->VendorIdOffset && p[devDesc->VendorIdOffset]) {
				ciw->di.vendorid[0] = 0;
				ciw->di.productid[0] = 0;
				ciw->di.revision[0] = 0;
				int j = 0;
				for (int i = devDesc->VendorIdOffset; p[i] != (UCHAR) NULL && i < returnedLength && j < sizeof (ciw->di.vendorid) / sizeof (TCHAR) - 1; i++)
					ciw->di.vendorid[j++] = p[i];
			}
			if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductIdOffset) && devDesc->ProductIdOffset && p[devDesc->ProductIdOffset]) {
				int j = 0;
				for (int i = devDesc->ProductIdOffset; p[i] != (UCHAR) NULL && i < returnedLength && j < sizeof (ciw->di.productid) / sizeof (TCHAR) - 1; i++)
					ciw->di.productid[j++] = p[i];
			}
			if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductRevisionOffset) && devDesc->ProductRevisionOffset && p[devDesc->ProductRevisionOffset]) {
				int j = 0;
				for (int i = devDesc->ProductRevisionOffset; p[i] != (UCHAR) NULL && i < returnedLength && j < sizeof (ciw->di.revision) / sizeof (TCHAR) - 1; i++)
					 ciw->di.revision[j++] = p[i];
			}
			trim (ciw->di.vendorid);
			trim (ciw->di.productid);
			trim (ciw->di.revision);
			break;
		}
	}

	write_log (_T("IOCTL: device '%s' (%s/%s/%s) opened succesfully (unit=%d,media=%d)\n"),
		ciw->devname, ciw->di.vendorid, ciw->di.productid, ciw->di.revision,
		unitnum, ciw->di.media_inserted);
	if (!_tcsicmp (ciw->di.vendorid, _T("iomega")) && !_tcsicmp (ciw->di.productid, _T("rrd"))) {
		write_log (_T("Device blacklisted\n"));
		goto error2;
	}
	uae_sem_init (&ciw->sub_sem, 0, 1);
	uae_sem_init (&ciw->sub_sem2, 0, 1);
	//ciw->usesptiread = true;
	ioctl_command_stop (unitnum);
	update_device_info (unitnum);
	ciw->open = true;
	return 0;
error:
	win32_error (ciw, unitnum, _T("CreateFile"));
error2:
	VirtualFree (ciw->tempbuffer, 0, MEM_RELEASE);
	ciw->tempbuffer = NULL;
	CloseHandle (ciw->h);
	ciw->h = NULL;
	return -1;
}
Пример #22
0
uae_u32 uaenative_call_function (TrapContext *context, int flags)
{
    if (!currprefs.native_code) {
        return UNI_ERROR_NOT_ENABLED;
    }

    struct uni uni;
    uni.function = m68k_areg (regs, 0);
    if (flags & UNI_FLAG_COMPAT) {
        uni.library = 0;
#ifdef AHI
        uni.uaevar_compat = uaenative_get_uaevar();
#else
        uni.uaevar_compat = NULL;
#endif
    }
    else if (flags & UNI_FLAG_NAMED_FUNCTION) {
        uni.library = m68k_dreg (regs, 0);
    }
    else {
        uni.library = 0;
    }

    struct library_data *library_data;

    if (uni.library) {
        // library handle given, function is pointer to function name
        const char *function = (const char *) get_real_address (uni.function);

        library_data = get_library_data_from_handle (uni.library);
        if (library_data == NULL) {
            write_log (_T("uni: get_function - invalid library (%d)\n"),
                    uni.library);
            return UNI_ERROR_INVALID_LIBRARY;
        }

        uni.native_function = dl_symbol (library_data->dl_handle, function);
        if (uni.native_function == NULL) {
            write_log (_T("uni: get_function - function (%s) not found ")
                       _T("in library %d (%p)\n"), function, uni.library,
                                                   library_data->dl_handle);
            return UNI_ERROR_FUNCTION_NOT_FOUND;
        }
    }
    else {
        // library handle not given, function argument is function handle
        int index = uni.function - (uae_u32) 0x80000000;
        if (index >= 0 && index <= g_max_handle) {
            uni.native_function = g_handles[index].function;
            library_data = g_handles[index].library;
        }
        else {
            uni.native_function = NULL;
        }
        if (uni.native_function == NULL) {
            // printf ("UNI_ERROR_INVALID_FUNCTION\n");
            return UNI_ERROR_INVALID_FUNCTION;
        }
    }

    if (context == NULL) {
        // we have no context and cannot call into m68k space
        flags &= ~UNI_FLAG_ASYNCHRONOUS;
    }

    uni.d1 = m68k_dreg (regs, 1);
    uni.d2 = m68k_dreg (regs, 2);
    uni.d3 = m68k_dreg (regs, 3);
    uni.d4 = m68k_dreg (regs, 4);
    uni.d5 = m68k_dreg (regs, 5);
    uni.d6 = m68k_dreg (regs, 6);
    uni.d7 = m68k_dreg (regs, 7);
    uni.a1 = m68k_areg (regs, 1);
    uni.a2 = m68k_areg (regs, 2);
    uni.a3 = m68k_areg (regs, 3);
    uni.a4 = m68k_areg (regs, 4);
    uni.a5 = m68k_areg (regs, 5);
    uni.a7 = m68k_areg (regs, 7);

    uni.flags = flags;
    uni.error = 0;

    if (flags & UNI_FLAG_ASYNCHRONOUS) {
        uaecptr sysbase = get_long (4);
        uni.task = get_long (sysbase + 276); // ThisTask

        // make sure signal bit is cleared
        m68k_dreg (regs, 0) = 0;
        m68k_dreg (regs, 1) = 1 << SIGBIT;
        CallLib (context, sysbase, -0x132); // SetSignal

        // start thread if necessary
        if (!library_data->thread_id) {
            uae_sem_init (&library_data->full_count, 0, 0);
            // we don't have a queue as such, the thread only processes
            // one item at a time with a "queue size" of 1
            uae_sem_init (&library_data->empty_count, 0, 1);
            uae_start_thread (_T("uaenative"), uaenative_thread,
                              library_data, &library_data->thread_id);
        }

        // signal async thread to process new function call
        uae_sem_wait(&library_data->empty_count);
        library_data->uni = &uni;
        uae_sem_post(&library_data->full_count);

        // wait for signal
        m68k_dreg (regs, 0) = 1 << SIGBIT;
        CallLib (context, sysbase, -0x13e); // Wait
        write_log (_T("uni: -- Got async result --\n"));
    }
    else {
        // synchronous mode, just call the function here and now
        do_call_function(&uni);
    }
    return uni.result;
}
Пример #23
0
void native2amiga_install (void)
{
	init_comm_pipe (&native2amiga_pending, 100, 2);
	uae_sem_init (&n2asem, 0, 1);
}