source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Libraries/math.asm@ 79

Last change on this file since 79 was 77, checked in by krille_n_@…, 14 years ago

Minor size optimizations plus a bug fix in print.asm in Print_IntSW (DI was left hanging on the stack if the parameter in AX was positive). Also a very minor speed optimization in keys.asm in Keys_Backspace.

File size: 4.8 KB
RevLine 
[3]1; File name : math.asm
2; Project name : Math library
3; Created date : 7.10.2009
[77]4; Last update : 4.1.2011
5; Author : Tomi Tilli,
6; : Krister Nordvall (optimizations)
[3]7; Description : ASM library to for math related functions.
8
9;--------------- Equates -----------------------------
10
11; String library function to include
12;%define USE_MATH_MULDWBYW ; Math_MulDWbyW
13%define USE_MATH_DIVDWBYW ; Math_DivDWbyW
14%define USE_MATH_REMTOTENTHS ; Math_RemToTenths
15
16
17;-------------- Private global variables -------------
18; Section containing initialized data
19;SECTION .data
20
21
22;-------------- Public functions ---------------------
23; Section containing code
24SECTION .text
25
26
27;--------------------------------------------------------------------
28; Macro to select lesser of two unsigned operands.
29;
30; MIN_U
31; Parameters:
32; %1: Operand 1
33; %2: Operand 2
34; Returns:
35; %1: Lesser unsigned operand
36; Corrupts registers:
37; Nothing
38;--------------------------------------------------------------------
39%macro MIN_U 2
40 cmp %1, %2 ; Is %1 smaller?
41 jb %%Return ; If so, return
42 mov %1, %2 ; Copy %2 to %1
43ALIGN JUMP_ALIGN
44%%Return:
45%endmacro
46
47
48;--------------------------------------------------------------------
49; Macro to select greater of two unsigned operands.
50;
51; MAX_U
52; Parameters:
53; %1: Operand 1
54; %2: Operand 2
55; Returns:
56; %1: Greater unsigned operand
57; Corrupts registers:
58; Nothing
59;--------------------------------------------------------------------
60%macro MAX_U 2
61 cmp %1, %2 ; Is %1 greater?
62 ja %%Return ; If so, return
63 mov %1, %2 ; Copy %2 to %1
64ALIGN JUMP_ALIGN
65%%Return:
66%endmacro
67
68
69;--------------------------------------------------------------------
70; Macro to select lesser and greater of two unsigned operands.
71;
72; MINMAX_U
73; Parameters:
74; %1: Operand 1
75; %2: Operand 2
76; Returns:
77; %1: Lesser unsigned operand
78; %2: Greater unsigned operand
79; Corrupts registers:
80; Nothing
81;--------------------------------------------------------------------
82%macro MINMAX_U 2
83 cmp %1, %2 ; Is %1 smaller?
84 jbe %%Return ; If so, return
85 xchg %1, %2 ; Exchange operands
86ALIGN JUMP_ALIGN
87%%Return:
88%endmacro
89
90
91;--------------------------------------------------------------------
92; DWORD * WORD multiplication.
93; Multiplies unsigned 32-bit integer by unsigned 16-bit integer.
94; Result is unsigned 32-bit integer, so overflow is possible.
95;
96; Math_MulDWbyW
97; Parameters:
98; DX:AX: 32-bit unsigned integer to multiply
99; CX: 16-bit unsigned multiplier
100; Returns:
101; DX:AX: 32-bit unsigned integer
102; Corrupts registers:
103; Nothing
104;--------------------------------------------------------------------
105%ifdef USE_MATH_MULDWBYW
106ALIGN JUMP_ALIGN
107Math_MulDWbyW:
108 jcxz .RetZero ; If CX=0, return 0
109 push bx
110 mov bx, dx ; Copy hiword to BX
111 xor dx, dx ; Zero DX for multiplication
112 mul cx ; DX:AX = AX (loword) * CX (multiplier)
113 push dx ; Push possible overflow
114 xchg ax, bx ; => AX=old hiword, BX=new loword
115 xor dx, dx ; Zero DX for division
116 mul cx ; DX:AX = AX (hiword) * CX (multiplier)
117 pop dx ; Pop possible overflow from first mul
118 add dx, ax ; Add new hiword to overflow from first mul
119 mov ax, bx ; Copy new loword to AX
120 pop bx
121 ret
122ALIGN JUMP_ALIGN
123.RetZero: ; Return 0 in DX:AX
124 xor ax, ax
[77]125 cwd
[3]126 ret
127%endif
128
129
130;--------------------------------------------------------------------
131; Divide a 32-bit unsigned integer so that quotient can be 32-bit.
132;
133; Math_DivDWbyW
134; Parameters:
135; DX:AX: 32-bit unsigned divident
136; CX: 16-bit unsigned divisor
137; Returns:
138; DX:AX: 32-bit unsigned quotient
139; BX: 16-bit unsigned remainder
140; Corrupts registers:
141; Nothing
142;--------------------------------------------------------------------
143%ifdef USE_MATH_DIVDWBYW
144ALIGN JUMP_ALIGN
145Math_DivDWbyW:
[77]146 xor bx, bx
147 xchg bx, ax
148 xchg dx, ax
[3]149 div cx
150 xchg ax, bx
151 div cx
152 xchg dx, bx
153 ret
154%endif
155
156
157;--------------------------------------------------------------------
158; Converts remainder to tenths.
159;
160; Math_RemToTenths
161; Parameters:
162; BX: 16-bit unsigned remainder
163; CX: 16-bit unsigned divisor used when calculated the remainder (max 2559)
164; Returns:
165; BX: Remainder converted to tenths
166; Corrupts registers:
167; Nothing
168;--------------------------------------------------------------------
169%ifdef USE_MATH_REMTOTENTHS
170ALIGN JUMP_ALIGN
171Math_RemToTenths:
172 push cx
173 push ax
[77]174 mov al, 10 ; Load 10 to AL
175 xchg cx, ax ; AX = Divisor CL = 10
[3]176 div cl ; AL = Divisor divided by 10
177 inc ax ; Increment to compensate new remainder
178 xchg ax, bx ; AX = 16-bit remainder to convert
179 ; BL = Original divisor divided by 10
180 div bl ; AX = Original remainder converted to tenths
181 eMOVZX bx, al ; Copy return value to BX
182 pop ax
183 pop cx
184 ret
185%endif
Note: See TracBrowser for help on using the repository browser.