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

Last change on this file since 318 was 241, checked in by gregli@…, 13 years ago

Space optimizations in the Boot Menu and BootInfo routines, taking advantage of nested %s. Optimization in the init of RamVars to avoid writing the signature twice. Preparing for addition of serial floppy support, starting to break the assumption that our drives are always 80h or higher.

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