The MASM Forum Archive 2004 to 2012

Miscellaneous Forums => 16 bit DOS Programming => Topic started by: amrac on December 28, 2009, 03:50:31 PM

Title: A game in graphic mode
Post by: amrac on December 28, 2009, 03:50:31 PM
We're doing a game which consists of a block that deslocates itself through different columns. This blocks catches little points that fall and when that happends the player gets points. This is a kind of pong game. We already have a beginning  of the game in which we have a square, a little point and the mouse. There are several things that we don't know how to do but my first question is: how can I deslocate the square horizontaly with the help of the mouse or the arrow keys? The next step will be to make the little points fall randomly.
Title: Re: A game in graphic mode
Post by: amrac on December 28, 2009, 03:55:38 PM
I'm sorry, I forgot to post my code:
stack segment para stack
   db 64 dup ('mystack' )
   stack ends
   

   mycode segment para 'code'
   myproc proc far
   assume cs:mycode, ss:stack
   
   push ds
   sub  ax,ax
   push ax
   
   mov ah, 00h ; prepara para definir o mod grafico
   mov al, 04  ;modo graf 320x200 color mode
   int 10h         ;invoca a int 10h da BIOS   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,00      ;inicializa a cor de background
   mov bl,01      ;background azul
   int 10h         ;invoca a interrupção 10h da BIOS
   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,01      ;prepara conf do foreground
   mov bl,00      ;verde,vermelho e amarelo
   int 10h         ;invoca a intrrupção 10h 10 da Bios
   
   call rato
   ;desenhar o pontinho
   mov dx,64h      ;selecciona a linha 100
   mov cx,9eh       ; seleciona a coluna 158
   
   
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   ;inc dx         ;vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h      
   
   ;desenhar o primeiro rectangulo
   mov dx,98h      ;selecciona a linha 100
   mov cx,32h      ;selecciona a coluna 158
   call proc1
   
   
   ;2 rectangulo
   ;mov dx,64h      ;selecciona a linha 50
   ;mov cx,032h      ;selectiona a coluna 64
   ;call proc1
   ;desenhar um ponto
   
   
   ;terceiro rectangulo
   ;mov dx,32h      ;selecciona a linha 50
   ;mov cx,064h      ;selectiona a coluna 64
   ;call proc1
   
   
   mov ah,01        ;apenas espera
   int 21h         ;por outra tecla
   
   mov ah,00h      ;prepara para definir o modo grafico
   mov al,02h      ;repor modo texto.80.25
   int 10h   
   ;invoca a intrrupção 10h 10 da Bios
   ret
   myproc endp
   
proc1 proc near
   mov bl,0h         ;
   mov bh,0h         ;
   
um:
   mov al,bl
   cmp al,20      ;compara o valor que esta em AL é igual a  20
   jg iniciofor2   ; salta se for igual a 20
   call linha1
   inc bl
   jmp um
   
   ;linhas na vertical
   iniciofor2:
   mov bl,0h   ;inicia for a zero
dois:   
   mov al,bl      ;colocar o valor de bl em al
   cmp al,30      ;compara se o valor que está no al é igual a 30
   jg iniciofor3
   call coluna1
   inc bl
   jmp dois
   
   ;linha horizontal
   iniciofor3:   
   mov bl,0   ;coloca  o 0 no bl
tres:
   mov al,bl
   cmp al,20
   jg iniciofor4      ; salta para inicio4 se for menor  20
   call linha2         ; senão chama o procedimento linha esquerda, que é para desenhar as linhas
   inc bl            ;incrementa o bl
   jmp tres         ;salta para 3
   ;++++++++++++++++++++++++linha vertical em comprimentos ao anterior++++++++++++++++++++++++++++++++++++++++
   iniciofor4:
   mov bl,0h   ;inicia  a zero
quatro:
   mov al,bl
   cmp al,30   ; número de vezes que faz
   jg sair
   call coluna2
   inc bl
   jmp quatro
   
   sair:
   ret
   proc1 endp   ; acaba o procedimento forproc
   
   linha1 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc dx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha1 endp

linha2 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec dx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha2 endp

   
   coluna2 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc cx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna2 endp

coluna1 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec cx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna1 endp
rato proc near    ;
   mov ax,00
   int 33h
   mov ax,01
   int 33h
   ret
   rato endp


mycode ends
end   
Title: Re: A game in graphic mode
Post by: FORTRANS on December 28, 2009, 04:27:50 PM
Hi,

   Just took a quick look.  But what you are going to want
is probably something like the following pseudo code:


MainLoop:
    Check for key
        If key is Right, then
            Erase Box
            Inc Box X position
            Draw Box
        End if
        If key is Left, then
            Erase Box
            Dec Box X position
            Draw Box
        End if
    Erase Point1
    Inc Point1 Y position
    Draw Point1
    Erase Point2
    {And so forth}
    ...
    Wait for a short while,
Loop MainLoop


Steve
Title: Re: A game in graphic mode
Post by: amrac on December 28, 2009, 04:40:18 PM
Yes, thank you for your reply. But how can I do it with the mouse? Do you know an example from which I can guide myself?
Title: Re: A game in graphic mode
Post by: FORTRANS on December 28, 2009, 11:09:43 PM
Hi,

   Here are two examples.  Simple paint programs.

HTH,

Steve N.
Title: Re: A game in graphic mode
Post by: amrac on December 28, 2009, 11:40:20 PM
Thanks!!
Title: Re: A game in graphic mode
Post by: amrac on December 29, 2009, 10:05:35 AM
I have a problem with this game. I have a procedure in which I define the color of the square with the code:
mov al ,01

But when I move the square with the arrow keys I have to paint the square with the color of the background and paint it again to the left. It would be simple to create a variable:
color db 02
and that way I would easily change the value of the variable. But when I change the code to:
mov al,color
I get the error:
"Cannot address with segment register"
How can I solve this problem?
Title: Re: A game in graphic mode
Post by: FORTRANS on December 29, 2009, 02:06:01 PM
Hi,

   You need to correctly initialize the DS segment register.
And then tell MASM that you did so with an ASSUME
statement.

   How you initialize DS depends on where you are putting
the "color" variable.  Are you making a separate data
segment or putting it in the code segment?  If the first
try something like.


DATASEG SEGMENT
color   DB      0
DATASEG ENDS

... then go to where you have.
   push ds
   sub  ax,ax
   push ax

