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

Last change on this file since 589 was 589, checked in by krille_n_, 8 years ago

Changes:

  • BIOS: Fixed a purely cosmetic bug from r542 where, in builds containing MODULE_EBIOS, the boot menu would display an incorrect drive size (0.4 kB with MODULE_STRINGS_COMPRESSED or 0.5 kB without) for old drives with no support for LBA.
  • Fixed a bug from r392 where Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent would return the ID in AL instead of AH (if DANGEROUS_DETECTION had been defined).
  • Fixed a bug from r587 in AdvAtaInit.asm that would prevent detection of QDI Vision controllers.
  • Also changed how the QDI Vision IDs are defined (removed the need for shifting) to avoid confusion. This fixed a potential bug from r587 in AdvAtaInit.asm where some IDs were not being shifted.
  • Fixed a bug in PDC20x30.asm from r587 where GetPdcIDtoAX would not return with the IDE base port in DX so DisablePdcProgrammingMode would fail.
  • Made some changes to ModuleDependency.inc and other files so that MODULE_ADVANCED_ATA now requires USE_386. Consequently it is no longer included in the regular AT-builds, only in the 386_8k-build.
  • Moved the UNROLL_SECTORS_IN_CX_TO_xWORDS macros from IDE_8bit.inc to IdeIO.inc which means it's now possible to build a BIOS without MODULE_8BIT_IDE.
  • XTIDECFG: Added a minimum DOS version check (since it needs DOS version 2+) to allow the program to quit gracefully in the unlikely scenario where someone tries to run it under DOS version 1.
  • Made some changes to Drive.asm to improve drive enumeration. The old method using GET_DOS_DRIVE_PARAMETER_BLOCK_FOR_SPECIFIC_DRIVE worked well in Windows XP but not in Windows 98 SE (in Windows or in DOS mode). The two problems were; 1) The function call would access the drives which on single floppy drive systems would cause Windows to swap between A: and B: (throwing a blue screen asking the user to insert a disk etc). 2) Only floppy drives and FAT16 drives would be available in the list of drives, no FAT32/optical/network drives.
  • Improved code in IdeControllerMenu.asm so that the default port addresses for all IDE interfaces are now restored when (re-)selecting the (same) type of IDE device.
  • Also made it impossible to select a device type unless the required module is included in the loaded BIOS.
  • The version check done when loading a BIOS now uses the FLASH_SIGNATURE definition from Version.inc. Any changes affecting RomVars now only requires updating that definition. This means that changes to RomVars must be implemented in both the BIOS and XTIDECFG before being committed to the repository.
  • Added a compatibility fix for 3Com 3C503 cards to the ROM checksumming code in Buffers.asm (Buffers_GenerateChecksum).
  • SerDrive: Made some minor changes to file names and paths to improve compatibility with case sensitive environments.
  • BIOSDRVS: Made a minor size optimization which as a side effect also makes it compatible with all DOS versions including DOS version 1.
  • Library: Renamed the WAIT_RETRACE_IF_NECESSARY_THEN macro to CALL_WAIT_FOR_RETRACE_IF_NECESSARY_THEN and made a tail-call-optimized version of it (JMP_WAIT_FOR_RETRACE_IF_NECESSARY_THEN).
  • A speed optimization to the eRCL_IM macro for 386 and higher. This change breaks emulation in the sense that the macro will fail when given a memory operand as the first parameter.
  • Other minor optimizations and fixes.
