예제 #1
0
VOID
ScsiPortWriteRegisterUshort(
    IN PUSHORT Register,
    IN USHORT Value
)

/*++

Routine Description:

    Write to the specificed register address.

Arguments:

    Register - Supplies a pointer to the register address.

    Value - Supplies the value to be written.

Return Value:

    None

--*/

{

    WRITE_REGISTER_USHORT(Register, Value);
}
예제 #2
0
파일: stubs.c 프로젝트: RareHare/reactos
VOID
NTAPI
ScsiPortWriteRegisterUshort(
    IN PUSHORT Register,
    IN USHORT Value)
{
    WRITE_REGISTER_USHORT(Register, Value);
}
예제 #3
0
VOID
NTAPI
VideoPortWriteRegisterUshort(
    PUSHORT Register,
    USHORT Value)
{
    WRITE_REGISTER_USHORT(Register, Value);
}
예제 #4
0
USHORT
HWREG<USHORT>::Write(
    _In_ USHORT Value
    )
{
    volatile USHORT *addr = &m_Value;
    WRITE_REGISTER_USHORT((PUSHORT)addr, Value);
    return Value;
}
예제 #5
0
파일: hwtwl40x.c 프로젝트: GYGit/reactos
VOID
NTAPI
LlbHwOmap3TwlWrite(IN UCHAR ChipAddress,
                   IN UCHAR RegisterAddress,
                   IN UCHAR Length,
                   IN PUCHAR Values)
{
    volatile int i = 1000;
    ULONG j;

    /* Select chip address */
    WRITE_REGISTER_USHORT(0x4807002c, ChipAddress);
    WRITE_REGISTER_USHORT(0x48070018, Length + 1);

    /* Enable master transmit mode */
    WRITE_REGISTER_USHORT(0x48070024, 0x8601);
    WRITE_REGISTER_USHORT(0x4807001c, RegisterAddress);
    
    /* Loop each byte */
    for (j = 0; j < Length; j++)
    {
        /* Write the data */
        WRITE_REGISTER_USHORT(0x4807001c, Values[j]);
    }

    /* Issue stop command */
    WRITE_REGISTER_USHORT(0x48070024, 0x8602);
    for (i = 1000; i > 0; i--);
}
예제 #6
0
파일: debug.c 프로젝트: Gaikokujin/WinNT4
VOID vWriteFifoW(
VOID*   p,
ULONG   v)
{
    gcFifo--;
    if (gcFifo < 0)
    {
        gcFifo = 0;
        RIP("Incorrect FIFO wait count");
    }

    WRITE_REGISTER_USHORT(p, (USHORT) v);
}
예제 #7
0
파일: hwtwl40x.c 프로젝트: GYGit/reactos
UCHAR
NTAPI
LlbHwOmap3TwlRead1(IN UCHAR ChipAddress,
                   IN UCHAR RegisterAddress)
{
    volatile int i = 1000;
        
    /* Select the register */
    LlbHwOmap3TwlWrite(ChipAddress, RegisterAddress, 0, NULL);

    /* Now read it */
    WRITE_REGISTER_USHORT(0x48070024, 0x8401);
    for (i = 1000; i > 0; i--);
    return READ_REGISTER_USHORT(0x4807001c);
}
예제 #8
0
파일: snidisp.c 프로젝트: Gaikokujin/WinNT4
VOID
HalpResetCirrusChip(
    VOID
    )
/*+++
  
   This function resets/loads default values to the Cirrus Chip
   extended registers for use with extended text mode (80x50)

   Register values found in the cirrus manual, appendix D5

---*/
{
    UCHAR byte;

    WRITE_REGISTER_UCHAR(VGA_SEQ_IDX,  0x01);             // Screen off
    byte = READ_REGISTER_UCHAR(VGA_SEQ_DATA);
    WRITE_REGISTER_UCHAR(VGA_SEQ_DATA, (byte | 0x20));    // stop the sequencer

    // extended sequencer and crtc regs for cirrus

    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x1206);           // unlock the extended registers
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0007);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x4008);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x5709);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x180a);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x660b);

	// new modifs
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x3b1b);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x000f);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0016);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x001b);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0007);
    WRITE_REGISTER_USHORT(VGA_GRAPH_IDX, 0x0009);
    WRITE_REGISTER_USHORT(VGA_GRAPH_IDX, 0x000a);
    WRITE_REGISTER_USHORT(VGA_GRAPH_IDX, 0x000b);
	// end new modifs

    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0010);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0011);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0012);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0013);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0018);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0119);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x001a);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x3b1b);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x2f1c);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x301d);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x331e);

}
예제 #9
0
파일: card.c 프로젝트: BillTheBest/WinNT4
VOID
CardDialNumber(
    IN PHTDSU_ADAPTER       Adapter,
    IN USHORT               CardLine,    /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
    IN PUCHAR               DialString,
    IN ULONG                DialStringLength
    )

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Functional Description:

    Place a dial string on the adapter and start the dialing sequence.

Parameters:

    Adapter _ A pointer ot our adapter information structure.

    CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).

    DialString _ A pointer to an ASCII null-terminated string of digits.

    DialStringLength _ Number of bytes in dial string.

Return Values:

    None

---------------------------------------------------------------------------*/

{
    DBG_FUNC("CardDialNumber")

    UINT    Index;
    UINT    NumDigits;    

    PUSHORT DialRam;

    DBG_ENTER(Adapter);

    ASSERT(READ_REGISTER_USHORT(&Adapter->AdapterRam->TxDataEmpty));
    ASSERT(READ_REGISTER_USHORT(&Adapter->AdapterRam->Command) == HTDSU_CMD_NOP);

    /*
    // Copy the digits to be dialed onto the adapter.
    // The adapter interprets phone numbers as high byte is valid digit,
    // low byte is ignored, the last digit gets bit 15 set.
    */
    DialRam = (PUSHORT) &Adapter->AdapterRam->TxBuffer;

    for (NumDigits = Index = 0; Index < DialStringLength && *DialString; Index++)
    {
        if ((*DialString >= '0') && (*DialString <= '9'))
        {
            WRITE_REGISTER_USHORT(
                    DialRam,
                    (USHORT) ((*DialString - '0') << 8)
                    );
            DialRam++;

            /*
            // Make sure dial string is within the limit of the adapter.
            */
            if (++NumDigits >= HTDSU_MAX_DIALING_DIGITS)
            {
                break;
            }
        }
        DialString++;
    }

    /*
    // Set the MSB in the last digit.
    */
    DialRam--;
    WRITE_REGISTER_USHORT(
            DialRam,
            (USHORT) (READ_REGISTER_USHORT(DialRam) | 0x8000)
            );

    /*
    // Initiate the dial sequence.
    */
    CardDoCommand(Adapter, CardLine, HTDSU_CMD_DIAL);

    DBG_LEAVE(Adapter);
}
예제 #10
0
파일: card.c 프로젝트: BillTheBest/WinNT4
NDIS_STATUS
CardDoCommand(
    IN PHTDSU_ADAPTER       Adapter,
    IN USHORT               CardLine,   /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
    IN USHORT               CommandValue
    )

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Functional Description:

    This routine routine will execute a command on the card after making
    sure the previous command has completed properly.

Parameters:

    Adapter _ A pointer ot our adapter information structure.

    CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).

    CommandValue _ HTDSU_CMD_??? command to be executed.

Return Values:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_HARD_ERRORS

---------------------------------------------------------------------------*/
{
    DBG_FUNC("CardDoCommand")

    ULONG       TimeOut = 0;

    DBG_ENTER(Adapter);
    DBG_FILTER(Adapter, DBG_PARAMS_ON,("Line=%d, Command=%04X, LineStatus=%Xh\n",
                CardLine, CommandValue,
                READ_REGISTER_USHORT(&Adapter->AdapterRam->StatusLine1)
                ));

    /*
    // Wait for command register to go idle - but don't wait too long.
    // If we timeout here, there's gotta be something wrong with the adapter.
    */
    while ((READ_REGISTER_USHORT(&Adapter->AdapterRam->Command) != 
                    HTDSU_CMD_NOP) ||
           (READ_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorId) != 
                    HTDSU_COPROCESSOR_ID))
    {
        if (TimeOut++ > HTDSU_SELFTEST_TIMEOUT)
        {
            DBG_ERROR(Adapter,("Timeout waiting for %04X command to clear\n",
                      READ_REGISTER_USHORT(&Adapter->AdapterRam->Command)));
            /*
            // Ask for reset, and disable interrupts until we get it.
            */
            Adapter->NeedReset = TRUE;
            Adapter->InterruptEnableFlag = HTDSU_INTR_DISABLE;
            CardDisableInterrupt(Adapter);
            
            return (NDIS_STATUS_HARD_ERRORS);
        }
        NdisStallExecution(_100_MICROSECONDS);
    }
    DBG_NOTICE(Adapter,("Timeout=%d waiting to submit %04X\n",
               TimeOut, CommandValue));

    /*
    // Before starting a reset command, we clear the the co-processor ID
    // which then gets set to the proper value when the reset is complete.
    */
    if (CommandValue == HTDSU_CMD_RESET)
    {
        WRITE_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorId, 0);
    }

    /*
    // Send the command to the adapter.
    */
    WRITE_REGISTER_USHORT(
            &Adapter->AdapterRam->Command,
            (USHORT) (CommandValue + CardLine)
            );

    DBG_LEAVE(Adapter);

    return (NDIS_STATUS_SUCCESS);
}
예제 #11
0
VOID
DigiServiceEvent( IN PDIGI_CONTROLLER_EXTENSION ControllerExt,
                  IN USHORT Ein,
                  IN USHORT Eout )

