;******************************************************
;******************************************************
;
; Main Project     : FT301D
; Project Name     : FT301D - Replacement Digital Display
; File Name        : ft301d_main.asm
; Version          : A03
; PIC Used         : PIC16F887
; Assembler        : MPLAB MPASMWIN from Microchip Technology, Inc.
; Initial Date     : May 1, 2011
; Last Update date : Nov 3, 2012
; Firmware Eng.    : WA7ZVY
; HW Design Eng.   : WA7ZVY
;
;******************************************************
;
; Description of this code:
;
; This code starts execution upon the release of the
; power on reset condition. The code continually
; executes the main routine and executes the
; interrupt code upon an interrupting condition.
;
;	1) reset_vector
;	2) interrupt_vector, interrupt dispatcher
;	3) main loop
;
; ******************************************************
;
; Function List (in top-2-bottom order):
;   void interrupt(void);
;   void main(void);
;
;******************************************************
;
;   Modification History:
;   =-=-=-=-=-=-=-=-=-=-=
;   20110501 pm - Initial creation.
;   20121103 pm - Corrected WWV readout to fixed at " 5.000.0"
;   20121104 pm - Display dashes for unpopulated fixed channel xtals
;
;******************************************************

;*****************************************************
;   === Include files ===
;*****************************************************
	LIST   P=16F887				;List directive to define processor

#include	P16F887.INC			;Processor specific variable definitions
#include	constants.inc		;Coding constants
#include	micro_bits.inc		;Hardware defined bits
#include	variable_def.inc	;Variable definitions


;*****************************************************
;       === Configuration Word Definitions ===
;*****************************************************
; Defines for PIC16F887 operation in the FT301D Board

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

	__CONFIG _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_OFF & _WDT_OFF & _INTOSCIO
	__CONFIG _CONFIG2, _WRT_OFF & _BOR40V

; '__idlocs' sets the four ID locations to the hexadecimal value of expression.
; These are not readable by the cpu, but can be read by the programning hardware.

	__idlocs	0x1234

;**********************************************************************

RESET_VECTOR	ORG	0x0000	; processor reset vector location
;	nop						; for icd debug
	pagesel	ft301d_main		;
    goto    ft301d_main		; go to beginning of program

;	This code contains goto statements that are located
;	at the beginning of each page of processor memory
;	(except page0).  These goto statements send
;	run-amuck code execution back through the reset
;	vector location in page0 at location 0.  All unused
;	program memory locations are filled with goto 0x0000
;	instructions.
CRASH_VECTOR_PAGE1	ORG	0x0800
	pagesel	RESET_VECTOR
	goto	RESET_VECTOR

CRASH_VECTOR_PAGE2	ORG	0x1000
	pagesel	RESET_VECTOR
	goto	RESET_VECTOR

CRASH_VECTOR_PAGE3	ORG	0x1800
	pagesel	RESET_VECTOR
	goto	RESET_VECTOR



;*****************************************************
;*****************************************************
; 	Name:	interrupt
;	Abstract:
;	This is the interrupt handler. It is entered
;	whenever there is an interrupt asserted.
;	It looks for the source of the interrupt
;	and dispatches to the appropriate interrupt
;	handling routine.
;	This routine is the top level interrupt code (ie. it
;	calls other routines which return to it, but
;	it is never called by other routines).
;
;	Sources of interrupts are:
;	1). Timer/Counter 1
;
;	Callable Routines:  None.
;
;	Called Routines:
		extern	timer1_irq_service
		extern	timer2_irq_service
;
;	Global Variables Used:
;		w_temp
;		status_temp
;		pclath_temp
;
;	Local Variables Used:  None.
;		
;	Return Values:	None.
;		
;*****************************************************
;*****************************************************
INTERRUPT_VECTOR	ORG	0x0004	; processor interrupt vector location
; save current state
    movwf   w_temp          ; save off current W register contents
    movf    STATUS,W        ; move status register into W register
    movwf   status_temp     ; save off contents of STATUS register
    movf    PCLATH,W        ; move pclath register into w register
    movwf   pclath_temp     ; save off contents of PCLATH register

; call isr subroutines if an interrupt is pending
	banksel	BANK0
	pagesel	isr_1
	btfss	PIR1, TMR1IF
	goto	isr_1
	pagesel	timer1_irq_service
	call	timer1_irq_service

