flat assembler
Message board for the users of flat assembler.

Index > Tutorials and Examples > VGA 13h mode for16bit MZ exe on DOS

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Kitsune



Joined: 17 Apr 2023
Posts: 18
Kitsune 17 Apr 2023, 17:22
Hi,

it's my first try to making a VGA app on MS-DOS with assembly.
I not created the code at all but copy paste some code from differents sources on the web.
I have some bug before it work well but now it's done!
Code:
format MZ
start:
        ;set the video mode to 13h (VGA 320*200 256 colors)
        mov ah,0
        mov al,13h
        int 10h

        ;draw pixel - 160 column, 100 row, color purple
        mov ah,0ch
        mov cx,160 ;column
        mov dx,100 ;row
        mov al,5   ;color
        int 10h

        ;wait for a keypress
        mov ah,00h
        int 16h

        ;set DOS default text mode
        mov ah,00h
        mov al,03h
        int 10h
        ;terminate the program
        mov ah,4ch
        int 21h
    


If you can suggest some optimization it's welcome!

_________________
Kitsune


Last edited by Kitsune on 17 Apr 2023, 17:46; edited 1 time in total
Post 17 Apr 2023, 17:22
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20298
Location: In your JS exploiting you and your system
revolution 17 Apr 2023, 17:25
I don't think it needs any optimising. It is a good example of how to do something specific without any distracting extras.
Post 17 Apr 2023, 17:25
View user's profile Send private message Visit poster's website Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1766
Roman 17 Apr 2023, 18:05
Quote:
draw pixel

Draw animated sprite. This is more practically !
Image

Using 0A0000h
Write directly pixel in video memory.

Or using back buffer to store all sprites, than copy from back buffer to video memory.


Last edited by Roman on 18 Apr 2023, 03:04; edited 2 times in total
Post 17 Apr 2023, 18:05
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 17 Apr 2023, 23:52
i suggest to familiarize with functions.

if you rewrite the code with calls and even macros, you will start to touch the power of fasm.

for example:
Code:
include "dosMZ.inc"

   vgaMode 13h
   putPixel 160,100,5
   waitForKey key.escape
   vgaMode 3
   dosExit

    


the dosMZ.inc file can be like this
Code:
format MZ


key:
.escape=0

macro vgaMode mode {
 mov ax,mode
 int 10h
}

macro putPixel x,y,color {
....
}


start:

    


it is to now to you to write the content of dosMz.inc based on what i've shown to you.
Post 17 Apr 2023, 23:52
View user's profile Send private message Visit poster's website Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 926
Location: Russia
macomics 18 Apr 2023, 01:37
Code:
key:
.escape=0x0127

macro videoMode mode=3 {
        mov     ax,mode and 255
        int     10h
}

macro setPixel x,y,color=7 {
        mov     cx, x
        mov     dx,y
        mov     ax,color and 255 + 12 * 256
        int     10h
}

macro waitKey key=0 { local .loop, .wait
  .loop:
        mov     ah, 17
        int     22
        pushf
  .wait:
        mov     ah, 16
        int 22
        popf
        jnz     .loop
  if key <> 0
        pushf
        cmp     ax, key
        jnz     .wait
        popf
  end if
}

macro sysExit status=0 {
        mov     ax, status and 255 + 76 * 256
        int     33
}

macro .code aim=$ {
segment @code
entry @code:aim
}    


Code:
format MZ
stack 1024
heap 0

include "dosMZ.inc"

.code $
   videoMode 19
   setPixel 160,100
   waitKey key.escape
   videoMode
   sysExit    
Post 18 Apr 2023, 01:37
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20298
Location: In your JS exploiting you and your system
revolution 18 Apr 2023, 06:15
edfed wrote:
i suggest to familiarize with functions.

if you rewrite the code with calls and even macros, you will start to touch the power of fasm.

for example:
Code:
include "dosMZ.inc"

   vgaMode 13h
   putPixel 160,100,5
   waitForKey key.escape
   vgaMode 3
   dosExit

    
