Clonando un FDC765/SED9540 - Codificación MFM

Avatar de Usuario
wilco2009
Mensajes: 1607
Registrado: 07 Ene 2013 16:48
Ubicación: Valencia
Agradecido : 36 veces
Agradecimiento recibido: 87 veces

Clonando un FDC765/SED9540 - Codificación MFM

Mensajepor wilco2009 » 09 Abr 2017 20:33

Llevo tiempo dándole vueltas al tema de clonar la pareja, FDC765 y SED9540, que para el que no lo sepa son los chips que forman el núcleo de una controladora de floppy disk para Spectrum o para Amstrad.

Por raro que parezca aun nadie ha desarrollado una descripción hardware para implementar estos chips con una CPLD, o al menos no la ha compartido.
Cansado de buscar una descripción ya realizada en verilog, me he decidido a intentar hacerla yo, y entonces he comprendido porqué todavía no lo ha hecho nadie.
El chip FDC765 parece sencillo de implementar, ya que únicamente controla los comandos de lectura y escritura de la disquetera, además de los registros de estado y cosas así, pero el el SED9540 es algo más complicado, ya que es el que se encarga de interpretar la ristra de datos que llegan desde la disquetera y separar los datos de la señal de reloj, reajustando el reloj (clock recovery) cuando es necesario, y enviando al 765 las señales de datos y del reloj ya separadas.

La codificación que usan las disqueteras es la conocida como MFM, que permite albergar la señal de reloj junto con la de datos, permitiendo además reajustar dicha señal, ya que las lecturas provenientes de la disquetera no son siempre constantes debido a factores mecánicos, por lo que es necesario un mecanismo de reajuste.

Para el que quiera profundizar algo más en el tema puede leer este artículo de la Wikipedia, en el que se explica la codificación, que es bastante sencilla, aunque no se explica como podemos decodificar la señal aprovechándola para reajustar el reloj, por lo que esto me ha llevado más de un dolor de cabeza.

Tras mucho pelearme con el tema he conseguido un éxito parcial, ya que consigo decodificar y reajustar la señal en una CPLD, pero todavía no acabo de entender quién se encarga de gestionar el "sync mark" y como se usa.

Doy por supuesto que dicha marca de sincronización la debe gestionar el SED9540, pero para poder tener claro como lo hace creo que voy a tener que tirar de analizador lógico.

Si alguien conoce el tema en profundidad y me quiere echar un cable, bienvenido sea.

Os dejo aquí el listado funcional en Verilog que decodifica la señal MFM y reajusta el reloj utilizando un reloj auxiliar de 16MHz exactamente igual que se hace en el SED9540.

► Mostrar Spoiler
"Nada viaja a mayor velocidad que luz con la posible excepción de las malas noticias las cuales obedecen a sus propias leyes."

Douglas Adams. Guía de autoestopista galáctico.

Avatar de Usuario
Jinks
Mensajes: 932
Registrado: 09 Oct 2013 16:47
Agradecido : 25 veces
Agradecimiento recibido: 49 veces
Contactar:

Re: Clonando un FDC765/SED9540 - Codificación MFM

Mensajepor Jinks » 09 Abr 2017 21:45

¿Estás seguro que el SED9540 es completamente digital? ¿No tendrá alguna parte analógica?

jose_leandro
Mensajes: 288
Registrado: 23 Ene 2012 20:20
Agradecimiento recibido: 20 veces

Re: Clonando un FDC765/SED9540 - Codificación MFM

Mensajepor jose_leandro » 09 Abr 2017 22:13

Hola Wilco

¿Y has pensado estudiar algún diseño sin el SED? Lo digo por la controladora de +3 donde no está este chip y se usa una PROM

http://www.worldofspectrum.org/BackToThePlus3/

http://microhobby.speccy.cz/250503/hard ... ra+2A.html

Saludos

José Leandro

Avatar de Usuario
wilco2009
Mensajes: 1607
Registrado: 07 Ene 2013 16:48
Ubicación: Valencia
Agradecido : 36 veces
Agradecimiento recibido: 87 veces

Re: Clonando un FDC765/SED9540 - Codificación MFM

Mensajepor wilco2009 » 09 Abr 2017 23:28

Jinks escribió:¿Estás seguro que el SED9540 es completamente digital? ¿No tendrá alguna parte analógica?


Efectivamente en el SED se utiliza un circuito PLL, cosa que no está a mi alcance con una CPLD, pero debería poder utilizar en su lugar un algoritmo DPLL para resincronizar el reloj, que es lo que intento hacer en mi código.

En principio, en el simulador parece comportarse adecuadamente, pero no tengo claro sin con 16MHz tendré suficiente resolución para poder amortiguar las variaciones de la señal. Quizás sería mejor replantearlo todo utilizando un reloj de 50MHz, aunque no sea totalmente compatible con el circuito original.

