summaryrefslogtreecommitdiff
path: root/QemuVGADriver/src
diff options
context:
space:
mode:
Diffstat (limited to 'QemuVGADriver/src')
-rwxr-xr-x[-rw-r--r--]QemuVGADriver/src/DriverDoDriverIO.c52
-rwxr-xr-x[-rw-r--r--]QemuVGADriver/src/DriverGestaltHandler.c5
-rwxr-xr-x[-rw-r--r--]QemuVGADriver/src/DriverQDCalls.c278
-rw-r--r--QemuVGADriver/src/QemuVga.c187
-rwxr-xr-x[-rw-r--r--]QemuVGADriver/src/QemuVga.h17
-rwxr-xr-x[-rw-r--r--]QemuVGADriver/src/VideoDriverPrivate.h11
-rwxr-xr-x[-rw-r--r--]QemuVGADriver/src/VideoDriverPrototypes.h5
7 files changed, 314 insertions, 241 deletions
diff --git a/QemuVGADriver/src/DriverDoDriverIO.c b/QemuVGADriver/src/DriverDoDriverIO.c
index 38f861a..d72fd9c 100644..100755
--- a/QemuVGADriver/src/DriverDoDriverIO.c
+++ b/QemuVGADriver/src/DriverDoDriverIO.c
@@ -25,7 +25,7 @@ DriverDescription TheDriverDescription = {
| (0 * kDriverIsLoadedUponDiscovery) /* Loader runtime options */
| (1 * kDriverIsOpenedUponLoad) /* Opened when loaded */
| (1 * kDriverIsUnderExpertControl) /* I/O expert handles loads/opens */
- | (01 * kDriverIsConcurrent) /* concurrent */
+ | (0 * kDriverIsConcurrent) /* concurrent */
| (0 * kDriverQueuesIOPB), /* Internally queued */
QEMU_PCI_VIDEO_PNAME, /* Str31 driverName (OpenDriver param) */
0, 0, 0, 0, 0, 0, 0, 0, /* UInt32 driverDescReserved[8] */
@@ -42,8 +42,6 @@ DriverDescription TheDriverDescription = {
1, 0, 0, 0
};
-#pragma internal on
-
/*
* All driver-global information is in a structure defined in NCRDriverPrivate.
* Note that "modern" drivers do not have access to their dce. In native Power PC
@@ -77,8 +75,6 @@ DriverGlobal gDriverGlobal;
* If it returns busy status, the driver promises to call IOCommandIsComplete when
* the transaction has completed.
*/
-#pragma internal off
-
OSStatus
DoDriverIO( AddressSpaceID addressSpaceID, IOCommandID ioCommandID, IOCommandContents ioCommandContents,
IOCommandCode ioCommandCode, IOCommandKind ioCommandKind )
@@ -90,8 +86,8 @@ DoDriverIO( AddressSpaceID addressSpaceID, IOCommandID ioCommandID, IOCommandCon
* or immediate. Read, Write, Control, and Status may be immediate,
* synchronous, or asynchronous.
*/
-
- Trace(DoDriverIO);
+
+ lprintf("DoDriverIO cmdCode=%d\n", ioCommandCode);
switch( ioCommandCode ) {
case kInitializeCommand: /* Always immediate */
@@ -119,7 +115,6 @@ DoDriverIO( AddressSpaceID addressSpaceID, IOCommandID ioCommandID, IOCommandCon
(CntrlParam*)ioCommandContents.pb );
break;
case kStatusCommand:
- /* lprintf("kStatusCommand\n"); */
status = DriverStatusCmd( ioCommandID, ioCommandKind,
(CntrlParam *)ioCommandContents.pb );
break;
@@ -138,6 +133,8 @@ DoDriverIO( AddressSpaceID addressSpaceID, IOCommandID ioCommandID, IOCommandCon
status = paramErr;
break;
}
+ lprintf("Completing with status=%d (kind: %x)\n", status, ioCommandKind);
+
/*
* Force a valid result for immediate commands -- they must return a valid
* status to the Driver Manager: returning kIOBusyStatus would be a bug..
@@ -166,8 +163,6 @@ DoDriverIO( AddressSpaceID addressSpaceID, IOCommandID ioCommandID, IOCommandCon
return status;
}
-#pragma internal on
-
/*
* DriverInitializeCmd
*
@@ -180,6 +175,11 @@ DriverInitializeCmd( AddressSpaceID addressSpaceID, DriverInitInfoPtr driverInit
Trace(DriverInitializeCmd);
+ lprintf("** First call:\n");
+ lprintf(" DoDriverIO @ %p\n", DoDriverIO);
+ lprintf(" DriverStatusCmd @ %p\n", DriverStatusCmd);
+ lprintf(" DriverControlCmd @ %p\n", DriverControlCmd);
+
GLOBAL.refNum = driverInitInfoPtr->refNum;
GLOBAL.openCount = 0;
GLOBAL.inInterrupt = false;
@@ -217,6 +217,7 @@ DriverInitializeCmd( AddressSpaceID addressSpaceID, DriverInitInfoPtr driverInit
GLOBAL.boardRegAddress, GLOBAL.boardRegMappedSize);
+ lprintf("Enabling memory space..\n");
status = EnablePCIMemorySpace(&GLOBAL.deviceEntry);
if (status != noErr) {
lprintf("EnablePCIMemorySpace returned %d\n", status);
@@ -224,7 +225,9 @@ DriverInitializeCmd( AddressSpaceID addressSpaceID, DriverInitInfoPtr driverInit
}
status = QemuVga_Init();
-
+ if (status != noErr)
+ goto bail;
+
bail:
DBG(lprintf("Driver init result: %d\n", status));
@@ -330,12 +333,11 @@ DriverControlCmd( AddressSpaceID addressSpaceID, IOCommandID ioCommandID,
switch( pb->csCode ) {
case cscReset: // Old obsolete call..return a 'controlErr'
- status = controlErr;
+ return controlErr;
break;
case cscKillIO: // Old obsolete call..do nothing
- status = controlErr;
- break;
+ return noErr;
case cscSetMode:
status = GraphicsCoreSetMode((VDPageInfo *) genericPtr);
@@ -368,8 +370,7 @@ DriverControlCmd( AddressSpaceID addressSpaceID, IOCommandID ioCommandID,
break;
case cscSetDefaultMode:
- status = controlErr;
- break;
+ return controlErr;
case cscSwitchMode:
status = GraphicsCoreSwitchMode((VDSwitchInfoRec *) genericPtr);
@@ -394,11 +395,10 @@ DriverControlCmd( AddressSpaceID addressSpaceID, IOCommandID ioCommandID,
status = GraphicsCoreSetPowerState((VDPowerStateRec *) genericPtr);
break;
default:
- status = controlErr;
break;
}
- if( status )
- status = controlErr;
+ if (status)
+ status = paramErr;
return status;
}
@@ -425,7 +425,7 @@ DriverStatusCmd( IOCommandID ioCommandID, IOCommandKind ioCommandKind, CntrlPara
genericPtr = (void *) *((UInt32 *) &(pb->csParam[0]));
Trace(DriverStatusCmd);
-
+ lprintf("csCode=%d\n", pb->csCode);
switch( pb->csCode ) {
case cscGetMode:
status = GraphicsCoreGetMode((VDPageInfo *) genericPtr);
@@ -510,13 +510,15 @@ DriverStatusCmd( IOCommandID ioCommandID, IOCommandKind ioCommandKind, CntrlPara
case cscGetPowerState:
status = GraphicsCoreGetPowerState((VDPowerStateRec *) genericPtr);
break;
-
- default:
- status = statusErr;
+ case cscGetClutBehavior:
+ *(VDClutBehaviorPtr)genericPtr = kSetClutAtSetEntries;
+ status = noErr;
break;
+ default:
+ return statusErr;
}
- if( status )
- status = statusErr;
+ if (status)
+ status = paramErr;
return status;
}
diff --git a/QemuVGADriver/src/DriverGestaltHandler.c b/QemuVGADriver/src/DriverGestaltHandler.c
index ca37874..84189e0 100644..100755
--- a/QemuVGADriver/src/DriverGestaltHandler.c
+++ b/QemuVGADriver/src/DriverGestaltHandler.c
@@ -16,6 +16,11 @@ DriverGestaltHandler( CntrlParam *pb )
PB.driverGestaltResponse = 0;
status = noErr;
+ lprintf("DriverGestalt, selector=%c%c%c%c\n",
+ PB.driverGestaltSelector >> 24,
+ (PB.driverGestaltSelector >> 16) & 0xff,
+ (PB.driverGestaltSelector >> 8) & 0xff,
+ (PB.driverGestaltSelector ) & 0xff);
switch( PB.driverGestaltSelector ) {
case kdgSync:
PB.driverGestaltResponse = FALSE; /* We handle asynchronous I/O */
diff --git a/QemuVGADriver/src/DriverQDCalls.c b/QemuVGADriver/src/DriverQDCalls.c
index 2383643..f33a76e 100644..100755
--- a/QemuVGADriver/src/DriverQDCalls.c
+++ b/QemuVGADriver/src/DriverQDCalls.c
@@ -3,10 +3,60 @@
#include "DriverQDCalls.h"
#include "QemuVga.h"
-static OSStatus GraphicsCoreDoSetEntries(VDSetEntryRecord *entryRecord, Boolean directDevice, UInt32 start, UInt32 stop, Boolean useValue);
+#define MAX_DEPTH_MODE kDepthMode3
+
+static UInt8 DepthToDepthMode(UInt8 depth)
+{
+ switch (depth) {
+ case 8:
+ return kDepthMode1;
+ case 15:
+ case 16:
+ return kDepthMode2;
+ case 24:
+ case 32:
+ return kDepthMode3;
+ default:
+ return kDepthMode1;
+ }
+}
+
+static UInt8 DepthModeToDepth(UInt8 mode)
+{
+ switch (mode) {
+ case kDepthMode1:
+ return 32;
+ case kDepthMode2:
+ return 15;
+ case kDepthMode3:
+ return 32;
+ default:
+ return 8;
+ }
+}
/************************ Color Table Stuff ****************************/
+static OSStatus
+GraphicsCoreDoSetEntries(VDSetEntryRecord *entryRecord, Boolean directDevice, UInt32 start, UInt32 stop, Boolean useValue)
+{
+ UInt32 i;
+
+ CHECK_OPEN( controlErr );
+ if (GLOBAL.depth != 8)
+ return controlErr;
+ if (NULL == entryRecord->csTable)
+ return controlErr;
+
+ /* Note that stop value is included in the range */
+ for(i=start;i<=stop;i++) {
+ UInt32 colorIndex = useValue ? entryRecord->csTable[i].value : i;
+ QemuVga_SetColorEntry(colorIndex, &entryRecord->csTable[i].rgb);
+ }
+
+ return noErr;
+}
+
OSStatus
GraphicsCoreSetEntries(VDSetEntryRecord *entryRecord)
{
@@ -32,29 +82,6 @@ GraphicsCoreDirectSetEntries(VDSetEntryRecord *entryRecord)
}
OSStatus
-GraphicsCoreDoSetEntries(VDSetEntryRecord *entryRecord, Boolean directDevice, UInt32 start, UInt32 stop, Boolean useValue)
-{
- UInt32 i;
-
- CHECK_OPEN( controlErr );
- if (GLOBAL.depth != 8)
- return controlErr;
- if (NULL == entryRecord->csTable)
- return controlErr;
-// if (directDevice != (VMODE.depth != 8))
-// return controlErr;
-
- /* Note that stop value is included in the range */
- for(i=start;i<=stop;i++) {
- UInt32 tabIndex = i-start;
- UInt32 colorIndex = useValue ? entryRecord->csTable[tabIndex].value : tabIndex;
- QemuVga_SetColorEntry(colorIndex, &entryRecord->csTable[tabIndex].rgb);
- }
-
- return noErr;
-}
-
-OSStatus
GraphicsCoreGetEntries(VDSetEntryRecord *entryRecord)
{
Boolean useValue = (entryRecord->csStart < 0);
@@ -64,10 +91,11 @@ GraphicsCoreGetEntries(VDSetEntryRecord *entryRecord)
Trace(GraphicsCoreGetEntries);
+ if (GLOBAL.depth != 8)
+ return controlErr;
for(i=start;i<=stop;i++) {
- UInt32 tabIndex = i-start;
- UInt32 colorIndex = useValue ? entryRecord->csTable[tabIndex].value : tabIndex;
- QemuVga_GetColorEntry(colorIndex, &entryRecord->csTable[tabIndex].rgb);
+ UInt32 colorIndex = useValue ? entryRecord->csTable[i].value : i;
+ QemuVga_GetColorEntry(colorIndex, &entryRecord->csTable[i].rgb);
}
return noErr;
@@ -117,13 +145,17 @@ GraphicsCoreGetGamma(VDGammaRecord *gammaRecord)
OSStatus
GraphicsCoreGrayPage(VDPageInfo *pageInfo)
{
+ UInt32 pageCount;
+
CHECK_OPEN( controlErr );
Trace(GraphicsCoreGrayPage);
- if (pageInfo->csPage != 0)
+ QemuVga_GetModePages(GLOBAL.curMode, GLOBAL.depth, NULL, &pageCount);
+ if (pageInfo->csPage >= pageCount)
return paramErr;
-
+
+ /* XXX Make it gray ! */
return noErr;
}
@@ -142,12 +174,16 @@ GraphicsCoreSetGray(VDGrayRecord *grayRecord)
OSStatus
GraphicsCoreGetPages(VDPageInfo *pageInfo)
{
-/* DepthMode mode; */
+ UInt32 pageCount, depth;
+
CHECK_OPEN( statusErr );
Trace(GraphicsCoreGetPages);
- pageInfo->csPage = 1;
+ depth = DepthModeToDepth(pageInfo->csMode);
+ QemuVga_GetModePages(GLOBAL.curMode, depth, NULL, &pageCount);
+ pageInfo->csPage = pageCount;
+
return noErr;
}
@@ -233,79 +269,22 @@ GraphicsCoreGetInterrupt(VDFlagRecord *flagRecord)
return noErr;
}
-/* assume initial state is always "power-on" */
-// XXX FIXME
-static unsigned long MOLVideoPowerState = kAVPowerOn;
-
OSStatus
GraphicsCoreSetSync(VDSyncInfoRec *syncInfo)
{
- unsigned char syncmask;
- unsigned long newpowermode;
-
Trace(GraphicsCoreSetSync);
CHECK_OPEN( controlErr );
- syncmask = (!syncInfo->csFlags)? kDPMSSyncMask: syncInfo->csFlags;
- if (!(syncmask & kDPMSSyncMask)) /* nothing to do */
- return noErr;
- switch (syncInfo->csMode & syncmask) {
- case kDPMSSyncOn:
- newpowermode = kAVPowerOn;
- break;
- case kDPMSSyncStandby:
- newpowermode = kAVPowerStandby;
- break;
- case kDPMSSyncSuspend:
- newpowermode = kAVPowerSuspend;
- break;
- case kDPMSSyncOff:
- newpowermode = kAVPowerOff;
- break;
- default:
- return paramErr;
- }
- if (newpowermode != MOLVideoPowerState) {
- //OSI_SetVPowerState(newpowermode);
- MOLVideoPowerState = newpowermode;
- }
-
- return noErr;
+ return paramErr;
}
OSStatus
GraphicsCoreGetSync(VDSyncInfoRec *syncInfo)
{
- CHECK_OPEN( statusErr );
-
Trace(GraphicsCoreGetSync);
- if (syncInfo->csMode == 0xff) {
- /* report back the capability */
- syncInfo->csMode = 0 | ( 1 << kDisableHorizontalSyncBit)
- | ( 1 << kDisableVerticalSyncBit)
- | ( 1 << kDisableCompositeSyncBit);
- } else if (syncInfo->csMode == 0) {
- /* current sync mode */
- switch (MOLVideoPowerState) {
- case kAVPowerOn:
- syncInfo->csMode = kDPMSSyncOn;
- break;
- case kAVPowerStandby:
- syncInfo->csMode = kDPMSSyncStandby;
- break;
- case kAVPowerSuspend:
- syncInfo->csMode = kDPMSSyncSuspend;
- break;
- case kAVPowerOff:
- syncInfo->csMode = kDPMSSyncOff;
- break;
- }
- } else /* not defined ? */
- return paramErr;
-
- return noErr;
+ return paramErr;
}
OSStatus
@@ -313,18 +292,7 @@ GraphicsCoreSetPowerState(VDPowerStateRec *powerStateRec)
{
Trace(GraphicsCoreSetPowerState);
- CHECK_OPEN( controlErr );
-
- if (powerStateRec->powerState > kAVPowerOn)
- return paramErr;
-
- if (MOLVideoPowerState != powerStateRec->powerState) {
- //OSI_SetVPowerState(powerStateRec->powerState);
- MOLVideoPowerState = powerStateRec->powerState;
- }
- powerStateRec->powerFlags = 0;
-
- return noErr;
+ return paramErr;
}
OSStatus
@@ -332,11 +300,7 @@ GraphicsCoreGetPowerState(VDPowerStateRec *powerStateRec)
{
Trace(GraphicsCoreGetPowerState);
- CHECK_OPEN( statusErr );
-
- powerStateRec->powerState = MOLVideoPowerState;
- powerStateRec->powerFlags = 0;
- return noErr;
+ return paramErr;
}
OSStatus
@@ -349,30 +313,6 @@ GraphicsCoreSetPreferredConfiguration(VDSwitchInfoRec *switchInfo)
return noErr;
}
-static UInt8 DepthToDepthMode(UInt8 depth)
-{
- switch (depth) {
- case 8:
- return kDepthMode1;
- case 15:
- case 16:
- return kDepthMode2;
- default:
- return kDepthMode3;
- }
-}
-
-static UInt8 DepthModeToDepth(UInt8 mode)
-{
- switch (mode) {
- case kDepthMode1:
- return 8;
- case kDepthMode2:
- return 15;
- default:
- return 32;
- }
-}
OSStatus
GraphicsCoreGetPreferredConfiguration(VDSwitchInfoRec *switchInfo)
@@ -394,14 +334,18 @@ GraphicsCoreGetPreferredConfiguration(VDSwitchInfoRec *switchInfo)
OSStatus
GraphicsCoreGetBaseAddress(VDPageInfo *pageInfo)
{
+ UInt32 pageCount, pageSize;
+
Trace(GraphicsCoreGetBaseAddress);
CHECK_OPEN( statusErr );
- if (pageInfo->csPage != 0)
+ QemuVga_GetModePages(GLOBAL.curMode, GLOBAL.depth, &pageSize, &pageCount);
+ if (pageInfo->csPage >= pageCount)
return paramErr;
- pageInfo->csBaseAddr = FB_START;
+ pageInfo->csBaseAddr = FB_START + pageInfo->csPage * pageSize;
+
return noErr;
}
@@ -431,11 +375,10 @@ GraphicsCoreGetMode(VDPageInfo *pageInfo)
CHECK_OPEN( statusErr );
- //lprintf("GetMode\n");
pageInfo->csMode = DepthToDepthMode(GLOBAL.depth);
- pageInfo->csPage = 0;
- pageInfo->csBaseAddr = FB_START;
-
+ pageInfo->csPage = GLOBAL.curPage;
+ pageInfo->csBaseAddr = GLOBAL.curBaseAddress;
+
return noErr;
}
@@ -449,8 +392,8 @@ GraphicsCoreGetCurrentMode(VDSwitchInfoRec *switchInfo)
//lprintf("GetCurrentMode\n");
switchInfo->csMode = DepthToDepthMode(GLOBAL.depth);
switchInfo->csData = GLOBAL.curMode + 1;
- switchInfo->csPage = 0;
- switchInfo->csBaseAddr = FB_START;
+ switchInfo->csPage = GLOBAL.curPage;
+ switchInfo->csBaseAddr = GLOBAL.curBaseAddress;
return noErr;
}
@@ -480,15 +423,25 @@ GraphicsCoreGetModeTiming(VDTimingInfoRec *timingInfo)
OSStatus
GraphicsCoreSetMode(VDPageInfo *pageInfo)
{
+ UInt32 newDepth, newPage, pageCount;
+
Trace(GraphicsCoreSetMode);
CHECK_OPEN(controlErr);
- if (pageInfo->csPage != 0)
+ newDepth = DepthModeToDepth(pageInfo->csMode);
+ newPage = pageInfo->csPage;
+ QemuVga_GetModePages(GLOBAL.curMode, newDepth, NULL, &pageCount);
+
+ lprintf("Requested depth=%d page=%d\n", newDepth, newPage);
+ if (pageInfo->csPage >= pageCount)
return paramErr;
- QemuVga_SetMode(GLOBAL.curMode, DepthModeToDepth(pageInfo->csMode));
- pageInfo->csBaseAddr = FB_START;
+ if (newDepth != GLOBAL.depth || newPage != GLOBAL.curPage)
+ QemuVga_SetMode(GLOBAL.curMode, newDepth, newPage);
+
+ pageInfo->csBaseAddr = GLOBAL.curBaseAddress;
+ lprintf("Returning BA: %lx\n", pageInfo->csBaseAddr);
return noErr;
}
@@ -497,23 +450,26 @@ GraphicsCoreSetMode(VDPageInfo *pageInfo)
OSStatus
GraphicsCoreSwitchMode(VDSwitchInfoRec *switchInfo)
{
- UInt32 newMode, newDepth;
+ UInt32 newMode, newDepth, newPage, pageCount;
Trace(GraphicsCoreSwitchMode);
CHECK_OPEN(controlErr);
-
- if (switchInfo->csPage != 0)
- return paramErr;
newMode = switchInfo->csData - 1;
newDepth = DepthModeToDepth(switchInfo->csMode);
-
- if (newMode != GLOBAL.curMode || newDepth != GLOBAL.depth) {
- if (QemuVga_SetMode(newMode, newDepth))
+ newPage = switchInfo->csPage;
+ QemuVga_GetModePages(GLOBAL.curMode, newDepth, NULL, &pageCount);
+
+ if (newPage >= pageCount)
+ return paramErr;
+
+ if (newMode != GLOBAL.curMode || newDepth != GLOBAL.depth ||
+ newPage != GLOBAL.curPage) {
+ if (QemuVga_SetMode(newMode, newDepth, newPage))
return controlErr;
}
- switchInfo->csBaseAddr = FB_START;
+ switchInfo->csBaseAddr = GLOBAL.curBaseAddress;
return noErr;
}
@@ -548,7 +504,7 @@ GraphicsCoreGetNextResolution(VDResolutionInfoRec *resInfo)
resInfo->csHorizontalPixels = width;
resInfo->csVerticalLines = height;
resInfo->csRefreshRate = 60;
- resInfo->csMaxDepthMode = kDepthMode3; /* XXX Calculate if it fits ! */
+ resInfo->csMaxDepthMode = MAX_DEPTH_MODE; /* XXX Calculate if it fits ! */
return noErr;
}
@@ -557,29 +513,26 @@ GraphicsCoreGetNextResolution(VDResolutionInfoRec *resInfo)
OSStatus
GraphicsCoreGetVideoParams(VDVideoParametersInfoRec *videoParams)
{
- UInt32 width, height, depth;
+ UInt32 width, height, depth, rowBytes, pageCount;
OSStatus err = noErr;
Trace(GraphicsCoreGetVideoParams);
CHECK_OPEN(statusErr);
-
- //lprintf("GetVideoParams(ID=%d, depthMode=%d)\n",
- // videoParams->csDisplayModeID,
- // videoParams->csDepthMode);
if (videoParams->csDisplayModeID < 1 || videoParams->csDisplayModeID > GLOBAL.numModes)
return paramErr;
-
+ if (videoParams->csDepthMode > MAX_DEPTH_MODE)
+ return paramErr;
if (QemuVga_GetModeInfo(videoParams->csDisplayModeID - 1, &width, &height))
return paramErr;
-
- videoParams->csPageCount = 1;
depth = DepthModeToDepth(videoParams->csDepthMode);
-
- //lprintf(" -> width=%d, height=%d, depth=%d\n", width, height, depth);
+ QemuVga_GetModePages(videoParams->csDisplayModeID - 1, depth, NULL, &pageCount);
+ videoParams->csPageCount = pageCount;
+ lprintf("Video Params says %d pages\n", pageCount);
+ rowBytes = width * ((depth + 7) / 8);
(videoParams->csVPBlockPtr)->vpBaseOffset = 0; // For us, it's always 0
(videoParams->csVPBlockPtr)->vpBounds.top = 0; // Always 0
(videoParams->csVPBlockPtr)->vpBounds.left = 0; // Always 0
@@ -589,10 +542,9 @@ GraphicsCoreGetVideoParams(VDVideoParametersInfoRec *videoParams)
(videoParams->csVPBlockPtr)->vpHRes = 0x00480000; // Hard coded to 72 dpi
(videoParams->csVPBlockPtr)->vpVRes = 0x00480000; // Hard coded to 72 dpi
(videoParams->csVPBlockPtr)->vpPlaneBytes = 0; // Always 0
-
(videoParams->csVPBlockPtr)->vpBounds.bottom = height;
(videoParams->csVPBlockPtr)->vpBounds.right = width;
- (videoParams->csVPBlockPtr)->vpRowBytes = width * ((depth + 7) / 8);
+ (videoParams->csVPBlockPtr)->vpRowBytes = rowBytes;
switch (depth) {
case 8:
diff --git a/QemuVGADriver/src/QemuVga.c b/QemuVGADriver/src/QemuVga.c
index 8c996a7..a208ae0 100644
--- a/QemuVGADriver/src/QemuVga.c
+++ b/QemuVGADriver/src/QemuVga.c
@@ -2,6 +2,7 @@
#include "VideoDriverPrototypes.h"
#include "DriverQDCalls.h"
#include "QemuVga.h"
+#include <Timer.h>
/* List of supported modes */
struct vMode {
@@ -77,11 +78,82 @@ static UInt32 ExtReadL(UInt32 reg)
return val;
}
+static OSStatus VBLTimerProc(void *p1, void *p2);
+
+#ifndef USE_DSL_TIMER
+static TMTask gLegacyTimer;
+
+static pascal void legacyTimerCB(TMTaskPtr *inTask)
+{
+ VBLTimerProc(NULL, NULL);
+}
+
+static const RoutineDescriptor gLegacyTimerDesc = BUILD_ROUTINE_DESCRIPTOR(uppTimerProcInfo, legacyTimerCB);
+static const TimerUPP gLegacyTimerProc = (TimerUPP) &gLegacyTimerDesc;
+static int gTimerInstalled;
+
+static OSStatus ScheduleVBLTimer(void)
+{
+ if (!gTimerInstalled) {
+ BlockZero(&gLegacyTimer, sizeof(gLegacyTimer));
+ gLegacyTimer.tmAddr = gLegacyTimerProc;
+ gLegacyTimer.qLink = (QElemPtr)'eada';
+ InsXTime((QElemPtr)&gLegacyTimer);
+ gTimerInstalled = true;
+ }
+ PrimeTime((QElemPtr)&gLegacyTimer, TIMER_DURATION);
+ return noErr;
+}
+
+#else
+
+static OSStatus ScheduleVBLTimer(void)
+{
+ AbsoluteTime target = AddDurationToAbsolute(TIMER_DURATION, UpTime());
+ return SetInterruptTimer(&target, VBLTimerProc, NULL, &GLOBAL.VBLTimerID);
+}
+
+#endif
+
+static OSStatus VBLTimerProc(void *p1, void *p2)
+{
+ static UInt32 VBcnt;
+
+ GLOBAL.inInterrupt = 1;
+
+ /* This can be called before the service is ready */
+ if (GLOBAL.qdVBLInterrupt && GLOBAL.qdInterruptsEnable)
+ VSLDoInterruptService(GLOBAL.qdVBLInterrupt);
+
+ /* Reschedule */
+ ScheduleVBLTimer();
+
+ GLOBAL.inInterrupt = 0;
+}
+
+#ifdef USE_PCI_IRQ
+static InterruptMemberNumber PCIInterruptHandler(InterruptSetMember ISTmember,
+ void *refCon, UInt32 theIntCount)
+{
+ UInt32 reg;
+
+ reg = ExtReadL(2);
+ if (!(reg & 1))
+ return kIsrIsNotComplete;
+ if (GLOBAL.qdVBLInterrupt && GLOBAL.qdInterruptsEnable)
+ VSLDoInterruptService(GLOBAL.qdVBLInterrupt);
+ ExtWriteL(2, 3);
+ return kIsrIsComplete;
+}
+#endif
+
+
OSStatus QemuVga_Init(void)
{
UInt16 id, i;
UInt32 mem, width, height, depth;
+ lprintf("First MMIO read...\n");
id = DispiReadW(VBE_DISPI_INDEX_ID);
mem = DispiReadW(VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
mem <<= 16;
@@ -110,34 +182,20 @@ OSStatus QemuVga_Init(void)
lprintf("Not found in list ! using default.\n");
i = 0;
}
- GLOBAL.curMode = GLOBAL.bootMode = i;
+ GLOBAL.bootMode = i;
GLOBAL.numModes = sizeof(vModes) / sizeof(struct vMode) - 1;
- return noErr;
-}
-
-static OSStatus VBLTimerProc(void *p1, void *p2);
-
-static OSStatus ScheduleVBLTimer(void)
-{
- /* XXX HACK: Run timer at 20Hz */
- AbsoluteTime target = AddDurationToAbsolute(50, UpTime());
-
- return SetInterruptTimer(&target, VBLTimerProc, NULL, &GLOBAL.VBLTimerID);
-}
-
-static OSStatus VBLTimerProc(void *p1, void *p2)
-{
- GLOBAL.inInterrupt = 1;
-
- /* This can be called before the service is ready */
- if (GLOBAL.qdVBLInterrupt && GLOBAL.qdInterruptsEnable)
- VSLDoInterruptService(GLOBAL.qdVBLInterrupt);
-
- /* Reschedule */
- ScheduleVBLTimer();
+ QemuVga_SetMode(GLOBAL.bootMode, depth, 0);
- GLOBAL.inInterrupt = 0;
+#ifdef USE_PCI_IRQ
+ if (SetupPCIInterrupt(&GLOBAL.deviceEntry, &GLOBAL.irqInfo,
+ PCIInterruptHandler, NULL) == noErr)
+ GLOBAL.hasPCIInterrupt = true;
+ else
+#else
+ GLOBAL.hasPCIInterrupt = false;
+#endif
+ return noErr;
}
OSStatus QemuVga_Open(void)
@@ -146,22 +204,29 @@ OSStatus QemuVga_Open(void)
GLOBAL.isOpen = true;
- /* Schedule the timer now if timers are supported. They aren't on OS X
- * in which case we must not create the VSL service, otherwise OS X will expect
- * a VBL and fail to update the cursor when not getting one.
- */
- GLOBAL.hasTimer = (ScheduleVBLTimer() == noErr);
- GLOBAL.qdInterruptsEnable = GLOBAL.hasTimer;
+ if (GLOBAL.hasPCIInterrupt) {
+ QemuVga_EnableInterrupts();
+ lprintf("VBL registered using PCI interrupts\n");
+ } else {
+ /* Schedule the timer now if timers are supported. They aren't on OS X
+ * in which case we must not create the VSL service, otherwise OS X will expect
+ * a VBL and fail to update the cursor when not getting one.
+ */
+ lprintf("Testing using timer to simulate VBL..\n");
+ GLOBAL.hasTimer = (ScheduleVBLTimer() == noErr);
+ GLOBAL.qdInterruptsEnable = GLOBAL.hasTimer;
+
+ if (GLOBAL.hasTimer)
+ lprintf("Using timer to simulate VBL.\n");
+ else
+ lprintf("No timer service (OS X ?), VBL not registered.\n");
+
+ }
- /* Create VBL if timer works */
- if (GLOBAL.hasTimer && !GLOBAL.qdVBLInterrupt)
+ /* Create VBL if we have a PCI interrupt or timer works */
+ if (GLOBAL.hasPCIInterrupt || GLOBAL.hasTimer)
VSLNewInterruptService(&GLOBAL.deviceEntry, kVBLInterruptServiceType, &GLOBAL.qdVBLInterrupt);
- if (GLOBAL.hasTimer)
- lprintf("Using timer to simulate VBL.\n");
- else
- lprintf("No timer service (OS X ?), VBL not registered.\n");
-
return noErr;
}
@@ -190,7 +255,11 @@ void QemuVga_EnableInterrupts(void)
{
GLOBAL.qdInterruptsEnable = true;
if (GLOBAL.hasTimer)
- ScheduleVBLTimer();
+ ScheduleVBLTimer();
+ else if (GLOBAL.hasPCIInterrupt) {
+ GLOBAL.irqInfo.enableFunction(GLOBAL.irqInfo.interruptSetMember, GLOBAL.irqInfo.refCon);
+ ExtWriteL(2, 3);
+ }
}
void QemuVga_DisableInterrupts(void)
@@ -200,6 +269,10 @@ void QemuVga_DisableInterrupts(void)
GLOBAL.qdInterruptsEnable = false;
if (GLOBAL.hasTimer)
CancelTimer(GLOBAL.VBLTimerID, &remaining);
+ else if (GLOBAL.hasPCIInterrupt) {
+ ExtWriteL(2, 1);
+ GLOBAL.irqInfo.disableFunction(GLOBAL.irqInfo.interruptSetMember, GLOBAL.irqInfo.refCon);
+ }
}
OSStatus QemuVga_SetColorEntry(UInt32 index, RGBColor *color)
@@ -238,17 +311,41 @@ OSStatus QemuVga_GetModeInfo(UInt32 index, UInt32 *width, UInt32 *height)
return noErr;
}
+OSStatus QemuVga_GetModePages(UInt32 index, UInt32 depth,
+ UInt32 *pageSize, UInt32 *pageCount)
+{
+ UInt32 width, height, pBytes;
+
+ if (index >= GLOBAL.numModes)
+ return paramErr;
+ width = vModes[index].width;
+ height = vModes[index].height;
+ pBytes = width * ((depth + 7) / 8) * height;
+ if (pageSize)
+ *pageSize = pBytes;
+ if (pageCount) {
+ if (pBytes <= (GLOBAL.boardFBMappedSize / 2))
+ *pageCount = 2;
+ else
+ *pageCount = 1;
+ }
+ return noErr;
+}
-OSStatus QemuVga_SetMode(UInt32 mode, UInt32 depth)
+OSStatus QemuVga_SetMode(UInt32 mode, UInt32 depth, UInt32 page)
{
UInt32 width, height;
+ UInt32 pageSize, numPages;
if (mode >= GLOBAL.numModes)
return paramErr;
+
width = vModes[mode].width;
height = vModes[mode].height;
-
- lprintf("Set Mode: %dx%dx%d\n", width, height, depth);
+ QemuVga_GetModePages(mode, depth, &pageSize, &numPages);
+ lprintf("Set Mode: %dx%dx%d has %d pages\n", width, height, depth, numPages);
+ if (page >= numPages)
+ return paramErr;
DispiWriteW(VBE_DISPI_INDEX_ENABLE, 0);
DispiWriteW(VBE_DISPI_INDEX_BPP, depth);
@@ -256,12 +353,14 @@ OSStatus QemuVga_SetMode(UInt32 mode, UInt32 depth)
DispiWriteW(VBE_DISPI_INDEX_YRES, height);
DispiWriteW(VBE_DISPI_INDEX_BANK, 0);
DispiWriteW(VBE_DISPI_INDEX_VIRT_WIDTH, width);
- DispiWriteW(VBE_DISPI_INDEX_VIRT_HEIGHT, height);
+ DispiWriteW(VBE_DISPI_INDEX_VIRT_HEIGHT, height * numPages);
DispiWriteW(VBE_DISPI_INDEX_X_OFFSET, 0);
- DispiWriteW(VBE_DISPI_INDEX_Y_OFFSET, 0);
+ DispiWriteW(VBE_DISPI_INDEX_Y_OFFSET, height * page);
DispiWriteW(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED | VBE_DISPI_8BIT_DAC);
GLOBAL.curMode = mode;
GLOBAL.depth = depth;
+ GLOBAL.curPage = page;
+ GLOBAL.curBaseAddress = FB_START + page * pageSize;
return noErr;
}
diff --git a/QemuVGADriver/src/QemuVga.h b/QemuVGADriver/src/QemuVga.h
index e401ef3..d7bf053 100644..100755
--- a/QemuVGADriver/src/QemuVga.h
+++ b/QemuVGADriver/src/QemuVga.h
@@ -1,6 +1,19 @@
#ifndef __QEMU_VGA_H__
#define __QEMU_VGA_H__
+/* This must be enabled for the MacOS X version of the timer otherwise
+ * we don't know if the call failed and don't back off to non-VBL ops
+ */
+#define USE_DSL_TIMER
+
+/* Pseudo VBL timer duration in ms */
+#define TIMER_DURATION 30
+
+/* Enable use of the PCI IRQ as VBL using non-upstream QEMU VGA
+ * extensions
+ */
+#undef USE_PCI_IRQ
+
/* --- Qemu/Bochs special registers --- */
#define VBE_DISPI_IOPORT_INDEX 0x01CE
@@ -48,7 +61,9 @@ extern OSStatus QemuVga_SetDepth(UInt32 bpp);
extern OSStatus QemuVga_SetColorEntry(UInt32 index, RGBColor *color);
extern OSStatus QemuVga_GetColorEntry(UInt32 index, RGBColor *color);
+extern OSStatus QemuVga_GetModePages(UInt32 index, UInt32 depth,
+ UInt32 *pageSize, UInt32 *pageCount);
extern OSStatus QemuVga_GetModeInfo(UInt32 index, UInt32 *width, UInt32 *height);
-extern OSStatus QemuVga_SetMode(UInt32 modeIndex, UInt32 depth);
+extern OSStatus QemuVga_SetMode(UInt32 modeIndex, UInt32 depth, UInt32 page);
#endif
diff --git a/QemuVGADriver/src/VideoDriverPrivate.h b/QemuVGADriver/src/VideoDriverPrivate.h
index cd4cdba..65c161c 100644..100755
--- a/QemuVGADriver/src/VideoDriverPrivate.h
+++ b/QemuVGADriver/src/VideoDriverPrivate.h
@@ -10,7 +10,7 @@
#include <DriverServices.h>
#include <PCI.h>
-#pragma internal on
+#include "MacDriverUtils.h"
#ifndef FALSE
#define TRUE 1
@@ -19,8 +19,8 @@
#define QEMU_PCI_VIDEO_VENDOR_ID 0x1234
#define QEMU_PCI_VIDEO_DEVICE_ID 0x1111
-#define QEMU_PCI_VIDEO_NAME "\pQemuVgaVideo"
-#define QEMU_PCI_VIDEO_PNAME "\p.QemuVgaVideo"
+#define QEMU_PCI_VIDEO_NAME "\pQEMU,VGA"
+#define QEMU_PCI_VIDEO_PNAME "\p.Display_Video_QemuVGA"
#define QEMU_PCI_VIDEO_BASE_REG 0x10
#define QEMU_PCI_VIDEO_MMIO_REG 0x18
@@ -51,6 +51,9 @@ struct DriverGlobal {
Boolean qdInterruptsEnable; /* Enable VBLs for qd */
Boolean qdLuminanceMapping;
+ Boolean hasPCIInterrupt;
+ IRQInfo irqInfo;
+
Boolean hasTimer;
InterruptServiceIDType qdVBLInterrupt;
TimerID VBLTimerID;
@@ -63,6 +66,8 @@ struct DriverGlobal {
UInt32 bootMode;
UInt32 curMode;
UInt32 numModes;
+ UInt32 curPage;
+ LogicalAddress curBaseAddress;
};
typedef struct DriverGlobal DriverGlobal, *DriverGlobalPtr;
diff --git a/QemuVGADriver/src/VideoDriverPrototypes.h b/QemuVGADriver/src/VideoDriverPrototypes.h
index b4d6c6f..682671a 100644..100755
--- a/QemuVGADriver/src/VideoDriverPrototypes.h
+++ b/QemuVGADriver/src/VideoDriverPrototypes.h
@@ -7,7 +7,6 @@
/*
* The Driver Manager calls DoDriverIO to perform I/O.
*/
-#pragma internal off
OSStatus
DoDriverIO( AddressSpaceID addressSpaceID,
@@ -16,8 +15,6 @@ DoDriverIO( AddressSpaceID addressSpaceID,
IOCommandCode ioCommandCode,
IOCommandKind ioCommandKind);
-#pragma internal on
-
#include "MacDriverUtils.h"
/*
@@ -80,8 +77,6 @@ OSStatus
DriverGestaltHandler( CntrlParam* pb);
-#pragma internal on
-
/* .___________________________________________________________________________________.
| Utitlity function to clear a block of memory. |
.___________________________________________________________________________________.