This is really just HLL IMO. No assembly required. Razz
Post 18 Apr 2023, 06:15
View user's profile Send private message Visit poster's website Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1766
Roman 18 Apr 2023, 07:40
This is macros nice for writing game!
Post 18 Apr 2023, 07:40
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 18 Apr 2023, 07:56
It is just a tiny pixel in the center of the screen.

Kitsune wrote:

Code:
        ;draw pixel - 160 column, 100 row, color purple
    



Ah, I misunderstood it, I thought the function is to draw 160 columns x 100 rows rectangle.

Good beginning for you, Kitsune.


Description:
Filesize: 4.56 KB
Viewed: 6968 Time(s)

kitsune.png


Post 18 Apr 2023, 07:56
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 18 Apr 2023, 08:31
A slightly modified version to draw horizontal line:

Code:
DrawLine:
        mov cx,100   ;start of column
        mov dx,100   ;row
redraw:
        push cx
        push dx
        call DrawPixel
        pop dx
        pop cx
        inc cx         ;increment column, row unchanged
        cmp cx, 300    ;end of column
        jb redraw
        ret

DrawPixel:
        ;draw pixel - 160 column, 100 row, color purple
        mov ah,0ch
        mov al,5   ;color
        int 10h
        ret              


Oh, I just realized that I don't know how to draw diagonal line!
Post 18 Apr 2023, 08:31
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1389
Location: Piraeus, Greece
Picnic 18 Apr 2023, 10:38
I have an old VGA Snake-like program. Quite simple code. Both fasm and Tasm versions included. It may seem useful to someone.

Image


Description:
Download
Filename: VGA_SNAKE.zip
Filesize: 905 Bytes
Downloaded: 219 Time(s)

Post 18 Apr 2023, 10:38
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20298
Location: In your JS exploiting you and your system
revolution 18 Apr 2023, 10:44
FlierMate2 wrote:
Oh, I just realized that I don't know how to draw diagonal line!
Bresenham's line algorithm.
Post 18 Apr 2023, 10:44
View user's profile Send private message Visit poster's website Reply with quote
Kitsune



Joined: 17 Apr 2023
Posts: 18
Kitsune 18 Apr 2023, 11:22
Tanks for all your reply!

Roman wrote:
Quote:
draw pixel

Draw animated sprite. This is more practically !

Using 0A0000h
Write directly pixel in video memory.

Or using back buffer to store all sprites, than copy from back buffer to video memory.


I'am curious to how to do this (using the video memory in assembly language).

for now I have continue the first code and draw something with a loop to clear the screen and showing a sprite but I don't have back buffer so warning to your eyes:

Code:
format MZ
start:
        ;macro pixel
        macro pixel column,row{
                mov ah, 0ch    ;change color of one pixel    
                mov cx, column ;set column
                mov dx, row    ;set row
                mov al, 14     ;set color to yellow
                int 10h        ;put the pixel on screen
        }
        macro line start,endofline,row{
                mov cx, start
                repeat endofline-start 
                        pixel cx,row
                        inc cx
                end repeat
 
        }
        ;set the video mode to 13h (VGA 320*200 256 colors)
        mov ah,0
        mov al,13h
        int 10h

        mov eax, 1

        loop1:
        inc eax
        push eax

                ;draw lines of the sprite (start,end+1,row)
                line 160,165,100
                line 158,167,101
                line 157,168,102
                line 156,169,103
                line 156,169,104
                line 155,167,105
                line 155,164,106
                line 155,161,107
                line 155,164,108
                line 155,167,109
                line 156,169,110
                line 156,169,111
                line 157,168,112
                line 158,167,113
                line 160,165,114

                ;clear the screen
                mov ax,0A000h
                mov es,ax
                xor di,0
                xor al,0
                mov cx,64000
                rep stosb

        pop eax
        cmp eax,100
        jb loop1

        ;wait for a keypress
        mov ah,00h
        int 16h

        ;set DOS default text mode
        mov ah,00h
        mov al,03h
        int 10h
        ;terminate the program
        mov ah,4ch
        int 21h
    

_________________
Kitsune
Post 18 Apr 2023, 11:22
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 926
Location: Russia
macomics 18 Apr 2023, 11:39
Code:
        macro line start,endofline,row{
                mov cx, start
                repeat endofline-start 
                        pixel cx,row
                        inc cx
                end repeat
 
        }    
