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

Last change on this file since 590 was 590, checked in by Krister Nordvall, 9 years ago

Changes:

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