Vistas de página en total

Mostrando entradas con la etiqueta mouse. Mostrar todas las entradas
Mostrando entradas con la etiqueta mouse. Mostrar todas las entradas

miércoles, 20 de noviembre de 2013

TEST PUERTO CENTRONICS

   En esta entrada voy a poner una aplicación muy útil para testear el puerto Centronics. El uso más importante que he hecho de esta aplicación es la prueba prototipos controlados por centronics,
   Mediante este programa podemos configurar bit a bit la los puertos del Centronics y ver sus entradas. De esta manera podemos controlar las señales que enviamos por el para testear pequeños circuitos.
   En este caso los textos asociados a cada señal están nombrados con la función que desempeñan en el puerto centronics. Cada uno puede luego cambiar estos textos por el uso que haga de cada bit en su prototipo.
  Como el puerto Centronis tiene dos puertos de salida y uno de entradas, y los de salidas no son de entradas, normalmente, no podemos leer los puertos 378h y 37Ah , que normalmente son simplemente un latch de salida. Por ello, no siempre el dato inicial será correcto. En el caso de realizar un programa test particularizado para una aplicación, podemos cargar al comienzo del programa en estos puertos un valor inicial, para no tener que ir colocando bit a bit.

  En el siguiente blog colocaré el esquema de una targeta que permitirá obtener 48 E/S a través de dos PIO's.
   Estos podrán ser programados y manejados por el ordenador a través del puerto centronics.
    Por supuesto, una vez realizada la tarjeta hay que probarla, y para ello es necesario este programa. Con él podremos ir enviando las señales de control a la tarjeta y verificando que funciona.  
    Con el esquema de la tarjeta añadiré una versión de este programa con los textos cambiados y adapatados al uso que se vaya ha hacer en esa tarjeta.

    Una vez que la tarjeta funcione podremos realizar librerías de control de esta, para programarla y manejar sus 48 E/S. De esta forma crearemos unos drive's de control para estas tarjeta.
 
     Con estas librerías podremos hacer un programa equivalente a este pero que en pantalla aparezcan en vez de los tres puertos centronics los 6 puertos de la tarjeta y sus puertos de configuración. Esta será, al igual que este programa, una herramienta para crear prototipos controlados mediante esta tarjeta.

     Un ejemplo que pondré, bajo una licencia GPL será un emulador de 8051.

       Como todos mis programas, todo lo que uso está basado en mis propias librerías. No existe ni una sola línea de programación estandar o cogido de librerías estandar. Por ello, quien quiera entender como funcionan las funciones implementadas, debe de recorrer este blog, ya que el código de todo lo que se usa ya ha sido publicado en él.


CENTRON.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
;programa monitor del puerto centronics

include main.mac
include stdio.mac
include mouse.mac
include math.mac
include window.mac

.model compact,pascal
.stack 100

.data
raton dw 0   ;bandera para detectar flanco de pulsación

m1 db "Control puerto paralelo V1.1",10,13
   db "              (c)Jose Angel Moneo Fernández",0

datos db "Dato-378H",0
control db "Cont-37AH",0
Estado db "Esta-379H",0
idest1 db "/Ocupado-11--------+¦¦¦¦",0
idest2 db "Reconocido-10-------+¦¦¦",0
idest3 db "Sin papel-12---------+¦¦",0
idest4 db "Seleccion Entrada-13--+¦",0
idest5 db "Error-15---------------+",0
idcont1 db "¦¦¦¦+------ /Strobe-1",0
idcont2 db "¦¦¦+------- /Auto feed-14",0
idcont3 db "¦¦+-------- Inicializacion-16",0
idcont4 db "¦+--------- /Select-17",0
idcont5 db "+---------- En. In.",0

msalir  db "Salir",0

orden db "76543210",0
;Inicializamos la varialbe con 100h para que al presentar el número en 
; binario siempre mantenga los 8 dígitos. Despuñes borraremos el 1 inical
; en pantalla
numero dw 100h,0
ncontrol dw 100h,0
nestado dw 100h,0



.code