jose_leandro escribió:Hola Wilco

¿Y has pensado estudiar algún diseño sin el SED? Lo digo por la controladora de +3 donde no está este chip y se usa una PROM

http://www.worldofspectrum.org/BackToThePlus3/

http://microhobby.speccy.cz/250503/hard ... ra+2A.html

Saludos

José Leandro


Eso puede ser una buena idea. Estudiando el contenido de la PROM puedo deducir como hace el tratamiento de la señal.

Gracias!
"Nada viaja a mayor velocidad que luz con la posible excepción de las malas noticias las cuales obedecen a sus propias leyes."

Douglas Adams. Guía de autoestopista galáctico.

Avatar de Usuario
wilco2009
Mensajes: 1607
Registrado: 07 Ene 2013 16:48
Ubicación: Valencia
Agradecido : 36 veces
Agradecimiento recibido: 87 veces

Re: Clonando un FDC765/SED9540 - Codificación MFM

Mensajepor wilco2009 » 12 Abr 2017 16:34

Pues ya le he echado una ojeada al proyecto back to the plus 3, y resulta que la lógica del SED es mucho más sencilla de lo que esperaba, pero depende de algunas señales que se retroalimentan del FDC765 y que todavía no acabo de entender.
No acabo de ser capaz de ver la correspondencia de la lógica del SED con la codificación MFM, si no tiene parte de la implementación en el 765.

Al final, la PROM es poco más que un contador algo especial, y su contenido se puede resumir en el siguiente código:

Código: Seleccionar todo

      
      //PROM
      if (!IC9Q[5]) begin  // esto parece un contador desplazado
            IC8O[6:4] = IC9Q[4:2]+1;
            IC8O[7] = IC9Q[4];
      end else begin
         IC8O = IC9Q[4:1]+1;
      end
      
   end


El reloj que le envía al 765, al contrario de lo que yo pensaba, no tiene ningún tipo de corrección, siendo simplemente una división del reloj principal de entrada.

Código: Seleccionar todo

   
   always @(negedge clk16) begin
      cnt = cnt + 1;
   end
   assign wrclk = cnt[1]; // 4MHz   


El meollo de la cuestión es la señal Data Window, que aun no acabo de entender como la genera, ya que también depende de la señal VCO que viene del 765 y es algo así como una señal de sincronización.

Código: Seleccionar todo

   
   always @(negedge IC9Q[4] or negedge VCO) begin
//74LS74 IC10A
      if (!IC9Q[4]) begin
         DW = 1b1; // IC10A.Q
      end else begin
         DW = !DW; // IC10A.Q
      end
   end


Luego hay algunas señales que se usan en el esquema de la disquetera original y aquí no las usa, como INT.

El código completo que he convertido es este.

Código: Seleccionar todo

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    08:36:39 04/12/2017
// Design Name:
// Module Name:    backtothep3
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module backtothep3(
    input clk16,
    input VCO,
    input FDRD,
    output wrclk,
    output reg RDDATA,
    output reg DW
    );
   
    reg [1:0] cnt = 0;
    reg [6:1] IC9Q = 0;
    reg [7:4] IC8O = 4b1111;

   always @(negedge clk16) begin
      cnt = cnt + 1;
   end
   
   always @(posedge cnt[0] /* 8MHz */) begin
// 74LS174 IC9
      IC9Q[1] = IC8O[4];
      IC9Q[2] = IC8O[5];
      IC9Q[3] = IC8O[6];
      IC9Q[4] = IC8O[7];
      
      IC9Q[5] = !RDDATA;
      IC9Q[6] = RDDATA;


      //PROM
      if (!IC9Q[5]) begin  // esto parece un contador desplazado
            IC8O[6:4] = IC9Q[4:2]+1;
            IC8O[7] = IC9Q[4];
      end else begin
         IC8O = IC9Q[4:1]+1;
      end
      
   end
   
   always @(negedge FDRD or negedge IC9Q[5]) begin
//74LS74 IC10B
      if (!IC9Q[5]) begin
         RDDATA = 1b0; // IC10B.Q
      end else begin
         RDDATA = VCO; // IC10B.Q
      end
   end

   always @(negedge IC9Q[4] or negedge VCO) begin
//74LS74 IC10A
      if (!IC9Q[4]) begin
         DW = 1b1; // IC10A.Q
      end else begin
         DW = !DW; // IC10A.Q
      end
   end

   assign wrclk = cnt[1]; // 4MHz
   
endmodule
"Nada viaja a mayor velocidad que luz con la posible excepción de las malas noticias las cuales obedecen a sus propias leyes."

Douglas Adams. Guía de autoestopista galáctico.


Volver a “Hardware Spectrum”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado