source: xtideuniversalbios/trunk/Configurator/Src/Libraries/math.asm@ 601

Last change on this file since 601 was 445, checked in by krille_n_@…, 12 years ago

Changes:

  • A speed optimization to the eSHL_IM macro for 386 and higher. This change breaks emulation in the sense that the macro will fail when given a memory operand as the first parameter.
  • Memory_SumCXbytesFromESSItoAL now returns with the zero flag set/cleared according to the result.
  • Unrolled all the 8 bit READ transfer loops to do 16 bytes per iteration. Added a new macro (UNROLL_SECTORS_IN_CX_TO_OWORDS) as part of it. Size wise this is expensive but I think it should be worth the ROM space. The WRITE transfer loops were left as is since writes are rare anyway (<10% of all disk I/O IIRC).
  • Minor optimizations and fixes here and there.
File size: 4.6 KB
Line 
1; Project name : Math library
2; Description : ASM library for math related functions.
3
4;--------------- Equates -----------------------------
5
6; String library function to include
7%define USE_MATH_MULDWBYW ; Math_MulDWbyW
8%define USE_MATH_DIVDWBYW ; Math_DivDWbyW
9%define USE_MATH_REMTOTENTHS ; Math_RemToTenths
10
11
12;-------------- Private global variables -------------
13; Section containing initialized data
14;SECTION .data
15
16
17;-------------- Public functions ---------------------
18; Section containing code
19SECTION .text
20
21
22;--------------------------------------------------------------------
23; Macro to select lesser of two unsigned operands.
24;
25; MIN_U
26; Parameters:
27; %1: Operand 1
28; %2: Operand 2
29; Returns:
30; %1: Lesser unsigned operand
31; Corrupts registers:
32; Nothing
33;--------------------------------------------------------------------
34%macro MIN_U 2
35 cmp %1, %2 ; Is %1 smaller?
36 jb %%Return ; If so, return
37 mov %1, %2 ; Copy %2 to %1
38ALIGN JUMP_ALIGN
39%%Return:
40%endmacro
41
42
43;--------------------------------------------------------------------
44; Macro to select greater of two unsigned operands.
45;
46; MAX_U
47; Parameters:
48; %1: Operand 1
49; %2: Operand 2
50; Returns:
51; %1: Greater unsigned operand
52; Corrupts registers:
53; Nothing
54;--------------------------------------------------------------------
55%macro MAX_U 2
56 cmp %1, %2 ; Is %1 greater?
57 ja %%Return ; If so, return
58 mov %1, %2 ; Copy %2 to %1
59ALIGN JUMP_ALIGN
60%%Return:
61%endmacro
62
63
64;--------------------------------------------------------------------
65; Macro to select lesser and greater of two unsigned operands.
66;
67; MINMAX_U
68; Parameters:
69; %1: Operand 1
70; %2: Operand 2
71; Returns:
72; %1: Lesser unsigned operand
73; %2: Greater unsigned operand
74; Corrupts registers:
75; Nothing
76;--------------------------------------------------------------------
77%macro MINMAX_U 2
78 cmp %1, %2 ; Is %1 smaller?
79 jb %%Return ; If so, return
80 xchg %1, %2 ; Exchange operands
81ALIGN JUMP_ALIGN
82%%Return:
83%endmacro
84
85
86;--------------------------------------------------------------------
87; DWORD * WORD multiplication.
88; Multiplies unsigned 32-bit integer by unsigned 16-bit integer.
89; Result is unsigned 32-bit integer, so overflow is possible.
90;
91; Math_MulDWbyW
92; Parameters:
93; DX:AX: 32-bit unsigned integer to multiply
94; CX: 16-bit unsigned multiplier
95; Returns:
96; DX:AX: 32-bit unsigned integer
97; Corrupts registers:
98; Nothing
99;--------------------------------------------------------------------
100%ifdef USE_MATH_MULDWBYW
101ALIGN JUMP_ALIGN
102Math_MulDWbyW:
103 jcxz .RetZero ; If CX=0, return 0
104 push bx
105 mov bx, dx ; Copy hiword to BX
106 mul cx ; DX:AX = AX (loword) * CX (multiplier)
107 push dx ; Push possible overflow
108 xchg ax, bx ; => AX=old hiword, BX=new loword
109 mul cx ; DX:AX = AX (hiword) * CX (multiplier)
110 pop dx ; Pop possible overflow from first mul
111 add dx, ax ; Add new hiword to overflow from first mul
112 mov ax, bx ; Copy new loword to AX
113 pop bx
114 ret
115ALIGN JUMP_ALIGN
116.RetZero: ; Return 0 in DX:AX
117 xor ax, ax
118 cwd
119 ret
120%endif
121
122
123;--------------------------------------------------------------------
124; Divide a 32-bit unsigned integer so that quotient can be 32-bit.
125;
126; Math_DivDWbyW
127; Parameters:
128; DX:AX: 32-bit unsigned divident
129; CX: 16-bit unsigned divisor
130; Returns:
131; DX:AX: 32-bit unsigned quotient
132; BX: 16-bit unsigned remainder
133; Corrupts registers:
134; Nothing
135;--------------------------------------------------------------------
136%ifdef USE_MATH_DIVDWBYW
137ALIGN JUMP_ALIGN
138Math_DivDWbyW:
139 xor bx, bx
140 xchg bx, ax
141 xchg dx, ax
142 div cx
143 xchg ax, bx
144 div cx
145 xchg dx, bx
146 ret
147%endif
148
149
150;--------------------------------------------------------------------
151; Converts remainder to tenths.
152;
153; Math_RemToTenths
154; Parameters:
155; BX: 16-bit unsigned remainder
156; CX: 16-bit unsigned divisor used when calculated the remainder (max 2559)
157; Returns:
158; BX: Remainder converted to tenths
159; Corrupts registers:
160; Nothing
161;--------------------------------------------------------------------
162%ifdef USE_MATH_REMTOTENTHS
163ALIGN JUMP_ALIGN
164Math_RemToTenths:
165 push cx
166 push ax
167 mov al, 10 ; Load 10 to AL
168 xchg cx, ax ; AX = Divisor CL = 10
169 div cl ; AL = Divisor divided by 10
170 inc ax ; Increment to compensate new remainder
171 xchg ax, bx ; AX = 16-bit remainder to convert
172 ; BL = Original divisor divided by 10
173 div bl ; AX = Original remainder converted to tenths
174 eMOVZX bx, al ; Copy return value to BX
175 pop ax
176 pop cx
177 ret
178%endif
Note: See TracBrowser for help on using the repository browser.