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

Last change on this file since 234 was 223, checked in by krille_n_@…, 13 years ago

Changes:

  • Fixed what appears to be a mistake in EBIOS.inc
  • Added a 'release' option to the makefile of the Serial Server (invokes UPX)
  • Some very minor optimizations
  • Removed the eSEG macro and did some other cleanups (fixed typos etc)
File size: 11.1 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
[184]129 db "aIAduxsSct-+%"
[134]130%else
[184]131 db "IAuxsc-" ; 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
[44]154 dw PrepareToPrependParameterWithSpaces
[134]155%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[44]156 dw PrepareToAppendSpacesAfterParameter
157 dw percent_FormatPercent
[134]158%endif
[41]159
[44]160
[41]161;--------------------------------------------------------------------
[44]162; PrependOrAppendSpaces
[41]163; Parameters:
[44]164; CX: Minimum length for format specifier in characters
[41]165; DS: BDA segment (zero)
166; ES:DI: Ptr to cursor location in video RAM
167; Returns:
[44]168; Nothing
[41]169; Corrupts registers:
170; AX, BX, CX, DX
171;--------------------------------------------------------------------
172ALIGN JUMP_ALIGN
[44]173PrependOrAppendSpaces:
174 mov ax, di
175 sub ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
176 test cx, cx
177 js SHORT .PrependWithSpaces
178 ; Fall to .AppendSpaces
[41]179
180;--------------------------------------------------------------------
[44]181; .AppendSpaces
[41]182; Parameters:
[44]183; AX: Number of format parameter BYTEs printed
184; CX: Minimum length for format specifier in characters
[41]185; DS: BDA segment (zero)
186; ES:DI: Ptr to cursor location in video RAM
187; Returns:
[44]188; Nothing
[41]189; Corrupts registers:
[44]190; AX, CX, DX
[41]191;--------------------------------------------------------------------
[44]192.AppendSpaces:
193 call DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
194 sub cx, ax
195 jle SHORT .NothingToAppendOrPrepend
[41]196 mov al, ' '
[44]197 jmp DisplayPrint_RepeatCharacterFromALwithCountInCX
[41]198
199;--------------------------------------------------------------------
[44]200; .PrependWithSpaces
[41]201; Parameters:
[44]202; AX: Number of format parameter BYTEs printed
203; CX: Negative minimum length for format specifier in characters
[41]204; DS: BDA segment (zero)
205; ES:DI: Ptr to cursor location in video RAM
206; Returns:
[44]207; Nothing
[41]208; Corrupts registers:
[44]209; AX, BX, CX, DX
[41]210;--------------------------------------------------------------------
211ALIGN JUMP_ALIGN
[44]212.PrependWithSpaces:
213 xchg ax, cx
214 neg ax
215 call DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
216 sub ax, cx ; AX = BYTEs to prepend, CX = BYTEs to move
217 jle SHORT .NothingToAppendOrPrepend
[41]218
[47]219 std
220 push si
[41]221
[47]222 lea si, [di-1] ; SI = Offset to last byte formatted
223 add di, ax ; DI = Cursor location after preceeding completed
224 push di
225 dec di ; DI = Offset where to move last byte formatted
226 xchg bx, ax ; BX = BYTEs to prepend
[48]227 call .ReverseCopyCXbytesFromESSItoESDI
[47]228 xchg ax, bx
229 call .ReversePrintAXspacesStartingFromESDI
230
231 pop di
232 pop si
233 cld ; Restore DF
234.NothingToAppendOrPrepend:
235 ret
236
237;--------------------------------------------------------------------
[48]238; .ReverseCopyCXbytesFromESSItoESDI
[47]239; Parameters:
[48]240; CX: Number of bytes to copy
[47]241; DS: BDA segment (zero)
[48]242; ES:SI: Ptr to old location
243; ES:DI: Ptr to new location
[47]244; Returns:
[48]245; DI: Updated to before last character copied
[47]246; Corrupts registers:
247; AX, CX, DX, SI
248;--------------------------------------------------------------------
249ALIGN JUMP_ALIGN
[48]250.ReverseCopyCXbytesFromESSItoESDI:
251 test BYTE [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags], FLG_CONTEXT_ATTRIBUTES
252 jz SHORT .CopyWithoutDisplayProcessing
[47]253
[48]254 WAIT_RETRACE_IF_NECESSARY_THEN rep movsb
255 dec di ; Point to preceeding character instead of attribute
256 ret
257ALIGN JUMP_ALIGN
258.CopyWithoutDisplayProcessing:
[44]259 eSEG_STR rep, es, movsb
[47]260 ret
261
262;--------------------------------------------------------------------
263; .ReversePrintAXspacesStartingFromESDI
264; Parameters:
265; AX: Number of spaces to print
266; DS: BDA segment (zero)
267; ES:DI: Ptr to destination in video RAM
268; Returns:
269; DI: Updated
270; Corrupts registers:
271; AX, CX, DX
272ALIGN JUMP_ALIGN
273.ReversePrintAXspacesStartingFromESDI:
[44]274 call DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
275 xchg cx, ax ; CX = Spaces to prepend
276 mov al, ' '
[47]277 jmp DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]278
279
280
281;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
282; Formatting functions
[41]283; Parameters:
284; DS: BDA segment (zero)
[44]285; SS:BP: Pointer to next format parameter (-=2 updates to next parameter)
[41]286; ES:DI: Ptr to cursor location in video RAM
287; Returns:
[44]288; SS:BP: Points to last WORD parameter used
[41]289; Corrupts registers:
290; AX, BX, DX
[44]291;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[134]292%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]293ALIGN JUMP_ALIGN
[44]294a_FormatAttributeForNextCharacter:
[41]295 mov bl, [bp]
296 xchg bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
[44]297 push bx
298 push cx
299 push di
300 call DisplayFormat_ParseCharacters ; Recursive call
301 pop WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
302 pop cx
303 pop bx
[41]304 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
[44]305 ret
[134]306%endif
[41]307
308ALIGN JUMP_ALIGN
[44]309A_FormatAttributeForRemainingString:
[41]310 mov al, [bp]
311 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
[44]312 ret
[41]313
[134]314%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]315ALIGN JUMP_ALIGN
[44]316d_FormatSignedDecimalWord:
[41]317 mov ax, [bp]
[44]318 mov bx, 10
319 jmp DisplayPrint_SignedWordFromAXWithBaseInBX
[134]320%endif
[41]321
[223]322ALIGN JUMP_ALIGN
[44]323u_FormatUnsignedDecimalWord:
[41]324 mov ax, [bp]
325 mov bx, 10
[44]326 jmp DisplayPrint_WordFromAXWithBaseInBX
[41]327
328ALIGN JUMP_ALIGN
[44]329x_FormatHexadecimalWord:
[41]330 mov ax, [bp]
331 mov bx, 16
332 call DisplayPrint_WordFromAXWithBaseInBX
333 mov al, 'h'
[44]334 jmp DisplayPrint_CharacterFromAL
[41]335
336ALIGN JUMP_ALIGN
[184]337I_FormatDashForZero:
338 mov ax, [bp]
339 test ax,ax
[223]340 jnz u_FormatUnsignedDecimalWord
[184]341 mov [bp], word g_szDashForZero
342;;; fall-through
[223]343
[184]344ALIGN JUMP_ALIGN
[44]345s_FormatStringFromSegmentCS:
[41]346 xchg si, [bp]
347 call DisplayPrint_NullTerminatedStringFromCSSI
[44]348 mov si, [bp]
349 ret
[41]350
[134]351%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]352ALIGN JUMP_ALIGN
[44]353S_FormatStringFromFarPointer:
354 mov bx, [bp-2]
[41]355 xchg si, [bp]
356 call DisplayPrint_NullTerminatedStringFromBXSI
[44]357 mov si, [bp]
358 dec bp
359 dec bp
360 ret
[134]361%endif
[41]362
363ALIGN JUMP_ALIGN
[44]364c_FormatCharacter:
[41]365 mov al, [bp]
[44]366 jmp DisplayPrint_CharacterFromAL
[41]367
[134]368%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[41]369ALIGN JUMP_ALIGN
[44]370t_FormatRepeatCharacter:
371 push cx
[41]372 mov cx, [bp-2]
373 mov al, [bp]
374 call DisplayPrint_RepeatCharacterFromALwithCountInCX
[44]375 pop cx
376 dec bp
377 dec bp
378 ret
[41]379
380ALIGN JUMP_ALIGN
[44]381percent_FormatPercent:
[41]382 mov al, '%'
[44]383 jmp DisplayPrint_CharacterFromAL
[134]384%endif
[41]385
386ALIGN JUMP_ALIGN
[44]387PrepareToPrependParameterWithSpaces:
388 neg cx
389 ; Fall to PrepareToAppendSpacesAfterParameter
[41]390
391ALIGN JUMP_ALIGN
[44]392PrepareToAppendSpacesAfterParameter:
393 add sp, BYTE 2 ; Remove return offset
394 jmp ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.