Пример #1
0
/*********************************************************************
  Pass a note, in half steps relative to 400 Hz.  The 12 step scale
is an exponential thing.  The speaker control is at port 0x61.
Setting the lowest two bits enables timer 2 of the 8253/8254 timer
and turns on the speaker.
*********************************************************************/
void playnote(NOTE note)
{
	_outp(0x61, _inp(0x61) | 0x03);			// start speaker going
	setfreq((int)(400 * pow(2, note.pitch / 12.0)));
	Sleep(note.duration);
	_outp(0x61, _inp(0x61) & ~0x03);		// stop that racket!
}
Пример #2
0
static int check_comport ()
{
	_outp(COM_LCR, 0x0C);
	if((BYTE)_inp(COM_LCR) != 0x0C) return (-1);
	_outp(COM_LCR, 0x03);
	if((BYTE)_inp(COM_LCR) != 0x03) return (-1);
	return (0);
}
Пример #3
0
static int check_lptport ()
{
	_outp(LPT_CTL, 0);
	_outp(LPT_DAT, 0x08);
	if((BYTE)_inp(LPT_DAT) != 0x08) return (-1);
	_outp(LPT_DAT, 0x40);
	if((BYTE)_inp(LPT_DAT) != 0x40) return (-1);
	return (0);
}
Пример #4
0
static void WriteOPLRegister(BYTE opl_register, BYTE value)
{
#if defined(_M_IX86)
   int i;

   _outp(0x388, opl_register);
   for (i = 0; i < 6; i++)
      _inp(0x388);

   _outp(0x389, value);

   for (i = 0; i < 35; i++)
      _inp(0x388);
#endif
}
Пример #5
0
void parOut() 
{
	int locresult;

	unsigned char cat = 0;

	if (chip_sel_A) cat += 1;
	if (chip_sel_B) cat += 2;
	if (board_sel_A) cat += 4;
	if (board_sel_B) cat += 8;
	if (board_enable) cat += 64;

	_outp( PPORT, cat );
  
	cat=0;

	if (clk == 0)  
		cat += 1;
	if (d_in == 0)  
		cat += 2;
	_outp( PPORT+2, cat );


	locresult=_inp(PPORT + 1);
	d_out=0;
	if(locresult & 8)
		d_out = 1;


// delay to avoid going over 400k clk rate
//usleep(1);  // may be needed for computers over 266 MHZ, adjust delay as necessary

}
Пример #6
0
void mono_init()
{
	int i;

	OSVERSIONINFO ver;
	
	ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&ver);
	if ( ver.dwPlatformId == VER_PLATFORM_WIN32_NT )	{
		mono_found = 0;
		return;
	}

	_outp( 0x3b4, 0x0f );
	_outp( 0x3b4+1, 0x55 );

	if ( _inp( 0x3b4+1 ) == 0x55 )	{
		mono_found = 1;
		_outp( 0x3b4+1, 0 );
	} else {
		mono_found = 0;
		return;
	}


	for (i=0; i<80*25; i++ )	{
		mono_ram[i*2+0] = ' ';
		mono_ram[i*2+1] = 0x07;
	}
	mono_flush();
	mono_x = mono_y = 0;
}
Пример #7
0
short _stdcall Inp32(short PortAddress)
{
	BYTE retval;
	switch(sysver)
	{

	case 1:
	retval = _inp(PortAddress);
	return retval;
	break;
	case 2:
		unsigned int error;
		DWORD BytesReturned;
		unsigned char Buffer[3];
		unsigned short * pBuffer;
		pBuffer = (unsigned short *)&Buffer;
		*pBuffer = LOWORD(PortAddress);
		Buffer[2] = 0;
		error = DeviceIoControl(hdriver,
                            IOCTL_READ_PORT_UCHAR,
                            &Buffer,
                            2,
                            &Buffer,
                            1,
                            &BytesReturned,
                            NULL);

		return((int)Buffer[0]);

	break;
	}
return 0;
}
Пример #8
0
int main(int argc, char* argv[])
{
short data;

if(argc<2)
{
printf("Usage\n\n");
printf("partest1.exe ,,\n\n\n");
return 0;
}

if(!strcmp(argv[1],"read"))
{
data = _inp(atoi(argv[2])); 
printf("Data read from parallel port is  ");
printf("%d\n\n\n\n",data);
}

if(!strcmp(argv[1],"write"))
{
_outp(atoi(argv[2]),atoi(argv[3])); 
printf("Data written to parallel port is  ");
printf("%s\n\n\n\n\n",argv[3]);
}
return 0;
}
Пример #9
0
static BYTE hardsid_inb(unsigned int addrint)
{
    WORD addr = (WORD)addrint;
    DWORD tmp;
    BYTE retval = 0;

    /* make sure the above conversion did not loose any details */
    assert(addr == addrint);

    if (hardsid_use_lib) {
        if (hardsid_use_winio_dll) {
            winio_inp32fp(addr, &tmp, 1);
            retval = (BYTE)tmp;
        } else {
            retval = (BYTE)inpout_inp32fp(addr);
        }
    } else {
#ifdef  _M_IX86
#ifdef WATCOM_COMPILE
        retval = inp(addr);
#else
        retval = _inp(addr);
#endif
#endif
    }
    return retval;
}
Пример #10
0
unsigned ftAnalog (unsigned short port, int nTrigger) {
  unsigned result = 0;
#ifdef _WIN32
  unsigned short status = port+1;
  int enabled = ftDisable && _disable();
#endif
#ifdef SC12
  unsigned short status = port;
#endif
  int data = (nTrigger ? triggerX : triggerY)|clock;
  if (ftLoadOut) data |= loadOut;

  trace(64, ("analog %03x", port));
  trace(128, (" >%02x", data));
  _outp(port, data); idle(ftIdle);
  data = triggerX|triggerY|clock;
  if (ftLoadOut) data |= loadOut;
  trace(128, (" >%02x", data));
  _outp(port, data);
  while (_inp(status) & busy) ++ result, idle(ftScale);
  trace(64, (" %u\n", result));
#ifdef _WIN32
  if (enabled) _enable();
#endif
  return result;
}
Пример #11
0
CParallelPortSettings::ECPPortMode CParallelPort::ReadECPMode(unsigned short nBaseAddress)
{
    CParallelPortSettings::ECPPortMode mode = CParallelPortSettings::ECPModeUndefined;
    int nEcrData = _inp((unsigned short)(nBaseAddress+0x402));
    nEcrData = (nEcrData & 0xE0) >> 5;
    switch (nEcrData)
    {
    case 0:
        mode = CParallelPortSettings::ECPModeSPP;
        break;
    case 1:
        mode = CParallelPortSettings::ECPModePS2;
        break;
    case 2:
        mode = CParallelPortSettings::ECPModeFastCentronics;
        break;
    case 3:
        mode = CParallelPortSettings::ECPModeECP;
        break;
    case 4:
        mode = CParallelPortSettings::ECPModeEPP;
        break;
    case 6:
        mode = CParallelPortSettings::ECPModeTest;
        break;
    case 7:
        mode = CParallelPortSettings::ECPModeConfiguration;
        break;
    default:
        break;
    }
    return mode;
}
Пример #12
0
/* linux sound driver opl3.c does a so called tenmicrosec() delay */
static void tenmicrosec(void)
{
#if defined(_M_IX86)
    int i;
    for (i = 0; i < 16; i++)
        _inp(0x80);
#endif
}
Пример #13
0
int GetValidPpt(void)
{
	// search for valid parallel port
	_outp(LPT1, 0x55);
	if((int)_inp(LPT1) == 0x55)
	    return LPT1;
	
	_outp(LPT2, 0x55);
	if((int)_inp(LPT2) == 0x55)
	    return LPT2;
	
	_outp(LPT3, 0x55);
	if((int)_inp(LPT3) == 0x55)
	    return LPT3;
	
	return 0;	
}
Пример #14
0
void ftShowState (unsigned short port) {
  if (ftTraceFlags) {
    int s = _inp((unsigned short)(port+1));
    int c = _inp((unsigned short)(port+2));
    printf("%03x status", port);
    if (s & 0x80) fputs(" /BSY", stdout);
    if (s & 0x40) fputs(" /ACK", stdout);
    if (s & 0x20) fputs(" PAP", stdout);
    if (s & 0x10) fputs(" OFON", stdout);
    if (s & 0x04) fputs(" /FEN", stdout);
    fputs(" control", stdout);
    if (c & 0x10) fputs(" IRQ", stdout);
    if (c & 0x08) fputs(" DSL", stdout);
    if (c & 0x04) fputs(" /INI", stdout);
    if (c & 0x02) fputs(" ALF", stdout);
    if (c & 0x01) fputs(" STR", stdout);
    putchar('\n');
  }
}
Пример #15
0
BOOL CParallelPort::GetECPPort(unsigned short nBaseAddress)
{
    //If the ECP is idle and the FIFO empty,
    //in the ECP's Ecp (at base address+402h),
    //bit 1 (Fifo full)=0, and bit 0 (Fifo empty)=1.
    //The first test is to see if these bits differ from the
    //corresponding bits in the control port (at base address+2).
    //If so a further test is to write 34h to the Ecr,
    //then read it back. Bit 1 is read/write and bit 0 is read-only.
    //If the value read is 35h, the port is an ECP.
    BOOL bSuccess = FALSE;

    unsigned short nEcrAddress = (unsigned short)(nBaseAddress+0x402);
    int nEcrData = _inp(nEcrAddress);

    //Read bits 0 and 1 and control port bit 1
    int nEcrBit0 = nEcrData & 0x1;
    int nEcrBit1 = (nEcrData & 0x2) >> 1;
    int nControlBit1 = (ReadControl(nBaseAddress) & 0x2) >> 1;

    if (nEcrBit0 == 1 && nEcrBit1 == 0)
    {
        //Compare control bit 1 to ECR bit 1
        //Toggle the control bit if necessary
        //to be sure the two registers are different.
        if (nControlBit1 == 0)
        {
            WriteControl(nBaseAddress, 0xF);
            nControlBit1 = (ReadControl(nBaseAddress) & 0x2) >> 1;
        }

        if (nEcrBit1 != nControlBit1)
        {
            int nOriginalEcrData = nEcrData;
            _outp(nEcrAddress, 0x34);
            if (_inp(nEcrAddress) == 0x35)
                bSuccess = TRUE;

            //Restore the ECR to its original value
            _outp(nEcrAddress, nOriginalEcrData);
        }
    }
Пример #16
0
/**
  Reads an 8-bit I/O port.

  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
  This function must guarantee that all I/O read and write operations are
  serialized.

  If 8-bit I/O port operations are not supported, then ASSERT().

  @param  Port  The I/O port to read.

  @return The value read.

**/
UINT8
EFIAPI
IoRead8 (
  IN      UINTN                     Port
  )
{
  UINT8                             Value;

  _ReadWriteBarrier ();
  Value = (UINT8)_inp ((UINT16)Port);
  _ReadWriteBarrier ();
  return Value;
}
Пример #17
0
static void ShutdownMPU
   (
   void
   )

   {
   volatile DWORD dwCount;

   for (dwCount=0; dwCount<0x2000; dwCount++) ;
   dwCount = 0x2000;
   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
   _outp(MPUPort(1), MPU_RESET_CMD);
   for (dwCount=0; dwCount<0x2000; dwCount++) ;
   _inp(MPUPort(0));

   for (dwCount=0; dwCount<0x2000; dwCount++) ;
   dwCount = 0x2000;
   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
   _outp(MPUPort(1), MPU_RESET_CMD);
   for (dwCount=0; dwCount<0x2000; dwCount++) ;
   _inp(MPUPort(0));
   }
Пример #18
0
U8 InputPpt( void ) {
#if !defined(_WIN32) || defined(__CYGWIN__)
#if defined(LINUX_PPDEV) && ! defined(__CYGWIN__)
    int i;
    ioctl(validPpt, PPRSTATUS, &i);
    return (i & 0xff);
#else
    int j=inb( base_address + 1 );
    return j;
#endif
#else
    return _inp( (U16) (base_address + 1) );
#endif
}
Пример #19
0
////////////////////////////////////////////
// Windows95
// delay_us: CPU and clock independent delay
////////////////////////////////////////////
void delay_us (USHORT us)
{
	BYTE lo, hi;
	long summ,c,d,e,max;
	__int64 Delay;


	if ( InitTimeOut (TimDLY) )								// Use high speed timer for clock/cpu independent delay
	{									
		Delay = (__int64)(us) * TIM_1us;							// Number of clock ticks for given delay
		do {
		} while ( !TimeOut (TimDLY, Delay) );
	}
	else													// Use access of isa keyboard hardware for clock/cpu independent delay
	{
		DLLInfo = DLLInfo | DLLInfo_NoDelayTimer;					// High speed timer not used for delay!

		max=us*2380L/1000L;
		summ=0L;
		_outp(67,0);					
		lo=_inp(64); 					// Read low  byte
		hi=_inp(64); 					// Read high byte
		d=(hi<<8)+lo;					// Start time
		while(summ<max)
		{
			_outp(67,0);
			lo=_inp(64);  				// Read low  byte
			hi=_inp(64);  				// Read high byte
			c=(hi<<8)+lo; 				// Current time
			e=d-c;						// Elapsed time
			if(e<0L) e=e+65535L;		// If negative correct overflow
			summ=summ+e;	
			d=c;
		}
	}
}
Пример #20
0
void delay(double seconds)
{
	int al,ah=0;
	unsigned long  cnt,i;
	cnt=(long)(seconds/15.085e-6);
	for(i=0;i<cnt;i++)
	{
		do
		{
			al=_inp(0x61)&0x10;
		}
		while(al==ah);
		ah=al;
	}
}
Пример #21
0
void CParallelPort::SetECPMode(CParallelPortSettings::ECPPortMode mode)
{
    ASSERT(IsOpen()); //Port must be open
    CParallelPortSettings& settings = sm_Ports.ElementAt(m_nPortIndex);
    ASSERT(settings.m_Type == CParallelPortSettings::ParallelTypeECP); //Must be an ECP port
    ASSERT(mode != CParallelPortSettings::ECPModeUndefined);

    unsigned short nEcrAddress = (unsigned short)(m_nBaseAddress + 0x402);

    //Read the ECR & clear bits 5, 6 & 7
    int nEcrData = _inp(nEcrAddress) & 0x1F;

    //Write the selected value to bits 5, 6 & 7
    switch (mode)
    {
    case CParallelPortSettings::ECPModeSPP:
        nEcrData |= (0 << 5);
        break;
    case CParallelPortSettings::ECPModePS2:
        nEcrData |= (1 << 5);
        break;
    case CParallelPortSettings::ECPModeFastCentronics:
        nEcrData |= (2 << 5);
        break;
    case CParallelPortSettings::ECPModeECP:
        nEcrData |= (3 << 5);
        break;
    case CParallelPortSettings::ECPModeEPP:
        nEcrData |= (4 << 5);
        break;
    case CParallelPortSettings::ECPModeTest:
        nEcrData |= (6 << 5);
        break;
    case CParallelPortSettings::ECPModeConfiguration:
        nEcrData |= (7 << 5);
        break;
    default:
        ASSERT(FALSE);
        break;
    }
    _outp(nEcrAddress, nEcrData);

    //Update the value in our cached array
    settings.m_ECPMode = mode;
}
Пример #22
0
static void iodly()
{
	WORD d;
	LARGE_INTEGER val1, val2;


	if(PortType == TY_VCOM) {
		QueryPerformanceCounter(&val1);
		QueryPerformanceFrequency(&val2);
		val1.QuadPart += val2.QuadPart / 1000000 * PortDly;
		do
			QueryPerformanceCounter(&val2);
		while(val2.QuadPart < val1.QuadPart);
	}
	else {
		for(d = PortDly; d > 0; d--)
			_inp(PortBase);
	}
}
Пример #23
0
/* read the TDO bit from port */
unsigned char readTDOBit()
{
#ifdef WIN95PP
    /* Old Win95 example that is similar to a GPIO register implementation.
       The old Win95 reads the hardware input register and extracts the TDO
       value from the bit within the register that is assigned to the
       physical JTAG TDO signal. 
       */
    in_word.value = (unsigned char) _inp( (unsigned short) (base_port + STATUS_OFFSET) );
    if (in_word.bits.tdo == 0x1) {
        return( (unsigned char) 1 );
    }
#endif
    /* You must return the current value of the JTAG TDO signal. */
    //return( (unsigned char) 0 );

	delay_jtag(2000);
	return CPLD_TDO_STATE;
}
Пример #24
0
bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize)
{
  tagPort32Struct Port32Struct;
  DWORD dwBytesReturned;
  
  if (!IsWinIoInitialized)
    return false;

  if (IsNT)
  {
    switch (bSize)
    {
      case 1:

        *pdwPortVal = _inp(wPortAddr);

      break;

      case 2:

        *pdwPortVal = _inpw(wPortAddr);

      break;

      case 4:

        *pdwPortVal = _inpd(wPortAddr);

      break;
    }
  }
  else
  {
   Port32Struct.bSize = bSize;
   Port32Struct.wPortAddr = wPortAddr;
   
   return DeviceIoControl(hDriver, WINIO_READPORT, &Port32Struct, sizeof(Port32Struct),
                          pdwPortVal, sizeof(DWORD), &dwBytesReturned, NULL);
  }

  return true;
}
Пример #25
0
int main(int argc, char **argv) {
    int port_addr;
    int divisor;

    if (argc == 3) {

	unsigned char old_lcr_val;
	short msl;
	short msh;
	short lcr;

	sscanf(argv[1],"%d",&port_addr);
	sscanf(argv[2],"%d",&divisor);

	printf("Setting divisor of uart at port 0x%x to %d\n",port_addr,divisor);

	msl = port_addr + 0;
	msh = port_addr + 1;
	lcr = port_addr + 3;

	if ((port_addr == 0) || (divisor == 0)) {
	    printf("Error: Invalid arguments\n");
	    usage();
	    return -1;
	}

	// Save control register settings
	old_lcr_val = _inp(lcr);

	// Set UART to recieve new divisor
	_outp(lcr,(old_lcr_val | 0x80));

	// Set new divisor a byte at a time
	_outp(msl,divisor & 0xff);
	_outp(msh,divisor >> 8);

	// Restore UART
	_outp(lcr,old_lcr_val);

    } else {
Пример #26
0
void init_com1(void)
  {
  cout << "Begin Com1 initialization.   ";
  // disable cpu interrupts
  _disable();
  
  // set vector for COM1, irq4
  com1_old_vector = _dos_getvect(4+8); // irq4
  _dos_setvect(4+8, com1_isr);
     
  // initialize COM1 16550
  _outp( COM1_LCR, (DLAB1 | NO | STOP1 | EIGHT));
  _outp( COM1_DLL, BR_9600);
  //_outp( COM1_DLL, BR_115200);
  //_outp( COM1_DLL, BR_57600);
  //_outp( COM1_DLL, BR_19200);
  _outp( COM1_DLM, 0);
  _outp( COM1_LCR, (DLAB0 | NO | STOP1 | EIGHT));
  //_outp( COM1_FCR, 0xc1); // enable FIFOs to 14, reset FIFOs
  _outp( COM1_FCR, 0xc7); // enable FIFOs to 14, reset FIFOs
    
  // unmask all com1 uart interrupts
  //_outp( COM1_IER, 0x0f);  //jtm
  _outp( COM1_IER, 0x07);
  
  // clear garbage from the com1 iir
  while((_inp(COM1_IIR) & 0x01) != 1)
    {
    _inp(COM1_RX);
    _inp(COM1_LSR);
    _inp(COM1_MSR);
    }
  
  // enable com1 irq4 interrupts at the pic
  _outp(0x21, _inp(0x21) & 0xef);

  // turn on the com1 mcr gate (out2)
  _outp( COM1_MCR, _inp(COM1_MCR) | 0x08); 
  
  // enable cpu interrupts          
  _enable();
  cout << "Com1 initialized." << endl;
  // done 
  } // end init_com1()
Пример #27
0
void init_com2(void)
  {
  cout << "Begin Com2 initialization.   ";
  // disable cpu interrupts
  _disable();
  
  // set vector for COM2, irq3
  com2_old_vector = _dos_getvect(3+8);
  _dos_setvect(3+8, com2_isr);
     
  // initialize COM2 16550
  _outp( COM2_LCR, (DLAB1 | NO | STOP1 | EIGHT));
  _outp( COM2_DLL, BR_19200);  // for acoustic modem
  //_outp( COM2_DLL, BR_9600);  // for acoustic modem
  //_outp( COM2_DLL, BR_4800);  // for desert star
  //_outp( COM2_DLL, BR_57600);  // for crossbow
  _outp( COM2_DLM, 0);
  _outp( COM2_LCR, (DLAB0 | NO | STOP1 | EIGHT));
//sjc  _outp( COM2_FCR, 0xc1); // enable FIFOs to 14, reset FIFOs
  _outp( COM2_FCR, 0xc7); // enable FIFOs to 14, reset FIFOs
    
  // unmask all com1 uart interrupts
//sjc  _outp( COM2_IER, 0x0f);
  _outp( COM2_IER, 0x07);
  
  // clear garbage from the com1 iir
  while((_inp(COM2_IIR) & 0x01) != 1)
    {
    _inp(COM2_RX);
    _inp(COM2_LSR);
    _inp(COM2_MSR);
    }
  
  // enable com2 irq3 interrupts at the pic
  _outp(0x21, _inp(0x21) & 0xf7);

  // turn on the com2 mcr gate (out2)
  _outp( COM2_MCR, _inp(COM2_MCR) | 0x08); 
  
  // enable cpu interrupts          
  _enable();
  cout << "Com2 initialized." << endl;
  // done 
  } // end init_com2()
Пример #28
0
/* read the TDO bit from port */
unsigned char readTDOBit()
{
#ifdef DONT_DO_THIS
    /* Old Win95 example that is similar to a GPIO register implementation.
       The old Win95 reads the hardware input register and extracts the TDO
       value from the bit within the register that is assigned to the
       physical JTAG TDO signal. 
       */
    in_word.value = (unsigned char) _inp( (unsigned short) (base_port + STATUS_OFFSET) );
    if (in_word.bits.tdo == 0x1) {
        return( (unsigned char) 1 );
    }
#endif
		if (TDO_HIGH)
		{
			return(1);
		}
		else
		{
			return(0);
		}
    /* You must return the current value of the JTAG TDO signal. */
    return( (unsigned char) 0 );
}
Пример #29
0
void init_com4(void)
  {
  cout << "Begin Com4 initialization.   ";
  // disable cpu interrupts
  _disable();
  
  // set vector for COM4, irq9
  com4_old_vector = _dos_getvect(9+0x70-8);
  _dos_setvect(9+0x70-8, com4_isr);
     
  // initialize COM4 16550
  _outp( COM4_LCR, (DLAB1 | NO | STOP1 | EIGHT));
  _outp( COM4_DLL, BR_9600);  // for gps
  //_outp( COM4_DLL, BR_4800);  //
  //_outp( COM4_DLL, BR_57600);
  _outp( COM4_DLM, 0);
  _outp( COM4_LCR, (DLAB0 | NO | STOP1 | EIGHT));
  _outp( COM4_FCR, 0xc1); // enable FIFOs to 14, reset FIFOs
    
  // unmask all com4 uart interrupts
  _outp( COM4_IER, 0x0f);
  
  // clear garbage from the com4 iir
  while((_inp(COM4_IIR) & 0x01) != 1)
    {
    _inp(COM4_RX);
    _inp(COM4_LSR);
    _inp(COM4_MSR);
    }
  
  // enable com4 irq9 interrupts at the pic
  _outp(0xa1, _inp(0xa1) & 0xfd);

  // turn on the com4 mcr gate (out2)
  _outp( COM4_MCR, _inp(COM4_MCR) | 0x08); 
  
  // enable cpu interrupts          
  _enable();
  cout << "Com4 initialized." << endl;
  // done 
  } // end init_com4()
Пример #30
-1
unsigned char ftDigital (unsigned short port) {
  unsigned char result = 0;
#ifdef _WIN32
  unsigned short status = port+1;
  int enabled = ftDisable && _disable();
#endif
#ifdef SC12
  unsigned short status = port;
#endif
  int bit = 8;
  int data = triggerX|triggerY|loadIn;
  if (ftLoadOut) data |= loadOut;
  
  trace(8, ("digital %03x", port));
  trace(32, (" >%02x", data));
  _outp(port, data); idle(ftIdle);
  data |= clock;
  trace(32, (" >%02x", data));
  _outp(port, data);
  while (bit-- > 0) {
    idle(ftIdle);
    result |= ((_inp(status) & busy) != 0) << bit;
    trace(16, (" <%02x", result));
    data = triggerX|triggerY;
    if (ftLoadOut) data |= loadOut;
    trace(32, (" >%02x", data));
    _outp(port, data); idle(ftIdle);
    data |= clock;
    trace(32, (" >%02x", data));
    _outp(port, data);
  }
  trace(8, (" %02x\n", result));
#ifdef _WIN32
  if (enabled) _enable();
#endif
  return result;
}