THINGS... y parte 3

Jochen Merz
Alemania
Artículo aparecido en la revista QL Today volumen 4 número 5

Traducción:
Afx
Junio de 2009

Viene del artículo anterior

En esta última parte vamos a estudiar de una forma más atenta los Things en tu sistema, cómo se organizan en la memoria y la forma en la que están vinculados.

Te mostraré un programa SBASIC bastante corto al final de éste artículo (listado 1), que puedes teclear o copiar, y que te mostrará algunos detalles de los Thing en tu sistema. Cuando lo ejecutes, probablemente listará todos los Things que tienes actualmente disponibles. A modo de ejemplo, puedes ver en la tabla 2 los Things cargados en mi sistema.

Debería mencionar en primer lugar, que el "hacking" a través de una lista como la de los Things (u otra lista, como la de los controladores de dispositivos etc.) debería hacerse en ensamblador mientras el programa se está ejecutando en modo Supervisor. Esto asegura, que otros jobs no pueden enlazar o des-enlazar Things mientras nosotros examinamos la lista. Esto no lo podemos hacer en SBASIC, pero siempre y cuando tú no añadas y quietes Thigs durante la ejecución del propio programa no pasará nada. Además, dudo que estés continuamente añadiendo o eliminando Things mientras estás probando esto.

Los Things se guardan en una lista enlazada y los nuevos Things se añaden en la parte superior de esta lista. Una variable de sistema

sys_thgl  equ $b8  

apunta a la primera entrada en la lista. El extraño PEEK_L con los dos signos de exclamación lee una palabra larga desde las variables del sistema en un desplazamiento B8 en hexadecimal desde el inicio de dichas variables del sistema.

En lugar de eso puedes escribir en QDOS "ordinario" lo siguiente:

PEEK_L(HEX("280B8"))

La dirección leída desde esta variable es un puntero al primer Thing en la lista de Things. Cada uno de ellos apunta al siguiente, así que es muy fácil rastrear la lista de arriba abajo. La lista termina cuando el siguiente puntero no apunta a un sitio válido, en este caso contiene un 0. Si observas la tabla 1 que está más abajo, verás una explicación de la estructura a la que estos punteros apuntan.

Las tres direcciones siguientes serán llenadas por: la rutina que vincula el Thing en la lista, de esta manera no necesitas preocuparte de ellos cuando se crea un Thing, un puntero que apunta a una lista enlazada de todos los jobs que están usando este Thing en un momento dado, y otro puntero a rutinas que no deberían ser tocadas en absoluto. El puntero al Thing en si mismo necesita contener un valor, pero nadie sabe exactamente donde está realmente situado el Thing.

Las siguientes cuatro punteros apuntan a rutinas que deben ser suministradas por ti para que hagas lo que quieras cuando el job intenta usarlo, liberarlo o eliminar este Thing específico. Además se puede suministrar una rutina de limpieza (por ejemplo para des-enlazar drivers o eliminar rutinas desde una lista de interrupciones, etc.).

Si el Thing puede solamente ser usado por un job al mismo tiempo, entonces deberías establecer el bit superior de un flag que indica no-compartido (marcado con un "-" en el listado de salida de nuestro programa BASIC).

La omisión de la comprobación del byte se hace para ejecutar una comparación de nombre más rápida. Sin embargo, el ID de la versión (o lista de características) debería ser llenada por el programador.

El programa BASIC lee unos bits muy interesantes de cada una de las entradas de los Thing. En mi ejemplo (tabla 2 otra vez), puedes ver que el último Thing que ha sido añadido al Sistema es "Calculator" (está especificado el último en mi definición HOTKEY en mi programa BOOT). Es interesante ver que "Calculator" no tiene número de versión.QD, que está más abajo, ha sido cargado con LRESPR anteriormente, pero después de QPAC2 (que aparece como un montón de Things linkados desde "Button Frame" hasta "Things" ...)

Todo lo que está por debajo hasta "HOTKEY" es linkado por el sistema operativo SMSQ/E, esto explica el orden.

