⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 finance.mac

📁 calculator code ,use toshibaor nec LSI
💻 MAC
📖 第 1 页 / 共 2 页
字号:
	$nolist
;*******************************************************************************
;*******************************************************************************
;*                                                                             *
;*              (C)Copyright, CLOVER China Electronics Co.,LTD.                *
;*                         (Company No:190077-X)                               *
;*                          All Rigits Reserved                                *
;*   add:No.58-F Yang Dong Road, LuoFeng Demonstrative Zone Suzhou, China      *
;*                    Tel: 0512-67261886 Fax:0512-67261882                     *
;*                        http://www.clover.co.jp                              *
;*                                                                             *
;*******************************************************************************
;*******************************************************************************
;
;		OBS CPD3212T source program
;		CPU: TOSHIBA TLC-870/C series TMP86CM74AF
;		RAM: 2Kbytes(0040h - 083Fh)
;		ROM: 32Kbytes(8000h - FFFFh)
;
;
;Basic function............................

	?trigger(@)
	@include	"symdef_ram.inc"
	@include	"symdef_sub.inc"
	@include	"macro.inc"
	@include	"define.inc"
	$list

	public	key_amount,key_interest,key_payment,key_month
	public	w2_print,w2_round_print,w2_round,fn_register_clear
	public	w1_to_w4,w4_to_w1,w2_to_w4,w4_to_w2,w1_to_ftemp,ftemp_to_w2
	extern	function_end,move_9byte,sys_error
	extern	move_to_w1,move_to_w2,clear_9byte	

ROM	section	code
;==============================================================================
@define(KEY_ENABLE)(
;V2.13	set	(TC4CR).3
;V2.15	set	(TC4CR).5	;V2.13
)
;------------------------------------------------
@define(KEY_DISABLE)(
;V2.13	clr	(TC4CR).3
;V2.15	clr	(TC4CR).5	;V2.13
)
;==============================================================================

;==============================================================================
;Loan Amount	 amount key function
;==============================================================================
key_amount:
		ld	(KEYIN),K_AMOUNT	;V1.25
		@BBS	(F_TNKEY,input_amount)
		@BBS	(F_FNEABL,input_amount)		;finacial input enable? yes-->
		@BBS	(F_MODIFIED,calculate_amount)	;if any financial item modified, need to recalculate FN_AMOUNT
		@BBC	(F_FNRECALL,input_amount)	;V1.09
		jp	recall_amount			;
;tenkey -> FN_AMOUNT....................................
input_amount:
		call	ten_to_w2dp		;tenkey ->W2 follow dp selector
		call	w2_to_famount		;-WORK02 -->FN_AMOUNT
		ld	(SYM),S_DLTA	;-print out amount
		call	w2_print	;/
		call	w2_to_ten	;V1.10 for display
		@SEB	(F_MODIFIED)		;F_MODIFIED,for new entry,or modify-->for recalculate next function key press
		@SEB	(F_AMOUNT)		;F_AMOUNT=1 with new numeric input
		@CLB	(F_INTEREST)
		@CLB	(F_MONTH)
		@CLB	(F_PAYMENT)
		@CLB	(F_FNEABL)	;V5.02 clear finacial input enable
		jp	end_sequence
		
;Recall FN_AMOUNT even it is 0, if no tenkey input
recall_amount:
		call	famount_to_ten		;for display
		ld	(SYM),S_DLTA
		call	amount_print		;print out amount
		@CLB	(F_AMOUNT)		;clear indicate not new numerc entry in amount buffer
		@CLB	(F_MONTH)
		@CLB	(F_INTEREST)
		@CLB	(F_PAYMENT)
		jp	end_sequence
;..........................................................
calculate_amount:						;check whether the FN_INTEREST,FN_MONTH,FN_PAYMENT have data
		@BBS	(F_AMOUNT,input_amount)		;V1.12
		@SEB	(F_FINBUSY)	; busy with finacial calculate
		@BBS	(F_AMOUNT,compute_amount_err)	;cannot recalculate,if enter FN_AMOUNT just in prior
		call	fn_chk_interest		;\
		j	z,compute_amount_err		;-if interest=0,error occured
		call	fn_chk_month
		j	z,compute_amount_err		;if month=0,error occured
		call	fn_chk_payment
		j	z,compute_amount_err		;if payment=0,error occured
		call	compute_amount		;calculation loan amount
		@BBS	(F_CALER,compute_amount_err)
		call	famount_to_w2		;FN_AMOUNT --> WORK02
		ld	(SYM),S_ASDL
		call	w2_round_print
		call	w2_to_ten		;to dispaly prepare
		call	feed_1
		@CLB	(F_MODIFIED)
		@CLB	(F_AMOUNT)
		@CLB	(F_MONTH)
		@CLB	(F_INTEREST)
		@CLB	(F_PAYMENT)
		@SEB	(F_FNRECALL)	;V1.09
		ld	(FLG_C),0		;C_MUL,C_DIV,C_MUP,C_DLTP,C_COST,C_SELL off	V4.05
		jp	end_sequence

