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
RevLine 
[41]1; Project name  :   Assembly Library
2; Description   :   Functions for displaying formatted strings.
3
[376]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
[41]20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
24; DisplayFormat_ParseCharacters
25;   Parameters:
26;       DS:     BDA segment (zero)
[44]27;       SS:BP:  Pointer to first format parameter (-=2 updates to next parameter)
[41]28;       CS:SI:  Pointer to string to format
29;       ES:DI:  Ptr to cursor location in video RAM
30;   Returns:
[44]31;       CS:SI:  Ptr to end of format string (ptr to one past NULL)
[41]32;       DI:     Updated offset to video RAM
33;   Corrupts registers:
[44]34;       AX, BX, CX, DX, BP
[41]35;--------------------------------------------------------------------
[369]36ALIGN DISPLAY_JUMP_ALIGN
[41]37DisplayFormat_ParseCharacters:
[44]38    call    ReadCharacterAndTestForNull
[101]39    jz      SHORT ReturnFromFormat
[44]40
41    ePUSH_T cx, DisplayFormat_ParseCharacters   ; Return address
42    xor     cx, cx                              ; Initial placeholder size
43    cmp     al, '%'                             ; Format specifier?
[101]44    jne     SHORT DisplayPrint_CharacterFromAL
45    ; Fall to ParseFormatSpecifier
[44]46
[41]47;--------------------------------------------------------------------
[44]48; ParseFormatSpecifier
[41]49;   Parameters:
[44]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
[101]65    jc      SHORT ParsePlaceholderSizeDigitFromALtoCX
[44]66    call    GetFormatSpecifierParserToAX
67    call    ax              ; Parser function
68    dec     bp
69    dec     bp              ; SS:BP now points to next parameter
[181]70    inc     cx
71    loop    PrependOrAppendSpaces
[101]72ReturnFromFormat:
[44]73    ret
74
75;--------------------------------------------------------------------
[101]76; ParsePlaceholderSizeDigitFromALtoCX
[44]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;--------------------------------------------------------------------
[369]87ALIGN DISPLAY_JUMP_ALIGN
[101]88ParsePlaceholderSizeDigitFromALtoCX:
[44]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:
[41]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;--------------------------------------------------------------------
[369]108ALIGN DISPLAY_JUMP_ALIGN
[44]109ReadCharacterAndTestForNull:
[223]110    cs lodsb                                ; Load from CS:SI to AL
[41]111    test    al, al                          ; NULL to end string?
112    ret
113
114
115;--------------------------------------------------------------------
[44]116; GetFormatSpecifierParserToAX
[41]117;   Parameters:
[44]118;       AL:     Format specifier character
[41]119;   Returns:
[44]120;       AX:     Offset to parser function
[41]121;   Corrupts registers:
[44]122;       AX, BX
[41]123;--------------------------------------------------------------------
[369]124ALIGN DISPLAY_JUMP_ALIGN
[44]125GetFormatSpecifierParserToAX:
126    mov     bx, .rgcFormatCharToLookupIndex
[369]127ALIGN DISPLAY_JUMP_ALIGN
[44]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
[369]136ALIGN DISPLAY_JUMP_ALIGN
[44]137.ConvertIndexToFunctionOffset:
138    sub     bx, .rgcFormatCharToLookupIndex
139    shl     bx, 1               ; Shift for WORD lookup
140    mov     ax, [cs:bx+.rgfnFormatSpecifierParser]
141    ret
[41]142
[44]143.rgcFormatCharToLookupIndex:
[134]144%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[241]145    db      "aIAduxsSctz-+%"
[134]146%else
[241]147    db      "IAuxscz-"      ; Required by XTIDE Universal BIOS
[134]148%endif
[44]149.rgcFormatCharToLookupIndexEnd:
150ALIGN WORD_ALIGN
151.rgfnFormatSpecifierParser:
[134]152%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]153    dw      a_FormatAttributeForNextCharacter
[134]154%endif
[184]155    dw      I_FormatDashForZero
[44]156    dw      A_FormatAttributeForRemainingString
[134]157%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]158    dw      d_FormatSignedDecimalWord
[134]159%endif
[44]160    dw      u_FormatUnsignedDecimalWord
161    dw      x_FormatHexadecimalWord
162    dw      s_FormatStringFromSegmentCS
[134]163%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]164    dw      S_FormatStringFromFarPointer
[134]165%endif
[44]166    dw      c_FormatCharacter
[134]167%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]168    dw      t_FormatRepeatCharacter
[134]169%endif
[241]170    dw      z_FormatStringFromSegmentZero
[44]171    dw      PrepareToPrependParameterWithSpaces
[134]172%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]173    dw      PrepareToAppendSpacesAfterParameter
174    dw      percent_FormatPercent
[134]175%endif
[41]176
[44]177
[41]178;--------------------------------------------------------------------
[44]179; PrependOrAppendSpaces
[41]180;   Parameters:
[44]181;       CX:     Minimum length for format specifier in characters
[41]182;       DS:     BDA segment (zero)
183;       ES:DI:  Ptr to cursor location in video RAM
184;   Returns:
[44]185;       Nothing
[41]186;   Corrupts registers:
187;       AX, BX, CX, DX
188;--------------------------------------------------------------------
[369]189ALIGN DISPLAY_JUMP_ALIGN
[44]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
[41]196
197;--------------------------------------------------------------------
[44]198; .AppendSpaces
[41]199;   Parameters:
[44]200;       AX:     Number of format parameter BYTEs printed
201;       CX:     Minimum length for format specifier in characters
[41]202;       DS:     BDA segment (zero)
203;       ES:DI:  Ptr to cursor location in video RAM
204;   Returns:
[44]205;       Nothing
[41]206;   Corrupts registers:
[44]207;       AX, CX, DX
[41]208;--------------------------------------------------------------------
[44]209.AppendSpaces:
210    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
211    sub     cx, ax
212    jle     SHORT .NothingToAppendOrPrepend
[41]213    mov     al, ' '
[44]214    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
[41]215
216;--------------------------------------------------------------------
[44]217; .PrependWithSpaces
[41]218;   Parameters:
[44]219;       AX:     Number of format parameter BYTEs printed
220;       CX:     Negative minimum length for format specifier in characters
[41]221;       DS:     BDA segment (zero)
222;       ES:DI:  Ptr to cursor location in video RAM
223;   Returns:
[44]224;       Nothing
[41]225;   Corrupts registers:
[44]226;       AX, BX, CX, DX
[41]227;--------------------------------------------------------------------
[369]228ALIGN DISPLAY_JUMP_ALIGN
[44]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
[41]235
[47]236    std
237    push    si
[41]238
[47]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
[48]244    call    .ReverseCopyCXbytesFromESSItoESDI
[47]245    xchg    ax, bx
246    call    .ReversePrintAXspacesStartingFromESDI
247
248    pop     di
249    pop     si
250    cld                         ; Restore DF
251.NothingToAppendOrPrepend:
252    ret
253
254;--------------------------------------------------------------------
[48]255; .ReverseCopyCXbytesFromESSItoESDI
[47]256;   Parameters:
[48]257;       CX:     Number of bytes to copy
[47]258;       DS:     BDA segment (zero)
[48]259;       ES:SI:  Ptr to old location
260;       ES:DI:  Ptr to new location
[47]261;   Returns:
[48]262;       DI:     Updated to before last character copied
[47]263;   Corrupts registers:
264;       AX, CX, DX, SI
265;--------------------------------------------------------------------
[369]266ALIGN DISPLAY_JUMP_ALIGN
[48]267.ReverseCopyCXbytesFromESSItoESDI:
268    test    BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
269    jz      SHORT .CopyWithoutDisplayProcessing
[47]270
[48]271    WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
272    dec     di                  ; Point to preceeding character instead of attribute
273    ret
[369]274ALIGN DISPLAY_JUMP_ALIGN
[48]275.CopyWithoutDisplayProcessing:
[44]276    eSEG_STR rep, es, movsb
[47]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
[369]289ALIGN DISPLAY_JUMP_ALIGN
[47]290.ReversePrintAXspacesStartingFromESDI:
[44]291    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
292    xchg    cx, ax              ; CX = Spaces to prepend
293    mov     al, ' '
[47]294    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]295
296
297
298;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
299; Formatting functions
[41]300;   Parameters:
301;       DS:     BDA segment (zero)
[44]302;       SS:BP:  Pointer to next format parameter (-=2 updates to next parameter)
[41]303;       ES:DI:  Ptr to cursor location in video RAM
304;   Returns:
[44]305;       SS:BP:  Points to last WORD parameter used
[41]306;   Corrupts registers:
307;       AX, BX, DX
[44]308;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[134]309%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]310ALIGN DISPLAY_JUMP_ALIGN
[44]311a_FormatAttributeForNextCharacter:
[41]312    mov     bl, [bp]
313    xchg    bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
[44]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
[41]321    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
[44]322    ret
[134]323%endif
[41]324
[369]325ALIGN DISPLAY_JUMP_ALIGN
[44]326A_FormatAttributeForRemainingString:
[41]327    mov     al, [bp]
328    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
[44]329    ret
[41]330
[134]331%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]332ALIGN DISPLAY_JUMP_ALIGN
[44]333d_FormatSignedDecimalWord:
[41]334    mov     ax, [bp]
[44]335    mov     bx, 10
336    jmp     DisplayPrint_SignedWordFromAXWithBaseInBX
[134]337%endif
[41]338
[369]339ALIGN DISPLAY_JUMP_ALIGN
[44]340u_FormatUnsignedDecimalWord:
[41]341    mov     ax, [bp]
342    mov     bx, 10
[44]343    jmp     DisplayPrint_WordFromAXWithBaseInBX
[41]344
[369]345ALIGN DISPLAY_JUMP_ALIGN
[44]346x_FormatHexadecimalWord:
[41]347    mov     ax, [bp]
348    mov     bx, 16
349    call    DisplayPrint_WordFromAXWithBaseInBX
350    mov     al, 'h'
[44]351    jmp     DisplayPrint_CharacterFromAL
[41]352
[369]353ALIGN DISPLAY_JUMP_ALIGN
[184]354I_FormatDashForZero:
355    mov     ax, [bp]
356    test    ax,ax
[223]357    jnz     u_FormatUnsignedDecimalWord
[184]358    mov     [bp], word g_szDashForZero
359;;; fall-through
[223]360
[369]361ALIGN DISPLAY_JUMP_ALIGN
[44]362s_FormatStringFromSegmentCS:
[241]363    push    si
364    push    cx
365    mov     si, [bp]
[341]366
[241]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
[341]376
377.notFormatted:
[241]378    call    DisplayPrint_NullTerminatedStringFromCSSI
[341]379
[241]380.done:
381    pop     cx
382    pop     si
[341]383    ret
[241]384
[369]385ALIGN DISPLAY_JUMP_ALIGN
[341]386z_FormatStringFromSegmentZero:
[41]387    xchg    si, [bp]
[241]388    xor     bx, bx
389    call    DisplayPrint_NullTerminatedStringFromBXSI
[44]390    mov     si, [bp]
[341]391    ret
[41]392
[134]393%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]394ALIGN DISPLAY_JUMP_ALIGN
[44]395S_FormatStringFromFarPointer:
396    mov     bx, [bp-2]
[41]397    xchg    si, [bp]
398    call    DisplayPrint_NullTerminatedStringFromBXSI
[44]399    mov     si, [bp]
400    dec     bp
401    dec     bp
402    ret
[134]403%endif
[41]404
[369]405ALIGN DISPLAY_JUMP_ALIGN
[44]406c_FormatCharacter:
[41]407    mov     al, [bp]
[44]408    jmp     DisplayPrint_CharacterFromAL
[41]409
[134]410%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]411ALIGN DISPLAY_JUMP_ALIGN
[44]412t_FormatRepeatCharacter:
413    push    cx
[41]414    mov     cx, [bp-2]
415    mov     al, [bp]
416    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]417    pop     cx
418    dec     bp
419    dec     bp
420    ret
[41]421
[369]422ALIGN DISPLAY_JUMP_ALIGN
[44]423percent_FormatPercent:
[41]424    mov     al, '%'
[44]425    jmp     DisplayPrint_CharacterFromAL
[134]426%endif
[41]427
[369]428ALIGN DISPLAY_JUMP_ALIGN
[44]429PrepareToPrependParameterWithSpaces:
430    neg     cx
431    ; Fall to PrepareToAppendSpacesAfterParameter
[41]432
[369]433ALIGN DISPLAY_JUMP_ALIGN
[44]434PrepareToAppendSpacesAfterParameter:
435    add     sp, BYTE 2              ; Remove return offset
436    jmp     ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.