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

Last change on this file since 445 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.