; Message demodulation... woo woo...
; Heres the pseudo code
;
;msg_demod {
;    newbyte = demodulate_byte();
;#ifdef SMART_MODE
;    if(newbyte == MSGEND){
;        process_message(msg);
;        return;
;    }
;    else{
;        msg += newbyte;
;    }
;#else /* Serial Mode */
;   transmitbyte(newbyte);
;#endif
;}
;
;demodulate_byte {
;    for (1 to 8) {
;        (real, imag) = collect();
;        (real2, imag2) = collect();
;        bitv = demodulate(real, imag, real2, imag2);
;        shift(mybyte, bitv);
;    }
;    return mybyte;
;}
;

msg_demod   call    demod_byte
;#ifdef SMART_MODE
;#else
;            call    sout
;#endif            
            ret

sout        mov     xmt_byte,mybyte	;put mbyte into xmtbyte
            mov	    bit_cntr,#8		;Eight bits in a byte
	    clrb    TX			;start bit
            call    bit_delay		

:xmit       rr	    xmt_byte		;Rotate right moves data
            movb    TX,c
	    call    bit_delay
            djnz    bit_cntr,:xmit
            setb    TX			;stop bit
            call    bit_delay
            ret

ssout        mov     xmt_byte,mybyte	;put mbyte into xmtbyte
            mov	    bit_cntr,#8		;Eight bits in a byte
	    clrb    TX			;start bit
            call    lbit_delay		

:xmit       rr	    xmt_byte		;Rotate right moves data
            movb    TX,c
	    call    lbit_delay
            djnz    bit_cntr,:xmit
            setb    TX			;stop bit
            call    lbit_delay
            ret
            

lbit_delay   mov	    delay_cntr,#100
:loop       nop
            djnz	delay_cntr,:loop
            ret

bit_delay   mov	    delay_cntr,#Serial_K
:loop       nop
            djnz	delay_cntr,:loop
            ret

supersamp   mov     imag_r, #10
            mov     bit_cntr, #0
:l          call    collect
            mov     real, byte1
            mov     imag, byte2
            call    ookdemod
            inc     bit_cntr
            djnz    imag_r, :l
            cjae    bit_cntr, #5, :isone
            clrb    bitv
            ret
:isone      setb    bitv
            ret
            
demod_byte  jb      skipcollect, :skipme
            jb      inmsg, :nextbit
:scan       call    collect
            mov     real, byte1
            mov     imag, byte2
            call    collect
            mov     cosine1, byte1
            mov     cosine2, byte2
            call    ookdemod2
            jb      bitv, :gotstart
            jmp     :scan

:gotstart   mov     bytect, #8
            setb    inmsg
            setb    skipcollect
            mov     RTCC, #125
            ret
:skipme     clrb    skipcollect
            ret
:nextbit    mov     quad, #0
:dloop      clrb    adcon0.3
            setb    go_done
            clrb    RA3
            setb    RA3
            call    adwait
            mov     byte1, adres
            setb    go_done
            clrb    RA3
            setb    RA3
            call    adwait
            mov     byte2, adres
            mov     real, byte1
            mov     imag, byte2
            call    collect
            mov     cosine1, byte1
            mov     cosine2, byte2
            call    ookdemod2
            movb    c, bitv
            rr      txbyte
            djnz    bytect, :still
            mov     mybyte, txbyte
            call    canned
            clrb    inmsg
:still      ret

ookdemod2   call    ookdemod
            mov     cosine3, byte1
            mov     real, cosine1
            mov     imag, cosine2
            call    ookdemod
            add     cosine3, byte1
            rr      cosine3
            cjae    cosine3, #thresh, :bit1
            clrb    bitv
            ret
:bit1       setb    bitv
            ret

canned      cje     mybyte, #77, :sendit
            clrb    RA3
            nop
            nop
            nop
            setb    RA3
            nop
            clrb    RA3
            nop
            setb    RA3
            ret
:sendit     mov     imag_r, #20
:cset       call    setme
            djnz    imag_r, :cset
            ret


setme       clrb    TX
            mov     sine3, #5
