📄 sub.asm
字号:
;***********************************************************
; Version 2.20.01
;***********************************************************
;*****************************************************************************
; Function: sub
; Description: vector sub
;
; Copyright Texas instruments Inc, 1998
;-----------------------------------------------------------------------------
; Revision History:
; 1.00 R. Piedra, 8/31/98. Original version. Started from TIF code.
; 2.00 - Li Yuan, 4/09/02. fixed overflow flag setup at the end of code.
;
;*****************************************************************************
.mmregs
; Far-mode adjustment
.if __far_mode
offset .set 1 ; far mode uses one extra location for ret subr ll
.else
offset .set 0
.endif
.asg (2), ret_addr
; x in A
.asg (3 + offset), arg_y
.asg (4 + offset), arg_z
.asg (5 + offset), arg_n
.asg (6 + offset), arg_scale
; register usage
; ar0: addr. idx
.asg ar2, ar_x
.asg ar3, ar_y
.asg ar4, ar_z
.asg ar5, ar_temp
;*****************************************************************************
.def _sub
.text
_sub
PSHM ST0 ; 1 cycle
PSHM ST1 ; 1 cycle
RSBX OVA ; 1 cycle
RSBX OVB ; 1 cycle
; Preserve registers
;-------------------
ssbx sxm ; sign extension on
ld #0,ASM ; clear ASM (st||ld)
stm #0,bk ; bk = 0
rsbx ova
; Get arguments
;--------------
stlm a, ar_y ; pointer to x (swap order)
mvdk *sp(arg_y),*(ar_x) ; pointer to y (swap order)
mvdk *sp(arg_z),*(ar_z) ; pointer to z
ld *sp(arg_scale),b ; b = scale parameter
ld *sp(arg_n),-1,a ; a = n/2
sub #2,a
stlm a, brc ; brc = n/2 -2
xc 1, bneq ; if a=0 (no scaling) skip
ld #-1,ASM ; ASM = -1 --> div by 2
ld *sp(arg_n), a ; a = n
stm #3,ar0 ; array index
; Compute z(0) and z(1) outside
; -----------------------------
sub *ar_y+, *ar_x+,a ; ah = x(0) + y(0)
sth a, ASM, *ar_z+ ; z(0) = x(0) + y(0)
; Compute (n/2) -1 elements
; -------------------------
rptbd eloop-1
sub *ar_y+, *ar_x+,a ; ah = x(1) + y(1)
mar *ar_x+ ; points to x(3), y(2), z(1)
st a,*ar_z+ ; write z(1)
|| ld *ar_x-,B ; bh = x(3) and point to x(2)
sub *ar_y+, *ar_x+0%,a ; ah = x(2) - y(2); point to x(5), y(3)
st a,*ar_z+ ; write z(2)
|| sub *ar_y+,a ; ah = y(3) - (b=x(3))
eloop
; for n=4 or 5 --> points to y(4), z(3) x(5)
; Store last computed element
; ---------------------------
sth a, ASM, *ar_z+ ; store last output z(3)
; Check if n is even
; ------------------
ld *sp(arg_n),a
and #1,a
bc end, aeq ; if a = 0 --> even , then skip
; If n is odd, one more element to compute
; ----------------------------------------
mar *ar_x- ; adjust x to point to last x(n-1)
sub *ar_y, *ar_x, a ; if n=5 --> a = x(4) + a(4)
sth a, ASM, *ar_z+
; Return
;--------
end:
ld #0,a
xc 1, AOV ; return overflow flag
ld #1,a
POPM ST1 ; 1 cycle
POPM ST0 ; 1 cycle
.if __far_mode
fret
.else
ret
.endif
;end of file. please do not remove. it is left here to ensure that no lines of code are removed by any editor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -