void uae_PutMsg (uaecptr port, uaecptr msg) { uae_sem_wait (&n2asem); 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); }
void uae_PutMsg(uaecptr port, uaecptr msg) { uae_pt data; data.i = 1; write_comm_pipe_int (&native2amiga_pending, 1, 0); write_comm_pipe_u32 (&native2amiga_pending, port, 0); write_comm_pipe_u32 (&native2amiga_pending, msg, 1); uae_int_requested = 1; }
static uae_u32 REGPARAM2 dev_beginio (TrapContext *context) { uae_u32 request = m68k_areg (&context->regs, 1); uae_u8 flags = get_byte (request + 30); int command = get_word (request + 28); struct priv_devstruct *pdev = getpdevstruct (request); struct devstruct *dev = getdevstruct (pdev->unit); put_byte (request+8, NT_MESSAGE); if (!dev || !pdev) { 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)) write_log ("device %s command %d bug with IO_QUICK\n", getdevname (pdev->type), command); return get_byte (request + 31); } else { add_async_request (dev, request, ASYNC_REQUEST_TEMP, 0); put_byte (request+30, get_byte (request + 30) & ~1); write_comm_pipe_u32 (&dev->requests, request, 1); return 0; } }
static void dev_close_3 (struct devstruct *dev) { uaeser_close (dev->sysdata); dev->open = 0; xfree (dev->sysdata); write_comm_pipe_u32 (&dev->requests, 0, 1); }
static void do_abort_async (struct s2devstruct *dev, uaecptr request) { put_byte (request + 30, get_byte (request + 30) | 0x20); put_byte (request + 31, IOERR_ABORTED); put_long (request + 32, S2WERR_GENERIC_ERROR); write_comm_pipe_u32 (&dev->requests, request, 1); }
static void dev_reset (void) { int i; struct s2devstruct *dev; int unitnum = 0; write_log (_T("%s reset\n"), getdevname()); for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) { dev = &devst[i]; if (dev->opencnt) { struct asyncreq *ar = dev->ar; while (ar) { if (!ar->ready) { dev->ar->ready = 1; do_abort_async (dev, ar->request); } ar = ar->next; } write_comm_pipe_u32 (&dev->requests, 0, 1); uae_sem_wait (&dev->sync_sem); } while (dev->mc) delmulticastaddresses (dev, dev->mc->start, dev->mc->end); memset (dev, 0, sizeof (struct s2devstruct)); } for (i = 0; i < MAX_OPEN_DEVICES; i++) memset (&pdevst[i], 0, sizeof (struct priv_s2devstruct)); uaenet_vsync_requested = 0; uaenet_int_requested = 0; irq_init = 0; }
static void open_screen(struct uae_prefs *p) { graphics_subshutdown(); current_resource_amigafb = 0; currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect; currprefs.gfx_fullscreen_ratio = changed_prefs.gfx_fullscreen_ratio; #ifdef PICASSO96 if (screen_is_picasso) { display_width = picasso_vidinfo.width ? picasso_vidinfo.width : 640; display_height = picasso_vidinfo.height ? picasso_vidinfo.height : 256; } else #endif { p->gfx_resolution = p->gfx_monitor.gfx_size.width ? (p->gfx_monitor.gfx_size.width > 600 ? 1 : 0) : 1; display_width = p->gfx_monitor.gfx_size.width ? p->gfx_monitor.gfx_size.width : 640; display_height = (p->gfx_monitor.gfx_size.height ? p->gfx_monitor.gfx_size.height : 256) << p->gfx_vresolution; } write_comm_pipe_u32(display_pipe, DISPLAY_SIGNAL_OPEN, 1); uae_sem_wait (&display_sem); if (prSDLScreen != NULL) { InitAmigaVidMode(p); init_row_map(); } calibrate_done = false; reset_sync(); }
/* * Shut down SCSI layer */ static void dev_exit (void) { int i, j; struct devstruct *dev; for (i = 0; i < MAX_TOTAL_DEVICES; i++) { dev = &devst[i]; if (dev->opencnt > 0) { /* Abort any outstanding requests */ for (j = 0; j < MAX_ASYNC_REQUESTS; j++) { uaecptr request; if ((request = dev->d_request[i])) abort_async (dev, request, 0, 0); } /* Kill dev thread and wait for it to die */ write_comm_pipe_u32 (&dev->requests, 0, 1); uae_sem_wait (&dev->sync_sem); /* Close device */ dev->opencnt = 0; sys_command_close (DF_SCSI, dev->unitnum); sys_command_close (DF_IOCTL, dev->unitnum); } memset (dev, 0, sizeof (struct devstruct)); dev->unitnum = dev->aunit = -1; } }
void uae_ReplyMsg(uaecptr msg) { write_comm_pipe_int (&native2amiga_pending, 2, 0); write_comm_pipe_u32 (&native2amiga_pending, msg, 1); uae_int_requested = 1; }
void uae_Signal(uaecptr task, uae_u32 mask) { write_comm_pipe_int (&native2amiga_pending, 0, 0); write_comm_pipe_u32 (&native2amiga_pending, task, 0); write_comm_pipe_int (&native2amiga_pending, mask, 1); uae_int_requested = 1; }
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); }
void graphics_subshutdown(void) { if(display_tid != 0) { wait_for_display_thread(); write_comm_pipe_u32(display_pipe, DISPLAY_SIGNAL_SUBSHUTDOWN, 1); uae_sem_wait (&display_sem); } }
void uae_ReplyMsg(uaecptr msg) { uae_nativesem_wait(); write_comm_pipe_int (&native2amiga_pending, 2, 0); write_comm_pipe_u32 (&native2amiga_pending, msg, 1); do_uae_int_requested(); uae_nativesem_post(); }
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; } }
void show_screen(int mode) { unsigned long start = read_processor_time(); last_synctime = start; while(last_synctime < next_amiga_frame_ends && last_synctime < start + time_per_frame) { usleep(10); last_synctime = read_processor_time(); } amiga_frame = amiga_frame + 1 + currprefs.gfx_framerate; if(amiga_frame == currVSyncRate) { bool do_check = true; if(host_frame < host_hz) { // we are here before relevant vsync occured wait_for_vsync(); if(sync_was_bogus) do_check = false; } if(do_check && host_frame == host_hz) { // Check time difference between Amiga and host sync. // If difference is too big, slightly ajust time per frame. long diff; static long last_diff = 0; if(next_amiga_frame_ends > host_frame_timestamp) { diff = next_amiga_frame_ends - host_frame_timestamp; if(diff > 50 && last_diff != 0 && diff > last_diff) time_per_frame--; last_diff = diff; } else { diff = host_frame_timestamp - next_amiga_frame_ends; if(diff > time_per_frame / 2) { next_amiga_frame_ends += time_per_frame; diff = -diff; last_diff = 0; } else { diff = -diff; if(diff < -50 && last_diff != 0 && diff < last_diff) time_per_frame++; last_diff = diff; } } write_log("Diff Amiga frame to host: %6d, time_per_frame = %6d\n", diff, time_per_frame); } host_frame = 0; amiga_frame = 0; } next_amiga_frame_ends += time_per_frame; if(currprefs.gfx_framerate) next_amiga_frame_ends += time_per_frame; wait_for_display_thread(); write_comm_pipe_u32(display_pipe, DISPLAY_SIGNAL_SHOW, 1); idletime += last_synctime - start; }
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); }
static void signalasync (struct s2devstruct *dev, struct asyncreq *ar, int actual, int err) { uaecptr request = ar->request; int command = get_word (request + 28); if (log_net) write_log (_T("%s:%d CMD=%d async request %x completed\n"), getdevname(), dev->unit, command, request); put_long (request + 32, actual); put_byte (request + 31, err); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); }
static void cdtvcr_4510_do_something(void) { if (cdtvcr_4510_ram[CDTVCR_INTACK]) { cdtvcr_4510_ram[CDTVCR_INTACK] = 0; rethink_cdtvcr(); } if (cdtvcr_4510_ram[CDTVCR_CD_CMD_DO]) { cdtvcr_4510_ram[CDTVCR_CD_CMD_DO] = 0; cdtvcr_4510_ram[CDTVCR_SYS_STATE] |= 2; write_comm_pipe_u32 (&requests, 0x0100, 1); } }
static void dev_close_3 (struct devstruct *dev, struct priv_devstruct *pdev) { if (!dev->opencnt) return; dev->opencnt--; if (!dev->opencnt) { if (pdev->scsi) sys_command_close (DF_SCSI, dev->unitnum); if (pdev->ioctl) sys_command_close (DF_IOCTL, dev->unitnum); pdev->inuse = 0; write_comm_pipe_u32 (&dev->requests, 0, 1); } }
static void abort_async (struct devstruct *dev, uaecptr request) { struct asyncreq *ar = get_async_request (dev, request, 1); if (!ar) { write_log (_T("%s:%d: abort async but no request %x found!\n"), getdevname(), dev->unit, request); return; } if (log_uaeserial) write_log (_T("%s:%d asyncronous request=%08X aborted\n"), getdevname(), dev->unit, request); put_byte (request + 31, IOERR_ABORTED); put_byte (request + 30, get_byte (request + 30) | 0x20); write_comm_pipe_u32 (&dev->requests, request, 1); }
void graphics_thread_leave(void) { if(display_tid != 0) { write_comm_pipe_u32 (display_pipe, DISPLAY_SIGNAL_QUIT, 1); while(display_tid != 0) { sleep_millis(10); } destroy_comm_pipe(display_pipe); xfree(display_pipe); display_pipe = 0; uae_sem_destroy(&display_sem); display_sem = 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; }
static uint32_t REGPARAM2 dev_beginio (TrapContext *context) { uint32_t request = m68k_areg (regs, 1); uint8_t flags = get_byte (request + 30); int32_t command = get_word (request + 28); struct devstruct *dev = getdevstruct (get_long (request + 24)); put_byte (request + 8, NT_MESSAGE); if (!dev) { 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("device %s:%d command %d bug with IO_QUICK\n"), getdevname(), dev->unit, command); return get_byte (request + 31); } else { put_byte (request + 30, get_byte (request + 30) & ~1); write_comm_pipe_u32 (&dev->requests, request, 1); return 0; } }
static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context) { uae_u32 request = m68k_areg (regs, 1); struct priv_s2devstruct *pdev = getps2devstruct (request); struct s2devstruct *dev; if (!pdev) { write_log (_T("%s close with unknown request %08X!?\n"), SANA2NAME, request); return 0; } dev = gets2devstruct (pdev->unit); if (!dev) { write_log (_T("%s:%d close with unknown request %08X!?\n"), SANA2NAME, pdev->unit, request); return 0; } if (log_net) write_log (_T("%s:%d close, open=%d req=%08X\n"), SANA2NAME, pdev->unit, dev->opencnt, request); put_long (request + 24, 0); dev->opencnt--; pdev->inuse = 0; if (!dev->opencnt) { dev->exclusive = 0; if (pdev->tempbuf) { m68k_areg (regs, 1) = pdev->tempbuf; m68k_dreg (regs, 0) = pdev->td->mtu + ETH_HEADER_SIZE + 2; CallLib (context, get_long (4), -0xD2); /* FreeMem */ pdev->tempbuf = 0; } ethernet_close (pdev->td, dev->sysdata); xfree (dev->sysdata); dev->sysdata = NULL; write_comm_pipe_u32 (&dev->requests, 0, 1); write_log (_T("%s: opencnt == 0, all instances closed\n"), SANA2NAME); } put_word (m68k_areg (regs, 6) + 32, get_word (m68k_areg (regs, 6) + 32) - 1); return 0; }
static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) { int i, j; int gotit; struct asyncreq *ar; if (uae_sem_trywait (&async_sem)) { uaenet_int_requested = 0; uaenet_int_late = 1; return 0; } for (i = 0; i < MAX_OPEN_DEVICES; i++) pdevst[i].tmp = 0; for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) { struct s2devstruct *dev = &devst[i]; struct s2packet *p; if (dev->online) { while (dev->readqueue) { uae_u16 type; p = dev->readqueue; type = (p->data[2 * ADDR_SIZE] << 8) | p->data[2 * ADDR_SIZE + 1]; ar = dev->ar; gotit = 0; while (ar) { if (!ar->ready) { uaecptr request = ar->request; int command = get_word (request + 28); uae_u32 packettype = get_long (request + 32 + 4); if (command == CMD_READ && (packettype == type || (packettype <= 1500 && type <= 1500))) { struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev && pdev->tmp == 0) { if (handleread (ctx, pdev, request, p->data, p->len, command)) { if (log_net) write_log (_T("-> %p Accepted, CMD_READ, REQ=%08X LEN=%d\n"), p, request, p->len); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); dev->packetsreceived++; gotit = 1; pdev->tmp = 1; } else { if (log_net) write_log (_T("-> %p PacketFilter() rejected, CMD_READ, REQ=%08X LEN=%d\n"), p, request, p->len); pdev->tmp = -1; } } } } ar = ar->next; } ar = dev->ar; while (ar) { if (!ar->ready) { uaecptr request = ar->request; int command = get_word (request + 28); if (command == S2_READORPHAN) { struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev && pdev->tmp <= 0) { if (log_net) write_log (_T("-> %p Accepted, S2_READORPHAN, REQ=%08X LEN=%d\n"), p, request, p->len); handleread (ctx, pdev, request, p->data, p->len, command); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); dev->packetsreceived++; dev->unknowntypesreceived++; gotit = 1; pdev->tmp = 1; } } } ar = ar->next; } if (!gotit) { if (log_net) write_log (_T("-> %p packet dropped, LEN=%d\n"), p, p->len); for (j = 0; j < MAX_OPEN_DEVICES; j++) { if (pdevst[j].unit == dev->unit) { if (pdevst[j].tracks[type]) pdevst[j].packetsdropped++; } } } dev->readqueue = dev->readqueue->next; freepacket (p); } } else { while (dev->readqueue) { p = dev->readqueue; dev->readqueue = dev->readqueue->next; freepacket (p); } } ar = dev->ar; while (ar) { if (!ar->ready) { uaecptr request = ar->request; int command = get_word (request + 28); if (command == S2_ONLINE) { struct priv_s2devstruct *pdev = getps2devstruct (request); dev->packetsreceived = 0; dev->packetssent = 0; dev->baddata = 0; dev->overruns = 0; dev->unknowntypesreceived = 0; dev->reconfigurations = 0; if (pdev && pdev->timerbase) { m68k_areg (regs, 0) = pdev->tempbuf; CallLib (ctx, pdev->timerbase, -0x42); /* GetSysTime() */ } else { put_long (pdev->tempbuf + 0, 0); put_long (pdev->tempbuf + 4, 0); } dev->online_secs = get_long (pdev->tempbuf + 0); dev->online_micro = get_long (pdev->tempbuf + 4); checkevents (dev, S2EVENT_ONLINE, 0); dev->online = 1; ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); uaenet_vsync_requested--; } else if (command == CMD_FLUSH) { /* do not reply CMD_FLUSH until all other requests are gone */ if (dev->ar->next == NULL) { if (log_net) write_log (_T("CMD_FLUSH replied %08x\n"), request); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); uaenet_vsync_requested--; } else { struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev) { dev->flush_timeout--; if (dev->flush_timeout <= 0) { dev->flush_timeout = FLUSH_TIMEOUT; if (dev->flush_timeout_cnt > 1) write_log (_T("WARNING: %s:%d CMD_FLUSH possibly frozen..\n"), getdevname(), pdev->unit); dev->flush_timeout_cnt++; flush (pdev); } } } } } ar = ar->next; } } if (uaenet_int_late) uaenet_int_requested = 1; else uaenet_int_requested = 0; uaenet_int_late = 0; uae_sem_post (&async_sem); return 0; }
static void *cdda_play_func (void *v) { int cdda_pos; int num_sectors = CDDA_BUFFERS; int quit = 0; int bufnum; int bufon[2]; int oldplay; int idleframes; bool foundsub; struct cdunit *cdu = (struct cdunit*)v; while (cdu->cdda_play == 0) Sleep (10); oldplay = -1; bufon[0] = bufon[1] = 0; bufnum = 0; cda_audio *cda = new cda_audio (num_sectors); while (cdu->cdda_play > 0) { if (oldplay != cdu->cdda_play) { struct cdtoc *t; int sector, diff; struct _timeb tb1, tb2; idleframes = 0; foundsub = false; _ftime (&tb1); cdda_pos = cdu->cdda_start; oldplay = cdu->cdda_play; sector = cdu->cd_last_pos = cdda_pos; t = findtoc (cdu, §or); if (!t) { write_log (_T("IMAGE CDDA: illegal sector number %d\n"), cdu->cdda_start); setstate (cdu, AUDIO_STATUS_PLAY_ERROR); } else { write_log (_T("IMAGE CDDA: playing from %d to %d, track %d ('%s', offset %lld, secoffset %d)\n"), cdu->cdda_start, cdu->cdda_end, t->track, t->fname, t->offset, sector); // do this even if audio is not compressed, t->handle also could be // compressed and we want to unpack it in background too while (cdimage_unpack_active == 1) Sleep (10); cdimage_unpack_active = 0; write_comm_pipe_u32 (&unpack_pipe, cdu - &cdunits[0], 0); write_comm_pipe_u32 (&unpack_pipe, t - &cdu->toc[0], 1); while (cdimage_unpack_active == 0) Sleep (10); } idleframes = cdu->cdda_delay_frames; while (cdu->cdda_paused && cdu->cdda_play > 0) { Sleep (10); idleframes = -1; } if (cdu->cdda_scan == 0) { // find possible P-subchannel=1 and fudge starting point so that // buggy CD32/CDTV software CD+G handling does not miss any frames bool seenindex = false; for (sector = cdda_pos - 200; sector < cdda_pos; sector++) { int sec = sector; t = findtoc (cdu, &sec); if (t) { uae_u8 subbuf[SUB_CHANNEL_SIZE]; getsub_deinterleaved (subbuf, cdu, t, sector); if (seenindex) { for (int i = 2 * SUB_ENTRY_SIZE; i < SUB_CHANNEL_SIZE; i++) { if (subbuf[i]) { // non-zero R-W subchannels int diff = cdda_pos - sector + 2; write_log (_T("-> CD+G start pos fudge -> %d (%d)\n"), sector, -diff); idleframes -= diff; cdda_pos = sector; break; } } } else if (subbuf[0] == 0xff) { // P == 1? seenindex = true; } } } } cdda_pos -= idleframes; _ftime (&tb2); diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm); diff -= cdu->cdda_delay; if (idleframes >= 0 && diff < 0 && cdu->cdda_play > 0) Sleep (-diff); setstate (cdu, AUDIO_STATUS_IN_PROGRESS); } cda->wait(bufnum); bufon[bufnum] = 0; if (!cdu->cdda_play) goto end; if (idleframes <= 0 && cdda_pos >= cdu->cdda_start && !isaudiotrack (&cdu->di.toc, cdda_pos)) { setstate (cdu, AUDIO_STATUS_PLAY_ERROR); write_log (_T("IMAGE CDDA: attempted to play data track %d\n"), cdda_pos); goto end; // data track? } if ((cdda_pos < cdu->cdda_end || cdu->cdda_end == 0xffffffff) && !cdu->cdda_paused && cdu->cdda_play > 0) { struct cdtoc *t; int sector, cnt; int dofinish = 0; gui_flicker_led (LED_CD, cdu->di.unitnum - 1, LED_CD_AUDIO); memset (cda->buffers[bufnum], 0, num_sectors * 2352); for (cnt = 0; cnt < num_sectors; cnt++) { uae_u8 *dst = cda->buffers[bufnum] + cnt * 2352; uae_u8 subbuf[SUB_CHANNEL_SIZE]; sector = cdda_pos; memset (subbuf, 0, SUB_CHANNEL_SIZE); t = findtoc (cdu, §or); if (t) { if (!(t->ctrl & 4)) { if (t->enctype == ENC_CHD) { do_read (cdu, t, dst, sector, 0, t->size); for (int i = 0; i < 2352; i+=2) { uae_u8 p; p = dst[i + 0]; dst[i + 0] = dst[i + 1]; dst[i +1] = p; } } else if (t->handle) { int totalsize = t->size + t->skipsize; if ((t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC) && t->data) { if (t->filesize >= sector * totalsize + t->offset + t->size) memcpy (dst, t->data + sector * totalsize + t->offset, t->size); } else if (t->enctype == AUDENC_PCM) { if (sector * totalsize + t->offset + totalsize < t->filesize) { zfile_fseek (t->handle, (uae_u64)sector * totalsize + t->offset, SEEK_SET); zfile_fread (dst, t->size, 1, t->handle); } } } } getsub_deinterleaved (subbuf, cdu, t, cdda_pos); } if (idleframes > 0) { idleframes--; memset (dst, 0, 2352); memset (subbuf, 0, SUB_CHANNEL_SIZE); } if (cdda_pos < cdu->cdda_start && cdu->cdda_scan == 0) memset (dst, 0, 2352); dosub (cdu, subbuf); if (cdu->cdda_scan) { cdda_pos += cdu->cdda_scan; if (cdda_pos < 0) cdda_pos = 0; } else { cdda_pos++; } if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end) dofinish = 1; } if (idleframes <= 0) cdu->cd_last_pos = cdda_pos; bufon[bufnum] = 1; cda->setvolume (currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, cdu->cdda_volume[0], cdu->cdda_volume[1]); if (!cda->play (bufnum)) { setstate (cdu, AUDIO_STATUS_PLAY_ERROR); goto end; } if (dofinish) { setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE); cdu->cdda_play = -1; cdda_pos = cdu->cdda_end + 1; } } if (bufon[0] == 0 && bufon[1] == 0) { while (cdu->cdda_paused && cdu->cdda_play == oldplay) Sleep (10); } bufnum = 1 - bufnum; } end: cda->wait (0); cda->wait (1); while (cdimage_unpack_active == 1) Sleep (10); delete cda; cdu->cdda_play = 0; write_log (_T("IMAGE CDDA: thread killed\n")); return NULL; }
void uaeser_signal (void *vdev, int32_t sigmask) { struct devstruct *dev = (struct devstruct*)vdev; struct asyncreq *ar; int32_t i = 0; uae_sem_wait (&async_sem); ar = dev->ar; while (ar) { if (!ar->ready) { uaecptr request = ar->request; uint32_t io_data = get_long (request + 40); // 0x28 uint32_t io_length = get_long (request + 36); // 0x24 int32_t command = get_word (request + 28); uint32_t io_error = 0, io_actual = 0; uint8_t *addr; int32_t io_done = 0; switch (command) { case SDCMD_BREAK: if (ar == dev->ar) { uaeser_break (dev->sysdata, get_long (request + io_BrkTime)); io_done = 1; } break; case CMD_READ: if (sigmask & 1) { addr = memmap(io_data, io_length); if (addr) { if (uaeser_read (dev->sysdata, addr, io_length)) { io_error = 0; io_actual = io_length; io_done = 1; } } else { io_error = IOERR_BADADDRESS; io_done = 1; } } break; case CMD_WRITE: if (sigmask & 2) { io_error = IOERR_BADADDRESS; addr = memmap(io_data, io_length); if (addr && uaeser_write (dev->sysdata, addr, io_length)) io_error = 0; io_actual = io_length; io_done = 1; } break; default: write_log (_T("%s:%d incorrect async request %x (cmd=%d) signaled?!"), getdevname(), dev->unit, request, command); break; } if (io_done) { if (log_uaeserial) write_log (_T("%s:%d async request %x completed\n"), getdevname(), dev->unit, request); put_long (request + 32, io_actual); put_byte (request + 31, io_error); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); } } ar = ar->next; } uae_sem_post (&async_sem); }