Don't do that. Using repeat, you do not create a loop in the program, but repeat the commands several times. At the same time, the size of the program code starts to grow very quickly, but in DOS you have limits on a 64 kb code segment!

If you want to create a loop, then use assembler commands with conditional jumps.
Code:
        macro line start,endofline,row{ local .loop
                mov cx, start
                .loop
                        pixel cx,row
                        inc cx
                cmp cx, endlofine
                jc .loop
 
        }    


There are no additional debugging tools included with fasm. And since you are just starting to write programs in assembler, then you should choose a good debugger for yourself so that it is easier to correct logical errors and correctly represent the result of the compiler.

Under DOS, I advise you to install TASM 5.0 and take the debugger TD.EXE from there. When you start writing programs for Windows, you should look at x64dbg.


Last edited by macomics on 18 Apr 2023, 11:44; edited 1 time in total
Post 18 Apr 2023, 11:39
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 18 Apr 2023, 11:41
revolution wrote:
FlierMate2 wrote:
Oh, I just realized that I don't know how to draw diagonal line!
Bresenham's line algorithm.


Thanks, I have some success!

Code:
format MZ
start:
        ;set the video mode to 13h (VGA 320*200 256 colors)
        mov ah,0
        mov al,13h
        int 10h

        mov [_x1], 280
        mov [_y1], 180
        mov [_x0], 40
        mov [_y0], 20
        call DrawLine

        ;wait for a keypress
        mov ah,00h
        int 16h

        ;set DOS default text mode
        mov ah,00h
        mov al,03h
        int 10h
        ;terminate the program
        mov ah,4ch
        int 21h

;Bresenham's line algorithm

_dx      dw      0
_dy      dw      0
_x1      dw      0
_x0      dw      0
_y1      dw      0
_y0      dw      0
_x       dw      0
_y       dw      0
_D       dw      0

;plotLine(x0, y0, x1, y1)
;    dx = x1 - x0
;    dy = y1 - y0
;    D = 2*dy - dx
;    y = y0
;
;    for x from x0 to x1
;        plot(x, y)
;        if D > 0
;            y = y + 1
;            D = D - 2*dx
;        end if
;        D = D + 2*dy
DrawLine:
        mov     dx, [_x1]
        mov     [_dx], dx
        mov     dx, [_x0]
        sub     [_dx], dx
        mov     dx, [_y1]
        mov     [_dy], dx
        mov     dx, [_y0]
        sub     [_dy], dx
        mov     ax, [_dy]
        mov     dx, 2
        mul     dx
        sub     ax, [_dx]
        mov     [_D], ax
        mov     cx, [_x0]
        mov     dx, [_y0]
        mov     [_y], dx   
redraw:
        push    cx
        mov     dx, [_y]
        call    DrawPixel
        cmp     [_D], 0
        jg      branch
        mov     ax, [_dy]
        mov     dx, 2
        mul     dx
        mov     dx, [_D]
        add     dx, ax
        mov     [_D], dx
        jmp     continue
branch:
        add     [_y], 1
        mov     ax, [_dx]
        mov     dx, 2
        mul     dx
        mov     dx, [_D]
        sub     dx, ax
        mov     [_D], dx
continue:
        pop     cx
        inc     cx
        cmp     cx, [_x1]
        jbe     redraw
        ret


DrawPixel:
        ;draw pixel - color purple
        mov ah,0ch
        mov al,5   ;color
        int 10h
        ret    


Maybe there is bug, the output is not 100% correct.


Description: Diagonal line
Filesize: 4.45 KB
Viewed: 6888 Time(s)

kitsune.png




Last edited by FlierMate2 on 18 Apr 2023, 12:45; edited 1 time in total
Post 18 Apr 2023, 11:41
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 926
Location: Russia
macomics 18 Apr 2023, 11:46
FlierMate2 wrote:
Thanks, I have some success!
It is worth adding checks for leaving the boundaries of the screen for drawing points.
Post 18 Apr 2023, 11:46
View user's profile Send private message Reply with quote
Kitsune