isr_1
	banksel	BANK0
	pagesel	isr_2
	btfss	PIR1, TMR2IF
	goto	isr_2
	pagesel	timer2_irq_service
	call	timer2_irq_service

isr_2
; restore previous state	
    movf    pclath_temp,W   ; retrieve copy of PCLATH register
    movwf   PCLATH          ; restore pre-isr PCLATH register contents
    movf    status_temp,W   ; retrieve copy of STATUS register
    movwf   STATUS          ; restore pre-isr STATUS register contents
    swapf   w_temp,F
    swapf   w_temp,W        ; restore pre-isr W register contents
    retfie                  ; return from interrupt



;*****************************************************
;   === Define the LED Segment Lookup Table ===
;
;  This table contains the LED segments to light up
;  for each character.  To look up a pattern for an
;  ASCII character, subtract 20 from the ASCII value
;  to use as the index into the table.
;
;  This table is located in the first 256 bytes of
;  program memory space so no need to worry about
;  crossing a 256 byte boundary when looking up a value.
;*****************************************************
	global	segment_table

segment_table
	addwf	PCL,F

	dt		CHAR_SP
	dt		CHAR_BANG
	dt		CHAR_QUOTE
	dt		CHAR_POUND
	dt		CHAR_DOLLAR
	dt		CHAR_PERCENT
	dt		CHAR_AMPERSAND
	dt		CHAR_SQUOTE
	dt		CHAR_LPAREN
	dt		CHAR_RPAREN
	dt		CHAR_SPLAT
	dt		CHAR_PLUS
	dt		CHAR_COMMA
	dt		CHAR_MINUS
	dt		CHAR_PERIOD
	dt		CHAR_SLASH

	dt		CHAR_0
	dt		CHAR_1
	dt		CHAR_2
	dt		CHAR_3
	dt		CHAR_4
	dt		CHAR_5
	dt		CHAR_6
	dt		CHAR_7
	dt		CHAR_8
	dt		CHAR_9
	dt		CHAR_CO
	dt		CHAR_SC
	dt		CHAR_LT
	dt		CHAR_EQ
	dt		CHAR_GT
	dt		CHAR_QM

	dt		CHAR_AT
	dt		CHAR_A
	dt		CHAR_B
	dt		CHAR_C
	dt		CHAR_D
	dt		CHAR_E
	dt		CHAR_F
	dt		CHAR_G
	dt		CHAR_H
	dt		CHAR_I
	dt		CHAR_J
	dt		CHAR_K
	dt		CHAR_L
	dt		CHAR_M
	dt		CHAR_N
	dt		CHAR_O

	dt		CHAR_P
	dt		CHAR_Q
	dt		CHAR_R
	dt		CHAR_S
	dt		CHAR_T
	dt		CHAR_U
	dt		CHAR_V
	dt		CHAR_W
	dt		CHAR_X
	dt		CHAR_Y
	dt		CHAR_Z
	dt		CHAR_LB
	dt		CHAR_BS
	dt		CHAR_RB
	dt		CHAR_TD
	dt		CHAR_UL

MHz_digit_table
						;A   B   C   D
						;PORT PINS
						;R   R   R   R
						;C   D   D   D
						;7   4   3   2
	addwf	PCL,F
	dt		" "			;0   0   0   0
	dt		"8"			;0   0   0   1
	dt		"4"			;0   0   1   0
	dt		" "			;0   0   1   1
	dt		" "			;0   1   0   0
	dt		" "			;0   1   0   1
	dt		" "			;0   1   1   0
	dt		" "			;0   1   1   1
	dt		"1"			;1   0   0   0
	dt		"9"			;1   0   0   1
	dt		"5"			;1   0   1   0
	dt		" "			;1   0   1   1
	dt		"3"			;1   1   0   0
	dt		" "			;1   1   0   1
	dt		"7"			;1   1   1   0
	dt		" "			;1   1   1   1

MHz_digit_table_overflow	;This table is for the case where
							;b0_overflow = TRUE && ADD_500KHz~ = TRUE
						;A   B   C   D
						;PORT PINS
						;R   R   R   R
						;C   D   D   D
						;7   4   3   2
	addwf	PCL,F
	dt		" "			;0   0   0   0
	dt		"9"			;0   0   0   1
	dt		" "			;0   0   1   0
	dt		" "			;0   0   1   1
	dt		" "			;0   1   0   0
	dt		" "			;0   1   0   1
	dt		" "			;0   1   1   0
	dt		" "			;0   1   1   1
	dt		"2"			;1   0   0   0
	dt		"0"			;1   0   0   1
	dt		" "			;1   0   1   0
	dt		" "			;1   0   1   1
	dt		"4"			;1   1   0   0
	dt		" "			;1   1   0   1
	dt		" "			;1   1   1   0
	dt		" "			;1   1   1   1

