mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-19 21:30:04 +00:00
0ba83392d4
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
708 lines
14 KiB
C
708 lines
14 KiB
C
/*
|
|
File: PCIUtil.c
|
|
|
|
Contains: xxx put contents here xxx
|
|
|
|
Written by: xxx put writers here xxx
|
|
|
|
Copyright: © 1993 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Change History (most recent first):
|
|
|
|
<1> 11/5/93 fau first checked in
|
|
<1> 10/27/93 fau first checked in
|
|
<1> 10/19/93 fau first checked in
|
|
|
|
*/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: PrimaryInit.c
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 4/23/92
|
|
*
|
|
*Purpose: Main interface file for ATI video driver primary init.
|
|
*
|
|
*Category: Macintosh driver
|
|
*File: PrimaryInit.c
|
|
*
|
|
*Exports: main - Main entry point for primary init.
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*
|
|
* Includes
|
|
*
|
|
*-----------------------------------------------------------------------*/
|
|
|
|
#include <Types.h>
|
|
#include <Errors.h>
|
|
#include <OSUtils.h>
|
|
|
|
#include "ATIStdTypes.h"
|
|
#include "ATI.h"
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*
|
|
* Imported Procedures
|
|
*
|
|
*-----------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*
|
|
* Beginning of Procedure Definitions
|
|
*
|
|
*-----------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: PerformPCIHack
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/22/93
|
|
*
|
|
*Purpose: Does a read of the CPU ID for the PCI IO problem.
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: void
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
void
|
|
PerformPCIHack()
|
|
{
|
|
|
|
UInt8 *ioReg;
|
|
volatile UInt8 dumb;
|
|
|
|
// DebugStr("\pPerformPCIHack");
|
|
|
|
ioReg = (UInt8 *) kCPUIDReg;
|
|
dumb = *ioReg; // Read CPU ID for PCI hack
|
|
dumb = *ioReg; // Read CPU ID for PCI hack
|
|
|
|
} /* End of PerformPCIHack */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: LByteSwap
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/13/93
|
|
*
|
|
*Purpose: Does bytes swapping for endianess of 32 bits
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: UInt32
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
UInt32
|
|
LByteSwap(UInt32 theLong)
|
|
{
|
|
|
|
UInt32 Temp;
|
|
|
|
// DebugStr("\pLByteSwap");
|
|
|
|
Temp = ((theLong & 0x000000ff) << 24);
|
|
Temp += (((theLong >> 8) & 0x000000ff) << 16);
|
|
Temp += (((theLong >> 16) & 0x000000ff) << 8);
|
|
Temp += ((theLong >> 24) & 0x000000ff);
|
|
return(Temp);
|
|
|
|
} /* End of LByteSwap */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: WByteSwap
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/13/93
|
|
*
|
|
*Purpose: Does bytes swapping for endianess of 16 bits
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: UInt16
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
UInt16
|
|
WByteSwap(UInt16 theWord)
|
|
{
|
|
|
|
UInt16 Temp;
|
|
|
|
// DebugStr("\pWByteSwap");
|
|
|
|
Temp = ((theWord & 0x00ff) << 8);
|
|
Temp += ((theWord >> 8) & 0x00ff);
|
|
return(Temp);
|
|
|
|
} /* End of WByteSwap */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: IOByteWrite
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/13/93
|
|
*
|
|
*Purpose: Writes a byte to the specified IO register.
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: void
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
* 9/22/93 George W. Added PCI IO hack
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
void
|
|
IOByteWrite(UInt32 theReg, UInt8 theByte)
|
|
{
|
|
|
|
UInt8 *ioReg;
|
|
|
|
// DebugStr("\pIOByteWrite");
|
|
|
|
ioReg = (UInt8 *) theReg;
|
|
*ioReg = theByte;
|
|
|
|
PerformPCIHack();
|
|
|
|
} /* End of IOByteWrite */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: IOWordWrite
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/13/93
|
|
*
|
|
*Purpose: Writes a word to the specified IO register.
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: void
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
* 9/22/93 George W. Added PCI IO hack
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
void
|
|
IOWordWrite(UInt32 theReg, UInt16 theWord)
|
|
{
|
|
|
|
UInt16 *ioReg;
|
|
|
|
// DebugStr("\pIOWordWrite");
|
|
|
|
ioReg = (UInt16 *) theReg;
|
|
*ioReg = WByteSwap(theWord);
|
|
|
|
PerformPCIHack();
|
|
|
|
|
|
} /* End of IOWordWrite */
|
|
|
|
void IOLongWrite(unsigned long theReg, unsigned long bogus)
|
|
{
|
|
unsigned long *ioReg;
|
|
|
|
ioReg = (unsigned long *) theReg;
|
|
*ioReg = LByteSwap(bogus);
|
|
|
|
PerformPCIHack();
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: FindPCICard
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/13/93
|
|
*
|
|
*Purpose: Searches all PCI slots for the ATI graphics card.
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: UInt8
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
UInt8
|
|
FindPCICard(UInt16 *type)
|
|
{
|
|
UInt32 *configRegPtr;
|
|
UInt32 *dataRegPtr;
|
|
UInt32 data;
|
|
UInt32 someValue;
|
|
|
|
// DebugStr("\pFindPCICard");
|
|
|
|
configRegPtr = (UInt32 *) kConfigAddressReg;
|
|
dataRegPtr = (UInt32 *) kConfigDataReg;
|
|
|
|
someValue = kPCIVendorIDOffset | (kSecondPCISlot << 12);
|
|
*configRegPtr = LByteSwap(someValue); // Tell Bandit which device
|
|
data = LByteSwap(*dataRegPtr); // Get Vendor ID
|
|
|
|
if ( data == (kATIVendorID | (kATIDeviceID << 16)) ) {
|
|
*type = kATIVendorID;
|
|
return(kSecondPCISlot);
|
|
}
|
|
|
|
if ( data == (kDiamondVendorID | (kDiamondDeviceID << 16)) ) {
|
|
*type = kDiamondVendorID;
|
|
return(kSecondPCISlot);
|
|
}
|
|
|
|
return(0); // No card found
|
|
|
|
} /* End of FindPCICard */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: EnableIOAccess
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/13/93
|
|
*
|
|
*Purpose: Enables or disables PCI IO/Mem access for a specific PCI card.
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: OSErr
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
OSErr
|
|
EnableIOAccess(UInt8 devID, Boolean enable, UInt16 type)
|
|
{
|
|
#pragma unused (enable)
|
|
|
|
UInt32 *configRegPtr;
|
|
UInt8 *dataByteRegPtr;
|
|
UInt32 *dataLongRegPtr;
|
|
UInt32 someValue;
|
|
|
|
// DebugStr("\pEnableIOAccess");
|
|
|
|
configRegPtr = (UInt32 *) kConfigAddressReg;
|
|
dataByteRegPtr = (UInt8 *) kConfigDataReg;
|
|
dataLongRegPtr = (UInt32 *) kConfigDataReg;
|
|
|
|
someValue = (devID << 12) | kPCICommandOffset; // Set the PCI device
|
|
|
|
*configRegPtr = LByteSwap(someValue); // Tell Bandit which device
|
|
*dataByteRegPtr = 0x03; // Enable Memory accesses
|
|
|
|
if (type == kATIVendorID) {
|
|
someValue = (devID << 12) | kPCIBaseReg1Offset; // Set the PCI base address reg
|
|
*configRegPtr = LByteSwap(someValue); // Tell Bandit which device
|
|
*dataLongRegPtr = LByteSwap(kATIVRAMAddr); // Set VRAM address in PCI base reg
|
|
}
|
|
|
|
if (type == kDiamondVendorID) {
|
|
someValue = (devID << 12) | kPCIBaseReg1Offset; // Set the PCI base address reg
|
|
*configRegPtr = LByteSwap(someValue); // Tell Bandit which device
|
|
*dataLongRegPtr = LByteSwap(kDiamondVRAMAddr); // Set VRAM address in PCI base reg
|
|
|
|
someValue = (devID << 12) | kPCIBaseReg2Offset; // Set the PCI base address reg
|
|
|
|
*configRegPtr = LByteSwap(someValue); // Tell Bandit which device
|
|
*dataLongRegPtr = LByteSwap(kDiamondIOAddr); // Set IO base address in PCI base reg
|
|
}
|
|
|
|
return(noErr);
|
|
|
|
} /* End of EnableIOAccess */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*start
|
|
*
|
|
*Name: SlamRegisters
|
|
*Creator: George D. Wilson Jr.
|
|
*Date: 9/13/93
|
|
*
|
|
*Purpose: Set all needed ATI graphics registers.
|
|
*
|
|
*Category:
|
|
*File: PCIUtil.c
|
|
*
|
|
*Calls:
|
|
*
|
|
*Called By:
|
|
*
|
|
*Entry:
|
|
*
|
|
*Alters:
|
|
*
|
|
*Exit: OSErr
|
|
*
|
|
*Detailed:
|
|
*
|
|
*Algorithm:
|
|
*
|
|
*Note:
|
|
*
|
|
*History:
|
|
*
|
|
* Date Programmer Modification
|
|
* -------- ---------- -----------------------------------------
|
|
*
|
|
*stop
|
|
*-----------------------------------------------------------------------*/
|
|
OSErr
|
|
SlamRegisters(UInt8 devID)
|
|
{
|
|
IOLongWrite(0xF2800000, (devID << 12) | 4);
|
|
*(unsigned char *)(0xF2C00000) = 0x3;
|
|
PerformPCIHack();
|
|
|
|
IOByteWrite(PCI_CNTL, 0xFC);
|
|
IOByteWrite(kAPERTURE_CNTL, 0x4C);
|
|
|
|
IOByteWrite(kADVFUNC_CNTL, 0x01);
|
|
|
|
IOWordWrite(kMISC_OPTIONS, 0x70A8);
|
|
IOByteWrite(kADVFUNC_CNTL, 0x01);
|
|
IOWordWrite(kEXT_GE_CONFIG, 0x4010);
|
|
|
|
IOWordWrite(kSUBSYS_CNTL, kRESET_GE);
|
|
IOWordWrite(kSUBSYS_CNTL, kNORMAL_GE);
|
|
|
|
ATIWaitForIdle();
|
|
|
|
IOWordWrite(kCLOCK_SEL, 0x1251);
|
|
|
|
ATIReset68800();
|
|
ATIWaitForIdle();
|
|
|
|
//====================================
|
|
// DAC Stuff
|
|
//====================================
|
|
// IOWordWrite(kEXT_GE_CONFIG,0x1000);
|
|
// IOWordWrite(kDAC_MASK,0x03);
|
|
// IOWordWrite(kEXT_GE_CONFIG,0x2000);
|
|
// IOWordWrite(kDAC_R_INDEX,0x00);
|
|
// IOWordWrite(kEXT_GE_CONFIG,0x3000);
|
|
// IOWordWrite(kDAC_W_INDEX,0x2D);
|
|
// IOWordWrite(kEXT_GE_CONFIG,0x0000);
|
|
// IOWordWrite(kDAC_MASK,0xFF);
|
|
#if 0
|
|
IOByteWrite(kH_TOTAL,0x63);
|
|
IOByteWrite(kH_DISP,0x4F);
|
|
IOByteWrite(kH_SYNC_STRT,0x52);
|
|
IOByteWrite(kH_SYNC_WID,0x2C);
|
|
IOWordWrite(kV_TOTAL,0x0418);
|
|
IOWordWrite(kV_DISP,0x03BF);
|
|
IOWordWrite(kV_SYNC_STRT,0x03DF);
|
|
IOWordWrite(kV_SYNC_WID,0x0022);
|
|
#endif
|
|
|
|
ATISetSyncRegisters();
|
|
ATIWaitForIdle();
|
|
|
|
IOByteWrite(kDISP_CNTL,0x23); // 0x22
|
|
|
|
IOWordWrite(kHORIZONTAL_OVERSCAN, 0);
|
|
IOWordWrite(kVERTICAL_OVERSCAN, 0);
|
|
IOWordWrite(kOVERSCAN_COLOR_8_BLUE, 0);
|
|
IOWordWrite(kOVERSCAN_COLOR_GREEN_RED, 0);
|
|
|
|
IOByteWrite(kSHADOW_CTL, 0x7F);
|
|
IOByteWrite(kSHADOW_SET, 0);
|
|
|
|
IOWordWrite(kMULTIFUNC_CNTL, kSCISSOR_TOP | 0);
|
|
IOWordWrite(kMULTIFUNC_CNTL, kSCISSOR_LEFT | 0);
|
|
IOWordWrite(kMULTIFUNC_CNTL, kSCISSOR_BOTTOM | 0x5FF);
|
|
IOWordWrite(kMULTIFUNC_CNTL, kSCISSOR_RIGHT | 0x5FF);
|
|
|
|
IOWordWrite(kSRC_Y_DIR, 1);
|
|
IOWordWrite(kWRT_MASK, 0xFFFF);
|
|
IOWordWrite(kDEST_CMP_FN, 0);
|
|
|
|
IOWordWrite(kDP_CONFIG, kDP_CONFIG_WRITE |
|
|
kDP_CONFIG_POLY_FILL_DISABLE |
|
|
kDP_CONFIG_READ_MODE_COLOR_DATA |
|
|
kDP_CONFIG_ENABLE_DRAW |
|
|
kDP_CONFIG_MONO_SRC_ALWAYS1 |
|
|
kDP_CONFIG_BG_COLOR_SRC_BG |
|
|
kDP_CONFIG_DATA_WIDTH_16 |
|
|
kDP_CONFIG_MSB_FIRST |
|
|
kDP_CONFIG_FG_COLOR_SRC_FG);
|
|
|
|
IOWordWrite(kFRGD_MIX, kCOLOR_SRC_FG |
|
|
kMIX_FN_S);
|
|
|
|
// IOWordWrite(0x7AEE + ATIIOBase,0x4010);
|
|
|
|
IOLongWrite(0xF2800000, (devID << 12) | 4);
|
|
*(unsigned char *)(0xF2C00000) = 0x2;
|
|
PerformPCIHack();
|
|
|
|
return(noErr);
|
|
|
|
} /* End of SlamRegisters */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*
|
|
* End of Module
|
|
*
|
|
*-----------------------------------------------------------------------*/
|
|
|
|
void ATIReset68800 (void)
|
|
{
|
|
IOWordWrite(kCRT_OFFSET_LOW, 0);
|
|
IOWordWrite(kCRT_OFFSET_HIGH, 0);
|
|
IOWordWrite(kCRT_PITCH, 0x80);
|
|
IOWordWrite(kGE_OFFSET_LOW, 0);
|
|
IOWordWrite(kGE_OFFSET_HIGH, 0);
|
|
IOWordWrite(kGE_PITCH, 0x80);
|
|
IOWordWrite(kHORIZONTAL_OVERSCAN, 0);
|
|
IOWordWrite(kVERTICAL_OVERSCAN, 0);
|
|
IOWordWrite(kOVERSCAN_COLOR_8_BLUE, 0);
|
|
IOWordWrite(kOVERSCAN_COLOR_GREEN_RED, 0);
|
|
IOWordWrite(kCURSOR_OFFSET_HIGH, 0);
|
|
IOWordWrite(kDAC_MASK, 0xFF);
|
|
}
|
|
|
|
void ATISetSyncRegisters (void)
|
|
{
|
|
#if 0
|
|
IOByteWrite(kH_TOTAL,0x63);
|
|
IOByteWrite(kH_DISP,0x4F);
|
|
IOByteWrite(kH_SYNC_STRT,0x52);
|
|
IOByteWrite(kH_SYNC_WID,0x2C);
|
|
IOWordWrite(kV_TOTAL,0x0418);
|
|
IOWordWrite(kV_DISP,0x03BF);
|
|
IOWordWrite(kV_SYNC_STRT,0x03DF);
|
|
IOWordWrite(kV_SYNC_WID,0x0022);
|
|
#endif
|
|
|
|
IOByteWrite(kH_TOTAL, 0x63);
|
|
IOByteWrite(kH_DISP, 0x4F);
|
|
IOByteWrite(kH_SYNC_STRT, 0x52);
|
|
IOByteWrite(kH_SYNC_WID, 0x2C);
|
|
|
|
IOWordWrite(kV_TOTAL, 0x0418);
|
|
IOWordWrite(kV_DISP, 0x03BF);
|
|
IOWordWrite(kV_SYNC_STRT, 0x03DF); // 0x03D6
|
|
IOWordWrite(kV_SYNC_WID, 0x0022);
|
|
}
|
|
|
|
void ATIFix688111Bug (void)
|
|
{
|
|
unsigned char clockSelect;
|
|
short cx;
|
|
|
|
clockSelect = *(unsigned char *)kCLOCK_SELECT;
|
|
clockSelect |= 1;
|
|
IOByteWrite(kCLOCK_SELECT, clockSelect);
|
|
|
|
ATIWaitForIdle();
|
|
|
|
/* set all pixel clock values to fix bug in 18811 clock chip */
|
|
for (cx = 0; cx < 16; cx++) {
|
|
clockSelect = (cx << 2) | 0x1;
|
|
IOByteWrite(kCLOCK_SELECT, clockSelect);
|
|
}
|
|
|
|
IOWordWrite(kCLOCK_SELECT,
|
|
kCLOCK_SELECT_ENABLE_8514 |
|
|
kCLOCK_SELECT_FREQ(4) |
|
|
kCLOCK_SELECT_DIV_2 |
|
|
kCLOCK_SELECT_FIFO_DEPTH(2) |
|
|
kCLOCK_SELECT_COMPOSITE_SYNC);
|
|
}
|
|
|
|
long ATIWaitForIdle (void)
|
|
{
|
|
unsigned long loopCount;
|
|
unsigned char fifoBusy;
|
|
unsigned char geBusy;
|
|
|
|
loopCount = 0xFFFF;
|
|
fifoBusy = *(unsigned char *)kEXT_FIFO_STATUS;
|
|
while (loopCount > 0 && fifoBusy & 1) {
|
|
fifoBusy = *(unsigned char *)kEXT_FIFO_STATUS;
|
|
loopCount--;
|
|
}
|
|
|
|
if (loopCount == 0) {
|
|
return 0;
|
|
}
|
|
|
|
loopCount = 0xFFFF;
|
|
geBusy = *(unsigned char *)kGE_STAT_BUSY;
|
|
while (loopCount > 0 && geBusy & kGE_BUSY) {
|
|
geBusy = *(unsigned char *)kGE_STAT_BUSY;
|
|
loopCount--;
|
|
}
|
|
|
|
if (loopCount == 0) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|