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

Last change on this file since 44 was 44, checked in by aitotat, 14 years ago

Spaces can now be generated before format specifier when printing formatted string.
Background character and attribute can now be easily specified before compiling.

File size: 9.4 KB
Line 
1; File name     :   DisplayFormat.asm
2; Project name  :   Assembly Library
3; Created date  :   29.6.2010
4; Last update   :   26.9.2010
5; Author        :   Tomi Tilli
6; Description   :   Functions for displaying formatted strings.
7
8; Section containing code
9SECTION .text
10
11;--------------------------------------------------------------------
12; DisplayFormat_ParseCharacters
13;   Parameters:
14;       DS:     BDA segment (zero)
15;       SS:BP:  Pointer to first format parameter (-=2 updates to next parameter)
16;       CS:SI:  Pointer to string to format
17;       ES:DI:  Ptr to cursor location in video RAM
18;   Returns:
19;       CS:SI:  Ptr to end of format string (ptr to one past NULL)
20;       DI:     Updated offset to video RAM
21;   Corrupts registers:
22;       AX, BX, CX, DX, BP
23;--------------------------------------------------------------------
24ALIGN JUMP_ALIGN
25DisplayFormat_ParseCharacters:
26    call    ReadCharacterAndTestForNull
27    jz      SHORT .QuitCharacterParsing
28
29    ePUSH_T cx, DisplayFormat_ParseCharacters   ; Return address
30    xor     cx, cx                              ; Initial placeholder size
31    cmp     al, '%'                             ; Format specifier?
32    je      SHORT ParseFormatSpecifier
33    jmp     DisplayPrint_CharacterFromAL
34
35ALIGN JUMP_ALIGN
36.QuitCharacterParsing:
37    ret
38
39
40;--------------------------------------------------------------------
41; ParseFormatSpecifier
42;   Parameters:
43;       CX:     Placeholder size
44;       DS:     BDA segment (zero)
45;       SS:BP:  Pointer to first format parameter (-=2 for next parameter)
46;       CS:SI:  Pointer to string to format
47;       ES:DI:  Ptr to cursor location in video RAM
48;   Returns:
49;       SI:     Updated to first unparsed character
50;       DI:     Updated offset to video RAM
51;       BP:     Updated to next format parameter
52;   Corrupts registers:
53;       AX, BX, CX, DX
54;--------------------------------------------------------------------
55ALIGN JUMP_ALIGN
56ParseFormatSpecifier:
57    call    ReadCharacterAndTestForNull
58    call    Char_IsDecimalDigitInAL
59    jc      SHORT .ParsePlaceholderSizeDigitFromALtoCX
60    call    GetFormatSpecifierParserToAX
61    call    ax              ; Parser function
62    dec     bp
63    dec     bp              ; SS:BP now points to next parameter
64    test    cx, cx
65    jnz     SHORT PrependOrAppendSpaces
66    ret
67
68;--------------------------------------------------------------------
69; .ParsePlaceholderSizeDigitFromALtoCX
70;   Parameters:
71;       AL:     Digit character from format string
72;       CX:     Current placeholder size
73;       DS:     BDA segment (zero)
74;   Returns:
75;       CX:     Current placeholder size
76;       Jumps back to ParseFormatSpecifier
77;   Corrupts registers:
78;       AX
79;--------------------------------------------------------------------
80ALIGN JUMP_ALIGN
81.ParsePlaceholderSizeDigitFromALtoCX:
82    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
83    sub     al, '0'             ; Digit '0'...'9' to integer 0...9
84    mov     ah, cl              ; Previous number parameter to AH
85    aad                         ; AL += (AH * 10)
86    mov     cl, al              ; Updated number parameter now in CX
87    jmp     SHORT ParseFormatSpecifier
88
89
90;--------------------------------------------------------------------
91; ReadCharacterAndTestForNull
92;   Parameters:
93;       CS:SI:  Pointer next character from string
94;   Returns:
95;       AL:     Character from string
96;       SI:     Incremented to next character
97;       ZF:     Set if NULL, cleared if valid character
98;   Corrupts registers:
99;       Nothing
100;--------------------------------------------------------------------
101ALIGN JUMP_ALIGN
102ReadCharacterAndTestForNull:
103    eSEG    cs
104    lodsb                                   ; Load from CS:SI to AL
105    test    al, al                          ; NULL to end string?
106    ret
107
108
109;--------------------------------------------------------------------
110; GetFormatSpecifierParserToAX
111;   Parameters:
112;       AL:     Format specifier character
113;   Returns:
114;       AX:     Offset to parser function
115;   Corrupts registers:
116;       AX, BX
117;--------------------------------------------------------------------
118ALIGN JUMP_ALIGN
119GetFormatSpecifierParserToAX:
120    mov     bx, .rgcFormatCharToLookupIndex
121ALIGN JUMP_ALIGN
122.CheckForNextSpecifierParser:
123    cmp     al, [cs:bx]
124    je      SHORT .ConvertIndexToFunctionOffset
125    inc     bx
126    cmp     bx, .rgcFormatCharToLookupIndexEnd
127    jb      SHORT .CheckForNextSpecifierParser
128    mov     ax, c_FormatCharacter
129    ret
130ALIGN JUMP_ALIGN
131.ConvertIndexToFunctionOffset:
132    sub     bx, .rgcFormatCharToLookupIndex
133    shl     bx, 1               ; Shift for WORD lookup
134    mov     ax, [cs:bx+.rgfnFormatSpecifierParser]
135    ret
136
137.rgcFormatCharToLookupIndex:
138    db      "aAduxsSct-+%"
139.rgcFormatCharToLookupIndexEnd:
140ALIGN WORD_ALIGN
141.rgfnFormatSpecifierParser:
142    dw      a_FormatAttributeForNextCharacter
143    dw      A_FormatAttributeForRemainingString
144    dw      d_FormatSignedDecimalWord
145    dw      u_FormatUnsignedDecimalWord
146    dw      x_FormatHexadecimalWord
147    dw      s_FormatStringFromSegmentCS
148    dw      S_FormatStringFromFarPointer
149    dw      c_FormatCharacter
150    dw      t_FormatRepeatCharacter
151    dw      PrepareToPrependParameterWithSpaces
152    dw      PrepareToAppendSpacesAfterParameter
153    dw      percent_FormatPercent
154
155
156;--------------------------------------------------------------------
157; PrependOrAppendSpaces
158;   Parameters:
159;       CX:     Minimum length for format specifier in characters
160;       DS:     BDA segment (zero)
161;       ES:DI:  Ptr to cursor location in video RAM
162;   Returns:
163;       Nothing
164;   Corrupts registers:
165;       AX, BX, CX, DX
166;--------------------------------------------------------------------
167ALIGN JUMP_ALIGN
168PrependOrAppendSpaces:
169    mov     ax, di
170    sub     ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
171    test    cx, cx
172    js      SHORT .PrependWithSpaces
173    ; Fall to .AppendSpaces
174
175;--------------------------------------------------------------------
176; .AppendSpaces
177;   Parameters:
178;       AX:     Number of format parameter BYTEs printed
179;       CX:     Minimum length for format specifier in characters
180;       DS:     BDA segment (zero)
181;       ES:DI:  Ptr to cursor location in video RAM
182;   Returns:
183;       Nothing
184;   Corrupts registers:
185;       AX, CX, DX
186;--------------------------------------------------------------------
187.AppendSpaces:
188    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
189    sub     cx, ax
190    jle     SHORT .NothingToAppendOrPrepend
191    mov     al, ' '
192    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
193
194;--------------------------------------------------------------------
195; .PrependWithSpaces
196;   Parameters:
197;       AX:     Number of format parameter BYTEs printed
198;       CX:     Negative minimum length for format specifier in characters
199;       DS:     BDA segment (zero)
200;       ES:DI:  Ptr to cursor location in video RAM
201;   Returns:
202;       Nothing
203;   Corrupts registers:
204;       AX, BX, CX, DX
205;--------------------------------------------------------------------
206ALIGN JUMP_ALIGN
207.PrependWithSpaces:
208    xchg    ax, cx
209    neg     ax
210    call    DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
211    sub     ax, cx              ; AX = BYTEs to prepend, CX = BYTEs to move
212    jle     SHORT .NothingToAppendOrPrepend
213
214    mov     bx, di
215    add     bx, ax              ; BX = DI after prepending
216
217    push    si
218    dec     di                  ; DI = Offset to last byte formatted
219    mov     si, di
220    add     di, ax              ; DI = Offset to new location for last byte
221    std
222    eSEG_STR rep, es, movsb
223
224    mov     dl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags]
225    and     dx, BYTE FLG_CONTEXT_ATTRIBUTES
226    not     dx
227    and     di, dx              ; WORD alignment when using attributes
228
229    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
230    xchg    cx, ax              ; CX = Spaces to prepend
231    mov     al, ' '
232    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
233    cld                         ; Restore DF
234
235    mov     di, bx
236    pop     si
237.NothingToAppendOrPrepend:
238    ret
239
240
241;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
242; Formatting functions
243;   Parameters:
244;       DS:     BDA segment (zero)
245;       SS:BP:  Pointer to next format parameter (-=2 updates to next parameter)
246;       ES:DI:  Ptr to cursor location in video RAM
247;   Returns:
248;       SS:BP:  Points to last WORD parameter used
249;   Corrupts registers:
250;       AX, BX, DX
251;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
252ALIGN JUMP_ALIGN
253a_FormatAttributeForNextCharacter:
254    mov     bl, [bp]
255    xchg    bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
256    push    bx
257    push    cx
258    push    di
259    call    DisplayFormat_ParseCharacters   ; Recursive call
260    pop     WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
261    pop     cx
262    pop     bx
263    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
264    ret
265
266ALIGN JUMP_ALIGN
267A_FormatAttributeForRemainingString:
268    mov     al, [bp]
269    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
270    ret
271
272ALIGN JUMP_ALIGN
273d_FormatSignedDecimalWord:
274    mov     ax, [bp]
275    mov     bx, 10
276    jmp     DisplayPrint_SignedWordFromAXWithBaseInBX
277
278ALIGN JUMP_ALIGN
279u_FormatUnsignedDecimalWord:
280    mov     ax, [bp]
281    mov     bx, 10
282    jmp     DisplayPrint_WordFromAXWithBaseInBX
283
284ALIGN JUMP_ALIGN
285x_FormatHexadecimalWord:
286    mov     ax, [bp]
287    mov     bx, 16
288    call    DisplayPrint_WordFromAXWithBaseInBX
289    mov     al, 'h'
290    jmp     DisplayPrint_CharacterFromAL
291
292ALIGN JUMP_ALIGN
293s_FormatStringFromSegmentCS:
294    xchg    si, [bp]
295    call    DisplayPrint_NullTerminatedStringFromCSSI
296    mov     si, [bp]
297    ret
298
299ALIGN JUMP_ALIGN
300S_FormatStringFromFarPointer:
301    mov     bx, [bp-2]
302    xchg    si, [bp]
303    call    DisplayPrint_NullTerminatedStringFromBXSI
304    mov     si, [bp]
305    dec     bp
306    dec     bp
307    ret
308
309ALIGN JUMP_ALIGN
310c_FormatCharacter:
311    mov     al, [bp]
312    jmp     DisplayPrint_CharacterFromAL
313
314ALIGN JUMP_ALIGN
315t_FormatRepeatCharacter:
316    push    cx
317    mov     cx, [bp-2]
318    mov     al, [bp]
319    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
320    pop     cx
321    dec     bp
322    dec     bp
323    ret
324
325ALIGN JUMP_ALIGN
326percent_FormatPercent:
327    mov     al, '%'
328    jmp     DisplayPrint_CharacterFromAL
329
330ALIGN JUMP_ALIGN
331PrepareToPrependParameterWithSpaces:
332    neg     cx
333    ; Fall to PrepareToAppendSpacesAfterParameter
334
335ALIGN JUMP_ALIGN
336PrepareToAppendSpacesAfterParameter:
337    add     sp, BYTE 2              ; Remove return offset
338    jmp     ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.