2017-11-22 2 views
-1

Guten Nachmittag, ich versuche, auf dem Bildschirm eine Reihe von Strings mit GUI Turbo Assembler TASM, das Problem, dass ich nicht alle Saiten nur die erste zeigen kann. Wenn jemand auf dem Bildschirm hilft mir die Saiten korrekt angezeigt werden und durch diese Anordnung bewegen, sehr grateful-In Bildschirm-Array mit Zeichen-GUI TASM Assembly drucken

Dies ist ein Beispiel in Borland C++

Example

Das tatsächlich in TASM:

Program in tasm

der Code ist der folgende.

.MODEL small 

.STACK 100h ; reserves 256 bytes of uninitialized storage 

.DATA 
startX equ 35 
startY equ 8 
y db ? 
x db ? 
t1 db ? 
t2 db ? 
t3 db ? 

zSprite db'M','M','L','E','E','N','A','E','V','E', 
    db'E','R','H','O','N','G','O','S','T','R', 
    db'X','X','O','T','I','R','R','A','C','A', 
    db'I','S','A','P','P','O','T','A','P','S', 
    db'C','C','M','L','A','A','I','Z','O','T', 
    db'O','A','A','U','A','N','U','L','P','U', 
    db'S','O','M','B','R','E','R','O','M','P', 
    db'C','N','E','A','R','R','I','I','O','O', 
    db'W','O','J','E','N','O','C','P','Z','E', 
    db'A','A','Z','A','A','L','N','Y','T','D' 


.386 ;enabled assembly of non privileged 80386 instructions 
.CODE 
start: 
;set DS to point to the data segment 
mov ax,@data 
mov ds,ax 

mov di,offset zSprite 

mov y,0 

l5: 
cmp y,10 
jl l0 
jmp l1 

l0: 
mov x,0 

l4: 
cmp x,10 
jl l2 
jmp l3 

l2: 
mov al,startX 
add al,x 
mov t1,al 

mov al,startY 
add al,y 
mov t2,al 

; set cursor position at (x,y) 
mov ah,02h ;set cursor position service 
mov bh,00h ;page number 
mov dh,t2 ;row 
mov dl,t1 ;column 
int 10h ;bios interrupt 

mov ax,0 ;reset ax 
mov al,y ;ax = y 
mov bx,10 
mul bx ;ax = ax * 10 
mov bx,0 ;reset bx 
mov bl,x ;bx = x 
add ax,bx ;ax = ax + x 
mov bx,ax 

; set color 
mov ah,09h ;service 
mov al, zSprite;character 
mov bh,00h ;page number 
mov bl,[bx+di] ;color 
mov cx,01h ;number of times to print character 
int 10h 

;print symbol 
mov ah, 02h 
mov dl, zSprite 
int 21h 

inc x 
jmp l4 

l3: 
inc y 
jmp l5 

l1: 
nop 

exit: 
;DOS: terminate the program 
mov ah,4ch ; mov ax, 4c00h 
mov al,0h 
int 21h 

delay PROC 
pop bx 

mov ax,1000d 
mov dx,ax 

delay1: 
mov cx,ax 

delay2: 
dec cx 
jnz delay2 
dec dx 
jnz delay1 

push bx 

ret 
delay ENDP 

END start 
+0

Ähm, dein ** eigener Kommentar ** sagt _ "mov al, 0feh; Charakter" _ ... das ** ist ** dein "Bild". – Jester

+0

Es tut mir leid für mein schlechtes Englisch. Ich weiß nicht, wie man die Buchstaben anstelle eines fehlerhaften Zeichens zeigt. Danke für Ihre Hilfe. – raintrooper

+0

Es ist nicht "falsch", es ist das, was Sie dem Programm gesagt haben. – Jester

Antwort

0

Hmm .. ich entschieden etwas erweiterte Version der Anzeigetafel zu schreiben ... Ich weiß, die rein Code Antworten nicht guten sind, aber ich viele Kommentare in den Code hinzugefügt, um es klar zu machen, wie es funktioniert.

Einige Hinweise über Konzepte verwendet:

Ich bin direkt in VGA text video memory zu schreiben, die Vermeidung BIOS/DOS-Dienste (sie sind langsam und umständlich in Fällen zu verwenden, wie Spielbrett Zeichnung).

Die Daten board enthalten nicht nur Buchstaben, sondern das obere Bit (80h Wert) jedes "Buchstaben" wird als verwendeter/unbenutzter Marker verwendet. Die Zeichenroutine ändert die Farbe des Buchstabens basierend auf dem Wert dieses Bits.

I.e. Der Wert 41h in der Karte funktioniert als "unbenutzt A", und der Wert 41h + 80h = 0C1h funktioniert als "gebraucht A".

Unbenutzte/verwendete Buchstaben haben eine hell/magenta/weiße Farbe, die aus dem verwendeten Bit berechnet wird und auch das 40h-Bit des Buchstaben-ASCII-Werts ausnutzt. (Ziffern hätten helle_red/gelbe Farben, wie '0' = 30h, so ASCII-Code von Ziffern enthält nicht 40h Bit gesetzt = andere Farbe Berechnungsergebnis).

Der Cursor wird durch Hinzufügen/Subtrahieren von Farbe zur ursprünglichen Buchstabenfarbe "gezeichnet" + "versteckt".


und der Wand des Codes (mit TASM 4.1 unter dosbox getestet):

.MODEL small 

.STACK 100h ; reserves 256 bytes of uninitialized storage 

.DATA 

BOARD_SIZE_X EQU  10 
BOARD_SIZE_Y EQU  10 
START_X   EQU  35 
START_Y   EQU  8 
CURSOR_COLOR EQU  0B0h  ; add "blink" + cyan background 