centronics proc far

      main
      setcursor off
      resmouse
      mouse on
      putmouse 64,64
      clrscr

      gotoxy 10,1
      puts m1
      draw_win 9,35,12,46,control
      gotoxy 37,10
      puts orden
      draw_win 15,25,18,36,estado
      gotoxy 27,16
      puts orden
      draw_win 9,18,12,29,datos
      gotoxy 20,10
      puts orden
      gotoxy 8,19
      puts idest1
      gotoxy 8,20
      puts idest2
      gotoxy 8,21
      puts idest3
      gotoxy 8,22
      puts idest4
      gotoxy 8,23
      puts idest5
      gotoxy 40,13
      puts idcont1
      gotoxy 40,14
      puts idcont2
      gotoxy 40,15
      puts idcont3
      gotoxy 40,16
      puts idcont4
      gotoxy 40,17
      puts idcont5
       gotoxy 50,22
      puts msalir    
      mov dx,378h
      in al,dx
      mov byte ptr numero,al
      mov dx,37Ah
      in al,dx
      mov byte ptr ncontrol,al
refresca:      
      ;imprime el valor para enviar como dato
      gotoxy 19,11
      printf numero,@b   ;imprime el valor en binario
      gotoxy 19,11   ; borra el uno no valido
      putchar ' '
      ; imprime el valor para ncontrol
      gotoxy 36,11
      printf ncontrol,@b
      gotoxy 36,11   ; borra el uno no valido
      putchar ' '

test2:
      mov dx,379h
      in al,dx
      cmp al,byte ptr nestado  ; no imprime si no cambia el valor
      je espera
      mov byte ptr nestado,al
      gotoxy 26,17
      printf nestado,@b
      gotoxy 26,17   ; borra el uno no valido
      putchar ' '
      
 espera:

        getmouse                ;comprueba el estado del raton
        cmp ax,1
        jnz actual              ;si no se ha pulsado se espera
        cmp ax,raton            ;si se pulso se verifica si ha sido un
        mov raton,ax            ;flanco de subida
        jnz  seleccion           ;si es asi se selecciona la opcion deseada
actual:
        mov raton,ax
        jmp espera      
seleccion:
        getmousexy 19,11,8,0    ; numero
        cmp al,0ffh
        jnz op_numero
        getmousexy 36,11,8,0    ; ncontrol
        cmp al,0ffh
        jnz op_control
        getmousexy 50,22,5,0    ; ventana para salir
        cmp al,0ffh
        jnz fin
        jmp espera
        
op_control:        
        ; ncontrol

        ;Creamos una palabra con el bit indicado a 1
        ;mediante traslaciones de un bit
       
        mov cl,ah
        xor al,al   ; borra al , donde crearemos la mascara
        stc    ; carry a 1
        rcr al,cl      ; situa el bit elegido
        mov ah,al
        mov al,byte ptr ncontrol
        xor al,ah
        ;cambiar bit ncontrol para enviarlo
        mov byte ptr ncontrol,al
        mov dx,37Ah
        out dx,al
      
        jmp refresca
        
op_numero: ;numero 

        ;Creamos una palabra con el bit indicado a 1
        ;mediante traslaciones de un bit
        mov cl,ah
        xor al,al   ; borra al , donde crearemos la mascara
        stc    ; carry a 1
        rcr al,cl      ; situa el bit elegido
        mov ah,al
        mov al,byte ptr numero
        xor al,ah
        ;cambiar bit ncontrol para enviarlo
        mov byte ptr numero,al
        ;saca el dato por el puerto
        mov dx,378h
        out dx,al
       
        jmp refresca
fin:
      setcursor on
      mouse off
      ret
centronics endp

end centronics


martes, 13 de agosto de 2013

GETMOUSEXY

     Hoy toca la segunda parte necesaria para tomar la posición de ratón en una ventana de texto acotada.
     La llamaremos getmousexy.

      La parte correspondiente en el programa TIC_TAC_TOE es:
    ;toma la coordenada
        getmousex  
        shr ax,4 ;divide por 16 para obtener coordenada letra   
        sub ax,5 ;referencia desde cero de la posicion en la matriz
        cmp al,2  ;no valido si pulsamos fuera
        ja espera 
        mov posx,al
        getmousey  
        shr ax,4 ;divide por 16 para obtener coordenada letra   
        sub ax,2 ;referencia desde cero de la posicion en la matriz
        cmp al,2    ;no valido si pulsamos fuera
        ja espera 
        mov posy,al

   Ahora queremos convertirla en una rutina estándar que nos valga para siempre. Para ello en vez de dividir por 16 lo haremos por 8 para que nos de posiciones en carácter de pantalla.
    Para implementarla crearemos una macro a la que le pasaremos hasta 4 parámetros.
    inx e iniy serán las coordenadas de inicio de la ventana
    rangx y rangy será la longitud x e y de la ventana.
    Se podrá no indicar, por parejas, estos parámetros. Si no se indican rangos, se tomará 0,0, 80,24 como ventana.
 
   Como hemos dicho esto está pensado para ser usado junto con waitmouse y analizar una pulsación del ratón. A veces nos interesará hacer waitmouse en un punto del programa y llamar a esta rutina varias veces para analizar varias posibilidades (varias ventanas activas). Otras veces, simplemente tengo activa una ventana válida y solo quiero ver la coordenada pulsada, como es el caso del juego TIC_TAC_TOE.
   Como resulta que para ver si se no pulsó dentro de la ventana debemos verificar si nos ha devuelto 0ffh, en el caso de que solo haya una ventana activa, resulta en este caso un sobrecoste de análisis. Por ello, resulta cómodo tener una función que ya lo implemente y se quede esperando dentro, hasta que la posición sea válida.
   Es por eso que además de la macro getmousexy vamos a crear waitmousexy, que combinará la espera y la toma de posición, para hacer en una sola instrucción las dos cosas.


   IMPLEMENTACIÓN GETMOUSEXY

