#include <stdio.h>
#include <errno.h>
#include <math.h>
#define FSAMPLE 9600
#define TRUE 1
#define FALSE !TRUE
#define KBSIGNAL 2001
typedef struct {
short index;
unsigned int data[64];
} FRAME;
typedef struct {
short vco;
short signsign;
short vcofreq;
short centerfreq;
short lp1;
short lp2;
short sign;
short clock;
short phase;
short diff;
int byte;
short bitcount;
FRAME *rxbuf;
short frame;
short sintbl[256];
} DSP;
DSP *dsp;
int sighand();
int key = FALSE;
int quit = FALSE;
main(argc, argv)
int argc;
char *argv[];
{
FRAME *rxbuf;
int i, freq;
unsigned char c;
dsp = (DSP *)malloc(sizeof(DSP));
freq = 1200;
dsp->centerfreq = 0xffff*freq/FSAMPLE;
for (i=0; i<256; i++) {
dsp->sintbl[i] = 0x7fff*sin(2*PI*i/256);
}
rxbuf = (FRAME *)malloc(sizeof(FRAME));
dsp->rxbuf = rxbuf;
rxbuf->index = 0;
dsp->bitcount = -1;
intercept(sighand);
_ss_ssig(0, KBSIGNAL);
init(dsp);
cls(0);
do {
/* process received frames */
if (dsp->byte == 0x1acffc1d) {
printf("sync found!\n");
}
if (dsp->frame) {
dsp->frame = FALSE;
for (i=0; i<64; i++) {
printf("%08x\n", rxbuf->data[i]);
}
}
if (key) {
read(0, &c, 1);
switch(c) {
case 'q':
quit = TRUE;
break;
case '+':
freq += 50;
break;
case '-':
freq -= 50;
break;
}
dsp->centerfreq = 0xffff*freq/FSAMPLE;
showfreq(freq);
_ss_ssig(0, KBSIGNAL);
key = FALSE;
}
} while (!quit);
deinit();
}
trace(frm)
FRAME *frm;
{
int i, len;
/* len = frm->len;
while (--len > 0) {
putchar(frm->data[i++]);
if (!(i%32))
printf("\n");
}
*/
}
showfreq(f)
{
char str[80];
sprintf(str, "center: %4d", f);
cursor(0,0);
prstr(str);
}
sighand(signal)
register int signal;
{
switch(signal) {
case KBSIGNAL:
key = TRUE;
break;
default:
deinit();
exit(1);
}
}
#asm
PADDR equ $05
PADR equ $11
TCR equ $21
CPRH equ $27
CPRM equ $29
CPRL equ $2B
TSR equ $35
ADC equ $100
oldvec dc.l 1
init: link a5,#0
movem.l d0-d2/a0-a3,-(sp)
lea.l irq6+6(pc),a0
move.l d0,(a0)
lea.l oldvec(pc),a0
move.l $78,(a0)
lea.l irq6(pc),a0
move.l a0,$78
lea.l $c01000,a0
move.b #$e0,TCR(a0)
nop
move.b #00,CPRH(a0)
nop
move.b #00,CPRM(a0)
nop
move.b #25,CPRL(a0)
nop
move.b #$e1,TCR(a0)
movem.l (sp)+,d0-d2/a0-a3
unlk a5
rts
deinit: movem.l a0,-(sp)
lea.l $c01000,a0
move.b #0,TCR(a0)
lea.l oldvec(pc),a0
move.l (a0),$78
movem.l (sp)+,a0
rts
irq6: movem.l d0-d2/a0-a3,-(sp)
movea.l #-1,a2
lea.l $c01000,a3
move.b #$01,TSR(a3)
move ADC(a3),d1
andi #$fff,d1
subi #$440,d1
* asl #2,d1
move d1,d2
move (a2),d0 vco in d0
lsr #8,d0 make word
lsl #1,d0 and even for offset
add #32,d0 offset to sin table
muls (a2,d0.w),d1
move (a2)+,d0
move (a2),d1 get previous sign in d1
andi #$8000,d2 new sign in d2
move d2,(a2)+ save it
sub d1,d2 any difference?
beq.s equ branch if not
move d0,d2
lsl #1,d2
subi #$2000,d2
move d2,d1
asr #4,d1
sub d1,d0
equ move (a2)+,d1
add d1,d2
sub (a2)+,d2
asr #8,d2
sub d2,d1
move d1,-4(a2)
add d1,d0
move d0,-8(a2)
swap d1
add (a2),d1 lowpass to remove the carrier
asr #1,d1
move d1,(a2)+ lp1
add (a2),d1
asr #1,d1
move d1,(a2)+ lp2
* Clock recovery DPLL & Carrier detect
andi #$8000,d1 limit sample stream
move (a2),d0 sign
move d1,(a2)+
move.l (a2),d2 bitclock and fraction
cmp d1,d0
beq.s L38
move.l d2,d0 cccc.pppp
lsr.l #3,d0 000c.cccp
subi #$9000,d0
ext.l d0
sub.l d0,d2
* Sampling / 8
L38 swap d2 clock in d2
move d2,d0
addq #1,d2 clock++
swap d2
move.l d2,(a2)+ update clock
andi #7,d0
beq.s rdbit sample data at 8 clockticks
movem.l (a7)+,d0-d2/a0-a3
rte
* Decode NRZI
rdbit move (a2),d0 search for transitions
move d1,(a2)+
sub d0,d1
not d1
move.l (a2),d0 get byte
roxl #1,d1 sign of d1 is bit
roxl.l #1,d0 shift it in
move.l d0,(a2)+ and save it
move (a2),d2 bitcount in d2 (init at -1)
bpl.s rxfram
cmpi.l #$1acffc1d,d0 start sequence in stream
bne.s irq9
move #2048,d2 256 bytes of 8 bits to go
move.l 2(a2),a3 rxbuf ptr
clr (a3) reset index
rxfram move d2,d1
subq #1,d2
bpl.s cont
move #-1,6(a2) frame complete
cont move d2,(a2)+ update bitcount
andi #$1f,d1 write every 4 bytes
bne.s irq9
move.l (a2)+,a3 rxbuf ptr
move (a3)+,d1 index in rxbuf
move.l d0,(a3,d1.w)
addq #4,d1
move d1,-2(a3)
irq9 movem.l (a7)+,d0-d2/a0-a3
rte
#endasm