source: xtideuniversalbios/trunk/Assembly_Library/Src/Display/DisplayPrint.asm @ 590

Last change on this file since 590 was 590, checked in by krille_n_, 8 years ago

Changes:

  • Updated URLs and copyright info in BIOSDRVS and XTIDECFG.
  • BIOSDRVS should now build under Linux.
  • Minor optimizations to the library.
File size: 12.7 KB
RevLine 
[41]1; Project name  :   Assembly Library
2; Description   :   Functions for display output.
3
[376]4;
[491]5; XTIDE Universal BIOS and Associated Tools
[526]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
[491]12;
[376]13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
[491]16; GNU General Public License for more details.
[376]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[491]18;
[376]19
[41]20; Section containing code
21SECTION .text
22
[376]23
[41]24;--------------------------------------------------------------------
25; Supports following formatting types:
26;   %a      Specifies attribute for next character
27;   %A      Specifies attribute for remaining string (or until next %A)
28;   %d      Prints signed 16-bit decimal integer
29;   %u      Prints unsigned 16-bit decimal integer
30;   %x      Prints 16-bit hexadecimal integer
31;   %s      Prints string (from CS segment)
32;   %S      Prints string (far pointer)
33;   %c      Prints character
34;   %t      Prints character number of times (character needs to be pushed first, then repeat times)
35;   %%      Prints '%' character (no parameter pushed)
36;
37;   Any placeholder can be set to minimum length by specifying
38;   minimum number of characters. For example %8d would append spaces
39;   after integer so that at least 8 characters would be printed.
[48]40;
41;   When placing '-' after number, then spaces will be used for prepending.
42;   For example %8-d would prepend integer with spaces so that at least
43;   8 characters would be printed.
[162]44;
[41]45; DisplayPrint_FormattedNullTerminatedStringFromCSSI
46;   Parameters:
47;       BP:     SP before pushing parameters
48;       DS:     BDA segment (zero)
49;       CS:SI:  Pointer to string to format
50;       ES:DI:  Ptr to cursor location in video RAM
51;       Stack:  Parameters for formatting placeholders.
52;               Parameter for first placeholder must be pushed first.
53;               Low word must pushed first for placeholders requiring
54;               32-bit parameters (two words).
55;   Returns:
56;       DI:     Updated offset to video RAM
57;   Corrupts registers:
58;       AX, DX
59;--------------------------------------------------------------------
[369]60ALIGN DISPLAY_JUMP_ALIGN
[41]61DisplayPrint_FormattedNullTerminatedStringFromCSSI:
62    push    bp
63    push    si
64    push    cx
65    push    bx
66    push    WORD [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
67
68    dec     bp                  ; Point BP to...
69    dec     bp                  ; ...first stack parameter
70    call    DisplayFormat_ParseCharacters
71
72    ; Pop original character attribute
73    pop     ax
74    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute], al
75
76    pop     bx
77    pop     cx
78    pop     si
79    pop     bp
[376]80
[41]81    ret
82
83
84;--------------------------------------------------------------------
[590]85; DisplayPrint_SignedWordFromAXWithBaseInBL
[41]86;   Parameters:
87;       AX:     Word to display
[590]88;       BL:     Integer base (binary=2, octal=8, decimal=10, hexadecimal=16)
[41]89;       DS:     BDA segment (zero)
90;       ES:DI:  Ptr to cursor location in video RAM
91;   Returns:
92;       DI:     Updated offset to video RAM
93;   Corrupts registers:
[590]94;       AX, BH, DX
[41]95;--------------------------------------------------------------------
[134]96%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]97ALIGN DISPLAY_JUMP_ALIGN
[590]98DisplayPrint_SignedWordFromAXWithBaseInBL:
99    sahf
100    jns     SHORT DisplayPrint_WordFromAXWithBaseInBL
[41]101
102    push    ax
103    mov     al, '-'
104    call    DisplayPrint_CharacterFromAL
105    pop     ax
106    neg     ax
[590]107    ; Fall to DisplayPrint_WordFromAXWithBaseInBL
[134]108%endif
[41]109
[376]110
[41]111;--------------------------------------------------------------------
[590]112; DisplayPrint_WordFromAXWithBaseInBL
[41]113;   Parameters:
114;       AX:     Word to display
[590]115;       BL:     Integer base (binary=2, octal=8, decimal=10, hexadecimal=16)
[41]116;       DS:     BDA segment (zero)
117;       ES:DI:  Ptr to cursor location in video RAM
118;   Returns:
119;       DI:     Updated offset to video RAM
120;   Corrupts registers:
[590]121;       AX, BH, DX
[376]122;--------------------------------------------------------------------
[491]123%ifndef MODULE_STRINGS_COMPRESSED
[369]124ALIGN DISPLAY_JUMP_ALIGN
[590]125DisplayPrint_WordFromAXWithBaseInBL:
[41]126    push    cx
127
128    xor     cx, cx
[590]129    xor     bh, bh              ; Base now in BX
[369]130ALIGN DISPLAY_JUMP_ALIGN
[41]131.DivideLoop:
[580]132    inc     cx                  ; Increment character count
[41]133    xor     dx, dx              ; DX:AX now holds the integer
134    div     bx                  ; Divide DX:AX by base
135    push    dx                  ; Push remainder
136    test    ax, ax              ; All divided?
137    jnz     SHORT .DivideLoop   ;  If not, loop
[44]138
[580]139ALIGN DISPLAY_JUMP_ALIGN
[532]140PrintAllPushedDigits:           ; Unused entrypoint OK
[44]141.PrintNextDigit:
142    pop     ax                  ; Pop digit
[580]143    cmp     al, 10              ; Convert binary digit in AL to ASCII hex digit ('0'-'9' or 'A'-'F')
144    sbb     al, 69h
145    das
[41]146    call    DisplayPrint_CharacterFromAL
[44]147    loop    .PrintNextDigit
[41]148
149    pop     cx
150    ret
[580]151%endif ; ~MODULE_STRINGS_COMPRESSED
[341]152
153;--------------------------------------------------------------------
154; DisplayPrint_QWordFromSSBPwithBaseInBX
155;   Parameters:
156;       SS:BP:  QWord to display
157;       BX:     Integer base (binary=2, octal=8, decimal=10, hexadecimal=16)
158;       DS:     BDA segment (zero)
159;       ES:DI:  Ptr to cursor location in video RAM
160;   Returns:
161;       DI:     Updated offset to video RAM
162;   Corrupts registers:
163;       AX, DX, [SS:BP]
164;--------------------------------------------------------------------
[491]165%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS OR EXCLUDE_FROM_XTIDECFG
[369]166ALIGN DISPLAY_JUMP_ALIGN
[341]167DisplayPrint_QWordFromSSBPwithBaseInBX:
168    push    cx
169
170    mov     cx, bx              ; CX = Integer base
171    xor     bx, bx              ; BX = Character count
[369]172ALIGN DISPLAY_JUMP_ALIGN
[341]173.DivideLoop:
174    call    Math_DivQWatSSBPbyCX; Divide by base
175    push    dx                  ; Push remainder
176    inc     bx                  ; Increment character count
177    cmp     WORD [bp], BYTE 0   ; All divided?
178    jne     SHORT .DivideLoop   ;  If not, loop
[580]179    xchg    cx, bx              ; Character count to CX, Integer base to BX
[341]180    jmp     SHORT PrintAllPushedDigits
[491]181%endif
[41]182
183
184;--------------------------------------------------------------------
185; DisplayPrint_CharacterBufferFromBXSIwithLengthInCX
186;   Parameters:
187;       CX:     Buffer length (characters)
188;       BX:SI:  Ptr to NULL terminated string
189;       DS:     BDA segment (zero)
190;       ES:DI:  Ptr to cursor location in video RAM
191;   Returns:
192;       DI:     Updated offset to video RAM
193;   Corrupts registers:
194;       AX, DX
195;--------------------------------------------------------------------
[223]196%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]197ALIGN DISPLAY_JUMP_ALIGN
[41]198DisplayPrint_CharacterBufferFromBXSIwithLengthInCX:
[44]199    jcxz    .NothingToPrintSinceZeroLength
200    push    si
[41]201    push    cx
202
[369]203ALIGN DISPLAY_JUMP_ALIGN
[44]204.PrintNextCharacter:
205    mov     ds, bx
206    lodsb
207    LOAD_BDA_SEGMENT_TO ds, dx
208    call    DisplayPrint_CharacterFromAL
209    loop    .PrintNextCharacter
210
[41]211    pop     cx
[44]212    pop     si
213.NothingToPrintSinceZeroLength:
[41]214    ret
[376]215%endif
[41]216
[376]217
[41]218;--------------------------------------------------------------------
[67]219; DisplayPrint_ClearScreenWithCharInALandAttributeInAH
[41]220;   Parameters:
[67]221;       AL:     Character to clear with
222;       AH:     Attribute to clear with
[41]223;       DS:     BDA segment (zero)
224;       ES:DI:  Ptr to cursor location in video RAM
225;   Returns:
226;       Nothing
227;   Corrupts registers:
228;       AX, DX
229;--------------------------------------------------------------------
[491]230%ifdef INCLUDE_MENU_LIBRARY
[369]231ALIGN DISPLAY_JUMP_ALIGN
[67]232DisplayPrint_ClearScreenWithCharInALandAttributeInAH:
[41]233    push    di
[67]234    push    cx
235
236    xchg    cx, ax
[41]237    xor     ax, ax
[67]238    call    DisplayCursor_SetCoordinatesFromAX      ; Updates DI
[41]239    call    DisplayPage_GetColumnsToALandRowsToAH
[67]240    mul     ah      ; AX = AL*AH = Characters on screen
241    xchg    cx, ax  ; AX = Char+Attr, CX = WORDs to store
242    rep stosw
243
244    pop     cx
[41]245    pop     di
246    mov     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fpCursorPosition], di
247    ret
[489]248%endif
[491]249
250
[41]251;--------------------------------------------------------------------
252; DisplayPrint_ClearAreaWithHeightInAHandWidthInAL
253;   Parameters:
254;       AH:     Area height
255;       AL:     Area width
256;       DS:     BDA segment (zero)
257;       ES:DI:  Ptr to cursor location in video RAM
258;   Returns:
[42]259;       DI:     Updated offset to video RAM
[41]260;   Corrupts registers:
261;       AX, DX
262;--------------------------------------------------------------------
[134]263%ifndef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
[369]264ALIGN DISPLAY_JUMP_ALIGN
[41]265DisplayPrint_ClearAreaWithHeightInAHandWidthInAL:
[42]266    push    si
[41]267    push    cx
268    push    bx
269
[42]270    xchg    bx, ax                          ; Area size to BX
[41]271    call    DisplayCursor_GetSoftwareCoordinatesToAX
[42]272    xchg    si, ax                          ; Software (Y,X) coordinates now in SI
273    xor     cx, cx
[41]274
[369]275ALIGN DISPLAY_JUMP_ALIGN
[42]276.ClearRowLoop:
277    mov     cl, bl                          ; Area width now in CX
[44]278    mov     al, SCREEN_BACKGROUND_CHARACTER
[42]279    call    DisplayPrint_RepeatCharacterFromALwithCountInCX
[41]280
[42]281    xchg    ax, si                          ; Coordinates to AX
282    inc     ah                              ; Increment row
283    mov     si, ax
[41]284    call    DisplayCursor_SetCoordinatesFromAX
[42]285    dec     bh                              ; Decrement rows left
286    jnz     SHORT .ClearRowLoop
[41]287
288    pop     bx
289    pop     cx
[42]290    pop     si
[41]291    ret
[134]292%endif
[42]293
[492]294%ifdef EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS
295    %define EXCLUDE
[532]296    %ifndef MODULE_STRINGS_COMPRESSED
297        %undef EXCLUDE
298    %endif
[589]299    %ifdef MODULE_HOTKEYS OR MODULE_BOOT_MENU
[492]300        %undef EXCLUDE
301    %endif
302%endif
[42]303
[505]304%ifndef EXCLUDE
[42]305;--------------------------------------------------------------------
306; DisplayPrint_RepeatCharacterFromALwithCountInCX
307;   Parameters:
308;       AL:     Character to display
309;       CX:     Repeat count
310;       DS:     BDA segment (zero)
311;       ES:DI:  Ptr to cursor location in video RAM
312;   Returns:
313;       DI:     Updated offset to video RAM
314;   Corrupts registers:
[181]315;       DX
[42]316;--------------------------------------------------------------------
[369]317ALIGN DISPLAY_JUMP_ALIGN
[42]318DisplayPrint_RepeatCharacterFromALwithCountInCX:
[44]319    jcxz    .NothingToRepeat
320    push    cx
321
[369]322ALIGN DISPLAY_JUMP_ALIGN
[44]323.RepeatCharacter:
[42]324    push    ax
325    call    DisplayPrint_CharacterFromAL
326    pop     ax
[44]327    loop    .RepeatCharacter
328
329    pop     cx
330.NothingToRepeat:
[42]331    ret
[492]332%endif
333%undef EXCLUDE
[223]334
[186]335;--------------------------------------------------------------------
336; DisplayPrint_NullTerminatedStringFromCSSI
337;   Parameters:
338;       CS:SI:  Ptr to NULL terminated string
339;       DS:     BDA segment (zero)
340;       ES:DI:  Ptr to cursor location in video RAM
341;   Returns:
342;       DI:     Updated offset to video RAM
343;   Corrupts registers:
344;       AX, DX
345;--------------------------------------------------------------------
[376]346%ifndef MODULE_STRINGS_COMPRESSED
347;;;
348;;; Take care when using this routine with compressed strings (which is why it is disabled).
349;;; All strings in CSSI should go through the DisplayFormatCompressed code to be decoded.
350;;;
[369]351ALIGN DISPLAY_JUMP_ALIGN
[186]352DisplayPrint_NullTerminatedStringFromCSSI:
353    push    bx
354    mov     bx, cs
355    call    DisplayPrint_NullTerminatedStringFromBXSI
356    pop     bx
357    ret
[376]358%endif
[42]359
360
[376]361;;;
362;;; Note that the following routines need to be at the bottom of this file
363;;; to accomodate short jumps from the next file (DisplayFormat/DisplayFormatCompressed)
364;;;
365
[42]366;--------------------------------------------------------------------
[44]367; DisplayPrint_Newline
368;   Parameters:
369;       DS:     BDA segment (zero)
370;       ES:DI:  Ptr to cursor location in video RAM
371;   Returns:
372;       DI:     Updated offset to video RAM
373;   Corrupts registers:
374;       AX, DX
375;--------------------------------------------------------------------
[376]376%ifdef MODULE_STRINGS_COMPRESSED
[369]377ALIGN DISPLAY_JUMP_ALIGN
[376]378DisplayPrint_Newline_FormatAdjustBP:
379    inc     bp                  ; we didn't need a parameter after all, readjust BP
380    inc     bp
381    ; fall through to DisplayPrint_Newline
382%endif
383
[369]384ALIGN DISPLAY_JUMP_ALIGN
[44]385DisplayPrint_Newline:
[52]386    mov     al, LF
387    call    DisplayPrint_CharacterFromAL
[44]388    mov     al, CR
389    ; Fall to DisplayPrint_CharacterFromAL
390
391;--------------------------------------------------------------------
[42]392; DisplayPrint_CharacterFromAL
393;   Parameters:
394;       AL:     Character to display
[567]395;               Zero value is ignored (no character is printed)
[42]396;       DS:     BDA segment (zero)
397;       ES:DI:  Ptr to cursor location in video RAM
398;   Returns:
399;       DI:     Updated offset to video RAM
400;   Corrupts registers:
401;       AX, DX
402;--------------------------------------------------------------------
[369]403ALIGN DISPLAY_JUMP_ALIGN
[42]404DisplayPrint_CharacterFromAL:
[505]405    test    al, al
[376]406    jz      DisplayPrint_Ret
407
[42]408    mov     ah, [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.bAttribute]
409    jmp     [VIDEO_BDA.displayContext+DISPLAY_CONTEXT.fnCharOut]
[223]410
[376]411
[186]412;--------------------------------------------------------------------
413; DisplayPrint_NullTerminatedStringFromBXSI
414;   Parameters:
415;       DS:     BDA segment (zero)
416;       BX:SI:  Ptr to NULL terminated string
417;       ES:DI:  Ptr to cursor location in video RAM
418;   Returns:
419;       DI:     Updated offset to video RAM
420;   Corrupts registers:
421;       AX, DX
422;--------------------------------------------------------------------
[369]423ALIGN DISPLAY_JUMP_ALIGN
[186]424DisplayPrint_NullTerminatedStringFromBXSI:
425    push    si
426    push    cx
427
428    xor     cx, cx
[369]429ALIGN DISPLAY_JUMP_ALIGN
[186]430.PrintNextCharacter:
431    mov     ds, bx              ; String segment to DS
432    lodsb
433    mov     ds, cx              ; BDA segment to DS
434    test    al, al              ; NULL?
435    jz      SHORT .EndOfString
436    call    DisplayPrint_CharacterFromAL
437    jmp     SHORT .PrintNextCharacter
438
[369]439ALIGN DISPLAY_JUMP_ALIGN
[186]440.EndOfString:
441    pop     cx
442    pop     si
[376]443
444DisplayPrint_Ret:               ; random ret to jump to
[186]445    ret
446
Note: See TracBrowser for help on using the repository browser.