summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/common/_int64.asm
diff options
context:
space:
mode:
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.asm309
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
OpenPOWER on IntegriCloud