compute_amount_err:
		jp	finance_error
;..........................................................
;Calculate Loan Amount (by using Interest,Monthly Payment,# of Months)
;		[(1+interest)^month-1] x payment
;amount=     ------------------------------------
;		     (1+interest)^month
;..........................................................
compute_amount:
		@KEY_DISABLE		;speedup calcute.(don't run key scan)
		call	cal_rate_puls_1_power_month	;FN_TEMP <- W <- [(1+interest)^month]

		call	ftemp_to_w1	;FN_TEMP --> W1
		call	w2_clear	;
		ld	(W2+0),1	;
		ld	(W2+7),1	;W2 <- -1
		call	fn_calc_add	;W1 <- [(1+interest)^month]-1
		
		call	w2_clear	;
		call	fpayment_to_w2	;-FN_PAYMENT --> W2
		call	fn_calc_mult	;W1 <-{[(1+interest)^month]-1}*Payment
		call	w1_to_ftemp1	;-W1 --> FN_TEMP1

		call	w1_clear
		call	w2_clear
		call	fmthrate_to_w1			;interest--> W1
		call	ftemp_to_w2			;[(1+interest)^month] --> W2
		call	fn_calc_mult			;W1 <- [(1+interest)^month]*interest
		
		call	w1_to_w2			;W1 --> W2
		call	w1_clear
		call	ftemp1_to_w1			;{[(1+interest)^month]-1}*Payment -> W1
		call	fn_calc_div			;W1<- W1/W2
		call	adjust_for_m14_or_m12	;V1.07
		call	w1_to_w2	;
		call	w2_round
		call	w2_to_famount	;
		@KEY_ENABLE		;
		ret					;exit and back
;==============================================================================
;Loan Interest		interest key function
;==============================================================================
key_interest:
		ld	(KEYIN),K_INTEREST		;V1.25
		@BBS	(F_TNKEY,input_interest)
		@BBS	(F_FNEABL,input_interest)	;finacial input enable
		@BBS	(F_MODIFIED,calculate_interest);if F_TNKY=0,check F_MODIFIED,recall FN_INTEREST if F_MODIFIED=0
		@BBC	(F_FNRECALL,input_interest)
		jp	recall_interest
;tenkey -> FN_INTEREST..................................
input_interest:
		call	ten_to_w2dp		;tenkey ->W2 follow dp selector
		@SEB	(F_MODIFIED)
		@SEB	(F_INTEREST)
		call	w2_to_finterest		
		ld	(SYM),S_PER
		call	w2_print
		call	w2_to_ten	;V1.10 for display
		call	w2_to_w1		;\
		call	w2_clear		;|
		ld	(W2_LSD-1),0x12		;|mthrate=interest/1200
		call	fn_calc_div		;|
		call	w1_to_fmthrate		;/
		@CLB	(F_AMOUNT)
		@CLB	(F_MONTH)
		@CLB	(F_PAYMENT)
		@CLB	(F_FNEABL)		;clear finacial input enable
		jp	end_sequence

recall_interest:
		call	finterest_to_ten	;FN_INTEREST --> W2
		call	finterest_to_w2
		ld	(SYM),S_PER
		call	w2_print
		@CLB	(F_INTEREST)
		@CLB	(F_AMOUNT)
		@CLB	(F_MONTH)
		@CLB	(F_PAYMENT)
		@CLB	(F_FINAL)
		jp	end_sequence

compute_interest_err:
		@CLB	(F_FINAL)
		jp	finance_error
;----------------------------------------------------------
;
;estimate interest value
;
;----------------------------------------------------------
calculate_interest:
		@BBS	(F_INTEREST,input_interest)	;V1.12
		@SEB	(F_FINBUSY)	; busy with finacial calculate V5.05
		call	fn_chk_amount
		j	z,compute_interest_err			;if FN_INTEREST=0,error occured
		call	fn_chk_payment
		j	z,compute_interest_err			;if FN_MONTH=0,error occured
		call	fn_chk_month
		j	z,compute_interest_err			;if FN_PAYMENT=0,error occured
		@KEY_DISABLE
		call	w1_clear	;\
		ld	(W1_LSD),1	;|
		call	w2_clear	;|
		ld	a,(FN_MONTH+1)	;|
		ld	(W2_LSD-1),a	;|1/month
		ld	a,(FN_MONTH+0)	;|
		ld	(W2_LSD),a	;|	
		call	fn_calc_div	;/

		call	w1_to_w4	;backup 1/month

		call	fpayment_to_w1	;\
		call	famount_to_w2	;|payment/amount
		call	fn_calc_div	;/
		
		call	w4_to_w2	;\
		ld	(W2_S),1	;|(payment/amount) - (1/month)
		call	fn_calc_add	;/

		call	w1_to_w2
		call	fn_calc_add	;2*[(payment/amount) - (1/month)]=r(guess)
		call	w1_to_fmthrate	;---->r0

;calculate f(r)
cal_interest_1:

		call	cal_rate_puls_1_power_month	;(1+interest)^month-->FN_TEMP
		call	fmthrate_to_w2
		call	fn_calc_mult			;interest*(1+interest)^month
		call	w1_to_w4			;backup result "interest*(1+interest)^month"

		call	ftemp_to_w1	;\
		call	w2_clear	;|
		ld	(W2_LSD),1	;|[(1+interest)^month-1]
		ld	(W2_S),1	;|
		call	fn_calc_add	;/

		call	w1_to_w2	;\
		call	w4_to_w1	;|[interest*(1+interest)^month]/[(1+interest)^month-1]
		call	fn_calc_div	;/
		call	w1_to_w4	;backup result

		call	fpayment_to_w1	;\
		call	famount_to_w2	;|payment/amount
		call	fn_calc_div	;/

		call	w1_to_w2	;\
		xor	(W2_S),1	;|[interest*(1+interest)^month]/[(1+interest)^month-1]-payment/amount
		call	w4_to_w1	;|\__________expressed with f(r)____________________________________/
		call	fn_calc_add	;/
		call	w1_to_ftemp1	;backup f(r)

		call	w1_zerock
		j	nz,cal_interest_2
		@SEB	(F_FINAL)	;flag for compute one more time and then end compute
		jp	cal_interest_3
cal_interest_2:
		ld	a,(W1_S)
		j	z,cal_interest_3
		@SEB	(F_FINAL)


;calculate f'(r)
cal_interest_3:
	call	fmthrate_to_w1	;\
	call	w2_clear	;|(1+interest)
	ld	(W2_LSD),1	;|
	call	fn_calc_add	;/

	call	w1_to_w2	;\
	call	ftemp_to_w1	;|[(1+interest)^month]/(1+interest)
	call	fn_calc_div	;/

	call	fmthrate_to_w2	;\
	call	fn_calc_mult	;|
	call	fmonth_to_w2	;|
	call	fn_calc_mult	;|{[(1+interest)^month]/(1+interest)}*interest*month-[(1+interest)^month]
	call	ftemp_to_w2	;|
	call	fn_calc_add	;/

	call	w1_to_w4	;backup result

	call	ftemp_to_w1	;\
	call	ftemp_to_w2	;|[(1+interest)^month]^2
	call	fn_calc_mult	;/

	call	w4_to_w2;\
	xor	(W2_S),1;|[(1+interest)^month]^2-{{[(1+interest)^month]/(1+interest)}*interest*month-[(1+interest)^month]}
	call	fn_calc_add;/
	call	w1_to_w4	;backup result

	call	ftemp_to_w1	;\
	call	w2_clear	;|
	ld	(W2_S),1	;|(1+interest)^month]-1
	ld	(W2_LSD),1	;|
	call	fn_calc_add	;/
	call	w1_to_w2	;\
	call	fn_calc_mult	;/[(1+interest)^month]-1]^2

	call	w1_to_w2	;\
	call	w4_to_w1	;|{[(1+interest)^month]^2-{{[(1+interest)^month]/(1+interest)}*interest*month-[(1+interest)^month]}}/{[(1+interest)^month]-1]^2}
	call	fn_calc_div	;/\_________express by f'(r)___________________________________________________________________________________________________/