MHz_digit_table_underflow	;This table is for the case where
							;b0_underflow = TRUE && ADD_500KHz~ = FALSE
						;A   B   C   D
						;PORT PINS
						;R   R   R   R
						;C   D   D   D
						;7   4   3   2
	addwf	PCL,F
	dt		" "			;0   0   0   0
	dt		"7"			;0   0   0   1
	dt		"3"			;0   0   1   0
	dt		" "			;0   0   1   1
	dt		" "			;0   1   0   0
	dt		" "			;0   1   0   1
	dt		" "			;0   1   1   0
	dt		" "			;0   1   1   1
	dt		"0"			;1   0   0   0
	dt		"8"			;1   0   0   1
	dt		" "			;1   0   1   0
	dt		" "			;1   0   1   1
	dt		" "			;1   1   0   0
	dt		" "			;1   1   0   1
	dt		"6"			;1   1   1   0
	dt		" "			;1   1   1   1



;*****************************************************
;   === Define the Special Messages Table       ===
;*****************************************************
; Format is: ASCII message
; NOTE!  All of this resides in the first 256 words of code space, therefore
; there is no need to worry about crossing a 256 word boundary.
	global	message_table, message_hello,  message_yaesu
	global	message_ft301, message_ledtest

message_table
message_hello
	addwf	PCL,F
	dt	" HELLO"
message_yaesu
	addwf	PCL,F
	dt	" YAESU"
message_ft301
	addwf	PCL,F
	dt	"FT-301"
message_ledtest
	addwf	PCL,F
	dt	"888888"



MAIN_CODE	CODE			;ft301d_main code space

;*****************************************************
;*****************************************************
;
;	Name:		ft301d_main
;	
;	Abstract:
;		This is the main entry point for code execution
;		on the ft301d display replacement board.
;		This routine is the highest level code (ie. it
;		calls other routines which return to it, but
;		it is never called by other routines).
;
;	Callable Routines:  None.
;
;	Called Routines:
		extern	init_hardware, delay_100msec, binary_to_decimal
		extern	divide32bd10
		extern	convert_to_segments, load_message
;
;	Global Variables Used:
;		b0_counter0, b0_counter1, b0_counter2, b0_counter3
;		b0_digit0, b0_digit1, b0_digit2, b0_digit3, b0_digit4, b0_digit5
;		arg1_wrd, arg2_wrd, arg3_wrd, arg4_wrd, arg5_wrd
;		b0_underflow
;		b0_overflow
;		b0_tmp1_lo
;		
;	Local Variables Used:
;	
;	Return Values:	N/A.
; 		
;*****************************************************
;*****************************************************
ft301d_main
	pagesel	init_hardware		;Initialize the various hardware functions
	call	init_hardware
	banksel	BANK0
	pagesel	ft301d_main

	movlw	" "					;Initialize the digit memories to all space characters
	movwf	b0_digit0
	movwf	b0_digit1
	movwf	b0_digit2
	movwf	b0_digit3
	movwf	b0_digit4
	movwf	b0_digit5
	pagesel	convert_to_segments
	call	convert_to_segments
	pagesel	ft301d_main

	clrf	b0_digit_select		;Initialize the digit select
	clrf	b0_dpoint_flags		;Initialize the decimal point activation flags
	clrf	b0_error_flags		;Clear the error flag

	banksel	BANK1				;Enable the timer1 and timer 2 interrupts
	bsf		PIE1,TMR1IE
	nop
	bsf		PIE1,TMR2IE
	banksel	BANK0
	bsf		INTCON,PEIE
	nop
	bsf		INTCON,GIE

	;NOTE: This is where we can put some startup
	;messages in the display and then spin for awhile
	;as they are displayed.
	; <<<=======