/*++

Routine Description:


Arguments:


Return Value:


--*/

{
   const USHORT Emax = 0x03FC;

   DigiDump( (DIGIFLOW|DIGIEVENT), ("Entering DigiServiceEvent\n") );

   // Event registers should be in range and DWORD-aligned.
   ASSERT( Ein <= Emax && (Ein & 3) == 0 );
   ASSERT( Eout <= Emax && (Eout & 3) == 0 );

   DigiDump( DIGIEVENT, ("---------  Ein(0x%.4x) != Eout(0x%.4x)\n",
                         Ein, Eout ) );

   for( ; Eout != Ein ; Eout += 4, Eout &= Emax )
   {
      PDIGI_DEVICE_EXTENSION DeviceExt;
      PFEP_EVENT pEvent;
      FEP_EVENT Event;
      ULONG EventReason;

      pEvent = (PFEP_EVENT)(ControllerExt->VirtualAddress +
                  ControllerExt->EventQueue.Offset + Eout );

      EnableWindow( ControllerExt, ControllerExt->EventQueue.Window );

      READ_REGISTER_BUFFER_UCHAR( (PUCHAR)pEvent, (PUCHAR)&Event, sizeof(Event) );

      DisableWindow( ControllerExt );

      if( (Event.Channel <= 0xDF) &&
          (Event.Channel < ControllerExt->NumberOfPorts) )
      {
         DeviceExt = ControllerExt->DeviceObjectArray[Event.Channel]->DeviceExtension;
      }
      else // bad command?
      {
         DeviceExt = NULL;
         DigiDump( DIGIEVENT, ("Event on unknown channel %d (flags = 0x%.2x), ignored\n", Event.Channel, Event.Flags) );
         continue;
      }

      DigiDump( DIGIEVENT, ("---------  Channel = %d\tFlags = 0x%.2x\n"
                            "---------  Current = 0x%.2x\tPrev. = 0x%.2x\n",
                           Event.Channel, Event.Flags, Event.CurrentModem,
                           Event.PreviousModem) );

      //
      // OK, let's process the event
      //

      if( Event.Flags & ~(FEP_ALL_EVENT_FLAGS) )
      {
         DigiDump( DIGIERRORS, ("Unknown event queue flag 0x%.2x\n",
               Event.Flags & ~(FEP_ALL_EVENT_FLAGS) ) );
         // Process the event bits that we *do* understand.
      }

      // Modem signals are always processed, regardless of whether the port is open.
      if( Event.Flags & FEP_MODEM_CHANGE_SIGNAL )
      {
         DigiDump( (DIGIMODEM|DIGIEVENT|DIGIWAIT),
                     ("---------  Modem Change Event (%s:%d)\n",
                      __FILE__, __LINE__ ) );

         KeAcquireSpinLockAtDpcLevel( &DeviceExt->ControlAccess );

         DigiDump( (DIGIMODEM|DIGIWAIT),
                             ("   CurrentModem = 0x%x\tPreviousModem = 0x%x\n",
                              Event.CurrentModem, Event.PreviousModem ));

         DeviceExt->CurrentModemSignals = Event.CurrentModem;

         KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
      }

      // If the port isn't open, don't bother with the rest.
      if( DeviceExt->DeviceState != DIGI_DEVICE_STATE_OPEN )
      {
         // If we might return to OPEN, don't touch anything!
         if( DeviceExt->DeviceState != DIGI_DEVICE_STATE_CLEANUP)
         {
            if( Event.Flags & (FEP_RX_PRESENT | FEP_RECEIVE_BUFFER_OVERRUN | FEP_UART_RECEIVE_OVERRUN) )
            {
               PFEP_CHANNEL_STRUCTURE ChInfo;

               FlushReceiveBuffer( ControllerExt, DeviceExt );

               ChInfo = (PFEP_CHANNEL_STRUCTURE)(ControllerExt->VirtualAddress +
                                                DeviceExt->ChannelInfo.Offset);

               // Notify us when more data comes in.
               EnableWindow( ControllerExt, DeviceExt->ChannelInfo.Window );
               WRITE_REGISTER_UCHAR( &ChInfo->idata, TRUE );
               DisableWindow( ControllerExt );
            }
            // Don't flush transmit (might kill end of data).
         }
         continue;
      }

      // Reset event notifications.
      EventReason = 0;

      if( Event.Flags & FEP_EV_BREAK )
      {
         EventReason |= SERIAL_EV_BREAK;

         KeAcquireSpinLockAtDpcLevel( &DeviceExt->ControlAccess );
         DeviceExt->ErrorWord |= SERIAL_ERROR_BREAK;
         KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
      }

      if( (Event.Flags & (FEP_TX_LOW | FEP_TX_EMPTY) ) )
      {
         PLIST_ENTRY WriteQueue;

#if DBG
         switch( Event.Flags & (FEP_TX_LOW | FEP_TX_EMPTY) )
         {
            case FEP_TX_LOW:
               DigiDump( (DIGIEVENT|DIGIWRITE), ("%s:\tTXLOW event\n", DeviceExt->DeviceDbgString) );
               break;
            case FEP_TX_EMPTY:
               DigiDump( (DIGIEVENT|DIGIWRITE), ("%s:\tTXEMPTY event\n", DeviceExt->DeviceDbgString) );
               break;
            default:
               DigiDump( (DIGIEVENT|DIGIWRITE), ("%s:\tTXLOW and TXEMPTY events\n", DeviceExt->DeviceDbgString) );
               break;
         }
#endif

         WriteQueue = &DeviceExt->WriteQueue;

         KeAcquireSpinLockAtDpcLevel( &DeviceExt->ControlAccess );

         if( !IsListEmpty( WriteQueue ) )
         {
            PIRP Irp;

            Irp = CONTAINING_RECORD( WriteQueue->Flink,
                                     IRP,
                                     Tail.Overlay.ListEntry );

            if( Irp->IoStatus.Information != MAXULONG )
            {
               PIO_STACK_LOCATION IrpSp;

               IrpSp = IoGetCurrentIrpStackLocation( Irp );

               if( IrpSp->MajorFunction == IRP_MJ_WRITE
               ||  (  IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL
                   && Irp->IoStatus.Information == 0
                   )
                 )
               {
                  DigiDump( DIGIEVENT, ("---------  WriteQueue list NOT empty\n") );

                  if( IrpSp->MajorFunction == IRP_MJ_WRITE )
                  {
                     ASSERT( Irp->IoStatus.Information < IrpSp->Parameters.Write.Length );
                  }
                  else
                  {
                     ASSERT(  IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                                 IOCTL_SERIAL_IMMEDIATE_CHAR
                           || IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                                 IOCTL_SERIAL_XOFF_COUNTER );
                  }

                  if( WriteTxBuffer( DeviceExt ) == STATUS_SUCCESS )
                  {
                     KIRQL OldIrql = DISPATCH_LEVEL;

                     DigiDump( DIGIEVENT, ("---------  Write complete.  Successfully completing Irp.\n"
                                           "---------  #bytes completing = %d\n",
                                           Irp->IoStatus.Information ) );

                     DIGI_INC_REFERENCE( Irp );
                     DigiTryToCompleteIrp( DeviceExt, &OldIrql,
                                           STATUS_SUCCESS, WriteQueue,
                                           NULL,
                                           &DeviceExt->WriteRequestTotalTimer,
                                           StartWriteRequest );

                     goto WriteDone; // skip unlock
                  } // WriteTxBuffer returned SUCCESS
               } // IRP is eligible for WriteTxBuffer
            } // IRP started
            KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
WriteDone:;
         }
         else // empty(WQ)
         {
            DigiDump( DIGIEVENT, ("---------  WriteQueue was empty\n") );

            if( Event.Flags & FEP_TX_EMPTY )
               EventReason |= SERIAL_EV_TXEMPTY;

            KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
         }
      } // FEP_TX_LOW | FEP_TX_EMPTY

      if( Event.Flags & FEP_RX_PRESENT )
      {
         PLIST_ENTRY ReadQueue;
         PFEP_CHANNEL_STRUCTURE ChInfo;
         USHORT Rin, Rout, Rmax, RxSize;

         DigiDump( DIGIEVENT, ("---------  Rcv Data Present Event: (%s:%d)\n",
                              __FILE__, __LINE__ ) );

GetReceivedData:;

         ChInfo = (PFEP_CHANNEL_STRUCTURE)(ControllerExt->VirtualAddress +
                                           DeviceExt->ChannelInfo.Offset);

         KeAcquireSpinLockAtDpcLevel( &DeviceExt->ControlAccess );

         EnableWindow( ControllerExt, DeviceExt->ChannelInfo.Window );
         Rout = READ_REGISTER_USHORT( &ChInfo->rout );
         Rin = READ_REGISTER_USHORT( &ChInfo->rin );
         Rmax = READ_REGISTER_USHORT( &ChInfo->rmax );
         DisableWindow( ControllerExt );

         if( (DeviceExt->WaitMask & SERIAL_EV_RXCHAR) &&
             (DeviceExt->PreviousRxChar != (ULONG)Rin) )
         {
            EventReason |= SERIAL_EV_RXCHAR;
         }

         if( (DeviceExt->WaitMask & SERIAL_EV_RXFLAG) &&
             (DeviceExt->UnscannedRXFLAGPosition != (ULONG)Rin) )
         {
            if( ScanReadBufferForSpecialCharacter( DeviceExt,
                                                   DeviceExt->SpecialChars.EventChar ) )
            {
               EventReason |= SERIAL_EV_RXFLAG;
            }
         }

         //
         // Determine if we are waiting to notify a 80% receive buffer
         // full.
         //
         //    NOTE: I assume the controller will continue to notify
         //          us that data is still in the buffer, even if
         //          we don't take the data out of the controller's
         //          buffer.
         //
         if( (DeviceExt->WaitMask & SERIAL_EV_RX80FULL)
         &&  !(DeviceExt->HistoryWait & SERIAL_EV_RX80FULL) ) // notification is already pending
         {
            //
            // Okay, is the receive buffer 80% or more full??
            //
            RxSize = (Rin - Rout) & Rmax;

            if( RxSize )
            {
               if( DeviceExt->SpecialFlags & DIGI_SPECIAL_FLAG_FAST_RAS )
               {
                  if( RxSize >= DeviceExt->ReceiveNotificationLimit )
                  {
                     EventReason |= SERIAL_EV_RX80FULL;
                  }
               }
               else // not RAS
               {
                  // Perform 32-bit math to avoid roundoff errors.
                  if( RxSize >= (USHORT) ( ((ULONG)Rmax + 1UL) * 8UL / 10UL) )
                  {
                     EventReason |= SERIAL_EV_RX80FULL;
                  }
                  else
                  {
                     USHORT RxHighWater;

                     EnableWindow( ControllerExt, DeviceExt->ChannelInfo.Window );
                     RxHighWater = READ_REGISTER_USHORT( &ChInfo->rhigh );
                     DisableWindow( ControllerExt );

                     // If flow control is engaged, trigger the event (we won't get any more data).
                     if( RxSize >= RxHighWater - 1 )
                     {
                        EventReason |= SERIAL_EV_RX80FULL;
                     }
                  }
               } // not RAS
            } // if data
         } // RX80FULL

         ReadQueue = &DeviceExt->ReadQueue;
         if( !IsListEmpty( ReadQueue ) )
         {
            PIRP Irp;

            Irp = CONTAINING_RECORD( ReadQueue->Flink,
                                     IRP,
                                     Tail.Overlay.ListEntry );

            if( DeviceExt->ReadStatus == STATUS_PENDING
            &&  Irp->IoStatus.Information != MAXULONG ) // not started yet
            {
               KIRQL OldIrql = DISPATCH_LEVEL;

               // Hold IRP across lock drop in ReadRxBuffer:ProcessSlowRead:DigiSatisfyWait.
               DIGI_INC_REFERENCE( Irp );

               if( STATUS_SUCCESS == ReadRxBuffer( DeviceExt, &OldIrql ) )
               {
#if DBG
                  if( DigiDebugLevel & DIGIRXTRACE )
                  {
                     PUCHAR Temp;
                     ULONG i;

                     Temp = Irp->AssociatedIrp.SystemBuffer;

                     DigiDump( DIGIRXTRACE, ("Read buffer contains: %s",
                                              DeviceExt->DeviceDbgString) );
                     for( i = 0;
                          i < Irp->IoStatus.Information;
                          i++ )
                     {
                        if( (i & 15) == 0 )
                           DigiDump( DIGIRXTRACE, ( "\n\t") );

                        DigiDump( DIGIRXTRACE, ( "-%02x", Temp[i]) );
                     }
                     DigiDump( DIGIRXTRACE, ("\n") );
                  }
#endif
                  //
                  // We have satisfied this current request, so lets
                  // complete it.
                  //
                  DigiDump( DIGIEVENT, ("---------  Read complete.  Successfully completing Irp.\n") );

                  DigiDump( DIGIEVENT, ("---------  #bytes completing = %d\n",
                                        Irp->IoStatus.Information ) );

                  DeviceExt->ReadStatus = SERIAL_COMPLETE_READ_COMPLETE;

                  DigiTryToCompleteIrp( DeviceExt, &OldIrql,
                                        STATUS_SUCCESS, ReadQueue,
                                        &DeviceExt->ReadRequestIntervalTimer,
                                        &DeviceExt->ReadRequestTotalTimer,
                                        StartReadRequest );

                  goto ReadDone; // skip DEC and unlock
               } // else ReadRxBuffer != SUCCESS
               DIGI_DEC_REFERENCE( Irp );
            } // else ReadStatus != STATUS_PENDING || IRP not started
            KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
ReadDone:;
         }
         else // empty(RQ)
         {
            PSERIAL_XOFF_COUNTER Xc;

            //
            // We don't have an outstanding read request, so make sure
            // we reset the IDATA flag on the controller.
            //
            ChInfo = (PFEP_CHANNEL_STRUCTURE)(ControllerExt->VirtualAddress +
                                              DeviceExt->ChannelInfo.Offset);

            EnableWindow( ControllerExt, DeviceExt->ChannelInfo.Window );
            WRITE_REGISTER_UCHAR( &ChInfo->idata, TRUE );
            DisableWindow( ControllerExt );

            DigiDump( DIGIEVENT, ("---------  No outstanding read IRP's to place received data.\n") );

            DeviceExt->PreviousRxChar = (ULONG)Rin;

            // The perception of receive data might complete an XOFF_COUNTER on the WriteQueue.
            // Keep track of what we've eaten via XcPreview to avoid counting bytes twice (in ReadRxBuffer).
            Xc = DeviceExt->pXoffCounter;
            if( Xc )
            {
               RxSize = (Rin - Rout) & Rmax;

               if( RxSize < Xc->Counter )
               {
                  DigiDump( (DIGIWRITE|DIGIDIAG1), ("IDATA reduced XOFF_COUNTER\n") );
                  Xc->Counter -= RxSize;
                  DeviceExt->XcPreview += RxSize;
               }
               else
               {
                  // XOFF_COUNTER is complete.

                  KIRQL OldIrql = DISPATCH_LEVEL;
#if DBG
                  Xc->Counter = 0; // Looks a little nicer...
#endif
                  DigiDump( (DIGIWRITE|DIGIDIAG1), ("IDATA on empty(RQ) is completing XOFF_COUNTER\n") );
                  DigiTryToCompleteIrp( DeviceExt, &OldIrql, STATUS_SUCCESS,
                        &DeviceExt->WriteQueue, NULL, &DeviceExt->WriteRequestTotalTimer, StartWriteRequest );
                  goto XcDone; // skip unlock
               }
            }
            KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
XcDone:;
         }
      } // FEP_RX_PRESENT

      if( Event.Flags & FEP_MODEM_CHANGE_SIGNAL )
      {
         ULONG WaitMask;
         UCHAR ChangedModemState;

         ChangedModemState = Event.CurrentModem ^ Event.PreviousModem;

         KeAcquireSpinLockAtDpcLevel( &DeviceExt->ControlAccess );

         WaitMask = DeviceExt->WaitMask;

         DigiDump( (DIGIMODEM|DIGIEVENT|DIGIWAIT),
                     ("---------  Modem Change Event (%s:%d)\t",
                      "   ChangedModemState = 0x%x\n",
                      ChangedModemState,
                      __FILE__, __LINE__ ) );

         if( (WaitMask & SERIAL_EV_CTS) &&
             (ControllerExt->ModemSignalTable[CTS_SIGNAL] & ChangedModemState) )
         {
            EventReason |= SERIAL_EV_CTS;
         }
         if( (WaitMask & SERIAL_EV_DSR) &&
             (ControllerExt->ModemSignalTable[DSR_SIGNAL] & ChangedModemState) )
         {
            EventReason |= SERIAL_EV_DSR;
         }
         if( (WaitMask & SERIAL_EV_RLSD) &&
             (ControllerExt->ModemSignalTable[DCD_SIGNAL] & ChangedModemState) )
         {
            EventReason |= SERIAL_EV_RLSD;
         }
         if( (WaitMask & SERIAL_EV_RING) &&
             (ControllerExt->ModemSignalTable[RI_SIGNAL] & ChangedModemState) )
         {
            EventReason |= SERIAL_EV_RING;
         }

         if( DeviceExt->EscapeChar )
         {
            UCHAR MSRByte, CurrentModemSignals;

            if( DeviceExt->PreviousMSRByte )
               DigiDump( DIGIERRORS, ("   PreviousMSRByte != 0\n") );

            MSRByte = 0;

            if( ControllerExt->ModemSignalTable[CTS_SIGNAL] & ChangedModemState )
            {
               MSRByte |= SERIAL_MSR_DCTS;
            }
            if( ControllerExt->ModemSignalTable[DSR_SIGNAL] & ChangedModemState )
            {
               MSRByte |= SERIAL_MSR_DDSR;
            }
            if( ControllerExt->ModemSignalTable[RI_SIGNAL] & ChangedModemState )
            {
               MSRByte |= SERIAL_MSR_TERI;
            }
            if( ControllerExt->ModemSignalTable[DCD_SIGNAL] & ChangedModemState )
            {
               MSRByte |= SERIAL_MSR_DDCD;
            }

            CurrentModemSignals = DeviceExt->CurrentModemSignals;
            if( ControllerExt->ModemSignalTable[CTS_SIGNAL] & CurrentModemSignals )
            {
               MSRByte |= SERIAL_MSR_CTS;
            }
            if( ControllerExt->ModemSignalTable[DSR_SIGNAL] & CurrentModemSignals )
            {
               MSRByte |= SERIAL_MSR_DSR;
            }
            if( ControllerExt->ModemSignalTable[RI_SIGNAL] & CurrentModemSignals )
            {
               MSRByte |= SERIAL_MSR_RI;
            }
            if( ControllerExt->ModemSignalTable[DCD_SIGNAL] & CurrentModemSignals )
            {
               MSRByte |= SERIAL_MSR_DCD;
            }

            if( !IsListEmpty( &DeviceExt->ReadQueue ) )
            {
               PIRP Irp;
               PIO_STACK_LOCATION IrpSp;

               Irp = CONTAINING_RECORD( DeviceExt->ReadQueue.Flink,
                                        IRP,
                                        Tail.Overlay.ListEntry );

               IrpSp = IoGetCurrentIrpStackLocation( Irp );

               if( (IrpSp->Parameters.Read.Length - Irp->IoStatus.Information) > 3 )
               {
                  PUCHAR ReadBuffer;

                  ReadBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer +
                               Irp->IoStatus.Information;

                  ReadBuffer[0] = DeviceExt->EscapeChar;
                  ReadBuffer[1] = SERIAL_LSRMST_MST;
                  ReadBuffer[2] = MSRByte;
                  Irp->IoStatus.Information += 3;

                  DeviceExt->PreviousMSRByte = 0;

                  DigiDump( DIGIMODEM, ("      CurrentModemSignals = 0x%x\n"
                                        "      ChangedModemState = 0x%x\n"
                                        "      MSRByte = 0x%x\n",
                                        DeviceExt->CurrentModemSignals,
                                        ChangedModemState,
                                        MSRByte) );
               }
               else
               {
                  DigiDump( (DIGIMODEM|DIGIERRORS),
                            ("Insufficient read IRP space available to record modem status change!\n") );
                  DeviceExt->PreviousMSRByte = MSRByte;
               }
            }
            else
            {
               DigiDump( (DIGIMODEM|DIGIERRORS),
                         ("No read IRP in which to record modem status change!\n") );
               DeviceExt->PreviousMSRByte = MSRByte;
            }
            KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );

            //
            // We need to read any data which may be available.
            //
            Event.Flags &= ~FEP_MODEM_CHANGE_SIGNAL;
            goto GetReceivedData;
         }
         else
         {
            KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
         }
      } // FEP_MODEM_CHANGE_SIGNAL

      if( Event.Flags & FEP_RECEIVE_BUFFER_OVERRUN )
      {
         KeAcquireSpinLockAtDpcLevel( &DeviceExt->ControlAccess );
         DeviceExt->ErrorWord |= SERIAL_ERROR_QUEUEOVERRUN;
         InterlockedIncrement(&DeviceExt->PerfData.BufferOverrunErrorCount);
         KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
      }

      if( Event.Flags & FEP_UART_RECEIVE_OVERRUN )
      {
         KeAcquireSpinLockAtDpcLevel( &DeviceExt->ControlAccess );
         DeviceExt->ErrorWord |= SERIAL_ERROR_OVERRUN;
         InterlockedIncrement(&DeviceExt->PerfData.SerialOverrunErrorCount);
         KeReleaseSpinLockFromDpcLevel( &DeviceExt->ControlAccess );
      }

      if( EventReason )
         DigiSatisfyEvent( ControllerExt, DeviceExt, EventReason );

   }

   //
   // Regardless of whether we processed the event, make sure we forward
   // the event out pointer.
   //
   EnableWindow( ControllerExt, ControllerExt->Global.Window );

   WRITE_REGISTER_USHORT( (PUSHORT)((PUCHAR)ControllerExt->VirtualAddress+FEP_EOUT),
                          Eout );

   DisableWindow( ControllerExt );

   DigiDump( (DIGIFLOW|DIGIEVENT), ("Exiting DigiServiceEvent\n") );

}  // DigiServiceEvent
예제 #12
0
파일: kdcpuapi.c 프로젝트: conioh/os-design
VOID
KdpWriteIoSpaceExtended (
    IN PDBGKD_MANIPULATE_STATE64 m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a read io space extended state
    manipulation message.  Its function is to read system io
    locations.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_WRITE_IO_EXTENDED64 a = &m->u.ReadWriteIoExtended;
    ULONG Length;
    STRING MessageHeader;
    PUCHAR b;
    PUSHORT s;
    PULONG l;
    ULONG BusNumber;
    ULONG AddressSpace;
    ULONG SavedAddressSpace;
    PHYSICAL_ADDRESS IoAddress;
    ULONG DataSize;
    PHYSICAL_ADDRESS TranslatedAddress;
    INTERFACE_TYPE InterfaceType;
    ULONG Value;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    ASSERT(AdditionalData->Length == 0);

    m->ReturnStatus = STATUS_SUCCESS;

    InterfaceType = a->InterfaceType;
    BusNumber = a->BusNumber;
    AddressSpace = SavedAddressSpace = a->AddressSpace;
    IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    DataSize = a->DataSize;
    Value = a->DataValue;

    //
    // Translate the bus address to the physical system address
    // or QVA.
    //

    if( !HalTranslateBusAddress( InterfaceType,
                                 BusNumber,
                                 IoAddress,
                                 &AddressSpace,
                                 &TranslatedAddress ) ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendWriteIoSpaceExtendedResponse;
    }

    //
    // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    //        is one.  It may be in later systems that we will have to
    //        check the address space, map it, perform the virtual read
    //        unmap, and then return the data - only we will have to be
    //        careful about what Irql we are to make sure the memory mgmt
    //        stuff will all work
    //

    if( !AddressSpace ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendWriteIoSpaceExtendedResponse;
    }

    //
    // Do the IO space read using the appropriate HAL routines based upon
    // the original address space and the data size requested.
    //

    if( !SavedAddressSpace ){

        //
        // Memory (buffer) space on the bus
        //

        switch( DataSize ){

        case 1:
            WRITE_REGISTER_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value );
            break;

        case 2:
            WRITE_REGISTER_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value );
            break;

        case 4:
            WRITE_REGISTER_ULONG( (PULONG)TranslatedAddress.QuadPart, Value );
            break;

        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
        }

    } else {

        //
        // I/O space on the bus
        //

        switch( DataSize ){

        case 1:
            WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value );
            break;

        case 2:
            WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value);
            break;

        case 4:
            WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value );
            break;

        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
        }
    }



