Dobry wieczór, pisze sobie w assembly algorytm Bresenhama, no, dokładniej to portuje go z przykładu na wiki o stąd , ale coś nie działa gdy x2
jest większe od x1
, i ogólnie coś nie trybi z współrzędnymi x2
oraz x1
, błędu wypatrzeć - nie moge.
Może ktoś baardziej doświadczony w asm zerknie i zobaczy co jest nie tak. Generalnie błąd sie tak objawia że rysowana jest tylko jedna kratka, lub cały ekran (na pewno więcej niż 2000 wordów).
Sprawdziłem sobie na SFML-u jak to chodzi, i tam jest okej dla współrzędnych co podaje w asm, także to nie problem z algorytmem.
Od razu odpowiem na pytanie dlaczego kod jest taki syfiasty z tymi pop
ami przy każdej prawie operacji, otóż przeklepuje go z wiki i chce odtworzyć takie warunki jakby nieruszalne gdzie modyfikuje tylko te rejestry co na nich operacje wykonuje, w sensie, że jako takie bezpieczniki. No, i nie ma być szybkie tylko działać :D
W celach nauki to będzie służyć do 16 bitowego kernela ;p
//edit
kompiluje nasmem, kod ten wykonywany jest w real mode
algorytm:
; dx - x1, ax - y1, bx - x2, cx - y2
bresenham_line:
mov word [.x], dx ; x = x1
mov word [.y], ax ; y = y1
cmp dx, bx ; (x1 < x2)?
jnb .e0 ; if not jump
mov word [.xi], 1 ; xi = 1
mov word [.dx], bx ; dx = bx x2
sub word [.dx], dx ; dx = x2-x1
jmp .aft_e0
.e0:
mov word [.xi], -1 ; xi = -1
mov word [.dx], dx ; dx = x1
sub word [.dx], bx ; dx = x1 - x2
.aft_e0:
cmp ax, cx
jnb .e1 ; y1 < y2?
mov word [.yi], 1 ; tak, yi = 1
mov word [.dy], cx ; dy = y2
sub word [.dy], ax ; dy = y2 - y1
jmp .aft_e1
.e1:
mov word [.yi], -1 ; nie, y1 = -1
mov word [.dy], ax ; dy = y1
sub word [.dy], cx ; dy = y1 - y2
.aft_e1:
pusha
mov dx, word [.y]
mov bx, word [.x]
mov ax, 0x490c
call fx_write_memory1
popa
mov bp, word [.dx] ;
cmp bp, word [.dy]
jng .else0
push ax
mov ax, word [.dy] ; dy
sub ax, word [.dx] ; dy - dx
mul word [.tw] ; (dy - dx) * 2
mov word [.ai], ax ; ai = -||-
pop ax
push ax
mov ax, word [.dy] ; bi
mul word [.tw] ;
mov word [.bi], ax
pop ax
push ax
mov ax, word [.bi]
sub ax, word [.dx]
mov word [.d], ax
pop ax
.loop0:
push ax
mov ax, word [.x]
cmp ax, word [.x2]
pop ax
je .end
cmp word[.d], 0
jnae .else_nested0
push ax
mov ax, word [.x] ; x
add ax, word [.xi] ; x + xi
mov word [.x], ax ; x = x + xi
pop ax
push ax
mov ax, word [.y] ; y
add ax, word [.yi] ; y + yi
mov word [.y], ax ; y = y + yi
pop ax
push ax
mov ax, word [.d] ; d
add ax, word [.ai] ; d + ai
mov word [.d], ax ; d = d + ai
pop ax
pusha
mov dx, word [.y]
mov bx, word [.x]
mov ax, 0x490c
call fx_write_memory1
popa
jmp .loop0
.else_nested0:
push ax
mov ax, word [.d] ; d
add ax, word [.bi] ; d + bi
mov word [.d], ax ; d = d + bi
pop ax
push ax
mov ax, word [.x] ; x
add ax, word [.xi] ; x + xi
mov word [.x], ax ; x = x + xi
pop ax
pusha
mov dx, word [.y]
mov bx, word [.x]
mov ax, 0x490c
call fx_write_memory1
popa
jmp .loop0
.else0:
push ax
mov ax, word [.dx] ; dx
sub ax, word [.dy] ; dx - dy
mul word [.tw] ; (dx - dy) * 2
mov word [.ai], ax ; ai
pop ax
push ax
mov ax, word [.dx] ; dx
mul word [.tw] ; dx * 2
mov word [.bi], ax ; bi = dx * 2
pop ax
push ax
mov ax, word [.bi] ; bi
sub ax, word [.dy] ; bi - dy
mov word [.d], ax ; d = bi - dy
pop ax
.loop1:
push ax
mov ax, word [.y]
cmp ax, word [.y2]
pop ax
je .end
cmp [.d], word 0
jnae .else_nested1
push ax
mov ax, word [.x] ; x
add ax, word [.xi] ; x + xi
mov word [.x], ax ; x = x + xi
pop ax
push ax
mov ax, word [.y] ; y
add ax, word [.yi] ; y + yi
mov word [.y], ax ; y = y + yi
pop ax
push ax
mov ax, word [.d] ; d
add ax, word [.ai] ; d + ai
mov word [.d], ax ; d = d + ai
pop ax
pusha
mov dx, word [.y]
mov bx, word [.x]
mov ax, 0x490c
call fx_write_memory1
popa
jmp .loop1
.else_nested1:
push ax
mov ax, word [.d] ; d
add ax, word [.bi] ; d + bi
mov word [.d], ax ; d = d + bi
pop ax
push ax
mov ax, word [.y] ; y
add ax, word [.yi] ; y + yi
mov word [.y], ax ; y = y + yi
pop ax
pusha
mov dx, word [.y]
mov bx, word [.x]
mov ax, 0x490c
call fx_write_memory1
popa
jmp .loop1
.end:
ret
.x1 dw 0
.x2 dw 0
.y1 dw 0
.y2 dw 0
.x dw 0
.y dw 0
.d dw 0
.dx dw 0
.dy dw 0
.ai dw 0
.bi dw 0
.xi dw 0
.yi dw 0
.tw dw 2
I funkcja którą maże sobie po pamięci VGA.
; dx y, bx - x
; ax - byte
; y + 160 + (x * 2)
fx_write_memory1:
push es
push ax
mov ax, 0x0b800
mov es, ax
xor di, di
mov ax, dx ; y
mov cx, 160
mul cx ; y * 160
add di, ax ; di = offset_y
mov ax, bx
mov cx, 2
mul cx
add di, ax
pop ax
mov word [es:di], ax
pop es
ret