How to make drawing program to work on 200x320 pixels (instead of 200x255) assembly?

Viewed 85

I have a simple drawing program, when pressing arrow keys, a pixel "snake" moves to that direction. My problem that the program works on 200x255 pixels but I would like to make it work on 200x 320 pixels. So I need to store the x coordinate in a 16 bit register instead of 8 bit one (max 255 pixels). I tried to rewrite it but this stuff is a little bit too advanced to me because of the pixel calculation and I can't find help.

Draw:   //I calculate the pixel position like Pixel = Y * 320 + X
    pop dx
    xor ah, ah
    mov al, dh
    push dx
    mov bx, 320
    mul bx
    pop dx
    add al, dl
    jnc Pixel
    inc ah

Pixel: //Color and stuff
    push dx
    mov di, ax
    mov al, [si]
    mov es:[di], al

//I read input key and then decide where to display pixel

Left:
    pop dx
    dec dl
    cmp dl, 1

    jnc Store
    inc dl
    jmp Store

Right: //I need 320 and 16 bit register here instead of dl
    pop dx
    inc dl
    cmp dl, 250

    jc Store
    dec dl
    jmp Store

Up:
    pop dx
    dec dh
    cmp dh, 1

    jnc Store
    inc dh
    jmp Store

Down:
    pop dx
    inc dh
    cmp dh, 200

    jc Store
    dec dh
    jmp Store

Store:
    push dx
    jmp Draw

Thank you so much for your help

2 Answers

As you can see in the lines of Draw: dh is used for Y, dl is used for X. Both are 8-bit and the higher or lower half of the 16-bit register dx, respectively. cx seems to be used nowhere in your program. Also bp (which in other programs is often used to access variables on the stack) is available.

By the way, the push dx and pop dx is only needed to prevent dh and dl from being overwritten. On a quick glance I see mul as only command, which would do that. This could, if those are used nowhere else, not be needed for cx or bp.

Probably a better strategy for push/pop would be to save the value before it is overwritten by mul and restore it after the result of mul is not needed anymore, instead of loading and storing dx at every use on the stack.

How to make drawing program to work on 200x320 pixels (instead of 200x255) assembly?

These resolutions look very unfamiliar. Normally we would specify this as XRes x YRes.


Your current program uses the byte-sized registers DL for X and DH for Y. This suits your 255x200 resolution where no single value has to exceed 255. If you want to move on to the larger 320x200 resolution, then use the word-sized registers CX for X and DX for Y. Those are also the choice that BIOS has made for specifying coordinates. Always nice to go with the flow!

It's hard to follow how you use the stack for storage of the coordinates. I think you could simplify this ...

Next solution expects the (X,Y) to stay within a rectangle that respects a border of 5 pixels around the screen. Change the numbers as you need:

XRES equ 320
YRES equ 200
BORDER equ 5  ; Resolution 320x200 --> X=[5,314] Y=[5,194]

; assuming CX contains X and DX contains Y
Left:
    cmp  cx, BORDER + 1
    cmc
    sbb  cx, 0
    jmp  Draw
Right:
    cmp  cx, XRES - BORDER - 1
    adc  cx, 0
    jmp  Draw
Up:
    cmp  dx, BORDER + 1
    cmc
    sbb  dx, 0
    jmp  Draw
Down:
    cmp  dx, YRES - BORDER - 1
    adc  dx, 0
    jmp  Draw

Using word-sized registers the calculation of the address is now much simpler:

Draw:
    push dx
    mov  ax, XRES
    mul  dx           ; DX:AX == Y * 320
    pop  dx
    add  ax, cx       ; AX == Y * 320 + X
    mov  di, ax
    ...

And if you're not limited to then this becomes:

Draw:
    imul di, dx, XRES ; DI == Y * 320
    add  di, cx       ; DI == Y * 320 + X
    ...
Related