SendWriteIoSpaceExtendedResponse:

    KdpSendPacket(
        PACKET_TYPE_KD_STATE_MANIPULATE,
        &MessageHeader,
        NULL
        );
}
예제 #13
0
파일: snidisp.c 프로젝트: Gaikokujin/WinNT4
VOID
HalpInitializeVGADisplay(
    TEXT_MODE TextMode
    )
{

static UCHAR _80x50_crt_regs [MAX_CRT] = {        // 80x50 text mode
        0x5f, 0x4f, 0x50, 0x82, 0x55,             // cr0 - cr4
        0x81, 0xBF, 0x1f, 0x0,  0x47,             // cr9 - 7 lines per char
        0x20, 0x00, 0x00, 0x00, 0x00,             // cra - cursor off
        0x00, 0x9c, 0x8e, 0x8f, 0x28, 
        0x1f, 0x96, 0xb9, 0xa3, 0xff 
        };

static UCHAR _132x50_crt_regs [MAX_CRT] = {       // 132x50 text mode
        0xa0, 0x83, 0x84, 0x83, 0x8a,             // cr0 - cr4
        0x9e, 0xBF, 0x1f, 0x0,  0x47,             // cr9 - 7 lines per char
        0x20, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x9c, 0x85, 0x8f, 0x42, 
        0x1f, 0x95, 0xa5, 0xa3, 0xff 
        };

static UCHAR default_graph_regs[GRAPH_MAX] = 
        {
        0x00, 0x00, 0x00, 0x00, 0x00, 
        0x10, 0x0e, 0x00, 0xff
        };

static UCHAR default_pal_regs[MAX_PALETTE] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 
        0x05, 0x14, 0x7,  0x38, 0x39, 
        0x3A, 0x3B, 0x3C, 0x3d, 0x3e, 
        0x3f, 0x08, 0x00, 0x0f, 0x00, 
        0x00
        };

    int i;
    UCHAR byte;
 
   	// reset ATC FlipFlop
   	byte = READ_REGISTER_UCHAR(VGA_ATC_FF);
   	WRITE_REGISTER_UCHAR(VGA_ATC_DATA, 0); // Disable palette
     
    // stop the sequencer
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0100);

    if (TextMode == TEXT_132x50) {
        // external clock (40MHz)
        WRITE_REGISTER_UCHAR(VGA_MISC_WRITE, 0xAF);
    } else {
        // COLOR registers , enable RAM, 25 MHz (???) 400 Lines,  
		if (HalpVideoChip == VGA_P9100)	{
	        WRITE_REGISTER_UCHAR(VGA_MISC_WRITE, 0x67) ; // 28.322 Mhz
		} else {
	        WRITE_REGISTER_UCHAR(VGA_MISC_WRITE, 0x63) ; // 25,175 MHz (don't use with P9100).
		}
    }

    // Select the timing sequencer values
    // 8 dot/char

    WRITE_REGISTER_USHORT(VGA_SEQ_IDX,  0x0101);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX,  0x0302);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX,  0x0003);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX,  0x0204);

    // start the sequencer 
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX,  0x0300);

    // Unprotect CRT regs and program them 

    WRITE_REGISTER_USHORT(VGA_CRT_IDX , 0x0011);

    for(i=0; i<MAX_CRT; i++) {
        WRITE_REGISTER_UCHAR(VGA_CRT_IDX, i);
        if (TextMode == TEXT_132x50){
            WRITE_REGISTER_UCHAR(VGA_CRT_DATA, _132x50_crt_regs[i]);
        } else {
           	WRITE_REGISTER_UCHAR(VGA_CRT_DATA, _80x50_crt_regs[i]);
        }
    }

    DownLoadVGAFont();
    
    HalpDisplayWidth = (TextMode == TEXT_132x50) ? 132 : 80;
    HalpDisplayText  = 50;
        
    HalpClearVGADisplay();

    i = READ_REGISTER_UCHAR(VGA_ATC_FF);          // Reset attr FF

    if (!HalpFirstBoot) {
    
        //
        // if this is not the First Boot
        // i.e. an Bugcheck; we have to setup
        // the Attribute and colors of the VGA PART
        //

        for(i=0; i<GRAPH_MAX; i++) {
            WRITE_REGISTER_UCHAR(VGA_GRAPH_IDX , i);
            WRITE_REGISTER_UCHAR(VGA_GRAPH_DATA, default_graph_regs[i]);
        }
   
        for(i=0; i<MAX_PALETTE; i++) {                // PALETTE (ATC)
            WRITE_REGISTER_UCHAR(VGA_ATC_IDX , i);
            WRITE_REGISTER_UCHAR(VGA_ATC_DATA, default_pal_regs[i]);
        }

    }
    
    WRITE_REGISTER_UCHAR(VGA_DAC_MASK       , 0xff);

    //
    // set the 16 base colors for text mode in the DAC
    //

    WRITE_REGISTER_UCHAR(VGA_DAC_WRITE_INDEX, 0x00);
    for(i=0; i<48; i++) {
        WRITE_REGISTER_UCHAR(VGA_DAC_DATA, base_colors[i]);
    }

    WRITE_REGISTER_UCHAR(VGA_ATC_IDX, 0x20);

    WRITE_REGISTER_UCHAR(VGA_SEQ_IDX,  0x01);             // Screen on
    byte = READ_REGISTER_UCHAR(VGA_SEQ_DATA);
    WRITE_REGISTER_UCHAR(VGA_SEQ_DATA, (byte & 0xdf));    // in the sequencer
}
예제 #14
0
파일: snidisp.c 프로젝트: Gaikokujin/WinNT4
VOID
HalpVGASetup(
    VOID
    )
