mirror of
https://github.com/PDP-10/klh10.git
synced 2026-01-11 23:52:54 +00:00
Use USB Panda Display.
Build with -DKLH10_DEV_LITES=1. Use the KLH10 command "lights usb" to enable this feature.
This commit is contained in:
parent
0402660bf0
commit
129e3d0f16
@ -1,7 +1,7 @@
|
||||
language: c
|
||||
dist: trusty
|
||||
sudo: required
|
||||
install: true
|
||||
install: sudo apt-get install libusb-1.0-0-dev
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- mkdir tmp
|
||||
|
||||
@ -54,7 +54,7 @@ CFLAGS_LINT ?=
|
||||
LINKER ?= $(CC)
|
||||
LDFLAGS ?=
|
||||
LDOUTF ?= -o
|
||||
LIBS ?=
|
||||
LIBS := -lusb-1.0
|
||||
NETLIBS ?= -lpcap
|
||||
|
||||
# Variables specific to this makefile setup
|
||||
@ -193,7 +193,7 @@ OFILES_KS = klh10.o prmstr.o fecmd.o feload.o wfio.o osdsup.o \
|
||||
vmtape.o dvtm03.o \
|
||||
dvlhdh.o dvdz11.o dvch11.o \
|
||||
dpsup.o \
|
||||
dvhost.o #dvlites.o is NOT needed for the KS-10
|
||||
dvhost.o dvlites.o
|
||||
|
||||
# Device Processes (DPs) built concurrently with KN10
|
||||
|
||||
|
||||
144
src/dvlites.c
144
src/dvlites.c
@ -20,6 +20,8 @@
|
||||
** and is used by permission.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "klh10.h"
|
||||
|
||||
#if !KLH10_DEV_LITES && CENV_SYS_DECOSF
|
||||
@ -31,6 +33,7 @@ static int decosfcclossage;
|
||||
|
||||
#if KLH10_DEV_LITES /* Moby conditional for entire file */
|
||||
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <sys/io.h>
|
||||
#include "dvlites.h"
|
||||
|
||||
@ -171,8 +174,110 @@ static const unsigned char control[8] = {
|
||||
|
||||
static int port = 0; /* parallel port, normally LPT1 (0x378) */
|
||||
static int unit = -1; /* currently selected unit */
|
||||
static libusb_device_handle *lights_handle = NULL;
|
||||
static unsigned int lights_left = 0;
|
||||
static unsigned int lights_right = 0;
|
||||
static int lights_aux = 0;
|
||||
|
||||
|
||||
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
||||
#define USB_CFG_DEVICE_ID 0xdf, 0x05
|
||||
#define USB_CFG_DEVICE_NAME 'P','a','n','d','a',' ','D','i','s','p','l','a','y',
|
||||
#define USB_CFG_DEVICE_NAME_LEN 13
|
||||
|
||||
static libusb_device_handle *get_panda_handle(libusb_device **devs)
|
||||
{
|
||||
libusb_device *dev;
|
||||
libusb_device_handle *handle = NULL;
|
||||
int i = 0;
|
||||
int r;
|
||||
|
||||
int found = 0;
|
||||
int openable = 0;
|
||||
|
||||
unsigned char prod[256];
|
||||
char devname[USB_CFG_DEVICE_NAME_LEN] = {USB_CFG_DEVICE_NAME};
|
||||
|
||||
unsigned char rawVid[2] = {USB_CFG_VENDOR_ID};
|
||||
unsigned char rawPid[2] = {USB_CFG_DEVICE_ID};
|
||||
|
||||
int vid = rawVid[0] + 256 * rawVid[1];
|
||||
int pid = rawPid[0] + 256 * rawPid[1];
|
||||
|
||||
|
||||
while ((dev = devs[i++]) != NULL) {
|
||||
struct libusb_device_descriptor desc;
|
||||
libusb_get_device_descriptor(dev, &desc); /* this always succeeds */
|
||||
// Do the VID and PID match?
|
||||
if (desc.idVendor == vid && desc.idProduct == pid) {
|
||||
found = 1;
|
||||
r = libusb_open(dev, &handle);
|
||||
// If we can't open it, keep trying.
|
||||
// There may be a device with the same pid and vid but not a Panda Display
|
||||
if (r < 0) {
|
||||
continue;
|
||||
}
|
||||
openable = 1;
|
||||
r = libusb_get_string_descriptor_ascii(handle, desc.iProduct, prod, sizeof prod);
|
||||
if (r < 0) {
|
||||
libusb_close(handle);
|
||||
return NULL;
|
||||
}
|
||||
// Here we have something that matches the free
|
||||
// VID and PID offered by Objective Development.
|
||||
// Now we need to Check device name to see if it
|
||||
// really is a Panda Display.
|
||||
if ((0 == strncmp((char *)prod, devname, USB_CFG_DEVICE_NAME_LEN)) &&
|
||||
(desc.idVendor == vid) &&
|
||||
(desc.idProduct == pid)) {
|
||||
return handle;
|
||||
}
|
||||
libusb_close(handle);
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (openable)
|
||||
fprintf (stderr, "Found USB device matching 16c0:05df, but it isn't a Panda Display\n");
|
||||
else
|
||||
fprintf (stderr, "Found something that might be a Panda Display, but couldn't open it.\n");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int lites_init_usb (void)
|
||||
{
|
||||
libusb_device **devs;
|
||||
libusb_context *ctx = NULL;
|
||||
ssize_t cnt;
|
||||
int r, i, pos;
|
||||
|
||||
if (lights_handle != NULL)
|
||||
return 1;
|
||||
|
||||
r = libusb_init(&ctx);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
cnt = libusb_get_device_list(ctx, &devs);
|
||||
if (cnt < 0)
|
||||
return 0;
|
||||
|
||||
lights_handle = get_panda_handle(devs);
|
||||
if (lights_handle == NULL)
|
||||
return 0;
|
||||
|
||||
if (libusb_kernel_driver_active(lights_handle, 0) == 1)
|
||||
libusb_detach_kernel_driver(lights_handle, 0);
|
||||
|
||||
r = libusb_claim_interface(lights_handle, 0);
|
||||
if(r < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* One-time initialization
|
||||
* Accepts: port base register
|
||||
* Returns: T if success, NIL if failure
|
||||
@ -182,6 +287,9 @@ int lites_init (unsigned int prt)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
if (prt == 0)
|
||||
return lites_init_usb ();
|
||||
/* enable access to the port */
|
||||
if (ret = !ioperm (prt,PORT_MAX,ENABLE)) {
|
||||
port = prt; /* access granted, note port */
|
||||
@ -277,6 +385,34 @@ static void lites_wreg (unsigned char reg,unsigned char data)
|
||||
outb (control[reg],port + PORT_CONTROL);
|
||||
}
|
||||
}
|
||||
|
||||
static void lights_latch (void)
|
||||
{
|
||||
unsigned char buffer[8];
|
||||
|
||||
if (lights_handle == NULL)
|
||||
return;
|
||||
|
||||
buffer[0] = (lights_left >> 14) & 0037;
|
||||
buffer[1] = (lights_left >> 6) & 0377;
|
||||
buffer[2] = (lights_left << 2) & 0374;
|
||||
buffer[2] |= (lights_right >> 16) & 0003;
|
||||
buffer[3] = (lights_right >> 8) & 0377;
|
||||
buffer[4] = lights_right & 0377;
|
||||
|
||||
buffer[5] = (lights_aux << 4) & 0340;
|
||||
buffer[6] = 0;
|
||||
buffer[7] = 0;
|
||||
|
||||
libusb_control_transfer(lights_handle,
|
||||
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
|
||||
LIBUSB_REQUEST_SET_CONFIGURATION,
|
||||
0x0000,
|
||||
0,
|
||||
buffer,
|
||||
sizeof buffer,
|
||||
5000);
|
||||
}
|
||||
|
||||
/* Routines specific to the primary display lights */
|
||||
|
||||
@ -291,6 +427,14 @@ static unsigned char byte0 = 0; /* save of aux bits and high 4 pgm lites */
|
||||
void lights_pgmlites (unsigned long lh,unsigned long rh)
|
||||
{
|
||||
unsigned char data[5];
|
||||
|
||||
if (lights_handle) {
|
||||
lights_left = lh;
|
||||
lights_right = rh;
|
||||
lights_latch ();
|
||||
return;
|
||||
}
|
||||
|
||||
lites_setdisplay (UNIT_PGM); /* select program display lights unit */
|
||||
/* calculate MSB with aux bits */
|
||||
byte0 = data[0] = ((lh >> 14) & 0xf) | (byte0 & 0xe0);
|
||||
|
||||
@ -247,7 +247,7 @@ CMDDEF(cd_devwait,fc_devwait, CMRF_TLIN,
|
||||
"[<devid>] [<secs>]",
|
||||
"Wait for device (or all devs)", "")
|
||||
#if KLH10_DEV_LITES
|
||||
CMDDEF(cd_lights, fc_lights, CMRF_TLIN, "<hexaddr>",
|
||||
CMDDEF(cd_lights, fc_lights, CMRF_TLIN, "<hexaddr>|usb",
|
||||
"Set console lights I/O base address", "")
|
||||
#endif
|
||||
|
||||
@ -2745,6 +2745,12 @@ fc_lights(struct cmd_s *cm)
|
||||
char *sloc = cm->cmd_arglin;
|
||||
|
||||
if (sloc && *sloc) {
|
||||
if (strcasecmp(sloc, "usb") == 0) {
|
||||
if (!lites_init(0))
|
||||
printf("?Can't init lights -- probably not root\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while(isxdigit(c = *sloc++)) {
|
||||
port *= 16;
|
||||
port += c - (isdigit(c) ? '0' : (islower(c) ? 'a' : 'A'));
|
||||
|
||||
@ -626,7 +626,7 @@ iodef(IOINOP(0700, 07), NULL, IO_SO_APR, io_so_apr, IF_IO) /* SO APR, */
|
||||
iodef(IOINOP(0700, 012),"SBDIAG",IO_SBDIAG,io_sbdiag,IF_IO) /* BO PI, */
|
||||
#endif
|
||||
/* DATAO PI, - (KA/KI: Disp data on console lites) */
|
||||
iodef(IOINOP(0700, 013), NULL, IO_DO_PI, io_do_pi, IF_IO) /* DO PI, */
|
||||
iodef(IOINOP(0700, 013), "WRLI", IO_DO_PI, io_do_pi, IF_IO) /* DO PI, */
|
||||
iodef(IOINOP(0700, 014), "WRPI", IO_WRPI, io_wrpi, IF_IO) /* CO PI, */
|
||||
iodef(IOINOP(0700, 015), "RDPI", IO_RDPI, io_rdpi, IF_IO) /* CI PI, */
|
||||
iodef(IOINOP(0700, 016), NULL, IO_SZ_PI, io_sz_pi, IF_IO) /* SZ PI, */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user