Home
Home
Principio Anterior Contenido Próximo Término
Principio - Anterior - Contenido - Próximo - Término
English Deutsch Italiano
English - Deutsch - Italiano

Apéndice E: Formatos de Fichero del Emulador

En este apéndice se describen los formatos de fichero de uso común en el campo de la emulación del Commodore 64. Está dirigido a los interesados en programación que quieran estudiar el funcionamiento interno del emulador. Si sólo quiere jugar a su juego favorito de C64, no tiene que preocuparse por los detalles aquí expuestos.

Power64 utiliza diferentes iconos para los diferentes formatos de archivo. Como Power64 permite la utilización de archivos comprimidos GZ/ZIP o LHA, muchos de los iconos están divididos en tres subtipos. Un icono simple indica archivos sin comprimir, un icono con una franja amarilla indica compresión GZ y un icono con una franja roja indica compresión ZIP. Los archivos con compresión LHA no llevan un icono especial indicando el tipo de archivo. Debido a que son muy raros, se utiliza un único icono de documento LHA para todos los archivos con compresión LHA.

E.1 Formato de Programa *.P00

P00 Icon

El formato de programa *.P00 es un formato de fichero versátil que es capaz de alojar todos los tipos usuales de archivos del C64. Como contiene una constante 'mágica' en el encabezamiento del fichero, también permite que el emulador detecte que no se usan archivos inadecuados. De ahí que sea el formato recomendado para ficheros individuales.

typedef struct
 {
  Byte P00Magic[8];    /* $00 - $07 */
  Byte OrigFName[17];  /* $08 - $18 */
  Byte RecordSize;     /* $19 */
  Byte Data[n];        /* $1A - ... */
 } P00File;
P00Magic - Constante 'mágica' C64File = {$43, $36, $34, $46, $69, $6C, $65, $00}
OrigFName - Nombre original del fichero de C64 (en caracteres CBM)
RecordSize- Tamaño de registro para archivos RELativos
Data - Los datos en sí

Este formato de fichero fue utilizado por vez primera por Wolfgang Lorenz en PC64. Observe que la extensión *.P00 no es fija, sino que la 'P' significa 'PRG' y puede convertirse en una 'S' para 'SEQ', o 'R' para 'REL'. Además el '00' puede usarse para contar '01', '02', '03'… para disolver conflictos entre nombres causados por el truncamiento de un nombre de archivo de 16 caracteres al formato 8+3 de MS-DOS. Por supuesto ésto no concierne al Macintosh, es sólo una aclaración por si se encuentra con un algún fichero *.P01.

E.2 Formato de Programa *.C64

C64/PRG Icon

El formato *.C64 es exactamente el mismo formato que utiliza el Commodore 64 original para almacenar programas en disquete o cinta.

typedef struct
 {
  Byte LoadAddrLow, LoadAddrHigh; /* $00 - $01 */
  Byte PrgData[n];                /* $02 - ... */
 } C64File;
LoadAddr - Dirección de la RAM en la que se cargará el programa desde el dispositivo secundario número 1.
PrgData - El programa en sí.

Este formato de archivo fue presentado en el mundo de los emuladores por Miha Peternel en C64S. Como puede verse por la definición de arriba, éste es un formato sencillo. Sin embargo su empleo no es recomendado, ya que no permite al emulador asegurarse de que sólo se utilicen ficheros válidos.

E.3 Formato de Imagen de Disco *.X64

X64 Icon

*.X64 es un versátil formato de archivos para imágenes de disco que incorpora una amplia variedad de disquetes. Observe pues, que el mecanismo de *.X64 de Power64 sólo puede manejar disquetes 1541.

typedef struct
 {
  Byte X64Magic[4];   /* $00 - $03 */
  Byte Version[2];    /* $04 - $05 */
  Byte DiskType;      /* $06 */
  Byte TrackCnt;      /* $07 */
  Byte SecondSide;    /* $08 */
  Byte ErrorFlag;     /* $09 */
  Byte Reserved[22];  /* $0A - $1F */
  Byte DiskInfo[31];  /* $20 - $3E */
  Byte ConstZero;     /* $3F */
  Byte DiskImage[683 * 256];
 } X64File;
X64Magic - Constante 'mágica' 'C'1541/64 = {$43, $15, $41, $64}
Version - Versión 2.6 de C1541 = {$02, $06}
DiskType - Tipo de disquete: 1541 = {$01} Otros valores definidos: (no utilizables con Power64)
0..1540, 1..1541, 2..1542, 3..1551,
4..1570, 5..1571, 6..1572, 8..1581,
16..2031 y 4031, 17..2040 y 3040, 18..2041
24..4040,
32..8050, 33..8060, 34..8061,
48..SFD 1001, 49..8250, 50..8280
TrackCnt - Número de pistas del disquete (Lado 0) = {35}
SecondSide- ¿Es un disquete de dos caras? (0..No, 1..Sí) = {$00}
ErrorFlag - Señal de error (no se conoce su significado preciso) (no se usa)
Reserved - Debe ser $00
DiskInfo - Descripción de la imagen de disco (en ASCII o ISO Latin/1)
ConstZero - Debe ser $00
DiskImage - 683 sectores de disco de 256 bytes cada uno.
(Para más información sobre imágenes de disco vea también: *.D64)

El formato de imagen de disco *.X64 fue creado originalmente por Teemu Rantanen para usarlo en X64.
Como *.X64 emplea un encabezamiento bien definido, el emulador puede asegurarse de que sólo se usan ficheros válidos.
Ésta es una clara ventaja sobre el (desafortunadamente más difundido) formato *.D64.

E.4 Formato de Imagen de Disco *.D64

D64 Icon

El formato *.D64 es una copia idéntica de los sectores tal como aparecen en un disquete.
En un disquete iniciado con C1541 (y por ende en un fichero *.D64) cada sector consiste de 256 bytes. Con el fin de tratar con posibles sectores defectuosos, el formato *.D64 incluye optativamente un byte de errores por cada sector. Un disquete que haya sido iniciado usando la orden NEW de C1541 tendrá 35 pistas con un total de 683 sectores. Mediante el uso de software especial se pueden iniciar y grabar disquetes con hasta 40 pistas. Aunque no están dentro de las especificaciones originales, tales disquetes son utilizables con la mayoría de las unidades C1541. (Nota: Su lectura no precisa software especial).

Actualmente hay cuatro formatos *.D64 diferentes:

Advierta que las pistas exteriores del disquete contienen más sectores que las interiores.
La cantidad de sectores de cada pista es:

      Pistas   1..17 - 21 Sectores
      Pistas  18..24 - 19 Sectores
      Pistas  25..30 - 18 Sectores
      Pistas  31..35 - 17 Sectores
      Pistas  36..40 - 17 Sectores (¡no estándar!)