... and add
; - - - Initialization - - -
        MOV     AX,SEG DATASEG  ; Set DS for rest of code ...
        MOV     DS,AX
        ASSUME  DS:DATASEG   


Regards,

Steve N.
Title: Re: A game in graphic mode
Post by: amrac on December 29, 2009, 03:22:16 PM
Yes, a very basic mistake, I forgot to put the assume directive. Thanks
Title: Re: A game in graphic mode
Post by: amrac on December 29, 2009, 03:52:09 PM
Our game has changed and now we detect if the user has clicked the left key and in that case we paint the square with the color of the background. But the problem is that the square doesn't disappear and letters appear on the screen. The program ends if we click the enter key. On the end we receive the message that the program is doing an ilegal instruction. Here is our code:
stack segment para stack
   db 64 dup ('mystack' )
   stack ends

   mydata segment para 'data'
   color db 02
   lado dw 0
   mydata ends

   mycode segment para 'code'
   myproc proc far
   assume cs:mycode, ss:stack, ds:mydata
   
   push ds
   sub  ax,ax
   push ax
   
   mov ah, 00h ; prepara para definir o mod grafico
   mov al, 04  ;modo graf 320x200 color mode
   int 10h         ;invoca a int 10h da BIOS   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,00      ;inicializa a cor de background
   mov bl,01      ;background azul
   int 10h         ;invoca a interrupção 10h da BIOS
   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,01      ;prepara conf do foreground
   mov bl,00      ;verde,vermelho e amarelo
   int 10h         ;invoca a intrrupção 10h 10 da Bios
   
   call rato
   ;desenhar o pontinho
   mov dx,10h      ;selecciona a linha 100
   mov cx,9eh       ; seleciona a coluna 158
   
   
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   ;inc dx         ;vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h      
   
   ;desenhar o primeiro rectangulo
   mov dx,98h      ;selecciona a linha 100
   mov cx,32h      ;selecciona a coluna 158
   call proc1
   
here:mov ah,01        ;apenas espera
   int 21h         ;por outra tecla
   cmp ax, 4b00h
   mov lado,4b00h
   je apaga
   cmp ax,4d00h
   mov lado,4d00h
   je apaga
   mov ah,01        ;apenas espera
   int 21h         ;por outra tecla
   cmp al, 0dh      ;enquanto for diferente de ENTER não sai do programa
   jne here
apaga:mov color,01
   call proc1
   mov ah,00h      ;prepara para definir o modo grafico
   mov al,02h      ;repor modo texto.80.25
   int 10h      ;invoca a interrupção 10h 10 da Bios
   ret
   myproc endp
   
proc1 proc near
   mov bl,0h         ;
   mov bh,0h         ;
   
um:
   mov al,bl
   cmp al,20      ;compara o valor que esta em AL é igual a  20
   jg iniciofor2   ; salta se for igual a 20
   call linha1
   inc bl
   jmp um
   
   ;linhas na vertical
   iniciofor2:
   mov bl,0h   ;inicia for a zero
dois:   
   mov al,bl      ;colocar o valor de bl em al
   cmp al,30      ;compara se o valor que está no al é igual a 30
   jg iniciofor3
   call coluna1
   inc bl
   jmp dois
   
   ;linha horizontal
   iniciofor3:   
   mov bl,0   ;coloca  o 0 no bl
tres:
   mov al,bl
   cmp al,20
   jg iniciofor4      ; salta para inicio4 se for menor  20
   call linha2         ; senão chama o procedimento linha esquerda, que é para desenhar as linhas
   inc bl            ;incrementa o bl
   jmp tres         ;salta para 3
   ;++++++++++++++++++++++++linha vertical em comprimentos ao anterior++++++++++++++++++++++++++++++++++++++++
   iniciofor4:
   mov bl,0h   ;inicia  a zero
quatro:
   mov al,bl
   cmp al,30   ; número de vezes que faz
   jg sair
   call coluna2
   inc bl
   jmp quatro
   
   sair:ret
   cmp color,01
   je muda
   ret
   proc1 endp   ; acaba o procedimento proc1
   
   
   muda proc near
   mov color,02
   jmp here
   ret
   muda endp
linha1 proc near
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc dx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha1 endp

linha2 proc near
   
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec dx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha2 endp

   
coluna2 proc near
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc cx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna2 endp

coluna1 proc near
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec cx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna1 endp
rato proc near    ;
   mov ax,00
   int 33h
   mov ax,01
   int 33h
   ret
   rato endp
   


mycode ends
end   
Title: Re: A game in graphic mode
Post by: FORTRANS on December 29, 2009, 04:29:37 PM
Hi,

   You put in the ASSUME, but Idon't see where you
actually initialize DS.

Steve N.

Title: Re: A game in graphic mode
Post by: dedndave on December 29, 2009, 04:33:19 PM
also a good idea to name the entry point in the END directive...

        END     myproc
Title: Re: A game in graphic mode
Post by: amrac on January 04, 2010, 07:18:53 PM
I have been dividing my game into several parts . In this part I have the little "balls" falling and on the other part I have the square going to the right and to the left. But now I have this problem. I need to have the little balls continuously falling so this means I have an infinite loop. But when I'm in this infinite loop nothing else goes on. But how can I make the infinite loop go on and simultaneously wait for the user to press some keys. For example if he presses 1 it means that the balls fall at velocity one and if he presses 2 it means they'll fall at velocity two and so on. What I mean is that I have my game at an infinite loop but I need other things to go on. How do I do that? Here goes my code:
STACK SEGMENT PARA STACK
   DB   64 DUP ('MYSTACK ')
