Vistas de página en total

viernes, 29 de noviembre de 2013

CABECERA 48IOCENT

   Una vez que tenemos la tarjeta de E/S lista y hemos probado que llegan todas las señales correctamente y funcionan todas sus puertas, podemos comenzar a realizar el driver, o la librería para su control directo.
   Con esta librería podremos manejar ya sus puertos de forma transparente y configurar de forma sencilla la tarjeta.

    Para ello, como siempre, primero crearemos la cabecera con las constantes de control y configuración y las funciones de llamada.

    Para manejar los puertos de esta tarjeta necesitaremos:
                         Una función de configuración de tarjeta que llamaremos PioConfig.
                         Una función de envío a puerto que llamaremos OutPio.
                         Una función de lectura de puerto que llamaremos InPio.



    Aquí pongo la definición de la cabecera. En la siguiente entrada pondré la definición de las funciones que aquí llamo.



48IOCENT.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/

;DIRECCIONAMENTO DE PUERTOS DE LA TARJETA 48IOCENT
;USART 1
PA0 EQU 0
PB0 EQU 1
PC0 EQU 2
P0 EQU 3        ;REGISTRO DE CONTROL
;USART 2
PA1 EQU 4
PB1 EQU 5
PC1 EQU 6
P1 EQU 7        ;REGISTRO DE CONTROL

;CONFIGURACIONES DE LOS PUERTOS
PSALIDA EQU 80H
PA EQU  10010000B
PB EQU  10000010B
PCH EQU 10001000B
PCL EQU 10000001B

;lee un dato del puero 8255 indicado y lo devuelve en al o en la variable indicada
InPio macro dest,puerto
ifndef _inpio
        extrn _inpio:near
endif
        mov ax,puerto
        push ax
        call _inpio
ifdif <reg>,<al>
        mov dest,al
endif
endm

;envío  un dato del puero 8255 indicado
OutPio macro puerto,dato
ifndef _outpio
        extrn _outpio:near
endif

        mov ax,puerto
        push ax
        mov al,dato
        push ax
        call _outpio

 endm

;CONFIGURA UN PUERTO 8255 DE LA TARJETA
 ;PARA DEFINIR LOS MODOS DE FUNCIONAMIENTO DE LOS PUERTOS BASTARA
;INDICAR LOS QUE SEAN DE ENTRADA, LOS DEMAS SERAN DE SALIDA
;ASI PA-I PB-O PCH-I SE INDICARA COMO.. "PA" OR "PCH"
;EN EL CASO DE TODO COMO SALIDA SE INDICARA "PSALIDA"
; PIOCONFIG P0,PA,PB ESTO CONFIGURARIA EL 8255 0 CON LOS PUERTOS
; A Y B COMO ENTRADA
; el puerto C podrá ser definido por nible como entrada o salida
PioConfig macro pio,cnfg0,cnfg1,cnfg2,cnfg3
ifndef _outpio
        extrn _outpio:near
endif
        mov ax,pio
        push ax
ifnb <cnfg3>
        mov al,cnfg0 or cnfg1 or cnfg2 or cnfg3
else
  ifnb <cnfg2>
        mov al,cnfg0 or cnfg1 or cnfg2
else
  ifnb <cnfg1>
        mov al,cnfg0 or cnfg1
else
        mov al,cnfg0
endif
endif
endif
        push ax
        call _outpio
endm

 

martes, 26 de noviembre de 2013

TEST 48IOCENT

   Tras poner en la entrada anterior la tarjeta de  48 E/S, ahora hay que pensar en probarla. Para ello, podemos usar una versión modificad del programa de Test de puerto Centronics.

   lo que haremos es cambiar los textos, para que simbolicen la función asignada para la tarjeta 48IOCENT en vez de indicar la función estándar de Impresión.



TEST_48IO.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 test para poner en marcha la tarjeta 48IOcent

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 "Test tarjeta 48ioCENT  Por Jose Angel Moneo Fernández",0

datos db "Dato-378H",0
control db "Cont-37AH",0
Estado db "Esta-379H",0
iddat1 db "┌───────────── D0",0
iddat2 db "│┌──────────── D1",0
iddat3 db "││┌─────────── D2",0
iddat4 db "│││┌────────── D3",0
iddat5 db "││││┌───────── D4",0
iddat6 db "│││││┌──────── D5",0
iddat7 db "││││││┌─────── D6",0
iddat8 db "│││││││┌────── D7",0