La tabla de asignación de bloques se almacena en la pista 18, sector 0; el directorio comienza en la pista 18, sector 1.

Para el almacenamiento en una imagen *.D64 los sectores se ordenan de la forma siguiente:

  Pista  1 - Sector  0: Desplazamiento   0 * 256
  Pista  1 - Sector  1: Desplazamiento   1 * 256
                .....
  Pista  1 - Sector 20: Desplazamiento  20 * 256
  Pista  2 - Sector  0: Desplazamiento  21 * 256
  Pista  2 - Sector  1: Desplazamiento  22 * 256
                .....
  Pista  2 - Sector 20: Desplazamiento  41 * 256
  Pista  3 - Sector  0: Desplazamiento  42 * 256
                .....
  Pista 18 - Sector  0: Desplazamiento 357 * 256
  Pista 18 - Sector  1: Desplazamiento 358 * 256
                .....
  Pista 35 - Sector  0: Desplazamiento 666 * 256
  Pista 35 - Sector  1: Desplazamiento 667 * 256
                .....
  Pista 35 - Sector 16: Desplazamiento 682 * 256

Tenga en cuenta que las pistas se cuentan comenzando en la pista 1, mientras que los números de sector comienzan en 0.

typedef struct
 {
  Byte DiskImage[SectorCnt][256];
  Byte ErrorInfo[SectorCnt]; /* Optativo */
 } D64File;
DiskImage - 256 bytes por sector
ErrorInfo - 1 byte por sector

Advierta que las marcas de errores se aglomeran al final del archivo. No se intercala la información de errores al final de cada sector.
El significado de ErrorInfo se aclara en la siguiente tabla:

    Código  Error  Tipo       Reseña del error de 1541
    ------  -----  ---------  ------------------------------
      01     00    N/A        Sin errores, sector en orden
      02     20    Lectura    Encabezamiento no encontrado
      03     21    Búsqueda   Falta marca de sincronización
      04     22    Lectura    Falta bloque de datos
      05     23    Lectura    Error de comprobación del bloque de datos
      06     24    Grabación  Error de verificación de grabación (al iniciar)
      07     25    Grabación  Error de verificación de grabación
      08     26    Grabación  Protección contra grabación
      09     27    Búsqueda   Error de comprobación en encabezamiento
      0A     28    Grabación  Error de grabación
      0B     29    Búsqueda   Desigualdad del identificador de disco
      0F     74    Lectura    Disco no preparado (ausencia del dispositivo 1)

E.5 Formato de Archivo ZipCode (1!*, 2!*, …)

ZipCode Icon

Éste es una versión comprimida de un archivo D64 que suele encontrarse en sitios de C64 de cierta trayectoria (y que han servido a los usuarios de C64 antes de que se popularizase la emulación). Un fichero D64 individual se fracciona en 4 ó 5 segmentos, para 35 y 40 pistas respectivamente. A continuación se empaqueta cada porción usando el sencillo (e ineficaz) método de compresión por cifrado de la longitud de carrera (RLE: Run Lenght Encoding).

La principal razón de la existencia de este formato es que cada segmento de un fichero ZipCode abarca menos de 44 KByte, con lo que un auténtico C64 y su unidad de disco 1541 pueden manejarlo (p.e. después de recibirlo por modem de un BBS). Además el empaquetado y desempaquetado se realizan muy rápido en un C64.

Los computadores de hoy en día, como los Power Macintosh, en los que se usan emuladores de C64, no tienen inconvenientes para trabajar con archivos de 171 KByte (como los D64), así que no obtienen ningún beneficio de la división de ficheros 'grandes' en varios pequeños. Es más, debido a los bloques de asignación más grandes de las unidades de disco rígido y disco compacto actuales, el espacio desperdiciado por los 4 bloques a medio llenar de los 4 ficheros bien podría superar el ahorro de espacio por compresión, tratándose de disquetes bien cargados. Además, los formatos de compresión modernos como Zip, GZ, LHA o SIT ofrecen una compresión mucho más eficaz que la RLE empleada en ZipCode.

Aunque ZipCode no es la mejor solución para un emulador sigue siendo un formato útil en un C64 de verdad, y muchos sitios ofrecen sus ficheros en este formato para apoyar a los leales seguidores que conservan sus equipos originales.

Observe que hay además otros dos formatos Zip para el C64, que no funcionan con Power64. En ellos se usan los prefijos 1!!, 2!!, 3!!… y A!, B!, C!… respectivamente. Se detallan en la colección sobre formatos de archivos de Peter Schepers, autor de 64COPY (schepers@dcs1.uwaterloo.ca), pero nunca he visto ficheros con ninguno de estos dos formatos en la red.

El contenido del disquete se distribuye entre los 4 ó 5 segmentos de acuerdo con la siguiente tabla:

    Nombre     Pistas   Cant. de Bloques
   --------  ---------  ----------------
   1!xxxxxx    1 - 8     168 Sectores
   2!xxxxxx    9 - 16    168 Sectores
   3!xxxxxx   17 - 25    172 Sectores
   4!xxxxxx   26 - 35    175 Sectores
   5!xxxxxx   36 - 40     85 Sectores (sólo para discos de 40 pistas)

Todos los segmentos poseen una estructura parecida, basada en los sectores del disco comprimidos. Note que el encabezamiento del primer segmento difiere un poco de los otros.

typedef struct
 {
  Byte LoadAddr[2];     /* Const. $03FE = { 0xFE, 0x03}; */
  Byte FloppyID[2];
  ZipSector Image[168];
 } ZipSegment_1!;
typedef struct
 {
  Byte LoadAddr[2];     /* Const. $0400 = { 0x00, 0x04}; */
  ZipSector Image[...];
 } ZipSegment_n!;       /* n = {2, 3, 4, 5} */

La compresión se efectúa sector por sector. Para cada sector existe la siguiente estructura:

typedef struct
 {
  Byte Track;     /* Número de pista y modo de compresión */
  Byte Sector;    /* Número de sector */
  union {
    { Byte NoCompression[256]; } Mode00;
    { Byte SingleByte; } Mode01;
    { Byte Length;
      Byte RepeatChar;
      Byte RLEData[Length]; } Mode10;
   } Data;
 } ZipSector;
Track - contiene el número de pista del sector comprimido en los bits del 5 al 0. Los bits 7 y 6 indican el modo de compresión.
Sector- contiene el número del sector comprimido.
Data - El significado de Data depende del modo de compresión:

Modos de compresión:

00 - Sin compresión, el sector se almacena íntegramente. Los 256 bytes de datos reflejan el contenido del sector.
01 - Se rellena todo el sector con un byte determinado. El mismo se repetirá 256 veces para ocupar todo el sector.
10 - Sector con cifrado de carrera - Lenght indica el número de bytes de datos comprimidos por RLE. RepeatChar es un byte que no aparecía en el sector original y que ahora se usa para delimitar las porciones de datos con cifrado de carrera. RLEData distinto de RepeatChar, no es más que información sin comprimir, que puede copiarse directamente. Cuando se encuentra RepeatChar, el byte siguiente indica la longitud de carrera y un tercer byte denota el carácter a repetir.
11 - No se usa.

Los sectores de una pista NO se almacenan en orden creciente (1, 2, 3, 4…). Para que el empaquetado y desempaquetado sean mucho más rápidos en una 1541 auténtica, se utiliza interpaginado. La secuencia de sectores apropiada depende del número de sectores por pista y se muestra debajo.

Pistas  1-17:  0 11 1 12 2 13 3 14 4 15 5 16 6 17 7 18 8 19 9 20 10
Pistas 18-24:  0 10 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9
Pistas 25-30:  0  9 1 10 2 11 3 12 4 13 5 14 6 15 7 16 8 17
Pistas 31-40:  0  9 1 10 2 11 3 12 4 13 5 14 6 15 7 16 8

Ejemplo de los primeros sectores del primer segmento(1!*):

$0000: 0xFE, 0x03,       /* Dirección de carga Const $03FE */
$0002: 0x36, 0x34,       /* Identificación del disquete */
$0004: 0x41, 0x00, 0x00, /* Pista 1, Sector  0 relleno con 0x00 */
$0007: 0x41, 0x0B, 0x00, /* Pista 1, Sector 11 relleno con 0x00 */
$000B: 0x41, 0x01, 0x00, /* Pista 1, Sector  1 relleno con 0x00 */
$0007: 0x01, 0x0C,       /* Pista 1, Sector 12 datos sin comprimir */
... 256 bytes de datos ...
$0109: 0x81, 0x02,       /* Pista 1 ,Sector 2 Cifrado RLE */
       0x12, 0xEA,       /* Byte 0x12(18), RepeatChar: 0xEA */
       0x45, 0x22, 0x34, 0x08,/* Datos */
       0xEA, 0xD0, 0x77,      /* 0x77 repetido 0xD0 veces */
       0x12, 0xFF, 0x00, 0x00, 0x32, 0x11 /* Datos */
       0xEA, 0x24, 0x55,      /* 0x55 repetido 0x24 veces */
       0xEE, 0x98,            /* Datos */
$011F: 0x41, 0x0D, 0x11  /* Pista 1, Sector 13 relleno con 0x11 */
$0122: ...

E.6 Formato de Imagen de Disco *.D71

D71 Icon

El formato de archivo *.D71 es una copia 1:1 de todos los sectores que aparecen en un disquete 1571. En un disco C1571 formateado (y por tanto también en un archivo *.D71) cada sector está formado por 256 Bytes. Para tratar los sectores dañados el formato *.D71 dispone opcionalmente de un byte de error adicional por sector.

La unidad de disco 1571 utiliza discos de 5.25" de doble cara que contienen 35 pistas por cada lado (haciendo un total de 70 pistas). Las pistas de la parte más externa del disco contienen más sectores que aquellas que están cerca del centro del disco (Zone Bit Recording). El número de sectores de cada pista es:

      Pistas  1..17 - 21 Sectores
      Pistas 18..24 - 19 Sectores
      Pistas 25..30 - 18 Sectores
      Pistas 31..35 - 17 Sectores
      Pistas 36..52 - 21 Sectores (como las Pistas  1..17 - otra cara del disco)
      Pistas 53..59 - 19 Sectores (como las Pistas 18..24 - otra cara del disco)
      Pistas 60..65 - 18 Sectores (como las Pistas 25..30 - otra cara del disco)
      Pistas 66..70 - 17 Sectores (como las Pistas 31..35 - otra cara del disco)

Comparando esto con la distribución de una imagen de disco *.D64 tal y como se describe en el Apéndice E.4 se ve fácilmente que una imagen de disco *.D71 se compone simplemente de dos imágenes *.D64 pegadas juntas.

El Mapa de Asignación de Bloques (BAM) se almacena en la Pista 18 - Sector 0 y en la Pista 53 - Sector 0. El Directorio comienza en la Pista 18 - Sector 1.

Para el almacenamiento en una imagen *.D71 los sectores se disponen de la siguiente manera:

  Pista  1 - Sector  0: Desplazamiento   0 * 256
  Pista  1 - Sector  1: Desplazamiento   1 * 256
                .....
  Pista  1 - Sector 20: Desplazamiento  20 * 256
  Pista  2 - Sector  0: Desplazamiento  21 * 256
  Pista  2 - Sector  1: Desplazamiento  22 * 256
                .....
  Pista  2 - Sector 20: Desplazamiento  41 * 256
  Pista  3 - Sector  0: Desplazamiento  42 * 256
                .....
  Pista 18 - Sector  0: Desplazamiento 357 * 256
  Pista 18 - Sector  1: Desplazamiento 358 * 256
                .....
  Pista 35 - Sector  0: Desplazamiento 666 * 256
  Pista 35 - Sector  1: Desplazamiento 667 * 256
                .....
  Pista 35 - Sector 16: Desplazamiento 682 * 256
                .....
  Pista 36 - Sector  0: Desplazamiento 683 * 256
  Pista 36 - Sector  1: Desplazamiento 684 * 256
                .....
  Pista 36 - Sector 20: Desplazamiento 703 * 256
                .....
  Pista 70 - Sector  0: Desplazamiento 1349 * 256
  Pista 70 - Sector  1: Desplazamiento 1350 * 256
                .....
  Pista 70 - Sector 16: Desplazamiento 1365 * 256

Tenga en cuenta que las pistas se cuentan comenzando en la pista 1, mientras que los número de sector comienzan en 0.

E.7 Formato de Imagen de Disco *.D81

D81 Icon

El formato de archivo *.D81 es una copia 1:1 de todos los sectores que aparecen en un disquete 1581. En un disco C1581 formateado (y por tanto también en un archivo *.D81) cada sector está formado por 256 Bytes. Para tratar los sectores dañados el formato *.D81 dispone opcionalmente de un byte de error adicional por sector.

La unidad de disco 1571 utiliza discos de 3.5" de doble cara que contienen 40 pistas por cada lado (haciendo un total de 80 pistas). Todas las pistas pares se encuentran en una cara del disco, y todas las pistas impares en la otra. Por tanto la pista 40 se encuentra en la mitad del disco. Cada pista contiene 40 sectores, por tanto una imagen de disco 1581 completa contiene 80*40 = 3200 sectores.

El bloque maestro del disco se encuentra en la Pista 40 -Sector 0. Esta seguido del Mapa de Asignación de Bloques (BAM) en la Pista 40 - Sector 1 y Sector 2 y el Directorio comienza en la Pista 40 - Sector 3.