:break      call    forever
            djnz    sine3, :break
            setb    TX
            call    forever
            
            mov     cosine3, #0
:l2         movf    cosine3, 0
            call    stringcan
            movwf   mybyte
            call    ssout
            inc     cosine3
            call    forever
            cjbe    cosine3, #15, :l2
            
            setb    TX
            mov     sine3, #100
:break2      call    forever
            djnz    sine3, :break2
            ret

stringcan   jmp     pc+w
            retw    25, '0', '5', ' ', '1', '2', '0', '0', '0', '8', '0', '1', '9', '7', 25, 0

forever     mov     sine1, #200
:loopme2    mov     sine2, #255
:loopme     nop
            djnz    sine2, :loopme
            djnz    sine1, :loopme2
            ret

checkset    cje     real_r, mybyte, :pair            
            mov     real_r, mybyte
            mov     framect, #0
            ret
:pair       inc     framect
            cjae    framect, #3, :gotit
            ret
:gotit      call    sout
            ret
            
ookdemod    mov     tempb, real
            call    absol
            mov     byte1, tempa
            mov  tempb, imag
            call    absol
            add byte1, tempa
;            mov     mybyte, byte1
;            call    sout
            cjae byte1, #thresh, :bit1
            clrb bitv
            ret
:bit1       setb bitv
            ret

            
; Yuck.  Actually do the demodulation of a pair of message bits            
pskdemod    call	getquad		
	    mov	quad_a, quad	; quad_a = getquad(real_a, imag_a)

	mov	real, real2
	mov 	imag, imag2
	call	getquad
;	mov	quad_b, quad	; quad_b = getquad(real_b, imag_b)

;	csne	quad_a, quad_b	; if( 	(quad_a != quad_b)
	csne	quad_a, quad	; if( 	(quad_a != quad_b)            ; 3 or 4
	jmp	:equalb                                                ; 4&5
				;	&&			
	add	quad_a, #1                                            ; 5&6
;	csne	quad_a, quad_b	;	((quad_a+1) != quad_b)
	csne	quad_a, quad	;	((quad_a+1) != quad_b)        ; 9 or 10
	jmp	:equala                                                ; 10 &11
				;	&&
	sub	quad_a, #2                                            ; 11&12
;	csne	quad_a, quad_b	;	((quad_a-a) != quad_b))
	csne	quad_a, quad	;	((quad_a-a) != quad_b))       ; 15 or 16
	jmp	:equal                                                ; 16 &17

:nequal	setb	bitv		;	bitv = 1;                     ; 17
        nop                                                           ; 18
	ret
:equalb nop
        nop
        nop
        nop
        nop
        nop
:equala nop
        nop
        nop
        nop
        nop
        nop
				; equal
:equal	clrb	bitv		;		bitv = 0;
	ret


; This takes two register values: real and imag which
; are the real and imaginary components of the point
; Another value center, is the zero of real and imag

; First, I need to generate some useful temporary values
; real_r	This is the absolute value of real
; imag_r	This is the absolute value of imag
; real2_r	This is real_r * 2
; imag2_r	This is imag_r * 2
;
; quad		This is the quadrant, which the point is in


; subroutine absol
; tempa = abs(tempb)
; absol is now constant time! :-)
absol	cjb	tempb,#center,:sless	; if(real > center)               ; 4 or 5
	mov	tempa, tempb                                              ; 5&6
	sub	tempa, #center		; 	val_r = val-center;       ; 7&8
        nop                                                               ; 9         
        nop                                                               ; 10
        nop                                                               ; 11
	ret				;	return
					; else
:sless	mov	tempa, #center		                                  ; 6&7
	sub	tempa, tempb		;	val_r = center-val        ; 8&9
	sub	tempa, #1                                                 ; 10&11
	ret				; 	return
					; endif

;
; subroutine getquad
;
; This does the bulk of the work...

; tempa and tempb IN USE
; tempa will be the result of calling absol
; tempb is the input to absol
; ie, tempa = absol(tempb)
; Getquad is constant time now!
getquad	mov	tempb, real
	call	absol
	mov	real_r, tempa		; real_r = absol(real)

	mov	tempb, imag
	call	absol
	mov	imag_r, tempa		; imag_r = absol(imag)
