Jump to content

ATI Framebuffer development


Slice
 Share

466 posts in this topic

Recommended Posts

Your log shows that all information can be fetched from BIOS or injected without problem. Now comes the real issue, how to use them to drive the card in OSX.

My real issue is step before. I have mixture of sources with different structures

struct fb_var_screeninfo {
...
struct fb_videomode {
...
typedef struct _ScrnInfoRec {
....
/* Video mode */
typedef struct _DisplayModeRec {

Old procedures work fine with old structures and new with new. :D

When I resolve all contradictions I begin to study how to drive the card.

 

Next week I am going to vacancy and will be absent up to middle of september.

Hope you will have some success during the time.

Link to comment
Share on other sites

I probably found new problem.

The linux sources adjust different radeon registers for different monitor output

   switch(radeon_output->MonType) {
	case MT_LCD:
		ErrorF("restore LVDS\n");
		RADEONRestoreLVDSRegisters(pScrn, info->ModeReg);
		break;
	case MT_DFP:
		if (radeon_output->TMDSType == TMDS_INT) {
			ErrorF("restore FP\n");
			RADEONRestoreFPRegisters(pScrn, info->ModeReg);
		} else {
			ErrorF("restore FP2\n");
			if (info->IsAtomBios) {
				unsigned char *RADEONMMIO = info->MMIO;
				uint32_t fp2_gen_cntl;

				atombios_external_tmds_setup(output, mode);
				/* r4xx atom has hard coded crtc mappings in the atom code
					* Fix it up here.
					*/
				fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & 
~R200_FP2_SOURCE_SEL_MASK;
				if (radeon_crtc->crtc_id == 1)
					fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
				else {
					if (radeon_output->Flags & RADEON_USE_RMX)
						fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
					else
						fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
				}
				OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
			} else {
				RADEONRestoreDVOChip(pScrn, output);
				RADEONRestoreFP2Registers(pScrn, info->ModeReg);
			}
		}
		break;
	case MT_STV:
	case MT_CTV:
		ErrorF("restore tv\n");
		RADEONRestoreDACRegisters(pScrn, info->ModeReg);
		RADEONRestoreTVRegisters(pScrn, info->ModeReg);
		break;
	default:
		ErrorF("restore dac\n");
		RADEONRestoreDACRegisters(pScrn, info->ModeReg);
   }

But I see ATIRadeonXXXX.kext adjust only CRTC registers.

If so then we can't have good output on LVDS? Or software QE only?

What about ATY_Caretta?

:P

Link to comment
Share on other sites

I'm not looking into the control part of Carreta yet, just finished with the status part. Such that I can have a rough idea how the structure of DriverGlobal looks like. It will help when analyze the control codes.

As you will see, it will also help us deal with status cmds.

OSStatus STATUSDRVR(DriverGlobals *global, void* contents) {

IONDRVControlParameters* pb = (IONDRVControlParameters*) contents;



if ((global->flag4 & 1) == 0) return noErr; //display not power on?

if (((global->flag4 >> 12 & 1) == 0) && (pb->code != cscGetPowerState))

return noErr; //display not wake up?

if (pb->code > 227) return 0xFFEE; //227: cscGetDisplayParams

switch (pb->code) {

case 2:

return DoGetMode(pb->params, global);

case 3:

return DoGetEntries(pb->params, global);

case 4:

return DoGetPages(pb->params, global);

case 5:

return DoGetBaseAddr(pb->params, global);

case 7:

return DoGetInterrupt(pb->params, global);

case 8:

return DoGetGamma(pb->params, global);

case 9:

return DoGetDefaultMode(pb->params, global);

case 10:

return DoGetCurrentMode(pb->params, global);

case 11:

return DoGetSync(pb->params, global);

case 12:

return DoGetConnection(pb->params, global);

case 13:

return DoGetModeTiming(pb->params, global);

case 16:

return DoGetConfiguration(pb->params, global);

case 17:

return DoGetNextResolution(pb->params, global);

case 18:

return DoGetVideoParameters(pb->params, global);

case 22:

return DoSupportsHardwareCursor(pb->params, global);

case 23:

return DoGetHardwareCursorState(pb->params, global);

case 25:

return DoGetPowerState(pb->params, global);

case 27:

return DoFetchDDCBlock(pb->params, global);

case 29:

return DoGetClutBehavior(pb->params, global);

case 30:

return DoGetTimingRanges(pb->params, global);

case 31:

return DoGetDetailTiming(pb->params, global);

case 32:

return DoATIGetCommunicationInfo(pb->params, global);

case 34:

return DoGetVideoStatus(pb->params, global);

case 35:

return DoGetScalerInfo(pb->params, global);

case 36:

return DoGetScaler(pb->params, global);

case 37:

return DoGetMirror(pb->params, global);

case 38:

return DoGetFeatureConfiguratoin(pb->params, global); //original source has the typo error

case 39:

return DoGetFeatureList(pb->params, global);

case 128:

return DoATIGetInfo(pb->params, global);

case 226:

return DoGetUnderscan(pb->params, global);

case 227:

return DoATIGetDispParams(pb->params, global);

default:

return 0xFFEE;

}

}



OSStatus DoGetMode(void* para, DriverGlobal* global) {

VDSwitchInfoRec* modeInfo = (VDSwitchInfoRec*) para;

modeInfo->csPage = 0;

modeInfo->csMode = global->currentDepth;

modeInfo->csBaseAddr = global->baseAddr;

return noErr;

}



OSStatus DoGetEntries(void* para, DriverGlobal* global) {

VDSetEntryRecord* entryPtr = (VDSetEntryRecord*) para;

if (entryPtr->ColorSpec == NULL) return 0xFFFFFFEE;

ulong maxCount = 256; //pixelSize == 24/32

if (HALPixelSize(global, global->currentDepth, global->currentMode) == 16) maxCount = 32;

if (entryPtr->csStart < -1) return 0xFFFFFFEE;

if ((entryPtr->csStart >= 0)

&& ((entryPtr->csStart + entryPtr->csCount + 1) > maxCount)) return 0xFFFFFFEE;

if ((entryPtr->csStart == -1)

&& ((entryPtr->csCount + 1) > maxCount)) return 0xFFFFFFEE;

return HALGetDACIntoTable(global, entryPtr->csStart, entryPtr->csCount + 1, entryPtr->csTable);

}



OSStatus HALGetDACIntoTable(DriverGlobal* global, short start, short count, ColorSpec* table) {

short start1;

short start2 = -1;

ulong size;



if (global->colorDepth == 16) size = 8; //pixelSize == 16

else size = 1;

HW_SetupPaletteAccess(global, global->connectorType);

for (i = 0; i< count;i++) {

if (start == -1) start1 = table[i].value;

else start1 = start + i;

if ((start1 == 0) || (start1 != (start2 + 1))) start2 = -1;

HW_GetPaletteEntry(global, start1 * size, &table[i].rgb.red, &table[i].rgb.green,

&table[i].rgb.blue, 16, (start2 == -1));

start2 = start1;

}

return noErr;

}



void HW_SetupPaletteAccess(DriverGlobal* global, Byte connectorType) {

HW_SetPaletteAccess(global, connectorType);

global->atisg->433 = connectorType;

}



void HW_SetPaletteAccess(DriverGlobal* global, Byte connectorType) {

ulong lutControl = 0;

ulong lutRWMode = 0;

ulong blackOffset = 0;

ulong whiteOffset = 0;

ulong offset = 0;

if (connectorType != 0) offset = 0x800;



regw32(global, 0x6480, connectorType); //DC_LUT_RW_SELECT, 0:lowerHalf 1:upperHalf

if (global->colorBits > 8) { //for pixelSize 32:10bitsEach or 64

lutRWMode = 1;

lutControl = global->colorBits - 7;

if (global->colorFormat != 1) {

whiteOffset = 0x7FFF;

lutControl--;

lutControl |= 16;

if (((global->colorFormat & 2) != 0) && (global->colorBits == 16))

whiteOffset = 0x7BFF;

}

if ((global->colorFormat & 2) != 0) lutControl |= 32;

}

regw32(global, 0x6484, lutRWMode); //DC_LUT_RW_MODE, 0:tableMode 1:linearMode

regw32(global, 0x64C0 + offset, (lutControl | (lutControl << 8) | (lutControl << 16));

//DC_LUT_CONTROL, RGB each 8 bits

regw32(global, 0x64CC + offset, blackOffset); //DC_LUT_BLACK_OFFSET for 3 color components

regw32(global, 0x64C8 + offset, blackOffset);

regw32(global, 0x64C4 + offset, blackOffset);

regw32(global, 0x64D8 + offset, whiteOffset); //DC_LUT_WHITE_OFFSET for 3 color components

regw32(global, 0x64D4 + offset, whiteOffset);

regw32(global, 0x64D0 + offset, whiteOffset);

}



void HW_GetPaletteEntry(DriverGlobal* global, short offset, ushort* red, ushort* green,

ushort* blue, Byte denoteBits, Boolean yesNo) {

ulong colorRange = global->colorRange[offset];

ushort oldRange = (colorRange & 0x3FF00000) >> 20; //get red 10 bits

*red = (ushort) NewRange(global, oldRange, 10, denoteBits);

oldRange = (colorRange & 0xFFC00) >> 10; //get green 10 bits

*green = (ushort) NewRange(global, oldRange, 10, denoteBits);

oldRange = colorRange & 0x3FF; //get blue 10 bits

*blue = (ushort) NewRange(global, oldRange, 10, denoteBits);

}



ulong NewRange(DriverGlobal* global, ushort oldRange, Byte colorBits, Byte denoteBits) {

if (colorBits > denoteBits)

return oldRange >> (colorBits - denoteBits); //use higher part

else

return (oldRange << (denoteBits - colorBits)) //use higher part to fill the gap 

| (oldRange >> (colorBits - denoteBits + colorBits)); 

}



OSStatus DoGetPages(void* para, DriverGlobal* global) {

(VDPageInfo*) para->csPage = 1;

return noErr;

}



OSStatus DoGetBaseAddr(void* para, DriverGlobal* global) {

VDPageInfo* baseAddrPtr = (VDPageInfo*) para;

baseAddrPtr->csBaseAddr = 0;

if (baseAddrPtr->csPage != 0) return 0xFFFFFFEE;

baseAddrPtr->csBaseAddr = global->baseAddr;

return noErr;

}



OSStatus DoGetInterrupt(void* para, DriverGlobal* global) {

if ((global->flag4 >> 29 & 1) == 1) (ulong) *para = 0;

else (ulong) *para = 1;

return noErr;

}



OSStatus DoGetGamma(void* para, DriverGlobal* global) {

(VDGammaRecord*) para->csGTable = 0;

if (global->gammaRecord != NULL) (VDGammaRecord*) *para = global->gammaRecord;

return noErr;

}



OSStatus DoGetDefaultMode(void* para, DriverGlobal* global) {

(Byte) *para = global->currentModeID;

return noErr;

}



OSStatus DoGetCurrentMode(void* para, DriverGlobal* global) {

VDSwitchInfoRec* switchPtr = (VDSwitchInfoRec*) para;

switchPtr->csMode = global->currentDepth;

switchPtr->csData = global->currentModeID;

switchPtr->csPage = 0;

switchPtr->csBaseAddr = global->baseAddr;

switchPtr->csReserved = 0;

return noErr;

}



OSStatus DoGetSync(void* para, DriverGlobal* global) {

if ((Byte)*para == 0) (Byte) *para = global->sync;

else if ((Byte)*para == 255) (Byte) *para = 0x87;

return noErr;

}



OSStatus DoGetConnection(void* para, DriverGlobal* global) {

ushort ret = 0;

do {

if ((global->flag4 >> 7 & 1) == 1) {

if (global->atisg->conInfo == NULL) kdelay(500);

global->flag4 &= 0x7F;

Byte var_9 = DoDetectNewConnection(global, 1);

}

ret = CheckConnectionInfo((VDDisplayConnectInfoRec*) para, global);

if ((global->atisg->conInfo != NULL)

&& (global->atisg->conInfo != global->conInfo))

global->flag4 |= 0x80;

} while ((global->flag4 >> 7 & 1) == 1);

debug_connect_info((VDDisplayConnectInfoRec*) para);

return ret;

}



Boolean DoDetectNewConnection(DriverGlobal* global, Byte val) {

ulong edidP1 = 0;

ulong edidP2 = 0;

ConnectionInfo conInfo;



if (DetectNewConnectionEnabled(global) == FALSE) return FALSE;

GetEDIDProperties(global, global->connection, &edidP1);

GetConnectionInfo(global, &conInfo, 0, 1, val);

global->flag4 &= 0xFFFDFFFF;

if ((global->connectedFlags == conInfo.connectedFlags)

&& (global->connectTaggedType == conInfo.connectTaggedType)

&& (global->112BF == conInfo.3)

&& (global->connectTaggedData == conInfo.connectTaggedData)

&& (global->112C1 == conInfo.5)

&& (global->edidP1 == conInfo.edidP1)

&& (global->edidP2 == conInfo.edidP2))

return CopyConectionInfo2Globals(global, &conInfo);

CopyConectionInfo2Globals(global, &conInfo);

ProgramCrsrState(global, 0, 0, 0, global->connectorType);

InitScalerInfo(global);

InitOutputs(global);

InitDefault(global);

GetEDIDProperties(global, global->connection, &edidP2);

if (edidP1 != edidP2) {

InitDisplayParameters(global, &global->dispPara2);

memcpy(&global->dispPara1, &global->dispPara2, 0x260);

}

HALSetUpDetailTable(global);

InitMemPartition(global);

InitMonitorTables(global);

if (global->modesNum == 0) {

global->connectedFlags = 1;

InitDefault(global);

InitMemPartition(global);

InitMonitorTables(global);

}

return TRUE;

}



Boolean DetectNewConnectionEnabled(DriverGlobal* global) {

if ((global->flag4 >> 6 & 1) == 0) return FALSE;

if ((global->flag4 & 0x40800) != 0) return FALSE;

if (global->atisg->serviceID[global->connectorType] == NULL) return FALSE;

return TRUE;

}



void ProgramCrsrState(DriverGlobal* global, ulong crsrX, ulong crsrY, ulong val3, Byte connectorType) {

ulong hotSpotX = 0;

ulong hotSpotY = 0;

ulong offset = 0;



if (val3 == 0) {

crsrX = 0x1FFF;

crsrY = 0x1FFF;

} else {

if (crsrX < 0) {

hotSpotX = -crsrX;

crsrX = 0;

}

if (crsrY < 0) {

hotSpotY = -crsrY;

crsrY = 0;

}

hotSpotX = (hotSpotX > 0x3F)?0x3F:hotSpotX;

hotSpotY = (hotSpotY > 0x3F)?0x3F:hotSpotY;

}

ulong cursorAddress = global->cursorAddress + offset;

ulong value2 = crsrX << 16 | crsrY;

ulong value1 = hotSpotX << 16 | hotSpotY;

if (connectorType == 0) {

regw32(global, 0x6418, value1); //D1CUR_HOT_SPOT

value1 = regr32(global, 0x6400); //D1CUR_CONTROL

regw32(global, 0x6414, value2); //D1CUR_POSITION

value2 = (global->cursorMode << 8) | (value1 & 0xFFFFFCFF) | 1; //set cursorMode and enable

if (value2 != value1) regw32(global, 0x6400, value2);

regw32(global, 0x6408, cursorAddress); //D1CUR_SURFACE_ADDRESS

} else {

regw32(global, 0x6C18, value1); //D2CUR_HOT_SPOT

value1 = regr32(global, 0x6C00); //D2CUR_CONTROL

if (global->atisg->62C != 0) global->atisg->cursorPosition = value2;

regw32(global, 0x6C14, value2); //D2CUR_POSITION

value2 = (global->cursorMode << 8) | (value1 & 0xFFFFFCFF) | 1;

if (value2 != value1) regw32(global, 0x6C00, value2);

regw32(global, 0x6C08, cursorAddress); //D2CUR_SURFACE_ADDRESS

}

WaitForCursorUpdate(global, connectorType);

}



void WaitForCursorUpdate(DriverGlobal* global, Byte connectorType) {

Byte var_C = connectorType;

}



OSStatus CheckConnectionInfo(VDDisplayConnectInfoRec* displayInfo, DriverGlobal* global) {

Byte DriversConnectorsLen = 1;

ulong DriversConnectors[4] = {0x4, 0x18, 0, 0};



ushort ret = noErr;

ulong flag = 0;

displayInfo->csConnectFlags = 0;

GetConnectionSense(global, global->connection, &var_10, &var_11);

if (global->connection == 1) flag = 1 << kConnectionInactive;

for (i = 0;i < DriversConnectorsLen;i++) {

if ((global->connection & DriversConnectors[i + 1]) == 0) continue; //not DFP2&CRT1

if ((DriversConnectors[i] >> 1 & 1) == 0) break;

flag |= 1 << kBuiltInConnection;

break;

}

displayInfo->csDisplayType = global->monP->4;

displayInfo->csConnectFlags |= 1 << kReportsHotPlugging;

displayInfo->csConnectFlags |= 1 << kReportsHotPlugging; //a repeat

if ((global->connection & global->edidFlags) != 0) //edid not available yet

displayInfo->csConnectFlags |= 1 << kOverrideConnection;//needs do it manually

else

displayInfo->csConnectFlags |= 1 << kReportsTagging;

displayInfo->csConnectFlags |= 1 << kReportsDDCConnection;

ret = CheckLoadEDIDBlock(global, global->connection, 1, 0);

if (ret == noErr) displayInfo->csConnectFlags |= 1 << kHasDDCConnection;//find a DDC display

displayInfo->csConnectTaggedType = var_10;

if (var_11 == 0xFF) {

displayInfo->csConnectTaggedData = 0;

displayInfo->csConnectFlags |= 1 << kTaggingInfoNonStandard;

} else displayInfo->csConnectTaggedData = var_11;

displayInfo->csConnectFlags |= flag;

displayInfo->csDisplayComponent = 0;

displayInfo->csConnectReserved = 0;

return noErr;

}



void void GetConnectionSense(DriverGlobal* global, Byte connection, Byte* connectType, Byte* connectData) {

if (connection == 8) //DFP2

Panel_GetSenseCode(global, connectType, connectData);

else if (connection == 16) //CRT1

Apple_GetHWSenseCode(global, global->connectedFlags, connectType, connectData);

else {

*connectType = 7;

*connectData = 0x3F;

}

}



void Panel_GetSenseCode(DriverGlobal* global, Byte* connectType, Byte* connectData) {

*connectType = 0x90;

*connectData = 0xFF;

}



void debug_connect_info(VDDisplayConnectInfoRec* displayInfo) {

const UChar aAllmodesvalid[28] = "AllModesValid ";

const UChar aAllmodessafe[28] = "AllModesSafe ";

const UChar aReportstagging[28] = "ReportsTagging ";

const UChar aHasdirectconne[28] = "HasDirectConnection ";

const UChar aIsmonodev[28] = "IsMonoDev ";

const UChar aUncertainconne[28] = "UncertainConnection ";

const UChar aTagginginfonon[28] = "TaggingInfoNonStandard ";

const UChar aReportsddcconn[28] = "ReportsDDCConnection ";

const UChar aHasddcconnecti[28] = "HasDDCConnection ";

const UChar aConnectioninac[28] = "ConnectionInactive ";

const UChar aDependentconne[28] = "DependentConnection ";

const UChar aBuiltinconnect[28] = "BuiltInConnection ";

const UChar aOverrideconnec[28] = "OverrideConnection ";

const UChar aFastcheckfordd[28] = "FastCheckForDDC ";

const UChar aReportshotplug[28] = "ReportsHotPlugging ";

global const UChar aUnknownconnect[28] = "UnknownConnect ";

global const UChar aPanelconnect[28] = "PanelConnect ";

global const UChar aPaneltftconnec[28] = "PanelTFTConnect ";

global const UChar aFixedmodecrtco[28] = "FixedModeCRTConnect ";

global const UChar aMultimodecrt1c[28] = "MultiModeCRT1Connect ";

global const UChar aMultimodecrt2c[28] = "MultiModeCRT2Connect ";

global const UChar aMultimodecrt3c[28] = "MultiModeCRT3Connect ";

global const UChar aMultimodecrt4c[28] = "MultiModeCRT4Connect ";

global const UChar aModelessconnec[28] = "ModelessConnect ";

global const UChar aFullpageconnec[28] = "FullPageConnect ";

global const UChar aVgaconnect[28] = "VGAConnect ";

global const UChar aNtscconnect[28] = "NTSCConnect ";

global const UChar aPalconnect[28] = "PALConnect ";

global const UChar aHrconnect[28] = "HRConnect ";

global const UChar aPanelfstnconne[28] = "PanelFSTNConnect ";

global const UChar aMonotwopagecon[28] = "MonoTwoPageConnect ";

global const UChar aColortwopageco[28] = "ColorTwoPageConnect ";

global const UChar aColor16connect[28] = "Color16Connect ";

global const UChar aColor19connect[28] = "Color19Connect ";

global const UChar aGenericcrt[28] = "GenericCRT ";

global const UChar aGenericlcd[28] = "GenericLCD ";

global const UChar aDdcconnect[28] = "DDCConnect ";

global const UChar aNoconnect[28] = "NoConnect ";

C_26_14195 = aUnknownconnect;



memcpy(&var_A4, &C_26_14195, 0x5C);

for (i = 0;i <= 14;i++);

//dubug code obviously not compiled

}



OSStatus DoGetModeTiming(void* para, DriverGlobal* global) {

VDTimingInfoRec* timingPtr = (VDTimingInfoRec*) para;

ulong timingFlags = 0;

timingPtr->csTimingFormat = kDeclROMtables;

displayMode* mode = HALFindCrtcValues(global, timingPtr->csTimingMode);

if (mode == NULL) return 0xFFFFFFCE;

if (IsDetailMode(global, timingPtr->csTimingMode)

|| IsAliasMode(global, timingPtr->csTimingMode))

timingPtr->csTimingFormat = kDetailedTimingFormat;

if ((mode->flag >> 3 & 1) == 1) timingFlags |= 0x40; //interlaced mode

HALGetMonitorModeFlags(global, timingPtr->csTimingMode, &timingFlags);

if ((mode->flag >> 6 & 1) == 1) timingFlags |= 8; //mode always be shown

timingPtr->csTimingData = mode->timingMode;

timingPtr->csTimingFlags = timingFlags;

return noErr;

}



Boolean IsAliasMode(DriverGlobal* global, ulong modeID) {

if (modeID >= 0) return FALSE;

if (modeID > -5) return FALSE;

return TRUE;

}



OSStatus DoGetConfiguration(void* para, DriverGlobal* global) {

GetConfigurationRec* confPtr = (GetConfigurationRec*) para; //the structure need a definition

Byte connection;

DoNVPrefs(global, global->4E, FALSE, &connection);

if (global->connectorType == 0) {

confPtr->0 = global->50;

confPtr->2 = global->4E;

} else {

confPtr->0 = global->58;

confPtr->2 = global->56;

}

displayMode* mode = HALGetCrtcValues(global, confPtr->2, confPtr->0);

if (mode == NULL) return 0xFFFFFFCE;

confPtr->8 = 0;

return noErr;

}



OSStatus DoGetNextResolution(void* para, DriverGlobal* global) {

global diplayMode* myCrtcValues_14347;

VDResolutionInfoRec* resolutionPtr = (VDResolutionInfoRec*) para;

ulong modeID;

displayMode* mode;

Boolean find = FALSE;



resolutionPtr->csDisplayModeID = 0;

resolutionPtr->csHorizontalPixels = 0

resolutionPtr->csVerticalLines = 0;

resolutionPtr->csRefreshRate = 0;

resolutionPtr->csMaxDepthMode = 0;



ulong previousID = resolutionPtr->csPreviousDisplayModeID;

if (previousID == kDisplayModeIDFindFirstProgrammable) {

mode = global->detailModes[0];

find = TRUE;

} else if (previousID == kDisplayModeIDCurrent) {

mode = HALGetCrtcValues(global, global->currentModeID, global->currentDepth);

if (mode != NULL) find = TRUE;

} else {

if ((myCrtcValues_14347 != NULL) && (myCrtcValues_14347->modeID == previousID))

mode = myCrtcValues_14347;

else {

if (global->modesNum == 0) mode = NULL;

else mode = global->modes[0];

if (IsDetailMode(global, previousID)) mode = global->detailModes[0];

}

while(mode != NULL) {

modeID = mode->modeID;

if (previousID == kDisplayModeIDFindFirstResolution) {

find = TRUE;

break;

}

if (modeID == previousID) find = TRUE;

else if (find) break;

mode = HALGetNextCrtc(global, mode);

}

if (find) myCrtcValues_14347 = mode;

else myCrtcValues_14347 = NULL;

}

if (!find) return 0xFFFFFFCE;

if (mode == NULL) {

resolutionPtr->csDisplayModeID = kDisplayModeIDNoMoreResolutions;

return noErr;

}

resolutionPtr->csDisplayModeID = mode->modeID;

resolutionPtr->csHorizontalPixels = mode->width;

resolutionPtr->csVerticalLines = mode->height;

resolutionPtr->csRefreshRate = HALGetRefreshRate(global, mode);

resolutionPtr->csMaxDepthMode = kDepthMode6;

if (((mode->flag & 0xF00 >> 8 & 1) == 1)

&& ((global->flag4 >> 26 & 1) == 1)) { //rotate

resolutionPtr->csVerticalLines = mode->width;

resolutionPtr->csHorizontalPixels = mode->height;

}

return noErr;

}



displayMode* HALGetCrtcValues(DriverGlobal* global, ulong modeID, ulong depthMode) {

displayMode* mode = HALFindCrtcValues(global, modeID);

if (mode == NULL) return NULL;

DetailTimingState* DTState;

if ((HALGetDetailTimingState(global, mode->modeID, DTState) == noErr)

&& (DTState->modeState == kDMSModeFree)) return NULL; //not used yet

if (HALPixelSize(global, depthMode, mode) <= 7) return NULL;

if (HALPixelSize(global, depthMode, mode) > HALMaxPixelSize(global, mode))

return NULL;

return mode;

}



OSStatus DoGetVideoParameters(void* para, DriverGlobal* global) {

VDVideoParametersInfoRec* videoParaPtr = (VDVideoParametersInfoRec*) para;

ushort ret = noErr;

ulong modeID = videoParaPtr->csDisplayModeID;

if (modeID == 0) modeID = global->currentModeID;

displayMode* mode = HALFindCrtcValues(global, modeID);

if (mode == NULL) return 0xFFFFFFCE;

videoParaPtr->csPageCount = 1;

videoParaptr->csVPBlockPtr->vpBounds.top = 0;

videoParaPtr->csVPBlockPtr->vpBounds.left = 0;

videoParaPtr->csVPBlockPtr->vpHRes = 0x480055;

videoParaPtr->csVPBlockPtr->vpVRes = 0x480044;

videoParaPtr->csVPBlockPtr->VPVersion = 0;

videoParaPtr->csVPBlockPtr->vpPackType = 0;

videoParaPtr->csVPBlockPtr->vpPackSize = 0;

videoParaPtr->csVPBlockPtr->vpPlaneBytes = 0;

videoParaPtr->csVPBlockPtr->vpBaseOffset = 0;

videoParaPtr->csVPBlockPtr->vpCmpSize = HALColorBits(global, videoParaPtr->csDepthMode, mode);

videoParaPtr->csVPBlockPtr->vpPixelSize = HALPixelSize(global, videoParaPtr->csDepthMode, mode);

ushort bitsPerPixel = videoParaPtr->csVPBlockPtr->vpPixelSize;

if (bitsPerPixel < 0) bitsPerPixel += 7;

ulong bytesPerPixel = bitsPerPixel / 8;

if (videoParaPtr->csVPBlockPtr->vpPixelSize > 32) return 0xFFFFFFCE;

if (videoParaPtr->csVPBlockPtr->vpPixelSize <= 7) return 0xFFFFFFCE;

if (videoParaPtr->csVPBlockPtr->vpCmpSize > 8) return 0xFFFFFFCE;

if (videoParaPtr->csVPBlockPtr->vpCmpSize <= 0) return 0xFFFFFFCE;

if (bytesPerPixel == 0) return 0xFFFFFFCE;

if (bytesPerPixel == 1) {

videoParaPtr->csDeviceType = 0; //Direct

videoParaPtr->csVPBlockPtr->vpPixelType = 0;

videoParaPtr->csVPBlockPtr->vpCmpCount = 1;

} else {

videoParaPtr->csDeviceType = 2; //CLUT

videoParaPtr->csVPBlockPtr->vpPixelType = 0x10;

videoParaPtr->csVPBlockPtr->vpCmpCount = 3;

}

ulong height = mode->height;

ulong width = mode->width;

if (((mode->flag & 0xF00 >> 8 & 1) == 1)

&& (global->flag4 >> 26 & 1) == 1) { //rotate bit

height = mode->width;

width = mode->height;

}

videoParaPtr->vpBlockPtr->vpBounds.bottom = height;

videoParaPtr->vpBlockPtr->vpBounds.right = width;

videoParaPtr->vpBlockPtr->vpRowBytes = GetPitch(global, width, bytesPerPixel);

if (((global->flag4 >> 13 & 1) == 1) //HWmirror

&& (global->currentModeID == modeID)) { //current mode

videoParaPtr->vpBlockPtr->vpBounds.right = global->width;

videoParaPtr->vpBlockPtr->vpBounds.bottom = global->height;

videoParaPtr->vpBlockPtr->vpRowBytes = global->pitch;

} else if (((mode->flag & 0xF00 >> 8 & 1) == 1)

&& ((global->flag4 >> 26 & 1) == 1)) { //rotate

videoParaPtr->vpBlockPtr->vpBounds.right = global->height;

videoParaPtr->vpBlockPtr->vpBounds.bottom = global->width;

videoParaPtr->vpBlockPtr->vpRowBytes = GetPitch(global, global->height, bytesPerPixel);

}

if (videoParaPtr->vpBlockPtr->vpPixelSize > HALMaxPixelSize(global, mode)) ret = 0xFFCE;

if ((ret == noErr)

&& (HALNeedSWScaler(global, mode, videoParaPtr->vpBlockPtr->vpPixelSize) == 1))

return 0xFFFFFFCE;

return ret;

}



ulong HALColorBits(DriverGlobal* global, ushort depthMode, displayMode* mode) {

const ulong colorBits[7] = {8, 5, 8, 10, 16, 16, 32};



if (depthMode < kDepthMode1) return 0;

depthMode -= kDepthMode1;

if (depthMode > 6) return 0; //only support a max of 6 depthMode

return colorBits[depthMode];

}



ulong HALPixelSize(DriverGlobal* global, ushort depthMode, displayMode* mode) {

const ulong pixelSize[7] = {8, 16, 32, 32, 64, 64, 128};



if (depthMode < kDepthMode1) return 0;

depthMode -= kDepthMode1;

if (depthMode > 6) return 0; //only support a max of 6 depthMode

return pixelSize[depthMode];

}



OSStatus DoSupportsHardwareCursor(void* para, DriverGlobal* global) {

(VDSupportsHardwareCursorRec*) para->csSupportsHardwareCursor = TRUE;

return noErr;

}



OSStatus DoGetHardwareCursorState(void* para, DriverGlobal* global) {

VDHardwareCursorDrawStateRec* hwCursorStatePtr = (VDHardwareCursorDrawStateRec*) para;

hwCursorStatePtr->csCursorSet = global->cursorSet; //true if cursor was set

if (global->cursorSet != FALSE) {

hwCursorStatePtr->csCursorX = global->cursorX;

hwCursorStatePtr->csCursorY = global->cursorY;

hwCursorStatePtr->csCursorVisible = global->cursorVisible; //true if cursor visible

}

return noErr;

}



OSStatus DoGetPowerState(void* para, DriverGlobal* global) {

VDPowerStateRec* powerStatePtr = (VDPowerStateRec*) para;



if (global->powerState == kAVPowerOff) global->powerFlags = 1; //need refreshing when turn on it from off

else global->powerFlags = 0; //otherwise no refresh need

powerStatePtr->powerState = global->powerState;

powerStatePtr->powerFlags = global->powerFlags | 0x28; //support power down sleep, wake to doze

return noErr;

}



OSStatus DoFetchDDCBlock(void* para, DriverGlobal* global) {

ushort ret = 0;

VDDDCBlockRec* ddcBlockPtr = (VDDDCBlockRec*) para;



if ((global->flag4 >> 11 & 1) == 1) return 0xFFFFFFED;

if (ddcBlockPtr->ddcBlockNumber == 0) return 0xFFFFFFCE;

if (ddcBlockPtr->ddcBlockType != 0) return 0xFFFFFFCE;

if (ddcBlockPtr->ddcBlockNumber != 0)

ddcBlockPtr->ddcFlags &= 0xFFFFFFFE; //clear bit0

if (ret != noErr) return ret;

if ((ddcBlockPtr->ddcFlags & 1) == 1)

CheckDDCConnection(global, global->connection, 1, &var_10, global->112CC, global->connectedFlags);

ret = CheckLoadEDIDBlock(global, global->connection, ddcBlockPtr->ddcBlockNumber, ddcBlockPtr->ddcBlockData);

return ret;

}



OSStatus DoGetClutBehavior(void* para, DriverGlobal* global) {

if ((global->flag4 >> 8 & 1) == 1) (VDClutBehavior*) para = 0;

else (VDClutBehavior*) para = 1;

return noErr;

}



OSStatus DoGetTimingRanges(void* para, DriverGlobal* global) {

return HALGetTimingRanges(global, (VDDisplayTimingRangeRec*) para, global->connection);

}



OSStatus HALGetTimingRanges(DriverGlobal* global, VDDisplayTimingRangeRec* timingRangePtr, Byte connection) {

if (timingRangeRec->csRangeBlockIndex != 0) return 0xFFFFFFCE; //not first index

return GetHWTimingRange(global, timingRangePtr, connection, 1);

}



OSStatus GetHWTimingRange(DriverGlobal* global, VDDisplayTimingRangeRec* timingRangePtr, Byte connection, Byte val) {

const DisplayTimingRanges DTRs[0xF0] = {

0xF0, 0, ......

}



if (timingRangePtr == NULL) return 0xFFFFFFEE;

memcpy(timingRangePtr, DTRs, 0xF0);

ulong Clock = global->atisg->sysClock;

if (val == 0)

Clock = Clock - Clock * 1000 / 10000 - 1;

else if (((global->F0 >> 1 & 1) == 1) && (global->F4 != 0))

Clock = Clock - Clock * global->F4 / 10000;

Clock = (Clock > 55000)?55000:Clock;

timingRangePtr->csMinPixelClock = 708;

timingRangePtr->csMaxPixelClock = (Clock > 110000)?110000:Clock;

if ((connection >> 3 & 1) == 1) { //DFP2

if (timingRangePtr->csMinPixelClock < 708)

timingRangePtr->csMinPixelClock = 708;

if ((global->112B5 == 0) && (timingRangePtr->csMaxPixelClock > 33000))

timingRangePtr->csMaxPixelClock = 33000;

else if (timingRangePtr->csMaxPixelClock > 16500)

timingRangePtr->csMaxPixelClock = 16500;

timingRangePtr->csReserved2 = timingRangePtr->csMinPixelClock;

timingRangePtr->csReserved3 = (timingRangePtr->csMaxPixelClock > 16500)?

16500:timingRangePtr->csMaxPixelClock;

timingRangePtr->csReserved1 = 1;

if (global->112B5 == 0) {

timingRangePtr->csReserved4 = timingRangePtr->csReserved2;

timingRangePtr->csReserved5 = timingRangePtr->csReserved3;

timingRangePtr->csReserved1 = 2;

}

}

if ((connection >> 4 & 1) == 1) { //CRT1

if (timingRangePtr->csMinPixelClock < 708)

timingRangePtr->csMinPixelClock = 708;

if (timingRangePtr->csMaxPixelClock > 40000)

timingRangePtr->csMaxPixelClock = 40000;

}

if (timingRangePtr->csMaxPixelClock > Clock)

timingRangePtr->csMaxPixelClock = Clock;

if (timingRangePtr->csReserved3 > Clock)

timingRangePtr->csReserved3 = Clock;

if (timingRangePtr->csReserved5 > Clock)

timingRangePtr->csReserved5 = Clock;

timingRangePtr->csMinPixelClock *= 10000;

timingRangePtr->csMaxPixelClock *= 10000;

timingRangePtr->csReserved2 *= 10000;

timingRangePtr->csReserved3 *= 10000;

timingRangePtr->csReserved4 *= 10000;

timingRangePtr->csReserved5 *= 10000;

timingRangePtr->csRangeBlockCount = 1;

return noErr;

}



OSStatus DoGetDetailTiming(void* para, DriverGlobal* global) {

return HALGetDetailTiming(global, (VDDetailedTimingRec*) para);

}



OSStatus HALGetDetailTiming(DriverGlobal* global, VDDetailedTimingRec* dtPtr) {

ulong modeID = dtPtr->csDisplayModeID;

if (HALArbitraryAvailable(global) == 0) return 0xFFFFFFEE;

if (modeID == 0x3000) return 0xFFFFFFEE;

BlockZero(dtPtr, dtPtr->csTimingSize);

HALConvertAlias(global, &modeID);

displayMode* mode = HALFindCrtcValues(global, modeID);

if (mode == NULL) return 0xFFFFFFEE;

mode = HALFindNativeTiming(global, mode, 1);

if (mode == NULL) return 0xFFFFFFEE;

Byte timingFlags = HALGetTimingFlagsRec(global, mode, global->activeFlags);

if (HALGetDetailTimingState(global, modeID, DTState) != noErr) DTState = NULL;

dtPtr->csDisplayModeID = mode->modeID;

if (DTState != NULL) {

dtPtr->csPixelClock = DTState->Clock;

dtPtr->MinPixelClock = 0;

dtPtr->csHorizontalActive = DTState->width;

dtPtr->csVerticalActive = DTState->height;

dtPtr->csDisplayModeState = DTState->modeState;

dtPtr->csDisplayModeSeed = DTState->modeSeed;

dtPtr->csDisplayModeAlias = DTState->modeAlias;

} else {

dtPtr->csPixelClock = mode->Clock * 10000; //Hz

dtPtr->csMinPixelClock = 0;

dtPtr->csHorizontalActive = mode->width;

dtPtr->csVerticalActive = mode->height;

dtPtr->csDisplayModeState = 1;

dtPtr->csDisplayModeSeed = 0;

dtPtr->csDisplayModeAlias = dtPtr->csDisplayModeID;

}

dtPtr->csMinPixelClock = dtPtr->csPixelClock;

dtPtr->csMaxPixelClock = dtPtr->csPixelClock;

if (mode->Clock != 0)

var_2C = CalculateVCLK(global, mode->Clock, global->connectorType, timingFlags);

else var_2C = 0;

var_10 = var_2C;

if (mode->Clock >= var_10) dtPtr->csMinPixelClock = var_10 * 10000;

else dtPtr->csMaxPixelClock = var_10 * 10000;

dtPtr->csHorizontalBlanking = mode->HTotal - dtPtr->csHorizontalActive;

dtPtr->csHorizontalSyncOffset = mode->dHSyncS;

dtPtr->csHorizontalSyncPulseWidth = mode->dHSyncE;

dtPtr->csVerticalBlanking = mode->VTotal - dtPtr->csVerticalActive;

dtPtr->csVerticalSyncOffset = dtPtr->dVSyncS;

dtPtr->csVerticalSyncPulseWidth = dtPtr->dVSyncE;

if ((mode->flag >> 3 & 1) == 1) dtPtr->csSignalConfig |= 4;

if ((timingFlags >> 3 & 1) == 1) {

dtPtr->csSignalConfig |= 1;

dtPtr->csReserved1 = 1;

if ((mode->flag >> 12 & 1) == 1) dtPtr->csReserved1 = 2;

}

if ((mode->flag & 1) == 1) dtPtr->csHorizontalSyncConfig = 1;

if ((mode->flag >> 1 & 1) == 1) dtPtr->csVerticalSyncConfig = 1;

dtPtr->csTimingSize = 0xA0;

dtPtr->csSignalLevels = 0;

return noErr;

}



OSStatus DoATIGetCommunicationInfo(void* para, DriverGlobal* global) {

VDCommunicationInfoRec* commInfoPtr = (VDCommunicationInfoRec*) para;

commInfoPtr->csBusID = 0;

commInfoPtr->csBusType = 1;

commInfoPtr->csMinBus = 0;

commInfoPtr->csMaxBus = 0;

commInfoPtr->csSupportedTypes = 7;

commInfoPtr->csSupportedTypes = 15;

commInfoPtr->csSupportedCommFlags = 2;

return noErr;

}



OSStatus DoGetVideoStatus(void* para, DriverGlobal* global) {

(Byte) para->0 = 0;

return noErr;

}



OSStatus DoGetScalerInfo(void* para, DriverGlobal* global) {

return HALGetScalerInfo(global, (VDScalerInfoRec*) para);

}



OSStatus HALGetScalerInfo(DriverGlobal* global, (VDScalerInfoRec*) scalerInfoPtr) {

if (HALScalerAvailable(global) == 0) return 0xFFFFFFEE;

scalerInfoPtr->csScalerFeatures = 0x1A; //more active clocks than pixels, enable scale an interlaced, enable scale a timing with insets

if ((global->flag4 >> 26 & 1) == 1) scalerInfoPtr->csScalerFeatures |= 0x20; //enable rotate

scalerInfoPtr->csScalerFeatures |= 4; //fewer active clocks than pixels

global->14 = 0x1000;

global->18 = 0x1000;

scalerInfoPtr->csReserved1 = 0;

scalerInfoPtr->csReserved2 = 0;

scalerInfoPtr->csReserved3 = 0;

return noErr;

}



OSStatus DoGetScaler(void* para, DriverGlobal* global) {

return HALGetScaler(global, (VDScalerRec*) para);

}



OSStatus HALGetScaler(DriverGlobal* global, VDScalerRec* scalerPtr) {

displayMode* mode;

ulong modeID;

DetailTimingState* DTState;

ret = noErr;



if (HALScalerAvailable(global) == FALSE) return 0xFFFFFFEE;

modeID = scalerPtr->csDisplayModeID;

HALConvertAlias(global, &modeID);

mode = HALFindCrtcValues(global, modeID);

if (mode == NULL) return 0xFFFFFFEE;

scalerPtr->csScalerFlags = 0;

if ((mode->flag >> 6 & 1) == 1) scalerPtr->csScalerFlags |= 1; //set bit0

scalerPtr->csHorizontalPixels = mode->width;

scalerPtr->csVerticalPixels = mode->height;

if (HALGetDetailTimingState(global, modeID, DTState) == 0) {

scalerPtr->csDisplayModeSeed = DTState->modeSeed;

scalerPtr->csDisplayModeState = DTState->modeState;

scalerPtr->csHorizontalInset = DTState->horiInset;

scalerPtr->csVerticalInset = DTState->verInset;

scalerPtr->csScalerFlags |= mode->flag & 0xF00 >> 4;

if ((scalerPtr->csScalerFlags >> 4 & 1) == 1) { //bit4: SwapAxesMask

scalerPtr->csHorizontalPixels = mode->height;

scalerPtr->csVerticalPixels = mode->width;

}

} else {

scalerPtr->csDisplayModeSeed = 0;

scalerPtr->csDisplayModeState = 1;

scalerPtr->csHorizontalInset = 0;

scalerPtr->csVerticalInset = 0;

}

return ret;

}



Boolean HALScalerAvailable(DriverGlobal* global) {

if (HALArbitraryAvailable(global) == FALSE) return FALSE;

InitScalerInfo(global);

if (HW_ScalerAvailable(global, global->connectorType) == FALSE) return FALSE;

return TRUE;

}



Boolean HALArbitraryAvailable(DriverGlobal* global) {

return TRUE;

}



Boolean HW_ScalerAvailable(DriverGlobal* global, Byte connectorType) {

Byte conType = connectorType;

return TRUE;

}



OSStatus DoGetMirror(void* para, DriverGlobal* global) {

RegEntryID* regID;

ret = noErr;

VDMirrorRec* mirrorPtr = (VDMirrorRec*) para;



mirrorPtr->csMirrorFeatures = 1; //same depth only

mirrorPtr->csMirrorSupportedFlags = 0x9F; //HW mirror, clipped or not, can center

mirrorPtr->csMirrorFlags = global->11528 & 0xFFFFFFFC; //clear bit0,1 = not HW mirror yet

if (HWMirrorCheck(global) == noErr) mirrorPtr->csMirrorFlags |= 1; //enable HW mirror

if ((global->flag4 >> 13 & 1) == 1) mirrorPtr->csMirrorFlags |= 2; //is HW mirror now

if (global->connectorType == 0) regID = global->atisg->mirrorEntryID[1];

else regID = global->atisg->mirrorEntryID[0];

if ((RegistryEntryIDCompare(mirrorPtr->csMirrorReuestID[0], NULL) == TRUE)

|| (RegistryEntryIDCompare(mirrorPtr->csMirrorReuestID[0], regID) == FALSE)) {

if ((global->flag4 >> 13 & 1) == 1) //has HW mirror

RegistryEntryIDCopy(regID, mirrorPtr->csMirrorResultID[0]);

else RegistryEntryIDInit(mirrorPtr->csMirrorResultID[0]);

} else RegistryEntryIDCopy(mirrorPtr->csMirrorReuestID[0], mirrorPtr->csMirrorResultID[0]);

return ret;

}



OSStatus HWMirrorCheck(DriverGlobal* global) {

if (global->driverNodesNum == 0) return 0xFFFFFFEF;

if (global->atisg->mirrorEntryID[1] == NULL) return 0xFFFFFFEF;

if (global->atisg->mirrorEntryID[0] == NULL) return 0xFFFFFFEF;

if (global->atisg->43C != global->atisg->450) return 0xFFFFFFEF;

if (global->atisg->434 <= 7) return 0xFFFFFFEF;

if (global->atisg->448 <= 7) return 0xFFFFFFEF;

if (global->atisg->438 <= 1) return 0xFFFFFFEF;

if (global->atisg->44C <= 1) return 0xFFFFFFEF;

return noErr;

}



OSStatus DoGetFeatureConfiguratoin(void* para, DriverGlobal* global) {

ret = 0xFFEE;

displayMode mode;

DisplayParameters dispPara;

ScaledParameters scaledPara;

VDConfigurationRec* confPtr = (VDConfigurationRec*) para;



confPtr->csConfigSupport = 0;

confPtr->csConfigValue = 0;

confPtr->csReserved1 = 0;

confPtr->csReserved2 = 0;

if (confPtr->csConfigFeature == "htid") {

confPtr->csConfigSupport = 1;

confPtr->csConfigValue = global->11550;

confPtr->csReserved1 = 0;

confPtr->csReserved2 = 1;

return noErr;

}

if (confPtr->csConfigFeature == "rgi") {

confPtr->csConfigSupport = 1;

confPtr->csReserved1 = 0;

confPtr->csReserved2 = 1;

confPtr->csConfigValue = global->atisg->431;

confPtr->csConfigValue |= 0x80000000;

return noErr;

}

if (confPtr->csConfigFeature == "mrht") {

confPtr->csConfigSupport = 1;

ReadAsicTemperature(confPtr->csConfigValue, global);

confPtr->csReserved1 = 0;

confPtr->csReserved2 = 0x78;

return noErr;

}

if (confPtr->csConfigFeature == "ncsp") {

dispPara.size = 0x260;

dispPara.2 = 0;

ret = DoATIGetdispParams(&dispPara, global);

if (ret != noErr) return ret;

if ((global->currentMode == 0) || (global->112E8 == 0)) return 0xFFFFFFEE;

displayMode mode = *(global->currentMode);

mode.width = global->width;

mode.height = global->height;

CalculateScaledconfPtrms(global, &mode, global->scaledMode, &scaledconfPtr);

confPtr->csConfigSupport = 1;

var_C = global->height;

if ((global->flag4 >> 30 & 1) == 1) var_C = global->11536;

if ((global->flag4 >> 14 & 1) == 1) var_C = global->1152E;

confPtr->csConfigValue = 100 - (var_C * 200 / global->112E8 + 1) / 2;

if (global->powerState8D != 0) {

var_C = global->width;

if ((global->flag4 >> 30 & 1) == 1) var_C = global->11534;

if ((global->flag4 >> 14 & 1) == 1) var_C = global->1152C;

var_C = 100 - (var_C * 200 / global->112E0 + 1) / 2;

if (confPtr->csConfigValue > var_C) confPtr->csConfigValue = var_C;

}

confPtr->csReserved1 = 0;

confPtr->csReserved2 = 100;

return noErr;

}

return ret;

}



OSStatus ReadAsicTemperature(ushort* value, DriverGlobal* global) {

ulong var_24[6] = { //not used

7, 0x3F000000, 6, 0x3E800000, 5, 0x3E000000

};

Byte tempR = ReadLM63(global, 1);

if ((tempR >> 7 & 1) == 1) temp= 0; //tempR < 0

else temp = tempR;

(*value) = temp;

return noErr;

}



OSStatus DoGetFeatureList(void* para, DriverGlobal* global) {

UChar fsupported[5][4] = {

"mrht", "htid", "rgi", "ncsp", ""

};



if (para == NULL) return 0xFFFFFFCE;

ulong size = (FeatureList*) para->size;

if (size > 5) size = 5;

UChar** feature = (FeatureList*) para->fsupported;

if ((feature != NULL) && (size != 0))

for (i = 0;i < size;i++) feature[i] = fsupported[i];

(FeatureList*) para->size = 5;

return noErr;

}



OSStatus DoATIGetInfo(void* para, DriverGlobal* global) {

CreateInfo(global->atiInfo, global);

ulong size = 0x4C;

if ((ATIInfo*) para->size < size) (ATIInfo*) para->size = size;

global->atiInfo->size = size;

BlockCopy(global->atiInfo, (ATIInfo*) para, size);

}



void CreateInfo(ATIInfo* atiInfo, DriverGlobal* global) {

atiInfo->4 = 1;

atiInfo->8 = global->E4;

atiInfo->10 = 0;

atiInfo->IOMapBase = global->IOMapBase;

atiInfo->20 = 0;

atiInfo->2C = global->12C;

atiInfo->30 = global->120;

atiInfo->34 = global->130;

atiInfo->38 = global->134;

atiInfo->3C = global->130;

atiInfo->40 = global->134;

atiInfo->44 = 0x201;

atiInfo->chipID = global->chipID;

atiInfo->size = 0x4C;

atiInfo->14 = 0;

atiInfo->scanoutStart = global->scanoutStart;

atiInfo->28 = global->CC;

atiInfo->totalVram = global->totalVram;

atiInfo->18 = global->E4;

if ((global->flag4 >> 13 & 1) == 0) return;

if (global->connectorType == 0) var_1C = global->atisg->totalVram;

else var_1C = 0;

atiInfo->C = var_1C;

}



OSStatus DoGetUnderscan(void* para, DriverGlobal* global) {

(Byte) (*para) = global->underScan;

return noErr;

}



OSStatus DoATIGetDispParams(void* para, DriverGlobal* global) {

if ((DisplayParameters*) para->size != 0x260) return 0xFFFFFFCE;

if ((DisplayParameters*) para->8 != 0) InitDisplayParameters(global, (DisplayParameters*) para);

else memcpy((DisplayParameters*) para, global->dispPara2, 0x260);

return noErr;

}

There are still mistakes in it, but the information it provides is useful.

Link to comment
Share on other sites

I'm not looking into the control part of Carreta yet, just finished with the status part. Such that I can have a rough idea how the structure of DriverGlobal looks like. It will help when analyze the control codes.

As you will see, it will also help us deal with status cmds.

 

There are still mistakes in it, but the information it provides is useful.

Yes!!! It will be very useful as we have no other sample for many status/command.

At last I understand what you mean "DriverGlobal". It is not structure, there are no definition for it.

It is common practice for compiler from high-level languages such as C++, Pascal etc.

In these languages assumed that we have access to global variables from local procedure. So local variables allocated in stack and have access through stack pointer. For global variables there is frame pointer that always push into stack when some routine is called.

So DriverGlobal is a place of all global variables. The pointer to it is always first argument of any functions.

For example

; =============== S U B	R O U T	I N E =======================================

; Attributes: bp-based frame

; IOATIR200Accelerator::IOATIR200Accelerator(OSMetaClass  const*)   // only one argument

var_18		= dword	ptr -18h   //internal var
var_14		= dword	ptr -14h   //internal var
arg_0		= dword	ptr  8	  // Frame pointer 
arg_4		= dword	ptr  0Ch  // argument

	push	ebp
	mov	ebp, esp
	push	ebx
	sub	esp, 14h						 // spaces for internal vars in stack
	mov	ebx, [ebp+arg_0]		   // Frame pointer obtained from outer caller
	mov	eax, [ebp+arg_4]			// argument of type OSMetaClass
	mov	[esp+18h+var_14], eax  // use it
	mov	[esp+18h+var_18], ebx  // send Frame pointer to internal routine
	call	near ptr __ZN13IOAcceleratorC2EPK11OSMetaClass; IOAccelerator::IOAccelerator(OSMetaClass  const*)
	mov	dword ptr [ebx], offset	__ZTV20IOATIR200Accelerator; `vtable for'IOATIR200Accelerator
	mov	eax, ebx					  // return value
	add	esp, 14h					   //free stack
	pop	ebx
	pop	ebp
	retn
; ---------------------------------------------------------------------------

For this purpose Intel register EBP exists but the compiler ( or programmer :hysterical: ) is not so smart to use it.

You made no mistake in its interpretation. Only you need no write global as argument of all functions.

Continue!

Link to comment
Share on other sites

No, I still think DriverGlobal is really a structure used in purpose, just like ScrnInfoRec in linux source. In your example, the frame pointer you commented is actually a pointer pointing to the beginning of the class itself (just check any c++ document and you will see). It facilitates the access of other members and methods in the same class. So for each class method, there is such an extra argument, but not for any non-class procedure.

There is actually a DriverGlobal* pointer member in Carreta class (located at offset of 0x204 from the beginning of the class) which I found out from the initialization procedures.

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

I am here!

 

Just came across a OpenSolaris 2008.02 live DVD that supported the ATI Mobility X1400 right out of the box with Res, Toggle etc.

Hope that might help. Thanks

Linux, Unix, Solaris - no problem, as well as Windows.

The problem is MacOSX.

 

 

Anyone!

;)

Any comment

http://www.barbariangroup.com/posts/619-ch...d_line_on_a_mac

Link to comment
Share on other sites

newscreen is kind of thing like display preference but offer more resolution choices, that means it still depend on our framebuffer driver.

CGError CGConfigureDisplayMode (

CGDisplayConfigRef configRef,

CGDirectDisplayID display,

CFDictionaryRef mode

);

The display mode you provide must be one of the following:

 

I found this apple link:

http://developer.apple.com/documentation/H...vers/index.html

You may already know it, but I just see it and think it is useful.

Link to comment
Share on other sites

newscreen is kind of thing like display preference but offer more resolution choices, that means it still depend on our framebuffer driver.

OK!

May be knowledge how a framebuffer driver is used will be helpful for its design.

I found this apple link:

http://developer.apple.com/documentation/H...vers/index.html

You may already know it, but I just see it and think it is useful.

Yes, it is useful to read. But I don't know how much relations between MacOS Classic and X.

© 1999 Apple Computer, Inc. – (Last Updated 26 March 99)

Nontheless I see some similarities.

PCI display drivers have a category of kServiceCategoryNdrvDriver and a service type of kNdrvTypeIsVideo. They export a driver description structure and use the DoDriverIO entry point
Link to comment
Share on other sites

Yes, it is useful to read. But I don't know how much relations between MacOS Classic and X.

ATI native drivers are definitely based on these outdated information. The discovery of the link is during the study of Carreta. If you read a little more, you will see it explains in detail what data structures (defined in IOMacOSVideo.h) are being used in most status and control cmds, these really help a lot during reverse engineering.

Link to comment
Share on other sites

ATI native drivers are definitely based on these outdated information. The discovery of the link is during the study of Carreta. If you read a little more, you will see it explains in detail what data structures (defined in IOMacOSVideo.h) are being used in most status and control cmds, these really help a lot during reverse engineering.

OK. I find very few command and very few possibilities in its. -- too old. These commands useful for carbon applications and we can take its into account.

 

I found new drivers sources. From Apple!!! It is opensources IOKitUser.tar.gz. Inside I found interface for GA.plugin, EDID interpretation, modes list and change.

kern_return_t
IOCreatePlugInInterfaceForService(io_service_t service,
				CFUUIDRef pluginType, CFUUIDRef interfaceType,
				IOCFPlugInInterface *** theInterface, SInt32 * theScore)
{
...
static Boolean
EDIDDescToDisplayTimingRangeRec( EDID * edid, EDIDGeneralDesc * desc,
							 IODisplayTimingRange * range )
{
UInt8 byte;
...
static kern_return_t
IOFBBuildModeList( IOFBConnectRef connectRef )
{
...
__private_extern__ kern_return_t
IOFBInstallMode( IOFBConnectRef connectRef, IODisplayModeID mode,
			 IOFBDisplayModeDescription * desc,
			 UInt32 driverFlags, IOOptionBits modeGenFlags )
{
IOReturn			   ret = kIOReturnSuccess;
...

These sources is concurrent so it much better then analogous Joblo or Linux sources.

But they use abstract hardware calls (from BIOS, ROM, PEF or any else?).

I am sick of conforming one sources to another.

Link to comment
Share on other sites

Well, these are possibly kernel client interface for IOGraphicsFamily. If you have a working IOGraphicsFamily, you may write useful applications to tweak the graphics setting by using these procedures. The "IOFBConnectRef" should be a reference to the framebufferClient instance.

Yes, it still offer information on how the system communicates with IOGraphicsFamily.

Link to comment
Share on other sites

Well, these are possibly kernel client interface for IOGraphicsFamily. If you have a working IOGraphicsFamily, you may write useful applications to tweak the graphics setting by using these procedures. The "IOFBConnectRef" should be a reference to the framebufferClient instance.

Yes, it still offer information on how the system communicates with IOGraphicsFamily.

It is useful!

I agree that the interface is not a driver we try to write. I want to put your attention that it contain useful procedures and structures. I have

1. Joblo's procedures parse_edid and modes_db that adusted to Framebuffer use. But ATI fuctions in not good.

2. Linux's sources with good ATI function and other procedure interpret_edid. But these sources are not reliable for use inside Apple's Framebuffer. As I understand you have the same problem.

3. Now I see Apple's sources for interpret_EDID, create mode_set, and more for graphics driver. I think it is also information to study.

 

Really I can take latest Joblo's project, correct it for me and say "that's all". I think it is not good practice. My purpose is to create best driver. Now I use my Ati.kext (uploaded in topic) without resolution switch (OK, I already have native resolution) and dream about QE.

I wonder that no any tester confirm that my Ati.kext works or no for other Radeon. How can I do anything without help, support, testing, advices? Only Dong is here.

AMD is a bad company. They give me no "developer support" even though I do registration.

Link to comment
Share on other sites

sorry Slice, i'm feeling useless. I've tried to contact ati but nothing happened....

 

I'm following very close your progress, but i've no skills to help you. Sorry.

You can help me if do testing of ATILead122+Ati.kext. Links at topic.

You need to change ATILead.info.plist

				<key>@0,address</key>
			<integer>-805306368</integer>  -- dunno your value, set 0
			<key>@0,model</key>
			<string>ATY,RS300</string>  -- your value RS400
			<key>chipset-model</key>
			<string>ATY,RS300</string>

Value for address can be find in your ioreg

ioreg -l -x -w 1024 >ioreg.txt

	| |   |   +-o VGA@5  <class IOPCIDevice, registered, matched, active, busy 0, retain 11>
| |   |	 | {
| |   |	 |   "IOPCIResourced" = Yes
| |   |	 |   "IOInterruptControllers" = ("io-apic-0")
| |   |	 |   "IOName" = "display"
| |   |	 |   "subsystem-id" = <85300000>
| |   |	 |   "IODeviceMemory" = (({"address"=0xffffffffc0000000,"length"=0x10000000}),{"parent"=({"address"=0x0,"length"=0x10000}),"offset"=0x9000,"length"=0x100},({"address"=0xffffffffb0100000,"length"=0x10000}))

in the example 0xffffffffc0000000 or shortly 0xc0000000.

 

Without Callisto!

Link to comment
Share on other sites

I wonder that no any tester confirm that my Ati.kext works or no for other Radeon. How can I do anything without help, support, testing, advices? Only Dong is here.

AMD is a bad company. They give me no "developer support" even though I do registration.

 

I'm sure more people would help with testing if they knew how but with the current state of the forum thread it gets very confusing for non-developers to keep track of what is going on, what files to test and how to test them.

Link to comment
Share on other sites

Hi to all... i follow this thread also from some time, and i will like to help/debug, i dont know programming, but i can dive into the code to change things (commenting lines, changing values, etc), i have xcode installed and willing, just need a little guide to know how to do the correct testing.

 

My hardware:

Ati X2300 (DEV: 718A) on sony vaio laptop (This graphic card is an old rebranded x1450)

Link to comment
Share on other sites

;)

Very rare skill is programmer!

But I thought that not only noobs install MacOSX on PC! What do I need to explain?

OK.

 

How to test?

1. Install ATILead.kext and Ati.kext.

2. Correct its info.plist

3. Try to boot.

4. Catch messages to show me.

5. Undo all changes and rest.

 

Details.

1. How to install kexts? Type in terminal.

sudo -s

cp -r -v ~/Desktop/ATILead.kext /S*/L*/E*/

cp -r -v ~/Desktop/Ati.kext /S*/L*/E*/

rm -v /S*/L*/E*.ke*

rm -v /S*/L*/E*.mke*

diskutil repairpermissions /

2. How to correct info.plist?

sudo -s

nano /S*/L*/E*/ATILead.kext/Contents/info.plist

ctrl^o

ctrl^x

What to correct? See my previous post.

3. How to boot?

Best in single user mode with -v -s keys.

4. How to catch messages?

After boot with -s you may enter

/sbin/fsck -fy

/sbin/mount -uw /

sh /etc/rc

wait for all messages

type crtl^c

dmesg >dmesgYourNick.txt

exit

exit

If you can't boot make digital photo of screen

If you successfully boot the type in terminal

sudo -s

dmesg >dmesgYourNick.txt

ioreg -l -x -w 2048 >ioregYourNick.txt

kextstat >kextstatYourNick.txt

kextload -v RadeonPCI.kext

./RadeonDump -r 0,400 >regsYourNick.txt

Check also xBench, OpenMark or other graphics tests.

5. How to finish tests?

sudo -s

rm -r -v /S*/L*/E*/ATILead.kext

rm -r -v /S*/L*/E*/Ati.kext

reboot

6. How to rest?

Take two bottle of beer... ;)

 

Is there any news here?

 

For programmers/hackers/coders and so on.

If you find an error at the boot try to understand what is wrong.

 

Compatibility: at the moment for all except nVidia and Intel. :)

Link to comment
Share on other sites

Thanks, i will try and post what i find. ;)

 

Got kernel panic.... im trying to get good pictures, but cant find where in the code the error comes from the kernel panic, if you like i can add iologs to see where the kernel panic comes, but first need to guess where the iologs should be added....

When KP you see hexadecimal values on screen.

Find EIP register - it is address of last command

Look for loading address of kext where KP is occur. It might be slightly less then address of KP.

Then I can binary find a place in sources.

Link to comment
Share on other sites

Thanks, doing it now....

Panic (CPU 0 caller 0x001A8CD4)

 

EIP: 0x34bfa33a

If is not the correct loading adress, please tell me where to look for it.

 

It looks like

Ati.kext: (0x34bf123456)

 

or ATILead

or other with near address

Link to comment
Share on other sites

Done:

 

EIP: 0x34bfa33a

Com.free.driver.ati (1.0.3)@ 0x34650000>0x34b5dfff

Sorry, but this address is too far

0x34bfa33a - 0x34b5dfff = 0x9C33B = 639 803 ( Application Calculator in programmer's mode)

But Ati.kext has size only 100kb. So this address is out of the kext.

Try to look more carefully.

 

It may be a problem of address as I said before.

Link to comment
Share on other sites

I get this:

 

| | | +-o EVGA@0

| | | | {

| | | | "IOPCIResourced" = Yes

| | | | "IOInterruptControllers" = ("io-apic-0","IOPCIMessagedInterruptController")

| | | | "IOName" = "display"

| | | | "subsystem-id" =

| | | | "IODeviceMemory" = (({"address"=0xfffffffff0000000,"length"=0x4000000}),{"parent"=({"address"=0x0,"length"=0x10000}),"offset"=0x2000,"length"=0x100},({"address"=0xfffffffffc000000,"length"=0x10000}))

| | | | "display-connect-flags" =

| | | | "class-code" =

| | | | "revision-id" =

| | | | "assigned-addresses" =

 

and insert it as 0x0000000....

Better i try to post a good picture.... :P

No. "address"=0xfffffffff0000000 = 0xf0000000

Yes, show picture.

Link to comment
Share on other sites

Sorry cause my mistakes... i have clean my posts also, dont want to flood the thread.

I added 0xf0000000 I have used plist editor for this, not text edit.

, so it looked like:

 

<key>@0,address</key>

<integer>-268435456</integer

<key>@0,model</key>

<string>ATY,M64</string

 

<key>chipset-model</key>

<string>ATY,M64</string>

 

Then got kernel panic on boot, i have attached two pics cause the camera didnt do a good job.

post-98153-1221314114_thumb.jpg

post-98153-1221314128_thumb.jpg

Link to comment
Share on other sites

Sorry cause my mistakes... i have clean my posts also, dont want to flood the thread.

I added 0xf0000000 I have used plist editor for this, not text edit.

, so it looked like:

 

@0,address

-268435456

@0,model

ATY,M64

 

chipset-model

ATY,M64

 

Then got kernel panic on boot, i have attached two pics cause the camera didnt do a good job.

Now all is clear.

Bad reading name of card from ATOMBIOS. Actually ATOMBIOS doesn't contain card name. It is not hard to correct.

For example using list of different names.

 

EIP=0x3476733a

Ati =0x34765000

 

relative address = 0x233a.

It is in procedure GetConnectorInfoFromBIOS. KP is here. Some mistake in my codes. Actually Dong has good sources for GetConnectorInfo for ATOMBIOS. But very complex. Dong, look at my codes, please! Where is zero pointer for AtomBIOS?

 

EDITED: Found! MasterDataStart is undefined! Sorry!

	int MasterDataStart;

//	rinfo->ROMHeaderStart = BIOS_IN16(0x48);
if(rinfo->IsAtomBios)
{
//		MasterDataStart = BIOS_IN16( rinfo->ROMHeaderStart + 32 );
	tmp = BIOS_IN16( MasterDataStart + 22);  // unassigned

Should be

//	int MasterDataStart;		 // don't need local definition

//	rinfo->ROMHeaderStart = BIOS_IN16(0x48);
if(rinfo->IsAtomBios)
{
//		MasterDataStart = BIOS_IN16( rinfo->ROMHeaderStart + 32 );
	tmp = BIOS_IN16(rinfo->MasterDataStart + 22);

Link to comment
Share on other sites

 Share

×
×
  • Create New...