Anterior Siguiente Indice

8. Apendice A: Varias Funciones Útiles

8.1 Funciones ASC

Nota: Aunque este documento menciona solo SX, ASC\-> y \->ASC funcionan tanto en la SX como en la GX.

Texto original de Bill Wickes

Codificando Objetos de la HP48 SX en formato ASCII

Mandar un objeto de la HP48 SX a través del correo electrónico puede ser difícil si el objeto no tiene una forma ASCII, como es el caso de los objetos librerías. Hay varios esquemas de codificación disponibles en distintos sistemas de computadoras, pero estos requieren que el transmisor y el receptor tengan computadores similares, o al menos esquemas de codificación/decodificacion compatibles. Los programas listados mas abajo realizan la codificación y descodificación en la HP48 SX directamente, que tiene la ventaja de ser completamente independiente de cualquier computador.

Los programas son normalmente llamados \->ASC y ASC\->. El primero toma un objeto de la pila y lo convierte en un string en que cada nibble del objeto y su suma de verificación es convertida a un carácter entre 0-9 o A-F. (El objeto debe estar en la RAM, de otra manera el error "ROM Object" es devuelto.) Para facilitar la inclusión en cartas de correo electrónico, el string es cortado por caracteres de línea nueva cada 64 caracteres.

ASC\-> es el inverso de \->ASC: toma un string creado por \->ASC y lo convierte de vuelta a un objeto. Cuando transmitas el string codificado, esta seguro de no cambiar el string; ASC\-> usa la suma de verificación codificada en el string para verificar que la descodificación sea correcta. EL error "Invalid String" es devuelto si el objeto resultante no concuerda con el objeto originalmente codificado por \->ASC. Cuando transmitas el string a tu computador, usa el modo de traducción 3 de la HP48 para que así la HP48 convierta cualquier CR/LF de vuelta a LF cuando el string sea bajado posteriormente.

Dos versiones de ASC\-> están incluidas aquí. La primera (P1) esta en lenguaje de usuario de la HP48 (UserRPL), usando SYSEVALs para ejecutar objetos de sistema. P2 es un string, que el programa setup descodifica ocupando P1, creando ASC\->, y después descarta P1. La segunda versión es mas compacta que la primera, y también no se puede editar, por lo que es mas segura (pero no puede ser transmitida en forma ASCII, lo que ayuda a llegar al punto de este ejercicio).

Aquí están los programas, contenidos en un directorio:


%%HP: T(3)A(D)F(.);

DIR

P1              @ ASC\-> Versión 1.

\<<

  IF DUP TYPE 2 \=/

  THEN "Not A String" DOERR

  END RCWS \-> ws

  \<< 16 STWS

    #0 NEWOB SWAP DUP SIZE

    IF DUP 4 <

    THEN DROP SWAP DROP "Invalid String" DOERR

    END

    DUP 65 / IP - 4 - # 18CEAh SYSEVAL

    "" OVER # 61C1Ch SYSEVAL

    SWAP # 6641F8000AF02DCCh

    # 130480679BF8CC0h # 518Ah SYSEVAL

    # 19610313418D7EA4h # 518Ah SYSEVAL

    # 7134147114103123h # 518Ah SYSEVAL

    # 5F6A971131607414h # 518Ah SYSEVAL

    # 12EA1717EA3F130Ch # 518Ah SYSEVAL

    # 280826B3012808F4h # 518Ah SYSEVAL

    # 6B7028080BEE9091h # 518Ah SYSEVAL

    # BE5DC1710610C512h # 518Ah SYSEVAL

    # 705D00003431A078h # 518Ah SYSEVAL

    # 3D8FA26058961431h # 518Ah SYSEVAL

    # 312B0514h # 518Ah SYSEVAL

    # 18F23h SYSEVAL

    DUP BYTES DROP 4 ROLL

    IF ==

    THEN SWAP DROP

    ELSE DROP "Invalid String" DOERR

    END ws STWS

  \>>

\>>



P2      @ ASC\->  Version 2.  To be converted by ASC\-> version 1.



"D9D20D29512BF81D0040D9D20E4A209000000007566074726636508813011920

140007FE30B9F060ED3071040CA1304EC3039916D9D2085230B9F06C2A201200

094E66716C696460235472796E676933A1B21300ED30FD5502C230C1C1632230

CCD20FA0008F14660CC8FB97608403104AE7D814313016913213014117414317

414706131179A6F5C031F3AE7171AE214F8082103B6280821909EEB0808207B6

