]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/common/_gatimer.asm
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / common / _gatimer.asm
1 ;****************************************************************************
2 ;*
3 ;*                  SciTech Nucleus Graphics Architecture
4 ;*
5 ;*               Copyright (C) 1991-1998 SciTech Software, Inc.
6 ;*                            All rights reserved.
7 ;*
8 ;*  ======================================================================
9 ;*  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
10 ;*  |                                                                    |
11 ;*  |This copyrighted computer code contains proprietary technology      |
12 ;*  |owned by SciTech Software, Inc., located at 505 Wall Street,        |
13 ;*  |Chico, CA 95928 USA (http://www.scitechsoft.com).                   |
14 ;*  |                                                                    |
15 ;*  |The contents of this file are subject to the SciTech Nucleus        |
16 ;*  |License; you may *not* use this file or related software except in  |
17 ;*  |compliance with the License. You may obtain a copy of the License   |
18 ;*  |at http://www.scitechsoft.com/nucleus-license.txt                   |
19 ;*  |                                                                    |
20 ;*  |Software distributed under the License is distributed on an         |
21 ;*  |"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or      |
22 ;*  |implied. See the License for the specific language governing        |
23 ;*  |rights and limitations under the License.                           |
24 ;*  |                                                                    |
25 ;*  |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
26 ;*  ======================================================================
27 ;*
28 ;* Language:    80386 Assembler, NASM or TASM
29 ;* Environment: IBM PC 32 bit Protected Mode.
30 ;*
31 ;* Description: Assembly support functions for the Nucleus library for
32 ;*              the high resolution timing support functions provided by
33 ;*              the Intel Pentium and compatible processors.
34 ;*
35 ;****************************************************************************
36
37         IDEAL
38
39 include "scitech.mac"           ; Memory model macros
40
41 header  _gatimer
42
43 begcodeseg  _gatimer
44
45 ifdef   USE_NASM
46 %macro mCPU_ID 0
47 db  00Fh,0A2h
48 %endmacro
49 else
50 MACRO   mCPU_ID
51 db  00Fh,0A2h
52 ENDM
53 endif
54
55 ifdef   USE_NASM
56 %macro mRDTSC 0
57 db  00Fh,031h
58 %endmacro
59 else
60 MACRO   mRDTSC
61 db  00Fh,031h
62 ENDM
63 endif
64
65 ;----------------------------------------------------------------------------
66 ; bool _GA_haveCPUID(void)
67 ;----------------------------------------------------------------------------
68 ; Determines if we have support for the CPUID instruction.
69 ;----------------------------------------------------------------------------
70 cprocstart  _GA_haveCPUID
71
72         enter_c
73         pushfd                      ; Get original EFLAGS
74         pop     eax
75         mov     ecx, eax
76         xor     eax, 200000h        ; Flip ID bit in EFLAGS
77         push    eax                 ; Save new EFLAGS value on stack
78         popfd                       ; Replace current EFLAGS value
79         pushfd                      ; Get new EFLAGS
80         pop     eax                 ; Store new EFLAGS in EAX
81         xor     eax, ecx            ; Can not toggle ID bit,
82         jnz     @@1                 ; Processor=80486
83         mov     eax,0               ; We dont have CPUID support
84         jmp     @@Done
85 @@1:    mov     eax,1               ; We have CPUID support
86 @@Done: leave_c
87         ret
88
89 cprocend
90
91 ;----------------------------------------------------------------------------
92 ; uint _GA_getCPUIDFeatures(void)
93 ;----------------------------------------------------------------------------
94 ; Determines the CPU type using the CPUID instruction.
95 ;----------------------------------------------------------------------------
96 cprocstart  _GA_getCPUIDFeatures
97
98         enter_c
99
100         xor     eax, eax            ; Set up for CPUID instruction
101         mCPU_ID                     ; Get and save vendor ID
102         cmp     eax, 1              ; Make sure 1 is valid input for CPUID
103         jl      @@Fail              ; We dont have the CPUID instruction
104         xor     eax, eax
105         inc     eax
106         mCPU_ID                     ; Get family/model/stepping/features
107         mov     eax, edx
108 @@Done: leave_c
109         ret
110
111 @@Fail: xor     eax,eax
112         jmp     @@Done
113
114 cprocend
115
116 ;----------------------------------------------------------------------------
117 ; void  _GA_readTimeStamp(GA_largeInteger *time)
118 ;----------------------------------------------------------------------------
119 ; Reads the time stamp counter and returns the 64-bit result.
120 ;----------------------------------------------------------------------------
121 cprocstart  _GA_readTimeStamp
122
123         mRDTSC
124         mov     ecx,[esp+4]     ; Access directly without stack frame
125         mov     [ecx],eax
126         mov     [ecx+4],edx
127         ret
128
129 cprocend
130
131 ;----------------------------------------------------------------------------
132 ; N_uint32 GA_TimerDifference(GA_largeInteger *a,GA_largeInteger *b)
133 ;----------------------------------------------------------------------------
134 ; Computes the difference between two 64-bit numbers (a-b)
135 ;----------------------------------------------------------------------------
136 cprocstart  GA_TimerDifference
137
138         ARG     a:DPTR, b:DPTR, t:DPTR
139
140         enter_c
141
142         mov     ecx,[a]
143         mov     eax,[ecx]       ; EAX := b.low
144         mov     ecx,[b]
145         sub     eax,[ecx]
146         mov     edx,eax         ; EDX := low difference
147         mov     ecx,[a]
148         mov     eax,[ecx+4]     ; ECX := b.high
149         mov     ecx,[b]
150         sbb     eax,[ecx+4]     ; EAX := high difference
151         mov     eax,edx         ; Return low part
152
153         leave_c
154         ret
155
156 cprocend
157
158 ; Macro to delay briefly to ensure that enough time has elapsed between
159 ; successive I/O accesses so that the device being accessed can respond
160 ; to both accesses even on a very fast PC.
161
162 ifdef   USE_NASM
163 %macro  DELAY_TIMER 0
164         jmp     short $+2
165         jmp     short $+2
166         jmp     short $+2
167 %endmacro
168 else
169 macro   DELAY_TIMER
170         jmp     short $+2
171         jmp     short $+2
172         jmp     short $+2
173 endm
174 endif
175
176 ;----------------------------------------------------------------------------
177 ; void _OS_delay8253(N_uint32 microSeconds);
178 ;----------------------------------------------------------------------------
179 ; Delays for the specified number of microseconds, by directly programming
180 ; the 8253 timer chips.
181 ;----------------------------------------------------------------------------
182 cprocstart  _OS_delay8253
183
184         ARG     microSec:UINT
185
186         enter_c
187
188 ; Start timer 2 counting
189
190         mov     _ax,[microSec]      ; EAX := count in microseconds
191         mov     ecx,1196
192         mul     ecx
193         mov     ecx,1000
194         div     ecx
195         mov     ecx,eax             ; ECX := count in timer ticks
196         in      al,61h
197         or      al,1
198         out     61h,al
199
200 ; Set the timer 2 count to 0 again to start the timing interval.
201
202         mov     al,10110100b        ; set up to load initial (timer 2)
203         out     43h,al              ; timer count
204         DELAY_TIMER
205         sub     al,al
206         out     42h,al              ; load count lsb
207         DELAY_TIMER
208         out     42h,al              ; load count msb
209         xor     di,di               ; Allow max 64K loop iterations
210
211 @@LoopStart:
212         dec     di                  ; This is a guard against the possibility that
213         jz      @@LoopEnd           ; someone eg. stopped the timer behind our back.
214                                     ; After 64K iterations we bail out no matter what
215                                     ; (and hope it wasn't too soon)
216         mov     al,00000000b        ; latch timer 0
217         out     43h,al
218         DELAY_TIMER
219         in      al,42h              ; least significant byte
220         DELAY_TIMER
221         mov     ah,al
222         in      al,42h              ; most significant byte
223         xchg    ah,al
224         neg     ax                  ; Convert from countdown remaining
225                                     ;  to elapsed count
226         cmp     ax,cx               ; Has delay expired?
227         jb      @@LoopStart         ; No, so loop till done
228
229 ; Stop timer 2 from counting
230 @@LoopEnd:
231         in      al,61H
232         and     al,0FEh
233         out     61H,al
234
235 ; Some programs have a problem if we change the control port; better change it
236 ; to something they expect (mode 3 - square wave generator)...
237         mov     al,0B6h
238         out     43h,al
239
240         leave_c
241         ret
242
243 cprocend
244
245 endcodeseg  _gatimer
246
247         END
248