Módulos de SMSQ dependientes del idioma

Le Grand Pressigny, FRANCIA - Tony Tebby
(Artículo original: revista “International QL Report” V5i1, Mayo de 1995)
Traducción: Juan José Ruiz Leo - Febrero de 2008

Para ser capaz de distribuir versiones de SMSQ que provean mensajes en más de un idioma y dar soporte a múltiples tipos de teclado, SMSQ usa una estructura uniforme de “módulo dependiente del idioma”.

Por el momento, SMSQ soporta cuatro tipos de módulo dependiente del idioma:

1. tablas de preferencias de idioma,
2. tablas de mensajes,
3. tablas de teclado,
4. tablas de traducción para impresora.

El principio subyacente a la estructura de módulo dependiente del idioma es que cada módulo se identifica por un código: para los principales idiomas soportados éste es el código telefónico internacional (normalmente 1, 33, 44 ó 49). Se pueden añadir nuevos módulos, pero éstos (en el presente) no sustituyen a los módulos existentes. Por esta razón, si vive en el sur de Francia, y desea añadir mensajes en occitano, se recomienda encarecidamente que identifique los mensajes con un código que no sea 33 (por ejemplo 3300).

Cabeceras del Módulo de Idioma

SMSQ crea una tabla de módulos de idioma. Ésta es simplemente una tabla de apuntadores a los módulos individuales. Claramente esto no impone ninguna restricción al tamaño del módulo, pero requiere que cada módulo tenga una cabecera con un formato conocido (definiendo el tipo de módulo y su código de idioma). Además, cada cabecera de módulo incluye un apuntador que enlaza a otra cabecera de módulo de modo que se pueden añadir al sistema muchos módulos en una sola llamada. Finalmente, para proveer la máxima flexibilidad, la cabecera de módulo no está adjunta directamente al módulo, sino que la última palabra larga de la cabecera del módulo es un apuntador relativo al módulo en sí.

El código para incluir una lista de módulos de idioma es bastante simple.

moveq #sms.lldm,d0 clave para incluir
lea lang_mod,a1 apuntador a los módulos a enlazar
trap #1 hacer la llamada a SMSQ
rts
lang_mod los módulos empiezan aquí

Este código se puede escribir en un fichero usando WPUT (use LPUT para mayor eficacia, si lo desea).

WPUT #fch,$7030,$43FA,$0006,$4E41,$4E75

Alternativamente, se puede escribir el código directamente en la memoria del ordenador (útil para hacer pruebas).

POKE_W base,$7030,$43FA,$0006,$4E41,$4E75

Tablas de preferencias de idioma

Las tablas de preferencias de idioma son las más importantes y las más simples. Una tabla de preferencias de idioma es simplemente un nombre de idioma (habitualmente la letra de registro internacional de coches) seguido por una tabla de números de idiomas aceptables en orden decreciente de aceptabilidad.

Esto permite la creación de una variación de un idioma sin la necesidad de definir todas las tablas. Así, para el occitano, el segundo idioma preferido probablemente sería el francés, y, ya que hay un conjunto completo de tablas para el francés, no sería necesario que hubiera más preferencias.

occitan_pref
dc.w 0 es una tabla de preferencias
dc.w 0 siempre cero
dc.w 3300 número de idioma occitano
dc.w next-* apuntador relativo a la siguiente tabla o cero
dc.l occ_pref-* apuntador a la tabla de preferencias
occ_pref
dc.l 'FOC' el occitano es un idioma de Francia
dc.w 3300 occitano es el más aceptable
dc.w 33 francés es el siguiente más aceptable
dc.w 0 ...y ya no hay más

Si la tabla de preferencias se va a escribir en un fichero usando SBASIC, WPUT y BPUT son las rutinas más apropiadas para hacerlo.

WPUT #fch,0,0,3300,0,0,4 la cabecera, sin siguiente, la tabla justo detrás
BPUT #fch,'FOC' el nombre: justificado a la izquierda, relleno de espacios hasta 4 caracteres
WPUT #fch,3300,33,0 los idiomas preferidos

Si esto parece un poco pesado, lo es. El sistema está diseñado para resistir muchos más idiomas de los que seguramente jamás necesite y para permitir añadir dialectos o variaciones personales sin inhibir el acceso a los idiomas estándar. Una vez que haya incluido la nueva tabla de preferencias, puede comprobar si está allí escribiendo LANGUAGE$:

PRINT LANGUAGE$(3300) should print FOC

Tablas de Mensajes