MOUSE.MAC  ( a añadir a lo que ya existe)
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
;toma la posicion xy del raton en coordenadas texto referidas a inix,iniy
;devuelve la posición en ah=x al=y. Si está fuera de la ventana devueve al=0ffh
;inix e iniy son las coordenadas cero
;rangx,rangy son el rango válido
;ej mousexy 10,10,20,20 devuelve las coordenada pulsada
;si está dentro de la ventana 10,10,20,20 con la coordenada referida al origen 10,10

getmousexy macro inix,iniy,rangx,rangy
ifndef _getmousexy
      extrn _getmousexy:near
endif
  ifnb <rangy>
      mov ax,inix
      push ax
      mov ax,iniy
      push ax
     mov ax,rangx
      push ax
      mov ax,rangy
      push ax
  else
      mov ax,0
      push ax
      push ax
      mov ax,80
      push ax
      mov ax,4
      push ax
  endif
      call _getmousexy
endm


;espera pulsación de ratón y toma la posicion xy del raton en coordenadas texto referidas a inix,iniy
;devuelve la posición en ah=x al=y.

waitmousexy macro   inix,iniy,rangx,rangy
waitmouse 
getmousexy inix,iniy,rangx,rangy
endm



GETMOUSEXY.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

title librería getmousexy

.model compact,pascal
     public _getmousexy
.286
.data
.code
proc _getmousexy  uses bx,inix,iniy,rangx,rangy
     ;toma la coordenada
        getmousex  
        shr ax,3               ;divide por 8 para obtener coordenada texto
        sub ax,inix             ;referencia cero de la posicion en la matriz
        cmp ax,rangx           ;no valido si pulsamos fuera
        ja fuera
        mov bh,al
        getmousey  
        shr ax,3             ;divide por 8 para obtener coordenada texto
        sub ax,iniy          ;referencia cero de la posicion en la matriz
        cmp ax,rangy         ;no valido si pulsamos fuera
        ja fuera 
        mov ah,bh
        ret
fuera:
        mov ax,0ffh
       ret
_getmousexy endp
end

domingo, 11 de agosto de 2013

WAITMOUSE

    Como dije en la entrada donde expuse el juego TIC_TAC_TOC completo (TIC_TAC_TOC 5/5),  la parte del programa en donde analizamos la pulsación del ratón, comprobamos que se encuentra dentro de el tablero y la transformamos en coordenadas de texto, puede resultar muy útil en en futuro.
    Este es un caso típico. Mientras programamos aplicaciones, nos damos cuenta que ciertas partes de las funciones pueden resultarnos muy útiles en el futuro. Es ahí cuando debemos crear nuevas instrucciones y librerías. Por esto, es deseable pararnos un momento a pensar, pues esto es lo que nos dará una nueva herramienta, y aumentará nuestro poder informático. Además nos aliviará de carga de trabajo para el futuro.

  Eso sí, hay que pensarlo bien.
  He visto que la función  me ha servido bien, y que es muy útil, si quisiera obtener la posición del ratón en coordenadas de texto y limitar su acción a una sección de pantalla como es el caso de una ventana.
    Esta función sera muy útil para gestión de menús desplegables y ventanas emergentes.
   Si la hiciéramos tal y como está en el juego no nos sirve, pues está pensada para hacer una matriz de 2 caracteres. Además se queda esperando una pulsación, lo cual nos impediría analizar varias ventanas en un mismo programa.
   Si miramos la sección de programa veremos que en realidad tiene dos partes.
   En la primera esperamos el flanco de subida de la pulsación del ratón. Eso ya sería algo útil por si mismo. Incluso, se puede pensar en hacer una función que detecte el flaco de subida o el de bajada. Es decir, detecte "push mouse" y "release mouse".
   En la segunda parte se leen e interpretan como validas las coordenadas, pasándolas a coordenadas relativas a la ventana

