Está en la página 1de 104

; Este es un programa en Ensamblador A51 (Keil Software) para hacer funcionar un Letrero ; Electrnico Programable. ; AUTOR: Walter C.

Lpez ;******************************************************************************* *********************** ;P R O G R A M A : L E T R E R O . A 5 1 ;******************************************************************************* *********************** ;Realiza todo el control del letrero, tiene la organizacin siguiente: ; ;La rutina del TIMER 0 realiza de manera autnoma (por medio de interrupciones) la visualizacion ;dinmica de la informacin, guardada en RAM interna a partir de la direccin 80H. ; ;Hay una Rutina inicial que se encarga de ir leyendo el primer byte de cada mens aje desde la zona ;de mensajes (situada a partir de la direccin 1C00H), en este byte se guarda el t ipo de efecto. ;Con este cdigo se realiza una bsqueda por una Tabla de Ordenes para localizar la direccin donde ;se encuentra la rutina que realiza dicho efecto. ;Cada rutina realiza una tarea diferente, y la adicin de efectos se realiza de fo rma muy cmoda. ;******************************************************************************* *********************** $ DATE (23/07/00) ;incluye en la cabecera la cadena entre parentesis (FECH A) $ DB ;incluye informacin de depuracin en el archivo objeto $ OJ ;genera un fichero objeto $ PL (72) ;page length $ PW (120) ;page width $ PRINT ;genera un fichero listing de salida $ EP (LETRERO.ERR) $ RB(0,1,2) $ NOMOD51 ;El programa no reconocer los smbolos DATA y BIT del 8051 $ INCLUDE (REG52.INC) ;Inserta el contenido del Fichero de Definicin de Registr os para el 8052 ;******************************************************************************* ************************* ;Para tener una idea exacta de la capacidad utilizada y ociosa del Microcontrola dor utilizado, haremos ;un balance de las Entradas/Salidas (I/O) utilizadas: ;P0.0 hasta P0.7 : Usado - Pines 39 a 32 (Parte baja del bus Direcciones y bus d e Datos) ;P2.0 hasta P2.7 : Usado - Pines 21 a 28 (Parte alta del bus de direcciones) ;P1.0 hasta P1.6 : Usado (pines 1 a 7) Control de las 7 lneas del Letrero ;P1.7 : (Pin 8) Libre (se usar como seal sonora o como CS para el DS12887) ;P3.0 : (Pin 10) Usado - (Latch 74LS373 para los datos serie que controlan cada columna del Letrero) ;P3.1 : (Pin 11) Usado - (Salida de los datos serie hacia los Shift Register 74L S164) ;P3.2 : (Pin 12) Usado - (INT0) Entrada de los pulsos de Clock desde el Teclado ;P3.3 : (Pin 13) Usado - (INT1) Entrada de la Interrupcin Externa proveniente del RTC ;P3.4 : (Pin 14) Usado - (Entrada de los datos provenientes del Teclado) ;P3.5 : (Pin 15) Usado - (Salida de los pulsos Clock para los Shift Register 74L S164) ;P3.6 : (Pin 16) "NO UTILIZABLE" (seal de escritura en Ram Externa)

;P3.7 : (Pin 17) "NO UTILIZABLE" (seal de lectura en Ram Externa) ;******************************************************************************* ************************* ALE BIT P3.0 DATO BIT P3.1 egisters (74LS164) CLK BIT P3.5 ) EDGEINT BIT TCON.0 KEYDAT BIT P3.4 ;El pin P3.2 (INT EXT0) se usa para la eclado ZVI IDATA VIDEO_L EQU xterna VIDEO_H EQU 00H=1536 Bytes CVIDEO_L EQU xterna CVIDEO_H EQU 100H=256 bytes MINI_L EQU MINI_H EQU MFIN_L EQU MFIN_H EQU 80H 00H 1AH 00H 19H 00H 08H 0FFH 18H ;Pin que controla el latcheo ;Pin de salida de los datos a los shift r ;Seal de reloj para los registros (74LS164

entrada de los pulsos de Clock desde el t ;Direccin comienzo zona video RAM interna ;Direccin de la 1ra zona de video en RAM e ;Capacidad de la Zona VIDEO=2000H-1A00H=6 ;Direccin de la 2da zona de video en RAM e ;Capacidad de la Zona CVIDEO=1A00H-1900H= ;Direccin comienzo Zona de Mensajes... ;...en Memoria Ram Externa ;Direccin Final Zona de Mensajes... ;...en Memoria Ram Externa

;******************************************************************************* *********************** ; INICIO DE LA ZONA DE PROGRAMA ;******************************************************************************* *********************** EXTRN CODE (CODIGOS) ;Tabla con Trama de Bits de los caractere s imprimibles EXTRN CODE (SHIFTAB) ;Tabla con la conversin SCAN CODE/ASCII pa ra SHIFTED EXTRN CODE (UNSHIFT) ;Tabla con la conversin SCAN CODE/ASCII pa ra UNSHIFTED EXTRN CODE (CLTAB) ;Tabla con la conversin SCAN CODE/ASCII pa ra Caps Lock Activated DATA_SEG SEGMENT s muy usadas STACK SEGMENT PROG SEGMENT VISUAL SEGMENT INT_EXT0 SEGMENT BIT_SEG SEGMENT PARPADEO SEGMENT OR) PGRMODE SEGMENT jes VAIVEN SEGMENT o esttico) TIMEDATA SEGMENT y fecha) RTC_PGR SEGMENT RSEG DATA IDATA CODE CODE CODE BIT CODE CODE CODE CODE CODE STACK ;segmento de DATA reservado para variable ;Segmento de IDATA reservado para el SP ;Cuerpo principal del programa ;Rutina interrupcin TIMER 0 ;Rutina Interrupcin Externa 0 ;Rutina Interrupcin TIMER 1 (parpadeo CURS ;Rutina para Modo Programacin de los mensa ;Rutina Interrupcin TIMER 2 (oscilacin text ;Rutina Interrupcin Externa 0 (atencin hora ;Rutina para Modo Programacin del RTC ;seleccionamos el segmento STACK

DS

1CH

;Reserva 1CH (28) bytes para STACK ;Shift key flag ;Flag de estado del Modo PROGRAM/NO PROGR ;Flag que indica tratamiento de ERROR en ;Flag (bit) para cambiar el valor del ori ; ;Flag que indica que estamos con cdigo de ;Flag que sirve para el parpadeo del CURS ;Flag que indica a ASTRA si se la llam des ;Flag que nos indica si estamos dentro de ;Flag que indica 2do "0" consecutivo ledo ;Flag que indica que no hay Mensajes en R ;Flag que indica que es la 1ra pasada (lo ;si hay mensajes grabados en RAM) ;Flag que indica falta ACK del envo del Cdi ;Flag que indica falta ACK del envo del Da ;Flag que indica falta ACK del envo del Cdi ;Flag que indica falta ACK del envo del Da ;Flag para encender/apagar el Led CAPS LO ;Flag que indica transmisin Micro--->Tecla ;1er bit de datos en la Transmisin Micro-;Bit para guardar el Carry "C" en la ruti ;Flag que indica Fin de Mensaje para Cdigo ;Flag que indica que se apret la Tecla "IN ;Flag que indica que se apret la Tecla "FI ;Flag que indica que no quedan msbytes de ;Flag que indica salto al origen del prxim ;Flag que indica salto al orgen del mensaj ;Flag de Temporizacin alcanzada (oscilacin ;Flag que indica que se est procesando un ;Flag que indica que estamos en RTC mode ;Flag que indica visualizacin de HORA y FE

RSEG BIT_SEG SHIFT: DBIT 1 PROGMODE: DBIT 1 AM WARNING: DBIT 1 curso TAB: DBIT 1 gen al llamar a ASTRA SIX: DBIT 1 DX_SX: DBIT 1 efecto I o D ON_ALL: DBIT 1 OR ZCODE: DBIT 1 de la Rutina DESPLAZA Z_SI: DBIT 1 un mensaje cdigo "Z". FIN_FIN: DBIT 1 (Fin de Mensajes) NO_MSG: DBIT 1 AM PASS1: DBIT 1 usamos para determinar CMD_RD: DBIT 1 go para RATE/DELAY SEND_RD: DBIT 1 to para RATE/DELAY CMD_CL: DBIT 1 go para CAPS LOCK SEND_CL: DBIT 1 to para CAPS LOCK CAPLOCK: DBIT 1 CK SEND: DBIT 1 do (11 pulsos de clock) BIT_DAT: DBIT 1 ->Teclado MASK: DBIT 1 na GOTEO FIRST_0: DBIT 1 "Z" ya fuprocesado SXINI: DBIT 1 ICIO" DXFIN: DBIT 1 N" BASTA: DBIT 1 Trama en VIDEO para FOW: DBIT 1 o mensaje REV: DBIT 1 e anterior T2_FL: DBIT 1 mensajes estticos) STATIC: DBIT 1 mensaje esttico RTC_IN: DBIT 1 VERHORA: DBIT 1

CHA pendiente ;trasladar a CVIDEO (para su desplazamiento (RLC), su copia a ZVI y posterior vi sualizacin por INT T0) RSEG VECES: DS TIEMPO: DS PORT1: DS CDPL: DS CDPH: DS ) UDPL: DS VIDEO (Low Byte) UDPH: DS VIDEO (High Byte) NBITS: DS lado NBYTES: DS LASTKEY: DS a tecla pulsada DATA_SEG 1 1 1 1 1 1 1 1 1 1 ;Variable ;Variable ;Variable ;Variable ;Variable del segundo cdigo del mensaje del primer cdigo del mensaje para guardar el estado de P1 para guardar el DPTR (low byte) para guardar el DPTR (high byte

;Guarda la direccin del ltimo byte en Zona ;Guarda la direccin del ltimo byte en Zona ;Contador de Bits que llegan desde el tec ;Nmero de Bytes en el Buffer (mximo=INMAX) ;Variable que contiene el valor de la ltim ;(til para saber si el caracter actual es

shifted or unsfifted) KEYTEMP: DS 1 KEYBUFF: DS 1 ) CURSORL: DS 1 URSOR CURSORH: DS 1 URSOR ORG_L: DS 1 ORG_H: DS 1 SALTO: DS 1 tar para pasar a la DESPLAZA) ERROR: DS 1 de error a mostrar RD_CODE: DS 1 de RATE+DELAY RD_DATA: DS 1 AY CL_CODE: DS 1 n/Off (Micro-->Teclado) CL_DATA: DS 1 (Micro-->Teclado) BYTEDATA: DS 1 >Teclado TOPMSGL: DS 1 aje Cdigo "Z" (LOW) TOPMSGH: DS 1 aje Cdigo "Z" (HIGH) CEROS: DS 1 de Mensajes "00" PDPL: DS 1 de PROGRAM PDPH: DS 1 de PROGRAM L_ROW: DS 1 DELTA: DS 1

;Used to build the key bit by bit ;Store the chars here (buffer del teclado ;Variable que contiene el byte bajo del C ;Variable que contiene el byte alto del C ; ; ;Le indica a PONVI cuantos bytes debe sal ;fila siguiente (este valor se calcula en ;Le indica a PON_CAD el nmero del mensaje ;Cdigo para enviar Micro-->Teclado el dato ;Dato Micro-->Teclado para fijar RATE+DEL ;Cdigo para enviar dato de led CAPS LOCK O ;Dato para encender/apagar led CAPS LOCK ;Dato que se enva en la transmisin Micro--;Lmite que puede alcanzar el "0" para mens ;Lmite que puede alcanzar el "0" para mens ;Contador de "ceros" para detectar el Fin ;Byte bajo de la Direccin con la que sale ;Byte alto de la Direccin con la que sale ;Longitud en bytes de cada fila de Trama ;Diferencia (Longitud Fila Trama VIDEO -

12) Se usa en DESPLAZA VECES1: DS 1 OTEO) HORA: DS 1 ora MINUTO: DS 1 Minutos DD_SEM: DS 1 e la Semana DD_MES: DS 1 el Mes MES: DS 1 del ao HORALA: DS 1 ora de Alarma MINALA: DS 1 Minutos de Alarma NRO_MSG: DS 1 A=2 y ALARMA=3) NRO_I1: DS 1 DS12887) NRO_I2: DS 1 (DS12887)

;Guarda el byte de Trama ledo (en Rutina G ;Byte que guarda el valor binario de la H ;Byte que guarda el valor binario de los ;Byte que guarda el valor binario del Da d ;Byte que guarda el valor binario del Da d ;Byte que guarda el valor binario del Mes ;Byte que guarda el valor binario de la H ;Byte que guarda el valor binario de los ;Indica el Nmero del Mensaje (HORA=1, FECH ;Contador primario de Interrup. del RTC ( ;Contador secundario de Interrup. del RTC

;Creamos un segmento absoluto tipo Code en direccin 0 (org=0), esta direccin corre sponde ;al lugar de la vectorizacin del RESET, desde aqui salta a INICIO. CSEG USING SJMP RSEG AT 0 0 INICIO PROG

;******************************************************************************* *********************** ; MACRO DIEZ_MSG ; ; DIEZ MILISEGUNDOS (SE SUPONE UN RELOJ DE 11,0592 Mhz) ENTRETIENE AL uC DURANT E 10msg APROXIMADAM. ; NOTA: Tener en cuenta que un ciclo mquinaconsume 12 pulsos de clock, por lo tan to si el cristal es ; de 11.0592 Mhz, para demorar 10msg hacen falta: (11.0592/12)x10=9216 ciclos mqu ina/msg ;******************************************************************************* *********************** DIEZ_MSG MACRO NRO10 LOCAL DIEZM_04,DIEZM_10,DIEZM_05 PUSH 01H ;2 EMPILA R1 DEL BANCO 0 PUSH 02H ;2 EMPILA R2 DEL BANCO 0 PUSH 03H ;2 EMPILA R3 DEL BANCO 0 MOV 01H,NRO10 ;Cantidad de 10 Milisegundos a temporizar DIEZM_04: MOV 02H,#20 ;2 Vale para reloj de 11.0592 Mhz DIEZM_05: MOV 03H,#45 ;2 DIEZM_10: DJNZ 03H,DIEZM_10 ;2 45*2=90 ciclos mquina DJNZ 02H,DIEZM_05 ;2 (2+2+90)*20=1880 ciclos mquina(falta lo s 4 ciclos al entrar) ;Hay que tener en cuenta que al estar los TIMERS en marcha, la cantidad de ciclo s mquina de esta Macro ;vara a causa de las demoras en ejecutarse las Rutinas de los Timers.

DJNZ POP POP POP ENDM

01H,DIEZM_04 03H 02H 01H

;2 Desempilamos R3 ;2 Desempilamos R2 ;2 Desempilamos R1

;******************************************************************************* ************************* ;FIVE_MSG: Demora al Microcontrolador durante 2.5 milisegundos (la cuarta parte que la Macro DIEZ_MSG) ;******************************************************************************* ************************* DOS5_MSG MACRO NRO5 LOCAL DOS5_04,DOS5_05,DOS5_10 PUSH 01H ;2 Empilamos R1 del Banco 0 PUSH 02H ;2 Empilamos R2 del Banco 0 PUSH 03H ;2 Empilamos R3 del Banco 0 MOV 01H,NRO5 ;NRO5 = Cantidad de 5 milisegundos a temp orizar DOS5_04: MOV 02H,#04 ;2 Vale para reloj de 11.0592 Mhz DOS5_05: MOV 03H,#45 ;2 DOS5_10: DJNZ 03H,DOS5_10 ;2 ==> 45*2=90 ciclos mquina DJNZ 02H,DOS5_05 ;2 (2+2+90)*04=376 ciclos mquina(falta los 4 ciclos al entrar) ;Hay que tener en cuenta que al estar los TIMERS en marcha, la cantidad de ciclo s mquina de esta Macro ;vara a causa de las demoras en ejecutarse las Rutinas de los Timers. DJNZ 01H,DOS5_04 POP 03H ;2 Desempilamos R3 POP 02H ;2 Desempilamos R2 POP 01H ;2 Desempilamos R1 ENDM ;******************************************************************************* ************************* ; Macro: BEEP ; Este Cdigo Sirve para generar un sonido (beep) de advertencia, estos pulsos sal drn por el pin P1.7 ; con una frecuencia de aproximadamente 9200 pulsos/seg = 9.2 pulsos/mseg, como la frecuencia del Micro ; es 11.0592Mhz=11059.2pulsos/mseg=921.6 ciclos mq./mseg ==> que debemos contar 9 2 ciclos mquina para ; producir una oscilacin en el beep de salida. NOTA : Valor Normal para W1 es 10H ;******************************************************************************* ************************* BEEP: PUSH 00H PUSH 01H CLR TR0 BEEP_10: MOV R1,#0FFH ;Ac tenemos FFH=255 repeticiones ==> total : 18*255=4590 vueltas BEEP_20: MOV R0,#8AH ;(2) Cargamos R0 con el valor para tiempo de OFF BEEP_30: DJNZ R0,BEEP_30 ;(2) Total de 24*2=48 ciclos mquina(tiempo de OFF) SETB P1.7 ;(2) Encendemos Beep MOV R0,#8AH ;(2) Cargamos R0 con el valor para tiempo de ON BEEP_40: DJNZ R0,BEEP_40 ;(2) Total de 24*2=48 ciclos mquina(tiempo de ON)

CLR DJNZ SETB POP POP RET

P1.7 R1,BEEP_20 TR0 01H 00H

;(2) Apagamos Beep

;******************************************************************************* ************************* INICIO: DLY1: MOV MOV MOV DJNZ DJNZ DJNZ R0,#0FFH R1,#0FFH R2,#004H R0,$ R1,DLY1 R2,DLY1 ;Power Supply settling time

;******************************************************************************* ************************* MOV SP,#STACK-1 ;inicializa el SP MOV TH0,#0F8H ;inicializa registros TIMER0 (para visual izacin) MOV TL0,#000H MOV TH1,#00H ;Inicializa registros TIMER1 (para parpad eo del CURSOR) MOV TL1,#00H MOV TMOD,#10H ;T1 de 16 bits y T2 de 13 bits como Tempo rizadores MOV TH2,#00H ;Inicializa registros TIMER2 (permanencia mensaje esttico) MOV TL2,#00H MOV RCAP2L,#00H ;Registro recarga TIMER 2 (low byte) MOV RCAP2H,#00H ;Registro recarga TIMER 2 (High byte) MOV T2CON,#0 ;T2 como temporizador de 16 bits con auto rrecarga ;NOTA: Para habilitar el TIMER 2 debemos setear el bit TR2. Tener en cuenta que el Flag de desborde del ;TIMER 2 (TF2) no se desactiva por hardware (debe hacerse por software) MOV RD_CODE,#0F9H ;Byte code RATE/DELAY a transmitir (7 las t code bits + Parity) MOV RD_DATA,#29H ;Byte datos RATE/DELAY a transmitir (7 la st data bits + Parity) MOV CL_CODE,#0F6H ;Byte code CAPS LOCK a transmitir (7 last code bits + Parity) MOV CL_DATA,#83H ;Byte datos CAPS LOCK a transmitir (7 las t data bits + Parity) CLR CLR rrado CLR CLR MOV MOV MOV MOV MOV CLR -->Teclado SETB EA ;habilita interrup. puestas a 1 en el reg VERHORA SHIFT KEYBUFF,#00H NBYTES,#00H NBITS,#00H LASTKEY,#00H KEYTEMP,#00H SEND ;Empezamos con Flag VERHORA=0 ;Clear Keyboard shift flag ;Condicin ;Condicin ;Condicin ;Condicin inicial para la inicial para la inicial para la inicial: No hay 1ra Int Ext 1ra Int Ext 1ra Int Ext transmisin 0 0 0 MicroRTC_IN PROGMODE ;Comenzamos con Flag RTC_IN=0 ;Empezamos con el Flag de PROGRAM MODE bo

istro IE (b7 de IE) SETB ET0 SETB TR0 SETB ET1 del TIMER 1 SETB ET2 del TIMER 2 CLR TR1 CLR TR2 SETB EX0 SETB EDGEINT e borra por hard) SETB PX0 SETB TCON.2 e borra por hard) SETB EX1 CLR NO_MSG si hubiera mensajes) CLR STATIC estticos en proceso) SETB eniente del RTC SETB el Teclado SETB l Teclado MOV ra TIMER 1) P3.3 P3.2 P3.4 17H,#4

