Module Barith

Once upon a time I needed binary arithmatic functions for Modula-2 and I did not yet know about the BITSET type and associated functions. So I created my own Module: Binary ARITHmatic. Here's the implementation module:

DEFINITION MODULE barith;

(*  This is FREE software, as described in the GNU General Public Licences.
    Therefore it comes WITH THE FULL SOURCES. Please feel free to improve this
    code when necessary. You OWN this code. I am not Bill Gates.

    I would appreciate that people let in this message when extending this
    library, as a small tribute to me (for laying the foundation). 

    In case people need extra information, contact me via:

        snail mail: Jan Verhoeven, 5012 GH 272, The Netherlands
   electronic mail: jverhoeven@bigfoot.com

    I remain full copyrights to these sources. If you want to send me a small 
    "thanks", please send me a postcard of your hometown to the above shown
    snailmail address. Yes it is in code; the internal code of our national 
    mail deliverer.

    Use this software at your own risk. Please find yourself a GNU GPL if you
    are in any doubt. I use these functions for all my own software, but there
    is NO GUARANTEE OF ANY KIND covering it.            *)

(*  Add support for bitwise logical operators to Modula-2.
    Binary ARITHmatic.
    *)

PROCEDURE and (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x AND y.
    *)

PROCEDURE nand (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x AND not Y.
    *)

PROCEDURE or (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x OR Y.
    *)

PROCEDURE nor (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x OR NOT y.
    *)

PROCEDURE xor (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x XOR y.
    *)

PROCEDURE test (x, y : CARDINAL) : BOOLEAN;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := TEST (x, y).
    *)

PROCEDURE shl (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := SHL x, y
    *)

PROCEDURE shr (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := SHR x for y bits.
    *)

PROCEDURE MulDiv (Mul1, Mul2, Div : CARDINAL) : CARDINAL;
(*
    Calculate Mul1 * Mul2 / Div with 32 bit intermediate result.  *)

END barith.
   
And not only binary arithmatic... I also borrowed the MulDiv instruction from FORTH. It is a word x word multiplication with the intermediate result kept in a double word.

Here's the implementation module:
   IMPLEMENTATION MODULE barith;

(*  This is FREE software, as described in the GNU General Public Licences.
    Therefore it comes WITH THE FULL SOURCES. Please feel free to improve this
    code when necessary. You OWN this code. I am not Bill Gates.

    I would appreciate that people let in this message when extending this
    library, as a small tribute to me (for laying the foundation).

    In case people need extra information, contact me via:

        snail mail: Jan Verhoeven, 5012 GH 272, The Netherlands
   electronic mail: jverhoeven@bigfoot.com

    I remain full copyrights to these sources. If you want to send me a small
    "thanks", please send me a postcard of your hometown to the above shown
    snailmail address. Yes it is in code; the internal code of our national
    mail deliverer.

    Use this software at your own risk. Please find yourself a GNU GPL if you
    are in any doubt. I use these functions for all my own software, but there
    is NO GUARANTEE OF ANY KIND covering it.            *)

FROM    SYSTEM      IMPORT  ASSEMBLER;


PROCEDURE and (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x AND y.
    *)

VAR Result  : CARDINAL;

BEGIN
    ASM
        MOV  AX, x
        MOV  BX, y
        AND  AX, BX
        MOV  Result, AX
    END;
    RETURN Result;
END and;


PROCEDURE nand (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x AND not Y.
    *)

VAR Result  : CARDINAL;

BEGIN
    ASM
        MOV  AX, x
        MOV  BX, y
        NOT  BX
        AND  AX, BX
        MOV  Result, AX
    END;
    RETURN Result;
END nand;


PROCEDURE or (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x OR Y.
    *)

VAR Result  : CARDINAL;

BEGIN
    ASM
        MOV  AX, x
        MOV  BX, y
        OR   AX, BX
        MOV  Result, AX
    END;
    RETURN Result;
END or;


PROCEDURE nor (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x OR NOT y.
    *)

VAR Result  : CARDINAL;

BEGIN
    ASM
        MOV  AX, x
        MOV  BX, y
        NOT  BX
        OR   AX, BX
        MOV  Result, AX
    END;
    RETURN Result;
END nor;


PROCEDURE xor (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := x XOR y.
    *)

VAR Result  : CARDINAL;

BEGIN
    ASM
        MOV  AX, x
        MOV  BX, y
        XOR  AX, BX
        MOV  Result, AX
    END;
    RETURN Result;
END xor;


PROCEDURE test (x, y : CARDINAL) : BOOLEAN;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := TEST (x, y)
    *)

VAR Result  : BOOLEAN;

BEGIN
    ASM
        MOV  DX, 0
        MOV  AX, x
        MOV  BX, y
        TEST AX, BX
        JZ   L0
        INC  DX
    L0: MOV  Result, DX
    END;
    RETURN Result;
END test;


PROCEDURE shl (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := SHL x, y
    *)

VAR result  : CARDINAL;

BEGIN
    ASM
        MOV  AX, x
        MOV  CX, y
        AND  CX, 15
        JCXZ ok
        SHL  AX, CL
    ok: MOV  result, AX
    END;
    RETURN result;
END shl;


PROCEDURE shr (x, y : CARDINAL) : CARDINAL;
(*
    Perform binary arithmatic to operands x and y and return it.
    Operation:  Result := SHR x for y bits.
    *)

VAR result      : CARDINAL;

BEGIN
    ASM
        MOV  AX, x
        MOV  CX, y
        AND  CX, 15
        JCXZ ok
        SHR  AX, CL
    ok: MOV  result, AX
    END;
    RETURN result;
END shr;


PROCEDURE MulDiv (Mul1, Mul2, Div : CARDINAL) : CARDINAL;
(*
    Calculate Mul1 * Mul2 / Div with 32 bit intermediate result.  *)

VAR Result      : CARDINAL;

BEGIN
    ASM
        MOV  AX, Mul1
        MOV  BX, Mul2
        MUL  BX             (* DX:AX = result   *)
        MOV  BX, Div
        DIV  BX
        MOV  Result, AX
    END;
    RETURN Result;
END MulDiv;

END barith.
   

Page created September 9, 2012 and