I am programming a game similar to breakout in assembly (tools:DosBOX, notepad++, tasm), and whilst creating the borders and platform in Graphics mode, I've stumbled upon 2 problems:
This is my current code, the main procedures that are involved in the creating of the borders, platform and movement of the platform are BorderPaint
, PlatBuild
and PlatMove
IDEAL
MODEL small
STACK 100h
DATASEG
platLoc dw 63806
speed1 dw 10
speed2 dw 0FFFFh
CODESEG
;procedure to paint borders-6 px white pixels
proc BorderPaint
push ax
push bx
push di
push cx
mov ax,0A000h ;accesses graphics mode video memory
mov es,ax
xor di,di
;first line-left vertical
;sets color white
mov ax,0Fh
mov cx,200 ;enters nested loop
FirstLoop1:
push cx
mov cx,6
SecondLoop1:
mov [es:di],ax
inc di
loop SecondLoop1
sub di,6
add di,320
pop cx
loop FirstLoop1
;second line- up horizontal
mov di,7
mov cx,313
FirstLoop2:
push cx
mov cx,6
SecondLoop2:
mov [es:di],ax
add di,320
loop SecondLoop2
sub di,1920
inc di
pop cx
loop FirstLoop2
mov di,314
mov cx,200
FirstLoop3:
push cx
mov cx,6
SecondLoop3:
mov [es:di],ax
inc di
loop SecondLoop3
sub di,6
add di,320
pop cx
loop FirstLoop3
; xor di,di
; mov ax,0Fh
; mov cx,200
; FirstLoop4:
; push cx
; mov cx,6
; SecondLoop4:
; mov [es:di],ax
; inc di
; loop SecondLoop4
; sub di,6
; add di,320
; pop cx
; loop FirstLoop4
pop cx
pop di
pop bx
pop ax
ret
endp BorderPaint
proc PlatBuild
push di
push cx
push ax
mov di,[platLoc]
mov ax,5
mov cx,40
LoopPaint2:
push cx
mov cx,10
LoopPaint1:
mov [es:di],ax
sub di,320
loop LoopPaint1
add di,320*10
inc di
pop cx
loop LoopPaint2
pop ax
pop cx
pop di
ret
endp PlatBuild
Proc PlatErase
push di
push cx
push ax
mov di,[platLoc]
mov ax,0
mov cx,40
LoopPaint4:
push cx
mov cx,10
LoopPaint3:
mov [es:di],ax
sub di,320
loop LoopPaint3
add di,320*10
inc di
pop cx
loop LoopPaint4
pop ax
pop cx
pop di
ret
endp PlatErase
Proc PlatMove
push ax
push cx
push dx
push di
mov ax,0A000h
mov es,ax
call BorderPaint
;Input
CheckPress1:
mov ah,0h
int 16h
cmp al,'a'
jne nxt11
jmp MoveLeft1
Nxt11:
cmp al,'d'
jne nxt12
jmp MoveRight1
Nxt12:
cmp al,'q'
jne CheckPress1
jmp endproc1
MoveLeft1:
call Delay
mov dx,[platLoc]
add dx,8*320
sub dx,1d
mov di,dx
mov ax,[es:di]
cmp ax,0Fh
jne move1
jmp CheckPress1
move1:
call PlatErase
dec [platLoc]
call PlatBuild
mov ah,1h
int 16h
je MoveLeft1
jmp CheckPress1
MoveRight1:
call Delay
mov dx,[platLoc]
add dx,41
mov di,dx
mov ax,[es:di]
cmp ax,0Fh
jne move2
jmp CheckPress1
move2:
call PlatErase
inc [platLoc]
call PlatBuild
mov ah,1h
int 16h
je MoveRight1
jmp CheckPress1
EndProc1:
pop di
pop dx
pop cx
pop ax
ret
endp PlatMove
proc Delay
push cx
mov cx, [speed2]
LoopLong:
push cx
mov cx, [speed1]
LoopShort:
loop LoopShort
pop cx
loop LoopLong
pop cx
ret
Endp Delay
start:
mov ax,@data
mov ds,ax
mov ax,13h
int 10h
call BorderPaint
call PlatBuild
mov ax, [es:63680]
call PlatMove
exit:
mov ax,4c00h
int 21h
END startenter code here
mov [es:di],ax
writes WORD (two bytes) into VRAM, ax = 0x000F
, so you write at [es:di]
value 0x0F
, and at [es:di+1]
value 0x00
(black). sub di,6
add di,320
This is blasphemy :/ ... add di,320-6
remains the intent visible on source level, but also shows less ignorance toward the machine, minimizing the amount of instructions used.
BTW, if you want to store 6 bytes with 0x0F value, you can also store three words of 0x0F0F value, saving half of VRAM accesses (which are expensive). So then
mov di,<some VRAM address>
mov cx,<number of lines>
mov ax,0F0Fh ; <color><color> (two pixels at same time)
Draw6PixelsLoop:
mov [es:di],ax
mov [es:di+2],ax
mov [es:di+4],ax
add di,320
dec cx
jnz Draw6PixelsLoop
is more optimal hard-coded way how to draw 6 pixels (with only 3 VRAM writes) and move 1 line below.
PlatMove
and then comparing them with 0Fh cmp ax,0Fh
, i.e. two pixels "white + black" = 000Fh
. So on the left side this will probably work well, but on the right side it will find such two pixels only at the end of the border (keep in mind after the last pixel on the right side the next byte is the first left pixel on next line, so if you have borders 6 pixels strong, the first white+black pixel is at next line where the left border ends).