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 ////////