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++) {
{
if (bltstate == BLT_done)
return;
- if (bltcon) {
- if (bltstate != BLT_work)
- blit_bltset (bltcon);
- }
+ if (bltcon)
+ blit_bltset (bltcon);
blit_modset ();
}
blit_bltset (1|2);
blit_modset ();
+ ddat1use = ddat2use = 0;
if (blitline) {
blitsing = bltcon1 & 0x2;
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);
|| 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)
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;
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;
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;
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);
}
}
#include "fsusage.h"
#include "native2amiga.h"
#include "scsidev.h"
+#include "uaeserial.h"
#include "fsdb.h"
#include "zfile.h"
#include "gui.h"
* 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) {
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*);
--- /dev/null
+ /*
+ * 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
+};
#include "uaeexe.h"
#include "native2amiga.h"
#include "scsidev.h"
+#include "uaeserial.h"
#include "akiko.h"
#include "savestate.h"
#include "filesys.h"
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;
scsidev_reset ();
scsidev_start_threads ();
#endif
+#ifdef UAESERIAL
+ uaeserialdev_reset ();
+ uaeserialdev_start_threads ();
+#endif
#if defined (PARALLEL_PORT)
initparallel ();
#endif
#ifdef SCSIEMU
scsidev_install ();
#endif
+#ifdef UAESERIAL
+ uaeserialdev_install ();
+#endif
#ifdef AUTOCONFIG
/* Install resident module to get 8MB chipmem, if requested */
rtarea_setup ();
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;
}
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)) {
// { 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 },
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 ())
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;
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;
* 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;
}
/*
* 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;
}
/*
* 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;
* 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;
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;
* 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;
}
/*
* 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;
}
/*
{
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] = {
* 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;
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)
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);
}
}
}
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
*
* 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<MIDI_INBUFFERS;i++)
- {
- midiin[i].lpData = inbuffer[i];
- midiin[i].dwBufferLength = INBUFFLEN-1;
- midiin[i].dwBytesRecorded = INBUFFLEN-1;
- midiin[i].dwUser = 0;
- midiin[i].dwFlags = 0;
- result=midiInPrepareHeader(inHandle,&midiin[i], sizeof(MIDIHDR));
- result=midiInAddBuffer(inHandle,&midiin[i],sizeof(MIDIHDR));
- }
- }
+ } else {
+ for (i = 0;i < MIDI_INBUFFERS; i++) {
+ midiin[i].lpData = inbuffer[i];
+ midiin[i].dwBufferLength = INBUFFLEN - 1;
+ midiin[i].dwBytesRecorded = INBUFFLEN - 1;
+ midiin[i].dwUser = 0;
+ midiin[i].dwFlags = 0;
+ result=midiInPrepareHeader(inHandle, &midiin[i], sizeof(MIDIHDR));
+ result=midiInAddBuffer(inHandle, &midiin[i], sizeof(MIDIHDR));
+ }
}
- midi_ready = TRUE;
+ }
+ midi_ready = TRUE;
result = 1;
serdev = 1;
- }
- else
- {
- midiOutClose( outHandle );
- if( midi_in_ready )
- {
- midiInClose( inHandle );
- midi_in_ready = FALSE;
+ } else {
+ midiOutClose(outHandle);
+ if(midi_in_ready) {
+ midiInClose(inHandle);
+ midi_in_ready = FALSE;
}
result = 0;
DeleteCriticalSection(&cs_proc);
* 1999.08.02 1.0 Brian King - Creation
*
*/
-void Midi_Close( void )
+void Midi_Close(void)
{
int i;
- if( midi_ready )
- {
+ if(midi_ready) {
midiOutReset(outHandle);
- for( i = 0; i < MIDI_BUFFERS; i++ )
- {
- while( MIDIERR_STILLPLAYING == midiOutUnprepareHeader( outHandle, &midiout[i], sizeof(MIDIHDR) ) )
- {
- Sleep(100);
+ for(i = 0; i < MIDI_BUFFERS; i++) {
+ while(MIDIERR_STILLPLAYING == midiOutUnprepareHeader(outHandle, &midiout[i], sizeof(MIDIHDR))) {
+ Sleep(10);
}
}
- MidiOut_Free();
- midiOutClose( outHandle );
-
- if( midi_in_ready )
- {
-
-
- //while( MIDIERR_STILLPLAYING == midiInUnprepareHeader( inHandle, &midiin, sizeof(MIDIHDR)) )
- exitin=1;//for safeness sure no callback come now
- midiInReset(inHandle);
- for (i=0;i<MIDI_INBUFFERS;i++)
- {
- midiInUnprepareHeader( inHandle,&midiin[i], sizeof(MIDIHDR));
- }
+ MidiOut_Free();
+ midiOutClose(outHandle);
+
+ if(midi_in_ready) {
+ exitin = 1; //for safeness sure no callback come now
+ midiInReset(inHandle);
+ for (i = 0; i < MIDI_INBUFFERS; i++) {
+ midiInUnprepareHeader(inHandle, &midiin[i], sizeof(MIDIHDR));
+ }
MidiIn_Free();
- midiInClose( inHandle );
+ midiInClose(inHandle);
midi_in_ready = FALSE;
- exitin = 0;
+ exitin = 0;
}
midi_ready = FALSE;
- {
- //Bernd Roesch:
- //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
- extern uae_u16 serper;
- serper = 0x30;
- }
- write_log( "MIDI: closed.\n" );
+ write_log("MIDI: closed.\n");
DeleteCriticalSection(&cs_proc);
}
}
#include "parallel.h"
#include "zfile.h"
#include "threaddep/thread.h"
+#include "serial.h"
#include <Ghostscript/errors.h>
#include <Ghostscript/iapi.h>
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;
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)
CommTimeOuts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts (hCom, &CommTimeOuts);
+ dcb.DCBlength = sizeof (DCB);
GetCommState (hCom, &dcb);
dcb.BaudRate = 9600;
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;
}
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)) {
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) {
}
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)
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");
}
}
#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
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
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
}
extern HWND hMainWnd;
-
+extern void setvolume_ahi(LONG);
static void setvolume (void)
{
HRESULT hr;
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)
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)
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)) {
#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 */
}
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;
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;
#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 )
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
}
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;
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;
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;
}
}
PAINTSTRUCT ps;
HBITMAP bm;
BITMAP binfo;
- HDC hdc, memdc;
+ HDC memdc;
int w, h, i;
for (i = 0; ToolTipHWNDS2[i].hwnd; i++) {
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);
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);
RelativePath="..\..\uaelib.c"
>
</File>
+ <File
+ RelativePath="..\..\uaeserial.c"
+ >
+ </File>
<File
RelativePath="..\..\unzip.c"
>
+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)
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);
}
#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
*/
+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));
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)
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 */
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
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;
}
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;
}
{
struct devstruct *dev = devs;
- set_thread_priority (2);
+ uae_set_thread_priority (2);
dev->thread_running = 1;
uae_sem_post (&dev->sync_sem);
for (;;) {
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);
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;
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 ();
/* BeginIO */
beginiofunc = here ();
- calltrap (deftrap (dev_beginio));
- dw (RTS);
+ calltrap (deftrap (dev_beginio)); dw (RTS);
/* AbortIO */
abortiofunc = here ();
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 */
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
+}