Como todas las pistas tienen el mismo tamaño el desplazamiento de un sector en un disco *.D81 puede calcularse con una simple fórmula:
Desplazamiento = (40 * (Pista - 1) + Sector) * 256

Tenga en cuenta que las pistas se cuentan comenzando en la pista 1, mientras que los número de sector comienzan en 0.

E.8 Formato de Archivo *.Lynx

Lynx Icon

El formato de archivo Lynx (o LNX o Ultimate Lynx) fue desarrollado por Will Corley para usarlo en el C64(¡!). Consiste en bloques de 254 bytes, que corresponden a los 256 bytes de un sector de disquete 1541 menos los 2 bytes que contienen la especificación de la siguiente pista y sector, y facilita la copia entre disquetes 1541 y ficheros Lynx.
Desgraciadamente el encabezamiento Lynx se graba en un formato un poco más difícil de tratar que el de un fichero T64 o D64, por lo que este formato recibió poca atención por parte de los programadores de emuladores.

typedef struct
 {
  Byte Directory[DirSectorCnt * 254];
  Byte Data[DataSectorCnt * 254];
 } LynxFile;

El directorio empieza por un pequeño programa en BASIC que, al cargarlo y ejecutarlo, muestra el mensaje 'Use LYNX to dissolve this file' (Utilice LYNX para disolver este archivo). El mensaje y el tamaño del programa pueden variar. Generalmente, ocupa 94 bytes, desde $0000 hasta $005D. Observe que algunos emuladores necesitan una longitud de exactamente 94 bytes, y que además la palabra 'LYNX' se encuentre en la posición de $003C a $003F.

$0000: 0x01, 0x08, 0x5B, 0x08, 0x0A, 0x00, 0x97, 0x35, /* .......5 */
$0008: 0x33, 0x32, 0x38, 0x30, 0x2C, 0x30, 0x3A, 0x97, /* 3280,0:. */
$0010: 0x35, 0x33, 0x32, 0x38, 0x31, 0x2C, 0x30, 0x3A, /* 53281,0: */
$0018: 0x97, 0x36, 0x34, 0x36, 0x2C, 0xC2, 0x28, 0x31, /* .646,.(1 */
$0020: 0x36, 0x32, 0x29, 0x3A, 0x99, 0x22, 0x93, 0x11, /* 62):.".. */
$0028: 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, /* ......." */
$0030: 0x3A, 0x99, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, /* :."      */
$0038: 0x55, 0x53, 0x45, 0x20, 0x4C, 0x59, 0x4E, 0x58, /* USE LYNX */
$0040: 0x20, 0x54, 0x4F, 0x20, 0x44, 0x49, 0x53, 0x53, /*  TO DISS */
$0048: 0x4F, 0x4C, 0x56, 0x45, 0x20, 0x54, 0x48, 0x49, /* OLVE THI */
$0050: 0x53, 0x20, 0x46, 0x49, 0x4C, 0x45, 0x22, 0x3A, /* S FILE": */
$0058: 0x89, 0x31, 0x30, 0x00, 0x00, 0x00,             /* .10...   */

Esto equivale al siguiente programa en BASIC:

  10 POKE53280,0:POKE53281,0:POKE646,PEEK(162):
        PRINT"<CLS><DOWN><DOWN><DOWN><DOWN><DOWN><DOWN><DOWN><DOWN>":
        PRINT"     USE LYNX TO DISSOLVE THIS FILE":
        GOTO10

A continuación de esto se encuentra un <CR> (carácter de retorno de carro) y el número de bloques del directorio en ASCII con espacios al principio y al final. Para un directorio con un solo bloque sería:

$005E:  0x0D, 0x20, 0x31, 0x20, 0x20                    /* . 1     */

Después de esto está la signatura del archivo: un texto en minúsculas en CBM (equivalente a ASCII en su mayor parte) terminado en un <CR>, que describe el archivo Lynx. Normalmente esta signatura contendrá la cadena 'LYNX'.
Power64 emplea la siguiente:

$0063: 0x2A, 0x4C, 0x59, 0x4E, 0x58, 0x20, 0x41, 0x52, /* *LYNX AR */
$006B: 0x43, 0x48, 0x49, 0x56, 0x45, 0x20, 0x42, 0x59, /* CHIVE BY */
$0073: 0x20, 0x50, 0x4F, 0x57, 0x45, 0x52, 0x36, 0x34  /*  POWER64 */
$007B: 0x0D

A lo que sigue el número de ficheros del archivo Lynx. Como antes esto se indica con un número en ASCII entre espacios y delimitado con un <CR>.
Para un directorio con 3 ficheros sería:

$007C: 0x20, 0x33, 0x20, 0x0D                          /*  3 .     */

Tras estos encabezamientos se halla el directorio en sí. Cada fichero se especifica con su nombre (en PETASCII, a menudo suplementado con mayúsculas+espacio hasta 16 caracteres), seguido por el tamaño del fichero (más 2 bytes para las direcciones) en bloques de 254 bytes, el tipo de fichero (P, S, R, U) y el tamaño en bytes del bloque anterior. Si el fichero es de tipo relativo, este valor es el tamaño de registro, y el siguiente es el tamaño del bloque anterior. Si no lo es, el siguiente valor será el nombre del fichero que sigue. Los ficheros relativos no funcionan con Power64. Cada valor se delimita con un <CR>, y los números se señalan entre espacios. Por ejemplo:

Fichero 1: "Block Out", PRG, 2+2519 Byte (2521 = (10-1) * 254 + 235)
$0080: 0x42, 0x4C, 0x4F, 0x43, 0x4B, 0x20, 0x4F, 0x55, /* BLOCK OU */
$0088: 0x54, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, /* T        */
$0090: 0x0D, 0x20, 0x31, 0x30, 0x20, 0x0D, 0x50, 0x0D, /* . 10 .P. */
$0098: 0x20, 0x32, 0x33, 0x35, 0x20, 0x0D,             /*  235 .   */

Fichero 2: "Serpentine", PRG, 2+8703 Byte (8705 = (35-1) * 254 + 69)
$009E: 0x53, 0x45, 0x42, 0x4C, 0x45, 0x4E, 0x54, 0x49, /* SERPENTI */
$00A6: 0x4E, 0x45, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, /* NE       */
$00AE: 0x0D, 0x20, 0x33, 0x35, 0x20, 0x0D, 0x50, 0x0D, /* . 35 .P. */
$00B6: 0x20, 0x36, 0x39, 0x20, 0x0D,                   /*  69 .    */

Fichero 3: "Quadromania", PRG, 2+7056 Byte (7058 = (28-1) * 254 + 200)
$00BB: 0x51, 0x55, 0x41, 0x44, 0x52, 0x4F, 0x4D, 0x41, /* QUADROMA */
$00C3: 0x4E, 0x49, 0x41, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, /* NIA      */
$00CB: 0x0D, 0x20, 0x32, 0x38, 0x20, 0x0D, 0x50, 0x0D, /* . 28 .P. */
$00D3: 0x20, 0x32, 0x30, 0x30, 0x20, 0x0D,             /*  200 .   */

El contenido de los archivos va detrás del directorio. Cada archivo consta de 2 bytes de la dirección de carga más los datos en sí.

Advierta que el tamaño del directorio y de cada archivo es múltiplo de 254 bytes. Si la información precisa menos espacio, hay una brecha que se malgasta, y en Power64 se rellena con 0x00 (puede variar en otros emuladores).

En el ejemplo de arriba el directorio consiste de un solo bloque, y así Block Out comienza con el desplazamiento 1 * 254. El segundo fichero (Serpentine) principia en la posición (1+10) * 254 y Quadromania arranca desde (1+10+35) * 254.

$00FE: 0x01, 0x08, 0x26, 0x08, 0xC1, 0x07, 0x9E, 0x32, /* ..&.i..2 */
$0106: 0x30, 0x38, 0x38, 0x3A, 0x12, 0x42, 0x4C, 0x4F, /* 088:.BLO */
$011E: 0x43, 0x4B, 0xAB, 0x4F, 0x55, 0x54, ...         /* CK-OUT.. */
... /* (1+10) * 254 = $0AEA */
$0AEA: 0x01, 0x08, 0x26, 0x08, 0xC1, 0x07, 0x9E, 0x32, /* ..&.¡..2 */
$0AF2: 0x30, 0x38, 0x38, 0x3A, 0x12, 0x53, 0x45, 0x52, /* 088:.SER */
$0AFA: 0x50, 0x45, 0x4E, 0x54, 0x49, 0x4E, 0x45,...    /* PENTINE  */
...

E.9 Formato de Imagen de Cinta *.T64

T64 Icon

El formato de archivos *.T64 está muy bien diseñado (y por ello su documentación ha sido escasa). Fue desarrollado por Miha Peternel para C64S. Al igual que un fichero de imagen de disco, es capaz de alojar varios ficheros lógicos, lo que ayuda mucho para mantener organizados una gran cantidad de archivos. Por otra parte hay muy pocos 'gastos organizativos', tanto en términos de espacio ocupado en el sistema de archivos que lo hospeda, como de tiempo de carga en el emulador. Además, como contiene un encabezamiento 'mágico', hace posible que se prevenga el uso de ficheros inadecuados.

typedef struct
 {
  TapeHeader Header;          /*  $0000  -  $003F  */
  TapeEntry  Entry[MaxFiles]; /*  $0040  - ($03FF) */
  Byte       Data[n];         /* ($0400) -   ...   */
 } T64File;
Header- Información general; contiene una cadena 'mágica' para distinguir al fichero *.T64, el número de archivos en la cinta, etc… (vea debajo para más detalles)
Entry - Directorio de la cinta; un catálogo de todos los ficheros almacenados en la cinta. El valor MaxFiles se define en Header, pero suele ser 30 (vea debajo para más detalles).
Data - Los datos de todos los archivos.
typedef struct
 {
  Byte TapeDescr[32]; /* $00 - $1F */
  Byte Version[2];    /* $20 - $21 */
  Byte MaxFiles[2];   /* $22 - $23 */
  Byte CurrFiles[2];  /* $24 - $25 */
  Byte Reserved[2];   /* $26 - $27 */
  Byte UserDescr[24]; /* $28 - $3F */
 } TapeHeader;
TapeDescr- Cadena 'mágica' "C64 tape image file"; suplementada con $00
Observe que esta cadena 'mágica' no necesita ser igual palabra por palabra. Se buscan las secuencias "C64" y "tape" para identificar un fichero *.T64.
Version - Versión de cinta 1.0 = {$00, $01}
MaxFiles - Número de lugares en el directorio. Algunos emuladores cuentan con que haya exactamente 30 lugares en el directorio. Así que los archivos *.T64 creados con Power64 tendrán este valor. = {$1E, $00}
CurrFiles- Número de archivos grabados actualmente en la cinta. Este número no puede superar el valor de MaxFiles. Tenga en cuenta que algunos emuladores no pueden leer más que el primer fichero de una imagen *.T64.
Reserved - Debe ser $00.
UsedDescr- Descripción de la cinta del usuario (caracteres CBM).
typedef struct
 {
  Byte EntryUsed;     /* $00 */
  Byte FileType;      /* $01 */
  Byte StartAddr[2];  /* $02 - $03 */
  Byte EndAddr[2];    /* $04 - $05 */
  Byte ReservedA[2];  /* $06 - $07 */
  Byte TapePos[4];    /* $08 - $0B */
  Byte ReservedB[4];  /* $0C - $0F */
  Byte FileName[16];  /* $10 - $1F */
 } TapeEntry;
EntryUsed- ¿Se utiliza esta anotación del directorio? (0..No, 1..Sí)
FileType - Hay muy poca información disponible sobre este campo.
Power64 adopta la hipótesis de Star Commander de que corresponde a los especificadores de tipo de archivo usados en disquetes:
$82..Programa resituable, $81..Fichero de datos
Las versiones anteriores de Power64 usaban el siguiente criterio:
0..Programa transportable, 1.Programa de carga forzada., 2..Fichero de datos
Para evitar mensages de error, los demás valores también se interpretaban como programas transportables.
StartAddr- Comienzo del espacio de memoria de destino. (Bajo, alto)
EndAddr - Fin del espacio de memoria de destino. (Bajo, alto)
ReservedA- Debe valer $00
TapePos - Desplazamiento desde el principio de la imagen de cinta a los datos de los ficheros
ReservedB- Debe valer $00
FileName - Nombre del archivo (en caracteres CBM).

Ha habido muy poca información oficial sobre el formato *.T64. Lo que se sabe se averiguó por lo general examinando ficheros *.T64 ya existentes. A veces se hizo sin escudriñar lo suficiente. Así que hay muchos ficheros *.T64 en internet que no siguen el formato descrito. Por ejemplo, es muy común que la diferencia entre EndAddr y StartAddr no coincida con la longitud del fichero *.T64. Power64 intenta remediar automáticamente esas incompatibilidades.

Como se enuncia arriba hay algunos emuladores que cuentan con que haya exactamente 30 registros en el directorio, a la vez que siempre cargan el primer fichero. Por favor tenga esto en cuenta cuando ponga ficheros de Commodore 64 al alcance del público en general, que puede estar usando una amplia variedad de emuladores.

Todos los valores de varios bytes se almacenan con su byte de menor valor primero (bajo, alto) como se hace habitualmente en el C64.

E.10 Formato de Imagen de Cinta *.TAP

TAP Icon

El formato de imagen de cinta *.TAP (o *.RAW), ofrece una imagen muy precisa de una cinta de datos del C64. Debido al alto nivel de precisión y detalle, la mayoría de los trucos que eran posibles con la unidad de cinta del C64 pueden ser emulados. Incluso los cargadores rápidos no ofrecen ningún problema. La desventaja del formato *.TAP es su enorme cantidad de memoria (al menos 8 veces, normalmente 10-12 veces, y hasta 45 veces en el peor de los casos el tamaño de una imagen T64 que contenga los mismos datos) y el largo y lento proceso de carga (utilizando las rutinas originales de la ROM del C64 pueden leerse alrededor de 110 bytes/segundo de pico, pero debido a la redundancia para la corrección de errores la media es de 50 bytes/segundo; utilizando cargadores rápidos especiales pueden alcanzarse alrededor de 200-500 bytes/segundo).

La información en una cinta de C64 está codificada en pulsos individuales. El tiempo de espera entre dos pulsos sucesivos lleva la información actual. Exactamente estos tiempos de espera son almacenados en un archivo *.TAP.

typedef struct
 {
  Byte TAPMagic[12];    /* $00 - $0B */
  Byte Version;         /* $0C */
  Byte Reserved[3];     /* $0D - $0F */
  Byte Size[4];         /* $10 - $13 */
  Byte Data[Size];      /* $14 - ... */
 } TAPFile;
