Код:
================================================================================
Note 1.1 MUL, DIV, ASH for Falcon(+) 1 of 6
JAWS::KAISER 144 lines 25-MAR-1985 09:13
--------------------------------------------------------------------------------
+---------------+ +-----------------+
| d i g i t a l | | uNOTE # 001 |
+---------------+ +-----------------+
+----------------------------------------------------+-----------------+
| Title: MUL,DIV and ASH Instruction for the FALCON | Date: 13-APR-84 |
| and the FALCON-PLUS | |
+----------------------------------------------------+-----------------+
| Originator: Charlie Giorgetti | Page 1 of 4 |
+----------------------------------------------------+-----------------+
There is no hardware support for the EIS, FIS, or FPP instruction sets.
For FALCON SBC-11/21 applications that need the ability to perform the
EIS instructions MUL, DIV, and ASH, equivalent software routines can be
substituted. These callable routines do not do any form of error
checking. A user should be aware that extensive use of these software
routines for hardware instructions will have impact on system
performance. These routines can be incorporated into an application and
called as a subroutine. The calling sequence for the subroutines can be
set-up in a macro. The following is a list of each of the subroutines
and the macros that are used to set-up and call the software MUL, DIV,
and ASH routines.
Page 2
The following macro and subroutine can be used to perform the MUL
instruction in software:
.MACRO SMUL A,B,HI,LO
MOV A,-(SP) ; Push a multiplier onto the stack
MOV B,-(SP) ; Push the other multiplier as well
JSR PC,$MUL ; Call the MUL subroutine
MOV (SP)+,HI ; Get the most significant part of
the result
MOV (SP)+,LO ; Get the least significant part of
the result
.ENDM
$MUL:: MOV R0,-(SP) ; Save some work registers
MOV R1,-(SP)
MOV 10(SP),R1 ; Obtain the value of A from the stack
MOV #21,-(SP) ; Initialize the shift counter
CLR R0 ; Initialize the high 16-bit accumulator
10$: ROR R0 ; Perform multiplication
ROR R1
BCC 20$
ADD 10(SP),R0
CLC
20$: DEC (SP) ; Bump the shift counter
BNE 10$ ; Not done ?
TST (SP)+ ; Romove the counter from the stack
MOV R1,10(SP) ; Save the low 16-bit value on the stack
MOV R0,6(SP) ; Save the high 16-bit value on the stack
MOV (SP)+,R1 ; Restore the work registers
MOV (SP)+,R0
RTS PC ; Return
Page 3
The following macro and subroutine can be used to perform the DIV
instruction in software:
.MACRO SDIV DIVSOR,DIVHI,DIVLO,REM,QUO
MOV DIVSOR,-(SP); Push the divisor onto the stack
MOV DIVHI,-(SP) ; Push the upper 16-bits of the dividend
MOV DIVLO,-(SP) ; Push the lower 16-bits of the dividend
JSR PC,$DIV ; Call the DIV subroutine
MOV (SP)+,REM ; Get the remainder
MOV (SP)+,QUO ; Get the quotient
.ENDM
$DIV:: MOV R5,-(SP) ; Get some work registers
MOV R4,-(SP)
MOV R3,-(SP)
MOV R0,-(SP)
MOV 14.(SP),R3 ; Get the divisor from the stack
MOV 12.(SP),R4 ; Get the high 16-bits of the dividend
MOV 10.(SP),R5 ; as well as low 16-bits
CLR R0 ; Clear an accumulator
MOV #32.,-(SP) ; Shift counter
1$: ASL R5 ; Perform the division
ROL R4
ROL R0
CMP R0,R3
BLO 2$
SUB R3,R0
INC R5
2$: DEC (SP)
BNE 1$ ; Not done ?
TST (SP)+ ; Remove the counter from the stack
MOV R0,12.(SP) ; Store the remainder on the stack
MOV R5,14.(SP) ; Store the quotient as well
MOV (SP)+,R0 ; Restore the work registers
MOV (SP)+,R3
MOV (SP)+,R4
MOV (SP)+,R5
MOV (SP)+,(SP) ; Update the return PC
RTS PC ; Return
Page 4
The following macro and subroutine can be used to perform the ASH
instruction in software:
.MACRO SASH COUNT,VAL
MOV COUNT,-(SP) ; Push the shift count
MOV VAL,-(SP) ; Push what is to be shifted
JSR PC,$ASH ; Call the ASH subroutine
MOV (SP)+,VAL ; Get the results of the shift
.ENDM
$SASH:: MOV R0,-(SP) ; Get a couple of work registers
MOV R1,-(SP)
MOV 6(SP),R0 ; R0 = value to be shifted
MOV 8.(SP),R1 ; R1 = direction and shift count
BIC #^C<77>,R1
BEQ 20$ ; Get out if no shifting
CMP R1,#31. ; What direction is the shift
BGT 10$ ; go to the corection direction shift
5$: ASL R0
DEC R1
BNE 5$
BR 20$
10$: NEG R1
BIC #^C<77>,R1
11$: ASR R0
DEC R1
BNE 11$
20$: MOV R0,8.(SP) ; Store the shifted result on the stack
MOV (SP)+,R1 ; Restore the work registers
MOV (SP)+,R0
MOV (SP)+,(SP) ; Update the return PC
RTS PC ; Return