/* rtty med HAMCOMM-interfacet */


#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
#include <mem.h>
#include <math.h>

extern void cmpt_init(void);
extern void cmpt_exit(void);
extern unsigned tone_freq;
unsigned old_tonefreq;
extern unsigned int timerticks;
unsigned char letter;
unsigned char c;
int smp_cntr;

#define LTRS 0x1f
#define FGRS 0x1b
#define LTRS_OFF 0
#define FGRS_OFF 32
int tab_offs = LTRS_OFF;

unsigned char b2a_tab[] =
{

 0, 'T',  13, 'O', ' ', 'H', 'N', 'M',  10, 'L', 'R', 'G', 'I', 'P', 'C',
'V', 'E', 'Z', 'D', 'B', 'S', 'Y', 'F', 'X', 'A', 'W', 'J', '*', 'U', 'Q',
'K', '*',

 0, '5',  13, '9', ' ',   0, ',', '.',  10, ')', '4',   0, '8', '0', ':',
'=', '3', '+',   0, '?',   0, '6',   0, '/', '-', '2',   7, '*', '7', '1',
'(', '*'

};

char scrbuf[4000];


unsigned fc,markfreq,spacefreq,shift;
float baud;
unsigned wait_tm;
int x_sav,y_sav;
unsigned freq_cntr,noise_cntr;

int rev;
char *nrmrevstr[2] = {"NORMAL","REVERSE"};
unsigned maxval;

main()
{
int i;

       cmpt_init();
       clrscr();

       fc=2200;
       baud=45.45;
       shift=170;
       rev=0;
       set_freqs(1);

       tone_freq=0;

       while(1) {
               maxval=(shift/2)-5;
               freq_cntr = 0;

               while(1) {
                       if((tone_freq >= spacefreq-maxval) && (tone_freq <= spacefreq+maxval))
                               freq_cntr++;
                       else
                               freq_cntr=0;

                       if(freq_cntr==30) break;

                       if(kbhit())
                               if(process_key())
                                       break;
                               else
                                       goto rdy;
               }

               wait_tm=(unsigned)(1193180l/baud);
               wait(wait_tm+(wait_tm/2));
               do_letter();

               if(kbhit())
                       if(! process_key()) break;
       }
rdy:
       cmpt_exit();
}

process_key()
{
int c;

       c = getch();
       if(c==0) {
               c=getch();
               switch(c){
                       case 0x30:      set_baud();       /* Alt-B */
                                               break;
                       case 0x1f:  set_shift();      /* Alt-S */
                                               break;
                       case 0x2e:  set_fc();         /* Alt-C */
                                               break;
                       case 0x13:  rev ^= 1;         /* Alt-R */
                                               set_freqs(1);
                                               break;
                       case 0x14:  tune();           /* Alt-T */
                                               break;
                       case 0x2d:  return 0;         /* Alt-X */
               }
       }
       return 1;
}


set_baud()
{
char baudstr[20];

       printf("\nEnter baud rate: ");
       gets(baudstr);
       baud = atof(baudstr);
}

set_shift()
{
char shiftstr[20];

       printf("\nEnter shift: ");
       gets(shiftstr);
       shift = atoi(shiftstr);
       set_freqs(0);
}

set_fc()
{
char fcstr[20];

       printf("\nEnter Center frequency: ");
       gets(fcstr);
       fc = atoi(fcstr);
       set_freqs(0);
}


tune()
{
int center_x,tone_x;

       HideCur();
       cursave();
       save_scr();
       clrscr();

       center_x=fc/50;

       gotoxy(1+center_x,1);
       putch('*');

       while(1) {
               if(tone_x != center_x) {
                       gotoxy(1+tone_x,1);
                       putch(' ');
               }
               tone_x=tone_freq/50;
               gotoxy(1+tone_x,1);
               putch('|');
               if(tone_x == center_x){
                       gotoxy(1+center_x,1);
                       putch('*');
               }

               if(kbhit()){
                       getch();
                       break;
               }
       }
       rest_scr();
       currest();
       ShowCur(6,7);
}


do_letter()
{
int i,err;
unsigned t;

       letter = 0x00;
       err=0;

       for(i=0;i<5;i++){
               letter <<= 1;
               if((tone_freq >= markfreq-maxval) && (tone_freq <= markfreq+maxval))
                       letter |= 0x01;
               else if((tone_freq >= spacefreq-maxval) && (tone_freq <= spacefreq+maxval))
                       letter |= 0x00;
               else err=1;
               wait(wait_tm);
       }

       if(! err){
               switch(letter) {
                       case LTRS:      tab_offs = LTRS_OFF;
                                               break;
                       case FGRS:      tab_offs = FGRS_OFF;
                                               break;
                       default:    c = b2a_tab[tab_offs+letter];
                                               putchar(c);
               }
       }
}

set_freqs(int with_text)
{
       switch(rev){
               case 0: markfreq = fc+shift/2;
                               spacefreq = fc-shift/2;
                               break;
               case 1: markfreq = fc-shift/2;
                               spacefreq = fc+shift/2;
       }
       if(with_text)
               printf("\nNrm/Rev: %s\n",nrmrevstr[rev]);
}

wait(unsigned t)
{
unsigned latch1,latch2;

       asm{
               push ax
               push dx
               mov al,00h
               out 43h,al
               in al,40h
               mov dl,al
               in al,40h
               mov dh,al
               mov latch1,dx
               pop dx
               pop ax
       }

       while(1) {
               asm{
                       push ax
                       push dx
                       mov al,00h
                       out 43h,al                /* latch current counter value */
                       in al,40h
                       mov dl,al
                       in al,40h
                       mov dh,al
                       mov latch2,dx
                       pop dx
                       pop ax
               }
               if(latch1-latch2 >= t)
                       break;
       }
}

HideCur()
{
        asm{
               push ax
               push cx

               mov ah,01h
               mov ch,00100110b
               mov cl,00000111b
               int 10H

               pop cx
               pop ax
        }
}

ShowCur(char start, char end)
{
        asm{
               push ax
               push cx

               mov ah,01H
               mov ch,start
               mov cl,end
               int 10H

               pop cx
               pop ax
        }
}

cursave()
{
       x_sav = wherex();
       y_sav = wherey();
}

currest()
{
       gotoxy(x_sav,y_sav);
}

save_scr() {
char far* p;
       p = MK_FP(0xb800,0x0000);
       _fmemcpy((char far*)scrbuf,p,4000);
}
rest_scr()
{
char far* p;

       p = MK_FP(0xb800,0x0000);
       _fmemcpy(p,(char far*)scrbuf,4000);
}