board LABEL BYTE 
    DB "MMLEENAEVE" 
    DB "ERHONGOSTR" 
    DB "XXOTIRRACA" 
    DB "ISAPPOTAPS" 
    DB "CCMLAAIZOT" 
    DB "OAAUANULPU" 
    DB "SOMBREROMP" 
    DB "CNEARRIIOO" 
    DB "WOJENOCPZE" 
    DB "AAZAALNYTD" 

cursor_x  db 5 
cursor_y  db 7 

.386 
.CODE 
start: 
    ;set DS to point to the data segment 
    mov  ax,@data 
    mov  ds,ax ; ds = data segment 
    mov  ax,0B800h 
    mov  es,ax ; es = text VRAM segment for direct VRAM writes 

    ; fake some characters being "used" to test drawing code 
    or  BYTE PTR [board+34],80h  ; mark the "POT" word 
    or  BYTE PTR [board+35],80h  ; on fourth line in middle 
    or  BYTE PTR [board+36],80h 

    call clear_screen 
    call draw_board 
    mov  dl,CURSOR_COLOR 
    call draw_cursor 

    ; wait for keystroke 
    xor  ah,ah 
    int  16h 

    ; fake "move cursor" 
    mov  dl,-CURSOR_COLOR  ; hide cursor on old position 
    call draw_cursor 
    inc  BYTE PTR [cursor_x]  ; move it up+right 
    dec  BYTE PTR [cursor_y] 
    mov  dl,CURSOR_COLOR   ; show cursor on new position 
    call draw_cursor 
    ; (other option would be to redraw whole board) 

    ; wait for keystroke before exit 
    xor  ah,ah 
    int  16h 
    ; exit to DOS 
    mov  ax,4C00h 
    int  21h 

; sets whole text video RAM to white "space" with red background 
; modifies ax, cx, di, assumes es=B800 
clear_screen PROC 
    xor  di,di ; B800:0000 target address 
    mov  ax,' ' + 4Fh*256 ; white space on red background 
    mov  cx,80*25 
    rep stosw  ; fill up video RAM with that 
    ret 
ENDP 

; redraws whole board to the video RAM, marks "used" characters too 
; modifies ax, cx, dx, si, di, assumes [email protected], es=B800 
draw_board PROC 
    mov  si,OFFSET board ; si = address of first letter of board 
    ; di = offset of starting position in video RAM 
    ; 2 bytes per char (char+color), 80 chars (160B) per line 
    mov  di,(START_Y*80 + START_X)*2 
    ; output BOARD_SIZE_Y lines 
    mov  dx,BOARD_SIZE_Y 
board_line_loop: 
    ; output BOARD_SIZE_X coloured characters 
    mov  cx,BOARD_SIZE_X 
board_char_loop: 
    lodsb   ; al = next character + used bit, advance si +1 
    mov  ah,al ; color of unused/used will be: 12 + 1 || 3 = 13 || 15 
    and  al,7Fh ; clear the top bit (used/unused): al = ASCII letter 
    shr  ah,6 ; ah = 1 || 3 (80h "used" bit + 40h bit from letter code) 
    add  ah,12 ; ah = 13 || 15 by "used" bit (magenda/white on black) 
    stosw   ; write letter+color to VRAM es:di, advance di +2 
    dec  cx 
    jnz  board_char_loop ; loop till whole line is displayed 
    ; move video ram pointer to start of next line 
    add  di,(80-BOARD_SIZE_X)*2 ; advance to start of next line 
    dec  dx 
    jnz  board_line_loop ; loop till every line is displayed 
    ret 
ENDP 

; Modifies letter color at current cursor position by adding DL 
; modifies ax, di, assumes [email protected], es=B800 
draw_cursor PROC 
    mov  al,[cursor_y] 
    mov  ah,160 
    mul  ah  ; ax = cursor_y * 160 
    movzx di,BYTE PTR [cursor_x] ; di = zero-extended cursor_x 
    add  di,di ; di *= 2 (cursor_x*2) 
    add  di,ax ; di += cursor_y * 160 
    ; add initial board offset and +1 to address attribute only 
    add  di,(START_Y*80 + START_X)*2 + 1 
    add  es:[di],dl ; modify letter color by adding DL 
    ret 
ENDP 

END start 

Befehle exe aufzubauen:

REM source file has name: wordgame.asm 
tasm /m5 /w2 /t /l wordgame 
tlink wordgame.obj 

Verwenden Turbo Debugger einzigen Schritt über Anweisungen, und beobachten Sie, wie sie den CPU-Zustand beeinflussen und wie sie Speicher ändern (setzen Sie unter Optionen den Bildschirm auf " swap always ", um den direkten Video-RAM auf dem Benutzerbildschirm sichtbar zu machen (Alt + F5). Versuche alles zu verstehen, auch deinen alten Code, wie er funktioniert und wo er Probleme hat.

+0

Vielen Dank für Ihre Hilfe. Ich werde es analysieren und meine Fehler überprüfen, um mehr zu erfahren. – raintrooper

+1

@raintrooper Leider erklärt das nicht die Probleme in deinem Code, aber das wäre viel mehr im Chat und ich bin sicher, du wirst in der Lage sein, einige von ihnen bald selbst zu identifizieren, da du mehr Erfahrung sammeln wirst. Holen Sie sich einfach einen Debugger (der Turbo-Debugger ist Teil der TASM-Installation) und lernen Sie, wie Sie einzelne Befehle überprüfen können. Versuchen Sie dann immer, Ihre Erwartungen mit den tatsächlichen CPU-Werten zu vergleichen. wie http://x86.renejeschke.de/ oder offizielle Intel-Dokumente). Auch wenn Sie bestimmte Dinge in meinem Code nicht verstehen, fragen Sie einfach. – Ped7g