home *** CD-ROM | disk | FTP | other *** search
- /*
- pmptest.c
-
- A program to test the hardware (modem) setup for PMP
-
- August, 1989
- Andrew C. Payne
- */
-
- /* ----- Includes ----- */
- #include <stdio.h>
- #include <conio.h>
- #include <dos.h>
- #include <bios.h>
-
- #define EXTERN
- #include "types.h"
- #include "ports.h"
- #include "keys.h"
-
- int monochrome;
- #define VIDEO 0x10
- #define TRUE 1
- #define FALSE 0
-
- #define BITTIME 1988 /* 1200 baud bit time in ticks */
- #define CAPSIZE 2400 /* number of capture transitions */
-
- int TXState; /* current transmit (PTT) state */
- int TXLev;
-
- int prevRXCarrier; /* prev values to minimize screen updates */
- int prevRXLevel;
-
- int capbuf[CAPSIZE];
-
- /* ----- Low Level Screen Control ----- */
-
- /* v_setctype(start,end)
- Set the cursor size: start and end.
- */
- void cdecl v_setctype(int s,int e)
- {
- _AH = 1;
- _CH = s;
- _CL = e;
- geninterrupt(VIDEO);
- }
-
- /* curoff()
- Turns the cursor off.
- */
- void cdecl curoff(void)
- {
- v_setctype(0x0f,0x0f);
- }
-
- /* curon()
- Turns the cursor on.
- */
- void cdecl curon(void)
- {
- if(monochrome)
- v_setctype(12,13);
- else
- v_setctype(6,7);
- }
-
- /* putstring(x,y,len,attr,string)
- Given an absolute screen position, a buffered length, and a string,
- write string to screen. (FAST!!)
- */
- void putstring(int x, int y, int len, char attr, char *s)
- {
- char buf[80*2]; /* buffer for string */
- char *p;
- int i;
-
- /* fill buffer with screen data */
- p = buf;
- for(i=0; i<len; i++) {
- if(*s)
- *p++ = *s++;
- else
- *p++ = ' '; /* buffer with spaces */
-
- *p++ = attr; /* character attribute */
- }
-
- /* write string to screen */
- puttext(x,y,x+len-1,y,buf);
- }
-
- void TitleScreen()
- {
- clrscr();
- cprintf("┌─────────────────────────────────────────────────────────────────────────────┐\r\n");
- cprintf("│ PMP Test Version 0.7 Alignment and Test Program for Poor Man's Packet │\r\n");
- cprintf("│ Copyright (c) 1990 Andrew C. Payne All rights reserved. │\r\n");
- cprintf("└─────────────────────────────────────────────────────────────────────────────┘\r\n");
-
- cprintf(" Commands:\r\n");
- cprintf(" [ESC] to exit\r\n");
- cprintf(" [SPACE] to toggle transmit on and off\r\n");
- cprintf(" [F1] for on-air modem alignment mode\r\n");
- cprintf(" [F2] to toggle transmit data level\r\n");
- cprintf(" [F3] to select 600hz transmit modulation\r\n");
- cprintf(" [F4] for loopback alignment (not implemented)\r\n");
- gotoxy(1,22);
- cprintf(" Carrier Receive Transmit Push To\r\n");
- cprintf(" Detect Data Data Talk\r\n");
- }
-
- void InitParameters()
- {
- /* default I/O ports */
- PTTPort = TXPort = 0x378;
- TXBit = 1;
- PTTBit = 2;
-
- CDPort = RXPort = 0x379;
- RXBit = 8;
- CDBit = 0x80;
- CDLevel = 0;
- }
-
- /* ----- Low Level I/O ----- */
-
- /* RXCarrier()
- Returns TRUE if receive carrier detected.
- */
- int RXCarrier()
- {
- register byte x;
-
- x = inportb(CDPort) & CDBit;
- return CDLevel ? x : !x;
- }
-
- /* RXLevel()
- Returns the current level of the RX data line.
- */
- int RXLevel()
- {
- return (inportb(RXPort) & RXBit) == RXBit;
- }
-
- /* TXKey(state)
- Sets the transmitter state to the state given (TRUE = 1 = keyup).
- Updates screen status.
- */
- void TXKey(int state)
- {
- if(state) {
- outportb(PTTPort,inportb(PTTPort) | PTTBit);
- putstring(59,24,4,0x70," TX ");
- } else {
- outportb(PTTPort,inportb(PTTPort) & ~PTTBit);
- putstring(59,24,4,0," ");
- }
- }
-
- /* TXLevel(x)
- Sets the TX data level to the level specified.
- Updates screen status.
- */
- void TXLevel(int x)
- {
- if(x) {
- putstring(42,24,4,0x70," TD ");
- outportb(TXPort,inportb(TXPort) | TXBit);
- } else {
- outportb(TXPort,inportb(TXPort) & ~TXBit);
- putstring(42,24,4,0," ");
- }
- TXLev = x;
- }
-
- /* UpdateScreen()
- Update the screen status to reflect the current Carrier Detect
- level and the current receive level.
- */
- void UpdateScreen()
- {
- int t;
-
- /* show status of CD */
- if((t = RXCarrier()) != prevRXCarrier) {
- prevRXCarrier = t;
- if(prevRXCarrier)
- putstring(7,24,4,0x70," CD ");
- else
- putstring(7,24,4,0," ");
- }
-
- /* show receive level */
- if((t = RXLevel()) != prevRXLevel) {
- prevRXLevel = t;
- if(prevRXLevel)
- putstring(23,24,4,0x70," RD ");
- else
- putstring(23,24,4,0," ");
- }
- }
-
- /* SquareWave()
- Generate a 600hz square wave on the output until a key is pressed.
- */
- void SquareWave(void)
- {
- word from;
-
- /* show what is going on on the screen */
- gotoxy(1,13);
- cprintf("┌────────────────────────────── 600hz Transmit ───────────────────────────────┐\r\n");
- cprintf("│ │\r\n");
- cprintf("│ Transmitting 600hz square wave │\r\n");
- cprintf("│ │\r\n");
- cprintf("│ │\r\n");
- cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
-
- from = timer();
- while(!keypressed()) /* wait tell key interrupt */
- transit(from -= BITTIME);
-
- putstring(1,13,79,0,""); /* clear the lines */
- putstring(1,14,79,0,"");
- putstring(1,15,79,0,"");
- putstring(1,16,79,0,"");
- putstring(1,17,79,0,"");
- putstring(1,18,79,0,"");
- getkey(); /* gobble */
- }
-
- /* Alignment()
- Waits for carrier detect (or user keystroke), and captures a
- few transitions of data. Computes and displays alignment information
- from transition timing.
- */
- void Alignment(void)
- {
- int i;
- word t,t1,t2;
- int actual,delta;
- long deltahi,deltalo;
- int deltahict, deltaloct;
- char s[100];
-
- /* show what is going on on the screen */
- gotoxy(1,13);
- cprintf("┌────────────────────────────── Modem Alignment ──────────────────────────────┐\r\n");
- cprintf("│ Adjust modem for lowest numbers possible (see manual for more info) │\r\n");
- cprintf("│ │\r\n");
- cprintf("│ │\r\n");
- cprintf("│ │\r\n");
- cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
-
- loop:
- while(!RXCarrier() && !keypressed())
- ;
-
- if(keypressed()) {
- putstring(1,13,79,0,""); /* clear the lines */
- putstring(1,14,79,0,"");
- putstring(1,15,79,0,"");
- putstring(1,16,79,0,"");
- putstring(1,17,79,0,"");
- putstring(1,18,79,0,"");
- getkey(); /* gobble key */
- return;
- }
- UpdateScreen();
-
- /* start capture */
- deltahi = deltalo = deltahict = deltaloct = 0;
- disable();
- for(i=0; i<CAPSIZE; i++) {
- t2 = waittrans(t1-20000);
- t = t1 - t2;
- t1 = t2;
- actual = ((t + 994) / BITTIME) * BITTIME;
- delta = actual - t;
- if(RXLevel()) {
- deltahi += delta;
- deltahict++;
- } else {
- deltalo += delta;
- deltaloct++;
- }
- if(!RXCarrier())
- break;
- }
- enable();
- UpdateScreen();
- sprintf(s,"Low -> High error: %5ld%% High -> Low error: %5ld%%",
- (deltahi / deltahict) * (long)100 / BITTIME,
- (deltalo / deltaloct) * (long)100 / BITTIME);
- putstring(15,16,60,7,s);
- delay(1000);
-
- goto loop;
- }
-
- /* Loopback()
- Does a loopback alignemnt. Assumes that the transmit audio is
- looped back into the receive audio.
- */
- void Loopback()
- {
- word t,t1,d;
- int i,j,k;
- long deltalo, deltahi;
- char s[100];
-
- /* show what's going on */
- gotoxy(1,13);
- cprintf("┌──────────────────────────── Loopback Alignment ─────────────────────────────┐\r\n");
- cprintf("│ Adjust modem for lowest numbers possible (see manual for more info) │\r\n");
- cprintf("│ │\r\n");
- cprintf("│ │\r\n");
- cprintf("│ │\r\n");
- cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
-
- /* loop until keypressed */
- while(!keypressed()) {
- deltalo = deltahi = 0;
- TXLevel(0);
- delay(100);
- disable();
- deltahi = 0;
- t = timer();
- j = RXLevel();
- transit(t -= BITTIME);
- waituntil(t -= 50000);
- waituntil(t -= 50000);
- i = RXLevel();
- enable();
- delay(100);
- cprintf("%d %d\r\n",j,i);
- }
- getkey();
-
- #ifdef ANDY
- /* do a second-long sample */
- for(i=0; i<600; i++) {
-
- /* do a low->high transition */
- transit(t -= BITTIME); /* do a transition */
- deltahi = t - waittrans(t - 50000);
- break;
- d = RXLevel();
- if(d)
- deltahi++;
-
- /* do a high-low transition */
- transit(t -= BITTIME); /* do a transition */
- d = RXLevel();
- if(!d)
- deltalo++;
- }
- enable();
-
- sprintf(s,"%5ld %5ld",
- deltahi, deltalo);
- putstring(15,16,60,7,s);
- }
- getkey(); /* gobble the key */
- #endif
- }
-
- /* HandleKey()
- Handles user's keystrokes.
- */
- int HandleKey()
- {
- KEY k;
-
- switch(getkey()) {
- case ESC:
- case ALTX:
- return TRUE; /* done! */
- case SPC:
- TXState = !TXState;
- TXKey(TXState);
- break;
- case F1: /* on-air alignment */
- Alignment();
- break;
- case F2: /* toggle TX level */
- TXLev = !TXLev;
- TXLevel(TXLev);
- break;
- case F3: /* 600hz square wave */
- SquareWave();
- break;
- case F4: /* loopback test */
- /* Loopback();
- */
- break;
- }
- return FALSE;
- }
-
- /* ----- Main Program ----- */
-
- main(int argc, char **argv)
- {
- /* Initialize */
- monochrome = TRUE;
- TXKey(TXState = FALSE);
- TitleScreen();
- curoff();
- InitParameters();
-
- /* loop, handling keystrokes and showing current status */
- while(TRUE) {
- if(keypressed()) {
- if(HandleKey())
- break;
- }
- UpdateScreen();
- }
-
- /* clean up and exit */
- clrscr();
- curon();
- TXKey(FALSE); /* drop transmit */
- _exit(0);
- }