Say I have a code that makes a dot move around in the ES (extra seg) with the wasd keys. How do I check if the dot is at the first line and if so, it doesn't move?
(I asked my teacher if I need to use cmp
and he said no)
In the proc of the up motion; (I took BX and set it to 0 to check if SI is also 0, then I just made a loop that checks if they're equal until BX is no longer on the first row). When I ran it, it didn't respond when I pressed w.
proc up
mov ah, 0
mov al, ' '
mov [es:si], ax
sub si, 80*2
mov ah, 156
mov al, '*'
mov [es:si], ax
ret
endp up
I tried to use cmp
proc up
mov ah, 0
mov al, ' '
mov [es:si], ax
mov bx, 0
check:
cmp bx, 80*2
jz move
cmp si, bx
jz not_move
inc bx
jmp check
move:
sub si, 80*2
mov ah, 156
mov al, '*'
mov [es:si], ax
not_move:
ret
endp up
mov bx, 0 check: <<< does not need a loop cmp bx, 80*2 jz move cmp si, bx jz not_move <<< needs redrawing because of unconditional wipe inc bx <<< faster with `add bx,2` jmp check
Any character that could exist in the top row of the 80x25 text screen will necessarily be located at one of the even addresses in the list {0, 2, 4, ... 158}.
What your check loop currently is doing is verifying all the addresses in the top row, even the odd ones that won't ever match with SI.
But why even have a loop? Just compare SI to 160 and if SI has a value of 160 or more then you know that the asterisk is not yet in the first row, and so you can safely move up.
What follows is the corrected version of your up proc. If the code finds that the asterisk is in the first row then either not touch the screen at all (best) or, after wiping, redraw first instead of just returning!
proc up
cmp si, 160
jb not_move
mov ax, 00h << 8 + ' ' ; BlackOnBlack space
mov [es:si], ax
sub si, 160
mov ax, 9Ch << 8 + '*' ; LightRedOnLightBlue asterisk
mov [es:si], ax
not_move:
ret
endp up
(I asked my teacher if I need to use
cmp
and he said no)
He was right, because instead of a cmp
we could just try to subtract 160 from the dot's current address and check if the sub
instruction produced a borrow, which it would do for all the addresses in the top row since they are in the list {0, 2, 4, ... 158}. If a borrow exists we would not move and maintain SI as it is:
proc up
mov ax, si ; Keeps SI unmodified in case of 'not_move'
sub ax, 160
jb not_move
mov ax, 00h << 8 + ' ' ; BlackOnBlack space
mov [es:si], ax
sub si, 160
mov ax, 9Ch << 8 + '*' ; LightRedOnLightBlue asterisk
mov [es:si], ax
not_move:
ret
endp up