source: trunk/bootcode/regular/conv.asm@ 65

Last change on this file since 65 was 57, checked in by Ben Rietbroek, 10 years ago

All source-files lowercased [v1.1.1-testing]

Some standard files like 'COPYING', 'LICENSE', etc. have not been
converted to lower case because they are usually distributed uppercased.

File size: 12.5 KB
Line 
1; AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz
2;
3; This file is part of AiR-BOOT
4;
5; AiR-BOOT is free software: you can redistribute it and/or modify it under
6; the terms of the GNU General Public License as published by the Free
7; Software Foundation, either version 3 of the License, or (at your option)
8; any later version.
9;
10; AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY
11; WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS
12; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13; details.
14;
15; You should have received a copy of the GNU General Public License along with
16; AiR-BOOT. If not, see <http://www.gnu.org/licenses/>.
17;
18;---------------------------------------------------------------------------
19; AiR-BOOT / CONVERSION
20;---------------------------------------------------------------------------
21
22
23; ----------------------
24; Rousseau: # CONV.ASM #
25; ----------------------
26; This module contains various conversion routines.
27; Some have to do with bin to ascii, others with translation.
28
29
30IFDEF MODULE_NAMES
31DB 'CONV',0
32ENDIF
33
34; Convert a byte in AL to it's Hex Ascii value.
35; In: AL - value to convert
36; Out: AX - two (Hex) Ascii digits
37; Destroyed: none
38CONV_BinToAsc Proc Near
39 mov ah,al ; Save value to process high nibble later
40 and al,0fh ; Mask low nibble
41 add al,'0' ; Convert to ASCII
42 cmp al,'9' ; Is it in the range of '0' - '9' ?
43 jbe CONV_BinToAsc_DecDigit_1 ; Yep, done
44 add al,7 ; Nope, adjust to Hex Ascii
45 CONV_BinToAsc_DecDigit_1:
46 xchg al,ah ; Exchange with saved value to process high nibble
47 shr al,4 ; Move high nibble to low nibble (80186+)
48 ;shr al
49 ;shr al
50 ;shr al
51 add al,'0' ; Convert to ASCII
52 cmp al,'9' ; Is it in the range of '0' - '9' ?
53 jbe CONV_BinToAsc_DecDigit_2
54 add al,7 ; Nope, adjust to Hex Ascii
55 CONV_BinToAsc_DecDigit_2:
56 xchg al,ah ; Correct order, AX now contains the two (hex) digits
57 ret
58CONV_BinToAsc Endp
59
60
61
62; See if a character is printable.
63; Replace with a '.' if not.
64; In: AL - char to print
65; AH - char to print if AL is non-printable
66; Out: AL - char printed (could be dot)
67; Destroyed: none
68CONV_ConvertToPrintable Proc Near
69 cmp al,20h
70 jb CONV_ConvertToPrintable_NP ; Below space, so not printable
71 cmp al,7eh ; Above tilde, so not printable
72 ja CONV_ConvertToPrintable_NP
73 jmp CONV_ConvertToPrintable_End ; Go output it
74 CONV_ConvertToPrintable_NP:
75 mov al,ah ; Use the replacement character
76 CONV_ConvertToPrintable_End:
77 ret
78CONV_ConvertToPrintable EndP
79
80
81
82; Convert CHS values to LBA address
83; Formula: LBA = ((c * H) + h) * S + s -1
84; c,h,s: requested
85; H,S: heads per cylinder and sectors per track
86; In: DX:AX - Cylinder
87; BX - Head
88; CX - Sector
89; Out: BX:CX:DX:AX - LBA address (64-bits)
90; ZF=1 if upper 32-bits are zero (LBA32)
91; Destroyed: none
92CONV_CHS2LBA Proc Near
93 local req_cyl:dword
94 local req_head:word
95 local req_sec:word
96 local lba:qword
97
98 ; Save parameters
99 mov word ptr [req_cyl],ax ; save low cyl
100 mov word ptr [req_cyl+2],dx ; save high cyl
101 mov [req_head],bx ; save head
102 test cx,cx
103 jnz CONV_CHS2LBA_sec_ok
104 mov cx,1 ; cannot have sector 0, so change to 1
105 CONV_CHS2LBA_sec_ok:
106 dec cx ; prepare for calculation later
107 mov [req_sec],cx ; save sec
108
109 ; Clear return value
110 xor ax,ax
111 mov word ptr [lba+6],ax
112 mov word ptr [lba+4],ax
113 mov word ptr [lba+2],ax
114 mov word ptr [lba+0],ax
115
116 ; Cyls * Heads
117 mov dx,word ptr [req_cyl+2] ; high word of requested cylinder
118 mov ax,word ptr [req_cyl+0] ; low word of requested cylinder
119 xor bx,bx ; zero for 32-bit math
120 mov cx,word ptr [BIOS_Heads] ; number of heads
121 call MATH_Mul32
122
123 ; WE DISCARD HIGH 32-BITS HERE BECAUSE CALCULATION
124 ; WOULD REQUIRE 64-bits MATH.
125 ; THIS WILL BE FIXED LATER.
126 ; THIS MEANS LBA >2TiB IS NOT SUPPORTED YET.
127
128 ; Add requested head
129 add ax,[req_head]
130 adc dx,0
131 ;adc cx,0
132 ;adc bx,0
133
134 ; * Secs
135 xor bx,bx
136 mov cx,word ptr [TrueSecs] ; Implicitly address disk 80h
137 call MATH_Mul32
138
139 ; Add requested sec
140 add ax,[req_sec]
141 adc dx,0
142 ;adc cx,0
143 ;adc bx,0
144
145 xor bx,bx
146 xor cx,cx
147
148 ; Set ZF if high upper 32-bits are zero
149 or bx,cx
150
151 ret
152CONV_CHS2LBA EndP
153
154
155CONV_LBA2CYLS Proc Near
156 ret
157CONV_LBA2CYLS Endp
158
159
160; Convert a character to upper-case
161CONV_ToUpper Proc Near
162 cmp al,'a'
163 jb CONV_ToUpperSkip1
164 cmp al,'z'
165 ja CONV_ToUpperSkip1
166 sub al,20h
167 CONV_ToUpperSkip1:
168 ret
169CONV_ToUpper EndP
170
171
172;
173; The bitfield functions below are used to pack values into arrays.
174; A buffer needs to be provided, a bitfield width and an index into the array.
175; These functions are used to pack the hidden partition-table which is
176; too small in the 45-partition version.
177;
178
179
180; IN: DL = Index to store bitfield
181; DH = Bitfield width (1-8)
182; BX = Pointer to bitfield array
183; OUT: AL = Value of requested bitfield
184; AH = Mask value
185CONV_GetBitfieldValue Proc Near Uses bx cx dx
186 ; Normalize bit-width in DH.
187 dec dh ; Decrement bitfield width to mask invalid values.
188 and dh,07h ; Only 3 bits are significant to determine width.
189 mov cl,dh ; Save for later use to calculate mask.
190 inc dh ; Put back to normalized value.
191
192 ; Calculate corresponding AND-mask in CH.
193 mov ch,2 ; Were going to shift 2...
194 shl ch,cl ; to obtain the mask corresponding...
195 dec ch ; to the bitfield width.
196
197 ; Calculate byte-index.
198 mov al,dl ; Index in AL.
199 inc al ; Increment for calculations.
200 mul dh ; Multiply by bitfield width to get bits.
201 mov cl,8 ; Nr. of bits in a byte.
202 div cl ; Divide to get byte index.
203
204 ; Advance pointer to byte-index.
205 add bl,al ; Advance pointer...
206 adc bh,0 ; to byte index.
207
208 ; Determine if we need 1 or 2 byte access to extract the bitfield.
209 mov cl,ah ; Get remainder in CL.
210 sub cl,dh ; Substract bitfield width to get shift-count.
211 mov ah,0 ; Prepare upper=0 when field spans no byte bound.
212 ; Don't change to xor ah,ah or any CY will be lost.
213
214 ; Jump if the bitfield does not span byte boundaries.
215 ; (Remainder - bitfield width >= 0)
216 jae CONV_GetBitfieldValue_nospan
217
218 ; Bit-field spans byte boundaries, so adjust shift-count
219 ; and use AH to get first part of bitfield.
220 add cl,8 ; Adjust shift-count.
221 mov ah,[bx] ; Get byte into AH instead.
222 dec bx ; Adjust pointer to load rest of bitfield.
223
224 CONV_GetBitfieldValue_nospan:
225 mov al,[bx] ; Load (rest of) bitfield into AL.
226 shr ax,cl ; Shift bitfield to the right.
227 mov ah,ch ; Get mask in AH.
228 and al,ah ; Mask value.
229 ret
230CONV_GetBitfieldValue EndP
231
232
233
234
235; IN: AL = Value to store
236; DL = Index to store bitfield
237; DH = Bitfield width (1-8)
238; BX = Pointer to bitfield array
239; OUT: AL = Value of stored bitfield
240; AH = Mask value
241CONV_SetBitfieldValue Proc Near Uses bx cx dx
242 ; Push value for later use.
243 push ax
244
245 ; Normalize bit-width in DH.
246 dec dh ; Decrement bitfield width to mask invalid values.
247 and dh,07h ; Only 3 bits are significant to determine width.
248 mov cl,dh ; Save for later use to calculate mask.
249 inc dh ; Put back to normalized value.
250
251 ; Calculate corresponding AND-mask in CH.
252 mov ch,2 ; Were going to shift 2...
253 shl ch,cl ; to obtain the mask corresponding...
254 dec ch ; to the bitfield width.
255
256 ; Calculate byte-index.
257 mov al,dl ; Index in AL.
258 inc al ; Increment for calculations.
259 mul dh ; Multiply by bitfield width to get bits.
260 mov cl,8 ; Nr. of bits in a byte.
261 div cl ; Divide to get byte index.
262
263 ; Advance pointer to byte-index.
264 add bl,al ; Advance pointer...
265 adc bh,0 ; to byte index.
266
267 ; Determine if we need 1 or 2 byte access to extract the bitfield.
268 mov cl,ah ; Get remainder in CL.
269 sub cl,dh ; Substract bitfield width to get shift-count.
270
271 ; Restore value to poke.
272 pop ax
273
274
275 ; Jump if the bitfield does not span byte boundaries.
276 ; (Remainder - bitfield width >= 0)
277 jae CONV_SetBitfieldValue_nospan
278
279 ; Bit-field spans byte boundaries, so adjust shift-count
280 ; and use 16-bit access.
281 add cl,8 ; Adjust shift-count.
282
283 ; Merge the bitfield to the array.
284 push cx ; Save mask (CH) and shift-count (CL).
285 push ax ; Save value to store.
286 xor ah,ah ; Clear upper byte so we can shift in it.
287 and al,ch ; Mask value.
288 shl ax,cl ; Move the bitfield to the proper location.
289 mov dh,[bx] ; Get 1st part of bitfield from array.
290 dec bx ; Adjust pointer.
291 mov dl,[bx] ; Get 2nd part of bitfield from array.
292 push bx ; We need BX so save it.
293 xor bh,bh ; Clear upper byte so we can shift in it.
294 mov bl,ch ; Put mask in BL.
295 shl bx,cl ; Shift mask to proper location.
296 not bx ; Complement it to mask-out the required bitfield.
297 and dx,bx ; Mask-out the required bitfield.
298 pop bx ; Restore pointer.
299 or ax,dx ; Merge the bitfields.
300 mov [bx],al ; Store lower byte.
301 inc bx ; Adjust pointer.
302 mov [bx],ah ; Store upper byte.
303 pop ax ; Restore value.
304 pop cx ; Restore mask and shift-count.
305
306 ; Done.
307 jmp CONV_SetBitfieldValue_end
308
309 CONV_SetBitfieldValue_nospan:
310 ; Merge the bitfield to the array.
311 push cx ; Save mask (CH) and shift-count (CL).
312 push ax ; Save value to store.
313 and al,ch ; Mask value.
314 shl al,cl ; Move the bitfield to the proper location.
315 mov dl,[bx] ; Get byte containing bitfield.
316 shl ch,cl ; Shift mask to proper location.
317 not ch ; Complement it to mask-out the required bitfield.
318 and dl,ch ; Mask-out the required bitfield.
319 or al,dl ; Merge the bitfields.
320 mov [bx],al ; Store byte containing bitfield.
321 pop ax ; Restore value.
322 pop cx ; Restore mask and shift-count.
323
324 CONV_SetBitfieldValue_end:
325 mov ah,ch ; Get mask in AH.
326 and al,ah ; Mask value.
327 ret
328CONV_SetBitfieldValue EndP
329
Note: See TracBrowser for help on using the repository browser.