ESPERA PULSACIÓN
   La sección de programa es:

 espera:
        getmouse                ;lee el estado del raton
        cmp ax,1
        jnz actual              ;si no se ha pulsado se espera
        cmp bx,ax               ;si se pulso se verifica si ha sido un
        mov bx,ax               ;flanco de subida
        jnz  seleccion           ;si es así se selecciona la opción deseada
actual:
        mov bx,ax
        jmp espera
seleccion:
   
       Este código está hecho para pasar de 0 a 1 en el estado del ratón.
       El código de abajo en cambio detectaría el paso de 1 a 0

 espera:
        getmouse                ;lee el estado del raton
        cmp ax,0
        jnz actual              ;si no se ha pulsado se espera
        cmp bx,ax               ;si se pulso se verifica si ha sido un
        mov bx,ax               ;flanco de bajada
        jnz  seleccion           ;si es si se selecciona la opción deseada
actual:
        mov bx,ax
        jmp espera
seleccion:

    Ya tenemos, por lo tanto definida la función. La vamos a llamar waitmouse. Esta función esperará la pulsación y como parámetro le daremos press o release , para seleccionar el flanco 0->1 0 1->0. Si no se indica nada será press.

    Como se ve no hace falta más que cambiar la primera comparación, por lo que press=1 release=0.
    Para implementarla añadiremos estas constantes y la definición con la llamada a la función en mouse.mac, y crearemos una rutina para almacenar en la librería.


   IMPLEMENTACIÓN WAITMOUSE

MOUSE.MAC  ( a añadir a lo que ya existe)
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

press=1
release=0

waitmouse macro flanco
ifndef _waitemouse
       extrn  _waitmouse:near
endif

ifb <flanco>
     mov ax,1
else
     mov ax,flanco
endif
     push ax
     call _waitmouse
endm


WMOUSE.ASM
(C) José Angel Moneo Ferdz
include mouse.mac
    public _waitmouse
.modul compact,pascal
.code
proc _waitmouse uses bx,flanco
 espera:
        getmouse                ;lee el estado del raton
        cmp ax,flanco
        jnz actual              ;si no se ha pulsado se espera
        cmp bx,ax               ;si se pulso se verifica si ha sido un
        mov bx,ax               ;flanco de bajada
        jnz  seleccion           ;si es si se selecciona la opción deseada
actual:
        mov bx,ax
        jmp espera
seleccion:
        ret
_waitmouse endp
end




miércoles, 7 de agosto de 2013

TIC_TAC_TOE (5/5)

     Aquí está por fin el juego TIC_TAC_TOE completo, aunque simplificable mediante la posterior rutina getmousexy.
 
      Esta es al última entrada hecha con mis directivas _data,_code, _rutina. A partir de la siguiente entrada de blog, comenzaré a usar las directivas de TASM. Una vez declarada la función getmousexy, volveré a colocar este juego, pero ya totalmente en TASM 2.0

     En este caso veis como introducimos al comienzo una macro. Esta macro nos permite definir una nueva instrucción (tablero), mediante la cual pasamos los parámetros a la rutina _tablero.


TIC_TAC_TOE.ASM

; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.


title tic_tac_toe

include main.mac
include stdio.mac
include string.mac
include time.mac
include mouse.mac

.286  ; para poder usar shr al,3

; macro para crear la instrución de dibujo de tablero
tablero macro jugador,simbolo
        push bx
        mov bl,jugador
        mov bh,simbolo
        call _tablero
        pop bx
endm

_modelo exe

_stack 250

_data
;Mapa de juego
;significado tabla
;     oponente,respuesta,siguiente lista(2 byte)
;significado siguiente lista si
;   offset ->continual el juego en otro nivel
;   0-> ha finalizado el juego
;   1->  si la situación de la máquina es 30h
;   2->  si la situación de la máquina es 90H
;significado respuesta
;   si <>0 es posición de respuesta
;   si =0 no hay respuesta. Son tablas



nivel1  db 80h,20h
            dw offset n2_20h
        db 40h,20h
            dw offset n2_20h
        db 20h,80h
            dw offset n2_80h
        db 10h,80h
            dw offset n2_80h
        db 8,10h
            dw offset n2_10h
        db 4,80h
            dw offset n2_80h
        db 2,40h
            dw offset n2_40h
        db 1,40h
            dw offset n2_40h