;calcuate f(r)/f'(r)
	call	w1_to_w2	;\
	call	ftemp1_to_w1	;|f(r)/f'(r)
	call	fn_calc_div	;/
	call	w1_to_w2
	xor	(W2_S),1	;\
	call	fmthrate_to_w1	;|f(r)/f'(r)+interest
	call	fn_calc_add	;/
	@BBS	(F_CALER,compute_interest_err)	;V1.10
	call	w1_to_fmthrate	;update with new insterest
	@BBS	(F_FINAL,cal_interest_3_1)	;
	jp	cal_interest_1			;

cal_interest_3_1:
	call	w2_clear
	ld	(W2_LSD-1),0x12	;1200
	call	fn_calc_mult
	call	adjust_for_m14_or_m12	;V1.07
	ld	(SYM),S_PER
;V2.03	@BBC	(M_V1205,cal_interest_3_2)	;V1.32
;V2.03	ld	(SYM),S_STAPER			;V1.32
;V2.03cal_interest_3_2:				;V1.32
	call	w1_round_print
	call	w1_to_finterest
	call	w1_to_ten	;for display
	@CLB	(F_MODIFIED)
	@CLB	(F_AMOUNT)
	@CLB	(F_INTEREST)
	@CLB	(F_MONTH)
	@CLB	(F_PAYMENT)
	@CLB	(F_FINAL)
	@SEB	(F_FNRECALL)	;V1.09
	ld	(FLG_C),0	
	@KEY_ENABLE
	jp	end_sequence
