📄 finance.mac
字号:
$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 + -