;habilita interrup. TIMER0 ;pone en marcha TIMER0 ;Habilita Interrupcin por sobrepasamiento ;Habilita Interrupcin por sobrepasamiento ;Arrancamos con TIMER1 parado (stop) ;arrancamos con TIMER2 parado (stop) ;Habilita Interrupcin Externa 0 ;Make INT EXT 0 edge activated (el Flag s ;Alta prioridad para la Int. Ext.0 ;Make INT EXT 1 edge activated (el Flag s ;Habilita INT EXT 1 ;Empezamos con Flag NO_MSG=0 (o sea como ;Empezamos con Flag STATIC=0 (No mensajes ;INT EXT 1: Entrada de la interrupcin prov ;INT EXT 0: Entrada pulsos de clock desde ;KEYDAT: Entrada de Bits de datos desde e ;Cargamos R7 (banco 2) con el valor 4 (pa

MOV 8,#ZVI ;comenzamos apuntando al 1er byte R0 <== ZVI (08=R0 del Banco 1) MOV 0AH,#1 ;apuntamos a la 1ra lnea R2 <== 1 (0AH=R2 del Banco 1) ;Las direcciones 8(R0) y 0AH (R2) pertenecen al Banco 1 ;******************************************************************************* ************************* ;A continuacin fijamos los parmetros para el funcionamiento del RTC: MOV DPTR,#800AH MOVX A,@DPTR ANL A,#7FH ;Enmascaramos el bit MSB (UIP=update in p rogress) CJNE A,#2FH,PAR_RTC MOV DPTR,#800BH MOVX A,@DPTR CJNE A,#4EH,PAR_RTC ;En este punto sabemos que los valores en los registros A y B del RTC son correc tos CALL BEEP ;Aviso acstico MOV DPTR,#TEXT4 ;'REGISTROS RTC OK': Grabacin en Ram Exter na Okey CALL PON_CAD MOV R0,#60H DIEZ_MSG R0 ;Introducimos una demora para que se pued a ver el mensaje AJMP SIGUE ;Ahora vamos a regrabar los registros A y B del RTC (porque estn incorrectos): PAR_RTC: MOV DPTR,#800AH ;Apuntamos al Registro A del RTC ;Ahora programamos el registro A del RTC: UIP-DV2-DV1-DV0-RS3-RS2-RS1-RS0 ==> (X

0101111) MOV A,#2FH ;Cargamos los valores de DV0,DV1,DV2,RS3, RS2,RS1 y RS0 (X0101111) MOVX @DPTR,A ;Escribimos los valores en el Registro A del RTC MOV DPTR,#800BH ;Apuntamos al registro B del RTC ;Ahora programamos el registro B del RTC: SET-PIE-AIE-UIE-SQWE-DM-24/12-DSE ==> (01001110) MOV A,#4EH ;Cargamos el valor del Registro B (010011 10) MOVX @DPTR,A ;Guardamos el valor de A en el registro B del RTC MOV DPTR,#800AH MOVX A,@DPTR ANL A,#7FH ;Enmascaramos el bit MSB (UIP=update in p rogress) CJNE A,#2FH,NOGRABA CALL BEEP ;Aviso acstico MOV DPTR,#TEXT1 ;' GRABACION OKEY ': Grabacin en Ram Exter na Okey CALL PON_CAD MOV R0,#60H DIEZ_MSG R0 ;Introducimos una demora para que se pued a ver el mensaje MOV DPTR,#800BH MOVX A,@DPTR CJNE A,#4EH,NOGRABA CALL BEEP ;Aviso acstico MOV DPTR,#TEXT1 ;' GRABACION OKEY ': Grabacin en Ram Exter na Okey CALL PON_CAD MOV R0,#60H DIEZ_MSG R0 ;Introducimos una demora para que se pued a ver el mensaje AJMP SIGUE NOGRABA: CALL BEEP ;Aviso acstico MOV DPTR,#TEXT2 ;'ERROR GRABACION ' ==> Error de grabacin en Ram Externa CALL PON_CAD MOV R0,#60H DIEZ_MSG R0 ;Introducimos una demora para que se pued a ver el mensaje SIGUE: SETB PASS1 REPETIR: MOV DPTR,#0800H ;apuntamos al 1er mensaje DPTR<--0800H LAZO: MOVX A,@DPTR ;leemos cdigo del efecto (primer byte del mensaje) CJNE A,#50H,$+5 ;(3) Vemos si es "P" : Efecto Parpadeo AJMP NOCERO ;(2) El cdigo es P ==> correcto CJNE A,#44H,$+5 ;(3) Vemos si es "D" : Efecto Derecha AJMP NOCERO ;(2) El cdigo es D ==> correcto CJNE A,#49H,$+5 ;(3) Vemos si es "I" : Efecto Izquierda AJMP NOCERO ;(2) El cdigo es I ==> correcto CJNE A,#53H,$+5 ;(3) Vemos si es "S" : Efecto Sube AJMP NOCERO ;(2) El cdigo es S ==> correcto CJNE A,#42H,$+5 ;(3) Vemos si es "B" : Efecto Baja AJMP NOCERO ;(2) El cdigo es B ==> correcto CJNE A,#4EH,$+5 ;(3) Vemos si es "N" : Efecto Normal

AJMP NOCERO ;(2) El cdigo es N ==> correcto CJNE A,#47H,$+5 ;(3) Vemos si es "G" : Efecto Goteo AJMP NOCERO ;(2) El cdigo es G ==> correcto CJNE A,#5AH,$+5 ;(3) Cdigo Efecto no es (P,D,I,S,B,N,Z) in correcto (ERROR5) AJMP NOCERO ;(2) El cdigo es Z ==> correcto ;En este punto sabemos que el Cdigo Efecto no es vlido ==> No hay mensajes en RAM o es "0" lo cual ;significa que no es cdigo efecto sino que estamos al Final del ltimo Mensaje (Cdig o 00) CJNE A,#0,$+8 ;(3) Si no es "0" ==> ERROR5: No hay Mens ajes en RAM JB PASS1,$+5 ;(3) Si PASS1=1 ==> ERROR5 AJMP REPETIR ;(2) Si es "0" ==> Final de Mensajes (rep etir) CALL BEEP ;Generamos un BEEP de advertencia MOV DPTR,#ERROR5 ;' NO TEXT IN RAM ' CALL PON_CAD ;Escribimos CODIGO ERROR 5 y luego... MOV R0,#60H DIEZ_MSG R0 SETB NO_MSG ;No hay Mensaje en Zona Mensajes Ram Exte rna SETB PROGMODE ;...Ponemos el bit PROGMODE a 1 SJMP IN_PROG ;Entramos automticamente en PROGRAM MODE NOCERO: MOV CDPL,DPL ;guardamos DPL MOV CDPH,DPH ;guardamos DPH CALL LLAMA ;buscamos direccin del subprograma que pro duce el efecto JNB PROGMODE,IF_RTC ;Si PROGMODE=0 ==> Probamos con RTC_IN IN_PROG: CALL PROGRAM ; Si PROGMODE=1 ==> Entramos en modo PROG RAM MOV DPL,PDPL ;Apuntamos al siguiente "caracter" en Zon a de Mensajes RAM EXT. MOV DPH,PDPH ; IF_RTC: JNB RTC_IN,IF_IE1 ;Si RTC_IN=0 ==> Probamos con VERHORA CALL BEEP MOV DPTR,#TEXT5 ;'ENTRAR MODO RTC ' CALL PON_CAD MOV R0,#50H DIEZ_MSG R0 CALL RTC ;Si RTC_IN=1 ==> Entramos en Modo RTC (pr ogramacin del RTC) MOV DPL,PDPL ;Apuntamos al siguiente "caracter" en Zon a de Mensajes RAM EXT. MOV DPH,PDPH IF_IE1: JNB VERHORA,DE_NUEVO CALL BEEP MOV DPTR,#TEXT6 ;'ENTRAR A VERTIME' CALL PON_CAD MOV R0,#60H DIEZ_MSG R0 CALL VERTIME ;Llamamos Rutina visualizacin Mensaje HORA y FECHA MOV DPL,PDPL ;Apuntamos al siguiente "caracter" en Zon a de Mensajes RAM EXT. MOV DPH,PDPH DE_NUEVO: LJMP LAZO ;*******************************************************************************

*********************** ; Nombre: LLAMA ; Esta rutina busca la direccin del subprograma que produce el efecto ;******************************************************************************* *********************** LLAMA: MOV R0,A ;guarda en R0 el 1er codigo (EFECTO) que figura en el mensaje MOV DPTR,#ORDENES ;apuntamos a la tabla de ordenes (P, D, I , S, B, N, Z) MOV R1,#TOTAL ;total de efectos disponibles *** (NO ES NECESARIO) *** BUCLE: MOV A,#00H MOVC A,@A+DPTR ;leemos cdigo en tabla de rdenes y CJNE A,0,BUC_10 ;lo comparamos con el 1er cdigo del mensaj e (guardado en R0) CLR PASS1 ;PASS1=0 porque el cdigo es vlido y se va a leer el mensaje LJMP BUC_20 ;cdigo encontrado (coinciden los dos) BUC_10: ;cdigo no encontrado (no coinciden) INC DPTR ;si no coinciden vemos el siguiente cdigo en la tabla DJNZ R1,BUCLE ;vamos a BUCLE para compararlo con el cdig o del mensaje ; Ac podriamos colocar una porcin de cdigo para el caso de que R1 llegue a "0" o se a que el cdigo ; efecto sea desconocido pero, como eso no ocurrir, no ponemos nada (porque los Cd igos Efecto son ve; rificados en el momento de escribirlos). BUC_20: DEC R1 ;decrementamos R1 MOV A,R1 ;se suma 3 veces R1 porque cada instruc. LJMP ocupa 3 bytes ADD A,R1 ;de memoria de cdigo ADD A,R1 MOV DPTR,#SALTOS ;DPTR contiene la direccion de SALTOS JMP @A+DPTR ;direccion=DPTR+offset(A) ;******************************************************************************* *********************** ; TABLA DE SALTOS ;******************************************************************************* *********************** SALTOS: LJMP GOTEO LJMP DESPLAZA LJMP NORMAL LJMP BAJA LJMP SUBE LJMP IZQUIERDA LJMP DERECHA LJMP PARPADEA ;******************************************************************************* *********************** ; CODIGOS DE LOS EFECTOS ;******************************************************************************* *********************** ORDENES:

DB lo tanto DB ejemplo en DB a la cual DB in es: DB DB DB DB TOTAL EQU

'P' 'D' 'I' 'S' 'B' 'N' 'Z' 'G' $-ORDENES

;cada instruccin LJMP ocupa 3 bytes de cdigo, por ;si la coincidencia de los cdigos se produce por ;R1=5 (cdigo D) entonces para obtener la direccin ;saltar hacemos: 3*(R1-1)=12, entonces la direcc ;SALTOS + 12

;******************************************************************************* *********************** ; COMIENZO DE LAS RUTINAS GENERALES DE USO ;******************************************************************************* *********************** ;******************************************************************************* *********************** ; RUTINA DE INTERRUPCION DEL TIMER 0 ; A cada interrupcin se visualiza una nueva lnea ; R0 : Apunta al 1er byte de la ZVI (R0 del Banco 1) - Recordar que en INICIO fi gura: MOV 8,#ZVI ; R1 : Cuenta bytes por lnea ; R2 : Numero de lnea (R2 del banco 1) - Recordar que en INICIO figura: MOV 0A H,#1 ; R3 : Bits por Byte ;******************************************************************************* *********************** ;Creamos un segmento absoluto tipo code en direccion 0BH, esta direccion corresp onde ;al lugar de la vectorizacion de la Interrup. del Timer 0. CSEG USING LJMP RSEG INT_TIM0: PUSH Registros PUSH ACC SETB RS0 ;cambiamos al BANCO 1 CLR RS1 ; A continuacin cargamos R1 con la cantidad de bytes por lnea (12) esto es vlido pa ra un letrero con ; 16 caracteres. En el caso de que estemos por visualizar un mensaje con cdigo "Z " debemos tener en ; cuenta que en ZVI tenemos 24 caracteres (o sea 18 bytes por lnea) pero solo pod emos visualizar 16 ; (o sea 12 bytes por lnea) por lo tanto los 6 bytes por lnea sobrantes deben ser "saltados" y conti; nuar en la siguiente lnea. MOV VI_10: MOV l mensaje) R1,#12 A,@R0 ;nmero de bytes por lnea ;lee byte (porque vimos que R0 apuntaba a PSW ;Salvamos estado de los flags y Banco de AT 000BH 1 INT_TIM0 VISUAL

MOV VI_20:

R3,#8

;8 bits por byte ;dato en Pin de salida (entrada serie del ;genera un pulso de clock (dato adentro d ;otro bit (decrem. y salta si no cero) ;apuntamos al prximo byte ;Va por otro byte (hasta completar los 12 ;activamos lnea (en la primera pasada R2=1 ;cargamos Latches de salida ;preparamos la prxima lnea a visualizar ;desplazamos el "1" un lugar a la izquier ;siguiente lnea ;nuevo valor en R2 (corresponde a la sigu ;porque son 7 filas (la P1.7 no es utiliz

RLC A MOV DATO,C shift register 74LS164) CALL CLOCK el registro) DJNZ R3,VI_20 INC R0 DJNZ R1,VI_10 bytes de la lnea) MOV P1,R2 ) SETB CLR MOV RL da para activar la MOV iente lnea) JNB ada por ahora) ACC.7,VI_30 ALE ALE A,R2 A R2,A

;desde P1.0 a P1.6 son las filas ; Como ya visualizamos las 7 filas (ACC.7 = 1), entonces volvemos a las condicio nes iniciales para que ; en la prxima INT_TIM0 empecemos otra vez desde el principio. MOV R2,#1 ;preparamos de nuevo la 1ra lnea MOV R0,#ZVI ;apuntamos al 1er byte de RAM interna VI_30: MOV TH0,#0F8H ;inicializamos registros del Timer0 (a ca da interrupcin MOV TL0,#000H ;visualizamos una nueva lnea) POP ACC POP PSW CLR RS0 ;volvemos al BANCO 0 RETI CLOCK: CLR CLK ;pulso de reloj para los registros SETB CLK RET ;******************************************************************************* *********************** ; Nombre: RUTINA INTERRUPCION TIMER 1 ; Esta rutina se encarga de hacer parpadear el CURSOR mientras se est en PROGRAM MODE ;******************************************************************************* *********************** CSEG del TIMER 1 USING LJMP RSEG INT_TIM1: PUSH PUSH PUSH DPH DPL PSW 2 INT_TIM1 PARPADEO ;Usaremos el Banco de Registros 2 AT 001BH ;Lugar de la Vectorizacin de la Interrup.

PUSH CLR SETB DJNZ cuentas del TIMER1 SJMP INT_T10: LJMP CPL MOV es" del TIMER 1

ACC RS0 RS1 R7,INT_T10 $+5 O_LOOP ON_ALL R7,#4

;Activamos Banco de Registros 2 ;(2) Entramos solo cuando se completan R7 ;(2) ;(3) ;Se entra en INT_TIM1 despus de 5 "desbord

CLR C ;Por las dudas borramos el Carry MOV DPL,#VIDEO_L ;Comenzamos apuntando al origen... MOV DPH,#VIDEO_H ;de la Zona de memoria Ram Externa ;A continuacin debe tenerse en cuenta que la posicin del CURSOR est dada por los 2 bytes CURSORL y ;CURSORH, donde la diferencia entre CURSORH y 0800H es lo que debe tenerse en cu enta MOV A,CURSORL SUBB A,ORG_L ;A=Distancia en bytes entre el origen del mensaje y el CURSOR MOV R0,#ZVI ;Apuntamos a ZVI (Zona Video Ram Interna) MOV B,#8 ; DIV AB ;A=distancia en "octetos" de caracteres ( B=resto de bytes) MOV R1,B ;B=R1=distancia en "caracteres" (resto de la divisin) MOV B,#6 ; MUL AB ;A=distancia "parcial1" en bytes de Trama (B=0) PUSH ACC ADD A,R0 MOV R0,A ;R0 an no apunta al CURSOR pues faltan los "caracteres" de R1 MOV A,R1 MOV B,#6 MUL AB ;A=cantidad bits de trama que faltan para llegar al CURSOR (B=0) MOV B,#8 DIV AB ;A=Nro bytes de trama que faltan para lle gar al byte donde est ;el CURSOR y B=bits que faltan rotar al ltimo byte para estar realmente sobre el CURSOR MOV R1,A ADD A,R0 MOV R0,A ;Ahora finalmente R0 apunta al byte de tr ama que contiene "algu;nos" bits del CURSOR. POP ACC ;Desempilamos distancia "parcial1" ADD A,R1 ;Sumamos las 2 distancias parciales MOV R1,A ;Guardamos distancia "total" en R1 ;A continuacin hacemos que tambin el DPTR apunte al 1er byte de los 2 que vamos a rotar MOV A,DPL ADD A,R1 MOV DPL,A JNC $+4 ;(2) INC DPH ;(2) ;A continuacin debemos tener en cuenta que el bit SIX nos indica que estamos sobr e los bits que perte-

;necen al CURSOR. CLR SIX MOV R6,#7 ;R6=Nro de lneas para repasar (7 lneas) PROXIM: MOV R1,#6 ;R1=cantidad de bits del caracter apuntad o por el CURSOR a rotar PUSH B ;Guardamos B ( Nro de bits a rotar sin ca mbios) MOV A,B ;Si comenzamos con B distinto de 0 entonc es ==> que 1ro debemos ; rotar el byte a la SX (RLC) "B" veces y, luego recin estaremos en condicin de ac tuar sobre los bits ; del CURSOR y reemplazarlos por "0" o dejarlos tal cual. JNZ $+5 ;(2) Si B no es igual a "0" seguimos norm almente DEC R1 ;(1) DEC R1 para que solo se acte sobre 5 columnas del caracter SETB SIX ;(2) Si B=0 ==> el CURSOR est al comienzo del byte por lo tanto ; debemos reemplazar por "0" o "dejarlo tal cual" (segn el bit ON_ALL) los siguie ntes 6 bits y luego ; los otros sextetos (de las otras filas), para hacerlo debemos setear el bit SI X. MOV R3,#2 ;R3=Nmero de bytes para rotar (solo rotamo s 2 bytes) INC_PTR: MOV R2,#8 ;R2=cantidad de bits por byte MOVX A,@DPTR ;Leemos el byte apuntado por DPTR (desde RAM externa) MOV R4,A MOV A,R4 ;R4 contiene el byte que ser cambiado (sol o algunos bits) RLC A ;Los 1ros B bits del byte deben ser rotad os sin cambiarlos MOV R4,A R_LEFT: JB ON_ALL,$+7 ;(3) Reemplazamos todos los bits del cara cter por "0" ;En este punto tenemos ON_ALL=0, por lo tanto debemos "dejar tal cual" al byte d el CURSOR, para esto lo ;que hacemos es "rotar" una vuelta completa y dejarlo como estaba. RLC A ;(1) MOV R4,A ;(1) SJMP DEC_R2 ;(2) JNB SIX,TIM1_4 ;(3) Primero debemos "rotar a la SX" B ve ces, luego reemplazamos ;los bits del caracter donde est el CURSOR por "0" CLR C ;Ac ya estamos apuntando al caracter del C URSOR y tenemos que ;reemplazar todos sus bits por "0" (carac ter todo iluminado) RLC A MOV R4,A SJMP TIM1_5 ;A continuacin lo que hacemos en TIM1_4 es "rotar" B bits sin cambios, luego los dems(8-B) bits del ;byte se reemplazarn por "0". Los "0" que falten (si es que faltan) para los 6 bi ts del caracter del ;CURSOR, se agregarn en el siguiente byte. TIM1_4: RLC MOV A R4,A ;Guardamos en R5 el byte nuevo que se com

pletar con B bits sin ;cambios, luego con (8-B) bits "ceros". Los bits (ceros) que falten para los 6 d el caracteres se agrega;garn en el siguiente byte. DJNZ B,DEC_R2 ;(3) Si B no es 0 debemos seguir "rotando a la SX" SETB SIX ;(1) Si B=0 debemos poner "ceros" en los siguientes 6 bits, pero ;debemos tener en cuenta que al llegar a los 8 bits se debe guardar el byte comp leto y saltar al si;guiente, luego "rotar" este poniendo "ceros" nada msque hasta completar los 6 bi ts del caracter apun;tado por el CURSOR, los demsbits quedan sin cambios. TIM1_5: CURSOR DEC_R2: DJNZ R1,DEC_R2 ;(2) R1=contador de bits del caracter del

CLR SIX DJNZ R2,R_LEFT ;(2) R2 es el contador de bits por byte MOV A,R4 ;El siguiente paso es escribir en ZVI el byte "rotado" antes de hacerlo sera conv eniente detener el ;TIMER 0 (porque la Rutina de la Interrupcin del TIMER 0 lee en la ZVI) MOV @R0,A ;Guardamos byte "rotado" directamente en ZVI INC R0 ;Apuntamos al siguiente byte de la ZVI (p ara sobreescribirlo) INC DPTR ;Apuntamos al siguiente byte de VIDEO (pa ra leerlo y rotarlo) DJNZ R3,INC_PTR ;Decrementamos contador de bytes a rotar (solo rotamos 2) ;En este punto ya rotamos los 2 bytes de trama correspondiente a una fila y, nos faltan las otras, para ;pasar a la siguiente fila debemos "saltar" 10 bytes, pues cada fila de trama oc upa 12 bytes pero como ;ya pasamos 2, solo nos restan 10 ms. DJNZ R6,$+6 ;(2) Vamos por la siguiente fila POP B ;(2) Ya rotamos la ltima fila SJMP O_LOOP ;(2) Si ya pas la ltima "fila" salimos de l a Interrupcin CLR C ;Para que no influya en la suma que sigue MOV A,R0 ;Cargamos el "apuntador" a la ZVI ADD A,#0AH ;Saltar 10 (0CH) bytes para rotar la sigt e lnea del CURSOR MOV R0,A ;Apuntamos a la siguiente "fila" en Ram I nterna CLR C MOV A,DPL ADD A,#0AH MOV DPL,A JNC $+4 INC DPH POP B ts a rotar sin cambios) LJMP PROXIM O_LOOP: MOV TH1,#00 MOV TL1,#00 POP ACC POP PSW POP DPL ;Para que no influya en la suma que sigue

;Desempilamos valor original de B (Nro bi ;Recargamos registros del TIMER1

POP RETI

DPH

;******************************************************************************* *********************** ; Nombre: RUTINA INTERRUPCION TIMER 2 ; Esta rutina se encarga de fijar la frecuencia de la oscilacin para mensajes estt icos. ;******************************************************************************* *********************** CSEG AT 002BH ;Lugar de la Vectorizacin de la Interrup. del TIMER 2 USING 2 ;Usaremos el Banco de Registros 2 LJMP INT_TIM2 RSEG VAIVEN ;Segmento de programa relocalizable INT_TIM2: CLR TF2 ;El flag activado por el desborde del TIM ER 2 se borra por soft PUSH DPH PUSH DPL PUSH PSW PUSH ACC CLR RS0 SETB RS1 ;Activamos Banco de Registros 2 DJNZ R6,T2_10 ;Entramos despus de R6 Temporizaciones SETB T2_FL ;Activamos Flag de Temporizacin alcanzada T2_10: POP ACC POP PSW POP DPL POP DPH RETI ;******************************************************************************* ************************* ;Nombre: RUTINA INTERRUPCION EXTERNA 1 ;Esta Rutina se encarga de la visualizacin de la HORA y FECHA. ;******************************************************************************* ************************* ;Para las funciones de RTC usamos el Chip DS12887 el cual tiene integrados ademsu na batera de Litio, ;el Cristal de cuarzo y circuito de proteccin contra escritura. ;Los puntos a tener en cuenta son los siguientes: ;1) El pin 1 "MOT" debe estar conectado a GND (Bus Intel) ;2) El pin 13 "CS" del RTC es el Chip Select y es activo bajo. Este pin lo manej aremos como una direccin ; de memoria, usaremos el pin 28 (A15) para hacer seleccionar el RTC y deselec cionar la RAM, para hacer ; esto usaremos una NAND (MC74F00) con su salida "invertida" conectada al CS d el RTC y una conexin di; recta del pin 28 maneja el CS de la RAM. CSEG Externa 1 USING LJMP RSEG INT_EXT1: PUSH PUSH DPH DPL 2 INT_EXT1 TIMEDATA ;Usaremos el Banco de Registros 2 ;Segmento de programa relocalizable AT 0013H ;Lugar de la Vectorizacin de la Interrupcin

PUSH PSW ;Para resguardar el Banco de Registros y luego "desempilarlo" PUSH ACC CLR TR0 ;Stop TIMER 0 CLR RS0 SETB RS1 ;Activamos Banco de Registros 2 ;Ahora debemos leer el registro C del RTC para que se resetee el flag que provoc la Interrupcin: MOV DPTR,#800CH ;Apuntamos al registro C del RTC MOVX A,@DPTR ;Leemos el registro C ;Las interrupciones son generadas por el Pin IRQ del DS12887 y se producen una v ez cada 0.5 seg., por lo ;tanto contaremos 1800 (40x45=1800) interrupciones antes de setear el Bit VERHOR A: INC NRO_I1 ;Incrementamos contador primario de inter rrupciones MOV A,NRO_I1 CJNE A,#45,IE1_OUT MOV NRO_I1,#0 ;Ponemos contador primario a cero INC NRO_I2 ;Incrementamos contador secundario de int errupciones MOV A,NRO_I2 CJNE A,#20,IE1_OUT MOV NRO_I1,#0 ;Ponemos contador primario a cero MOV NRO_I2,#0 ;Ponemos contador secundario a cero SETB VERHORA ;Seteamos Flag de Visualizacin Hora pendie nte IE1_OUT: SETB TR0 ;Start TIMER 0 POP ACC POP PSW POP DPL POP DPH RETI ;******************************************************************************* ************************* ;Nombre: VERTIME ;Esta Rutina se encarga de mostrar la HORA y FECHA en cada interrupcin del RTC. ;******************************************************************************* ************************* VERTIME: ; MOV PDPL,DPL ;Guardamos valor DPTR al prximo mensaje ; MOV PDPH,DPH ;Antes de leer los registros de HOURS y MINUTES, debemos asegurarnos que no se p roduzca un Update duran;te el mismo; para ello esperamos (ciclamos) hasta que PF=1 (registro C), luego hacemos SET=1, y ya esta;mos listos para leer los registros del RTC: MOV DPTR,#800CH ;Apuntamos al registro C del RTC IEXT_10: MOVX A,@DPTR JNB ACC.6,IEXT_10 ;Ciclamos hasta que PF=ACC.6=1 MOV DPTR,#800BH ;Apuntamos al registro B del RTC MOVX A,@DPTR ORL A,#80H ;Ponemos el bit SET=1 (en el registro B) (mscara=10000000b) MOVX @DPTR,A ;Copiamos el nuevo valor en B ;Lo que tenemos que hacer ahora es leer los registros de Horas (8004H) y Minutos (8002H) y luego copiar;los en sus ubicaciones respectivas (8029H-802AH) y (802CH-802DH)

;******************************************************************************* ************************* ;A continuacin copiamos en el "mensaje" los valores reales de Horas y Minutos del RTC: MOV DPTR,#8004H ;Apuntamos al registro HOURS del RTC MOVX A,@DPTR ;Leemos el registro HOURS (valor binario) ;Ahora debemos copiar el nible SX (decenas) en 8029H y el nibble DX (unidades) e n 802AH: MOV B,#10 DIV AB ;A=cociente (decenas) - B=resto (unidades ) ADD A,#30H MOV DPTR,#8029H MOVX @DPTR,A ;Guardamos decenas de Horas MOV A,B ADD A,#30H INC DPTR MOVX @DPTR,A ;Guardamos unidades de Horas ;Ahora leemos registro MINUTES y copiamos el nibble SX (decs) en 802CH y el nibb le DX (unids) en 802DH: MOV DPTR,#8002H ;Apuntamos al registro MINUTES del RTC MOVX A,@DPTR MOV B,#10 DIV AB ADD A,#30H MOV DPTR,#802CH MOVX @DPTR,A ;Guardamos decenas de Minutos MOV A,B ADD A,#30H INC DPTR MOVX @DPTR,A ;Guardamos unidades de Minutos ;******************************************************************************* ************************* ;A continuacin copiamos en el "mensaje" los valores reales de los 3 registros de Fecha del RTC, los que ;estn situados en las direcciones (8006H, 8007H y 8008H) ;*** PRIMER REGISTRO (DAY OF THE WEEK) (address 8006H) *** MOV DPTR,#8006H ;Apuntamos al registro DAY OF THE WEEK MOVX A,@DPTR ;Leemos el valor en el registro DEC A ;Porque mnimo valor de DAY OF THE WEEK es 1 MOV B,#3 ;Porque cada "da" tiene 3 letras MUL AB ;A=offset para entrar a la tabla D_WEEK MOV R1,#44H ;Valor para DPL cuando apunte al 1er cara cter del "da" MOV R0,#3 ;Ser en contador de los caracteres del "da" IEXT_20: PUSH ACC MOV DPTR,#D_WEEK ;Apuntamos a la Tabla de los Das de la Sem ana MOVC A,@A+DPTR ;Apuntamos al "da" de la Tabla que corresp onde ;Ahora debemos copiar los 3 caracteres del "dia" en el lugar correspondiente del mensaje que mostrar ;la fecha del sistema: N33 DOM 00 ENE 0 (direccin base 8030H): MOV DPH,#80H MOV DPL,R1 MOVX @DPTR,A ;Copiamos el "da" de la Tabla en el Mensaj e de Fecha POP ACC INC A ;Apuntamos al siguiente caracter del "dia

" de la Tabla en EPROM INC R1 ;Apuntamos al siguiente caracter del "da" del mensaje en Ram Ext. DJNZ R0,IEXT_20 ;******************************************************************************* ************************* ;*** SEGUNDO REGISTRO (DAY OF THE MONTH) (Address 8007H) *** MOV DPTR,#8007H ;Apuntamos al registro DAY OF THE WEEK de l RTC MOVX A,@DPTR ;Leemos el registro del "da del mes" ;Ahora debemos copiar el nible SX (decenas) en 8048H y el nibble DX (unidades) e n 8039H: MOV B,#10 DIV AB ;A=cociente (decenas) - B=resto (unidades ) ADD A,#30H MOV DPTR,#8048H MOVX @DPTR,A ;Guardamos decenas de "da del mes" MOV A,B ADD A,#30H INC DPTR MOVX @DPTR,A ;Guardamos unidades de "da del mes" ;******************************************************************************* ************************* ;*** TERCER REGISTRO (MONTH) (Address 8008H) *** MOV DPTR,#8008H ;Apuntamos al registro MONTH MOVX A,@DPTR ;Leemos el valor en el registro DEC A ;Porque mnimo valor de MONTH es 1 MOV B,#3 ;Porque cada "mes" tiene 3 letras MUL AB ;A=offset para entrar a la tabla MONTHS MOV R1,#4BH ;Valor para DPL cuando apunte al 1er cara cter del "mes" MOV R0,#3 ;Ser en contador de los caracteres del "me s" IEXT_25: PUSH ACC MOV DPTR,#MONTHS ;Apuntamos a la Tabla de los Meses del ao MOVC A,@A+DPTR ;Apuntamos al "mes" de la Tabla que corre sponde ;Ahora debemos copiar los 3 caracteres del "mes" en el lugar correspondiente del mensaje que mostrar ;la fecha del sistema: N33 DOM 00 ENE 0 (direccin base 8040H): MOV DPH,#80H MOV DPL,R1 MOVX @DPTR,A ;Copiamos el "mes" de la Tabla en el Mens aje de Fecha POP ACC INC A ;Apuntamos al siguiente caracter del "mes " de la Tabla en EPROM INC R1 ;Apuntamos al siguiente caracter del "mes " del mensaje en Ram Ext. DJNZ R0,IEXT_25 ;Ahora que los valores reales de HORA, FECHA y ALARMA fueron ya copiados, hacemo s de nuevo SET=0: MOV DPTR,#800BH ;Apuntamos al registro B del RTC MOVX A,@DPTR ANL A,#7FH ;Ponemos el bit SET=0 (registro B) (sin a fectar los demsbits) MOVX @DPTR,A ;Copiamos el nuevo valor en B ;A continuacin debe estar el cdigo para la visualizacin de los 2 mensajes (HORA y F

ECHA), para la vi;sualizacin usaremos la Rutina IZQUIERDA (o quizs DERECHA): MOV CDPL,#20H ;Apuntamos al orgen del Mensaje de la HORA MOV CDPH,#80H CALL BEEP ;Generamos un BEEP de advertencia MOV DPL,CDPL ;Apuntamos al orgen del Mensaje de la HORA MOV DPH,CDPH CALL LLAMA MOV CDPL,#40H ;Apuntamos al orgen del Mensaje de la FECH A MOV CDPH,#80H CALL BEEP ;Generamos un BEEP de advertencia MOV DPL,CDPL ;Apuntamos al orgen del Mensaje de la FECH A MOV DPH,CDPH CALL LLAMA ; MOV DPL,PDPL ;Recuperamos puntero (DPTR) al prximo Men saje ; MOV DPH,PDPH CLR VERHORA ;Borramos flag de Visualizacin Hora pendie nte RET ;******************************************************************************* ************************* ;NOMBRE: VERIFICA : Comprueba que los mensajes en EPROM y en RAM EXT. RTC sean i d nticos ;DPTR: Apunta al orgen del mensaje guardado en EPROM ;R0: Cantidad de caracteres a verificar ;R1: Byte bajo de la direccin del mensaje en Ram Ext. (RTC) ;******************************************************************************* ************************* VERIFICA: MOV A,#0 ;Offset para leer los caracteres del mens aje (guardado en EPROM) VERIF05: PUSH DPL ;Empilamos DPTR orgen del mensaje "formato " en EPROM PUSH DPH PUSH ACC MOVC A,@A+DPTR ;Leemos caracter del mensaje "formato" gu ardado en EPROM MOV B,A ;Guardamos caracter ledo en B MOV DPH,#80H ;Apuntamos al orgen del mensaje guardado e n Ram Ext. (del RTC) MOV DPL,R1 MOVX A,@DPTR ;Leemos el caracter del mensaje en Ram Ex terna (RTC) CJNE A,B,OTRAVEZ ;Caracter mal grabado en RAM EXTERNA RTC POP ACC INC A ;Apuntamos al prximo caracter del mensaje "formato" en EPROM INC R1 ;Apuntamos al prximo caracter del mensaje en Ram Ext.(RTC) POP DPH ;Desempilamos DPTR orgen del mensaje "form ato" en EPROM POP DPL DJNZ R0,VERIF05 ;Vamos por el prximo caracter RET ;Mensaje grabado okey (seguimos con el pr ograma) OTRAVEZ: CALL BEEP

MOV DPTR,#TEXT2 ;Aparece el mensaje 'ERROR GRABACION ' CALL PON_CAD MOV R0,#60H DIEZ_MSG R0 ;En este punto sabemos que los mensajes en RAM EXT. RTC no coinciden con los gua rdados en EPROM, por lo ;tanto debemos escribirlos de nuevo. ;******************************************************************************* ************************* ;A continuacin escribiremos en la Ram del RTC (8020H, 8035H y 8050H) los "formato s" de los mensajes de ;HORA, FECHA y ALARMA que estn definidos en memoria EPROM y que son: HORA_TX, FEC HA_TX y ALARM_TX. ;******************************************************************************* ************************* ;Ahora debemos escribir el "formato" del mensaje de la Hora: N33 HORA 00:00--0 ( situado en HORA_TX de la ;memoria de programas) en la direccin 8020H de la Ram Externa: GRAB00: MOV ensaje MOV R0,#17 ;Cantidad de caracteres del mensaje MOV A,#0 ;Offset para leer los caracteres del mens aje (guardado en EPROM) GRAB04: MOV DPTR,#HORA_TX ;Apuntamos al orgen del mensaje "formato" de la Hora PUSH ACC MOVC A,@A+DPTR ;Leemos caracter del mensaje "formato" gu ardado en EPROM MOV DPH,#80H MOV DPL,R1 MOV R2,#3 GRAB08: MOVX @DPTR,A ;Copiamos el caracter en RAM EXT. (R2 vec es) DJNZ R2,GRAB08 POP ACC INC A ;Apuntamos al prximo caracter del mensaje "formato" en EPROM INC R1 ;Apuntamos al prximo caracter del mensaje en Ram Ext. DJNZ R0,GRAB04 ;******************************************************************************* ************************* ;Ahora debemos escribir el "formato" del mensaje de la Fecha: N33 DOM 00 ENE--0 (situado en FECHA_TX de ;la memoria de programas) en la direccin 8040H de la Ram Externa: GRAB10: MOV R1,#40H ensaje en Ram Ext. MOV R0,#17 MOV A,#0 aje (guardado en EPROM) GRAB14: MOV DPTR,#FECHA_TX de la Fecha PUSH ACC MOVC A,@A+DPTR EPROM MOV DPH,#80H ;Byte bajo (variable) de la direccin del m ;Cantidad de caracteres del mensaje ;Offset para leer los caracteres del mens ;Apuntamos al orgen del mensaje "formato" ;Leemos caracter del mensaje "formato" en R1,#20H ;Byte bajo (variable) de la direccin del m

MOV DPL,R1 MOV R2,#3 GRAB18: MOVX @DPTR,A ;Copiamos el caracter en Ram Ext. DJNZ R2,GRAB18 POP ACC INC A ;Apuntamos al prximo caracter del mensaje "formato" en EPROM INC R1 ;Apuntamos al prximo caracter del mensaje en Ram Ext. DJNZ R0,GRAB14 ;******************************************************************************* ************************* ;Ahora debemos escribir el "formato" del mensaje de la Alarma: '--ALARMA 00:00-' situado en ALARM_TX ;(de la memoria de programas) en la direccin 8060H de la Ram Externa (en el RTC): GRAB20: MOV R1,#60H aje en Ram Ext. MOV R0,#17 MOV A,#0 aje (guardado en EPROM) GRAB24: MOV DPTR,#ALARM_TX de la Alarma PUSH ACC MOVC A,@A+DPTR o" en EPROM MOV DPH,#80H MOV DPL,R1 MOV R2,#3 GRAB28: MOVX @DPTR,A en Ram Ext. DJNZ R2,GRAB28 POP ACC INC A "formato" en EPROM INC R1 real en Ram Ext. DJNZ R0,GRAB24 AJMP VERIFICA ;Byte bajo de la direccin de orgen del mens ;Cantidad de caracteres del mensaje ;Offset para leer los caracteres del mens ;Apuntamos al orgen del mensaje "formato" ;Leemos caracter desde el mensaje "format

;Copiamos el caracter en el mensaje real

;Apuntamos al prximo caracter del mensaje ;Apuntamos al prximo caracter del mensaje

;******************************************************************************* ************************* ;RTC: Esta porcin de cdigo se encarga de la puesta en Hora y Fecha del RTC (DS1288 7). ;Se entra a esta Subrrutina pulsando la Tecla F2 (Scan Code 06H). ;Para que el sistema tome "acepte" el nuevo valor debe pulsarse ENTER (5AH) ;Para salir de esta subrrutina debe pulsarse la Tecla ESC (76H) ;******************************************************************************* ************************* ;Antes de nada veamos como deben estar los Registros A,B,C y D: ;Registro A: X0101111 (UIP, DV2, DV1, DV0, RS3, RS2, RS1, RS0) ;Registro B: 01001110 (SET, PIE, AIE, UIE, SQWE, DM, 24/12, DSE) ;Registro C: XXXXXXXX (IRQF, PF, AF, UF, 0, 0, 0, 0) Este registro solo puede leerse. ;Registro D: XXXXXXXX (VRT, 0, 0, 0, 0, 0, 0, 0) Este registro solo puede leer se. RSEG RTC: RTC_PGR

MOV NRO_MSG,#1 ;Indica el Nro del mensaje (HORA=1, FECHA =2 y ALARMA=3) SETB TR1 ;Ponemos en marcha el TIMER1 ;Para la puesta en Hora y Fecha se utilizarn 2 formatos definidos, cada uno de el los contar de 12 ca;racteres y estarn localizados a partir de la Direccin 8010H. ;Para la Puesta en Hora se usar el formato: N33 HORA 21:47 0 ==> Address: 8020H ( hasta 802FH) ;Para la puesta en Fecha se usar el formato: N33 MIE 27 OCT 0 ==> Address: 8030H (Hasta 803FH) ;Antes de leer los registros de HOURS y MINUTES, debemos asegurarnos que no se p roduzca un Update duran;te el mismo; para ello esperamos (ciclamos) hasta que UF=1 (registro C), luego hacemos SET=1, y ya esta;mos listos para leer los registros del RTC: MOV DPTR,#800CH ;Apuntamos al registro C del RTC RTC_15: MOVX A,@DPTR JNB ACC.4,RTC_15 ;Ciclamos hasta que UF=ACC.4=1 MOV DPTR,#800BH ;Apuntamos al registro B del RTC MOVX A,@DPTR ORL A,#80H ;Ponemos el bit SET=1 (en el registro B) (stop update) MOVX @DPTR,A ;Copiamos el nuevo valor en B ;Lo que tenemos que hacer ahora es leer los registros de Horas (8004H) y Minutos (8002H) y luego copiar;los en sus ubicaciones respectivas (8019H-801AH) y (801CH-801DH) ;******************************************************************************* ************************* ;A continuacin copiamos en el "mensaje" los valores reales de Horas y Minutos del RTC: MOV DPTR,#8004H ;Apuntamos al registro HOURS del RTC MOVX A,@DPTR ;Leemos el registro HOURS (valor binario) ;Ahora debemos copiar el nible SX (decenas) en 8029H y el nibble DX (unidades) e n 802AH: MOV HORA,A ;Copiamos el valor del registro HOURS en HORA MOV B,#10 DIV AB ;A=cociente (decenas) - B=resto (unidades ) ADD A,#30H MOV DPTR,#8029H MOVX @DPTR,A ;Guardamos decenas de Horas MOV A,B ADD A,#30H INC DPTR MOVX @DPTR,A ;Guardamos unidades de Horas ;Ahora leemos registro MINUTES y copiamos el nibble SX (decs) en 802CH y el nibb le DX (unids) en 802DH: MOV DPTR,#8002H ;Apuntamos al registro MINUTES del RTC MOVX A,@DPTR MOV MINUTO,A ;Copiamos el valor del registro MINUTES e n MINUTO MOV B,#10 DIV AB ADD A,#30H MOV DPTR,#802CH MOVX @DPTR,A ;Guardamos decenas de Minutos MOV A,B ADD A,#30H INC DPTR

MOVX

@DPTR,A

;Guardamos unidades de Minutos

;******************************************************************************* ************************* ;A continuacin copiamos en el "mensaje" los valores reales de los 3 registros de Fecha del RTC, los que ;estn situados en las direcciones (8006H, 8007H y 8008H) ;******************************************************************************* ************************* ;*** 1er Registro (DAY OF THE WEEK) (address 8006H) *** ;Para el caso del DAY OF THE WEEK necesitamos el valor num rico "binario" del "da d e la semana", para ;con este valor entrar en la Tabla D_WEEK y hallar el "da" correspondiente (en le tras): MOV DPTR,#8006H ;Apuntamos al registro DAY OF THE WEEK (v alor en BCD) MOVX A,@DPTR ;Leemos el valor en el registro (valor BC D = valor Binario) MOV DD_SEM,A ;Copiamos el valor del registro DAY OF TH E WEEK en DD_SEM DEC A ;Porque mnimo valor de DAY OF THE WEEK es 1 MOV B,#3 ;Porque cada "da" tiene 3 letras MUL AB ;A=offset para entrar a la tabla D_WEEK MOV R1,#44H ;Valor para DPL cuando apunte al 1er cara cter del "da" MOV R0,#3 ;Ser en contador de los caracteres del "da" RTC_20: PUSH ACC ;BCD=BINARIO pues las decenas son siempre "0" MOV DPTR,#D_WEEK ;Apuntamos a la Tabla de los Das de la Sem ana MOVC A,@A+DPTR ;Apuntamos al "da" de la Tabla que corresp onde ;Ahora debemos copiar los 3 caracteres del "dia" en el lugar correspondiente del mensaje que mostrar ;la fecha del sistema: N33 DOM 00 ENE--0 (direccin base 8040H): MOV DPH,#80H MOV DPL,R1 MOVX @DPTR,A ;Copiamos caracter del "da" de la Tabla en el Mensaje de Fecha POP ACC INC A ;Apuntamos al siguiente caracter del "dia " de la Tabla en EPROM INC R1 ;Apuntamos al siguiente caracter del "da" del mensaje en Ram Ext. DJNZ R0,RTC_20 ;*** 2do Registro (DAY OF THE MONTH) (Address 8007H) *** MOV DPTR,#8007H ;Apuntamos al registro DAY OF THE MONTH d el RTC MOVX A,@DPTR ;Leemos el registro del "da del mes" ;Ahora debemos copiar el nible SX (decenas) en 8048H y el nibble DX (unidades) e n 8049H: MOV DD_MES,A ;Copiamos el valor del registro DAY OF TH E MONTH en DD_MES MOV B,#10 DIV AB ;A=cociente (decenas) - B=resto (unidades ) ADD A,#30H MOV DPTR,#8048H

MOVX MOV ADD INC MOVX

@DPTR,A A,B A,#30H DPTR @DPTR,A

;Guardamos decenas de "da del mes"

;Guardamos unidades de "da del mes"

;*** 3er Registro (MONTH) (8008H) *** ;Para el caso del mes necesitamos el valor num rico "binario" del mes del ao (guard ado en mes), para ;con este valor entrar en la Tabla MONTHS y hallar el "mes" correspondiente (en letras): MOV DPTR,#8008H ;Apuntamos al registro MONTH (valor BCD) MOVX A,@DPTR ;Leemos el valor en el registro (valor bi nario) MOV MES,A ;Copiamos el valor del registro MONTH en MES DEC A ;Porque mnimo valor de MONTH es 1 MOV B,#3 ;Porque cada "mes" tiene 3 letras MUL AB ;A=offset para entrar a la tabla MONTHS MOV R1,#4BH ;Valor para DPL cuando apunte al 1er cara cter del "mes" MOV R0,#3 ;Ser el contador de los caracteres del "me s" RTC_32: PUSH ACC ;Empilamos valor de Mes MOV DPTR,#MONTHS ;Apuntamos a la Tabla de los Meses del ao MOVC A,@A+DPTR ;Apuntamos al "mes" de la Tabla que corre sponde ;Ahora debemos copiar los 3 caracteres del "mes" en el lugar correspondiente del mensaje que mostrar ;la fecha del sistema: N33 DOM 00 ENE--0 (direccin base 8040H): MOV DPH,#80H MOV DPL,R1 MOVX @DPTR,A ;Copiamos un caracter del "mes" de la Tab la en el Mensaje de Fecha POP ACC INC A ;Apuntamos al siguiente caracter del "mes " de la Tabla en EPROM INC R1 ;Apuntamos al siguiente caracter del "mes " del mensaje en Ram Ext. DJNZ R0,RTC_32 ;******************************************************************************* ************************* ;Ahora falta leer los registros de alarmas del RTC: MINUTES ALARM (8003H) y HOUR S ALARM (8005H) y copiar;los en los lugares correspondientes del "mensaje" --ALARMA 00:00-- (address bas e 8060H) que muestra el ;momento de visualizar HORA y FECHA: MOV DPTR,#8005H ;Apuntamos al registro HOURS ALARM del RT C MOVX A,@DPTR ;Leemos el registro HOURS ALARM ;Ahora debemos copiar el nible SX (decenas) en 8069H y el nibble DX (unidades) e n 806AH: MOV HORALA,A ;Copiamos el valor del registro HOURS ALA RM en HORALA MOV B,#10 DIV AB ;A=cociente (decenas) - B=resto (unidades ) ADD A,#30H MOV DPTR,#8069H MOVX @DPTR,A ;Guardamos decenas de "hora alarma"

MOV A,B ADD A,#30H INC DPTR MOVX @DPTR,A ;Guardamos unidades de "hora alarma" ;Ahora leeremos el registro MINUTES ALARM (8003H) ;Copiaremos el High nibble (decenas) en 806CH y el Low nibble (unidades) en 806D H: MOV DPTR,#8003H ;Apuntamos al registro MINUTES ALARM del RTC MOVX A,@DPTR ;Leemos el registro MINUTES ALARM MOV MINALA,A ;Copiamos el valor del registro MINUTES A LARM en MINALA MOV B,#10 DIV AB ;A=cociente (decenas) - B=resto (unidades ) ADD A,#30H MOV DPTR,#806CH MOVX @DPTR,A ;Guardamos decenas de "minutos alarma" MOV A,B ADD A,#30H INC DPTR MOVX @DPTR,A ;Guardamos unidades de "minutos alarma" ;Ahora que los valores reales de HORA, FECHA y ALARMA fueron ya copiados, hacemo s SET=0 (start update): MOV DPTR,#800BH ;Apuntamos al registro B del RTC MOVX A,@DPTR ANL A,#7FH ;Ponemos el bit SET=0 (registro B) (sin a fectar los demsbits) MOVX @DPTR,A ;Copiamos el nuevo valor en el Registro B del RTC ;******************************************************************************* ************************* ;A continuacin el programa le da la posibilidad al usuario para que cambie los va lores que crea conve;niente; para ello estn disponibles las siguientes opciones: ;01: La tecla SX () desplaza el CURSOR a la izquierda (sin salir de los parmetros variables) ;02: La tecla DX () desplaza el CURSOR a la derecha (sin salir de los parmetros v ariables) ;03: La tecla UP (CURSOR ARRIBA) incrementa el valor de la variable apuntada por el CURSOR (sin pasar del ; mximo valor permitido para el parmetro apuntado) ;04: La tecla DOWN (CURSOR ABAJO) decrementa el valor de la variable apuntada po r el CURSOR (sin pasar ; del mnimo valor permitido para el parmetro apuntado) ;05: La tecla TAB (TAB) desplaza el CURSOR hasta el siguiente mensaje (como solo hay tres mensajes, des; pu s del tercero salta de nuevo al primero) ;06: La tecla ENTER hace que los cambios introducidos sean guardados en memoria. ;07: La tecla ESC permite salir de la Rutina RTC ;******************************************************************************* ************************* ;NOTA: Al entrar en la rutina RTC el CURSOR se sita automticamente en el lugar de la decenas de las ;horas. El comando ENTER acta sobre los 3 "mensajes" simultneamente y una vez guar dados los cambios ;hace salir de la rutina RTC (al igual que ESC, solo que esta no guarda los camb ios).

MOV CURSORL,#29H ;colocamos el CURSOR en la direccin de las decenas de HORA MOV CURSORH,#80H ;de la Hora del sistema o sea apuntando a 8019H LJMP FINAL1 BARRIDO: MOV A,KEYTEMP ;Leemos el Scan Code CJNE A,#5AH,LEFT ;Si no se apret ENTER (5AH) probamos con 6 BH (cursor a SX) ;******************************************************************************* ************************* ;GRABAR: Esta porcin de cdigo se ejecuta si KEYTEMP=5AH (ENTER) y hace que los cam bios introducidos ;por el usuario sean guardados y luego termina la ejecucin de la rutina RTC. ;******************************************************************************* ************************* GRABAR: ;Antes de grabar los nuevos valores de HORA, FECHA y ALARMA hacemos SET=1 (stop update): MOV DPTR,#800BH ;Apuntamos al registro B del RTC MOVX A,@DPTR ORL A,#80H ;Ponemos el bit SET=1 (registro B) (sin a fectar los demsbits) MOVX @DPTR,A ;Copiamos el nuevo valor en B ;ahora estamos en condiciones de "guardar" los cambios. ;Vamos a guardar el nuevo valor de HOURS (guardado en HORA ==> valor binario): MOV A,HORA MOV DPTR,#8004H ;Apuntamos al registro HOURS del RTC MOVX @DPTR,A ;Guardamos el nuevo valor en el RTC ;Vamos a guardar el nuevo valor de MINUTES (guardado en MINUTO ==> valor binario ): MOV A,MINUTO MOV DPTR,#8002H ;Apuntamos al registro MINUTES del RTC MOVX @DPTR,A ;Guardamos el nuevo valor en el RTC ;Vamos a guardar el nuevo valor de DAY OF DE WEEK (que est guardado en DD_SEM ==> valor binario): MOV A,DD_SEM ;Leemos nuevo valor (BINARIO=BCD) del Da d e la Semana MOV DPTR,#8006H ;Apuntamos al registro 8006H (DAY OF THE WEEK) del RTC MOVX @DPTR,A ;Guardamos el nuevo valor del Dia de la S emana ;Vamos a guardar el nuevo valor de DAY OF THE MONTH (guardado en DD_MES ==> valo r binario): MOV A,DD_MES MOV DPTR,#8007H ;Apuntamos al registro DAY OF THE MONTH d el RTC MOVX @DPTR,A ;Guardamos el nuevo valor en el RTC ;Vamos a guardar el nuevo valor de MONTH (guardado en MES==> valor binario): MOV A,MES ;Leemos nuevo valor del MES MOV DPTR,#8008H ;Apuntamos al registro 8008H (MONTH) del RTC MOVX @DPTR,A ;Guardamos el nuevo valor (en formato BCD ) del MES ;Vamos a guardar el nuevo valor de HOURS ALARM (guardado en HORALA ==> valor bin ario): MOV A,HORALA MOV DPTR,#8005H ;Apuntamos al registro HOURS ALARM del RT C MOVX @DPTR,A ;Guardamos el nuevo valor en el RTC

;Vamos a guardar el nuevo valor de MINUTES ALARM (guardado en MINALA ==> valor b inario): MOV A,MINALA MOV DPTR,#8003H ;Apuntamos al registro MINUTES ALARM del RTC MOVX @DPTR,A ;Guardamos el nuevo valor en el RTC ;Ya tenemos guardados los nuevos valores, lo que nos queda por hacer es poner SE T=0 y luego salir de la ;rutina RTC: MOV DPTR,#800BH ;Apuntamos al registro B del RTC MOVX A,@DPTR ANL A,#7FH ;Ponemos el bit SET=0 (registro B) (sin a fectar los demsbits) MOVX @DPTR,A ;Copiamos el nuevo valor en B LJMP SALIR1 ;Salimos de la rutina RTC ;******************************************************************************* ************************* ;LEFT: Esta porcin de cdigo se ejecuta si KEYTEMP=6BH (cursor izquierda) y hace qu e el CURSOR pase a ;apuntar a la siguiente variable de la izquierda. ;******************************************************************************* ************************* LEFT: CJNE A,#6BH,RIGHT ;Si no se apret 6BH (SX) probamos con 74H (cursor a DX) MOV DPL,CURSORL MOV DPH,CURSORH MOV A,NRO_MSG ;Vemos en que mensaje estamos (puede ser 1,2 o 3) CJNE A,#1,LEFT_10 ;Estamos en el Mensaje Nro 1: N33 HORA CH) MOV A,DPL CJNE A,#29H,LEFT_04 ) MOV KEYTEMP,#0 AJMP EMPTY1 > ignoramos LEFT_04: CJNE A,#20H,LEFT_06 MOV KEYTEMP,#0 LJMP EMPTY1 > ignoramos LEFT_06: CJNE A,#2CH,LEFT_08 os) MOV DPL,#29H AJMP LEFT_30 LEFT_08: DEC DPL AJMP LEFT_30 LEFT_10: CJNE A,#2,LEFT_20 a Mensaje Nro 3 ;Estamos en el Mensaje Nro 2: N33 MIE y 4BH) MOV A,DPL CJNE A,#44H,LEFT_12 MOV KEYTEMP,#0 AJMP EMPTY1 > ignoramos ;No estamos en el Mensaje Nro 2 ==> Vamos 27 OCT 0 (Posiciones: 40H,41H,42H,44H,48H ; ; ;Si el CURSOR est en MSG_NRO2 y DPL=44H == ;No estamos en el Mensaje Nro 1 21:47--0 (Posiciones: 20H,21H,22H,29H y 2 ;El CURSOR no est apuntando a 8029H (horas ; ;Si el CURSOR est en MSG_NRO1 y DPL=29H == ;El CURSOR no est apuntando al Cdigo Efecto ;Si el CURSOR est en MSG_NRO1 y DPL=20H == ;El CURSOR no est apuntando a 802CH (minut ;Si CURSORL=2CH ==> hacemos CURSORL=29H

LEFT_12:

CJNE MOV AJMP

A,#40H,LEFT_14 KEYTEMP,#0 EMPTY1 A,#4BH,LEFT_16 DPL,#48H LEFT_30 A,#48H,LEFT_18 DPL,#44 LEFT_30 DPL LEFT_30

;Si el CURSOR est en MSG_NRO2 y DPL=40H == ; ;Si CURSOR=804BH ==> hacemos CURSOR=8048H ; ; ;Si CURSOR=8048H ==> hacemos CURSOR=8044H

> ignoramos LEFT_14: CJNE MOV AJMP LEFT_16: CJNE MOV AJMP LEFT_18: DEC AJMP

;Estamos en el Mensaje Nro 3: --ALARMA LEFT_20: MOV A,DPL CJNE A,#69H,LEFT_24 MOV KEYTEMP,#0 AJMP EMPTY1 > ignoramos LEFT_24: MOV DPL,#69H LEFT_30: MOV CURSORL,DPL MOV CURSORH,DPH AJMP FINAL1

00:00--:(posiciones: 69H y 6CH) ; ; ;Si el CURSOR est en MSG_NRO3 y DPL=69H == ;Si CURSOR=806C ==> hacemos CURSOR=8069H ;Reposicionamos el CURSOR

;******************************************************************************* ************************* ;RIGHT: Esta porcin de cdigo se ejecuta si KEYTEMP=74H (cursor derecha) y hace que el CURSOR pase a ;apuntar a la siguiente variable de la derecha. RIGHT: CJNE A,#74H,ORIGIN ;Si no se apret 74H (DX) probamos con 75H (cursor arriba) MOV DPL,CURSORL MOV DPH,CURSORH MOV A,NRO_MSG ;Vemos en que mensaje estamos (puede ser 1,2 o 3) CJNE A,#1,RIGHT_10 ;Estamos en el Mensaje Nro 1: N33 HORA H) MOV A,DPL CJNE A,#2CH,RIGHT_04 MOV KEYTEMP,#0 AJMP EMPTY1 > ignoramos RIGHT_04: CJNE A,#22H,RIGHT_06 saje MOV DPL,#29H AJMP RIGHT_30 RIGHT_06: CJNE A,#29H,RIGHT_08 MOV DPL,#2CH AJMP RIGHT_30 RIGHT_08: INC DPL AJMP RIGHT_30 RIGHT_10: CJNE A,#2,RIGHT_20 ;No estamos en el mensaje Nro 2 ;No estamos en el mensaje Nro 1 21:47 0 (Posiciones: 20H,21H,22H,29H y 2C ; ;El CURSOR no apunta a los minutos (2CH) ; ;Si el CURSOR est en MSG_NRO1 y DPL=2CH == ;No estamos en el 3er cdigo efecto del men ;Si CURSORL=22 ==> hacemos CURSORL=29H ; ;Si CURSORL=29H ==> hacemos CURSORL=2CH

;Estamos en el Mensaje Nro 2: N33 MIE 4BH) MOV A,DPL CJNE A,#4BH,RIGHT_12 MOV KEYTEMP,#0 AJMP EMPTY1 > ignoramos RIGHT_12: CJNE A,#42H,RIGHT_14 saje MOV DPL,#44H AJMP RIGHT_30 RIGHT_14: CJNE A,#44H,RIGHT_16 MOV DPL,#48H 48H AJMP RIGHT_30 RIGHT_16: CJNE A,#48H,RIGHT_18 mes) MOV DPL,#4BH AJMP RIGHT_30 RIGHT_18: INC DPL AJMP RIGHT_30

27 OCT 0 (Posiciones:40H,41H,42H,44H,48H y ;Estamos en el mensaje Nro 2 ; ; ;Si el CURSOR est en MSG_NRO2 y DPL=4BH == ;No estamos en el 3er cdigo efecto del men ;Si CURSORL=42H ==> hacemos CURSORL=44H ;(3) ;(2) Si CURSORL=44H ==> hacemos CURSORL= ;El CURSOR no est apuntando a 8048H (da del ;Si CURSORL=48H ==> hacemos CURSORL=4BH

;Estamos en el Mensaje Nro 3: --ALARMA 00:00--:(posiciones: 69H y 6CH) RIGHT_20: MOV A,DPL CJNE A,#6CH,RIGHT_24 MOV KEYTEMP,#0 ; AJMP EMPTY1 ;Si el CURSOR est en MSG_NRO3 y DPL=6DH == > ignoramos RIGHT_24: ;El CURSOR est apuntando a 8069H (hora ala rma) MOV DPL,#6CH ;Si CURSORL=69H ==> hacemos CURSORL=6CH RIGHT_30: MOV CURSORL,DPL ;Reposicionamos el CURSOR MOV CURSORH,DPH AJMP FINAL1 ;******************************************************************************* ************************* ORIGIN: CJNE A,#6CH,ARRIBA ;Si no se apret 6CH (INICIO) probamos con 75H (cursor arriba) MOV DPL,CURSORL MOV DPH,CURSORH MOV A,NRO_MSG ;Vemos en que mensaje estamos (puede ser 1,2 o 3) CJNE A,#1,ORIG_10 ;No estamos en el mensaje Nro 1 MOV DPL,#20H ;Estamos en el mensaje Nro 1 SJMP ORIG_30 ORIG_10: CJNE A,#2,ORIG_20 ;No estamos en el mensaje Nro 2 MOV DPL,#40H ;Estamos en el mensaje Nro 2 SJMP ORIG_30 ORIG_20: MOV DPL,#60H ;Estamos en el mensaje Nro 3 ORIG_30: MOV CURSORL,DPL MOV CURSORh,DPH AJMP FINAL1 ;******************************************************************************* *************************

;ARRIBA: Esta porcin de cdigo se ejecuta si KEYTEMP=75H (cursor arriba) y hace inc rementar en una uni;dad a la variable apuntada por el CURSOR. ARRIBA: CJNE A,#75H,$+5 ;(3) Si no se apret 75H (UP) probamos con 72H (DOWN) SJMP $+5 ;(2) LJMP ABAJO ;(3) MOV DPL,CURSORL MOV DPH,CURSORH MOV A,NRO_MSG ;Vemos en que mensaje estamos (puede ser 1,2 o 3) ;CODEUP: EFECTO ;TIEMPUP: TIEMPO ;VECESUP: VECES ARRI_10: CJNE MOV CJNE en Ram) MOV CJNE MOV LJMP a ARRI_12: nte LJMP ARRI_14: en Ram) MOV CJNE MOV cla ARRI_16: iente LJMP ARRI_20: y 4BH FINAL1 ;Mensaje FECHA: Posiciones: DPL=44H, 48H LJMP INC MOV CALL EMPTY1 A MINUTO,A COPIA1 ;Guardamos nuevo valor binario de minutos ;Copiamos MINUTO en el mensaje correspond A,MINUTO A,#3BH,ARRI_16 KEYTEMP,#0 FINAL1 ;El CURSOR apunta a MINUTOS (en mensaje ;Leemos valor binario de los minutos ;Valor de minutos no es 59 ;Si MINUTO=59 ==> ignoramos accin de la te INC MOV CALL A,HORA A,#17H,ARRI_12 KEYTEMP,#0 EMPTY1 A HORA,A COPIA1 ;Leemos valor binario de las horas ;Valor de horas no es 23 ;Si HORA=23 ==> ignoramos accin de la tecl ;Guardamos nuevo valor binario de horas ;Copiamos HORA en el mensaje correspondie A,#1,ARRI_20 A,DPL A,#29H,ARRI_14 ;Cdigo para cambiar (hacia arriba) el Cdigo ;Cdigo para cambiar (hacia arriba) el Cdigo ;Cdigo para cambiar (hacia arriba) el Cdigo ;Mensaje HORA: Posiciones: DPL=29H y 2CH ;El CURSOR no apunta a HORAS (en mensaje

CJNE A,#2,ARRI_30 ;No estamos en el mensaje Nro 2 MOV A,DPL CJNE A,#44H,ARRI_24 ;El CURSOR no apunta al "Da de la Semana" ;Tener en cuenta que necesitamos el valor num rico (binario) del Da de la Semana, p ara poder entrar en ;la Tabla D_WEEK y hallar el "da" que corresponde. MOV A,DD_SEM ;Leemos el Da de la Semana (valor BINARIO= BCD) CJNE A,#7,ARRI_22 ;No estamos en el da Nro 7 MOV KEYTEMP,#0 ;

LJMP la ARRI_22: a Semana MOV MOV MOV MOV CALL LJMP ARRI_24: CJNE MOV CJNE MOV LJMP INC MOV CALL iente INC MOV

EMPTY1 A DD_SEM,A R1,DPL DPTR,#D_WEEK R2,DPL R3,DPH COPIA2 FINAL1 A,#48H,ARRI_26 A,DD_MES A,#1FH,ARRI_25 KEYTEMP,#0 EMPTY1 A DD_MES,A COPIA1

;Si DD_SEM=7 ==> ignoramos accin de la tec ;Guardamos nuevo valor binario del Da de l ;Apunta al "nombre del da" en el mensaje ;Apuntamos a la tabla D_WEEK

;El CURSOR no apunta al da del mes ;Leemos el Da del Mes (valor binario) ;Da del mes no es igual a 31 ;Si DD_MES=31 ==> ignoramos accin de la te

cla ARRI_25: Mes ;Copiamos DD_MES en el mensaje correspond LJMP FINAL1 ;Tener en cuenta que necesitamos el valor num rico (binario) del Mes, para poder e ntrar en la Tabla ;MONTHS y hallar el "mes en letras" que corresponde. ARRI_26: MOV A,MES ;Leemos el valor de MES (valor binario) CJNE A,#0CH,ARRI_28 ;El valor del mes no es igual a 12 (0CH) MOV KEYTEMP,#0 LJMP EMPTY1 ;Si Mes=12 ==> ignoramos accin de la tecla ARRI_28: l Ao MOV MOV MOV MOV CALL LJMP ARRI_30: H MOV R1,DPL DPTR,#MONTHS R3,DPH R2,DPL COPIA2 FINAL1 A,DPL A,#69H,ARRI_36 A,HORALA A,#0FFH,ARRI_32 KEYTEMP,#0 EMPTY1 A,#17H,ARRI_34 HORALA,#0FFH COPIA1 FINAL1 A HORALA,A COPIA1 ;Apunta al "nombre del mes" en el mensaje ;Apuntamos a la tabla MONTHS INC MOV A MES,A ;Guardamos nuevo valor binario del Mes de ;Guardamos nuevo valor binario del Da del

;Mensaje ALARMA: Posiciones: DPL=69H y 6C ;El CURSOR no apunta a la hora de alarma ;Leemos la hora de alarma ;La Hora de Alarma no es igual a 0FFH (do ;Si HORALA=23 ==> ignoramos accin de la te ;Colocamos un "don't care code" en el lug ;Copiamos HORALA en el mensaje correspond

CJNE MOV CJNE n't care code) MOV LJMP cla ARRI_32: CJNE MOV ar de HORA ALARMA CALL iente LJMP ARRI_34: INC MOV CALL

;Guardamos nuevo valor ;Copiamos HORALA en el mensaje correspond

iente LJMP ARRI_36: MOV CJNE MOV LJMP cla ARRI_38: iente LJMP FINAL1 ;******************************************************************************* ************************* ;ABAJO: Esta porcin de cdigo se ejecuta si KEYTEMP=72H (cursor abajo) y hace decre mentar en una unidad ;a la variable apuntada por el CURSOR. ABAJO: CJNE A,#72H,$+5 ;(3) Si no se apret 72H (DOWN) probamos co n 0DH (TAB) SJMP $+5 ;(2) LJMP PROXIMO ;(3) MOV DPL,CURSORL MOV DPH,CURSORH MOV A,NRO_MSG ;Vemos en que mensaje estamos (puede ser 1,2 o 3) ABAJ_10: ;Mensaje HORA: Posiciones: DPL=29H y 2CH CJNE A,#1,ABAJ_20 MOV A,DPL CJNE A,#29H,ABAJ_14 ;El CURSOR no apunta a HORAS (en mensaje en Ram) MOV A,HORA ;Leemos valor binario de las horas CJNE A,#00H,ABAJ_12 ;Valor de horas no es 00 MOV KEYTEMP,#0 LJMP EMPTY1 ;Si HORA=00 ==> ignoramos accin de la tecl a ABAJ_12: DEC A MOV HORA,A ;Guardamos nuevo valor binario de horas CALL COPIA1 ;Copiamos HORA en el mensaje correspondie nte LJMP FINAL1 ABAJ_14: ;El CURSOR apunta a MINUTOS (en mensaje en Ram) MOV A,MINUTO ;Leemos valor binario de los minutos CJNE A,#00H,ABAJ_16 ;Valor de minutos no es 00 MOV KEYTEMP,#0 LJMP EMPTY1 ;Si MINUTO=00 ==> ignoramos accin de la te cla ABAJ_16: DEC A MOV MINUTO,A ;Guardamos nuevo valor binario de minutos CALL COPIA1 ;Copiamos MINUTO en el mensaje correspond iente LJMP FINAL1 ABAJ_20: y 4BH CJNE MOV CJNE A,#2,ABAJ_30 A,DPL A,#44H,ABAJ_24 ;Mensaje FECHA: Posiciones: DPL=44H, 48H ;No estamos en el mensaje Nro 2 ;El CURSOR no apunta al "Da de la Semana" INC MOV CALL A,MINALA A,#3BH,ARRI_38 KEYTEMP,#0 EMPTY1 A MINALA,A COPIA1 FINAL1 ;El CURSOR no apunta a Minutos Alarma ;Leemos los minutos de alarma ;Minutos alarma no es igual a 59 ;Si MINALA=59 ==> ignoramos accin de la te ;Guardamos nuevo valor ;Copiamos MINALA en el mensaje correspond

;Tener en cuenta que necesitamos el valor num rico (binario) del Da de la Semana, p ara poder entrar en ;la Tabla D_WEEK y hallar el "da" que corresponde. MOV A,DD_SEM ;Leemos el Da de la Semana (valor BINARIO= BCD) CJNE A,#1,ABAJ_22 ;No estamos en el da Nro 1 MOV KEYTEMP,#0 ; LJMP EMPTY1 ;Si DD_SEM=1 ==> ignoramos accin de la tec la ABAJ_22: DEC A MOV DD_SEM,A ;Guardamos nuevo valor binario del Da de l a Semana MOV R1,DPL ;Apunta al "nombre del da" en el mensaje MOV DPTR,#D_WEEK ;Apuntamos a la tabla D_WEEK MOV R3,DPH MOV R2,DPL CALL COPIA2 LJMP FINAL1 ABAJ_24: CJNE MOV CJNE MOV LJMP DEC MOV CALL iente LJMP FINAL1 ;Tener en cuenta que necesitamos el valor num rico (binario) del Mes, para poder e ntrar en la Tabla ;MONTHS y hallar el "mes en letras" que corresponde. ABAJ_26: MOV A,MES ;Leemos el valor de MES (valor binario) CJNE A,#01H,ABAJ_28 ;El valor del mes no es igual a 01 (0CH) MOV KEYTEMP,#0 LJMP EMPTY1 ;Si MES=01 ==> ignoramos accin de la tecla ABAJ_28: l Ao MOV MOV MOV MOV CALL LJMP ABAJ_30: H MOV CJNE MOV CJNE MOV LJMP cla ABAJ_32: CJNE MOV CALL R1,DPL DPTR,#MONTHS R3,DPH R2,DPL COPIA2 FINAL1 A,DPL A,#69H,ABAJ_36 A,HORALA A,#00H,ABAJ_32 KEYTEMP,#0 EMPTY1 A,#0FFH,ABAJ_34 HORALA,#17H COPIA1 ;Apunta al "nombre del da" en el mensaje ;Apuntamos a la tabla MONTHS DEC MOV A MES,A ;Guardamos nuevo valor binario del Mes de A,#48H,ABAJ_26 A,DD_MES A,#01H,ABAJ_25 KEYTEMP,#0 EMPTY1 A DD_MES,A COPIA1 ;El CURSOR no apunta al da del mes ;Leemos el Da del Mes (valor binario) ;Da del mes no es igual a 01 ;Si DD_MES=01 ==> ignoramos accin de la te ;Guardamos nuevo valor binario del Da del ;Copiamos DD_MES en el mensaje correspond

cla ABAJ_25: Mes

;Mensaje ALARMA: Posiciones: DPL=69H y 6C ;El CURSOR no apunta a la hora de alarma ;Leemos la hora de alarma ;La Hora de Alarma no es igual a 00 ;Si HORALA=00 ==> ignoramos accin de la te ;Hacemos HORALA=24 ;Copiamos HORALA en el mensaje correspond

iente ABAJ_34: iente LJMP ABAJ_36: MOV CJNE MOV LJMP cla ABAJ_38: iente LJMP FINAL1 ;******************************************************************************* ************************* ;PROXIMO: Esta porcin de cdigo se ejecuta si KEYTEMP=0DH (TAB) y hace que el CURSO R apunte a la 1ra ;variable (SX) del mensaje siguiente (si estamos en el ltimo pasa a apuntar al 1r o) PROXIMO: CJNE A,#0DH,AFUERA ;Si no se apret 0DH (TAB) probamos con 76H (ESC) MOV A,NRO_MSG CJNE A,#3,PROX_10 MOV NRO_MSG,#1 MOV CURSORL,#29H ;Apuntamos a las decenas de hora del mens aje HORA MOV CURSORH,#80H AJMP FINAL1 PROX_10: INC A MOV NRO_MSG,A CJNE A,#2,PROX_20 MOV CURSORL,#44H ;Apuntamos al da de la semana del mensaje FECHA MOV CURSORH,#80H AJMP FINAL1 PROX_20: MOV CURSORL,#69H ;Apuntamos a las decenas de hora del mens aje ALARMA MOV CURSORH,#80H AJMP FINAL1 ;******************************************************************************* ************************* ;AFUERA: Esta porcin de cdigo se ejecuta si KEYTEMP=76H (ESC) y hace salir de la R utina RTC y volver ;al lugar siguiente desde donde se la llam. AFUERA: CJNE A,#76H,EMPTY1 ;Si no se apret 76H (ESC) esperamos por ot ra tecla pulsada AJMP SALIR1 FINAL1: ;Actualiza la visualizacin MOV A,NRO_MSG ;Vemos en que mensaje estamos (puede ser 1,2 o 3) MOV ORG_H,#80H ;Byte alto del orgen de la parte visible ( no vara) DEC MOV CALL A,MINALA A,#00H,ABAJ_38 KEYTEMP,#0 EMPTY1 A MINALA,A COPIA1 FINAL1 ;El CURSOR no apunta a Minutos Alarma ;Leemos los minutos de alarma ;Minutos alarma no es igual a 00 ;Si MINALA=00 ==> ignoramos accin de la te ;Guardamos nuevo valor ;Copiamos MINALA en el mensaje correspond LJMP DEC MOV CALL FINAL1 A HORALA,A COPIA1 ;Guardamos nuevo valor ;Copiamos HORALA en el mensaje correspond

CJNE A,#1,NOR2_20 ;No estamos en el mensaje Nro 1 ;Estamos en el mensaje Nro 1 ==> HORA: N33 HORA 21:47--0 (orgen 8020H) MOV ORG_L,#20H SJMP NOR2_40 NOR2_20: ; CJNE A,#2,NOR2_30 ;No estamos en el mensaje Nro 2 ;Estamos en el mensaje Nro 2 ==> FECHA: N33 DOM 00 ENE--0 (orgen 8040H) MOV ORG_L,#40H SJMP NOR2_40 NOR2_30: ;Estamos en el mensaje Nro 3 ==> ALARMA: --ALARMA 00:00--0 (orgen 8060H) MOV ORG_L,#60H NOR2_40: MOV DPL,ORG_L MOV DPH,ORG_H CLR STATIC CALL ASTRA ;Generamos la Trama de bits MOV SALTO,#0 MOV R7,#VIDEO_H ;Apuntamos al comienzo de la Zona Video R am Externa, esta... MOV R6,#VIDEO_L ;... zona contiene la Trama de bits del M ensaje. CALL PONVI ;Pasamos los datos desde Video Ram Extern a a ZVI. MOV MOV MOV EMPTY1: LJMP BARRIDO ; A continuacin est el cdigo para salir de PROGRAM, antes de salir debemos asegurar nos que est pues; to el Cdigo de fin de ltimo Mensaje (00), si no est puesto debemos ponerlo. SALIR1: CLR TR1 ;Stop TIMER1 (solo est en marcha durante m odo programacin) CLR RTC_IN ;Borramos Flag que indica estamos dentro de RTC CALL BEEP ;Aviso acstico MOV DPTR,#TEXT7 ;'OUT OF RTC MODE ' ==> Mensaje de salida de modo RTC CALL PON_CAD MOV R0,#50H DIEZ_MSG R0 RET ;******************************************************************************* ************************* ;Nombre: COPIA2 ;Esta rutina se encarga de traducir de nmeros a nombres los "das de la semana" y l os "meses del ao" y ;luego copiar los nombres en el mensaje correspondiente. ;******************************************************************************* ************************* ;R1: Contiene el valor del DPL que apunta a la posicin del "nombre del da" en el m ensaje ;R2: Contiene la direccin base de la Tabla situada en EPROM (D_WEEK o MONTHS) COPIA2: MOV R0,#3 ;Cantidad de caracteres a copiar COPI2_10: PUSH ACC ;Valor del Offset para apuntar al element KEYTEMP,#0 KEYBUFF,#0 NBYTES,#0 ;Borramos KEYTEMP pues ya fue ledo ;Borramos KEYBUFF pues ya fue ledo

o de la Tabla MOV B,#3 ;Valor del salto de un Da al siguiente DEC A ; MUL AB ;Valor del Offset: (ACC-1)*3 MOV DPL,R2 ;Apuntamos a la Tabla correspondiente (D_ WEEK o MONTHS) MOV DPH,R3 MOVC A,@A+DPTR ;Leemos un caracter del "nombre del da" de la Tabla ;Ahora debemos copiar los 3 caracteres del "nombre del dia" en el lugar correspo ndiente del mensaje que ;mostrar la fecha del sistema: N33 DOM 00 ENE 0 (direccin base 8040H): MOV DPH,CURSORH ;Byte alto de la posicin del "nombre del da " MOV DPL,R1 ;Apuntamos a la posicin del "nombre del da" en el mensaje MOVX @DPTR,A ;Copiamos el caracter del "nombre del da" en el Mensaje POP ACC ;Desempilamos Offset tabla INC A ;Apuntamos al siguiente caracter del "dia " de la Tabla en EPROM INC R1 ;Apuntamos al siguiente caracter del "da" del mensaje en Ram Ext. DJNZ R0,COPI2_10 RET ;******************************************************************************* ************************* ;Nombre: COPIA1 ;Esta rutina se encarga de copiar los nuevos valores en la posicin correspondient e del mensaje que se ;est editando (HORA, FECHA o ALARMA). ;******************************************************************************* ************************* COPIA1: CJNE A,#0FFH,COPI_10 MOV A,#58H ;Si A=0FFH (don't care code) ==> escribim os X = ascii 58H MOVX @DPTR,A INC DPTR MOVX @DPTR,A SJMP COPI_20 COPI_10: MOV B,#10 DIV AB ;A=cociente (decenas) - B=resto (unidades ) ADD A,#30H ;Para pasar de binario a Ascii MOVX @DPTR,A ;Copiamos el valor de las decenas de hora s MOV A,B ADD A,#30H ;Para pasar de binario a Ascii INC DPL ;Apuntamos a la posicin de las unidades en el mensaje MOVX @DPTR,A ;Copiamos el valor de las unidades de hor as COPI_20: RET ;******************************************************************************* *************************

; Nombre: PROGRAM ; R7R6: Guarda direccin de MENSAJES en RAM externa (0800H) ;******************************************************************************* ************************* ; PROGRAMA QUE SE ENCARGA DE LEER LOS CODIGOS DE SCAN Y/O ASCII PROVENIENTES DEL PROGRAMA QUE ; ATIENDE LA INTERRUPCION EXTERNA 0 (CONTROL DE UN TECLADO TIPO PC) ;******************************************************************************* ************************* ;NBYTES ;KEYTEMP ;KEYBUFF ;CURSORH ;CURSORL PROGRAM: CLR TC) MOV 17H,#7 ;17H=R7 del Banco 2 (Nro de cuentas a com pletar por el TIMER1) CLR TAB ;Inicializamos TAB a 0 (CURSOR al comienz o del mensaje) SETB TR1 ;Ponemos en marcha al TIMER1 MOV CEROS,#00 ;Contador de "ceros" consecutivos (para h allar el Fin de Mensajes) CLR FOW ;Entramos a PROGRAM con bit FOW=0 (forwar d) CLR REV ;Entramos a PROGRAM con bit REV=0 (revers e) CLR SXINI ;Entramos a PROGRAM con bit SXINI=0 (salt o al inicio) CLR DXFIN ;Entramos a PROGRAM con bit DXFIN=0 (salt o al final) CLR CMD_RD ;Entramos a PROGRAM con Flag CMD_RD=0 CLR SEND_RD ;Entramos a PROGRAM con Flag SEND_RD=0 CLR CMD_CL ;Entramos a PROGRAM con Flag CMD_CL=0 CLR SEND_CL ;Entramos a PROGRAM con Flag SEND_CL=0 ;ATENCION : En este punto quizs sera bueno tener una porcin de Cdigo que detecte la presencia o no ;de un Teclado conectado a la Plaqueta. ;La porcin de Cdigo siguiente sirve para fijar el Modo CAPS LOCK (traba de mayscula s), la Velocidad ;de Repeticin de Teclas (RATE) y la Demora en el Inicio de la Repeticin (DELAY) al Microcontrolador. ;Para fijar la Velocidad de Repeticin del Teclado se deben enviar 2 bytes por la lnea KEYDAT (P3.4), ;luego de cada uno de estos bytes se recibir un byte de "reconocimiento" (ACK), e stos 4 bytes son: ; A) OUT: Cdigo Comando: F3H: 11110011 (indica que se enviar 1 byte con los valore s para RATE y DELAY) ; B) IN: Byte Reconocimiento: FAH: 11111010 ; C) OUT: Codigo Dato: 01010010 (01010==>RATE=12rps y 01==>DELAY= seg y "0" final Not Used) ; D) IN: Byte Reconocimiento: FAH: 11111010 ;Para fijar el Modo CAPS LOCK se deben enviar 2 bytes y por la lnea KEYDAT (P3.4) EX1 ;Desactivamos INT EXT 1 (interrupcin del R :Nmero de bytes en el buffer :used to build the key bit by :store the chars here (buffer :Byte alto de la posicin del :Byte bajo de la posicin del RSEG PGRMODE (maximo=INMAX) bit del teclado) CURSOR CURSOR

, luego de cada uno de ;estos bytes se recibir un byte de "reconocimiento" (ACK) estos 4 bytes son : ; A) OUT: Cdigo Comando: EDH: 11101101 (indica que se enviar un comando para el Le d CAPS LOCK) ; B) IN: Byte Reconocimiento: FAH: 11111010 ; C) OUT: Cdigo Dato: 06H: 00000110 (bit 1=1=NUM LOCK LED ON, bit2=1=CAPS LOCK LE D ON) ; D) IN: Byte Reconocimiento: FAH: 11111010 ;Antes de iniciar una transmisin hacia el Teclado el Micro debe "tirar" hacia aba jo la lnea CLOCK du;rante aproximadamente 400useg, despus de 350useg baja la lnea DATA para tenerla l ista para el bit de ;start, entonces sube (libera) la lnea clock y espera la seal de CLOCK desde el Te clado, a partir de ;all enva el START y luego los bits de datos (8), luego est el bit Parity (El bit d e STOP no existe). ; La frecuencia de funcionamiento del Micro es 11.0592Mhz=11059.2 pulsos/mseg=92 1.6 ciclos mq./mseg ==> ; que Frec=0.9216 ciclo mq./useg, por lo tanto para un pulso de 400useg necesitam os: ; 0.9216 ciclos mquina/useg x 400useg = 368.6 ciclos mquina. MOV TIR_LOW: CLR TR0 CLR TR1 CLR EX0 CLR P3.2 ;"Tira Abajo" la lnea CLOCK NOP CLR IE0 MOV NBITS,#00H MOV R0,#95 ;(2) TIRON_1: DJNZ R0,TIRON_1 ;(95x2=190 ciclos mquina) tiempo para "baj ar" lnea DATA CLR P3.4 ;(2) "Tira abajo" lnea DATA MOV R0,#85 ;(2) TIRON_2: DJNZ R0,TIRON_2 ;(85x2=170 ciclos mquina) MOV A,#00H ;(3) SETB SEND ;Seteamos Bit (que indica transmisin Micro --->Teclado) SETB TR0 SETB TR1 SETB EX0 JMP @A+DPTR ;(1) Saltamos a la etiqueta apuntada por ACC ;En este punto el control quedar a cargo de un cdigo includo en la Rutina INT EXT0, que se encargar ;de enviar hacia el Teclado los bits de Comando/Datos sincronizados con el CLOCK que genera el teclado. TIRON_3: SETB CMD_RD ;(2) SETB BIT_DAT MOV BYTEDATA,RD_CODE SETB P3.2 ;"libero" lnea CLOCK (El Teclado se har car go de lnea CLOCK) JB CMD_RD,$ ;Ciclamos hasta que bit CMD_RD se ponga a "0" (despus del ACK) MOV DPTR,#TIRON_4 AJMP TIR_LOW DPTR,#TIRON_3 ;En la 1ra pasada vamos a TIRON_3

