/* File: VGASpeed.c Name: 测试VGA12H模式的速度 Author: zyl910 Blog: http://blog.csdn.net/zyl910/ Version: V1.0 Updata: 2006-11-14 */ #include <stdio.h> #include <conio.h> #include <mem.h> #include <dos.h> typedef unsigned char BYTE; typedef unsigned int WORD; typedef unsigned long DWORD; typedef void far* LPVOID; #define SCR_W 640 #define SCR_H 480 #define SCR_PLANES 4 #define SCANSIZE_DIB ((SCR_W)/2) #define SCANSIZE_VGA ((SCR_W)/8) #define SEG_VIDEO 0xA000 #define WaitVR() while(!(inportb(0x3da)&0x08)) static volatile DWORD far* const pbiosclock = MK_FP(0x0040, 0x6C); #define BIOSCLOCK_F ((double)18.2) void repmovsb(LPVOID lpD, LPVOID lpS, WORD cBytes) { _asm{ push ds push es mov cx, cBytes les di, lpD lds si, lpS rep movsb pop es pop ds; } } void repmovsw(LPVOID lpD, LPVOID lpS, WORD cWords) { _asm{ push ds push es mov cx, cWords les di, lpD lds si, lpS rep movsw pop es pop ds; } } void repmovsd(LPVOID lpD, LPVOID lpS, WORD cDWords) { _asm{ push ds push es mov cx, cDWords les di, lpD lds si, lpS db 0x66; rep movsw; /* rep movsd */ pop es pop ds } } int main(void) { BYTE byVGA[SCR_PLANES][SCANSIZE_VGA]; DWORD cntF; int iX, iY; BYTE iP; WORD pscan; BYTE far *pbyV; BYTE *pbyM; BYTE bymask; DWORD tmrold, tmrcur, tmrover; double fpsR_C, fpsR_BYTE, fpsR_WORD, fpsR_DWORD; double fpsW_C, fpsW_BYTE, fpsW_WORD, fpsW_DWORD; double fpsWaitW_BYTE, fpsWaitW_WORD, fpsWaitW_DWORD; /* init VGA 12h: 640*480*4bit */ _asm{ mov ax, 0x0012; int 0x10; cld; } printf("Testing..."); /* R:C */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ pscan = 0; for(iY=0; iY<SCR_H; iY++) { for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3CE; /* gc[4]:Read Map Select */ mov al, 4; out dx, al; inc dx; mov al, iP; out dx, al; } pbyM = byVGA[iP]; pbyV = MK_FP(SEG_VIDEO, pscan); for(iX=0; iX<SCANSIZE_VGA; iX++) { *pbyM++ = *pbyV++; } } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsR_C = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* W:C */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA); memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA); memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA); memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA); pscan = 0; for(iY=0; iY<SCR_H; iY++) { bymask = 1; for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3C4; /* sc[2]:Map Mask */ mov al, 2; out dx, al; inc dx; mov al, bymask; out dx, al; } pbyM = byVGA[iP]; pbyV = MK_FP(SEG_VIDEO, pscan); for(iX=0; iX<SCANSIZE_VGA; iX++) { *pbyV++ = *pbyM++; } bymask <<= 1; } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsW_C = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* R:Byte */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ pscan = 0; for(iY=0; iY<SCR_H; iY++) { for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3CE; /* gc[4]:Read Map Select */ mov al, 4; out dx, al; inc dx; mov al, iP; out dx, al; } repmovsb(byVGA[iP], MK_FP(SEG_VIDEO, pscan), SCANSIZE_VGA); } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsR_BYTE = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* W:BYTE */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA); memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA); memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA); memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA); pscan = 0; for(iY=0; iY<SCR_H; iY++) { bymask = 1; for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3C4; /* sc[2]:Map Mask */ mov al, 2; out dx, al; inc dx; mov al, bymask; out dx, al; } repmovsb(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA); bymask <<= 1; } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsW_BYTE = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* R:Word */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ pscan = 0; for(iY=0; iY<SCR_H; iY++) { for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3CE; /* gc[4]:Read Map Select */ mov al, 4; out dx, al; inc dx; mov al, iP; out dx, al; } repmovsw(byVGA[iP], MK_FP(SEG_VIDEO, pscan), SCANSIZE_VGA/2); } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsR_WORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* W:WORD */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA); memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA); memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA); memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA); pscan = 0; for(iY=0; iY<SCR_H; iY++) { bymask = 1; for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3C4; /* sc[2]:Map Mask */ mov al, 2; out dx, al; inc dx; mov al, bymask; out dx, al; } repmovsw(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/2); bymask <<= 1; } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsW_WORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* R:DWord */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ pscan = 0; for(iY=0; iY<SCR_H; iY++) { for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3CE; /* gc[4]:Read Map Select */ mov al, 4; out dx, al; inc dx; mov al, iP; out dx, al; } repmovsd(byVGA[iP], MK_FP(SEG_VIDEO, pscan), SCANSIZE_VGA/4); } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsR_DWORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* W:DWORD */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA); memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA); memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA); memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA); pscan = 0; for(iY=0; iY<SCR_H; iY++) { bymask = 1; for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3C4; /* sc[2]:Map Mask */ mov al, 2; out dx, al; inc dx; mov al, bymask; out dx, al; } repmovsd(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/4); bymask <<= 1; } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsW_DWORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* WaitW:BYTE */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA); memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA); memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA); memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA); pscan = 0; WaitVR(); for(iY=0; iY<SCR_H; iY++) { bymask = 1; for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3C4; /* sc[2]:Map Mask */ mov al, 2; out dx, al; inc dx; mov al, bymask; out dx, al; } repmovsb(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA); bymask <<= 1; } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsWaitW_BYTE = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* WaitW:WORD */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA); memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA); memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA); memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA); pscan = 0; WaitVR(); for(iY=0; iY<SCR_H; iY++) { bymask = 1; for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3C4; /* sc[2]:Map Mask */ mov al, 2; out dx, al; inc dx; mov al, bymask; out dx, al; } repmovsw(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/2); bymask <<= 1; } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsWaitW_WORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* WaitW:DWORD */ do{ cntF = 0; tmrold = *pbiosclock; tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */ do{ memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA); memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA); memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA); memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA); pscan = 0; WaitVR(); for(iY=0; iY<SCR_H; iY++) { bymask = 1; for(iP=0; iP<SCR_PLANES; iP++) { _asm{ mov dx, 0x3C4; /* sc[2]:Map Mask */ mov al, 2; out dx, al; inc dx; mov al, bymask; out dx, al; } repmovsd(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/4); bymask <<= 1; } pscan += SCANSIZE_VGA; } cntF++; tmrcur = *pbiosclock; }while((tmrcur<tmrover)&&(tmrcur>=tmrold)); if (tmrcur < tmrold) continue; }while(0); fpsWaitW_DWORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F); /* Exit VGA */ _asm{ mov ax, 0x0003; int 0x10; } /* out */ printf("[FPS]/n"); printf("R_C :%16.4f/n", fpsR_C); printf("W_C :%16.4f/n", fpsW_C); printf("R_BYTE :%16.4f/n", fpsR_BYTE); printf("W_BYTE :%16.4f/n", fpsW_BYTE); printf("R_WORD :%16.4f/n", fpsR_WORD); printf("W_WORD :%16.4f/n", fpsW_WORD); printf("R_DWORD:%16.4f/n", fpsR_DWORD); printf("W_DWORD:%16.4f/n", fpsW_DWORD); printf("WaitW_B:%16.4f/n", fpsWaitW_BYTE); printf("WaitW_W:%16.4f/n", fpsWaitW_WORD); printf("WaitW_D:%16.4f/n", fpsWaitW_DWORD); return 0; } |