STACK ENDS
MYDATA SEGMENT PARA 'DATA'
frase1 db 'DDDddddddddd','$'
nivel dw 200
coluna dw 96h
MYDATA ENDS
MYCODE SEGMENT PARA 'CODE'
MYPROC PROC FAR
   ASSUME CS:MYCODE,SS:STACK,DS:MYDATA
   
      PUSH DS
      SUB AX,AX
      PUSH AX
      MOV AX,MYDATA
      MOV DS,AX
      
      MOV AH, 00h
      MOV AL, 04h
      INT 10h
      
      ; MOV AH, 11
      ; MOV BH, 00
      ; MOV BL, 01
      ; INT 10h
      
      MOV AH, 11
      MOV BH, 01
      MOV BL, 00
      INT 10h
      
      
      
      ;push ax
      ;push bx
      ;por a mensagem no ecran
      ;MOV     DX,0       ;256 * row + column (0,0 = upper left corner)
        ;MOV     BH,0
        ;MOV     AH,2
        ;INT     10h
      ;lea dx,frase1         ;coloca mensagem
      ;mov ah,09h            ;inicialização de parâmetro de interrupção
      ;int 21h               ;interrupção que envia frase para o ecran
      ;pop bx
      ;pop ax
      
      ;
      
      push ax
      pix:call pixel
      mov ax,10
      call MsDelay
      jmp pix
      pop ax
      
      push dx
      mov ah,6        ;apenas espera
      mov dl,0ffh
      int 21h         ;por outra tecla
      cmp al,31h      ;se o utilizador carrega na tecla 1 escolhe o nivel um
      je um
      cmp al,32h      ;se o utilizador carrega no 2 escolhe nivel dois (mais lento)
      je dois
      um:mov nivel,200
      dois:mov nivel,500
      pop dx
      
      MOV ah, 01
      INT 21h
      
      MOV AH, 00h
      MOV AL, 02h
      INT 10h
      
      RET
MYPROC ENDP
pixel proc near
      push ax
      push bx
      mov ah,2ch      ;para ir buscar as centésimas de segundo
      int 21h
      sub dh,dh
      mov ax,dx      ;para fazer a multiplicação do valor por ah
      mov cx,0ah
      mul cx
      ;mov aleatorio, ax   ;guarda os centesimos de segundo em aleatorio
      ;o resultado da multiplicação está em ax
      ;o resto fica em dx
      ;vai dividir ax por 2bch
      mov bx,2bch
      div bx
      cmp dx,12ch      ;verificar se o resto da divisao é maior q 300
      jg maior
      maior: mov coluna,12ch      ; se o resto da divisao for maior que 300 retorna a coluna 300
      mov coluna,dx            ;poe o resto da divisao na coluna
      pop bx
      pop ax
            
      mov dx,10h      ;selecciona a linha 100
      mov cx,coluna       ; seleciona a coluna
      
      
      ;MOV DX, 64h
      MOV CX,180
      
Game:
      PUSH CX
      MOV AL, 02      ;pixel cor vermelha
      MOV AH, 12
      MOV CX, coluna
      INT 10h
      
      ;MOV ah, 01
      ;INT 21h      ;espera por uma tecla
      mov     ax, nivel
        call    MsDelay
      
      MOV AL, 00      ;pixel cor preto
      MOV AH, 12
      MOV CX, coluna   ;considerando que temos 300 colunas
      INT 10h
      
      INC DX
      POP CX
      Loop Game
pixel endp
MsDelay proc near
; -----------------------------------------------------------
; This proc delays for the specified number of milliseconds.
; It does this by counting memory refresh requests, which
; for AT-class systems are generated by system timer 1,
; normally programmed by the BIOS to generate an output once
; every 18/1193182 = 15.09 microseconds. Each request toggles
; bit 4 of I/O port 61h. We are counting full cycles of the
; bit, with two toggles per cycle, so each cycle takes 30.18
; microseconds and we count 34 cycles for each millisecond.
;
; Call with the number of milliseconds in AX.
;
; Preserves all registers other than AX.
;
; Note that the delay will be much shorter when running
; under the NT versions of Windows.
; -----------------------------------------------------------
    push cx

    mov cx, ax            ; load msLoop count
  msLoop:
    push cx               ; preserve msLoop counter
    mov cx, 34            ; load repeat count
  wait1:
    in  al, 61h           ; read byte from port
    test al, 10h          ; test bit 4
    jz  wait1             ; jump if bit clear
  wait2:
    in  al, 61h           ; read byte from port
    test al, 10h          ; test bit 4
    jnz wait2             ; jump if bit not clear
    dec cx                ; decrement repeat count
    jnz wait1             ; jump if count not zero
    pop cx                ; recover msLoop counter
    dec cx                ; decrement msLoop count
    jnz msLoop            ; jump if count not zero

    pop cx
    ret
MsDelay endp
MYCODE ENDS

   END
Title: Re: A game in graphic mode
Post by: amrac on January 04, 2010, 11:45:30 PM
I think I didn't explain myself very well. I have 2 procedures. One is continuously making these balls fall. And the other is waiting for the user to press the keys for right and left to move a rectangle right and left. If I can't use threads of course I will have to interrupt the procedure that makes the balls fall to wait for the keys that are pressed by the user. Is there a way in which I can make a procedure function for some milliseconds and then make the other procedure function another milliseconds?
Title: Re: A game in graphic mode
Post by: dedndave on January 05, 2010, 12:42:42 AM
tomorrow, i will have a look at it and see what we can figure out   :U
Title: Re: A game in graphic mode
Post by: FORTRANS on January 05, 2010, 01:21:22 PM
Hi,

   If you can use the timer ticks (18.2 times a second) you
can read the value in the BIOS data segment and use it to
determine if the routine should exit.


; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BIOSSEG SEGMENT AT 40H  ; BIOS Data area
        ORG    6CH
ClockTic LABEL DWORD    ; 55 ms timer ticks since CPU reset
BIOSSEG ENDS

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        MOV     AX,WORD PTR [ClockTic]
        MOV     [TestTic],AX
DoWork:
        ; Insert your routine here.
        MOV     AX,WORD PTR [ClockTic]
        CMP     [TestTic],AX    ; Have we used enough time to quit?
        JE      DoWork          ; No, continue.
        RET


   This gives about the same resolution you would get with
using the timer interrupt, but is a bit simpler.

   If shorter periods are required, you can try Int 15H, function 83H.
This gives about 1 millisecond resolution, if allowed by your computer.
On my computers, Windows 2000 and XP do not allow it.


        MOV     AX,8300H
        XOR     CX,CX           ; CX:DX = Microsecond count.
        MOV     DX,10000        ; 10 milliseconds
        PUSH    ES              ; ES:BX = user memory byte.
        PUSH    DS
        POP     ES
        MOV     BX,OFFSET TestTic
        INT     15H
        POP     ES
        MOV     [TestTic],0     ; Zero flag byte.
DoWork:
        ; Insert your routine here.
        CMP     [TestTic],0     ; Have we used enough time to quit?
        JE      DoWork          ; No, continue.
        RET


   If these will not work for you, you can program timer 2 to