/*++

Routine Description:

    This routine initializes a VGA based Graphic card

Arguments:

    None.

Return Value:

    None.

--*/
{
    UCHAR  byte;


    switch (HalpVideoBoard){
        case S3_GENERIC_VLB:
        case CIRRUS_GENERIC_VLB:
        case VGA_GENERIC_VLB:
		case P9100_WEITEK:
//
// N.B.
// on an SNI desktop model the VL I/O space is transparent, so 
// acces in the normal Backplane area results in correct values
// the minitower instead, does not decode all VL signals  correct,
// so ther is an EXTRA I/O space for accessing VL I/O (0x1exxxxxx)
// this is handled in the definition of VESA_IO in SNIdef.h
//

            HalpVGAControlBase = (HalpIsRM200) ? (PVOID)HalpEisaControlBase : (PVOID)VESA_IO;
            VideoBuffer = ( PUSHORT)( VESA_BUS + 0xb8000);
            FontBuffer  = ( PUCHAR )( VESA_BUS + 0xa0000);

            break;

        case CIRRUS_ONBOARD:
            HalpVGAControlBase = (PVOID)HalpOnboardControlBase;
            VideoBuffer = ( PUSHORT)( RM200_ONBOARD_MEMORY + 0xb8000);
            FontBuffer  = ( PUCHAR )( RM200_ONBOARD_MEMORY + 0xa0000);
            break;

        case S3_GENERIC:
        case CIRRUS_GENERIC:
        case VGA_GENERIC:
        default:
            HalpVGAControlBase = (PVOID)HalpEisaControlBase;
            VideoBuffer = ( PUSHORT)( EISA_MEMORY_BASE + 0xb8000);
            FontBuffer  = ( PUCHAR )( EISA_MEMORY_BASE + 0xa0000);
            break;       
    }



    //
    // if "only" VGA is detected look for an S3 or cirrus chip (VGA ON ATBUS)
    // if the firmware detects an S3 chip, look if this is an 805i (interleave)
    //
    

    if ((HalpVideoChip == VGA) || (HalpVideoChip == S3)){
        WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x1206);               // look for Cirrus chips
        byte = READ_REGISTER_UCHAR(VGA_SEQ_DATA);                 // read it back
        if (byte != 0x12) {                                       // no cirrus
            WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x4838);           // unlock the S3 regs
            WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xa539);           // Unlock the SC regs
            WRITE_REGISTER_UCHAR(VGA_CRT_IDX, 0x30);              // look for s3 chip id
            byte = READ_REGISTER_UCHAR(VGA_CRT_DATA) ;            // look only for major id
            switch (byte & 0xf0){  
                case 0xa0:                                        // 801/805 chipset
                           if (byte == 0xa8) {                    // the new 805i (interleave)
//                             DebugPrint(("HAL: Found the new 805i Chip resetting to 805 mode\n"));
                               WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0053);
                               WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0067);
                           }
                case 0x80:
                case 0x90:
//                         DebugPrint(("HAL: Found S3 Chip set - Chip id 0x%x\n",byte));
                           HalpVideoChip = S3;
                           WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0038); // lock s3 regs
                           WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0039); // lock more s3 regs
                           break;
                default:   DebugPrint(("HAL: This seems to be no S3 Chip\n"));
            }
        } else {                                                   // this may be an cirrus
            WRITE_REGISTER_UCHAR(VGA_CRT_IDX, 0x27);               // cirrus id reg
            byte = READ_REGISTER_UCHAR(VGA_CRT_DATA);
            if ((byte & 0xe0) == 0x80) {                           // look for 100xxxxx
//              DebugPrint(("HAL: Found Cirrus Chip set - Chip id 0x%x\n",byte));
                HalpVideoChip = CIRRUS;
                WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0006);        // lock Cirrus extensions
            }
        }
    }


    switch (HalpVideoChip) {

        case VGA_P9000:  
                      HalpResetP9000();

                      //
                      // we have programmed the clock into register 0 of the ICD2061, so 
                      // select it via the VGA_MISC register
                      //

//                      WRITE_REGISTER_UCHAR(VGA_MISC_WRITE, 0xa3);
                      break;

        case S3:      HalpResetS3Chip();
                      break;    

        case CIRRUS:  HalpResetCirrusChip();
                      break;
   
        case VGA_P9100:  
                      HalpResetP9100();
                      break;
   
        default:      ;
    }

    HalpInitializeVGADisplay(TEXT_80x50);

    //
    // Initialize the current display column, row, and ownership values.
    //

    HalpColumn = 0;
    HalpRow = 0;
    HalpDisplayOwnedByHal = TRUE;
    return;
}
예제 #15
0
VOID
KdpWriteIoSpace (
    IN PDBGKD_MANIPULATE_STATE m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a write io space state
    manipulation message.  Its function is to write to system io
    locations.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo;
    STRING MessageHeader;
    PUCHAR b;
    PUSHORT s;
    PULONG l;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    ASSERT(AdditionalData->Length == 0);

    m->ReturnStatus = STATUS_SUCCESS;

    //
    // Check Size and Alignment
    //

    switch ( a->DataSize ) {
        case 1:
            b = (PUCHAR)MmDbgWriteCheck(a->IoAddress);
            if ( b ) {
                WRITE_REGISTER_UCHAR(b,(UCHAR)a->DataValue);
            } else {
                m->ReturnStatus = STATUS_ACCESS_VIOLATION;
            }
            break;
        case 2:
            if ((ULONG)a->IoAddress & 1 ) {
                m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
            } else {
                s = (PUSHORT)MmDbgWriteCheck(a->IoAddress);
                if ( s ) {
                    WRITE_REGISTER_USHORT(s,(USHORT)a->DataValue);
                } else {
                    m->ReturnStatus = STATUS_ACCESS_VIOLATION;
                }
            }
            break;
        case 4:
            if ((ULONG)a->IoAddress & 3 ) {
                m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
            } else {
                l = (PULONG)MmDbgWriteCheck(a->IoAddress);
                if ( l ) {
                    WRITE_REGISTER_ULONG(l,a->DataValue);
                } else {
                    m->ReturnStatus = STATUS_ACCESS_VIOLATION;
                }
            }
            break;
        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
    }

    KdpSendPacket(
        PACKET_TYPE_KD_STATE_MANIPULATE,
        &MessageHeader,
        NULL
        );
}
예제 #16
0
파일: hwlcd.c 프로젝트: GYGit/reactos
VOID
NTAPI
LlbHwOmap3LcdInitialize(VOID)
{
    /*
     * N.B. The following initialization sequence took about 12 months to figure
     *      out.
     *      This means if you are glancing at it and have no idea what on Earth
     *      could possibly be going on, this is *normal*.
     *      Just trust that this turns on the LCD.
     *      And be thankful all you ever have to worry about is Java and HTML.
     */

    /* Turn on the functional and interface clocks in the entire PER domain */
    WRITE_REGISTER_ULONG(0x48005000, 0x3ffff);  /* Functional clocks */
    WRITE_REGISTER_ULONG(0x48005010, 0x3ffff);  /* Interface clocks */

    /* Now that GPIO Module 3 is on, send a reset to the LCD panel on GPIO 96 */
    WRITE_REGISTER_ULONG(0x49054034, 0);             /* FIXME: Enable all as output */
    WRITE_REGISTER_ULONG(0x49054094, 0xffffffff);    /* FIXME: Output on all gpios */

    /* Now turn on the functional and interface clocks in the CORE domain */
    WRITE_REGISTER_ULONG(0x48004a00, 0x03fffe29); /* Functional clocks */
    WRITE_REGISTER_ULONG(0x48004a10, 0x3ffffffb); /* Interface clocks */
    
    /* The HS I2C interface is now on, configure it */
    WRITE_REGISTER_USHORT(0x48070024, 0x0);    /* Disable I2c */
    WRITE_REGISTER_USHORT(0x48070030, 0x17);   /* Configure clock divider */
    WRITE_REGISTER_USHORT(0x48070034, 0xd);    /* Configure clock scaler */
    WRITE_REGISTER_USHORT(0x48070038, 0xf);    /* Configure clock scaler */
    WRITE_REGISTER_USHORT(0x48070020, 0x215);  /* Configure clocks and idle */
    WRITE_REGISTER_USHORT(0x4807000c, 0x636f); /* Select wakeup bits */
    WRITE_REGISTER_USHORT(0x48070014, 0x4343); /* Disable DMA */
    WRITE_REGISTER_USHORT(0x48070024, 0x8000); /* Enable I2C */
    
    /*
     * Set the VPLL2 to cover all device groups instead of just P3.
     * This essentially enables the VRRTC to power up the LCD panel.
     */
    LlbHwOmap3TwlWrite1(0x4B, 0x8E, 0xE0);

    /* VPLL2 runs at 1.2V by default, so we need to reprogram to 1.8V for DVI */
    LlbHwOmap3TwlWrite1(0x4B, 0x91, 0x05);

    /* Set GPIO pin 7 on the TWL4030 as an output pin */
    LlbHwOmap3TwlWrite1(0x49, 0x9B, 0x80);

    /* Set GPIO pin 7 signal on the TWL4030 ON. This powers the LCD backlight */
    LlbHwOmap3TwlWrite1(0x49, 0xA4, 0x80);
   
    /* Now go on the McSPI interface and program it on for the channel */
    WRITE_REGISTER_ULONG(0x48098010, 0x15);
    WRITE_REGISTER_ULONG(0x48098020, 0x1);
    WRITE_REGISTER_ULONG(0x48098028, 0x1);
    WRITE_REGISTER_ULONG(0x4809802c, 0x112fdc);

    /* Send the reset signal (R2 = 00h) to the NEC WVGA LCD Panel */
    WRITE_REGISTER_ULONG(0x48098034, 0x1);
    WRITE_REGISTER_ULONG(0x48098038, 0x20100);
    WRITE_REGISTER_ULONG(0x48098034, 0x0);

    /* Turn on the functional and interface clocks in the DSS domain */
    WRITE_REGISTER_ULONG(0x48004e00, 0x5);
    WRITE_REGISTER_ULONG(0x48004e10, 0x1);

    /* Reset the Display Controller (DISPC) */
    WRITE_REGISTER_ULONG(0x48050410, 0x00000005); // DISPC_SYSCONFIG
    
    /* Set the frame buffer address */
	WRITE_REGISTER_ULONG(0x48050480, 0x800A0000); // DISPC_GFX_BA0

	/* Set resolution and RGB16 color mode */
	WRITE_REGISTER_ULONG(0x4805048c, 0x01df031f); // DISPC_GFX_SIZE
	WRITE_REGISTER_ULONG(0x480504a0, 0x0000000d); // DISPC_GFX_ATTRIBUTES

    /* Set LCD timings (VSync and HSync), pixel clock, and LCD size */
	WRITE_REGISTER_ULONG(0x4805046c, 0x00003000); // DISPC_POL_FREQ
	WRITE_REGISTER_ULONG(0x48050470, 0x00010004); // DISPC_DIVISOR
	WRITE_REGISTER_ULONG(0x48050464, 0x00300500); // DISPC_TIMING_H
	WRITE_REGISTER_ULONG(0x48050468, 0x00400300); // DISPC_TIMING_V
	WRITE_REGISTER_ULONG(0x4805047c, 0x01df031f); // DISPC_SIZE_LCD

    /* Turn the LCD on */
	WRITE_REGISTER_ULONG(0x48050440, 0x00018309); // DISPC_CONTROL
}
예제 #17
0
BOOLEAN
HalHandleNMI(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext
    )
