; 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

bit_delay   mov	    delay_cntr,#Serial_K
:loop       nop
            djnz	delay_cntr,:loop
            ret
            
demod_byte  jb      skipcollect, :skipme
            jb      inmsg, :nextbit
:scan       call    collect
            mov     real, byte1
            mov     imag, byte2
            call    ookdemod
            jb      bitv, :gotstart
            jmp     :scan
:gotstart   mov     bytect, #8
            setb    inmsg
            setb    skipcollect
            mov     RTCC, #100
            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
            cjae    byte1, byte2, :b1bigger
            sub     byte2, byte1
            cjae    byte2, #96, :aone
            jmp     :azero
:b1bigger   sub     byte1, byte2
            cjae    byte1, #96, :aone
            jmp     :azero
:aone       setb    c
            jmp     :foo
:azero      clrb    c            
            

:foo        rr      mybyte
            djnz    bytect, :still
            call    sout
            clrb    inmsg
:still      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
            