ft301d_main_startup_messages
	banksel	BANK0

	movlw	message_hello - message_table	;Display " HELLO" message
	movwf	arg1_lo
	pagesel	load_message
	call	load_message
	movlw	0x0a
	movwf	arg1_lo
	pagesel	delay_100msec
	call	delay_100msec

	movlw	message_yaesu - message_table	;Display " YAESU" message
	movwf	arg1_lo
	pagesel	load_message
	call	load_message
	movlw	0x0a
	movwf	arg1_lo
	pagesel	delay_100msec
	call	delay_100msec

	movlw	message_ft301 - message_table	;Display "FT-301" message
	movwf	arg1_lo
	pagesel	load_message
	call	load_message
	movlw	0x0a
	movwf	arg1_lo
	pagesel	delay_100msec
	call	delay_100msec

	banksel	BANK0				;Display the LED Test Message (all on!)
	movlw	B'00111111'			;Turn on all of the decimal point activation flags
	movwf	b0_dpoint_flags
	movlw	message_ledtest - message_table	;Display "888888" message
	movwf	arg1_lo
	pagesel	load_message
	call	load_message
	movlw	0x0a
	movwf	arg1_lo
	pagesel	delay_100msec
	call	delay_100msec

	pagesel	ft301d_main

ft301d_main_loop
	banksel	BANK0
								;Sync up with the 5Hz Gate signal
fm_1
	btfsc	PORTB,5				;Spin waiting for the Timer 1 Gate to be inactive
	goto	$-1
	bcf		T1CON,TMR1ON		;Turn off Timer 1
	clrf	TMR1L				;Clear the low order frequency counter registers
	clrf	TMR1H
	clrf	b0_counter2			;Clear the high order frequency counter registers
	clrf	b0_counter3
	bsf		T1CON,TMR1ON		;Turn Timer 1 back on
	btfsc	PORTB,5				;check to see if the gate went active while we were
	goto	fm_1				; clearing the counter registers, if it did, go back
								; and try again

	btfss	PORTB,5
	goto	$-1					;Spin until the gate goes active
	btfsc	PORTB,5
	goto	$-1					;Loop here until the gate closes

								;We are now at the point where the gate just went inactive
	bcf		T1CON,TMR1ON		;Turn Timer 1 off and
	movf	TMR1L,W				;capture the 16 bit Timer 1 Count value
	movwf	b0_counter0
	movf	TMR1H,W
	movwf	b0_counter1

	clrf	b0_underflow		;Clear the underflow and overflow flags
	clrf	b0_overflow
	clrf	b0_error_flags		;Clear the error flag
	movlw	B'00010010'			;Set the decimal point activation flags for normal readout
	movwf	b0_dpoint_flags

								;The upper 16 bits are already in b0_counter2 and 3.
								;The count value is for a 0.1 second period.  The
								;incoming frequency is 13.0MHz to 13.5MHz.  So, the
								;count value is going to be 1,300,000 decimal to
								;1,350,000 decimal (0x13d620 to 0x149970).

								;But, first check for a zero count having occurred.
								;A zero count would be caused by no xtal being installed
								;in a selected "Fix" frequency switch position. We'll
								;just check the two most significant bytes for zero.
	movf	b0_counter3,F
	btfss	STATUS,Z
	goto	fm_1_1
	movf	b0_counter2,F
	btfss	STATUS,Z
	goto	fm_1_1
	movlw	"-"					;The count was zero, so put dashes in the non-MHz display digits
	movwf	b0_digit0
	movwf	b0_digit1
	movwf	b0_digit2
	movwf	b0_digit3
	goto	fm_19				;Since count was zero, bypass all of the non-MHz digit calculations

								;To scale the count for display, divide the count
								;by 0x0a, then subtract 0x1fbd0, and finally
								;convert it to decimal nibbles and ASCII characters.
fm_1_1
	movf	b0_counter0,W		;Put the values into a working register set
	movwf	arg1_lo
	movf	b0_counter1,W
	movwf	arg1_hi
	movf	b0_counter2,W
	movwf	arg2_lo
	movf	b0_counter3,W
	movwf	arg2_hi

	pagesel	divide32bd10		;Divide the value by 10.
	call	divide32bd10		;Result returned in arg5_wrd(MSW), arg4_wrd(LSW)
	pagesel	ft301d_main
	banksel	BANK0

;----------------------------------------------------------------------------
	btfss	PORTD,6				;If ADD_500KHz~ == FALSE
	goto	fm_7
	movlw	0xd0				;Then subtract the 0x0001fbd0 (130000.) value
	subwf	arg4_lo,F
	btfsc	STATUS,C
	goto	fm_2
	movlw	0x01				;A borrow happened so account for that
	subwf	arg4_hi,F
	btfsc	STATUS,C
	goto	fm_2
	subwf	arg5_lo,F			;A borrow happened so account for that
	btfsc	STATUS,C
	goto	fm_2
	subwf	arg5_hi,F			;A borrow happened so account for that
	btfsc	STATUS,C
	goto	fm_2
	bsf		b0_underflow,0		;Set the underflow flag

