|
Por Eugene Mortimore
Todos los programas deben aprovechar las máximas ventajas ofrecidas por el sistema, tanto a nivel hardware como a nivel software. Para ello sus programas deben configurarse óptimamente desde el arranque, para adaptarse a posibles cambios futuros tanto en el hardware como en las rutinas del sistema. Usted, por tanto, debe escribir un programa capaz de detectar los cambios y autoadaptarse a nuevas configuraciones. El entorno hardware determina la configuración inicial de su programa, mientras que el continuo cambio del entorno software determina el camino que tomará su programa en la ejecución.
Para ayudarle a resolver este problema, el software de sistema del Amiga contiene una serie de rutinas internas que constantemente recogen información acerca del estado corriente del sistema. Las rutinas chequean todo el hardware así como el software en el sistema de arranque, e inicializa los parámetros apropiados que reflejarán dicho 'estado inicial de sistema0.
Sus programas deberían contemplar dichos parámetros de especificación del sistema, para que de esta forma se consiguiese una máxima eficiencia en la ejecución de los programas. Por ejemplo todos los programas necesitan conocer que CPU se encuentra presente, además de obtener información sobre la cantidad de memoria externa e interna disponible, y las librerías que se encuentran presentes en el sistema. Este es el caso de los programas existentes en los mercados de América y Europa, los cuales deben conocer la frecuencia de la toma de corriente.
Sistema de librerías
Cada librería de sistema provee la estructura necesaria para saber a qué recurso acudir en el estado actual de la máquina. Por ejemplo la librería gráfica usa la estructura GfxBase, la librería DOS usa la estructura DosBase, y la librería Intuition usa la estructura IntuiBase. Estas estructuras son vitales a la hora de poder leer, y en algunas ocasiones escribir, los parámetros del sistema, así como para los diferentes mecanismos software.
En este artículo nos centraremos en la más importante de las librerías: la librería Exec, estructura ExecBase. Como referencia puede realizar una copia impresa del fichero include execbase.h, el cual contiene 50 parámetros para la estructura ExecBase.
Al mismo tiempo la estructura ExecBase posee un cuadro global con las características software y hardware más importantes del sistema. Algunos de estos parámetros se encuentran en continuo cambio, siendo updateados por las rutinas 'escondidas' del Exec. Por ejemplo los parámetros Low-MemChkSum, ChkBase y ChkSum, se encuentran presentes únicamente para la realización de testeos internos sobre la integridad de la memoria. El sistema monitoriza dichos parámetros y su programa raramente puede verse concernido con los valores obtenidos anteriormente. De igual forma sus programas no podrán escribir nuevos valores en los parámetros de la estructura ExecBase.
Las rutinas escondidas del Exec son las que caracterizan el sistema hardware de usuario, así como las que realizan la configuración del sistema cada vez que se reinicializa el ordenador. La mayoría de los resultados de este proceso se reflejan en los parámetros del ExecBase, los cuales se actualizan al final de la secuencia de arranque. Un programa puede leer dichos parámetros de estructura (y configurarse él mismo) para un uso con futuras configuraciones. Si su programa necesita examinar alguna lista de sistema (Library list, Device list, Memory list) tendrá que acceder a los parámetros apropiados de la estructura ExecBase.
Las rutinas escondidas de la Exec sitúan automáticamente todas las librerías añadidas (Exec, DOSC, Graphics, así como otras) sobre la lista de estructura de la ExecBase. Al final de la secuencia de arranque, los parámetros en la librería LibList del ExecBase representan una estructura de la lista que contiene el listado actual de librerías. Con un bucle de lectura de la lista, su programa puede determinar qué librerías han sido añadidas al sistema.
Cada vez que el sistema borra (o añade) una estructura de librería, desde la library list del sistema, o el programa actual borra (o añade) una librería, las rutinas internas del Exec separan (o juntan) dicha librería en la library list del ExecBase. Esto mismo se puede aplicar a Device resources, Message ports, y otros. Usted puede ver de este modo por qué algunos de los parámetros del ExecBase se encuentran en continuo cambio, siempre que varios programas se están ejecutando en modo multitarea.
Consultando los libros
En este artículo nos centraremos |
 |
en la más importante de las librerías |
 |
la librería Exec. |
 |
