source: xtideuniversalbios/trunk/Assembly_Library/Src/Time/TimerTicks.asm@ 524

Last change on this file since 524 was 491, checked in by krille_n_@…, 12 years ago

Changes:

  • Added a new define (USE_UNDOC_INTEL) that enables optimizations possible by using undocumented instructions available on all Intel processors and truly compatible clones. AFAIK the only exceptions are the NEC V-series and the Sony CXQ70108 processors so this option should be safe for use on the AT builds.
  • Building BIOSDRVS or the BIOS without MODULE_STRINGS_COMPRESSED would fail due to the recent code exclusions so I changed them a bit. Also fixed the mistaken change to Main.asm
  • Changed the Tandy specific info in Configuration_FullMode.txt so it matches the info in the Wiki.
  • Optimizations and fixes in general.
File size: 6.5 KB
Line 
1; Project name : Assembly Library
2; Description : Functions for system timer related operations.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; With a PIT input clock of 1193181.6666... Hz and a maximum
21; 16 bit divisor of 65536 (if PIT programmed with 0) we get:
22;
23; Clock / Divisor = ~18.2065 ticks per second
24; Clock * SecondsPerMinute / Divisor = ~1092 ticks per minute
25; Clock * SecondsPerHour / Divisor = ~65543 ticks per hour
26;
27; Since 65543 can't fit in a 16 bit register we use the
28; maximum possible instead and disregard the last ~8 ticks.
29
30TICKS_PER_HOUR EQU 65535
31TICKS_PER_MINUTE EQU 1092
32TICKS_PER_SECOND EQU 18
33
34
35; Section containing code
36SECTION .text
37
38;--------------------------------------------------------------------
39; TimerTicks_GetHoursToAXandRemainderTicksToDXfromTicksInDXAX
40; TimerTicks_GetMinutesToAXandRemainderTicksToDXfromTicksInDX
41; TimerTicks_GetSecondsToAXandRemainderTicksToDXfromTicksInDX
42; Parameters
43; DX(:AX): Timer ticks to convert
44; Returns:
45; AX: Hours, minutes or seconds
46; DX: Remainder ticks
47; Corrupts registers:
48; CX
49;--------------------------------------------------------------------
50%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
51%ifndef EXCLUDE_FROM_XTIDECFG
52ALIGN JUMP_ALIGN
53TimerTicks_GetHoursToAXandRemainderTicksToDXfromTicksInDXAX:
54 mov cx, TICKS_PER_HOUR
55 div cx ; Divide DX:AX by CX, Hours to AX, remainder ticks to DX
56 ret
57%endif ; EXCLUDE_FROM_XTIDECFG
58
59ALIGN JUMP_ALIGN
60TimerTicks_GetMinutesToAXandRemainderTicksToDXfromTicksInDX:
61 xor ax, ax
62 xchg ax, dx ; Ticks now in DX:AX
63 mov cx, TICKS_PER_MINUTE
64 div cx ; Divide DX:AX by CX, Minutes to AX, remainder ticks to DX
65 ret
66%endif ; EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
67
68%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS OR EXCLUDE_FROM_XTIDECFG
69ALIGN JUMP_ALIGN
70TimerTicks_GetSecondsToAXandRemainderTicksToDXfromTicksInDX:
71 ; This procedure can handle at most 4607 ticks in DX (almost 256 seconds)
72 ; More than 4607 ticks will generate a divide overflow exception!
73 xchg ax, dx ; Ticks now in AX
74 mov cl, TICKS_PER_SECOND
75 div cl ; Divide AX by CL, Seconds to AL, remainder ticks to AH
76 xor dx, dx
77 xchg dl, ah ; Seconds in AX, remainder in DX
78 ret
79%endif
80
81
82%ifdef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
83 %ifndef MODULE_BOOT_MENU
84 %define EXCLUDE
85 %endif
86%endif
87;--------------------------------------------------------------------
88; TimerTicks_GetSecondsToAXfromTicksInDX
89; Parameters
90; DX: Timer ticks to convert
91; Returns:
92; AX: Seconds
93; Corrupts registers:
94; DX
95;--------------------------------------------------------------------
96%ifndef EXCLUDE ; 1 of 3
97ALIGN JUMP_ALIGN
98TimerTicks_GetSecondsToAXfromTicksInDX:
99 mov ax, 3600 ; Approximately 65536 / (Clock / Divisor)
100 mul dx
101 xchg dx, ax
102 ret
103%endif
104
105
106;--------------------------------------------------------------------
107; First tick might take 0...54.9 ms and remaining ticks
108; will occur at 54.9 ms intervals. Use delay of two (or more) ticks to
109; ensure at least 54.9 ms timeout.
110;
111; TimerTicks_InitializeTimeoutFromAX
112; Parameters:
113; AX: Timeout ticks (54.9 ms) before timeout
114; DS:BX: Ptr to timeout variable WORD
115; Returns:
116; [DS:BX]: Initialized for TimerTicks_SetCarryIfTimeoutFromDSBX
117; Corrupts registers:
118; AX
119;--------------------------------------------------------------------
120%ifndef EXCLUDE ; 2 of 3
121ALIGN JUMP_ALIGN
122TimerTicks_InitializeTimeoutFromAX:
123 mov [bx], ax ; Store timeout ticks
124 call TimerTicks_ReadFromBdaToAX
125 add [bx], ax ; [bx] now contains end time for timeout
126 ret
127%endif
128
129
130;--------------------------------------------------------------------
131; TimerTicks_GetTimeoutTicksLeftToAXfromDSBX
132; Parameters:
133; DS:BX: Ptr to timeout variable WORD
134; Returns:
135; AX: Number of ticks left before timeout
136; CF: Set if timeout
137; Cleared if time left
138; Corrupts registers:
139; Nothing
140;--------------------------------------------------------------------
141%ifndef EXCLUDE ; 3 of 3
142ALIGN JUMP_ALIGN
143TimerTicks_GetTimeoutTicksLeftToAXfromDSBX:
144 push dx
145 mov dx, [bx]
146 call TimerTicks_ReadFromBdaToAX
147 xchg ax, dx
148 sub ax, dx ; AX = End time - current time
149 pop dx
150 ret
151%endif
152
153%undef EXCLUDE
154
155
156;--------------------------------------------------------------------
157; TimerTicks_GetElapsedToAXandResetDSBX
158; Parameters
159; DS:BX: Ptr to WORD containing previous reset time
160; Returns:
161; AX: 54.9 ms ticks elapsed since last reset
162; [DS:BX]: Reset to latest time
163; Corrupts registers:
164; Nothing
165;--------------------------------------------------------------------
166%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
167ALIGN JUMP_ALIGN
168TimerTicks_GetElapsedToAXandResetDSBX:
169 call TimerTicks_ReadFromBdaToAX
170 push ax
171 sub ax, [bx]
172 pop WORD [bx] ; Latest time to [DS:BX]
173 ret
174%endif
175
176
177;--------------------------------------------------------------------
178; TimerTicks_GetElapsedToAXfromDSBX
179; Parameters
180; DS:BX: Ptr to WORD containing previous update time
181; Returns:
182; AX: 54.9 ms ticks elapsed since initializing [DS:BX]
183; Corrupts registers:
184; Nothing
185;--------------------------------------------------------------------
186%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
187ALIGN JUMP_ALIGN
188TimerTicks_GetElapsedToAXfromDSBX:
189 call TimerTicks_ReadFromBdaToAX
190 sub ax, [bx]
191 ret
192%endif
193
194
195;--------------------------------------------------------------------
196; TimerTicks_ReadFromBdaToAX
197; Parameters
198; Nothing
199; Returns:
200; AX: System time in 54.9 ms ticks
201; Corrupts registers:
202; Nothing
203;--------------------------------------------------------------------
204%ifdef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
205 %ifndef MODULE_BOOT_MENU OR MODULE_HOTKEYS
206 %define EXCLUDE
207 %endif
208%endif
209
210%ifndef EXCLUDE
211ALIGN JUMP_ALIGN
212TimerTicks_ReadFromBdaToAX:
213 push ds
214
215 LOAD_BDA_SEGMENT_TO ds, ax
216 mov ax, [BDA.dwTimerTicks] ; Read low WORD only
217
218 pop ds
219 ret
220%endif
221%undef EXCLUDE
Note: See TracBrowser for help on using the repository browser.