#include #include #include #include typedef unsigned char BYTE; typedef unsigned int WORD; typedef unsigned long DWORD; typedef int BOOL; typedef DWORD FOURCC; typedef char far * LPSTR; typedef BYTE far * LPBYTE; typedef WORD far * LPWORD; typedef DWORD far * LPDWORD; typedef BYTE huge * HPBYTE; typedef WORD huge * HPWORD; typedef DWORD huge * HPDWORD; #define BSIZE 256 #define FALSE 0x0000 #define TRUE (!FALSE) #define VIDERR_OK 0x0000 #define HIWORD(a) ((a) >> 16) #define LOWORD(a) ((a) & 0xFFFF) #define HIBYTE(a) ((a) >> 8) #define LOBYTE(a) ((a) & 0xFF) #define makeFOURCC(a,b,c,d) ((DWORD) (((DWORD) d)<<24|((DWORD) c)<<16|((DWORD) b)<<8|((DWORD) a))) #define comptypeDIB makeFOURCC(0,0,0,0) #define comptypeMSVIDEO makeFOURCC('M','S','V','C') #define ID_Unknown 0x00 #define ID_ProMovieSpectrumNTSC 0x01 #define ID_ProMovieSpectrumPAL 0x02 #define MAXBUFFER 20 extern LPSTR glpcBoardName; extern DWORD Buffer; extern DWORD FrameCount; extern DWORD GetBuffer(); extern WORD JSeg,JOff; extern WORD wRow,wColumn,VPos,VSlice; extern WORD HBytes,HAdjust; extern WORD BUFoff,BUFseg; extern WORD VGAoff; extern WORD N2Move; extern void VGAput(); static BYTE bPMS[48]; static LPBYTE B2C; static WORD seg_B2C; static WORD off_B2C; static WORD cuts[200]; static WORD FrameSize; static WORD gwBoardID; static WORD wPMSPort = 0x250; static WORD wPMSAddr = 0xC800; static WORD wPMSIRQ = 10; static WORD wIntrNum; static WORD wVideoStandard; static LPWORD lpwVGA; static DWORD OldBuffer; static BOOL CANAL = FALSE; static BOOL CLEAN = FALSE; static BOOL GREY = FALSE ; static int iPMSBoardID; static int iPMSID; static int lborder; static int rborder; static int startline; static int endline; static int topline; static int botline; static int minoffset; static int maxoffset; static int countdown; static int XORminsum = 200; static void (cdecl interrupt far *pOldVector)(); //extern void cdecl interrupt far JJDeviceISR(void); extern void DeviceISR(); /************************************************************************/ void JJSetInterruptVector( WORD wIRQ ) { if(wIRQ<8) wIntrNum = wIRQ + 0x08; else wIntrNum = (0x70 - 0x08) + wIRQ; if(!pOldVector) pOldVector = _dos_getvect(wIntrNum); // _dos_setvect(wIntrNum,JJDeviceISR); } WORD JJSetInterruptMask( WORD wIRQ, WORD wIntMask) { BYTE btmp; BYTE bOldMask; WORD wPICReg; if(wIRQ<8) wPICReg = 0x21; else wPICReg = 0xA1; btmp = 0x0001 << (wIRQ & 0x0007); wIntMask = ( ((wIntMask & 0x0001) << (wIRQ & 0x0007))) & btmp; _disable(); bOldMask = inp(wPICReg); outp(wPICReg,(bOldMask & ( btmp)) | wIntMask); _enable(); return(bOldMask); } void PMSWrite (nIndex, nValue) int nIndex; int nValue; { WORD i; if(wPMSPort) { i=0x1000; while((--i)&&((inp(wPMSPort)&0x03)!=0x03)); if(!i) printf("PMSWrite failed to write index (0x%02X)\n",nIndex); outpw (wPMSPort, (nValue << 8) | nIndex); bPMS[nIndex] = nValue; } } unsigned int PMSRead(wIndex) WORD wIndex; { return(bPMS[wIndex]); } int PMSReadReg(wIndex) WORD wIndex; { WORD i; i=0x1000; while((--i)&&((inp(wPMSPort)&0x01)!=0x01)); if(i) { } else { printf("PMSReadReg failed to write index (0x%02X)\n",wIndex); return(0xFF); } outp(wPMSPort,0x80 | wIndex); i=0x1000; while((--i)&&(inp(wPMSPort)&0x04)); if(i) return(inp(wPMSPort+1)); else { printf("PMSReadReg failed to read register (0x%02X)\n",wIndex); return(0xFF); } } void PMSIRQEnable(fEnable) BOOL fEnable; { if(fEnable) { SetInterruptVector(wPMSIRQ,(&DeviceISR)); SetInterruptMask(wPMSIRQ,0x01); PMSWrite(0x10,PMSReadReg(0x10) | 0x03); PMSWrite(0x01,PMSReadReg(0x01) | 0x01); } else { PMSWrite(0x01,PMSRead(0x01) | 0xFE); PMSWrite(0x10,PMSRead(0x10) & 0xFC); SetInterruptMask(wPMSIRQ,0x00); } } void PMSSetVertDeci(wDeciNum,wDeciDen) WORD wDeciNum; WORD wDeciDen; { printf("VertDeci Num,Den %d %d\n",wDeciNum,wDeciDen); if((wDeciNum%5)==0) { wDeciDen /= 5; wDeciNum /= 5; } while(((wDeciNum%3)==0)&&((wDeciDen%3)==0)) { wDeciDen /= 3; wDeciNum /= 3; } while((((wDeciNum&0x0001)|(wDeciDen&0x0001))==0x0000) ) { wDeciDen >>= 1; wDeciNum >>= 1; } while((wDeciDen>32)) { wDeciDen >>= 1; wDeciNum = (wDeciNum+1)>>1; } if(wDeciDen==32) { wDeciDen--; } if(wDeciDen==2) { wDeciDen |= 0x80; } printf("VertDeci Num,Den %d %d\n",wDeciNum,wDeciDen); PMSWrite(0x1C,wDeciDen); PMSWrite(0x1D,wDeciNum); } void PMSSetHorzDeci(wDeciNum,wDeciDen) WORD wDeciNum; WORD wDeciDen; { printf("HorzDeci Num,Den %d %d\n",wDeciNum,wDeciDen); if((wDeciNum%5)==0) { wDeciDen /= 5; wDeciNum /= 5; } while((((wDeciNum&0x0001)|(wDeciDen&0x0001))==0x0000) ) { wDeciDen >>= 1; wDeciNum >>= 1; } while((wDeciDen>32)) { wDeciDen >>= 1; wDeciNum = (wDeciNum+1)>>1; } if(wDeciDen==32) { wDeciDen--; } printf("HorzDeci Num,Den %d %d\n",wDeciNum,wDeciDen|0x80); PMSWrite(0x24,0x80 | wDeciDen); PMSWrite(0x25,wDeciNum); } unsigned int IdentifyPMSBoard() { BYTE BType; PMSWrite(0x02,0); BType = PMSReadReg(0x02) & 0x80; printf("Board Type read %x\n",BType); if(BType==0x80) { wVideoStandard = 2; printf("This board is PAL\n"); return(ID_ProMovieSpectrumPAL); } else { wVideoStandard = 1; /* should be 1 ! */ printf("This board is NTSC\n"); return(ID_ProMovieSpectrumNTSC); } } BOOL WakeUpPMSpectrum(wPort) WORD wPort; { int i; int iTmp; printf("WakeUpPMS: wPMSPort=%04X\n",wPMSPort); outp(wPMSPort+2,0x01); inp(wPMSPort); inp(wPMSPort); inp(wPMSPort); inp(wPMSPort); inp(wPMSPort); outp(wPMSPort+2,0x00); i=0x1000; while((--i)&&((iTmp=inp(wPMSPort))&0x04)); inp(wPMSPort+1); iTmp = PMSReadReg(0x03); if((iTmp&0xF0)!=0x10) return(FALSE); return(TRUE); } void PMSIRQClear () { PMSWrite(0x00,PMSRead(0x00) | 0x01); } void SetPMSVideoSource(wID,wData) WORD wID; WORD wData; { PMSWrite(0x2E,(PMSRead(0x2E) & 0xFE) | (wData & 0x01)); } void SetPMSHue(wID,wData) WORD wID; WORD wData; { printf("Set Hue to %d\n",wData); PMSWrite(0x26,wData); printf(" Confirm %d \n",PMSRead(0x26)); } void SetPMSColor(wID,wData) WORD wID; WORD wData; { printf("Set Colour to %d",wData); PMSWrite(0x2C,wData); printf(" Confirm %d \n",PMSRead(0x2C)); } void SetPMSContrast(wID,wData) WORD wID; WORD wData; { // printf("Set Contrast to %d",wData); PMSWrite(0x2A,wData); // printf(" Confirm %d \n",PMSRead(0x2A)); } void SetPMSBrightness(wID,wData) WORD wID; WORD wData; { printf("Set Brightness to %d\n",wData); PMSWrite(0x27,wData); PMSWrite(0x28,wData); PMSWrite(0x29,wData); } void SetPMSHStart(wID,wData) WORD wID; WORD wData; { printf("Set Horizontal Start to %d ",wData); PMSWrite(0x20,wData); PMSWrite(0x21,(wData & 0x0300)>>8); printf(" Confirm %d \n",PMSReadReg(0x20)); } void SetPMSVStart(wID,wData) WORD wID; WORD wData; { PMSWrite(0x16,wData); PMSWrite(0x17,(wData & 0x0300)>>8); } void CursorPos(y,x) int x,y; { wRow = x; wColumn = y; SetCursorPos(); } void ConDitherRGB() { WORD ScanBytes = HBytes; WORD Line = FrameSize; WORD iDS = FP_SEG(OldBuffer); WORD iSI = FP_OFF(OldBuffer); _asm { pushf push es push ds push di push si mov ax, iDS mov ds, ax mov es, ax mov si, iSI mov di, iSI DoScanLine: cld xor bx, bx ; zero error field mov cx, ScanBytes DoPutBytes: lodsw test ax,4210h jz Dither ;Add in previous error in BX (carefully) and ax,7BDFh ;Clear lsb of pixel color fields and bx,7BDFh ;Clear lsb of error color fields add ax,bx mov bx,ax test bh,80h ;Test for R overflow jz DitherG or ah,7Ch DitherG: test bh,04h ;Test for G overflow jz DitherB or ax,03E0h DitherB: test bl,20h ;Test for B overflow jz DitherDone or ax,001Fh DitherDone: xor bx,bx Dither: add ax,bx mov bx,ax and bx,1C67h ;Save discarded bits push bx mov bx,ax shr al,3 and al,03h ;Blue and ah,60h or al,ah ;Red shl bx,3 and bh,1Ch or al,bh ;Green pop bx stosb loop DoPutBytes dec Line jnz DoScanLine pop si pop di pop ds pop es popf } } void ConDitherGrey() { WORD ScanBytes = HBytes; WORD Line = FrameSize; WORD iDS = FP_SEG(OldBuffer); WORD iSI = FP_OFF(OldBuffer); _asm { pushf push es push ds push di push si mov ax, iDS mov ds, ax mov es, ax mov si, iSI mov di, iSI DoScanLine: cld mov cx, ScanBytes DoPutBytes: lodsw shr ax, 10 stosb loop DoPutBytes dec Line jnz DoScanLine pop si pop di pop ds pop es popf } } void GetRGBSwap() { WORD iDS = FP_SEG(OldBuffer); WORD iSI = FP_OFF(OldBuffer); WORD iES = seg_B2C; WORD iDI = off_B2C; WORD ScanBytes = HBytes; WORD iST,FirstP,LastP,start,end; WORD iSI0 = iSI; int i,ic; int lb = lborder; int rb = rborder; int line = startline; int endl = endline; int maxo = HBytes; int split,bbest; int mins[200],Sum,amin; iSI += (line-1)*HBytes; _asm { pushf pusha push ds push si push es push di mov ax, iDS ; data segment mov ds, ax ; in DS line_loop: mov si, iSI mov ax, iSI ; address of scan line mov start, ax mov bx, lb add start, bx ; first pixel address add ax, ScanBytes ; iSI + ScanBytes i.e. next line address dec ax ; last pixel this line sub ax, rb ; next line minus right hand border mov end, ax ; last pixel to consider on this line sub ax, ScanBytes mov LastP, ax ; last considered pixel on previous mov ax, start sub ax, ScanBytes mov FirstP, ax ; first considered pixel on previous mov amin, 0EFFFh ; min summed pixel xor xor cx, cx ; split value to start with is 0 mov bbest, cx cld offset_loop: mov dx, 0 ; zero sum mov si, start ; set address of start pixel add si, cx ; this split value mov bx, FirstP ; set address of start pixel on previous mov ax, iES mov es, ax xor ah, ah ; set top byte to zero compare_loop: mov al, ds:[si] ; this pixel xor al, ds:[bx] ; should be zero for perfect match mov di, iDI ; bit count table offset add di, al ; count offset mov al, es:[di] ; bit count for this al add dx, ax ; sum bits set cmp dx, amin ; test against best jae test_ok ; jump to next if sum already too big inc si ; move address this line on one inc bx ; move address prev line on one cmp bx, LastP ; check all prev line pixels compared ja end_of_line cmp si, end ; end of this line ? jbe compare_loop mov si, start ; continue at the beginning jmp compare_loop end_of_line: cmp dx, amin jae test_ok mov amin, dx ; this dx is the best mov bbest, cx ; set bbest to the good cut point test_ok: inc cx ; next value for split cmp cx, maxo ; have we done the last possible split offset? jbe offset_loop ; if not, jump to it mov bx, start add bx, bbest mov ds:[bx], 0FFh ; mark eventual left border mov bx, end mov ds:[bx], 0FFh ; mark right border do_swap: cmp bbest, 0 ; don't need to swap if best is 0 je done_swap ; now swap the line at the bbest position. Use iSI0 as a line buffer mov ax, iDS mov es, ax mov di, iSI0 ; destination address is offset 0 mov si, start ; source address is first considered pixel cld mov cx, bbest ; need to save the first bbest bytes rep movsb ; copy bbest bytes from si to di mov di, start ; prepare destination address mov si, start add si, bbest ; prepare source address mov cx, end sub cx, si ; number of bytes to move to 'end' rep movsb mov cx, bbest ; now saved buffer mov si, iSI0 rep movsb ; add the saved bbest bytes at the end done_swap: } cuts[line] = bbest; mins[line] = amin; _asm { inc line mov ax, line cmp ax, endl ; last scan line to do ? ja Finished mov ax, iSI add ax, ScanBytes ; move iSI to start of next scanline mov iSI, ax jmp line_loop Finished: pop di pop es pop si pop ds popa popf } // CursorPos(25,1); // printf("Line Cut Val"); // ic = 2; // for(i=startline;i<=endline;i++) { // CursorPos(25,ic++); // printf("%3d %3d %4d",i,cuts[i],mins[i]); // } } void GetGreySwap() { WORD iDS = FP_SEG(OldBuffer); WORD iSI = FP_OFF(OldBuffer); WORD iES = seg_B2C; WORD iDI = off_B2C; WORD ScanBytes = HBytes; WORD iST,FirstP,LastP,start,end; WORD iSI0 = iSI; int i,ic; int lb = lborder; int rb = rborder; int line = startline; int endl = endline; int maxo = HBytes-maxoffset; int mino = minoffset; int split,bbest; int c[200],mins[200],Sum,amin; iSI += (startline-1)*HBytes; _asm { pushf pusha push ds push si push es push di mov ax, iDS ; data segment mov ds, ax ; in DS line_loop: mov si, iSI mov ax, iSI ; address of scan line mov start, ax mov bx, lb add start, bx ; first pixel address add ax, ScanBytes ; iSI + ScanBytes i.e. next line address dec ax ; last pixel this line sub ax, rb ; next line minus right hand border mov end, ax ; last pixel to consider on this line sub ax, ScanBytes mov LastP, ax ; last considered pixel on previous mov ax, start sub ax, ScanBytes mov FirstP, ax ; first considered pixel on previous mov amin, 0EFFFh ; min summed pixel xor xor cx, cx ; split value to start with is 0 mov bbest, cx cld offset_loop: mov dx, 0 ; zero sum mov si, start ; set address of start pixel add si, cx ; this split value mov bx, FirstP ; set address of start pixel on previous mov ax, iES mov es, ax xor ah, ah ; set top byte to zero compare_loop: mov al, ds:[si] ; this pixel xor al, ds:[bx] ; should be zero for perfect match cmp al, 0 je L1 mov di, iDI ; bit count table offset add di, al ; count offset mov al, es:[di] ; bit count for this al add dx, ax ; add to sum if the pixels are diff cmp dx, amin ; test against best jae test_ok ; jump to next if sum already too big L1: inc si ; move address this line on one inc bx ; move address prev line on one cmp bx, LastP ; check all prev line pixels compared ja end_of_line cmp si, end ; end of this line ? jbe compare_loop mov si, start ; continue at the beginning jmp compare_loop end_of_line: cmp dx, amin jae test_ok mov amin, dx ; this dx is the best mov bbest, cx ; set bbest to the good cut point cmp cx, 0 ja test_ok mov cx, mino dec cx test_ok: inc cx ; next value for split cmp cx, maxo ; have we done the last possible split offset? jbe offset_loop ; if not, jump to it mov bx, start add bx, bbest mov ds:[bx], 0FFh ; mark eventual left border mov bx, end mov ds:[bx], 0FFh ; mark right border do_swap: cmp bbest, 0 ; don't need to swap if best is 0 je done_swap ; now swap the line at the bbest position. Use iSI0 as a line buffer mov ax, iDS mov es, ax mov di, iSI0 ; destination address is offset 0 mov si, start ; source address is first considered pixel cld mov cx, bbest ; need to save the first bbest bytes rep movsb ; copy bbest bytes from si to di mov di, start ; prepare destination address mov si, start add si, bbest ; prepare source address mov cx, end sub cx, si ; number of bytes to move to 'end' rep movsb mov cx, bbest ; now saved buffer mov si, iSI0 rep movsb ; add the saved bbest bytes at the end done_swap: } c[line] = bbest; mins[line] = amin; _asm { inc line mov ax, line cmp ax, endl ; last scan line to do ? ja Finished mov ax, iSI add ax, ScanBytes ; move iSI to start of next scanline mov iSI, ax jmp line_loop Finished: pop di pop es pop si pop ds popa popf } CursorPos(25,1); printf("Line Cut Val"); ic = 2; for(i=startline;i<=endline;i++) { CursorPos(25,ic++); printf("%3d %3d %5d",i,c[i],mins[i]); } } void DoSort() { WORD iDS = FP_SEG(OldBuffer); WORD iSI = FP_OFF(OldBuffer); WORD iES = seg_B2C; WORD iDI = off_B2C; WORD ScanBytes = HBytes; WORD FirstP,LastP,start,end,start2; WORD iEN = iSI; WORD iSI0 = iSI; int i,ic; int lb = lborder; int rb = rborder; int line; int maxo = maxoffset; int mino = minoffset-1; int top = topline; int bot = botline; int NPix = HBytes-lborder-rborder-1; int LDone,amin,bbest; int NLines = botline-topline+1; int Lframe = HBytes*NLines; int mins[500]; int Minimum = XORminsum; iEN += (botline-1)*HBytes+lb; // last considered start pixel line = startline; for (i=0;ibotline) line = line-botline+topline-1; start = (line-1)*HBytes + iSI + lb; end = start + NPix; _asm { pushf pusha push ds push si push es push di mov ax, iDS ; data segment mov ds, ax ; in DS mov es, ax ; and ES mov cx, 1 ; First line to consider is 1 away mov bbest, cx mov amin, 0EFFFh ; min summed pixel xor cld offset_loop: mov si, start ; start parent line pixel address mov ax, cx ; line offset in ax mul ScanBytes ; number of bytes ahead add ax, si ; start address for compare cmp ax, iEN ; wrap back to top ? jbe nowrap sub ax, Lframe ; wrap offset nowrap: mov FirstP, ax ; i.e. first pixel for match add ax, NPix ; add number of pixels to match mov LastP, ax ; last pixel for match mov dx, 0 ; zero sum for this pair mov bx, FirstP ; set address of start pixel mov ax, iES ; set segment for bit count array mov es, ax compare_loop: mov al, ds:[si] ; this pixel xor al, ds:[bx] ; should be zero for perfect match cmp al, 0 ; is it ? je Label1 ; skip the addition if so mov di, iDI ; bit count table offset add di, al ; count offset mov al, es:[di] ; bit count for these xor'ed pixels xor ah, ah ; set top byte to zero add dx, ax ; sum bits set cmp dx, amin ; test against best jae test_ok ; jump to next if sum already too big Label1: inc si ; move address this line on one inc bx ; move address other line on one cmp bx, LastP ; check all pixels compared jbe compare_loop ; do another if not mov amin, dx ; this dx is the best mov bbest, cx ; set bbest to be the best line mov ax, FirstP mov start2, ax ; save offset for eventual swap test_ok: cmp cx, 1 ; the first line ? ja not_first mov cx, mino ; minimum offset allowed not_first: inc cx ; next line offset cmp cx, maxo ; have we done the last line? jbe offset_loop ; do another if not done_line: cmp bbest, 1 ; skip if best match is next line je Finished mov ax, amin cmp ax, Minimum ; test against minimum allowed jae Finished ; skip if too big mov si, start ; start address in source line add si, ScanBytes ; line after's start address mov bx, start2 ; target swap line's start address mov cx, NPix ; start,end difference inc cx ; number of pixels to move move_byte: mov al, ds:[si] ; get source byte xchg ds:[bx], al ; move it into target byte mov ds:[si], al ; put target byte back at source inc si inc bx loop move_byte Finished: mov bx, start mov ax, line pop di pop es pop si pop ds popa popf } cuts[line] = bbest; mins[line] = amin; line++; } CursorPos(25,1); printf("Line Cut Min"); ic = 2; line = startline; for(i=0;i<23;i++) { if(line>botline) line = line-botline+topline-1; CursorPos(25,ic++); printf("%3d %3d %3d",line,cuts[line],mins[line]); line++; } } void DoRGBSwap(int Line,int Cut) { WORD iDS = FP_SEG(OldBuffer); WORD iSI = FP_OFF(OldBuffer); WORD ScanBytes = HBytes; WORD iST,FirstP,LastP,start,end; WORD iSI0 = iSI; int i,ic; int lb = lborder; int rb = rborder; int line = Line; int bbest = Cut; unsigned int mins[500],Sum,amin; if(Cut==0) return; iSI += (line-1)*HBytes; _asm { pushf pusha push ds push si push es push di mov ax, iDS ; data segment mov ds, ax ; in DS mov es, ax ; in ES mov ax, iSI ; address of scan line mov start, ax mov bx, lb add start, bx ; first pixel address add ax, ScanBytes ; iSI + ScanBytes i.e. next line address dec ax ; last pixel this line sub ax, rb ; next line minus right hand border mov end, ax ; last pixel to consider on this line ; now swap the line at the bbest position. Use iSI0 as a line buffer mov ax, iDS mov es, ax mov di, iSI0 ; destination address is offset 0 mov si, start ; source address is first considered pixel cld mov cx, bbest ; need to save the first bbest bytes rep movsb ; copy bbest bytes from si to di mov di, start ; prepare destination address mov si, start add si, bbest ; prepare source address mov cx, end sub cx, si ; number of bytes to move to 'end' rep movsb mov cx, bbest ; now saved buffer mov si, iSI0 rep movsb ; add the saved bbest bytes at the end pop di pop es pop si pop ds popa popf } } void VideoBufferCopy() { if(GREY) { ConDitherGrey(); GetGreySwap(); } else { ConDitherRGB(); GetRGBSwap(); } BUFseg = FP_SEG(OldBuffer); BUFoff = FP_OFF(OldBuffer); N2Move = FrameSize; VGAoff = 0; VGAPut(); } void CanalBufferCopy() { int i,Nline,line; unsigned int ip; Nline = botline-topline+1; if(GREY) { ConDitherGrey(); } else { ConDitherRGB(); } DoSort(); BUFseg = FP_SEG(OldBuffer); ip = FP_OFF(OldBuffer); N2Move = botline-startline+1; VGAoff = 0; BUFoff = (startline-1)*HBytes + ip; VGAPut(); VGAoff = 640*N2Move; N2Move = startline-topline; BUFoff = (topline-1)*HBytes + ip; VGAPut(); } void BitTable() { int i,j,n; printf("Calculating Bit table ...\n"); for (i=0;i>j) ) ; } *(B2C+i) = n; } } void main() { long ii; int svga; int i,red,green,blue; int contrast=137,brightness=65,colour=243,hue=188; int mbuffer; int nbuffer; int ibuffer; WORD j,k; int VDeci = 8; int HStart = 6; int VStart = 22; int VSkip = 1; DWORD FrameBytes; BOOL fExit = FALSE; DWORD QueueBuffer[MAXBUFFER]; char ch; printf("Testing for Pro MovieSpectrum board.\n"); wPMSPort = 0x250; if(!WakeUpPMSpectrum(wPMSPort)) { printf("Failed to find board\n"); exit(); } wPMSAddr = 0xC800; wPMSIRQ = 10; gwBoardID = IdentifyPMSBoard(); SetPMSContrast(0,contrast); SetPMSBrightness(0,brightness); SetPMSColor(0,colour); SetPMSHue(0,hue); printf("Hue is %d\n",PMSReadReg(0x26)); printf("Colour is %d\n",PMSReadReg(0x2C)); printf("Contrast is %d\n",PMSReadReg(0x2A)); printf("Brightness is %d\n",PMSReadReg(0x27)); printf("Brightness is %d\n",PMSReadReg(0x28)); printf("Brightness is %d\n",PMSReadReg(0x29)); if(GREY) { PMSWrite(0x2E,0x00); /* decoder control */ } else { PMSWrite(0x2E,0x02); /* set colour */ } VSlice = 160; HBytes = 200; HStart = 48; lborder = 2; rborder = 6; startline = 20; endline = 70; minoffset = 10; maxoffset = 10; topline = 4; botline = VSlice-4; if(CANAL) { startline = VSlice*0.9; minoffset = 4; maxoffset = 16; } B2C = (LPBYTE) _fmalloc(BSIZE); if(B2C == NULL) { printf("Can't malloc Bit table ...\n"); exit(); } else { printf("B2C at %lp\n",B2C); seg_B2C = FP_SEG(B2C); off_B2C = FP_OFF(B2C); } BitTable(); /* Set Conversion for bit counts */ printf("Bit Table is calculated ...\n"); PMSWrite(0x14,VSkip); /* capture every ? frame */ PMSWrite(0x15,0x01); /* out of 1 */ PMSWrite(0x16,VStart); /* vertical position to start */ PMSWrite(0x17,(VStart&0x0100)>>8); PMSSetHorzDeci(HBytes,768); PMSWrite(0x18,VSlice); /* Number of lines in band*/ PMSWrite(0x19,(VSlice&0x0100)>>8); PMSWrite(0x1A,0x01 ); /* interrupt at line */ PMSWrite(0x1B,(0x01 & 0x0100)>>8); PMSSetVertDeci(VSlice,300); PMSWrite(0x20,HStart); /* skip HStart pixels at line start */ PMSWrite(0x21,(HStart&0x0100)>>8); PMSWrite(0x22,(HBytes)); /* capture HBytes pixels */ PMSWrite(0x23,(HBytes)>>8); PMSWrite(0x01,PMSRead(0x01) & 0xFD); /*field interrupt */ FrameSize = (WORD) VSlice; FrameBytes = (DWORD) HBytes * FrameSize * 2; nbuffer = 0; for (i=1;i<=MAXBUFFER;i++) { Buffer = GetBuffer((DWORD) FrameBytes, 0x00); if(Buffer == -1) goto end_buff; nbuffer++; QueueBuffer[nbuffer] = Buffer; } end_buff: printf("\n%d %dk Buffers are allocated for Frames\n",nbuffer,FrameBytes/1000); if (nbuffer==0) exit(); printf("Any key to continue ..."); getch(); mode13(); /* sets mode 2e */ /* Set Colour or Grey Table */ outp(0x3c8,0x00); for (i=0;i<256;i++) { if(GREY) { outp(0x3c9,i&0x3F); outp(0x3c9,i&0x3F); outp(0x3c9,i&0x3F); } else { outp(0x3c9,(i&0x60)>>1); /* red */ outp(0x3c9,(i&0x1C)<<1); /* green */ outp(0x3c9,(i&0x03)<<4); /* blue */ } } countdown = 0; FrameCount = 0; ibuffer = 1; Buffer = QueueBuffer[ibuffer]; PMSIRQEnable(TRUE); do { if(kbhit()) { ch = getch(); switch(ch) { case 0x1B : fExit = TRUE; break; case 0x71 : lborder--; if(lborder<0) lborder=0; break; case 0x77 : lborder++; if(lborder>HBytes) lborder=HBytes; break; case 0x72 : rborder--; if(rborder<0) rborder=0; break; case 0x65 : rborder++; if(rborder>HBytes) rborder=HBytes; break; case 'h' : topline--; if(topline<0) topline = 0; break; case 'j' : topline++; if(topline>VSlice) topline = VSlice; break; case 'k' : botline--; if(botlineVSlice) botline = VSlice; break; case 0x61 : startline--; if(startline<2) startline=2; break; case 0x73 : startline++; if(!CANAL) { if(startline>endline) startline=endline; } else { if(startline>FrameSize) startline=FrameSize; } break; case 0x64 : endline--; if(endlineFrameSize) endline=FrameSize; break; case 'o' : minoffset--; if(minoffset<0) minoffset=0; if(CANAL && minoffset<2) minoffset=2; break; case 'p' : minoffset++; if(minoffset>HBytes/2) minoffset=HBytes/2; break; case 'O' : maxoffset--; if(maxoffsetVSlice) maxoffset=VSlice; break; case 'z' : contrast++; SetPMSContrast(0,contrast); break; case 'x' : contrast--; SetPMSContrast(0,contrast); break; case 'c' : brightness++; SetPMSBrightness(0,brightness); break; case 'v' : brightness--; SetPMSBrightness(0,brightness); break; case 'm' : XORminsum++; if(XORminsum>1000) XORminsum=1000; break; case 'n' : XORminsum--; if(XORminsum<1) XORminsum=1; break; default : break; } CursorPos(1,21); printf("min=%1d max=%2d top=%2d bot=%3d", minoffset,maxoffset,topline,botline); CursorPos(1,22); printf("L=%2d R=%2d St=%3d En=%3d", lborder,rborder,startline,endline); CursorPos(1,23); printf("CON=%3d BRI=%3d",contrast,brightness); CursorPos(1,24); printf("XORminsum=%3d",XORminsum); } ibuffer++; if(ibuffer>nbuffer) ibuffer=1; OldBuffer = Buffer; Buffer = QueueBuffer[ibuffer]; if(CANAL) { CanalBufferCopy(); } else { VideoBufferCopy(); } // countdown--; // if(countdown<0) countdown=10; } while(!fExit); PMSIRQEnable(FALSE); txtmode(); printf("Capture disabled... "); Buffer = GetBuffer((DWORD)FrameBytes, 0x01); free(B2C); printf("Memory freed\n"); }