File size: 12.4 KB
RevLine 
[41]1; Project name  :   Assembly Library
2; Description   :   Functions for displaying formatted strings.
3
[376]4;
[445]5; XTIDE Universal BIOS and Associated Tools
[526]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]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.
[445]12;
[376]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
[445]16; GNU General Public License for more details.
[376]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[445]18;
[376]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
[445]139    eSHL_IM bx, 1               ; Shift for WORD lookup
[44]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
[589]271    CALL_WAIT_FOR_RETRACE_IF_NECESSARY_THEN rep movsb
[48]272    dec     di                  ; Point to preceeding character instead of attribute
273    ret
[589]274
[369]275ALIGN DISPLAY_JUMP_ALIGN
[48]276.CopyWithoutDisplayProcessing:
[44]277    eSEG_STR rep, es, movsb
[47]278    ret
279
280;--------------------------------------------------------------------
281; .ReversePrintAXspacesStartingFromESDI
282;   Parameters:
283;       AX:     Number of spaces to print
284;       DS:     BDA segment (zero)
285;       ES:DI:  Ptr to destination in video RAM
286;   Returns:
287;       DI:     Updated
288;   Corrupts registers:
289;       AX, CX, DX
[369]290ALIGN DISPLAY_JUMP_ALIGN
[47]291.ReversePrintAXspacesStartingFromESDI:
[44]292    call    DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
293    xchg    cx, ax              ; CX = Spaces to prepend
294    mov     al, ' '
[47]295    jmp     DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]296
297
298
299;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
300; Formatting functions
[41]301;   Parameters:
302;       DS:     BDA segment (zero)
[44]303;       SS:BP:  Pointer to next format parameter (-=2 updates to next parameter)
[41]304;       ES:DI:  Ptr to cursor location in video RAM
305;   Returns:
[44]306;       SS:BP:  Points to last WORD parameter used
[41]307;   Corrupts registers:
308;       AX, BX, DX
[44]309;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[134]310%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]311ALIGN DISPLAY_JUMP_ALIGN
[44]312a_FormatAttributeForNextCharacter:
[41]313    mov     bl, [bp]
314    xchg    bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
[44]315    push    bx
316    push    cx
317    push    di
318    call    DisplayFormat_ParseCharacters   ; Recursive call
319    pop     WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
320    pop     cx
321    pop     bx
[41]322    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
[44]323    ret
[134]324%endif
[41]325
[369]326ALIGN DISPLAY_JUMP_ALIGN
[44]327A_FormatAttributeForRemainingString:
[41]328    mov     al, [bp]
329    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
[44]330    ret
[41]331
[134]332%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]333ALIGN DISPLAY_JUMP_ALIGN
[44]334d_FormatSignedDecimalWord:
[41]335    mov     ax, [bp]
[44]336    mov     bx, 10
337    jmp     DisplayPrint_SignedWordFromAXWithBaseInBX
[134]338%endif
[41]339
[369]340ALIGN DISPLAY_JUMP_ALIGN
[44]341u_FormatUnsignedDecimalWord:
[41]342    mov     ax, [bp]
343    mov     bx, 10
[44]344    jmp     DisplayPrint_WordFromAXWithBaseInBX
[41]345
[369]346ALIGN DISPLAY_JUMP_ALIGN
[44]347x_FormatHexadecimalWord:
[41]348    mov     ax, [bp]
349    mov     bx, 16
350    call    DisplayPrint_WordFromAXWithBaseInBX
351    mov     al, 'h'
[44]352    jmp     DisplayPrint_CharacterFromAL
[41]353
[369]354ALIGN DISPLAY_JUMP_ALIGN
[184]355I_FormatDashForZero:
356    mov     ax, [bp]
357    test    ax,ax
[223]358    jnz     u_FormatUnsignedDecimalWord
[184]359    mov     [bp], word g_szDashForZero
360;;; fall-through
[223]361
[369]362ALIGN DISPLAY_JUMP_ALIGN
[44]363s_FormatStringFromSegmentCS:
[241]364    push    si
365    push    cx
366    mov     si, [bp]
[341]367
[241]368    cmp     si, byte 07fh       ;  well within the boundaries of ROMVARS_size
369    jb      .notFormatted
370
371    dec     bp
372    dec     bp
373    call    DisplayFormat_ParseCharacters
374    inc     bp                  ; will be decremented after the call is done
375    inc     bp
376    jmp     .done
[341]377
378.notFormatted:
[241]379    call    DisplayPrint_NullTerminatedStringFromCSSI
[341]380
[241]381.done:
382    pop     cx
383    pop     si
[341]384    ret
[241]385
[369]386ALIGN DISPLAY_JUMP_ALIGN
[341]387z_FormatStringFromSegmentZero:
[41]388    xchg    si, [bp]
[241]389    xor     bx, bx
390    call    DisplayPrint_NullTerminatedStringFromBXSI
[44]391    mov     si, [bp]
[341]392    ret
[41]393
[134]394%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]395ALIGN DISPLAY_JUMP_ALIGN
[44]396S_FormatStringFromFarPointer:
397    mov     bx, [bp-2]
[41]398    xchg    si, [bp]
399    call    DisplayPrint_NullTerminatedStringFromBXSI
[44]400    mov     si, [bp]
401    dec     bp
402    dec     bp
403    ret
[134]404%endif
[41]405
[369]406ALIGN DISPLAY_JUMP_ALIGN
[44]407c_FormatCharacter:
[41]408    mov     al, [bp]
[44]409    jmp     DisplayPrint_CharacterFromAL
[41]410
[134]411%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]412ALIGN DISPLAY_JUMP_ALIGN
[44]413t_FormatRepeatCharacter:
414    push    cx
[41]415    mov     cx, [bp-2]
416    mov     al, [bp]
417    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]418    pop     cx
419    dec     bp
420    dec     bp
421    ret
[41]422
[369]423ALIGN DISPLAY_JUMP_ALIGN
[44]424percent_FormatPercent:
[41]425    mov     al, '%'
[44]426    jmp     DisplayPrint_CharacterFromAL
[134]427%endif
[41]428
[369]429ALIGN DISPLAY_JUMP_ALIGN
[44]430PrepareToPrependParameterWithSpaces:
431    neg     cx
432    ; Fall to PrepareToAppendSpacesAfterParameter
[41]433
[369]434ALIGN DISPLAY_JUMP_ALIGN
[44]435PrepareToAppendSpacesAfterParameter:
436    add     sp, BYTE 2              ; Remove return offset
437    jmp     ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.