From: Frank Kotler on
gnoirzox wrote:
> Thanks Frank and Steve for trying help me.

You're welcome. I've dropped comp.arch from the newsgroups list. Nice as
it is to hear from some of those guys (on a.l.a. mostly), I don't think
this is "their thing".

> No, I didn't know that I could use the buffer.

Sure, it's asm! I guess Steve showed you how. Feel free to ask questions
if you don't "get" parts of it. I'll start: int 19h Steve??? :)

> I use directly screen memory, it's a little bit low but before I used interruptions 10h and 21h, so It was very slow.

Yeah! Writing directly to screen memory, as you do, is way faster than
dos/bios. It's reading from screen memory - as you might do to determine
whether you're in a "collision" - that can be slow. In text mode, it
isn't "that bad".

> I'll try 'movsd' or 'movsw'.

Okay. They move a word or a dword (but not on a real 8086!) from ds:si
to es:di (and add 2 or 4 to si and di). Apparently you've got es set to
screen memory, so that's all set. I'm not sure where your ds is
pointing. If your "mov [00h], al" isn't trashing anything, it must be
somewhere "safe"(?). If it's going to be the "source" for your buffer...
be careful you don't scribble on yourself...

> To help you to understand how I display obstacle, I post my code here:

Great. The main question this answers for me is that we're going to see
'|' or '-' in the place we propose to "move" to, if we have a collision.
If you'd showed a "mode 13h" routine to draw the obstacle, speed might
be more of an issue...

> obstacle PROC
> mov bx, 40
> mov al, 12
> mov cx, 2
>
> mov [00h], al
> mov [02h], bx
> mov [04h], al
> mov [06h], bx

Although this'll work (if ds is set right), it's more usual to use named
variables. I think you'll find this awkward to use as your code changes.
I copied your routine - to make sure I understood what it did (not too
easy to follow) - but I just couldn't resist giving these names.

You've got a weird mixture of hard-coded numbers and
unnamed-but-numbered variables there, but it works alright. I added just
enough to try out "collision detection". Instead of comparing for '|'
and '-', I compared to "space", ASSuming that anything else is an
"obstacle". If that's not true, you'll need a somewhat more complicated
"collision detector".

I (of course) translated it to Nasm. :) Mostly involved es:[bx] ->
[es:bx] (Nasm is fussy that way) Don't forget to translate it back, if
you try to use any of it.

;-------------------------------------
; nasm -f bin -o myfile.com myfile.asm

org 100h

section .bss
; your old "[00h]", etc.
row resw 1
col resw 1
row2 resw 1
col2 resw 1

section .text

; cheapo "clearscreen"
mov ax, 3
int 10h

; initialize es to screen memory (and leave it there)
mov ax, 0B800h
mov es, ax

call obstacle

call guy

exit:
; cheapo "clearscreen" again
mov ax, 3
int 10h

; return to dos
ret
;----------

;----------
guy:

; initial position: (row * 80 + col) * 2 bytes per char
mov bx, (80 * 5 + 10) * 2
mov dx, bx
jmp doguy

getkey:
mov dx, bx ; save old position

mov ax, 10h
int 16h

cmp al, 1Bh ; ESC
jz done

cmp al, 0 ; we're interested in "extended" keys
jnz getkey

; for debugging purposes - couldn't remember
; which arrow key was which!
;
; mov al, ah
; int 29h
;jmp getkey

cmp ah, 'P'
jnz not_down
add bx, 160
jmp doguy
not_down:
cmp ah, 'H'
jnz not_up
sub bx, 160
jmp doguy
not_up:
cmp ah, 'K'
jnz not_left
sub bx, 2
jmp doguy
not_left:
cmp ah, 'M'
jnz not_right
add bx, 2
jmp doguy

not_right:
; any other keys to check? no?
jmp getkey

doguy:
cmp bx, 25 * 160 ; if off the bottom of screen
jna onscreen
sub bx, 25 * 160 ; "wrap" to top
onscreen:

cmp byte [es:bx], ' '
jnz collision ; simple as that?

; erase the old "guy"
xchg bx, dx
mov byte [es:bx], ' '
xchg bx, dx

; and set the new "guy"
mov byte [es:bx], 'X'
jmp getkey

collision:
mov al, 7 ; BEL a.k.a "beep"
int 29h
; restore old position
mov bx, dx
jmp getkey

done:
ret
;--------------


obstacle: ; PROC
mov bx, 40 ; column
mov al, 12 ; row
mov cx, 2 ; color

mov [row], al
mov [col], bx
mov [row2], al
mov [col2], bx

call position_centre

position_verti1:
mov bx, 40
mov al, [row]
inc al

call position_verticale

mov [row], al

position_hori1:
mov al, 12
mov bx, [col]
dec bx

call position_horizontale

mov [col], bx

position_verti2:
mov bx, 40
mov al, [row2]
dec al

call position_verticale

mov [row2], al

position_honri2:
mov al, 12
mov bx, [col2]
inc bx

call position_horizontale

mov [col2], bx

cmp bx, 50
je init
jmp position_verti1

init: ; ?
ret
; endproc?

position_centre: ; PROC
push cx
push bx
push ax

mov ah, 160
mul ah
shl bx, 1
add bx, ax
mov ch, 02Bh ;equal mov ch, '+'
xchg ch, cl
mov [es:bx], cx

pop ax
pop bx
pop cx

ret
; position_centre endp

position_horizontale: ; PROC
push cx
push bx
push ax

mov ah, 160
mul ah
shl bx, 1
add bx, ax
mov ch, 02Dh ;equal "mov ch, '-'"
xchg ch, cl
mov [es:bx], cx

pop ax
pop bx
pop cx

ret
; position_horizontale endp

position_verticale: ; PROC
push cx
push bx
push ax

mov ah, 160
mul ah
shl bx, 1
add bx, ax
mov ch, 07Ch ;equal "mov ch, '|'"
xchg ch, cl
mov [es:bx], cx


pop ax
pop bx
pop cx

ret
; position_verticale endp

From: s_dubrovich on
On Jun 13, 4:23 pm, Frank Kotler <fbkot...(a)myfairpoint.net> wrote:
> gnoirzox wrote:

> > No, I didn't know that I could use the buffer.
>
> Sure, it's asm! I guess Steve showed you how. Feel free to ask questions
> if you don't "get" parts of it. I'll start: int 19h Steve??? :)
>

Yeah, I used to do:

;;---exit program---
;; do dos exit in this version...

%IF pcDos
mov ax, 4C00h
int 21h
%ELSE ;; binary exit thru RomBios.
mov ah, 0
int 16h ;; pause until keypress.
%ENDIF
int 19h ;; reboot, just in case.
;;------------

...but int 19h works fine on CMD.EXE to close the box, plus the .com
also works on a boot floppy that loads a .com without the rest of dos
(hence no int 21h calls). Easier for me to keep just one version
around.

Steve