home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / source / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-31  |  5.9 KB  |  243 lines

  1. /*  IO.C -- DSP CARD 3 low-level interface routines
  2.  *
  3.  *  Copyright (C) by Alef Null 1990, 1991
  4.  *  Author(s): Jarkko Vuori, OH2LNS
  5.  *  Modification(s):
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <dos.h>
  10. #include <conio.h>
  11. #include <stdlib.h>
  12. #include "dspio.h"
  13.  
  14. /* i/o-port definitions */
  15. #define PIC_MASK  0x21    // 8259 mask register
  16. #define PIC_EOI   0x20    // 8259 EOI command
  17. static const struct {
  18.     int data,        // Centronics data register
  19.     control,    //          control register
  20.     status;     //          status register
  21.     int intno;        // interrupt number
  22.     int mask;        // PIC mask
  23. } *parallelport, parallelports[] = {
  24.     /* LPT1 on display controller */
  25.     0x3bc, 0x3be, 0x3bd,
  26.     0x0f,
  27.     0x80,
  28.  
  29.     /* LPT1 */
  30.     0x378, 0x37a, 0x379,
  31.     0x0f,
  32.     0x80,
  33.  
  34.     /* LPT2 */
  35.     0x278, 0x27a, 0x279,
  36.     0x0f,
  37.     0x80,
  38. };
  39.  
  40. /* control port bits */
  41. #define STROBEBIT 0x01
  42. #define INITBIT   0x04
  43. #define SELECTBIT 0x08
  44. #define IRQBIT      0x10
  45. #define DIRBIT      0x20
  46.  
  47. /* status port bits */
  48. #define ACKBIT      0x40
  49. #define BUSYBIT   0x80
  50.  
  51. /* DSP CARD 3 latch bits */
  52. #define ADRMASK   0x07
  53. #define RWBIT      0x08
  54. #define TSTBIT      0x10
  55. #define SELBIT      0x20
  56.  
  57. /* Parallel port control byte handling */
  58. #define SYNCBITS(p)    outp((p)->control, CommandData)
  59. #define RESETBIT(p, x) outp((p)->control, CommandData |= (x))
  60. #define SETBIT(p, x)   outp((p)->control, CommandData &= ~(x))
  61. #define TOGGLEBIT(p,x) (ShortDelay(0), RESETBIT(p, x), ShortDelay(0), SETBIT(p, x))
  62.  
  63. /* Parallel port status byte handling */
  64. #define GETBIT(p, x)   (~inp((p)->status) & (x))
  65.  
  66. #pragma intrinsic(inp, outp)            // produces more beautiful code with this
  67.  
  68. static int CommandData = INITBIT | IRQBIT,  // parallel port command register value store
  69.        LatchData   = 0x00;            // DSP CARD 3 latch value store
  70.  
  71.  
  72. /* programmable delay (n*54.9mS - (n+1)*54.9mS) */
  73. static unsigned BiosDelay(unsigned n) {
  74.     unsigned      i = 0;
  75.     unsigned long start;
  76.  
  77.     #define BIOS_TIMER (unsigned long far *)(0x46c)
  78.  
  79.     /* wait until timer changes its state */
  80.     start = *BIOS_TIMER; while (start == *BIOS_TIMER);
  81.  
  82.     /* the wait specified time and count how many steps can be performed at the same time */
  83.     start = *BIOS_TIMER;
  84.     while (start+(unsigned long)n != *BIOS_TIMER)
  85.     i++;
  86.  
  87.     return (i);
  88. }
  89.  
  90.  
  91. /* a very short delay */
  92. static void ShortDelay(int mode) {
  93.     static unsigned delay_constant;
  94.     unsigned        i;
  95.  
  96.     if (mode)
  97.     /* determine delay constant */
  98.     delay_constant = 2*max(3000, BiosDelay(1))/3000;
  99.     else
  100.     /* delay loop */
  101.     for (i = 0; i < delay_constant; i++);
  102. }
  103.  
  104.  
  105. /* set DSP CARD 3 latch bits */
  106. static void SetCardLatch(int data) {
  107.     outp(parallelport->data, LatchData |= data);
  108.     TOGGLEBIT(parallelport, SELECTBIT);
  109. }
  110.  
  111.  
  112. /* reset DSP CARD 3 latch bits */
  113. static void ResetCardLatch(int data) {
  114.     outp(parallelport->data, LatchData &= ~data);
  115.     TOGGLEBIT(parallelport, SELECTBIT);
  116. }
  117.  
  118.  
  119. /* set DSP CARD 3 latch address bits and set direction for reading */
  120. static void SetHostAddressForReading(int address) {
  121.     outp(parallelport->data, LatchData = (LatchData & ~ADRMASK) | address | RWBIT);
  122.     TOGGLEBIT(parallelport, SELECTBIT);
  123. }
  124.  
  125.  
  126. /* set DSP CARD 3 latch address bits and set direction for writing */
  127. static void SetHostAddressForWriting(int address) {
  128.     outp(parallelport->data, LatchData = (LatchData & ~ADRMASK) | address & ~RWBIT);
  129.     TOGGLEBIT(parallelport, SELECTBIT);
  130. }
  131.  
  132.  
  133. /* check that there is i/o port and DSP CARD 3 connected to it */
  134. static int Ontology(int *fAdapter) {
  135.     #define CHK(p,d) (outp(p, d), inp(p) == (d))
  136.  
  137.     /* check that parallel port adapter is present */
  138.     SYNCBITS(parallelport);
  139.     if (CHK(parallelport->data, 0x55) && CHK(parallelport->data, 0xaa)) {
  140.     *fAdapter = -1;
  141.     /* check that DSP CARD 3 is present */
  142.     if ((SetCardLatch(TSTBIT),   GETBIT(parallelport, BUSYBIT)) &&
  143.        !(ResetCardLatch(TSTBIT), GETBIT(parallelport, BUSYBIT)))
  144.         return(0);
  145.     }
  146.  
  147.     return (-1);
  148. }
  149.  
  150.  
  151. /*
  152.  * Initializes communication
  153.  *
  154.  * When sel is nonzero, do not search the port
  155.  *
  156.  * returns:
  157.  *  nonzero if failed
  158.  */
  159. int OpenCardIo(int sel) {
  160.     #define SIZE(p)  (sizeof(p)/sizeof((p)[0]))
  161.     int fAdapter = 0;
  162.  
  163.     ShortDelay(-1);
  164.  
  165.     if (sel)
  166.     if ((parallelport = ¶llelports[sel]) < ¶llelports[SIZE(parallelports)]) {
  167.         if (!Ontology(&fAdapter))
  168.         return (0);
  169.     } else {
  170.         fprintf(stderr, "io error: No such port defined\n");
  171.         return (-1);
  172.     }
  173.     else
  174.     /* search for parallelport */
  175.     for (parallelport = parallelports; parallelport < ¶llelports[SIZE(parallelports)]; parallelport++)
  176.         if (!Ontology(&fAdapter))
  177.         return (0);
  178.  
  179.     if (fAdapter)
  180.     fprintf(stderr, "io error: No DSP CARD detected\n");
  181.     else
  182.     fprintf(stderr, "io error: No LPT1 or LPT2 port\n");
  183.  
  184.     return (-1);
  185. }
  186.  
  187.  
  188. /*
  189.  * Reset DSP CARD
  190.  */
  191. void ResetCard(void) {
  192.     SETBIT(parallelport, INITBIT);
  193.     BiosDelay(3);
  194.     RESETBIT(parallelport, INITBIT);
  195. }
  196.  
  197.  
  198. /*
  199.  * Select SSI source
  200.  *
  201.  *  when source is nonzero, onboard converter chip is selected
  202.  *  otherwise external interface is selected
  203.  */
  204. void SelectSSI(int source) {
  205.     if (source)
  206.     SetCardLatch(SELBIT);
  207.     else
  208.     ResetCardLatch(SELBIT);
  209. }
  210.  
  211.  
  212. /*
  213.  * Writes one byte to the specified Host register
  214.  */
  215. int WriteByte(int address, int byte) {
  216.     SetHostAddressForWriting(address & ADRMASK);
  217.     outp(parallelport->data, byte);
  218.     TOGGLEBIT(parallelport, STROBEBIT);
  219.     return (byte);
  220. }
  221.  
  222.  
  223. /*
  224.  * Reads one byte from the specified Host register
  225.  */
  226. int ReadByte(int address) {
  227.     int t;
  228.  
  229.     SetHostAddressForReading(address & ADRMASK);
  230.     RESETBIT(parallelport, DIRBIT); ShortDelay(0); RESETBIT(parallelport, STROBEBIT); ShortDelay(0);
  231.     t = inp(parallelport->data);
  232.     SETBIT(parallelport, STROBEBIT); SETBIT(parallelport, DIRBIT);
  233.  
  234.     return (t);
  235. }
  236.  
  237.  
  238. /*
  239.  * Terminates Card IO
  240.  */
  241. void CloseCardIo(void) {
  242. }
  243.