; tempa and tempb NO LONGER IN USE

; tempa and tempb IN USE
; tempa will be real_r*2, aka real2_r
; tempb will be imag_r*2, aka imag2_r
	mov	tempa, real_r
	rl	tempa			; real2_r = 2*real_r
	mov	tempb, imag_r
	rl	tempb			; imag2_r = 2*imag_r

	cjb	real, #center, :else_a	; if (real > center)                                 ; 4 or 5
	cjb	imag, #center, :else_b	;	if(imag > center)                            ; 8 or 9
	cjb	imag_r, real_r, :else_c	;		if(imag_r > real_r)                  ; 12 or 13
	cjb	imag_r, tempa, :else_d	;			if(imag_r > real2_r)         ; 16 or 17
	mov	quad, #3	        ;				quad = 4             ; 17&18
        nop
        nop
        nop
        nop                                                                                  ; 22
	ret				
					;			else
:else_d	mov	quad, #2		;				quad = 3             ; 18&19
        nop
        nop
        nop                                                                                  ; 22
	ret				;			endif
					;		else
:else_c	cjb	real_r, tempb, :else_e;			if(real_r > imag2_r)                 
	mov	quad, #0		;				quad = 1             ; 18&19
        nop
        nop
        nop                                                                                  ; 22
	ret
					;			else
:else_e	mov	quad, #1		;				quad = 2             ; 19&20
        nop
        nop
	ret				;			endif
					;		endif
					;	else
:else_b	cjb	imag_r, real_r, :else_f	;		if(imag_r >real_r)                   ; 13 or 14
	cjb	imag_r, tempa, :else_g	;			if(imag_r > real2_r)         ; 17 or 18
	mov	quad, #12		;				quad = 13            ; 18&19
        nop
        nop
        nop
	ret
					;			else                         
:else_g	mov	quad, #13		;				quad = 14            ; 19&20
        nop
        nop
	ret				;			endif
					;		else
:else_f	cjb	real_r, tempb, :else_h;			if(real_r > imag2_r)                 ; 18 or 19
	mov	quad, #15		;				quad = 16            ; 19&20
        nop
        nop
	ret
					;			else
:else_h	mov	quad, #14		;				quad = 15            ; 20&21
        nop
	ret				;			endif
					;		endif
					;	endif
					; else
:else_a	cjb	imag, #center, :else_i	;	if(imag > center)                           ; 9 or 10
	cjb	imag_r, real_r, :else_j	;		if(imag_r > real_r)                 ; 13 or 14
	cjb	imag_r, tempa, :else_k	;			if(imag_r > real2_r)        ; 17 or 18
	mov	quad, #4		;				quad = 5            ; 18&19
        nop
        nop
        nop
	ret				
					;			else
:else_k	mov	quad, #5		;				quad = 6            ; 19&20
        nop
        nop
	ret				;			endif
					;		else
:else_j	cjb	real_r, tempb, :else_l;			if(real_r > imag2_r)                ; 18 or 19
	mov	quad, #7		;				quad = 8            ; 19&20
        nop
        nop
	ret
					;			else
:else_l	mov	quad, #6		;				quad = 7            ; 20&21
        nop
	ret				;			endif
					;		endif
					;	else
:else_i	cjb	imag_r, real_r, :else_m	;		if(imag_r >real_r)                  ; 14 or 15
	cjb	imag_r, tempa, :else_n;			if(imag_r > real2_r)                ; 18 or 19
	mov	quad, #11		;				quad = 12           ; 19&20
        nop
        nop
	ret
					;			else
:else_n	mov	quad, #10		;				quad = 11           ; 20&21
        nop
	ret				;			endif
					;		else
:else_m	cjb	real_r, tempb, :else_o;			if(real_r > imag2_r)                ; 19 or 20
	mov	quad, #8		;				quad = 9            ; 20&21
        nop
	ret
					;			else
:else_o	mov	quad, #9		;				quad = 10           ; 21&22
	ret				;			endif
					;		endif
					;	endif
					; endif
; tempa and tempb NO LONGER IN USE
            