SMSQ/E usa cuatro tablas de mensajes propiamente dichas. Los mensajes están en cuatro grupos. Es posible añadir nuevas tablas de mensajes a estos cuatro grupos para nuevos idiomas. También es posible añadir nuevos grupos de mensajes para los idiomas existentes y para nuevos idiomas. Los desarrolladores de programas no deberían tomar esto a la ligera creando grupos nuevos frívolamente.

Actualmente, los grupos están numerados de 4 en 4 (el grupo 0 es el conjunto de mensajes estándar del viejo QL, el grupo 4 es el conjunto de mensajes de error de sintaxis y de ejecución de SBASIC, etc.). El código de error o de mensaje usado para acceder a un mensaje es:

-(número de mensaje de error + 32 x número de grupo de mensajes)

Los mensajes de un grupo se pueden listar usando REPORT

FOR mens = 1 TO 50: REPORT #n, -(mens + 32 * grup)

Una tabla de mensajes tiene la cabecera estándar de módulo dependiente del idioma. La tabla en sí tiene apuntadores a los mensajes relativos al principio de la tabla. Como no puede haber mensaje 0, el apuntador de la posición 0 se substituye por el número de idioma. Podemos añadir una tabla de mensajes nueva al grupo 12 (tabla de meses y días de la semana) que (afortunadamente para este ejemplo) sólo tiene dos entradas.

occitan_ms12
dc.w 3 es una tabla de mensajes
dc.w 12 grupo 12
dc.w 3300 número de idioma occitano
dc.w next-* apuntador relativo a la siguiente tabla o cero
dc.l occ_ms12-* apuntador a la tabla de preferencias
occ_ms12
dc.w 3300 occitano
dc.w occ_mnth-occ_ms12 apuntador al primer mensaje
dc.w occ_dow-occ_ms12 apuntador al segundo mensaje
occ_mnth
dc.w 36,'IchNi SanGo Ro ShiHa Ku Ju JuiJun'
occ_dow
dc.w 21,'Ni Ge Ka SuiMo KinDo '

Note que el primer mensaje debe seguir al último apuntador: el primer apuntador es, por lo tanto, dos veces el número de mensajes de la tabla más 2. Es posible escribir esta tabla de mensajes en un fichero usando un simple programa SBASIC como el siguiente, pero para tablas más complejas con mensajes de longitud variable se requiere un programa más complejo.

WPUT #fch,3,12,3300,0,0,4 la cabecera, sin siguiente, la tabla justo detrás
WPUT #fch,3300,6,6+2+36 el número y dos apuntadores
PUT #fch,'IchNi SanGo Ro ShiHa Ku Ju JuiJun'
PUT #fch,'Ni Ge Ka SuiMo KinDo' las dos cadenas
BPUT #fch,0 un octeto de ajuste porque las dos cadenas tenían longitud impar

Una vez que haya incluido esta nueva tabla de mensajes, puede usarla tecleando el comando LANG_USE:

LANG_USE 3300
o
LANG_USE FOC

Tablas de teclado

El módulo dependiente del idioma que probablemente será el siguiente en ser añadido es una tabla de teclado. Una tabla de teclado tiene la cabecera estándar de módulo dependiente del idioma. Por razones históricas, el apuntador al módulo en la cabecera apunta a una estructura intermedia. Esta estructura intermedia tiene el código de idioma seguido por un par de apuntadores relativos, el primero de los cuales apunta a la tabla de teclado “normal”, el segundo apunta a la tabla de “caracteres de composición”. Éstas son teclas que cuando se presionan no hacen nada más que modificar el siguiente carácter tecleado.

Estas teclas son habitualmente teclas de acentos que se usan para añadir un acento a la siguiente letra. (Algunos controladores de teclado puede que no soporten caracteres de composición.)

occitan_kbd
dc.w 1 es una tabla de teclado
dc.w 0 no hay grupos
dc.w 3300 número de idioma occitano
dc.w next-* apuntador relativo a la siguiente tabla o cero
dc.l occ_kbd-* apuntador a la tabla de preferencias
occ_kbd
dc.w 3300 occitano
dc.w occ_ktab-* apuntador a la tabla de teclado
dc.w occ_nsid-* apuntador a la tabla de caracteres de composición

Si la tabla de teclado sigue inmediatamente a la cabecera y la tabla de composición sigue inmediatamente después, la cabecera puede ser escrita por un simple programa SBASIC.

WPUT #fch,1,0,3300,0,0,4 la cabecera, sin siguiente, la tabla justo detrás
WPUT #fch,3300,4,2+512 el número y los dos apuntadores (todos excepto el teclado QL)
o
WPUT #fch,1,0,3300,0,0,4 la cabecera, no siguiente, la tabla justo detrás
WPUT #fch,3300,4,2+256 el número y los dos apuntadores (teclado QL)

El tamaño de la tabla de teclado depende del teclado en sí mismo. La tabla se divide en cuatro bloques: pulsaciones normales, pulsaciones con MAYS, pulsaciones con CTRL y pulsaciones con MAYS y CTRL. Las tablas son los caracteres producidos por cada uno de los posibles códigos de teclado. Para los teclados principales, estos códigos de teclado son los siguientes.

Teclado QL - 64 entradas en cada uno de los 4 bloques



Así, para un teclado normal de QL, los códigos de las teclas de la cifras son 27, 9, 25, etc. La 27ª entrada en la tabla de teclado debería ser el carácter '1', la 9ª entrada '2', etc. (La tabla comienza con la entrada número 0.) Los códigos entre paréntesis son capturados por el controlador (MAYS, CTRL y ALT) y los valores correspondientes en las tablas de teclado deberían ser 0.

Teclado de Atari ST/TT - 128 entradas en cada uno de los 4 bloques



Así, para un teclado normal de ST, los códigos de las teclas de las cifras son 2, 3, 4, etc. La 2ª entrada en la tabla de teclado debería ser el carácter '1', la 3ª entrada '2', etc. (La tabla comienza con la entrada número 0.) Los códigos entre paréntesis son capturados por el controlador (MAYS, CTRL y ALT) y los valores correspondientes en las tablas de teclado deberían ser 0.

Teclado AT para QXL - 128 entradas en cada uno de los 4 bloques - Los modelos de PC AT y posteriores incorporan un controlador de teclado "inteligente" que tiene tres funciones principales:

1. convertir los códigos del teclado AT de 102 teclas, fáciles de manejar y explícitos, en confusas secuencias de códigos de teclado XT (¡hasta 10 códigos de tecla por cada pulsación!);

2. perder pulsaciones;

3. dejar las teclas de cambio "siempre pulsadas".

Las tablas de teclado están, por lo tanto, basadas en los códigos de tecla del XT.



Así, para un teclado normal de PC, los códigos de las teclas de las cifras son 2, 3, 4, etc. La 2ª entrada en la tabla de teclado debería ser el carácter '1', la 3ª entrada '2', etc. (La tabla comienza con la entrada número 0.) Los códigos entre paréntesis son capturados por el controlador (MAYS, CTRL y ALT) y los valores correspondientes en las tablas de teclado deberían ser 0.

Tabla de Teclado de Ejemplo

Lo más fácil es ver el formato de la tabla de teclado si se toma como ejemplo el teclado de 102 teclas de PC/AT. El primer bloque de 128 caracteres es para los caracteres sin cambio.

occ_ktab teclas sin cambio del teclado UK (en grupos de 16)
dc.b 0,$1B,'1','2','3','4','5','6','7','8','9','0','-','=',$C2,$09
dc.b 'q','w','e','r','t','y','u','i','o','p',$5B,$5D,$0A,0,'a','s'
dc.b 'd','f','g','h','j','k','l',';',$27,$9F,0,'#','z','x','c','v'
dc.b 'b','n','m',',','.','/',0,'*',0,' ',$E0,$E8,$EC,$F0,$F4,$F8
dc.b $EA,$EE,$F2,$F6,$FA,0,$F9,'7','8','9','-','4','5','6','+','1'
dc.b '2','3','0','.',0,0,'\',0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,$D5,$D0,$D4,0,$C0,0,$C8,0,$DD
dc.b $D8,$DC,$EB,$CA,0,'/',0,0,0,0,0,0,$0A,0,0,0

Este bloque está seguido inmediatamente por el bloque de 128 caracteres producidos con la tecla MAYS, después los 128 caracteres producidos con la tecla CTRL y finalmente los 128 caracteres producidos con las teclas MAYS y CTRL conjuntamente. Como solamente hay 256 valores diferentes que se pueden almacenar en un octeto y hay en total 512 entradas en la tabla de teclado, naturalmente habrá un gran número de ceros en las tablas así como un cierto número de códigos duplicados.

Caracteres de Composición

La tabla de caracteres de composición es un poco rara. Es una tabla de 256 octetos que está (casi) llena de ceros. Por cada carácter que pueda ser usado como carácter de composición, la entrada correspondiente en la tabla es distinta de cero. Así, si el ´ es usado como carácter de composición para producir caracteres acentuados, la 39ª entrada de la tabla es distinta de cero (el código ASCII de ´ es 39). El valor distinto de cero al que nos referimos es el desplazamiento desde el final de la tabla a la lista de caracteres modificados por este carácter de composición.

