mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 08:43:23 +00:00
Added Cortex-I Frame Grabber by Paul S. LaFollette, Jr.
Submitted by: Paul S. LaFollette, Jr.
This commit is contained in:
parent
7ce005d7c1
commit
fae772f7b2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=3272
@ -4,7 +4,7 @@
|
||||
#
|
||||
# This kernel is NOT MEANT to be runnable!
|
||||
#
|
||||
# $Id: LINT,v 1.90 1994/10/01 05:43:09 davidg Exp $
|
||||
# $Id: LINT,v 1.91 1994/10/01 16:44:07 phk Exp $
|
||||
#
|
||||
|
||||
machine "i386"
|
||||
@ -212,6 +212,9 @@ device snd6 at isa? port 0x220 irq 7 drq 5 vector sbintr
|
||||
device snd7 at isa? port 0x300
|
||||
device snd1 at isa? port 0x388
|
||||
|
||||
# Cortex-I Frame Grabber driver
|
||||
device ctx0 at isa? port 0x230 iomem 0xd0000
|
||||
|
||||
# The digital speaker driver (/dev/pcaudio).
|
||||
device pca0 at isa? tty
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This file tells config what files go into building a kernel,
|
||||
# files marked standard are always included.
|
||||
#
|
||||
# $Id: files.i386,v 1.50 1994/10/01 02:36:24 swallace Exp $
|
||||
# $Id: files.i386,v 1.51 1994/10/01 02:55:57 davidg Exp $
|
||||
#
|
||||
i386/apm/apm.c optional apm device-driver
|
||||
i386/apm/apm_setup.s optional apm
|
||||
@ -48,6 +48,7 @@ i386/isa/aic6360.c optional aic device-driver
|
||||
i386/isa/b004.c optional bqu device-driver
|
||||
i386/isa/bt742a.c optional bt device-driver
|
||||
i386/isa/clock.c standard
|
||||
i386/isa/ctx.c optional ctx device-driver
|
||||
i386/isa/fd.c optional fd device-driver
|
||||
i386/isa/ft.c optional ft device-driver
|
||||
i386/isa/elink.c optional ie device-driver
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# This kernel is NOT MEANT to be runnable!
|
||||
#
|
||||
# $Id: LINT,v 1.90 1994/10/01 05:43:09 davidg Exp $
|
||||
# $Id: LINT,v 1.91 1994/10/01 16:44:07 phk Exp $
|
||||
#
|
||||
|
||||
machine "i386"
|
||||
@ -212,6 +212,9 @@ device snd6 at isa? port 0x220 irq 7 drq 5 vector sbintr
|
||||
device snd7 at isa? port 0x300
|
||||
device snd1 at isa? port 0x388
|
||||
|
||||
# Cortex-I Frame Grabber driver
|
||||
device ctx0 at isa? port 0x230 iomem 0xd0000
|
||||
|
||||
# The digital speaker driver (/dev/pcaudio).
|
||||
device pca0 at isa? tty
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# This kernel is NOT MEANT to be runnable!
|
||||
#
|
||||
# $Id: LINT,v 1.90 1994/10/01 05:43:09 davidg Exp $
|
||||
# $Id: LINT,v 1.91 1994/10/01 16:44:07 phk Exp $
|
||||
#
|
||||
|
||||
machine "i386"
|
||||
@ -212,6 +212,9 @@ device snd6 at isa? port 0x220 irq 7 drq 5 vector sbintr
|
||||
device snd7 at isa? port 0x300
|
||||
device snd1 at isa? port 0x388
|
||||
|
||||
# Cortex-I Frame Grabber driver
|
||||
device ctx0 at isa? port 0x230 iomem 0xd0000
|
||||
|
||||
# The digital speaker driver (/dev/pcaudio).
|
||||
device pca0 at isa? tty
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This file tells config what files go into building a kernel,
|
||||
# files marked standard are always included.
|
||||
#
|
||||
# $Id: files.i386,v 1.50 1994/10/01 02:36:24 swallace Exp $
|
||||
# $Id: files.i386,v 1.51 1994/10/01 02:55:57 davidg Exp $
|
||||
#
|
||||
i386/apm/apm.c optional apm device-driver
|
||||
i386/apm/apm_setup.s optional apm
|
||||
@ -48,6 +48,7 @@ i386/isa/aic6360.c optional aic device-driver
|
||||
i386/isa/b004.c optional bqu device-driver
|
||||
i386/isa/bt742a.c optional bt device-driver
|
||||
i386/isa/clock.c standard
|
||||
i386/isa/ctx.c optional ctx device-driver
|
||||
i386/isa/fd.c optional fd device-driver
|
||||
i386/isa/ft.c optional ft device-driver
|
||||
i386/isa/elink.c optional ie device-driver
|
||||
|
@ -41,7 +41,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)conf.c 5.8 (Berkeley) 5/12/91
|
||||
* $Id: conf.c,v 1.35 1994/09/29 08:59:33 sos Exp $
|
||||
* $Id: conf.c,v 1.36 1994/10/01 02:55:59 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -544,6 +544,21 @@ d_ioctl_t apmioctl;
|
||||
#define apmioctl (d_ioctl_t *)enxio
|
||||
#endif
|
||||
|
||||
#include "ctx.h"
|
||||
#if NCTX > 0
|
||||
d_open_t ctxopen;
|
||||
d_close_t ctxclose;
|
||||
d_rdwr_t ctxread;
|
||||
d_rdwr_t ctxwrite;
|
||||
d_ioctl_t ctxioctl;
|
||||
#else
|
||||
#define ctxopen (d_open_t *)enxio
|
||||
#define ctxclose (d_close_t *)enxio
|
||||
#define ctxread (d_rdwr_t *)enxio
|
||||
#define ctxwrite (d_rdwr_t *)enxio
|
||||
#define ctxioctl (d_ioctl_t *)enxio
|
||||
#endif
|
||||
|
||||
#define noopen (d_open_t *)enodev
|
||||
#define noclose (d_close_t *)enodev
|
||||
#define noread (d_rdwr_t *)enodev
|
||||
@ -685,8 +700,11 @@ struct cdevsw cdevsw[] =
|
||||
{ apmopen, apmclose, noread, nowrite, /*39*/
|
||||
apmioctl, nostop, nullreset, NULL, /* laptop APM */
|
||||
seltrue, nommap, NULL },
|
||||
/* character device 40 is reserved for local use */
|
||||
{ (d_open_t *)enxio, (d_close_t *)enxio, (d_rdwr_t *)enxio, /*40*/
|
||||
{ ctxopen, ctxclose, ctxread, ctxwrite, /*40*/
|
||||
ctxioctl, nostop, nullreset, NULL, /* cortex framegrabber */
|
||||
seltrue, nommap, NULL },
|
||||
/* character device 41 is reserved for local use */
|
||||
{ (d_open_t *)enxio, (d_close_t *)enxio, (d_rdwr_t *)enxio, /*41*/
|
||||
(d_rdwr_t *)enxio, (d_ioctl_t *)enxio, (d_stop_t *)enxio,
|
||||
(d_reset_t *)enxio, NULL, (d_select_t *)enxio,
|
||||
(d_mmap_t *)enxio, NULL }
|
||||
|
30
sys/i386/include/ioctl_ctx.h
Normal file
30
sys/i386/include/ioctl_ctx.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 1994, Paul S. LaFollette, Jr. This software may be used,
|
||||
* modified, copied, distributed, and sold, in both source and binary form
|
||||
* provided that the above copyright and these terms are retained. Under
|
||||
* no circumstances is the author responsible for the proper functioning
|
||||
* of this software, nor does the author assume any responsibility
|
||||
* for damages incurred with its use
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* ioctl constants for Cortex-I frame grabber
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_IOCTL_CTX_H_
|
||||
#define _MACHINE_IOCTL_CTX_H_
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
typedef char _CTX_LUTBUF[256]; /* look up table buffer */
|
||||
|
||||
#define CTX_LIVE _IO('x', 1) /* live video */
|
||||
#define CTX_GRAB _IO('x', 2) /* frame grab */
|
||||
#define CTX_H_ORGANIZE _IO('x', 3) /* file goes across screen (horiz. read) */
|
||||
#define CTX_V_ORGANIZE _IO('x', 4) /* file goes down screen (vert. read) */
|
||||
#define CTX_SET_LUT _IOW('x', 5, _CTX_LUTBUF) /* set lookup table */
|
||||
#define CTX_GET_LUT _IOR('x', 6, _CTX_LUTBUF) /* get lookup table */
|
||||
|
||||
#endif /* ifndef _MACHINE_IOCTL_CTX_H */
|
415
sys/i386/isa/ctx.c
Normal file
415
sys/i386/isa/ctx.c
Normal file
@ -0,0 +1,415 @@
|
||||
/*
|
||||
* CORTEX-I Frame Grabber driver V1.0
|
||||
*
|
||||
* Copyright (C) 1994, Paul S. LaFollette, Jr. This software may be used,
|
||||
* modified, copied, distributed, and sold, in both source and binary form
|
||||
* provided that the above copyright and these terms are retained. Under
|
||||
* no circumstances is the author responsible for the proper functioning
|
||||
* of this software, nor does the author assume any responsibility
|
||||
* for damages incurred with its use.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Device Driver for CORTEX-I Frame Grabber
|
||||
* Made by ImageNation Corporation
|
||||
* 1200 N.E. Keyues Road
|
||||
* Vancouver, WA 98684 (206) 944-9131
|
||||
* (I have no ties to this company, just thought you might want
|
||||
* to know how to get in touch with them.)
|
||||
*
|
||||
* In order to understand this device, you really need to consult the
|
||||
* manual which ImageNation provides when you buy the board. (And
|
||||
* what a pleasure it is to buy something for a PC and actually get
|
||||
* programming information along with it.) I will limit myself here to
|
||||
* a few comments which are specific to this driver. See also the file
|
||||
* ctxreg.h for definitions of registers and control bits.
|
||||
*
|
||||
* 1. Although the hardware supports low resolution (256 x 256)
|
||||
* acqusition and display, I have not implemented access to
|
||||
* these modes in this driver. There are some fairly quirky
|
||||
* aspects to the way this board works in low resolution mode,
|
||||
* and I don't want to deal with them. Maybe later.
|
||||
*
|
||||
* 2. Choosing the base address for the video memory: This is set
|
||||
* using a combination of hardware and software, using the left
|
||||
* most dip switch on the board, and the AB_SELECT bit of control
|
||||
* port 1, according to the chart below:
|
||||
*
|
||||
* Left DIP switch || DOWN | UP |
|
||||
* =================================================
|
||||
* AB_SELECT = 0 || 0xA0000 | 0xB0000 |
|
||||
* -------------------------------------------------
|
||||
* AB_SELECT = 1 || 0xD0000 | 0xE0000 |
|
||||
* ------------------------------------------------
|
||||
*
|
||||
* When the RAM_ENABLE bit of control port 1 is clear (0), the
|
||||
* video ram is disconnected from the computer bus. This makes
|
||||
* it possible, in principle, to share memory space with other
|
||||
* devices (such as VGA) which can also disconnect themselves
|
||||
* from the bus. It also means that multiple CORTEX-I boards
|
||||
* can share the same video memory space. Disconnecting from the
|
||||
* bus does not affect the video display of the video ram contents,
|
||||
* so that one needs only set the RAM_ENABLE bit when actually
|
||||
* reading or writing to memory. The cost of this is low,
|
||||
* the benefits to me are great (I need more than one board
|
||||
* in my machine, and 0xE0000 is the only address choice that
|
||||
* doesn't conflict with anything) so I adopt this strategy here.
|
||||
*
|
||||
* XXX-Note... this driver has only been tested for the
|
||||
* XXX base = 0xE0000 case!
|
||||
*
|
||||
* 3) There is a deficiency in the documentation from ImageNation, I
|
||||
* think. In order to successfully load the lookup table, it is
|
||||
* necessary to clear SEE_STORED_VIDEO in control port 0 as well as
|
||||
* setting LUT_LOAD_ENABLE in control port 1.
|
||||
*
|
||||
* 4) This driver accesses video memory through read or write operations.
|
||||
* Other functionality is provided through ioctl's, manifest
|
||||
* constants for which are defined in ioctl_ctx.h. The ioctl's
|
||||
* include:
|
||||
* CTX_LIVE Display live video
|
||||
* CTX_GRAB Grab a frame of video data
|
||||
* CTX_H_ORGANIZE Set things up so that sequential read
|
||||
* operations access horizontal lines of
|
||||
* pixels.
|
||||
* CTX_V_ORGANIZE Set things up so that sequential read
|
||||
* operations access vertical lines of
|
||||
* pixels.
|
||||
* CTX_SET_LUT Set the lookup table from an array
|
||||
* of 256 unsigned chars passed as the
|
||||
* third parameter to ioctl.
|
||||
* CTX_GET_LUT Return the current lookup table to
|
||||
* the application as an array of 256
|
||||
* unsigned chars. Again the third
|
||||
* parameter to the ioctl call.
|
||||
*
|
||||
* Thus,
|
||||
* ioctl(fi, CTX_H_ORGANIZE, 0);
|
||||
* lseek(fi, y*512, SEEK_SET);
|
||||
* read(fi, buffer, 512);
|
||||
*
|
||||
* will fill buffer with 512 pixels (unsigned chars) which represent
|
||||
* the y-th horizontal line of the image.
|
||||
* Similarly,
|
||||
* ioctl(fi, CTX_V_ORGANIZE, 0:
|
||||
* lseek(fi, x*512+y, SEEK_SET);
|
||||
* read(fi, buffer, 10);
|
||||
*
|
||||
* will read 10 a vertical line of 10 pixels starting at (x,y).
|
||||
*
|
||||
* Obviously, this sort of ugliness needs to be hidden away from
|
||||
* the casual user, with an appropriate set of higher level
|
||||
* functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ctx.h"
|
||||
#if NCTX > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include "isa.h"
|
||||
#include "isa_device.h"
|
||||
#include "ctxreg.h"
|
||||
#include <machine/ioctl_ctx.h>
|
||||
|
||||
int waitvb(short);
|
||||
|
||||
/* state flags */
|
||||
#define OPEN (0x01) /* device is open */
|
||||
|
||||
#define UNIT(x) ((x) & 0x07)
|
||||
|
||||
int ctxprobe(), ctxattach();
|
||||
struct isa_driver ctxdriver = {ctxprobe, ctxattach, "ctx"};
|
||||
|
||||
#define LUTSIZE 256 /* buffer size for Look Up Table (LUT) */
|
||||
#define PAGESIZE 65536 /* size of one video page, 1/4 of the screen */
|
||||
|
||||
/*
|
||||
* Per unit shadow registers (because the dumb hardware is RO)
|
||||
*/
|
||||
|
||||
struct ctx_soft_registers {
|
||||
u_char *lutp;
|
||||
u_char cp0;
|
||||
u_char cp1;
|
||||
u_char flag;
|
||||
short iobase;
|
||||
caddr_t maddr;
|
||||
int msize;
|
||||
} ctx_sr[NCTX];
|
||||
|
||||
|
||||
|
||||
int
|
||||
ctxprobe(struct isa_device * devp)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (inb(devp->id_iobase) == 0xff) /* 0xff only if board absent */
|
||||
status = 0;
|
||||
else
|
||||
status = 1;
|
||||
return (status);
|
||||
}
|
||||
|
||||
int
|
||||
ctxattach(struct isa_device * devp)
|
||||
{
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
sr = &(ctx_sr[devp->id_unit]);
|
||||
sr->cp0 = 0; /* zero out the shadow registers */
|
||||
sr->cp1 = 0; /* and the open flag. wait for */
|
||||
sr->flag = 0; /* open to malloc the LUT space */
|
||||
sr->iobase = devp->id_iobase;
|
||||
sr->maddr = devp->id_maddr;
|
||||
sr->msize = devp->id_msize;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
ctxopen(dev_t dev, int flag)
|
||||
{
|
||||
struct ctx_soft_registers *sr;
|
||||
u_char unit;
|
||||
int i;
|
||||
|
||||
unit = UNIT(minor(dev));
|
||||
|
||||
/* minor number out of range? */
|
||||
|
||||
if (unit >= NCTX)
|
||||
return (ENXIO);
|
||||
sr = &(ctx_sr[unit]);
|
||||
|
||||
if (sr->flag != 0) /* someone has already opened us */
|
||||
return (EBUSY);
|
||||
|
||||
/* get space for the LUT buffer */
|
||||
|
||||
sr->lutp = malloc(LUTSIZE, M_DEVBUF, M_WAITOK);
|
||||
if (sr->lutp == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
sr->flag = OPEN;
|
||||
|
||||
/*
|
||||
Set up the shadow registers. We don't actually write these
|
||||
values to the control ports until after we finish loading the
|
||||
lookup table.
|
||||
*/
|
||||
sr->cp0 |= SEE_STORED_VIDEO;
|
||||
if ((kvtop(sr->maddr) == 0xB0000) || (kvtop(sr->maddr) == 0xE0000))
|
||||
sr->cp1 |= AB_SELECT; /* map to B or E if necessary */
|
||||
/* but don't enable RAM */
|
||||
/*
|
||||
Set up the lookup table initially so that it is transparent.
|
||||
*/
|
||||
|
||||
outb(sr->iobase + ctx_cp0, (u_char) 0);
|
||||
outb(sr->iobase + ctx_cp1, (u_char) (LUT_LOAD_ENABLE | BLANK_DISPLAY));
|
||||
for (i = 0; i < LUTSIZE; i++) {
|
||||
outb(sr->iobase + ctx_lutaddr, (u_char) i);
|
||||
sr->lutp[i] = (u_char) i;
|
||||
outb(sr->iobase + ctx_lutdata, (u_char) sr->lutp[i]);
|
||||
}
|
||||
/*
|
||||
Disable LUT loading, and push the data in the shadow
|
||||
registers into the control ports.
|
||||
*/
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
return (0); /* successful open. All ready to go. */
|
||||
}
|
||||
|
||||
int
|
||||
ctxclose(dev_t dev, int flag)
|
||||
{
|
||||
int unit;
|
||||
|
||||
unit = UNIT(minor(dev));
|
||||
ctx_sr[unit].flag = 0;
|
||||
free(ctx_sr[unit].lutp, M_DEVBUF);
|
||||
ctx_sr[unit].lutp = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ctxwrite(dev_t dev, struct uio * uio)
|
||||
{
|
||||
int unit, status = 0;
|
||||
int page, count, offset;
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
unit = UNIT(minor(dev));
|
||||
sr = &(ctx_sr[unit]);
|
||||
|
||||
page = uio->uio_offset / PAGESIZE;
|
||||
offset = uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
while ((page >= 0) && (page <= 3) && (count > 0)) {
|
||||
sr->cp0 &= ~3;
|
||||
sr->cp0 |= page;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
|
||||
/*
|
||||
Before doing the uiomove, we need to "connect" the frame buffer
|
||||
ram to the machine bus. This is done here so that we can have
|
||||
several different boards installed, all sharing the same memory
|
||||
space... each board is only "connected" to the bus when its memory
|
||||
is actually being read or written. All my instincts tell me that
|
||||
I should disable interrupts here, so I have done so.
|
||||
*/
|
||||
|
||||
disable_intr();
|
||||
sr->cp1 |= RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
status = uiomove(sr->maddr + offset, count, uio);
|
||||
sr->cp1 &= ~RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
enable_intr();
|
||||
|
||||
page = uio->uio_offset / PAGESIZE;
|
||||
offset = uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
}
|
||||
if (uio->uio_resid > 0)
|
||||
return (ENOSPC);
|
||||
else
|
||||
return (status);
|
||||
}
|
||||
|
||||
int
|
||||
ctxread(dev_t dev, struct uio * uio)
|
||||
{
|
||||
int unit, status = 0;
|
||||
int page, count, offset;
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
unit = UNIT(minor(dev));
|
||||
sr = &(ctx_sr[unit]);
|
||||
|
||||
page = uio->uio_offset / PAGESIZE;
|
||||
offset = uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
while ((page >= 0) && (page <= 3) && (count > 0)) {
|
||||
sr->cp0 &= ~3;
|
||||
sr->cp0 |= page;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
/*
|
||||
Before doing the uiomove, we need to "connect" the frame buffer
|
||||
ram to the machine bus. This is done here so that we can have
|
||||
several different boards installed, all sharing the same memory
|
||||
space... each board is only "connected" to the bus when its memory
|
||||
is actually being read or written. All my instincts tell me that
|
||||
I should disable interrupts here, so I have done so.
|
||||
*/
|
||||
disable_intr();
|
||||
sr->cp1 |= RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
status = uiomove(sr->maddr + offset, count, uio);
|
||||
sr->cp1 &= ~RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
enable_intr();
|
||||
|
||||
page = uio->uio_offset / PAGESIZE;
|
||||
offset = uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
}
|
||||
if (uio->uio_resid > 0)
|
||||
return (ENOSPC);
|
||||
else
|
||||
return (status);
|
||||
}
|
||||
|
||||
int
|
||||
ctxioctl(dev_t dev, int cmd, caddr_t data, int flag)
|
||||
{
|
||||
int error;
|
||||
int unit, i;
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
error = 0;
|
||||
unit = UNIT(minor(dev));
|
||||
sr = &(ctx_sr[unit]);
|
||||
|
||||
switch (cmd) {
|
||||
case CTX_LIVE:
|
||||
sr->cp0 &= ~SEE_STORED_VIDEO;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_GRAB:
|
||||
sr->cp0 &= ~SEE_STORED_VIDEO;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
sr->cp0 |= ACQUIRE;
|
||||
if (waitvb(sr->iobase)) /* wait for vert blank to start
|
||||
* acquire */
|
||||
error = ENODEV;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
if (waitvb(sr->iobase)) /* wait for two more to finish acquire */
|
||||
error = ENODEV;
|
||||
if (waitvb(sr->iobase))
|
||||
error = ENODEV;
|
||||
sr->cp0 &= ~ACQUIRE; /* turn off acquire and turn on
|
||||
* display */
|
||||
sr->cp0 |= SEE_STORED_VIDEO;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_H_ORGANIZE:
|
||||
sr->cp0 &= ~PAGE_ROTATE;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_V_ORGANIZE:
|
||||
sr->cp0 |= PAGE_ROTATE;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_SET_LUT:
|
||||
bcopy((u_char *) data, sr->lutp, LUTSIZE);
|
||||
outb(sr->iobase + ctx_cp0, (u_char) 0);
|
||||
outb(sr->iobase + ctx_cp1, (u_char) (LUT_LOAD_ENABLE | BLANK_DISPLAY));
|
||||
for (i = 0; i < LUTSIZE; i++) {
|
||||
outb(sr->iobase + ctx_lutaddr, i);
|
||||
outb(sr->iobase + ctx_lutdata, sr->lutp[i]);
|
||||
}
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0); /* restore control
|
||||
* registers */
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
break;
|
||||
case CTX_GET_LUT:
|
||||
bcopy(sr->lutp, (u_char *) data, LUTSIZE);
|
||||
break;
|
||||
default:
|
||||
error = ENODEV;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
waitvb(short port)
|
||||
{ /* wait for a vertical blank, */
|
||||
if (inb(port) == 0xff) /* 0xff means no board present */
|
||||
return (1);
|
||||
|
||||
while ((inb(port) & VERTICAL_BLANK) != 0) {
|
||||
}
|
||||
while ((inb(port) & VERTICAL_BLANK) == 0) {
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* NCTX > 0 */
|
59
sys/i386/isa/ctxreg.h
Normal file
59
sys/i386/isa/ctxreg.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 1994, Paul S. LaFollette, Jr. This software may be used,
|
||||
* modified, copied, distributed, and sold, in both source and binary form
|
||||
* provided that the above copyright and these terms are retained. Under
|
||||
* no circumstances is the author responsible for the proper functioning
|
||||
* of this software, nor does the author assume any responsibility
|
||||
* for damages incurred with its use
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register and bit definitions for CORTEX-I frame grabber
|
||||
*/
|
||||
|
||||
#ifndef _I386_ISA_CTXREG_H_
|
||||
#define _I386_ISA_CTXREG_H_
|
||||
|
||||
/* Control Ports (all are write-only) */
|
||||
|
||||
#define ctx_cp0 0 /* offset to control port 0 */
|
||||
#define ctx_cp1 1 /* offset to control port 1 */
|
||||
#define ctx_lutaddr 2 /* offset to lut address port */
|
||||
#define ctx_lutdata 3 /* offset to lut data port */
|
||||
|
||||
/* Status port (read-only but same address as control port 0) */
|
||||
|
||||
#define ctx_status 0 /* offset to status port */
|
||||
|
||||
/* Bit assignments for control port 0 */
|
||||
|
||||
#define PAGE_SELECT0 1 /* These two bits choose which 1/4 of the */
|
||||
#define PAGE_SELECT1 2 /* video memory is accessible to us. */
|
||||
#define PAGE_ROTATE 4 /* 0 => horizontal access. 1 => vertical */
|
||||
#define ACQUIRE 8 /* set to start frame grab */
|
||||
#define SEE_STORED_VIDEO 16 /* set to allow stored frame to be seen */
|
||||
#define LOW_RESOLUTION 32 /* set to enable 256 x 256 mode */
|
||||
|
||||
/* Bit assignments for control port 1 */
|
||||
|
||||
#define INTERRUPT_ENABLE 1 /* Allow interrupts (we avoid this bit) */
|
||||
#define TRIGGER_ENABLE 2 /* Enable external trigger for frame grab */
|
||||
#define LUT_LOAD_ENABLE 4 /* Allow loading of lookup table */
|
||||
#define BLANK_DISPLAY 8 /* Turn off display */
|
||||
#define AB_SELECT 16 /* Along with HW switch, choose base memory */
|
||||
#define RAM_ENABLE 32 /* Connect video RAM to computer bus */
|
||||
|
||||
/* Bit assignments for status port */
|
||||
|
||||
#define INTERRUPT_STATUS 1 /* Ignored by us */
|
||||
#define ADC_OVERFLOW 2 /* Set if any pixes from camera "too bright"*/
|
||||
#define FIELD 4 /* 0 or 1 shows which interlace field are in*/
|
||||
#define VERTICAL_BLANK 8 /* 1 if in vertical blanking interval */
|
||||
#define TRIGGERED 16 /* 1 if HW trigger contacts closed */
|
||||
#define ACQUIRING_ACK 32 /* 1 if currently grabbing a frame */
|
||||
|
||||
|
||||
#endif /* ifndef _I386_ISA_CTXREG_H_ */
|
Loading…
Reference in New Issue
Block a user