	title 			"Engine Fuel Monitor."
	subtitle		"K. Grabe, Cork Ireland"
        __IDLOCS H'0007'  	; PIC id equal to s/w revision.
;********************************************************************
;
; Main.asm			Engine Fuel Monitor main source file
;
; Revision History:
;	V00	26 Jun 95	Initial
;	v01	30 Jun 95	Math devide routine		
;	v02
;	v04	05 Jul 95	Devide fuel by 100
;				Reset counters on overflow	
;	v05	12 Jul 95	Fuel consumption rate display
;	v06	13 Jul 95	MPG rate display, EE lib routines
;	v07	18 Jul 95	Display fuel, dist >$FFFF using EE
;
; Read LCD_DATA inputs outside of read/write to display (use btfss and not
;      full port read as this resets 4:7 mismatch)
; to do :speaker - drive from opposing outputs
;
;********************************************************************
        LIST    P=16C84, C=132, N=100, R=HEX, F=INHX8M
;			       (^^^^^ For Monaco font, size9, A4 @ 60%)	
#DEFINE		RamStart	h'0c'	; For '84
#DEFINE		RamEnd		h'2f'	; For '84
#DEFINE		PAGE0		BCF	STATUS, RP0	; Page 0
#DEFINE		PAGE1		BSF	STATUS, RP0	; Page 1
#DEFINE		IntOn		BSF	INTCON, GIE	; Interrupts on
#DEFINE		IntOff		BCF	INTCON, GIE	; Interrupts off

INCLUDE         "P16CXX.INC"
;INCLUDE		"P16CXXD.INC"
        __FUSES _CP_OFF&_WDT_ON&_XT_OSC&_PWRTE_ON

INCLUDE MACROS.INC
	expand			; Macro expansion on or off

;*************************************************************************
;
; Constants
;
;*************************************************************************

;#DEFINE	Debug			; No delay loops, Ports=ram for debug
TRUE		EQU	1		; 
FALSE		EQU	0		;

F_OSC           EQU     d'4000000'    	; Oscillator frequency (timers etc)
FuelRateTime	equ	d'2000'		; Time/ms that fuel rate counter runs
MPG_RateAmount	equ	d'250'		; Number of fuel units to measure distance
					; for instantaenous mpg readout
; 
; LCD contstants
;
LineEnd		equ	d'20'		; Where line one ends (8: LM020) 
LineLenght	equ	d'20'		; Total chars in a line
FourBit		EQU     TRUE  		; Selects 4- or 8-bit data transfers
DataHi		EQU     FALSE		; If 4-bit transfers, Hi or Low nibble of PORT
AboutDispTime 	EQU	d'3'		; Time/sec about message is displayed	

; LCD Display positions
PowerUpPosn	equ	d'21'		; Power up conter message

DistancePosn	equ	d'01'		
FuelPosn	equ	d'08'
TimePosn	equ	d'15'
MPGposn		equ	d'21'		; Bug in lcd.asm if 20		
					
FuelRatePosn	equ	d'29'
MPG_RatePosn	equ	d'36'		; Force lsd off screen
		page
;*************************************************************************
;
; RAM File Registers:	
;
;*************************************************************************
CBLOCK  RamStart       			; Begin data registers
					; Wait10ms
; Interrupt Service
	I_W_S				; Interrupt W reg save
	I_S_S				; Interrupt STATUS reg save
	I_FSR_S				; Interrupt FSR reg save
	LastPB				; Need for <4:7> Port B interrupt
	TempB				; Save Port B reading 

; Interrupt tick counters
	TICK_LO				; Interrupt Tick counter lo. Wraps at 9
	TICK_HI				;  ... hi. In milleseconds. Wraps at 99
	TICK100				; 1 = 100ms
	SECONDS				; Seconds counter
	SECONDS_H			; High seconds
	
; Interrupt sound
	Freq				; To store sound frequency value
	Freq_Cnt			; Counts down from Freq during interrupts