;==============================================================================
;Number of Months	key month function
;==============================================================================
key_month:
		ld	(KEYIN),K_MONTH		;V1.25
;V2.03		@BBS	(M_HAND,key_monthhand)	;V1.22
;V2.03		ld	(KEYIN),K_PAYMENT	;V1.22
;V2.03		jp	key_paymenthand		;V1.22
;V2.03key_monthhand:					;V1.22
		@BBS	(F_TNKEY,input_month)
		@BBS	(F_FNEABL,input_month)
		@BBS	(F_MODIFIED,calculate_month)
		@BBC	(F_FNRECALL,input_month)
		jp	recall_month
;tenkey -> FN_MONTH...................................
input_month:
		call	ten_to_w2		;tenkey ->W2 follow dp selector
		call	w02_exp_cancel			;W2 adjusted to DP=0
		ld	a,(W2_LSD-2)	;\
		or	a,(W2_LSD-3)	;|
		or	a,(W2_LSD-4)	;|if w2 over 9999 or minus
		or	a,(W2_LSD-5)	;|
		or	a,(W2_LSD-6)	;|
		or	a,(W2_S)	;/
		j	nz,compute_month_err
		ld	a,(W2_LSD-1)	;\
		ld	(FN_MONTH+1),a	;|
		ld	a,(W2_LSD)	;|
		ld	(FN_MONTH+0),a	;/

		@SEB	(F_MODIFIED)
		@SEB	(F_MONTH)
		ld	(SYM),S_MKUP	;SYM= "M "

		call	w2_print
		call	w2_to_ten	;V1.10
		@CLB	(F_AMOUNT)
		@CLB	(F_INTEREST)
		@CLB	(F_PAYMENT)
		@CLB	(F_FNEABL)	;clear finacial input enable
		jp	end_sequence
		
compute_month_err:
		jp	finance_error


;FN_MONTH -> TEMP_BUF,W2.........................
recall_month:
		call	w2_clear		;TEMP_BUF 10byte clear
		ld	a,(FN_MONTH+1)
		ld	(W2+6),a
		ld	a,(FN_MONTH)
		ld	(W2+7),a
		@CLB	(F_MONTH)
		ld	(SYM),S_MKUP		;SYM= "M "
		call	w2_print	;
		call	w2_to_ten	;for display
		@CLB	(F_AMOUNT)
		@CLB	(F_INTEREST)
		@CLB	(F_PAYMENT)

		jp	end_sequence