fm_2
	movlw	0xfb
	subwf	arg4_hi,F
	btfsc	STATUS,C
	goto	fm_3
	movlw	0x01				;A borrow happened so account for that
	subwf	arg5_lo,F
	btfsc	STATUS,C
	goto	fm_3
	subwf	arg5_hi,F			;A borrow happened so account for that
	btfsc	STATUS,C
	goto	fm_3
	bsf		b0_underflow,0		;Set the underflow flag

fm_3
	movlw	0x01
	subwf	arg5_lo,F
	btfsc	STATUS,C
	goto	fm_4
	movlw	0x01				;A borrow happened so account for that
	subwf	arg5_hi,F
	btfsc	STATUS,C
	goto	fm_4
	bsf		b0_underflow,0		;Set the underflow flag

fm_4
	movlw	0x00
	subwf	arg5_hi,F
	btfsc	STATUS,C
	goto	fm_5
	bsf		b0_underflow,0		;Set the underflow flag

fm_5
		;Now check for an underflow condition
		; If an underflow, then add 0x2710 (10000.) to the value
	btfss	b0_underflow,0
	goto	fm_16
	movlw	0x10
	addwf	arg4_lo,F
	btfss	STATUS,C
	goto	fm_6
	movlw	0x01				;Account for the carry
	addwf	arg4_hi,F
	btfss	STATUS,C
	goto	fm_6
	addwf	arg5_lo,F
	btfss	STATUS,C
	goto	fm_6
	addwf	arg5_hi,F

fm_6
	movlw	0x27
	addwf	arg4_hi,F
	btfss	STATUS,C
	goto	fm_16
	movlw	0x01				;Account for the carry
	addwf	arg5_lo,F
	btfss	STATUS,C
	goto	fm_16
	addwf	arg5_hi,F

	goto	fm_16
;----------------------------------------------------------------------------

fm_7
	btfsc	PORTD,6				;If ADD_500KHz~ == TRUE
	goto	fm_16
	movlw	0x48				;Then subtract only 0x0001e848 (125000.)
	subwf	arg4_lo,F
	btfsc	STATUS,C
	goto	fm_8
	movlw	0x01				;A borrow happened so account for that
	subwf	arg4_hi,F
	btfsc	STATUS,C
	goto	fm_8
	subwf	arg5_lo,F			;A borrow happened so account for that
	btfsc	STATUS,C
	goto	fm_8
	subwf	arg5_hi,F			;A borrow happened so account for that
	btfsc	STATUS,C
	goto	fm_8
	bsf		b0_error_flags,0	;Set the error flag (we should never have a borrow!)

fm_8
	movlw	0xe8
	subwf	arg4_hi,F
	btfsc	STATUS,C
	goto	fm_9
	movlw	0x01				;A borrow happened so account for that
	subwf	arg5_lo,F
	btfsc	STATUS,C
	goto	fm_9
	subwf	arg5_hi,F			;A borrow happened so account for that
	btfsc	STATUS,C
	goto	fm_9
	bsf		b0_error_flags,0	;Set the error flag (we should never have a borrow!)

fm_9
	movlw	0x01
	subwf	arg5_lo,F
	btfsc	STATUS,C
	goto	fm_10
	movlw	0x01				;A borrow happened so account for that
	subwf	arg5_hi,F
	btfsc	STATUS,C
	goto	fm_10
	bsf		b0_error_flags,0	;Set the error flag (we should never have a borrow!)

fm_10
	movlw	0x00
	subwf	arg5_hi,F
	btfsc	STATUS,C
	goto	fm_11
	bsf		b0_error_flags,0	;Set the error flag (we should never have a borrow!)

fm_11
		;Now check for, and flag if, an overflow condition (value >= 0x2710 (10000.))
		; If an overflow, then set the overflow flag
	movf	arg4_lo,W			;First copy the value into a temp working register
	movwf	b0_tmp1_lo
	movf	arg4_hi,W
	movwf	b0_tmp1_hi
	movlw	0xf0				;Add 0xd8f0 to the value and check for a carry
	addwf	b0_tmp1_lo,F
	btfsc	STATUS,C
	incf	b0_tmp1_hi,F
	movlw	0xd8
	addwf	b0_tmp1_hi,F
	btfsc	STATUS,C
	bsf		b0_overflow,0		;There was a carry, so set the overflow flag

