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

Last change on this file since 107 was 101, checked in by Tomi Tilli, 14 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.