/*++

Routine Description:

   This function is called when an EISA NMI occurs.  It prints the 
   appropriate status information and bugchecks.

Arguments:

   Interrupt - Supplies a pointer to the interrupt object

   ServiceContext - Bug number to call bugcheck with.

Return Value:

   Returns TRUE.

--*/
{
    LEGO_SRV_MGMT  SmRegister;
    UCHAR   NmiControl, NmiStatus;
    BOOLEAN GotSerr, GotIochk, GotSmFan, GotSmTemp, GotHalt;
    
    NMIcount++;

#if DBG
    if (NMIcount<5) {
        DbgPrint("II<NMI><");
    }
    if (NMIcount % 100 == 0) {
        DbgPrint("II<NMI><%08x><", NMIcount);
    }
#endif

    GotSerr = GotIochk = GotSmFan = GotSmTemp = GotHalt = FALSE;

    //
    // Set the Eisa NMI disable bit. We do this to mask further NMI 
    // interrupts while we're servicing this one.
    //
    NmiControl = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 1;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);

#ifdef DBG
    DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
#endif

    NmiStatus =
        READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);

    if (NmiStatus & 0x80) {
        GotSerr = TRUE;

#ifdef DBG
        DbgPrint("HalHandleNMI: Parity Check / Parity Error\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
#endif
        HalAcquireDisplayOwnership(NULL);
        HalDisplayString ("NMI: Parity Check / Parity Error\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }

    if (NmiStatus & 0x40) {
        GotIochk = TRUE;
#ifdef DBG
        DbgPrint("HalHandleNMI: Channel Check / IOCHK\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
#endif
        HalAcquireDisplayOwnership(NULL);
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }

    // Read server management register
    //  Events that can be reported as NMI are:
    //      Enclosure temperature too high
    //      CPU Fan failure
    //
    // For now, generate a bugcheck.
    // [wem] Future: perform secondary dispatch to give
    //       driver shot at reporting problem.
    //
    SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );

    GotSmFan = SmRegister.CpuFanFailureNmi == 1;
    GotSmTemp = SmRegister.EnclTempFailureNmi == 1;

    if (GotSmFan || GotSmTemp) {

#ifdef DBG
        DbgPrint("HalHandleNMI: Server management NMI\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
        DbgPrint("HalHandleNMI:    Server Management Status = 0x%x\n", SmRegister);
#endif

        //
        // If secondary dispatch enabled, do it now.
        //
#if 0
        if (HalpLegoDispatchNmi
            && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[SM_ERROR_VECTOR])(
                    PCR->InterruptRoutine[SM_ERROR_VECTOR],
                    TrapFrame)
           ) {
            return TRUE;
        }
#endif

        //
        // Build uncorrectable error frame and 
        // prepare for orderly shutdown
        //
        // The delayed shutdown depends on watchdog timer support
        // A power off cannot be directly done since KeBugChk() turns
        // off interrupts, so there's no way to get control back.
        //
        // WARNING: Pick a delay that allows a dump to complete.
        //

        LegoServerMgmtReportFatalError(SmRegister.All);
        LegoServerMgmtDelayedShutdown(8);                  // Issue reset in 8 seconds

        HalAcquireDisplayOwnership(NULL);

        HalDisplayString ("NMI: Hardware Failure -- ");
        HalDisplayString ((SmRegister.CpuFanFailureNmi==1) ? "CPU fan failed."
                                                           : "Enclosure termperature too high.");
        HalDisplayString ("\nSystem Power Down will be attempted in 8 seconds...\n\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }


    // 
    // Halt button was hit.
    //
    // [wem] Perform second-level dispatch here too?
    //
    if (!GotSerr && !GotIochk && !GotSmFan && !GotSmTemp) {

        //
        // If secondary dispatch enabled, do it now.
        //
#if 0
        if (HalpLegoDispatchHalt
            && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[HALT_BUTTON_VECTOR])(
                    PCR->InterruptRoutine[HALT_BUTTON_VECTOR],
                    TrapFrame)
           ) {
            return TRUE;
        }
#endif

        GotHalt = TRUE;
        HalDisplayString ("NMI: Halt button pressed.\n");

        if (HalpHaltButtonBreak) {
            DbgBreakPoint();
        }

        return (TRUE);
    }

    //
    // Clear and re-enable SERR# and IOCHK#, then re-enable NMI
    //

#ifdef DBG
    DbgPrint("HalHandleNMI: Shouldn't get here!\n");
#endif

    if (GotSerr) {
#ifdef DBG
        DbgPrint("HalHandleNMI: Resetting SERR#; NMI count = %d\n", NMIcount);
#endif
        //
        // Reset SERR# (and disable it), then re-enable it.
        //
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x04);
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
    }

    if (GotIochk) {
#ifdef DBG
        DbgPrint("HalHandleNMI: Resetting IOCHK#; NMI count = %d\n", NMIcount);
#endif
        //
        // Reset IOCHK# (and disable it), then re-enable it.
        //
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x08);
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
    }

    if (GotSmFan || GotSmTemp) {
        //
        // Reset Server management condition.
        //
        // Interrupt must be cleared or the NMI will continue
        // to occur.
        //
        SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
        if (GotSmFan) {
            SmRegister.CpuFanFailureNmi = 1;
        }
        else {
            SmRegister.EnclTempFailureNmi = 1;
        }
        WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
    }

    //
    // Clear the Eisa NMI disable bit. This re-enables NMI interrupts,
    // now that we're done servicing this one.
    //
    NmiControl = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 0;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);
#ifdef DBG
    DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
#endif

    return(TRUE);
}
예제 #18
0
파일: card.c 프로젝트: BillTheBest/WinNT4
VOID
CardPrepareTransmit(
    IN PHTDSU_ADAPTER       Adapter,
    IN USHORT               CardLine,    /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
    IN USHORT               BytesToSend
    )

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Functional Description:

    This routine will write the packet header information into the
    transmit buffer.  This assumes that the controller has notified the
    driver that the transmit buffer is empty.

