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