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

Last change on this file since 590 was 590, checked in by krille_n_, 8 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.