Parameters:

    Adapter _ A pointer ot our adapter information structure.

    CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).

    BytesToSend _ Number of bytes to transmit.

Return Values:

    None

---------------------------------------------------------------------------*/

{
    DBG_FUNC("CardPrepareTransmit")

    DBG_ENTER(Adapter);

    ASSERT((CardLine==HTDSU_CMD_LINE1) || (CardLine==HTDSU_CMD_LINE2));
    ASSERT(READ_REGISTER_USHORT(&Adapter->AdapterRam->TxDataEmpty));
    ASSERT(BytesToSend > 0);

    /*
    // Tell the adapter how many bytes are to be sent, and which line to use.
    */
    WRITE_REGISTER_USHORT(
            &Adapter->AdapterRam->TxBuffer.Address,
            (USHORT) (CardLine - HTDSU_CMD_LINE1)
            );
    WRITE_REGISTER_USHORT(
            &Adapter->AdapterRam->TxBuffer.Length,
            BytesToSend
            );

    /*
    // Mark the end of packet and end of packet list.
    */
    WRITE_REGISTER_USHORT(
            &Adapter->AdapterRam->TxBuffer.Data[(BytesToSend+1)/sizeof(USHORT)],
            HTDSU_DATA_TERMINATOR
            );
    WRITE_REGISTER_USHORT(
            &Adapter->AdapterRam->TxBuffer.Data[(BytesToSend+3)/sizeof(USHORT)],
            HTDSU_DATA_TERMINATOR
            );

    DBG_LEAVE(Adapter);
}
예제 #19
0
VOID
HalpAcknowledgeClockInterrupt(
    VOID
    )