215C0160171CD5EB870A13430000D50713416985062AF8D341508813044950B9

F06BBF06EFC36B9F0644230C2A201200094E66716C696460235472796E676933

A1B2130B21300373"



P3      @\->ASC.     To be converted by ASC\->.

"D9D20D2951881304495032230FD5502C230A752688130ADB467FE30322306AC3

0CB916E0E30CBD30F6E30C1C1632230CCD20DC0008F14660CC8FB97608403104

AE7D8143130169174147061741431311534AC6B4415141534946908D9B026155

4A6F53131F3AE731A014C161AE215F08082103A6280821939EEC08082170A621

4C161170CD56B870A18503430000D5071351796A9F8D2D02639916D9D2085230

C2A209100025F4D402F426A6563647933A1B2130A2116B213033C0"



SETUP   @Automatic setup program

\<< P2 P1 'ASC\->' STO

    P3 ASC\-> '\->ASC' STO

    { P1 P2 P3 SETUP } PURGE

\>>



END

Instrucciones de instalación:

  1. Edita el texto anterior entre (%%HP...) y (END) en un archivo de texto llamado CONV (por ejemplo). Esta seguro de dejar el string exactamente como esta arriba, con ningún espacio extra o caracteres invisibles al comienzo o final de las líneas.
  2. Pon a la HP48 SX en modo de transferencia ASCII.
  3. Usando Kermit, transmite el archivo de texto CONV a la HP 48, compara su suma de verificación (6C8Ah).
  4. Ejecuta CONV para convertirlo en el directorio actual.
  5. Ejecuta SETUP.
  6. El directorio CONV ahora contiene ASC\-> y \->ASC, listos para usarse.

Para grabar las versiones descodificadas de ASC\-> y \->ASC de vuelta en tu computador, esta seguro de poner a la HP48 SX en modo de transferencia binario antes de la transmisión.

Aviso:

8.2 OBJFIX

Cuando un objeto binario recibido por Kermit en la HP48 es dejado como un string que empieza con HPHP48, OBFIX extraerá el objeto de la HP48 si el único problema es que aparecieron bytes extra al final.

OBJFIX toma un nombre de una variable del nivel 1 de la pila y modifica el contenido de la variable si ningún otro problema se detecta.

Nota: Este programa es parecido a FIXIT de Horn y Heiskanen del Goodies Disk 8, pero este es de HP y por eso supongo que es mas confiable. Aunque falla los casos de prueba incluidos con FIXIT, que pueden ser porque fueron casos artificialmente creados. Prueba ambos en transferencias reales que necesiten arreglo. Cual te gustar mas?

OBJFIX.ASC


%%HP: T(3)A(D)F(.);

"D9D202BA81D9F81B2040D9D20F2A26DA91629C8145126489162C23072C80CCD2

0BD0008FB9760147108134164142C2818F24D534501008B2F41643150D73B840

58405438314A161966D2BF6BF6A6F5BE16314213114334CF8208A6F58F235A04

55136D7D4EA494D231A1CA101110131CA130DBE284F8FC0760D41198F29960D4

130142119EA1408F5E0108D341503223072D70B2130B21301460"

8.3 FIXIT

Texto original de Joe Horn y Mika Heiskanen

PROPÓSITO:

Convierte un string mal transmitido en el objeto original.

TEORÍA:

Un montón de personas transfieren objetos desde la HP48 mal, lo que causa que cuando tu los transfieres a tu calculadora, solo obtienes un string lleno de basura que se ve como esto:


"HPHP48-E#c&r$a%p@!*!..."     [parece familiar, eh?]
Eso es porque ellos transfirieron al computador usando XMODEM, o lograron subirlo de alguna otra manera. El programa FIXIT toma un string como ese y extrae el objeto De la HP48 que ellos originalmente trataron de transmitir al computador (si es posible).

Una extracción de objeto como esta puede ser hecha a mano, pero es muy peligroso. FIXIT minimiza el peligro de borrar la memoria. Revisa si el objeto extraído es un objeto valido, i si no, lo bota de la pila antes de que la HP48 trate de mostrarlo. Todas las malas transferencias que he archivado durante los años han sido arregladas por FIXIT, así como cerca de la mitad de ellas causaron la perdida de memoria cuando las extraje manualmente. Sin embargo, no hay garantía. Úsalo bajo tu responsabilidad.

La extracción actual es efectuada por un "Code Object" escrito por Mika Heiskanen. La "interfaz" en User RPL alrededor de este objeto código es lo que minimiza el peligro de perder la memoria, fue escrita por Joe Horn.

