source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Libraries/print.asm @ 26

Last change on this file since 26 was 3, checked in by aitotat, 14 years ago
File size: 18.9 KB
Line 
1; File name     :   print.asm
2; Project name  :   Print library
3; Created date  :   6.10.2009
4; Last update   :   31.12.2009
5; Author        :   Tomi Tilli
6; Description   :   ASM library to for character and string
7;                   printing related functions.
8
9;--------------- Equates -----------------------------
10
11; String library function to include
12%define USE_PRINT_FORMAT            ; Print_Format
13%define USE_PRINT_NEWLINE           ; Print_Newline
14;%define USE_PRINT_CHARBUFFER       ; Print_CharBuffer
15%define USE_PRINT_REPEAT            ; Print_Repeat
16;%define USE_PRINT_BOOL             ; Print_Bool
17;%define USE_PRINT_INTSW            ; Print_IntSW
18%define USE_PRINT_INTUW             ; Print_IntUW
19;%define USE_PRINT_INTUDW           ; Print_IntUDW
20%define USE_PRINT_INTHEXB           ; Print_IntHexB
21%define USE_PRINT_INTHEXW           ; Print_IntHexW
22;%define USE_PRINT_INTHEXDW         ; Print_IntHexDW
23
24
25; Text mode character attribute byte bits for CGA+
26FLG_CGA_FG_B        EQU     (1<<0)
27FLG_CGA_FG_G        EQU     (1<<1)
28FLG_CGA_FG_R        EQU     (1<<2)
29FLG_CGA_FG_I        EQU     (1<<3)
30FLG_CGA_BG_B        EQU     (1<<4)
31FLG_CGA_BG_G        EQU     (1<<5)
32FLG_CGA_BG_R        EQU     (1<<6)
33FLG_CGA_BG_I        EQU     (1<<7)
34FLG_CGA_BG_BLNK     EQU     (1<<7)  ; Blinking is default
35
36; Text mode character attribute bytes for MDA/Hercules (mono)
37; *Not displayed on some monitors
38ATTR_MDA_HIDDEN     EQU     00h ; Not displayed
39ATTR_MDA_ULINE      EQU     01h ; Underlined
40ATTR_MDA_NORMAL     EQU     07h ; Normal (white on black)
41ATTR_MDA_INT_U      EQU     09h ; High intensity, underlined
42ATTR_MDA_INT        EQU     0Fh ; High intensity
43ATTR_MDA_REVERSE    EQU     70h ; Reverse video (black on white)
44ATTR_MDA_BLNK       EQU     87h ; Blinking white on black*
45ATTR_MDA_BLNK_INT   EQU     8Fh ; Blinking high intensity*
46ATTR_MDA_BLNK_REV   EQU     0F0h; Blinking reverse video
47
48
49;-------------- Private global variables -------------
50; Section containing initialized data
51;SECTION .data
52
53g_rgbHex:       db  "0123456789ABCDEF"  ; Hexadecimal printing
54g_rgbFormat:    ; Placeholders for Print_Format
55%ifdef USE_PRINT_INTSW
56                db  'd' ; Prints signed 16-bit integer (WORD)
57%endif
58%ifdef USE_PRINT_INTUW
59                db  'u' ; Prints unsigned 16-bit integer (WORD)
60%endif
61%ifdef USE_PRINT_INTUDW
62                db  'U' ; Prints unsigned 32-bit integer (DWORD)
63%endif
64%ifdef USE_PRINT_INTHEXW
65                db  'x' ; Prints 8- or 16-bit hexadecimal (BYTE, WORD)
66%endif
67%ifdef USE_PRINT_INTHEXDW
68                db  'X' ; Prints 32-bit hexadecimal (DWORD)
69%endif
70                db  's' ; Prints string (DS segment)
71                db  'S' ; Prints string (far pointer)
72%ifdef USE_PRINT_BOOL
73                db  'b' ; Prints boolean value 0 or 1
74%endif
75                db  'c' ; Prints character
76                db  'C' ; Prints character number of times
77_g_rgbFormatEnd:
78
79; Number of different placeholders for Print_Format
80CNT_PLCEHLDRS       EQU     (_g_rgbFormatEnd-g_rgbFormat)
81
82
83
84;-------------- Public functions ---------------------
85; Section containing code
86SECTION .text
87
88; Include one file to use DOS, BIOS or VRAM macros and functions
89;%include "prntdos.asm"         ; Include to use DOS printing functions
90%include "prntbios.asm"         ; Include to use BIOS printing functions
91;%include "prntvram.asm"            ; Include to access VRAM directly
92
93
94;--------------------------------------------------------------------
95; Debugging macro that prints wanted character and newline.
96; 
97; PRINT_DBG_CH
98;   Parameters:
99;       %1:     Character to print
100;   Returns:
101;       Nothing
102;   Corrupts registers:
103;       Nothing
104;--------------------------------------------------------------------
105%macro PRINT_DBG_CH 1
106    pushf
107    push    dx
108    push    ax
109    mov     dl, %1
110    PRINT_CHAR
111    ;mov        dl, CR
112    ;PRINT_CHAR
113    ;mov        dl, LF
114    ;PRINT_CHAR
115    pop     ax
116    pop     dx
117    popf
118%endmacro
119
120
121;--------------------------------------------------------------------
122; Simplified printf-style string formatting function.
123; Strings must end to STOP character.
124; Supports following formatting types:
125;   %d      Prints signed 16-bit integer (WORD)
126;   %u      Prints unsigned 16-bit integer (WORD)
127;   %U      Prints unsigned 32-bit integer (DWORD)
128;   %x      Prints 8- or 16-bit hexadecimal (BYTE, WORD)
129;   %X      Prints 32-bit hexadecimal (DWORD)
130;   %s      Prints string (DS segment)
131;   %S      Prints string (far pointer)
132;   %b      Prints boolean value 0 or 1
133;   %c      Prints character
134;   %[num]C Prints character number of times (up to 256, 0=256)
135;   %%      Prints '%' character (no parameter pushed)
136;
137;   Any placeholder can be set to minimum length by specifying
138;   minimum number of characters. For example %8d would append spaces
139;   after integer so that at least 8 characters would be printed.
140;
141;   NOTE! Caller must clean the stack variables!
142; 
143; Print_Format
144;   Parameters:
145;       DL:         Min length character (usually space)
146;       DS:SI:      Pointer to string to format
147;       Stack:      Parameters for formatting placeholders.
148;                   Parameter for first placeholder must be pushed last
149;                   (to top of stack).
150;                   High word must be pushed first for 32-bit parameters.
151;   Returns:
152;       Nothing
153;   Corrupts registers:
154;       AX, SI
155;--------------------------------------------------------------------
156%ifdef USE_PRINT_FORMAT
157ALIGN JUMP_ALIGN
158Print_Format:
159    push    es
160    push    bp
161    push    di
162    push    cx
163    push    dx                  ; Push min length character
164    push    cs                  ; Copy CS...
165    pop     es                  ; ...to ES
166    mov     bp, sp              ; Copy SP to BP
167    add     bp, 2*6             ; Set BP to point first stack parameter
168    cld                         ; Set LODSB to increment SI
169ALIGN JUMP_ALIGN
170.PrintLoop:         ; Load characters from string
171    lodsb                       ; Load char from DS:SI to AL, increment SI
172    xor     cx, cx              ; Zero minimum length
173    cmp     al, STOP            ; End of string?
174    je      .Return             ;  If so, return
175    cmp     al, '%'             ; Format placeholder?
176    je      .Format             ;  If so, jump to format
177ALIGN JUMP_ALIGN
178.PrintChar:         ; Prints single character from AL
179    mov     dl, al              ; Copy character to DL
180    PRINT_CHAR                  ; Print character
181    mov     dx, 1               ; One char printed
182ALIGN JUMP_ALIGN
183.PrintXtraSoMin:    ; Checks how many spaces to append
184    sub     cx, dx              ; Number of spaces needed
185    jle     .PrintLoop          ; Read next character if no spaces needed
186    pop     dx                  ; Pop min length character to DL
187ALIGN JUMP_ALIGN
188.PrintSpaceLoop:    ; Loop to print the required spaces
189    PRINT_CHAR
190    loop    .PrintSpaceLoop
191    push    dx                  ; Store min length character
192    jmp     .PrintLoop          ; Jump to read next character
193ALIGN JUMP_ALIGN
194.Return:            ; The only return point for this function
195    pop     dx
196    pop     cx
197    pop     di
198    pop     bp
199    pop     es
200    ret
201ALIGN JUMP_ALIGN
202.UpdateMinLen:      ; Updates placeholder minimum length
203    mov     al, ah              ; Copy digit to AL
204    mov     ah, cl              ; Copy previous length to AH
205    aad                         ; AL=10*AH+AL, AH=0
206    mov     cx, ax              ; Copy new length to CX
207ALIGN JUMP_ALIGN
208.Format:
209    lodsb                       ; Load char from DS:SI to AL, increment SI
210    cmp     al, STOP
211    je      .Return             ; Invalid string
212    mov     ah, al              ; Copy char to AH
213    sub     ah, '0'             ; Possible digit char to digit
214    cmp     ah, 9               ; Was valid digit?
215    jbe     .UpdateMinLen       ;  If so, jump to update minimum length
216    push    cx                  ; Store number of spaces needed
217    mov     cx, CNT_PLCEHLDRS   ; Load number of placeholders to CX
218    mov     di, g_rgbFormat     ; Load offset to format placeholder table
219    repne scasb                 ; Compare AL to [ES:DI] until match
220    pop     cx                  ; Restore spaces needed
221    jne     .PrintChar          ; If no match, jump to print character
222    sub     di, g_rgbFormat+1   ; To placeholder index
223    shl     di, 1               ; Shift for word lookup
224    jmp     [cs:di+.g_rgwFormJump]  ; Jump to format
225
226%ifdef USE_PRINT_INTSW
227ALIGN JUMP_ALIGN
228.Print_d:   ; Print signed 16-bit integer
229    mov     ax, [bp]            ; Load word to print
230    times 2 inc bp
231    call    Print_IntSW
232    jmp     .PrintXtraSoMin
233%endif
234%ifdef USE_PRINT_INTUW
235ALIGN JUMP_ALIGN
236.Print_u:   ; Print unsigned 16-bit integer
237    mov     ax, [bp]            ; Load word to print
238    times 2 inc bp
239    call    Print_IntUW
240    jmp     .PrintXtraSoMin
241%endif
242%ifdef USE_PRINT_INTUDW
243ALIGN JUMP_ALIGN
244.Print_U:   ; Print unsigned 32-bit integer
245    mov     ax, [bp]            ; Load loword
246    mov     dx, [bp+2]          ; Load hiword
247    add     bp, 4
248    call    Print_IntUDW
249    jmp     .PrintXtraSoMin
250%endif
251%ifdef USE_PRINT_INTHEXW
252ALIGN JUMP_ALIGN
253.Print_x:   ; Prints 8- or 16-bit hexadecimal
254    mov     ax, [bp]            ; Load word to print
255    times 2 inc bp
256%ifdef USE_PRINT_INTHEXB
257    test    ah, ah              ; 16-bit hexadecimal?
258    jnz     .Print_x16          ;  If so, jump to print it
259    call    Print_IntHexB
260    jmp     .PrintXtraSoMin
261.Print_x16:
262%endif
263    call    Print_IntHexW
264    jmp     .PrintXtraSoMin
265%endif
266%ifdef USE_PRINT_INTHEXDW
267ALIGN JUMP_ALIGN
268.Print_X:   ; Prints 32-bit hexadecimal
269    mov     ax, [bp]            ; Load loword
270    mov     dx, [bp+2]          ; Load hiword
271    add     bp, 4
272    call    Print_IntHexDW
273    jmp     .PrintXtraSoMin
274%endif
275ALIGN JUMP_ALIGN
276.Print_s:   ; Prints string from DS segment
277    mov     dx, [bp]            ; Load offset to string
278    times 2 inc bp
279    PRINT_STR_LEN               ; Print string
280    jmp     .PrintXtraSoMin
281ALIGN JUMP_ALIGN
282.Print_S:   ; Prints string using far pointer
283    push    ds                  ; Store DS
284    mov     dx, [bp]            ; Load offset to string
285    mov     ds, [bp+2]          ; Load segment to string
286    add     bp, 4
287    PRINT_STR_LEN               ; Print string
288    pop     ds                  ; Restore DS
289    jmp     .PrintXtraSoMin
290%ifdef USE_PRINT_BOOL
291ALIGN JUMP_ALIGN
292.Print_b:   ; Prints boolean value
293    mov     ax, [bp]            ; Load boolean value to print
294    times 2 inc bp
295    call    Print_Bool
296    jmp     .PrintXtraSoMin
297%endif
298ALIGN JUMP_ALIGN
299.Print_c:   ; Prints character
300    mov     ax, [bp]            ; Load character to print
301    times 2 inc bp
302    jmp     .PrintChar          ; Jump to print character
303ALIGN JUMP_ALIGN
304.Print_C:
305    mov     dx, [bp]            ; Load character to print
306    times 2 inc bp
307ALIGN JUMP_ALIGN
308.CharLoop:
309    PRINT_CHAR
310    loop    .CharLoop
311    jmp     .PrintLoop
312
313ALIGN JUMP_ALIGN
314.g_rgwFormJump:                 ; Jump table for Print_Format
315%ifdef USE_PRINT_INTSW
316    dw      .Print_d
317%endif
318%ifdef USE_PRINT_INTUW
319    dw      .Print_u
320%endif
321%ifdef USE_PRINT_INTUDW
322    dw      .Print_U
323%endif
324%ifdef USE_PRINT_INTHEXW
325    dw      .Print_x
326%endif
327%ifdef USE_PRINT_INTHEXDW
328    dw      .Print_X
329%endif
330    dw      .Print_s
331    dw      .Print_S
332%ifdef USE_PRINT_BOOL
333    dw      .Print_b
334%endif
335    dw      .Print_c
336    dw      .Print_C
337%endif
338
339
340;--------------------------------------------------------------------
341; Prints newline character to change line.
342; 
343; Print_Newline
344;   Parameters:
345;       Nothing
346;   Returns:
347;       Nothing
348;   Corrupts registers:
349;       Nothing
350;--------------------------------------------------------------------
351%ifdef USE_PRINT_NEWLINE
352ALIGN JUMP_ALIGN
353Print_Newline:
354    push    ax
355    push    dx
356    mov     dl, LF
357    PRINT_CHAR
358    mov     dl, CR
359    PRINT_CHAR
360    pop     dx
361    pop     ax
362    ret
363%endif
364   
365
366;--------------------------------------------------------------------
367; Prints wanted number of characters.
368; 
369; Print_CharBuffer
370;   Parameters:
371;       CX:     Number of characters to print
372;       ES:DI:  Ptr to character buffer
373;   Returns:
374;       Nothing
375;   Corrupts registers:
376;       AX, CX
377;--------------------------------------------------------------------
378%ifdef USE_PRINT_CHARBUFFER
379ALIGN JUMP_ALIGN
380Print_CharBuffer:
381    jcxz    .Return
382    push    ds
383    push    si
384    push    dx
385    push    es
386    pop     ds
387    mov     si, di
388    cld                         ; LODSB to increment SI
389ALIGN JUMP_ALIGN
390.Rep:
391    lodsb                       ; Load from [DS:SI] to AL
392    mov     dl, al              ; Copy to DL for printing
393    PRINT_CHAR
394    loop    .Rep
395    pop     dx
396    pop     si
397    pop     ds
398.Return:
399    ret
400%endif
401
402
403;--------------------------------------------------------------------
404; Repeats wanted character.
405; 
406; Print_Repeat
407;   Parameters:
408;       CX:     Number of times to repeat character
409;       DL:     Character to repeat
410;   Returns:
411;       Nothing
412;   Corrupts registers:
413;       AX, CX
414;--------------------------------------------------------------------
415%ifdef USE_PRINT_REPEAT
416ALIGN JUMP_ALIGN
417Print_Repeat:
418    jcxz    .Return
419ALIGN JUMP_ALIGN
420.Rep:
421    PRINT_CHAR
422    loop    .Rep
423.Return:
424    ret
425%endif
426
427
428;--------------------------------------------------------------------
429; Prints boolean value.
430; 
431; Print_Bool
432;   Parameters:
433;       AX:     Boolean value (0=FALSE, non-zero=TRUE)
434;   Returns:
435;       DX:     Number of characters printed
436;   Corrupts registers:
437;       AX
438;--------------------------------------------------------------------
439%ifdef USE_PRINT_BOOL
440ALIGN JUMP_ALIGN
441Print_Bool:
442    mov     dl, '0'             ; Assume FALSE
443    test    ax, ax              ; Is FALSE?
444    jz      .Print              ;  If so, jump to print
445    inc     dx                  ; Increment to '1'
446ALIGN JUMP_ALIGN
447.Print:
448    PRINT_CHAR
449    mov     dx, 1               ; One character printed
450    ret
451%endif
452
453
454;--------------------------------------------------------------------
455; Prints signed or unsigned 16-bit integer.
456; 
457; Print_IntSW   Prints signed 16-bit word
458; Print_IntUW   Prints unsigned 16-bit word
459;   Parameters:
460;       AX:     Word to print
461;   Returns:
462;       DX:     Number of characters printed
463;   Corrupts registers:
464;       AX
465;--------------------------------------------------------------------
466%ifdef USE_PRINT_INTSW
467ALIGN JUMP_ALIGN
468Print_IntSW:
469    push    di                  ; Store DI
470    cmp     ax, 0               ; Positive integer?
471    jge     Print_IntUW         ;  If so, jump to print it
472    push    ax                  ; Store word
473    mov     dl, '-'             ; Print '-'
474    PRINT_CHAR
475    mov     di, 1               ; One character printed
476    pop     ax                  ; Restore word
477    neg     ax                  ; Negative to positive
478    jmp     Print_ContinueFromIntSW
479%endif
480
481%ifdef USE_PRINT_INTUW or USE_PRINT_INTSW
482ALIGN JUMP_ALIGN
483Print_IntUW:
484    push    di                  ; Store DI
485    xor     di, di              ; Zero character counter
486Print_ContinueFromIntSW:
487    push    bx                  ; Store BX
488    push    cx                  ; Store CX
489    mov     bx, 10              ; Load divisor to BX
490    mov     cx, 5               ; Load number of divisions to CX
491ALIGN JUMP_ALIGN
492.DivLoop:
493    xor     dx, dx              ; Zero DX for division
494    div     bx                  ; DX:AX / 10 => AX=quot, DX=rem
495    push    dx                  ; Push digit
496    loop    .DivLoop            ; Loop to separate all characters
497    xor     bx, bx              ; First char printed flag
498    mov     cl, 5               ; Load number of characters to CL
499ALIGN JUMP_ALIGN
500.PrintLoop:
501    pop     dx                  ; Pop character to DX
502    or      bx, dx              ; Still skipping zeroes?
503    loopz   .PrintLoop          ;  If so, loop
504    add     dx, '0'             ; Digit to character
505    PRINT_CHAR                  ; Print character
506    inc     di                  ; Increment chars printed
507    test    cx, cx              ; Characters left
508    jnz     .PrintLoop          ;  If so, loop
509    mov     dx, di              ; Copy chars printed to DX
510    pop     cx
511    pop     bx
512    pop     di
513    ret
514%endif
515
516
517;--------------------------------------------------------------------
518; Prints unsigned 32-bit integer.
519; 
520; Print_IntUDW
521;   Parameters:
522;       DX:AX:  32-bit unsigned integer to print
523;   Returns:
524;       DX:     Number of characters printed
525;   Corrupts registers:
526;       AX
527;--------------------------------------------------------------------
528%ifdef USE_PRINT_INTUDW
529ALIGN JUMP_ALIGN
530Print_IntUDW:
531    push    di                  ; Store DI
532    push    si                  ; Store SI
533    push    bx                  ; Store BX
534    push    cx                  ; Store CX
535    mov     cx, 10              ; Load divider to CX
536    mov     si, cx              ; Load number of divisions (10) to SI
537    xor     di, di              ; Zero DI (char counter)
538ALIGN JUMP_ALIGN
539.DivLoop:
540    call    Math_DivDWbyW       ; DX:AX / 10 => DX:AX=quot, BX=rem
541    push    bx                  ; Push digit
542    dec     si                  ; Decrement number of divisions
543    jnz     .DivLoop            ;  Loop while divisions left
544    xor     bx, bx              ; First char printed flag
545ALIGN JUMP_ALIGN
546.PrintLoop:
547    pop     dx                  ; Pop character to DX
548    or      bx, dx              ; Still skipping zeroes?
549    loopz   .PrintLoop          ;  If so, loop
550    add     dx, '0'             ; Digit to character
551    PRINT_CHAR                  ; Print character
552    inc     di                  ; Increment chars printed
553    test    cx, cx              ; Characters left
554    jnz     .PrintLoop          ;  If so, loop
555    mov     dx, di              ; Copy characters printed to DX
556    pop     cx
557    pop     bx
558    pop     si
559    pop     di
560    ret
561%endif
562
563
564;--------------------------------------------------------------------
565; Prints 8-bit byte as hexadecimal string.
566; 
567; Print_IntHexB
568;   Parameters:
569;       AL:     8-bit BYTE to print
570;   Returns:
571;       DX:     Number of characters printed
572;   Corrupts registers:
573;       AX
574;--------------------------------------------------------------------
575%ifdef USE_PRINT_INTHEXB
576ALIGN JUMP_ALIGN
577Print_IntHexB:
578    push    bx
579    xor     ah, ah              ; Zero AH, AX=word to print
580    mov     bx, 0FFh            ; Set to print two digits
581    call    Print_HexString     ; Print hex string
582    push    dx                  ; Store number of chars printed
583    mov     dl, 'h'             ; Print 'h' at the end
584    PRINT_CHAR
585    pop     dx                  ; Restore number of chars printed
586    inc     dx                  ; Increment for 'h'
587    pop     bx
588    ret
589%endif
590
591
592;--------------------------------------------------------------------
593; Prints 16-bit word as hexadecimal string.
594; 
595; Print_IntHexW
596;   Parameters:
597;       AX:     16-bit WORD to print
598;   Returns:
599;       DX:     Number of characters printed
600;   Corrupts registers:
601;       AX
602;--------------------------------------------------------------------
603%ifdef USE_PRINT_INTHEXW
604ALIGN JUMP_ALIGN
605Print_IntHexW:
606    push    bx
607    xor     bx, bx              ; Set to print all zeroes...
608    dec     bx                  ; ...BX = FFFFh
609    call    Print_HexString     ; Print hex string
610    push    dx                  ; Store number of chars printed
611    mov     dl, 'h'             ; Print 'h' at the end
612    PRINT_CHAR
613    pop     dx                  ; Restore number of chars printed
614    inc     dx                  ; Increment for 'h'
615    pop     bx
616    ret
617%endif
618
619
620;--------------------------------------------------------------------
621; Prints 32-bit dword as hexadecimal string.
622; 
623; Print_IntHexDW
624;   Parameters:
625;       DX:AX:  32-bit DWORD to print
626;   Returns:
627;       DX:     Number of characters printed
628;   Corrupts registers:
629;       AX
630;--------------------------------------------------------------------
631%ifdef USE_PRINT_INTHEXDW
632ALIGN JUMP_ALIGN
633Print_IntHexDW:
634    push    cx
635    push    bx
636    push    ax                  ; Store loword
637    mov     ax, dx              ; Copy hiword to AX
638    xor     bx, bx              ; Set to print all zeroes...
639    dec     bx                  ; ...BX = FFFFh
640    call    Print_HexString     ; Print hex string
641    mov     cx, dx              ; Copy number of chars printed
642    pop     ax                  ; Pop loword
643    call    Print_HexString     ; Print hex string
644    add     cx, dx              ; Add number of chars printed
645    mov     dl, 'h'             ; Print 'h' at the end
646    PRINT_CHAR
647    inc     cx                  ; Increment number of chars printed
648    mov     dx, cx              ; Copy number of chars printed to DX
649    pop     bx
650    pop     cx
651    ret
652%endif
653
654
655;-------------- Private functions --------------------
656
657;--------------------------------------------------------------------
658; Prints hexadecimal character for every nybble for WORD.
659; 
660; Print_HexString
661;   Parameters:
662;       AX:     16-bit WORD to print
663;       BX:     Mask for zero nybbles to print:
664;               FFFFh   = prints all digits
665;               0FFFh   = does not print digit 3 if it is zero
666;               00FFh   = does not print digits 3 and 2 if both are zeroes
667;               000Fh   = prints only digit 0 if other are zeroes
668;               0000h   = prints nothing if value is zero
669;   Returns:
670;       DX:     Number of characters printed
671;   Corrupts registers:
672;       AX
673;--------------------------------------------------------------------
674%ifdef USE_PRINT_INTHEXB or USE_PRINT_INTHEXW or USE_PRINT_INTHEXDW
675ALIGN JUMP_ALIGN
676Print_HexString:
677    push    bp
678    push    di
679    push    si
680    push    cx
681
682    mov     di, ax              ; Backup WORD to DI
683    mov     cl, 12              ; Prepare to shift nybbles
684    xor     dx, dx              ; Zero DX
685ALIGN JUMP_ALIGN
686.NybbleLoop:
687    mov     bp, bx              ; Copy mask to BP
688    mov     si, di              ; Copy WORD to SI
689    shr     bp, cl              ; Shift wanted mask nybble to BP
690    shr     si, cl              ; Shift wanted nybble to SI
691    and     bp, 0Fh             ; Clear unwanted mask bits
692    and     si, 0Fh             ; Clear unwanted bits
693    or      bp, si              ; Skip zeroes in front?
694    jz      .SkipPrint          ;  If so, skip printing
695    mov     dl, [cs:si+g_rgbHex]; Load char to DL
696    PRINT_CHAR                  ; Print character
697    inc     dh                  ; Increment characters printed
698.SkipPrint:
699    sub     cl, 4               ; Prepare to shift next nybble
700    jnc     .NybbleLoop         ; Loop while nybbles left
701    mov     dl, dh              ; Copy chars printed to DL
702    xor     dh, dh              ; Zero DH
703
704    pop     cx
705    pop     si
706    pop     di
707    pop     bp
708    ret
709%endif
Note: See TracBrowser for help on using the repository browser.