diff options
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/common/_int64.asm')
-rw-r--r-- | board/MAI/bios_emulator/scitech/src/pm/common/_int64.asm | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/common/_int64.asm b/board/MAI/bios_emulator/scitech/src/pm/common/_int64.asm new file mode 100644 index 0000000000..fdec1b58d8 --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/common/_int64.asm @@ -0,0 +1,309 @@ +;**************************************************************************** +;* +;* SciTech OS Portability Manager Library +;* +;* ======================================================================== +;* +;* The contents of this file are subject to the SciTech MGL Public +;* License Version 1.0 (the "License"); you may not use this file +;* except in compliance with the License. You may obtain a copy of +;* the License at http://www.scitechsoft.com/mgl-license.txt +;* +;* Software distributed under the License is distributed on an +;* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +;* implied. See the License for the specific language governing +;* rights and limitations under the License. +;* +;* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc. +;* +;* The Initial Developer of the Original Code is SciTech Software, Inc. +;* All Rights Reserved. +;* +;* ======================================================================== +;* +;* Language: NASM or TASM Assembler +;* Environment: Intel 32 bit Protected Mode. +;* +;* Description: Code for 64-bit arhithmetic +;* +;**************************************************************************** + + IDEAL + +include "scitech.mac" + +header _int64 + +begcodeseg _int64 ; Start of code segment + +a_low EQU 04h ; Access a_low directly on stack +a_high EQU 08h ; Access a_high directly on stack +b_low EQU 0Ch ; Access b_low directly on stack +shift EQU 0Ch ; Access shift directly on stack +result_2 EQU 0Ch ; Access result directly on stack +b_high EQU 10h ; Access b_high directly on stack +result_3 EQU 10h ; Access result directly on stack +result_4 EQU 14h ; Access result directly on stack + +;---------------------------------------------------------------------------- +; void _PM_add64(u32 a_low,u32 a_high,u32 b_low,u32 b_high,__u64 *result); +;---------------------------------------------------------------------------- +; Adds two 64-bit numbers. +;---------------------------------------------------------------------------- +cprocstart _PM_add64 + + mov eax,[esp+a_low] + add eax,[esp+b_low] + mov edx,[esp+a_high] + adc edx,[esp+b_high] + mov ecx,[esp+result_4] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + +;---------------------------------------------------------------------------- +; void _PM_sub64(u32 a_low,u32 a_high,u32 b_low,u32 b_high,__u64 *result); +;---------------------------------------------------------------------------- +; Subtracts two 64-bit numbers. +;---------------------------------------------------------------------------- +cprocstart _PM_sub64 + + mov eax,[esp+a_low] + sub eax,[esp+b_low] + mov edx,[esp+a_high] + sbb edx,[esp+b_high] + mov ecx,[esp+result_4] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + +;---------------------------------------------------------------------------- +; void _PM_mul64(u32 a_high,u32 a_low,u32 b_high,u32 b_low,__u64 *result); +;---------------------------------------------------------------------------- +; Multiples two 64-bit numbers. +;---------------------------------------------------------------------------- +cprocstart _PM_mul64 + + mov eax,[esp+a_high] + mov ecx,[esp+b_high] + or ecx,eax + mov ecx,[esp+b_low] + jnz @@FullMultiply + mov eax,[esp+a_low] ; EDX:EAX = b.low * a.low + mul ecx + mov ecx,[esp+result_4] + mov [ecx],eax + mov [ecx+4],edx + ret + +@@FullMultiply: + push ebx + mul ecx ; EDX:EAX = a.high * b.low + mov ebx,eax + mov eax,[esp+a_low+4] + mul [DWORD esp+b_high+4] ; EDX:EAX = b.high * a.low + add ebx,eax + mov eax,[esp+a_low+4] + mul ecx ; EDX:EAX = a.low * b.low + add edx,ebx + pop ebx + mov ecx,[esp+result_4] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + +;---------------------------------------------------------------------------- +; void _PM_div64(u32 a_low,u32 a_high,u32 b_low,u32 b_high,__u64 *result); +;---------------------------------------------------------------------------- +; Divides two 64-bit numbers. +;---------------------------------------------------------------------------- +cprocstart _PM_div64 + + push edi + push esi + push ebx + xor edi,edi + mov eax,[esp+a_high+0Ch] + or eax,eax + jns @@ANotNeg + +; Dividend is negative, so negate it and save result for later + + inc edi + mov edx,[esp+a_low+0Ch] + neg eax + neg edx + sbb eax,0 + mov [esp+a_high+0Ch],eax + mov [esp+a_low+0Ch],edx + +@@ANotNeg: + mov eax,[esp+b_high+0Ch] + or eax,eax + jns @@BNotNeg + +; Divisor is negative, so negate it and save result for later + + inc edi + mov edx,[esp+b_low+0Ch] + neg eax + neg edx + sbb eax,0 + mov [esp+b_high+0Ch],eax + mov [esp+b_low+0Ch],edx + +@@BNotNeg: + or eax,eax + jnz @@BHighNotZero + +; b.high is zero, so handle this faster + + mov ecx,[esp+b_low+0Ch] + mov eax,[esp+a_high+0Ch] + xor edx,edx + div ecx + mov ebx,eax + mov eax,[esp+a_low+0Ch] + div ecx + mov edx,ebx + jmp @@BHighZero + +@@BHighNotZero: + mov ebx,eax + mov ecx,[esp+b_low+0Ch] + mov edx,[esp+a_high+0Ch] + mov eax,[esp+a_low+0Ch] + +; Shift values right until b.high becomes zero + +@@ShiftLoop: + shr ebx,1 + rcr ecx,1 + shr edx,1 + rcr eax,1 + or ebx,ebx + jnz @@ShiftLoop + +; Now complete the divide process + + div ecx + mov esi,eax + mul [DWORD esp+b_high+0Ch] + mov ecx,eax + mov eax,[esp+b_low+0Ch] + mul esi + add edx,ecx + jb @@8 + cmp edx,[esp+a_high+0Ch] + ja @@8 + jb @@9 + cmp eax,[esp+a_low+0Ch] + jbe @@9 +@@8: dec esi +@@9: xor edx,edx + mov eax,esi + +@@BHighZero: + dec edi + jnz @@Done + +; The result needs to be negated as either a or b was negative + + neg edx + neg eax + sbb edx,0 + +@@Done: pop ebx + pop esi + pop edi + mov ecx,[esp+result_4] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + +;---------------------------------------------------------------------------- +; __i64 _PM_shr64(u32 a_low,s32 a_high,s32 shift,__u64 *result); +;---------------------------------------------------------------------------- +; Shift a 64-bit number right +;---------------------------------------------------------------------------- +cprocstart _PM_shr64 + + mov eax,[esp+a_low] + mov edx,[esp+a_high] + mov cl,[esp+shift] + shrd edx,eax,cl + mov ecx,[esp+result_3] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + +;---------------------------------------------------------------------------- +; __i64 _PM_sar64(u32 a_low,s32 a_high,s32 shift,__u64 *result); +;---------------------------------------------------------------------------- +; Shift a 64-bit number right (signed) +;---------------------------------------------------------------------------- +cprocstart _PM_sar64 + + mov eax,[esp+a_low] + mov edx,[esp+a_high] + mov cl,[esp+shift] + sar edx,cl + rcr eax,cl + mov ecx,[esp+result_3] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + +;---------------------------------------------------------------------------- +; __i64 _PM_shl64(u32 a_low,s32 a_high,s32 shift,__u64 *result); +;---------------------------------------------------------------------------- +; Shift a 64-bit number left +;---------------------------------------------------------------------------- +cprocstart _PM_shl64 + + mov eax,[esp+a_low] + mov edx,[esp+a_high] + mov cl,[esp+shift] + shld edx,eax,cl + mov ecx,[esp+result_3] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + +;---------------------------------------------------------------------------- +; __i64 _PM_neg64(u32 a_low,s32 a_high,__u64 *result); +;---------------------------------------------------------------------------- +; Shift a 64-bit number left +;---------------------------------------------------------------------------- +cprocstart _PM_neg64 + + mov eax,[esp+a_low] + mov edx,[esp+a_high] + neg eax + neg edx + sbb eax,0 + mov ecx,[esp+result_2] + mov [ecx],eax + mov [ecx+4],edx + ret + +cprocend + + +endcodeseg _int64 + + END |