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

Last change on this file since 133 was 101, checked in by aitotat, 13 years ago

Changes to Assembly Library:

  • Some minor size optimizations to Display Library.
File size: 10.3 KB
RevLine 
[41]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)
[44]11;       SS:BP:  Pointer to first format parameter (-=2 updates to next parameter)
[41]12;       CS:SI:  Pointer to string to format
13;       ES:DI:  Ptr to cursor location in video RAM
14;   Returns:
[44]15;       CS:SI:  Ptr to end of format string (ptr to one past NULL)
[41]16;       DI:     Updated offset to video RAM
17;   Corrupts registers:
[44]18;       AX, BX, CX, DX, BP
[41]19;--------------------------------------------------------------------
20ALIGN JUMP_ALIGN
21DisplayFormat_ParseCharacters:
[44]22    call    ReadCharacterAndTestForNull
[101]23    jz      SHORT ReturnFromFormat
[44]24
25    ePUSH_T cx, DisplayFormat_ParseCharacters   ; Return address
26    xor     cx, cx                              ; Initial placeholder size
27    cmp     al, '%'                             ; Format specifier?
[101]28    jne     SHORT DisplayPrint_CharacterFromAL
29    ; Fall to ParseFormatSpecifier
[44]30
[41]31;--------------------------------------------------------------------
[44]32; ParseFormatSpecifier
[41]33;   Parameters:
[44]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
[101]49    jc      SHORT ParsePlaceholderSizeDigitFromALtoCX
[44]50    call    GetFormatSpecifierParserToAX
51    call    ax              ; Parser function
52    dec     bp
53    dec     bp              ; SS:BP now points to next parameter
54    test    cx, cx
55    jnz     SHORT PrependOrAppendSpaces
[101]56ReturnFromFormat:
[44]57    ret
58
59;--------------------------------------------------------------------
[101]60; ParsePlaceholderSizeDigitFromALtoCX
[44]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
[101]72ParsePlaceholderSizeDigitFromALtoCX:
[44]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:
[41]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
[44]93ReadCharacterAndTestForNull:
[41]94    eSEG    cs
95    lodsb                                   ; Load from CS:SI to AL
96    test    al, al                          ; NULL to end string?
97    ret
98
99
100;--------------------------------------------------------------------
[44]101; GetFormatSpecifierParserToAX
[41]102;   Parameters:
[44]103;       AL:     Format specifier character
[41]104;   Returns:
[44]105;       AX:     Offset to parser function
[41]106;   Corrupts registers:
[44]107;       AX, BX
[41]108;--------------------------------------------------------------------
109ALIGN JUMP_ALIGN
[44]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
[41]127
[44]128.rgcFormatCharToLookupIndex:
129    db      "aAduxsSct-+%"
130.rgcFormatCharToLookupIndexEnd:
131ALIGN WORD_ALIGN
132.rgfnFormatSpecifierParser:
133    dw      a_FormatAttributeForNextCharacter
134    dw      A_FormatAttributeForRemainingString
135    dw      d_FormatSignedDecimalWord
136    dw      u_FormatUnsignedDecimalWord
137    dw      x_FormatHexadecimalWord
138    dw      s_FormatStringFromSegmentCS
139    dw      S_FormatStringFromFarPointer
140    dw      c_FormatCharacter
141    dw      t_FormatRepeatCharacter
142    dw      PrepareToPrependParameterWithSpaces
143    dw      PrepareToAppendSpacesAfterParameter
144    dw      percent_FormatPercent
[41]145
[44]146
[41]147;--------------------------------------------------------------------
[44]148; PrependOrAppendSpaces
[41]149;   Parameters:
[44]150;       CX:     Minimum length for format specifier in characters
[41]151;       DS:     BDA segment (zero)
152;       ES:DI:  Ptr to cursor location in video RAM
153;   Returns:
[44]154;       Nothing
[41]155;   Corrupts registers:
156;       AX, BX, CX, DX
157;--------------------------------------------------------------------
158ALIGN JUMP_ALIGN
[44]159PrependOrAppendSpaces:
160    mov     ax, di
161    sub     ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
162    test    cx, cx
163    js      SHORT .PrependWithSpaces
164    ; Fall to .AppendSpaces
[41]165
166;--------------------------------------------------------------------
[44]167; .AppendSpaces
[41]168;   Parameters:
[44]169;       AX:     Number of format parameter BYTEs printed
170;       CX:     Minimum length for format specifier in characters
[41]171;       DS:     BDA segment (zero)
172;       ES:DI:  Ptr to cursor location in video RAM
173;   Returns:
[44]174;       Nothing
[41]175;   Corrupts registers:
[44]176;       AX, CX, DX
[41]177;--------------------------------------------------------------------
[44]178.AppendSpaces:
179    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
180    sub     cx, ax
181    jle     SHORT .NothingToAppendOrPrepend
[41]182    mov     al, ' '
[44]183    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
[41]184
185;--------------------------------------------------------------------
[44]186; .PrependWithSpaces
[41]187;   Parameters:
[44]188;       AX:     Number of format parameter BYTEs printed
189;       CX:     Negative minimum length for format specifier in characters
[41]190;       DS:     BDA segment (zero)
191;       ES:DI:  Ptr to cursor location in video RAM
192;   Returns:
[44]193;       Nothing
[41]194;   Corrupts registers:
[44]195;       AX, BX, CX, DX
[41]196;--------------------------------------------------------------------
197ALIGN JUMP_ALIGN
[44]198.PrependWithSpaces:
199    xchg    ax, cx
200    neg     ax
201    call    DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
202    sub     ax, cx              ; AX = BYTEs to prepend, CX = BYTEs to move
203    jle     SHORT .NothingToAppendOrPrepend
[41]204
[47]205    std
206    push    si
[41]207
[47]208    lea     si, [di-1]          ; SI = Offset to last byte formatted
209    add     di, ax              ; DI = Cursor location after preceeding completed
210    push    di
211    dec     di                  ; DI = Offset where to move last byte formatted
212    xchg    bx, ax              ; BX = BYTEs to prepend
[48]213    call    .ReverseCopyCXbytesFromESSItoESDI
[47]214    xchg    ax, bx
215    call    .ReversePrintAXspacesStartingFromESDI
216
217    pop     di
218    pop     si
219    cld                         ; Restore DF
220.NothingToAppendOrPrepend:
221    ret
222
223;--------------------------------------------------------------------
[48]224; .ReverseCopyCXbytesFromESSItoESDI
[47]225;   Parameters:
[48]226;       CX:     Number of bytes to copy
[47]227;       DS:     BDA segment (zero)
[48]228;       ES:SI:  Ptr to old location
229;       ES:DI:  Ptr to new location
[47]230;   Returns:
[48]231;       DI:     Updated to before last character copied
[47]232;   Corrupts registers:
233;       AX, CX, DX, SI
234;--------------------------------------------------------------------
235ALIGN JUMP_ALIGN
[48]236.ReverseCopyCXbytesFromESSItoESDI:
237    test    BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
238    jz      SHORT .CopyWithoutDisplayProcessing
[47]239
[48]240    WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
241    dec     di                  ; Point to preceeding character instead of attribute
242    ret
243ALIGN JUMP_ALIGN
244.CopyWithoutDisplayProcessing:
[44]245    eSEG_STR rep, es, movsb
[47]246    ret
247
248;--------------------------------------------------------------------
249; .ReversePrintAXspacesStartingFromESDI
250;   Parameters:
251;       AX:     Number of spaces to print
252;       DS:     BDA segment (zero)
253;       ES:DI:  Ptr to destination in video RAM
254;   Returns:
255;       DI:     Updated
256;   Corrupts registers:
257;       AX, CX, DX
258ALIGN JUMP_ALIGN
259.ReversePrintAXspacesStartingFromESDI:
[44]260    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
261    xchg    cx, ax              ; CX = Spaces to prepend
262    mov     al, ' '
[47]263    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]264
265
266
267;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
268; Formatting functions
[41]269;   Parameters:
270;       DS:     BDA segment (zero)
[44]271;       SS:BP:  Pointer to next format parameter (-=2 updates to next parameter)
[41]272;       ES:DI:  Ptr to cursor location in video RAM
273;   Returns:
[44]274;       SS:BP:  Points to last WORD parameter used
[41]275;   Corrupts registers:
276;       AX, BX, DX
[44]277;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[41]278ALIGN JUMP_ALIGN
[44]279a_FormatAttributeForNextCharacter:
[41]280    mov     bl, [bp]
281    xchg    bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
[44]282    push    bx
283    push    cx
284    push    di
285    call    DisplayFormat_ParseCharacters   ; Recursive call
286    pop     WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
287    pop     cx
288    pop     bx
[41]289    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
[44]290    ret
[41]291
292ALIGN JUMP_ALIGN
[44]293A_FormatAttributeForRemainingString:
[41]294    mov     al, [bp]
295    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
[44]296    ret
[41]297
298ALIGN JUMP_ALIGN
[44]299d_FormatSignedDecimalWord:
[41]300    mov     ax, [bp]
[44]301    mov     bx, 10
302    jmp     DisplayPrint_SignedWordFromAXWithBaseInBX
[41]303
304ALIGN JUMP_ALIGN
[44]305u_FormatUnsignedDecimalWord:
[41]306    mov     ax, [bp]
307    mov     bx, 10
[44]308    jmp     DisplayPrint_WordFromAXWithBaseInBX
[41]309
310ALIGN JUMP_ALIGN
[44]311x_FormatHexadecimalWord:
[41]312    mov     ax, [bp]
313    mov     bx, 16
314    call    DisplayPrint_WordFromAXWithBaseInBX
315    mov     al, 'h'
[44]316    jmp     DisplayPrint_CharacterFromAL
[41]317
318ALIGN JUMP_ALIGN
[44]319s_FormatStringFromSegmentCS:
[41]320    xchg    si, [bp]
321    call    DisplayPrint_NullTerminatedStringFromCSSI
[44]322    mov     si, [bp]
323    ret
[41]324
325ALIGN JUMP_ALIGN
[44]326S_FormatStringFromFarPointer:
327    mov     bx, [bp-2]
[41]328    xchg    si, [bp]
329    call    DisplayPrint_NullTerminatedStringFromBXSI
[44]330    mov     si, [bp]
331    dec     bp
332    dec     bp
333    ret
[41]334
335ALIGN JUMP_ALIGN
[44]336c_FormatCharacter:
[41]337    mov     al, [bp]
[44]338    jmp     DisplayPrint_CharacterFromAL
[41]339
340ALIGN JUMP_ALIGN
[44]341t_FormatRepeatCharacter:
342    push    cx
[41]343    mov     cx, [bp-2]
344    mov     al, [bp]
345    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]346    pop     cx
347    dec     bp
348    dec     bp
349    ret
[41]350
351ALIGN JUMP_ALIGN
[44]352percent_FormatPercent:
[41]353    mov     al, '%'
[44]354    jmp     DisplayPrint_CharacterFromAL
[41]355
356ALIGN JUMP_ALIGN
[44]357PrepareToPrependParameterWithSpaces:
358    neg     cx
359    ; Fall to PrepareToAppendSpacesAfterParameter
[41]360
361ALIGN JUMP_ALIGN
[44]362PrepareToAppendSpacesAfterParameter:
363    add     sp, BYTE 2              ; Remove return offset
364    jmp     ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.