Example #1
0
void ethernet_trigger (struct netdriverdata *ndd, void *vsd)
{
	if (!ndd)
		return;
	switch (ndd->type)
	{
		case UAENET_SLIRP:
		case UAENET_SLIRP_INBOUND:
		{
			struct ethernet_data *ed = (struct ethernet_data*)vsd;
			if (slirp_data) {
				uae_u8 pkt[4000];
				int len = sizeof pkt;
				int v;
				uae_sem_wait (&slirp_sem1);
				v = slirp_data->getfunc(ed->userdata, pkt, &len);
				uae_sem_post (&slirp_sem1);
				if (v) {
					uae_sem_wait (&slirp_sem2);
					slirp_input(pkt, len);
					uae_sem_post (&slirp_sem2);
				}
			}
		}
		return;
#ifdef WITH_UAENET_PCAP
		case UAENET_PCAP:
		uaenet_trigger (vsd);
		return;
#endif
	}
}
static int fetch_geometry (struct dev_info_ioctl *ciw, int unitnum, struct device_info *di)
{
	DISK_GEOMETRY geom;
	DWORD len;
	int cnt = 3;

	if (!open_createfile (ciw, 0))
		return 0;
	uae_sem_wait (&ciw->sub_sem);
	seterrormode (ciw);
	while (cnt-- > 0) {
		if (!DeviceIoControl (ciw->h, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &geom, sizeof (geom), &len, NULL)) {
			DWORD err = GetLastError ();
			if (err == ERROR_WRONG_DISK) {
				if (win32_error (ciw, unitnum, _T("IOCTL_CDROM_GET_DRIVE_GEOMETRY")) < 0)
					continue;
			}
			reseterrormode (ciw);
			uae_sem_post (&ciw->sub_sem);
			return 0;
		}
		break;
	}
	reseterrormode (ciw);
	uae_sem_post (&ciw->sub_sem);
	if (di) {
		di->cylinders = geom.Cylinders.LowPart;
		di->sectorspertrack = geom.SectorsPerTrack;
		di->trackspercylinder = geom.TracksPerCylinder;
		di->bytespersector = geom.BytesPerSector;
	}
	return 1;
}
Example #3
0
static int32_t release_async_request (struct devstruct *dev, uaecptr request)
{
	struct asyncreq *ar, *prevar;

	uae_sem_wait (&async_sem);
	ar = dev->ar;
	prevar = NULL;
	while (ar) {
		if (ar->request == request) {
			if (prevar == NULL)
				dev->ar = ar->next;
			else
				prevar->next = ar->next;
			uae_sem_post (&async_sem);
			xfree (ar);
			if (log_uaeserial)
				write_log (_T("%s:%d async request %x removed\n"), getdevname(), dev->unit, request);
			return 1;
		}
		prevar = ar;
		ar = ar->next;
	}
	uae_sem_post (&async_sem);
	write_log (_T("%s:%d async request %x not found for removal!\n"), getdevname(), dev->unit, request);
	return 0;
}
Example #4
0
static void *dev_thread (void *devs)
{
	struct devstruct *dev = (struct devstruct*)devs;

	uae_set_thread_priority (2);
	dev->thread_running = 1;
	uae_sem_post (&dev->sync_sem);
	for (;;) {
		uaecptr request = (uaecptr)read_comm_pipe_u32_blocking (&dev->requests);
		uae_sem_wait (&change_sem);
		if (!request) {
			dev->thread_running = 0;
			uae_sem_post (&dev->sync_sem);
			uae_sem_post (&change_sem);
			return 0;
		} else if (get_async_request (dev, request, 1)) {
			uae_ReplyMsg (request);
			release_async_request (dev, request);
		} else if (dev_do_io (dev, request, 0) == 0) {
			uae_ReplyMsg (request);
		} else {
			add_async_request (dev, request);
			uaeser_trigger (dev->sysdata);
		}
		uae_sem_post (&change_sem);
	}
	return 0;
}
Example #5
0
static void *dev_thread (void *devs)
{
	struct s2devstruct *dev = (struct s2devstruct*)devs;

	uae_set_thread_priority (NULL, 1);
	dev->thread_running = 1;
	uae_sem_post (&dev->sync_sem);
	for (;;) {
		uaecptr request = (uaecptr)read_comm_pipe_u32_blocking (&dev->requests);
		uae_sem_wait (&change_sem);
		if (!request) {
			dev->thread_running = 0;
			uae_sem_post (&dev->sync_sem);
			uae_sem_post (&change_sem);
			write_log (_T("%s: dev_thread killed\n"), getdevname ());
			return 0;
		} else if (get_async_request (dev, request, 1)) {
			uae_ReplyMsg (request);
			release_async_request (dev, request);
			rem_async_packet (dev, request);
		} else if (dev_do_io (dev, request, 0) == 0) {
			uae_ReplyMsg (request);
			rem_async_packet (dev, request);
		} else {
			add_async_request (dev, request);
			ethernet_trigger (dev->sysdata);
		}
		uae_sem_post (&change_sem);
	}
	return 0;
}
Example #6
0
static void *uaenet_trap_threadr (void *arg)
{
	struct uaenetdatawin32 *sd = (struct uaenetdatawin32*)arg;
	struct pcap_pkthdr *header;
	const u_char *pkt_data;

	uae_set_thread_priority (NULL, 1);
	sd->threadactiver = 1;
	uae_sem_post (&sd->sync_semr);
	while (sd->threadactiver == 1) {
		int r;
		r = pcap_next_ex (sd->fp, &header, &pkt_data);
		if (r == 1) {
			uae_sem_wait (&sd->change_sem);
			sd->gotfunc ((struct s2devstruct*)sd->user, pkt_data, header->len);
			uae_sem_post (&sd->change_sem);
		}
		if (r < 0) {
			write_log (L"pcap_next_ex failed, err=%d\n", r);
			break;
		}
	}
	sd->threadactiver = 0;
	uae_sem_post (&sd->sync_semr);
	return 0;
}
Example #7
0
/*
 * Call m68k function from an extended trap handler
 *
 * This function is to be called from the trap context.
 */