idest1 db "---------- ────────┘││││",0
idest2 db "D3-D7----- ─────────┘│││",0
idest3 db "D2-D6----- ──────────┘││",0
idest4 db "D1-D5----- ───────────┘│",0
idest5 db "D0-D4──────────────────┘",0

idcont1 db "││││└────── WR",0
idcont2 db "│││└─────── RDL",0
idcont3 db "││└──────── RDH",0
idcont4 db "│└───────── EN DIR",0
idcont5 db "└────────── ",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. Despues borraremos el 1 inical
; en pantalla
numero dw 100h,0
ncontrol dw 100h,0
nestado dw 100h,0



.code

test48io  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
test48io endp

end test48io


sábado, 23 de noviembre de 2013

TARJETA 48IO CONTROLADA POR CENTRONICS (HARDWARE)

    Esta vez voy a colocar hardware en vez de software, por primera vez. No tiene sentido el ensamblador sin hardwre, por ello para aprender ensamblador hace falta hard.

   Voy a colocar el desarrollo de una tarjeta de 48 entradas/salidas, que será controlada por puerto centronics.

      Mediante esta tarjeta podremos controlar 6 puertos de 8 bits, configurables. 
      Esta tarjeta es una aplicaión de uso general que puede servirnos para probar, controlar o desarrollar otras futuros desarrollos hardware.
      Como la complejidad de control de manejo de los puertos de esta tarjeta aumenta respecto de la ya de por si complicada forma de manejo del Centronics, para manejarla deberemos de crear una librería de funciones.
      Estas librería estará compuesta por unas macros para crear llamadas a funciones de manejo, y una librería de funciones, que implementen las diferentes configuraciones y las diferenteS aperturas y cierres de puertos para el control a través del Centronics.
     Con la librería "48IO", que pondré en sucesivas entradas, haremos tanto el puerto Centronics, como esta tarjeta transparente a nuestras aplicaciones, de manera que será muy fácil centrarse en la tarjeta aplicación que estemos desarrollando olvidándonos del hardware que sirve de interface.
     
      Dado que la comunicación resulta crítica en muchos casos, por su ralentización en la respuesta de la aplicación que estemos desarrollando, el puerto Centronics resulta perfecto, dado que la velocidad de respuesta es muy alta en comparación con un puerto serie. Así mismo que las librerías de comunicación estén en ensamblador nos permitirá tener una gran velocidad de proceso, reservando para el proceso real, todo el mayor tiempo posible, y reduciendo al mínimo el tiempo de lectura y escritura de datos sobre la tarjeta prototipo.



ESQUEMA TARJETA 48IOCENT
 Copyright (C) 2013  José Ángel Moneo Fernández

    This program is free hardware: 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/>.

     Esta tarjeta aunque es simple, pues lleva pocos componentes, puede que necesite algunas aclaraciones.

     JP8 es el conector de alimentación
     JP7 es el conector centonics, el cual se usa para conectar al PC.
     JP1 a JP6 son los puertos de salida, colocados en conectores de 8 bits con toma de tensión y tierra, de forma que puedan usarse independientemente para alimentar y controlar diferentes tarjetas.

      El corazón del equipo son dos 8255, los cuales se utilizarán directamente como puertos. Por ello no se utilizan latch y buffer de protección. igualmente no se han colocado ningún tipo de sistema de optoacoplamiento, pues esta tarjeta es de propósito general. Estos elementos deberán ser parte de los prototipos colgados de esta carta. De manera que la protección de los 8255 queda en manos de las cartas adicionales. Esto es necesario para permitir que esta tarjeta pueda trabajar como entradas o salidas en cualquier caso.

      Como interface entre los 8255 y el puerto centronics están el U1,U4 y U5. El U1 es un buffer que sirve de puerta para pasar los datos del puerto de salida centronics a los 8255. Esto nos permitirá mover los datos del puerto centronics, sin que el 8255 vea los cambios hasta que la información esté estable. Esta puerta será abierta a través de la señal WR mediante el Strobe del puerto centronics (pin 1), que pasará a tener la función de WR.

     A su vez U4 y $5 son dos latch de 4 bits que nos permitirán recoger el bus de datos de 8 bits del 8255, y descomponerlo en dos nible. Dado que el puerto centronics no tiene un puerto de 8 bits de entradas sino solo de 4 bits. Por lo tanto usaremos el puerto de estado del centronics para recoger los datos de los 8255, en dos partes, una el nible alto y otra el nibel bajo. Este direccionamiento se hará a través de las señales RDL y RDH que serán controladas por los pines 14 y 16 del centronics. La señal del pin 14 está en el centronics invertida, por lo que para que sea más transparente a nuestro programa la invertimos por hardware mediante el inversor U2B(74LS04). De esta manera en programa consideraremos un 1 lectura, independientemente de que la señale en el centronics la inverta.

    Los diodos D1 y D2 con U2D forman una NOR qye nos permite tener una señal común de lectura para abrir el puerto de lectura de los 82555 tanto si leemos el nible bajo como si leemos el nible alto.

    El U3 es un lacth, o bufer para el almacenamiento del direccionamiento interno de los 8255. En el almacenaremos la dirección del registro al que queremos acceder dentro de los 8255. De este registro solo se usan 3 bits, y el bit alto, bit 2, será el que seleccione el 8255, mientras que los dos bit bajos seleccionan el registro interno dentro del 8255. De esta forma el mapa quedará como 4 direcciones consecutivas. Las cuatro primeas 0-3 direccionan los puertos de U6 y las siguientes 4-7 los puertos del U7.

   Para finalizar indicar simplemente que las resistencias R2,R4,R5 están puestas para asegurar el estado correcto de las señales a falta de señal.

    Esta tarjeta ha sido probada durante mucho tiempo en aplicaciones posteriores, muy complejas. Y puedo garantizar su estabilidad y perfecto funcionamiento.
     
     El esquema es tan sencillo que no resulta difícil fabricarlo en placas pretaladradas, mediante cables soldados. De hecho el primer prototipo lo fabrique así, y todavía funciona. por ello fabricar esta placa resulta muy barato. Por 15€ se puede hacer.

     Aquí tenéis el Esquema en formato PDF.
  
                                   