TAPMagic- Constante Mágica "C64-TAPE-RAW" = {$43, $36, $34, $2D, $54, $41, $50, $45, $2D, $52, $41, $57}
Version - $00 o $01: ver Data
Reserved- Siempre $00
Size - Tamaño del archivo *.TAP en formato Little-Endian, sin incluir la cabecera.
Data - El tiempo de espera entre dos pulsos sucesivos en la cinta.
Los valores $01-$FF representan directamente el tiempo entre dos pulsos, medido en múltiplos de 8 ciclos de CPU. (p.e. un valor de $2E significa que hay 8*$2E = $170 ciclos de CPU entre dos pulsos.
El valor $00 tiene un significado especial. En la versión $00 del formato TAP, un valor de $00 simplemente significa cualquier valor mayor que 8*$FF ciclos de CPU. En la versión $01 los tres valores siguientes al $00 dan (en formato Little-Endian) el número de ciclos de CPU (sin multiplicar por 8) que pasarán antes de que el siguiente pulso llegue.

Las rutinas de la ROM del C64 originales utilizan para codificar los datos un algoritmo bastante ineficiente pero realmente bueno para corregir errores. Cada byte de datos útiles se escribe utilizando un bit de comienzo, los 8 bits útiles (LSB primero, MSB después) y un bit de paridad (haciendo el número de bits '1' impar). El bit de comienzo consiste en un intervalo muy largo (4T) seguido de otro largo (3T). Los bits '0' se codifican con un intervalo corto (2T) seguido de otro largo (3T), y los bits '1' se codifican con un intervalo largo (3T) seguido de otro corto (2T). 'T' es una unidad de tiempo básica que es aproximadamente 8*$16 = $B0 ciclos de CPU. El valor puede variar significativa y rápidamente, ya que la unidad de cinta nunca fue optimizada para un movimiento uniforme. Las rutinas de la ROM intentan compensar esto ajustando constantemente un parámetro de velocidad de la cinta. Un intervalo muy largo (4T) seguido de otro corto (2T) indican el final de un bloque de datos.
Estimación de la eficiencia: para un byte de datos útiles la cinta necesita (4+3)+9*(3+2)=52T.
Esto se corresponde aproximadamente con 52 * 8 * $16 = 9152 ciclos de CPU, consiguiendo un proceso de alrededor de 110 bytes/segundo. Como cada bloque se almacena dos veces para permitir la corrección de errores y hay espacios sin utilizar entre las copias, menos de la mitad del proceso (aproximadamente 50 bytes/segundo) está disponible para los datos útiles.
Por otro lado, almacenar un byte útil necesita 2+9*2 = 20 intervalos para codificación de un byte. Para permitir la compensación de errores todos los datos se almacenan dos veces, haciendo un total de 40 bytes del tamaño de un archivo TAP para cada byte de información útil. Además muchos achivos TAP contienen generosos espacios libres entre sus áreas utilizadas, incrementando aún más el tamaño de los archivos.

Los distintos cargadores rápidos almacenan sus datos en formatos propios diferentes. En general ganan eficiencia utilizando sólo un único intervalo para cada bit útil, reduciendo el tamaño de cada intervalo, dejando los bits de comienzo y de paridad y almacenando los datos completos una sola vez. Aunque esto reduce drásticamente la posibilidad de detectar y corregir errores, consigue aumentar la velocidad de la carga hasta 200-500 bytes/segundo. Al mismo tiempo el tamaño del archivo TAP se reduce aproximadamente en 8 veces el tamaño de los datos útiles que contiene.

La Central de Información de Cintas del Commodore 64 disponible en http://www.geocities.com/SiliconValley/Platform/8224/c64tape/index.html dispone de información detallada sobre muchos formatos de cinta.

Si está interesado en pasar datos desde cintas físicas a tu Mac, debería leer el FAQ sobre Transferencia de Cintas del Commodore 64 disponible en: http://www.geocities.com/SiliconValley/Platform/8224/c64tape/faq.html. También encontrará enlaces (DOS/Windows-, por desgracia no para Mac-) a herramientas que convierten archivos WAV en imágenes TAP o T64.

E.11 Formato de Módulo de ROM *.CRT

Cartridge Icon

El formato de módulo de ROM *.CRT es bastante versátil y permite cifrar de forma eficaz una amplia variedad de módulos. Además es fácil de interpretar, tiene una cadena 'mágica' fácilmente reconocible y consume pocos gastos administrativos.

Un fichero CRT consiste fundamentalmente de un encabezamiento de módulo que contiene información general, seguido de uno o más paquetes que encierran el contenido de un circuito integrado de ROM.

Todos los valores de más de un byte se almacenan con sus bytes de orden alto a orden bajo.

typedef struct
 {
  Byte CartrigeMagic[16];  /* $00 - $0F */
  Long HeaderSize;         /* $10 - $13 */
  Word Version;            /* $14 - $15 */
  Word HardwareType;       /* $16 - $17 */
  Byte ExROM_Line          /* $18 */
  Byte Game_Line           /* $19 */
  Byte Unused[6];          /* $1A - $1F */
  Byte CartridgeName[32];  /* $20 - $3F */
 } CartridgeHeader;
CartridgeMagic- Constante mágica 'C64 CARTRIDGE ' =
{$43, $36, $34, $20, $43, $41, $52, $54,
$52, $49, $44, $47, $45, $20, $20, $20}
HeaderSize - sizeof(CartridgeHeader) = 64 = {$00, $00, $00, $40}
Version - Versión de CRT 1.0 = {$01, $00}
HardwareType - En el formato CRT se resumen los formatos de muchos tipos diferentes de módulos. Todos éstos contienen alguna ROM (como planearon los diseñadores del C64), pero además de eso algunos módulos incluyen RAM o circuitos lógicos. Por lo general se usaron estos diseños para proyectos individuales, así que el trabajo necesario para su emulación difícilmente vale la pena. Power64 admite los tipos de cartuchos 0, 4, 6, 7, 8, 11 y 12, que cubren toda la variedad de juegos.
0 - Cartucho normal
1 - Action Replay
2 - KCS Power Cartridge
3 - Final Cartridge III
4 - Simon's Basic
5 - Ocean tipo 1 (256 y 128 KByte)
6 - Expert Cartridge
7 - Fun Play
8 - Super Games
9 - Atomic Power
10 - Epyx Fastload
11 - Westermann
12 - Rex
13 - Final Cartridge I
14 - Magic Formel
ExROM_Line - Señal de la línea ExROM (para configurar la memoria)
Game_Line - Señal de la línea Game (para configurar la memoria)
CartridgeName- Nombre inteligible del módulo (cadena con delimitador nulo)
typedef struct {
  Byte ChipMagic[4];  /* 0x00 - 0x03 */
  Long PacketLength;  /* 0x04 - 0x07 */
  Word ChipType;      /* 0x08 - 0x09 */
  Word Bank;          /* 0x0A - 0x0B */
  Word Address;       /* 0x0C - 0x0D */
  Word Length;        /* 0x0E - 0x0F */
  Byte Data[Length];  /* 0x10 - ...  */
 } ChipPacket;
ChipMagic - Constante 'mágica' 'CHIP' = {$43, $48, $49, $50}
PacketLength- Tamaño del paquete (= Length + 0x10)
ChipType - 0..ROM, 1..RAM (campo de datos vacío), 2..EEPROM
Bank - para módulos de varios bancos de memoria (si hay un solo banco: 0)
Address - Dirección de carga de los módulos de ROM (generalmente $8000 o $A000)
Length - Tamaño de la ROM (usualmente $1000, $2000 o $4000)
Data - Contenido de la ROM

Ejemplo: Módulo del Simon's Basic

$0000: 0x43, 0x36, 0x34, 0x20, 0x43, 0x41, 0x52, 0x54, /* C64 CART */
$0008: 0x52, 0x49, 0x44, 0x47, 0x45, 0x20, 0x20, 0x20, /* RIDGE    */
$0010: 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x04, /* ...@.... */
$0018: 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
$0020: 0x53, 0x69, 0x6D, 0x6F, 0x6E, 0x27, 0x73, 0x20, /* Simon's  */
$0028: 0x42, 0x61, 0x73, 0x69, 0x63, 0x00, 0x00, 0x04, /* Basic... */
$0030: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
$0038: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */

$0040: 0x43, 0x48, 0x49, 0x50, 0x00, 0x00, 0x20, 0x10, /* CHIP.. . */
$0048: 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00  /* ...... . */
$0050: .... $2000 Byte for Bank 0: $8000 - $9FFF ....

$2050: 0x43, 0x48, 0x49, 0x50, 0x00, 0x00, 0x20, 0x10, /* CHIP.. . */
$2058: 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x20, 0x00  /* ...... . */
$2060: .... $2000 Byte for Bank 0: $A000 - $BFFF ....

$4060: Fin del archivo

E.12 Archivo de Imagen de RAM

RAM Snapshot Icon

El formato de las imágenes de RAM fue adaptado en base a una sugerencia de Jouka Valta para el emulador VICE en sistemas Unix. La especificación original, que describe los campos del encabezamiento con más detalle, se encuentra en http://stekt.oulu.fi:/~jopi/x64/RAM-format

typedef struct
 {
  Byte MagicCode[6];     /* $00 - $05 */
  Byte ReservedA[2];     /* $06 - $07 */
  Byte Version[2];       /* $08 - $09 */
  Byte EmulatorID;       /* $0A */
  Byte SnapType;         /* $0B */
  Byte RAMStart[2];      /* $0C - $0D */
  Byte RAMSizeKB[2];     /* $0E - $0F */
  Byte REUSizeKB[2];     /* $10 - $11 */
  Byte ReservedB[14];    /* $12 - $1F */
  Byte Config[6];        /* $20 - $25 */
  Byte IORAM;            /* $26 */
  Byte CPURestore;       /* $27 */
  Byte PCHigh, PCLow;    /* $28 - $29 */
  Byte RegA, RegX, RegY; /* $2A - 2C */
  Byte RegFlags, RegSP;  /* $2D - $2E */
  Byte IOPort;           /* $2F */
  Byte Z80_CPU[16];      /* $30 - $3F */
  Byte REC[16];          /* $40 - $4F */
  Byte OSVersion;        /* $50 */
  Byte OSPatch;          /* $51 */
  Byte PatchID[2];       /* $52 - $53 */
  Byte ReservedC[44];    /* $54 - $7F */
  Byte Custom[128];      /* $80 - $FF */
  Byte RAM[65536];
  Byte IOArea[4096];
  Byte REU[REUSize];
  FloppyState Floppy1541[FloppyCnt];
 } Snapshot;

Nota: Los bytes de los valores se ordenan del más alto al más bajo, al contrario del orden que usa el C64.

MagicCode - Constante 'mágica' 'CBM'64 = {$43, $42, $4D, $64, $00, $00}
ReservedA - Debe ser {$00, $00}
Version - Números de versión principal y secundario 1.0 = {$01, $00}
EmulatorID- Identificador del emulador. Power64 usa '/' = $2F
SnapType - Para una imagen de RAM es = $00
RAMStart - Posición de la imagen de RAM en el fichero. El encabezamiento ocupa generalmente 256 bytes. Luego RamStart = {$01, $00}.
RAMSizeKB - Tamaño de la RAM en KBytes (¡no en bytes!) = {$00, $40}
REUSizeKB - Tamaño de la unidad de expansión de RAM en KBytes
ReservedB - Todos deben contener $00
Config - Reservado para los filtros de bits de configuración - Normalmente todos valen $00
IORAM - Bits 2 y 1: RAM del VDC disponible (00..No, 01..16KB, 10..64KB, 11..32KB)
Bit 0: Datos de E/S disponibles (0..No, 1..Sí)
Valor que usa Power64: $01
CPURestore- CPU(s) disponible(s): (Bit 0: M6502, Bit 1: Z80, Bit 2: REC) = $01
PCHigh, PCLow- Contador de programa del M6502
RegA, RegX, RegY, RegFlags, RegSP- Registros del M6502
IOPort - Cerrojo de E/S del 6502
Z80_CPU - Reservado para la condición interna del Z80 (no se usa)
REC - Reservado para la condición interna del REC (no se usa)
OSVersion - Byte de identificación del Kernal C64 (no se usa)
OSPatch - Identificador de parche de Kernal para extensiones (aceleradores de carga, etc.) (no se usa)
PatchID - Información sobre la versión de parche (no se usa)
ReservedC - Información sobre la versión de Kernal (no se usa)
Custom - Información sobre periféricos, etc. (no se usa)
RAM - Contenido de la RAM
IOArea - Contenido de la región de E/S (VIC, SID, ColorRAM, CIA1/2, REU)
Cada dispositivo se almacena solo una vez, aún así aparecen varios 'agujeros' en el espacio de memoria del C64. Los claros se rellenan con información del estado interno de Power64, y ceros a granel.
REU - El contenido del módulo de expansión de RAM, si está presente.
0, 128, 256 ó 512 KByte - lo que se especifique en REUSizeKB.
Floppy1541- La condición actual de cada unidad 1541 activada y emulada por completo.
typedef struct
 {
  Byte MagicCode[6];     /* $00 - $05 ('CBM',$15, $41, $00) */
  Byte ReservedA[2];     /* $06 - $07 */
  Byte Version[2];       /* $08 - $09 */
  Byte EmulatorID;       /* $0A */
  Byte SnapType;         /* $0B */
  Byte RAMStart[2];      /* $0C - $0D */
  Byte RAMSizeKB[2];     /* $0E - $0F */
  Byte REUSizeKB[2];     /* $10 - $11 */
  Byte ReservedB[14];    /* $12 - $1F */
  Byte Config[6];        /* $20 - $25 */
  Byte IORAM;            /* $26 */
  Byte CPURestore;       /* $27 */
  Byte PCHigh, PCLow;    /* $28 - $29 */
  Byte RegA, RegX, RegY; /* $2A - 2C */
  Byte RegFlags, RegSP;  /* $2D - $2E */
  Byte ReservedC[81];    /* $2F - $7F */
  Byte Custom[128];      /* $80 - $FF */
  Byte RAM[2048];
  Byte IOArea[512];
 } FloppyState;

E.13 Archivo de Audio de Commodore64 (reSID)

Sound Icon

El formato de audio de Commodore64 fue desarrollado por Roland Lieger para Power64 y reSID. Se basa en una idea empleada por Richard Bannister en Frodo, pero fue mejorado en versatilidad y se redujo el espacio utilizado por los ficheros.

Nota: Todos los valores de más de un byte se almacenan con sus bytes de orden alto a orden bajo, al revés de la ordenación nativa del C64.

typedef struct
 {
  Byte MagicString[24];    /* $00 - $17 */
                           /* -> "Commodore64 Audio File\n\0" */
  Word Version;            /* $18 - $19 */
  Word HeaderSize;         /* $1A - $1B */
  Byte EmulatorID;         /* $1C */
  Byte Reserved;           /* $1D */
  Word EmulatorVersion;    /* $1E - $1F */
  Word PrivHeaderSize;     /* $20 - $21 */
 } GlobalHeader;

typedef struct
 {
  Long SystemClockSpeed;   /* $22 - $26 */
  Word ClockGrain;         /* $27 - $28 */
 } SystemHeader;

typedef struct
 {
  GlobalHeader GlobalHdr;
  SystemHeader SystemHdr;
  Byte         PrivateHdr[PrivHeaderSize];
  Byte         InitialSIDState[25];
  Byte         Reserved[7];
  Byte         SIDCommands[...];
  Byte         EOFMarker[3];
 } C64_Audio_File;
MagicString - "Commodore64 Audio File\n\0"
Version - Números de versión principal y secundario 1.0 = {$01, $00}
HeaderSize - Tamaño del encabezamiento SystemHeader (generalmente 6 bytes = {$00, $06}, puede que en versiones futuras se añadan nuevos campos)
EmulatorID - Power64 emplea '/' = $2F
EmulatorVersion- Números de versión principal y secundario del emulador de origen.
PrivHeaderSize - Tamaño de la información privada almacenada por el emulador.
SystemClockSpeed- Velocidad del reloj de sistema. 982.800 Hz para PAL, 1.021.800 Hz para NTSC
ClockGrain - Intervalo de muestreo del temporizador de grabación del SID, medido en pulsos del reloj de sistema. Usualmente es un período de línea (63 pulsos para PAL, 65 pulsos para NTSC) - Esto da suficiente precisión, mientras no ocupa mucho espacio. No use un intervalo de 1 pulso porque cree que se acercará más al original. ¡No notará la diferencia!
InitialSIDState- Contenido de los 25 registros del usuario del SID al principio de la grabación.
SIDCommands - Es una secuencia de órdenes de 2 y 3 bytes. Cada orden consta de de un Delay (retraso, medido en intervalos de reloj) y por lo general de una orden de grabación en un registro del SID. El primer byte indica el lapso de Delay (bits 7..5) y qué registro del SID se usará (bits 4..0)
Si el valor del Delay está en el intervalo 0..5, éste es el número de intervalos del reloj en que el SID genera sonido.
Si el Delay es igual a 6, el siguiente byte contiene un valor ExtDelay, y hay un retraso de 6+ExtDelay intervalos del reloj.
Si Delay es igual a 6, el siguiente byte contiene un valor ExtDelay, y hay un retraso de 6+256+ExtDelay intervalos del reloj.
ExtDelay debe ser ≤ 254, lo que hace un retraso máximo de 516 intervalos de reloj (casi 2 frames completos de NTSC si se elige un intervalo de un período de línea). El valor ExtDelay de 255 se reserva para señalar el fin de archivo.
Si el valor de SID_Register está entre 0x00..0x18, el siguiente byte (posiblemente después de ExtDelay), indica el valor a anotar en el registro SID.
Los valores de SID_Register 0x19..0x1E están reservados y no deben usarse.
El valor 0x1F indica que no se efectúa anotación alguna en los registros del SID. Ésto es necesario si hay un retraso de más de 516 intervalos de reloj entre dos anotaciones.
EOFMarker - Marca del fin de archivo = {$FF, $FF, $FF}
Home Principio Anterior Contenido Próximo Término Top of Page

Fuente: http://www.salto.at/Power64/Documentation/Power64-Leame/AE-Formatos_Ficheros.html
Power64 Homepage: http://www.infinite-loop.at y http://www.salto.at - EMail:
© Roland Lieger, Goethegasse 39, A-2340 Mödling, Austria - Europe
Últiomo Modificación: 29 de Febrero de 2008
Valid HTML 4.01!