From: Toni Wilen Date: Wed, 6 Dec 2006 16:40:40 +0000 (+0200) Subject: imported winuaesrc1340b3.zip X-Git-Tag: 2100~263 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=82ae727a942db10380ccfd6cfcaef517a17f731e;p=francis%2Fwinuae.git imported winuaesrc1340b3.zip --- diff --git a/blitter.c b/blitter.c index 48c5bb82..4250d570 100644 --- a/blitter.c +++ b/blitter.c @@ -956,7 +956,6 @@ static void blit_bltset (int con) if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) write_log("warning: ECS BLTCON1 DOFF-bit set\n"); - ddat1use = ddat2use = 0; blit_dmacount = blit_dmacount2 = 0; blit_nod = 1; for (i = 0; i < blit_diag[1]; i++) { @@ -991,10 +990,8 @@ void reset_blit (int bltcon) { if (bltstate == BLT_done) return; - if (bltcon) { - if (bltstate != BLT_work) - blit_bltset (bltcon); - } + if (bltcon) + blit_bltset (bltcon); blit_modset (); } @@ -1020,6 +1017,7 @@ void do_blitter (int hpos) blit_bltset (1|2); blit_modset (); + ddat1use = ddat2use = 0; if (blitline) { blitsing = bltcon1 & 0x2; diff --git a/cfgfile.c b/cfgfile.c index 6924c664..04864b58 100644 --- a/cfgfile.c +++ b/cfgfile.c @@ -280,6 +280,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write (f, "serial_hardware_ctsrts=%s\n", p->serial_hwctsrts ? "true" : "false"); cfgfile_write (f, "serial_direct=%s\n", p->serial_direct ? "true" : "false"); cfgfile_write (f, "scsi=%s\n", p->scsi ? "true" : "false"); + cfgfile_write (f, "uaeserial=%s\n", p->uaeserial ? "true" : "false"); cfgfile_write (f, "sound_output=%s\n", soundmode1[p->produce_sound]); cfgfile_write (f, "sound_bits=%d\n", p->sound_bits); @@ -1027,6 +1028,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu || cfgfile_yesno (option, value, "comp_midopt", &p->comp_midopt) || cfgfile_yesno (option, value, "comp_lowopt", &p->comp_lowopt) || cfgfile_yesno (option, value, "rtg_nocustom", &p->picasso96_nocustom) + || cfgfile_yesno (option, value, "uaeserial", &p->uaeserial) || cfgfile_yesno (option, value, "scsi", &p->scsi)) return 1; if (cfgfile_intval (option, value, "cachesize", &p->cachesize, 1) @@ -2486,6 +2488,7 @@ void default_prefs (struct uae_prefs *p, int type) p->keyboard_leds_in_use = 0; p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0; p->scsi = 0; + p->uaeserial = 0; p->cpu_idle = 0; p->catweasel = 0; p->tod_hack = 0; @@ -2600,6 +2603,7 @@ static void buildin_default_prefs (struct uae_prefs *p) p->collision_level = 2; p->produce_sound = 3; p->scsi = 0; + p->uaeserial = 0; p->cpu_idle = 0; p->catweasel = 0; p->tod_hack = 0; @@ -2848,6 +2852,7 @@ static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck) p->floppy_speed = 0; p->cpu_idle = 150; p->scsi = 1; + p->uaeserial = 1; p->socket_emu = 1; p->cart_internal = 0; p->picasso96_nocustom = 1; diff --git a/disk.c b/disk.c index 6e851b6c..f758825e 100644 --- a/disk.c +++ b/disk.c @@ -2461,7 +2461,7 @@ static void disk_doupdate_predict (drive * drv, int startcycle) updatetrackspeed (drv, drv->mfmpos); if (diskevent_flag) { disk_sync_cycle = startcycle >> 8; - event2_newevent(ev2_disk, startcycle - firstcycle); + event2_newevent(ev2_disk, (startcycle - firstcycle) / CYCLE_UNIT); } } diff --git a/filesys.c b/filesys.c index 0b4cad8c..c8f45cb8 100644 --- a/filesys.c +++ b/filesys.c @@ -40,6 +40,7 @@ #include "fsusage.h" #include "native2amiga.h" #include "scsidev.h" +#include "uaeserial.h" #include "fsdb.h" #include "zfile.h" #include "gui.h" @@ -3747,8 +3748,12 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *context) * diag entry. */ //resaddr = uaeresource_startup(resaddr); - resaddr = scsidev_startup(resaddr); - +#ifdef SCSIEMU + resaddr = scsidev_startup (resaddr); +#endif +#ifdef UAESERIAL + resaddr = uaeserialdev_startup (resaddr); +#endif /* scan for Residents and return pointer to array of them */ residents = resaddr; while (tmp < residents && tmp > start) { diff --git a/include/serial.h b/include/serial.h index 0eb8834f..d0a0f2de 100644 --- a/include/serial.h +++ b/include/serial.h @@ -27,4 +27,17 @@ extern int doreadser, serstat; extern void serial_flush_buffer(void); extern void serial_hsynchandler (void); -extern void serial_check_irq (void); \ No newline at end of file +extern void serial_check_irq (void); + +extern int uaeser_getdatalenght (void); +extern int uaeser_getbytespending (void*); +extern int uaeser_open (void*, void*, int); +extern void uaeser_close (void*); +extern int uaeser_read (void*, uae_u8 *data, uae_u32 len); +extern int uaeser_write (void*, uae_u8 *data, uae_u32 len); +extern int uaeser_query (void*, uae_u16 *status, uae_u32 *pending); +extern int uaeser_setparams (void*, int baud, int rbuffer, int bits, int sbits, int rtscts, int parity); +extern int uaeser_break (void*, int brklen); +extern void uaeser_signal (void*, int source); +extern void uaeser_trigger (void*); +extern void uaeser_clearbuffers (void*); diff --git a/include/uaeserial.h b/include/uaeserial.h new file mode 100644 index 00000000..30d4bce9 --- /dev/null +++ b/include/uaeserial.h @@ -0,0 +1,22 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * uaeserial.device + * + * (c) 2006 Toni Wilen + */ + +uaecptr uaeserialdev_startup (uaecptr resaddr); +void uaeserialdev_install (void); +void uaeserialdev_reset (void); +void uaeserialdev_start_threads (void); + +extern int log_uaeserial; + +struct uaeserialdata +{ +#ifdef _WIN32 + void *handle; + void *writeevent; +#endif +}; diff --git a/main.c b/main.c index 4105fffb..96c9137c 100644 --- a/main.c +++ b/main.c @@ -36,6 +36,7 @@ #include "uaeexe.h" #include "native2amiga.h" #include "scsidev.h" +#include "uaeserial.h" #include "akiko.h" #include "savestate.h" #include "filesys.h" @@ -310,6 +311,9 @@ void fixup_prefs (struct uae_prefs *p) p->scsi = 0; p->win32_aspi = 0; #endif +#if !defined (UAESERIAL) + p->uaeserial = 0; +#endif #if defined(CPUEMU_6) if (p->cpu_cycle_exact) p->gfx_framerate = 1; @@ -487,6 +491,10 @@ void reset_all_systems (void) scsidev_reset (); scsidev_start_threads (); #endif +#ifdef UAESERIAL + uaeserialdev_reset (); + uaeserialdev_start_threads (); +#endif #if defined (PARALLEL_PORT) initparallel (); #endif @@ -630,6 +638,9 @@ static void real_main2 (int argc, char **argv) #ifdef SCSIEMU scsidev_install (); #endif +#ifdef UAESERIAL + uaeserialdev_install (); +#endif #ifdef AUTOCONFIG /* Install resident module to get 8MB chipmem, if requested */ rtarea_setup (); diff --git a/od-win32/ahidsound.c b/od-win32/ahidsound.c index 70cbbc55..9be7d316 100644 --- a/od-win32/ahidsound.c +++ b/od-win32/ahidsound.c @@ -301,6 +301,16 @@ static int ahi_init_record_win32 (void) return 1; } +void setvolume_ahi (LONG vol) +{ + HRESULT hr; + if (!lpDS2) + return; + hr = IDirectSoundBuffer_SetVolume (lpDSB2, vol); + if (FAILED(hr)) + write_log ("AHI: SetVolume(%d) failed: %s\n", vol, DXError (hr)); +} + static int ahi_init_sound_win32 (void) { HRESULT hr; @@ -355,19 +365,16 @@ static int ahi_init_sound_win32 (void) } sound_buffer.dwBufferBytes = ahisndbufsize; sound_buffer.lpwfxFormat = &wavfmt; - sound_buffer.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME /*| DSBCAPS_CTRLPOSITIONNOTIFY */ - | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_STATIC ; + sound_buffer.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME + | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_LOCSOFTWARE; + sound_buffer.guid3DAlgorithm = GUID_NULL; hr = IDirectSound_CreateSoundBuffer(lpDS2, &sound_buffer, &lpDSB2, NULL); if (FAILED(hr)) { write_log("AHI: CreateSoundBuffer() failure: %s\n", DXError(hr)); return 0; } - hr = IDirectSoundBuffer_SetVolume (lpDSB2, 0); - if (FAILED(hr)) { - write_log("AHI: SetVolume() 2 failure: %s\n", DXError(hr)); - return 0; - } + setvolume_ahi (0); hr = IDirectSoundBuffer_GetFormat(lpDSBprimary2,&wavfmt,500,0); if(FAILED(hr)) { diff --git a/od-win32/keyboard_win32.c b/od-win32/keyboard_win32.c index 3367daf6..ab0bc1f4 100644 --- a/od-win32/keyboard_win32.c +++ b/od-win32/keyboard_win32.c @@ -163,7 +163,8 @@ static struct uae_input_device_kbr_default keytrans[] = { // { DIK_SYSRQ, INPUTEVENT_KEY_6E }, // { DIK_F12, INPUTEVENT_KEY_6F }, { DIK_INSERT, INPUTEVENT_KEY_47 }, - { DIK_PRIOR, INPUTEVENT_KEY_48 }, +// { DIK_PRIOR, INPUTEVENT_KEY_48 }, + { DIK_PRIOR, INPUTEVENT_SPC_FREEZEBUTTON }, { DIK_NEXT, INPUTEVENT_KEY_49 }, { DIK_F11, INPUTEVENT_KEY_4B }, @@ -417,13 +418,6 @@ void my_kbd_handler (int keyboard, int scancode, int newstate) case DIK_SCROLL: code = AKS_INHIBITSCREEN; break; - case DIK_PRIOR: -#ifdef ACTION_REPLAY - code = AKS_FREEZEBUTTON; -#endif - break; - case DIK_NEXT: - break; case DIK_NUMPADMINUS: if (specialpressed ()) { if (shiftpressed ()) diff --git a/od-win32/midi.c b/od-win32/midi.c index d293af04..d5c47a25 100644 --- a/od-win32/midi.c +++ b/od-win32/midi.c @@ -54,8 +54,8 @@ extern int serdev; static HMIDIIN inHandle; static MIDIHDR midiin[MIDI_INBUFFERS]; -static char *inbuffer[ MIDI_INBUFFERS ] = { 0, 0} ; -static long inbufferlength[ MIDI_INBUFFERS ] = { 0,0}; +static char *inbuffer[MIDI_INBUFFERS] = { 0, 0} ; +static long inbufferlength[MIDI_INBUFFERS] = { 0,0}; static int in_allocated = 0; @@ -63,10 +63,10 @@ static int in_allocated = 0; static MidiOutStatus out_status; static HMIDIOUT outHandle; -static MIDIHDR midiout[ MIDI_BUFFERS ]; +static MIDIHDR midiout[MIDI_BUFFERS]; -static char *outbuffer[ MIDI_BUFFERS ] = { 0, 0} ; -static long outbufferlength[ MIDI_BUFFERS ] = { 0,0 }; +static char *outbuffer[MIDI_BUFFERS] = { 0, 0 }; +static long outbufferlength[MIDI_BUFFERS] = { 0, 0 }; static int outbufferselect = 0; static int out_allocated = 0; static volatile exitin = 0; @@ -88,11 +88,10 @@ static CRITICAL_SECTION cs_proc; * 1999.09.06 1.0 Brian King - Creation * */ -static char MidiOutErrorMsg[ 256 ]; -static char *getmidiouterr( int err ) +static char *getmidiouterr(char *txt, int err) { - midiOutGetErrorText( err, MidiOutErrorMsg, 256 ); - return MidiOutErrorMsg; + midiOutGetErrorText(err, txt, MAX_DPATH); + return txt; } /* @@ -111,35 +110,27 @@ static char *getmidiouterr( int err ) * 1999.09.06 1.0 Brian King - Creation * */ -static int MidiOut_Alloc( void ) +static int MidiOut_Alloc(void) { int i; - if( !out_allocated ) - { - for( i = 0; i < MIDI_BUFFERS; i++ ) - { - if( !outbuffer[ i ] ) - { - outbuffer[ i ] = (char *)xmalloc( BUFFLEN ); - if( outbuffer[ i ] ) - { - outbufferlength[ i ] = BUFFLEN; + if(!out_allocated) { + for(i = 0; i < MIDI_BUFFERS; i++) { + if(!outbuffer[i]) { + outbuffer[i] = (char*)xmalloc(BUFFLEN); + if(outbuffer[i]) { + outbufferlength[i] = BUFFLEN; out_allocated++; - } - else - { - outbufferlength[ i ] = 0; + } else { + outbufferlength[i] = 0; } } } outbufferselect = 0; + } else { + write_log("MIDI: ERROR - MidiOutAlloc() called twice?\n"); } - else - { - write_log( "MIDI: ERROR - MidiOutAlloc() called twice?\n" ); - } - return( out_allocated ); + return out_allocated; } /* @@ -157,18 +148,15 @@ static int MidiOut_Alloc( void ) * 1999.09.06 1.0 Brian King - Creation * */ -static void MidiOut_Free( void ) +static void MidiOut_Free(void) { int i; - for( i = 0; i < out_allocated; i++ ) - { - if( outbuffer[ i ] ) - { - //out_allocated--; - free( outbuffer[i] ); - outbufferlength[ i ] = 0; - outbuffer[ i ] = NULL; + for(i = 0; i < out_allocated; i++) { + if(outbuffer[i]) { + free(outbuffer[i]); + outbufferlength[i] = 0; + outbuffer[i] = NULL; } } outbufferselect = 0; @@ -194,9 +182,10 @@ static void MidiOut_Free( void ) * 1999.08.02 1.0 Brian King - Creation * */ -static int MidiOut_PrepareHeader( LPMIDIHDR out, LPSTR data, DWORD length ) +static int MidiOut_PrepareHeader(LPMIDIHDR out, LPSTR data, DWORD length) { int result = 1; + char err[MAX_DPATH]; out->lpData = data; out->dwBufferLength = length; @@ -204,9 +193,8 @@ static int MidiOut_PrepareHeader( LPMIDIHDR out, LPSTR data, DWORD length ) out->dwUser = 0; out->dwFlags = 0; - if( ( result = midiOutPrepareHeader( outHandle, out, sizeof( MIDIHDR ) ) ) ) - { - write_log( "MIDI: error %s / %d\n", getmidiouterr(result), result ); + if((result = midiOutPrepareHeader(outHandle, out, sizeof( MIDIHDR)))) { + write_log( "MIDI: error %s / %d\n", getmidiouterr(err, result), result); result = 0; } return result; @@ -232,11 +220,10 @@ static int MidiOut_PrepareHeader( LPMIDIHDR out, LPSTR data, DWORD length ) * 1999.09.06 1.0 Brian King - Creation * */ -static char MidiInErrorMsg[ 256 ]; -static char *getmidiinerr( int err ) +static char *getmidiinerr(char *txt, int err) { - midiInGetErrorText( err, MidiInErrorMsg, 256 ); - return MidiInErrorMsg; + midiInGetErrorText(err, txt, MAX_DPATH); + return txt; } /* @@ -255,34 +242,26 @@ static char *getmidiinerr( int err ) * 1999.09.06 1.0 Brian King - Creation * */ -static int MidiIn_Alloc( void ) +static int MidiIn_Alloc(void) { int i; - if( !in_allocated ) - { - for( i = 0; i < MIDI_INBUFFERS; i++ ) - { - if( !inbuffer[ i ] ) - { - inbuffer[ i ] = (char *)xmalloc( INBUFFLEN ); - if( inbuffer[ i ] ) - { - inbufferlength[ i ] = INBUFFLEN; + if(!in_allocated) { + for(i = 0; i < MIDI_INBUFFERS; i++) { + if(!inbuffer[i]) { + inbuffer[i] = (char*)xmalloc(INBUFFLEN); + if(inbuffer[i]) { + inbufferlength[i] = INBUFFLEN; in_allocated++; - } - else - { - inbufferlength[ i ] = 0; + } else { + inbufferlength[i] = 0; } } } + } else { + write_log("MIDI: ERROR - MidiInAlloc() called twice?\n"); } - else - { - write_log( "MIDI: ERROR - MidiInAlloc() called twice?\n" ); - } - return( in_allocated ); + return in_allocated; } /* @@ -304,18 +283,16 @@ static void MidiIn_Free( void ) { int i; - for( i = 0; i < in_allocated; i++ ) - { - if( inbuffer[ i ] ) - { + for( i = 0; i < in_allocated; i++ ) { + if(inbuffer[i]) { //in_allocated--; - free( inbuffer[i] ); - inbufferlength[ i ] = 0; - inbuffer[ i ] = NULL; + free(inbuffer[i]); + inbufferlength[i] = 0; + inbuffer[i] = NULL; } } - in_allocated = 0; - only_one_time = 0; + in_allocated = 0; + only_one_time = 0; } static unsigned char plen[128] = { @@ -349,138 +326,87 @@ static unsigned char plen[128] = { * 1999.08.02 1.0 Brian King - Creation * */ -int Midi_Parse( midi_direction_e direction, BYTE *dataptr ) +int Midi_Parse(midi_direction_e direction, BYTE *dataptr) { int result = 0; static unsigned short bufferindex; static char *bufferpoint = 0; - if( direction == midi_output ) - { + if(direction == midi_output) { BYTE data = *dataptr; - DBGOUT_MIDI_BYTE( data ); - if( data >= 0x80 ) - { - if( data >= MIDI_CLOCK ) - { - switch( data ) + DBGOUT_MIDI_BYTE(data); + if(data >= 0x80) { + if(data >= MIDI_CLOCK) { + switch(data) { - case MIDI_CLOCK: - + case MIDI_CLOCK: TRACE(( "MIDI: MIDI_CLOCK\n" )); break; - case MIDI_START: - + case MIDI_START: TRACE(( "MIDI: MIDI_START\n" )); break; - case MIDI_CONTINUE: - + case MIDI_CONTINUE: TRACE(( "MIDI: MIDI_CONTINUE\n" )); break; - case MIDI_STOP: - + case MIDI_STOP: TRACE(( "MIDI: MIDI_STOP\n" )); break; default: - break; } - } - /* - else if( data == MIDI_MTC ) - { - out_status.timecode = 1; - } - */ - else if( out_status.sysex ) - { - if( out_allocated ) - { - bufferpoint[ bufferindex++ ] = (char)MIDI_EOX; - if( bufferindex >= BUFFLEN ) + } else if(out_status.sysex) { + if(out_allocated) { + bufferpoint[bufferindex++] = (char)MIDI_EOX; + if(bufferindex >= BUFFLEN) bufferindex = BUFFLEN - 1; out_status.status = MIDI_SYSX; // Flush this buffer using midiOutLongMsg - MidiOut_PrepareHeader( &midiout[ outbufferselect ], bufferpoint, bufferindex ); - midiOutLongMsg( outHandle, &midiout[ outbufferselect ], sizeof( MIDIHDR ) ); - + MidiOut_PrepareHeader(&midiout[ outbufferselect ], bufferpoint, bufferindex); + midiOutLongMsg(outHandle, &midiout[outbufferselect], sizeof(MIDIHDR)); outbufferselect = !outbufferselect; - bufferpoint = outbuffer[ outbufferselect ]; - midiOutUnprepareHeader( outHandle, &midiout[ outbufferselect ], sizeof( MIDIHDR ) ); + bufferpoint = outbuffer[outbufferselect]; + midiOutUnprepareHeader(outHandle, &midiout[outbufferselect], sizeof(MIDIHDR)); } out_status.sysex = 0; // turn off MIDI_SYSX mode out_status.unknown = 1; // now in an unknown state - if( data == MIDI_EOX ) + if(data == MIDI_EOX) return 0; } out_status.status = data; - out_status.length = plen[ data & 0x7F ]; + out_status.length = plen[data & 0x7F]; out_status.posn = 0; out_status.unknown = 0; - if( data == MIDI_SYSX ) - { + if(data == MIDI_SYSX) { out_status.sysex = 1; // turn on MIDI_SYSX mode - if( out_allocated ) - { + if(out_allocated) { bufferindex = 0; - bufferpoint = outbuffer[ outbufferselect ]; - bufferpoint[ bufferindex++ ] = (char)MIDI_SYSX; + bufferpoint = outbuffer[outbufferselect]; + bufferpoint[bufferindex++] = (char)MIDI_SYSX; } return 0; } - } // data & 0x80 -/* - else if( out_status.timecode ) - { - out_status.timecode = 0; - out_status.status = MIDI_MTC; - out_status.byte1 = data; - // process MIDI_MTC msg - write_log( "MIDI OUT: MIDI_MTC message\n" ); - return 0; - }*/ - else if( out_status.sysex ) - { - if( out_allocated ) - { - bufferpoint[ bufferindex++ ] = data; - if( bufferindex >= BUFFLEN ) + } else if(out_status.sysex) { + if(out_allocated) { + bufferpoint[bufferindex++] = data; + if(bufferindex >= BUFFLEN) bufferindex = BUFFLEN - 1; } return 0; - } - else if( out_status.unknown ) - { + } else if(out_status.unknown) { return 0; - } - else if( ++out_status.posn == 1 ) - { + } else if(++out_status.posn == 1) { out_status.byte1 = data; - } - else - { + } else { out_status.byte2 = data; } - if( out_status.posn >= out_status.length ) - { + if(out_status.posn >= out_status.length) { + DWORD shortMsg; out_status.posn = 0; - /* if( out_status.status == MIDI_SONGPP ) - { - // Handle this by doing a process-midi-clock ?? - write_log( "MIDI OUT: MIDI_SONGPP message\n" ); - return 0; - } - else*/ - { - // flush the packet using midiOutShortMessage - DWORD shortMsg = MAKELONG( MAKEWORD( out_status.status, out_status.byte1 ), MAKEWORD( out_status.byte2, 0 ) ); - midiOutShortMsg( outHandle, shortMsg ); - - } + // flush the packet using midiOutShortMessage + shortMsg = MAKELONG(MAKEWORD(out_status.status, out_status.byte1), MAKEWORD(out_status.byte2, 0)); + midiOutShortMsg(outHandle, shortMsg); } - } - else // handle input-data - { + } else { // handle input-data } return result; @@ -498,35 +424,35 @@ int Midi_Parse( midi_direction_e direction, BYTE *dataptr ) static unsigned char midibuf[BUFFLEN]; static long midi_inptr = 0, midi_inlast = 0; -static void add1byte(DWORD_PTR w) //put 1 Byte to Midibuffer +static void add1byte(DWORD_PTR w) //put 1 Byte to Midibuffer { - if(midi_inlast >= BUFFLEN - 10) { - TRACE(("add1byte buffer full %d %d (%02.2X)\n", midi_inlast, midi_inptr, w)); - return; - } - midibuf[midi_inlast++] = (uae_u8)w; + if(midi_inlast >= BUFFLEN - 10) { + TRACE(("add1byte buffer full %d %d (%02.2X)\n", midi_inlast, midi_inptr, w)); + return; + } + midibuf[midi_inlast++] = (uae_u8)w; } -static void add2byte(DWORD_PTR w) //put 2 Byte to Midibuffer +static void add2byte(DWORD_PTR w) //put 2 Byte to Midibuffer { - if(midi_inlast >= BUFFLEN - 10) { - TRACE(("add2byte buffer full %d %d (%04.4X)\n", midi_inlast, midi_inptr, w)); - return; - } - midibuf[midi_inlast++] = (uae_u8)w; - w = w>>8; - midibuf[midi_inlast++] = (uae_u8)w; + if(midi_inlast >= BUFFLEN - 10) { + TRACE(("add2byte buffer full %d %d (%04.4X)\n", midi_inlast, midi_inptr, w)); + return; + } + midibuf[midi_inlast++] = (uae_u8)w; + w = w >> 8; + midibuf[midi_inlast++] = (uae_u8)w; } -static void add3byte(DWORD_PTR w) //put 3 Byte to Midibuffer +static void add3byte(DWORD_PTR w) //put 3 Byte to Midibuffer { - if(midi_inlast >= BUFFLEN - 10) { - TRACE(("add3byte buffer full %d %d (%08.8X)\n", midi_inlast, midi_inptr, w)); - return; - } - midibuf[midi_inlast++] = (uae_u8)w; - w = w>>8; - midibuf[midi_inlast++] = (uae_u8)w; - w = w>>8; - midibuf[midi_inlast++] = (uae_u8)w; + if(midi_inlast >= BUFFLEN - 10) { + TRACE(("add3byte buffer full %d %d (%08.8X)\n", midi_inlast, midi_inptr, w)); + return; + } + midibuf[midi_inlast++] = (uae_u8)w; + w = w >> 8; + midibuf[midi_inlast++] = (uae_u8)w; + w = w >> 8; + midibuf[midi_inlast++] = (uae_u8)w; } int ismidibyte(void) @@ -542,29 +468,20 @@ LONG getmidibyte(void) //return midibyte or -1 if none LONG rv; EnterCriticalSection (&cs_proc); - if (overflow == 1) - { - char szMessage[ MAX_DPATH ]; - WIN32GUI_LoadUIString(IDS_MIDIOVERFLOW, szMessage, MAX_DPATH ); - gui_message( szMessage ); + if (overflow == 1) { + char szMessage[MAX_DPATH]; + WIN32GUI_LoadUIString(IDS_MIDIOVERFLOW, szMessage, MAX_DPATH); + gui_message(szMessage); overflow = 0; } TRACE(("getmidibyte(%02.2X)\n", midibuf[midi_inptr])); - if (midibuf[midi_inptr] >= 0xf0) // only check for free buffers if status sysex - { - for (i = 0;i < MIDI_INBUFFERS;i++) - { - if (midiin[i].dwFlags==(MHDR_DONE|MHDR_PREPARED)){ + if (midibuf[midi_inptr] >= 0xf0) { // only check for free buffers if status sysex + for (i = 0;i < MIDI_INBUFFERS;i++) { + if (midiin[i].dwFlags == (MHDR_DONE|MHDR_PREPARED)) { // add a buffer if one is free - /* midiInUnprepareHeader( inHandle,&midiin[i], sizeof(MIDIHDR)); - midiin[i].dwBufferLength = INBUFFLEN-1; - midiin[i].dwBytesRecorded = INBUFFLEN-1; - midiin[i].dwUser = 0; - midiin[i].dwFlags = 0; - midiInPrepareHeader(inHandle,&midiin[i], sizeof(MIDIHDR));*/ - LeaveCriticalSection(&cs_proc); - midiInAddBuffer(inHandle,&midiin[i],sizeof(MIDIHDR)); - EnterCriticalSection(&cs_proc); + LeaveCriticalSection(&cs_proc); + midiInAddBuffer(inHandle, &midiin[i], sizeof(MIDIHDR)); + EnterCriticalSection(&cs_proc); } } } @@ -579,107 +496,99 @@ LONG getmidibyte(void) //return midibyte or -1 if none static void CALLBACK MidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2) { - EnterCriticalSection (&cs_proc); - if(wMsg == MIM_ERROR) - { - TRACE(("MIDI Data Lost\n")); + EnterCriticalSection (&cs_proc); + if(wMsg == MIM_ERROR) { + TRACE(("MIDI Data Lost\n")); + } + if(wMsg == MIM_LONGDATA) { + LPMIDIHDR midiin = (LPMIDIHDR)dwParam1; + static long synum; + TRACE(("MIM_LONGDATA bytes=%d ts=%u\n", midiin->dwBytesRecorded, dwParam2)); + if (exitin == 1) + goto end; //for safeness midi want close + if ((midi_inlast + midiin->dwBytesRecorded) >= (BUFFLEN-6)) { + overflow = 1; + TRACE(("MIDI overflow1\n")); + //for safeness if buffer too full (should not occur) + goto end; } - if(wMsg == MIM_LONGDATA) - { - LPMIDIHDR midiin = (LPMIDIHDR)dwParam1; - static long synum; - TRACE(("MIM_LONGDATA bytes=%d ts=%u\n", midiin->dwBytesRecorded, dwParam2)); - if (exitin == 1) goto end; //for safeness midi want close - if ((midi_inlast + midiin->dwBytesRecorded) >= (BUFFLEN-6)) - { - overflow = 1; - TRACE(("MIDI overflow1\n")); - //for safeness if buffer too full (should not occur) - goto end; - } - - if (midiin->dwBufferLength == midiin->dwBytesRecorded) - { - //for safeness if buffer too full (should not occur) - overflow = 1; - TRACE(("MIDI overflow2\n")); - goto end; - } - - memcpy(&midibuf[midi_inlast], midiin->lpData, midiin->dwBytesRecorded); - midi_inlast = midi_inlast + midiin->dwBytesRecorded; - - + if (midiin->dwBufferLength == midiin->dwBytesRecorded) { + //for safeness if buffer too full (should not occur) + overflow = 1; + TRACE(("MIDI overflow2\n")); + goto end; } + memcpy(&midibuf[midi_inlast], midiin->lpData, midiin->dwBytesRecorded); + midi_inlast = midi_inlast + midiin->dwBytesRecorded; + } - if(wMsg == MM_MIM_DATA || wMsg == MM_MIM_MOREDATA) - { - BYTE state = (BYTE)dwParam1; - TRACE(("%s %08.8X\n", wMsg == MM_MIM_DATA ? "MM_MIM_DATA" : "MM_MIM_MOREDATA", dwParam1)); - if(state == 254) goto end; - if(state < 0xf0) state = state & 0xf0; - //else {add1byte(state); goto end;} - switch (state) - { - case 0x80: //Note OFF - add3byte(dwParam1); - break; - case 0x90: // Note On - add3byte(dwParam1); - break; - case 0xa0: // Poly Press - add3byte(dwParam1); - break; - case 0xb0: //CTRL Change - add3byte(dwParam1); - break; - case 0xc0: //ProgramChange - add2byte(dwParam1); - break; - case 0xd0: //ChanPress - add2byte(dwParam1); - break; - case 0xe0: //PitchBend - add3byte(dwParam1); - break; - //System Common Messages - case 0xf1: //QuarterFrame-message ... MIDI_Time_Code - add2byte(dwParam1); - break; - case 0xf2: //Song Position - add3byte(dwParam1); - break; - case 0xf3: //Song Select - add2byte(dwParam1); - break; - case 0xf6: //Tune Request - add3byte(dwParam1); - break; -//System Real Time Messages - case 0xf8: //MIDI-Clock - add1byte((char)dwParam1); - break; - case 0xfa: //Start - add1byte((char)dwParam1); - break; - case 0xfb: //Continue - add1byte((char)dwParam1); - break; - case 0xfc: //Stop - add1byte((char)dwParam1); - break; - case 0xfe: //Active Sense (selden used) - add1byte((char)dwParam1); - break; - case 0xff: //Reset (selden used) - add2byte(dwParam1); - break; - - } + if(wMsg == MM_MIM_DATA || wMsg == MM_MIM_MOREDATA) { + BYTE state = (BYTE)dwParam1; + TRACE(("%s %08.8X\n", wMsg == MM_MIM_DATA ? "MM_MIM_DATA" : "MM_MIM_MOREDATA", dwParam1)); + if(state == 254) + goto end; + if(state < 0xf0) + state = state & 0xf0; + switch (state) + { + case 0x80: //Note OFF + add3byte(dwParam1); + break; + case 0x90: // Note On + add3byte(dwParam1); + break; + case 0xa0: // Poly Press + add3byte(dwParam1); + break; + case 0xb0: //CTRL Change + add3byte(dwParam1); + break; + case 0xc0: //ProgramChange + add2byte(dwParam1); + break; + case 0xd0: //ChanPress + add2byte(dwParam1); + break; + case 0xe0: //PitchBend + add3byte(dwParam1); + break; + //System Common Messages + case 0xf1: //QuarterFrame-message ... MIDI_Time_Code + add2byte(dwParam1); + break; + case 0xf2: //Song Position + add3byte(dwParam1); + break; + case 0xf3: //Song Select + add2byte(dwParam1); + break; + case 0xf6: //Tune Request + add3byte(dwParam1); + break; + //System Real Time Messages + case 0xf8: //MIDI-Clock + add1byte((char)dwParam1); + break; + case 0xfa: //Start + add1byte((char)dwParam1); + break; + case 0xfb: //Continue + add1byte((char)dwParam1); + break; + case 0xfc: //Stop + add1byte((char)dwParam1); + break; + case 0xfe: //Active Sense (selden used) + add1byte((char)dwParam1); + break; + case 0xff: //Reset (selden used) + add2byte(dwParam1); + break; } + } end: - LeaveCriticalSection(&cs_proc); - } + LeaveCriticalSection(&cs_proc); + } /* * FUNCTION: Midi_Open * @@ -696,65 +605,50 @@ end: * 1999.08.02 1.0 Brian King - Creation * */ -int Midi_Open( void ) +int Midi_Open(void) { - unsigned long result = 0,i; + unsigned long result = 0, i; + char err[MAX_DPATH]; - if( ( result = midiOutOpen( &outHandle, currprefs.win32_midioutdev, 0, 0,CALLBACK_NULL ) ) ) - { - write_log( "MIDI OUT: error %s / %d while opening port %d\n", getmidiouterr(result), result, currprefs.win32_midioutdev ); + if((result = midiOutOpen(&outHandle, currprefs.win32_midioutdev, 0, 0,CALLBACK_NULL))) { + write_log("MIDI OUT: error %s / %d while opening port %d\n", getmidiouterr(err, result), result, currprefs.win32_midioutdev); result = 0; - } - else - { + } else { InitializeCriticalSection(&cs_proc); // We don't need input for output... - if( ( currprefs.win32_midiindev >= 0 ) && - ( result = midiInOpen( &inHandle, currprefs.win32_midiindev, (DWORD_PTR)MidiInProc, 0, CALLBACK_FUNCTION|MIDI_IO_STATUS) ) ) - { - write_log( "MIDI IN: error %s / %d while opening port %d\n", getmidiinerr(result), result, currprefs.win32_midiindev ); - } - else - { - - midi_in_ready = TRUE; + if((currprefs.win32_midiindev >= 0) && + (result = midiInOpen( &inHandle, currprefs.win32_midiindev, (DWORD_PTR)MidiInProc, 0, CALLBACK_FUNCTION|MIDI_IO_STATUS))) { + write_log( "MIDI IN: error %s / %d while opening port %d\n", getmidiinerr(err, result), result, currprefs.win32_midiindev); + } else { + midi_in_ready = TRUE; result=midiInStart(inHandle); } - if( MidiOut_Alloc() ) - { - if( midi_in_ready ) - { - if( !MidiIn_Alloc() ) - { - midiInClose( inHandle ); + if(MidiOut_Alloc()) { + if(midi_in_ready) { + if(!MidiIn_Alloc()) { + midiInClose(inHandle); midi_in_ready = FALSE; - } - else - { - for (i=0;i #include @@ -480,6 +481,267 @@ int doprinter (uae_u8 val) return prtopen; } +struct uaeserialdatawin32 +{ + HANDLE hCom; + HANDLE evtr, evtw, evtt, evtwce; + OVERLAPPED olr, olw, olwce; + int readactive, writeactive; + void *readdata, *writedata; + volatile int threadactive; + uae_thread_id tid; + uae_sem_t change_sem, sync_sem; + void *user; +}; + +int uaeser_getdatalenght (void) +{ + return sizeof (struct uaeserialdatawin32); +} + +static void uaeser_initdata (struct uaeserialdatawin32 *sd, void *user) +{ + memset (sd, 0, sizeof (struct uaeserialdatawin32)); + sd->hCom = INVALID_HANDLE_VALUE; + sd->evtr = sd->evtw = sd->evtt = sd->evtwce = 0; + sd->user = user; +} + +int uaeser_query (struct uaeserialdatawin32 *sd, uae_u16 *status, uae_u32 *pending) +{ + DWORD err, modem; + COMSTAT ComStat; + uae_u16 s = 0; + + if (!ClearCommError (sd->hCom, &err, &ComStat)) + return 0; + *pending = ComStat.cbInQue; + if (status) { + s |= (err & CE_BREAK) ? (1 << 10) : 0; + s |= (err & CE_RXOVER) ? (1 << 8) : 0; + if (GetCommModemStatus (sd->hCom, &modem)) { + s |= (modem & MS_CTS_ON) ? 0 : (1 << 4); + s |= (modem & MS_DSR_ON) ? 0 : (1 << 7); + s |= (modem & MS_RING_ON) ? (1 << 2) : 0; + } + *status = s; + } + return 1; +} + +int uaeser_break (struct uaeserialdatawin32 *sd, int brklen) +{ + if (!SetCommBreak (sd->hCom)) + return 0; + Sleep (brklen / 1000); + ClearCommBreak (sd->hCom); + return 1; +} + +int uaeser_setparams (struct uaeserialdatawin32 *sd, int baud, int rbuffer, int bits, int sbits, int rtscts, int parity) +{ + DCB dcb; + + dcb.DCBlength = sizeof (DCB); + if (!GetCommState (sd->hCom, &dcb)) + return 0; + + dcb.BaudRate = baud; + dcb.ByteSize = bits; + dcb.Parity = parity == 0 ? NOPARITY : (parity == 1 ? ODDPARITY : EVENPARITY); + dcb.StopBits = sbits == 1 ? ONESTOPBIT : TWOSTOPBITS; + + dcb.fDsrSensitivity = FALSE; + dcb.fOutxDsrFlow = FALSE; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + + if (rtscts) { + dcb.fOutxCtsFlow = TRUE; + dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + } else { + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.fOutxCtsFlow = FALSE; + } + + dcb.fTXContinueOnXoff = FALSE; + dcb.fOutX = FALSE; + dcb.fInX = FALSE; + + dcb.fErrorChar = FALSE; + dcb.fNull = FALSE; + dcb.fAbortOnError = FALSE; + + dcb.XoffLim = 512; + dcb.XonLim = 2048; + + dcb.ByteSize = rbuffer; + + if (!SetCommState (sd->hCom, &dcb)) + return 0; + return 1; +} + +static void startwce(struct uaeserialdatawin32 *sd, DWORD *evtmask) +{ + WaitCommEvent(sd->hCom, evtmask, &sd->olwce); +} + +static void *uaeser_trap_thread (void *arg) +{ + struct uaeserialdatawin32 *sd = arg; + HANDLE handles[4]; + int cnt, actual; + DWORD evtmask; + + uae_set_thread_priority (2); + sd->threadactive = 1; + uae_sem_post (&sd->sync_sem); + startwce(sd, &evtmask); + while (sd->threadactive) { + int sigmask = 0; + uae_sem_wait (&sd->change_sem); + if (WaitForSingleObject(sd->evtwce, 0) == WAIT_OBJECT_0) { + if ((evtmask & EV_RXCHAR) && !sd->readactive) + sigmask |= 1; + if ((evtmask & EV_TXEMPTY) && !sd->writeactive) + sigmask |= 2; + startwce(sd, &evtmask); + } + cnt = 0; + handles[cnt++] = sd->evtt; + handles[cnt++] = sd->evtwce; + if (sd->readactive) { + if (GetOverlappedResult (sd->hCom, &sd->olr, &actual, FALSE)) { + sd->readactive = 0; + sigmask |= 1; + } else { + handles[cnt++] = sd->evtr; + } + } + if (sd->writeactive) { + if (GetOverlappedResult (sd->hCom, &sd->olw, &actual, FALSE)) { + sd->writeactive = 0; + sigmask |= 2; + } else { + handles[cnt++] = sd->evtw; + } + } + if (!sd->writeactive) + sigmask |= 1; + if (!sd->readactive) + sigmask |= 2; + if (sigmask) + uaeser_signal (sd->user, sigmask); + uae_sem_post (&sd->change_sem); + WaitForMultipleObjects(cnt, handles, FALSE, INFINITE); + } + sd->threadactive = 0; + uae_sem_post (&sd->sync_sem); + return 0; +} + +void uaeser_trigger (struct uaeserialdatawin32 *sd) +{ + SetEvent (sd->evtt); +} + +int uaeser_write (struct uaeserialdatawin32 *sd, uae_u8 *data, uae_u32 len) +{ + int ret = 1; + if (!WriteFile (sd->hCom, data, len, NULL, &sd->olw)) { + sd->writeactive = 1; + if (GetLastError() != ERROR_IO_PENDING) { + ret = 0; + sd->writeactive = 0; + } + } + SetEvent (sd->evtt); + return ret; +} + +int uaeser_read (struct uaeserialdatawin32 *sd, uae_u8 *data, uae_u32 len) +{ + int ret = 1; + if (!ReadFile (sd->hCom, data, len, NULL, &sd->olr)) { + sd->readactive = 1; + if (GetLastError() != ERROR_IO_PENDING) { + ret = 0; + sd->readactive = 0; + } + } + SetEvent (sd->evtt); + return ret; +} + +void uaeser_clearbuffers (struct uaeserialdatawin32 *sd) +{ + PurgeComm (sd->hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); +} + +int uaeser_open (struct uaeserialdatawin32 *sd, void *user, int unit) +{ + char buf[256]; + COMMTIMEOUTS CommTimeOuts; + + sd->user = user; + sprintf (buf, "\\.\\\\COM%d", unit); + sd->evtr = CreateEvent (NULL, TRUE, FALSE, NULL); + sd->evtw = CreateEvent (NULL, TRUE, FALSE, NULL); + sd->evtt = CreateEvent (NULL, FALSE, FALSE, NULL); + sd->evtwce = CreateEvent (NULL, TRUE, FALSE, NULL); + if (!sd->evtt || !sd->evtw || !sd->evtt || !sd->evtwce) + goto end; + sd->olr.hEvent = sd->evtr; + sd->olw.hEvent = sd->evtw; + sd->olwce.hEvent = sd->evtwce; + sd->hCom = CreateFile (buf, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (sd->hCom == INVALID_HANDLE_VALUE) { + write_log("UAESER: '%s' failed to open, err=%d\n", buf, GetLastError()); + goto end; + } + uae_sem_init (&sd->sync_sem, 0, 0); + uae_sem_init (&sd->change_sem, 0, 1); + uae_start_thread (uaeser_trap_thread, sd, &sd->tid); + uae_sem_wait (&sd->sync_sem); + + CommTimeOuts.ReadIntervalTimeout = 0; + CommTimeOuts.ReadTotalTimeoutMultiplier = 0; + CommTimeOuts.ReadTotalTimeoutConstant = 0; + CommTimeOuts.WriteTotalTimeoutMultiplier = 0; + CommTimeOuts.WriteTotalTimeoutConstant = 0; + SetCommTimeouts (sd->hCom, &CommTimeOuts); + SetCommMask (sd->hCom, EV_RXCHAR | EV_TXEMPTY | EV_BREAK); + + return 1; + +end: + uaeser_close (sd); + return 0; +} + +void uaeser_close (struct uaeserialdatawin32 *sd) +{ + if (sd->hCom) + CloseHandle(sd->hCom); + if (sd->evtr) + CloseHandle(sd->evtr); + if (sd->evtw) + CloseHandle(sd->evtw); + if (sd->evtwce) + CloseHandle(sd->evtwce); + if (sd->evtt) { + if (sd->threadactive) { + sd->threadactive = 0; + SetEvent (sd->evtt); + while (sd->threadactive) + Sleep(10); + } + CloseHandle (sd->evtt); + } + uaeser_initdata (sd, sd->user); +} + static HANDLE hCom = INVALID_HANDLE_VALUE; static DCB dcb; static HANDLE writeevent; @@ -490,7 +752,7 @@ static uae_u8 outputbufferout[SERIAL_WRITE_BUFFER]; static uae_u8 inputbuffer[SERIAL_READ_BUFFER]; static int datainoutput; static int dataininput, dataininputcnt; -static OVERLAPPED writeol, readol; +static OVERLAPPED writeol; static writepending; int openser (char *sername) @@ -523,6 +785,7 @@ int openser (char *sername) CommTimeOuts.WriteTotalTimeoutConstant = 0; SetCommTimeouts (hCom, &CommTimeOuts); + dcb.DCBlength = sizeof (DCB); GetCommState (hCom, &dcb); dcb.BaudRate = 9600; @@ -570,10 +833,15 @@ void closeser (void) CloseHandle (hCom); hCom = INVALID_HANDLE_VALUE; } - if (midi_ready) + if (midi_ready) { + extern int serper; Midi_Close(); - if( writeevent ) - CloseHandle( writeevent ); + //need for camd Midi Stuff(it close midi and reopen it but serial.c think the baudrate + //is the same and do not open midi), so setting serper to different value helps + serper = 0x30; + } + if(writeevent) + CloseHandle(writeevent); writeevent = 0; uartbreak = 0; } @@ -590,13 +858,10 @@ static void outser (void) void writeser (int c) { - if (midi_ready) - { + if (midi_ready) { BYTE outchar = (BYTE)c; - Midi_Parse( midi_output, &outchar ); - } - else - { + Midi_Parse(midi_output, &outchar); + } else { if (!currprefs.use_serial) return; if (datainoutput + 1 < sizeof(outputbuffer)) { @@ -651,15 +916,12 @@ int readser (int *buffer) DWORD actual; - if (midi_ready) - { + if (midi_ready) { *buffer = getmidibyte (); if (*buffer < 0) return 0; return 1; - } - else - { + } else { if (!currprefs.use_serial) return 0; if (dataininput > dataininputcnt) { @@ -668,18 +930,14 @@ int readser (int *buffer) } dataininput = 0; dataininputcnt = 0; - if (hCom != INVALID_HANDLE_VALUE) - { + if (hCom != INVALID_HANDLE_VALUE) { /* only try to read number of bytes in queue */ ClearCommError (hCom, &dwErrorFlags, &ComStat); - if (ComStat.cbInQue) - { + if (ComStat.cbInQue) { int len = ComStat.cbInQue; - if (len > sizeof (inputbuffer)) len = sizeof (inputbuffer); - if (ReadFile (hCom, inputbuffer, len, &actual, &readol)) - { + if (ReadFile (hCom, inputbuffer, len, &actual, NULL)) { dataininput = actual; dataininputcnt = 0; if (actual == 0) @@ -740,35 +998,27 @@ void setserstat (int mask, int onoff) int setbaud (long baud) { - if( baud == 31400 && currprefs.win32_midioutdev >= -1) /* MIDI baud-rate */ - { - if (!midi_ready) - { + if(baud == 31400 && currprefs.win32_midioutdev >= -1) { + /* MIDI baud-rate */ + if (!midi_ready) { if (Midi_Open()) write_log ("Midi enabled\n"); } return 1; - } - else - { - if (midi_ready) - { + } else { + if (midi_ready) { Midi_Close(); } if (!currprefs.use_serial) return 1; - if (hCom != INVALID_HANDLE_VALUE) - { - if (GetCommState (hCom, &dcb)) - { + if (hCom != INVALID_HANDLE_VALUE) { + if (GetCommState (hCom, &dcb)) { dcb.BaudRate = baud; if (!SetCommState (hCom, &dcb)) { write_log ("SERIAL: Error setting baud rate %d!\n", baud); return 0; } - } - else - { + } else { write_log ("SERIAL: setbaud internal error!\n"); } } diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index 979ed82f..ba8db068 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -587,6 +587,8 @@ #define IDC_T7 1557 #define IDC_PSPRINTERDETECT 1557 #define IDC_T8 1558 +#define IDC_SHARED2 1558 +#define IDC_UAESERIAL 1558 #define IDC_T9 1559 #define IDC_T10 1560 #define IDC_T11 1561 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 4e04fba2..241828ec 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -291,7 +291,7 @@ BEGIN PUSHBUTTON "Save As...",IDC_SAVE,175,225,40,15 END -IDD_PORTS DIALOGEX 0, 0, 300, 222 +IDD_PORTS DIALOGEX 0, 0, 300, 238 STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN @@ -305,24 +305,25 @@ BEGIN EDITTEXT IDC_PRINTERAUTOFLUSH,263,33,25,12,ES_NUMBER RTEXT "Ghostscript extra parameters:",IDC_STATIC,12,49,91,15,SS_CENTERIMAGE EDITTEXT IDC_PS_PARAMS,120,50,169,12,ES_AUTOHSCROLL - GROUPBOX "Serial Port",IDC_SERIALFRAME,4,72,292,29 - COMBOBOX IDC_SERIAL,19,83,95,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Serial Port",IDC_SERIALFRAME,4,72,292,48 + COMBOBOX IDC_SERIAL,19,84,95,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Shared",IDC_SHARED,"Button",BS_AUTOCHECKBOX | BS_VCENTER | WS_TABSTOP,132,83,48,13 CONTROL "RTS/CTS",IDC_SER_CTSRTS,"Button",BS_AUTOCHECKBOX | BS_VCENTER | WS_TABSTOP,185,83,53,12 CONTROL "Direct []Use when emulating serial-link games on two PCs running WinUAE",IDC_SERIAL_DIRECT, "Button",BS_AUTOCHECKBOX | BS_VCENTER | WS_TABSTOP,243,83,46,12 - GROUPBOX "MIDI",IDC_MIDIFRAME,4,104,292,33 - RTEXT "Out:",IDC_MIDI,10,115,34,15,SS_CENTERIMAGE - COMBOBOX IDC_MIDIOUTLIST,50,115,95,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "In:",IDC_MIDI2,150,115,29,15,SS_CENTERIMAGE - COMBOBOX IDC_MIDIINLIST,185,115,95,134,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Mouse/Joystick Ports",IDC_PORT0,4,139,292,75 - COMBOBOX IDC_PORT0_JOYS,45,155,241,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_PORT1_JOYS,45,176,241,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Swap ports",IDC_SWAP,211,195,75,14 - RTEXT "Port 0:",IDC_STATIC,11,154,25,15,SS_CENTERIMAGE - RTEXT "Port 1:",IDC_STATIC,11,175,25,15,SS_CENTERIMAGE - LTEXT "X-Arcade layout information []#1",IDC_STATIC,16,195,106,15,SS_NOTIFY | SS_CENTERIMAGE + GROUPBOX "MIDI",IDC_MIDIFRAME,4,123,292,33 + RTEXT "Out:",IDC_MIDI,10,134,34,15,SS_CENTERIMAGE + COMBOBOX IDC_MIDIOUTLIST,50,134,95,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "In:",IDC_MIDI2,150,134,29,15,SS_CENTERIMAGE + COMBOBOX IDC_MIDIINLIST,185,134,95,134,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Mouse/Joystick Ports",IDC_PORT0,4,158,292,75 + COMBOBOX IDC_PORT0_JOYS,45,174,241,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_PORT1_JOYS,45,195,241,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Swap ports",IDC_SWAP,211,214,75,14 + RTEXT "Port 0:",IDC_STATIC,11,173,25,15,SS_CENTERIMAGE + RTEXT "Port 1:",IDC_STATIC,11,194,25,15,SS_CENTERIMAGE + LTEXT "X-Arcade layout information []#1",IDC_STATIC,16,213,106,15,SS_NOTIFY | SS_CENTERIMAGE + CONTROL "uaeserial.device",IDC_UAESERIAL,"Button",BS_AUTOCHECKBOX | BS_VCENTER | WS_TABSTOP,132,100,131,13 END IDD_CONTRIBUTORS DIALOGEX 0, 0, 411, 242 diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index 1edcd209..345cd927 100644 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -185,7 +185,7 @@ static void close_audio_ds (void) } extern HWND hMainWnd; - +extern void setvolume_ahi(LONG); static void setvolume (void) { HRESULT hr; @@ -196,6 +196,7 @@ static void setvolume (void) hr = IDirectSoundBuffer_SetVolume (lpDSBsecondary, vol); if (FAILED(hr)) write_log ("SOUND: SetVolume(%d) failed: %s\n", vol, DXError (hr)); + setvolume_ahi (vol); } static int open_audio_ds (int size) @@ -268,24 +269,25 @@ static int open_audio_ds (int size) goto error; } + hr = IDirectSound_SetCooperativeLevel (lpDS, hMainWnd, DSSCL_PRIORITY); + if (FAILED(hr)) { + write_log ("SOUND: Can't set cooperativelevel: %s\n", DXError (hr)); + goto error; + } + + memset (&wavfmt, 0, sizeof (WAVEFORMATEX)); wavfmt.wFormatTag = WAVE_FORMAT_PCM; wavfmt.nChannels = (currprefs.sound_stereo == 3 || currprefs.sound_stereo == 2) ? 4 : (currprefs.sound_stereo ? 2 : 1); wavfmt.nSamplesPerSec = freq; wavfmt.wBitsPerSample = 16; wavfmt.nBlockAlign = 16 / 8 * wavfmt.nChannels; wavfmt.nAvgBytesPerSec = wavfmt.nBlockAlign * freq; - wavfmt.cbSize = 0; max_sndbufsize = size * 4; if (max_sndbufsize > SND_MAX_BUFFER2) max_sndbufsize = SND_MAX_BUFFER2; dsoundbuf = max_sndbufsize * 2; - hr = IDirectSound_SetCooperativeLevel (lpDS, hMainWnd, DSSCL_PRIORITY); - if (FAILED(hr)) { - write_log ("SOUND: Can't set cooperativelevel: %s\n", DXError (hr)); - goto error; - } if (dsoundbuf < DSBSIZE_MIN) dsoundbuf = DSBSIZE_MIN; if (dsoundbuf > DSBSIZE_MAX) @@ -303,7 +305,8 @@ static int open_audio_ds (int size) sound_buffer.dwBufferBytes = dsoundbuf; sound_buffer.lpwfxFormat = &wavfmt; sound_buffer.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; - sound_buffer.dwFlags |= DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY; + sound_buffer.dwFlags |= DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE; + sound_buffer.guid3DAlgorithm = GUID_NULL; hr = IDirectSound_CreateSoundBuffer(lpDS, &sound_buffer, &pdsb, NULL); if (FAILED(hr)) { diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h index 96a58a96..f992b3ef 100644 --- a/od-win32/sysconfig.h +++ b/od-win32/sysconfig.h @@ -34,6 +34,7 @@ #define PARALLEL_DIRECT /* direct parallel port emulation */ #define SERIAL_PORT /* serial port emulation */ #define SCSIEMU /* uaescsi.device emulation */ +#define UAESERIAL /* uaeserial.device emulation */ #define FPUEMU /* FPU emulation */ #define CPUEMU_0 /* generic 680x0 emulation */ #define CPUEMU_5 /* 68000+prefetch emulation */ diff --git a/od-win32/win32.c b/od-win32/win32.c index 944228be..00e52da2 100644 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -2503,7 +2503,7 @@ static void getstartpaths(int start_data) } extern void test (void); -extern int screenshotmode, b0rken_ati_overlay, postscript_print_debugging, sound_debug; +extern int screenshotmode, b0rken_ati_overlay, postscript_print_debugging, sound_debug, log_uaeserial; extern int force_direct_catweasel, cpu_affinity; static int original_affinity; @@ -2580,6 +2580,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR if (!strcmp (arg, "-forcerdtsc")) no_rdtsc = -1; if (!strcmp (arg, "-norawinput")) no_rawinput = 1; if (!strcmp (arg, "-scsilog")) log_scsi = 1; + if (!strcmp (arg, "-seriallog")) log_uaeserial = 1; if (!strcmp (arg, "-nomultidisplay")) multi_display = 0; if (!strcmp (arg, "-legacypaths")) start_data = -1; if (!strcmp (arg, "-screenshotbmp")) screenshotmode = 0; diff --git a/od-win32/win32.h b/od-win32/win32.h index 10b03080..12d5bbe3 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,9 +15,9 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEBETA 2 +#define WINUAEBETA 3 #define WINUAEPUBLICBETA 1 -#define WINUAEDATE MAKEBD(2006, 12, 2) +#define WINUAEDATE MAKEBD(2006, 12, 6) #define IHF_WINDOWHIDDEN 6 #define NORMAL_WINDOW_STYLE (WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU ) diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index f32028f9..8938fd3d 100644 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -6873,29 +6873,31 @@ static void enable_for_portsdlg( HWND hDlg ) v = workprefs.input_selected_setting > 0 ? FALSE : TRUE; EnableWindow (GetDlgItem (hDlg, IDC_SWAP), v); #if !defined (SERIAL_PORT) - EnableWindow( GetDlgItem( hDlg, IDC_MIDIOUTLIST), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_MIDIINLIST), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_SHARED), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_SER_CTSRTS), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_SERIAL_DIRECT), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_SERIAL), FALSE ); + EnableWindow(GetDlgItem(hDlg, IDC_MIDIOUTLIST), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_MIDIINLIST), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_SHARED), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_SER_CTSRTS), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_SERIAL_DIRECT), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_SERIAL), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_UAESERIAL), FALSE); #else v = workprefs.use_serial ? TRUE : FALSE; - EnableWindow( GetDlgItem( hDlg, IDC_SHARED), v); - EnableWindow( GetDlgItem( hDlg, IDC_SER_CTSRTS), v); - EnableWindow( GetDlgItem( hDlg, IDC_SERIAL_DIRECT), v); + EnableWindow(GetDlgItem(hDlg, IDC_SHARED), v); + EnableWindow(GetDlgItem(hDlg, IDC_SER_CTSRTS), v); + EnableWindow(GetDlgItem(hDlg, IDC_SERIAL_DIRECT), v); + EnableWindow(GetDlgItem(hDlg, IDC_UAESERIAL), full_property_sheet); #endif #if !defined (PARALLEL_PORT) - EnableWindow( GetDlgItem( hDlg, IDC_PRINTERLIST), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_FLUSHPRINTER), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_PSPRINTER), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_PS_PARAMS), FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_PRINTER_AUTOFLUSH), FALSE ); + EnableWindow(GetDlgItem(hDlg, IDC_PRINTERLIST), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_FLUSHPRINTER), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_PSPRINTER), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_PS_PARAMS), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_PRINTER_AUTOFLUSH), FALSE); #else - EnableWindow( GetDlgItem( hDlg, IDC_FLUSHPRINTER), isprinteropen () ? TRUE : FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_PSPRINTER), full_property_sheet && ghostscript_available ? TRUE : FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_PSPRINTERDETECT), full_property_sheet ? TRUE : FALSE ); - EnableWindow( GetDlgItem( hDlg, IDC_PS_PARAMS), full_property_sheet && ghostscript_available ); + EnableWindow(GetDlgItem(hDlg, IDC_FLUSHPRINTER), isprinteropen () ? TRUE : FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_PSPRINTER), full_property_sheet && ghostscript_available ? TRUE : FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_PSPRINTERDETECT), full_property_sheet ? TRUE : FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_PS_PARAMS), full_property_sheet && ghostscript_available); #endif } @@ -7090,6 +7092,9 @@ static void values_from_portsdlg (HWND hDlg) strcpy(workprefs.sername, "none"); break; } + workprefs.uaeserial = 0; + if (IsDlgButtonChecked (hDlg, IDC_UAESERIAL)) + workprefs.uaeserial = 1; workprefs.serial_demand = 0; if (IsDlgButtonChecked (hDlg, IDC_SHARED)) workprefs.serial_demand = 1; @@ -7137,30 +7142,28 @@ static void values_to_portsdlg (HWND hDlg) result = 0; } } - SetDlgItemInt( hDlg, IDC_PRINTERAUTOFLUSH, workprefs.parallel_autoflush_time, FALSE ); - CheckDlgButton( hDlg, IDC_PSPRINTER, workprefs.parallel_postscript_emulation ); - CheckDlgButton( hDlg, IDC_PSPRINTERDETECT, workprefs.parallel_postscript_detection ); - SetDlgItemText (hDlg, IDC_PS_PARAMS, workprefs.ghostscript_parameters); + SetDlgItemInt(hDlg, IDC_PRINTERAUTOFLUSH, workprefs.parallel_autoflush_time, FALSE); + CheckDlgButton(hDlg, IDC_PSPRINTER, workprefs.parallel_postscript_emulation); + CheckDlgButton(hDlg, IDC_PSPRINTERDETECT, workprefs.parallel_postscript_detection); + SetDlgItemText(hDlg, IDC_PS_PARAMS, workprefs.ghostscript_parameters); - SendDlgItemMessage( hDlg, IDC_PRINTERLIST, CB_SETCURSEL, result, 0 ); - SendDlgItemMessage( hDlg, IDC_MIDIOUTLIST, CB_SETCURSEL, workprefs.win32_midioutdev + 2, 0 ); + SendDlgItemMessage(hDlg, IDC_PRINTERLIST, CB_SETCURSEL, result, 0); + SendDlgItemMessage(hDlg, IDC_MIDIOUTLIST, CB_SETCURSEL, workprefs.win32_midioutdev + 2, 0); if (!bNoMidiIn && workprefs.win32_midiindev >= 0) - SendDlgItemMessage( hDlg, IDC_MIDIINLIST, CB_SETCURSEL, workprefs.win32_midiindev, 0 ); + SendDlgItemMessage(hDlg, IDC_MIDIINLIST, CB_SETCURSEL, workprefs.win32_midiindev, 0); else - SendDlgItemMessage( hDlg, IDC_MIDIINLIST, CB_SETCURSEL, 0, 0 ); - EnableWindow( GetDlgItem( hDlg, IDC_MIDIINLIST ), workprefs.win32_midioutdev < -1 ? FALSE : TRUE); + SendDlgItemMessage(hDlg, IDC_MIDIINLIST, CB_SETCURSEL, 0, 0); + EnableWindow(GetDlgItem(hDlg, IDC_MIDIINLIST ), workprefs.win32_midioutdev < -1 ? FALSE : TRUE); - CheckDlgButton( hDlg, IDC_SHARED, workprefs.serial_demand ); - CheckDlgButton( hDlg, IDC_SER_CTSRTS, workprefs.serial_hwctsrts ); - CheckDlgButton( hDlg, IDC_SERIAL_DIRECT, workprefs.serial_direct ); + CheckDlgButton(hDlg, IDC_UAESERIAL, workprefs.uaeserial); + CheckDlgButton(hDlg, IDC_SHARED, workprefs.serial_demand); + CheckDlgButton(hDlg, IDC_SER_CTSRTS, workprefs.serial_hwctsrts); + CheckDlgButton(hDlg, IDC_SERIAL_DIRECT, workprefs.serial_direct); - if( strcasecmp( workprefs.sername, "none") == 0 ) - { + if(strcasecmp(workprefs.sername, "none") == 0) { SendDlgItemMessage (hDlg, IDC_SERIAL, CB_SETCURSEL, 0, 0L); workprefs.use_serial = 0; - } - else - { + } else { int t = (workprefs.sername[0] == '\0' ? 0 : workprefs.sername[3] - '0'); int i; LRESULT result = -1; @@ -7170,23 +7173,20 @@ static void values_to_portsdlg (HWND hDlg) break; } } - if( result < 0 ) - { + if(result < 0) { if (t > 0) { // Warn the user that their COM-port selection is not valid on this machine - char szMessage[ MAX_DPATH ]; - WIN32GUI_LoadUIString( IDS_INVALIDCOMPORT, szMessage, MAX_DPATH ); + char szMessage[MAX_DPATH]; + WIN32GUI_LoadUIString(IDS_INVALIDCOMPORT, szMessage, MAX_DPATH); pre_gui_message (szMessage); // Select "none" as the COM-port - SendDlgItemMessage( hDlg, IDC_SERIAL, CB_SETCURSEL, 0L, 0L ); + SendDlgItemMessage(hDlg, IDC_SERIAL, CB_SETCURSEL, 0L, 0L); } // Disable the chosen serial-port selection strcpy( workprefs.sername, "none" ); workprefs.use_serial = 0; - } - else - { + } else { workprefs.use_serial = 1; } } @@ -8440,7 +8440,7 @@ static LRESULT FAR PASCAL ToolTipWndProc (HWND hwnd, UINT message, WPARAM wParam PAINTSTRUCT ps; HBITMAP bm; BITMAP binfo; - HDC hdc, memdc; + HDC memdc; int w, h, i; for (i = 0; ToolTipHWNDS2[i].hwnd; i++) { @@ -8452,6 +8452,19 @@ static LRESULT FAR PASCAL ToolTipWndProc (HWND hwnd, UINT message, WPARAM wParam switch (message) { + case WM_WINDOWPOSCHANGED: + bm = LoadBitmap (hInst, MAKEINTRESOURCE (ToolTipHWNDS2[i].imageid)); + GetObject (bm, sizeof (binfo), &binfo); + w = binfo.bmWidth; + h = binfo.bmHeight; + GetWindowRect (hwnd, &r1); + GetCursorPos (&p1); + r1.right = r1.left + w; + r1.bottom = r1.top + h; + MoveWindow (hwnd, r1.left, r1.top, r1.right - r1.left, r1.bottom - r1.top, TRUE); + DeleteObject (bm); + return 0; + case WM_PAINT: bm = LoadBitmap (hInst, MAKEINTRESOURCE (ToolTipHWNDS2[i].imageid)); GetObject (bm, sizeof (binfo), &binfo); @@ -8461,18 +8474,16 @@ static LRESULT FAR PASCAL ToolTipWndProc (HWND hwnd, UINT message, WPARAM wParam GetCursorPos (&p1); r1.right = r1.left + w; r1.bottom = r1.top + h; + BeginPaint (hwnd, &ps); + memdc = CreateCompatibleDC (ps.hdc); + SelectObject (memdc, bm); ShowWindow (hwnd, SW_SHOWNA); MoveWindow (hwnd, r1.left, r1.top, r1.right - r1.left, r1.bottom - r1.top, TRUE); - hdc = GetDC (hwnd); - memdc = CreateCompatibleDC (hdc); - SelectObject (memdc, bm); - BeginPaint (hwnd, &ps); SetBkMode (ps.hdc, TRANSPARENT); - BitBlt (hdc, 0, 0, w, h, memdc, 0, 0, SRCCOPY); + BitBlt (ps.hdc, 0, 0, w, h, memdc, 0, 0, SRCCOPY); DeleteObject (bm); EndPaint (hwnd, &ps); DeleteDC (memdc); - ReleaseDC (hwnd, hdc); return FALSE; case WM_PRINT: PostMessage (hwnd, WM_PAINT, 0, 0); diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 9aec0d1f..3ddf8ac2 100644 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -1522,6 +1522,10 @@ RelativePath="..\..\uaelib.c" > + + diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 6cec7f81..332d12cf 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,22 @@ +Beta 3: + +- uaeserial.device implemented, serial.device-like device that maps + unit numbers directly to host's COMx-ports (unit 1 = COM1, 2 = COM2 + etc..) Supports most serial.device features (No xOn/xOff support) + Bugs possible. Tested using Term and Nokia E70 via bluetooth serial + connection :) +- page down is now properly configurable in input-panel (previously + was internally always mapped to freeze button) +- GUI AHI sound volume adjustment support (previously was Paula only) +- disk emulation event handler error fixed, broke most custom loaders + (bug introduced in b1) +- X-Arcade GUI tooltip compatibility update, in some cases only tiny + piece of upper left corner was visible. (Vista only?) +- more blitter tweaks, try to be compatible with broken programs that + write to blitter registers while previous blit has not yet finished. +- some DirectSound tweaks + Beta 2: - fixed possible crash when input recording stops (introduced in b1) diff --git a/scsiemul.c b/scsiemul.c index 9b7f4569..38e59d15 100644 --- a/scsiemul.c +++ b/scsiemul.c @@ -648,7 +648,7 @@ static void *dev_thread (void *devs) uae_ReplyMsg (request); } else { if (log_scsi) - write_log ("async request %08.8X\n", request); + write_log ("%s:%d async request %08.8X\n", getdevname(0), dev->unitnum, request); } uae_sem_post (&change_sem); } diff --git a/uaeserial.c b/uaeserial.c index 33ecf48f..245f9ffc 100644 --- a/uaeserial.c +++ b/uaeserial.c @@ -10,26 +10,22 @@ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "uae.h" #include "threaddep/thread.h" #include "options.h" #include "memory.h" #include "custom.h" -#include "events.h" #include "newcpu.h" +#include "traps.h" #include "autoconf.h" #include "execlib.h" #include "native2amiga.h" +#include "uaeserial.h" +#include "serial.h" -#define MAX_ASYNC_REQUESTS 20 #define MAX_TOTAL_DEVICES 8 -#define MAX_OPEN_DEVICES 20 -#define ASYNC_REQUEST_NONE 0 -#define ASYNC_REQUEST_TEMP 1 - -static int log_serial = 1; +int log_uaeserial = 0; #define CMD_INVALID 0 #define CMD_RESET 1 @@ -118,35 +114,42 @@ static int log_serial = 1; */ +struct asyncreq { + struct asyncreq *next; + uaecptr request; + int ready; +}; + struct devstruct { int unit; - char *name; int uniq; int exclusive; - volatile uaecptr d_request[MAX_ASYNC_REQUESTS]; - volatile int d_request_type[MAX_ASYNC_REQUESTS]; - volatile uae_u32 d_request_data[MAX_ASYNC_REQUESTS]; + + struct asyncreq *ar; smp_comm_pipe requests; uae_thread_id tid; int thread_running; uae_sem_t sync_sem; + + int brk; + void *sysdata; }; static int uniq; static struct devstruct devst[MAX_TOTAL_DEVICES]; -static uae_sem_t change_sem; +static uae_sem_t change_sem, async_sem; -static char *getdevname (int type) +static char *getdevname (void) { return "uaeserial.device"; } static void io_log (char *msg, uaecptr request) { - if (log_serial) + if (log_uaeserial) write_log ("%s: %08X %d %08.8X %d %d io_actual=%d io_error=%d\n", msg, request,get_word(request + 28),get_long(request + 40),get_long(request + 36),get_long(request + 44), get_long (request + 32), get_byte (request + 31)); @@ -181,33 +184,66 @@ static int start_thread (struct devstruct *dev) static void dev_close_3 (struct devstruct *dev) { dev->unit = -1; - xfree(dev->name); + uaeser_close (dev->sysdata); + xfree (dev->sysdata); write_comm_pipe_u32 (&dev->requests, 0, 1); } -static uae_u32 dev_close_2 (void) +static uae_u32 REGPARAM2 dev_close (TrapContext *context) { - uae_u32 request = m68k_areg (regs, 1); + uae_u32 request = m68k_areg (&context->regs, 1); struct devstruct *dev; - dev = getdevstruct (pdev->uniq); - if (log_serial) - write_log ("%s:%d close, req=%08.8X\n", dev->name, dev->unit, request); + dev = getdevstruct (get_long(request + 24)); + if (log_uaeserial) + write_log ("%s:%d close, req=%x\n", getdevname(), dev->unit, request); if (!dev) return 0; dev_close_3 (dev); put_long (request + 24, 0); - put_word (m68k_areg(regs, 6) + 32, get_word (m68k_areg(regs, 6) + 32) - 1); + put_word (m68k_areg(&context->regs, 6) + 32, get_word (m68k_areg(&context->regs, 6) + 32) - 1); return 0; } -static uae_u32 dev_close (void) +static int setparams(struct devstruct *dev, uaecptr req) { - return dev_close_2 (); -} -static uae_u32 diskdev_close (void) -{ - return dev_close_2 (); + int v; + int rbuffer, baud, rbits, wbits, sbits, rtscts, parity; + + rbuffer = get_long (req + io_RBufLen); + v = get_long (req + io_ExtFlags); + if (v) { + write_log ("UAESER: io_ExtFlags=%d, not supported\n", v); + return 5; + } + baud = get_long (req + io_Baud); + dev->brk = get_long (req + io_BrkTime); + v = get_byte (req + io_SerFlags); + if (v & SERF_EOFMODE) { + write_log ("UAESER: SERF_EOFMODE not supported\n"); + return 5; + } + if (!(v & SERF_XDISABLED)) { + write_log ("UAESER: xOn/xOff not supported\n"); + return 5; + } + rtscts = (v & SERF_7WIRE) ? 1 : 0; + parity = 0; + if (v & SERF_PARTY_ON) + parity = (v & SERF_PARTY_ODD) ? 1 : 2; + rbits = get_byte (req + io_ReadLen); + wbits = get_byte (req + io_WriteLen); + sbits = get_byte (req + io_StopBits); + if ((rbits != 7 && rbits != 8) || (wbits != 7 && wbits != 8) || (sbits != 1 && sbits != 2) || rbits != wbits) { + write_log ("UAESER: Read=%d, Write=%d, Stop=%d, not supported\n", rbits, wbits, sbits); + return 5; + } + write_log ("UAESER: BAUD=%d BUF=%d BITS=%d+%d RTSCTS=%d PARITY=%d\n", + baud, rbuffer, rbits, sbits, rtscts, parity); + v = uaeser_setparams (dev->sysdata, baud, rbuffer, rbits, sbits, rtscts, parity); + if (!v) + write_log("->failed\n"); + return v; } static int openfail (uaecptr ioreq, int error) @@ -217,18 +253,14 @@ static int openfail (uaecptr ioreq, int error) return (uae_u32)-1; } -static uae_u32 dev_open_2 (int type) +static uae_u32 REGPARAM2 dev_open (TrapContext *context) { - uaecptr ioreq = m68k_areg(regs, 1); - uae_u32 unit = m68k_dreg (regs, 0); - uae_u32 flags = m68k_dreg (regs, 1); + uaecptr ioreq = m68k_areg (&context->regs, 1); + uae_u32 unit = m68k_dreg (&context->regs, 0); + uae_u32 flags = m68k_dreg (&context->regs, 1); struct devstruct *dev; int i; - char devname[256]; - if (log_serial) - write_log ("opening %s:%d ioreq=%08.8X\n", getdevname (type), unit, ioreq); - sprintf(devname,"COM%d", unit); for (i = 0; i < MAX_TOTAL_DEVICES; i++) { if (devst[i].unit == unit && devst[i].exclusive) return openfail (ioreq, -6); /* busy */ @@ -240,106 +272,203 @@ static uae_u32 dev_open_2 (int type) dev = &devst[i]; if (i == MAX_TOTAL_DEVICES) return openfail (ioreq, 32); /* badunitnum */ + dev->sysdata = xcalloc (uaeser_getdatalenght(), 1); + if (!uaeser_open (dev->sysdata, dev, unit)) { + xfree (dev->sysdata); + return openfail (ioreq, 32); /* badunitnum */ + } dev->unit = unit; - dev->name = my_strdup (devname); dev->uniq = ++uniq; dev->exclusive = (get_word(ioreq + io_SerFlags) & SERF_SHARED) ? 0 : 1; - put_long (ioreq + 24, i); + put_long (ioreq + 24, dev->uniq); + setparams (dev, ioreq); + if (log_uaeserial) + write_log ("%s:%d open ioreq=%08.8X\n", getdevname(), unit, ioreq); start_thread (dev); - put_word (m68k_areg(regs, 6) + 32, get_word (m68k_areg(regs, 6) + 32) + 1); + put_word (m68k_areg(&context->regs, 6) + 32, get_word (m68k_areg(&context->regs, 6) + 32) + 1); put_byte (ioreq + 31, 0); put_byte (ioreq + 8, 7); return 0; } -static uae_u32 dev_open (void) -{ - return dev_open_2 (0); -} - -static uae_u32 dev_expunge (void) +static uae_u32 REGPARAM2 dev_expunge (TrapContext *context) { return 0; } -static int is_async_request (struct devstruct *dev, uaecptr request) +static struct asyncreq *get_async_request (struct devstruct *dev, uaecptr request, int ready) { - int i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request) - return 1; - i++; + struct asyncreq *ar; + int ret = 0; + + uae_sem_wait (&async_sem); + ar = dev->ar; + while (ar) { + if (ar->request == request) { + if (ready) + ar->ready = 1; + break; + } + ar = ar->next; } - return 0; + uae_sem_post (&async_sem); + return ar; } -static int add_async_request (struct devstruct *dev, uaecptr request, int type, uae_u32 data) +static int add_async_request (struct devstruct *dev, uaecptr request) { - int i; + struct asyncreq *ar, *ar2; - if (log_serial) - write_log ("async request %p (%d) added\n", request, type); - i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request) { - dev->d_request_type[i] = type; - dev->d_request_data[i] = data; - return 0; - } - i++; - } - i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == 0) { - dev->d_request[i] = request; - dev->d_request_type[i] = type; - dev->d_request_data[i] = data; - return 0; - } - i++; + if (log_uaeserial) + write_log ("%s:%d async request %x added\n", getdevname(), dev->unit, request); + + uae_sem_wait (&async_sem); + ar = xcalloc (sizeof (struct asyncreq), 1); + ar->request = request; + if (!dev->ar) { + dev->ar = ar; + } else { + ar2 = dev->ar; + while (ar2->next) + ar2 = ar2->next; + ar2->next = ar; } - return -1; + uae_sem_post (&async_sem); + return 1; } static int release_async_request (struct devstruct *dev, uaecptr request) { - int i = 0; - - if (log_serial) - write_log ("async request %p removed\n", request); - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request) { - int type = dev->d_request_type[i]; - dev->d_request[i] = 0; - dev->d_request_data[i] = 0; - dev->d_request_type[i] = 0; - return type; + 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 ("%s:%d async request %x removed\n", getdevname(), dev->unit, request); + return 1; } - i++; + prevar = ar; + ar = ar->next; } - return -1; + uae_sem_post (&async_sem); + write_log ("%s:%d async request %x not found for removal!\n", getdevname(), dev->unit, request); + return 0; } -static void abort_async (struct devstruct *dev, uaecptr request, int errcode, int type) +static void abort_async (struct devstruct *dev, uaecptr request) { - int i; - i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request && dev->d_request_type[i] == ASYNC_REQUEST_TEMP) { - /* ASYNC_REQUEST_TEMP = request is processing */ - sleep_millis (10); - i = 0; - continue; + struct asyncreq *ar = get_async_request (dev, request, 1); + if (!ar) { + write_log ("%s:d: abort sync but no request %x found!\n", getdevname(), dev->unit, request); + return; + } + if (log_uaeserial) + write_log ("%s:%d asyncronous request=%08.8X aborted\n", getdevname(), dev->unit, request); + put_byte (request + 31, -2); + put_byte (request + 30, get_byte (request + 30) | 0x20); + write_comm_pipe_u32 (&dev->requests, request, 1); +} + +static uae_u8 *memmap(uae_u32 addr, uae_u32 len) +{ + addrbank *bank_data = &get_mem_bank (addr); + if (!bank_data->check (addr, len)) + return NULL; + return bank_data->xlateaddr (addr); +} + +void uaeser_signal (struct devstruct *dev, int sigmask) +{ + struct asyncreq *ar; + int i = 0; + + uae_sem_wait (&async_sem); + ar = dev->ar; + while (ar) { + if (!ar->ready) { + uaecptr request = ar->request; + uae_u32 io_data = get_long (request + 40); // 0x28 + uae_u32 io_length = get_long (request + 36); // 0x24 + int command = get_word (request + 28); + uae_u32 io_error = 0, io_actual = 0; + uae_u8 *addr; + int io_done = 0; + int v; + + switch (command) + { + case CMD_READ: + if (sigmask & 1) { + if (uaeser_query (dev->sysdata, NULL, &v)) { + if (v >= io_length) { + io_error = -5; + addr = memmap(io_data, io_length); + if (addr && uaeser_read (dev->sysdata, addr, io_length)) + io_error = 0; + io_actual = io_length; + io_done = 1; + } + } + } + break; + case CMD_WRITE: + if (sigmask & 2) { + io_error = -5; + 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("%s:%d incorrect async request %x (cmd=%d) signaled?!", getdevname(), dev->unit, request, command); + break; + } + + if (io_done) { + if (log_uaeserial) + write_log ("%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); + } + } - i++; + ar = ar->next; } - i = release_async_request (dev, request); - if (i >= 0 && log_serial) - write_log ("asyncronous request=%08.8X aborted, error=%d\n", request, errcode); + uae_sem_post (&async_sem); } -static int dev_do_io (struct devstruct *dev, uaecptr request) +static void cmd_reset(struct devstruct *dev, uaecptr req) +{ + while (dev->ar) + abort_async (dev, dev->ar->request); + put_long (req + io_RBufLen, 8192); + put_long (req + io_ExtFlags, 0); + put_long (req + io_Baud, 57600); + put_long (req + io_BrkTime, 250000); + put_long (req + io_TermArray0, 0); + put_long (req + io_TermArray1, 0); + put_long (req + io_ReadLen, 8); + put_long (req + io_WriteLen, 8); + put_long (req + io_StopBits, 1); + put_long (req + io_SerFlags, SERF_XDISABLED); + put_word (req + io_Status, 0); +} + +static int dev_do_io (struct devstruct *dev, uaecptr request, int quick) { uae_u32 command; uae_u32 io_data = get_long (request + 40); // 0x28 @@ -347,29 +476,43 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) uae_u32 io_actual = get_long (request + 32); // 0x20 uae_u32 io_offset = get_long (request + 44); // 0x2c uae_u32 io_error = 0; + uae_u16 io_status; int async = 0; - struct devstruct *dev = getdevstruct (get_long(request + 24)); if (!dev) return 0; - command = get_word (request+28); + command = get_word (request + 28); + io_log ("dev_io_START",request); switch (command) { case SDCMD_QUERY: + if (uaeser_query (dev->sysdata, &io_status, &io_actual)) + put_byte (request + io_Status, io_status); + else + io_error = -5; break; case SDCMD_SETPARAMS: + io_error = setparams(dev, request); break; case CMD_WRITE: + async = 1; break; case CMD_READ: + async = 1; + break; + case SDCMD_BREAK: + uaeser_break (dev->sysdata, dev->brk); break; - case SDCMD_BREAK; - case CMD_FLUSH; - case CMD_START: - case CMD_STOP: case CMD_CLEAR: + uaeser_clearbuffers(dev->sysdata); + break; case CMD_RESET: + cmd_reset(dev, request); + break; + case CMD_FLUSH: + case CMD_START: + case CMD_STOP: break; default: io_error = -3; @@ -377,47 +520,34 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) } put_long (request + 32, io_actual); put_byte (request + 31, io_error); - io_log ("dev_io",request); + io_log ("dev_io_END",request); return async; } -static int dev_can_quick (uae_u32 command) -{ -/* - switch (command) - { - return 1; - } -*/ - return 0; -} - static int dev_canquick (struct devstruct *dev, uaecptr request) { - uae_u32 command = get_word (request + 28); - return dev_can_quick (command); + return 0; } -static uae_u32 dev_beginio (void) +static uae_u32 REGPARAM2 dev_beginio (TrapContext *context) { - uae_u32 request = m68k_areg(regs, 1); + uae_u32 request = m68k_areg (&context->regs, 1); uae_u8 flags = get_byte (request + 30); int command = get_word (request + 28); struct devstruct *dev = getdevstruct (get_long(request + 24)); - put_byte (request+8, NT_MESSAGE); + put_byte (request + 8, NT_MESSAGE); if (!dev) { put_byte (request + 31, 32); return get_byte (request + 31); } - put_byte (request+31, 0); + put_byte (request + 31, 0); if ((flags & 1) && dev_canquick (dev, request)) { - if (dev_do_io (dev, request)) - write_log ("device %s:%d command %d bug with IO_QUICK\n", dev->name, dev->unit, command); + if (dev_do_io (dev, request, 1)) + write_log ("device %s:%d command %d bug with IO_QUICK\n", getdevname(), dev->unit, 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); + put_byte (request + 30, get_byte (request + 30) & ~1); write_comm_pipe_u32 (&dev->requests, request, 1); return 0; } @@ -427,7 +557,7 @@ static void *dev_thread (void *devs) { struct devstruct *dev = devs; - set_thread_priority (2); + uae_set_thread_priority (2); dev->thread_running = 1; uae_sem_post (&dev->sync_sem); for (;;) { @@ -438,77 +568,75 @@ static void *dev_thread (void *devs) uae_sem_post (&dev->sync_sem); uae_sem_post (&change_sem); return 0; - } else if (dev_do_io (dev, request) == 0) { - put_byte (request + 30, get_byte (request + 30) & ~1); + } 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 { - if (log_serial) - write_log ("async request %08.8X\n", request); + add_async_request (dev, request); + uaeser_trigger (dev->sysdata); } uae_sem_post (&change_sem); } return 0; } -static uae_u32 dev_init_2 (int type) +static uae_u32 REGPARAM2 dev_init (TrapContext *context) { - uae_u32 base = m68k_dreg (regs,0); - if (log_serial) - write_log ("%s init\n", getdevname (type)); + uae_u32 base = m68k_dreg (&context->regs, 0); + if (log_uaeserial) + write_log ("%s init\n", getdevname ()); return base; } -static uae_u32 dev_init (void) +static uae_u32 REGPARAM2 dev_abortio (TrapContext *context) { - return dev_init_2 (0); -} - -static uae_u32 dev_abortio (void) -{ - uae_u32 request = m68k_areg(regs, 1); + uae_u32 request = m68k_areg (&context->regs, 1); struct devstruct *dev = getdevstruct (get_long(request + 24)); if (!dev) { put_byte (request + 31, 32); return get_byte (request + 31); } - put_byte (request + 31, -2); - if (log_serial) - write_log ("abortio %s:%d, request=%08.8X\n", dev->name, dev->unit, request); - abort_async (dev, request, -2, 0); + abort_async (dev, request); return 0; } static void dev_reset (void) { - int i, j; - struct uaeserial_info *uaedev; + int i; struct devstruct *dev; for (i = 0; i < MAX_TOTAL_DEVICES; i++) { dev = &devst[i]; - if (dev->opencnt > 0) { - for (j = 0; j < MAX_ASYNC_REQUESTS; j++) { - uaecptr request; - if (request = dev->d_request[i]) - abort_async (dev, request, 0, 0); - } + if (dev->unit >= 0) { + while (dev->ar) + abort_async (dev, dev->ar->request); } - free (dev->name); memset (dev, 0, sizeof (struct devstruct)); dev->unit = -1; } } -static uaecptr ROM_serialdev_resname = 0, - ROM_serialdev_resid = 0, - ROM_serialdev_init = 0; +static uaecptr ROM_uaeserialdev_resname = 0, + ROM_uaeserialdev_resid = 0, + ROM_uaeserialdev_init = 0; -uaecptr serialdev_startup (uaecptr resaddr) +uaecptr uaeserialdev_startup (uaecptr resaddr) { + int i; + struct devstruct *dev; + if (!currprefs.uaeserial) return resaddr; + if (log_uaeserial) + write_log ("uaeserialdev_startup(0x%x)\n", resaddr); + for (i = 0; i < MAX_TOTAL_DEVICES; i++) { + dev = &devst[i]; + dev->unit = -1; + dev->brk = 250000; + } /* Build a struct Resident. This will set up and initialize * the serial.device */ put_word(resaddr + 0x0, 0x4AFC); @@ -516,15 +644,15 @@ uaecptr serialdev_startup (uaecptr resaddr) put_long(resaddr + 0x6, resaddr + 0x1A); /* Continue scan here */ put_word(resaddr + 0xA, 0x8101); /* RTF_AUTOINIT|RTF_COLDSTART; Version 1 */ put_word(resaddr + 0xC, 0x0305); /* NT_DEVICE; pri 05 */ - put_long(resaddr + 0xE, ROM_serialdev_resname); - put_long(resaddr + 0x12, ROM_serialdev_resid); - put_long(resaddr + 0x16, ROM_serialdev_init); /* calls scsidev_init */ + put_long(resaddr + 0xE, ROM_uaeserialdev_resname); + put_long(resaddr + 0x12, ROM_uaeserialdev_resid); + put_long(resaddr + 0x16, ROM_uaeserialdev_init); resaddr += 0x1A; return resaddr; } -void serialdev_install (void) +void uaeserialdev_install (void) { uae_u32 functable, datatable; uae_u32 initcode, openfunc, closefunc, expungefunc; @@ -533,8 +661,8 @@ void serialdev_install (void) if (!currprefs.uaeserial) return; - ROM_serialdev_resname = ds ("uaeserial.device"); - ROM_serialdev_resid = ds ("UAE serial.device 0.2"); + ROM_uaeserialdev_resname = ds ("uaeserial.device"); + ROM_uaeserialdev_resid = ds ("UAE serial.device 0.1"); /* initcode */ initcode = here (); @@ -554,8 +682,7 @@ void serialdev_install (void) /* BeginIO */ beginiofunc = here (); - calltrap (deftrap (dev_beginio)); - dw (RTS); + calltrap (deftrap (dev_beginio)); dw (RTS); /* AbortIO */ abortiofunc = here (); @@ -578,7 +705,7 @@ void serialdev_install (void) dw (0x0300); /* NT_DEVICE */ dw (0xC000); /* INITLONG */ dw (0x000A); /* LN_NAME */ - dl (ROM_serialdev_resname); + dl (ROM_uaeserialdev_resname); dw (0xE000); /* INITBYTE */ dw (0x000E); /* LIB_FLAGS */ dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */ @@ -590,23 +717,25 @@ void serialdev_install (void) dw (0x0000); /* end of table already ??? */ dw (0xC000); /* INITLONG */ dw (0x0018); /* LIB_IDSTRING */ - dl (ROM_serialdev_resid); + dl (ROM_uaeserialdev_resid); dw (0x0000); /* end of table */ - ROM_serialdev_init = here (); + ROM_uaeserialdev_init = here (); dl (0x00000100); /* size of device base */ dl (functable); dl (datatable); dl (initcode); } -void serialdev_start_threads (void) +void uaeserialdev_start_threads (void) { + uae_sem_init (&change_sem, 0, 1); + uae_sem_init (&async_sem, 0, 1); } -void serialdev_reset (void) +void uaeserialdev_reset (void) { if (!currprefs.uaeserial) return; dev_reset (); -} \ No newline at end of file +}