; Interrupt timers
	TMR_Flags			; Status Bits for timers - defined below:
;	TMRA_LO				; Timer A - milliseconds
;	TMRA_HI
	TMRB_LO				; Timer B - milliseconds. W_10ms
	TMRB_HI	
;	TMRC_LO				; Timer C - seconds 
;	TMRC_HI				



; GLOBAL RAM for main
	Distance			; 16 bit Distance counter, lsb
	DistanceHi
	Fuel				; 16 bit Fuel counter, lsb
	FuelHi				
	FuelRate			; Fuel rate counter
	MPG_Rate			; Intaneous MPG rate counter
	MPG_RateHi			; ... hi byte
	MPG_RateReset			; Counts fuel upto MPG_RateAmount
		
; Binary to BCD routines:
;	count
;	temp
	R0				; Highest 2 display chars (one used)
	R1				; Middle

	Scratch          		; Scratch Register
					; Wait_S, Warble, LCD driver
	Scratch1    			; Scratch Register 

	L_byte				; 
	H_byte				; Binary I/P
	R2				; Lower 2 display chars

; LCD routines
	CHAR				; Save char/inst to print	
	CHAR2				; Save char to print
	TablePtr			; Table message pointer
	Cursor				; LCD Cursor Posn
;	MsgLen				; Lenght of a table message
;	WhichMsg 			; Save message pointer (CenMsg)
;	LCD_T2				; Temp 4 bit xfer to port: Wh2LCDl
;	LCD_T				; Reading busy flag: Busy_Q					
	ENDC

; Re-use some of the ram

; LCD routines
MsgLen	equ	CHAR			; Lenght of a table message
WhichMsg equ	CHAR2			; Save message pointer (CenMsg)
LCD_T2	EQU	Scratch			; Temp 4 bit xfer to port: Wh2LCDl
LCD_T	EQU	Scratch			; Reading busy flag: Busy_Q					

; B2_BCD
count	equ	Scratch
temp	equ	CHAR2

; Math routines RAM (some MUST be contigous memory):
ACCaLO  equ     R0
ACCaHI  equ     R1
ACCbLO  equ     Scratch			; Result saved here
ACCbHI  equ     Scratch1
ACCcLO  equ     L_byte
ACCcHI  equ     H_byte
ACCdLO  equ	R2     
ACCdHI  equ     CHAR
;temp - see B2_BCD



; TMR_Flags: 
;#define TMRA_EXP 	TMR_Flags, 0	; 0 = timer A has expired.
#define	FuelIncEE	TMR_Flags, 0	; 1 = Increment Fuel EE data reg

#define TMRB_EXP 	TMR_Flags, 1	; 0 = timer B has expired.

;#define TMRC_EXP 	TMR_Flags, 2	; 0 = timer B has expired.
#define	DistanceIncEE	TMR_Flags, 2	; 1 = Increment Distance EE data reg

#define SecondsIncEE	TMR_Flags, 3	; 1 = Increment Seconds EE data reg
#define Snd_On   	TMR_Flags, 4	; 0 = Sound off.		
#define FuelRateMeasure	TMR_Flags, 5	; 1 = FuelRate counter incrementing
#define	MPG_RateMeasure	TMR_Flags, 6	; 1 = MPG_Rate counter incrementing
#define	HiFuelDistance	TMR_Flags, 7	; 1 = Fuel or Distance > $FFFF
	page
;*************************************************************************
; EE data File Registers:	
;*************************************************************************

CBLOCK  d'0'       			; Begin EE data registers
	PowerUpCount			; Number of time device powered up
	PowerUpCountHi			; ... Hi byte
	FuelEE				; Third most sig Fuel counter
	DistanceEE			; Third most sig Distance counter
	SecondsEE			; Highest seconds counter
	endc