generate a square wave of your choice of duration.  Then
have one routine run when the timer output is high and the
other when it is low.

Regards,

Steve N.
Title: Re: A game in graphic mode
Post by: dedndave on January 05, 2010, 08:46:17 PM
amrac - i wonder if i could get you to explain, as well as you can, how you want the game to play
i don't understand what is supposed to happen with the keys
is there some other game that is similar ? - it kind of sounds like Centipede - lol
or - is there a game like it already written that we could try ?

also - are the comments in Portuguese ? (Brazil ?)
some of it i can understand because it's similar to Spanish  :P
i had 3 years of Latin in high school, but i don't remember very much - lol
i can use a translator
maybe that is the best way for you to convey how it is supposed to play
Title: Re: A game in graphic mode
Post by: amrac on January 05, 2010, 09:59:07 PM
Yes the comments are in portuguese. I think that there is an old game that is very similar. I have a block that stays on the bottom of the screen and deslocates itself to the right and to the left. The old game that I know had a ball bouncing and you had to touch the ball with the block when it touched the ground. In my game you have several balls falling, one at each time, and you have to touch the ball with the block to have ponctuation. One procedure makes the balls fall. The other procedure makes the block move . But you have to give a little time to each other and interrupt each procedure for a little time. The code that I left only had the balls falling. The code that I'm going to leave now has the procedure quadrado which draws the block to the right and to the left and the procedure pixeis which makes the balls fall. The procedures call each other but it isn't working. What is supposed to happen with the keys is to deslocate the block to the right and to the left. n for right, m for left ENTER to exit the game.


stack segment para stack
db 64 dup ('mystack' )
stack ends

mydata segment para 'data'
color db 02
lado dw 0
nivel dw 200
inicio dw 32h
coluna dw 96h
mydata ends

mycode segment para 'code'
myproc proc far
assume cs:mycode, ss:stack, ds:mydata

PUSH DS
SUB AX,AX
PUSH AX
MOV AX,MYDATA
MOV DS,AX

mov ah, 00h ; prepara para definir o mod grafico
mov al, 04  ;modo graf 320x200 color mode
int 10h ;invoca a int 10h da BIOS

mov ah,11 ;prepara configuração da palete de cores
mov bh,00 ;inicializa a cor de background
mov bl,01 ;background azul
    int 10h ;invoca a interrupção 10h da BIOS


mov ah,11 ;prepara configuração da palete de cores
mov bh,01 ;prepara conf do foreground
mov bl,00 ;verde,vermelho e amarelo
int 10h ;invoca a intrrupção 10h 10 da Bios

call rato
call quadrado ;procedimento que vai desenhar e apagar os quadrados



mov ah,00h ;prepara para definir o modo grafico
mov al,02h ;repor modo texto.80.25
int 10h ;invoca a interrupção 10h 10 da Bios
ret
myproc endp

pixeis proc near ;procedimento que vai continuamente fazer cair os pixeis
push ax
pix:call pixel ;procedimento que faz cair um pixel
mov ax,10
call MsDelay
;++++++++++++++++++++++++++++++++chama o procedimento quadrado++++++++++++++++++++++++++++++++++++++++++++++++
call quadrado

jmp pix
pop ax
pixeis endp


quadrado proc near
;desenhar o rectangulo
quad: mov dx,98h ;selecciona a linha 100
mov cx,inicio ;selecciona a coluna 158
call proc1

;++++++++++++++++++++++++++++++chama o procedimento pixeis+++++++++++++++++++++++++++++++++
call pixeis

here:
push dx
    mov ah,6  ;apenas espera
mov dl,0ffh
int 21h ;por outra tecla
pop dx
cmp al, 6eh ;se for igual a tecla n vai apagar quadrado
je apaga
cmp al,6dh ;se for igual a tecla m vai apagar quadrado
je apaga
cmp al,0dh ;se for ENTER sai do programa
je fim
push dx
    mov ah,6  ;apenas espera
mov dl,0ffh
int 21h ;por outra tecla
pop dx
cmp al, 0dh ;enquanto for diferente de ENTER não sai do programa
jne here

apaga:mov color,00
mov ax,10
call MsDelay
sub ah,ah
mov lado,ax
call proc1
mov color,02
cmp lado,6dh ;se foi escolhida a tecla para a direita vai ser desenhado o quadrado à direita
je inicio2
cmp lado,6eh ;se foi escolhida a tecla para a esquerda vai ser desenhado o quadrado à esquerda
je inicio1
inicio2:add inicio,10h
jmp quad
inicio1:sub inicio, 10h
jmp quad




fim:
    mov ah,1  ;apenas espera
int 21h ;por outra tecla

quadrado endp
proc1 proc near
mov bl,0h ;
mov bh,0h ;

um:
mov al,bl
cmp al,20 ;compara o valor que esta em AL é igual a  20
jg iniciofor2 ; salta se for igual a 20
call linha1
inc bl
jmp um

;linhas na vertical
iniciofor2:
mov bl,0h ;inicia for a zero
dois:
mov al,bl ;colocar o valor de bl em al
cmp al,30 ;compara se o valor que está no al é igual a 30
jg iniciofor3
call coluna1
inc bl
jmp dois

;linha horizontal
iniciofor3:
mov bl,0 ;coloca  o 0 no bl
tres:
mov al,bl
cmp al,20
jg iniciofor4 ; salta para inicio4 se for menor  20
call linha2 ; senão chama o procedimento linha esquerda, que é para desenhar as linhas
inc bl ;incrementa o bl
jmp tres ;salta para 3
;++++++++++++++++++++++++linha vertical em comprimentos ao anterior++++++++++++++++++++++++++++++++++++++++
iniciofor4:
mov bl,0h ;inicia  a zero
quatro:
mov al,bl
cmp al,30 ; número de vezes que faz
jg sair
call coluna2
inc bl
jmp quatro

sair:ret
cmp color,01
je muda
ret
proc1 endp ; acaba o procedimento proc1


muda proc near
mov color,02
jmp here
ret
muda endp
linha1 proc near
mov al,color ;cor dos pontos vermelho, configura
mov ah,12 ;conf int 10h para plot do pixel
inc dx ; vai incrementar o número de vezes que for chamado dentro do FOR
int 10h ;invoca a int 10h
ret
linha1 endp

linha2 proc near