;revisado      
n2_10h db 9,40h
           dw offset n3_40h
       db 88h,1,0,0
       db 48h,1,0,0
       db 28h,1,0,0
       db 0ch,1,0,0
       db 0ah,1,0,0
       dd 0


n2_20h db 84h,10h
          dw offset n3_10h_1
       db 44h,10h
          dw offset n3_10h_2
       db 0c0h,4,0,0
       db 90h,4,0,0
       db 88h,4,0,0
       db 82h,4,0,0
       db 81h,4,0,0
       db 50h,4,0,0
       db 48h,4,0,0
       db 42h,4,0,0
       db 41h,4,0,0
       dd 0

;revisado
n2_40h db 82h,10h
            dw offset n3_10h_3
       db 81h,4
            dw offset n3_4h
       db 22h,80h,0,0
       db 21h,80h,0,0
       db 12h,80h,0,0
       db 11h,80h,0,0
       db 0ah,80h,0,0
       db 9,80h,0,0
       db 6,80h,0,0
       db 5,80h,0,0
       db 3,80h,0,0
       dd 0


n2_80h db 60h,10h
            dw offset n3_10h_3
       db 44h,10h
            dw offset n3_10h_3
       db 50h,4
            dw offset n3_4h
       db 30h,40h,0,0
       db 28h,40h,0,0
       db 24h,40h,0,0
       db 22h,40h,0,0
       db 21h,40h,0,0
       db 0ch,40h,0,0
       db 18h,40h,0,0
       db 14h,40h,0,0
       db 12h,40h,0,0
       db 11h,40h,0,0
       db 6,40h,0,0
       db 5,40h,0,0
       dd 0

n3_4h db 70h,8
         dw offset n4_8h
      db 58h,20h,0,0
      db 52h,20h,0,0
      db 51h,20h,0,0
      db 0a1h,10h,0,0
      db 91h,20h,0,0
      db 89h,20h,0,0
      db 83h,20h,0,0
   

n3_10h_1 db 0c4h,8,0        
       db 85h,8,0,0
       db 8ch,1,0,0
       db 86h,8,0,0
       dd 0

n3_10h_2 db 0c4h,8,0,0
       db 4ch,1,0,0
       db 86h,8,0,0
       db 85,8,0,0
       dd 0

n3_10h_3 db 0c4h,2,0,0
       db 0c2h,1,0,0
       db 0c8h,2,0,0
       db 0c1h,2,0,0
       db 4ch,2,0,0
       db 86h,1,0,0
       db 85h,2,0,0
       db 8ah,4,0,0
       db 83h,4,0,0
       db 0a2h,4,0,0
       db 61h,2,0,0
       db 62h,1,0,0
       db 64h,2,0,0
       db 68h,2,0,0
       db 46h,1,0,0
       db 45h,2,0,0
       dd 0



n3_40h db 89h,4,0,0
       db 29h,80h,0,0
       db 0dh,80h,0,0
       db 0bh,80h,0,0
       dd 0
   
n4_8h  db 72h,1,1,0
       db 71h,2,1,0
       dd 0
   
   
nivel_act dw 0 ; almacen de puntero de nivel actual    
maquina db 0 ; situación de la maquina
oponente db 0 ; situación del oponente
ocupados db 0 ; estado ocupados
 
estado db 0; estado partida
posx db 0   ; posicion pulsación del raton
posy db 0
raton dw 0


titulo db "TRES EN LINEA",0
ayuda db "PULSA CON EL RATON EN LA POSICION DESEADA",0
m_gana db "Lo siento has perdido.",0
m_tablas db "Esta partida son tablas",0
m_error db " Ha surgido un error",0

tablero1 db 201,205,203,205,203,205,187,0 ; "╔═╦═╦═╗"
Tablero2 db 186,32,186,32,186,32,186,0      ; "║ ║ ║ ║"
Tablero3 db 204,205,206,205,206,205,185,0   ; "╠═╬═╬═╣"
Tablero4 db 200,205,202,205,202,205,188,0   ; "╚═╩═╩═╝

NW_intento db "Quieres intentarlo de nuevo? S/N",0

_code
tic_tac_toe proc far
        main   ; inicia
        setcursor off
        resmouse
        mouse off
        putmouse 8,8
