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

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

Space optimizations in the Boot Menu and BootInfo routines, taking advantage of nested %s. Optimization in the init of RamVars to avoid writing the signature twice. Preparing for addition of serial floppy support, starting to break the assumption that our drives are always 80h or higher.

File size: 11.5 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
[181]54    inc     cx
55    loop    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:
[223]94    cs lodsb                                ; Load from CS:SI to AL
[41]95    test    al, al                          ; NULL to end string?
96    ret
97
98
99;--------------------------------------------------------------------
[44]100; GetFormatSpecifierParserToAX
[41]101;   Parameters:
[44]102;       AL:     Format specifier character
[41]103;   Returns:
[44]104;       AX:     Offset to parser function
[41]105;   Corrupts registers:
[44]106;       AX, BX
[41]107;--------------------------------------------------------------------
108ALIGN JUMP_ALIGN
[44]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
[41]126
[44]127.rgcFormatCharToLookupIndex:
[134]128%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[241]129    db      "aIAduxsSctz-+%"
[134]130%else
[241]131    db      "IAuxscz-"      ; Required by XTIDE Universal BIOS
[134]132%endif
[44]133.rgcFormatCharToLookupIndexEnd:
134ALIGN WORD_ALIGN
135.rgfnFormatSpecifierParser:
[134]136%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]137    dw      a_FormatAttributeForNextCharacter
[134]138%endif
[184]139    dw      I_FormatDashForZero
[44]140    dw      A_FormatAttributeForRemainingString
[134]141%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]142    dw      d_FormatSignedDecimalWord
[134]143%endif
[44]144    dw      u_FormatUnsignedDecimalWord
145    dw      x_FormatHexadecimalWord
146    dw      s_FormatStringFromSegmentCS
[134]147%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]148    dw      S_FormatStringFromFarPointer
[134]149%endif
[44]150    dw      c_FormatCharacter
[134]151%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]152    dw      t_FormatRepeatCharacter
[134]153%endif
[241]154    dw      z_FormatStringFromSegmentZero
[44]155    dw      PrepareToPrependParameterWithSpaces
[134]156%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]157    dw      PrepareToAppendSpacesAfterParameter
158    dw      percent_FormatPercent
[134]159%endif
[41]160
[44]161
[41]162;--------------------------------------------------------------------
[44]163; PrependOrAppendSpaces
[41]164;   Parameters:
[44]165;       CX:     Minimum length for format specifier in characters
[41]166;       DS:     BDA segment (zero)
167;       ES:DI:  Ptr to cursor location in video RAM
168;   Returns:
[44]169;       Nothing
[41]170;   Corrupts registers:
171;       AX, BX, CX, DX
172;--------------------------------------------------------------------
173ALIGN JUMP_ALIGN
[44]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
[41]180
181;--------------------------------------------------------------------
[44]182; .AppendSpaces
[41]183;   Parameters:
[44]184;       AX:     Number of format parameter BYTEs printed
185;       CX:     Minimum length for format specifier in characters
[41]186;       DS:     BDA segment (zero)
187;       ES:DI:  Ptr to cursor location in video RAM
188;   Returns:
[44]189;       Nothing
[41]190;   Corrupts registers:
[44]191;       AX, CX, DX
[41]192;--------------------------------------------------------------------
[44]193.AppendSpaces:
194    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
195    sub     cx, ax
196    jle     SHORT .NothingToAppendOrPrepend
[41]197    mov     al, ' '
[44]198    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
[41]199
200;--------------------------------------------------------------------
[44]201; .PrependWithSpaces
[41]202;   Parameters:
[44]203;       AX:     Number of format parameter BYTEs printed
204;       CX:     Negative minimum length for format specifier in characters
[41]205;       DS:     BDA segment (zero)
206;       ES:DI:  Ptr to cursor location in video RAM
207;   Returns:
[44]208;       Nothing
[41]209;   Corrupts registers:
[44]210;       AX, BX, CX, DX
[41]211;--------------------------------------------------------------------
212ALIGN JUMP_ALIGN
[44]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
[41]219
[47]220    std
221    push    si
[41]222
[47]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
[48]228    call    .ReverseCopyCXbytesFromESSItoESDI
[47]229    xchg    ax, bx
230    call    .ReversePrintAXspacesStartingFromESDI
231
232    pop     di
233    pop     si
234    cld                         ; Restore DF
235.NothingToAppendOrPrepend:
236    ret
237
238;--------------------------------------------------------------------
[48]239; .ReverseCopyCXbytesFromESSItoESDI
[47]240;   Parameters:
[48]241;       CX:     Number of bytes to copy
[47]242;       DS:     BDA segment (zero)
[48]243;       ES:SI:  Ptr to old location
244;       ES:DI:  Ptr to new location
[47]245;   Returns:
[48]246;       DI:     Updated to before last character copied
[47]247;   Corrupts registers:
248;       AX, CX, DX, SI
249;--------------------------------------------------------------------
250ALIGN JUMP_ALIGN
[48]251.ReverseCopyCXbytesFromESSItoESDI:
252    test    BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
253    jz      SHORT .CopyWithoutDisplayProcessing
[47]254
[48]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:
[44]260    eSEG_STR rep, es, movsb
[47]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:
[44]275    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
276    xchg    cx, ax              ; CX = Spaces to prepend
277    mov     al, ' '
[47]278    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]279
280
281
282;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
283; Formatting functions
[41]284;   Parameters:
285;       DS:     BDA segment (zero)
[44]286;       SS:BP:  Pointer to next format parameter (-=2 updates to next parameter)
[41]287;       ES:DI:  Ptr to cursor location in video RAM
288;   Returns:
[44]289;       SS:BP:  Points to last WORD parameter used
[41]290;   Corrupts registers:
291;       AX, BX, DX
[44]292;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[134]293%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]294ALIGN JUMP_ALIGN
[44]295a_FormatAttributeForNextCharacter:
[41]296    mov     bl, [bp]
297    xchg    bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
[44]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
[41]305    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
[44]306    ret
[134]307%endif
[41]308
309ALIGN JUMP_ALIGN
[44]310A_FormatAttributeForRemainingString:
[41]311    mov     al, [bp]
312    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
[44]313    ret
[41]314
[134]315%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]316ALIGN JUMP_ALIGN
[44]317d_FormatSignedDecimalWord:
[41]318    mov     ax, [bp]
[44]319    mov     bx, 10
320    jmp     DisplayPrint_SignedWordFromAXWithBaseInBX
[134]321%endif
[41]322
[223]323ALIGN JUMP_ALIGN
[44]324u_FormatUnsignedDecimalWord:
[41]325    mov     ax, [bp]
326    mov     bx, 10
[44]327    jmp     DisplayPrint_WordFromAXWithBaseInBX
[41]328
329ALIGN JUMP_ALIGN
[44]330x_FormatHexadecimalWord:
[41]331    mov     ax, [bp]
332    mov     bx, 16
333    call    DisplayPrint_WordFromAXWithBaseInBX
334    mov     al, 'h'
[44]335    jmp     DisplayPrint_CharacterFromAL
[41]336
337ALIGN JUMP_ALIGN
[184]338I_FormatDashForZero:
339    mov     ax, [bp]
340    test    ax,ax
[223]341    jnz     u_FormatUnsignedDecimalWord
[184]342    mov     [bp], word g_szDashForZero
343;;; fall-through
[223]344
[184]345ALIGN JUMP_ALIGN
[44]346s_FormatStringFromSegmentCS:
[241]347    push    si
348    push    cx
349    mov     si, [bp]
350       
351    cmp     si, byte 07fh       ;  well within the boundaries of ROMVARS_size
352    jb      .notFormatted
353
354    dec     bp
355    dec     bp
356    call    DisplayFormat_ParseCharacters
357    inc     bp                  ; will be decremented after the call is done
358    inc     bp
359    jmp     .done
360       
361.notFormatted: 
362    call    DisplayPrint_NullTerminatedStringFromCSSI
363       
364.done:
365    pop     cx
366    pop     si
367    ret     
368
369ALIGN JUMP_ALIGN
370z_FormatStringFromSegmentZero: 
[41]371    xchg    si, [bp]
[241]372    xor     bx, bx
373    call    DisplayPrint_NullTerminatedStringFromBXSI
[44]374    mov     si, [bp]
[241]375    ret     
[41]376
[134]377%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]378ALIGN JUMP_ALIGN
[44]379S_FormatStringFromFarPointer:
380    mov     bx, [bp-2]
[41]381    xchg    si, [bp]
382    call    DisplayPrint_NullTerminatedStringFromBXSI
[44]383    mov     si, [bp]
384    dec     bp
385    dec     bp
386    ret
[134]387%endif
[41]388
389ALIGN JUMP_ALIGN
[44]390c_FormatCharacter:
[41]391    mov     al, [bp]
[44]392    jmp     DisplayPrint_CharacterFromAL
[41]393
[134]394%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]395ALIGN JUMP_ALIGN
[44]396t_FormatRepeatCharacter:
397    push    cx
[41]398    mov     cx, [bp-2]
399    mov     al, [bp]
400    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]401    pop     cx
402    dec     bp
403    dec     bp
404    ret
[41]405
406ALIGN JUMP_ALIGN
[44]407percent_FormatPercent:
[41]408    mov     al, '%'
[44]409    jmp     DisplayPrint_CharacterFromAL
[134]410%endif
[41]411
412ALIGN JUMP_ALIGN
[44]413PrepareToPrependParameterWithSpaces:
414    neg     cx
415    ; Fall to PrepareToAppendSpacesAfterParameter
[41]416
417ALIGN JUMP_ALIGN
[44]418PrepareToAppendSpacesAfterParameter:
419    add     sp, BYTE 2              ; Remove return offset
420    jmp     ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.