/*++

Routine Description:

    Acknowledge the clock interrupt from the interval timer.  The interval
    timer for Lego comes from the Dallas real-time clock.

Arguments:

    None.

Return Value:

    None.

--*/
{
    LEGO_WATCHDOG  WdRegister;
    
    static LEGO_WATCHDOG WdRegisterDbg;
    static ULONG DbgWdCnt = 0;
    static ULONG WdNextService = 0;
    static BOOLEAN WdIntervalSet = FALSE;
     
    //
    // Make watchdog service interval a function of the timer period.
    //
    
#if 1
    static ULONG WdServiceIntervals[8] = {1, 1, 5, 15, 100, 600, 3000, 20000};
#else
    static ULONG WdServiceIntervals[8] = {1, 1, 1, 1, 1, 1, 1, 1};
#endif

    //
    // Acknowledge the clock interrupt by reading the control register C of
    // the Real Time Clock.
    //

    HalpReadClockRegister( RTC_CONTROL_REGISTERC );

    //
    // If we are to service the Watchdog Timer, do it here
    //
    // Setting Phase to one will restart the timer...
    // [wem] this needs more work. For example, no need to touch it each clock tick!...
    //

    if (HalpLegoServiceWatchdog) {

        if (WdNextService==0) {

            //
            // read register to get service interval
            //

            WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );
            WdNextService = WdServiceIntervals[WdRegister.TimerOnePeriod];

#if DBG
            if (!WdIntervalSet) {
                DbgPrint(" <Watchdog:%04x> ",WdRegister.All);
                DbgPrint(" <WdInterval:%d> ",WdNextService);
                WdRegisterDbg.All = WdRegister.All;
                WdIntervalSet = TRUE;
            }
#endif
        }

        WdNextService--;

        //
        // If service interval falls to zero, read register to service timer
        //

        if (WdNextService==0) {

            WdRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva );

#if DBG

            if (WdRegisterDbg.All != WdRegister.All) {
                WdRegisterDbg.All = WdRegister.All;
                DbgWdCnt = 0;
            }

            if (DbgWdCnt < 2) {
                DbgPrint(" <Watchdog:%04x> ",WdRegister.All);
            }

            if ((DbgWdCnt % 10000)==0) {
                DbgPrint(" <Watchdog:%04x> ",WdRegister.All);
                DbgWdCnt = 1;
            }

            DbgWdCnt++;
#endif

            // 
            // Reset the timer. This is done by writing 1 then 0
            // to the Watchdog register's Phase bit
            //
            // If LegoDebugWatchdogIsr is true, let watchdog timer expire.
            // This will result in a watchdog interrupt or a system reset 
            // depending on the watchdog mode.
            //

            if (!LegoDebugWatchdogIsr) {
#if 0
                if (HalpLegoWatchdogSingleMode) {
                    WdRegister.Mode = WATCHDOG_MODE_1TIMER;
                }
#endif
                WdRegister.Phase = 1;
                WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All);
                WdRegister.Phase = 0;
                WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoWatchdogQva, WdRegister.All);
            }
        }
    }
}
예제 #20
0
VOID
HalDisableSystemInterrupt (
    IN ULONG Vector,
    IN KIRQL Irql
    )

/*++

Routine Description:

    This routine disables the specified system interrupt.

Arguments:

    Vector - Supplies the vector of the system interrupt that is disabled.

    Irql - Supplies the IRQL of the interrupting source.

Return Value:

    None.

--*/

{

    KIRQL OldIrql;

    //
    // Raise IRQL to the highest level and acquire device enable spinlock.
    //

    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    KiAcquireSpinLock(&HalpSystemInterruptLock);

    //
    // If the vector number is within the range of builtin devices, then
    // disable the builtin device interrupt.
    //

    if ((Vector >= (DEVICE_VECTORS + 1)) && (Vector <= MAXIMUM_BUILTIN_VECTOR)) {
        HalpBuiltinInterruptEnable &= ~(1 << (Vector - DEVICE_VECTORS - 1));

#if defined(_R94A_)

        if ( READ_REGISTER_ULONG(&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ASIC3Revision.Long) == 0 ){

            //
            // The bit assign of TYPHOON(in STORM chipset)'s I/O Device Interrupt
            // Enable register is zero origin.
            // 
            // N.B. This obstruction is limiteded to beta-version of STORM chipset.
            //

            WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Fill,
                              HalpBuiltinInterruptEnable);
        } else {

            WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable,
                              HalpBuiltinInterruptEnable);
        }

#else

        WRITE_REGISTER_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable,
                              HalpBuiltinInterruptEnable);

#endif

    }

    //
    // If the vector number is within the range of the EISA interrupts, then
    // disable the EISA interrrupt.
    //

    if (Vector >= EISA_VECTORS &&
        Vector < EISA_VECTORS + MAXIMUM_EISA_VECTOR &&
        Irql == EISA_DEVICE_LEVEL) {
        HalpDisableEisaInterrupt(Vector);
    }

#if defined(_R94A_)

    //
    // If the vector number is within the range of the PCI interrupts, then
    // disable the PCI interrrupt.
    //

    if (Vector >= PCI_VECTORS &&
        Vector <= PCI_VECTORS + R94A_PCI_SLOT &&
        Irql == EISA_DEVICE_LEVEL) {
        HalpDisablePCIInterrupt(Vector);
    }

#endif

    //
    // Release the device enable spin loc and lower IRQL to the previous level.
    //

    KiReleaseSpinLock(&HalpSystemInterruptLock);
    KeLowerIrql(OldIrql);
    return;
}
예제 #21
0
파일: snidisp.c 프로젝트: Gaikokujin/WinNT4
VOID
HalpResetS3Chip(
    VOID
    )
/*+++
  
   This function resets/loads default values to the S3 Chip
   extended registers

   this code is borrowed/derived from the s3 miniport driver

---*/
{
    UCHAR byte;

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x4838);           // unlock the S3 regs
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xa539);           // Unlock the SC regs

    WRITE_REGISTER_UCHAR(VGA_SEQ_IDX,  0x01);             // Screen off
    byte = READ_REGISTER_UCHAR(VGA_SEQ_DATA);
    WRITE_REGISTER_UCHAR(VGA_SEQ_DATA, (byte | 0x20));    // stop the sequencer

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0140);           // Enable the enhanced 8514 registers
    WRITE_REGISTER_USHORT(S3_ADVFUNC_CNTL, 0x02);         // reset to normal VGA operation

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0032);           // Backward Compat 3
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0035);           // CRTC Lock

    WRITE_REGISTER_UCHAR(VGA_SEQ_IDX,  0x00);             // async reset
    WRITE_REGISTER_UCHAR(VGA_SEQ_DATA, 0x01);             //
 
    WRITE_REGISTER_UCHAR(VGA_FEAT_CNTRL, 0x00);           // normal sync
    WRITE_REGISTER_UCHAR(VGA_MISC_READ,  0x00);            //

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x8531); 
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x2033);           // Backward Compat 2
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0034);           // Backward Compat 3
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x853a);           // S3 Misc 1
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x5a3b);           // Data Transfer Exec Pos
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x103c);           // Interlace Retrace start

    WRITE_REGISTER_UCHAR(VGA_SEQ_IDX,  0x00);             // start the sequencer
    WRITE_REGISTER_UCHAR(VGA_SEQ_DATA, 0x03);             //
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xa640);           // VLB: 3Wait 
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x1841);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0050);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0051);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff52);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0053);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x3854);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0055);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0056);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0057);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x8058);          // ISA Latch ? (bit 3)
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x005c);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x005d);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x005e);

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0760);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x8061);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xa162);

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0043);           // Extended Mode
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0045);           // HW graphics Cursor Mode
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0046);           // HW graphics Cursor Orig x
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff47);           // HW graphics Cursor Orig x
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xfc48);           // HW graphics Cursor Orig y
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff49);           // HW graphics Cursor Orig y
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff4a);           // HW graphics Cursor Orig y
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff4b);           // HW graphics Cursor Orig y
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff4c);           // HW graphics Cursor Orig y
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff4d);           // HW graphics Cursor Orig y
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xff4e);           // Dsp Start x pixel pos
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0xdf4f);           // Dsp Start y pixel pos

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0042);           // select default clock    

    WRITE_REGISTER_UCHAR(VGA_MISC_WRITE, 0x63);           // Clock select
/*
// this should be done in the InitializeVGA code ...

    WRITE_REGISTER_UCHAR(VGA_SEQ_IDX,  0x01);             // Screen on
    byte = READ_REGISTER_UCHAR(VGA_SEQ_DATA);
    WRITE_REGISTER_UCHAR(VGA_SEQ_DATA, (byte & 0xdf));    // in the sequencer
*/

    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0038);           // lock s3 regs
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x0039);           // lock more s3 regs

}