En la parte inferior puedes encontrar un thing especial llamado "THING" que define la entrada al sistema Things, pero esto ya lo he explicado.Verás cómo usarlo en el futuro.

La tabla que muestra la salida de mi sistema después de ejecutar el programa BASIC, en mi caso, el sistema de variables Thing apunta a $C3810, que apunta a $91E30, que apunta a $917C0 ...y así hasta $56C10, que apunta a "0".

Nosotros tenemos también el número de versión de cada Thing. Se corresponde con lo que el programador defina como etiqueta de versión - la mayoría de la gente lo llena con cuatro caracteres ASCII que define la versión-. SBASIC, por ejemplo, tiene como número de versión etiquetas como "HBA".

También es posible ver en los 4 caracteres que ocupan 32 bits, especifican "características" soportadas por el Thing. Esto significa que no puedes ver realmente una secuencia de caracteres sino una serie de patrones o caracteres extraños. En el ejemplo de la lista de Things de mi sistema lo podrás ver en el Thing llamadao "FileInfo".

El nombre del thing se reduce a 20 caracteres en caso de ser más largo. Tienes que especificar el nombre correcto del Thing si quieres usarlo o eliminarlo.

Seguramente has notado que la estructura de las lista enlazada de los Things contienen menos información de la que hemos listado, por ejemplo el nombre del Thing no está almacenado en la estructura sino en el Thing en sí mismo (th_thing que apunta al Thing). Hemos hecho alguna trampa por ahora pero léelo desde ahí.

Para terminar el tema, echemos un vistazo a las diversas estructuras para varios tipos posible de Things en las siguientes Tablas. También te muestro el listado del programa SBASIC que hemos comentado en el artículo y la salida producida en mi sistema.

TABLA 1 
------- 

; Thing linkage block 
 
th_nxtth  equ $00 ; long link to NeXT THing 
th_usage  equ $04 ; long thing' s USAGE list 
th_frfre  equ $08 ; long address of "close" routine for FoRced FREe 
th_frzap  equ $0c ; long address of "close" routine for FoRced ZAP 
th_thing  equ $10 ; long pointer to THING itself 
th_use    equ $14 ; long code to USE a thing 
th_free   equ $18 ; long code to FREE a thing 
th_ffree  equ $1c ; long code to Force FREE a thing 
th_remov  equ $20 ; long code to tidy before REMOVing thing 
th_nshar  equ $24 ; byte Non-SHAReable Thing if top bit set 
th_check  equ $25 ; byte CHECK byte --- set by LTHG 
th_verid  equ $26 ; long version ID 
th_name   equ $2a ; string name of thing 
th.len    equ $2c ;        basic length of thing linkage_ 

TABLA 2 
------- 
 
