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

Last change on this file since 624 was 624, checked in by Krister Nordvall, 2 years ago

Changes:

  • The BIOS version string has been changed to show the repository revision number instead of the useless "v2.0.0 beta 3+" string. In other words, the seemingly never ending beta is finally over! The version string is now updated by TortoiseSVN client side hook scripts (residing in \Tools) to be used when committing changes to the repository. It should also be possible to use these scripts with other subversion clients under Windows since they are essentially just regular batch (cmd) files!
  • The eSEG_STR macro has been changed to always disable interrupts. The workaround used for the buggy, early revisions of the 8088/8086 CPUs apparently does not work. Many thanks to Jim Leonard (Trixter) for reporting this problem!
  • Minor optimizations to the eBSF and eBSR macros.
File size: 12.3 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:
[592]144%ifndef EXCLUDE_FROM_XUB
[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:
[592]152%ifndef EXCLUDE_FROM_XUB
[44]153 dw a_FormatAttributeForNextCharacter
[134]154%endif
[184]155 dw I_FormatDashForZero
[44]156 dw A_FormatAttributeForRemainingString
[592]157%ifndef EXCLUDE_FROM_XUB
[44]158 dw d_FormatSignedDecimalWord
[134]159%endif
[44]160 dw u_FormatUnsignedDecimalWord
161 dw x_FormatHexadecimalWord
162 dw s_FormatStringFromSegmentCS
[592]163%ifndef EXCLUDE_FROM_XUB
[44]164 dw S_FormatStringFromFarPointer
[134]165%endif
[44]166 dw c_FormatCharacter
[592]167%ifndef EXCLUDE_FROM_XUB
[44]168 dw t_FormatRepeatCharacter
[134]169%endif
[241]170 dw z_FormatStringFromSegmentZero
[44]171 dw PrepareToPrependParameterWithSpaces
[592]172%ifndef EXCLUDE_FROM_XUB
[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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[592]310%ifndef EXCLUDE_FROM_XUB
[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
[592]332%ifndef EXCLUDE_FROM_XUB
[369]333ALIGN DISPLAY_JUMP_ALIGN
[44]334d_FormatSignedDecimalWord:
[41]335 mov ax, [bp]
[590]336 mov bl, 10
337 jmp DisplayPrint_SignedWordFromAXWithBaseInBL
[134]338%endif
[41]339
[369]340ALIGN DISPLAY_JUMP_ALIGN
[44]341u_FormatUnsignedDecimalWord:
[41]342 mov ax, [bp]
[590]343 mov bl, 10
344 jmp DisplayPrint_WordFromAXWithBaseInBL
[41]345
[369]346ALIGN DISPLAY_JUMP_ALIGN
[44]347x_FormatHexadecimalWord:
[41]348 mov ax, [bp]
[590]349 mov bl, 16
350 call DisplayPrint_WordFromAXWithBaseInBL
[41]351 mov al, 'h'
[44]352 jmp DisplayPrint_CharacterFromAL
[41]353
[369]354ALIGN DISPLAY_JUMP_ALIGN
[184]355I_FormatDashForZero:
[590]356 cmp WORD [bp], 0
357 jne SHORT u_FormatUnsignedDecimalWord
358 mov WORD [bp], g_szDashForZero
[184]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
[590]367 cmp si, BYTE 7Fh ; well within the boundaries of ROMVARS_size
[624]368 jb SHORT .notFormatted
[241]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
[624]375 jmp SHORT .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
[592]393%ifndef EXCLUDE_FROM_XUB
[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
[592]410%ifndef EXCLUDE_FROM_XUB
[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.