Joined: 17 Apr 2023
Posts: 18
Kitsune 18 Apr 2023, 12:05
macomics wrote:


If you want to create a loop, then use assembler commands with conditional jumps.
Code:
        macro line start,endofline,row{ local .loop
                mov cx, start
                .loop
                        pixel cx,row
                        inc cx
                cmp cx, endlofine
                jc .loop
 
        }    




Thanks for the tips, need a colon ":" after ".loop" and it work.

Code:
macro line start,endofline,row{
                local .loop
                mov cx, start
                .loop:
                        pixel cx,row
                        inc cx
                cmp cx, endlofine
                jc .loop
 
        }    

_________________
Kitsune
Post 18 Apr 2023, 12:05
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 18 Apr 2023, 12:18
macomics wrote:
FlierMate2 wrote:
Thanks, I have some success!
It is worth adding checks for leaving the boundaries of the screen for drawing points.


Thanks. Slightly better with boundary check:

Code:
DrawLine:
        mov     dx, [_x1]
        mov     [_dx], dx
        mov     dx, [_x0]
        sub     [_dx], dx  ;dx = x1 - x0
        mov     dx, [_y1]
        mov     [_dy], dx
        mov     dx, [_y0]
        sub     [_dy], dx  ;dy = y1 - y0
        mov     ax, [_dy]
        mov     dx, 2
        mul     dx
        sub     ax, [_dx]
        mov     [_D], ax   ; D = 2*dy - dx
        mov     cx, [_x0]  ;for x from x0 to x1
        mov     dx, [_y0]
        mov     [_y], dx   ;y = y0
redraw:
        push    cx
        mov     dx, [_y]
        call    DrawPixel  ;plot(x, y)
        cmp     [_D], 0
        jg      branch     ;if D > 0
        mov     ax, [_dy]
        mov     dx, 2
        mul     dx
        mov     dx, [_D]
        add     dx, ax
        mov     [_D], dx   ;D = D + 2*dy
        jmp     continue
branch:
        add     [_y], 1   ;y = y + 1
        mov     ax, [_dx]
        mov     dx, 2
        mul     dx
        mov     dx, [_D]
        sub     dx, ax
        mov     [_D], dx  ;D = D - 2*dx
continue:
        pop     cx
        inc     cx
        cmp     cx, 320
        jae     quit
        mov     dx, [_y]
        cmp     dx, 200
        jae     quit
        cmp     cx, [_x1]  ;for x from x0 to x1
        jbe     redraw
quit:
        ret      


But it is not 40-280 for x, and 20-180 for y. Hmm....

I think either I follow the wrong code or I have bug when translating it to Assembly code. Sorry everyone.


Description:
Filesize: 5.22 KB
Viewed: 6868 Time(s)

kitsune.png




Last edited by FlierMate2 on 18 Apr 2023, 12:44; edited 1 time in total
Post 18 Apr 2023, 12:18
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 18 Apr 2023, 12:44
I know why it doesn't work, need to test for signed integer, NOT unsigned.

This is the correction:
Code:
        cmp     [_D], 0
        jg      branch     ;if D > 0        


...instead of "ja branch".

Also, might need to decrement "x" if x0 is greater than x1.
Currently it assumes x1 is always greater than x0.

Code:
        mov [_x1], 280
        mov [_y1], 100
        mov [_x0], 40
        mov [_y0], 50
        call DrawLine

        mov [_x1], 280
        mov [_y1], 80
        mov [_x0], 40
        mov [_y0], 80
        call DrawLine          

        mov [_x1], 300
        mov [_y1], 180
        mov [_x0], 20
        mov [_y0], 20
        call DrawLine        


Description:
Filesize: 6.24 KB
Viewed: 6841 Time(s)

kitsune.png


Post 18 Apr 2023, 12:44
View user's profile Send private message Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1766
Roman 18 Apr 2023, 14:06
Write antialiasing for lines Smile
Post 18 Apr 2023, 14:06
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 18 Apr 2023, 14:43
Roman wrote:
Write antialiasing for lines Smile


https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
(Xiaolin Wu's line algorithm)

Cool
Post 18 Apr 2023, 14:43
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.