mov al,color ;cor dos pontos vermelho, configura
mov ah,12 ;conf int 10h para plot do pixel
dec dx ; vai decrementar o número de vezes que for chamado dentro do FOR
int 10h ;invoca a int 10h
ret
linha2 endp


coluna2 proc near
mov al,color ;cor dos pontos vermelho, configura
mov ah,12 ;conf int 10h para plot do pixel
inc cx ; vai incrementar o número de vezes que for chamado dentro do FOR
int 10h ;invoca a int 10h
ret
coluna2 endp

coluna1 proc near
mov al,color ;cor dos pontos vermelho, configura
mov ah,12 ;conf int 10h para plot do pixel
dec cx ; vai decrementar o número de vezes que for chamado dentro do FOR
int 10h ;invoca a int 10h
ret
coluna1 endp
rato proc near    ;
mov ax,00
int 33h
mov ax,01
int 33h
ret
rato endp
pixel proc near
push ax
push bx
mov ah,2ch ;para ir buscar as centésimas de segundo
int 21h
sub dh,dh
mov ax,dx ;para fazer a multiplicação do valor por ah
mov cx,0ah
mul cx
;mov aleatorio, ax ;guarda os centesimos de segundo em aleatorio
;o resultado da multiplicação está em ax
;o resto fica em dx
;vai dividir ax por 2bch
mov bx,2bch
div bx
cmp dx,12ch ;verificar se o resto da divisao é maior q 300
jg maior
maior: mov coluna,12ch ; se o resto da divisao for maior que 300 retorna a coluna 300
mov coluna,dx ;poe o resto da divisao na coluna
pop bx
pop ax

mov dx,10h ;selecciona a linha 100
mov cx,coluna     ; seleciona a coluna


;MOV DX, 64h
MOV CX,180

Game:
PUSH CX
MOV AL, 02 ;pixel cor vermelha
MOV AH, 12
MOV CX, coluna
INT 10h

;MOV ah, 01
;INT 21h ;espera por uma tecla
mov     ax, nivel
        call    MsDelay

MOV AL, 00 ;pixel cor preto
MOV AH, 12
MOV CX, coluna ;considerando que temos 300 colunas
INT 10h

INC DX
POP CX
Loop Game
pixel endp
MsDelay proc near
; -----------------------------------------------------------
; This proc delays for the specified number of milliseconds.
; It does this by counting memory refresh requests, which
; for AT-class systems are generated by system timer 1,
; normally programmed by the BIOS to generate an output once
; every 18/1193182 = 15.09 microseconds. Each request toggles
; bit 4 of I/O port 61h. We are counting full cycles of the
; bit, with two toggles per cycle, so each cycle takes 30.18
; microseconds and we count 34 cycles for each millisecond.
;
; Call with the number of milliseconds in AX.
;
; Preserves all registers other than AX.
;
; Note that the delay will be much shorter when running
; under the NT versions of Windows.
; -----------------------------------------------------------
    push cx

    mov cx, ax            ; load msLoop count
  msLoop:
    push cx               ; preserve msLoop counter
    mov cx, 34            ; load repeat count
  wait1:
    in  al, 61h           ; read byte from port
    test al, 10h          ; test bit 4
    jz  wait1             ; jump if bit clear
  wait2:
    in  al, 61h           ; read byte from port
    test al, 10h          ; test bit 4
    jnz wait2             ; jump if bit not clear
    dec cx                ; decrement repeat count
    jnz wait1             ; jump if count not zero
    pop cx                ; recover msLoop counter
    dec cx                ; decrement msLoop count
    jnz msLoop            ; jump if count not zero

    pop cx
    ret
MsDelay endp


mycode ends
end


added code tags
Title: Re: A game in graphic mode
Post by: dedndave on January 05, 2010, 10:38:37 PM
ohhh - maybe similar to BreakOut
give me some time to mess with it - i have just gotten busy, here - lol
Title: Re: A game in graphic mode
Post by: amrac on January 05, 2010, 10:44:12 PM
Quote from: FORTRANS on January 05, 2010, 01:21:22 PM
Hi,

   If you can use the timer ticks (18.2 times a second) you
can read the value in the BIOS data segment and use it to
determine if the routine should exit.


; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BIOSSEG SEGMENT AT 40H  ; BIOS Data area
        ORG    6CH
ClockTic LABEL DWORD    ; 55 ms timer ticks since CPU reset
BIOSSEG ENDS

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        MOV     AX,WORD PTR [ClockTic]
        MOV     [TestTic],AX
DoWork:
        ; Insert your routine here.
        MOV     AX,WORD PTR [ClockTic]
        CMP     [TestTic],AX    ; Have we used enough time to quit?
        JE      DoWork          ; No, continue.
        RET


   This gives about the same resolution you would get with
using the timer interrupt, but is a bit simpler.

   If shorter periods are required, you can try Int 15H, function 83H.
This gives about 1 millisecond resolution, if allowed by your computer.
On my computers, Windows 2000 and XP do not allow it.


        MOV     AX,8300H
        XOR     CX,CX           ; CX:DX = Microsecond count.
        MOV     DX,10000        ; 10 milliseconds
        PUSH    ES              ; ES:BX = user memory byte.
        PUSH    DS
        POP     ES
        MOV     BX,OFFSET TestTic
        INT     15H
        POP     ES
        MOV     [TestTic],0     ; Zero flag byte.
DoWork:
        ; Insert your routine here.
        CMP     [TestTic],0     ; Have we used enough time to quit?
        JE      DoWork          ; No, continue.
        RET


   If these will not work for you, you can program timer 2 to
generate a square wave of your choice of duration.  Then
have one routine run when the timer output is high and the
other when it is low.

Regards,

Steve N.


How do I initialize this segment in the assume directive? In the first example if I want to give the procedure a time of 55 milliseconds how do I initialize this time?
Title: Re: A game in graphic mode
Post by: dedndave on January 06, 2010, 12:20:11 AM
something like this...

BIOSSEG SEGMENT AT 0    ;absolute Data area
        ORG    46CH
ClockTic LABEL DWORD    ; 55 ms timer ticks since CPU reset
BIOSSEG ENDS
.
.
        .CODE
.
.
        ASSUME  DS:BIOSSEG

        push    ds
        xor     ax,ax
        mov     ds,ax
        MOV     AX,ClockTic
        pop     ds

        ASSUME  DS:DGROUP

        MOV     TestTic,AX