static uae_u32 trap_Call68k (TrapContext *context, uaecptr func_addr)
{
	/* Enter critical section - only one trap at a time, please! */
	uae_sem_wait (&trap_mutex);
	current_context = context;

	/* Don't allow an interrupt and thus potentially another
	 * trap to be invoked while we hold the above mutex.
	 * This is probably just being paranoid. */
	regs.intmask = 7;

	/* Set up function call address. */
	context->call68k_func_addr = func_addr;

	/* Set PC to address of 68k call trap, so that it will be
	 * executed when emulator context resumes. */
	m68k_setpc (m68k_call_trapaddr);
	fill_prefetch ();

	/* Switch to emulator context. */
	uae_sem_post (&context->switch_to_emu_sem);

	/* Wait for 68k call return handler to switch back to us. */
	uae_sem_wait (&context->switch_to_trap_sem);

	/* End critical section. */
	uae_sem_post (&trap_mutex);

	/* Get return value from 68k function called. */
	return context->call68k_retval;
}
Example #8
0
static void *dev_thread (void *devs)
{
    struct devstruct *dev = devs;

    uae_set_thread_priority (2);
    dev->thread_running = 1;

    sys_command_open_thread (DF_SCSI, dev->unitnum);
    sys_command_open_thread (DF_IOCTL, dev->unitnum);

    uae_sem_post (&dev->sync_sem);
    for (;;) {
	uaecptr request = (uaecptr)read_comm_pipe_u32_blocking (&dev->requests);
	uae_sem_wait (&change_sem);
	if (!request) {
	    dev->thread_running = 0;
	    uae_sem_post (&dev->sync_sem);
	    uae_sem_post (&change_sem);
	    break;
	} else if (dev_do_io (dev, request) == 0) {
	    put_byte (request + 30, get_byte (request + 30) & ~1);
	    release_async_request (dev, request);
	    uae_ReplyMsg (request);
	} else {
	    if (log_scsi)
		write_log ("async request %08.8X\n", request);
	}
	uae_sem_post (&change_sem);
    }

    sys_command_close_thread (DF_SCSI, dev->unitnum);
    sys_command_close_thread (DF_IOCTL, dev->unitnum);

   return 0;
}
Example #9
0
static void *uaenet_trap_threadw (void *arg)
{
	struct uaenetdatawin32 *sd = (struct uaenetdatawin32*)arg;

	uae_set_thread_priority (NULL, 1);
	sd->threadactivew = 1;
	uae_sem_post (&sd->sync_semw);
	while (sd->threadactivew == 1) {
		int donotwait = 0;
		int towrite = sd->mtu;
		uae_sem_wait (&sd->change_sem);
		if (sd->getfunc ((struct s2devstruct*)sd->user, sd->writebuffer, &towrite)) {
			if (log_ethernet & 1) {
				TCHAR out[1600 * 2], *p;
				p = out;
				for (int i = 0; i < towrite && i < 1600; i++) {
					_stprintf(p, _T("%02x"), sd->writebuffer[i]);
					p += 2;
					*p = 0;
				}
				write_log(_T("OUT %4d: %s\n"), towrite, out);
			}
			ppcap_sendpacket(sd->fp, sd->writebuffer, towrite);
			donotwait = 1;
		}
		uae_sem_post (&sd->change_sem);
		if (!donotwait)
			WaitForSingleObject (sd->evttw, INFINITE);
	}
	sd->threadactivew = 0;
	uae_sem_post (&sd->sync_semw);
	return 0;
}
Example #10
0
static void *sound_thread (void *dummy) {
	for (;;) {
		int cmd = read_comm_pipe_int_blocking(&to_sound_pipe);
		switch(cmd) {
        case 0:
            open_sound();
            uae_sem_post(&sound_init_sem);
            break;
        case 1:
            uae_sem_post(&sound_init_sem);
            return 0;
        }
	}
}
Example #11
0
static void subfunc(uae_u8 *data, int cnt)
{
	uae_u8 out[SUB_CHANNEL_SIZE];
	sub_to_deinterleaved(data, out);
	setsubchannel(out);

	uae_sem_wait(&sub_sem);
	if (subcodebufferinuse[subcodebufferoffsetw]) {
		memset (subcodebufferinuse, 0,sizeof (subcodebufferinuse));
		subcodebufferoffsetw = subcodebufferoffset = 0;
	} else {
		int offset = subcodebufferoffsetw;
		while (cnt > 0) {
			if (subcodebufferinuse[offset]) {
				write_log (_T("CD32: subcode buffer overflow 2\n"));
				break;
			}
			subcodebufferinuse[offset] = 1;
			memcpy (&subcodebuffer[offset * SUB_CHANNEL_SIZE], data, SUB_CHANNEL_SIZE);
			data += SUB_CHANNEL_SIZE;
			offset++;
			if (offset >= MAX_SUBCODEBUFFER)
				offset = 0;
			cnt--;
		}
		subcodebufferoffsetw = offset;
	}
	uae_sem_post(&sub_sem);
}
Example #12
0
static int execscsicmd (struct dev_info_spti *di, int unitnum, uae_u8 *data, int len, uae_u8 *inbuf, int inlen)
{
	SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
	DWORD status;
	int err, dolen;

	uae_sem_wait (&scgp_sem);
	memset (&swb, 0, sizeof (swb));
	swb.spt.Length = sizeof (SCSI_PASS_THROUGH);
	swb.spt.CdbLength = len;
	if (inbuf) {
		swb.spt.DataIn = SCSI_IOCTL_DATA_IN;
		swb.spt.DataTransferLength = inlen;
		swb.spt.DataBuffer = inbuf;
		memset (inbuf, 0, inlen);
	} else {
		swb.spt.DataIn = SCSI_IOCTL_DATA_OUT;
	}
	swb.spt.TimeOutValue = 80 * 60;
	swb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf);
	swb.spt.SenseInfoLength = 32;
	memcpy (swb.spt.Cdb, data, len);
	status = doscsi (di, unitnum, &swb, &err);
	uae_sem_post (&scgp_sem);
	dolen = swb.spt.DataTransferLength;
	if (!status)
		return -1;
	return dolen;
}
Example #13
0
/*
 * Handles the emulator's side of a 68k call (from an extended trap)
 */
