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

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

Space optimization, added a new format character 'I' which is the same as 'u' but shows a dash if the operand is zero. Replaces the PushIRQ functionality in bootmenuprintcfg.asm. This only saves a few bytes now, but saves significantly more with the string compression code.

File size: 11.1 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 eSEG cs
95 lodsb ; Load from CS:SI to AL
96 test al, al ; NULL to end string?
97 ret
98
99
100;--------------------------------------------------------------------
101; GetFormatSpecifierParserToAX
102; Parameters:
103; AL: Format specifier character
104; Returns:
105; AX: Offset to parser function
106; Corrupts registers:
107; AX, BX
108;--------------------------------------------------------------------
109ALIGN JUMP_ALIGN
110GetFormatSpecifierParserToAX:
111 mov bx, .rgcFormatCharToLookupIndex
112ALIGN JUMP_ALIGN
113.CheckForNextSpecifierParser:
114 cmp al, [cs:bx]
115 je SHORT .ConvertIndexToFunctionOffset
116 inc bx
117 cmp bx, .rgcFormatCharToLookupIndexEnd
118 jb SHORT .CheckForNextSpecifierParser
119 mov ax, c_FormatCharacter
120 ret
121ALIGN JUMP_ALIGN
122.ConvertIndexToFunctionOffset:
123 sub bx, .rgcFormatCharToLookupIndex
124 shl bx, 1 ; Shift for WORD lookup
125 mov ax, [cs:bx+.rgfnFormatSpecifierParser]
126 ret
127
128.rgcFormatCharToLookupIndex:
129%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
130 db "aIAduxsSct-+%"
131%else
132 db "IAuxsc-" ; Required by XTIDE Universal BIOS
133%endif
134.rgcFormatCharToLookupIndexEnd:
135ALIGN WORD_ALIGN
136.rgfnFormatSpecifierParser:
137%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
138 dw a_FormatAttributeForNextCharacter
139%endif
140 dw I_FormatDashForZero
141 dw A_FormatAttributeForRemainingString
142%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
143 dw d_FormatSignedDecimalWord
144%endif
145 dw u_FormatUnsignedDecimalWord
146 dw x_FormatHexadecimalWord
147 dw s_FormatStringFromSegmentCS
148%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
149 dw S_FormatStringFromFarPointer
150%endif
151 dw c_FormatCharacter
152%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
153 dw t_FormatRepeatCharacter
154%endif
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 xchg si, [bp]
348 call DisplayPrint_NullTerminatedStringFromCSSI
349 mov si, [bp]
350 ret
351
352%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
353ALIGN JUMP_ALIGN
354S_FormatStringFromFarPointer:
355 mov bx, [bp-2]
356 xchg si, [bp]
357 call DisplayPrint_NullTerminatedStringFromBXSI
358 mov si, [bp]
359 dec bp
360 dec bp
361 ret
362%endif
363
364ALIGN JUMP_ALIGN
365c_FormatCharacter:
366 mov al, [bp]
367 jmp DisplayPrint_CharacterFromAL
368
369%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
370ALIGN JUMP_ALIGN
371t_FormatRepeatCharacter:
372 push cx
373 mov cx, [bp-2]
374 mov al, [bp]
375 call DisplayPrint_RepeatCharacterFromALwithCountInCX
376 pop cx
377 dec bp
378 dec bp
379 ret
380
381ALIGN JUMP_ALIGN
382percent_FormatPercent:
383 mov al, '%'
384 jmp DisplayPrint_CharacterFromAL
385%endif
386
387ALIGN JUMP_ALIGN
388PrepareToPrependParameterWithSpaces:
389 neg cx
390 ; Fall to PrepareToAppendSpacesAfterParameter
391
392ALIGN JUMP_ALIGN
393PrepareToAppendSpacesAfterParameter:
394 add sp, BYTE 2 ; Remove return offset
395 jmp ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.