Xref: utzoo comp.graphics:10908 sci.electronics:11192 comp.sys.ibm.pc:48211 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!rpi!image.soe.clarkson.edu!news From: nelson@sun.soe.clarkson.edu (Russ Nelson) Newsgroups: comp.graphics,sci.electronics,comp.sys.ibm.pc Subject: Re: DAK Video Digitizer.... Message-ID: Date: 9 Apr 90 15:44:48 GMT References: <1788@xn.LL.MIT.EDU> Sender: news@sun.soe.clarkson.edu Reply-To: nelson@clutx.clarkson.edu Organization: Clarkson University, Potsdam NY Lines: 223 In-reply-to: tj@XN.LL.MIT.EDU's message of 9 Apr 90 13:26:17 GMT In article <1788@xn.LL.MIT.EDU> tj@XN.LL.MIT.EDU (Thomas E. Jones) writes: 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. Check this program out. It digitizes continuously, and copies the image to the VGA screen. Note that you *must* have a VGA, and the program doesn't check. No copies of the frames are kept, although that's pretty simple to add. Most of the time is spent copying it to the VGA memory because of all the wait states (ick). If you have a few meg of EMS, you could probably make a cute small movie. Curiously enough, I got the information on programming it simply by calling DAK's technical support number. I didn't even have to plead and beg, they just offered to send me the technical specs and program fragments! This is in Turbo C 2.0: #include #include #include #define VID 0x3ef /* when reading VID: */ #define HSYNC 0x40 #define VSYNC 0x80 /* when writing VID: */ #define RDFIOM 0x80 #define ELAYM 0x70 #define DELAYSHF 4 #define DELAYNOM 0x60 #define RFSHEN 8 #define READMODE 4 #define CAPTURE 2 #define VCLEAR 1 int their_palette[64*3]; int our_palette[64*3]; /* * Bios function call definitions */ #define BIOS_VIDFN 0x10 /* Video functions */ #define VID_PALETTE 0x10 /* palette access function */ #define PAL_SETPAL 0x00 /* update single palette register */ #define PAL_SETPALBLOCK 0x02 /* update all palette registers */ #define PAL_GETPALBLOCK 0x09 /* read all palette registers */ #define PAL_GETDACBLOCK 0x17 /* read current VGA DAC values */ #define PAL_SETDACBLOCK 0x12 /* set new VGA DAC values */ #define VID_SETPIXEL 0x0C /* store pixel value */ #define VID_DISPLAY 0x1A /* video display combination */ #define VID_SUBSYSTEM 0x12 /* video subsystem configuration */ /* * Arguments to the vid_vgapalette and vid_setpalette functions */ #define PAL_SAVE 0 /* Save existing values */ #define PAL_RESTORE 1 /* Restore saved values */ #define PAL_SETGREY 2 /* Set greyscale mapping */ #define PAL_SETLIN 3 /* Set 1:1 mapping (vid_setpalette) */ /* * Routine to map VGA palette registers (256 colour mode) * to and from a greyscale display. */ #define BITSPERBYTE 8 #define BITSPERVGACOLOUR 6 /* no. VGA DAC registers */ #define SIZE_DACS 256 /* no. distinct greyscale values */ #define NUM_GREY (1 << BITSPERVGACOLOUR) /* no. palette registers that map * to the same greyscale value */ #define GREY_SAME (SIZE_DACS / NUM_GREY) /* no. underlying colours on vga */ #define PRIMARY_COLOURS 3 static void vid_vgapalette(action) int action; { union REGS regs; struct SREGS sreg; static unsigned char SaveDacs[SIZE_DACS * PRIMARY_COLOURS], *GreyDacs = 0; switch(action) { case PAL_SAVE: /* Save existing palette */ regs.h.ah = VID_PALETTE; regs.h.al = PAL_GETPALBLOCK; regs.x.bx = 0; /* first palette register */ regs.x.cx = SIZE_DACS; /* read all palette registers */ segread(&sreg); sreg.es = sreg.ds; regs.x.dx = (unsigned int) SaveDacs; int86x(BIOS_VIDFN, ®s, ®s, &sreg); break; case PAL_RESTORE: /* restore saved palette */ regs.h.ah = VID_PALETTE; regs.h.al = PAL_SETDACBLOCK; regs.x.bx = 0; /* first palette register */ regs.x.cx = SIZE_DACS; /* read all palette registers */ segread(&sreg); sreg.es = sreg.ds; regs.x.dx = (unsigned int) SaveDacs; int86x(BIOS_VIDFN, ®s, ®s, &sreg); break; case PAL_SETGREY: /* set palette to greyscale */ if (GreyDacs == 0) { unsigned char *p; int c; if ((GreyDacs = malloc(SIZE_DACS*PRIMARY_COLOURS)) == 0) { return; } for (p = GreyDacs, c = 0; c < SIZE_DACS; c++) { int i; for (i = 0; i < PRIMARY_COLOURS; i++) *p++ = (c & 0x3f); } } regs.h.ah = VID_PALETTE; regs.h.al = PAL_SETDACBLOCK; regs.x.bx = 0; /* first palette register */ regs.x.cx = SIZE_DACS; /* read all palette registers */ segread(&sreg); sreg.es = sreg.ds; regs.x.dx = (unsigned int) GreyDacs; int86x(BIOS_VIDFN, ®s, ®s, &sreg); break; } } insb(int port, void far *buf, int cnt) { _DX = port; _CX = cnt; _ES = FP_SEG(buf); _DI = FP_OFF(buf); __emit__(0xf3, 0x6c); /* rep insb */ } video() { int i; geninterrupt(0x10); } vidinit() { outportb(VID, READMODE | DELAYNOM); outportb(VID, VCLEAR | RFSHEN | READMODE | DELAYNOM); } main() { int y; _AX = 0x13; video(); vid_vgapalette(PAL_SAVE); vid_vgapalette(PAL_SETGREY); while (!kbhit()) { while ((inportb(VID) & VSYNC) == VSYNC) if (kbhit()) break; outportb(VID, DELAYNOM | READMODE); outportb(VID, VCLEAR | DELAYNOM); outportb(VID, VCLEAR | DELAYNOM | CAPTURE); while ((inportb(VID) & VSYNC) == 0) if (kbhit()) break; while ((inportb(VID) & VSYNC) == VSYNC) if (kbhit()) break; outportb(VID, DELAYNOM); outportb(VID, READMODE | DELAYNOM | RDFIOM); outportb(VID, READMODE | VCLEAR | DELAYNOM | RDFIOM); for (y = 0; y < 200; y++) { insb(VID, MK_FP(0xa000, y * 320), 256); } outportb(VID, READMODE | VCLEAR | DELAYNOM); vidinit(); } getch(); vid_vgapalette(PAL_RESTORE); _AX = 0x3; video(); } -- --russ (nelson@clutx [.bitnet | .clarkson.edu]) Russ.Nelson@$315.268.6667 Violence never solves problems, it just changes them into more subtle problems