2015-09-17 50 views
2

我正在使用TASM 1.4,我試圖做一個輸出,將顯示不同顏色的句子,都在同一個屏幕上。我可以製作顯示彩色文本的東西,但所有文字都具有相同的顏色。我如何製作顯示不同顏色的字符串/句子的東西? 例如,像:TASM 1.4 - 顯示特定的彩色字符串?

Hi, what group would you like to join? 
The Founders 
The Vox Populi 

隨着「嗨,你想哪個組加入?」綠色。 「創始人」染成藍色。而「Vox Populi」紅色,也許我想要另一個閃爍的句子?我只能將它們全部顯示爲藍色或紅色或綠色。任何幫助? 謝謝。

+1

的可能重複[?TASM 1.4 - 改變背景顏色,但不清除屏幕(http://stackoverflow.com/questions/32619237/tasm-1 -4-changing-background-color-without-clearing-the-screen) –

+0

@RossRidge嗨!呃,不,這實際上是一個不同的問題。在那裏,我試圖改變輸入背景而不清除以前的文本,但在這裏,我只是試圖在同一屏幕上顯示不同的彩色文本。 – xTan

+1

如果我的模糊內存是正確的,DOS中斷不是很好。 BIOS中斷10h,子功能13h可能是你想要的。甚至會做「彩虹」文字,每個角色都有不同的顏色。你認識拉爾夫布朗嗎? –

回答

4

您可以使用INT 10h/AH=13h用於這一目的:

.MODEL small 
.STACK 1000h 

.DATA 
    msg1 db "Hi, what group would you like to join?", 13, 10 
    msg1_len = $ - msg1 
    msg2 db "The Founders", 13, 10 
    msg2_len = $ - msg2 
    msg3 db "The Vox Populi", 13, 10 
    msg3_len = $ - msg3 
    msg4 db "Blinkers", 13, 10 
    msg4_len = $ - msg4 

.CODE 

main PROC 
    mov ax, @data 
    mov ds, ax    ; Don't forget to initialize DS! 
    mov es, ax    ; Segment needed for Int 10h/AH=13h 

    lea bp, msg1   ; ES:BP = Far pointer to string 
    mov cx, msg1_len  ; CX = Length of string 
    mov bl, 2    ; green (http://stackoverflow.com/q/12556973/3512216) 
    call print 

    lea bp, msg2   ; ES:BP = Far pointer to string 
    mov cx, msg2_len  ; CX = Length of string 
    mov bl, 3    ; blue (http://stackoverflow.com/q/12556973/3512216) 
    call print 

    lea bp, msg3   ; ES:BP = Far pointer to string 
    mov cx, msg3_len  ; CX = Length of string 
    mov bl, 4    ; red (http://stackoverflow.com/q/12556973/3512216) 
    call print 

    lea bp, msg4   ; ES:BP = Far pointer to string 
    mov cx, msg4_len  ; CX = Length of string 
    mov bl, 8Eh    ; blinking yellow (Bit7 set, works at least in DOSBox) 
    call print 

    mov ax, 4C00h   ; Return 0 
    int 21h 
main ENDP 

print PROC     ; Arguments: 
          ; ES:BP Pointer to string 
          ; CX  Length of string 
          ; BL  Attribute (color) 

    ; http://www.ctyme.com/intr/rb-0088.htm 
    push cx     ; Save CX (needed for Int 10h/AH=13h below) 
    mov ah, 03h    ; VIDEO - GET CURSOR POSITION AND SIZE 
    xor bh, bh    ; Page 0 
    int 10h     ; Call Video-BIOS => DX is current cursor position 
    pop cx     ; Restore CX 

    ; http://www.ctyme.com/intr/rb-0210.htm 
    mov ah, 13h    ; VIDEO - WRITE STRING (AT and later,EGA) 
    mov al, 1    ; Mode 1: move cursor 
    xor bh, bh    ; Page 0 
    int 10h     ; Call Video-BIOS 

    ret 
print ENDP 

END main 
+0

只是一個側面說明,閃爍的地方不會工作是在32位Windows DOS提示 –

+0

@MichaelPetch:第二個是emu8086。但是這個問題涉及到「TASM 1.4」,也就是DOSBox--就像你剛纔提到的那樣,我查了一下。 – rkhb

+0

我之所以提到它的原因是因爲像我一樣評論了閃爍的黃色閃爍(Bit7集合,至少在DOSBox中有效),有人可能想知道你和我所暗指的環境可能不支持它,正如我所說的是一個側面說明,並沒有說我沒有看到你的內聯評論;-)。而且值得眨眼的東西似乎在Bochs中得到了支持。我做了 - 投票你的答案,因爲它是另一種方式來剝皮這隻貓。 –

4

我打算提供一種實現DOS的方法int 21h

原始海報稱他們使用的是TASM 1.4(TASM安裝程序),它是基於DOSBox的環境,包含TASM 3.0和Turbo Debugger 3.1。在DOS的時代,有一個視頻控制檯驅動程序,可以通過DEVICE=C:\DOS\ANSI.SYS等命令將其添加到CONFIG.SYS。此驅動程序增強了DOS int 21h輸出,因此您可以指定屬性(背景色,前景色,閃爍);清除屏幕;重置回默認值(通常是白色的黑色)。 DOSBox中有一個部分實現建在ANSI.SYS的下面的代碼利用這些ANSI codes的:

.model small 
.stack 100h 

.data 
a_cls  db 27, "[2J$" ; Clear entire screen in currently set attributes 
a_reset  db 27, "[0m$" ; Reset attributes to standard (black on white) 
a_blink  db 27, "[5m$" ; Characters blink (blink doesn't work in all environments) 
a_bright  db 27, "[1m$" ; Bright colored characters 
a_dim  db 27, "[2m$" ; Dim colored characters 
a_fg_black db 27, "[30m$" ; Foreground colors 
a_fg_red  db 27, "[31m$" 
a_fg_green db 27, "[32m$" 
a_fg_yellow db 27, "[33m$" 
a_fg_blue db 27, "[34m$" 
a_fg_magenta db 27, "[35m$" 
a_fg_cyan db 27, "[36m$" 
a_fg_white db 27, "[37m$" 
a_bg_black db 27, "[40m$" ; Background colors 
a_bg_red  db 27, "[41m$" 
a_bg_green db 27, "[42m$" 
a_bg_yellow db 27, "[43m$" 
a_bg_blue db 27, "[44m$" 
a_bg_magenta db 27, "[45m$" 
a_bg_cyan db 27, "[46m$" 
a_bg_white db 27, "[47m$" 

text1  db "Blinking Bright Yellow on Blue$" 
text2  db " Back to Normal$" 
text3  db " Bright Yellow on Black$" 
combined  db 27, "[0;5;2;31;42m Blinking Dim Red on Green$" 

.code 
begin: 
    mov ax,@data 
    mov ds,ax 
    mov es,ax 
    mov ah,09h 
    lea dx,a_cls  ; clear screen 
    int 21h   
    lea dx,a_bright ; Bright colored characters 
    int 21h 
    lea dx,a_blink ; make the characters blink (if supported) 
    int 21h 
    lea dx,a_fg_yellow; make the characters yellow 
    int 21h 
    lea dx,a_bg_blue ; blue background for characters 
    int 21h 
    lea dx,text1  ; print text 
    int 21h 
    lea dx,a_reset ; reset to defaults 
    int 21h 
    lea dx,text2  ; print normal text 
    int 21h 
    lea dx,a_bright ; bright characters 
    int 21h 
    lea dx,a_fg_yellow; make the characters yellow 
    int 21h 
    lea dx,text3  ; print text 
    int 21h 
    lea dx,combined ; print combined text 
    int 21h 
    lea dx,a_reset ; reset to defaults before exiting back to DOS prompt 
    int 21h 
    .exit 
end begin 

在DOS中,ANSI碼開始與ESCAPE字符(十進制27),接着[(左括號)。對於屬性,可以使用命令m命令。屬性可以用分號分隔。除m之外還有一些其他命令,它們可以在ANSI specs中找到。如果您查看上面的代碼,您會看到我已經在ANSI代碼中分出了許多可能對原始海報感興趣的命令。

以下代碼是組合大量屬性(使用ANSI)而不是單獨執行它們的一個示例。

combined  db 27, "[0;5;2;31;42mBlinking Dim Red on Green$" 

爆發了,我們開始與ESCAPE[。 將當前屬性重置爲默認值(大多數硬件是黑色的白色)。其餘屬性由SEMI COLONS分隔。的下一個屬性閃爍,接下來是其變暗顏色,是前景色紅色,是綠色背景後跟命令m結束命令,之後的字符是要打印的文本。

基於前面的代碼轉義序列,下面將履行的具體問題的海報問:

.model small 
.stack 100h 

.data 
a_reset  db 27, "[0m$" ; Reset attributes to standard (black on white) 

      ; 13, 10 is carriage return line feed combination(CR/LF) 
line1  db 27, "[1;32mHi, what group would you like to join?", 13, 10, "$" 
line2  db 27, "[1;34mThe Founders", 13, 10, "$" 
line3  db 27, "[1;31mThe Vox Populi", 13, 10, "$" 
line4  db 27, "[1;5;31;47mand maybe I'd want another sentence that blinks?$" 

.code 
begin: 
    mov ax,@data 
    mov ds,ax 
    mov es,ax 
    mov ah,09h 
    lea dx,line1  ; print line 1 (bright green) 
    int 21h 
    lea dx,line2  ; print line 2 (bright blue) 
    int 21h 
    lea dx,line3  ; print line 3 (bright red) 
    int 21h 
    lea dx,line4  ; print line 4 (blinking bright red on white background) 
    int 21h 
    lea dx,a_reset ; reset colors back to default before exiting 
    int 21h 
    .exit 
end begin 

閃爍已知在DOSBox中,VMWare的,Bochs的工作,但沒有工作, emu8086和Windows NT + DOS提示符。

在這張海報的其他評論中,其他related question我的確提出了另一種方法,即編寫一個程序或函數,它需要一個字符串並使用DOS中斷和/或BIOS中斷來逐字改變字符的屬性並將它們顯示在屏幕上(同時跟蹤光標)。最有效的方法是直接將屬性寫入視頻內存(即0xb000:0)。上面我使用的ANSI.SYS方法是最簡單的,並且應該在現代版本的DOSBox中默認使用。