summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/common/_gatimer.asm
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/common/_gatimer.asm')
-rw-r--r--board/MAI/bios_emulator/scitech/src/common/_gatimer.asm248
1 files changed, 248 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/common/_gatimer.asm b/board/MAI/bios_emulator/scitech/src/common/_gatimer.asm
new file mode 100644
index 0000000000..0194a62f98
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/common/_gatimer.asm
@@ -0,0 +1,248 @@
+;****************************************************************************
+;*
+;* SciTech Nucleus Graphics Architecture
+;*
+;* Copyright (C) 1991-1998 SciTech Software, Inc.
+;* All rights reserved.
+;*
+;* ======================================================================
+;* |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
+;* | |
+;* |This copyrighted computer code contains proprietary technology |
+;* |owned by SciTech Software, Inc., located at 505 Wall Street, |
+;* |Chico, CA 95928 USA (http://www.scitechsoft.com). |
+;* | |
+;* |The contents of this file are subject to the SciTech Nucleus |
+;* |License; you may *not* use this file or related software except in |
+;* |compliance with the License. You may obtain a copy of the License |
+;* |at http://www.scitechsoft.com/nucleus-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. |
+;* | |
+;* |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
+;* ======================================================================
+;*
+;* Language: 80386 Assembler, NASM or TASM
+;* Environment: IBM PC 32 bit Protected Mode.
+;*
+;* Description: Assembly support functions for the Nucleus library for
+;* the high resolution timing support functions provided by
+;* the Intel Pentium and compatible processors.
+;*
+;****************************************************************************
+
+ IDEAL
+
+include "scitech.mac" ; Memory model macros
+
+header _gatimer
+
+begcodeseg _gatimer
+
+ifdef USE_NASM
+%macro mCPU_ID 0
+db 00Fh,0A2h
+%endmacro
+else
+MACRO mCPU_ID
+db 00Fh,0A2h
+ENDM
+endif
+
+ifdef USE_NASM
+%macro mRDTSC 0
+db 00Fh,031h
+%endmacro
+else
+MACRO mRDTSC
+db 00Fh,031h
+ENDM
+endif
+
+;----------------------------------------------------------------------------
+; bool _GA_haveCPUID(void)
+;----------------------------------------------------------------------------
+; Determines if we have support for the CPUID instruction.
+;----------------------------------------------------------------------------
+cprocstart _GA_haveCPUID
+
+ enter_c
+ pushfd ; Get original EFLAGS
+ pop eax
+ mov ecx, eax
+ xor eax, 200000h ; Flip ID bit in EFLAGS
+ push eax ; Save new EFLAGS value on stack
+ popfd ; Replace current EFLAGS value
+ pushfd ; Get new EFLAGS
+ pop eax ; Store new EFLAGS in EAX
+ xor eax, ecx ; Can not toggle ID bit,
+ jnz @@1 ; Processor=80486
+ mov eax,0 ; We dont have CPUID support
+ jmp @@Done
+@@1: mov eax,1 ; We have CPUID support
+@@Done: leave_c
+ ret
+
+cprocend
+
+;----------------------------------------------------------------------------
+; uint _GA_getCPUIDFeatures(void)
+;----------------------------------------------------------------------------
+; Determines the CPU type using the CPUID instruction.
+;----------------------------------------------------------------------------
+cprocstart _GA_getCPUIDFeatures
+
+ enter_c
+
+ xor eax, eax ; Set up for CPUID instruction
+ mCPU_ID ; Get and save vendor ID
+ cmp eax, 1 ; Make sure 1 is valid input for CPUID
+ jl @@Fail ; We dont have the CPUID instruction
+ xor eax, eax
+ inc eax
+ mCPU_ID ; Get family/model/stepping/features
+ mov eax, edx
+@@Done: leave_c
+ ret
+
+@@Fail: xor eax,eax
+ jmp @@Done
+
+cprocend
+
+;----------------------------------------------------------------------------
+; void _GA_readTimeStamp(GA_largeInteger *time)
+;----------------------------------------------------------------------------
+; Reads the time stamp counter and returns the 64-bit result.
+;----------------------------------------------------------------------------
+cprocstart _GA_readTimeStamp
+
+ mRDTSC
+ mov ecx,[esp+4] ; Access directly without stack frame
+ mov [ecx],eax
+ mov [ecx+4],edx
+ ret
+
+cprocend
+
+;----------------------------------------------------------------------------
+; N_uint32 GA_TimerDifference(GA_largeInteger *a,GA_largeInteger *b)
+;----------------------------------------------------------------------------
+; Computes the difference between two 64-bit numbers (a-b)
+;----------------------------------------------------------------------------
+cprocstart GA_TimerDifference
+
+ ARG a:DPTR, b:DPTR, t:DPTR
+
+ enter_c
+
+ mov ecx,[a]
+ mov eax,[ecx] ; EAX := b.low
+ mov ecx,[b]
+ sub eax,[ecx]
+ mov edx,eax ; EDX := low difference
+ mov ecx,[a]
+ mov eax,[ecx+4] ; ECX := b.high
+ mov ecx,[b]
+ sbb eax,[ecx+4] ; EAX := high difference
+ mov eax,edx ; Return low part
+
+ leave_c
+ ret
+
+cprocend
+
+; Macro to delay briefly to ensure that enough time has elapsed between
+; successive I/O accesses so that the device being accessed can respond
+; to both accesses even on a very fast PC.
+
+ifdef USE_NASM
+%macro DELAY_TIMER 0
+ jmp short $+2
+ jmp short $+2
+ jmp short $+2
+%endmacro
+else
+macro DELAY_TIMER
+ jmp short $+2
+ jmp short $+2
+ jmp short $+2
+endm
+endif
+
+;----------------------------------------------------------------------------
+; void _OS_delay8253(N_uint32 microSeconds);
+;----------------------------------------------------------------------------
+; Delays for the specified number of microseconds, by directly programming
+; the 8253 timer chips.
+;----------------------------------------------------------------------------
+cprocstart _OS_delay8253
+
+ ARG microSec:UINT
+
+ enter_c
+
+; Start timer 2 counting
+
+ mov _ax,[microSec] ; EAX := count in microseconds
+ mov ecx,1196
+ mul ecx
+ mov ecx,1000
+ div ecx
+ mov ecx,eax ; ECX := count in timer ticks
+ in al,61h
+ or al,1
+ out 61h,al
+
+; Set the timer 2 count to 0 again to start the timing interval.
+
+ mov al,10110100b ; set up to load initial (timer 2)
+ out 43h,al ; timer count
+ DELAY_TIMER
+ sub al,al
+ out 42h,al ; load count lsb
+ DELAY_TIMER
+ out 42h,al ; load count msb
+ xor di,di ; Allow max 64K loop iterations
+
+@@LoopStart:
+ dec di ; This is a guard against the possibility that
+ jz @@LoopEnd ; someone eg. stopped the timer behind our back.
+ ; After 64K iterations we bail out no matter what
+ ; (and hope it wasn't too soon)
+ mov al,00000000b ; latch timer 0
+ out 43h,al
+ DELAY_TIMER
+ in al,42h ; least significant byte
+ DELAY_TIMER
+ mov ah,al
+ in al,42h ; most significant byte
+ xchg ah,al
+ neg ax ; Convert from countdown remaining
+ ; to elapsed count
+ cmp ax,cx ; Has delay expired?
+ jb @@LoopStart ; No, so loop till done
+
+; Stop timer 2 from counting
+@@LoopEnd:
+ in al,61H
+ and al,0FEh
+ out 61H,al
+
+; Some programs have a problem if we change the control port; better change it
+; to something they expect (mode 3 - square wave generator)...
+ mov al,0B6h
+ out 43h,al
+
+ leave_c
+ ret
+
+cprocend
+
+endcodeseg _gatimer
+
+ END
+
OpenPOWER on IntegriCloud