/* * ATA command output */ EXPORT ER ataCommandOut(DrvTab *drv, W cmd, W cnt, W sec, W cyl, W head) { UW iob = drv->IOB; /* Wait for a while until it becomes ready status (BSY = 0) */ if (ataChkSts(drv, stBSY, 0) != E_OK) goto EEXIT; /* The drive/header number register setting */ OutB(REG_DRVHEAD, drDRV(drv->DrvNo) | head); /* Wait for a while until It gets to "BSY = 0" and "DRDY = 1" */ if (ataChkSts(drv, stBSY | stDRDY, stDRDY) != E_OK) goto EEXIT; /* Register setting of the number of sectors */ if (cnt != NOSET) { OutB(REG_SECCNT, cnt); } /* Register setting of sector number */ if (sec != NOSET) { OutB(REG_SECNO, sec); } /* Register setting of cylinder number */ if (cyl != NOSET) { OutB(REG_CYL_L, cyl); OutB(REG_CYL_H, cyl >> 8); }
/* * ATA (soft) reset */ EXPORT void ataReset(DrvTab *drv) { UW iob = drv->IOB; UW reg, tm; BOOL master; /* Set it to drive 0 */ ataSetDrive(drv, 0); /* Check the existence of drive 0 (Master) */ master = (InB(REG_DRVHEAD) == 0xff && InB(REG_STS) == 0xff) ? FALSE : TRUE; /* Reset pulse output */ reg = (drv->d.pcc.IOConf[0] & IOC_IO2_NONE)? REG_DEVCTL : REG_DEVCTL2; OutB(reg, dcSRST); WaitUsec(20); /* Wait for "20 usec" */ OutB(reg, dcNORM); /* Wait until it becomes ready status: Firstly set it to drive 1 when there is no "Master" */ for (tm = 0;;) { if (master == TRUE || ataSetDrive(drv, 0x100) == E_OK) { if ((ataStatusIn(drv) & stBSY) == 0) break; } if (drv->Spec.pccard && ataStatusIn(drv) == 0xff) break; /* There is no card */ if (sdChkTmout(&tm, RESET_TMO, 10)) break; } /* Set Drive (Master & Slave) to the reset status */ if (drv->Top != NULL) drv = drv->Top; for (; drv != NULL; drv = drv->Next) drv->Reset = TRUE; }
/* * Interrupt-enabled */ EXPORT void ataEnbInt(DrvTab *drv) { UW iob = drv->IOB; UW reg; reg = (drv->d.pcc.IOConf[0] & IOC_IO2_NONE)? REG_DEVCTL : REG_DEVCTL2; OutB(reg, dcNORM); }
/*--------------------------------------------*/ VOID SetupCommonPost (NPA npA) { UCHAR Data, Mask; NPU npU; RegOffset = 0; if (npA->FlagsT & ATBF_BM_DMA) { PciGetReg (CurPCIInfo->PCIAddr, PCIREG_COMMAND, (PULONG)&Data, 1); if (!(Data & PCI_CMD_BM)) WConfigBI (PCIREG_COMMAND, (UCHAR)(Data | PCI_CMD_BM)); } /******************************************/ /* Configure each unit to proper transfer */ /* mode for PIO and/or DMA */ /******************************************/ Data = 0; Mask = BMISTA_D0DMA; for (npU = npA->UnitCB; npU < (npA->UnitCB + npA->cUnits); npU++, Mask <<= 1) { if (npU->Flags & UCBF_NOTPRESENT) continue; if (!(npA->FlagsT & ATBF_BIOSDEFAULTS)) { if (npU->UltraDMAMode) npU->CurDMAMode = npU->UltraDMAMode + 2; if (npU->Flags & UCBF_BM_DMA) Data |= Mask; } if (npU->AMLevel != 0) IssueSetFeatures (npU, FX_SETAMLVL, (UCHAR)(0x80 + ~(npU->AMLevel))); if (npU->APMLevel != 0) IssueSetFeatures (npU, (UCHAR)(npU->APMLevel == 0xFF ? FX_DISABLE_APM : FX_ENABLE_APM), npU->APMLevel); if ((npU->LPMLevel != 0) && SCONTROL) { UCHAR Level = npU->LPMLevel & 3; if (Level != npU->FoundLPMLevel) { OutD (SCONTROL, (InD (SCONTROL) & SCTRL_SPD) | (Level << 8)); OutD (SERROR, InD (SERROR)); InD (SSTATUS); // flush } } } /*************************/ /* Set DMA Capable Bits */ /*************************/ if (BMSTATUSREG > 0x100) { OutB (BMSTATUSREG, Data); npA->BMStatus = Data | BMISTA_INTERRUPT; } }
/* * Drive setting */ EXPORT ER ataSetDrive(DrvTab *drv, W drvno) { UW iob = drv->IOB; UB dno; if (drvno < 0) drvno = drv->DrvNo; OutB(REG_DRVHEAD, dno = drDRV(drvno)); WaitUsec(4); /* Waiting is necessary depending on drive */ if (InB(REG_DRVHEAD) == dno) return E_OK; return ERR_NOPORT; }
/******************************************************************** * Function : WindowProc() * Purpose : Receive and handle windows messages. ********************************************************************/ long FAR PASCAL WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { DDSURFACEDESC ddsd; DDBLTFX BltFx; HRESULT ddreturn; switch (message) { case WM_ACTIVATEAPP : ActiveApp = wParam; break; case WM_CREATE : break; case WM_KEYDOWN : switch (wParam) { case VK_PAUSE : /* Start or Stop realtime. */ RealTime = !RealTime; break; case VK_SPACE : /* Flip a single frame. */ SimLoop(); break; case VK_ESCAPE : DestroyWindow(hwnd); break; case VK_LEFT : bLeftKey = TRUE; break; case VK_RIGHT : bRightKey = TRUE; break; case VK_UP : bForwardKey = TRUE; break; case VK_DOWN : bBackKey = TRUE; break; case VK_ADD : nGauge++; break; case VK_SUBTRACT : nGauge--; break; case VK_HOME : nGauge = 0; break; } break; case WM_KEYUP : switch (wParam) { case VK_F1 : nState = 1; break; case VK_F2 : nState = 2; break; case VK_F3 : nState = 3; break; case VK_F4 : nState = 4; break; case VK_F5 : nState = 5; break; case VK_F6 : nState = 6; break; case VK_F7 : nState = 7; break; case VK_F8 : nState = 8; break; case VK_F9 : nState = 9; break; case VK_F10 : nState = 0; break; case VK_LEFT : bLeftKey = FALSE; break; case VK_RIGHT : bRightKey = FALSE; break; case VK_UP : bForwardKey = FALSE; break; case VK_DOWN : bBackKey = FALSE; break; case 'S' : // Screen Snapshot. // This is not done very reliably, infact, it's more of a hack so // I can show some Chrome snapshots on my website. // Open a file named "Snapshot.tga" and write the current content // of the screen as a targa file. HANDLE hFile; hFile = CreateFile("Snapshot.tga", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != NULL) { // Write the Targa header, as appropriate for the current // screen type. DWORD dwWritten; /* Targa File Header : (Little Endian / Intel) * Offset Length Description * 0 1 ID field length * 1 1 Color map type. * 2 1 Image type. * 3 2 First color map entry. * 5 2 Color map length. * 7 1 Color map entry size. * 8 2 Image X origin. * 10 2 Image Y Origin. * 12 2 Image Width. * 14 2 Image Height. * 16 1 Bits per pixel. * 17 1 Image descriptor bits. * (from : "Graphics File Formats", David C. Kay and John R. Levine) */ # define OutB(b)\ { unsigned char b2;\ b2 = b;\ WriteFile(hFile, &b2, sizeof(b2), &dwWritten, NULL);\ } # define OutW(w)\ { unsigned short w2;\ w2 = w;\ WriteFile(hFile, &w2, sizeof(w2), &dwWritten, NULL);\ } OutB(0); // No message ID field length. OutB(0); // Colormap type = 0; true color. OutB(2); // Image type = 2, True color, uncompressed. OutW(0); // First colormap entry is 0, (Because Cmap type = 0). OutW(0); // Colormap length = 0, (CMap type = 0). OutB(0); // CMap entry size is 0 (because CMap type = 0) OutW(0); // OriginX = 0; OutW(0); // OriginY = 0; OutW(XRES); // Image Width is the value of the XRES constant. OutW(YRES); // Image Height is the value of the YRES constant. OutB(24); // Bits per pixel. OutB(0x20); // Image Descriptor Bits (0x20 = left to right, top to bottom). // Each pixel is written as a Blue Green Red triple. // Lock the surface & write each byte. DDSURFACEDESC ddsd; memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(ddsd); ddreturn = lpBackbuffer->Lock(NULL, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); if (ddreturn == DD_OK) { //DrawWorld((unsigned char *)ddsd.lpSurface, (int)ddsd.lPitch); int nX, nY; for (nY = 0; nY < YRES; nY++) { for (nX = 0; nX < XRES; nX++) { unsigned char ucByte; ucByte = *(((unsigned char *)ddsd.lpSurface) + ddsd.lPitch * nY + nX); // Index the colormap & write the BGR triple. OutB(WinColormap[ucByte].peBlue); OutB(WinColormap[ucByte].peGreen); OutB(WinColormap[ucByte].peRed); } } lpBackbuffer->Unlock(NULL); } // Close the file, we're done... CloseHandle(hFile); } } break; case WM_DESTROY : if (lpDirectDrawObject != NULL) { if (lpBackbuffer != NULL) lpBackbuffer->Release(); if (lpPrimary != NULL) lpPrimary->Release(); if (lpPalette != NULL) lpPalette->Release(); lpDirectDrawObject->Release(); } /* Free the world. */ EndWorld(); /* Free the font. */ if (AppFont != NULL) DeleteObject(AppFont); ShowCursor(TRUE); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0L; }