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

Last change on this file since 401 was 181, checked in by krille_n_@…, 13 years ago

Changes to all parts of the project:

  • Size optimizations.
  • Added a define (EXCLUDE_FROM_XTIDECFG) to exclude unused library code from XTIDECFG.
  • Tried to minimize time spent with interrupts disabled.
  • Some minor attempts to improve speed (reordering instructions etc).
  • Tried to improve readability, did some cleanup and fixed some errors in comments.
File size: 4.7 KB
RevLine 
[2]1; Project name : Math library
[181]2; Description : ASM library for math related functions.
[2]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.
[181]24;
[2]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.
[181]45;
[2]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.
[181]66;
[2]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?
[181]79 jb %%Return ; If so, return
[2]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.
[181]90;
[2]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 xor dx, dx ; Zero DX for multiplication
107 mul cx ; DX:AX = AX (loword) * CX (multiplier)
108 push dx ; Push possible overflow
109 xchg ax, bx ; => AX=old hiword, BX=new loword
110 xor dx, dx ; Zero DX for division
111 mul cx ; DX:AX = AX (hiword) * CX (multiplier)
112 pop dx ; Pop possible overflow from first mul
113 add dx, ax ; Add new hiword to overflow from first mul
114 mov ax, bx ; Copy new loword to AX
115 pop bx
116 ret
117ALIGN JUMP_ALIGN
118.RetZero: ; Return 0 in DX:AX
119 xor ax, ax
[78]120 cwd
[2]121 ret
122%endif
123
124
125;--------------------------------------------------------------------
126; Divide a 32-bit unsigned integer so that quotient can be 32-bit.
[181]127;
[2]128; Math_DivDWbyW
129; Parameters:
130; DX:AX: 32-bit unsigned divident
131; CX: 16-bit unsigned divisor
132; Returns:
133; DX:AX: 32-bit unsigned quotient
134; BX: 16-bit unsigned remainder
135; Corrupts registers:
136; Nothing
137;--------------------------------------------------------------------
138%ifdef USE_MATH_DIVDWBYW
139ALIGN JUMP_ALIGN
140Math_DivDWbyW:
[78]141 xor bx, bx
142 xchg bx, ax
143 xchg dx, ax
[2]144 div cx
145 xchg ax, bx
146 div cx
147 xchg dx, bx
148 ret
149%endif
150
151
152;--------------------------------------------------------------------
153; Converts remainder to tenths.
[181]154;
[2]155; Math_RemToTenths
156; Parameters:
157; BX: 16-bit unsigned remainder
158; CX: 16-bit unsigned divisor used when calculated the remainder (max 2559)
159; Returns:
160; BX: Remainder converted to tenths
161; Corrupts registers:
162; Nothing
163;--------------------------------------------------------------------
164%ifdef USE_MATH_REMTOTENTHS
165ALIGN JUMP_ALIGN
166Math_RemToTenths:
167 push cx
168 push ax
[78]169 mov al, 10 ; Load 10 to AL
170 xchg cx, ax ; AX = Divisor CL = 10
[2]171 div cl ; AL = Divisor divided by 10
172 inc ax ; Increment to compensate new remainder
173 xchg ax, bx ; AX = 16-bit remainder to convert
174 ; BL = Original divisor divided by 10
175 div bl ; AX = Original remainder converted to tenths
176 eMOVZX bx, al ; Copy return value to BX
177 pop ax
178 pop cx
179 ret
180%endif
Note: See TracBrowser for help on using the repository browser.