;----------------------------------------------------------------------------

fm_16
	movf	arg4_lo,W			;Setup to do the binary to decimal conversion
	movwf	arg1_lo
	movf	arg4_hi,W
	movwf	arg1_hi

	pagesel	binary_to_decimal
	call	binary_to_decimal	;4 decimal digits returned in arg2_wrd
	pagesel	ft301d_main
	banksel	BANK0

fm_18
	movf	arg2_lo,W			;Turn the four least significant into ASCII characaters 0 to 9
	andlw	0x0f
	addlw	0x30
	movwf	b0_digit0

	swapf	arg2_lo,W
	andlw	0x0f
	addlw	0x30
	movwf	b0_digit1

	movf	arg2_hi,W
	andlw	0x0f
	addlw	0x30
	movwf	b0_digit2

	swapf	arg2_hi,W
	andlw	0x0f
	addlw	0x30
	movwf	b0_digit3

	;Now read the IO ports and setup the one and ten MHz digits... also WWV
	;Some confusing bit shuffling goes on here... see the three digit_tables
fm_19
	movf	PORTD,W
	movwf	b0_tmp1_lo
	rrf		b0_tmp1_lo,F
	rrf		b0_tmp1_lo,F
	movlw	0x07
	andwf	b0_tmp1_lo,F
	btfsc	PORTC,7
	bsf		b0_tmp1_lo,3

	btfsc	PORTD,7		;Check to see if we should show WWV (5.000.0 MHz)
	goto	fm_20
	movlw	" "			;Force WWV frequency to 5.000.0
	movwf	b0_digit5
	movlw	"5"
	movwf	b0_digit4
	movlw	"0"
	movwf	b0_digit3
	movwf	b0_digit2
	movwf	b0_digit1
	movwf	b0_digit0
	goto	fm_30

fm_20
	;Figure out which MHz_digit_table to use and then lookup the correct value:

		;Use MHz_digit_table_overflow? ;This table is for the case where
							;b0_overflow = TRUE && ADD_500KHz~ = TRUE
	movf	b0_overflow,F
	btfsc	STATUS,Z
	goto	fm_22
	btfsc	PORTD,6
	goto	fm_22
	movf	b0_tmp1_lo,W
	pagesel	MHz_digit_table_overflow
	call	MHz_digit_table_overflow	;on return W contains the ASCII digit
	pagesel	ft301d_main
	movwf	b0_digit4
	goto	fm_26

fm_22
		;Use MHz_digit_table_underflow? ;This table is for the case where
							;b0_underflow = TRUE && ADD_500KHz~ = FALSE
	movf	b0_underflow,F
	btfsc	STATUS,Z
	goto	fm_24
	btfss	PORTD,6
	goto	fm_24
	movf	b0_tmp1_lo,W
	pagesel	MHz_digit_table_underflow
	call	MHz_digit_table_underflow	;on return W contains the ASCII digit
	pagesel	ft301d_main
	movwf	b0_digit4
	goto	fm_26

fm_24
		;Use MHz_digit_table? ;This table is for all other cases (nothing fancy!)
	movf	b0_tmp1_lo,W
	pagesel	MHz_digit_table
	call	MHz_digit_table		;on return W contains the ASCII digit
	pagesel	ft301d_main
	movwf	b0_digit4

fm_26
	;Figure out what "Tens of MHz" digit to show
	movlw	" "			;first assume that it should be a blank
	movwf	b0_digit5

	btfsc	PORTD,1		;next check for it to be a "1"
	goto	fm_28
	movlw	"1"
	movwf	b0_digit5
	goto	fm_30

fm_28
	btfsc	PORTD,0		;next check for it to be a "2"
	goto	fm_30
	movlw	"2"
	movwf	b0_digit5
	;however, if b0_overflow is TRUE and b0_digit4 is a "0" then it should be a "3"
	movf	b0_overflow,F
	btfsc	STATUS,Z
	goto	fm_30
	movf	b0_digit4,W
	xorlw	"0"
	btfss	STATUS,Z
	goto	fm_30
	movlw	"3"
	movwf	b0_digit5

fm_30
	pagesel	convert_to_segments
	call	convert_to_segments
	pagesel	ft301d_main_loop
	goto	ft301d_main_loop
	


	end

; End of File (main.asm)
