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

Last change on this file since 129 was 129, checked in by Ben Rietbroek, 8 years ago

Disabled 'CONV_CHS2LBA' function [v1.1.1-testing]

This one uses storage variables that are about to be removed.
It is not used anyway, so it will be disabled for now.

CAUTION:
This is a testbuild !
AirBoot uses the BIOS to access disks and a small coding error can trash
partition tables or other vital disk structures. You are advised to make
backups of TRACK0 and EBRs before using this testbuild. More info at:
https://rousseaux.github.io/netlabs.air-boot/pdf/AirBoot-v1.1.0-manual.pdf

File size: 14.6 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; Convert a byte in AL to it's packed BCD value in AX.
63; In: AL - value to convert
64; Out: AX - |digitcount|digit2|digit1|digit0|
65; Destroyed: none
66CONV_BinToPBCD Proc Near uses cx
67
68 ; Use AAM to convert to unpacked BCD
69 mov ch, 1 ; There always is at least one digit
70 aam ; Convert byte to unpacked BCD
71 test ah, ah ; If AH is zero, the value was below 10d
72
73 ; Just one digit, we're done
74 jz CONV_BinToPBCD_done
75
76 ; There are more digits
77 inc ch ; Increment digit count
78 cmp ah, 9 ; If AH is above 9, there is a third digit
79
80 ; There are three digits, AH needs to be processed too
81 ja CONV_BinToPBCD_three_digits
82
83 ; There are two digits, AH contains second digit
84 shl ah, 4 ; Correct the unpacked BCD nibble location
85 or al, ah ; Now we have a 2 digit packed BCD
86 xor ah, ah ; No third digit
87
88 ; Two digits, we're done
89 jmp CONV_BinToPBCD_done
90
91 CONV_BinToPBCD_three_digits:
92 ; There are three digits, process AH
93 inc ch ; Increment digit count
94 mov cl, al ; Store the first digit
95 mov al, ah ; Value in AH needs to be processed also
96 aam ; Convert byte to unpacked BCD
97 shl al, 4 ; Correct the unpacked BCD nibble location
98 or al, cl ; Merge the first BCD digit
99
100 ; Three digits, we're done
101 jmp CONV_BinToPBCD_done
102
103 CONV_BinToPBCD_done:
104 ; Compose the packed BCD value with the digit count in high nibble
105 shl ch, 4 ; Move count to correct nibble
106 or ah, ch ; Count is now in high nibble of AX
107 test ax, 0fffh ; Set ZF if all digits are 0
108
109 ret
110CONV_BinToPBCD Endp
111
112
113
114; See if a character is printable.
115; Replace with a '.' if not.
116; In: AL - char to print
117; AH - char to print if AL is non-printable
118; Out: AL - char printed (could be dot)
119; Destroyed: none
120CONV_ConvertToPrintable Proc Near
121 cmp al,20h
122 jb CONV_ConvertToPrintable_NP ; Below space, so not printable
123 cmp al,7eh ; Above tilde, so not printable
124 ja CONV_ConvertToPrintable_NP
125 jmp CONV_ConvertToPrintable_End ; Go output it
126 CONV_ConvertToPrintable_NP:
127 mov al,ah ; Use the replacement character
128 CONV_ConvertToPrintable_End:
129 ret
130CONV_ConvertToPrintable EndP
131
132
133
134; Convert CHS values to LBA address
135; Formula: LBA = ((c * H) + h) * S + s -1
136; c,h,s: requested
137; H,S: heads per cylinder and sectors per track
138; In: DX:AX - Cylinder
139; BX - Head
140; CX - Sector
141; Out: BX:CX:DX:AX - LBA address (64-bits)
142; ZF=1 if upper 32-bits are zero (LBA32)
143; Destroyed: none
144IF 0
145CONV_CHS2LBA Proc Near
146 local req_cyl:dword
147 local req_head:word
148 local req_sec:word
149 local lba:qword
150
151 ; Save parameters
152 mov word ptr [req_cyl],ax ; save low cyl
153 mov word ptr [req_cyl+2],dx ; save high cyl
154 mov [req_head],bx ; save head
155 test cx,cx
156 jnz CONV_CHS2LBA_sec_ok
157 mov cx,1 ; cannot have sector 0, so change to 1
158 CONV_CHS2LBA_sec_ok:
159 dec cx ; prepare for calculation later
160 mov [req_sec],cx ; save sec
161
162 ; Clear return value
163 xor ax,ax
164 mov word ptr [lba+6],ax
165 mov word ptr [lba+4],ax
166 mov word ptr [lba+2],ax
167 mov word ptr [lba+0],ax
168
169 ; Cyls * Heads
170 mov dx,word ptr [req_cyl+2] ; high word of requested cylinder
171 mov ax,word ptr [req_cyl+0] ; low word of requested cylinder
172 xor bx,bx ; zero for 32-bit math
173 mov cx,word ptr [BIOS_Heads] ; number of heads
174 call MATH_Mul32
175
176 ; WE DISCARD HIGH 32-BITS HERE BECAUSE CALCULATION
177 ; WOULD REQUIRE 64-bits MATH.
178 ; THIS WILL BE FIXED LATER.
179 ; THIS MEANS LBA >2TiB IS NOT SUPPORTED YET.
180
181 ; Add requested head
182 add ax,[req_head]
183 adc dx,0
184 ;adc cx,0
185 ;adc bx,0
186
187 ; * Secs
188 xor bx,bx
189 mov cx,word ptr [TrueSecs] ; Implicitly address disk 80h
190 call MATH_Mul32
191
192 ; Add requested sec
193 add ax,[req_sec]
194 adc dx,0
195 ;adc cx,0
196 ;adc bx,0
197
198 xor bx,bx
199 xor cx,cx
200
201 ; Set ZF if high upper 32-bits are zero
202 or bx,cx
203
204 ret
205CONV_CHS2LBA EndP
206ELSE
207CONV_CHS2LBA Proc Near
208 ret
209CONV_CHS2LBA EndP
210ENDIF
211
212CONV_LBA2CYLS Proc Near
213 ret
214CONV_LBA2CYLS Endp
215
216
217; Convert a character to upper-case
218CONV_ToUpper Proc Near
219 cmp al,'a'
220 jb CONV_ToUpperSkip1
221 cmp al,'z'
222 ja CONV_ToUpperSkip1
223 sub al,20h
224 CONV_ToUpperSkip1:
225 ret
226CONV_ToUpper EndP
227
228
229;
230; The bitfield functions below are used to pack values into arrays.
231; A buffer needs to be provided, a bitfield width and an index into the array.
232; These functions are used to pack the hidden partition-table which is
233; too small in the 45-partition version.
234;
235
236
237; IN: DL = Index to store bitfield
238; DH = Bitfield width (1-8)
239; BX = Pointer to bitfield array
240; OUT: AL = Value of requested bitfield
241; AH = Mask value
242CONV_GetBitfieldValue Proc Near Uses bx cx dx
243 ; Normalize bit-width in DH.
244 dec dh ; Decrement bitfield width to mask invalid values.
245 and dh,07h ; Only 3 bits are significant to determine width.
246 mov cl,dh ; Save for later use to calculate mask.
247 inc dh ; Put back to normalized value.
248
249 ; Calculate corresponding AND-mask in CH.
250 mov ch,2 ; Were going to shift 2...
251 shl ch,cl ; to obtain the mask corresponding...
252 dec ch ; to the bitfield width.
253
254 ; Calculate byte-index.
255 mov al,dl ; Index in AL.
256 inc al ; Increment for calculations.
257 mul dh ; Multiply by bitfield width to get bits.
258 mov cl,8 ; Nr. of bits in a byte.
259 div cl ; Divide to get byte index.
260
261 ; Advance pointer to byte-index.
262 add bl,al ; Advance pointer...
263 adc bh,0 ; to byte index.
264
265 ; Determine if we need 1 or 2 byte access to extract the bitfield.
266 mov cl,ah ; Get remainder in CL.
267 sub cl,dh ; Substract bitfield width to get shift-count.
268 mov ah,0 ; Prepare upper=0 when field spans no byte bound.
269 ; Don't change to xor ah,ah or any CY will be lost.
270
271 ; Jump if the bitfield does not span byte boundaries.
272 ; (Remainder - bitfield width >= 0)
273 jae CONV_GetBitfieldValue_nospan
274
275 ; Bit-field spans byte boundaries, so adjust shift-count
276 ; and use AH to get first part of bitfield.
277 add cl,8 ; Adjust shift-count.
278 mov ah,[bx] ; Get byte into AH instead.
279 dec bx ; Adjust pointer to load rest of bitfield.
280
281 CONV_GetBitfieldValue_nospan:
282 mov al,[bx] ; Load (rest of) bitfield into AL.
283 shr ax,cl ; Shift bitfield to the right.
284 mov ah,ch ; Get mask in AH.
285 and al,ah ; Mask value.
286 ret
287CONV_GetBitfieldValue EndP
288
289
290
291
292; IN: AL = Value to store
293; DL = Index to store bitfield
294; DH = Bitfield width (1-8)
295; BX = Pointer to bitfield array
296; OUT: AL = Value of stored bitfield
297; AH = Mask value
298CONV_SetBitfieldValue Proc Near Uses bx cx dx
299 ; Push value for later use.
300 push ax
301
302 ; Normalize bit-width in DH.
303 dec dh ; Decrement bitfield width to mask invalid values.
304 and dh,07h ; Only 3 bits are significant to determine width.
305 mov cl,dh ; Save for later use to calculate mask.
306 inc dh ; Put back to normalized value.
307
308 ; Calculate corresponding AND-mask in CH.
309 mov ch,2 ; Were going to shift 2...
310 shl ch,cl ; to obtain the mask corresponding...
311 dec ch ; to the bitfield width.
312
313 ; Calculate byte-index.
314 mov al,dl ; Index in AL.
315 inc al ; Increment for calculations.
316 mul dh ; Multiply by bitfield width to get bits.
317 mov cl,8 ; Nr. of bits in a byte.
318 div cl ; Divide to get byte index.
319
320 ; Advance pointer to byte-index.
321 add bl,al ; Advance pointer...
322 adc bh,0 ; to byte index.
323
324 ; Determine if we need 1 or 2 byte access to extract the bitfield.
325 mov cl,ah ; Get remainder in CL.
326 sub cl,dh ; Substract bitfield width to get shift-count.
327
328 ; Restore value to poke.
329 pop ax
330
331
332 ; Jump if the bitfield does not span byte boundaries.
333 ; (Remainder - bitfield width >= 0)
334 jae CONV_SetBitfieldValue_nospan
335
336 ; Bit-field spans byte boundaries, so adjust shift-count
337 ; and use 16-bit access.
338 add cl,8 ; Adjust shift-count.
339
340 ; Merge the bitfield to the array.
341 push cx ; Save mask (CH) and shift-count (CL).
342 push ax ; Save value to store.
343 xor ah,ah ; Clear upper byte so we can shift in it.
344 and al,ch ; Mask value.
345 shl ax,cl ; Move the bitfield to the proper location.
346 mov dh,[bx] ; Get 1st part of bitfield from array.
347 dec bx ; Adjust pointer.
348 mov dl,[bx] ; Get 2nd part of bitfield from array.
349 push bx ; We need BX so save it.
350 xor bh,bh ; Clear upper byte so we can shift in it.
351 mov bl,ch ; Put mask in BL.
352 shl bx,cl ; Shift mask to proper location.
353 not bx ; Complement it to mask-out the required bitfield.
354 and dx,bx ; Mask-out the required bitfield.
355 pop bx ; Restore pointer.
356 or ax,dx ; Merge the bitfields.
357 mov [bx],al ; Store lower byte.
358 inc bx ; Adjust pointer.
359 mov [bx],ah ; Store upper byte.
360 pop ax ; Restore value.
361 pop cx ; Restore mask and shift-count.
362
363 ; Done.
364 jmp CONV_SetBitfieldValue_end
365
366 CONV_SetBitfieldValue_nospan:
367 ; Merge the bitfield to the array.
368 push cx ; Save mask (CH) and shift-count (CL).
369 push ax ; Save value to store.
370 and al,ch ; Mask value.
371 shl al,cl ; Move the bitfield to the proper location.
372 mov dl,[bx] ; Get byte containing bitfield.
373 shl ch,cl ; Shift mask to proper location.
374 not ch ; Complement it to mask-out the required bitfield.
375 and dl,ch ; Mask-out the required bitfield.
376 or al,dl ; Merge the bitfields.
377 mov [bx],al ; Store byte containing bitfield.
378 pop ax ; Restore value.
379 pop cx ; Restore mask and shift-count.
380
381 CONV_SetBitfieldValue_end:
382 mov ah,ch ; Get mask in AH.
383 and al,ah ; Mask value.
384 ret
385CONV_SetBitfieldValue EndP
386
Note: See TracBrowser for help on using the repository browser.