📄 st7.txt
字号:
st7/ ; the first line is reserved
; for specifying the instruction set
; of the target processor
;************************************************************************
; TITLE: maths.ASM
; AUTHOR: Microcontroller Division Applications Team
; DESCRIPTION: Mathematics library for ST7 micros
;*************************************************************************
TITLE “maths.ASM”
; this title will appear on each
; page of the listing file
MOTOROLA ; this directive forces the Motorola
; format for the assembly (default)
#INCLUDE “st72251.inc” ; include st72251 registers and memory mapping
file
#INCLUDE “constant.inc” ; include general constants file
;***********************************************************************
; Variables, constants defined and referenced locally
; You can define your own values for a local reference here
;***********************************************************************
;************************************************************************
; Public routines (defined here)
;************************************************************************
; routines
;************************************************************************
; Extern routines (defined elsewhere)
;************************************************************************
; routines
;**********************************************************
; MACROs SUB-ROUTINES LIBRARY SECTION
;**********************************************************
; (must be placed here and not at the file’s end)
;**********************************************************
; Program code
;**********************************************************
WORDS ; define subsequent addresses as words
; meaning that all instructions are located
; in the address field after 0FFh in the ST72251
; memory mapping
segment ‘rom’
.main
ld A,#$01 ; negative edge sensitive and low level
ld MISCR,A ; for IT, ST72251 in normal mode
;*************************************
ld A,#$B8
ld number_a,A
ld A,#$01
ld number_b,A
call div_bxb
;*************************************
;*************************************
ld A,#$F3
ld operand_a,A
ld A,#$D3
ld {operand_a+1},A
ld A,#$FC
ld operand_b,A
ld A,#$C3
ld {operand_b+1},A
call multiw
;*************************************
;*************************************
ld A,#$0E
ld dividend,A
ld A,#$DC
ld {dividend+1},A
ld A,#$BA
ld {dividend+2},A
ld A,#$98
ld {dividend+3},A
ld A,#$AB
ld divisor,A
ld A,#$CD
ld {divisor+1},A
call div_lxw
;*************************************
;*************************************
ld A,#$FC
ld add_a,A
ld A,#$03
ld {add_a+1},A
ld A,#$F3
ld add_b,A
ld A,#$C3
ld {add_b+1},A
call addw
;*************************************
;*************************************
ld A,#$FC
ld sub_a,A
ld A,#$03
ld {sub_a+1},A
ld A,#$F3
ld sub_b,A
ld A,#$C3
ld {sub_b+1},A
call subw
;*************************************
;*************************************
ld A,#$CC
ld data,A
ld A,#$04
ld {data+1},A
ld A,#$00
ld min,A
ld A,#$C3
ld {min+1},A
ld A,#$CC
ld max,A
ld A,#$05
ld {max+1},A
CALL check_min_max
;*************************************
;*************************************
ld A,#$00
ld data,A
ld A,#$e2
ld {data+1},A
ld A,#$00
ld delta,A
ld A,#$23
ld {delta+1},A
ld A,#$CC
ld median,A
ld A,#$05
ld {median+1},A
call check_range
;*************************************
;*************************************
ld A,#$D4
call BtoD
;*************************************
jp main
; ********************************************
; * *
; * INTERRUPT SUB-ROUTINES LIBRARY SECTION *
; * *
; ********************************************
dummy iret ; Empty subroutine. Go back to main (iret instruction)
; ********************************************
; * *
; * CALL SUB-ROUTINES LIBRARY SECTION *
; * *
; ********************************************
;+--------------------------------------------------------------------------
+
;| DIVISION A / B |
;| |
;| DATE : 21/11/96 |
;| REVISION : V01.00 |
;| |
;| SOFTWARE DESCRIPTION : This routine divides two 8 bit numbers, A and |
;| B, the result is saved into an 8 bit register. |
;| A and B >= 0. |
;| |
;| INPUT PARAMETERS : NUMBER_A register contains the number A. |
;| NUMBER_B register contains the number B. |
;| |
;| INTERNAL PARAMETERS : COUNTER register contains the shift counter. |
;| |
;| |
;| OUTPUT PARAMETERS : RESULT register contains the result. |
;| REMAIND register contains the remainder. |
;| |
;| BYTE : 52 bytes |
;| |
;| EXAMPLE : ;***** program ***** |
;| ld A,#$E7h |
;| ld number_a,A |
;| ld A,#$10h | LD NUMBER_B,10h
|
;| ld number_b,A |
;| CALL DIVISION |
;| - do... |
;| - do... |
;| ;***** subroutine ***** |
;| . div_bxb |
;| END |
;| |
;+--------------------------------------------------------------------------
+
.div_bxb
; Initialize registers and save the context.
push A ; save the accumulator.
clr result ; clear the result register.
clr remaind ; clear the remainder register.
; Test A and B in order to enable the division subroutine.
ld A,number_b ; if B = 0 then the result = 0 ( not valid ).
jrugt div0 ; else test A
end_div pop A ; restore the accumulator.
ret ; and exit from sub routine.
div0 ld A,number_a ; if A = 0 then the result = 0.
jreq end_div ; else we can start the division subroutine
; Division subroutine.
rcf ; clear the carry flag.
ld A,#$08 ; load the shift counter.
ld counter,A
ld A,number_a ; \
rlc A ; | rotate left and save in result register.
ld result,A ; /
div1 ld A,remaind ; \
rlc A ; | rotate left the remainder register in
ld remaind,A ; / order to include the carry.
sub A,number_b
jrc div2 ; test if the subtraction is valid.
ld remaind,A
div2 ld A,result ; \
rlc A ; | rotate left the result register.
ld result,A ; /
dec counter
jreq div3
jra div1
div3 cpl A ; complement the result.
ld result,A
jra end_div
;+--------------------------------------------------------------------------
+
;| Multiplication A * B |
;| |
;| DATE : 21/11/96 |
;| REVISION : V01.00 |
;| |
;| SOFTWARE DESCRIPTION : This routine multiplies two 16 bit numbers |
;| A and B, the result is saved into four 8-bit |
;| registers (16x16= 32 bits) |
;| A and B >= 0. |
;| |
;| INPUT PARAMETERS : OPERAND_A registers contain the number A. |
;| OPERAND_B registers contain the number B. |
;| |
;| |
;| |
;| OUTPUT PARAMETERS : res registers contain the result. |
;| |
;| |
;| BYTE : 63 bytes |
;| |
;| EXAMPLE : ;***** program ***** |
;| ld A,#$F3 |
;| ld operand_a,A |
;| ld A,#$D3 |
;| ld {operand_a+1},A |
;| ld A,#$FC |
;| ld operand_b,A |
;| ld A,#$C3 |
;| ld {operand_b+1},A |
;| CALL multiw |
;| - do... |
;| - do... |
;| ;***** subroutine ***** |
;| . multiw |
;| END |
;| |
;+--------------------------------------------------------------------------
+
.multiw
push A ; save Accumulator in stack
push X ; save X register in stack
ld X,operand_b ; \
ld A,operand_a ; | Multiplies MSB operand
mul X,A ; /
ld res,X ; and store in the 2 MSB result registers
ld {res+1},A
ld X,{operand_a+1} ; \
ld A,{operand_b+1} ; | Multiplies LSB operand
mul X,A ; /
ld {res+2},X ; and store in the 2 LSB result registers
ld {res+3},A
ld X,operand_a ; \
ld A,{operand_b+1} ; | Multiplies cross operands
mul X,A ; /
add A,{res+2} ; Add to previous result
ld {res+2},A
ld A,X
adc A,{res+1}
ld {res+1},A
ld A,res
adc A,#0
ld res,A
ld X,operand_b ; \
ld A,{operand_a+1} ; | Multiplies cross operands
mul X,A ; /
add A,{res+2} ; Add to previous result
ld {res+2},A
ld A,X
adc A,{res+1}
ld {res+1},A
ld A,res
adc A,#0
ld res,A
pop X ; restore context before the CALL
pop A ; restore context before the CALL
ret ; and go back to main program
;+--------------------------------------------------------------------------
+
;| Long by Word division A/B |
;| |
;| DATE : 22/11/96 |
;| REVISION : V01.00 |
;| |
;| SOFTWARE DESCRIPTION : This routine divides one 32-bit number A by |
;| a 16-bit number B. The result is saved in two |
;| registers. |
;| A and B >= 0. |
;| |
;| INPUT PARAMETERS : DIVIDEND registers contain the DIVIDEND (32 b).|
;| DIVISOR registers contain the DIVISOR (16 b). |
;| |
;| INTERNAL PARAMETERS : TEMPQUOT registers contain the QUOTIENT |
;| temporary value (32 b). |
;| |
;| OUTPUT PARAMETERS : QUOTIENT registers contain the result (16 b). |
;| As the result is stored in 16 bits, this |
;| division is only valid for small numbers.
; See use TEMPQUOT for the 32-bit result.|
;| |
;| BYTE : 94 bytes |
;| |
;| EXAMPLE : ;***** program ***** |
;| ld A,#$0E |
;| ld dividend,A |
;| ld A,#$DC |
;| ld {dividend+1},A |
;| ld A,#$BA |
;| ld {dividend+2},A |
;| ld A,#$98 |
;| ld {dividend+3},A |
;| ld A,#$AB |
;| ld divisor,A |
;| ld A,#$CD |
;| ld {divisor+1},A |
;| CALL div_lxw |
;| - do... |
;| - do... |
;| ;***** subroutine ***** |
;| . div_lxw |
;| END |
;| |
;+--------------------------------------------------------------------------
.div_lxw
push A ; save Accumulator in stack
push X ; save X register in stack
ld X,#32 ; Initialization process
ld A,#0 ; We use the load instruction
ld quotient,A ; which is faster than the
ld {quotient+1},A; clear instruction for
ld tempquot,A ; multiple short datas.
ld {tempquot+1},A; For a smaller code size
ld {tempquot+2},A; you’d better use the clear
ld {tempquot+3},A; instruction
.execute
sla {dividend+3} ;Shift left dividend with 32 leading Zeros
rlc {dividend+2}
rlc {dividend+1}
rlc dividend
rlc {tempquot+3}
rlc {tempquot+2}
rlc {tempquot+1}
rlc tempquot
sla {quotient+1} ; The result cannot be greater than 16 bits
rlc quotient ; so we can shift left the quotient
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -