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

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

Changes:

  • Fixed what appears to be a mistake in EBIOS.inc
  • Added a 'release' option to the makefile of the Serial Server (invokes UPX)
  • Some very minor optimizations
  • Removed the eSEG macro and did some other cleanups (fixed typos etc)
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    cs lodsb                                ; Load from CS:SI to AL
95    test    al, al                          ; NULL to end string?
96    ret
97
98
99;--------------------------------------------------------------------
100; GetFormatSpecifierParserToAX
101;   Parameters:
102;       AL:     Format specifier character
103;   Returns:
104;       AX:     Offset to parser function
105;   Corrupts registers:
106;       AX, BX
107;--------------------------------------------------------------------
108ALIGN JUMP_ALIGN
109GetFormatSpecifierParserToAX:
110    mov     bx, .rgcFormatCharToLookupIndex
111ALIGN JUMP_ALIGN
112.CheckForNextSpecifierParser:
113    cmp     al, [cs:bx]
114    je      SHORT .ConvertIndexToFunctionOffset
115    inc     bx
116    cmp     bx, .rgcFormatCharToLookupIndexEnd
117    jb      SHORT .CheckForNextSpecifierParser
118    mov     ax, c_FormatCharacter
119    ret
120ALIGN JUMP_ALIGN
121.ConvertIndexToFunctionOffset:
122    sub     bx, .rgcFormatCharToLookupIndex
123    shl     bx, 1               ; Shift for WORD lookup
124    mov     ax, [cs:bx+.rgfnFormatSpecifierParser]
125    ret
126
127.rgcFormatCharToLookupIndex:
128%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
129    db      "aIAduxsSct-+%"
130%else
131    db      "IAuxsc-"       ; Required by XTIDE Universal BIOS
132%endif
133.rgcFormatCharToLookupIndexEnd:
134ALIGN WORD_ALIGN
135.rgfnFormatSpecifierParser:
136%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
137    dw      a_FormatAttributeForNextCharacter
138%endif
139    dw      I_FormatDashForZero
140    dw      A_FormatAttributeForRemainingString
141%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
142    dw      d_FormatSignedDecimalWord
143%endif
144    dw      u_FormatUnsignedDecimalWord
145    dw      x_FormatHexadecimalWord
146    dw      s_FormatStringFromSegmentCS
147%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
148    dw      S_FormatStringFromFarPointer
149%endif
150    dw      c_FormatCharacter
151%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
152    dw      t_FormatRepeatCharacter
153%endif
154    dw      PrepareToPrependParameterWithSpaces
155%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
156    dw      PrepareToAppendSpacesAfterParameter
157    dw      percent_FormatPercent
158%endif
159
160
161;--------------------------------------------------------------------
162; PrependOrAppendSpaces
163;   Parameters:
164;       CX:     Minimum length for format specifier in characters
165;       DS:     BDA segment (zero)
166;       ES:DI:  Ptr to cursor location in video RAM
167;   Returns:
168;       Nothing
169;   Corrupts registers:
170;       AX, BX, CX, DX
171;--------------------------------------------------------------------
172ALIGN JUMP_ALIGN
173PrependOrAppendSpaces:
174    mov     ax, di
175    sub     ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
176    test    cx, cx
177    js      SHORT .PrependWithSpaces
178    ; Fall to .AppendSpaces
179
180;--------------------------------------------------------------------
181; .AppendSpaces
182;   Parameters:
183;       AX:     Number of format parameter BYTEs printed
184;       CX:     Minimum length for format specifier in characters
185;       DS:     BDA segment (zero)
186;       ES:DI:  Ptr to cursor location in video RAM
187;   Returns:
188;       Nothing
189;   Corrupts registers:
190;       AX, CX, DX
191;--------------------------------------------------------------------
192.AppendSpaces:
193    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
194    sub     cx, ax
195    jle     SHORT .NothingToAppendOrPrepend
196    mov     al, ' '
197    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
198
199;--------------------------------------------------------------------
200; .PrependWithSpaces
201;   Parameters:
202;       AX:     Number of format parameter BYTEs printed
203;       CX:     Negative minimum length for format specifier in characters
204;       DS:     BDA segment (zero)
205;       ES:DI:  Ptr to cursor location in video RAM
206;   Returns:
207;       Nothing
208;   Corrupts registers:
209;       AX, BX, CX, DX
210;--------------------------------------------------------------------
211ALIGN JUMP_ALIGN
212.PrependWithSpaces:
213    xchg    ax, cx
214    neg     ax
215    call    DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
216    sub     ax, cx              ; AX = BYTEs to prepend, CX = BYTEs to move
217    jle     SHORT .NothingToAppendOrPrepend
218
219    std
220    push    si
221
222    lea     si, [di-1]          ; SI = Offset to last byte formatted
223    add     di, ax              ; DI = Cursor location after preceeding completed
224    push    di
225    dec     di                  ; DI = Offset where to move last byte formatted
226    xchg    bx, ax              ; BX = BYTEs to prepend
227    call    .ReverseCopyCXbytesFromESSItoESDI
228    xchg    ax, bx
229    call    .ReversePrintAXspacesStartingFromESDI
230
231    pop     di
232    pop     si
233    cld                         ; Restore DF
234.NothingToAppendOrPrepend:
235    ret
236
237;--------------------------------------------------------------------
238; .ReverseCopyCXbytesFromESSItoESDI
239;   Parameters:
240;       CX:     Number of bytes to copy
241;       DS:     BDA segment (zero)
242;       ES:SI:  Ptr to old location
243;       ES:DI:  Ptr to new location
244;   Returns:
245;       DI:     Updated to before last character copied
246;   Corrupts registers:
247;       AX, CX, DX, SI
248;--------------------------------------------------------------------
249ALIGN JUMP_ALIGN
250.ReverseCopyCXbytesFromESSItoESDI:
251    test    BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
252    jz      SHORT .CopyWithoutDisplayProcessing
253
254    WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
255    dec     di                  ; Point to preceeding character instead of attribute
256    ret
257ALIGN JUMP_ALIGN
258.CopyWithoutDisplayProcessing:
259    eSEG_STR rep, es, movsb
260    ret
261
262;--------------------------------------------------------------------
263; .ReversePrintAXspacesStartingFromESDI
264;   Parameters:
265;       AX:     Number of spaces to print
266;       DS:     BDA segment (zero)
267;       ES:DI:  Ptr to destination in video RAM
268;   Returns:
269;       DI:     Updated
270;   Corrupts registers:
271;       AX, CX, DX
272ALIGN JUMP_ALIGN
273.ReversePrintAXspacesStartingFromESDI:
274    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
275    xchg    cx, ax              ; CX = Spaces to prepend
276    mov     al, ' '
277    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
278
279
280
281;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
282; Formatting functions
283;   Parameters:
284;       DS:     BDA segment (zero)
285;       SS:BP:  Pointer to next format parameter (-=2 updates to next parameter)
286;       ES:DI:  Ptr to cursor location in video RAM
287;   Returns:
288;       SS:BP:  Points to last WORD parameter used
289;   Corrupts registers:
290;       AX, BX, DX
291;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
292%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
293ALIGN JUMP_ALIGN
294a_FormatAttributeForNextCharacter:
295    mov     bl, [bp]
296    xchg    bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
297    push    bx
298    push    cx
299    push    di
300    call    DisplayFormat_ParseCharacters   ; Recursive call
301    pop     WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
302    pop     cx
303    pop     bx
304    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
305    ret
306%endif
307
308ALIGN JUMP_ALIGN
309A_FormatAttributeForRemainingString:
310    mov     al, [bp]
311    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
312    ret
313
314%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
315ALIGN JUMP_ALIGN
316d_FormatSignedDecimalWord:
317    mov     ax, [bp]
318    mov     bx, 10
319    jmp     DisplayPrint_SignedWordFromAXWithBaseInBX
320%endif
321
322ALIGN JUMP_ALIGN
323u_FormatUnsignedDecimalWord:
324    mov     ax, [bp]
325    mov     bx, 10
326    jmp     DisplayPrint_WordFromAXWithBaseInBX
327
328ALIGN JUMP_ALIGN
329x_FormatHexadecimalWord:
330    mov     ax, [bp]
331    mov     bx, 16
332    call    DisplayPrint_WordFromAXWithBaseInBX
333    mov     al, 'h'
334    jmp     DisplayPrint_CharacterFromAL
335
336ALIGN JUMP_ALIGN
337I_FormatDashForZero:
338    mov     ax, [bp]
339    test    ax,ax
340    jnz     u_FormatUnsignedDecimalWord
341    mov     [bp], word g_szDashForZero
342;;; fall-through
343
344ALIGN JUMP_ALIGN
345s_FormatStringFromSegmentCS:
346    xchg    si, [bp]
347    call    DisplayPrint_NullTerminatedStringFromCSSI
348    mov     si, [bp]
349    ret
350
351%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
352ALIGN JUMP_ALIGN
353S_FormatStringFromFarPointer:
354    mov     bx, [bp-2]
355    xchg    si, [bp]
356    call    DisplayPrint_NullTerminatedStringFromBXSI
357    mov     si, [bp]
358    dec     bp
359    dec     bp
360    ret
361%endif
362
363ALIGN JUMP_ALIGN
364c_FormatCharacter:
365    mov     al, [bp]
366    jmp     DisplayPrint_CharacterFromAL
367
368%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
369ALIGN JUMP_ALIGN
370t_FormatRepeatCharacter:
371    push    cx
372    mov     cx, [bp-2]
373    mov     al, [bp]
374    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
375    pop     cx
376    dec     bp
377    dec     bp
378    ret
379
380ALIGN JUMP_ALIGN
381percent_FormatPercent:
382    mov     al, '%'
383    jmp     DisplayPrint_CharacterFromAL
384%endif
385
386ALIGN JUMP_ALIGN
387PrepareToPrependParameterWithSpaces:
388    neg     cx
389    ; Fall to PrepareToAppendSpacesAfterParameter
390
391ALIGN JUMP_ALIGN
392PrepareToAppendSpacesAfterParameter:
393    add     sp, BYTE 2              ; Remove return offset
394    jmp     ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.