LINK      VERS S ADDRESS  TYPE NAME 
--------  ---- - -------- ---- --------------------- 
000C381O       + 000C386E EXEC Calculator 
00091E30  2.25 + 00091E62 EXEC Sernet 
000917C0  1.30 + 00100BB4 EXEC Pic Viewer 
00091760  3.31 + 00100B80 EXEC FileInfo II thread 
00091700  3.31 + 0010091C EXTN FileInfo II extensio 
000916A0  3.31 + 001008FE DATA FileInfo II history 
00091640  FIv3 + 001008E0 DATA FileInfo II database 
000915E0  ###0 + 001008BA UTIL FileInfo 
00090FE0  1.00 - 000FC2D2 DATA DATAdesign mutex 
00091890  3.14 + 000918CE EXTN DATAdesign.engine 
0008B970  A.05 + 000E6D22 EXEC QD 
0008B920  1.13 + 000DB5B6 EXTN Scrap Extensions 
0008B8D0  7.57 + 000D8B1A EXTN Menus 
00091320  1.03 + 00091360 UTIL Button Frame 
000911F0  1.03 + 000CC6C2 EXTN Button Extensions 
000911A0  1.04 + 000CF1BE EXEC Button_Sleep 
00091150  1.02 + 000CF168 EXEC Button_Pick 
00091100  1.01 + 000CF0B0 EXEC Hotjobs 
000910B0  1.01 + 000CF098 EXEC Hotkeys 
00091060  1.04 + 000CEE78 EXEC Channels 
0008E7D0  1.02 + 000CEA44 EXEC Jobs 
0008E780  1.25 + 000CCDB2 EXEC Files 
0008E730  1.05 + 000CCAFC EXEC Sysdef 
0008E6E0  1.02 + 000CCA26 EXEC Rjob 
0008BBD0  1.02 + 000CC928 EXEC Pick 
0008BB80  1.02 + 000CC7E6 EXEC Wake 
0008BAA0  1.02 + 000CC7CE EXEC Exec 
0008BA50  1.02 + 000CC2C6 EXEC Button 
0008BA00  1.01 + 000CC068 EXEC Things 
000580C0  2.15 + 000B8AD2 EXTN Jmon 
0008A910  2.29 + 0008A948 UTIL HOTKEY 
0008B4B0  2.05 + 007EAEAE EXTN DEV 
0008A1A0  3.00 + 007EAC14 EXTN WIN Control 
0008A050  3.08 + 0008A050 UTIL DV3 
00089920  2.00 + 007F64E8 EXTN QVME 
000898D0  2.09 + 0000AA6E EXTN Ser_Par_Prt 
000581F0  2.11 + 0000A91E EXTN KBD 
00059250  HBA  + 007F9E9E UTIL SBAS/QD 
000591B0  HBA  + 007F9D5C EXEC SBASIC 
00056C10  0.05 + 00056C42 VECT THING 
  TH_ENTRY 00002FDA 
  TH_EXEC  00002F40_ 

100 REMark List Things 
110 : 
120 listptr = PEEK_L( !! $B8) 
130 chan = 3 : OPEN #chan, con 
140 PRINT #chan;LINK     VERS S ADDRESS  TYPE NAME" 
150 REPeat loop 
160   IF listptr = 0 THEN EXIT loop 
17O   cr_thgaddr = PEEK_L(listptr+$10) 
18O   PRINT #chan;HEX$(listptr,32)! 
190   IF PEEK_L(listptr+$26) < > O 
200     PRINT #chan; ! PEEK$(listptr+$26,4)! 
210   ELSE 
215     PRINT #chan;'     '; 
220   END IF 
230   PRINT #chan; ! "+-"((PEEK(listptr+$24) > $7F)+1)! 
240   PRINT #chan; !HEX$(cr_thgaddr,32);" "; 
250   cr_thgtyp = PEEK_L(cr_thgaddr+$4) 
260   th_nam$ = PEEK$(listptr+$2C, PEEK_W(listptr+$2A)) : namlen = LEN(th_nam$) 
280   IF namlen< 20 
290     th_nam$ = th_nam$&FILL$ (" ",20-namlen) 
300   ELSE 
310     IF namlen > 2O THEN th_nam$=tt_nam$( TO 20) 
320   END IF 
330   SELect ON cr_thgtyp 
340     =0:PRINT #chan;'UTIL'!th_nam$! 
350     =1:PRINT #chan;'EXEC'!tt_nam$! 
360     =2:PRINT #chan;'DATA'!th_nam$! 
370     =$1000003 : PRINT #chan;'EXTN'!th_nam$! 
380     =$1000004 : PRINT #chan;'EXTS'!th_nam$! 
390     =-1:PRINT#chan;'VECT'!th_nam$_TH_ENTRY'!HEX$(PEEK_L(cr_thgaddr+$8),32)_TH_EXEC'!HEX$(PEEK_L(cr_thgaddr+$C),32)! 
400     =REMAINDER:PRINT #chan;'    ';th_nam$!'UNKNOWN TYPE('!HEX$(cr_thgtyp,32)!') ' 
410   END SELect 
420   PRINT #chan 
430   listptr = PEEK_L(listptr) 
440 END REPeat loop 
450 CLOSE #chan

Artículo original: http://www.dilwyn.me.uk/docs/articles/thingtxt.zip


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