La tabla está seguida inmediatamente por una tabla de tamaño variable de caracteres modificables y modificados. Esta tabla tiene entradas cuya longitud es uno más que el número de caracteres modificables (cada entrada está terminada por un cero). La primera entrada lista los caracteres modificables. Ésta está seguida por entradas que proporcionan los caracteres modificados correspondientes a cada uno de los caracteres de composición.

occ_nsid
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0 ; apóstrofo para el acento agudo
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16 ; abrir comilla para el acento grave
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0.0.0.0.0,0.0,0.0.0,0,0.0,0.0,0
dc.b 0.0.0.0.0.0,0.0,0.0.0.0.0.0.0,0
dc.b 0.0,0.0.0.0.0,0.0.0.0.0.0.0,0,0
dc.b 'a','e','i','o','u','E',' ',0 ; cars. modificables (incl. espacio)
dc.b $8C,$83,$93,$96,$99,$A3,$27,0 ; cars. acento agudo (incl. ')
dc.b $8D,$90,$94,$97,$9A,'E',$9F,0 ; cars. acento grave (incl. `)

Esta tabla se puede escribir en un fichero usando comandos BPUT en un programa SBASIC.

nsid = FPOS(#fch) : REMark - remember where it starts
BPUT #fch,FILL$(CHR$(0),256) : REMark - fill table with zeros
BPUT #fch\nsid+39,8 : REMark - fill in apostrophe
BPUT #fch\nsid+159,16 : REMark - fill in open quote
BPUT #fch\nsid+256 : REMark - back to end of table
BPUT #fch,"aeiouE ",0 : REMark - unmodified characters at end
BPUT #fch,"áéíóúÉ'",0 : REMark - then acute accents
BPUT #fch,"àèìòùE`",0 : REMark - and grave accents

Una vez que haya incluido esta nueva tabla de teclado, puede usarla tecleando el comando KBD_TABLE:

KBD_TABLE 3300
o
KBD_TABLE FOC

Tablas de Traducción de Impresora

Las tablas de traducción de impresora son directamente compatibles con las antiguas, no muy útiles, tablas de traducción de impresora del QL usadas por el comando TRA. Estas tablas “dependientes del idioma” vinieron a existir porque alguien en Sinclair tenía la bastante extraña noción de que, de alguna manera, el carácter a (por ejemplo) debería imprimirse de forma diferente dependiendo del país. Creo que una a es una a dondequiera que estés.

SMSQ tiene una [tabla de] traducción de impresora estándar que funciona en cualquier impresora compatible PC configurada con el juego de caracteres USA (el uso de otros juegos de caracteres tiende a hacer imposible la impresión de ciertos caracteres).

Para impresoras peculiares, sin embargo, puede configurar sus propias tablas.

Una tabla de traducción de impresora tiene la cabecera estándar de módulo dependiente del idioma. Por razones históricas, el apuntador al módulo en la cabecera apunta a una estructura intermedia. Esta estructura intermedia tiene el código de idioma seguido por un par de apuntadores relativos al código de idioma. El primero de éstos apunta a la tabla de traducción “de octeto a octeto”, el segundo apunta a una tabla que traduce “un octeto en tres octetos”.

La tabla de octeto a octeto tiene, naturalmente, 256 entradas de un simple octeto. La primera entrada es cero (NULO permanece como NULO), todas las demás entradas son o caracteres traducidos o cero. Si la entrada es cero, el carácter se traduce usando la tabla de tres octetos.

La tabla de tres octetos está precedida por un octeto cero (histórico) y comienza con el número de secuencias de tres octetos (en un octeto). Esto está seguido por grupos de 4 octetos, el primero de los cuales es el carácter QL, los tres siguientes son los caracteres que se van a enviar a la impresora.

La siguiente es una copia de la tabla de traducción de la impresora IBM que puede ser usada como base para otras impresoras.

occitan_tra
dc.w 2 es una tabla de traducción de impresora
dc.w 0
dc.w 3300 número de idioma occitano
dc.w next-* apuntador relativo a la siguiente tabla o cero
dc.l occ_tra-* apuntador a la tabla de preferencias
occ_tra
dc.w 3300 occitano
dc.w occ_byte-occ_tra apuntador a la tabla “octeto a octeto”
dc.w occ_3byte-occ_tra apuntador a la tabla “octeto a tres octetos”
occ_byte
dc.b $00,$01,$02,$03,$04,$05,$06,$07
dc.b $08,$09,$0A,$0B,$0C,$0D,$0E,$0F
dc.b $10,$11,$12,$13,$14,$15,$16,$17
dc.b $18,$19,$1A,$1B,$1C,$1D,$1E,$1F
dc.b $20,$21,$22,$23,$24,$25,$26,$27
dc.b $28,$29,$2A,$2B,$2C,$2D,$2E,$2F
dc.b $30,$31,$32,$33,$34,$35,$36,$37
dc.b $38,$39,$3A,$3B,$3C,$3D,$3E,$3F
dc.b $40,$41,$42,$43,$44,$45,$46,$47
dc.b $48,$49,$4A,$4B,$4C,$4D,$4E,$4F
dc.b $50,$51,$52,$53,$54,$55,$56,$57
dc.b $58,$59,$5A,$5B,$5C,$5D,$5E,$5F
dc.b $9C,$61,$62,$63,$64,$65,$66,$67
dc.b $68,$69,$6A,$6B,$6C,$6D,$6E,$6F
dc.b $70,$71,$72,$73,$74,$75,$76,$77
dc.b $78,$79,$7A,$7B,$7C,$7D,$7E,$00
dc.b $84,$00,$86,$82,$94,$00,$00,$81
dc.b $87,$A4,$91,$00,$A0,$85,$83,$89
dc.b $8A,$88,$8B,$A1,$8D,$8C,$A2,$95
dc.b $93,$A3,$97,$96,$E1,$9B,$9D,$60
dc.b $8E,$00,$8F,$90,$99,$00,$00,$9A
dc.b $80,$A5,$92,$00,$E0,$EB,$E9,$00
dc.b $E6,$E3,$ED,$AD,$A8,$3F,$EC,$00
dc.b $AE,$AF,$F8,$F6,$00,$00,$00,$00
dc.b $C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7
dc.b $C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF
dc.b $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7
dc.b $D8,$D9,$DA,$DB,$DC,$DD,$DE,$DF
dc.b $B0,$B1,$B2,$B3,$B4,$B5,$B6,$B7
dc.b $B8,$B9,$BA,$BB,$BC,$BD,$BE,$BF
dc.b $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7
dc.b $F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF
dc.b 0 ;pad
occ_3byte
dc.b 15 ;15 sustituciones
dc.l $A54F087E ;O bs tilde
dc.l $AF5C082E ;\ bs .
dc.l $7F63084F ;c bs O
dc.l $8161087E ;a bs tilde
dc.l $856F087E ;o bs tilde
dc.l $866F082F ;o bs /
dc.l $8B6F6500 ;o e
dc.l $A141087E ;A bs tilde
dc.l $A64F082F ;O bs /
dc.l $AB4F4500 ;O E
dc.l $B76F0878 ;o bs x
dc.l $BC3C082D ;< bs -
dc.l $BD3E082D ;> bs -
dc.l $BE5E0821 ;^ bs !
dc.l $BF760821 ;v bs !

Una vez haya incluido esta nueva tabla de traducción de impresora, puede usarla tecleando el comando TRA:

TRA 1,3300
o
TRA 1,FOC

Una Extensión Dependiente del Idioma Completa

Este programa SBASIC crea una extensión dependiente del idioma completa con tablas de preferencias, teclado y mensajes. Los procedimientos SBASIC se usan para establecer apuntadores relativos: puede probar a descifrarlos si lo desea.

La tabla de teclado es del teclado estándar de un PC (QXL) del Reino Unido con una diferencia: las teclas F6 a F12 son usadas como caracteres de composición. Para evitar conflictos con los códigos de teclas existentes, se toman prestados los códigos de tecla de ALT-cursor (la tecla ALT es manejada dentro del controlador y por lo tanto los únicos códigos de tecla ALT que aparecen en la tabla son los de HOME (=ALT-MAYS-ARRIBA) y END (=ALT-MAYS-ABAJO)).

Las tablas de mensajes son versiones modificadas muy ligeramente de las tablas en inglés: se incluyen los cuatro grupos estándar para hacerle más fácil crear sus propias tablas de mensajes.

LANG_BAS

1000 REMark - Make complete language module for alternative English
1010 :
1020 fch = FOP_OVER(win1_lang_rext)
1030 :
1040 WPUT #fch, $7030, $43FA, $6, $4E41, $4E75
1060 ldm_link = 0 : REMark no language dependent links yet
1070 :
1080 make_ldm 0,0,440,ldm_link,eng_pref : REMark - set up LDM preference header
l090 make_ldm 1,0,440,ldm_link,eng_kbd : REMark - set up LDM keyboard header
1100 make_ldm 3,0,440,ldm_link,eng_ms0 : REMark - set up LDM message g0 header
1110 make_ldm 3,4,440,ldm_link,eng_ms4 : REMark - set up LDM message g4 header
1120 make_ldm 3,8,440,ldm_link,eng_ms8 : REMark - set up LDM message g8 header
1130 make_ldm 3,12,440,ldm_link,eng_ms12 : REMark - set up LDM message g12 header
1140 :
1150 set_ldm_pointer eng_pref : REMark - set pointer to pref table
1160 BPUT #fch,'GBA' : REMark - set modified car registration
1170 WPUT #fch,440,44,0 : REMark - and preferences
1180 :
1190 set_kbd_header eng_kbd,440,512 : REMark - set IBM PC size keyboard
1200 :
1210 BPUT #fch,0,$1B,'1','2','3','4','5','6','7','8','9','0','-','=',$C2,$9
1220 BPUT #fch,'q','w','e','r','t','y','u','i','o','p','[',']',$A,0,'a','s'
1230 BPUT #fch,'d','f,'g','h','j'.'k','l',';',$27,$9F,0,'#','z','x','c','v'
1240 BPUT #fch,'b','n','m',',','.','/',0,'*',0,' ',$E0,$E8,$EC,$F0,$F4,$F8
1250 BPUT #fch,$D1,$D3,$D7,$D9,$DB,0,$F9,'7','8','9','-','4','5','6','+','1'
1260 BPUT #fch,'2','3','0','.',0,0,'\',$DF,$E1,0,0,0,0,0,0,0
1270 BPUT #fch,0,0,0,0,0,0,0,$D5,$D0,$D4,0,$C0,0,$C8,0,$DD
1280 BPUT #fch,$D8,$DC,$EB,$CA,0,'/',0,0,0,0,0,0,$A,0,0,0
1290 :
1300 BPUT #fch,0,'©','!','"','£','$','%','^','&','*','(',')','_','+',$C6,$FD
1310 BPUT #fch,'Q','W','E','R'.'T','Y','U','I','O','P','{','}',$FE,0,'A','S'
1320 BPUT #fch,'D','F','G','H','J','K','L',':','@',$B5,0,'~','Z','X','C,'V'
1330 BPUT #fch,'B','N','M','<','>','?',0,'*',0,$FC,$E4,$EA,$EE,$F2,$F6,$FA
1340 BPUT #fch,$D1,$D3,$D7,$D9,$DB,0,$F9,'7','8','9','-','4','5','6','+','1'
1350 BPUT #fch,'2','3','0','.',0,0,'|',$DF,$E1,0,0,0,0,0,0,0
1360 BPUT #fch,0,0,0,0,0,0,0,$D5,$D4,$D4,0,$C4,0,$CC,0,$DD
1370 BPUT #fch,$DC,$DC,$EB,$CE,0,'/',0,0,0,0,0,0,$FE,0,0,0
1380 :
1390 BPUT #fch,$FF,'ä','ê','ï','í','ì','î','ó','ò','ô','ú','è','à','¢',$C2,$09
1400 BPUT #fch,$11,$17,$05,$12,$14,$19,$15,$09,$0F,$10,'÷','→',$0A,0,$01,$13
1410 BPUT #fch,$04,$06,$07,$08,$0A,$0B,$0C,'û','ü',0,0,0,$1A,$18,$03,$16
1420 BPUT #fch,$02,$0E,$0D,'á','â','ë',0,'*',0,$FF,$E2,$E9,$ED,$F1,$F5,$F9
1430 BPUT #fch,$D1,$D3,$D7,$D9,$DB,0,$F9,'7','8','9','-','4','5','6','+','1'
1440 BPUT #fch,'2','3','0','.',0,0,'\',$DF,$E1,0,0,0,0,0,0,0
1450 BPUT #fch,0,0,0,0,0,0,0,$D5,$D2,$D6,0,$C2,0,$CA,0,$DD
1460 BPUT #fch,$DA,$DE,$EB,$CA,0,'/',0,0,0,0,0,0,$0A,0,0,0
1470 :
1480 BPUT #fch,$FF,$1F,'ã','Ä','é','ö','õ','↑','ø','æ','ç','ñ','↓','õ',$C6,$FD
1490 BPUT #fch,'π','¤','õ','Φ','¿','»','Ṣ','Ñ','θ','λ',$1B,$1D,$FE,0,'Ã','¡'
1500 BPUT #fch,'Ö','Ø','Ü','Ç','Æ','Õ','α','ù','å',$1B,0,'|','̊','«','É','§'
1510 BPUT #fch,'Å','Θ','δ','β','¥','`',0,'*',0,' ',$E6,$EB,$EF,$F3,$F7,$FB
1520 BPUT #fch,$D1,$D3,$D7,$D9,$DB,0,$F9,'7','8','9','-','4','5','6','+','1'
1530 BPUT #fch,'2','3','0','.',0,0,'\',$DF,$E1,0,0,0,0,0,0,0
1540 BPUT #fch,0,0,0,0,0,0,0,$D5,$D6,$D6,0,$C6,0,$CE,0,$DD
1550 BPUT #fch,$DE,$DE,$EB,$CE,0,'/',0,0,0,0,0,0,$FE,0,0,0
1560 :
1570 BPUT #fch,FILL$(CHR$(0),$D0) : REMark - fill up to non-spacing chars
1580 BPUT #fch,0,14,0,28,0,0,0,42 : REMark - the seven non-spacing chars
1590 BPUT #fch,0,56,0,70,0,0,0,84
1600 BPUT #fch,0,98
1610 BPUT #fch,FILL$(CHR$(0),$FF-$E1) : REMark - fill the rest with 0
1620 :
1630 BPUT #fch,'aeioucnAEOUCN',0 : REMark - the modifiable characters
1640 BPUT #fch,'áéíóúcnAÉOUCN',0 : REMark - acute accents
1650 BPUT #fch,'âêîôûcnAEOUCN',0 : REMark - circumflex accents
1660 BPUT #fch,'áéíóúcnAEOUCN',0 : REMark - graveaccents
1670 BPUT #fch,'ãeiõucñÃEÕUCÑ',0 : REMark - tilde
1680 BPUT #fch,'äëïöücnÄEÖÜCN',0 : REMark - umlaut or diaeresis
1690 BPUT #fch,'åeiøu¢nÅEØUCN',0 : REMark - ̊ or /
1700 BPUT #fch,'æeiœuçnÆEŒUÇN',0 : REMark = +e
1710 :
1720 :
1730 :
1740 set_message_header eng_ms0,440,22 : REMark - message group 0 header
1750 :
1760 message_nl 'I have not finished yet!' : REMark - not complete
1770 message_nl 'invalid JobID'
1780 message_nl 'insufficient memory'
1790 message_nl 'value out of range'
1800 message_nl 'buffer full'
1810 message_nl 'invalid channelID'
1820 message_nl 'not found'
1830 message_nl 'already exists'
1840 message_nl 'is in use'
1850 message_nl 'end of file'
1860 message_nl 'medium is full'
1870 message_nl 'invalid name'
1880 message_nl 'transmission error'
1890 message_nl 'format failed'
1900 message_nl 'invalid parameter'
1910 message_nl 'medium check failed'
1920 message_nl 'error in expression'
1930 message_nl 'arithmetic overflow'
1940 message_nl 'not implemented'
1950 message_nl 'write protected'
1960 message_nl 'invalid syntax'
1970 message_nl 'unknown message'
1980 :
1990 set_message_header eng_ms4, 440,47 : REMark - message group 4 header
2000 :
2010 message_nl 'you screwed it up again' : REMark - syntax error in expression
2020 message_nl 'missing left parenthesis'
2030 message_nl 'missing right parenthesis'
2040 message_nl 'error in line number'
2050 message_nl 'bad string: missing delimiter'
2060 message_nl 'incorrect procedure or function definition'
2070 message_nl 'procedure or function definition not allowed here'
2080 message_nl 'DEFines may not be within other clauses'
2090 message_nl 'misplaced END DEFine'
2100 message_nl 'misplaced LOCal'
2110 message_nl 'RETurn not in procedure or function'
2120 message_nl 'WHEN clauses may not be nested'
2130 message_nl 'misplaced END WHEN'
2140 message_nl 'misplaced ELSE'
2150 message_nl 'misplaced END IF
2160 message_nl 'program structures nested too deeply, my brain aches'
2170 message_nl 'incomplete IF clause'
2180 message_nl 'incomplete SELect clause'
2190 message_nl 'incomplete DEFine'
2200 message_nl 'incomplete WHEN clause'
2210 message_nl 'unacceptable loop variable'
2220 message_nl 'unable to find an open loop'
2230 message_nl 'undefined loop control variable'
2240 message_nl 'incorrectly structured SELect clause'
2250 message_nl 'misplaced END SELect'
2260 message_nl 'DATA in command line has no meaning'
2270 message_nl 'unacceptable parameters for READ'
2280 message_nl 'SBASIC cannot perform READs within DATA expressions'
2290 message_nl 'end of DATA'
2300 message_nl 'unknown procedure'
2310 message_nl 'unknown function or array'
2320 message_nl 'only arrays may be dimensioned'
2330 message_nl 'procedure and function parameters may not be dimensioned'
2340 message_nl 'SBASIC cannot put up with negative dimensions'
2350 message_nl 'dimensional overflow - you cannot be serious!'
2360 message_nl 'error in index list'
2370 message_nl 'too many indexes'
2380 message_nl 'cannot assign to sub-array'
2390 message_nl 'unacceptable array index list'
2400 message_nl 'array index out of range'
2410 message_nl 'only arrays or strings may be indexed'
2420 message_nl 'assignment can only be to a variable or array element'
2430 message_nl 'MISTake in program'
2440 message_nl 'during when processing'
2450 message_nl 'PROC/FN cleared'
2460 message 'At line'
2470 message_nl 'fatal error in SBASIC interpreter'
2480 :
2490 set_message_header eng_ms8,440,13 : REMark - message group 8 header
2500 :
2510 message 'To destroy the UNIVERSE,press ':REMark -To FORMAT the disk,press
2520 message '******* ABORTED *******'
2530 message 'Working memory allocation (kilobytes)>'
2540 message 'last line recall'
2550 message 'YNAQ'
2560 message '..Y or N?'
2570 message '..Y/N/A/Q?'
2580 message ' TO '
2590 message ' exists, '
2600 message 'OK to overwrite'
2610 message_nl ' sectors'
2620 message_nl 'Job tag owner priority'
2630 message_nl 'net aborted'
2640 :
2650 set_message_header eng_ms12, 440,2 : REMark - message group 12 header
2660 :
2670 message 'JanFebMarAprMayJunJulAugSepOctNovDec'
2680 message 'SunMonTueWedThuFriSat'
2690 :
2700 CLOSE #fch
2710 :
2720 :
2730 :
2740 DEFine PROCedure make_ldm (type, group, lang, link, pointer)
2750 LOCal old_link
2760 old_link = link
2770 link = FPOS (#fch)
2780 IF old_link: WPUT #fch\old_link, link-old_link: REMark -fill in old link
2790 WPUT #fch\link, type, group, lang : REMark -fill in type of LDM
2800 pointer = link + 2 : REMark - link is updated and so is pointer
2810 :
2820 WPUT #fch\(link), 0,0,0 : REMark - fill in blanks but
2830 : : REMark - do not change value of link
2840 END DEFine make_ldm
2850 :
2860 DEFine PROCedure set_ldm_pointer (pointer)
2870 LOCal here
2880 here = FPOS (#fch)
2890 LPUT #fch\(pointer), here-pointer : REMark - set relative pointer
2900 BPUT #fch\(here) : REMark - and reset file pointer
2910 END DEFine set_ldm_pointer
2920 :
2930 DEFine PROCedure set_kbd_header (pointer, lang, size)
2940 set_ldm_pointer pointer
2950 WPUT #fch, lang, 4, size+2 : REMark - keyboard table follows
2960 END DEFine set_kbd_header
2970 :
2980 DEFine PROCedure set_message_header (pointer, lang, size)
2990 LOCal i
3000 :
3010 set_ldm_pointer pointer
3020 :
3030 message_table_base = FPOS (#fch) : REMark - base of table
3040 WPUT #fch,lang : REMark - set language
3050 message_table_pointer = FPOS (#fch) : REMark - message table starts here
3060 FOR i =1 TO size: WPUT #fch, 0 : REMark - empty table
3070 message_text_pointer = FPOS (#fch) : REMark - messages here
3080 END DEFine set_message_header
3090:
3100 DEFine PROCedure message (msg$)
3110 WPUT #fch\message_table_pointer,message_text_pointer - message_table_base
3120 REMark - sets the message table entry and updates the table pointer
3130 PUT #fch\message_text_pointer, msg$ : REMark - put message
3140 IF LEN(msg$) && 1: BPUT #fch\message_text_pointer,0
3150 REMark all messages must be an even number of bytes long
3160 END DEFine message
3170 :
3180 DEFine PROCedure message_nl (msg$)
3190 WPUT #fch\message_table_pointer,message_text_pointer - message_table_base
3200 REMark - sets the message table entry and updates the table pointer
3210 PUT #fch\message_text_pointer, msg$ & CHR$(10) : REMark - put message + <NL>
3220 IF NOT (LEN(msg$) && 1): BPUT #fch\message_text_pointer, 0
3230 REMark - all messages must be an even number of bytes long
3240 END DEFine message_nl
Ver también: Módulos de SMSQ


Sinclair QL Recursos en Castellano Alojado en / Hosted at:
Sinclair QL Recursos en Castellano
Sinclair QL Spanish Resources