Prototipo Inicialtarjeta 48IOCENT
Prototipo Inicial tarjeta 48IOCENT

Prototipo Inicial tarjeta 48IOCENT

Prototipo Final tarjeta 48IOCENT

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


domingo, 17 de noviembre de 2013

LIBRERÍA PROTOCOLO DH+ Network

  Hoy voy a poner las funciones que crearán el nivel de transmisión del protocolo DH+.

  Son muy simples, pues el protocolo es muy simple.



DH_Net.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/>.

include DH.mac

    public _Recive_DH
    public _Send_DH
   
   
.model compact,pascal


.data


.code


; extrae un mensaje del la trama DH+
; se le pasa el buffer de recepción
; devuelve :

;el mensaje en el buffer
; la longitud del mensaje en dh , maximo 256 byte
; el nodo que lo envía en dl   0-255
; Si al=0ffh ha habído un error en la recepción.

;la rutina contesta al emisor directamente ack o nack.
; la bandera de salida sirve para que el procedimiento principal
;pueda contar el número de errores consecutivos y pueda detener la transmisión
; o decidir reenviar el mensaje

proc _Recive_DH  uses bx si, datos
        ;Espera SOH. ignora todo lo que llegue antes.
espera0:
        getcaux
        cmp al,dle
        jnz espera1
        getcaux
        cmp al,soh
        jnz espera0 
        ;Recogida nodo destino
        getcaux
        mov dl,al  ; recogida del nodo destino
       
        ;espera inicio de mensaje
espera1:
        getcaux
        cmp al,dle
        jnz espera1
        getcaux
        cmp al,stx
        jnz espera1
        ;recogida de mensaje
        mov bx,0       ; inicio contador e indexamiento
        mov dh,0       ; incio el checksum
        mov si,datos   ; posición del buffer
leemsg:
        getcaux
        cmp al,dle
        jz control    ; es caracter de control
copiar: 
        mov [bx+si],al
        add dh,al     ;sumo checksum
        inc bx
        jmp leemsg
       
control:  ; recogida del dle duplicado
        getcaux
        cmp al,dle
        jz copiar     ; es dle duplicado
        ; caso de ser fin de texto
        cmp al,etx    ; si no es etx es un error de recepción
        jz fin_datos
error:        ;error de mensaje  
        putcaux NACK     ; envía mensaje no reconocido 
        mov al,0ffh
        ret
    
fin_datos:    
        ;comprobamos checksum
        getcaux
        cmp dh,al
        jnz error
        putcaux ACK     ; envía mensaje reconocido
        mov al,0       ; indica recepción correcta
        mov dh,bl      ; recoge el contador de datos
   
        ret
_Recive_DH  endp

;Monta la trama DH+    dle+stx+[texto]+dle+etx+ checksum


proc _Send_dh uses bx dx cx si,nodo:byte,datos,longitud
        putcaux dle      ;Inicio de paquete
        putc