TIRON_4:

SETB SEND_RD CLR BIT_DAT MOV BYTEDATA,RD_DATA SETB P3.2 go de lnea CLOCK) JB SEND_RD,$ a "0" (despus del ACK) MOV DPTR,#TIRON_5 AJMP TIR_LOW TIRON_5: SETB CMD_CL SETB BIT_DAT MOV BYTEDATA,CL_CODE SETB P3.2 go de lnea CLOCK) JB CMD_CL,$ "0" (despus del ACK) MOV DPTR,#TIRON_6 AJMP TIR_LOW TIRON_6: SETB SEND_CL CLR BIT_DAT MOV BYTEDATA,CL_DATA SETB P3.2 go de lnea CLOCK) JB SEND_CL,$ a "0" (despus del ACK) SETB CAPLOCK ;Ya se mandaron los 4 bytes al Teclado on PROGRAM... MOV CURSORL,#MINI_L ienzo de los Mensajes MOV CURSORH,#MINI_H ;Antes de seguir, fijamos el orgen de zada por NORMAL1: MOV ORG_L,CURSORL on Cdigo "Z" MOV ORG_H,CURSORH

;"libero" lnea CLOCK (El Teclado se har car ;Ciclamos hasta que bit SEND_RD se ponga

;"libero" lnea CLOCK (El Teclado se har car ;Ciclamos hasta que bit CMD_CL se ponga a

;"libero" lnea CLOCK (El Teclado se har car ;Ciclamos hasta que bit SEND_CL se ponga

y se recibieron los ACK, ahora seguimos c ;colocamos el CURSOR en la direccin de com ;en RAM Externa la cual es 0800H. la "parte visible", la que luego ser actuali ;Fijamos Orgen porcin visible del mensaje c

; A continuacin tenemos el cdigo que se ocupa de escribir el mensaje cuando se ent ra a PROGRAM con ; PROGMODE=1, en este caso el DPTR est apuntando al comienzo de Zona de Mensajes (0800H) JNB NO_MSG,$+5 ;(3) Solo entramos a FIRST si NO_MSG=1 (N o hay Mensajes en Ram) SJMP FIRST ;(2) LJMP FINAL FIRST: ;Como es la 1ra vez que entramos en PROGRAM, antes de escribir el 1er mensaje, v erificaremos que los ;"formatos" de los mensajes de HORA, FECHA y ALARMA estn correctamente escritos e n la Ram Ext RTC. ;Primer Mensaje: HORA: 'N33 HORA 00:00 ',0 ==> Formato del mensaje de la Hora MOV R0,#17 ;Nmero de caracteres a verificar MOV R1,#20H ;Byte bajo direccin mensaje HORA en RAM EX T. RTC MOV DPTR,#HORA_TX ;Apuntamos al mensaje HORA_TX en EPROM CALL VERIFICA ;Verificamos que la parte indicada de los mensajes sean id nticas ;Segundo Mensaje: FECHA: 'N33 DOM 00 ENE ',0 ==> Formato del mensaje de la Fech a

MOV MOV XT. RTC

R0,#17 R1,#40H

;Nmero de caracteres a verificar ;Byte bajo direccin mensaje FECHA en RAM E

MOV DPTR,#FECHA_TX ;Apuntamos al mensaje FECHA_TX en EPROM CALL VERIFICA ;Verificamos que la parte indicada de los mensajes sean id nticas ;Tercer Mensaje: ALARMA: ' ALARMA 00:00 ',0 ==> Formato del mensaje de alarma MOV R0,#17 ;Nmero de caracteres a verificar MOV R1,#60H ;Byte bajo direccin mensaje ALARMA en RAM EXT. RTC MOV DPTR,#ALARM_TX ;Apuntamos al mensaje ALARM_TX en EPROM CALL VERIFICA ;Verificamos que la parte indicada de los mensajes sean id nticas ;Ahora vamos a escribir el 1er mensaje (solo con blancos) MOV DPL,#MINI_L ;Apuntamos al Orgen de la Zona de Mensajes (0800H) MOV DPH,#MINI_H MOV R7,#0FH ;3+12=15=0FH ==> Nro de blancos (sern el 1 er mensaje) MOV R6,#2 ;Nro de veces que se repite la grabacin en Ram Ext. FIRST_10: MOV A,#20H ;Antes de nada lo que hacemos es llenar l os 1ros 15 MOVX @DPTR,A ;caracteres con 20H (blancos) DJNZ R6,FIRST_10 MOV R6,#2 ;Nro de veces que se repite la grabacin en Ram Ext. INC DPTR DJNZ R7,FIRST_10 ;Ahora vamos a poner el Fin de Mensaje (suponemos Cdigo Efecto no Z) MOV A,#00H ;(2) Si R7=16 entonces... MOVX @DPTR,A ;(1) Colocamos el Fin de Mensaje "0" (par a mensaje cdigo no Z) INC DPTR MOVX @DPTR,A ;Escribimos otro "0" porque es Fin de Men sajes (ya que hasta que ;no pasemos a un Mensaje Nuevo, ste es el ltimo). Vemos que el CURSOR no se movi de 0800H. CLR NO_MSG ;Borramos el flag de No mensaje en Ram (p ues ya escribimos uno) CALL BEEP ;Generamos un BEEP de advertencia MOV DPTR,#TEXT3 ;Apuntamos al mensaje TEXT3 guardado en E PROM CALL PON_CAD ;'PROGRAM MODE OK ':Exitosa entrada en PR OGRAM MODE MOV R0,#60H DIEZ_MSG R0 LJMP FINAL REPITE: MOV A,KEYTEMP ;KEYTEMP guarda el Cdigo de Scan de la tec la presionada CJNE A,#76H,BACK_SPA ;Con ESC (76H) salimos de Program Mode MOV KEYTEMP,#0 LJMP SALIR ;******************************************************************************* ************************* ; La caracterstica de BACK_SPA es que borra desde la posicin del CURSOR (sin inclu irla) hacia la iz-

; quierda y solo puede llegar hasta el "0" (caracter fin de mensaje) del mensaje anterior, alli se de; tiene y ulteriores pulsaciones de la tecla BACK SPACE no tienen ningn efecto; s i quiere pasarse al ; mensaje anterior debe usarse CURSORSX o REPAG. ; Debe tenerse en cuenta que los caracteres a la derecha del CURSOR se desplazan hacia la izquierda ; junto con el mismo (un salto a la SX cada vez que se pulsa la tecla). ;******************************************************************************* ************************* BACK_SPA: CJNE A,#66H,$+5 ;(3) Comprueba si se apret BACK SPACE (Sca n Code 66H) SJMP BKSPA05 ;(2) LJMP CL_ONOFF ;Antes de nada si el CURSOR est en el Orgen (0800H) de Zona de Mensajes no hacemos nada: BKSPA05: MOV A,CURSORL ;Tomamos CURSORL, si ... CJNE A,#MINI_L,BKSPA10 ;CURSORL > MINI_L (orgen Mensajes) continu amos en BK_SPA3 MOV A,CURSORH ; CJNE A,#MINI_H,BKSPA10 ;CURSORH > MINI_H (orgen Mensajes) continu amos en BK_SPA3 CALL BEEP ;Generamos un BEEP de advertencia MOV KEYTEMP,#0 LJMP EMPTY ;(3) Si CURSORL=MINI_L y CURSORH=MINI_H ==> "ignoramos" BKSPA10: MOV DPL,CURSORL MOV DPH,CURSORH ;Ahora, si el DPTR est apuntando al Cdigo Efecto del mensaje ignoramos la Tecla, p ara saberlo veremos ;si el caracter anterior es un "0": CLR Z_SI ;Se setear solo cuando se detecte un Cdigo "Z" DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 ;(3) DEC DPH ;(2) MOVX A,@DPTR INC DPTR ;Apuntamos nuevamente al lugar anterior JNZ BKSPA20 ;El caracter no es "0" ==> DPTR no apunta ba a un Cdigo Efecto CALL BEEP ;Generamos un BEEP de advertencia MOV KEYTEMP,#0 LJMP EMPTY BKSPA20: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 ;(3) DEC DPH ;(2) MOV A,DPL JNZ BKSPA25 ;No estamos en el orgen de la Zona de Mens ajes MOV A,DPH CJNE A,#08H,BKSPA25 ;No estamos en el orgen de la Zona de Mens ajes SJMP BKSPA30 ;Leemos el Cdigo Efecto (estamos en 0800H) BKSPA25: MOVX A,@DPTR JNZ BKSPA20 ;No estamos todava en el "0" ==> seguimos

ciclando INC Efecto BKSPA30: DPTR ;Incrementamos DPTR para apuntar al Cdigo ;Leemos Cdigo Efecto ;Apuntamos nuevamente a la posicin del CUR ;Apuntamos nuevamente a la posicin del CUR ;El mensaje no es Cdigo "Z" ;El mensaje es Cdigo "Z" ;Copiamos el caracter (ASCII) apuntado po ;Empilamos el caracter ledo ;(2) El caracter NO es "0" ==> seguimos d ;Vamos a la salida (AJMP FINAL) MOVX A,@DPTR MOV DPL,CURSORL SOR (low byte) MOV DPH,CURSORH SOR (high byte) CJNE A,#5AH,BKSPA40 SETB Z_SI BKSPA40: MOVX A,@DPTR r el DPTR PUSH ACC JNZ BKSPA50 esplazamiento a la SX JNB Z_SI,BKSPA70 INC CEROS MOV A,CEROS CJNE A,#2,BKSPA60 el desplazamiento DEC DPL 0" MOV A,DPL CJNE A,#0FFH,$+5 (solo si DPL=FFH) DEC DPH MOV A,#00 MOVX @DPTR,A gar a la SX MOV CEROS,#00 SJMP BKSPA70 BKSPA50: MOV CEROS,#00 ceros consecutivos BKSPA60: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 DEC DPH POP ACC MOVX @DPTR,A zquierda de donde estaba INC DPTR MOV A,#20H MOVX @DPTR,A INC DPTR SJMP BKSPA40 BKSPA70: POP ACC pila) MOV DPL,CURSORL MOV DPH,CURSORH DEC DPL r a la Izquierda) MOV A,DPL CJNE A,#0FFH,$+5 DEC DPH MOV CURSORL,DPL MOV CURSORH,DPH

;Para Cdigo "Z" el 1er cero no es el fin d ;Apuntamos al lugar donde estaba el 1er " ;(3) Vemos si hace falta decrementar DPH ;(2) ;Desplazamos el 2do "0" consecutivo un lu ;Vamos a la salida (AJMP FINAL)

;Contador de vuelta en cero ==> No hay 2

;(3) ;(2) ;Desempilamos el caracter ledo ;Lo escribimos nuevamente un lugar a la i

;Seguimos ciclando ;Desempilamos el ACC (solo para vaciar la ;Tomamos el CURSOR y... ;Lo decrementamos (reposicionamos un luga ;(3) ;(2) ;Guardamos el CURSOR

LJMP

FINAL

;******************************************************************************* ************************* ;El siguiente cdigo se encarga de encender o apagar el Led de CAPS LOCK cada vez que el usuario presione ;la tecla correspondiente (CAPS LOCK ==> Scan Code 58H) ;******************************************************************************* ************************* CL_ONOFF: CJNE A,#58H,CURSORSX CPL CAPLOCK JNB CAPLOCK,CL_OFF MOV CL_DATA,#83H ;Leds CAPS LOCK y NUM LOCK encendidos SJMP $+5 ;(2) CL_OFF: MOV CL_DATA,#01H ;(3) Led NUM LOCK=ON y Led CAPS LOCK=OFF ;A continuacin est el protocolo para iniciar la transmisin MICRO==> TECLADO MOV DPTR,#CAPS_40 ;En la 1ra pasada vamos a CAPS_40 CAPS_10: CLR TR0 CLR TR1 CLR EX0 ;Inhabilita Interrupcin Externa 0 CLR P3.2 ;"Tira Abajo" la lnea CLOCK NOP CLR IE0 MOV NBITS,#00H MOV R0,#95 ;(2) CAPS_20: DJNZ R0,CAPS_20 ;(95x2=190 ciclos mquina) tiempo para "baj ar" lnea DATA CLR P3.4 ;(2) "Tira abajo" lnea DATA MOV R0,#85 ;(2) CAPS_30: DJNZ R0,CAPS_30 ;(85x2=170 ciclos mquina) MOV A,#00H ;(3) SETB SEND SETB TR0 SETB TR1 SETB EX0 JMP @A+DPTR ;(1) Saltamos a la etiqueta apuntada por ACC ;En este punto el control quedar a cargo de un cdigo includo en la Rutina INT EXT0, que se encargar ;de enviar hacia el Teclado los bits de Comando/Datos sincronizados con el CLOCK que genera el teclado. CAPS_40: SETB CMD_CL SETB BIT_DAT MOV BYTEDATA,CL_CODE SETB P3.2 ;"libero" lnea CLOCK (El Teclado se har car go de lnea CLOCK) JB CMD_CL,$ ;Ciclamos hasta que bit CMD_CL se ponga a "0" (despus del ACK) MOV DPTR,#CAPS_50 SJMP CAPS_10 CAPS_50: SETB SEND_CL CLR BIT_DAT MOV BYTEDATA,CL_DATA SETB P3.2 ;"libero" lnea CLOCK (El Teclado se har car go de lnea CLOCK) JB SEND_CL,$ ;Ciclamos hasta que bit SEND_CL se ponga a "0" (despus del ACK) MOV KEYTEMP,#0 ;Borramos KEYTEMP pues ya fue ledo

LJMP

EMPTY

;******************************************************************************* ************************* CURSORSX: CJNE A,#6BH,SX_05 ;(3) Comprueba si se apret la tecla CURSOR LEFT (Scan Code 6BH) SJMP $+4 ;(2) SX_05: AJMP CURSORDX ;(2) MOV A,CURSORL ;Tomamos CURSORL, si ... CJNE A,#MINI_L,SX_10 ;(2) es mayor que MINI_L continuamos en $ +8... MOV A,CURSORH ;(2) CJNE A,#MINI_H,SX_10 ;(2) CALL BEEP ;Generamos un BEEP de advertencia MOV KEYTEMP,#0 LJMP EMPTY ;(2) Si CURSORL=MINI_L y CURSORH=MINI_H ==> "ignoramos" SX_10: MOV MOV ;Como el CURSOR an lo si el caracter ;de la izquierda no DEC zquierda MOV CJNE DEC MOVX CURSOR CJNE cionamos el CURSOR CALL MOV LJMP aje) ignoramos SX_20: MOV MOV LJMP DPL,CURSORL ;Apuntamos al lugar donde est el cursor DPH,CURSORH no est en 0800H, vamos a desplazarlo un lugar a la Izquierda so es un Fin de Mensaje "0". DPL ;Reposicionamos el CURSOR un lugar a la I A,DPL A,#0FFH,$+5 DPH A,@DPTR A,#0,SX_20 BEEP KEYTEMP,#0 EMPTY CURSORL,DPL CURSORH,DPH FINAL ;(3) ;(2) ;Leemos caracter anterior a la posicin del ;Si el caracter anterior NO es "0" reposi ;Generamos un BEEP de advertencia ;Si caracter anterior es "0" (Fin de Mens ;Reposicionamos... ;...el CURSOR

;******************************************************************************* ************************* ; El lmite hasta donde puede llegar el CURSOR en direccin DX es el caracter de Fin de Mensajes (00) o ; el Lmite de la Zona de Mensajes (1AFFH), aunque si estamos editando un mensaje por primera vez enton; ces CURSORDX no puede llevar al CURSOR hasta un caracter FF. ; NOTA : Para saber si estamos en Fin del ltimo Mensaje, 1ro vemos si estamos sob re el caracter "0" y ; luego vemos si el siguiente caracter tambin es un "0", en este caso el CURSOR n o se mueve. ;******************************************************************************* ************************* CURSORDX: CJNE A,#74H,DELETE ;Comprueba si se apret la tecla CURSOR RIG HT (Scan Code 74H) MOV A,CURSORL ;Antes de entrar comprobamos que... CJNE A,#MFIN_L,DX_10 ;(3) el CURSOR est situado antes MOV A,CURSORH ;(2) de la ltima direccin (18FFH)

CJNE A,#MFIN_H,DX_10 ;(3) de la memoria de mensajes. CALL BEEP ;Generamos un BEEP de advertencia MOV KEYTEMP,#0 LJMP EMPTY ;(3) Si el CURSOR est en la direccin 18FFH ==> "ignoramos" ;Tener en cuenta que en la zona de Mensajes (0800H - 18FFH) cuya longitud es de 10FFH bytes, entran a;proximadamente D9H (o sea 217) mensajes de 14H (o sea 20) caracteres de longitu d de los cuales 4 son ;cdigos (Ahora, si el mensaje es cdigo "Z" tenemos el lmite impuesto por la capacid ad de la memoria ;RAM EXT. para almacenar la trama; el lmite es de FCH= 3 cdigos + 248 caracteres + 1 Fin de Mensaje). ;NOTA: Mediante el uso de la Tecla de cursor DX el CURSOR solo puede llegar hast a el ltimo caracter ;del mensaje antes del "0" fin de mensaje (solo se mueve dentro de un mensaje). DX_10: MOV DPL,CURSORL ;Apuntamos al lugar donde est el cursor MOV DPH,CURSORH INC DPTR ;Reposicionamos el CURSOR un lugar a la d erecha MOVX A,@DPTR ;Leemos el caracter de la posicin siguient e al CURSOR CJNE A,#0,DX_20 ;Si el caracter NO es "0" reposicionamos el CURSOR CALL BEEP ;Generamos un BEEP de advertencia MOV KEYTEMP,#0 LJMP EMPTY ;Si el caracter es "0" ignoramos (el CURS OR no se mueve) DX_20: MOV CURSORL,DPL MOV CURSORH,DPH LJMP FINAL ;******************************************************************************* ************************* ; La caracterstica de DELETE es que borra el caracter sobre el que est situado el CURSOR y a la vez ; los caracteres situados a la derecha del mismo (salvo el 0 de fin de mensaje) se van desplazando ha; cia la izquierda mientras el CURSOR se mantiene inmvil. ; Como al actuar DELETE el "0" de fin de mensaje se mantiene en su lugar, signif ica que con DELETE no ; se puede borrar un mensaje solo podemos llenarlo de "blancos". Para borrar un mensaje debemos situar ; el CURSOR al comienzo del mensaje (cdigo efecto) y usar la tecla F10 (Scan Code 9). ;******************************************************************************* ************************* DELETE: CJNE A,#71H,$+5 ;(3) Comprueba si se apret la tecla DELETE (Scan Code 71H) SJMP DEL_01 ;(2) LJMP FINI DEL_01: MOV DPL,CURSORL MOV DPH,CURSORH CLR Z_SI ;Se setear solo cuando se detecte un Cdigo "Z" ;En este punto debemos tener en cuenta que el comportamiento de DELETE es distin to para un mensaje Cdigo

;"Z" que para el que no lo es, para el 1ro DELETE borra "elimina" uno a uno los caracteres a la derecha ;del mismo hasta el "00" de Fin de Mensajes (desplazando a este a la SX), mientr as que para mensaje con ;efecto NO "Z" no hay desplazamiento del "0" ni de los mensajes siguientes. ;Por lo tanto lo 1ro que haremos es averiguar el Cdigo Efecto del presente Mensaj e: DEL_02: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 ;(3) DEC DPH ;(2) MOV A,DPL JNZ DEL_04 ;No estamos en el orgen de la Zona de Mens ajes MOV A,DPH CJNE A,#08H,DEL_04 ;No estamos en el orgen de la Zona de Mens ajes SJMP DEL_06 ;Leemos el Cdigo Efecto (estamos en 0800H) DEL_04: MOVX A,@DPTR JNZ DEL_02 ;No estamos todava en el "0" ==> seguimos ciclando INC DPTR ;Incrementamos DPTR para apuntar al Cdigo Efecto DEL_06: MOVX A,@DPTR ;Leemos Cdigo Efecto MOV DPL,CURSORL ;Apuntamos nuevamente a la posicin del CUR SOR (low byte) MOV DPH,CURSORH ;Apuntamos nuevamente a la posicin del CUR SOR (high byte) CJNE A,#5AH,DEL_10 ;El mensaje no es Cdigo "Z" SETB Z_SI ;El mensaje es Cdigo "Z" ;Ahora haremos que suene un BEEP cuando el DPTR apunte a un "blanco" y el siguie nte caracter es un "0": MOVX A,@DPTR ;Leemos caracter donde est el CURSOR (y el DPTR) CJNE A,#20H,DEL_10 ;Si el caracter apuntado no es "20H" ==> seguimos PUSH DPL PUSH DPH INC DPTR ;Apunto al siguiente caracter MOVX A,@DPTR ;Leemos el siguiente caracter POP DPH POP DPL JNZ DEL_10 ;El siguiente caracter no es "0" ==> segu imos CALL BEEP ;El caracter actual es "20H" y el siguien te "0" ==> Ignoramos MOV KEYTEMP,#0 LJMP EMPTY DEL_10: MOV A,#20H ;Cargamos un "blanco" (20H) en el ACC MOVX @DPTR,A ;Copiamos el "blanco" en el lugar apuntad o por el DPTR INC DPTR ; En este punto debemos verificar que el DPTR no apunte sobre el "0" (Fin de Men saje) MOVX A,@DPTR ;Leemos caracter apuntado por el DPTR JNZ DEL_20 ;Si el caracter NO es "0" seguimos JNB Z_SI,DEL_15 ;El mensaje no es cdigo "Z" por lo tanto e l "0" es el Fin

;En este punto tenemos un mensaje Cdigo "Z", por lo tanto el desplazamiento es ha sta el "00": INC CEROS ;Incrementamos contador de ceros consecut ivos MOV A,CEROS CJNE A,#2,DEL_25 ;Para Cdigo "Z" el 1er cero no es el fin d el desplazamiento DEC DPL ;Apuntamos al lugar donde estaba el 1er " 0" MOV A,DPL CJNE A,#0FFH,$+5 ;(3) Vemos si hace falta decrementar DPH (solo si DPL=FFH) DEC DPH ;(2) MOV A,#00 MOVX @DPTR,A ;Escribimos el 2do "0" un lugar a la izqu ierda MOV CEROS,#00 ;Contador de vuelta en cero (terminamos e l desplazamiento) DEL_15: LJMP FINAL ;Si el caracter es "0" salimos DEL_20: MOV CEROS,#00 ;Contador de vuelta en cero ==> No hay 2 ceros consecutivos DEL_25: MOVX A,@DPTR ;Copiamos (leemos) el caracter (ASCII) PUSH ACC ;Empilamos el caracter ledo DEC DPL ;Solo decrementamos el DPL (no hace falta ms) MOV A,DPL CJNE A,#0FFH,$+5 ;(3) Vemos si hace falta decrementar DPH (solo si DPL=FFH) DEC DPH ;(2) POP ACC ;Desempilamos el caracter ledo MOVX @DPTR,A ;(1) Lo guardamos (escribimos) un lugar ms a la izquierda INC DPTR AJMP DEL_10 ;Seguimos ciclando... ;Tener en cuenta que DELETE borra el caracter donde est el CURSOR y que no produc e ningn desplaza;miento de este (ocurre que todos los caracteres de la derecha se corren un luga r a la Izquierda) ;******************************************************************************* ************************* ;FIN: Este cdigo sirve para situar el CURSOR al final del presente mensaje. ;Para activar esta funcin se usa la Tecla FIN (69H). ;******************************************************************************* ************************* FINI: CJNE A,#69H,COMIENZO ;(3) Esta porcin de cdigo sirve para setear o MOV DPL,CURSORL MOV DPH,CURSORH ;Ahora debemos encontrar el Fin de Mensaje "0" y situar el CURSOR en esa posicin: FINI_10: INC DPTR MOVX A,@DPTR CJNE A,#0,FINI_10 ;Si no estamos en el Fin de Mensaje segui mos ciclando

DEC ter del mensaje MOV CJNE DEC FINI_20: SETB MOV MOV LJMP

DPL A,DPL A,#0FFH,FINI_20 DPH DXFIN CURSORL,DPL CURSORH,DPH FINAL

;Decrementamos para apuntar al ltimo carac ;(3) ;(2) ;Reposicionamos el CURSOR

;******************************************************************************* ************************* ;COMIENZO: Este cdigo sirve para situar el CURSOR al inicio del presente mensaje ;Para activar esta funcin se usa la Tecla INICIO (6CH). ;******************************************************************************* ************************* COMIENZO: CJNE A,#6CH,RE_MSG MOV DPL,CURSORL MOV DPH,CURSORH ;Ahora debemos encontrar el Fin de Mensaje del mensaje anterior (o el orgen 0800H ), luego incrementamos ;el DPTR para situarnos en el Cdigo Efecto del presente mensaje: INI_10: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 ;(3) DEC DPH ;(2) MOV A,DPL CJNE A,#MINI_L,INI_20 ;Verificamos que no estamos en el orgen... MOV A,DPH CJNE A,#MINI_H,INI_20 ;...(0800H) de la Zona de Mensajes AJMP INI_30 ;Ya tenemos el Orgen (cdigo efecto) del Men saje (0800H) INI_20: MOVX A,@DPTR CJNE A,#0,INI_10 ;El caracter no es "0" ==> seguimos cicla ndo INC DPTR ;Incrementamos el DPTR para apuntar al Cdi go Efecto INI_30: SETB SXINI MOV CURSORL,DPL MOV CURSORH,DPH LJMP FINAL ;******************************************************************************* ************************* ;RE_MSG: (Retrocede Mensaje) Este cdigo sirve para pasar el CURSOR al mensaje ant erior (de la SX) si;tuando el CURSOR en el orgen del nuevo mensaje (el de la izquierda) ;NOTA: Debemos tener en cuenta que entramos a RE_MSG con la tecla RePg (Page Down ) Scan Code 7AH ;******************************************************************************* ************************* RE_MSG: CJNE A,#7AH,NEW_MSG MOV DPL,CURSORL MOV DPH,CURSORH MOV R0,#2

; Antes que nada debemos ver si el CURSOR est sobre el orgen (MINI_L, MINI_H) de l a Zona de Mensajes, ; en este caso se debe ignorar la tecla RePg. MOV A,CURSORL CJNE A,#MINI_L,BACK_10 MOV A,CURSORH CJNE A,#MINI_H,BACK_10 CALL BEEP ;No hay mensaje anterior MOV KEYTEMP,#0 LJMP EMPTY ;Si el CURSOR est sobre el orgen (0800H) ig noramos BACK_10: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 ;(3) DEC DPH ;(2) ; En este punto debemos tener en cuenta al ir hacia atrs (SX) que no podemos ir ms a la izquierda de ; 0800H (orgen de Zona de Mensajes) MOV A,DPL CJNE A,#MINI_L,BACK_20 MOV A,DPH CJNE A,#MINI_H,BACK_20 SJMP BACK_30 ; BACK_20: MOVX A,@DPTR ; Leemos caracter apuntado CJNE A,#0,BACK_10 DJNZ R0,BACK_10 ;En este punto el DPTR apunta al 2do "0" a la izquierda del mensaje original, po r lo tanto para apuntar ;al cdigo efecto debemos incrementar el DPTR: INC DPTR ; Apuntamos al 1er caracter del mensaje ( cdigo efecto) BACK_30: MOV CURSORL,DPL MOV CURSORH,DPH SETB REV ;Seteamos flag que indica salto al mensaj e anterior LJMP FINAL ;******************************************************************************* ************************* ;NEW_MSG: El siguiente Cdigo sirve para situarnos en un nuevo mensaje, y siempre sita el CURSOR en el ;1er caracter (cdigo efecto) del mensaje que si existe se lo ver tal cual, y si no existe se ver co;mo un mensaje de "blancos" con una longitud de 3+16+1=20 caracteres. O sea que se encarga de situar el ;cdigo de Fin de Mensaje "0" en el lugar correspondiente (supone un mensaje cdigo no Z) ;NOTA: Debemos tener en cuenta que a NEW_MSG entramos con la tecla AvPg (Scan Cod e 7DH) ;******************************************************************************* ************************* NEW_MSG: CJNE A,#7DH,NEW_03 ;Comprueba si se apret la tecla AvPg (Page Up) SJMP $+4 ;(2) NEW_03: AJMP DEL_MSG ;(2) MOV DPL,CURSORL MOV DPH,CURSORH ;Lo que tenemos que hacer ahora es encontrar el Fin de Mensaje (del mensaje actu

al) y luego incrementar ;una vez msel DPTR para apuntar al 1er caracter (cdigo efecto) del mensaje siguien te si es que exis;te, si no existe crea uno nuevo escribiendo 15 "blancos" y un "0" de Fin de Men saje. NEW_05: INC DPTR ;(1) MOVX A,@DPTR ;(1) CJNE A,#0,NEW_05 ;(3) Seguimos incrementando el DPTR hasta encontrar el "0" ; Si en este punto estamos al final de la Zona de Mensajes no podemos crear Mens aje Nuevo ==> ignoramos MOV A,DPL CJNE A,#MFIN_L,NEW_08 ; No estamos al final de Zona de Mensajes MOV A,DPH CJNE A,#MFIN_H,NEW_08 ; No estamos al final de Zona de Mensajes MOV KEYTEMP,#0 LJMP EMPTY ; Estamos al final de Zona de Mensajes == > ignoramos NEW_08: INC DPTR ;(1) Apuntamos al Cdigo Efecto del sigte m ensaje (si existe) PUSH DPL ; Guardamos (empilamos) el DPTR pues ac... PUSH DPH ; debe posicionarse el CURSOR y nos har fa lta ;Ahora tenemos que ver si en la direccin a la que apunta el DPTR hay un mensaje o no, para esto leemos ;el cdigo y si es un "0" no hay mensaje (porque es el 2do cero del Fin de Mensaje s): MOVX A,@DPTR CJNE A,#0,NEW_20 ; Si no es "0" entonces el mensaje existe ; Ahora debemos determinar si hay espacio en Memoria de Mensajes (0800H - 1AFFH) para crear el mensaje ; nuevo (siempre se crea un mensaje de 3+16+1+1=21=15H caracteres): MOV A,DPH CJNE A,#MFIN_H,NEW_09 ; Hay lugar en Memoria de Mensajes (no ha ce falta verificar DPL) MOV A,#0FFH CLR C SUBB A,DPL ; En ACC tenemos los espacios disponibles para el mensaje ;NOTA: En la anterior resta el C no puede ponerse a 1 pues DPL<FFH ;Debemos ver ahora si el espacio en caracteres (bytes) es mayor o igual a 17=3+1 2+2=11H SUBB A,#11H ; Si el espacio disponible es menor de 11 H ==> C=1 JNC NEW_09 ; Hay lugar en Memoria de Mensajes CALL BEEP ; No hay lugar en memoria para un nuevo M ensaje MOV KEYTEMP,#0 LJMP EMPTY ; No hay lugar en memoria de Mensajes ==> ignoramos ;ahora tenemos que colocar el doble cero al final del mensaje y reemplazar el ac tual por un "blanco" NEW_09: MOV A,#20H ;Cargamos un "blanco" MOV R0,#0 ;Contador de incrementos para el DPTR NEW_10: MOVX @DPTR,A ;Escribimos "blancos" desde el Cdigo Efect o... INC DPTR ;...hasta el caracter Nro 15 (ltimo)... INC R0 CJNE R0,#15,NEW_10 ; MOV A,#0

MOVX INC MOVX NEW_20: POP go efecto del... POP MOV MOV SETB mensaje LJMP

@DPTR,A DPTR @DPTR,A DPH DPL CURSORL,DPL CURSORH,DPH FOW FINAL

;1er "0" del Fin de Mensajes ;2do "0" del Fin de Mensajes ;desempilamos el DPTR (ahora apunta al cdi ;mensaje recin creado) ;Reposicionamos el CURSOR ;Seteamos flag que indica salto al prximo

;******************************************************************************* ************************* ; DEL_MSG: (Borra Mensaje) Sirve para "eliminar" un mensaje completo desde la Zo na de Mensajes. Para ; hacerlo debemos situarnos en el orgen (cdigo efecto) del mensaje y apretar la te cla F10, esto hace ; que todos los mensajes siguientes al que queremos borrar se desplacen a la SX en una cantidad de bytes ; igual a la cantidad de caracteres del mensaje a borrar. ;******************************************************************************* ************************* DEL_MSG: CJNE A,#09H,DEL_M05 ;Comprueba si se apret la tecla F10 (scan code 9) SJMP $+4 ;(2) DEL_M05: AJMP ASCII ;(2) MOV DPL,CURSORL MOV DPH,CURSORH MOV R1,#2 ;Contador de ceros consecutivos (para hal lar el "00") MOV R2,#0 ;Contador de caracteres desde el orgen del mensaje actual hasta ;el orgen del mensaje siguiente ;El prximo paso es encontrar el Orgen del mensaje actual (que ser borrado): DEL_M10: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 ;(3) DEC DPH ;(2) MOV A,DPL CJNE A,#MINI_L,DEL_M15 ;Verificamos que no estamos en el orgen... MOV A,DPH CJNE A,#MINI_H,DEL_M15 ;...(0800H) de la Zona de Mensajes AJMP DEL_M20 ;Ya tenemos el Orgen (cdigo efecto) del Men saje (0800H) DEL_M15: MOVX A,@DPTR CJNE A,#0,DEL_M10 ;El caracter no es "0" ==> seguimos cicla ndo INC DPTR ;Incrementamos el DPTR para apuntar al Cdi go Efecto DEL_M20: ;Ahora debemos encontrar la distancia hasta el orgen del siguiente mensaje, y lue go desplazaremos hacia ;la izquierda una distancia igual a todos los caracteres hasta llegar al "00": INC DPTR INC R2 ;R2=Nro bytes desde el Orgen hasta el "0" del mensaje siguiente MOVX A,@DPTR

CJNE A,#0,DEL_M20 ;En este punto necesitamos incrementar en uno a R2 para que tengamos la distanci a hasta el Orgen: INC R2 ;Ahora tambin necesitamos incrementar en uno el DPTR para leer el caracter y si e s "0" significa que es ;el 2do "0" del Fin de Mensajes, por lo tanto salimos (no se borra nada) INC DPTR MOVX A,@DPTR JNZ DEL_M25 CALL BEEP ;Generamos un BEEP de advertencia MOV KEYTEMP,#0 LJMP EMPTY DEL_M25: ;Volvemos a apuntar al "0" Fin de Mensaje DEC DPL MOV A,DPL CJNE A,#0FFH,DEL_M30 DEC DPH ;Ahora tenemos que desplazar R2 lugares a la Izquierda a todos los caracteres si tuados a la derecha del ;Fin de mensaje "0" del mensaje actual (que queremos borrar): DEL_M30: imo... INC PUSH PUSH MOVX DPTR DPL DPH A,@DPTR ;Incrementamos el DPTR hasta llegar al prx ;Empilo DPL ;Empilo DPH ;Leo caracter del mensaje a ser trasladad

o ;En este punto debemos saber si el caracter ledo es un "0" y si lo es debemos lee r el siguiente carac;y si es otro "0" quiere decir que estamos en un Fin de Mensajes y si el 2do car acter no es "0" signifi;ca que el 1er "0" es solo el Fin del Mensaje (no el Fin del ltimo mensaje) JNZ DEL_M40 ;El caracter ledo no es "0" ==> seguimos DJNZ R1,DEL_M50 ;El caracter es un "0" falta averiguar el siguiente SETB FIN_FIN ;Si leemos el 2do "0" consecutivo ==> FIN _FIN=1 SJMP DEL_M50 ;Vamos a trasladar el 2do "0" DEL_M40: MOV R1,#2 DEL_M50: PUSH ACC ;Empilamos ACC MOV A,DPL SUBB A,R2 MOV DPL,A JNC DEL_M55 ;Si C=0 ==> no decrementamos el DPH DEC DPH DEL_M55: POP ACC ;Desempilamos ACC MOVX @DPTR,A POP DPH POP DPL JB FIN_FIN,DEL_M60 AJMP DEL_M30 DEL_M60: MOV DPL,CURSORL MOV DPH,CURSORH LJMP FINAL ;*******************************************************************************

************************* ; Funcionamiento de ASCII: Primero comprueba que el caracter sea imprimible. ; Luego comprueba que el CURSOR no est situado sobre el final de la Zona de Mensa jes (1AFF), si todo ; est okey entonces escribe el caracter introducido en el lugar donde est el CURSO R, y el caracter so ; bre el que estaba este junto con todos los caracteres que estaban a la derecha son desplazados un lu; gar a la derecha; este desplazamiento se produce hasta el caracter de fin de m ensaje o el fin de zona ; de mensajes si este es alcanzado (en este caso el mensaje se trunca en 1AFFH) ;******************************************************************************* ************************* ASCII: ; Verificamos que el caracter introducido por el teclado sea imprimible MOV R1,#00H MOV A,KEYBUFF ;(2) Cargamos en ACC el caracter introduc ido por el teclado CJNE A,#00,$+6 ;(3) el caracter es imprimible continuamo s... LJMP EMPTY ;(3) El caracter no es imprimible (ignora mos) CLR Z_SI ;Por defecto el mensaje no ser efecto "Z" MOV DPL,CURSORL MOV DPH,CURSORH ;En este punto tenemos el DPTR en la direccin del CURSOR, y debemos saber si esta mos en la posicin de ;un Cdigo Efecto o no, para esto vemos si el caracter a la SX del CURSOR es un "0 " o si la direccin a ;la SX del CURSOR es 07FFH (un lugar a la SX de 0800H) entonces el caracter que introdujimos por el te;clado es un Cdigo Efecto: DEC DPL MOV A,DPL CJNE A,#0FFH,LEECHAR ;(3) Si DPL no es igual a FFH no estamos en el orgen DEC DPH ;(2) MOV A,DPH ;(2) CJNE A,#07H,LEECHAR ;(3) Si DPH no es igual a 07H entonces no estamos en el orgen SJMP EF_CODE ;(2) LEECHAR: MOVX A,@DPTR ;Leemos el caracter a la SX del CURSOR pa ra ver si es "0" CJNE A,#0,$+5 ;(3) El CURSOR no est en el lugar de un Cdi go Efecto SJMP EF_CODE ;(2) SJMP NO_EFEC ;(2) ;Ahora en este punto sabemos que el CURSOR est en el lugar de un cdigo efecto, por lo tanto debemos a;puntar el DPTR nuevamente al CURSOR y verificar que el caracter introducido por el teclado sea un Cdi;go Efecto vlido, luego recin lo escribimos en su lugar. EF_CODE: INC DPTR ;Apuntamos nuevamente al Cdigo Efecto MOV A,KEYBUFF CJNE A,#50H,$+5 ;(3) Vemos si es "P" SJMP CODE_OK ;(2) CJNE A,#47H,$+5 ;(3) Vemos si es "G"

SJMP CODE_OK CJNE A,#44H,$+5 SJMP CODE_OK CJNE A,#49H,$+5 SJMP CODE_OK CJNE A,#53H,$+5 SJMP CODE_OK CJNE A,#42H,$+5 SJMP CODE_OK CJNE A,#4EH,$+5 SJMP CODE_OK CJNE A,#5AH,$+5 SJMP CODE_OK ; En este punto produciremos un pitido ero sin mensaje de error CALL BEEP MOV KEYBUFF,#00 LJMP EMPTY s CODE_OK: CJNE A,#5AH,$+5 FEC y escribimos el nto del Fin de Mensaje "0"). SJMP MSG_Z1 LJMP MSG_NOZ MSG_Z1: ;Ahora debemos ver si el Cdigo Efecto MOV ORG_L,DPL o estamos en el orMOV ORG_H,DPH NT TIMER1. MOV DPL,CURSORL MOV DPH,CURSORH MOVX A,@DPTR CJNE A,#5AH,ZNUEVO MOV KEYBUFF,#00H s) LJMP EMPTY ZNUEVO: SETB Z_SI e "0" puede moverse) SJMP MSG_Z2 ;Ahora vamos a averiguar si el mensaje hacerlo NO_EFEC: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 DEC DPH MOV A,DPL CJNE A,#00H,NOEF_10 MOV A,DPH CJNE A,#08H,NOEF_10 apuntando a 0800H ;En este punto estamos sobre el orgen l Cdigo Efecto SJMP NOEF_20 NOEF_10: MOVX A,@DPTR CJNE A,#0,NO_EFEC

;(3) Vemos si es "D" ;(2) ;(3) Vemos si es "I" ;(2) ;(3) Vemos si es "S" ;(2) ;(3) Vemos si es "B" ;(2) ;(3) Vemos si es "N" ;(2) ;(3) Vemos si es "Z" ;(2) mediante el llamado a la Rutina PON_CAD p ;Generamos un BEEP de advertencia ;Borramos KEYBUFF pues ya no nos sirve ;Si el Cdigo efecto no es vlido lo ignoramo ;(3) Si el Cdigo no es "Z" saltamos a NO_E ;caracter en su lugar (no hay desplazamie ;(2) ;(2) ya es "Z", si es as no tomamos ninguna accin: ;Fijamos el ORG del mensaje Cdigo "Z", com ;gen, este ser el ORG inicial que usar la I

;El cdigo actual (ya existente) no es Z ;Borramos KEYBUFF (aunque no lo utilizamo

;El mensaje ser Cdigo "Z" (El fin de mensaj en el que estamos es Cdigo "Z" o no, para

;(3) ;(2) ;(2) ;(3) DPH no es igual a 08H ==> no estamos (0800H) de la Zona de Mensajes ==> leemos e ;DPTR=0800H ==> leemos el cdigo efecto. ;El caracter ledo no es un Cdigo Efecto seg

uimos ciclando ;En este punto el DPTR apunta al Fin de Mensaje "0" del mensaje anterior, por lo tanto para leer el c;digo efecto del mensaje sobre el que est el CURSOR debemos incrementar el DPTR. INC DPTR ;En este punto sabemos que el CURSOR est sobre el Orgen de la Zona de Mensajes o, sobre el cdigo E;fecto del mensaje donde est el CURSOR, por lo tanto lo que tenemos que hacer aho ra es averiguar el c;digo efecto del mensaje actual. NOEF_20: ;Leemos el Cdigo Efecto MOVX A,@DPTR CJNE A,#5AH,$+5 ;(3) Si el mensaje no es Cdigo "Z" ==> sal tamos a MSG_NOZ SJMP MSG_Z2 ;(2) LJMP MSG_NOZ ;Ahora calculamos la Mxima posicin que puede alcanzar el Fin de Mensaje "0": MSG_Z2: CLR C MOV A,#0FCH ; La Longitud Mxima 0FCH=3+248+1 puede modifi carse!!! ADD A,DPL MOV DPL,A JNC $+4 ;(2) INC DPH ;(2) MOV TOPMSGL,DPL MOV TOPMSGH,DPH ;En este punto estamos listos para escribir el caracter en el lugar del CURSOR, antes de hacerlo debemos ;desplazar un lugar a la DX a "todos" los caracteres a la derecha del CURSOR, te niendo como lmite para ;la posicin del "0" la dada por TOPMSG. CLR FIRST_0 MOV DPL,CURSORL MOV DPH,CURSORH MOVX A,@DPTR MOV R0,A MOV A,KEYBUFF MOVX @DPTR,A CODEZ_10: INC DPTR MOVX A,@DPTR PUSH ACC JB FIRST_0,NO_END ;El lmite TOPMSG solo vale para el 1er "0" JNZ NO_END ;Si el caracter no es "0" seguimos... SETB FIRST_0 MOV A,DPL ;Comprobamos que el "0" no lleg a su posic in Lmite (TOPMSG) CJNE A,TOPMSGL,NO_END ;An no estamos al final de la Zona de Mens ajes MOV A,DPH CJNE A,TOPMSGH,NO_END ;An no estamos al final de la Zona de Mens ajes ;En este punto el "0" (Fin de Mensaje) del mensaje actual ya alcanz el lmite, por lo tanto para los ;caracteres siguientes la "cadena" de desplazamiento termina en TOPMSG. SJMP CODEZ_30 ;El Fin de Mensaje "0" no se puede despla zar ms ;Comprobamos que si estamos en el Fin Zona de Mensajes (18FFH), si es as, este es el fin de la "cadena"

;de desplazamiento: NO_END: MOV A,DPL CJNE A,#MFIN_L,NO_TOP MOV A,DPH CJNE A,#MFIN_H,NO_TOP POP ACC SJMP CODEZ_30 azamiento ;Ahora veremos si estamos en el Fin de la "cadena" de des;plazamiento: NO_TOP: POP ACC PUSH ACC JNZ CODEZ_20 20 INC CEROS n de Mensajes (o sea 00) MOV A,CEROS CJNE A,#2,CODEZ_25 C MOV A,R0 de Mensajes MOVX @DPTR,A 00" INC DPTR POP ACC MOVX @DPTR,A 00" MOV CEROS,#00 SJMP CODEZ_30 azamiento CODEZ_20: MOV CEROS,#00 ay 1 ceros consecutivos CODEZ_25: MOV A,R0 MOVX @DPTR,A INC R1 se desplaz POP ACC MOV R0,A SJMP CODEZ_10 amiento CODEZ_30: CJNE R1,#00,$+6 LJMP FINAL MOV DPL,CURSORL MOV DPH,CURSORH INC DPTR MOV CURSORL,DPL erecha MOV CURSORH,DPH LJMP FINAL

; ; ; ;Este es el final de la "cadena" de despl Mensajes (00), si es as, este es el fin de

;Si el caracter ledo no es "0" ---> CODEZ_ ;Contador de "ceros" para ver si es el Fi ;Hemos ledo el 1er "0" y est guardado en AC ;Hemos ledo el 2do "0" consecutivo ==> Fin ;Escribo el 1er "0" del Fin de Mensajes "

;Escribo el 2do "0" del Fin de Mensajes " ;Este es el final de la "cadena" de despl ;Vuelvo a 0 el contador de ceros ==> No h

;Si R1 es distinto de cero ==> el CURSOR

;Al prximo eslabn de la "cadena" de desplaz ;(3) ;(3) ;Incrementamos el DPTR ;Reposicionamos el cursor un lugar a la d

;A continuacin tenemos la porcin de cdigo para el caso de que el CURSOR no est en la posicin co;rrespondiente a un Cdigo Efecto y, en cambio est apuntando a otro lugar (cualquie r otro) del mensaje ;La siguiente Porcin de Cdigo sirve tambin para la "escritura" del cdigo efecto en e

l lugar corres;pondiente (ya que la posicin del "0" ya fu ajustada para el caso de "Z" o "NO Z") ;NOTA: Lo 1ro que tenemos que hacer entonces es apuntar a la direccin del CURSOR: MSG_NOZ: MOV DPL,CURSORL MOV DPH,CURSORH MOV R1,#0 MOVX A,@DPTR ;Leemos caracter apuntado por el DPTR y.. . MOV R0,A ;...lo guardamos en R0. MOV A,KEYBUFF ;Leemos caracter ASCII desde KEYBUFF MOVX @DPTR,A ;Lo guardamos en el lugar apuntado por el DPTR ASCII_10: INC DPTR ;Apuntamos al lugar siguiente (incrementa mos DPTR) MOVX A,@DPTR ;Leemos el caracter siguiente del mensaje y CJNE A,#0,$+5 ;(3) Si no es "0" seguimos desplazando lo s caracteres a la DX SJMP ASCII_20 ;(2) Si es "0" salimos del bucle (el cdigo 0 no se mueve) INC R1 PUSH ACC MOV A,R0 a donde escribimos el MOVX ha del anterior) POP icin anterior) MOV SJMP ASCII_20: CJNE SJMP MOV MOV INC MOV erecha MOV @DPTR,A ACC R0,A ASCII_10 R1,#0,$+5 FINAL DPL,CURSORL DPH,CURSORH DPTR CURSORL,DPL CURSORH,DPH ;lo empilamos para usarlo luego ;Recupero el caracter anterior (que estab ;caracter introducido por el teclado) ;lo guardo en la nueva posicin (a la derec ;Desempilo caracter (que estaba en la pos ;lo guardo en R0 ;(3) ;(2) El CURSOR no cambia de posicin ;Incrementamos el DPTR ;Reposicionamos el cursor un lugar a la d

;******************************************************************************* *********************** FINAL: CALL NORMAL1 MOV KEYTEMP,#0 ;Borramos KEYTEMP pues ya fue ledo MOV KEYBUFF,#0 ;Borramos KEYBUFF pues ya fue ledo MOV NBYTES,#0 EMPTY: LJMP REPITE ; A continuacin est el cdigo para salir de PROGRAM, antes de salir debemos asegurar nos que est pues; to el Cdigo de fin de ltimo Mensaje (00), si no est puesto debemos ponerlo. SALIR: CLR PROGMODE CLR NO_MSG ;Reset Bit NO_MSG (No Mensaje en Ram) CLR TR1 ;Stop TIMER1 (solo est en marcha durante m

odo programacin) SETB RET

EX1

;Activamos INT EXT 1 (del RTC)

;******************************************************************************* *********************** ; Efecto : Visualiza el mensaje donde est situado el CURSOR durante MODO PROGRAMA CION ; Nombre : NORMAL1 ;******************************************************************************* ************************* ; FUNCIONAMIENTO DE NORMAL1: Lo que hace esta Rutina es encontrar el Orgen (Cdigo Efecto) del Mensaje ; que debe visualizar, luego si el Cdigo Efecto NO es "Z", de acuerdo al bit TAB salta o no los 1ros 3 ; bytes de cdigo y con este Orgen llama a ASTRA y luego a PONVI. Ahora si el Cdigo Efecto es "Z" en; tonces el bit TAB no se tiene en cuenta y el origen para llamar a ASTRA ser la posicin del cdigo e; fecto hasta que el CURSOR se ubique en la ltima posicin del letrero (caracter Nr o 16), a partir de ; all el Orgen se desplazar a la DX de la misma forma que el CURSOR. ; Ahora si el CURSOR se mueve a la SX el orgen se mantendr fijo hasta que el CURSO R coincida con ste, ; a partir de all el orgen se mover a la SX de la misma forma que el CURSOR. ;******************************************************************************* ************************* NORMAL1: MOV DPL,CURSORL ; MOV DPH,CURSORH ; ;Ahora vamos a ubicar el Orgen (Cdigo Efecto) del presente mensaje o el Orgen de la Zona de Mensajes ;(0800H), el que se encuentre primero: MOV A,DPL CJNE A,#00H,NORM_05 ;El CURSOR no est en el Orgen 0800H MOV A,DPH CJNE A,#08H,NORM_05 ;El CURSOR no est en el Orgen 0800H SJMP NORM_15 ;El CURSOR est sobre el Orgen 0800H NORM_05: DEC DPL MOV A,DPL CJNE A,#0FFH,$+5 ;(3) DEC DPH ;(2) MOV A,DPL CJNE A,#00H,NORM_10 MOV A,DPH ;(2) CJNE A,#08H,NORM_10 ;(3) DPH no es igual a 08H ==> no estamos apuntando a 0800H ;En este punto estamos sobre el orgen (0800H) de la Zona de Mensajes ==> leemos e l Cdigo Efecto SJMP NORM_15 ;DPTR=0800H ==> leemos el cdigo efecto. NORM_10: MOVX A,@DPTR CJNE A,#0,NORM_05 ;El caracter ledo no es un Cdigo Efecto seg uimos ciclando ;En este punto el DPTR apunta al Fin de Mensaje "0" del mensaje anterior, por lo tanto para leer el c;digo efecto del mensaje sobre el que est el CURSOR debemos incrementar el DPTR. INC DPTR ;En este punto sabemos que el CURSOR est sobre el Orgen de la Zona de Mensajes o, sobre el cdigo E-

;fecto del mensaje donde est el CURSOR, por lo tanto lo que tenemos que hacer aho ra es averiguar el c;digo efecto del mensaje actual. NORM_15: MOV PDPL,DPL ;Guardamos Orgen del Mensaje (lo usaremos al salir de PROGRAM) MOV PDPH,DPH ;Guardamos Orgen del Mensaje (lo usaremos al salir de PROGRAM) ;Ahora vamos a calcular ORG_L y ORG_H NI=1: JNB SXINI,NORM_20 MOV ORG_L,CURSORL MOV ORG_H,CURSORH MOV DPL,ORG_L s a ASTRA MOV DPH,ORG_H CLR SXINI LJMP NORM_60 NORM_20: ;Ahora vamos a calcular ORG_L y ORG_H FIN=1: JNB DXFIN,NORM_35 PUSH CURSORL PUSH CURSORH MOV B,#11 NORM_25: DEC CURSORL MOV A,CURSORL CJNE A,#0FFH,NORM_30 ementamos CURSORH DEC CURSORH NORM_30: DJNZ B,NORM_25 MOV ORG_L,CURSORL Fin de Mensaje) MOV ORG_H,CURSORH un lugar a la SX) MOV DPL,ORG_L s a ASTRA MOV DPH,ORG_H POP CURSORH POP CURSORL CLR DXFIN LJMP NORM_60 para el caso de un salto al Orgen o sea SXI ;Vamos a ;Hacemos ;Hacemos ;Fijamos ver si DXFIN est puesto a uno. coincidir el ORG con el CURSOR coincidir el ORG con el CURSOR el valor de DPTR con que llamamo

;Salimos de la Subrrutina para el caso de un salto al Final o sea DX ;Si DXFIN=0 saltamos a NORM_09 ;Empilamos CURSORL ;Empilamos CURSORH ;B=Nro de decrementos para CURSORL ;Si CURSORL no es igual 0FFH ==> no decr

;Fijamos ORG_L (11 caracteres a la SX del ;Fijamos ORG_H (igual a Fin de Mensaje o ;Fijamos el valor de DPTR con que llamamo ;Desempilamos CURSORH ;Desempilamos CURSORL ;Salimos de la Subrrutina mensaje, en est

;La siguiente porcin de cdigo es para el caso del salto a un nuevo e caso hacemos coin;cidir (ORG_L,ORG_H) con (CURSORL,CURSORH): NORM_35: JNB FOW,NORM_40 ;Si FOW=0 (no salto adelante) REV (salto atrs) MOV ORG_L,CURSORL ;Hacemos coincidir el ORG con MOV ORG_H,CURSORH ;Hacemos coincidir el ORG con MOV DPL,ORG_L ;Fijamos el valor de DPTR con s a ASTRA MOV DPH,ORG_H CLR FOW ;Borramos flag (FORWARD) LJMP NORM_60 ;Salimos de la Subrrutina

Verificamos el CURSOR el CURSOR que llamamo

;La siguiente porcin de cdigo es para el caso del salto al mensaje anterior, en es te caso hacemos coin-

;cidir (ORG_L,ORG_H) NORM_40: JNB MOV MOV MOV s a ASTRA MOV CLR LJMP

con (CURSORL,CURSORH): REV,NORM_45 ORG_L,CURSORL ORG_H,CURSORH DPL,ORG_L DPH,ORG_H REV NORM_60 ;Si bit REV=0 ==> Vamos a ;Hacemos coincidir el ORG ;Hacemos coincidir el ORG ;Fijamos el valor de DPTR ;Borramos flag (REVERSE) ;Salimos de la Subrrutina NORM_30 con el CURSOR con el CURSOR con que llamamo

;El siguiente cdigo sirve para que el valor del DPTR con que se llama a ASTRA vare de acuerdo a la po;sicin del CURSOR. Lo que tenemos que hacer es mantener la siguiente desigualdad: ;0 <= (CURSOR-DPTR) <= 16 (El DPTR se incrementar o decrementar segn corresponda) p ara mantener la ;desigualdad. NORM_45: CLR C MOV A,CURSORL ; SUBB A,ORG_L ; PUSH ACC JC NORM_55 ;C=1 ==> CURSORL<ORG_L por lo tanto compa ramos DPH y CURSORH ;En este punto tenemos que C=0 ==> CURSORL>=ORG_L, esta circunstancia puede dars e en 2 casos, a saber: ;1) Si CURSORH=ORG_H ==> que si A (diferencia) es mayor de 12 el DPTR debe increm entarse, y si A<=12 el ; DPTR debe mantenerse constante ;2) Cuando CURSORH<ORG_H, en este caso el DPTR se decrementar de manera que el CUR SOR y el DPTR apun; ten al mismo caracter (o sea que CURSOR estar en el 1er caracter de la parte visible del mensaje) MOV A,CURSORH CJNE A,ORG_H,NORM_50 ;En este caso tenemos CURSORH<ORG_H (no p uede ser a la inversa) POP ACC ;Desempilamos A=diferencia (positiva) ent re CURSORL y DPL CJNE A,#11,$+5 ;(3) Verificamos el Carry C para saber si A es > o < que 12 SJMP $+4 ;(2) Diferencia=12 ==> igual que si Difer encia<12 JNC NORM_INC ;(2) La diferencia entre CURSOR y DPTR es mayor de 12 caracteres AJMP NORM_FIX ;La "diferencia" es <= 12 caracteres ==> ORG_L no cambia (FIX) NORM_50: AJMP NORM_DEC ;Dado que CURSORH<ORG_H tenemos que decre mentar el ORG_L ;A continuacin est el cdigo para el caso que CURSORL<DPL, esta circunstancia puede darse en 2 casos: ;1) Si CURSORH>DPH ==> que si A (diferencia) es mayor de 12 el DPTR debe incremen tarse, y si A<=12 el ; DPTR debe mantenerse constante. ;2) Si CURSORH=DPH ==> en este caso el DPTR se decrementar de manera que el CURSOR y el DPTR apunten ; al mismo caracter (o sea que el CURSOR estaren el 1er carcter de la parte visi ble del mensaje) NORM_55: POP ACC ;Desempilamos el ACC (Solo para vaciar la

pila) MOV A,CURSORH CJNE A,ORG_H,$+5 ;(3) En este caso tenemos CURSORH>ORG_H AJMP NORM_DEC ;(2) En este caso CURSORH=ORG_H ==> decre mentamos el DPTR CLR C MOV A,ORG_L SUBB A,CURSORL ;Hacemos la diferencia (ORG_L - CURSORL) CJNE A,#0F0H,$+3 ;(3) Vemos el Carry C para saber si A es > o < que 0F0H ;Diferencia=0F0H, igual que si Diferencia>0F0H ==> ORG_L no cambia JNC NORM_FIX ;C=0 ==> diferencia>0F0H ==> ORG_L no cam bia (NORM_FIX) AJMP NORM_INC ;C=1 ==> diferencia<0F0H ==> ORG_L debe i ncrementarse (NORM_INC) NORM_FIX: MOV DPL,ORG_L MOV DPH,ORG_H AJMP NORM_60 NORM_INC: INC ORG_L MOV A,ORG_L CJNE A,#0,$+5 ;(3) INC ORG_H ;(2) MOV DPL,ORG_L MOV DPH,ORG_H SJMP NORM_60 NORM_DEC: DEC ORG_L MOV A,ORG_L CJNE A,#0FFH,$+5 ;(3) DEC ORG_H ;(2) MOV DPH,ORG_H MOV DPL,ORG_L NORM_60: CALL ASTRA ;genera la trama de bits MOV SALTO,#0 MOV R7,#VIDEO_H ;apuntamos al comienzo de zona video Ram Externa, esta MOV R6,#VIDEO_L ;zona contiene la trama de bits del mensa je. CALL PONVI ;pasa los datos (bytes) desde la zona vid eo Ram Externa a la ZVI RET ;******************************************************************************* *********************** ; Nombre: TECLADO (EXTERNAL INTERRUPT 0) ; Keyboard Interrupt Service Routine: Este programa captura los SCAN CODE enviad os por un teclado ; tipo PC y, si son imprimibles los traduce a sus correspondientes valores ASCII ;******************************************************************************* *********************** CSEG AT 0003 ;Lugar de la Vectorizacin de la Interrup. del TIMER 0 USING 3 JMP KBD RSEG INT_EXT0 KBD: PUSH DPL

;NBITS=Nro del prximo bit que se ;espera desde el teclado CJNE A,#0,BIT1_8 ;si no bit 0 entonces bit 1 a 8 ;******************************************************************************* ************************* ;En este punto el bit START ya fu ledo con la llegada del 1er pulso de CLOCK, lo q ue tenemos que hacer ;ahora es adecuar la lnea KEYDAT para que en el prximo CLOCK lea el 1er bit de dat o. ; BIT 0: A continuacin el Cdigo para fijar el nivel de KEYDAT para leerlo en el prx imo CLOCK: BIT0: JNB SEND,NOSEND1 JNB BIT_DAT,$+7 ;(3) SETB KEYDAT ;(2) AJMP BUMP ;(2) CLR KEYDAT NOSEND1: AJMP BUMP ;******************************************************************************* ************************* ; BIT 1-8: A continuacin el Cdigo para leer los bits de datos (bits 1ro al 8vo) BIT1_8: CJNE A,#9,$+3 ;(3) C=Carry flag is set if acc < 9 JNC BIT9 ;(2) Si C=0 ==> estamos en el Clock nro 9 JNB SEND,DAT_OUT ;Si SEND=0 ==> La transmisin es Teclado-->Micro ;Ahora debemos enviar los 7 bits faltantes del Cdigo comando para RATE/DELAY 1111 001 ms el bit de Pa;ridad (paridad par) que debe ser P=1, por lo tanto el byte completo es: 1111100 1 MOV A,BYTEDATA ;(2) Cargamos byte del Cdigo de comando pa ra RATE/DELAY RRC A ;(1) MOV BYTEDATA,A JC $+6 ;(2) CLR KEYDAT ;(2) AJMP BUMP ;(2) SETB KEYDAT AJMP BUMP ;(2) ;******************************************************************************* ************************* DAT_OUT: MOV C,KEYDAT ;lee dato desde lnea datos teclado MOV A,KEYTEMP ;como el arribo de los datos es 1ro RR A ;el bit menos signific., rotamos el MOV ACC.7,C ;old value y el nuevo bit es or'ed MOV KEYTEMP,ACC ;to the msb. AJMP BUMP ;******************************************************************************* ************************* ; BIT 9: A continuacin el Cdigo para leer el bit 9 (PARITY CHECK): ; Por lo pronto no escribiremos nign cdigo para verificar el bit de paridad, de ma nera que solo lo ; ignoramos y esperamos el prximo CLOCK (A=10) para ir al bit 10. BIT9: CJNE A,#9,BIT10

PUSH PUSH PUSH MOV

DPH PSW ACC ACC,NBITS

JNB SEND,$+5 ;(3) SETB KEYDAT ;(2) "Liberamos" lnea datos pues Teclado d ebe mandar el Handshake AJMP BUMP ;parity check code would go here ;******************************************************************************* ************************* ; BIT 10: A continuacin el cdigo para leer el bit 10. ;Este es el bit de Stop para el caso de una transmisin Teclado--->Micro, Si la tr ansmisin fuera a la ;inversa: Micro--->Teclado este es el ltimo bit "handshake". BIT10: MOV ACC,KEYTEMP ;tomamos cdigo Scan de la tecla apretada JNB SEND,RECEIVE CLR SEND ;Reseteamos bit SEND (Fin de transmisin Mi cro--->Teclado) AJMP TIDY ;Falta an el bit Nro 11 (o sea el Clock Nr o 12) RECEIVE: ;El byte furecibido por el Micro (puede se r un ACK o no) JB PROGMODE,ENTER1 ;Si estbamos en PROGMODE=1 continuamos... CJNE A,#05H,ENTER ;(3) Si la tecla no es F1 vemos si es F2 SETB PROGMODE ;(2) Si la tecla es F1 hacemos PROGMODE=1 AJMP TIDY ;(2) Salimos de la Interrupcin ;******************************************************************************* ************************* ENTER: JB RTC_IN,ENTER1 ;Si ya estamos en RTC Mode seguimos CJNE A,#06H,$+5 ;Si la tecla apretada no es F2 salimos (A JMP TIDY) SETB RTC_IN ;Seteamos Bit RTC_IN (habilita la entrada en RTC mode) AJMP TIDY ENTER1: ;En este punto debemos ver si KEYTEMP contiene el cdigo de reconocimiento (FAH), y si es as debemos ;verificar los bits CMD_RD, SEND_RD, CMD_CL y SEND_CL, resetear el que correspon da y saltar a TIDY. CJNE A,#0FAH,NO_ACK ;El Teclado no Envi un ACK *** ATENCION * ** JNB CMD_RD,NOCMD_RD ;Verificamos si falta el ACK de CLR CMD_RD ;Borramos flag de cambio de RATE/DELAY en proceso SJMP TIDY ;Ya borramos los flags, ahora salimos de la Interrupcin NOCMD_RD: JNB SEND_RD,NO_S_RD ; CLR SEND_RD SJMP TIDY ;Ya borramos los flags, ahora salimos de la Interrupcin NO_S_RD: JNB CMD_CL,NOCMD_CL ; CLR CMD_CL SJMP TIDY ;Ya borramos los flags, ahora salimos de la Interrupcin NOCMD_CL: ;En este punto solamente puede faltar el Bit SEND_CL, por lo tanto directamente lo reseteamos: CLR SEND_CL SJMP TIDY ;Ya borramos los flags, ahora salimos de la Interrupcin

;******************************************************************************* ************************* NO_ACK: ; Comparamos Scan Code de tecla apretada con 12H (Shift Key): CJNE A,#12H,NOTLS ;is it the left shift char? (12H = Scan C ode of Shift Key) ; A continuacin est el Cdigo para Tecla SHIFT apretada: MOV ACC,LASTKEY ;tomamos el ltimo valor (caracter)... CJNE A,#0F0H,MAKELS ;si es igual a F0H (primer octeto del cod igo de tecla soltada) ;entonces la tecla SHIFT ya fusoltada CLR SHIFT ;next keys will be unshifted MOV LASTKEY,#12H ;copy left shift key to last key SJMP TIDY ; MAKELS: ;En este punto debemos tener en cuenta si el octeto anterior (LASTKEY) fuun 0E0H, si es as no setea;mos el bit SHIFT porque el Scan Code 12H (pertenece al 2do octeto de los 4 que forman el Scan Code de ;una Tecla "ampliada") MOV ACC,LASTKEY CJNE A,#0E0H,MAKELS1 ;(3) Seteamos bit SHIFT MOV LASTKEY,#12H ;Ultima Tecla leda es 12H SJMP TIDY ;(2) No seteamos bit SHIFT MAKELS1: SETB SHIFT ;next key will be shifted MOV LASTKEY,#12H ;copy left shift key to last key SJMP TIDY ; Final del Cdigo para Tecla SHIFT apretada ;******************************************************************************* ************************* ;A continuacin tenemos el cdigo para el caso en que el octeto ledo sea 0E0H o 0F0H, ninguno de estos ;octetos debe ser tenido en cuenta porque el octeto 0E0H significa que es el 1er octeto del MAKE CODE de ;una tecla "ampliada" (formado por 4 octetos), y el octeto 0F0H siempre es el oc teto que antecede al SCAN ;CODE para formar el BREAK CODE de cualquier tecla (ampliada o no). ;NOTA: Tecla "ampliada" es cualquiera de las 10 teclas situadas entre las Normal es y las Num ricas. NOTLS: CJNE os MOV una tecla "ampliada" SJMP NOT_E0: CJNE os MOV ma el BREAK CODE SJMP NOTBREAK: MOV CJNE Octeto vlido ;Si LASTKEY=0F0H ==> amos MOV LASTKEY,A TIDY ;Si KEYTEMP=0E0H ==> es el 1er octeto de ;(2) A,#0E0H,NOT_E0 ;Si KEYTEMP no es igual a 0E0H ==> seguim

A,#0F0H,NOTBREAK ;Si KEYTEMP no es igual a 0F0H ==> seguim LASTKEY,A TIDY ACC,LASTKEY A,#0F0H,NOT_F0 ;Si KEYTEMP=0F0H ==> es el octeto que for ; ;Cargamos LASTKEY en el ACC ;Si LASTKEY no es igual a 0F0H ==> es un

que el valor en KEYTEMP es de una tecla "soltada" ==> ignor KEYTEMP,#0 ;Ignoramos el 2do Scan Code (de la tecla

apretada)... MOV LASTKEY,#0 ;porque estamos ante un "break code" SJMP TIDY ;******************************************************************************* ************************* ; A continuacin est el Cdigo para las teclas normales (no teclas de funcin) ; Lo que hacemos ahora es leer el Scan Code (que no corresponde a una tecla de f uncin) y de acuerdo al ; bit SHIFT buscamos el equivalente ASCII en SHIFTAB, UNSHIFT o CLTAB. NOT_F0: MOV A,KEYTEMP ;get current key MOV LASTKEY,A ;and copy to lastkey JB SHIFT,SHIFTED ;if in unshifted state JB CAPLOCK,CL_TAB ;Si bit CAPLOCK=1 leeremos de la Tabla CL TAB MOV DPTR,#UNSHIFT ;use the unshifted table SJMP SKIP1 CL_TAB: MOV DPTR,#CLTAB ;Apuntamos a la base de la Tabla CLTAB SJMP SKIP1 SHIFTED: MOV DPTR,#SHIFTAB ;else use the shift table SKIP1: MOVC A,@A+DPTR ;translate char in ACC to Ascii CJNE SJMP NOT0: MOV KEYBUFF,A ;store in keyboard buffer MOV NBYTES,#1 ;mark byte read ; A continuacin est el cdigo para el caso de que la tecla pulsada no tenga un carac ter imprimible co; mo salida (como por ejemplo teclas de funcin y letras minsculas) TIDY: MOV NBITS,#0 ;clear flags ready for next key SJMP INTDONE ;Salimos de la interrupcin ; End of Keyboard Translation and Save BUMP: INC INTDONE: POP POP POP POP RETI ACC PSW DPH DPL NBITS ;inc number of bits read so far A,#0,NOT0 TIDY ;if data is zero discard ;discard code goes here

;******************************************************************************* ************************* ; Nombre: PONVI ; R0 : Apunta a zona de video Ram Interna ; R1 : N de caracteres ; R7R6 : Guarda direccin de RAM Externa ;******************************************************************************* ************************* ; ; Este procedimiento copia en la zona de Video Ram Interna (ZVI) las zonas de Ram Externa que ; guardan copias de la visualizacin (o trama de puntos del mensaje).

; Debe tenerse en cuenta que cualquiera sea el tamao de la trama, PONVI solo copia en ZVI 84 bytes ; que corresponden a los 16 caracteres que entran en ZVI (y en el letrero). ; RSEG PONVI: CLR el copiado) PUSH 00H ;Empilamos R0 PUSH 01H ;empilamos R1 PUSH DPH ;empilamos el DPTR (apunta al 1er caracte r del mensaje) PUSH DPL PUSH 05H ;Usaremos R5 como un contador de caracter es copiados por fila PUSH 04H ;Usaremos R4 para contar los 6 caracteres del salto ; Ahora vamos a fijar la cantidad de bytes a copiar en R1=84 (16 caracteres exac tos) esto es vlido ; tanto para el caso de mensaje con cdigo de efecto "Z" o cualquier otro efecto. MOV 5FFH=1535 bytes y MOV MOV na MOV Externa PON_05: MOV R5,#12 ;Contador caracteres en 12 (bytes por fil a) ==> 12x8=96 columnas PON_10: MOVX A,@DPTR ;Leemos caracter desde Ram Externa MOV @R0,A ;Copiamos el caracter en Ram Interna INC R0 ;incrementamos apuntador a Ram Interna INC DPTR ;incrementamos apuntador a Ram Externa ; A continuacin debe habilitarse un contador para que vaya contando los caractere s que se van copiando ; desde RAM EXT. a ZVI, para que una vez copiados los 1ros 12 bytes (correspond ientes a la 1ra fila), ; se salten los siguientes SALTO bytes y se contine luego con la 2da fila y asi s ucesivamente. ; Para el contador usaremos (previo empilamiento) el registro R5. ; NOTA: SALTO es una variable cuyo valor se define en DESPLAZA. DJNZ R1,$+4 ;(2) SJMP PON_20 ;(2) DJNZ R5,PON_10 ;(2) Con cada caracter copiado a ZVI decr ementamos R5 MOV A,SALTO JZ PON_05 ;Si SALTO=0 vamos directamente a PON_05 MOV R4,SALTO ;Valor del SALTO desde una fila a la prxim a INC DPTR ;(1) DJNZ R4,$-1 ;(2) SJMP PON_05 ;(2) Una vez "saltados" los 6 caracteres vamos a PON_05 ... DPH,R7 ;ahora el DPTR apunta a la Zona Video Ram R1,#84 R0,#ZVI DPL,R6 ;Nmero de bytes a copiar (zona VIDEO tiene ;la zona CVIDEO tiene 54H=84 bytes) ;R0 apunta a ZVI ;recuperamos direccin zona video Ram Exter TR0 ;detenemos el Timer0 (stop Timer0 durante PROG

PON_20: POP POP POP acter del mensaje) POP POP POP SETB RET 04H 05H DPL DPH 01H 00H TR0 ;Desempilamos R4 ;Desempilamos R5 ;desempilamos el DPTR (apunta al 1er car ;Desempilamos R1 ;Desempilamos R0 ;Ponemos en marcha Timer0

;******************************************************************************* ************************* ; Rutina: PON_CAD ; Esta Rutina muestra en modo NORMAL el mensaje guardado en la direccin de la mem oria de programas a; puntada por el DPTR. Usamos esta Rutina para mostrar Mensajes de Error o Warni ngs. ;******************************************************************************* ************************* PON_CAD: PUSH ACC CLR STATIC ;ASTRA genera Trama normal (para 16 carac teres) SETB WARNING ;El mensaje est grabado en EPROM CALL ASTRA MOV R7,#VIDEO_H MOV R6,#VIDEO_L MOV SALTO,#00 ;PON_CAD no muestra mensajes con Cdigo "Z" CALL PONVI CLR WARNING POP ACC RET

;******************************************************************************* ************************* ; Nombre : ASTRA ; R0 : No se utiliza ; R1 : Cuenta bits tiles por caracter (6) ; R2 : Bits por byte ; R3 : Contador de filas ;******************************************************************************* ************************* ; ; Esta rutina transforma la cadena ASCII del mensaje en la "trama" de bits corres pondiente que, volca- ; da sobre la ZVI (por medio de PONVI) permite su salida (en serie) por el pin P3 .3 usando la Rutina ; de Interrupcin del Timer0 (INT_TIM0). ; Una cosa a tener en cuenta es que ASTRA genera la Trama de bits del mensaje com pleto, an si este ; tiene cdigo de efecto "Z"; en este caso el Mensaje puede tener como mximo FFH (25 6) caracteres, lo ; que da como resultado que la trama del mismo ocupa 256 x 5.25 = 1344 bytes, est o entra perfectamente ; en la Zona Video RAM EXT. puesto que la capacidad de sta es de 5FFH (1535) bytes . ; ; R0 : Contador de caracteres procesados (se usa cuando se est en modo PROGRAM)

; ; ; ; ; ; ;

R1 : Contar el nmero de bits tiles de la trama (6) R2 : Cuenta el nmero de bits por byte que se van procesando R3 : Control del nmero de fila o lnea R4 : Registro temporal de la trama R5 : Contendr el contenido binario "parcial" del byte R6R7 : Apunta a Video Ram Externa CURSON: Bit que indica si el "caracter" debe estar 1=apagado o 0=encendido PUSH MOV ACC R7,#VIDEO_H R6,#VIDEO_L R3,#0

ASTRA: ;apuntamos a Video (comienzo zona video R ;contador de filas (comenzamos por fila 0 ;guardamos DPTR (recordemos que "en la Ru ;DPTR apuntaba al primer "caracter" del m ;Contador de caracteres de vuelta en 0 ;8 bits por byte ;(3) Si no hay un ERROR en curso usamos M ;(2) Si hay un tratamiento de ERROR en cu ;(1) MOVC porque el mensaje de error est e ;(2) ;(1) leemos caracter del mensaje (ya no e ;guardamos puntero a caracter actual (cuy ;por generar) ;apuntamos a la Tabla de Cdigos de caracte ;7 bytes por cdigo (caracter) - 7 filas x ;A=7*ASCII (7 bytes por cada cdigo ASCII) ;obtenemos el desplazamiento de ASCII (by ;dentro de la Tabla segn la frmula: DPTR=CO ;A<==byte alto de AB ;DPH = byte alto de AB+byte alto del punt am Externa) MOV MOV ) PUSH DPL tina de efectos" PUSH DPH ensaje) FILA: MOV R0,#00 MOV R2,#8 CARACTER: JNB WARNING,$+8 OVX MOV A,#00 rso usamos... MOVC A,@A+DPTR n memoria de cdigo. SJMP $+3 MOVX A,@DPTR s un cdigo de efecto) PUSH DPL a trama estamos PUSH DPH MOV res MOV 5 columnas MUL AB (B=byte alto de AB) ADD A,DPL te bajo de AB + DPL) MOV DPL,A DIGOS=(7*ASCII)+FILA MOV A,B ADD A,DPH MOV DPH,A ero al cdigo ASCII CLR C MOV A,DPL ADD A,R3 MOV DPL,A tero a tabla cdigos) MOV A,DPH ADDC A,#0 MOV DPH,A MOV A,#00 B,#7 DPTR,#CODIGOS

; ;DPL=DPL+R3 (el arrastre queda en C) (pun ;Sumamos el arrastre (carry) al DPH ;DPH=DPH+C (puntero a tabla cdigos)

MOVC A,@A+DPTR ;Tomamos la trama (correspondiente a la f ila R3) ;A continuacin elegiremos el camino a seguir en base al bit STATIC (mensaje esttic o en proceso): JNB STATIC,NO_STAT ;Si STATIC=0 ==> Generamos trama normal ( para 16 caracteres) MOV DPL,R6 ;Apuntamos a VIDEO (en Ram Externa) MOV DPH,R7 MOVX @DPTR,A ;Guardamos la trama en Zona VIDEO Ram Ext erna MOV UDPL,DPL ;Guardamos direccin del ltimo byte almacena do en Zona VIDEO MOV UDPH,DPH INC DPTR ;Apuntamos a la posicin siguiente de VIDEO (prximo byte) MOV R6,DPL ;Guardamos puntero a VIDEO donde se guard ar el siguiente byte MOV R7,DPH POP DPH ;Desempilamos puntero al caracter POP DPL INC DPTR ;Apuntamos al siguiente caracter (zona de mensajes) INC R0 ;Incrementamos contador de caracteres pro cesados CJNE R0,#12,$+5 ;(3) SJMP ULTI_ST ;(2) AJMP CARACTER ;Si el caracter ledo no es "0" generamos l a Trama del mismo ULTI_ST: MOV CDPL,DPL ;Hacemos una copia del DPTR (puntero al lt imo caracter) MOV CDPH,DPH AJMP BYTEFULL ;Seguimos en la parte final de la Rutina NO_STAT: POP DPH ;Recuperamos puntero al caracter (del men saje) POP DPL RL A tes (los cuales se... RL A MOV R4,A 6 bits tiles) MOV R1,#6 SEIS: MOV A,R4 RLC A MOV R4,A MOV A,R5 e llena con 8 bits) RLC A MOV R5,A DJNZ R2,NOCHO a con 6 bits de un... ente) MOV PUSH je) R2,#8 DPL ;8 bits por byte (reponemos contador) ;Guardamos puntero al caracter (del mensa ;Descartamos los 2 bits izquierdos sobran ;... pierden ya que el RL es sin carry) ;Guardamos la trama en R4 (R4 solo tiene ;Aadir los 6 bits a la lnea ;Recuperamos la trama ;Cogemos un bit y lo guardamos en C ;Guardamos trama restante ;Cogemos el byte en proceso de relleno (s ;Le aadimos el bit que estaba en el C ;Guardamos el "parcial" del byte ;Ya se ha completado el byte? (se complet ;... caracter + 2 bits del caracter sigui

PUSH DPH MOV DPL,R6 MOV DPH,R7 MOVX @DPTR,A es) en Zona Video Ram Ext. MOV UDPL,DPL nado en Zona VIDEO MOV UDPH,DPH INC DPTR MOV R6,DPL dar el siguiente byte) MOV R7,DPH POP DPH saje) POP DPL NOCHO: DJNZ R1,SEIS INC DPTR saje) JNB PROGMODE,NOPROG INC R0 procesados MOV A,R0 CJNE A,#16,$+5 ==> leemos caracter SJMP ULTI a que es el ltimo JMP CARACTER

;Recuperamos puntero a VIDEO Ram Externa ;Guardamos Byte (completo con 8 bits util ;Guardamos direccin del ultimo byte almace ;Apuntamos a la posicion siguiente ;Guardamos puntero a Video (donde se guar ;Recuperamos puntero al caracter (del men

;A por otro bit de los 6 de la trama ;Apuntamos al siguiente caracter (del men ;(3) Si estamos en modo PROGRAM ;(1) Incrementamos contador de caracteres ;(1) ;(3) Si no estamos en el caracter Nro 16 ;(2) Si el caracter es el Nro 16 signific ;(2) Generamos trama del caracter

; A continuacin debe tenerse en cuenta que ASTRA genera la trama del mensaje leye ndo un caracter por ; vez, y asi hasta encontrar el "0" (fin de mensaje).Esto es vlido tanto para cdig o efecto "Z" como ; para cualquier otro efecto. NOPROG: JNB WARNING,NO_ERROR ;(3) Si no hay un ERROR en curso usamos M OVX MOV A,#00 ;(2) Si hay un tratamiento de ERROR en cu rso usamos... MOVC A,@A+DPTR ;(1) MOVC porque el mensaje de error est e n memoria de cdigo. SJMP $+3 ;(2) NO_ERROR: MOVX A,@DPTR ;(1) Leemos caracter del mensaje JZ ULTI ;(2) Si es el caracter "0", entonces es e l ltimo. JMP CARACTER ;Si no es el caracter "0" generamos la Tr ama ULTI: MOV CDPL,DPL ;Hacemos una copia del DPTR (puntero al c aracter del mensaje) MOV CDPH,DPH ; En este punto, puede ocurrir que el ltimo byte no est completo (R2 no es igual a 8), en este caso ; debemos completar (con "1") y guardar el byte incompleto y actualizar los valo res de UCPL y UCPH. CLR C MOV A,#8 SUBB A,R2 MOV B,A ;Guardamos en B la cantidad de espacios v acos del byte

JZ YTEFULL PUSH je)

BYTEFULL DPL

;El byte est completo (R2=8) ==> Vamos a B ;guardamos puntero al caracter (del mensa

PUSH DPH MOV DPL,R6 ;recuperamos puntero a VIDEO Ram Externa MOV DPH,R7 MOV A,R5 ;Recuperamos "parcial" del byte de trama ;Ahora vamos a rellenar con "unos" las B columnas vacas a la SX del byte de trama : UNO_MAS: SETB C RLC A DJNZ B,UNO_MAS MOVX @DPTR,A ;guardamos Byte Rellenado con B "unos" en Zona Video Ram Ext. MOV UDPL,DPL ;Guardamos direccin del ultimo byte almace nado en Zona VIDEO MOV UDPH,DPH INC DPTR ;apuntamos a la posicion siguiente MOV R6,DPL ;guardamos puntero a Video (donde se guar dar el siguiente byte) MOV R7,DPH POP DPH ;recuperamos puntero al caracter (del men saje) POP DPL BYTEFULL: INC R3 ;incrementamos contador de Filas POP DPH ;Recuperamos puntero al mensaje (1er cara cter). El puntero al POP DPL ;ultimo caracter qued guardado en CDPL y C DPH PUSH DPL ;Guardamos puntero al mensaje (1er caract er) PUSH DPH CJNE R3,#7,$+5 ;(3) A por otra fila (si no es la septima ) SJMP $+5 ;(2) LJMP FILA ;(3) POP POP POP RET DPH DPL ACC ;Recuperamos puntero al 1er caracter

;******************************************************************************* *********************** ; Nombre : LIMPIA ; R7R6 : Origen (en vez de R7R6 usamos directamente el DPTR o sea antes de llama r ; a LIMPIA se hizo: MOV DPTR,#CVIDEO) ; R3 : Nro de bytes a mover ;******************************************************************************* *********************** ; Esta rutina rellena con el valor del ACC, a partir de la direccin indicada ; en R7R6, en Nro de veces indicado en R3 LIMPIA: MOVX INC DJNZ @DPTR,A DPTR R3,LIMPIA ;Escribimos caracter 0FFH en CVIDEO ;Apuntamos a la direccion siguiente ;A por otro caracter

RET ;******************************************************************************* *********************** ; Nombre : MOVER ; R7R6 : Origen ; R5R4 : Destino ; R3 : Nro de Bytes a mover ;******************************************************************************* *********************** ; Esta Rutina copia una zona de Ram Externa a otra MOVER: MOV MOV MOVX INC MOV MOV MOV MOV MOVX INC MOV MOV DJNZ RET DPH,R7 DPL,R6 A,@DPTR DPTR R7,DPH R6,DPL DPH,R5 DPL,R4 @DPTR,A DPTR R5,DPH R4,DPL R3,MOVER ;Apuntamos a ORIGEN de VIDEO ;leemos caracter ;incrementamos apuntador a origen ;guardamos direccin origen incrementada ;apuntamos a DESTINO (o sea CVIDEO) ;Copiamos caracter ;Incrementamos apuntador a destino ;guardamos direccion destino incrementada ;A por otro caracter

;******************************************************************************* *********************** ; MACRO lneaS ; ; R7R6 : Apunta a VIDEO en Ram Externa ; R5R4 : Apunta a CVIDEO en Ram Externa ; R3 : Nro de Lneas a copiar ;******************************************************************************* *********************** ; ; Permite copiar: Desde VIDEO a partir de la lnea indicada en G1 ; Sobre CVIDEO a partir de la lnea indicada en G2 ; El nmero de lneas indicado en G3 ; ; Cada vez que se escribe el nombre de la MACRO, todas estas lneas se in; sertan en el programa y, los G1, G2 y G3, son sustituidos por los nmeros ; que coloquemos tras el nombre de la MACRO. ; lneaS MACRO G1,G2,G3 MOV R7,#VIDEO_H ;Apuntamos a VIDEO (byte alto) MOV R6,#G1*0CH ;Porque hay 12 bytes por lnea (en Zona VID EO Ram Externa) MOV MOV DEO Ram Externa) MOV CALL MOV MOV R5,#CVIDEO_H R4,#G2*0CH R3,#G3*0CH MOVER R7,#CVIDEO_H R6,#CVIDEO_L ;Apuntamos a CVIDEO ;Porque hay 12 bytes por lnea (en Zona CVI ;R3 Nro de lneas a copiar ;Mueve las lneas ;con R7R6 apuntamos a zona CVIDEO

CALL ) ENDM

PONVI

;Mueve datos (bytes) desde CVIDEO a ZVI ;Invocacion MACRO DIEZ_MSG (VECES=parmetro

DIEZ_MSG VECES

;******************************************************************************* *********************** ; Comienzo de las Rutinas de Efectos ;******************************************************************************* *********************** ; ;******************************************************************************* *********************** ; Efecto : Visualiza el mensaje ; Nombre : NORMAL ; Cdigo : 'N' ;******************************************************************************* *********************** NORMAL: MOV DPL,CDPL ;recuperamos direccion del mensaje MOV DPH,CDPH INC DPTR ;Apunta al byte de TIEMPO (2do byte) CLR C MOVX A,@DPTR ;Leemos el valor del 2do byte SUBB A,#30H MOV B,#5 MUL AB MOV TIEMPO,A ;Guardamos el valor en TIEMPO INC DPTR ;Apunta al byte de VECES (3er byte) MOVX A,@DPTR ;Leemos el 3er byte SUBB A,#30H ;Restamos 30H y lo que queda es el Nro de VECES MOV VECES,A ;lo guardamos en VECES (aunque no lo usem os) INC DPTR ;Incrementamos el DPTR (ahora apunta al 1 er caracter del mensaje) ;A continuacin si el Mensaje es de HORA o FECHA (VERHORA=1) debemos saltar un esp acio ms: JNB VERHORA,NO_RTC INC DPTR NO_RTC: SETB STATIC ;Activamos flag de mensaje esttico en proc eso CALL ASTRA ;Genera la trama de bits MOV SALTO,#0 ;Como estamos en una rutina de efecto NO "Z" ==> SALTO=1 ;Ahora vamos a copiar en CVIDEO todos los bytes de trama que estn en VIDEO: MOV R7,#VIDEO_H ;Apuntamos al comienzo de zona video Ram Externa, esta... MOV R6,#VIDEO_L ;... zona contiene la trama de bits del m ensaje. MOV R4,#CVIDEO_L MOV R5,#CVIDEO_H MOV R3,#84 CALL MOVER ;Copiamos en CVIDEO todos los bytes de tr ama que hay en VIDEO ;A continuacin desplazaremos toda la trama de CVIDEO, una columna a la derecha: MOV DPL,#CVIDEO_L ;Apuntamos al orgen de CVIDEO

MOV MOV NOR_10: MOV SETB NOR_20: MOVX a pasada) RRC MOVX icin

DPH,#CVIDEO_H R2,#7 R4,#12 C A,@DPTR A @DPTR,A

;Cantidad de filas a desplazar ;Ponemos un 1 en el Carry ;Leemos ltimo byte de la fila (si es la 1r ;Lo rotamos a la izquierda con Carry ;Guardamos el byte rotado en la misma pos

INC DPL ;Incrementamos el DPTR DJNZ R4,NOR_20 DJNZ R2,NOR_10 ;Decrementamos contador de filas rotadas ;En este punto la trama de CVIDEO est desplazada una columna a la derecha MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de Temporizacin alcanzada desactivad o SETB TR2 ;Arrancamos Timer 2 NOR_05: MOV R7,#VIDEO_H MOV R6,#VIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona VID EO Ram Externa a la ZVI DOS5_MSG VECES ;Velocidad (frecuencia) de la vibracin ;En este punto debemos desplazar una columna a la DX a toda la trama guardada en VIDEO, para hacerlo, ;1ro apuntamos al orgen de VIDEO y luego comenzamos el RRC hasta el ltimo byte de trama de VIDEO: MOV R7,#CVIDEO_H MOV R6,#CVIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI DOS5_MSG VECES ;Velocidad (frecuencia) de la vibracin JB T2_FL,NOR_30 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP NOR_05 NOR_30: ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje. CLR STATIC ;Borramos flag de mensaje esttico en proce so CLR TR2 ;Stop Timer 2 MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR ;ahora el DPTR apunta al mensaje siguient e ;ahora el PC (Program Counter) vuelve al lugar siguiente desde donde se llam (CAL L) a la Rutina LLAMA RET ;******************************************************************************* *********************** ; Efecto: Visualiza el Mensaje desplazndolo continuamente hacia la Izquierda ; Nombre: DESPLAZA ; Cdigo: 'Z' ; R0 : Cantidad de caracteres del mensaje

; R1 : Longitud total en bytes de cada lnea de Trama (usado para lazo DESPL_10) ( R1=R4) ; R2 : Contador de filas rotadas ; R3 : Contador de bits por byte (total de columnas a desplazar = R3 x R1) ; R4 : Longitud total en bytes de cada lnea de trama (usado para lazo DESPL_15) ( R4=R1) ; SALTO: ;******************************************************************************* *********************** ; ; Al mensaje con cdigo Z se lo escribe normalmente como a los de otros efectos, so lo que este no tie- ; ne lmite en la cantidad de caracteres. Una vez que el mensaje est escrito ASTRA t raduce el mismo a ; la trama de puntos correspondientes, luego PONVI copia en RAM INTERNA (ZVI) la trama situada en RAM ; EXTERNA (tomando grupos de 16 caracteres). Por ltimo la Rutina Interrup. del Tim er 0 (INT_TIMER 0) ; va sacando afuera lnea por lnea hasta sacar las 7 lneas. ; Para que el mensaje se desplace la rutina "Z" debe ir desplazando la Trama de a una columna a la vez ; y llamando a PONVI (despus de cada desplazamiento) y asi hasta desplazar todo el mensaje. ; el Mensaje se desplace 8 caracteres (si el letrero tiene 16 caracteres), luego llamar nuevamente a ; ASTRA generar la trama de otros 24 caracteres llamar nuevamente a PONVI y asi s ucesivamente. ; DESPLAZA: MOV MOV INC MOVX aje) SUBB MOV INC nsaje) MOVX MOV INC nsaje PUSH TRA PUSH DPH ; Ahora calculamos la cantidad de caracteres del mensaje (tener en cuenta que cu alquier mensaje ; debe terminar siempre con el cdigo 0, esto hace que ASTRA no busque mscaracteres y retorne ; al lugar desde donde se la llam) CLR BASTA ;Flag que indica que ya no quedan bytes e n VIDEO para ser tras;ladados a CVIDEO para su posterior despl azamiento a la SX (RLC) MOV R0,#0H ;Cuenta los caracteres del mensaje DESPL_05: MOVX A,@DPTR ;Leemos el caracter del mensaje JZ DESPL_10 ;(2) Si el caracter ledo es 0 ==> encontra DPL ;Nos har falta este valor para llamar a AS A,@DPTR VECES,A DPTR ;Leemos el valor del 3er byte ;Lo guardamos en VECES ;Apuntamos ahora al 1er "caracter" del me A,#30H TIEMPO,A DPTR ; ;guarda el valor leido en TIEMPO ;Apunta al byte de VECES (3er byte del me DPL,CDPL DPH,CDPH DPTR A,@DPTR ;apunta al byte de TIEMPO ;lee el byte de TIEMPO (2do byte del mens

mos R0 y continuamos INC DPTR INC R0 es del mensaje SJMP DESPL_05 "0" DESPL_10: ;Ac hace falta una porcin de cdigo l mensaje sea ;igual a 16 caracteres. POP DPH POP DPL CJNE R0,#12,DESPL_15 CALL IZQUIERDA RET DESPL_15: PUSH 00H SETB ZCODE CALL ASTRA d del mensaje.

;(1) ;(1) En R0 quedan la cantidad de caracter ;(2) Ciclamos hasta encontrar el caracter para el caso en que la cantidad de caracteres de

;Genera la trama de bits para la totalida

; La cantidad de memoria de Video Ram Externa que se ocupar con la Trama depender de la cantidad de ; caracteres del mensaje (recordar que la cantidad Mxima es de 3+248+1=252 caract eres) ; NOTA: Tener en cuenta que ASTRA pasa la direccin del ltimo caracter (0) ledo desd e la Zona de Men; sajes, en los registros CDPL y CDPH; por lo tanto si incrementamos una vez el DPTR apuntaremos al 1er ; caracter del mensaje siguiente. ; La longitud en bytes de cada lnea de la Trama es: Nro Bytes = R1 = (R0*6)/8 POP 00H MOV B,#8H MOV A,R0 DIV AB ;(R0/8) Cociente queda en A y el resto en B PUSH 0F0H ;Empilamos el Registro B (0F0H) (el resto queda aqui) MOV B,#6H MUL AB ;Byte bajo del producto en A, byte alto e n B (pero B=0) MOV R1,A ;Parcial de la dist. desde el 1er caracte r hasta el ;ltimo caracter de la lnea. ;Ahora hacemos el clculo de los bytes que faltan (porque qued el resto en B) MOV A,#6H POP 0F0H ;(desempilamos B) Nmero de caracteres que quedaron como resto MUL AB ;Nmero de columnas: solo hay byte bajo o s ea A (pues B<8) MOV B,#8H DIV AB ;Si B=0 en A quedan los bytes de Trama qu e hay que sumar a R1 ;para obtener la Distancia Total en bytes entre VIDEO y el ltimo caracter de la f ila correspondiente. ;Pero si B no es igual a 0 entonces se debe aumentar un Byte msde Trama (el cual quedar incompleto) PUSH ACC ;Empilamos ACC para usarlo luego...

MOV r)... JZ POP ilamos A y INC SJMP POP ADD d Total" MOV ila de Trama

A,B $+7 ACC A $+4 ACC A,R1 R5,A

;Tomamos el resto B (de la divisin anterio ;(2) Si B=0 ==> ADD A,R1 - pero... ;(2) Si B no es igual a 0 entonces desemp ;(1) lo incrementamos, luego... ;(2) ;(2) ;Lo sumamos a R1 para obtener la "Longitu ;R5 = Longitud "total" en bytes de cada f

; Ahora vamos a calcular DELTA que es la cantidad de bytes que se deben "saltar" para pasar de una fila ; de trama a otra cuando PONVI est copiando la trama desde RAM EXT. a la ZVI. MOV A,R5 ;Cargamos R5 en el ACC SUBB A,#12 ;Hacemos la resta R5-12=SALTO MOV DELTA,A ;Colocamos el resultado en la variable DE LTA ; Ahora vamos a llenar con "1" la Zona de CVIDEO que ocupar la trama, esta zona t endr 13 bytes por ; fila, o sea 13x7=91 bytes:; columna en columna hasta desplazar un byte (o sea 8 columnas) MOV A,#0FFH ;Llenaremos los 1ros 91 bytes de CVIDEO c on "unos" (7x13=9) MOV R3,#91 ;Cantidad de bytes de CVIDEO a rellenar c on "1" MOV DPTR,#CVIDEO ;Apuntamos al orgen de CVIDEO CLEAN2: MOVX @DPTR,A INC DPTR DJNZ R3,CLEAN2 ;Ahora necesitamos apuntar el DPTR al (orgen-1) de VIDEO, y (R0,R1) al byte Nro 1 3 de la 1ra fila de ;la Zona CVIDEO: MOV DPTR,#VIDEO DEC DPL ;Decrementamos el DPTR porque al leer el 1er byte desde... DEC DPH ;...Zona VIDEO tenemos una instruccin INC DPTR CLR C MOV A,#CVIDEO_L ADD A,#12 MOV R0,A MOV R1,#CVIDEO_H ;En este punto tenemos al DPTR apuntando al byte anterior a VIDEO y a (R0,R1) ap untando al byte Nro 13 ;de la 1ra Fila de CVIDEO. Ahora debemos trasladar un byte de cada Fila de VIDEO a los ltimos lugares ;de cada Fila de CVIDEO, como comenzamos apuntando al byte Nro 13 nos quedan 7 s altos hacia adelante. DESPL_20: MOV te por fila) INC ila de VIDEO PUSH ectura en VIDEO) DPL ;Empilamos DPL (lo usaremos en la prxima l DPTR ;Apuntamos al 1er byte no ledo de la 1ra f R3,#7 ;Contador de filas (debemos agregar un by

PUSH DPH ;Empilamos DPH (lo usaremos en la prxima l ectura en VIDEO) PUSH 00H PUSH 01H DESPL_30: MOVX A,@DPTR ;Leemos byte de Trama desde VIDEO PUSH DPL ;Empilamos valor de DPTR (puntero al ltimo byte de VIDEO) PUSH DPH MOV DPL,R0 MOV DPH,R1 MOVX @DPTR,A ;Escribimos (trasladamos) el byte de Tram a a CVIDEO ;Ahora debemos apuntar al siguiente byte de trama en VIDEO que vamos a trasladar a CVIDEO y este byte ;se encuentra (12+DELTA) bytes msadelante en VIDEO: POP DPH ;Desempilamos valor de DPTR (puntero al lt imo byte de VIDEO) POP DPL CLR C MOV A,DPL ADD A,DELTA ;Saltamos DELTA bytes adelante JNC $+4 ;(2) Si C no es "1" ==> No incrementamos DPH INC DPH ;(2) Si C=1 ==> Incrementamos DPH CLR C ADD A,#12 ;Saltamos 12 bytes adelante MOV DPL,A ;Apuntamos al siguiente byte de trama de VIDEO JNC DESPL_35 ;(2) Si C no es "1" ==> No incrementamos DPH INC DPH ;(2) Si C=1 ==> Incrementamos DPH DESPL_35: CLR C MOV A,R0 ADD A,#13 ;R0=R0+13 para pasar a la siguiente fila en CVIDEO MOV R0,A ;Nuevo valor para R0 DJNZ R3,DESPL_30 ;A continuacin tenemos que verificar que la cantidad de bytes de trama en VIDEO q ue faltan trasladar a ;CVIDEO (R5) no sea "0", si lo es significa que estamos al final y solo falta de splazar lo que queda en ;CVIDEO (hasta que desaparezca todo el mensaje) DJNZ R5,DESPL_40 ;Si R5 no es "0" seguimos hasta que lo se a MOV R5,#13 SETB BASTA ;Comenzamos el desplazamiento por el ltimo byte de la ltima Fila de CVIDEO, para a puntar al ltimo ;byte de trama de CVIDEO debemos decrementar 13 bytes a R0 (R1 lo ignoramos pues siempre R0<0FFH): DESPL_40: CLR C MOV A,R0 SUBB A,#13 ;Volvemos 13 bytes atrs en CVIDEO MOV R0,A ;Actualizamos R0 MOV R3,#8 ;Nro de bits por byte (Nro de columnas a desplazar) DESPL_45: MOV DPH,R1 ;Apuntamos al Final (ltimo byte (Nro 13) d

e la ltima fila)... MOV DPL,R0 ;... de la Zona CVIDEO en Ram Externa MOV R2,#7 ;Contador de filas rotadas DESPL_50: MOV R4,#13 SETB C ;Ponemos un 1 en el Carry DESPL_55: MOVX A,@DPTR ;Leemos ltimo byte de la fila (si es la 1r a pasada) RLC A ;Lo rotamos a la izquierda con Carry MOVX @DPTR,A ;Guardamos el byte rotado en la misma pos icin PUSH PSW ;Empilamos PSW (para resguardar el Carry "C") DEC DPL ;Decrementamos el DPTR MOV A,DPL CJNE A,#0FFH,$+5 ;(3) Si DPL no es igual a 0FFH ==> No dec rementamos DPH DEC DPH ;(2) Si DPL=0FFH ==> Decrementamos DPH POP PSW DJNZ R4,DESPL_55 DJNZ R2,DESPL_50 ;Decrementamos contador de filas rotadas ;En este punto tenemos una visualizacin completa para ser pasada a ZVI y luego vi sualizada, como la ;porcin de Trama se encuentra en CVIDEO, entonces llamamos a PONVI apuntando a CV IDEO con R6 y R7: MOV SALTO,#1 ;Porque cada fila de Trama en CVIDEO tien e 13 bytes MOV R7,#CVIDEO_H ;apuntamos al comienzo de zona video Ram Externa, esta MOV R6,#CVIDEO_L ;zona contiene la trama de bits del mensa je. CALL PONVI ;pasa los datos (bytes) desde la zona vid eo Ram Externa a la ZVI DOS5_MSG TIEMPO ;TIEMPO = Parmetro Macro DOS5_MSG (Velocid ad de desplazamiento) ; La cantidad de veces que se debe repetir este ciclo es igual a la cantidad tot al de bytes de tra; ma de una fila por 8 (cantidad de bits por c/byte de trama) DJNZ R3,DESPL_45 ;Decrementamos R3 (originalmente con valo r 8) JNB BASTA,DESPL_60 ;An quedan bytes en VIDEO para se traslada dos a CVIDEO MOV R3,#8 ;Recargamos R3 (para desplazar un byte ms) DJNZ R5,DESPL_45 ;Ciclamos hasta desplazar todos los bytes que quedan en CVIDEO ;En este punto ya se desplaz toda la Trama que quedaba en CVIDEO ==> Terminamos: POP 01H ;Desempilamos R1 (Banco 0) POP 00H ;Desempilamos R0 (Banco 0) POP DPH ;Desempilamos DPH (apunta al ltimo byte de VIDEO) POP DPL ;Desempilamos DPL (apunta al ltimo byte de VIDEO) SJMP DESPL_70 DESPL_60: POP 01H ;Desempilamos R1 (Banco 0) POP 00H ;Desempilamos R0 (Banco 0) POP DPH ;Desempilamos DPH (apunta al ltimo byte de VIDEO)

POP VIDEO)

DPL

;Desempilamos DPL (apunta al ltimo byte de

AJMP DESPL_20 ;Vamos por el prximo byte de la 1ra fila d e VIDEO ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje, por lo tanto ... DESPL_70: MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR ;ahora el DPTR apunta al mensaje siguient e CLR ZCODE RET ;******************************************************************************* ************************* ;Efecto: Visualiza el Mensaje haci ndolo aparecer como una lluvia de puntos ;Nombre: GOTEO ;Cdigo: 'G' ;******************************************************************************* ************************* GOTEO: MOV DPL,CDPL MOV DPH,CDPH INC DPTR ;apunta al byte de TIEMPO MOVX A,@DPTR ;lee el byte de TIEMPO (2do byte del mens aje) CLR C SUBB A,#30H ; MOV B,#5 MUL AB MOV TIEMPO,A ;Temporizacin (Nro de desbordes del TIMER 2) INC DPTR ;apunta al byte de VECES MOVX A,@DPTR ;leemos el 2do byte (VECES) SUBB A,#30H MOV VECES,A ;Velocidad de "goteo" y frecuencia de vib racin del mensaje INC DPTR ;incrementamos DPTR (ahora apunta al 1er caracter del mensaje) SETB STATIC ;Flag de mensaje esttico = 1 (ASTRA genera 84 bytes de trama) CALL ASTRA ;genera la trama de bits ; Debemos recordar que cada lnea de Trama consta de 96 bits (12 bytes) y que la u bicacin de la Trama ; comienza en la Direccin 1A00H de Ram Externa. tambin debemos recordar que CVIDEO comienza en 1900H. ; Lo que tenemos que hacer es apuntar al 1er byte de la 1ra lnea de la Trama, lue go usamos el ACC para ; (con un solo bit puesto a 1) hacer un AND entre ste y el byte de trama apuntado por el DPTR, luego al ; ACC (si no es 0) lo copiamos en una posicin "similar" en la Memoria CVIDEO y ll amamos a PONVI, luego ; lo vamos desplazando de fila en fila (de 12 en 12 bytes) y llamando a PONVI ca da vez, as hasta llegar ; a su lugar definitivo (o sea en la fila que le corresponde, alli deja de bajar el punto). MOV DPTR,#CVIDEO

MOV BARRE: "1" MOV MOVX INC DJNZ MOV 6 y 7) GOTA_10:

R3,#84 ;Llenamos Zona CVIDEO con FFH, o sea con A,#0FFH @DPTR,A DPTR R3,BARRE R2,#00H

;R2=Nro de la fila en proceso (1,2,3,4,5, ;R3 contador de bytes de la fila R2 (para ;R1 es el byte que servir para hacer el A ;Guardamos el Carry "C" que es el "0" rot ;Bits por byte (Nro de Shift Left para R1

MOV R3,#00H cada INC R2 ==> R3=0CH) GOTA_20: MOV R1,#0FFH NL con el byte de Trama CLR C MOV MASK,C ante en el bit MASK MOV DPTR,#VIDEO MOV R5,#08H ) CLR C MOV A,R2 MOV B,#12 MUL AB DEO ADD A,R3 ADD A,DPL ndica R3+(R2x12) MOV DPL,A JNC $+4 INC DPH MOVX A,@DPTR MOV VECES1,A CLR ni la suma MOV DPTR,#CVIDEO MOV A,#7 SUBB A,R2 MOV R4,A ebe saltar hacia abajo hasta la fila correcta. MOV A,#54H CVIDEO para situarse al a hacia atrs R4 veces). ADD A,R3 ADD A,DPL MOV DPL,A JNC $+4 INC DPH GOTA_30: PUSH 04H PUSH DPL PUSH DPH MOV A,R1 MOV C,MASK RRC A C

;A=(R2x12) cantidad de bytes a sumar a VI ;A VIDEO le sumamos el Nro de bytes que i ;Incrementamos DPL en R3 bytes ;(2) Si C=0 no incrementamos DPH ;(2) Si C=1 incrementamos DPH ;Leo byte desde VIDEO Ram Externa ;Guardamos (en R0) el byte de Trama ledo ;Hacemos C=0 para que no afecte la resta

;El carry C no es afectado pues R2<7 ;R4 guarda el valor de las veces que se d ;para llegar desde la 8va fila de CVIDEO ;Nro total de bytes que hay que sumarle a ;comienzo de 8va fila (desde aqui se salt ;Le sumamos los bytes de la lnea ;Sumamos (7*12)+R3 ==> 54H+R3 al DPL ;(2) Si C=0 ==> no incrementamos DPH ;(2) Si C=1 ==> incrementamos DPH ;Empilamos R4=Nro de saltos

;Recuperamos el Carry "C" ;Rotamos el byte "mscara" (el Carry entra

por la izquierda) MOV MASK,C ;Guardamos el Carry en MASK MOV R1,A ;R1 ya est rotado hacia la SX MOV A,VECES1 ;Recuperamos el byte de Trama original ORL A,R1 ;Enmascaramos R0 MOV R0,A ;R0 contiene el byte de Trama con el "0 q ue debe ser "goteado" CJNE A,#0FFH,GOTA_40 ;Si el ACC es distinto de FFH seguimos el proceso de Goteo AJMP GOTA_55 ;Si ACC=0FFH no lo "goteamos" ;En este punto ya tenemos el byte (R0) con un nico bit "1", que es el que deber ba jar de fila en fila, ;por lo tanto debemos empezar colocndolo en la fila superior y luego ir bajando. ; En este punto el DPTR est apuntando al byte R3 de la 8va fila de CVIDEO Ram Ext erna GOTA_40: MOV A,R0 ;Tomamos el byte que va a ser "goteado" MOVX @DPTR,A ;Escribimos el byte "enmascarado" en la n ueva posicin ; En este punto tenemos al byte R3 de la fila R2 en la posicin R3 de la fila 7ma, lo que tenemos que ; hacer entonces es comenzar a bajarlo de fila en fila hasta que se posicione nu evamente en la fila R2 ; aunque de la zona CVIDEO (por supuesto llamando a PONVI antes de cada salto). MOV SALTO,#00 MOV R7,#CVIDEO_H ;apuntamos al comienzo de la zona CVIDEO Ram Externa, esta... MOV R6,#CVIDEO_L ;... zona contiene la trama de bits del m ensaje. CALL PONVI ;pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI ;Introducimos una pequea demora de TIEMPO veces 2.5 milisegundos: DOS5_MSG VECES ;Velocidad de las "goteras" ;Ahora el punto ya estuvo encendido suficiente tiempo y debemos apagarlo para qu e lo encendamos de nuevo ;12 bytes (una fila) msabajo MOV A,#0FFH MOVX @DPTR,A ;Escribimos FFH en la direccin de CVIDEO a puntada por el DPTR ;Ahora tenemos que "bajar" el byte enmascarado una fila msabajo CJNE R4,#01,GOTA_60 ;Si R4 no es igual a 1 ==> Seguimos "gote ando" el byte R0 ;En este punto tenemos al byte enmascarado en la lnea inmediata superior a la def initiva, o sea que el ;prximo paso es bajarlo a su posicin final (que est ahora apuntada por el DPTR): CLR C ;hacemos C=0 para que no afecte la resta MOV A,DPL SUBB A,#12 MOV DPL,A JNC $+4 ;(2) DEC DPH ;(2) MOVX A,@DPTR ;Leemos byte desde CVIDEO (apuntado por e l DPTR) ANL A,R0 ;Hacemos una ANL con R0 MOVX @DPTR,A ;Escribimos nuevamente el byte en CVIDEO ;En este punto el Bit ya fu "goteado" y debemos ir por el prximo bit (hasta gotear los 8 bits del byte) ;Para leer el prximo bit debemos apuntar de vuelta al byte "empilado" al entrar a GOTA_30

GOTA_55:

POP DPH POP DPL POP 04H ;Desempilamos R4=N de saltos pues lo quere mos de vuelta DJNZ R5,GOTA_30 INC R3 CJNE R3,#12,$+5 ;(3) Si no estamos en el byte Nro 12 segu imos ciclando SJMP $+4 ;(2) AJMP GOTA_20 ;(2) INC R2 ;Incrementamos contador de fila en proces o CJNE R2,#7,$+5 ;(3) Si no estamos an en la fila 7 seguimo s ciclando SJMP GOTA_70 ;(2) Ahora el Mensaje se queda esttico dur ante VECES 10s de msg AJMP GOTA_10 GOTA_60: DEC R4 ;Decremento R4 para apuntar a la fila ant erior CLR C ;hacemos C=0 para que no afecte la resta MOV A,DPL SUBB A,#12 MOV DPL,A JNC $+4 ;(2) DEC DPH ;(2) AJMP GOTA_40 GOTA_70: ;Ahora vamos a copiar en VIDEO todos los bytes de trama que estn en CVIDEO: MOV R7,#CVIDEO_H ;Apuntamos al comienzo de zona video Ram Externa, esta... MOV R6,#CVIDEO_L ;... zona contiene la trama de bits del m ensaje. MOV R4,#VIDEO_L MOV R5,#VIDEO_H MOV R3,#84 CALL MOVER ;Copiamos en CVIDEO todos los bytes de tr ama que hay en VIDEO ;A continuacin desplazaremos toda la trama de CVIDEO, una columna a la derecha: MOV DPL,#CVIDEO_L ;Apuntamos al orgen de CVIDEO MOV DPH,#CVIDEO_H MOV R2,#7 ;Cantidad de filas a desplazar GOT_10: MOV R4,#12 SETB C ;Ponemos un 1 en el Carry GOT_20: MOVX A,@DPTR ;Leemos ltimo byte de la fila (si es la 1r a pasada) RRC A ;Lo rotamos a la izquierda con Carry MOVX @DPTR,A ;Guardamos el byte rotado en la misma pos icin INC DPL ;Incrementamos el DPTR DJNZ R4,GOT_20 DJNZ R2,GOT_10 ;Decrementamos contador de filas rotadas ;En este punto la trama de CVIDEO est desplazada una columna a la derecha MOV B,#6 ;velocidad (frecuencia) de la vibracin MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de Temporizacin alcanzada desactivad

o SETB GOT_05: MOV R7,#VIDEO_H MOV R6,#VIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona VID EO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin ;En este punto debemos desplazar una columna a la DX a toda la trama guardada en VIDEO, para hacerlo, ;1ro apuntamos al orgen de VIDEO y luego comenzamos el RRC hasta el ltimo byte de trama de VIDEO: MOV R7,#CVIDEO_H MOV R6,#CVIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin JB T2_FL,GOT_30 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP GOT_05 GOT_30: ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje. CLR STATIC ;Borramos flag de mensaje esttico en proce so CLR TR2 ;Stop Timer 2 MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR RET ;******************************************************************************* ************************* ; Efecto : Visualiza el mensaje deslizando hacia abajo ; Nombre : BAJA ; Cdigo : 'B' ;******************************************************************************* ************************* BAJA: MOV DPL,CDPL ;recupera direccin del mensaje MOV DPH,CDPH INC DPTR ;apunta al byte de tiempo MOVX A,@DPTR ;lee el byte de tiempo (2do byte del mens aje) CLR C SUBB A,#30H ; MOV B,#5 MUL AB MOV TIEMPO,A ;Temporizacin (Nro de desbordes del TIMER 2) INC DPTR ;apunta al byte de VECES MOVX A,@DPTR ;leemos el 2do byte (VECES) SUBB A,#30H MOV VECES,A ;Velocidad desplazamiento y frecuencia de vibracin del mensaje INC DPTR caracter del mensaje) SETB STATIC ;incrementamos DPTR (ahora apunta al 1er ;Flag de mensaje esttico = 1 (ASTRA genera TR2 ;Arrancamos Timer 2

84 bytes de trama) CALL ASTRA

;genera la trama de bits

MOV A,#0FFH ;borramos (rellenamos con unos) MOV R3,#84 ;la MOV DPTR,#CVIDEO ;zona CALL LIMPIA ;CVIDEO (rellenamos los bytes con FF, en total 70 bytes) MOV SALTO,#0 MOV R7,#CVIDEO_H ;apuntamos a CVIDEO con R7R6 MOV R6,#CVIDEO_L CALL PONVI ;copiamos CVIDEO en ZVI (rellenamos ZVI c on unos) MOV R0,#4 DIEZ_MSG R0 ;Esperamos (10xR0) milisegundos aproximad amente ;Ahora tenemos que empezar a "bajar" las 7 lneas del mensaje, empezamos apuntando al orgen de la 7 ;fila de la trama guardada en VIDEO (G1=6),luego trasladamos esta fila (una fila porque G3=1) al orgen ;de CVIDEO y desde aqui PONVI la traslada a ZVI para su visualizacin. A continuac in hacemos lo mismo ;con las 2 ltimas filas de VIDEO, tambin las trasladamos al orgen de CVIDEO y desde alli nuevamente ;PONVI las copia en ZVI y asi sucesivamente. lneaS 6,0,1 ;sale la 1ra lnea (se ve una lnea:7) lneaS 5,0,2 ;la 2da (se ven 2 lneas: 6 y 7) lneaS 4,0,3 ;la 3ra (se ven 3 lneas:5,6,7) lneaS 3,0,4 ;la 4ta (se ven 4 lneas:4,5,6,7) lneaS 2,0,5 ;la 5ta (se ven 5 lneas:3,4,5,6,7) lneaS 1,0,6 ;la 6ta (se ven 6 lneas:2,3,4,5,6,7) lneaS 0,0,7 ;la 7ma (y ltima lnea) (se ven las 7 lneas) ;En este punto tenemos toda la Trama en CVIDEO, ahora haremos que el mensaje se quede esttico y vibran;do; para eso 1ro tenemos que copiar toda la Trama a VIDEO: ;Ahora vamos a copiar en VIDEO todos los bytes de trama que estn en CVIDEO: MOV R7,#CVIDEO_H ;Apuntamos al comienzo de zona video Ram Externa, esta... MOV R6,#CVIDEO_L ;... zona contiene la trama de bits del m ensaje. MOV R4,#VIDEO_L MOV R5,#VIDEO_H MOV R3,#84 CALL MOVER ;Copiamos en CVIDEO todos los bytes de tr ama que hay en VIDEO ;A continuacin desplazaremos toda la trama de CVIDEO, una columna a la derecha: MOV DPL,#CVIDEO_L ;Apuntamos al orgen de CVIDEO MOV DPH,#CVIDEO_H MOV R2,#7 ;Cantidad de filas a desplazar BAJ_10: MOV R4,#12 SETB C ;Ponemos un 1 en el Carry BAJ_20: MOVX A,@DPTR ;Leemos ltimo byte de la fila (si es la 1r a pasada) RRC A ;Lo rotamos a la izquierda con Carry MOVX @DPTR,A ;Guardamos el byte rotado en la misma pos icin INC DPL ;Incrementamos el DPTR DJNZ R4,BAJ_20

DJNZ R2,BAJ_10 ;Decrementamos contador de filas rotadas ;En este punto la trama de CVIDEO est desplazada una columna a la derecha MOV B,#6 ;Velocidad (frecuencia) de la vibracin MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de Temporizacin alcanzada desactivad o SETB TR2 ;Arrancamos Timer 2 BAJ_05: MOV R7,#VIDEO_H MOV R6,#VIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona VID EO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin ;En este punto debemos desplazar una columna a la DX a toda la trama guardada en VIDEO, para hacerlo, ;1ro apuntamos al orgen de VIDEO y luego comenzamos el RRC hasta el ltimo byte de trama de VIDEO: MOV R7,#CVIDEO_H MOV R6,#CVIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin JB T2_FL,BAJ_30 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP BAJ_05 BAJ_30: ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje. CLR STATIC ;Borramos flag de mensaje esttico en proce so CLR TR2 ;Stop Timer 2 MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR RET ;******************************************************************************* *********************** ; Efecto : Visualiza el mensaje deslizando hacia arriba ; Nombre : SUBE ; Cdigo : 'S' ;******************************************************************************* *********************** SUBE: MOV DPL,CDPL ;recupera direccion del mensaje MOV DPH,CDPH INC DPTR ;apunta al byte de TIEMPO CLR C MOVX A,@DPTR ;lee el byte de TIEMPO SUBB A,#30H ; MOV B,#5 MUL AB MOV TIEMPO,A ;Temporizacin (Nro de desbordes del TIMER 2) INC DPTR ;apunta al byte de VECES MOVX A,@DPTR ;leemos el 2do byte (VECES) SUBB A,#30H MOV VECES,A ;Velocidad desplazamiento y frecuencia de

vibracin del mensaje INC ) SETB STATIC 84 bytes de trama) CALL ASTRA ;Flag de mensaje esttico = 1 (ASTRA genera ;genera la TRAMA de bits DPTR ;apuntamos al 3er byte (1er caracter vlido

MOV A,#0FFH ;borramos MOV R3,#84 ;la MOV DPTR,#CVIDEO ;zona CALL LIMPIA ;CVIDEO (llenamos los bytes con FF, en to tal 70 bytes rellenados) MOV SALTO,#0 MOV R7,#CVIDEO_H ;apuntamos a CVIDEO con R7R6 MOV R6,#CVIDEO_L CALL PONVI ;limpiamos el letrero (llenamos ZVI con u nos) MOV R0,#4 DIEZ_MSG R0 ;Esperamos (10 x R0) milisegundos aproxim adamente ;Ahora tenemos que empezar a "subir" el mensaje lnea por lnea, para esto lo que ha cemos es apuntar ;siempre a VIDEO (G1=0) y sacar primero 1 lnea (G3=1) y la ponemos en la 6ta lnea de CVIDEO (G2=6), ;luego 2 lneas (G3=2) y las ponemos en la 5ta lnea de CVIDEO (G2=5), etc. LINEAS 0,6,1 ;sale la 7ma lnea LINEAS 0,5,2 ;sale la 6ta LINEAS 0,4,3 ;sale la 5ta LINEAS 0,3,4 ;sale la 4ta LINEAS 0,2,5 ;sale la 3ra LINEAS 0,1,6 ;sale la 2da LINEAS 0,0,7 ;sale la 1ra ;En este punto tenemos toda la Trama en CVIDEO, ahora haremos que el mensaje se quede esttico y vibran;do; para eso 1ro tenemos que copiar toda la Trama a VIDEO: ;Ahora vamos a copiar en VIDEO todos los bytes de trama que estn en CVIDEO: MOV R7,#CVIDEO_H ;Apuntamos al comienzo de zona video Ram Externa, esta... MOV R6,#CVIDEO_L ;... zona contiene la trama de bits del m ensaje. MOV R4,#VIDEO_L MOV R5,#VIDEO_H MOV R3,#84 CALL MOVER ;Copiamos en CVIDEO todos los bytes de tr ama que hay en VIDEO ;A continuacin desplazaremos toda la trama de CVIDEO, una columna a la derecha: MOV DPL,#CVIDEO_L ;Apuntamos al orgen de CVIDEO MOV DPH,#CVIDEO_H MOV R2,#7 ;Cantidad de filas a desplazar SUB_10: MOV R4,#12 SETB C ;Ponemos un 1 en el Carry SUB_20: MOVX A,@DPTR ;Leemos ltimo byte de la fila (si es la 1r a pasada) RRC A ;Lo rotamos a la izquierda con Carry MOVX @DPTR,A ;Guardamos el byte rotado en la misma pos icin INC DPL ;Incrementamos el DPTR

DJNZ R4,SUB_20 DJNZ R2,SUB_10 ;Decrementamos contador de filas rotadas ;En este punto la trama de CVIDEO est desplazada una columna a la derecha MOV B,#6 ;Velocidad (frecuencia) de la vibracin MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de Temporizacin alcanzada desactivad o SETB TR2 ;Arrancamos Timer 2 SUB_05: MOV R7,#VIDEO_H MOV R6,#VIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona VID EO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin ;En este punto debemos desplazar una columna a la DX a toda la trama guardada en VIDEO, para hacerlo, ;1ro apuntamos al orgen de VIDEO y luego comenzamos el RRC hasta el ltimo byte de trama de VIDEO: MOV R7,#CVIDEO_H MOV R6,#CVIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin JB T2_FL,SUB_30 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP SUB_05 SUB_30: ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje. CLR STATIC ;Borramos flag de mensaje esttico en proce so CLR TR2 ;Stop Timer 2 MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR RET ;******************************************************************************* ******************* ; Efecto : Visualiza el mensaje completo (efecto NORMAL) y lo desliza hacia la i zquierda. ; Nombre : IZQUIERDA ; Cdigo : 'I' ;******************************************************************************* ******************* ; R2 : Nro de puntos horizontales del letrero (12 bytes x 8 = 96 (60H) columnas) ; R1 : Nro de lneas a desplazar ; R0 : Nro de bytes por lnea ; DPTR : apunta a VIDEO IZQUIERDA: MOV MOV INC MOVX SUBB MOV MUL DPL,CDPL DPH,CDPH DPTR A,@DPTR A,#30H B,#5 AB ;recupera direccion del mensaje ;apunta al byte de TIEMPO ;lee el byte de TIEMPO ;

MOV TIEMPO,A INC DPTR MOVX A,@DPTR SUBB A,#30H MOV VECES,A encia de vibracin CLR BASTA para trasladar en VIDEO) INC ) DPTR

;Nmero de "desbordes" del TIMER 2 ;apunta al byte de VECES ;leemos el 2do byte (veces) ;Velocidad desplazamiento mensaje y Frecu ;Reset Flag BASTA (No quedan bytes trama ;apuntamos al 3er byte (1er caracter vlido

SETB STATIC ;Flag de mensaje esttico = 1 (ASTRA genera 84 bytes de trama) CALL ASTRA ;genera la TRAMA de bits (84 bytes de Tra ma = 12 caracteres) MOV A,#0FFH ;Llenaremos los 1ros 91 bytes de CVIDEO c on "unos" (7x13=9) MOV R3,#91 ;Cantidad de bytes de CVIDEO a rellenar c on "1" MOV DPTR,#CVIDEO ;Apuntamos al orgen de CVIDEO CLEAN: MOVX @DPTR,A INC DPTR DJNZ R3,CLEAN ;Ahora necesitamos apuntar el DPTR al (orgen-1) de VIDEO, y (R0,R1) al byte Nro 1 3 de la 1ra fila de ;la Zona CVIDEO: MOV DPTR,#VIDEO DEC DPL ;Decrementamos el DPTR porque al leer el 1er byte desde... DEC DPH ;...Zona VIDEO tenemos una instruccin INC DPTR CLR C MOV A,#CVIDEO_L ADD A,#12 MOV R0,A MOV R1,#CVIDEO_H MOV R5,#12 ;Cantidad bytes/fila de trama de VIDEO qu e faltan pasar a CVIDEO ;En este punto tenemos al DPTR apuntando al 1er byte de VIDEO y a (R0,R1) apunta ndo al byte Nro 13 de ;la 1ra Fila de CVIDEO. Ahora debemos trasladar un byte de cada Fila de VIDEO a los ltimos lugares de ;cada Fila de CVIDEO, como comenzamos apuntando al byte Nro 13 nos quedan 7 salt os hacia adelante para ;llegar al byte Nro 13 de la ltima fila. IZQUI_38: MOV R3,#7 ;Contador de filas (debemos agregar un by te por fila) IZQUI_40: INC DPTR ;Apuntamos al 1er byte no ledo de la 1ra f ila de VIDEO PUSH DPL ;Empilamos DPL (lo usaremos en la prxima l ectura en VIDEO) PUSH DPH ;Empilamos DPH (lo usaremos en la prxima l ectura en VIDEO) PUSH 00H PUSH 01H IZQUI_45: MOVX A,@DPTR ;Leemos byte de Trama desde VIDEO PUSH DPL ;Empilamos valor de DPTR (puntero al ltimo byte de VIDEO)

;Escribimos (trasladamos) el byte de Tram a a CVIDEO ;Ahora debemos apuntar al siguiente byte de trama en VIDEO que vamos a trasladar a CVIDEO y este byte ;se encuentra 12 bytes msadelante en VIDEO: POP DPH ;Desempilamos valor de DPTR (puntero al lt imo byte de VIDEO) POP DPL CLR C MOV A,DPL ADD A,#12 ;Saltamos 12 bytes adelante MOV DPL,A ;Apuntamos al siguiente byte de trama de VIDEO ;Ahora debemos apuntar al siguiente byte de CVIDEO donde copiaremos el byte tras ladado desde VIDEO, el ;citado byte de CVIDEO se encuentra 13 bytes msadelante (en la siguiente fila): IZQUI_48: CLR C MOV A,R0 ADD A,#13 ;R0=R0+13 para pasar a la siguiente fila en CVIDEO MOV R0,A ;Nuevo valor para R0 DJNZ R3,IZQUI_45 ;A continuacin tenemos que verificar que la cantidad de bytes de trama en VIDEO q ue faltan trasladar a ;CVIDEO (R5) no sea "0", si lo es significa que estamos al final y solo falta de splazar lo que queda en ;CVIDEO (hasta que desaparezca todo el mensaje) DJNZ R5,IZQUI_50 ;Si R5 no es "0" seguimos hasta que lo se a MOV R5,#13 ;Cantidad de bytes/fila de Trama de CVIDE O que faltan desplazar SETB BASTA ; Comenzamos el desplazamiento por el ltimo byte de la ltima Fila de CVIDEO, para apuntar al ltimo ; byte de trama de CVIDEO debemos decrementar 13 bytes a R0 (R1 lo ignoramos pue s siempre R0<0FFH): IZQUI_50: CLR C MOV A,R0 SUBB A,#13 ;Volvemos 13 bytes atrs en CVIDEO MOV R0,A ;Actualizamos R0 MOV R3,#8 ;Nro de bits por byte (Nro de columnas a desplazar) IZQUI_55: MOV DPH,R1 ;Apuntamos al Final (ltimo byte (Nro 13) d e la ltima fila)... MOV DPL,R0 ;... de la Zona CVIDEO en Ram Externa MOV R2,#7 ;Contador de filas rotadas IZQUI_60: MOV R4,#13 SETB C ;Ponemos un 1 en el Carry IZQUI_65: MOVX A,@DPTR ;Leemos ltimo byte de la fila (si es la 1r a pasada) RLC A ;Lo rotamos a la izquierda con Carry MOVX @DPTR,A ;Guardamos el byte rotado en la misma pos

PUSH MOV MOV MOVX

DPH DPL,R0 DPH,R1 @DPTR,A

icin DEC DPL ;Decrementamos el DPTR DJNZ R4,IZQUI_65 DJNZ R2,IZQUI_60 ;Decrementamos contador de filas rotadas ;En este punto tenemos una visualizacin completa para ser pasada a ZVI y luego vi sualizada, como la ;porcin de Trama se encuentra en CVIDEO, entonces llamamos a PONVI apuntando a CV IDEO con R6 y R7: MOV SALTO,#1 ;Porque cada fila de Trama en CVIDEO tien e 13 bytes MOV R7,#CVIDEO_H ;apuntamos al comienzo de zona video Ram Externa, esta MOV R6,#CVIDEO_L ;zona contiene la trama de bits del mensa je. CALL PONVI ;pasa los datos (bytes) desde la zona vid eo Ram Externa a la ZVI DOS5_MSG VECES ;VECES = Parmetro de Macro DOS5_MSG (veloc idad desplazamiento) ; La cantidad de veces que se debe repetir este ciclo es igual a la cantidad tot al de bytes de tra; ma de una fila por 8 (cantidad de bits por c/byte de trama) DJNZ R3,IZQUI_55 ;Decrementamos R3 (originalmente con valo r 8) JNB BASTA,IZQUI_68 ;An quedan bytes en VIDEO para se traslada dos a CVIDEO SJMP $+5 ;(2) IZQUI_68: LJMP IZQUI_90 ;(3) ;En este punto ya no quedan bytes en VIDEO para desplazar, solo nos quedan los 1 3 bytes/fila de trama ;en CVIDEO. Entonces en este punto debe detenerse el mensaje por un cierto tiemp o y luego seguir el ;desplazamiento a la izquierda hasta que desaparezca. CJNE R5,#13,IZQUI_69 ;An quedan bytes de Trama en CVIDEO para d esplazar (RLC) SJMP $+5 ;(2) IZQUI_69: LJMP IZQUI_85 ;(3) ;Ahora que el mensaje est centrado en el Letrero, corresponde introducir la "demo ra": ;En este punto tenemos toda la Trama en CVIDEO, ahora haremos que el mensaje se quede esttico y vibran;do; para eso 1ro tenemos que copiar toda la Trama a VIDEO: PUSH 05H ;Lo empilamos pues guarda el Nro de bytes a desplazar MOV R7,#CVIDEO_H ;Apuntamos al comienzo de zona video Ram Externa, esta... MOV R6,#CVIDEO_L ;... zona contiene la trama de bits del m ensaje. MOV R4,#VIDEO_L MOV R5,#VIDEO_H MOV R3,#91 ;Porque son 7 filas de 13 bytes cada una CALL MOVER ;Copiamos en CVIDEO todos los bytes de tr ama que hay en VIDEO POP 05H ;Lo desempilamos (Nro de bytes a desplaza r) ;A continuacin desplazaremos toda la trama de CVIDEO, una columna a la derecha: MOV DPL,#CVIDEO_L ;Apuntamos al orgen de CVIDEO MOV DPH,#CVIDEO_H MOV R2,#7 ;Cantidad de filas a desplazar

IZQUI_70: MOV SETB IZQUI_75: MOVX a pasada) RRC MOVX icin INC DPL ;Incrementamos el DPTR DJNZ R4,IZQUI_75 DJNZ R2,IZQUI_70 ;Decrementamos contador de filas rotadas ;En este punto la trama de CVIDEO est desplazada una columna a la derecha. Ahora viene la "demora": MOV B,#6 ;Velocidad (frecuencia) de la vibracin MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de "Temporizacin Alcanzada" desactiv ado SETB TR2 ;Arrancamos Timer 2 IZQUI_80: MOV SALTO,#1 ;Porque cada fila de Trama en VIDEO tiene 13 bytes MOV R7,#VIDEO_H MOV R6,#VIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona VID EO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin ;En este punto debemos desplazar una columna a la DX a toda la trama guardada en VIDEO, para hacerlo, ;1ro apuntamos al orgen de VIDEO y luego comenzamos el RRC hasta el ltimo byte de trama de VIDEO: MOV SALTO,#1 ;Porque cada fila de Trama en CVIDEO tien e 13 bytes MOV R7,#CVIDEO_H MOV R6,#CVIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin JB T2_FL,IZQUI_85 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP IZQUI_80 ;Ciclamos "demoramos" hasta que el TIMER 2 active el flag T2_FL IZQUI_85: CLR TR2 ;Stop TIMER 2 MOV R3,#8 ;Recargamos R3 (para desplazar un byte ms) DJNZ R5,IZQUI_88 ;Ciclamos hasta desplazar todos los bytes que quedan en CVIDEO SJMP $+5 ;(2) IZQUI_88: LJMP IZQUI_55 ;(3) ;En este punto ya se desplaz toda la Trama que quedaba en CVIDEO ==> Terminamos: POP 01H ;Desempilamos R1 (Banco 0) POP 00H ;Desempilamos R0 (Banco 0) POP DPH ;Desempilamos DPH (apunta al ltimo byte de VIDEO) POP DPL ;Desempilamos DPL (apunta al ltimo byte de VIDEO) SJMP IZQUI_95 IZQUI_90: POP 01H ;Desempilamos R1 (Banco 0) A @DPTR,A ;Lo rotamos a la izquierda con Carry ;Guardamos el byte rotado en la misma pos A,@DPTR ;Leemos ltimo byte de la fila (si es la 1r R4,#13 C ;Ponemos un 1 en el Carry

POP POP VIDEO) POP VIDEO)

00H DPH DPL

;Desempilamos R0 (Banco 0) ;Desempilamos DPH (apunta al ltimo byte de ;Desempilamos DPL (apunta al ltimo byte de

AJMP IZQUI_38 ;Vamos por el prximo byte de la 1ra fila d e VIDEO ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje, por lo tanto ... IZQUI_95: ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje. CLR STATIC ;Borramos flag de mensaje esttico en proce so MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR ;ahora el DPTR apunta al mensaje siguient e RET ;******************************************************************************* ******************* ; Efecto : Visualiza el mensaje y lo borra deslizando hacia la derecha ; Nombre : DERECHA ; Cdigo : 'D' ;******************************************************************************* ******************* ; R2 : Nro de puntos horizontales del letrero (12 bytes x 8 = 96 columnas) ; R1 : Nro de lneas a desplazar (en total son 7 filas) ; R0 : Nro de bytes por lnea ; DPTR: Apunta a VIDEO (primera zona video en RAM externa) DERECHA: MOV MOV INC MOVX SUBB MOV MUL MOV INC MOVX SUBB MOV encia de vibracin CLR rasladar en VIDEO) INC ) SETB 84 bytes de trama) CALL ma = 12 caracteres) MOV on "unos" MOV STATIC ASTRA A,#0FFH R3,#91 ;Flag de mensaje esttico = 1 (ASTRA genera ;genera la TRAMA de bits (84 bytes de Tra ;Llenaremos los 1ros 91 bytes de CVIDEO c ;Cantidad de bytes de CVIDEO a rellenar c DPL,CDPL DPH,CDPH DPTR A,@DPTR A,#30H B,#5 AB TIEMPO,A DPTR A,@DPTR A,#30H VECES,A BASTA DPTR ;recupera direccion del mensaje ;apunta al byte de TIEMPO ;lee el byte de TIEMPO ; ;Nmero de "desbordes" del TIMER 2 ;apunta al byte de VECES ;leemos el 2do byte (VECES) ;Velocidad desplazamiento mensaje y Frecu ;Reset Flag BASTA (No quedan bytes para t ;apuntamos al 3er byte (1er caracter vlido

on "1" MOV CLEAN1: MOVX @DPTR,A INC DPTR DJNZ R3,CLEAN1 ;Ahora necesitamos apuntar el DPTR al (ltimo+1) byte de la ltima fila de trama (VI DEO+85) de VIDEO, y ;(R0,R1) al 1er byte de la ltima fila (CVIDEO+79) de CVIDEO. ;En este caso los bytes que se trasladen desde VIDEO se colocarn en los 1ros luga res de cada ;fila de CVIDEO, luego PONVI har la copia a ZVI a partir del 2do byte (CVIDEO+1) de CVIDEO, el despla;zamiento se har en CVIDEO a la derecha. MOV A,#VIDEO_L ADD A,#84 MOV DPL,A ;El DPTR apunta al byte Nro 85 de VIDEO MOV DPH,#VIDEO_H ;El DPH se mantiene igual. MOV A,#CVIDEO_L ;(R0,R1) Apuntan al 1er byte de la ltima f ila de CVIDEO ADD A,#78 MOV R0,A MOV R1,#CVIDEO_H MOV R5,#12 ;Cantidad bytes/fila de trama de VIDEO qu e faltan pasar a CVIDEO ;En este punto tenemos al DPTR apuntando al byte Nro 85 de VIDEO y a (R0,R1) apu ntando al 1er byte de ;la ltima Fila de CVIDEO. Ahora debemos trasladar un byte de cada Fila de VIDEO a los primeros lugares ;de cada Fila de CVIDEO, como comenzamos apuntando al byte Nro 1 de la ltima fila , nos quedan 7 saltos ;hacia atrs para llegar al 1er byte de la 1ra fila. DEREC_38: MOV R3,#7 ;Contador de filas (debemos agregar un by te por fila) DEREC_40: DEC DPL ;Apuntamos al ltimo byte no ledo de la ltima fila de VIDEO PUSH DPL ;Empilamos DPL (lo usaremos en la prxima l ectura en VIDEO) PUSH DPH ;Empilamos DPH (lo usaremos en la prxima l ectura en VIDEO) PUSH 00H PUSH 01H DEREC_45: MOVX A,@DPTR ;Leemos byte de Trama desde VIDEO PUSH DPL ;Empilamos valor de DPTR (puntero al ltimo byte de VIDEO) PUSH DPH MOV DPL,R0 MOV DPH,R1 MOVX @DPTR,A ;Escribimos (trasladamos) el byte de Tram a a CVIDEO ;Ahora debemos apuntar al siguiente byte de trama en VIDEO que vamos a trasladar a CVIDEO y este byte ;se encuentra 12 bytes msatrs en VIDEO: POP DPH ;Desempilamos valor de DPTR (puntero al lt imo byte de VIDEO) POP DPL CLR C MOV A,DPL SUBB A,#12 ;Saltamos 12 bytes hacia atrs DPTR,#CVIDEO ;Apuntamos al orgen de CVIDEO

MOV DPL,A ;Apuntamos al byte de trama de la fila an terior de VIDEO ;NOTA: DPH no cambia pues la Trama ocupa menos de 0FFH bytes ;Ahora debemos apuntar al siguiente byte de CVIDEO donde copiaremos el byte tras ladado desde VIDEO, el ;citado byte de CVIDEO se encuentra 13 bytes msadelante (en la siguiente fila): DEREC_48: CLR C MOV A,R0 SUBB A,#13 ;R0=R0-13 para pasar a la fila anterior e n CVIDEO MOV R0,A ;Nuevo valor para R0 DJNZ R3,DEREC_45 ;A continuacin tenemos que verificar que la cantidad de bytes de trama en VIDEO q ue faltan trasladar a ;CVIDEO (R5) no sea "0", si lo es significa que estamos al final y solo falta de splazar lo que queda en ;CVIDEO (hasta que desaparezca todo el mensaje) DJNZ R5,DEREC_50 ;Si R5 no es "0" seguimos hasta que lo se a MOV R5,#13 ;Cantidad de bytes/fila de Trama de CVIDE O que faltan desplazar SETB BASTA ;Comenzamos el desplazamiento por el 1er byte de la primera Fila de CVIDEO: DEREC_50: MOV R0,#CVIDEO_L ;Apuntamos al Orgen de la Zona CVIDEO MOV R1,#CVIDEO_H MOV R3,#8 ;Nro de bits por byte (Nro de columnas a desplazar) DEREC_55: MOV DPH,R1 ;Apuntamos al Orgen (primer byte (Nro 1) d e la primera fila)... MOV DPL,R0 ;... de la Zona CVIDEO en Ram Externa MOV R2,#7 ;Contador de filas rotadas DEREC_60: MOV R4,#13 SETB C ;Ponemos un 1 en el Carry DEREC_65: MOVX A,@DPTR ;Leemos primer byte de la fila (si es la 1ra pasada) RRC A ;Lo rotamos a la derecha con Carry MOVX @DPTR,A ;Guardamos el byte rotado en la misma pos icin INC DPL ;Incrementamos el DPTR DJNZ R4,DEREC_65 DJNZ R2,DEREC_60 ;Decrementamos contador de filas rotadas ;En este punto tenemos una visualizacin completa para ser pasada a ZVI y luego vi sualizada, como la ;porcin de Trama se encuentra en CVIDEO, entonces llamamos a PONVI apuntando a CV IDEO con R6 y R7: MOV SALTO,#1 ;Porque cada fila de Trama en CVIDEO tien e 13 bytes MOV R7,#CVIDEO_H ;apuntamos al comienzo de zona video Ram Externa, esta MOV R6,#CVIDEO_L ;zona contiene la trama de bits del mensa je. ;En este punto debemos tener en cuenta que el 1er byte de cada fila de CVIDEO no son visualizados, por ;lo tanto debemos evitar que PONVI copie en ZVI los 7 bytes que son los 1ros (un o de cada fila):

INC VIDEO

R6

;La copia a ZVI ser desde el 2do byte de C ;pasa los datos (bytes) desde la zona vid

CALL PONVI eo Ram Externa a la ZVI

DOS5_MSG VECES ;VECES = Parmetro de Macro DOS5_MSG (veloc idad desplazamiento) ; La cantidad de veces que se debe repetir este ciclo es igual a la cantidad tot al de bytes de tra; ma de una fila por 8 (cantidad de bits por c/byte de trama) DJNZ R3,DEREC_55 ;Decrementamos R3 (originalmente con valo r 8) JNB BASTA,DEREC_68 ;An quedan bytes en VIDEO para se traslada dos a CVIDEO SJMP $+5 ;(2) DEREC_68: LJMP DEREC_90 ;(3) ;En este punto ya no quedan bytes en VIDEO para desplazar, solo nos quedan los 1 3 bytes/fila de trama ;en CVIDEO. Entonces en este punto debe detenerse el mensaje por un cierto tiemp o y luego seguir el ;desplazamiento a la derecha hasta que desaparezca. CJNE R5,#13,DEREC_69 ;An quedan bytes de Trama en CVIDEO para d esplazar (RLC) SJMP $+5 ;(2) DEREC_69: LJMP DEREC_85 ;(3) ;Ahora que el mensaje est centrado en el Letrero, corresponde introducir la "demo ra": ;En este punto tenemos toda la Trama en CVIDEO, ahora haremos que el mensaje se quede esttico y vibran;do; para eso 1ro tenemos que copiar toda la Trama a VIDEO: PUSH 05H ;Lo empilamos pues guarda el Nro de bytes a desplazar MOV R7,#CVIDEO_H ;Apuntamos al comienzo de zona video Ram Externa, esta... MOV R6,#CVIDEO_L ;... zona contiene la trama de bits del m ensaje. MOV R4,#VIDEO_L MOV R5,#VIDEO_H MOV R3,#91 ;Porque son 7 filas de 13 bytes cada una CALL MOVER ;Copiamos en CVIDEO todos los bytes de tr ama que hay en VIDEO POP 05H ;Lo desempilamos (Nro de bytes a desplaza r) ;A continuacin desplazaremos toda la trama de CVIDEO, una columna a la derecha: MOV DPL,#CVIDEO_L ;Apuntamos al orgen de CVIDEO MOV DPH,#CVIDEO_H MOV R2,#7 ;Cantidad de filas a desplazar DEREC_70: MOV R4,#13 SETB C ;Ponemos un 1 en el Carry DEREC_75: MOVX A,@DPTR ;Leemos ltimo byte de la fila (si es la 1r a pasada) RRC A ;Lo rotamos a la izquierda con Carry MOVX @DPTR,A ;Guardamos el byte rotado en la misma pos icin INC DPL ;Incrementamos el DPTR DJNZ R4,DEREC_75 DJNZ R2,DEREC_70 ;Decrementamos contador de filas rotadas

;En este punto la trama de CVIDEO est desplazada una columna a la derecha. Ahora viene la "demora": MOV B,#6 ;Velocidad (frecuencia) de la vibracin MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de "Temporizacin Alcanzada" desactiv ado SETB TR2 ;Arrancamos Timer 2 DEREC_80: MOV SALTO,#1 ;Porque cada fila de Trama en VIDEO tiene 13 bytes MOV R7,#VIDEO_H MOV R6,#VIDEO_L INC R6 ;Porque los 1ros bytes de cada fila no so n de Trama. CALL PONVI ;Pasa los datos (bytes) desde la zona VID EO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin ;En este punto debemos desplazar una columna a la DX a toda la trama guardada en VIDEO, para hacerlo, ;1ro apuntamos al orgen de VIDEO y luego comenzamos el RRC hasta el ltimo byte de trama de VIDEO: MOV SALTO,#1 ;Porque cada fila de Trama en CVIDEO tien e 13 bytes MOV R7,#CVIDEO_H MOV R6,#CVIDEO_L INC R6 ;Porque los 1ros bytes de cada fila no so n de Trama. CALL PONVI ;Pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI DOS5_MSG B ;Velocidad (frecuencia) de la vibracin JB T2_FL,DEREC_85 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP DEREC_80 ;Ciclamos "demoramos" hasta que el TIMER 2 active el flag T2_FL DEREC_85: CLR TR2 ;Stop TIMER 2 MOV R3,#8 ;Recargamos R3 (para desplazar un byte ms) DJNZ R5,DEREC_88 ;Ciclamos hasta desplazar todos los bytes que quedan en CVIDEO SJMP $+5 ;(2) DEREC_88: LJMP DEREC_55 ;(3) ;En este punto ya se desplaz toda la Trama que quedaba en CVIDEO ==> Terminamos: POP 01H ;Desempilamos R1 (Banco 0) POP 00H ;Desempilamos R0 (Banco 0) POP DPH ;Desempilamos DPH (apunta al ltimo byte de VIDEO) POP DPL ;Desempilamos DPL (apunta al ltimo byte de VIDEO) SJMP DEREC_95 DEREC_90: POP 01H ;Desempilamos R1 (Banco 0) POP 00H ;Desempilamos R0 (Banco 0) POP DPH ;Desempilamos DPH (apunta al ltimo byte de VIDEO) POP DPL ;Desempilamos DPL (apunta al ltimo byte de VIDEO) AJMP DEREC_38 ;Vamos por el prximo byte de la 1ra fila d e VIDEO ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del

DPTR apuntando al ; ltimo caracter del mensaje, por lo tanto ... DEREC_95: ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje. CLR STATIC ;Borramos flag de mensaje esttico en proce so CLR TR2 ;Stop Timer 2 MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR ;ahora el DPTR apunta al mensaje siguient e RET ;******************************************************************************* ******************* ; Efecto : Visualiza el mensaje y lo borra, varias veces ; Nombre : PARPADEA ; Cdigo : 'P' ;******************************************************************************* ******************* PARPADEA: MOV DPL,CDPL ;recuperamos direccion del mensaje MOV DPH,CDPH INC DPTR ;Apunta al byte de TIEMPO (2do byte) CLR C MOVX A,@DPTR ;Leemos el valor del 2do byte SUBB A,#30H MOV B,#5 MUL AB MOV TIEMPO,A ;guardamos el valor en TIEMPO INC DPTR ;Apunta al byte de VECES (3er byte) MOVX A,@DPTR ;leemos el 3er byte SUBB A,#30H ;Restamos 30H y lo que queda es el Nro de VECES MOV VECES,A ;lo guardamos en VECES (aunque no lo usem os) INC DPTR ;incrementamos el DPTR (ahora apunta al 1 er caracter del mensaje) SETB eso CALL ASTRA ;genera la trama de bits ;Como estamos en una rutina de efecto NO los bytes de trama que estn en VIDEO: ;Apuntamos al comienzo de zona video Ram ;... zona contiene la trama de bits del m MOV SALTO,#0 "Z" ==> SALTO=0 ;Ahora vamos a copiar en CVIDEO todos MOV R7,#VIDEO_H Externa, esta... MOV R6,#VIDEO_L ensaje. MOV R4,#CVIDEO_L MOV R5,#CVIDEO_H MOV R3,#84 IDEO CALL MOVER ama que hay en VIDEO ;A continuacin desplazaremos toda la MOV DPL,#CVIDEO_L STATIC ;Activamos Flag de mensaje esttico en proc

;Movemos (7x12=84) bytes desde VIDEO a CV ;Copiamos en CVIDEO todos los bytes de tr trama de CVIDEO, una columna a la derecha: ;Apuntamos al orgen de CVIDEO

MOV MOV PAR_10: MOV SETB PAR_15: MOVX a pasada) RRC MOVX icin

DPH,#CVIDEO_H R2,#7 R4,#12 C A,@DPTR A @DPTR,A

;Cantidad de filas a desplazar ;Ponemos un 1 en el Carry ;Leemos ltimo byte de la fila (si es la 1r ;Lo rotamos a la izquierda con Carry ;Guardamos el byte rotado en la misma pos

INC DPL ;Incrementamos el DPTR DJNZ R4,PAR_15 DJNZ R2,PAR_10 ;Decrementamos contador de filas rotadas ;En este punto la trama de CVIDEO est desplazada una columna a la derecha. ;Ahora comenzaremos la oscilacin "vibracin" del mensaje: PAR_20: PUSH VECES ;Empilamos VECES (nmero de parpadeos) MOV VECES,#6 ;Damos un valor fijo a la velocidad (frec uencia) de vibracin MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de Temporizacin alcanzada desactivad o SETB TR2 ;Arrancamos Timer 2 (fija el tiempo que d ura la vibracin) PAR_25: MOV R7,#VIDEO_H MOV R6,#VIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona VID EO Ram Externa a la ZVI DOS5_MSG VECES ;Velocidad (frecuencia) de la vibracin ;Ahora mostramos la trama que se encuentra en CVIDEO (desplazada un columna resp ecto de VIDEO) MOV R7,#CVIDEO_H MOV R6,#CVIDEO_L CALL PONVI ;Pasa los datos (bytes) desde la zona CVI DEO Ram Externa a la ZVI DOS5_MSG VECES ;Velocidad (frecuencia) de la vibracin JB T2_FL,PAR_30 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP PAR_25 ;No se complet la temporizacin (seguimos ci clando) PAR_30: ;Ahora apagaremos el letrero (el tiempo de apagado tambin lo fija el TIMER 2) MOV 16H,TIEMPO ;Cargamos el R6 (Banco 2) con el valor de TIEMPO (demora) CLR T2_FL ;Flag de Temporizacin alcanzada desactivad o CLR TR0 ;Stop Timer0 MOV PORT1,P1 MOV P1,#0 ;Apagamos letrero PAR_35: JB T2_FL,PAR_40 ;Flag activado por el TIMER 2 para termin ar vibracin SJMP PAR_35 ;No se complet la temporizacin (seguimos ci clando) PAR_40: POP VECES ;Desempilamos VECES (cantidad de parpadeo s) SETB TR0 ;Timer0 en marcha

MOV P1,PORT1 ;Encendemos letrero DJNZ VECES,PAR_20 ;Nro de veces a parpadear ; Al final de la Rutina ASTRA guardamos en CDPL y CDPH los bytes bajo y alto del DPTR apuntando al ; ltimo caracter del mensaje. CLR STATIC ;Borramos flag de mensaje esttico en proce so CLR TR2 ;Stop Timer 2 MOV DPL,CDPL ;preparamos el apuntador para que MOV DPH,CDPH ;apunte al mensaje siguiente INC DPTR ;ahora el DPTR apunta al mensaje siguient e RET ;******************************************************************************* ******************* ; Zonas de memoria (En RAM externa) donde se manipula y guarda la informacin ante s de ser ; transferida a la zona de Video en Ram Interna. ; Se declaran 2 zonas de memoria (CVIDEO) y (VIDEO) porque a veces resulta impre scindible tener ; presente el resultado final en todo momento. ;******************************************************************************* ******************* ;******************************************************************************* ******************* ; Las posiciones de memoria correspondientes a la Zona CVIDEO (8 bits por byte) comienzan en 1B00H y ; terminan en 1B54, o sea que CVIDEO tiene una capacidad de memoria de 054H (84) bytes. ;******************************************************************************* ******************* ; El cuadro con las posiciones de memoria no lo dibujamos ya que es muy extenso. XSEG AT (para zona CVIDEO) CVIDEO: DS 54H asta 0FFH bytes. 1900H ;se crea segmento absoluto en RAM externa ;La longitud de este segmento puede ser h

; En realidad el espacio disponible en memoria para la zona CVIDEO es de 0FFH by tes pues comienza ; en 1900H y termina en 19FFH (solo usamos 054H bytes porque esta es la cantidad de bytes necesarios ; para escribir un mensaje de 16 caracteres.(Suponemos un letrero con 16 caracte res) ; NOTA: 54H=84 bytes=16x42/8 ;******************************************************************************* ******************* ; Las posiciones de memoria correspondientes a la Zona VIDEO (8 bits por byte) c omienzan en 1A00H y ; terminan en 1FFF, o sea que VIDEO tiene una capacidad de memoria de 1535 bytes . ;******************************************************************************* ******************* ; El cuadro con las posiciones de memoria no lo dibujamos ya que es muy extenso. XSEG AT 1A00H ;se crea segmento absoluto en RAM externa

(para zona VIDEO) VIDEO: DS 5FFH ytes)

;Longitud del segmento 5FFH (o sea 1535 b

; La capacidad de VIDEO es mucho mayor que la de CVIDEO, en razn de que VIDEO se usa para almacenar ; la Trama de los mensajes con Cdigo 'Z' y estos tienen un lmite mayor en la canti dad de caracteres ; (0FCH = 3+148+1 = 152 caracteres) ;******************************************************************************* *********************** ; A continuacin se define un segmento exclusivo para situar en el los mensajes de error ;******************************************************************************* *********************** CSEG ERROR1: ERROR2: ERROR3: etar Reset ERROR4: Teclado ERROR5: TEXT1: TEXT2: TEXT3: TEXT4: rabamos de TEXT5: TEXT6: TEXT7: HORA_TX: FECHA_TX: ALARM_TX: D_WEEK: DB DB DB DB DB DB DB MONTHS: DB DB DB DB DB DB DB DB DB DB DB DB 'ENE' 'FEB' 'MAR' 'ABR' 'MAY' 'JUN' 'JUL' 'AGO' 'SET' 'OCT' 'NOV' 'DIC' 'DOM' 'LUN' 'MAR' 'MIE' 'JUE' 'VIE' 'SAB' ;Tabla de los meses del ao. DB DB DB DB DB DB DB DB DB nuevo) DB DB DB DB DB DB AT 2800H ;Cdigo de efecto desconocido ;No hay Teclado conectado (TIMEOUT) ;Debe Conectar el Teclado luego apr ;Tx Error: No hay seal ACK desde el ;No hay Mensajes grabados en RAM ;Grabacin en Ram Externa Okey ;Error de Grabacin en Ram Externa ;Exitosa entrada en PROGRAM MODE ;Registros A y B del RTC okey (no g ;Mensaje ;Mensaje ;Mensaje ;Formato ;Formato ;Formato de entrada en Modo RTC de entrada en VERTIME de salida de Modo RTC del mensaje de la Hora del mensaje de la Fecha del mensaje de alarma

'WRONG CODE ERROR',0 'TX ERROR TIMEOUT',0 'TECLADO--->RESET',0 'TX ERROR: NO ACK',0 ' NO TEXT IN RAM ',0 ' GRABACION OKEY ',0 'ERROR GRABACION ',0 'PROGRAM MODE OK ',0 'REGISTROS RTC OK',0 'ENTRAR MODO RTC ',0 'ENTRAR A VERTIME',0 'OUT OF RTC MODE ',0 'N33 HORA 00:00 ',0 'N33 DOM 00 ENE ',0 ' ALARMA 00:00 ',0

;Tabla de los das de la semana

END