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

Last change on this file since 181 was 181, checked in by krille_n_@…, 12 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
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    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
120    cwd
121    ret
122%endif
123
124
125;--------------------------------------------------------------------
126; Divide a 32-bit unsigned integer so that quotient can be 32-bit.
127;
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:
141    xor     bx, bx
142    xchg    bx, ax
143    xchg    dx, ax
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.
154;
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
169    mov     al, 10              ; Load 10 to AL
170    xchg    cx, ax              ; AX = Divisor CL = 10
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.