📄 minmag.asm
字号:
.include "ccall.asm"
.def _ti_minmag
.text
_ti_minmag:
pre_ccall 2,AR_X,AR_N
setc OVM ; Enable overflow mode to handle abs(0x8000)
setc SXM
sar AR_X,*+,AR_X ; xmin=stack[0]=&x[min]=&x[0];
lacc *,AR_STACK
abs
sacl *+,AR_STACK ; stack[1] = x[min]
; Compute N%7 to make N divisible by 8 in the unrolled loop
sar AR_N,* ; stack[2]=N
lacl *+ ; acc=N
and #07h ; acc&=0111b - Unroll 8 iterations
sacl *- ; stack[3] = N % 0111b
lacc *,13 ; acch=N>>3
sach *+ ; stack[2]=N>>3
lar AR_N,*- ; AR_N = stack[3] = N%7
mar *-,AR_N
banz NEXT0,AR_X ; AR_N--, Skip loop if AR_N = 0
b NEXT1
; SP = &stack[1]
; Local variables
; &xmin - stack[0]
; *xmin - stack[1]
; ARP=AR_X
NEXT0:
; Is x[AR_X++] > x[min] ?
lacc *+,AR_STACK ; ACC = x[AR_X++];
abs
sub *,AR_N ; ACC -= x[min]; // (stack[1])
cc NEWMIN2,lt ; if(x[AR_X]<x[min]) newmin
; while(N--)
banz NEXT0,AR_X
NEXT1:
mar *,AR_STACK
mar *+
lar AR_N,*-,AR_N ; AR_N = stack[2]=N>>3
banz NEXT2,AR_X ; Go to 8x loop if AR_X > 0
b DONE
NEXT2:
.loop 7
lacc *+,AR_STACK ; ACC = x[AR_X++];
abs
sub *,AR_X ; ACC -= x[min];
cc NEWMIN1,lt ; if(x[AR_X]<x[min]) newmin
.endloop
lacc *+,AR_STACK ; ACC = x[AR_X++];
abs
sub *,AR_N ; ACC -= x[min];
cc NEWMIN2,lt ; if(x[AR_X]<x[min]) newmin
; while(N--)
banz NEXT2,AR_X
DONE:
mar *,AR_STACK
mar *- ; SP=0
lacl * ; acc=STACK[0]=&x[min]
clrc OVM
post_ccall 2
NEWMIN .macro AR
mar *,AR_X
mar *-,AR_STACK ; i--
sbrk #1 ; SP--
sar AR_X,*+,AR_X ; stack[0]=&x[i] (address of new min)
lacc *+,16,AR_STACK ; acc=x[i] shift left to saturate 8000
abs
sach *,AR
ret
.endm
; We need one NEWMIN that returns with ARP=AR_X and
; one with ARP=AR_N
NEWMIN1:
NEWMIN AR_X
NEWMIN2:
NEWMIN AR_N
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -