home *** CD-ROM | disk | FTP | other *** search
- (* TBTree13 Copyright (c) 1988 Dean H. Farwell II *)
-
- unit Math;
-
- (*****************************************************************************)
- (* *)
- (* M A T H M A T I C A L R O U T I N E S *)
- (* *)
- (*****************************************************************************)
-
-
- (* These routines augment the Turbo Pascal routines provided.
-
-
- (* Version Information
-
- Version 1.1 - No Changes
-
- Version 1.2 - No Changes
-
- Version 1.3 - Modified 11 July 1988 by Jack Dolby
- Gately Communication Company
- 501 Industry Drive
- Hampton, VA 23661
-
- These are inline assembly language macros to perform the same function
- as the Pascal versions in versions prior to 1.3.
-
- Note that the entire code for inline macros must be in the INTERFACE
- section. The code in these macros is actually placed in the code the
- compiler emits at each place they are invoked. This results in larger
- code but eliminates the time overhead for calling a routine and
- returning from it. Only the pushing of parameters and extracting the
- functional result are done rather than also pushing the return address,
- preserving registers in the code, setting up a stack frame, and
- restoring all registers and the stack on return. This results in
- faster code at the expense of code size (if called from more than one
- place) and in loosing the ability to hide the code in the
- IMPLEMENTATION SECTION. j. dolby
-
- My special thanks goes to j. dolby who took the time to make these
- improvements and graciously allowed me to include them for
- distribution!! Dean H. Farwell II *)
-
- (*\*)
- (*////////////////////////// I N T E R F A C E //////////////////////////////*)
-
- interface
-
- (* This function calculates and returns x ** y (x to the power of y) where
- both x and y are Integers. This function has not been tested with negative
- parameters.
-
- The author of the assembly version (j dolby) has tested this
- routine over the range of 0...32767. All answers are numerically
- the same as the original routine. However, some answers that are
- above the upper limit of 32767 will report that they are not the
- same. In these cases, the numeric value in the returned 16 bits
- are the same but Turbo Pascal will report them to be different. It
- is apparently either the upper 16 bits in DX (which is discarded)
- or the status flags that are causing this apparent error. However,
- the integer returned is the for these out of range answers and
- there is an exact Turbo Pascal equivalence for all answers in the
- range 0...32767.
-
- In the big picture of things this routine was only included
- originally because I needed it for the other two routines. Now,
- with the assembly versions of the other two routines, this routine
- is not required. I am leaving it in just in case someone is using
- it for something else. -- Dean *)
-
- function PowerInt(x,y : Integer) : Integer;
-
- INLINE
- (
- $59/ { pop cx get power y }
- $5B/ { pop bx get number x }
- $B8/$01/$00/ { mov ax,1 set up for first mul }
- $E3/$04/ { jcxz exit exit with answer = 1 if power = 0 }
- $F7/$E3/ { mul bx dx:ax := ax * bx }
- $E2/$FC { loop dec cx and do mul until cx = 0 }
- );
-
- (*\*)
- (* the following type supports the byte handling routine(s) *)
-
- type
- BytePosition = 0 .. 7;
- BitValue = 0 .. 1;
-
-
- (* This function will determine if a certain bit within a target byte is
- toggled on (equal to 1). The bit position is is the position within the
- byte of the bit to be tested. The least significant bit is 0 then most
- significant bit is 7. If the bit is 1 TRUE will be returned. If the bit
- is 0 FALSE will be returned. Notice that the target byte can be of any
- type. in this way, the routine will handle any a bit byte. In other
- words a character could also be passed in. *)
-
- (* Boolean functions return zero flag set and AL=0 for false,
- zero flag reset and AL=1 for true *)
-
- function BitOn(var targetByte;
- bitNum : BytePosition) : Boolean;
-
- INLINE (
- $59/ { pop cx get bitnum }
- $5B/ { pop bx get offset of targetbyte }
- $07/ { pop es get segment of targetbyte }
- $26/ { es use extra seg for data }
- $8A/$07/ { mov al,[bx] get targetbyte }
- $B2/$01/ { mov dl,01 start set up of mask }
- $D2/$E2/ { shl dl,cl put 1 in position bitnum }
- $20/$D0/ { and al,dl apply mask }
- $74/$03/ { jz exit done if zero }
- $B8/$01/$00 { mov ax,01 set accumulator = 1 }
- );
-
- (*\*)
- (* This will set a given bit to a value of zero or one depending on what is
- passed in as the last parameter. See above for description of the other
- parameters *)
-
- procedure SetBit(var targetByte;
- bitNum : BytePosition;
- bit : BitValue);
-
- INLINE (
- $58/ { pop ax get bitvalue }
- $59/ { pop cx get bitnum }
- $5B/ { pop bx get offset of targetbyte }
- $07/ { pop es get seg of targetbyte }
- $B2/$01/ { mov dl,1 set bit for mask }
- $D2/$E2/ { shl dl,cl move mask bit to proper }
- { position }
- $26/ { es use extra seg for data }
- $08/$17/$0A/ { or byte pointer[bx],dl set bit regardless }
- $C0/ { or al,al should it be a one? }
- $75/$03/ { jnz exit yes-exit else reset bit }
- $26/ { es use extra seg for data }
- $30/$17 { xor byte pointer[bx],dl reset bit }
- );
-
-
- (*///////////////////// I M P L E M E N T A T I O N /////////////////////////*)
-
- implementation
-
- end. (* end of Math unit *)