aux soh
        putcaux nodo     ;envío del nodo destino
        putcaux dle      ;STX comienzo de mensaje
        putcaux stx
        mov dl,0         ;inicio checksum
       
        ;transmision de los datos. si dato=dle se envía dle+dle
      
        mov cx,ax
        mov si,0
        mov bx,datos
resto:  mov al,[bx+si]

        cmp al,dle
        jnz no_dle
        putcaux dle
no_dle:
        mov al,[bx+si]
        add dl,al       ; añado el cara caracter al checksum
        putcaux al
        inc si
        loop resto
        putcaux dle      ;fin de mensaje
        putcaux etx
        ; fin de tansmisión de datos
       
        putcaux dl      ;envío checksum  
     
        ret
_Send_DH endp

   end


viernes, 15 de noviembre de 2013

Protocolo DH+ Network

    Debido a mi formación trabajo con  automática y a la necesidad de comunicar con autómatas concretos, el protocolo que implementé inicialmente para mis comunicaciones fue del DH+ de Allen- Bradley. Como este fue el primero que implementé, fue el que luego utilicé para mis desarrollos y el que ahora pongo.

    Es por esto, que cuando tuve que hacer cualquier comunicación entre robots y autómatas, robots y ordenadores, o ordenadores y placas con  procesadores, siempre usé este.
  
    Como no se trata de un protocolo x-modem literal, pongo un enlace en el que se explica este protocolo.
    En las librerías incorporo hasta el nivel de enlace al nivel de transporte. El resto de niveles, aunque se explican en el enlace para Allen-Bradeley, no los implementaré, pues se trata de ordenes específicas. Cada uno podrá usar los comandos que desee comunicar con sus tarjetas o equipos.




Comenzaré por lo tanto por colocar como siempre la cabecera para la llamada a las funciones.


DH.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/>.

 ; CABECERA PROTOCOLO  Data Highway II (DH+) network

include rs232.mac

;caracteres de comunicacion
SOH EQU 1      ;ENCABEZAMIENTO
STX EQU 2      ;COMIENZO TEXTO
ETB EQU 17H    ;FINAL BLOQUE (QUEDAN MAS)
ETX EQU 3      ;FINAL DE MENSAJE
ACK EQU 6      ;RECONOCIMEINTO
NACK EQU 15H   ;NO RECONOCIDO
DLE EQU 10H    ;CONTROL
ENQ EQU 5      ;SOLICITUD DE RESPUESTA
EOT EQU 4      ;FIN TRANSMISION
SYN EQU 16H    ;ESPERA SINCRONICA
CAN EQU 1BH    ;CANCELAR, ESC

; envía una cadena de datos por puerto serie mediante
; protocolo DH+
Send_DH macro nodo,datos,longitud
ifndef _Send_DH
    extrn _Send_DH:near
endif
        mov ax,nodo
        push ax
        lea ax,datos
        push ax
        mov ax,longitud
        push ax
        call _Send_DH
       
 endm

; recibe una cadena de datos por puerto serie mediante
; protocolo DH+
; devuelve en el mensaje en el buffer  datos
; dh= logitud del mensaje
; dl= nodo;   el nodo que lo envía en dl   0-255
; al=estado   Si al=0ffh error, al=0 ok
Recive_DH macro datos
ifndef _Recive_DH
    extrn _Recive_DH:near
endif
        lea ax,datos
        push ax
        call _Recive_DH
   
 endm
 

miércoles, 13 de noviembre de 2013

COMUNICACIÓN RS232

 Hoy vamos a comenzar con los puertos de comunicación, y en particular con el puerto serie.
 No vamos a usar interrupciones, ni el dos. Vamos a programar el PIO directamente.
 Para ello usaremos las nuevas funciones de la entrada anterior peek y poke.

     Con esta cabecera rearemos unas funciones básicas para inicialización, lectura y escritura sobre el PIO 8050, que nos permitirán leer y escribir sobre el puerto serie. Se pueden  ampliar después convirtiéndolas en funciones, con gestión de errores, pero como la idea de este blog es estar al menor nivel, pero que sea operativo, lo dejaré así.
    La idea del blog, como dije desde el principio es que sea didáctico a bajo nivel, pero permitiendo al mismo tiempo hacer operativo el ensamblador.
     Ya sabemos que se puede hacer mejor... pero para hacerlo mejor usaríamos las librerías ya existentes. Sin embargo los ejemplos que existen a bajo nivel no son realmente operativos sin un debuger, pues les falta implementación.

     Como ya habréis visto es blog es algo intermedio, estando siempre en bajo nivel, como si el PC fuera un microordenador, estamos haciendo programas útiles y ejecutables por si solos, sin necesidad de debuger, para ver los resultados.

   

