Reputation: 25
I'm trying to make a car game in Assembly's graphic mode. For this, I have to print a car to the screen that I could move on the x-axis with the keyboard. I'm trying to print an ASCII array but it doesn't work.
I attach the array and the printing procedure with the problem. I'd be happy if someone will spot the problem.
Thanks for the help!
The problem: While I'm running the program, everything works just fine Until the 'printing car' procedure has to work. It works but instead of printing a car on the screen, it prints lots of dispersed pixels on the same x axis.
car db 0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0
db 0,0,0,0,0,4,4,4,4,4,4,4,4,0,4,0,4,0,4,4,4,4,4,4,4,4,0,0,0,0,0
db 0,0,0,0,4,4,4,4,4,4,4,4,0,4,4,4,4,4,0,4,4,4,4,4,4,4,4,0,0,0,0
db 0,0,0,4,4,14,14,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,14,14,4,4,0,0,0
db 0,0,0,4,14,14,4,4,4,4,4,0,4,4,4,4,4,4,4,0,4,4,4,4,4,14,14,4,0,0,0
db 0,0,4,4,14,14,4,4,4,4,0,0,4,4,4,4,4,4,4,0,0,4,4,4,4,14,14,4,4,0,0
db 0,0,4,4,14,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,14,4,4,0,0
db 0,0,4,4,4,4,4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,4,4,4,4,0,0
db 0,0,4,4,0,4,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,4,0,4,4,0,0
db 0,0,0,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,0,0
db 0,0,0,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,0,0
db 0,0,0,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,0,0
db 0,0,0,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,0,0,0
db 0,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,0
db 0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,4
db 0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0
db 0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0
db 0,0,4,4,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,4,4,0,0
db 0,0,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,4,4,0,0
db 0,0,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,0,0
db 0,0,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,0,0
db 0,0,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,0,0
db 0,0,0,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,0,0,0
db 0,0,0,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,0,0,0
db 0,0,0,0,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0
db 0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0
db 0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0
Xcar dw 150
proc carP
push ax
push bx
push cx
push dx
push si
push di
xor si, si
xor di, di
mov bx, offset car
mov cx, [Xcar]
BLoop:
cmp [byte ptr bx], 0
je Pixel
mov al, [byte ptr bx]
mov ah, 0ch
mov dx, 140
add cx, si
int 10h
Pixel:
inc bx
inc si
cmp si, 34
jne BLoop
mov si, 0
inc cx
inc di
cmp di, 34
jne BLoop
pop ax
pop bx
pop cx
pop dx
pop si
pop di
ret
endp carP
Upvotes: 2
Views: 542
Reputation: 39166
push ax push bx push cx push dx push si push di ... pop ax pop bx pop cx pop dx pop si pop di
1 When you use the stack to preserve registers, you have to pop
them in reverse order from how you push
ed them!
push ax
push bx
push cx
push dx
push si
push di
...
pop di
pop si
pop dx
pop cx
pop bx
pop ax
2 I've counted for your car data 35 rows with each 31 bytes. This makes a total of 1085 bytes. However your nested loops process 34 x 34 bytes. That's 1156 bytes!
3 Skipping the black pixels might or might not be a good idea. It depends on whether you clear that part of the screen before drawing the car.
3 Because the outer loop uses inc cx
instead of reloading with mov cx, [Xcar]
, you'll get a skewed picture! Is this intentional?
4 Having mov dx, 140
within the inner loop will inevitably put all the pixels on the same Y coordinate. This instruction must go before starting the outer loop and you need to increment the DX
register at the completion of the inner loop.
5 Because the add cx, si
instruction was within a part of the code that gets skipped for every black color, the X coordinate will not advance like it should.
6 The BIOS.WritePixel function requires a display page parameter in the BH
register. Use display page 0. This required shifting a bit with how the registers are used in your code.
The completed code with all the necessary corrections:
push ax
push bx
push cx
push dx
push si
push di
push bp
xor di, di ; Vertical counter 0..34 (35)
mov dx, 140 ; Topside Y
mov si, offset car
mov bh, 0 ; Display page 0
cld ; DF=0 so pointer will auto-increment (*)
OuterLoop:
xor bp, bp ; Horizontal counter 0..30 (31)
mov cx, [Xcar] ; Leftside X
InnerLoop:
lodsb ; Fetch data byte plus increment pointer (*)
cmp al, 0
je SkipPixel
mov ah, 0Ch ; BIOS.WritePixel
int 10h
SkipPixel:
inc cx ; Next X coordinate
inc bp
cmp bp, 31 ; 31 bytes per row in DB for the car
jb InnerLoop
inc dx ; Next Y coordinate
inc di
cmp di, 35 ; 35 rows of DB for the car
jb OuterLoop
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
Upvotes: 4