nw:
;inicia tablero
        clrscr
        gotoxy 9,1
        puts titulo
        gotoxy 9,2
        puts ayuda
        gotoxy 9,3
        puts tablero1
        gotoxy 9,4
        puts tablero2
        gotoxy 9,5
        puts tablero3
        gotoxy 9,6
        puts tablero2
        gotoxy 9,7
        puts tablero3    
        gotoxy 9,8
        puts tablero2    
        gotoxy 9,9
        puts tablero4
        gotoxy 10,4
        putchar 'X'
        mov maquina,0
        mov oponente,0
        mov nivel_act,offset nivel1
     
otra:    
        tablero oponente,'O'
        tablero maquina,'X'


;espera seleccion oponente
        mouse on
espera:
        getmouse                ;comprueba el estado del raton
        cmp ax,1
        jnz actual              ;si no se ha pulsado se espera
        cmp ax,raton            ;si se pulso se verifica si ha sido un
        mov raton,ax            ;flanco de subida
        jnz  seleccion           ;si es asi se selecciona la opcion deseada
actual:
        mov raton,ax
        jmp espera
seleccion:
     ;toma la coordenada
        getmousex
        shr ax,4 ;divide por 16 para obtener coordenada letra
        sub ax,5 ;referencia desde cero de la posicion en la matriz
        cmp al,2  ;no valido si pulsamos fuera
        ja espera
        mov posx,al
        getmousey
        shr ax,4 ;divide por 16 para obtener coordenada letra
        sub ax,2 ;referencia desde cero de la posicion en la matriz
        cmp al,2    ;no valido si pulsamos fuera
        ja espera
        mov posy,al
     ;coloca el bit
        mov al,posy    ; posy*3+posx
        add al,posy
        add al,posy
        add al,posx

        cmp al,8       ; si pulsamos fuera no procesamos
        ja espera

        mov cl,al
        xor al,al   ; borra al
        stc    ; carry a 1
        rcr al,cl      ; situa el bit elegido
        ; comprueba que no esté seleccionada ya
   
        mov ah,oponente
        or ah,maquina
        mov ocupados,ah
        or ah,al     ;montamos nuevo bit
        cmp ah,ocupados   ; ha añadido bit nuevo?
        je  espera ; si no añade bit nuevo la posición está ya estaba ocupada
       
        or oponente,al   ; guarda la jugada
        call ver_respuesta
;presentamos la nueva posición del tablero
         ;si estado = 4 sigue el juego
        cmp estado,4
        jne sig01
        jmp otra
sig01:
       ;si estado=6 gana
        cmp estado,6
        je gano
        cmp estado,0ffh
        jne acierto
        gotoxy 10,20         ;error
        puts m_error
        jmp acabo
   
acierto:
       ;si estado=7 tablas
        gotoxy 10,20         ;ha acertado
        puts m_tablas
        jmp acabo
gano:
        mouse off
        gotoxy 10,20         ;ha acertado
        puts m_gana
acabo:    
        tablero oponente,'O'
        tablero maquina,'X'
        gotoxy 10,21
        puts nw_intento
        getch al             ;espera pulsación antes de salir
        upr                   ;convierte al en mayusculas
        cmp al,'S'
        jne  salir
        jmp nw
salir: setcursor on
        mouse off
        exit 0

tic_tac_toe endp


ver_respuesta proc near
; busca la respuesta a la situación del oponente en la tabla correspondiente
; devuelve estado=7 si gana, estado=6 si tablas y estado=4 si sigue el juego
;    0ffh= error
        mov si,nivel_act
comprueba:
        mov al,[si]    ;posibilidad
        cmp al,0        ;error fin de lista. No hay acción
        jne n_error
        mov estado,0ffh   ; marca error
        ret
n_error:
        cmp oponente,al  ;es la jugada hecha?
        je encontrado
sig_estado:
        add si,4   ; siguiente estado
        jmp comprueba
encontrado:
        mov al,[si+1]
        or maquina,al    ;añade al tablero de la máquina la jugada correspondiente
        mov al,[si+2]    ;dato siguiente estado
        cmp al,0          ;fin de la partida
        je _fin
        cmp al,1        ;tablas
        je _fin
        mov ax,[si+2]
        mov nivel_act,ax     ;pasamos el puntero del nivel a la lista del siguiente nivel
        xor al,al
        jmp _fin_ver


_fin:   or  al,2      ; devuelve al=6 si gana y al=7 si tablas
_fin_ver:            
        or  al,4      ;devuelve al=4 si sigue el juego
        mov estado,al
ret
ver_respuesta endp

_tablero proc near
; oponente viene en bl, y el simbolo a imprimir en bh
        mouse off
        shl bl,1
        jnc c2
        gotoxy 12,4
        putchar bh
c2:
        shl bl,1
        jnc c3
        gotoxy 14,4
        putchar bh
