Search code examples
assemblygraphicsx86vgax86-emulation

How do I color multiple pixels at the same time in x8086 assembly?


I'm using emu8086 on Windows 10 with VGA mode and 8-bit fixed RGBA pixel format, learning the basics of graphics and ASM just for fun. I found a way to draw one pixel at a time as shown in the code below:

org 100h       
mov ax, 13h 
int 10h       
mov ax, 40960
mov ds, ax
mov ax, 2Fh         
mov bx, 0 ; will hold addr of pxl to paint in.   
pntLnClr: 
mov [bx],ax ; paint color in ax into pixel at bx. 
inc bx
cmp bx, 40
JL pntLnClr
mov ah, 0 
int 16h 
ret

I want to write an ASM program that would paint multiple pixels at the same time instead of looping from pixel to pixel, making it look like a trail. I've been bouncing around SO and the rest of the Web trying to find a base code for accomplishing the objective but couldn't find anything. The accepted answer here seems like the closest thing to an answer, although it is unclear to me whether I actually need something like an extra segment and techniques like pushing and popping to access and write to multiple pixel addresses. Not only that, I tried the code from the answer, and the assembler told me that BITS is an illegal instruction and that the parameters in mov [es:di],dx are wrong.

[EDIT:] This question is coming from the idea of satisfying the goal of creating a 2D game-like demo with low resolution, something as simple as a board where the sprites and the background are on the same flat layer.


Solution

  • To iterate one of my comments from this thread:

    When running my assembly code with the mov [bx], ax instruction for painting pixels, every time this instruction is to be executed, my machine is using the CPU - already burdened with other tasks - to access and write to the screen memory (VRAM at A000H or B000H) all by itself, which takes up too much time. (See Refresh Rates, V-Sync Settings and Frame Buffers Explained on YouTube and 'Framebuffer' on Wiki.)

    [EDIT:] While you can access two bytes / one word at a time with rep stosw, that is still not enough to paint a whole image screen-size in a flash.

    In order to fulfill the goal of creating a 2D game-like demo (with or without scrolling ability), you would have to learn to capture a 320x200 part of a very large image. But to do that you have to learn to capture at least any 320x200 image. And to do that you would have to tap into the hardware directly or indirectly to store an image in a chunk of its memory. To do something like accessing the hardware indirectly you would need to write your own video driver. It was pointed out by a number of people that reinventing the wheel by way of doing all of this in Assembly is a tedious practice (as argued here). You are better off doing all of this in C unless there is a particular specialized task that cannot be accomplished in C.

    There may not be a need for a DMA to relieve the CPU of the accessing/writing operations. And in the '80s there were no graphics accelerators with graphics libraries and GPUs, which came in only in the early 90's to make animation much more fluid in worlds of higher definition. (See 'DMA' on Wiki.)