|
El listado, que acompaña este artículo, es un corto programa que lee y muestra 15 de los 50 parámetros de la estructura ExecBase. Primero compile y ejecute el programa en su máquina, e intente interpretar los resultados en términos de su sistema hardware y contenido de su diretorio LIBS. A continuación se detallan los parámetros que se consultan:
— SysStackUpper y SysStackLower son las dirección superior e inferior de la pila en el sistema supervisor de la CPU 68000.
— MaxLocMem y MaxExtMem son respectivamente las máximas direcciones de la memoria interna y expandida en el ordenador. Su programa puede consultar estos valores para testear la cantidad de memoria, y si es el caso advertir de una insuficiencia de memoria para que su programa pueda ser ejecutado correctamente.
— DebugEntry es la dirección de entrada en la ROM para ejecutar las rutinas RomWack del puerto serie RS-232 a 9.600 baudios. Dichas funciones son utilizadas primordialmente para revisar estructuras de datos después del 'cuelgue' de un programa.
— TaskTrapCode, TaskExceptCode y TaskExitCode son las direcciones que indican el punto de entrad en la Rom a los Trap de tareas, excepción y salida del programa. El sistema saltará a dicha dirección cada vez que suceda el evento correspondiente.
— Quantum es el número de tareas intercambiadas por segundo. Su programa puede cambiar este valor para escribir un nuevo valor en el parámetro Quantum, alterando de esta forma la frecuencia de interproceso.
— El parámetro AttnFlags es un buen ejemplo para observar cómo las rutinas escondidas del exec, primero determinar los valores iniciales y después escriben éstos en los parámetros de ExecBase. AttnFlags es una colección de bits que representan los procesos específicos del sistema. Si una máquina posee una CPU 68020, AttnFlags será AFF68020; una máquina con CPU 68020 y coprocesador matemático 68881 mostrará una combinación mediante OR de AFF68020 y AFF68881 (definido en el fichero include execbase.h). Un programa escrito para todos los aparatos comprendidos en el rango 68000-68030, debe determinar que procesador es el actual y ejecutar las instrucciones específicas de cada uno.
— VBlankFrequency es la frecuencia vertical de blanking en el sistema, mientras que PowerSupplyFrequency es la frecuencia en la línea de corriente para el sistema. Este valor deberá ser 50 para las máquinas PAL europeas.
Estudie las posibilidades de extender el programa, adaptando éste a sus propias necesidades de programa.
#incluse <exec/types.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <stdio.h>
#define SIZES 16
#define MINSIZE 3
#define MAXSIZE (SIZES + MINSIZE - 1)
struct ExecBase *SysBase
main()
{
shor size frequency[SIZES];
struct MEmChunk *memChunk;
struct MemHeader *MemHeader;
struct Node *node;
short index;
printf"SysStackUpper Address %lx\n", SysBase->SysStack Upper);
printf"SysStackLower Address %lx\n", SysBase->SysStack Lower);
printf"MaxLocMem Address %lx\n", SysBase->MaxLOcMem);
printf"MaxExtMem Address %lx\n", SysBase->MaxExtMem);
printf"Quantum task-switches/sec %lx\n", SysBase->Quantum);
printf"DebugEntry Jump Address %lx\n", SysBase->DebugEntry);
printf"TaskTrapCode Jump Address %lx\n", SysBase->TaskTrapCode);
printf"TaskExceptCode Jump Address %lx\n", SysBase->TaskExceptCode);
printf"TaskExitCode Jump Address %lx\n", SysBase->TaskExitCode);
printf"AttnFlags bits %lx\n", SysBase->AttnFlags);
printf"VBlankFrequency c/sec %lx\n", SysBase->VBlankFrequency);
printf"PowerSupplyFrequency c/sec %lx\n", SysBase->PowerSupplyFrequency);
Forbid();
for(node = (struct Node *)SysBase->LibList.lh_Head;
node != (struct Node *)SysBase->LibList.lh_TailPred;
node = node->ln_succ)
{
printf("Library Name %s\n", node->ln_Node0;
}
Permit():
for(index = 0; index < SIZES; index++)
{
size_frequency[index] = 0;
}
Forbid();
for(MemHeader = (struct MemHeader *)SysBase->MemList.lh_Head;
memHeader->mh_Node.lh_succ;
memHeader = (struct MemHeader *)memHeader->mh_Node.ln_succ)
{
for(memChunk = MemHeader->mhF; memChunk; memChunk = memChunk->mc_Next)
{
for(index = MAXSIZE; index >= MINSIZE; index--)
{
if((1 >> index) & memChunk->mc_bytes)
{
++size_frequency[index - MINSIZE];
break;
}
}
}
}
Permit():
printf("\nCurrent Free-memory-chunk-size Frequency Distribution:\n\n");
printf(" Size Frequency\n");
for(index = MINSIZE; index <= MAXSIZE; index++)
{
printf("%6ld: $4ld\n", (1 << index), size_frequency[index - MINSIZE];
} |
|
 |
 |
 |
|