RS232.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/>.

include io.mac

;CABECERA Y MACROS COMUNICACIÓN SERIE

;velocidades de transmisión
v4800 equ 24
V9600 EQU 12
V19200 EQU 6

;direcciones PUERTO COM 1
rtd equ 3f8h  ; Transmitter Holding Register
lsb equ 3f8h  ; Receiver Data Register SI BIT 7=0 EN LC, Baud Rate Divisor SI BIT 7=1 EN LC
msb equ 3f9h  ;Baud Rate Divisor    SI bit 7=1 LC
ie equ  3f9h  ;Interrupt Enable Register
ii equ  3fah  ;Interrupt Identification  Register
lc equ  3fbh  ;Line Control Register   
mc equ  3fch   ;Modem Control Register
ls equ  3fdh   ;Line Status Register   
ms equ  3feh   ;Modem Status  Register




; LECTURA DE CARACTER POR PUETO SERIE
getcaux macro
local rs_bien
local espera1
espera1:
        peek ls      ;LECTURA REGISTRO DE ESTADO
        test al,1eh  ; VERIFICACIÓN DE ERRORES          
        jz rs_bien    ;SI NO HAY ERROR SEGUIMOS
        peek rtd      ;TOMAMOS EL ERROR.. nO VAMOS A TRATARLO RODAVÍA. AQUÍ PODRÍAMOS TRATARLO MEDIANTE UN MENSAJE
rs_bien:
        test al,1     ; VERIFICAMOS SI HAY DATO
        jz espera1    ; ESPERAMOS RECIBIRLO
        peek rtd       ; LO LEEMOS
        endm

;ENVÍO DE CARACTER POR PUERTO SERIE
putcaux macro dato
local espera
espera: peek ls            ; SE LEE EL REGISTRO DE LECTURA
        test al,100000b     ; REGISTRO DE SALIDA DISPONIBLE
        jz espera
        poke rtd,dato      ; ESCRIBE EL DATO
        endm
       
       
;INICIALIZCIÓN DEL PUERTO A UNA VELODIAD
rs232_ini macro velocidad
        poke lc,80h         ; ACCESO A CONFIGURACIÓN DE VELOCIDAD
        mov bx,velocidad     ;ALAMACENA LA VELOCIDAD
        poke lsb,bl
        poke msb,bh
        poke lc,3           ;CONFIUGURA 8 BITS DE TRANSMISIÓN- 1 BIT DE STOP. SIN PARIDAD
        poke mc,0          
        poke ie,0
        endm

martes, 12 de noviembre de 2013

AMPLIACIÓN DE LA LIBRERÍA IO

   Vamos a ampliar la librería IO de manera que tengamos las funciones PEEK y POKE, que nos permitirán leer y escribir en un puerto del hardware.


    Esto, también, es un paso previo para la próxima entrada en la que  usaremos estas funciones para crear funciones de manejo del 8050, como puerto serie, creando un nivel de enlace mediante dos funciones getcaux, putcaux.

    Con estas últimas crearé un protocolo DH+ Network, para usar de forma sencillas en nuestras aplicaciones de comunicación serie, creando un nivel de transporte con las funciones send_dh y recive_dh.
   
   Estas nuevas funciones nos servirán así mismo, para manejar el puerto CENTRONICS. 
   En posteriores entradas veremos cómo usarlo para manejar hadware acoplado a él.
    Para dar más cache al blog incluiré algo de hardware,  para acoplar al puerto centronics y así poder convertir el ordenador en osciloscopio, analizador, o autómata a través del puerto Centronics.


     Ahora simplemente ampliaremos la cabecera IO.MAC, con estas dos funciones. Incluyo toda la cabecera nueva.
    Estas funciones las añado a IO, por considerar esta cabecera como una de Entrada-Salida no estándar, entendiendo como estándar el teclado  y la pantalla.
    Indico en rojo lo nuevo
IO.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/>.

; constantes para manejo de unidades
ifndef _unidades
    _unidades equ 1
;unidades
_A equ  0
_B equ 1
_C equ 2
_D equ 3
endif

; constantes para manejo de archivos
ifndef _atributos
   _atributos equ 1
