Date: Tue, 28 Nov 89 18:31:13 -0800
From: Marc T. Kaufman <kaufman@Neon.Stanford.EDU>
Message-Id: <8911290231.AA25951@Neon.Stanford.EDU>
Subject: Re: TAPR 9600 RAdio/Modems???

Enclosed is a new ROM for you to try with the 56KB modem, if you are
interested. (actually, it is a rom description and a program to compile
the ROM itself).

The waveshape used here is a band-limited, continuous-phase, pulse of
length L = 2T.  Each 16 bit run has the last half of the previous pulse,
and the first half of the current pulse.  The total bandwidth should be
on the order of (99% = 2.2 x b), which is OK since you would expect sidebands
at +/- 1 x b (for a bandwidth of 2 x b) anyway, unless you are using TFM with
a fairly long spread.

Anyway, try it if you have time, and tell me how it compares to Heatherington's
original.

Marc Kaufman (kaufman@Neon.stanford.edu)

***** program to make the rom *****

/* Program to build ROMs for Heatherington 56Kb modem
 *
 * Written by Marc Kaufman, WB6ECE
 *            6 September 1987
 *
 *  usage:  mkrom < Romdatafile > binaryromfile
 */
#include <stdio.h>

#define ROMSZ  1024
#define LINESZ 100
#define TRUE   1
#define FALSE  0

char	rom[ROMSZ];
char	line[LINESZ];

main() {
	int addr, j;
	int mode, innum, minus;
	char *p, c;

	for (addr = 0; addr < ROMSZ; addr++)
		rom[addr] = 0377;

	while (fgets(line, LINESZ, stdin) != NULL) {

		switch (line[0]) {

		case '.':	/* waveshape data */

			mode = 0;
			sscanf(&line[1], "%d", &addr);
			break;

		case '=':	/* state table data */
			mode = 1;
			sscanf(&line[1], "%d", &addr);
			break;

		case '/':	/* comments */
		case '\n':
			break;

		default:	/* line of data */
			p = line;
			innum = FALSE;
			minus = FALSE;
			j = 0;
			while (c = *p++) {
				if (c == '-') {
					minus = TRUE;
				} else if (c >= '0' && c <= '9') {
					innum = TRUE;
					if (mode == 0)
						j = 10*j + c - '0';
					else
						j = 4*j + c - '0';
				}
				else
					if (innum) {
						if (mode == 0)
							if (minus)
								j = 128 - j;
							else
								j = 128 + j;
						rom[addr++] = j;
						innum = FALSE;
						minus = FALSE;
						j = 0;
					}
			}
			break;
		}
	}

	write(fileno(stdout), rom, ROMSZ);
}

***** data for program *****

/ ROM data for Heatherington 56Kb modem
/ Developed by Marc Kaufman, WB6ECE
/              6 September 1987

/ data portion.  Each waveform segment is 1/2 of an L=2 CPM wave, so it is
/                the first half of the wave we want, plus the last half of
/                the previous wave.  The suffix 'S' or 'O' indicates whether
/                the current bit is going in the Same direction (in terms of
/                phasor rotation) or is Opposed (phasor reverses direction).
/                The NRZI algorithm says that if the current bit is '1', go
/                the same way (the result will be another FM pulse of the
/                same polarity as the last), and if the bit is a '0', go the
/                other way (the result will be an FM pulse of the opposite
/                polarity to the last).
/ Q data -
.512
/ state 0, clock 0, (0 -> 1)S
 -87  -77  -66  -55  -43  -31  -20   -8    4   15   27   39   51   62   73   84
/ state 0, clock 1, (1 -> 0)S
  94  102  109  116  120  124  126  127  127  127  124  121  117  111  104   96
/ state 0, clock 2, (0 -> -1)S
  86   76   65   54   42   30   19    7   -5  -16  -28  -40  -52  -63  -74  -85
/ state 0, clock 3, (-1 -> 0)S
 -95 -103 -110 -117 -121 -125 -127 -128 -128 -128 -125 -122 -118 -112 -105  -97
/ state 1, clock 0, (0 -> -1)S
  86   76   65   54   42   30   19    7   -5  -16  -28  -40  -52  -63  -74  -85
/ state 1, clock 1, (-1 -> 0)S
 -95 -103 -110 -117 -121 -125 -127 -128 -128 -128 -125 -122 -118 -112 -105  -97
/ state 1, clock 2, (0 -> 1)S
 -87  -77  -66  -55  -43  -31  -20   -8    4   15   27   39   51   62   73   84
/ state 1, clock 3, (1 -> 0)S
  94  102  109  116  120  124  126  127  127  127  124  121  117  111  104   96
/ state 2, clock 0, (0 -> 1)O
  84   71   58   45   34   25   18   15   15   18   25   34   45   58   71   84
/ state 2, clock 1, (1 -> 0)O
  96  106  114  119  123  125  126  127  127  126  125  123  119  114  106   96
/ state 2, clock 2, (0 -> 1)O
  84   71   58   45   34   25   18   15   15   18   25   34   45   58   71   84
/ state 2, clock 3, (1 -> 0)O
  96  106  114  119  123  125  126  127  127  126  125  123  119  114  106   96
