/* * 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; } }
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; }
/* * 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); } }
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); }
/* 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); }
/* * 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; }
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; }
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); }
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; }
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); }
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; }
/* * 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); }
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; }
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 }
/* * 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); }
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; }
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; }
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; }
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; }
void uaeserialdev_start_threads (void) { uae_sem_init (&change_sem, 0, 1); uae_sem_init (&async_sem, 0, 1); }
/* 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; }
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; }
void native2amiga_install (void) { init_comm_pipe (&native2amiga_pending, 100, 2); uae_sem_init (&n2asem, 0, 1); }