;;atributos de fichero
_O_READ  equ 1
_HIDE    equ 2
_SISTEM  equ 4
_VOL     equ 8
_DIR     equ 16
_ARCHIVO equ 32
_TODOS   equ 00111111B
endif

;posiciones de fseek
_INICIO EQU 0
_FIN    EQU 2
_ULTIMA EQU 3

;; modos de acceso
_R EQU 0
_W EQU 1
_R_W EQU 2

;;Estructuras
_DTA struc
   _RES_DTA DB 21 DUP (?)
   _ATTR    DB ?
   _HORA    DW ?
   _FECHA   DW ?
   _LONG    DD ?
   _NOMBRE  DB 13 DUP (?)
   ENDS

;dispositivos standar
_stdin equ 0
_stdout equ 1
_stderr equ 2
_stdaux equ 3
_stdprn equ 4








;; file direccion cadena ascii fichero
;;handle numero de fichero o codigo de retorno
;;atributo es el tipo de fichero
;;si cf =1 error
;;si cf=0 ax es numero de fichero

newfile macro file,atributo,handle
     mov ah,3ch
     push cx
     push dx
     mov cx,atributo
     lea dx,file
     int 21h
     pop dx
     pop cx
     mov handle,ax
 endm


;abre un fichero. 
; devuelve cf=0 si ok y el handle en la variable handle
;devuelve cf=1 si error y el error en la variable handle
open macro file,atributo,handle

     mov ah,3dh
     mov al,atributo
     push dx
     lea dx,file
     int 21h
     pop  dx
     mov handle,ax
 endm

close macro handle
     mov ah,3eh
     push bx
     mov bx,handle
     int 21h
     pop bx
 endm


;;fichero encontrado esta escrito en la zona DTA
;;      offset descripcion
;;       0      reservado para dos
;;      21      atributo de fichero encontado
;;      22      hora
;;      24      fecha
;;      26      tamaño
;;      30      nombre del fichero y extension
;; devuelve CF=1 si hay error
findfirst macro file,atributo
ifndef _find_first
        extrn _find_first:near
endif
        lea ax,file
        push ax
        mov ax,atributo
        push ax
        call _find_first
  endm


findnext macro
ifndef _find_next
        extrn _find_next:near
endif
        call _find_next
  endm

;; posicion en un fichero el puntero
;; cx marca la parte alta de la direccion
;; para hacerlo mas sencillo nos limitaremos a 65535 bytes por lo que
;; cx=0
;; el metodo es
;;      0    principio fichero
;;      1    desde la posicion actual
;;      2    desde final de fichero
;; devuelve en dx:ax la direccion en que se ha quedado referida al principo del fichero

fseek macro handle,metodo,posicion
ifndef _fseek
        extrn _fseek:near
endif
        mov ax,handle
        push ax        
        mov ax,metodo
        push ax
        mov ax,posicion
        push ax
        call _fseek

 endm

;;obtine direcion de transferencia de disco
;;devuelve en ax un codigo de retorno
;;devuelve en es:bx direccion de DTA
offsetdta macro
      mov ah,2fh
      int 21h
  endm



;READ y WRITE devuelven en ax el número de bytes leidos
;realmente.

read macro handle,n_bytes,buffer
ifndef _read
        extrn _read:near
endif
        mov ax,handle
        push ax
        mov ax,n_bytes
        push AX
        mov ax,offset buffer
        push ax
        call _read

 endm

;lee de un fichero

rseek macro handle,numero,registro

ifndef _rseek
        extrn _rseek:near
endif
        mov ax,handle
        push ax
        mov ax,numero
        push ax
        mov ax,size registro
        push ax
        call _rseek

 endm

; indica el DTA
setdta macro posicion
      mov ah,1ah
      PUSH DX
      lea dx,posicion
      int 21h
      POP DX
  endm

;escribe en un fichero write macro handle,n_bytes,buffer
ifndef _write
        extrn _write:near
endif
        mov ax,handle
        push ax
        mov ax,n_bytes
        push AX
        lea ax,buffer
        push ax
        call _write

 endm







;Toma el path de un camino getpath macro camino,path
ifndef _getpath
      extrn _getpath:near
endif
      lea ax,camino
      push ax
      lea ax,path
      push ax
      call _getpath

endm
 
    ; envía un dato a un puerto IO
poke macro direc,dato
        push dx
        mov dx,direc
        mov al,dato
        out dx,al
        pop dx
        endm



;lee un dato de un puerto IO
peek macro direc
        push dx
        mov dx,direc
        in al,dx
        pop dx
        endm