c3:
        shl bl,1
        jnc c4
        gotoxy 10,6
        putchar bh
c4:    
        shl bl,1
        jnc c5
        gotoxy 12,6
        putchar bh
c5:
        shl bl,1
        jnc c6
        gotoxy 14,6
        putchar bh
c6:
        shl bl,1
        jnc c7
        gotoxy 10,8
        putchar bh
c7:
        shl bl,1
        jnc c8
        gotoxy 12,8
        putchar bh
c8:
        shl bl,1
        jnc c9
        gotoxy 14,8
        putchar bh
c9:
        mouse on
        ret
_tablero endp
_end tic_tac_toe

sábado, 3 de agosto de 2013

TIC_TAC_TOE (3/5)

   Vais a ver hoy la forma de representar el estado de la jugada. Es el refresh del tablero.
   Podía programar  en esta rutina los bordes del tablero, pero dad que no van a borrarse la pantalla durante el juego, no tiene sentido gastar recursos en redibujar algo que ya está dibujado. Por ello, esta rutina solo rellena el interior del tablero, actualizando las "X" y las "O" según estén los bits de las variables oponente y máquina.
   Como ya se ha podido deducir de la entrada anterior, cada casilla está representada por un bit, partiendo de la segunda, contando desde la esquina superior izquierda.
  Hay nueve casillas, pero como la primera siempre es usada por la máquina como jugada inicial, quedan 8 para elegir. Por eso, un byte =8 bits, nos es suficiente para representar todas las casillas.
  Esta función, por lo tanto analiza cada bit y representa el símbolo.
   Dado que el tablero es idéntico para el oponente y la máquina, podemos utilizar la misma rutina, pasando la variable de máquina o la de oponente, según corresponda. Es por eso que se le pasa a la rutina dos parámetros. El byte con las casillas a presentar, un bit por cada una, y el símbolo a dibujar.

  Se podía haber utilizado un bucle con indices para recorrer las posibilidades, pero no quedaría ni más corto, ni más claro, ni sería más rápido, por lo que mejor lo programo de forma lineal

RUTINA _TABLERO

_tablero proc near
; oponente viene en bl, y el simbolo a imprimir en bh
        mouse off
        shl bl,1
        jnc c2
        gotoxy 12,4
        putchar bh
c2:
        shl bl,1
        jnc c3
        gotoxy 14,4
        putchar bh
c3:
        shl bl,1
        jnc c4
        gotoxy 10,6
        putchar bh
c4:       
        shl bl,1
        jnc c5
        gotoxy 12,6
        putchar bh
c5:
        shl bl,1
        jnc c6
        gotoxy 14,6
        putchar bh
c6:
        shl bl,1
        jnc c7
        gotoxy 10,8
        putchar bh
c7:
        shl bl,1
        jnc c8
        gotoxy 12,8
        putchar bh
c8:
        shl bl,1
        jnc c9
        gotoxy 14,8
        putchar bh
c9:
        mouse on
        ret
_tablero endp

viernes, 26 de julio de 2013

FUNCIONES MOUSE

Esta es la librería de funciones del ratón.
 Aquí existen algunas funciones que no están implementadas en macros de la cabecera. No todas las he usado, y por ello no creé macro.

MOUSE.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
_modelo exe
_code

      public _mouse_thd
      public _inst_sub_mouse
      public _set_rang
      public _mouse_graf
      public _vel_mouse


;DEFINE CURSOR DE TEXTO POR HARDWARE
;MOUSE_THD()
_mouse_thd proc near
        mov ax,10
        mov bx,1
        mov cx,1
        mov dx,24
        int 33h
        ret
_mouse_thd endp



;COLOCA RANGO DE MOVIMIENTO DEL RATON EN UNA CIERTA DIRECCION
;SET_RANG(INT DIRECCION,INT MINIMO,INT MAXIMO)
_set_rang proc near
        push bp                   ;DIRECCION 0 HORIZONTAL
        mov bp,sp                 ;          1 VERTICAL
        mov cx,[bp+6]
        mov dx,[bp+8]
        cmp byte ptr[bp+4],0
        jz horizontal
        cmp byte ptr [bp+4],1
        jz vertical
        pop bp
        ret

horizontal:
        mov ax,7
        int 33h
        pop bp
        ret

vertical:
        mov ax,8
        int 33h
        pop bp
        ret
_set_rang endp