static uae_u32 REGPARAM3 m68k_call_handler (TrapContext *dummy_ctx)
{
	TrapContext *context = current_context;

	uae_u32 sp;

	sp = m68k_areg (regs, 7);

	/* Push address of trap context on 68k stack. This is
	 * so the return trap can find this context. */
	sp -= sizeof (void *);
	put_pointer (sp, context);

	/* Push addr to return handler trap on 68k stack.
	 * When the called m68k function does an RTS, the CPU will pull this
	 * address off the stack and so call the return handler. */
	sp -= 4;
	put_long (sp, m68k_return_trapaddr);

	m68k_areg (regs, 7) = sp;

	/* Set PC to address of 68k function to call. */
	m68k_setpc (context->call68k_func_addr);
	fill_prefetch ();

	/* End critical section: allow other traps run. */
	uae_sem_post (&trap_mutex);

	/* Restore interrupts. */
	regs.intmask = context->saved_regs.intmask;

	/* Dummy return value. */
	return 0;
}
Example #14
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);
	}
}
Example #15
0
/*
 * Handles the return from a 68k call at the emulator's side.
 */
static uae_u32 REGPARAM3 m68k_return_handler (TrapContext *dummy_ctx)
{
	TrapContext *context;
	uae_u32 sp;

	/* One trap returning at a time, please! */
	uae_sem_wait (&trap_mutex);

	/* Get trap context from 68k stack. */
	sp = m68k_areg (regs, 7);
	context = (TrapContext *)get_pointer (sp);
	sp += sizeof (void *);
	m68k_areg (regs, 7) = sp;

	/* Get return value from the 68k call. */
	context->call68k_retval = m68k_dreg (regs, 0);

	/* Switch back to trap context. */
	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 another 68k function. */
	uae_sem_wait (&context->switch_to_emu_sem);

	/* Dummy return value. */
	return 0;
}
Example #16
0
/*
 * Handles completion of an extended trap and passes
 * return value from trap function to 68k space.
 */