; EEProm data area (PicStart doen't suppor this)
;	ORG     H'2100'
;	DE      "Automotive Fuel Monitor System KG, 1995"

	PAGE
;
;****************************************		
; I/O Port Usage			*
;****************************************
;
	ifdef	Debug
Port_1		equ	h'2e'		; Use ram in debug mode
Port_2		equ	h'2f'
	else
Port_1  	equ     PORTA
Port_2		equ	PORTB
	endif

; LCD data port
LCD_DATA	EQU	Port_2		; Connect to LCD data (4 or 8 pins)
LCD_TRIS 	EQU	Port_2		; Change LCD_DATA i/o 


; Lcd Control signals:
LCD_CNTL	EQU	Port_1
#define	LCD_E		LCD_CNTL, 0		; LCD 'E' stobe output
#define	LCD_RW 		LCD_CNTL, 1		; LCD Hi = reading lcd data
#define	LCD_RS		LCD_CNTL, 2		; LCD Hi = data and not instructions

#define	SpeakerPos	Port_1,   3		; Speaker o/p (+ve)
;#define SpeakerNeg	Port_1,	  2		; -ve of speaker if defined
#define FuelSensor	7			; Flow meter sensor, 
#define	Odometer	6			; Odomoter (from speedometer)
#define EEclearButton	5
	page
;*************************************************************************
;
; Start of code
;
;*************************************************************************
        ORG     h'00'    		; Reset 'vector'

        CALL    INIT			; Initialise everything
;        goto	testing
        GOTO    START			; Jump to start

        ORG     h'04'			; Interrupt 'vector'
        GOTO    S_INT      		; Service Interrupt


;	goto 	START

include messages.asm			; Display message tables
	page
;********************************************************************
; Start of code
;********************************************************************

START   
	Tone	d'5', d'10'	
	call	InitLCD			; Initialise the display

	call	SplashAbout		; Display s/w info

	call	ClearDispEE		; Clear EE Data
	
; Init HiFuelDistance flag
	CallW	MovEEw,	DistanceEE	; Get Hi EE byte of distance
	skpz				; 0, don't set flag
	bsf	HiFuelDistance		; Use FuelEE, DistanceEE as hi bytes
	CallW	MovEEw, FuelEE
	skpz
	bsf	HiFuelDistance		; Use FuelEE, DistanceEE as hi bytes

;********************************************************************
; Main Loop
;********************************************************************
MainLoop	
	clrwdt				; Also cleared in Wait routine

	Call	DisplayDistance		; Display cumulative distance
	
	Call	DisplayFuel		; Display cumulated Fuel

	Call	DisplayTime		; Display elapsed time
	
	CallW	PosCurs, MPGposn	; Position LCD Cursor
	Call	PrintMPG		; Calculate and print MPG
	
	call	HandleFuelRate		; Check/Print fuel rate counter

	call	HandleMPG_Rate		; Check/print mpg rate counter

	call	HandleEECounters	; Increment EE counters if required
					; 	(Fuel, Distance and Seconds)					
	call	HandleButtons		; Check/process any buttons pressed
	
	goto	MainLoop
	
	page
;********************************************************************
;
; Included Subroutine modules:
include library.asm			; General purpose routines
	page
include LCD.ASM				; LCD driver
	page
include dbl_divs.asm			; MChip devision routines
	page
include	EELIB.ASM			; Data eeprom library routines
	PAGE
;*************************************************************************
; Application Specific Subroutines
;*************************************************************************

; Get Distance counters (DistanceEE, DistanceHi, Distance)
; If DistanceEE >0 then use DistanceEE and DistanceHI
; 	else use DistanceHi and Distance
DisplayDistance
	CallW	PosCurs, DistancePosn	; Position LCD Cursor
	btfsc	HiFuelDistance
	goto	DoHiDistance
	CallW	PrintIntW, Distance	; Print journey elapsed distance
	return
DoHiDistance
	CallW	MovEEw,	DistanceEE	; Get Hi EE byte of distance
	movwf	H_byte
	MOVSD	DistanceHi, L_byte	; Get 'lo' byte
	Call	PrintInt
	return
	
; Get and display Fuel
; If FuelEE > 0 then Use FuelEE and FuelHi
;		else use FuelHi and Fuel
DisplayFuel
	CallW	PosCurs, FuelPosn	; Position LCD Cursor
	btfsc	HiFuelDistance
	goto	DoHiFuel
	CallW	PrintIntW, Fuel		; Print journey elapsed fuel
	return
DoHiFuel
	CallW	MovEEw, FuelEE		; Get Hi EE of Fuel
	movwf	H_byte
	MOVSD	FuelHi, L_byte		; get 'lo'byte
	Call	PrintInt
	return


; Get and display time
DisplayTime
	CallW	PosCurs, TimePosn	; Position LCD Cursor
	CallW	PrintIntW, SECONDS	; Print journey time elapsed
	return

; HandleButtons
; Check if user pressed a button and process event if so
HandleButtons
	btfsc	Port_2,	EEclearButton	; User requests EE data clear?
	return				; No button pressed
	CallW	Wait_S,	d'1'		; Wait a sec
	btfsc	Port_2,	EEclearButton
	return				; Failed to stay pressed
	goto	ClearDispEE	
; Cleare EE, except for PoerUPCount & display
ClearDispEE
	CallW 	CenMsg, EECleared-TableStart	
	CallW	MovEEw, PowerUpCount	; Save PowerUpCount
	movwf	Scratch
	call	ClearEE			; Clear EE data
	bcf	HiFuelDistance		; Use low fuel and dist words
	Movfw	Scratch			; Retrieve power up counter
	Call	MovwEE 			; Save power up counter in EE	
	call	ClearHome
	Return


; HandleEECounters
; Check if Fuel, Distance or Seconds have rolled over $FFFF and if so
; increment associated EE counter.
HandleEECounters
	btfss	FuelIncEE		; Requst to increment EE counter?
	goto	NotFuelEE
	CallW	IncEEw, FuelEE		; Increment EE counter
	bcf	FuelIncEE		; Clear increment request
	bsf	HiFuelDistance		; Fuel or distance > $FFFF
	
NotFuelEE	
	btfss	DistanceIncEE		; Requst to increment EE counter?
	goto 	NotDistanceEE
	CallW	IncEEw, DistanceEE	; Increment EE counter
	bcf	DistanceIncEE		; Clear increment request
	bsf	HiFuelDistance		; Fuel or distance > $FFFF
	
NotDistanceEE
	btfss	SecondsIncEE		; Requst to increment EE counter?
	goto	NotSecondsEE
	CallW	IncEEw, SecondsEE	; Increment EE counter
	bcf	SecondsIncEE		; Clear increment request

NotSecondsEE
	return


; Display About message and number of times powered up.
; Increment number of times powered up (in EE data)
SplashAbout
	CallW 	CenMsg, AboutMsg-TableStart
	CallW	PosCurs, PowerUpPosn	
	CallW	DispMsg, PowerUPmsg-TableStart 	
	CallW	IncEEw, PowerUpCount	; Increment power up counter
	skpz
	goto	NoPwrHiInc
	CallW	IncEEw, PowerUpCountHi	; Incremet Hi byte of pwr up cntr
NoPwrHiInc
	CallW	PrintEEintW, PowerUpCount
	CallW	Wait_S, AboutDispTime	; Leave message on screen for a while
	call	ClearHome

; Display EE counters
	CallW	PosCurs, DistancePosn
	CallW	MovEEw, DistanceEE
	call	PrintWint

	CallW	PosCurs, FuelPosn
	CallW	MovEEw, FuelEE
	call	PrintWint

	CallW	PosCurs, TimePosn
	CallW	MovEEw, SecondsEE
	call	PrintWint

	CallW	Wait_S, AboutDispTime
	call	ClearHome

	return

; Clear Fuel and distance counters in RAM
ClearCounters
	clrf	Fuel
	clrf	FuelHi
	clrf	Distance
	clrf	DistanceHi
	return


; HandleMPG_Rate
; Check if MPG_RateMeasure is off (finished) and if so print MPG_Rate,
; reset MPG_Rate and start measuring again. 
; 
HandleMPG_Rate
	btfsc	MPG_RateMeasure		; Leave if measurement in progress
	return

	CallW	PosCurs, MPG_RatePosn
	CallW	PrintIntW, MPG_Rate
	clrf	MPG_Rate		; Start a new measurement
	clrf	MPG_RateHi		
	bsf	MPG_RateMeasure		; Let new count betin
	return


; HandleFuelRate
; Check if fuel rate time is up (Timer B) and if so
; display FuelRate, clear it and restart Timer B 
HandleFuelRate
	btfsc	TMRB_EXP		; Timer B running?
	return				; Yes so fuel rate still counting
	CallW	PosCurs, FuelRatePosn	; Where to print

	bcf	FuelRateMeasure		; Stop counting fuel rate
	movfw	FuelRate
	call	PrintWint		; Print as 3 digits

	MOVLF16	TMRB_LO, FuelRateTime	; Time that fuel rate counter runs
	clrf	FuelRate		; Start again
	bsf	TMRB_EXP		; Timer b running
	bsf	FuelRateMeasure		; Start measuring fuel rate
	
	return

; PrintMPG
; Devide B/A with result in A
; (Distance/(Fuel/100))
; Then print result on LCD
; if HiFuelDistance 	then  
;				FuelEE, FuelHi & DistanceEE  DistanceHi
;			else	
;				FuelHi & Fuel, DistanceHi & Distace	
;
PrintMPG
	btfsc	HiFuelDistance		; Check if EE & Hi bytes to be used
	goto	MpgHiBytes
	MOVSD16	Fuel, ACCbLO
	MOVLF16	ACCaLO, MPG_RateAmount
	Call	D_divS			; Fuel/MPG_RateAmount in ACCb
	MOVSD16 ACCbLO, ACCaLO		; B->A
	
	MOVSD16 Distance, ACCbLO
	call    D_divS          	; Result: ACCb/ACCa, Remainder: ACCc
	CallW	PrintIntW, ACCbLO
	return

MpgHiBytes				; Use FuelEE, FuelHi etc
	MOVSD	FuelHi, ACCbLO
	CallW	MovEEw, FuelEE		; Get EE most significant byte
	movwf	ACCbHI
	MOVLF16	ACCaLO, MPG_RateAmount	; Devide into fuel
	Call	D_divS			; Fuel/MPG_RateAmount in ACCb (Hi EE bytes)
 	MOVSD16 ACCbLO, ACCaLO		; B->A

	MOVSD	DistanceHi, ACCbLO	; Get distance
	CallW	MovEEw, DistanceEE	; Get distance EE most sig byte
	movwf	ACCbHI
	call	D_divS			; Devide Distance by Fuel
	CallW	PrintIntW, ACCbLO	; Print result in ACCb
	return
	page
;*************************************************************************
;	
; Service Interrupt
; Check RTCC overflow and check Timers (A), B, (C), sound
; Check if a Fuel or Distance pulse has occurred
;*************************************************************************

S_INT              
	MOVWF	I_W_S			; Save w register
	MOVFF	I_S_S, STATUS		; Save status reg (carry, z flags etc.)
	MOVFF	I_FSR_S, FSR		; Save FSR reg
	bcf	STATUS, RP0		; Make sure we're in page 0
	BTFSS	INTCON,	T0IF		; Check RTCC overflow
	GOTO	NotRTCC

; RTCC has overflowed (10 KHz or 100 micro seconds intervals)
	bcf	INTCON, T0IF		; Clear rtcc overflow interrupt
	MOVLF	TMR0, h'ff' -d'100' -d'7' ; Leave 100 cycles to overflow
	; (7 cycles to figure out it's rtcc)

; ** Here every 100 micro seconds

;	Test Sound On bit
	BTFSC	Snd_On
	call	C_Snd			; Go check if speaker needs a toggle

Do_Tic	INCF	TICK_LO,F
	MOVFW	TICK_LO		 
	XORLW	D'9'			; Tick_lo =9 then reset
	SKPZ
	GOTO	FinishedRTCC		; End here this time

; ** Here every 1ms
	CLRF	TICK_LO		
	INCF	TICK_HI,F		; 1 ms tick counter
	MOVFW	TICK_HI
	XORLW	D'99'			; Reset before 100
	SKPZ	
	goto	LastTimers
	CLRF	TICK_HI			; Here every 100ms
	INCF	TICK100,f			
	MOVFW	TICK100
	XORLW	D'9'
	SKPZ	
	goto	LastTimers
	CLRF	TICK100
; Here every Second
	INCF	SECONDS,F		; Here every second
	SKPNZ				; Check for overflow
	incf	SECONDS_H, f		; Hi seconds counter
	skpnz
	bsf	SecondsIncEE		; Request EE seconds increment

; Decrement timer c (seconds timer) if enabled and disable if expired	
;	BTFSC	TMRC_EXP		; Is it enabled?
;	CALL	C_TMRC			; Check timer C
	
LastTimers
; Decrement remaining enabled s/w timers, disable any that have expired
;	BTFSC	TMRA_EXP		; Is it enabled?
;	CALL	C_TMRA			; Check Timer A
	
	BTFSC	TMRB_EXP		; Is it enabled?	
	CALL	C_TMRB			; Check timer B


; Continue servicing Interrupt
FinishedRTCC
NotRTCC
; Check Port_B 7:4 pin change
	btfss	INTCON, RBIF		; Port B 4:7 Change?
	goto	NotPortB		; Not port b interrupt

	movfw	Port_2			; Read the port to remove mismatch
	movwf	TempB			; Save for next I_LastPB
	xorwf	LastPB, f		; Find out which bits changed

	btfsc	LastPB, FuelSensor	; Was fuel sensor pulse?
	call	CountFuel		; Yes.

	btfsc	LastPB, Odometer	; Was it speedometer?
	call	CountDistance		; Yes.

	movfw	TempB
	movwf	LastPB			; Save for next interrupt
	bcf	INTCON,	RBIF		; Clear port B change interrupt

; Continue servicing Interrupt
NotPortB
;	btfss	INTCON, INTF		; Check if INT (RB0)
;	goto	NotInt			; Not INT pin
;	bcf	INTCON, INTF		; Clear the interrupt
;	goto	$			; ** INT not tested  **	

; Exit service interrupt routine
NotInt
Int_Ex	
	MOVFF	FSR, I_FSR_S		; Restor FSR register
	MOVFF	STATUS, I_S_S		; Restore Status register	
	swapf	I_W_S, f		; Swap to get ready for retrieve
	swapf	I_W_S, w		; Retrieve without changing STATUS
	RETFIE

; CountFuel
; Fuel pulse has occurred so increment Fuel counter
CountFuel
	btfss	Port_2, FuelSensor	; Count only lo to hi transition
	return

	btfsc	FuelRateMeasure 	; Increment fuel rate counter?
	incf	FuelRate, f		; Fuel rate counter 

	incf	MPG_RateReset,f		; Count fuel 'till MPG_RateAmount
	movfw	MPG_RateReset
	xorlw	MPG_RateAmount		; Test for end of measurment
	skpz				; Zero if equal
	goto	ContinueFuelCount
	bcf	MPG_RateMeasure		; Stop measuring mpg rate
	clrf	MPG_RateReset		; Reset fuel counter
	
ContinueFuelCount
	incf	Fuel, f			; Fuel consumed counter
	skpz
	return
	incf	FuelHi, f
	bnz	ExitFuelCount		; Check for overflow
;	Call	ClearCounters
	bsf	FuelIncEE		; Request EE fuel counter increment

ExitFuelCount
	return


; CountDistance
; Distance pulse has occurred so increment Distance counter
CountDistance
	btfss	Port_2, Odometer	; Count only lo to hi transition
	return

	btfsc	MPG_RateMeasure		; Are we measuring mpg rate?
	incf	MPG_Rate,f		; Yes so increment
	skpnz
	incf	MPG_RateHi, f		; .. and hi byte if needed
	
	incf	Distance, f		; Total journey distance
	skpnz
	incf	DistanceHi, f
	bnz	ExitCountDistance	; Check for overflow
;	Call	ClearCounters
	bsf	DistanceIncEE		; Request Distance EE increment

ExitCountDistance
	return


; C_TMRA
; Decrement and Clear timer bit (TMRA_EXP) if it has expired
;C_TMRA
;	MOVLW	TMRA_LO			; 16 bit timer to decrement
;	CALL	Dec16W			; Decrement 16 bit timer
;	SKPNZ				; Times out?
;	BCF	TMRA_EXP		; Timer rolled over so mark it expired
;	RETURN

; C_TMRB
; Decrement and Clear timer bit if it has expired
; (used by W_10ms)
C_TMRB
	MOVLW	TMRB_LO			; 16 bit timer to decrement
	CALL	Dec16W			; Decrement 16 bit timer
	SKPNZ				; Times out?
	BCF	TMRB_EXP		; Timer rolled over so mark it expired
	RETURN

; C_TMRC
; Decrement and Clear timer bit if it has expired
;C_TMRC
;	MOVLW	TMRC_LO			; 16 bit timer to decrement
;	CALL	Dec16W			; Decrement 16 bit timer
;	SKPNZ				; Times out?
;	BCF	TMRC_EXP		; Timer rolled over so mark it expired
;	RETURN

; Toggle speaker at a rate depending on Freq file register
C_Snd
	DECFSZ	Freq_Cnt, f
	return
	
	Call	TOGGLE			; Toggle Speaker
	movfw	Freq
	movwf	Freq_Cnt
	return
	PAGE	
;*************************************************************************
;	
; Initialise ports etc
;
;*************************************************************************
INIT
	CALL 	ClearRam		; Clear all file registers
;*** Page 1
	BSF	STATUS, RP0		; Page 1

; Port A Tri-State: 0=Output	
    	MOVLW   B'00000000'		; PortA
        MOVWF   TRISA - H'80'		; I/O
        
; Port B tri-State: 0=Output
        MOVLW   B'11110000'     	; PortB 
        MOVWF   TRISB - H'80'		; I/O

; Port B pullups, BCF = Enable
	bcf	OPTION_REG-H'80', NOT_RBPU	; Pullups for i/p's

; RTCC (TMR0) signal source, 1=RTCC external pin (BSF)
	BCF	OPTION_REG-H'80', T0CS		; TMR0 internal	

; Prescaler assignment, BSF = 1 = wdt:
; Assigning it to RTCC already causes a devide by 2 (if PS0..2 = 0) 
	BSF	OPTION_REG-H'80', PSA		; Prescaler

; Prescaler values:
	BSF	OPTION_REG-H'80', PS0
	BCF	OPTION_REG-H'80', PS1
	BSF	OPTION_REG-H'80', PS2

;*** Page 0	
	BCF	STATUS, RP0		; Back to page 0

        MOVLW   b'00000000'     	; Turn o/p's off
        MOVWF   Port_1
        MOVWF	Port_2


	clrf	INTCON			; Clear all interrupts
; Enable interrupts (BSF=on)
	BSF	INTCON, GIE		; Global interupts
	BSF	INTCON, T0IE		; RTCC interupts for TMR0
	bsf	INTCON, RBIE		; Port B 4:7 interrupt
;	bcf	INTCON, INTE		; INT on PORTB pin RB0
	movfw	Port_2			; Read the port to remove mismatch
	movwf	LastPB			; Init last port b read
	
; Init Timers
	CLRF	TMR_Flags		; Pre-expire all timers

        RETURN

	DE	"Karl Grabe, Kerry Pike, Cork Ireland"        
	DE	"Tel +353 21 284357"

	END
