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

📄 sub.mac

📁 calculator code ,use toshibaor nec LSI
💻 MAC
📖 第 1 页 / 共 3 页
字号:

;==============================================================================
;	Basic calculation routines  (Division)
;==============================================================================
calc_div:
		@BBC	(F_CALER,cdiv_00)
		ret
cdiv_00:
		call	w1_to_w3
		call	w1_clear
		ld	c,(W3_DP)		;DP culculation  W1_DP <- W3_DP(W1_DP) - W2_DP
		sub	c,(W2_DP)		;reg.c is use for keep DP value (BBC,CLB macro use wa register)
		@BBC	(F_PERCAL,cdiv_07)	;% calculation ?
		sub	c,2			;yes -> subtruct more 2
		@CLB	(F_PERCAL)
cdiv_07:
		ld	(W1_DP),c		;store calculated dp
		ld	(W3_DP),0		;clear loop counter
cdiv_08:
		call	sub_00			;W1 <- W1 - W2
		j	cc,cdiv_09		;no borrow?  yes->
		ld	a,(W1_S)		;15th digit is zero?
		j	z,cdiv_10		; yes(can't subtruct) -> restore(add data) W2 and shift data
		dec	(W1_S)			;15th digit - 1
cdiv_09:
		ld	a,(W3_LSD)		;W3_LSD (subtruction times)
		swap	a
		add	a,0x10
		daa	a
		swap	a
		ld	(W3_LSD),a		;W3_LSD + 1
		j	cc,cdiv_08		;still not yet 10 times  yes->
		@SEB	(F_ZDIVER)
;Zero divide error..............................
;error exit for Mul,Div routine.................
error_calc_s:
		ld	a,(W1_S)
		add	a,(W2_S)
		and	a,0x01
		ld	(W1_S),a		;update minus sign
		call	neg_check		;-0 --> 0
;error exit for Plus,Minus routine.................
error_calc:
		@SEB	(F_CALER)
		@CLB	(F_PERCAL)
		ld	a,(W1_DP)
		add	a,0			;check negative flag
		j	p,error_c9		;W1_DP is plus?  yes->
;V1.21	@if(@eqs(@D14,@ON))then(
;V1.21		add	(W1_DP),LENG_WK*2	;W1_DP adjustment for calclation error print (14digit)
;V1.21	)else(
;V1.21		add	(W1_DP),(LENG_WK-1)*2	;W1_DP adjustment for calclation error print (12digit)
;V1.21	)fi
		push	wa
		@BBC	(M14,error_calc6)	;V1.21
		add	(W1_DP),LENG_WK*2	;V1.21
		jp	error_calc8		;V1.21
error_calc6:					;V1.21
		@BBS	(M10,error_calc7)	;V1.21
		add	(W1_DP),(LENG_WK-1)*2	;V1.21
		jp	error_calc8		;V1.21
error_calc7:					;V1.21
		add	(W1_DP),(LENG_WK-2)*2	;V1.21
error_calc8:					;V1.21
		pop	wa			;V1.21
		@if_finance_on			;V1.07
		j	t,error_c9		;V1.07
		add	(W1_DP),LENG_WK*2	;V1.07

error_c9:
		@BBC(E_MUL,error_c9x)		;V3.09
error_c9y:					;V3.09
		ld	a,(W1_DP)		;V3.09
		j	eq,error_c9x		;V3.09
		ld	a,(W1_LSD)		;V3.09
		and	a,0x0f			;V3.09
		j	ne,error_c9x		;V3.09
		ld	hl,W1			;V3.09
		call	stg_sfr47		;V3.09
		dec	(W1_DP)			;V3.09
		jp	error_c9y		;V3.09
error_c9x:					;V3.09
		ret


;Add back W2, and shift data W3_LSD to W1_S.....
cdiv_10:
		call	add_00			;W1 <- W1 + W2
		cmp	(W3_DP),LENG_WK*2	;data shift 14 times?
		j	ge,cdiv_20		;if W3_DP is greater than or equal to length of work area?  yes ->division end
		inc	(W3_DP)			;increment loop cnt
cdiv_11:
		ld	hl,W3
		ld	c,OFF_LSD
		ld	a,0			;shift W3_LSD to W3_MSD(14digits)
cdiv_12:		
		rold	a,(hl+c)
		dec	c
		cmp	c,OFF_S
		j	ne,cdiv_12		;if c is not equal to sign pointer?  yes -> loop

		ld	hl,W1
		ld	c,OFF_LSD		;shift W1_LSD to W1_S(16digits)
cdiv_14:		
		rold	a,(hl+c)
		cmp	c,OFF_S
		j	eq,cdiv_16		;if c equal to sign pointer?  yes -> exit
		dec	c
		j	cdiv_14
cdiv_16:
		and	(W1_S),0x0f
		j	cdiv_08

cdiv_20:
		ld	a,(W3_MSD)		;14th digit of result
		and	a,0xf0
		j	nz,cdiv_29		;if 14th digit is not zero?  yes-> exit
		ld	a,(W1_DP)
		add	a,0			;check negative flag
		j	m,cdiv_22		;W1_DP is minus?  yes-> continue divide
		cmp	(W1_DP),LENG_WK*2-1	;W1_DP is maximum? (over 13?)
		j	ge,cdiv_29		;W1_DP is greater or equal to 13?  yes-> exit
cdiv_22:
		inc	(W1_DP)			;
		j	cdiv_11			;continue divide
cdiv_29:
		ld	a,(W1_DP)
		add	a,0			;check negative flag
		j	p,cdiv_30		;W1_DP is plus?  yes->
;over flow error.........
		ld	w,(W1_DP)		;reg.w is use for keep DP value (w3_to_w1 routine use a,c,ix,iy register)
		call	w3_to_w1		;transfer result(W3) to W1
		ld	(W1_DP),w		;recover W1_DP
		call	adjust_12		;adjust 14digit result -> 12 digits (selected 12digit model only)
		j	error_calc_s

cdiv_30:
		cmp	(W1_DP),LENG_WK*2
		j	lt,cdiv_32		;if W1_DP is lower than maximum digit?(14)  yes->
		ld	hl,W3
		call	stg_sfr47
		dec	(W1_DP)
		j	cdiv_30
cdiv_32:
		ld	w,(W1_DP)		;reg.w is use for keep DP value (w3_to_w1 routine use a,c,ix,iy register)
		call	w3_to_w1
		ld	(W1_DP),w		;update W1_DP
		call	adjust_12		;adjust 14digit result -> 12 digits (selected 12digit model only)
		j	m,error_calc_s		;W1_DP is minus?  yes-> error
		call	zsup_under_dp		;zero suppression for under dp
		ld	a,(W1_S)
		add	a,(W2_S)
		and	a,0x01
		ld	(W1_S),a		;update minus sign
		call	neg_check		;-0 --> 0
		ret

;==============================================================================
;	(WORK_01) <--- |(WORK_01)| + |(WORK_02)|  7bytes addition
;==============================================================================
add_00:
		ld	c,0
		clr	cf
		push	psw			;carry flag save
		ld	ix,W1_LSD
		ld	iy,W2_LSD
add_01:
		pop	psw			;carry flag recover
		ld	a,(ix)
		addc	a,(iy)
		daa	a			;decimal adjust for addition
		ld	(ix),a			;(W1) <- (W1)+(W2)
		push	psw			;carry flag save
		dec	ix
		dec	iy
		inc	c
		cmp	c,LENG_WK
		j	lt,add_01		;if c is lower than length of work area?  yes->loop
		pop	psw			;carry flag recover
		ret
;==============================================================================
;	(WORK_01) <--- |(WORK_01)| - |(WORK_02)|  7bytes subtruction
;==============================================================================
sub_00:
		ld	c,0
		clr	cf			;clear borrow flag
		push	psw			;borrow flag save
		ld	ix,W1_LSD
		ld	iy,W2_LSD
sub_01:
		pop	psw			;borrow flag recover
		ld	a,(ix)
		subb	a,(iy)
		das	a			;decimal adjust for subtruction
		ld	(ix),a			;(W1) <- (W1)-(W2)
		push	psw			;borrow flag save
		dec	ix
		dec	iy
		inc	c
		cmp	c,LENG_WK
		j	lt,sub_01		;if c is lower than length of work area?  yes->loop
		pop	psw			;borrow flag recover
		ret
;==============================================================================
;	Zero suppression for under DP	xx.xxx0000 ->  xx.xxx
;==============================================================================
zsup_under_dp:
		ld	a,(W1_DP)
		j	z,zsup_udp_9		;DP is zero?  yes -> exit
		ld	a,(W1_LSD)
		and	a,0x0f
		j	nz,zsup_udp_9
		ld	hl,W1
		call	stg_sfr47
		dec	(W1_DP)
		j	zsup_under_dp
zsup_udp_9:
		ret

;==============================================================================
;   	Adjust W1 contents 14 -> 12digit length (in case of D14 is off)
;==============================================================================
adjust_12:
	@if_finance_on		;V1.07
	j	f,adj12_6	;V1.07
;V1.21	@if(@eqs(@D14,@ON))then(
;V1.21		cmp	(W1_DP),0		;check negative flag
;V1.21	)else(
		@BBC	(M14,adj12_2)	;V1.21
		cmp	(W1_DP),0	;V1.21
		jp	adj12_9		;V1.21
adj12_2:
		@BBC	(M10,adjnot10)
		ld	a,(W1_MSD)	;V1.21
		or	a,(W1_MSD+1)	;V1.21
		jp	adjis12		;V1.21
adjnot10:
		ld	a,(W1_MSD)		;check 14,13 digit
adjis12:
		j	z,adj12_4		;zero? yes -> no right shift 
		ld	hl,W1
		call	stg_sfr47		;W1 right shift by nibble
		dec	(W1_DP)
		j	adj12_2
adj12_4:
		cmp	(W1_DP),0		;check negative flag
		j	m,adj12_9		;W1_DP is minus?  yes-> overflow error
;V1.21		cmp	(W1_DP),MAX_DIGIT	;DP is less than 12? (check in case of 0.123456789012)
		@BBS	(M14,adj12_41)	;V1.21
		@BBC	(M10,adj12_42)	;V1.21
		cmp	(W1_DP),10	;V1.21
		jp	adj12_43	;V1.21
adj12_41:				;V1.21
		cmp	(W1_DP),14	;V1.21
		jp	adj12_43	;V1.21
adj12_42:
		cmp	(W1_DP),12	;V1.21
adj12_43:	
		j	lt,adj12_6		; yes -> OK
		ld	hl,W1
		call	stg_sfr47		;W1 right shift one more time
		dec	(W1_DP)
		j	adj12_4
adj12_6:
		cmp	(W1_DP),0		;check negative flag
adj12_9:
;V1.21	)fi
		ret

;==============================================================================
;	Zero check, Negative 0 check
;==============================================================================
neg_check:
;V4.17		@BBC	(M_5514T,neg_check9)	;v4.11
;V4.19		@IS_5514_ON(neg_check9)	;V4.17
		@IS_5514_OFF(neg_check9)	;V4.19
		call	w1_zerock	;V1.13 V1.36
		j	nz,neg_check9	;V1.13 V1.36
		ld	(W1_S),0	;V1.13 V1.36;If all 0, then clear '-' sign and DP
		ld	(W1_DP),0	;V1.13 V1.36
neg_check9:
		ret

ten_zerock:
		ld	hl,TENKEY
		j	_zerock
w1_zerock:
		ld	hl,W1
		j	_zerock
w2_zerock:
		ld	hl,W2
_zerock:
		ld	a,(hl+OFF_MSD)		;7byte data zero check
		or	a,(hl+OFF_MSD+1)
		or	a,(hl+OFF_MSD+2)
		or	a,(hl+OFF_MSD+3)
		or	a,(hl+OFF_MSD+4)
		or	a,(hl+OFF_MSD+5)
		or	a,(hl+OFF_MSD+6)
		ret
_spaceck:
		ld	a,(hl+OFF_MSD)		;7byte data zero check
		cmp	a,0xff
		j	ne,_spaceck_end
		ld	a,(hl+OFF_MSD+1)
		cmp	a,0xff
		j	ne,_spaceck_end
		ld	a,(hl+OFF_MSD+2)
		cmp	a,0xff
		j	ne,_spaceck_end
		ld	a,(hl+OFF_MSD+3)
		cmp	a,0xff
		j	ne,_spaceck_end
		ld	a,(hl+OFF_MSD+4)
		cmp	a,0xff
		j	ne,_spaceck_end
		ld	a,(hl+OFF_MSD+5)
		cmp	a,0xff
		j	ne,_spaceck_end
		ld	a,(hl+OFF_MSD+6)
		cmp	a,0xff
		j	ne,_spaceck_end
		ld	a,(hl+OFF_MSD+7)
		cmp	a,0xff
		j	ne,_spaceck_end
_spaceck_end:
		ret		
;==============================================================================
;	Adjust DP position for W1 and W2 (for before addition)
;==============================================================================
adjust_dpw12:
		ld	a,(W1_DP)
		cmp	a,(W2_DP)
		j	eq,adj_dp_90
		j	lt,adj_dp_50		;if W1_DP is Lower than W2_DP?  yes ->
;W1_DP > W2_DP....................
		ld	hl,W2
adj_dp_02:
;V1.21	@if(@eqs(@D14,@ON))then(
;V1.21		ld	a,(hl+OFF_MSD)		;check MSD (in case of 14digit)
;V1.21	)else(
;V1.21		ld	a,(hl+OFF_MSD12)	;check MSD (in case of 12digit)
;V1.21	)fi
		@BBS	(F_FINCAL,adj_dp_020)	;V1.39b
		@BBC	(M14,adj_dp_021)	;V1.21;V1.32;V1.39b
adj_dp_020:
		ld	a,(hl+OFF_MSD)		;V1.21
		jp	adj_dp_022		;V1.21;V1.32;V1.39b
adj_dp_021:					;V1.21;V1.32;V1.39b
		@BBS	(M10,adj_dp_0210)	;V1.21;V1.32;V1.39b
		ld	a,(hl+OFF_MSD12)	;V1.21;V1.32;V1.39b
		jp	adj_dp_022		;V1.21;V1.32;V1.39b
adj_dp_0210:					;V1.21;V1.32;V1.39b
		ld	a,(hl+OFF_MSD10)	;V1.21;V1.32;V1.39b
adj_dp_022:					;V1.21;V1.32;V1.39b
		@if_finance_on			;V1.07
		j	t,adj_dp_03		;V1.07
		ld	a,(hl+OFF_MSD)		;V1.07
adj_dp_03:					;V1.07
		and	a,0xf0
		j	z,adj_dp_52		;no data?  yes->
		cmp	hl,W1
		j	eq,adj_dp_51
		ld	hl,W1
adj_dp_05:
		call	stg_sfr47		;4bit shift ->
		dec	(hl+OFF_DP)		;decriment DP
		j	adjust_dpw12
;W1_DP < W2_DP....................
adj_dp_50:
		ld	hl,W1
		j	adj_dp_02
adj_dp_51:
		ld	hl,W2
		j	adj_dp_05
adj_dp_52:
		call	stg_sfl47		;4bit shift <-
		inc	(hl+OFF_DP)		;increment DP
		j	adjust_dpw12
adj_dp_90:
		ret

;===================================================
;	7bytes data shift to right by 4bit
;	input:	HL <- data top address
;	shift area: top address +1 to +7
;===================================================
stg_sfr47:
		ld	c,OFF_MSD
		ld	a,0
stg_sfr470:		
		rord	a,(hl+c)
		inc	c
		cmp	c,OFF_DP
		j	lt,stg_sfr470		;if c is lower than offset of dp pointer?  yes->loop
		ret
;===================================================
;	7bytes data shift to left by 4bit
;	input:	HL <- data top address
;	shift area: top address +1 to +7
;===================================================
stg_sfl47:
		ld	c,OFF_LSD
		ld	a,0
stg_sfl470:		
		rold	a,(hl+c)
		dec	c
		cmp	c,OFF_MSD
		j	ge,stg_sfl470		;if c is greater or equal to MSD pointer?  yes->loop
		ret
;===================================================
;	9bytes data shift to right by 4bit(for #/D)
;	input:	HL <- data top address
;	shift area: top address +0 to +8
;===================================================
stg_sfr49:
		ld	c,0
		ld	a,0
stg_sfr490:		
		rord	a,(hl+c)
		inc	c
		cmp	c,9
		j	lt,stg_sfr490
		ret
;===================================================
;	9bytes data shift to left by 4bit(for #/D)
;	input:	HL <- data top address
;	shift area: top address +0 to +8
;===================================================
stg_sfl49:
		ld	c,8
		ld	a,0
stg_sfl490:		
		rold	a,(hl+c)
		dec	c
		j	f,stg_sfl490		;if c is not FF  yes->loop
		ret



	end

⌨️ 快捷键说明

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