My old code printed a line in mode 13h with int 10h
. I tried to change it from using int 10h
into writing in memory but for some reason it doesn't work. I am not familiar with writing in memory so I couldn't guess what is the problem.
Here's the new code:
proc PrintLine
;prints a line
;1.length
;2.colour
;3.x
;4.y
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push si
mov cx,[bp+10];leangth
mov dx,[bp+4];y
mov al,[bp+8];colour
mov si,[bp+6];x
xor bx,bx
pl:
push si
push dx
push ax
call PrintPixel
loop pl
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 8
endp PrintLine
proc PrintPixel
;print a pixel through writing into memory
;input:
;1.x
;2.y
;3.colour
;output:
;none
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push di
mov ax,0A000h
mov es,ax
mov ax,[bp+6];y
mov bx,[bp+8];x
mov dl,[bp+4];colour
mov cx,320
mul cx;each line is 320 pixles ax is the number of lines
add ax,bx;bx is the place on the line
mov di,ax
mov [es:di],dl
mov ax, @data
mov ds, ax
pop di
pop dx
pop cx
pop bx
pop ax
pop bp
ret 6
endp PrintPixel
This is the old code with int 10h
:
proc PrintLine
;prints a line
;1.length
;2.colour
;3.x
;4.y
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push si
mov cx,[bp+10];leangth
mov dx,[bp+4];y
mov al,[bp+8];colour
mov si,[bp+6];x
mov ah,0ch
xor bx,bx
pl:
push cx
mov cx,si
int 10h
inc si
pop cx
loop pl
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 8
endp PrintLine
Your PrintPixel procedure has 2 important problems.
Although you preserve a lot of registers, you also use the ES
segment register that you don't preserve at all! Why you then re-initialize the DS
segment register is a mystery.
Because you calculate the video offset address using mul cx
you've gotten a dword product in DX:AX
, but you kept the pixel color in DL
. This can only result in black pixels! They're there but you can't see them.
Since this question was tagged x86 you can use the versatile imul
instruction:
push bp
mov bp, sp
push ax
push bx
push ds
mov ax, 0A000h
mov ds, ax
mov bx, 320 ; Bytes per line in mode 13h
imul bx, [bp+6] ; y
add bx, [bp+8] ; x
mov al, [bp+4] ; colour
mov [bx], al <-- No need for any segment override prefix!
pop ds
pop bx
pop ax
pop bp
ret 6
See how much cleaner and shorter this has become?
With the shift to no longer using the BIOS WritePixel you should also clean-up the PrintLine procedure. It no longer needs e.g. the xor bx, bx
.
Did you know you can push a memory operand directly? Doing so, you'll save a lot of instructions!
push bp
mov bp, sp
push cx
mov cx, [bp+10] ; length
pl:
push word ptr [bp+6] ; x
push word ptr [bp+4] ; y
push word ptr [bp+8] ; colour
call PrintPixel
loop pl
pop cx
pop bp
ret 8