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.
Artículo original: http://www.dilwyn.me.uk/docs/articles/thingtxt.zipTABLA 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
![]() |
Alojado en / Hosted at: Sinclair QL Recursos en Castellano Sinclair QL Spanish Resources |