INSTRUCCIONES:

HAZ UNA COPIA DE SEGURIDAD DE TU MEMORIA, solo en caso de que el string contenga una bomba lógica.

Pon la transferencia mala en la pila (ves "HPHP48-..." y ejecuta FIXIT.

Posibles resultados:

EJEMPLOS:

Para hacer los siguientes ejemplos, baja el directorio FIXIT a tu HP48 y entra en el.

FIXIT.ASC

%%HP: T(3)A(D)F(.);

"69A20FF7CE20000000402414442340C2A203B000840584054383D25403A20FF7

2500000000403535947440D9D20E16329C2A2DBBF13013216DF1406A1C42328D

BF193632B213034000407545146540D9D20E163292CF1EFFB1DBBF1EBFB150FA

193632B2130003030303034C000402414441340C2A203B000840584054383D25

469A20FF72500000000403535947440D9D20E16329C2A2DBBF13013216DF1406

A1C42328DBF193632B213034000407545146540D9D20E163292CF1EFFB1DBBF1

EBFB150FA193632B2131313131313134C000407545146540C2A203B000840584

054383D25469A20FF72500000000403535947440D9D20E16329C2A2DBBF13013

216DF1406A1C42328DBF193632B213034000407545146540D9D20E163292CF1E

FFB1DBBF1EBFB150FA193632B2130003030303034C00020849420C2A20570008

40584054383D254D9D20E163284E2050841607079784E20603416D6075627936

32B2130A0BA02D456C616E63686F6C697022416269702BB28000506494859445

50D9D20E16323CE2278BF168BC1ED2A2167E1AFE22D9D203CE2278BF19C2A274

3A2C58C1C2A2031000840584054383D2167E1AFE22D9D2078BF18B9C1DBBF1AA

F028DBF1CCD201200014713717917F137145142164808C5BF22D9D2033920200

0000000005150933A1B21305DF22B21305BF22D9D20339202000000000004150

933A1B21305DF223CE2278BF168BC1D8DC1167E1AFE22D9D203FBF1339202000

000000002770933A1B21305DF223CE2278BF19D1A1DBBF18DBF1E0CF1D5CE1AF

E22D9D208DBF1339202000000000000030933A1B21305DF22CB2A193632B2130

B21303D4F"

8.4 LASTX

La función LASTX es útil en cálculos donde un numero ocurre mas de una vez. Al recuperar un numero usando LASTX, tu no tienes que digitar ese numero en la calculadora de nuevo. Nota sin embargo que LASTX usa la característica del ultimo argumento incorporada, así que si usas LASTX perderás los contenidos de tu LASTARG.

Por ejemplo, calcula:


 96.704 + 52.394706

--------------------

      52.394706



Digitaciones:                   Pila:

-----------------              --------------------

96.704 ENTER                    96.704



52.304706 +                     149.098706



LASTX                           149.098706

                                52.304706



/                               2.84568265351



@ Esta es una versión de LASTX para la HP48

@

%%HP: T(3)A(D)F(.);

\<< DEPTH \-> n

  \<< LASTARG DEPTH n

- DUP \-> s

    \<< ROLLD s 1 -

DROPN

    \>>

  \>>

\>>

8.5 Almacenamiento Compactado de Datos

Texto original de Jim Donnelly

Una técnica simple de codificación de largo puede ser usada por un sistema de almacenamiento de datos de formato libre, varios campos y compacto. Dos pequeños programas, SUBNUM y STRCON están aquí para ayudar el proceso, y están listados cerca del final de esta nota. Al final de esta nota esta un directorio que contiene ejemplos y deberías bajar a tu HP48.

El principio es guardar los índices de partida en el comienzo de un string que apunte a los campos almacenados subsecuentemente en el string. Los índices son guardados según el orden de los campos, con un índice adicional en el final para acomodar el ultimo campo. Hay varios puntos que vale la pena mencionar:

EJEMPLO:


               Índices  |          Campos

Carácter                |     1 11111111 12222222222

Posición :   1  2  3  4 |567890 12345678 90123456789

            +--+--+--+--+------+--------+-----------+

String :    | 5|11|19|30|Campo1| Campo2 |  Campo 3  |

            +--+--+--+--+------+--------+-----------+
Este es un string que contiene 3 campos, y por eso 4 entradas de índices. El primer campo comienza en el carácter 5, el segundo campo empieza en el carácter 11, y el tercer campo comienza en el carácter 19. Para mantener el patrón consistente, nota que el índice para el campo 4 es 30, que es uno mas que el largo del string de datos de 29 caracteres .

para extraer el segundo campo, pon el string en la pila, usa SUBNUM en el carácter 2 para extraer la posición de inicio, usa SUBNUM en el carácter 3 para extraer la (posición de termino+1), sustrae 1 de la (posición de termino+1), después haz un SUB para obtener el campo de datos. NOTA: El índice para el campo 1 esta guardado como el carácter dato 5, NO el string "5"! Para poner el índice de campo para el campo 1 en el string, deberías ejecutar "data" 1 5 CHR REPL.

PROGRAMA:

El siguiente programa acepta un string de datos codificados en el nivel 2 y un numero de campo en el nivel 1:


DESCODIFICA   "datos"  campo#  -->  "campo"



<<  --> f

  <<

    DUP f SUBNUM                ; "data" start -->

    OVER f 1 + SUBNUM           ; "data" start end+1 -->

    1 -                         ; "data" start end -->

    SUB                         ; "field" -->

  >>

>>

CODIFICACIÓN DE DATOS:

El siguiente programa espera una serie de 'n' strings en la pila y los codifica en un string de datos adecuado para ser leído por el primer ejemplo de arriba.

Los programas SUBNUM y STRCON son usados para ensamblar los índices.


CODIFICA      campo n  ...  campo 1   n   -->  "datos"



<< DUP 2 + DUP 1 - STRCON --> n  data

  <<

    1 n

    FOR i

      data i SUBNUM OVER SIZE   ; ... field index fieldsize

      + data SWAP               ; ... field "data" index'

      i 1 + i + SWAP CHR REPL   ; ... field "data"'

      SWAP + 'data' STO         ; ...

    NEXT

    data                        ; "data"

  >>

>>
En este ejemplo, cuatro strings son codificados:

Entrada:  5: "String"

          4: "Str"

          3: "STR"

          2: "STRING"

          1:         4
Salida: "xxxxxSTRINGSTRStrString" (String de 23 caracteres) (Los primeros 5 caracteres tienen códigos 6, 12, 15, 18 y 24)

VARIACIÓN:

La técnica de arriba tiene un limite practico de almacenamiento de hasta 254 caracteres de datos en un string. Para sobrepasar esto, solo asigna dos bytes por cada posición de campo. El código para extraer el índice de inicio es un poco mas complejo. En este caso, el índice es guardado como caracteres en hexadecimal.


               Índices  |          Campos

Carácter                | 11111 11111222 22222223333

Posición :   12 34 56 78|901234 56789012 34567890123

            +--+--+--+--+------+--------+-----------+

String :    |09|0F|17|21|Campo1| Campo2 |  Campo 3  |

            +--+--+--+--+------+--------+-----------+

<<  --> f

  <<

     DUP f 2 * 1 -           ; "data" "data" indx1 -->

     SUBNUM 16 *             ; "data" 16*start_left_byte  -->

     OVER f 2 * SUBNUM +     ; "data" start

     OVER f 2 * 1 + SUBNUM   ; "data" start end_left_byte -->

     16 * 3PICK f 1 + 2 *

     SUBNUM + 1 -            ; "data" start end -->

     SUB                     ; "field"  -->

  >>

>>

DOS PEQUEÑOS PROGRAMAS ÚTILES:


SUBNUM          "string"  posición  -->  código



<< DUP SUB NUM >>

STRCON          código  cuenta  -->  "string repetido"



<< -->  code count

  << "" code CHR 'code' STO

     1 count START code + NEXT

  >>

>>

Soluciones Alternativas al Problema:

Texto original de Matjaz Vencelj <vencelj@fmf.uni-lj.si>

Jim designa dos bytes por cada entrada de índice (para manejar strings mas largos). pero por el otro lado obviamente solo usa valores 00...FF para los pares de los índices, lo que no tiene sentido. El esta en el limite de 16*16 = 255 caracteres de nuevo!

Yo he juntado un conjunto de comandos, que soportan strings de hasta 65Kb, usando índices de dos-bytes.

El codificador (Encode) es un programa en User RPL que llama al binario N2C que convierte el real del nivel 1 en un string de 2 caracteres:


@*** Encode ***

%%HP: T(3)A(R)F(.);

\<<

  IF DUP TYPE 0 = THEN 514 DOERR END

  \-> N

    \<<

    N 1 + 2 * #18CEAh SYSEVAL #45676h SYSEVAL

    1 N FOR I I 2 * 1 - OVER SIZE 1 + N2C REPL SWAP + NEXT

    N 2 * 1 + OVER SIZE 1 + N2C REPL

    \>>

\>>


@*** N2C, cksum=#8919h ***

%%HP: T(3)A(R)F(.);

"D9D202BA812BF819FF30D9D20AEC8111920001007FE3057A50C57463223057A5

0EE250B2130B21307206"

Transfiérelo en modo ASCII con traducción 3, después ejecuta el programa 'Encode' con strings de datos en los niveles 2..n+1 y un real n en el nivel 1 indicando el numero de strings.

El descodificado de string (Decode), en el cual es usualmente la velocidad es critica, esta en el siguiente binario en formato \->ASC :


@*** Decode, cksum=#38E1h ***

%%HP: T(3)A(R)F(.);

"D9D20D8A81D9F811192013000D9D20AEC8113D26CA130F6E30CA130E0E305080

311920001002CE30CAF0650803CBD30CAF06FED30F6E30CA130E0E3050803119

20001002CE30CAF0650803CBD30E0E3033750B2130B21309534"

Toma un string de 'base de datos' del nivel 2 y un real (posición del registro) del nivel 1, después devuelve el substring (registro) apropiado.

8.6 Codigos de la impresora HP82240B

Texto original de Jarno Peschier

Tamaño físico de fila

Una fila impresa tiene 24 caracteres normales, 12 caracteres expandidos o 168 pixeles de ancho. Esto significa que un carácter normal tiene un ancho de 7 pixeles. Cualquier dato que "se caiga de la columna" será truncado e ignorado por la impresora.

Reinicio


ESC 255d
Esto reinicia la impresora al siguiente estado: conjunto de caracteres Roman8 (cuidado: el conjunto de caracteres cuando es encendida es ECMA94), ambos expandidos y con impresión subrayada apagada, buffer borrado.

Auto test


ESC 254d
Esto hace que la impresora imprima un dibujo de auto prueba. Esto consiste principalmente en imprimir el conjunto de caracteres Roman8.

Impresión expandida


ESC 253d
Esto pone el modo de impresión expandida. Esto significa que desde este código todos los caracteres que son impresos, serán impresos con el doble del ancho de un carácter normal, porque cada columna de pixeles es impresa dos veces. No tiene efecto si el modo de impresión expandida ya estaba puesto.


ESC 252d
esto apaga el modo de impresión expandida. Esto significa que desde este código todos los caracteres serán nuevamente impresos con el ancho normal de un carácter. No tiene efecto si el modo de impresión expandida ya estaba apagado.

Impresión subrayada


ESC 251d
Esto enciende el modo de impresión subrayada. Esto significa que desde este código todos los caracteres impresos, serán subrayados, porque el pixel de mas abajo de cada columna ahora esta siempre encendido. No tiene efecto si el modo de impresión subrayada ya estaba encendido.


ESC 250d
Esto apaga el modo de impresión subrayada. Esto significa que desde este código todos los caracteres no son impresos subrayados. El pixel de mas baja de cada columna es impreso como esta definido por el carácter impreso. No tiene efecto si el modo de impresión subrayada ya estaba apagado.

Conjunto de Caracteres


ESC 249d
Esto hace que la calculadora imprima en el conjunto de caracteres ECMA94. Este conjunto es idéntico 100% al conjunto de caracteres usado en las calculadoras HP48. Este es el conjunto de caracteres de impresión por defecto cuando la impresora es encendida. No tiene efecto si ECMA94 es el conjunto de caracteres actual.


ESC 248d
Esto hace que la impresora imprima en con el conjunto de caracteres Roman8. este conjunto es diferente al conjunto de caracteres usados en las calculadoras HP48 en los 128 últimos caracteres. Hasta donde yo se, este conjunto es usado por impresoras antiguas como la HP82240A y por las calculadoras HP28 (de ahí la necesidad del comando OLDPRT si vas a imprimir a una HP82240A). Este conjunto de caracteres es prendido si reinicias la impresora con el código de reinicio. No tiene efecto si Roman8 es el conjunto de caracteres actual.

Gráficos


ESC n datos (con n entre 1 y 247)
Esto hace que la impresora imprima gráficos especificados en datos (un byte por columna de pixeles). El valor n especifica el numero de bytes de datos que siguen al código de la impresora que serán interpretados como datos gráficos. Cualquier dato después de la columna de pixeles 168 será truncada e ignorada.


Anterior Siguiente Indice