.
.
.

EDIT - fixed an address   :bg
Title: Re: A game in graphic mode
Post by: dedndave on January 06, 2010, 01:23:44 AM
btw amrac - you should make your stack at least 512 bytes   :bg

here is a template you can use for 16-bit programs...

        .MODEL  SMALL
        .STACK  512

;------------------------------------------------------------------------
;libraries

;------------------------------------------------------------------------
;externals

;------------------------------------------------------------------------
;macros

;------------------------------------------------------------------------
;equates

;------------------------------------------------------------------------
;data

        .CONST

;constant data

        .DATA

;initialized data

Message db 'Hello World',13,10,36

        .DATA?

;uninitialized data

;------------------------------------------------------------------------
;code

        .CODE

_main   PROC    FAR

;initialize the data segment

        mov     ax,@DATA
        mov     ds,ax

;display the message

        mov     dx,offset Message
        mov     ah,9
        int     21h

;terminate program

        mov     ax,4C00h
        int     21h

_main   ENDP

;------------------------------------------------------------------------
;subroutine

;------------------------------------------------------------------------
;subroutine

;------------------------------------------------------------------------

        END     _main
Title: Re: A game in graphic mode
Post by: dedndave on January 06, 2010, 11:39:12 AM
i cleaned up the file a bit and got it to assemble with no errors - now i am ready to have a look at it
i see a few PROCs with no RET   :bg
today, i have some things i need to do - tomorrow we will see if we can make things move
Title: Re: A game in graphic mode
Post by: FORTRANS on January 06, 2010, 01:43:12 PM
Hi Dave,

   Typo?


        ASSUME  DS:BIOSSEG

        push    ds
        MOV     AX,40H  ; Not XOR
        mov     ds,ax
        MOV     AX,ClockTic
        pop     ds

        ASSUME  DS:DGROUP


Regards,

Steve N.
Title: Re: A game in graphic mode
Post by: dedndave on January 06, 2010, 01:54:40 PM
it looks ok to me Steve
ohhhhhhhhh
you access it via 40h
i always access the BIOS data segment from segment 0000
it makes no diff in the address sizes (just add 400h)
but it saves a byte by using XOR AX,AX instead of MOV AX,40h
it also allows you to access the interrupt vector table without changing segments   :bg
Title: Re: A game in graphic mode
Post by: amrac on January 06, 2010, 02:55:27 PM
Thanks for cleaning my file, that must have been a lot of work! About that other reply what does it mean:
ORG    46CH
Can't I just add the

ClockTic LABEL DWORD    in my data segment?
Title: Re: A game in graphic mode
Post by: FORTRANS on January 06, 2010, 03:14:44 PM
Hi Dave,

   Okay I see what you are doing.  Oops.  The references
I have differentiate between the interrupt vector segment
at 0, and the BIOS data segment at 40H.  Should have
read a bit closer.  Good ole habits...


Hi amrac,

   No, it is a specific place in memory that is updated by
the BIOS on each timer interrupt.  It is at 40:6C or 0:46C,
which address the same piece of memory, using segment:offset.
You generally load the tick count into a register, and then
store it into a variable in your data segment.

Steve
Title: Re: A game in graphic mode
Post by: dedndave on January 06, 2010, 03:19:52 PM
well - actually, you can place it in any segment
it is simply a label that has to have a specific offset
i don't know how well "SEGMENT AT" works with newer versions of masm, it wasn't great with older versions - lol
i think you can do it without a label at all like this.....

        push    ds
        xor     ax,ax
        mov     ds,ax
        mov     ax,ds:[46Ch]
        pop     ds

you shouldn't need an ASSUME directive, either

at any rate, the BIOS data segment is at 0040:0000
at offset 6Ch into that segment is the value for the clock tick (3 bytes i think)
0040:006C is the same physical address as 0000:046C
you can get it another way by using INT 1Ah (which is typically a pretty fast interrupt)

        mov     ah,0
        int     1Ah

;clock tick is in CX:DX, max value = 1800AFh
Title: Re: A game in graphic mode
Post by: amrac on January 06, 2010, 11:25:57 PM
I'm sorry I must be really stupid. The thing is, I already have a data segment and I can´t have two data segments. So what are the necessary modifications that I have to make to make things work? I'm sorry to ask this again but I didn't really understand.
Title: Re: A game in graphic mode
Post by: dedndave on January 07, 2010, 12:14:03 AM
well - the term "data segment" can be used in different context
in a broader definition, it might be any segment where you read or write data, including the video buffer
in a narrower definition, it is a specific section of an executable program
in this case, the BIOS code uses the area from 0040:0000 to 0040:00FF - that area is refered to as the "BIOS data segment"
a variety of low-level information is kept there
there are locations that hold the I/O addresses of serial and parallel ports
the keyboard buffer is in there, the amount of memory, and so on
a program can access the information, even though it is not really a data segment of that program

as for your program, you can have more than one data segment
it just isn't needed for most small programs because you do not have more than 64 Kb of data

the only stupid questions are the ones that aren't asked - lol
Title: Re: A game in graphic mode
Post by: FORTRANS on January 07, 2010, 03:18:22 PM
Hi,

   As Dave says, you can have many segments in your
program.  Normally you will have one data segment for a
small program.  I defined "ClockTic" as a location in the
BIOS data segment, as that was a way I like.  Dave has
showed how to access that location without a segment
declared in a SEGMENT directive.  If you want to have
more than one data segment, you declare them with
different names.


; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Set up the code definitions the operating system wants.  Data segment:
DATASEG SEGMENT PUBLIC
...
DATASEG ENDS

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Set up the code definitions the operating system wants.  Data segment 2:
EXTRASG  SEGMENT PUBLIC
... 
EXTRASG  ENDS
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Set up the code definitions the operating system wants.  Data segment 3:
MORESEG  SEGMENT PUBLIC
... 
MORESEG  ENDS



   You can specify the BIOS data segment and the video
display segment in SEGMENT AT directives to give them
names, or just set the segment register directly.  If using
a name makes things clearer, use that.  If the extra level
of indirection is confusing, then just set the registers as
needed.

   A minor "advantage" of using the SEGMENT way of doing
things, is that you then have to use the ASSUME directive to
tell MASM what is going on, or it will generate an error message.
That is either extra work, or a way to check that you have
correctly set the segment registers.

   So an amendment/correction to my code snippit.


; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BIOSSEG SEGMENT AT 40H  ; BIOS Data area
        ORG    6CH
ClockTic LABEL DWORD    ; 55 ms timer ticks since CPU reset
BIOSSEG ENDS

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        PUSH    DS              ; Save data segment pointer.
        MOV     AX,SEG BIOSSEG
        MOV     DS,AX           ; Point data references to the BIOS.
        ASSUME DS:BIOSSEG       ; And tell MASM what we are doing.
        MOV     AX,WORD PTR [ClockTic]
        POP     DS              ; Restore data segment, so we can access our data.
        ASSUME DS:MYDATA        ; Use the name you have set up.
        MOV     [TestTic],AX

DoWork:
        ; Insert your routine here.
        PUSH    DS
        MOV     AX,SEG BIOSSEG
        MOV     DS,AX
        ASSUME DS:BIOSSEG
        MOV     AX,WORD PTR [ClockTic]
        POP     DS
        ASSUME DS:MYDATA
        CMP     [TestTic],AX    ; Have we used enough time to quit?
        JE      DoWork          ; No, continue.
        RET


   A side note:  van Gilluwe in "The Undocumented PC" says
that the Int 1aH function 0 should be used only by the OS.
This is because if it is used, it clears the "24-hour overrun
flag", and if you manage to do that, instead of the os doing
it, you have caused the OS to lose a day.  Seems unlikely?

Regards,

Steve N.
Edit: Fix dumb error...
SRN
Title: Re: A game in graphic mode
Post by: dedndave on January 07, 2010, 08:10:50 PM
you're absolutely right about the rollover flag, Steve
i had never thought much about it - always ignored the flag
that means there is a lot of broken software out there - lol
of course, you can set the flag at 0040:0070, but, if you are doing that, you may as well get the tick count from 006C   :bg
Title: Re: A game in graphic mode
Post by: MichaelW on January 07, 2010, 11:36:46 PM
amrac,

As a test I threw together an app that does what I think you are describing. I ended up with ~200 lines of code, not including the comments, blank lines, etc. While I am not going to post the complete source, the attachment does contain the EXE. I tested only under Windows 2000, where the app had to be run full-screen. There is only one ball in flight at a time. For the ball paths the x coordinates are random. I set the ball animation speed so it starts out slow, and then speeds up every 10 balls, to the point of becoming completely unplayable in the vicinity of 50 balls. Under DOS or Windows 9x the animation speed should be about 1/3 of what it is under Windows NT/2000/XP. Use the left and right cursor-control keys to move the paddle. The ball number is displayed in the upper-left corner and the current score in the upper-right corner. Intercepting a ball with the paddle will increment the score, and missing it will decrement the score. Press Escape to exit at any time.

In case you are not already aware of the feature of the Interrupt 10h, Function 0Ch that allows it to XOR the pixel onto the screen, I included a demo app.

Title: Re: A game in graphic mode
Post by: dedndave on January 07, 2010, 11:52:11 PM
amrac - i was playing around with some code
at the same time, thinking about what the best approach to your problem is   BigGrin
i think the best way to go might be to write your own keyboard driver
the keyboard, by design, sends a signal whenever a key is pressed and again when it is released
the BIOS driver converts this into scan codes and key codes and handles the repeat delay and rate - all that
the repeat delay and rate are not desirable for what you want to do
i have done this kind of thing in the past (many years ago - lol)
it is a bit involved - but, i can do it again
the thing is - it will take me some time
right now, i had promised Zulfi i would work on a boot-sector for him
(another little thing i have wanted to do for a long time)
let me take care of that project, then come back to this one
that will give me some time to toss it around in my head for a while and let it ferment   BigGrin

in the mean time, i wrote this little quicky demo for video mode 13h that you might like
when we employ a keyboard driver, we may want to use that mode to get 256 colors   ThumbsUp

oh - press any key to exit the program
then, you can use Alt-Enter to toggle between full-screen and normal dos window
Title: Re: A game in graphic mode
Post by: dedndave on January 07, 2010, 11:55:30 PM
i like it Michael   :U

it looks like the makings of single-player pong, breakout, centipede or even space invaders - lol
i don't know what he has in mind when the ball hits the paddle

i don't know how many hours i spent playing "Digger" - a DigDug knockoff   :P

