; 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  mov     bytect, #8
            setb    RB5
            nop
            nop
            nop
            clrb    RB5
            setb    RB5
            nop
            nop
            nop
            clrb    RB5
:dloop      call    collect
            setb    RB5
            clrb    RB5
            setb    RB5
            clrb    RB5
            setb    RB5
            clrb    RB5
            mov     real, byte1
            mov     imag, byte2
            call    collect
            mov     real2, byte1
            mov     imag2, byte2
            mov     mybyte, #67
            call    sout
            mov     mybyte, real
            call    sout
            mov     mybyte, imag
            call    sout
            mov     mybyte, real2
            call    sout
            mov     mybyte, imag2
            call    sout
            mov     mybyte, #13
            call    sout
            call    pskdemod
            movb    c, bitv
            rr      mybyte
            djnz    bytect, :dloop
            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
            