; CDI ignition program for SDR
;****************************************

	list     p=16F84a
	#include p16F84a.inc
	radix dec

	__CONFIG	_WDT_OFF & _XT_OSC

; PRESET VALUES
;****************************************
#define prescaler	8
;# delay_multiple 18
#define pulse_width	200
#define min_count	19
#define max_count	60000000/256/2000
#define ign_table	98
#define high_multiple   3
#define low_multiple    39
#define input		PORTA,4
#define output     	PORTB,3
#define light     	PORTB,7
#define TMR0	    1

	cblock 8
	tmr0h,timl,timh,first,count
	endc

; START SEQUENCE
;****************************************
	org 0x00
	GOTO   MAIN

; INT SEQUENCE
;****************************************
	org 0x04
  	INCF tmr0h,f
  	BCF INTCON,2
  	retfie

; READ ignition_table
;****************************************
read_array:
	addwf  PCL,f
ignition:

ignition00 DT  46, 48, 51, 53, 55, 56, 55, 55, 56, 58, 60, 61, 63, 65, 67
ignition01 DT  68, 70, 72, 74, 75, 77, 79, 81, 82, 84, 86, 87, 89, 91, 93
ignition10 DT  95, 97,100,102,104,106,108,110,112,114,117,119,121,123,125
ignition11 DT 127,129,132,134,136,138,140,142,144,146,149,151,153,155,157
ignition20 DT 159,161,164,166,168,170,172,174,176,178,181,183,185,187,189
ignition21 DT 191,193,196,198,200,202,204,206,208,211,213,215,217,219,221
ignition30 DT 223,225,228,230,232,234,236,238,240


; PULSE WAIT AND READ TIMER SUB ROUTINE
;****************************************
wait_pulse:

waithigh:
    BTFSS  input
	GOTO   waithigh

waitlow:  
	BTFSC  input
	GOTO   waitlow

; READ TIMER DATA
;****************************************
	MOVF   TMR0,W
	MOVWF  timl
	MOVF   tmr0h,W
	MOVWF  timh

; CLEAR TIMER
;****************************************
	CLRF   TMR0
	CLRF   tmr0h

	retlw  0


; MAIN ROUTINE
;****************************************
MAIN: 

; INITIALIZE
;****************************************
	BSF    STATUS,RP0
	MOVLW  0
	MOVWF  TRISB		;Set Port B to all output
    MOVLW  16
	MOVWF  TRISA        ;Set Port A4 to input

	MOVLW  prescaler-1
	MOVWF  OPTION_REG   ;set prescaler
	BCF    STATUS,RP0

	BSF    first,0      ;ignore the first pulse
	CLRF   PORTB

        CLRF   tmr0h        ;

        MOVLW  0xA0         ;INTCON=0xa0; //T0IE=1
        MOVWF  INTCON
    BSF	   light
	BCF    output       ;set output low

; MAIN LOOP
;****************************************
main_loop:  
	CALL	wait_pulse

	BTFSS  first,0
	GOTO   nowait

	CALL	wait_pulse
	BCF    first,0

; TABLE RANGE CHECK FOR out_map
;****************************************
nowait:
	MOVF   timh,F
	BTFSS  STATUS,2
	GOTO   out_map
	MOVLW  min_count
	SUBWF  timl,W
	BTFSS  STATUS,0
	GOTO   out_map
	MOVLW  min_count+ign_table
	SUBWF  timl,W
	BTFSC  STATUS,0
	GOTO   out_map

; TABLE RANGE: (min_count < count < min_count+ign_table)
;****************************************
	MOVLW  min_count
	SUBWF  timl,W    ;timl=timl-min_count

	CALL   read_array
	MOVWF  count       ;count=ign[timl]

	MOVLW  9	       ;count=count-9
	SUBWF  count,F

        BCF    light

; delay_multiple = 18 (adjust by no. of nop)
;****************************************
loop1:	
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
	DECFSZ count,F
	GOTO   loop1
    BSF	   light
	GOTO   DO_PULSE

; OUT MAP SEQUENCE
;****************************************
out_map:
	MOVF   timh,F
	BTFSS  STATUS,2
	GOTO   LOW_RPM
	MOVLW  min_count+ign_table
	SUBWF  timl,W
	BTFSS  STATUS,0
;	GOTO   HIGH_RPM (disabled)
        GOTO   silent

; LOW RPM (< min_count)
;****************************************
LOW_RPM:
	INCF   timh,F  		;perh++
	INCF   timl,F		;perl++
    BCF	   light
loop2:
;low_multiple
    MOVLW (low_multiple-5)/3
    MOVWF count
loop3:
	DECFSZ count,F
	GOTO   loop3
;

	DECFSZ timl,F
	GOTO   loop2
	DECFSZ timh,F
	GOTO   loop2
    BSF	   light
	GOTO   DO_PULSE

; HIGH RPM (> min_count+ign_table)
;****************************************
HIGH_RPM:
	INCF   timl,F		;perl++;
        BCF    light
loop4:  
;high_rpm_multiple	10 us //0 degrees
	MOVLW  high_multiple-1
	MOVWF  count
loop5:
	DECFSZ count,F
	GOTO   loop5

	DECFSZ timl,F
        BSF    light
	GOTO   loop4

; SCR Pulse Output
;****************************************
DO_PULSE:
	BSF    output		;output high
	MOVLW  pulse_width/3
	MOVWF  count
loop9:
	DECFSZ count,F
	GOTO   loop9
	BCF    output		;output low

;silent_time, 768 us (256*3)
silent: 
        CLRF   count
loop10:
	DECFSZ count,F
	GOTO   loop10

	GOTO   main_loop

	END