(http://blog.photos2view.com/files/07-07-digger.gif)
Title: Re: A game in graphic mode
Post by: amrac on January 09, 2010, 12:20:50 AM
Hi Michael
Yes, that's exactly what I'm looking for. Thanks!

Title: Re: A game in graphic mode
Post by: amrac on January 09, 2010, 12:34:30 AM
Hi dedndave
Thanks for the file I liked it. I think I have the solution for my problem. I have to join the procedures altogether. I have to put the little balls falling and wait for the user to press the keys at the same time. I really don't want you to waist time with my project because I think I have the solution. I don't know if I'm going to find another problem because I'm going to try this other way of solving my problem. But anyway, thanks a lot! :U
Title: Re: A game in graphic mode
Post by: dedndave on January 09, 2010, 01:18:21 AM
yes - you should be able to have a routine for each, then service them in "round robin" fashion
i.e. a loop where you call the keyboard routine, call the paddle routine, call the ball routine, then start at the top of the loop again
Title: Re: A game in graphic mode
Post by: amrac on January 12, 2010, 11:54:54 AM
I've solved the problem and now I have another problem that has to do with preserving the values of registers.
My procedure is working like this:
-determine the column for the ball

-if the ball didn't rich the bottom

-1(true)make the ball fall

-2(true)draw the rectangle

-3(true)make the ball fall

-4(true) wait for a pressed key

-(false)determine the column of the ball

But the problem is that the first time the ball falls it falls correctly. The second time it falls, it jumps from one column to another. That is, it falls till the middle of the screen and then jumps to another column. And it falls always in the same columns (two columns alternately). And I know that the code that makes the balls fall randomly in several columns, work because I've already tested it. This means that it is getting the value for the column from some other procedure. My code that generates the columns randomly is:

push ax
   push bx
   push dx
   push cx
   mov quedas,180
   mov ah,2ch      ;para ir buscar as centésimas de segundo
      int 21h
      sub dh,dh
      mov ax,dx      ;para fazer a multiplicação do valor por ah
      mov cx,0ah
      mul cx
      ;mov aleatorio, ax   ;guarda os centesimos de segundo em aleatorio
      ;o resultado da multiplicação está em ax
      ;o resto fica em dx
      ;vai dividir ax por 2bch
      mov bx,2bch
      div bx
      cmp dx,12ch      ;verificar se o resto da divisao é maior q 300
      jg maior
      maior: mov coluna,12ch      ; se o resto da divisao for maior que 300 retorna a coluna 300
      mov coluna,dx            ;poe o resto da divisao na coluna
   pop cx
   pop dx
   pop bx
   pop ax   
   



Aren't those pushes enough to preserve the values of the registers? How to procede to preserve correctly the values of the registers?
Title: Re: A game in graphic mode
Post by: dedndave on January 12, 2010, 12:21:24 PM
hiya amrac

first - this code can be simplified a little bit...

      sub dh,dh
      mov ax,dx      ;para fazer a multiplicação do valor por ah
      mov cx,0ah
      mul cx

MOV DH,0 is as small as SUB DH,DH
you might use that on a word register to make the code 1 byte smaller
MOV DX,0 is 3 bytes - SUB DX,DX is 2 bytes

but, just put 10 into the AL register and multiply it by DL - the result will be in AX, CX and DX won't be affected...

        mov     al,10
        mul     dl

as for the column jump, the code modifies the "coluna" value, whether the registers are pushed or not

      maior: mov coluna,12ch      ; se o resto da divisao for maior que 300 retorna a coluna 300
      mov coluna,dx            ;poe o resto da divisao na coluna

that code doesn't make sense   :bg
Title: Re: A game in graphic mode
Post by: amrac on January 12, 2010, 02:49:55 PM
Quote from: dedndave on January 12, 2010, 12:21:24 PM

as for the column jump, the code modifies the "coluna" value, whether the registers are pushed or not

      maior: mov coluna,12ch      ; se o resto da divisao for maior que 300 retorna a coluna 300
      mov coluna,dx            ;poe o resto da divisao na coluna

that code doesn't make sense   :bg
I've runned this code and it runs fine. Sometimes I get a value in dx which is bigger than 12ch and in that case I want the value in coluna to be 12ch. That's because I want the ball to fall only in the left most 300 columns.
But I still don't know what is the right manner to preserve the registers in the procedures. That I think is the problem of my code. The random column code is running fine in another program without the rectangle.
Title: Re: A game in graphic mode
Post by: dedndave on January 12, 2010, 04:03:25 PM
it looks like this code is used to generate a random column number for a new ball to drop
if it is causing the ball to jump columns, it is because it is being executed before the ball hits the last row
perhaps you are trying to have more than one ball at a time ?
i don't know, as i can't see the rest of the code   :P

if you want to replace that code with something a little nicer, try this code...

        mov     quedas,180     ;falls = 180
        push    ax
        push    bx
        push    dx
        push    es
        xor     ax,ax
        mov     es,ax
        les     ax,es:[46Ch]
        mov     dx,es
        mov     bx,301
        div     bx
        mov     coluna,dx
        pop     es
        pop     dx
        pop     bx
        pop     ax

one problem that your code has is something like this...
a new random column is selected from a range of 0 to 699
if it is over 300, you set it to the limit value of 300
the problem is - it will be 300 more often than any other value
just divide by 301 - the remainder can never be more than 300   :U
Title: Re: A game in graphic mode
Post by: amrac on January 12, 2010, 04:26:22 PM
Hi dedndave
Thanks for your reply.
I've copied you're code and run it and the result is exactly the same. The ball falls and then jumps to another column. This only confirms what I suspected. I'm not preserving the registers the right way in another procedure.
One question. What does this code do:
les     ax,es:[46Ch]
Title: Re: A game in graphic mode
Post by: dedndave on January 12, 2010, 04:55:45 PM
LES is really just a shortcut
i wanted to load the timer value from 0000:046C, which is a dword
LES AX,xxxx gets the dword, low order word into AX, high order word into ES
then, i put the high order word into DX, where i wanted it
you could do the same thing with this code...

        mov     ax,es:[46Ch]
        mov     dx,es:[46Eh]
Title: Re: A game in graphic mode
Post by: dedndave on January 12, 2010, 04:59:06 PM
put your asm file into a zip
below the reply window is a link for Additional Options...
click that, and attach the zip file
i will look at the entire code and see if i can spot the problem   :U
Title: Re: A game in graphic mode
Post by: dedndave on January 12, 2010, 05:03:12 PM
come to think of it, this code is one byte shorter because there is no segment override   :bg

        mov     quedas,180     ;falls = 180
        push    ax
        push    bx
        push    dx
        push    ds
        xor     ax,ax
        mov     ds,ax
        lds     ax,ds:[46Ch]
        mov     dx,ds
        mov     bx,301
        pop     ds
        div     bx
        mov     coluna,dx
        pop     dx
        pop     bx
        pop     ax

LDS is similar to LES, except it uses the DS register instead of ES
Title: Re: A game in graphic mode
Post by: amrac on January 12, 2010, 05:30:27 PM
I've copied you're code and run it and the result is still exactly the same. The ball falls and then jumps to another column. I don't want to be dull  but I think I'm not preserving the registers the right way in another procedure.
I still don't understand that line of code:
lds     ax,ds:[46Ch]
Title: Re: A game in graphic mode
Post by: dedndave on January 12, 2010, 06:29:46 PM
put your ASM file into a ZIP file
below the reply window is a link for Additional Options...
click that, and attach the ZIP file
i will look at the entire code and see if i can spot the problem

        lds     ax,ds:[46Ch]

that line of code is the same thing as

        mov     ax,ds:[46Ch]
        mov     ds,ds:[46Eh]

LDS stands for Load DS
LDS AX,[nnnn] loads DS and AX at the same time from the dword addressed by [nnnn]
it could be a label like SomeDwordPointer
LDS AX,SomeDwordPointer
you might see it used with SI
LDS SI,SomeDwordPointer

http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html#HEADING1-102
Title: Re: A game in graphic mode
Post by: amrac on January 12, 2010, 06:46:37 PM
Hi
Here goes my code.
Title: Re: A game in graphic mode
Post by: dedndave on January 12, 2010, 08:01:07 PM
hiya amrac
i am looking at the "pixel" proc
i think there is something wrong with the way the count is kept
let me play with it a little bit....