flat assembler
Message board for the users of flat assembler.
Index
> Tutorials and Examples > VGA 13h mode for16bit MZ exe on DOS Goto page Previous 1, 2 |
Author |
|
FlierMate2 18 Apr 2023, 16:52
macomics wrote:
Yes, it works (like mine), but shorter. I didn't know add twice is equal to multiply by two, . And I learned stack handling from you too. But it still not able to draw vertical line, and does not draw diagonal line from lower left to upper right. I mean the following still don't work. Code: push 100 push 20 push 100 push 180 call DrawLine push 180 push 40 push 30 push 280 call DrawLine |
|||
18 Apr 2023, 16:52 |
|
Roman 18 Apr 2023, 17:17
Quote: push 100 Using linesArray and one call for draws many lines ! Code: dw 2 LinesArr dw ;first line dw ;second line Mov ax,LinesArr Mov cx,[LinesArr-2] ;how many lines draw Call drawAllLines |
|||
18 Apr 2023, 17:17 |
|
macomics 18 Apr 2023, 18:09
You just implemented only half of the algorithm. Here's the whole thing.
Code: use16 org 256 mov ax, 19 int 16 push 7 push 100 push 20 push 100 push 180 call DrawLine push 3 push 180 push -40 push 30 push 380 call DrawLine push 7 push 20 push 100 push 180 push 100 call DrawLine push 3 push 280 push 280 push -40 push 30 call DrawLine mov ax, 0 int 22 mov ax, 3 int 16 mov ax, 0x4C00 int 33 DrawPixel: cmp cx, 0 jl .out_of_bounds cmp cx, 320 jge .out_of_bounds cmp dx, 0 jl .out_of_bounds cmp dx, 200 jge .out_of_bounds push ax mov ah, 12 int 16 pop ax .out_of_bounds: retn DrawPixelRev: xchg cx, dx call DrawPixel xchg cx, dx retn ; push color ; push y1 ; push x1 ; push y0 ; push x0 ; call DrawLine DrawLine: label .x0 word at bp + 10 label .y0 word at bp + 12 label .x1 word at bp + 14 label .y1 word at bp + 16 label .color byte at bp + 18 label .plt word at bp - 2 label .D word at bp - 4 label .dv word at bp - 6 label .cx word at bp - 8 push di push si push bx push bp mov bp, sp sub sp, 8 mov di, [.y1] mov bx, [.x1] mov dx, [.y0] mov cx, [.x0] mov [.cx], 320 sub dx, di ; dx = y0 - y1 jns @f neg dx ; if y0 - y1 < 0 then dx = y1 - y0 @@: sub cx, bx ; cx = x0 - x1 jns @f neg cx ; if x0 - x1 < 0 then cx = x1 - x0 @@: mov si, DrawPixel cmp cx, dx ; if abs(x0 - x1) > abs(y0 - y1) mov cx, [.x0] mov dx, [.y0] jg @f mov si, DrawPixelRev xchg cx, dx xchg bx, di mov [.cx], 200 @@: mov [.plt], si cmp cx, bx jle @f xchg cx, bx xchg dx, di @@: mov al, [.color] mov si, bx ; si = u1 mov [.dv], 1 ; v` = 1 sub si, cx ; si = u1 - u0 sub di, dx ; di = v1 - v0 jge @f ; if v1 - v0 < 0: neg di ; di = v0 - v1 neg [.dv] ; v` = -1 @@: add di, di ; di = 2*dv mov [.D], di ; D = 2*dv sub [.D], si ; D = 2*dv - du add si, si ; si = 2*du sub si, di ; si = 2*(du - dv) cmp cx, 0 jge @f xor cx, cx cmp cx, bx jg .break @@: call [.plt] ; plot(cx, dx, al) cmp [.D], 0 jle .else ; if D > 0 sub [.D], si ; D = D + 2*(du - dv) add dx, [.dv] ; v = v + v` jmp .endif .else: add [.D], di ; D = D + 2*dy .endif: inc cx cmp cx, [.cx] jge .break cmp cx, bx ; for x from x0 to x1 jle @b .break: leave pop bx pop si pop di retn 10 ADD: Updated yesterday's version. Corrected the error and removed two identical routines. Now everything is completed in one.
|
||||||||||
18 Apr 2023, 18:09 |
|
macomics 19 Apr 2023, 13:06
Latest
Code: use16 org 256 mov ax, 19 int 16 push 7 push 100 push 20 push 100 push 180 call DrawLine push 3 push 180 push -40 push 30 push 380 call DrawLine push 5 push 20 push 100 push 180 push 100 call DrawLine push 8 push 280 push 280 push -40 push 30 call DrawLine mov ax, 0 int 22 mov ax, 3 int 16 mov ax, 0x4C00 int 33 DrawPixel: cmp cx, 0 jl .out_of_bounds cmp cx, 320 jge .out_of_bounds cmp dx, 0 jl .out_of_bounds cmp dx, 200 jge .out_of_bounds push ax mov ah, 12 int 16 pop ax .out_of_bounds: retn DrawPixelRev: xchg cx, dx call DrawPixel xchg cx, dx retn ; push color ; push y1 ; push x1 ; push y0 ; push x0 ; call DrawLine DrawLine: label .x0 word at bp + 10 label .y0 word at bp + 12 label .x1 word at bp + 14 label .y1 word at bp + 16 label .color byte at bp + 18 label .p word at bp - 2 label .D word at bp - 4 label .v word at bp - 6 push di push si push bx push bp mov bp, sp lea sp, [.v] mov di, [.y1] mov bx, [.x1] mov dx, [.y0] mov cx, [.x0] mov ax, 320 sub dx, di ; dx = y0 - y1 jns @f neg dx ; if y0 - y1 < 0 then dx = y1 - y0 @@: sub cx, bx ; cx = x0 - x1 jns @f neg cx ; if x0 - x1 < 0 then cx = x1 - x0 @@: mov si, DrawPixel cmp cx, dx ; if abs(x0 - x1) > abs(y0 - y1) mov cx, [.x0] mov dx, [.y0] jg @f add si, DrawPixelRev - DrawPixel xchg cx, dx xchg bx, di add ax, 200 - 320 @@: mov [.p], si cmp cx, bx jle @f xchg cx, bx xchg dx, di @@: cmp bx, ax jl @f mov bx, ax dec bx @@: mov si, bx ; si = u1 mov [.v], 1 ; v` = 1 sub si, cx ; si = u1 - u0 sub di, dx ; di = v1 - v0 jge @f ; if v1 - v0 < 0: neg di ; di = v0 - v1 neg [.v] ; v` = -1 @@: mov al, [.color] add di, di ; di = 2*dv mov [.D], di ; D = 2*dv sub [.D], si ; D = 2*dv - du add si, si ; si = 2*du sub si, di ; si = 2*(du - dv) cmp cx, 0 jge @f xor cx, cx cmp cx, bx jg .break @@: call [.p] ; plot(cx, dx, al) cmp [.D], 0 jle .else ; if D > 0 sub [.D], si ; D = D + 2*(du - dv) add dx, [.v] ; v = v + v` jmp .endif .else: add [.D], di ; D = D + 2*dv .endif: inc cx cmp cx, bx ; for x from x0 to x1 jle @b .break: leave pop bx pop si pop di retn 10 Last edited by macomics on 19 Apr 2023, 13:13; edited 1 time in total |
|||
19 Apr 2023, 13:06 |
|
revolution 19 Apr 2023, 13:11
If I wanted to draw a line from 10,10 to -10,-10 I would hope to see a line on the output going from 10,10 to 0,0 and the remaining out-of-bounds portion discarded.
Last edited by revolution on 19 Apr 2023, 14:20; edited 1 time in total |
|||
19 Apr 2023, 13:11 |
|
macomics 19 Apr 2023, 13:20
I wanted to reduce the number of iterations of the line drawing cycle, but I did not consider that there are two coordinates there and it is necessary to recalculate cx and dx. For now, it can simply be removed. Then I will recalculate dx, so that the loop does not iterate with negative cx
Code: use16 org 256 mov ax, 19 int 16 push 7 push 100 push 20 push 100 push 180 call DrawLine push 3 push 180 push -40 push 30 push 380 call DrawLine push 5 push 20 push 100 push 180 push 100 call DrawLine push 8 push 280 push 280 push -40 push 30 call DrawLine push 14 push -10 push -10 push 10 push 10 call DrawLine mov ax, 0 int 22 mov ax, 3 int 16 mov ax, 0x4C00 int 33 DrawPixel: cmp cx, 320 jae .out_of_bounds cmp dx, 200 jae .out_of_bounds push ax mov ah, 12 int 16 pop ax .out_of_bounds: retn DrawPixelRev: xchg cx, dx call DrawPixel xchg cx, dx retn ; push color ; push y1 ; push x1 ; push y0 ; push x0 ; call DrawLine DrawLine: label .x0 word at bp + 10 label .y0 word at bp + 12 label .x1 word at bp + 14 label .y1 word at bp + 16 label .color byte at bp + 18 label .p word at bp - 2 label .D word at bp - 4 label .v word at bp - 6 push di push si push bx push bp mov bp, sp lea sp, [.v] mov di, [.y1] mov bx, [.x1] mov dx, [.y0] mov cx, [.x0] mov ax, 320 sub dx, di ; dx = y0 - y1 jns @f neg dx ; if y0 - y1 < 0 then dx = y1 - y0 @@: sub cx, bx ; cx = x0 - x1 jns @f neg cx ; if x0 - x1 < 0 then cx = x1 - x0 @@: mov si, DrawPixel cmp cx, dx ; if abs(x0 - x1) > abs(y0 - y1) mov cx, [.x0] mov dx, [.y0] jg @f add si, DrawPixelRev - DrawPixel xchg cx, dx xchg bx, di add ax, 200 - 320 @@: mov [.p], si cmp cx, bx jle @f xchg cx, bx xchg dx, di @@: cmp bx, ax jl @f mov bx, ax dec bx @@: mov si, bx ; si = u1 mov [.v], 1 ; v` = 1 sub si, cx ; si = u1 - u0 sub di, dx ; di = v1 - v0 jge @f ; if v1 - v0 < 0: neg di ; di = v0 - v1 neg [.v] ; v` = -1 @@: mov al, [.color] add di, di ; di = 2*dv mov [.D], di ; D = 2*dv sub [.D], si ; D = 2*dv - du add si, si ; si = 2*du sub si, di ; si = 2*(du - dv) ; cmp cx, 0 ; jge @f ; xor cx, cx ; cmp cx, bx ; jg .break @@: call [.p] ; plot(cx, dx, al) cmp [.D], 0 jle .else ; if D > 0 sub [.D], si ; D = D + 2*(du - dv) add dx, [.v] ; v = v + v` jmp .endif .else: add [.D], di ; D = D + 2*dv .endif: inc cx cmp cx, bx ; for x from x0 to x1 jle @b .break: leave pop bx pop si pop di retn 10
|
||||||||||
19 Apr 2023, 13:20 |
|
edfed 19 Apr 2023, 20:58
Kitsune, are you still there?
|
|||
19 Apr 2023, 20:58 |
|
DimonSoft 19 Apr 2023, 22:09
I’m surprised noone has yet mentioned that pixel-drawing BIOS functions are very ineffective. Preparing arguments in specific registers, invoking the whole interrupt handling mechanism with at least 3 stack writes and, later, reads (even if we believe no additional stack/memory accesses are performed internally), then a multiplication+addition, changing a segment register value to access specific video memory segment, then restoring the value (invokes the segment register related stuff, which is not that simple, at least twice) — and all that for actually doing a single write to memory.
The only positive property is that it is somewhat video mode agnostic (and we do hope there’s a table lookup instead of a sequence of branches inside the function). But then again, for AL with highest bit set it performs XOR with what’s already on the screen which basically reduces the Mode 13h default 256 color palette to 128 colors, i.e. twice less. Or at least makes it way harder to achieve exactly the image expected. Don’t you, guys, want the topic starter to write a cool DOS demo some day? |
|||
19 Apr 2023, 22:09 |
|
edfed 20 Apr 2023, 12:18
BIOS put pixel is ineffective if you use it intensivelly. but if the put pixel is just used to set a single pixel for any reason, it is convenient. because it don't need extra code to work. just give arguements and call interrupt.
it can be interresting to make a demo yes... but what to do? what rules? |
|||
20 Apr 2023, 12:18 |
|
FlierMate2 20 Apr 2023, 12:47
edfed wrote:
According to a definition: Quote: Demos are special computer programs. They are beautiful presentations made by talented people - programmers, graphics, musicians - just for fun. This is real electronic art. Size-limited demos are called intros, and there are some categories of them - we have intros in 64 kilobytes, 4 kilobytes, even in 256 bytes and less. It's wonderful that some people make very impressive effects in so tiny space. http://hardcode.untergrund.net/ https://github.com/netspooky/hardcode One of my demo was also included. |
|||
20 Apr 2023, 12:47 |
|
DimonSoft 27 Apr 2023, 15:11
edfed wrote: BIOS put pixel is ineffective if you use it intensivelly. but if the put pixel is just used to set a single pixel for any reason, it is convenient. because it don't need extra code to work. just give arguements and call interrupt. Freeing and overwriting 4 GPRs (AX, CX, DX and, partially, BX) to put a single point? For direct video memory access one only has to have a segment register set up (let’s count it as 1) and, probably, a GPR register that would store the variable part defining the point coordinates (it’s now 2). Hmmm, let me think about what “convenient” means The only reason I can see to use the int 10h/0Ch function is that it is somewhat screen-mode-independent. Although one still has to deal with screen size and future image size. And the number of colors available. And palette, if some particular color is expected. Maybe the function was really introduced there “just because we can”? |
|||
27 Apr 2023, 15:11 |
|
Kitsune 14 Jun 2024, 19:57
edfed wrote: Kitsune, are you still there? Yes, I pass here sometimes and I am thrown by all these codes. I mainly programming in C language these times. Thank you for all your skills demonstrations. _________________ Kitsune |
|||
14 Jun 2024, 19:57 |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.