;DEFINE CURSOR GRAFICO
;MOUSE_GRAF(INT CEN_X,INT CEN_Y,INT *MASK)
_mouse_graf proc near
        push bp          ;cen_x y cen_y  -16 y 16
        mov bp,sp        ; fondo       cursor   efecto
        mov ax,9         ;   0          0        0
        mov bx,[bp+4]    ;   0          1        1
        mov cx,[bp+6]    ;   1          0        invariable
        mov dx,[bp+8]    ;   1          1        invertido
        int 33h          ;
        pop bp
        ret
_mouse_graf endp

;CAMBIA LA VELOCIDAD DEL RATON
;VEL_MOUSE(INT V_HORIZONTAL,INT V_VERTICAL)
_vel_mouse proc near
        push bp
        mov bp,sp
        mov ax,15
        mov cx,[bp+4]
        mov dx,[bp+6]
        int 33h
        pop bp
        ret
_vel_mouse endp
    end

viernes, 3 de mayo de 2013

CONTROL DEL RATÓN

  Esta es la librería para control del ratón. Como en "C" la he llamado MOUSE.
  En  este caso, al ser un código muy corto, he introducido el código como macro. Hacerlo como librería no aporta reducción de código, pues la implementación de código necesario para  pasar los datos a la función de la librería, a través de pila, ocupa tanto como el código mismo.
   Por lo tanto es mejor usar directamente el código en cada función, que llamar a una rutina asociada de la librería.

   En todas la llamadas se utiliza la pila para mantener transparentes los registros, de forma que llamar a la función no nos cause problemas con los datos que ya tenemos en los registros. Esto nos permite, como en "C", usar de forma cómoda las funciones sin preocuparnos por el estado de los datos almacenadas en los registros antes de la llamada.
  
  Por ello, en la mayoría de estas macros aparecen una serie de Push a la pila, que luego serán extraídos en orden inverso de esta. Estos registros salvados en la pila son precisamente los utilizados por nuestra rutina.

 Las macros nos permitirán crear de una forma cómoda y potente llamadas a nuestras funciones

MOUSE.MAC
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

ON = 1    ; definición de estado activado
OFF = 0   ; definición de estado apagado


; definición de constantes
;acciones posibles del ratón
m_move equ 1
m_p_left equ 2  ; Pulsar botón izquierdo
m_r_left equ 4  ; Pulsar soltar izquierdo
m_p_right equ 8   ; Pulsar botón derecho
m_r_right equ 16   ; Pulsar soltar derecho
m_p_medio equ 32   ; Pulsar botón medio
m_r_medio equ 64    ; Pulsar soltar medio


; Muestra u oculta el cursor del ratón
; la opcion es ON y OFF
mouse macro opcion
        mov ax,2-opcion
        int 33h
      endm

;reinicializa el ratón
resmouse macro
        mov ax,0
        int 33h
      endm

;coloca el ratón en una posición dada
putmouse macro x,y
      push cx  
      push dx
      mov ax,4
      mov cx,x
      mov dx,y
      int 33h
      pop dx
      pop cx
     endm

;lee los botones del ratón en ax 1 izquierdo,2 derecho,4 medio
getmouse macro
        push bx
        push dx
        mov ax,3
        int 33h
        mov ax,bx
        pop dx
        pop bx
     endm

;toma la posicion x del ratón y la devuelve en ax
getmousex macro
        push bx
        push cx
        push dx
        mov ax,3
        int 33h
        mov ax,cx
        pop dx
        pop cx
        pop bx
     endm

;toma la posicion y del ratón y la devuelve en ax
getmousey macro
        push bx
        push cx
        push dx
        mov ax,3
        int 33h
        mov ax,dx
        pop dx
        pop cx
        pop bx
     endm

;comprueba la corecta instalaci¢n del ratón
mouseok macro
        mov ax,0
        int 33h
        dec ax
        endm


;Activa un procedimiento asociado al ratón
mouseint macro accion,procedure
        mov ax,0ch
        push cx
push dx
        mov cx,accion
        push es
        push cs
        pop es
        mov dx,offset procedure
        int 33h
        pop es
        pod dx
        pop cx
        endm



;TOMA EL MOVIMIENTO DEL RATÓN DESDE LA ULTIMA LLAMADA
;SOBRE EL EJE X
movx_mouse macro
        push cx
        mov ax,11
        int 33h
        mov ax,cx
        pop cx
        endm
     

;TOMA EL MOVIMIENTO DEL RATÓN DESDE LA ULTIMA LLAMADA
;SOBRE EL EJE Y
movy_mouse macro
        push dx
        mov ax,11
        int 33h
        mov ax,dx
        pop dx
        endm