/ state 3, clock 0, (0 -> -1)O
 -85  -72  -59  -46  -35  -26  -19  -16  -16  -19  -26  -35  -46  -59  -72  -85
/ state 3, clock 1, (-1 -> 0)O
 -97 -107 -115 -120 -124 -126 -127 -128 -128 -127 -126 -124 -120 -115 -107  -97
/ state 3, clock 2, (0 -> -1)O
 -85  -72  -59  -46  -35  -26  -19  -16  -16  -19  -26  -35  -46  -59  -72  -85
/ state 3, clock 3, (-1 -> 0)O
 -97 -107 -115 -120 -124 -126 -127 -128 -128 -127 -126 -124 -120 -115 -107  -97

/ I data -  just like Q data, but permuted by 1 clock (quadrature)
.768
/ state 0, clock 0, (1 -> 0)S
  94  102  109  116  120  124  126  127  127  127  124  121  117  111  104   96
/ state 0, clock 1, (0 -> -1)S
  86   76   65   54   42   30   19    7   -5  -16  -28  -40  -52  -63  -74  -85
/ state 0, clock 2, (-1 -> 0)S
 -95 -103 -110 -117 -121 -125 -127 -128 -128 -128 -125 -122 -118 -112 -105  -97
/ state 0, clock 3, (0 -> 1)S
 -87  -77  -66  -55  -43  -31  -20   -8    4   15   27   39   51   62   73   84
/ state 1, clock 0, (-1 -> 0)S
 -95 -103 -110 -117 -121 -125 -127 -128 -128 -128 -125 -122 -118 -112 -105  -97
/ state 1, clock 1, (0 -> 1)S
 -87  -77  -66  -55  -43  -31  -20   -8    4   15   27   39   51   62   73   84
/ state 1, clock 2, (1 -> 0)S
  94  102  109  116  120  124  126  127  127  127  124  121  117  111  104   96
/ state 1, clock 3, (0 -> -1)S
  86   76   65   54   42   30   19    7   -5  -16  -28  -40  -52  -63  -74  -85
/ state 2, clock 0, (1 -> 0)O
  96  106  114  119  123  125  126  127  127  126  125  123  119  114  106   96
/ state 2, clock 1, (0 -> 1)O
  84   71   58   45   34   25   18   15   15   18   25   34   45   58   71   84
/ state 2, clock 2, (1 -> 0)O
  96  106  114  119  123  125  126  127  127  126  125  123  119  114  106   96
/ state 2, clock 3, (0 -> 1)O
  84   71   58   45   34   25   18   15   15   18   25   34   45   58   71   84
/ state 3, clock 0, (-1 -> 0)O
 -97 -107 -115 -120 -124 -126 -127 -128 -128 -127 -126 -124 -120 -115 -107  -97
/ state 3, clock 1, (0 -> -1)O
 -85  -72  -59  -46  -35  -26  -19  -16  -16  -19  -26  -35  -46  -59  -72  -85
/ state 3, clock 2, (-1 -> 0)O
 -97 -107 -115 -120 -124 -126 -127 -128 -128 -127 -126 -124 -120 -115 -107  -97
/ state 3, clock 3, (0 -> -1)O
 -85  -72  -59  -46  -35  -26  -19  -16  -16  -19  -26  -35  -46  -59  -72  -85

/ State Change portion
/  After each 16 waveform samples (64 clocks), A state lookup is performed
/  to get the correct phasor rotation for the next bit.  If the next bit
/  is a '1', we want to rotate in the same direction.  If the next bit is
/  a '0', we want to rotate in the opposite direction.  I and Q states
/  are independent.  The state entry is 4 bits of the form 'iiqq', where
/  'ii' is the next I state and 'qq' is the next Q state.  The basic pattern
/  (for Q states only) is:
/                             CURRENT STATE
/                            0    1    2    3
/                         ----------------------
/  Data bit = 0: Clock 0 |   2    3    2    3
/                Clock 1 |   2    3    2    3
/                Clock 2 |   3    2    2    3
/                Clock 3 |   3    2    2    3
/
/  Data bit = 1: Clock 0 |   0    1    0    1
/                Clock 1 |   0    1    0    1
/                Clock 2 |   0    1    1    0
/                Clock 3 |   0    1    1    0
/               
/  The I state table is identical, but shifted by 1 clock period.

=256
/  Data bit = 0, Clock 0
  22  23  22  23  32  33  32  33  22  23  22  23  32  33  32  33
/  Data bit = 0, Clock 1
  32  33  32  33  22  23  22  23  22  23  22  23  32  33  32  33
/  Data bit = 0, Clock 2
  33  32  32  33  23  22  22  23  23  22  22  23  33  32  32  33
/  Data bit = 0, Clock 3
  23  22  22  23  33  32  32  33  23  22  22  23  33  32  32  33

=320
/  Data bit = 1, Clock 0
  00  01  00  01  10  11  10  11  00  01  00  01  10  11  10  11
/  Data bit = 1, Clock 1
  00  01  00  01  10  11  10  11  10  11  10  11  00  01  00  01
/  Data bit = 1, Clock 2
  00  01  01  00  10  11  11  10  10  11  11  10  00  01  01  00
/  Data bit = 1, Clock 3
  00  01  01  00  10  11  11  10  00  01  01  00  10  11  11  10

//////// end of transmission ////////