home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / apps / educatin / morse / morse.c next >
C/C++ Source or Header  |  1985-11-17  |  8KB  |  314 lines

  1. /* The guts of a morse code tutorial/training/transmission system.
  2.    Set length variables to control speed and spacing.
  3.    Written for Lattice C.  Note short is 16 bits, int == long is 32 bits. */
  4. #include <osbind.h>
  5.  
  6. /* Constants for Giaccess */
  7. #define TRUE        1
  8. #define FALSE        0
  9. #define NO_ADDR        0x0L
  10. #define GI_WRITE    0x80
  11. #define GI_READ        0
  12. #define CHANA_LO    0
  13. #define CHANA_HI    1
  14. #define CHAN_ENABLE    7
  15. #define CHANA_VOLUME    8
  16. #define PORT_MASK    0xC0    /* Don't disturb i/o port bits */
  17. #define GI_STATE    0x3E    /* Tone ch A on; others off */
  18. #define OFF        0
  19.  
  20. /* Event flags, etc */
  21. short    ev_mwhich = 0,
  22.     ev_mflags = MU_KEYBD | MU_BUTTON | MU_TIMER,
  23.     ev_mbclicks = 2,
  24.     ev_mbmask = 2,
  25.     ev_mbstate = 2,
  26.     ev_mm1flags = 0,
  27.     ev_mm1x = 0,
  28.     ev_mm1y = 0,
  29.     ev_mm1width = 0,
  30.     ev_mm1height = 0,
  31.     ev_mm2flags = 0,
  32.     ev_mm2x = 0,
  33.     ev_mm2y = 0,
  34.     ev_mm2width = 0,
  35.     ev_mm2height = 0,
  36.     ev_mmox,
  37.     ev_mmoy,
  38.     ev_mmobutton,
  39.     ev_mmokstate,
  40.     ev_mkreturn,
  41.     ev_mbreturn;
  42. char    ev_mmgpbuff[16];
  43. /* Sound parameters */
  44. unsigned char    a_volume = 15,
  45.         a_hi_note = 1,
  46.         a_lo_note = 0;
  47.  
  48. /* Initial values are for 5 WPM */
  49. short    l_dot = 240,    /* 1200/WPM */
  50.     l_dash = 720,    /* 3*l_dot */
  51.     l_el = 240,    /* Interelement spacing == l_dot */
  52.     l_char = 480,    /* Char spacing, normally 2*l_el */
  53.     l_word = 960;    /* Word spacing, 4*l_dot */
  54. /* Note that the routine actually sends l_el after each element,
  55.    l_char after each character, and l_word for a space, so the
  56.    character space is l_el+l_char == 3*l_el, and word space is
  57.    l_el+l_char+l_word == 7*l_el, agreeing with the standards */
  58.  
  59. /* Coding table: '.' = send dit; '_' = send dah; ' ' = word space;
  60.    anything else (ie, '\0') terminates sequence. */
  61. #define NO_CODE    "\0"
  62. char *codes[128] =
  63. {
  64.     NO_CODE,    /* 00 */
  65.     NO_CODE,    /* 01 */
  66.     NO_CODE,    /* 02 */
  67.     NO_CODE,    /* 03 */
  68.     NO_CODE,    /* 04 */
  69.     NO_CODE,    /* 05 */
  70.     NO_CODE,    /* 06 */
  71.     NO_CODE,    /* 07 */
  72.     NO_CODE,    /* 08 */
  73.     " ",        /* 09 TAB */
  74.     " ",        /* 0A \N */
  75.     NO_CODE,    /* 0B */
  76.     NO_CODE,    /* 0C */
  77.     NO_CODE,    /* 0D */
  78.     NO_CODE,    /* 0E */
  79.     NO_CODE,    /* 0F */
  80.     NO_CODE,    /* 10 */
  81.     NO_CODE,    /* 11 */
  82.     NO_CODE,    /* 12 */
  83.     NO_CODE,    /* 13 */
  84.     NO_CODE,    /* 14 */
  85.     NO_CODE,    /* 15 */
  86.     NO_CODE,    /* 16 */
  87.     NO_CODE,    /* 17 */
  88.     NO_CODE,    /* 18 */
  89.     NO_CODE,    /* 19 */
  90.     NO_CODE,    /* 1A */
  91.     NO_CODE,    /* 1B */
  92.     NO_CODE,    /* 1C */
  93.     NO_CODE,    /* 1D */
  94.     NO_CODE,    /* 1E */
  95.     NO_CODE,    /* 1F */
  96.     " ",        /* 20 SPACE */
  97.     "..._.",    /* 21 ! Understood */
  98.     "._.._.",    /* 22 " */
  99.     "._._..",    /* 23 # Paragraph */
  100.     "..._.._",    /* 24 $ Dollar sign */
  101.     "_._._",    /* 25 % Start/Attention */
  102.     "._...",    /* 26 & Wait */
  103.     ".____.",    /* 27 ' */
  104.     "_.__.",    /* 28 ( */
  105.     "_.__._",    /* 29 ) */
  106.     "..._._",    /* 2A * End of Work */
  107.     "._._.",    /* 2B + End of Message */
  108.     "__..__",    /* 2C , */
  109.     "_..._",    /* 2D - */
  110.     "._._._",    /* 2E . */
  111.     "_.._.",    /* 2F / */
  112.     "_____",    /* 30 0 */
  113.     ".____",    /* 31 1 */
  114.     "..___",    /* 32 2 */
  115.     "...__",    /* 33 3 */
  116.     "...._",    /* 34 4 */
  117.     ".....",    /* 35 5 */
  118.     "_....",    /* 36 6 */
  119.     "__...",    /* 37 7 */
  120.     "___..",    /* 38 8 */
  121.     "____.",    /* 39 9 */
  122.     "___...",    /* 3A : */
  123.     "_._._.",    /* 3B ; */
  124.     NO_CODE,    /* 3C < */
  125.     "_..._",    /* 3D = Double dash */
  126.     "._._",        /* 3E > Newline */
  127.     "..__..",    /* 3F ? */
  128.     NO_CODE,    /* 40 @ */
  129.     "._",        /* 41 A */
  130.     "_...",        /* 42 B */
  131.     "_._.",        /* 43 C */
  132.     "_..",        /* 44 D */
  133.     ".",        /* 45 E */
  134.     ".._.",        /* 46 F */
  135.     "__.",        /* 47 G */
  136.     "....",        /* 48 H */
  137.     "..",        /* 49 I */
  138.     ".___",        /* 4A J */
  139.     "_._",        /* 4B K */
  140.     "._..",        /* 4C L */
  141.     "__",        /* 4D M */
  142.     "_.",        /* 4E N */
  143.     "___",        /* 4F O */
  144.     ".__.",        /* 50 P */
  145.     "__._",        /* 51 Q */
  146.     "._.",        /* 52 R */
  147.     "...",        /* 53 S */
  148.     "_",        /* 54 T */
  149.     ".._",        /* 55 U */
  150.     "..._",        /* 56 V */
  151.     ".__",        /* 57 W */
  152.     "_.._",        /* 58 X */
  153.     "_.__",        /* 59 Y */
  154.     "__..",        /* 5A Z */
  155.     NO_CODE,    /* 5B [ (start prosign, see below) */
  156.     "........",    /* 5C \\ Error */
  157.     NO_CODE,    /* 5D ] (end prosign, see below) */
  158.     NO_CODE,    /* 5E ^ */
  159.     "..__._",    /* 5F _ */
  160.     NO_CODE,    /* 60 ` */
  161.     "._",        /* 61 a */
  162.     "_...",        /* 62 b */
  163.     "_._.",        /* 63 c */
  164.     "_..",        /* 64 d */
  165.     ".",        /* 65 e */
  166.     ".._.",        /* 66 f */
  167.     "__.",        /* 67 g */
  168.     "....",        /* 68 h */
  169.     "..",        /* 69 i */
  170.     ".___",        /* 6A j */
  171.     "_._",        /* 6B k */
  172.     "._..",        /* 6C l */
  173.     "__",        /* 6D m */
  174.     "_.",        /* 6E n */
  175.     "___",        /* 6F o */
  176.     ".__.",        /* 70 p */
  177.     "__._",        /* 71 q */
  178.     "._.",        /* 72 r */
  179.     "...",        /* 73 s */
  180.     "_",        /* 74 t */
  181.     ".._",        /* 75 u */
  182.     "..._",        /* 76 v */
  183.     ".__",        /* 77 w */
  184.     "_.._",        /* 78 x */
  185.     "_.__",        /* 79 y */
  186.     "__..",        /* 7A z */
  187.     NO_CODE,    /* 7B { */
  188.     NO_CODE,    /* 7C | */
  189.     NO_CODE,    /* 7D } */
  190.     NO_CODE,    /* 7E ~ */
  191.     NO_CODE        /* 7F */
  192. };
  193.  
  194. /* send_morse: sends each character in the supplied string subject to the
  195.    above translation table.  Exception: '[' sets l_char :== 0 and ']'
  196.    returns l_char to its original value.  Thus prosigns can be composed
  197.    (eg, [SK], [KN]) rather than using the equivalent punctuation given
  198.    above.  It is the sender's responsibility to see that the results are
  199.    meaningful; send_morse will happily cram together anything, including
  200.    [absolute garbage].
  201.    Note that end of string simulates ']' so prosigns cannot be broken into
  202.    separate calls to send_morse.
  203.    Also note that for multiple calls, str should start or end with a space
  204.    character (' ', '\t', '\n') because the first character of a new str
  205.    will be sent immediately, and only inter-character space is given
  206.    following the last character of str */
  207. short send_morse( str )
  208. char *str;
  209. {
  210.     short ll_char, i, len, j, els, m_send(), m_pause();
  211.     char ch, elem, *seq;
  212.     unsigned char port_state=GI_STATE, new_state;
  213.  
  214.     /* Set sound chip */
  215.     port_state = (unsigned char) Giaccess( port_state, 
  216.       CHAN_ENABLE|GI_READ );
  217.     new_state = (port_state & PORT_MASK) | GI_STATE;
  218.     Giaccess( new_state, CHAN_ENABLE|GI_WRITE );
  219.  
  220.     Giaccess( OFF, CHANA_VOLUME|GI_WRITE );
  221.     Giaccess( a_hi_note, CHANA_HI|GI_WRITE );
  222.     Giaccess( a_lo_note, CHANA_LO|GI_WRITE );
  223.  
  224.     ev_mkreturn = 0;
  225.     ll_char = l_char;    /* Actual inter-character space */
  226.     len = strlen( str );
  227.     for( i=0; i<len; i++ )
  228.         if( ev_mkreturn != 0 ) break;
  229.         else if( (ch = str[i]) == '[' )
  230.             l_char = 0;
  231.         else if( ch == ']' )
  232.         {
  233.             l_char = ll_char;
  234.             m_pause( l_char );
  235.         }
  236.         else
  237.         {
  238.             els = strlen( seq = codes[ch] );
  239.             for( j=0; j<els; j++ )
  240.                 if( (elem = seq[j]) == ' ' )
  241.                     if( j == 0 ) m_pause( l_el+l_char+l_word );
  242.                     else m_pause( l_word );
  243.                 else if( elem == '.' )
  244.                 {
  245.                     m_send( l_dot );
  246.                     m_pause( l_el );
  247.                 }
  248.                 else if( elem == '_' )
  249.                 {
  250.                     m_send( l_dash );
  251.                     m_pause( l_el );
  252.                 }
  253.             if( elem != ' ' ) m_pause( l_char );
  254.         }
  255.     l_char = ll_char;
  256.     Giaccess( OFF, CHANA_VOLUME|GI_WRITE );
  257.     Giaccess( port_state, CHAN_ENABLE|GI_WRITE );
  258.     return( i );
  259. }    /* send_morse */
  260.  
  261. short m_pause( len )    /* pause len milliseconds */
  262. short len;
  263. {
  264.     short m_wait();
  265.  
  266.     Giaccess( OFF, CHANA_VOLUME|GI_WRITE );
  267.  
  268.     return( m_wait( len ) );
  269. }    /* m_pause */
  270.  
  271. short m_send( len )    /* send tone for len milliseconds */
  272. short len;
  273. {
  274.     short m_wait();
  275.  
  276.     Giaccess( a_volume, CHANA_VOLUME|GI_WRITE );
  277.     Giaccess( a_hi_note, CHANA_HI|GI_WRITE );
  278.     Giaccess( a_lo_note, CHANA_LO|GI_WRITE );
  279.  
  280.     return( m_wait( len ) );
  281. }    /* m_send */
  282.  
  283. short m_wait( len )    /* wait around for len milliseconds */
  284. short len;
  285. {
  286.     short item, done = FALSE, i, mmox, mmoy, mmobutton, mmokstate,
  287.       mkreturn, mbreturn;
  288.     char mmgpbuff[16];
  289.  
  290.     if( len == 0 ) return( 0 );
  291.     while( !done )
  292.     {
  293.         item = evnt_multi( ev_mflags, ev_mbclicks, ev_mbmask,
  294.           ev_mbstate, ev_mm1flags, ev_mm1x, ev_mm1y, ev_mm1width,
  295.           ev_mm1height, ev_mm2flags, ev_mm2x, ev_mm2y, ev_mm2width,
  296.           ev_mm2height, mmgpbuff, len, 0, &mmox, &mmoy, &mmobutton,
  297.           &mmokstate, &mkreturn, &mbreturn );
  298.         if( item & MU_TIMER ) done = TRUE;
  299.         if( item != MU_TIMER )
  300.         {
  301.             ev_mwhich = item;
  302.             for( i=0; i<16; i++ )
  303.                 ev_mmgpbuff[i] = mmgpbuff[i];
  304.             ev_mmox = mmox;
  305.             ev_mmoy = mmoy;
  306.             ev_mmobutton = mmobutton;
  307.             ev_mmokstate = mmokstate;
  308.             ev_mkreturn = mkreturn;
  309.             ev_mbreturn = mbreturn;
  310.         }
  311.     }
  312.     return( ev_mwhich );
  313. }    /* m_wait */
  314.