2012-06-15 4 views
5

Quindi sto scrivendo un gioco in C++ per MS-DOS e sto includendo alcuni assembly inline per la velocità. Questo particolare blocco di codice disegnerebbe una stella nella memoria video (0A000h). Il problema con il mio codice è che disegna solo un pixel in qualunque colore dh sia impostato. Per quanto ne so mov dx, 00007h equivale a impostare dh a 0 e dl a 7. Cosa c'è che non va?Cosa c'è di sbagliato con il mio codice assembly

L'equivalente codice C/C++ (o almeno la mia intenzione) viene commentato accanto a ciascuna riga. Il mio compilatore è turbo C++ 3.0. Sto provando a usare solo le istruzioni 8086/8088.

Inoltre so quanti anni MS-DOS è così non mi dicono di scrivere codice per un più recente compilatore/sistema operativo. Scrivere codice per dos è una specie di mio hobby.

pixelOffset = x + (y << 6) + (y << 8); 

_asm { 
    mov ax, WORD PTR pixelOffset 
    mov di, ax 
    mov ax, 0A000h   ;pointer to the video memory 
    mov es, ax 
    mov dx, 00007h   ;indexed color 00 and 07 
    mov cx, 0000Fh   ;indexed color white 0F 
    add ax, 2    ;pixelOffset += 2; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 319   ;pixelOffset += 319; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 317   ;pixelOffset += 317; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], cx  ;videomem[pixelOffset] = WHITE; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 317   ;pixelOffset += 317; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 319   ;pixelOffset += 319; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
} 
+4

Stai scrivendo * a ** DOS ** gioco? È fantastico. –

+0

+1 per la nostalgia del gioco MS-DOS! –

+0

@John Dibling: ya e lo metto su sourceforge quando ho finito – PgrAm

risposta

5

penso che si è dimenticato di aggiornare di dopo l'aggiornamento ascia

add ax,1 
mov di,ax ;don't forget this line 
mov es:[di],dl 
+0

grazie mille ora funziona. Sono davvero pessimo all'assemblaggio – PgrAm

+1

Di solito sto programmando solo a 32 bit, ma suppongo che l'istruzione 'inc' esista a 16-bit. Non puoi semplicemente usare 'inc di' senza tornare all'ascia comunque? Non vedo davvero perché non stai solo modificando 'di' direttamente tutto il tempo. – Nyerguds

3

Non sembra che tu abbia mai incrementato "di", vero? Forse intendevi "movsb"?

0

L'istruzione lea esistono anche in 16 bit:

lea di,[di+1] ; substitute for "inc di" and/or "add di,1" , if we do not need a flag 

Dirk

0

Non c'è alcuna necessità di incrementare la base utilizzando ax - prima; c'è anche il modo di indirizzamento con spostamento solo (considerato anche come indirizzo assoluto)

mov es:[1001], dh 
mov es:[1002], dl 
mov es:[1535], cl 

Per rendere più utile che - è possibile utilizzare quello con offset, che potrebbe ad esempio. lavorare come il centro della vostra stella:

mov es:[di - WIDTH], ... ;; pixel/character above the current cursor 
mov es:[di + WIDTH], ... ;; pixel/char below 
mov es:[di + 1], ...  ;; pixel right to the origin etc. 

Utilizzando il prefisso override di segmento es: è costoso. Invece suggerirei di usare

mov ax, 0a000h 
push ds 
mov ds, ax 
// 
mov [di + offset], cl  ;; this pays off when writing several pixels 
// 
pop ds    ;; restore DS after you have copied your stuff