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

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

Changes:

  • A speed optimization to the eSHL_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.
  • Memory_SumCXbytesFromESSItoAL now returns with the zero flag set/cleared according to the result.
  • Unrolled all the 8 bit READ transfer loops to do 16 bytes per iteration. Added a new macro (UNROLL_SECTORS_IN_CX_TO_OWORDS) as part of it. Size wise this is expensive but I think it should be worth the ROM space. The WRITE transfer loops were left as is since writes are rare anyway (<10% of all disk I/O IIRC).
  • Minor optimizations and fixes here and there.
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
[376]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.
[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
[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.