Xref: utzoo comp.graphics:10922 sci.electronics:11202 comp.sys.ibm.pc:48237 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!kuhub.cc.ukans.edu!bbb From: bbb@kuhub.cc.ukans.edu Newsgroups: comp.graphics,sci.electronics,comp.sys.ibm.pc Subject: Re: DAK Video Digitizer.... Message-ID: <22808.2621028e@kuhub.cc.ukans.edu> Date: 10 Apr 90 03:45:50 GMT References: <1788@xn.LL.MIT.EDU> Organization: University of Kansas Academic Computing Services Lines: 381 In article <1788@xn.LL.MIT.EDU>, tj@XN.LL.MIT.EDU (Thomas E. Jones) writes: > I just purchased the Video Digitizer from DAK ($169.00.) It is a > 256x256 64-grey level frame grabber. It comes with 3 programs to > allow you to display images from your camera (or VTR,) make a slide-show > of pictures, and a paint-like program. > > None of the software packages let you get the full 256X256 grey-level > image, they all do dithering and reduce the effective resolution. I > am trying to dis-assemble one of the programs to figure out how to > read from the card myself, but it's fairly difficult and time-consuming. > > Does anyone else have one of these systems? If so, I'd like to share > information with them. I have figured out a great deal about the card > (both from program disassembly and examination of the hardware.) Please > get ahold of me. Anyone who helps out will be entitled to all the software > I get finished. > > - tj@xn.ll.mit.edu > Thomas E. Jones > > -- > tj@xn.ll.mit.edu or tj@ll-xn.arpa (one of these should work) > Thomas E. Jones, home (617) 924-8326 work (617) 981-5093 THOMAS To answer your questions directed to BROWNRIGG (I'm his friend with the DAK card. Just got my account today.) The card really only appears to digitze about 245 lines @ 256 pix. The fundamental drivers I got from DAK software support. That number is in the manual you got with the board. I write all in MS-C and MS-QC. I have chosen MSQC for my software because is allows in-line assembly. (QC ver 2.00 that is) Below is the listing for my so called Super-Vid. (SVID) It will get about 4-6 frames/sec out to the VGA on a 286. Maybe more I haven't really tried to measure it. After that is the .h file I use. I saw you got a Turbo-C version. The major difference in my code is the watching the FRAME bit to make sure successive frames are the same one. Otherwise you will notice a 'jumping' of the image as it randomly gets different frames (even-vs-odd) of the interlace. I'm still looking for info on the Closed-Caption. In theory I should have about 33000 Usec between CC info lines and that leads me to think I could capture that single line, decode it and write it out to screen or file. Would be neat to be able to generate transcripts of CC programs of interest. ********************************************************************* SVID // modified for `max' transfer speed!!!!! I hope.. // SVID by Brett Bennett // Based orginally on information supplied by DAK // // Quick-C ver 2.0 // // compile line: QCL /G2 SVID.C // // program uses QC-2 inline assembly to max out transfer from interface // to VGA memory. Uses an INSB command that is available only on 80286's // and up. PROGRAM WILL NOT WORK ON AN 8086/88. A V-20 does seem to work. // // Program may be freely modified and distributed with proper acknowlegdments // #include #include #include #include "vid.h" #include //#define MAXSAMP 62000l #define MAXSAMP 51200l unsigned char huge *buf; int gain,enlighten,lines; int max,ofset=20; unsigned char DELAYNOM=0x00; unsigned char far *mem; /* ignore its warnings */ // //this var is crtical for precise frame grabbing applications. unsigned char flipflop=0; //controls frame grabbers frame syncing char key; main (argc, argv) int argc; char * argv[]; { long count,sum; int avg; count=MAXSAMP; //printf("Enter multiplier factor "); //scanf("%d",&gain); //printf("Enter # scanlines"); //scanf("%d",&lines); lines=200; ofset=0; if ( (argc>1) && (0==strcmpi(argv[1],"?")) ) { printf("\n\n B&D Electronics Super VIdeo Display 1990(c)\n\n"); printf("Format:\nSVID ofset lines\n"); printf("Ofset= number of lines to skip\n"); printf("lines= number of lines to display per frame\n"); printf("SVID w/no parameters defaults to ofset=0, lines=200\n"); printf("Press CR to toggle between frames\n"); printf("Space bar to freeze then again to end\n"); exit(0); } if ( argc > 1 ) ofset=atoi(argv[1]); ofset=ofset*256; if ( argc > 2 ) lines=atoi(argv[2]); buf = (char huge *)halloc( count, sizeof( char ) ); if ( buf == 0 ) {printf("allocate failed.\n");exit(1);} if ( 0 == _setvideomode(_MRES256COLOR)) { printf("Sorry VGA required.\n"); exit(0); } //build a 64 shade gray table! 4 times _disable(); //stop interupts for (max=0;max<64;max++) { // outp(0x3c8, (char)max); //VGA's DAC reg outp(0x3c9, (char)max); //RED outp(0x3c9, (char)max); //GREEN outp(0x3c9, (char)max); //BLUE outp(0x3c8, (char)max+64); outp(0x3c9, (char)max); outp(0x3c9, (char)max); outp(0x3c9, (char)max); outp(0x3c8, (char)max+128); outp(0x3c9, (char)max); outp(0x3c9, (char)max); outp(0x3c9, (char)max); outp(0x3c8, (char)max+192); outp(0x3c9, (char)max); outp(0x3c9, (char)max); outp(0x3c9, (char)max); } vidinit(); //init the video card. while ( key != 32) //wait for a space char { do { // modified ver of vxfer goes directly to video memory. _disable(); vxfer(); _enable(); } while ( !kbhit() ); key=getch(); flipflop=!flipflop; //toggle flipflop. controls which frame of the interlace } getch(); _setvideomode(_DEFAULTMODE); } //end main /***********************************************************************/ /* DRIVING ROUTINES Original code from DAK */ /***********************************************************************/ /* THIS FUNCTION INITIALIZES TME VIDEO BOARD LOGIC */ vidinit() { outp(VIDBOARD, DELAYNOM | READMODE); /* clear the board */ outp(VIDBOARD, VCLEAR | RFSHEN | DELAYNOM | READMODE); /* clear the board */ } /*******************************************************/ pas() /* this is a wait loop (pause) function */ { int i; int j; for (i=1; i<300;++i) for (j=1; j<100;++j ); } /******************************************************/ /* the CAPTURE FUNCTION FOR OPERATING THE VIDEO CARD */ /******************************************************/ vxfer() { int i; unsigned int j; int done; i = 10000; /* Start by making sure that vertical syncs are occurring */ done = 0; while ( !done ) { //flip-flop var controls what frame to grab. //while the DAK card doesn't know which frame is the even and which is odd //(depends on when the video signal was first applied to the card) It does //keep track of one from the other. This is critical for accurate capture //of images. ESP when doing things like R-G-B color seperation work. // wait for sync high AND field bit high. if( flipflop ) { //waits for high field bit. if ( (inp(VIDBOARD) & FVSYNCM) == FVSYNCM) done = 1; if (--i < 0) done = 1; } // wait for sync high AND field bit low. if( !flipflop ) { if ( (inp(VIDBOARD) & FVSYNCM) == VSYNCM) done = 1; if (--i < 0) done = 1; } } if (i < 0) { // _setvideomode(MTEXT); printf("Vertical sync is stuck high..aborting\r"); pas(); } else { i = 10000; done = 0; while ( !done ) { //NOW WAIT FOR SYNC TO GO LOW. if ( (inp(VIDBOARD) & VSYNCM) == 0) done = 1; if (--i < 0) done = 1; } if (i < 1) { // _setvideomode(MTEXT); printf("No vertical sync detected..aborting\r" ); pas(); i=10000; } else { //ok here we know that vertical syncs are occuring. that is good! //SYNCH IS LOW AND FIELD IS HIGH TAKE A PICTURE! //go with what I was given from DAK... outp(VIDBOARD, DELAYNOM | READMODE); /* clear the board */ outp(VIDBOARD, VCLEAR | DELAYNOM); /* set board in write mcde */ outp(VIDBOARD, VCLEAR | CAPTURE | DELAYNOM); /* capture */ i = 10000; while ( ( (inp(VIDBOARD) & VSYNCM) == 0) && (--i > 0) ); /* while sync present */ //reduce i here is you don't want to wait for a full screens worth. i = 10000; //appears to be a sufficently long enough delay. while ( ( (inp(VIDBOARD) & VSYNCM) == VSYNCM) && (--i > 0) ); /* Wait */ outp(VIDBOARD, DELAYNOM); /* set clear and remove capture */ outp(VIDBOARD, READMODE | DELAYNOM | RDFIOM); /* With clear set, goto read mode */ outp(VIDBOARD, READMODE | VCLEAR | RDFIOM | DELAYNOM); { //high speed direct to video memory transfer here. _disable(); //stop any further system interupts. except NMIs _asm { push ax ;save some regs push cx push dx push di push es mov dx,0x3ef ;prepare dx for port address mov cx,ofset ;get var OFSET and skip this many lines. jcxz noeatum ;jump cx=zero. if zero then jump to eatum eatum: in al,dx ;skip over requested lines. EXPECTED to be 256*#lines. loop eatum ;loop back and eat um up noeatum: mov cx,lines ;number of lines to do. jcxz exitstageleft mov ax,0xa000 ;segment of vga memory. mov es,ax ;move segment to es for INSB instruction to come. mov di,0 ;set inital offset to zero ;regs now prep. time to get the data. line: push cx ;save number of lines left to do. mov cx,256 ;load number of pixels for next line. rep insb ;do insb cx times. add di,64 ;shift to next line of video 320x200 mode only! pop cx ;get line count back loop line ;back to get next line. exitstageleft: pop es ;restore regs. pop di pop dx pop cx pop ax } } /* now disable DMA request */ //outp(VIDBOARD, READMODE | VCLEAR | DELAYNOM); } } }//end vxfer ****************************************************************** VID.H /* VID.H taken orginally for DAK supplied user info. Some of the items in their include did not seem to be accurate for this version of the digitizer. Major mode is addition is FVSYNCM used to monitor which frame (even/odd) is taken. */ /* DAKS include. */ /* Vid.d lnclude file Aug. 11, 1987 */ #define MTEXT 1 /* the Video modes */ #define GRAPH 2 /* the VIDEO BOARO DEFS */ #define VIDBOARD 0x3ef /* the read space */ #define VIDMASK 0x3f /* the 6 Video bit sample */ //#define HSYNCM 0x40 /*horizontal sync mask DOES NOT APPLY TO THIS BOARD!*/ /* low for 5 of each 62.5 usec <- apparently a different board than DAK's*/ #define FSYNCM 0x40 /*the frame sync mask toggles with each vsync field. */ #define VSYNCM 0x80 /*Vertical sync mask high for 180 Usec every 33.3 msec */ #define FVSYNCM 0xc0 /*Frame and Vertical sync mask use to ensure vertical */ /* the write space */ #define RDFIOM 0x80 /* 1 == read frame data via i/o */ #define DELAYM 0x50 /* delay bit mask */ #define RFSHEN 0x08 /*DMA request enable mask *actually enable main-board refreshs**/ #define READMODE 0x04 /* 1 = Read Mode ; 0 = Write mode */ #define CAPTURE 0x02 /* low to hlgh transiticn initiates a capture */ #define VCLEAR 0x01 /* when low, clears the line and pixel counters */ //I like to set these in my code //#define DELAYSHF 0x04 /* delay bit shlft */ //#define DELAYNOM 0x60 /* nominal delay Value defined in the */