#include "NuBusFPGADrvr.h" void linearGamma(NuBusFPGADriverGlobalsPtr dStore) { int i; dStore->gamma.gVersion = 0; dStore->gamma.gType = 0; dStore->gamma.gFormulaSize = 0; dStore->gamma.gChanCnt = 3; dStore->gamma.gDataCnt = 256; dStore->gamma.gDataWidth = 8; for (i = 0 ; i < 256 ; i++) { dStore->gamma.gFormulaData[0][i] = i; dStore->gamma.gFormulaData[1][i] = i; dStore->gamma.gFormulaData[2][i] = i; } } OSErr changeIRQ(AuxDCEPtr dce, char en, OSErr err) { NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage; NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl; char busMode = 1; if (en != dStore->irqen) { /* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0005); */ /* write_reg(dce, GOBOFB_DEBUG, en); */ if (en) { if (SIntInstall(dStore->siqel, dce->dCtlSlot)) { return err; } write_reg(dce, GOBOFB_DEBUG, 0x88888888); write_reg(dce, GOBOFB_DEBUG, dStore->siqel); write_reg(dce, GOBOFB_DEBUG, dStore->siqel->sqLink); } else { if (SIntRemove(dStore->siqel, dce->dCtlSlot)) { return err; } } SwapMMUMode ( &busMode ); write_reg(dce, GOBOFB_VBL_MASK, en ? GOBOFB_INTR_VBL : 0); SwapMMUMode ( &busMode ); dStore->irqen = en; } return noErr; } /* 7.1.1: 11 Debug: 0x00000003 2 Debug: 0x00000004 1 Debug: 0x00000005 4 Debug: 0x00000006 1 �Debug: 0x00000002 7.5.3: 4 Debug: 0x00000002 12 Debug: 0x00000003 3 Debug: 0x00000004 5 Debug: 0x00000005 5 Debug: 0x00000006 5 Debug: 0x00000009 4 Debug: 0x0000000a 5 Debug: 0x00000010 1 �Debug: 0x00000002 8.1: 5 Debug: 0x00000002 9 Debug: 0x00000003 1 Debug: 0x00000004 6 Debug: 0x00000005 6 Debug: 0x00000006 4 Debug: 0x00000009 5 Debug: 0x0000000a 4 Debug: 0x00000010 1 �Debug: 0x00000002 */ #pragma parameter __D0 cNuBusFPGACtl(__A0, __A1) OSErr cNuBusFPGACtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) { NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage; NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl; short ret = -1; char busMode = 1; /* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0001); */ /* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */ switch (pb->csCode) { case -1: asm volatile(".word 0xfe16\n"); break; case cscReset: /* 0x0 */ { VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam; dStore->curMode = nativeVidMode; dStore->curDepth = kDepthMode1; /* 8-bit */ vPInfo->csMode = nativeVidMode; vPInfo->csPage = 0; vPInfo->csBaseAddr = 0; ret = noErr; } break; case cscKillIO: /* 0x1 */ asm volatile(".word 0xfe16\n"); ret = noErr; break; case cscSetMode: /* 0x2 */ { VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam; ret = reconfHW(dce, dStore->curMode, vPInfo->csMode, vPInfo->csPage); if (ret == noErr) vPInfo->csBaseAddr = (void*)(vPInfo->csPage * 1024 * 1024 * 4); } break; case cscSetEntries: /* 0x3 */ if (1) { VDSetEntryRecord **vdentry = (VDSetEntryRecord **)(long *)pb->csParam; int csCount = (*vdentry)->csCount; int csStart = (*vdentry)->csStart; int i; if (csCount <= 0) { ret = noErr; goto cscSetMode_done; } SwapMMUMode ( &busMode ); if (csStart < 0) { for (i = 0 ; i <= csCount ; i++) { unsigned char idx = ((*vdentry)->csTable[i].value & 0x0FF); /* dStore->shadowClut[idx*3+0] = (*vdentry)->csTable[i].rgb.red; */ /* dStore->shadowClut[idx*3+1] = (*vdentry)->csTable[i].rgb.green; */ /* dStore->shadowClut[idx*3+2] = (*vdentry)->csTable[i].rgb.blue; */ write_reg(dce, GOBOFB_LUT_ADDR, 3 * idx); write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[0][(*vdentry)->csTable[i].rgb.red>>8 & 0xFF]); write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[1][(*vdentry)->csTable[i].rgb.green>>8 & 0xFF]); write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[2][(*vdentry)->csTable[i].rgb.blue>>8 & 0xFF]); /* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.red); */ /* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.green); */ /* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.blue); */ } } else { write_reg(dce, GOBOFB_LUT_ADDR, 3 * (csStart & 0xFF)); for (i = 0 ; i <= csCount ; i++) { /* dStore->shadowClut[(i+csStart)*3+0] = (*vdentry)->csTable[i].rgb.red; */ /* dStore->shadowClut[(i+csStart)*3+1] = (*vdentry)->csTable[i].rgb.green; */ /* dStore->shadowClut[(i+csStart)*3+2] = (*vdentry)->csTable[i].rgb.blue; */ write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[0][(*vdentry)->csTable[i].rgb.red>>8 & 0xFF]); write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[1][(*vdentry)->csTable[i].rgb.green>>8 & 0xFF]); write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[2][(*vdentry)->csTable[i].rgb.blue>>8 & 0xFF]); /* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.red); */ /* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.green); */ /* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.blue); */ } } SwapMMUMode ( &busMode ); ret = noErr; } else { ret = noErr; } cscSetMode_done: break; case cscSetGamma: /* 0x4 */ { VDGammaRecord *vdgamma = (VDGammaRecord *)*(long *)pb->csParam; GammaTbl *gammaTbl = (GammaTbl*)vdgamma->csGTable; int i; if (gammaTbl == NULL) { linearGamma(dStore); } else { ret = noErr; if (gammaTbl->gDataWidth != 8) ret = paramErr; if (gammaTbl->gDataCnt != 256) // 8-bits ret = paramErr; if ((gammaTbl->gChanCnt != 1) && (gammaTbl->gChanCnt != 3)) ret = paramErr; if ((gammaTbl->gType != 0) && (gammaTbl->gType != 0xFFFFBEEF)) ret = paramErr; if (gammaTbl->gFormulaSize != 0) ret = paramErr; if (ret != noErr) goto done; dStore->gamma.gVersion = gammaTbl->gVersion; dStore->gamma.gType = gammaTbl->gType; dStore->gamma.gFormulaSize = gammaTbl->gFormulaSize; dStore->gamma.gChanCnt = gammaTbl->gChanCnt; dStore->gamma.gDataCnt = gammaTbl->gDataCnt; dStore->gamma.gDataWidth = gammaTbl->gDataWidth; int og, ob; if (gammaTbl->gChanCnt == 1) og = ob = 0; else { og = 256; ob = 512; } for (i = 0 ; i < gammaTbl->gDataCnt ; i++) { dStore->gamma.gFormulaData[0][i] = ((unsigned char*)gammaTbl->gFormulaData)[i + 0]; dStore->gamma.gFormulaData[1][i] = ((unsigned char*)gammaTbl->gFormulaData)[i + og]; dStore->gamma.gFormulaData[2][i] = ((unsigned char*)gammaTbl->gFormulaData)[i + ob]; } } ret = noErr; } break; case cscGrayPage: /* 0x5 == cscGrayScreen */ { VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam; const uint8_t idx = dStore->curMode % 4; // checkme UInt32 a32 = dce->dCtlDevBase; UInt32 a32_l0, a32_l1; UInt32 a32_4p0, a32_4p1; const uint32_t wb = dStore->hres[0] >> idx; unsigned short j, i; short npage = (vPInfo->csMode == kDepthMode5) ? 1 : 2; if (vPInfo->csPage >= npage) { return paramErr; goto done; } a32 += vPInfo->csPage * 1024 * 1024 * 4; /* fixme */ SwapMMUMode ( &busMode ); #if 0 if ((dStore->curMode != kDepthMode5) && (dStore->curMode != kDepthMode6)) { /* grey the screen */ a32_l0 = a32; a32_l1 = a32 + wb; for (j = 0 ; j < dStore->vres[0] ; j+= 2) { a32_4p0 = a32_l0; a32_4p1 = a32_l1; for (i = 0 ; i < wb ; i += 4) { *((UInt32*)a32_4p0) = 0xFF00FF00; *((UInt32*)a32_4p1) = 0x00FF00FF; a32_4p0 += 4; a32_4p1 += 4; } a32_l0 += 2*wb; a32_l1 += 2*wb; } } else { /* testing */ a32_l0 = a32; a32_l1 = a32 + dStore->hres[0]*4; for (j = 0 ; j < dStore->vres[0] ; j+= 2) { a32_4p0 = a32_l0; a32_4p1 = a32_l1; for (i = 0 ; i < dStore->hres[0] ; i ++ ) { *((UInt32*)a32_4p0) = (i&0xFF);//(i&0xFF) | (i&0xFF)<<8 | (i&0xff)<<24; *((UInt32*)a32_4p1) = (i&0xFF)<<16;//(i&0xFF) | (i&0xFF)<<8 | (i&0xff)<<24; a32_4p0 += 4; a32_4p1 += 4; } a32_l0 += 2*dStore->hres[0]*4; a32_l1 += 2*dStore->hres[0]*4; } } #else #define WAIT_FOR_HW_LE(accel_le) \ while (accel_le->reg_status & (1<dCtlDevBase+GOBOFB_ACCEL_LE); WAIT_FOR_HW_LE(accel_le); accel_le->reg_width = dStore->hres[dStore->curMode - nativeVidMode]; // pixels accel_le->reg_height = dStore->vres[dStore->curMode - nativeVidMode]; accel_le->reg_bitblt_dst_x = 0; // pixels accel_le->reg_bitblt_dst_y = 0; accel_le->reg_dst_ptr = 0; accel_le->reg_fgcolor = fgcolor; accel_le->reg_cmd = (1<csParam; dStore->gray = vGInfo->csMode; ret = noErr; } break; case cscSetInterrupt: /* 0x7 */ { VDFlagRecord *vdflag = (VDFlagRecord *)*(long *)pb->csParam; ret = changeIRQ(dce, 1 - vdflag->csMode, controlErr); } break; case cscDirectSetEntries: /* 0x8 */ asm volatile(".word 0xfe16\n"); ret = controlErr; break; case cscSetDefaultMode: /* 0x9 */ { VDDefMode *vddefm = (VDDefMode *)*(long *)pb->csParam; ret = updatePRAM(dce, vddefm->csID, dStore->curDepth, 0); } break; case cscSwitchMode: /* 0xa */ { VDSwitchInfoRec *vdswitch = *(VDSwitchInfoRec **)(long *)pb->csParam; ret = reconfHW(dce, vdswitch->csData, vdswitch->csMode, vdswitch->csPage); if (ret == noErr) vdswitch->csBaseAddr = (void*)(vdswitch->csPage * 1024 * 1024 * 4); } break; /* cscSetSync */ /* 0xb */ /* 0xc ... 0xf : undefined */ case cscSavePreferredConfiguration: /* 0x10 */ { VDSwitchInfoRec *vdswitch = *(VDSwitchInfoRec **)(long *)pb->csParam; ret = updatePRAM(dce, vdswitch->csData, vdswitch->csMode, 0); } break; /* 0x11 .. 0x15 : undefined */ /* cscSetHardwareCursor */ /* 0x16 */ /* cscDrawHardwareCursor */ /* 0x17 */ /* cscSetConvolution */ /* 0x18 */ /* cscSetPowerState */ /* 0x19 */ /* cscPrivateControlCall */ /* 0x1a */ /* 0x1b : undefined */ /* cscSetMultiConnect */ /* 0x1c */ /* cscSetClutBehavior */ /* 0x1d */ /* 0x1e : undefined */ /* cscSetDetailedTiming */ /* 0x1f */ /* 0x20 : undefined */ /* cscDoCommunication */ /* 0x21 */ /* cscProbeConnection */ /* 0x22 */ default: /* always return controlErr for unknown csCode */ asm volatile(".word 0xfe16\n"); ret = controlErr; break; } done: if (!(pb->ioTrap & (1<dCtlStorage; NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl; const short npage = (depth == kDepthMode5) ? 1 : 2; OSErr err = noErr; char busMode = 1; /* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0031); */ /* write_reg(dce, GOBOFB_DEBUG, mode); */ /* write_reg(dce, GOBOFB_DEBUG, depth); */ /* write_reg(dce, GOBOFB_DEBUG, page); */ if ((mode == dStore->curMode) && (depth == dStore->curDepth) && (page == dStore->curPage)) { return noErr; } if (page >= npage) return paramErr; if ((mode < nativeVidMode) || (mode > dStore->maxMode)) return paramErr; switch (depth) { case kDepthMode1: break; case kDepthMode2: break; case kDepthMode3: break; case kDepthMode4: break; case kDepthMode5: break; case kDepthMode6: break; default: return paramErr; } SwapMMUMode ( &busMode ); if (mode != dStore->curMode) { unsigned short i; for (i = nativeVidMode ; i <= dStore->maxMode ; i++) { // disable spurious resources, enable only the right one SpBlock spb; spb.spParamData = (i != mode ? 1 : 0); /* disable/enable */ spb.spSlot = dStore->slot; spb.spID = i; spb.spExtDev = 0; SetSRsrcState(&spb); } dce->dCtlSlotId = mode; // where is that explained ? cscSwitchMode is not in DCDMF3, and you should'nt do that anymore says PDCD... UInt8 id = mode - nativeVidMode; unsigned int ho = ((dStore->hres[0] - dStore->hres[id]) / 2); unsigned int vo = ((dStore->vres[0] - dStore->vres[id]) / 2); /* write_reg(dce, GOBOFB_VIDEOCTRL, 0); */ write_reg(dce, GOBOFB_HRES_START, __builtin_bswap32(ho)); write_reg(dce, GOBOFB_VRES_START, __builtin_bswap32(vo)); write_reg(dce, GOBOFB_HRES_END, __builtin_bswap32(ho + dStore->hres[id])); write_reg(dce, GOBOFB_VRES_END, __builtin_bswap32(vo + dStore->vres[id])); /* write_reg(dce, GOBOFB_VIDEOCTRL, 1); */ } if (depth != dStore->curDepth) { switch (depth) { case kDepthMode1: write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_8BIT); break; case kDepthMode2: write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_4BIT); break; case kDepthMode3: write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_2BIT); break; case kDepthMode4: write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_1BIT); break; case kDepthMode5: write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_24BIT); break; case kDepthMode6: write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_15BIT); break; default: SwapMMUMode ( &busMode ); return paramErr; } } dStore->curMode = mode; dStore->curDepth = depth; dStore->curPage = page; /* FIXME: HW */ SwapMMUMode ( &busMode ); return err; } OSErr updatePRAM(AuxDCEPtr dce, unsigned char mode, unsigned char depth, unsigned short page) { NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage; NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl; const short npage = (depth == kDepthMode5) ? 1 : 2; SpBlock spb; NuBusFPGAPramRecord pram; OSErr err; if (page >= npage) return paramErr; if ((mode < nativeVidMode) || (mode > dStore->maxMode)) return paramErr; switch (depth) { case kDepthMode1: break; case kDepthMode2: break; case kDepthMode3: break; case kDepthMode4: break; case kDepthMode5: break; case kDepthMode6: break; default: return paramErr; } spb.spSlot = dce->dCtlSlot; spb.spResult = (UInt32)&pram; err = SReadPRAMRec(&spb); if (err == noErr) { pram.mode = mode; pram.depth = depth; pram.page = page; spb.spSlot = dce->dCtlSlot; spb.spsPointer = &pram; err = SPutPRAMRec(&spb); } return err; }