1. El mapa de memoria de los Fujitsu FM-7/8
Para comprender la interacción entre los dos procesadores 6809 de los Fujitsu, es básico conocer cómo se disponen los bancos de memoria de 64KB visibles por cada uno de dichas CPUs.
La organización de la memoria es la siguiente:
2. El Subsistema gráfico de los Fujitsu FM-7/8
Los Fujitsu FM-7/8 cuentan con dos procesadores 6809 responsables de gestionar el sistema principal uno de ellos, y el subsistema gráfico el segundo, contando cada uno de ellos con una memoria de 64KB.
Este subsistema gráfico tiene, como se puede uno imaginar, la responsabilidad de controlar todo lo relativo a la pantalla y además, gestionar también el teclado, funcionando todo ellos de forma totalmente independiente al sistema principal.
El acceso a este subsistema no es algo al alcance de todos y normalmente funciona como una caja negra; pero para alcanzar la máxima velocidad en determinadas tareas hay que echar mano de ciertos trucos para controlar el subsistema directamente, para ello contamos con el comando de mantenimiento.
3. Funcionamiento del Subsistema
A continuación se va a detallar de forma breve el funcionamiento del comando de mantenimiento, pieza fundamental para el complete conocimiento del Subsistema (en adelante SS).
Como ya se ha indicado, el SS es independiente del sistema principal y controlado por una CPU dedicada que reparte sus tareas entre la gestión gráfica y el teclado.
Conceptualmente el diagrama del SS es el siguiente:
A través de 128 bytes de RAM compartida, el Sistema principal está conectado con el SS. El el banco de memoria principal esta área se encuentra en la ventana $FC80-$FCFF, mientras que en el segundo banco, esta misma ventana ocupa el espacio $D380-$D3FF, en ambas áreas aparecen simultáneamente los mismos datos, el intercambio de datos entre ambos bancos se realizará a través de esta área compartida.
Muy resumido, el flujo de trabajo a la hora de presentar algún gráfico sería el siguiente:
A) A través de la RAM compartida, enviar el comando y los datos a visualizar.
B) El SS almacena los datos en la VRAM.
C) EL CRTC se encarga de visualizar los datos.
Puede parecer algo enrevesado; pero enviando los comandos y datos a procesar al SS, este puede tomar a partir de ese instante, el control sobre la tarea de forma independiente, permitiendo que el procesador central continúe con su trabajo.
Bien planificado, este procedimiento permite que la velocidad del procesamiento aumente, a diferencia de lo que sucede en otros equipos en los que la CPU principal debe continuar encargándose de tareas gráficas.
4. Operando con el Subsistema
El sistema principal y el SS están conectados, no sólo por el área compartida de memoria, sino también mediante la señal de HALT y la señal BUSY, permitiendo la sincronización mutua.
Esta sincronización puede llegar a ser algo compleja a la hora de controlar ambos sistemas. Dado que el área compartida forma parte de la memoria estándar de ambos procesadores, puede ser accedida simultáneamente por ambos, ninguno debe esperar por el otro.
Adicionalmente, si desde el sistema principal se escribe sobre el área compartida mientras el SS se encuentra procesando esa misma ubicación, el SS no podrá continuar su trabajo correctamente.
Por lo anterior queda patente que es necesario establecer un mecanismo de sincronización entre ambos sistemas, aquí es donde entran en juego las señales HALT y BUSY anteriormente mencionadas.
La señal BUSY está conectada desde el I/O del SS al I/O del sistema principal e informa a este último del estado “Ready/Busy” (Listo/Ocupado) del SS.
Cuando el SS está esperando comandos desde el principal se encuentra en estado “Ready”, pasando a “Busy” cuando comienza a procesar comandos.
En el sistema principal, la señal será visible mediante el bit más significativo de $FD05, siendo “Busy” cuando el bit sea 1 y “Ready” cuando este valga 0.
Así pues, el sistema principal deberá estar pendiente del valor de dicho bit en $FD05 y cuando este sea 0 (Ready), acceder a la RAM compartida y enviar los comandos.
La señal HALT es una línea conectada a la entrada HALT de la subCPU desde el sistema I/O del principal y permite forzar la detención del SS. Para ello, inicializaremos a 1 el bit más significativo de $FD05 desde el sistema principal, eso generará dicha señal.
Si queremos que la subCPU retome el trabajo, inicializaremos el bit de nuevo a 0.
Visto lo anterior, el flujo de comandos del sistema principal al SS será como sigue:
A) Esperar a que el SS esté “Ready” (chequear que MSB de $FD05=0).
B) Cuando el SS esté “Ready”, detener la subCPU con un HALT (inicializar MSB de $FD05 a 1).
C) Esperar hasta que la subCPU se encuentre detenida (chequear que MSB de $FD05=1).
D) Escribir en la RAM compartida los comandos.
E) Poner en marcha de nuevo la subCPU (inicializar MSB de $FD05 a 0)
5. El comando de mantenimiento del Subsistema
El comando de mantenimiento del SS es un comando diseñado para gestionar las operaciones entre el SS y el sistema principal.
Este comando no se supone que vaya a ser empleado por un usuario estándar de la máquina; pero si se desea programar juegos o de cualquier manera, acceder a la máxima velocidad gráfica, es fundamental dominar la técnica.
El código del comando es $3F, los comandos dirigidos al SS se escriben en la RAM compartida a partir de $FC82 ($D382 del SS).
Se debe comenzar especificando ese código, $3F y a continuación si se trata de un FM-8 la palabra clave: “YAMAUCHI”, si se trata de un FM-7 cualquier cadena servirá.
Tras la palabra clave se especificará el subcomando. Hay cuatro subcomandos:
1. $90 – Fin del comando de mantenimiento.
2. $91 <Origen> <destino> <número bytes> - Transferir bloque.
3. $92 <Dirección> - Cambiar dirección de la columna del subcomando.
4. $93 <Dirección> - Saltar a subrutina, equivalente a JSR <Dirección>.
Del subcomando 4 hay un programa de ejemplo a continuación.
6. Programa de ejemplo en BASIC
El programa de ejemplo a continuación extrae la ROM del SS de un FM-7/8 para poderla emplear en un emulador.
En primer lugar se vuelca el contenido de la RAM del banco secundario comprendida entre $D800 y $FFFF sobre la memoria principal, direcciones $2000-$4FFF y a continuación, a través del RS232C se transfiere vía serie dicho fragmento de memoria.
Línea 100: Invocamos rutina de control del SS,
Líneas 110-130: Se escribe el comando de control a la RAM compartida ($FC82-). El comando de control es el siguiente: Subcomando $91, transfiere $40 bytes de $D800 a $D3C0 (RAM compartida).
Línea 140: Reinicio del SS.
Líneas 160-180: Se transfieren $40 bytes de $FCC0 de $2000 en adelante.
Líneas 230-250: Se incrementa la dirección origen de transferencia (ubicada en $FC8C/8D) en $40 bytes y si no se ha alcanzado $FFFF se transfieren los siguientes $40 bytes. Si se ha alcanzado el fin, se continúa con la transferencia por serie.
Líneas 1000-1030: Rutina de control del SS, pasos A) a C) (Esperar por “Ready”, HALT subCPU).
Organización de la RAM compartida
Dirección RAM principal Dirección RAM secundaria Byte Descripción
$FC82 $D382 $3F Comando de mantenimiento
$FC83 $D383 $59 Y
$FC84 $D384 $41 A
$FC85 $D385 $4D M
$FC86 $D386 $41 A
$FC87 $D387 $55 U
$FC88 $D388 $43 C
$FC89 $D389 $48 H
$FC8A $D38A $49 I
$FC8B $D38B $91 Subcomando de transferencia
$FC8C $D38C $D8 Dirección origen
$FC8D $D38D $00
$FC8F $D38F $D3 Dirección destino
$FC90 $D390 $C0
$FC91 $D391 $00 Número de bytes
$FC92 $D392 $40
$FC93 $D393 $90 Fin de subcomando
… … … …
$FCC0- $D3C0- Zona de transferencia datos
Código: Seleccionar todo
10 CLEAR 300,&H2000:AD=&H2000:CLS
20 DIM D%(20)
30 FOR I=0 TO 16
40 READ A$: D%(I)=VAL(A$)
50 NEXT
55 Sub System Maintainance Command
60 DATA &H3F,&H59,&H41,&H4D,&H41,&H55,&H43,&H48,&H49,&H91,&HD8,&H00,&HD3,&HC0,&H00,&H40,&H90
100 GOSUB 1000SUB SYSTEM HALT
110 FOR I=0 TO 16
120 POKE &HFC82+I,D%(I)
130 NEXT
140 POKE &HFD05,0 START
150 GOSUB 1000
160 FOR I=0 TO &H3F
170 POKE AD+I,PEEK(&HFCC0+I)
180 NEXT
190 AD=AD+&H40
200 POKE &HFC80,PEEK(&HFC80) OR &H80
210 POKE &HFD05,0
220 LOCATE 1,10:PRINT HEX$(D%(10)*256+D%(11)+&H3F)
230 D%(11)=D%(11)+&H40
240 IF D%(11)>&HFF THEN D%(11)=0:D%(10)=D%(10)+1
250 IF D%(10)>&HFF THEN GOTO 300 ELSE GOTO 100
300 PRINT"SEND SUB SYSTEM ROM Y or N";
310 C$=INPUT$(1)
320 IF C$="y" OR C$="Y" THEN GOTO 400
330 IF C$="n" OR C$="N" THEN END
340 GOTO 310
400 OPEN "O",#1,"COM0:S8N1"
420 FOR I=&H2000 TO &H47FF
430 PRINT #1,CHR$(PEEK(I));
440 LOCATE 1,13:PRINT I-&H1FFF
450 NEXT
460 CLOSE
470 PRINT:PRINT"COMPLETE"
480 END
1000 IF (PEEK(&HFD05)AND &H80)<>0 THEN 1000 BUSY CHECK
1010 POKE &HFD05,&H80 HALT
1020 IF (PEEK(&HFD05)AND &H80)=0 THEN 1020 READY CHECK
1030 RETURN
Continúa en Tutorial (II)...