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

Last change on this file since 47 was 47, checked in by Tomi Tilli, 14 years ago

Assembly Library:
CGA snow prevention now works when copying strings on formatted printing.

File size: 11.2 KB
Line 
1; File name : DisplayFormat.asm
2; Project name : Assembly Library
3; Created date : 29.6.2010
4; Last update : 4.10.2010
5; Author : Tomi Tilli
6; Description : Functions for displaying formatted strings.
7
8; Section containing code
9SECTION .text
10
11;--------------------------------------------------------------------
12; DisplayFormat_ParseCharacters
13; Parameters:
14; DS: BDA segment (zero)
15; SS:BP: Pointer to first format parameter (-=2 updates to next parameter)
16; CS:SI: Pointer to string to format
17; ES:DI: Ptr to cursor location in video RAM
18; Returns:
19; CS:SI: Ptr to end of format string (ptr to one past NULL)
20; DI: Updated offset to video RAM
21; Corrupts registers:
22; AX, BX, CX, DX, BP
23;--------------------------------------------------------------------
24ALIGN JUMP_ALIGN
25DisplayFormat_ParseCharacters:
26 call ReadCharacterAndTestForNull
27 jz SHORT .QuitCharacterParsing
28
29 ePUSH_T cx, DisplayFormat_ParseCharacters ; Return address
30 xor cx, cx ; Initial placeholder size
31 cmp al, '%' ; Format specifier?
32 je SHORT ParseFormatSpecifier
33 jmp DisplayPrint_CharacterFromAL
34
35ALIGN JUMP_ALIGN
36.QuitCharacterParsing:
37 ret
38
39
40;--------------------------------------------------------------------
41; ParseFormatSpecifier
42; Parameters:
43; CX: Placeholder size
44; DS: BDA segment (zero)
45; SS:BP: Pointer to first format parameter (-=2 for next parameter)
46; CS:SI: Pointer to string to format
47; ES:DI: Ptr to cursor location in video RAM
48; Returns:
49; SI: Updated to first unparsed character
50; DI: Updated offset to video RAM
51; BP: Updated to next format parameter
52; Corrupts registers:
53; AX, BX, CX, DX
54;--------------------------------------------------------------------
55ALIGN JUMP_ALIGN
56ParseFormatSpecifier:
57 call ReadCharacterAndTestForNull
58 call Char_IsDecimalDigitInAL
59 jc SHORT .ParsePlaceholderSizeDigitFromALtoCX
60 call GetFormatSpecifierParserToAX
61 call ax ; Parser function
62 dec bp
63 dec bp ; SS:BP now points to next parameter
64 test cx, cx
65 jnz SHORT PrependOrAppendSpaces
66 ret
67
68;--------------------------------------------------------------------
69; .ParsePlaceholderSizeDigitFromALtoCX
70; Parameters:
71; AL: Digit character from format string
72; CX: Current placeholder size
73; DS: BDA segment (zero)
74; Returns:
75; CX: Current placeholder size
76; Jumps back to ParseFormatSpecifier
77; Corrupts registers:
78; AX
79;--------------------------------------------------------------------
80ALIGN JUMP_ALIGN
81.ParsePlaceholderSizeDigitFromALtoCX:
82 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
83 sub al, '0' ; Digit '0'...'9' to integer 0...9
84 mov ah, cl ; Previous number parameter to AH
85 aad ; AL += (AH * 10)
86 mov cl, al ; Updated number parameter now in CX
87 jmp SHORT ParseFormatSpecifier
88
89
90;--------------------------------------------------------------------
91; ReadCharacterAndTestForNull
92; Parameters:
93; CS:SI: Pointer next character from string
94; Returns:
95; AL: Character from string
96; SI: Incremented to next character
97; ZF: Set if NULL, cleared if valid character
98; Corrupts registers:
99; Nothing
100;--------------------------------------------------------------------
101ALIGN JUMP_ALIGN
102ReadCharacterAndTestForNull:
103 eSEG cs
104 lodsb ; Load from CS:SI to AL
105 test al, al ; NULL to end string?
106 ret
107
108
109;--------------------------------------------------------------------
110; GetFormatSpecifierParserToAX
111; Parameters:
112; AL: Format specifier character
113; Returns:
114; AX: Offset to parser function
115; Corrupts registers:
116; AX, BX
117;--------------------------------------------------------------------
118ALIGN JUMP_ALIGN
119GetFormatSpecifierParserToAX:
120 mov bx, .rgcFormatCharToLookupIndex
121ALIGN JUMP_ALIGN
122.CheckForNextSpecifierParser:
123 cmp al, [cs:bx]
124 je SHORT .ConvertIndexToFunctionOffset
125 inc bx
126 cmp bx, .rgcFormatCharToLookupIndexEnd
127 jb SHORT .CheckForNextSpecifierParser
128 mov ax, c_FormatCharacter
129 ret
130ALIGN JUMP_ALIGN
131.ConvertIndexToFunctionOffset:
132 sub bx, .rgcFormatCharToLookupIndex
133 shl bx, 1 ; Shift for WORD lookup
134 mov ax, [cs:bx+.rgfnFormatSpecifierParser]
135 ret
136
137.rgcFormatCharToLookupIndex:
138 db "aAduxsSct-+%"
139.rgcFormatCharToLookupIndexEnd:
140ALIGN WORD_ALIGN
141.rgfnFormatSpecifierParser:
142 dw a_FormatAttributeForNextCharacter
143 dw A_FormatAttributeForRemainingString
144 dw d_FormatSignedDecimalWord
145 dw u_FormatUnsignedDecimalWord
146 dw x_FormatHexadecimalWord
147 dw s_FormatStringFromSegmentCS
148 dw S_FormatStringFromFarPointer
149 dw c_FormatCharacter
150 dw t_FormatRepeatCharacter
151 dw PrepareToPrependParameterWithSpaces
152 dw PrepareToAppendSpacesAfterParameter
153 dw percent_FormatPercent
154
155
156;--------------------------------------------------------------------
157; PrependOrAppendSpaces
158; Parameters:
159; CX: Minimum length for format specifier in characters
160; DS: BDA segment (zero)
161; ES:DI: Ptr to cursor location in video RAM
162; Returns:
163; Nothing
164; Corrupts registers:
165; AX, BX, CX, DX
166;--------------------------------------------------------------------
167ALIGN JUMP_ALIGN
168PrependOrAppendSpaces:
169 mov ax, di
170 sub ax, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
171 test cx, cx
172 js SHORT .PrependWithSpaces
173 ; Fall to .AppendSpaces
174
175;--------------------------------------------------------------------
176; .AppendSpaces
177; Parameters:
178; AX: Number of format parameter BYTEs printed
179; CX: Minimum length for format specifier in characters
180; DS: BDA segment (zero)
181; ES:DI: Ptr to cursor location in video RAM
182; Returns:
183; Nothing
184; Corrupts registers:
185; AX, CX, DX
186;--------------------------------------------------------------------
187.AppendSpaces:
188 call DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
189 sub cx, ax
190 jle SHORT .NothingToAppendOrPrepend
191 mov al, ' '
192 jmp DisplayPrint_RepeatCharacterFromALwithCountInCX
193
194;--------------------------------------------------------------------
195; .PrependWithSpaces
196; Parameters:
197; AX: Number of format parameter BYTEs printed
198; CX: Negative minimum length for format specifier in characters
199; DS: BDA segment (zero)
200; ES:DI: Ptr to cursor location in video RAM
201; Returns:
202; Nothing
203; Corrupts registers:
204; AX, BX, CX, DX
205;--------------------------------------------------------------------
206ALIGN JUMP_ALIGN
207.PrependWithSpaces:
208 xchg ax, cx
209 neg ax
210 call DisplayContext_GetByteOffsetToAXfromCharacterOffsetInAX
211 sub ax, cx ; AX = BYTEs to prepend, CX = BYTEs to move
212 jle SHORT .NothingToAppendOrPrepend
213
214 std
215 push si
216
217 lea si, [di-1] ; SI = Offset to last byte formatted
218 add di, ax ; DI = Cursor location after preceeding completed
219 push di
220 dec di ; DI = Offset where to move last byte formatted
221 xchg bx, ax ; BX = BYTEs to prepend
222 call .ReverseMoveCXbytesFromESSItoESDI
223 xchg ax, bx
224 call .ReversePrintAXspacesStartingFromESDI
225
226 pop di
227 pop si
228 cld ; Restore DF
229.NothingToAppendOrPrepend:
230 ret
231
232;--------------------------------------------------------------------
233; .ReverseMoveCXbytesFromESSItoESDI
234; Parameters:
235; CX: Number of bytes to move
236; DS: BDA segment (zero)
237; ES:SI: Ptr to source in video RAM
238; ES:DI: Ptr to destination in video RAM
239; Returns:
240; DI: Offset to character preceeding string just moved
241; Corrupts registers:
242; AX, CX, DX, SI
243;--------------------------------------------------------------------
244ALIGN JUMP_ALIGN
245.ReverseMoveCXbytesFromESSItoESDI:
246%ifdef ELIMINATE_CGA_SNOW
247 call DisplayCharOut_LoadAndVerifyStatusRegisterFromBDA
248 je SHORT .WaitUntilReadyToMoveNextByte
249%endif
250
251 eSEG_STR rep, es, movsb
252
253%ifdef ELIMINATE_CGA_SNOW
254 jmp SHORT .AlignDIforFirstPreceedingSpace
255.WaitUntilReadyToMoveNextByte:
256 cli ; Interrupt request would mess up timing
257 WAIT_UNTIL_SAFE_CGA_WRITE
258.MovsbWithoutWaitSinceUnknownPort:
259 eSEG es
260 movsb
261 sti
262 loop .WaitUntilReadyToMoveNextByte
263%endif
264 ; Fall to .AlignDIforFirstPreceedingSpace
265
266;--------------------------------------------------------------------
267; .AlignDIforFirstPreceedingSpace
268; Parameters:
269; DS: BDA segment (zero)
270; ES:DI: Byte offset before last byte moved
271; Returns:
272; DI: Offset to space preceeding moved string
273; Corrupts registers:
274; AX
275;--------------------------------------------------------------------
276ALIGN JUMP_ALIGN
277.AlignDIforFirstPreceedingSpace:
278 mov al, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bFlags]
279 and ax, BYTE FLG_CONTEXT_ATTRIBUTES
280 not ax
281 and di, ax
282 ret
283
284;--------------------------------------------------------------------
285; .ReversePrintAXspacesStartingFromESDI
286; Parameters:
287; AX: Number of spaces to print
288; DS: BDA segment (zero)
289; ES:DI: Ptr to destination in video RAM
290; Returns:
291; DI: Updated
292; Corrupts registers:
293; AX, CX, DX
294ALIGN JUMP_ALIGN
295.ReversePrintAXspacesStartingFromESDI:
296 call DisplayContext_GetCharacterOffsetToAXfromByteOffsetInAX
297 xchg cx, ax ; CX = Spaces to prepend
298 mov al, ' '
299 jmp DisplayPrint_RepeatCharacterFromALwithCountInCX
300
301
302
303;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
304; Formatting functions
305; Parameters:
306; DS: BDA segment (zero)
307; SS:BP: Pointer to next format parameter (-=2 updates to next parameter)
308; ES:DI: Ptr to cursor location in video RAM
309; Returns:
310; SS:BP: Points to last WORD parameter used
311; Corrupts registers:
312; AX, BX, DX
313;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
314ALIGN JUMP_ALIGN
315a_FormatAttributeForNextCharacter:
316 mov bl, [bp]
317 xchg bl, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
318 push bx
319 push cx
320 push di
321 call DisplayFormat_ParseCharacters ; Recursive call
322 pop WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition]
323 pop cx
324 pop bx
325 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], bl
326 ret
327
328ALIGN JUMP_ALIGN
329A_FormatAttributeForRemainingString:
330 mov al, [bp]
331 mov [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
332 ret
333
334ALIGN JUMP_ALIGN
335d_FormatSignedDecimalWord:
336 mov ax, [bp]
337 mov bx, 10
338 jmp DisplayPrint_SignedWordFromAXWithBaseInBX
339
340ALIGN JUMP_ALIGN
341u_FormatUnsignedDecimalWord:
342 mov ax, [bp]
343 mov bx, 10
344 jmp DisplayPrint_WordFromAXWithBaseInBX
345
346ALIGN JUMP_ALIGN
347x_FormatHexadecimalWord:
348 mov ax, [bp]
349 mov bx, 16
350 call DisplayPrint_WordFromAXWithBaseInBX
351 mov al, 'h'
352 jmp DisplayPrint_CharacterFromAL
353
354ALIGN JUMP_ALIGN
355s_FormatStringFromSegmentCS:
356 xchg si, [bp]
357 call DisplayPrint_NullTerminatedStringFromCSSI
358 mov si, [bp]
359 ret
360
361ALIGN JUMP_ALIGN
362S_FormatStringFromFarPointer:
363 mov bx, [bp-2]
364 xchg si, [bp]
365 call DisplayPrint_NullTerminatedStringFromBXSI
366 mov si, [bp]
367 dec bp
368 dec bp
369 ret
370
371ALIGN JUMP_ALIGN
372c_FormatCharacter:
373 mov al, [bp]
374 jmp DisplayPrint_CharacterFromAL
375
376ALIGN JUMP_ALIGN
377t_FormatRepeatCharacter:
378 push cx
379 mov cx, [bp-2]
380 mov al, [bp]
381 call DisplayPrint_RepeatCharacterFromALwithCountInCX
382 pop cx
383 dec bp
384 dec bp
385 ret
386
387ALIGN JUMP_ALIGN
388percent_FormatPercent:
389 mov al, '%'
390 jmp DisplayPrint_CharacterFromAL
391
392ALIGN JUMP_ALIGN
393PrepareToPrependParameterWithSpaces:
394 neg cx
395 ; Fall to PrepareToAppendSpacesAfterParameter
396
397ALIGN JUMP_ALIGN
398PrepareToAppendSpacesAfterParameter:
399 add sp, BYTE 2 ; Remove return offset
400 jmp ParseFormatSpecifier
Note: See TracBrowser for help on using the repository browser.