static uae_u32 REGPARAM3 exit_trap_handler (TrapContext *dummy_ctx)
{
	TrapContext *context = current_context;

	/* Wait for trap context thread to exit. */
	uae_wait_thread (context->thread);

	/* Restore 68k state saved at trap entry. */
	regs = context->saved_regs;

	/* If trap is supposed to return a value, then store
	 * return value in D0. */
	if (context->trap_has_retval)
		m68k_dreg (regs, 0) = context->trap_retval;

	uae_sem_destroy (&context->switch_to_trap_sem);
	uae_sem_destroy (&context->switch_to_emu_sem);

	xfree (context);

	/* End critical section */
	uae_sem_post (&trap_mutex);

	/* Dummy return value. */
	return 0;
}
Example #17
0
static void cdtvcr_4510_reset(uae_u8 v)
{
	cdtvcr_4510_ram[CDTVCR_ID + 0] = 'C';
	cdtvcr_4510_ram[CDTVCR_ID + 1] = 'D';
	cdtvcr_4510_ram[CDTVCR_ID + 2] = 'T';
	cdtvcr_4510_ram[CDTVCR_ID + 3] = 'V';

	write_log(_T("4510 reset %d\n"), v);
	if (v == 3) {
		sys_command_cd_pause (unitnum, 0);
		sys_command_cd_stop (unitnum);
		cdtvcr_4510_ram[CDTVCR_CD_PLAYING] = 0;
		cdtvcr_4510_ram[CDTVCR_CD_STATE] = 0;
		return;
	} else if (v == 2 || v == 1) {
		cdtvcr_4510_ram[CDTVCR_INTENA] = 0;
		cdtvcr_4510_ram[CDTVCR_INTREQ] = 0;
		if (v == 1) {
			memset(cdtvcr_4510_ram, 0, 4096);
		}
		cdtvcr_4510_ram[CDTVCR_INTDISABLE] = 1;
		cdtvcr_4510_ram[CDTVCR_CD_STATE] = 1;
	}
	cdtvcr_4510_ram[CDTVCR_PLAYLIST_TIME_MODE] = 2;
	uae_sem_wait (&sub_sem);
	memset (subcodebufferinuse, 0, sizeof subcodebufferinuse);
	subcodebufferoffsetw = subcodebufferoffset = 0;
	uae_sem_post (&sub_sem);

	if (ismedia())
		get_toc();
}
Example #18
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;
    }
}
Example #19
0
void uae_ReplyMsg (uaecptr msg)
{
	uae_sem_wait (&n2asem);
	write_comm_pipe_int (&native2amiga_pending, 2, 0);
	write_comm_pipe_u32 (&native2amiga_pending, msg, 1);
	do_uae_int_requested ();
	uae_sem_post (&n2asem);
}
Example #20
0
void uae_Cause (uaecptr interrupt)
{
	uae_sem_wait (&n2asem);
	write_comm_pipe_int (&native2amiga_pending, 3, 0);
	write_comm_pipe_u32 (&native2amiga_pending, interrupt, 1);
	do_uae_int_requested ();
	uae_sem_post (&n2asem);
}
Example #21
0
void slirp_output (const uint8 *pkt, int pkt_len)
{
	if (!slirp_data)
		return;
	uae_sem_wait (&slirp_sem1);
	slirp_data->gotfunc (slirp_data->userdata, pkt, pkt_len);
	uae_sem_post (&slirp_sem1);
}
Example #22
0
static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
{
	uae_u32 request = m68k_areg (regs, 1);
	uae_u8 flags = get_byte (request + 30);
	int command = get_word (request + 28);
	struct priv_s2devstruct *pdev = getps2devstruct (request);
	struct s2devstruct *dev;

	put_byte (request + 8, NT_MESSAGE);
	if (!pdev) {
		write_log (_T("%s unknown iorequest (1) %08x\n"), getdevname (), request);
		put_byte (request + 31, 32);
		return get_byte (request + 31);
	}
	dev = gets2devstruct (pdev->unit);
	if (!dev) {
		write_log (_T("%s unknown iorequest (2) %08x\n"), getdevname (), request);
		put_byte (request + 31, 32);
		return get_byte (request + 31);
	}
	put_byte (request + 31, 0);
	if ((flags & 1) && dev_canquick (dev, request)) {
		if (dev_do_io (dev, request, 1))
			write_log (_T("%s: command %d bug with IO_QUICK\n"), SANA2NAME, command);
		return get_byte (request + 31);
	} else {
		if (command == CMD_WRITE || command == S2_BROADCAST || command == S2_MULTICAST) {
			struct s2packet *s2p;
			if (!pdev->copyfrombuff || !pdev->copytobuff) {
				put_long (request + 32, S2ERR_BAD_ARGUMENT);
				put_byte (request + 31, S2WERR_BUFF_ERROR);
			} else {
				if (command == S2_BROADCAST) {
					uaecptr dstaddr = request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES;
					put_byte (dstaddr +  0, 0xff);
					put_byte (dstaddr +  1, 0xff);
					put_byte (dstaddr +  2, 0xff);
					put_byte (dstaddr +  3, 0xff);
					put_byte (dstaddr +  4, 0xff);
					put_byte (dstaddr +  5, 0xff);
				}
				s2p = createwritepacket (context, request);
				if (s2p) {
					uae_sem_wait (&async_sem);
					add_async_packet (dev, s2p, request);
					uae_sem_post (&async_sem);
				}
				if (!s2p) {
					put_long (request + 32, S2WERR_BUFF_ERROR);
					put_byte (request + 31, S2ERR_NO_RESOURCES);
				}
			}
		}
		put_byte (request + 30, get_byte (request + 30) & ~1);
		write_comm_pipe_u32 (&dev->requests, request, 1);
		return 0;
	}
}
Example #23
0
void uae_Signal (uaecptr task, uae_u32 mask)
{
	uae_sem_wait (&n2asem);
	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);
}
Example #24
0
static void *uaenet_trap_threadw (void *arg)
{
	struct uaenetdata *sd = (struct uaenetdata*)arg;
	uae_set_thread_priority (1);
	sd->threadactivew = 1;
	uae_sem_post (&sd->sync_semw);
	while (sd->threadactivew == 1) {
		int32_t towrite = sd->mtu;
		uae_sem_wait (&sd->change_sem);
		if (sd->getfunc (sd->user, sd->writebuffer, &towrite)) {
			pcap_sendpacket (sd->fp, sd->writebuffer, towrite);
		}
		uae_sem_post (&sd->change_sem);
	}
	sd->threadactivew = 0;
	uae_sem_post (&sd->sync_semw);
	return 0;
}
Example #25
0
void uae_NotificationHack (uaecptr port, uaecptr nr)
{
	uae_sem_wait (&n2asem);
	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);
}
Example #26
0
void vsync_callback(unsigned int a, void* b)
{
	//vsync_timing=SDL_GetTicks();
	//vsync_frequency = vsync_timing - old_time;
	//old_time = vsync_timing;
	//need_frameskip =  ( vsync_frequency > 31 ) ? (need_frameskip+1) : need_frameskip;
	//printf("d: %i", vsync_frequency     );
	uae_sem_post (&vsync_wait_sem);
}
Example #27
0
static void *slirp_receive_func(void *arg)
{
	slirp_thread_active = 1;
	while (slirp_thread_active) {
		// Wait for packets to arrive
		fd_set rfds, wfds, xfds;
		int nfds;
		int ret, timeout;

		// ... in the output queue
		nfds = -1;
		FD_ZERO(&rfds);
		FD_ZERO(&wfds);
		FD_ZERO(&xfds);
		uae_sem_wait (&slirp_sem2);
		timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
		uae_sem_post (&slirp_sem2);
		if (nfds < 0) {
			/* Windows does not honour the timeout if there is not
			   descriptor to wait for */
			sleep_millis (timeout / 1000);
			ret = 0;
		} else {
			struct timeval tv;
			tv.tv_sec = 0;
			tv.tv_usec = timeout;
			ret = select(0, &rfds, &wfds, &xfds, &tv);
			if (ret == SOCKET_ERROR) {
				write_log(_T("SLIRP socket ERR=%d\n"), WSAGetLastError());
			}
		}
		if (ret >= 0) {
			uae_sem_wait (&slirp_sem2);
			slirp_select_poll(&rfds, &wfds, &xfds);
			uae_sem_post (&slirp_sem2);
		}
	}
	slirp_thread_active = -1;
	return 0;
}
Example #28
0
static void sound_callback (void *userdata, Uint8 *stream, int len)
{
    if (closing_sound)
	return;
    in_callback = 1;
    /* Wait for data to finish.  */
    uae_sem_wait (&data_available_sem);
    if (! closing_sound) {
	memcpy (stream, sndbuffer, sndbufsize);
	/* Notify writer that we're done.  */
	uae_sem_post (&callback_done_sem);
    }
    in_callback = 0;
}
Example #29
0
void uaenet_gotdata (struct s2devstruct *dev, const uae_u8 *d, int len)
{
	uae_u16 type;
	struct mcast *mc;
	struct s2packet *s2p;

	if (!dev->online)
		return;
	/* drop if bogus size */
	if (len < 20  || len >= dev->td->mtu + ETH_HEADER_SIZE + 2)
		return;
	/* drop if dst == broadcast and src == me */
	if (isbroadcast (d) && !memcmp (d + 6, dev->td->mac, ADDR_SIZE))
		return;
	/* drop if not promiscuous and dst != broadcast and dst != me */
	if (!dev->promiscuous && !isbroadcast (d) && memcmp (d, dev->td->mac, ADDR_SIZE))
		return;
	/* drop if multicast with unknown address */
	if (ismulticast (d)) {
		uae_u64 mac64 = addrto64 (d);
		/* multicast */
		mc = dev->mc;
		while (mc) {
			if (mac64 >= mc->start && mac64 <= mc->end)
				break;
			mc = mc->next;
		}
		if (!mc)
			return;
	}

	type = (d[12] << 8) | d[13];
	s2p = createreadpacket (dev, d, len);
	if (log_net)
		write_log (_T("<-DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X L=%d P=%p\n"),
		d[0], d[1], d[2], d[3], d[4], d[5],
		d[6], d[7], d[8], d[9], d[10], d[11],
		type, len, s2p);
	uae_sem_wait (&async_sem);
	if (!dev->readqueue) {
		dev->readqueue = s2p;
	} else {
		struct s2packet *s2p2 = dev->readqueue;
		while (s2p2->next)
			s2p2 = s2p2->next;
		s2p2->next = s2p;
	}
	uaenet_int_requested = 1;
	uae_sem_post (&async_sem);
}
Example #30
0
static void *uaenet_trap_threadw (void *arg)
{
	struct uaenetdatawin32 *sd = (struct uaenetdatawin32*)arg;

	uae_set_thread_priority (NULL, 1);
	sd->threadactivew = 1;
	uae_sem_post (&sd->sync_semw);
	while (sd->threadactivew == 1) {
		int donotwait = 0;
		int towrite = sd->mtu;
		uae_sem_wait (&sd->change_sem);
		if (sd->getfunc ((struct s2devstruct*)sd->user, sd->writebuffer, &towrite)) {
			pcap_sendpacket (sd->fp, sd->writebuffer, towrite);
			donotwait = 1;
		}
		uae_sem_post (&sd->change_sem);
		if (!donotwait)
			WaitForSingleObject (sd->evttw, INFINITE);
	}
	sd->threadactivew = 0;
	uae_sem_post (&sd->sync_semw);
	return 0;
}