home *** CD-ROM | disk | FTP | other *** search
- /* IO.C -- DSP CARD 3 low-level interface routines
- *
- * Copyright (C) by Alef Null 1990, 1991
- * Author(s): Jarkko Vuori, OH2LNS
- * Modification(s):
- */
-
- #include <stdio.h>
- #include <dos.h>
- #include <conio.h>
- #include <stdlib.h>
- #include "dspio.h"
-
- /* i/o-port definitions */
- #define PIC_MASK 0x21 // 8259 mask register
- #define PIC_EOI 0x20 // 8259 EOI command
- static const struct {
- int data, // Centronics data register
- control, // control register
- status; // status register
- int intno; // interrupt number
- int mask; // PIC mask
- } *parallelport, parallelports[] = {
- /* LPT1 on display controller */
- 0x3bc, 0x3be, 0x3bd,
- 0x0f,
- 0x80,
-
- /* LPT1 */
- 0x378, 0x37a, 0x379,
- 0x0f,
- 0x80,
-
- /* LPT2 */
- 0x278, 0x27a, 0x279,
- 0x0f,
- 0x80,
- };
-
- /* control port bits */
- #define STROBEBIT 0x01
- #define INITBIT 0x04
- #define SELECTBIT 0x08
- #define IRQBIT 0x10
- #define DIRBIT 0x20
-
- /* status port bits */
- #define ACKBIT 0x40
- #define BUSYBIT 0x80
-
- /* DSP CARD 3 latch bits */
- #define ADRMASK 0x07
- #define RWBIT 0x08
- #define TSTBIT 0x10
- #define SELBIT 0x20
-
- /* Parallel port control byte handling */
- #define SYNCBITS(p) outp((p)->control, CommandData)
- #define RESETBIT(p, x) outp((p)->control, CommandData |= (x))
- #define SETBIT(p, x) outp((p)->control, CommandData &= ~(x))
- #define TOGGLEBIT(p,x) (ShortDelay(0), RESETBIT(p, x), ShortDelay(0), SETBIT(p, x))
-
- /* Parallel port status byte handling */
- #define GETBIT(p, x) (~inp((p)->status) & (x))
-
- #pragma intrinsic(inp, outp) // produces more beautiful code with this
-
- static int CommandData = INITBIT | IRQBIT, // parallel port command register value store
- LatchData = 0x00; // DSP CARD 3 latch value store
-
-
- /* programmable delay (n*54.9mS - (n+1)*54.9mS) */
- static unsigned BiosDelay(unsigned n) {
- unsigned i = 0;
- unsigned long start;
-
- #define BIOS_TIMER (unsigned long far *)(0x46c)
-
- /* wait until timer changes its state */
- start = *BIOS_TIMER; while (start == *BIOS_TIMER);
-
- /* the wait specified time and count how many steps can be performed at the same time */
- start = *BIOS_TIMER;
- while (start+(unsigned long)n != *BIOS_TIMER)
- i++;
-
- return (i);
- }
-
-
- /* a very short delay */
- static void ShortDelay(int mode) {
- static unsigned delay_constant;
- unsigned i;
-
- if (mode)
- /* determine delay constant */
- delay_constant = 2*max(3000, BiosDelay(1))/3000;
- else
- /* delay loop */
- for (i = 0; i < delay_constant; i++);
- }
-
-
- /* set DSP CARD 3 latch bits */
- static void SetCardLatch(int data) {
- outp(parallelport->data, LatchData |= data);
- TOGGLEBIT(parallelport, SELECTBIT);
- }
-
-
- /* reset DSP CARD 3 latch bits */
- static void ResetCardLatch(int data) {
- outp(parallelport->data, LatchData &= ~data);
- TOGGLEBIT(parallelport, SELECTBIT);
- }
-
-
- /* set DSP CARD 3 latch address bits and set direction for reading */
- static void SetHostAddressForReading(int address) {
- outp(parallelport->data, LatchData = (LatchData & ~ADRMASK) | address | RWBIT);
- TOGGLEBIT(parallelport, SELECTBIT);
- }
-
-
- /* set DSP CARD 3 latch address bits and set direction for writing */
- static void SetHostAddressForWriting(int address) {
- outp(parallelport->data, LatchData = (LatchData & ~ADRMASK) | address & ~RWBIT);
- TOGGLEBIT(parallelport, SELECTBIT);
- }
-
-
- /* check that there is i/o port and DSP CARD 3 connected to it */
- static int Ontology(int *fAdapter) {
- #define CHK(p,d) (outp(p, d), inp(p) == (d))
-
- /* check that parallel port adapter is present */
- SYNCBITS(parallelport);
- if (CHK(parallelport->data, 0x55) && CHK(parallelport->data, 0xaa)) {
- *fAdapter = -1;
- /* check that DSP CARD 3 is present */
- if ((SetCardLatch(TSTBIT), GETBIT(parallelport, BUSYBIT)) &&
- !(ResetCardLatch(TSTBIT), GETBIT(parallelport, BUSYBIT)))
- return(0);
- }
-
- return (-1);
- }
-
-
- /*
- * Initializes communication
- *
- * When sel is nonzero, do not search the port
- *
- * returns:
- * nonzero if failed
- */
- int OpenCardIo(int sel) {
- #define SIZE(p) (sizeof(p)/sizeof((p)[0]))
- int fAdapter = 0;
-
- ShortDelay(-1);
-
- if (sel)
- if ((parallelport = ¶llelports[sel]) < ¶llelports[SIZE(parallelports)]) {
- if (!Ontology(&fAdapter))
- return (0);
- } else {
- fprintf(stderr, "io error: No such port defined\n");
- return (-1);
- }
- else
- /* search for parallelport */
- for (parallelport = parallelports; parallelport < ¶llelports[SIZE(parallelports)]; parallelport++)
- if (!Ontology(&fAdapter))
- return (0);
-
- if (fAdapter)
- fprintf(stderr, "io error: No DSP CARD detected\n");
- else
- fprintf(stderr, "io error: No LPT1 or LPT2 port\n");
-
- return (-1);
- }
-
-
- /*
- * Reset DSP CARD
- */
- void ResetCard(void) {
- SETBIT(parallelport, INITBIT);
- BiosDelay(3);
- RESETBIT(parallelport, INITBIT);
- }
-
-
- /*
- * Select SSI source
- *
- * when source is nonzero, onboard converter chip is selected
- * otherwise external interface is selected
- */
- void SelectSSI(int source) {
- if (source)
- SetCardLatch(SELBIT);
- else
- ResetCardLatch(SELBIT);
- }
-
-
- /*
- * Writes one byte to the specified Host register
- */
- int WriteByte(int address, int byte) {
- SetHostAddressForWriting(address & ADRMASK);
- outp(parallelport->data, byte);
- TOGGLEBIT(parallelport, STROBEBIT);
- return (byte);
- }
-
-
- /*
- * Reads one byte from the specified Host register
- */
- int ReadByte(int address) {
- int t;
-
- SetHostAddressForReading(address & ADRMASK);
- RESETBIT(parallelport, DIRBIT); ShortDelay(0); RESETBIT(parallelport, STROBEBIT); ShortDelay(0);
- t = inp(parallelport->data);
- SETBIT(parallelport, STROBEBIT); SETBIT(parallelport, DIRBIT);
-
- return (t);
- }
-
-
- /*
- * Terminates Card IO
- */
- void CloseCardIo(void) {
- }
-