What's wrong with my build code

So, I am writing a game in C ++ for MS-DOS, and I include some built-in assemblies for speed. This particular block of code would draw a star in the video memory (0A000h). The problem with my code is that it only draws one pixel in any dh color. As far as I know mov dx, 00007h is equivalent to setting dh to 0 and dl to 7. What is wrong?

The equivalent C / C ++ code (or at least my intention) next to each line is indicated. My compiler is turbo C ++ 3.0. I am trying to use only instructions 8086/8088.

I also know how old MS-DOS doesn’t tell me to write code for a newer compiler / operating system. Writing code for dos is a kind of 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;
}
+5
source share
4

, di ax

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

, - "", ? , "movsb"?

+3

The lea instruction also exists in 16 bits:

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

Dirk

0
source

There is no need to increase the base with ax- first; there is also an addressing mode with an offset (also considered an absolute address)

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

To make this more useful, you can use it with an offset that can, for example. work as the center of your star:

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.

Using a segment redefinition prefix es:is expensive. Instead, I suggest using

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
0
source

All Articles