calculate_month:						;check whether the FN_AMOUNT,FN_INTEREST,FN_PAYMENT have data
		@BBS	(F_MONTH,input_month)	;V1.12
		@SEB	(F_FINBUSY)	; busy with finacial calculate V5.05
		@BBS	(F_MONTH,compute_month_err)	;cannot recalculate,if enter FN_AMOUNT just in prior
		call	fn_chk_amount
		j	z,compute_month_err		;if interest=0,error occured
		call	fn_chk_interest
		j	z,compute_month_err		;if month=0,error occured
		call	fn_chk_payment
		j	z,compute_month_err		;if payment=0,error occured
		call	compute_month	;to compute month			
		@BBS	(F_CALER,compute_month_err)
		call	w1_to_ten
		ld	(SYM),S_ASM	;V1.10
		call	w1_print		;print result of compute
		call	feed_1
		@CLB	(F_FINAL)
		@CLB	(F_MODIFIED)
		@CLB	(F_AMOUNT)
		@CLB	(F_INTEREST)
		@CLB	(F_MONTH)
		@CLB	(F_PAYMENT)
		@SEB	(F_FNRECALL)	;V1.09
		call	const_clear		;broken 'const_reg' in month calculate routine		
		ld	(FLG_C),0		;C_MUL,C_DIV,C_MUP,C_DLTP,C_COST,C_SELL off		
		jp	end_sequence

compute_month:
	@KEY_DISABLE
	ld	(FN_MONTH),0
	ld	(FN_MONTH+1),0
	call	famount_to_w1	;
	call	w1_to_w4
compute_month_1:
	call	fmthrate_to_w2	;\
	call	fn_calc_mult	;|amount*interest, i.e. balance*interest
	call	w1_to_ftemp1	;/

	call	fpayment_to_w1	;\
	call	w1_to_w2	;|2*Payment
	call	fn_calc_add	;/

	call	ftemp1_to_w2	;restory balance*r to w02
	xor	(W2_S),1
	call	fn_calc_add	;2*payment-balance*interest
	call	w1_to_ftemp1
	call	w4_to_w1	;\restory bal to w02
	call	w1_to_w2	;|2*balance
	call	fn_calc_add	;/
	call	ftemp1_to_w2
	call	fn_calc_div	;(2*balance)/(2*payment-balance*interest)
compute_month_1_1:
	@BBS	(F_FINAL,compute_month_4)

	ld	a,(W1_DP)		;\
	j	z,compute_month_1_2	;|
	ld	hl,W1			;|
	call	stg_sfr47		;|cancel decimal
	dec	(W1_DP)			;|
	jp	compute_month_1_1	;/
compute_month_1_2:
	ld	a,(W1_S)
	j	nz,compute_month_1_3
	ld	a,(W1_LSD-2)
	j	z,compute_month_1_4	;if w1 over 9999, error
compute_month_1_3:
	jp	compute_month_err

compute_month_1_4:
	ld	a,(W1_LSD)	;\
	clr	cf		;|
	add	a,(FN_MONTH)	;|
	daa	a		;|new month
	ld	(FN_MONTH),a	;|
	ld	a,(W1_LSD-1)	;|
	addc	a,(FN_MONTH+1)	;|
	daa	a		;|
	ld	(FN_MONTH+1),a	;/
	j	cc,compute_month_1_5	
	jp	compute_month_err		
compute_month_1_5:			
	call	compute_balance	;calculate balance
	@BBS	(F_CALER,compute_month_err)	;V1.10
	call	w1_to_w4	;back up balance
	call	fpayment_to_w2	;\
	xor	(W2_S),1	;|balance-payment
	call	fn_calc_add	;/

	call	w1_zerock
	j	ne,compute_month_3
compute_month_2:
	@SEB	(F_FINAL)
compute_month_2_1:
	call	w4_to_w1	;restory balance
	@BBS	(F_CALER,compute_month_err)	;V1.10
	jp	compute_month_1
compute_month_3:
	ld	a,(W1_S)
	j	nz,compute_month_2
	jp	compute_month_2_1

compute_month_4:
	ld	a,(W1_S)		;\
	j	z,compute_month_4_1	;|can not be minus for month
	jp	compute_month_err		;/

compute_month_4_1:
	ld	a,(W1_DP)		;\
	j	z,compute_month_9	;|
	dec	(W1_DP)			;|
	ld	hl,W1			;|
	call	stg_sfr47		;|
	cmp	(W1_DP),2		;|
	j	eq,compute_month_4_2	;|
	jp	compute_month_4_1	;|
compute_month_4_2:			;|keep 2 decimal for compute result
	ld	a,(W1_LSD)		;|
	and	a,0xf0			;|
	j	z,compute_month_4_1	;|
	clr	cf			;|
	ld	a,(W1_LSD-1)		;|
	add	a,1			;|
	daa	a			;|
	ld	(W1_LSD-1),a		;|
	ld	a,(W1_LSD-2)		;|
	addc	a,0			;|
	daa	a			;|
	ld	(W1_LSD-2),a		;/	
	j	cc,compute_month_4_1	;no carry over

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -