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

Last change on this file since 376 was 376, checked in by gregli@…, 12 years ago

WIDE checkin... Added copyright and license information to sorce files, as per the GPL instructions for usage.

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-2012 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    shl     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    WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
272    dec     di                  ; Point to preceeding character instead of attribute
273    ret
274ALIGN DISPLAY_JUMP_ALIGN
275.CopyWithoutDisplayProcessing:
276    eSEG_STR rep, es, movsb
277    ret
278
279;--------------------------------------------------------------------
280; .ReversePrintAXspacesStartingFromESDI
281;   Parameters:
282;       AX:     Number of spaces to print
283;       DS:     BDA segment (zero)
284;       ES:DI:  Ptr to destination in video RAM
285;   Returns:
286;       DI:     Updated
287;   Corrupts registers:
288;       AX, CX, DX
289ALIGN DISPLAY_JUMP_ALIGN
290.ReversePrintAXspacesStartingFromESDI:
291    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
292    xchg    cx, ax              ; CX = Spaces to prepend
293    mov     al, ' '
294    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
295
296
297
298;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
299; Formatting functions
300;   Parameters:
301;       DS:     BDA segment (zero)
302;       SS:BP:  Pointer to next format parameter (-=2 updates to next parameter)
303;       ES:DI:  Ptr to cursor location in video RAM
304;   Returns:
305;       SS:BP:  Points to last WORD parameter used
306;   Corrupts registers:
307;       AX, BX, DX
308;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
309%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
310ALIGN DISPLAY_JUMP_ALIGN
311a_FormatAttributeForNextCharacter:
312    mov     bl, [bp]
313    xchg    bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
314    push    bx
315    push    cx
316    push    di
317    call    DisplayFormat_ParseCharacters   ; Recursive call
318    pop     WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
319    pop     cx
320    pop     bx
321    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
322    ret
323%endif
324
325ALIGN DISPLAY_JUMP_ALIGN
326A_FormatAttributeForRemainingString:
327    mov     al, [bp]
328    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
329    ret
330
331%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
332ALIGN DISPLAY_JUMP_ALIGN
333d_FormatSignedDecimalWord:
334    mov     ax, [bp]
335    mov     bx, 10
336    jmp     DisplayPrint_SignedWordFromAXWithBaseInBX
337%endif
338
339ALIGN DISPLAY_JUMP_ALIGN
340u_FormatUnsignedDecimalWord:
341    mov     ax, [bp]
342    mov     bx, 10
343    jmp     DisplayPrint_WordFromAXWithBaseInBX
344
345ALIGN DISPLAY_JUMP_ALIGN
346x_FormatHexadecimalWord:
347    mov     ax, [bp]
348    mov     bx, 16
349    call    DisplayPrint_WordFromAXWithBaseInBX
350    mov     al, 'h'
351    jmp     DisplayPrint_CharacterFromAL
352
353ALIGN DISPLAY_JUMP_ALIGN
354I_FormatDashForZero:
355    mov     ax, [bp]
356    test    ax,ax
357    jnz     u_FormatUnsignedDecimalWord
358    mov     [bp], word 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 07fh       ;  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.