source: xtideuniversalbios/trunk/Assembly_Library/Src/Display/DisplayFormat.asm@ 323

Last change on this file since 323 was 241, checked in by gregli@…, 13 years ago

Space optimizations in the Boot Menu and BootInfo routines, taking advantage of nested %s. Optimization in the init of RamVars to avoid writing the signature twice. Preparing for addition of serial floppy support, starting to break the assumption that our drives are always 80h or higher.

File size: 11.5 KB
Line 
1; Project name : Assembly Library
2; Description : Functions for displaying formatted strings.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; DisplayFormat_ParseCharacters
9; Parameters:
10; DS: BDA segment (zero)
11; SS:BP: Pointer to first format parameter (-=2 updates to next parameter)
12; CS:SI: Pointer to string to format
13; ES:DI: Ptr to cursor location in video RAM
14; Returns:
15; CS:SI: Ptr to end of format string (ptr to one past NULL)
16; DI: Updated offset to video RAM
17; Corrupts registers:
18; AX, BX, CX, DX, BP
19;--------------------------------------------------------------------
20ALIGN JUMP_ALIGN
21DisplayFormat_ParseCharacters:
22 call ReadCharacterAndTestForNull
23 jz SHORT ReturnFromFormat
24
25 ePUSH_T cx, DisplayFormat_ParseCharacters ; Return address
26 xor cx, cx ; Initial placeholder size
27 cmp al, '%' ; Format specifier?
28 jne SHORT DisplayPrint_CharacterFromAL
29 ; Fall to ParseFormatSpecifier
30
31;--------------------------------------------------------------------
32; ParseFormatSpecifier
33; Parameters:
34; CX: Placeholder size
35; DS: BDA segment (zero)
36; SS:BP: Pointer to first format parameter (-=2 for next parameter)
37; CS:SI: Pointer to string to format
38; ES:DI: Ptr to cursor location in video RAM
39; Returns:
40; SI: Updated to first unparsed character
41; DI: Updated offset to video RAM
42; BP: Updated to next format parameter
43; Corrupts registers:
44; AX, BX, CX, DX
45;--------------------------------------------------------------------
46ParseFormatSpecifier:
47 call ReadCharacterAndTestForNull
48 call Char_IsDecimalDigitInAL
49 jc SHORT ParsePlaceholderSizeDigitFromALtoCX
50 call GetFormatSpecifierParserToAX
51 call ax ; Parser function
52 dec bp
53 dec bp ; SS:BP now points to next parameter
54 inc cx
55 loop PrependOrAppendSpaces
56ReturnFromFormat:
57 ret
58
59;--------------------------------------------------------------------
60; ParsePlaceholderSizeDigitFromALtoCX
61; Parameters:
62; AL: Digit character from format string
63; CX: Current placeholder size
64; DS: BDA segment (zero)
65; Returns:
66; CX: Current placeholder size
67; Jumps back to ParseFormatSpecifier
68; Corrupts registers:
69; AX
70;--------------------------------------------------------------------
71ALIGN JUMP_ALIGN
72ParsePlaceholderSizeDigitFromALtoCX:
73 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
74 sub al, '0' ; Digit '0'...'9' to integer 0...9
75 mov ah, cl ; Previous number parameter to AH
76 aad ; AL += (AH * 10)
77 mov cl, al ; Updated number parameter now in CX
78 jmp SHORT ParseFormatSpecifier
79
80
81;--------------------------------------------------------------------
82; ReadCharacterAndTestForNull
83; Parameters:
84; CS:SI: Pointer next character from string
85; Returns:
86; AL: Character from string
87; SI: Incremented to next character
88; ZF: Set if NULL, cleared if valid character
89; Corrupts registers:
90; Nothing
91;--------------------------------------------------------------------
92ALIGN JUMP_ALIGN
93ReadCharacterAndTestForNull:
94 cs lodsb ; Load from CS:SI to AL
95 test al, al ; NULL to end string?
96 ret
97
98
99;--------------------------------------------------------------------
100; GetFormatSpecifierParserToAX
101; Parameters:
102; AL: Format specifier character
103; Returns:
104; AX: Offset to parser function
105; Corrupts registers:
106; AX, BX
107;--------------------------------------------------------------------
108ALIGN JUMP_ALIGN
109GetFormatSpecifierParserToAX:
110 mov bx, .rgcFormatCharToLookupIndex
111ALIGN JUMP_ALIGN
112.CheckForNextSpecifierParser:
113 cmp al, [cs:bx]
114 je SHORT .ConvertIndexToFunctionOffset
115 inc bx
116 cmp bx, .rgcFormatCharToLookupIndexEnd
117 jb SHORT .CheckForNextSpecifierParser
118 mov ax, c_FormatCharacter
119 ret
120ALIGN JUMP_ALIGN
121.ConvertIndexToFunctionOffset:
122 sub bx, .rgcFormatCharToLookupIndex
123 shl bx, 1 ; Shift for WORD lookup
124 mov ax, [cs:bx+.rgfnFormatSpecifierParser]
125 ret
126
127.rgcFormatCharToLookupIndex:
128%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
129 db "aIAduxsSctz-+%"
130%else
131 db "IAuxscz-" ; Required by XTIDE Universal BIOS
132%endif
133.rgcFormatCharToLookupIndexEnd:
134ALIGN WORD_ALIGN
135.rgfnFormatSpecifierParser:
136%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
137 dw a_FormatAttributeForNextCharacter
138%endif
139 dw I_FormatDashForZero
140 dw A_FormatAttributeForRemainingString
141%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
142 dw d_FormatSignedDecimalWord
143%endif
144 dw u_FormatUnsignedDecimalWord
145 dw x_FormatHexadecimalWord
146 dw s_FormatStringFromSegmentCS
147%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
148 dw S_FormatStringFromFarPointer
149%endif
150 dw c_FormatCharacter
151%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
152 dw t_FormatRepeatCharacter
153%endif
154 dw z_FormatStringFromSegmentZero
155 dw PrepareToPrependParameterWithSpaces
156%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
157 dw PrepareToAppendSpacesAfterParameter
158 dw percent_FormatPercent
159%endif
160
161
162;--------------------------------------------------------------------
163; PrependOrAppendSpaces
164; Parameters:
165; CX: Minimum length for format specifier in characters
166; DS: BDA segment (zero)
167; ES:DI: Ptr to cursor location in video RAM
168; Returns:
169; Nothing
170; Corrupts registers:
171; AX, BX, CX, DX
172;--------------------------------------------------------------------
173ALIGN JUMP_ALIGN
174PrependOrAppendSpaces:
175 mov ax, di
176 sub ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
177 test cx, cx
178 js SHORT .PrependWithSpaces
179 ; Fall to .AppendSpaces
180
181;--------------------------------------------------------------------
182; .AppendSpaces
183; Parameters:
184; AX: Number of format parameter BYTEs printed
185; CX: Minimum length for format specifier in characters
186; DS: BDA segment (zero)
187; ES:DI: Ptr to cursor location in video RAM
188; Returns:
189; Nothing
190; Corrupts registers:
191; AX, CX, DX
192;--------------------------------------------------------------------
193.AppendSpaces:
194 call DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
195 sub cx, ax
196 jle SHORT .NothingToAppendOrPrepend
197 mov al, ' '
198 jmp DisplayPrint_RepeatCharacterFromALwithCountInCX
199
200;--------------------------------------------------------------------
201; .PrependWithSpaces
202; Parameters:
203; AX: Number of format parameter BYTEs printed
204; CX: Negative minimum length for format specifier in characters
205; DS: BDA segment (zero)
206; ES:DI: Ptr to cursor location in video RAM
207; Returns:
208; Nothing
209; Corrupts registers:
210; AX, BX, CX, DX
211;--------------------------------------------------------------------
212ALIGN JUMP_ALIGN
213.PrependWithSpaces:
214 xchg ax, cx
215 neg ax
216 call DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
217 sub ax, cx ; AX = BYTEs to prepend, CX = BYTEs to move
218 jle SHORT .NothingToAppendOrPrepend
219
220 std
221 push si
222
223 lea si, [di-1] ; SI = Offset to last byte formatted
224 add di, ax ; DI = Cursor location after preceeding completed
225 push di
226 dec di ; DI = Offset where to move last byte formatted
227 xchg bx, ax ; BX = BYTEs to prepend
228 call .ReverseCopyCXbytesFromESSItoESDI
229 xchg ax, bx
230 call .ReversePrintAXspacesStartingFromESDI
231
232 pop di
233 pop si
234 cld ; Restore DF
235.NothingToAppendOrPrepend:
236 ret
237
238;--------------------------------------------------------------------
239; .ReverseCopyCXbytesFromESSItoESDI
240; Parameters:
241; CX: Number of bytes to copy
242; DS: BDA segment (zero)
243; ES:SI: Ptr to old location
244; ES:DI: Ptr to new location
245; Returns:
246; DI: Updated to before last character copied
247; Corrupts registers:
248; AX, CX, DX, SI
249;--------------------------------------------------------------------
250ALIGN JUMP_ALIGN
251.ReverseCopyCXbytesFromESSItoESDI:
252 test BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
253 jz SHORT .CopyWithoutDisplayProcessing
254
255 WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
256 dec di ; Point to preceeding character instead of attribute
257 ret
258ALIGN JUMP_ALIGN
259.CopyWithoutDisplayProcessing:
260 eSEG_STR rep, es, movsb
261 ret
262
263;--------------------------------------------------------------------
264; .ReversePrintAXspacesStartingFromESDI
265; Parameters:
266; AX: Number of spaces to print
267; DS: BDA segment (zero)
268; ES:DI: Ptr to destination in video RAM
269; Returns:
270; DI: Updated
271; Corrupts registers:
272; AX, CX, DX
273ALIGN JUMP_ALIGN
274.ReversePrintAXspacesStartingFromESDI:
275 call DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
276 xchg cx, ax ; CX = Spaces to prepend
277 mov al, ' '
278 jmp DisplayPrint_RepeatCharacterFromALwithCountInCX
279
280
281
282;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
283; Formatting functions
284; Parameters:
285; DS: BDA segment (zero)
286; SS:BP: Pointer to next format parameter (-=2 updates to next parameter)
287; ES:DI: Ptr to cursor location in video RAM
288; Returns:
289; SS:BP: Points to last WORD parameter used
290; Corrupts registers:
291; AX, BX, DX
292;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
293%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
294ALIGN JUMP_ALIGN
295a_FormatAttributeForNextCharacter:
296 mov bl, [bp]
297 xchg bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
298 push bx
299 push cx
300 push di
301 call DisplayFormat_ParseCharacters ; Recursive call
302 pop WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
303 pop cx
304 pop bx
305 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
306 ret
307%endif
308
309ALIGN JUMP_ALIGN
310A_FormatAttributeForRemainingString:
311 mov al, [bp]
312 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
313 ret
314
315%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
316ALIGN JUMP_ALIGN
317d_FormatSignedDecimalWord:
318 mov ax, [bp]
319 mov bx, 10
320 jmp DisplayPrint_SignedWordFromAXWithBaseInBX
321%endif
322
323ALIGN JUMP_ALIGN
324u_FormatUnsignedDecimalWord:
325 mov ax, [bp]
326 mov bx, 10
327 jmp DisplayPrint_WordFromAXWithBaseInBX
328
329ALIGN JUMP_ALIGN
330x_FormatHexadecimalWord:
331 mov ax, [bp]
332 mov bx, 16
333 call DisplayPrint_WordFromAXWithBaseInBX
334 mov al, 'h'
335 jmp DisplayPrint_CharacterFromAL
336
337ALIGN JUMP_ALIGN
338I_FormatDashForZero:
339 mov ax, [bp]
340 test ax,ax
341 jnz u_FormatUnsignedDecimalWord
342 mov [bp], word g_szDashForZero
343;;; fall-through
344
345ALIGN JUMP_ALIGN
346s_FormatStringFromSegmentCS:
347 push si
348 push cx
349 mov si, [bp]
350
351 cmp si, byte 07fh ; well within the boundaries of ROMVARS_size
352 jb .notFormatted
353
354 dec bp
355 dec bp
356 call DisplayFormat_ParseCharacters
357 inc bp ; will be decremented after the call is done
358 inc bp
359 jmp .done
360
361.notFormatted:
362 call DisplayPrint_NullTerminatedStringFromCSSI
363
364.done:
365 pop cx
366 pop si
367 ret
368
369ALIGN JUMP_ALIGN
370z_FormatStringFromSegmentZero:
371 xchg si, [bp]
372 xor bx, bx
373 call DisplayPrint_NullTerminatedStringFromBXSI
374 mov si, [bp]
375 ret
376
377%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
378ALIGN JUMP_ALIGN
379S_FormatStringFromFarPointer:
380 mov bx, [bp-2]
381 xchg si, [bp]
382 call DisplayPrint_NullTerminatedStringFromBXSI
383 mov si, [bp]
384 dec bp
385 dec bp
386 ret
387%endif
388
389ALIGN JUMP_ALIGN
390c_FormatCharacter:
391 mov al, [bp]
392 jmp DisplayPrint_CharacterFromAL
393
394%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
395ALIGN JUMP_ALIGN
396t_FormatRepeatCharacter:
397 push cx
398 mov cx, [bp-2]
399 mov al, [bp]
400 call DisplayPrint_RepeatCharacterFromALwithCountInCX
401 pop cx
402 dec bp
403 dec bp
404 ret
405
406ALIGN JUMP_ALIGN
407percent_FormatPercent:
408 mov al, '%'
409 jmp DisplayPrint_CharacterFromAL
410%endif
411
412ALIGN JUMP_ALIGN
413PrepareToPrependParameterWithSpaces:
414 neg cx
415 ; Fall to PrepareToAppendSpacesAfterParameter
416
417ALIGN JUMP_ALIGN
418PrepareToAppendSpacesAfterParameter:
419 add sp, BYTE 2 ; Remove return offset
420 jmp ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.