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

Last change on this file since 184 was 184, checked in by gregli@…, 12 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.