================================================================================ 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)+ ; Remove 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 ================================================================================