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

Last change on this file since 47 was 47, checked in by aitotat, 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.