SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Placez ici vos trucs et astuces, étalez sans retenue votre savoir-faire et votre science qui va nous permettre de redonner une apparence neuve et fonctionnelle à nos bouzes.

Modérateurs : Papy.G, fneck, Carl

Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Daniel »

Merci Carl, c'est une bonne nouvelle !

Le manque de sensibilité du MSX est quand même assez bizarre. L'Arduino délivre un signal de près de 5v d'amplitude crête à crête, c'est un niveau élevé. Il y a peut-être un problème d'impédance, auquel cas il suffirait d'ajouter un transistor à la sortie...

Je n'ai pas le courage de chercher dans la documentation du MSX, car c'est une machine que je ne connais pas du tout, mais il y a peut-être des membres du forum qui peuvent apporter une explication ?
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Carl »

Daniel, quelques infos...
msx.jpg
msx.jpg (169.42 Kio) Consulté 3710 fois
msx tape.jpg
msx tape.jpg (467.83 Kio) Consulté 3710 fois
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Daniel »

Ah oui, il y a un ampli opérationnel à l'entrée cassette du MSX. C'est donc le problème inverse : la sortie TTL de l'Arduino a une amplitude beaucoup trop grande et sature l'entrée du MSX. Il faut la ramener à un niveau 5 ou 10 fois plus faible, en ajoutant un diviseur de tension (deux résistances), ou encore mieux un potentiomètre de 4,7K pour permettre d'ajuster le niveau.

Code : Tout sélectionner

Arduino ----o
            |
            -
           | |
      4.7K | |
           | |<--------> MSX
            -
            |
------------o---------->
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Carl »

Daniel, le potentiomètre serait à la place de la résistance de 2k ?

Donc mon ampli n'a fait finalement qu'attenuateur...

CARL
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Daniel »

Tout ce que j'ai écrit n'est que le fruit de la réflexion en voyant le schéma. Tant que les essais n'ont pas été faits il n'y a pas de preuve, mais tout de même de fortes présomptions, car dans ce montage le gain de l'ampli opérationnel est important. Sa sortie est au niveau TTL, donc à l'entrée il faut nettement moins.

Ton amplificateur doit admettre en entrée une amplitude bien supérieure au MSX, c'est pour cela que ça marche, et effectivement il a du agir comme un atténuateur.

Tu as raison, il faut mettre le potentiomètre de 4K7 à la place de la résistance de 2K. La sortie doit être reliée au curseur du potentiomètre, il faut probablement couper une piste sur le circuit. La résistance de ce potentiomètre n'est pas critique, entre 2K et 10K ça doit être bon.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Carl »

J'ai fais un test avec potentiomètre et ça fonctionne...
J’hésite à mettre un sélecteur pour soit :
- du direct : VG5000, Alice, EXL...
- via résistance d'atténuation : MSX

Carl
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Daniel »

Bravo ! A deux nous y sommes arrivés...

On peut simplifier en mettant le potentiomètre dans tous les cas, à la place de la résistance de 2K. Pour le VG5000, l'Alice et l'EXL100 on règle au maximum, pour le MSX on diminue le volume.

Ce type de potentiomètre peut convenir : http://www.ebay.fr/itm/12Pcs-Blue-White ... 2013492710

Image
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
gleike
Messages : 1341
Inscription : 16 oct. 2014 11:12
Localisation : Ludres (54710) Meurthe & Moselle

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par gleike »

J'avais prévu également d'installer un potentiomètre dans mon module SDLEP-READER,
mais maintenant je vais implémenter le monitoring de la tension de sortie sur l'afficheur LCD pour un réglage fin
et le rendre plus polyvalent.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Carl »

Quelques fichiers LEP qui fonctionnent sur un MSX VG8020 et ceci confirme le bon fonctionnement du SDLEP avec les MSX 8)
xenon.7z
(72.48 Kio) Téléchargé 108 fois
xenon.jpg
xenon.jpg (99.42 Kio) Consulté 3612 fois
LEP.7z
(1.17 Mio) Téléchargé 113 fois
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Carl »

un autre micro est désormais compatible SDLEP, l'Amstrad CPC 464 8)
cpcadap.jpg
cpcadap.jpg (18.73 Kio) Consulté 3611 fois
cpc1.jpg
cpc1.jpg (77.93 Kio) Consulté 3611 fois
cpc2.jpg
cpc2.jpg (190.15 Kio) Consulté 3611 fois
cpc.jpg
cpc.jpg (96.73 Kio) Consulté 3611 fois
Roland_In_The_Caves.7z
(19 Kio) Téléchargé 105 fois
Carl
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Daniel »

Carl, tu es le meilleur promoteur de SDLEP-READER. Merci !
Pour l'instant les ventes n'ont pas décollé : 3 exemplaires expédiés (y compris le tien) en 4 mois.
Les utilisateurs doivent faire, comme gleike, des montages personnels :wink:

J'ai encore simplifié le logiciel de l'Arduino, voici la dernière version :

Code : Tout sélectionner

/**************************************************\
*                  S D - L E P                     * 
*           (c) 2017 - Daniel Coulom               *  
*           http://dcmoto.free.fr/                 *
*           http://forum.system-cfg.com/           *
*--------------------------------------------------*
* Ce code est distribue gratuitement dans l'espoir *
* qu'il sera utile, mais sans aucune  garantie  et *
* sans  engager  la  responsabilité  de  l'auteur. *
* Vous  pouvez  l' utiliser,  le  modifier  et  le *
* diffuser librement, en conservant cette  licence *
* et les références de l'auteur dans   toutes  les *
* copies. L'exploitation commerciale est interdite.*
\**************************************************/

/***************************************************
*                Version 2017.04.16                *
****************************************************
Historique
2017.04.16 optimisations des acces a la carte SD
2017.03.13 integration des acces a la carte SD
2017.01.17 bit data a 1 pendant l'arret moteur
2016.12.30 unite du delai definie en parametre
2016.12.29 noms de fichiers .lep sur 7 caracteres
2016.12.19 quelques optimisations mineures
2016.12.18 clignotement LED si fichier non trouve
2016.12.18 nom de fichier choisi par switches
2016.12.17 choix de broches different pour les I/O
2016.12.17 delai en dixiemes de ms dans sd.lep
2016.12.16 ajout LED d'activite
2016.12.16 reste de count/127 ecrit avant les zeros
2016.12.14 premiere version du programme

Emulation d'un lecteur de cassette Thomson TO ou MO
Lecture des donnees sur carte SD dans un fichier au
format .lep (image de cassette Thomson).

Connexions vers module Catalex pour carte micro SD
 GND --> GND
 D13 --> SCK
 D12 --> MISO
 D11 --> MOSI
 VCC --> VCC (5V)
 D10 --> CS 

Connexions vers DIN magnetophone
GND --> DIN 2
 D0 --> DIN 1  (MOTOR)
 D1 --> DIN 4  (READ DATA) 
   
Connexion vers DIN crayon optique
VCC --> DIN 5  (+5V)
   
Connexion LED d'activite
 D2 --> LED d'activite + resistance 1.5K
   
Connexion des interrupteurs de selection du fichier
 D3 --> interrupteur 1
 D4 --> interrupteur 2
 D5 --> interrupteur 3
 D6 --> interrupteur 4
 D7 --> interrupteur 5
 D8 --> interrupteur 6
 D9 --> interrupteur 7
 
*****************************************************************
SD card management is adapted from SimpleSDAudio library.
Visit SimpleSDAudio website for more information:
http://www.hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio
*****************************************************************
*/

// SD card constants
#define SD_CARD_TYPE_SD1        1 /** Standard capacity V1 SD card */
#define SD_CARD_TYPE_SD2        2 /** Standard capacity V2 SD card */
#define SD_CARD_TYPE_SDHC       3 /** High Capacity SD card */
#define SD_PARTTYPE_UNKNOWN     0
#define SD_PARTTYPE_SUPERFLOPPY 1
#define SD_PARTTYPE_FAT16       2
#define SD_PARTTYPE_FAT32       3
#define SD_INIT_TIMEOUT      2000 /** temps maxi pour l'initialisation */
#define SD_READ_TIMEOUT       300 /** temps maxi pour le debut de la lecture d'un bloc */
#define SD_COMMAND_TIMEOUT    300 /** temps maxi pour repondre a une commande */
#define SD_READY_STATE       0x00 /** status for card in the ready state */
#define SD_IDLE_STATE        0x01 /** status for card in the idle state */
#define SD_ILLEGAL_COMMAND   0x04 /** status bit for illegal command */
#define SD_DATA_START_BLOCK  0xFE /** start data token for read or write single block*/

// SD card commands
#define SD_CMD0   0x00  /** GO_IDLE_STATE - init card in spi mode if CS low */
#define SD_CMD8   0x08  /** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
#define SD_CMD9   0x09  /** SEND_CSD - read the Card Specific Data (CSD register), response R1 */
#define SD_CMD10  0x0A  /** SEND_CID - read the card identification information (CID register), response R1 */
#define SD_CMD12  0x0C  /** STOP_TRANSMISSION - end multiple block read sequence, response R1b */
#define SD_CMD13  0x0D  /** SEND_STATUS - read the card status register, response R2 */
#define SD_CMD16  0x10  /** SET_BLOCKLEN arg0[31:0]: block length, response R1 */
#define SD_CMD17  0x11  /** READ_SINGLE_BLOCK - read a single data block from the card, response R1 */
#define SD_CMD18  0x12  /** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card, response R1 */
#define SD_CMD55  0x37  /** APP_CMD - escape for application specific command */
#define SD_CMD58  0x3A  /** READ_OCR - read the OCR register of a card */
#define SD_CMD59  0x3B  /** CRC_ON_OFF - Turns CRC option on or off, response R1 */
#define SD_ACMD41 0x29  /** SD_SEND_OP_COMD - Sends host capacity support information and activates the card's initialization process */

// SD card error codes
#define SD_ERROR_CMD0           0x01 /** timeout error for command CMD0 (initialize card in SPI mode), signal problem */
#define SD_ERROR_CMD8           0x02 /** CMD8 was not accepted - not a valid SD card */
#define SD_ERROR_ACMD41         0x03 /** ACMD41 initialization process timeout */
#define SD_ERROR_CMD58          0x04 /** card returned an error response for CMD58 (read OCR) */
#define SD_ERROR_CMD16          0x05 /** card returned an error response for CMD16 (set block len) */
#define SD_ERROR_VOLTMATCH      0x06 /** card operation voltage range doesn't match (2.7V - 3.6V) */
#define SD_ERROR_READ_TIMEOUT   0x07 /** timeout while waiting for start of read data */
#define SD_ERROR_READ           0x08 /** card returned error token when tried to read data */
#define SD_ERROR_CMD17          0x09 /** card returned an error response for CMD17 (read single block) */
#define SD_ERROR_CMD9           0x0e /** card returned an error response for CMD9  (read CSD) */
#define SD_ERROR_CMD10          0x0f /** card returned an error response for CMD10 (read CID) */
#define SD_ERROR_CMD18          0x10 /** card returned an error response for CMD18 (read multi block) */
#define SD_ERROR_INVAL_SECT0    0x30 /** No valid MBR/FAT-BS signature found in sector 0 */
#define SD_ERROR_INVAL_BS       0x31 /** Malformed FAT boot sector */
#define SD_ERROR_FAT12          0x32 /** FAT12 is not supported */
#define SD_ERROR_FAT_NOT_INIT   0x33 /** FAT not initialized properly */
#define SD_ERROR_DIR_EOC        0x34 /** End of cluster reached (not a real error, just information) */
#define SD_ERROR_FILE_NOT_FOUND 0x35 /** File not found after reaching end of directory */
#define SD_ERROR_EOF            0x38 /** End of file reached */

// SD card variables
typedef struct {
  uint8_t     Attributes;
  uint32_t    Size;           // in bytes
  uint32_t    FirstCluster;   // First cluster
  uint32_t    ActSector;      // 0 to (SD_FAT.SecPerClus - 1)
  uint32_t    ActBytePos;     // 0 to Size
} SD_File_t;

SD_File_t LepFileInfo;  

typedef struct  {
  uint8_t     PartType;           // Use this to test whether it is FAT16 or FAT32 or not initialized
  // Stuff from FAT boot sector
  uint8_t     SecPerClus;
  uint16_t    RsvdSecCnt;
  uint8_t     NumFATs;
  uint16_t    RootEntryCount;
  uint32_t    TotalSec;
  uint32_t    SecPerFAT;
  uint32_t    RootClus;
  // For cluster calculations
  uint8_t     ClusterSizeShift;
  uint32_t    ClusterCount;
  // Start addresses (all in blocks / sector addresses)
  uint32_t    BootSectorStart;    // Address of boot sector from FAT
  uint32_t    FatStart;           // First file allocation table starts here
  uint32_t    RootDirStart;       // Root directory starts here
  uint32_t    DataStart;          // Cluster 0 starts here
  uint32_t    ClusterEndMarker;   // if Cluster >= this then end of file reached.
} SD_FAT_t;

SD_FAT_t SD_FAT;

uint8_t  SD_type;        // type de la carte SD
uint8_t  SD_CSPin;       // numero de la broche CS de la carte SD
uint8_t  SD_buffer[513]; // SD buffer must hold 512 bytes + 1

#define UNITE 50  //unite du delai en microsecondes


/**************************************************************************\
* Lecture du fichier .lep
\**************************************************************************/
void setup()
{
 int i;                      // compteur de boucle
 int delai;                  // delai en microsecondes 
 bool niveau;                // niveau du signal en sortie
 bool activite;              // niveau diode d'activite
 char octet;                 // zone de stockage d'un octet
 uint32_t count = 0;         // compteur d'octets
 char filename[13];          // nom du fichier .lep
 
 //Initialisations
 pinMode(0, INPUT_PULLUP);   // configurer pin0(RX) en entree (commande moteur)
 pinMode(1, OUTPUT);         // configurer pin1(TX) en sortie (donnees lues)
 pinMode(2, OUTPUT);         // configurer pin2 en sortie (led activite)
 pinMode(3, INPUT_PULLUP);   // interrupteur 1
 pinMode(4, INPUT_PULLUP);   // interrupteur 2
 pinMode(5, INPUT_PULLUP);   // interrupteur 3
 pinMode(6, INPUT_PULLUP);   // interrupteur 4
 pinMode(7, INPUT_PULLUP);   // interrupteur 5
 pinMode(8, INPUT_PULLUP);   // interrupteur 6
 pinMode(9, INPUT_PULLUP);   // interrupteur 7
 SD_CSPin = 10;              // definir CS de la carte SD en D10
 SD_Init_FileSystem();       // initialiser la carte SD
 SD_SpiSetHighSpeed();       // frequence d'horloge maxi 

 //Determination du nom du fichier (extension .lep)
 //en fonction de la position des 7 interrupteurs (128 possibilites)
 //Le nom du fichier est compose de sept chiffres 0 ou 1
 //decrivant la position des interrupteurs 1 à 7
 //Exemple : interrupteurs 2, 4, 6 sur ON --> fichier 0101010.lep 
 //Exemple : interrupteurs 5 sur ON --> fichier 0000100.lep
 //Exemple : interrupteurs 1,2,3,5,7 sur ON --> fichier 1110101.lep 
 strcpy(filename, "0000000.lep");
 if(digitalRead(3) == LOW) filename[0] = '1';
 if(digitalRead(4) == LOW) filename[1] = '1';
 if(digitalRead(5) == LOW) filename[2] = '1';
 if(digitalRead(6) == LOW) filename[3] = '1';
 if(digitalRead(7) == LOW) filename[4] = '1';
 if(digitalRead(8) == LOW) filename[5] = '1';
 if(digitalRead(9) == LOW) filename[6] = '1';
 
 // Search for file SD_FILE in Rootdir (=cluster 0),
 // search shortname files only (0x00,0x18)
 i = SD_SearchFile((uint8_t *)filename, 0UL, 0x00, 0x18, &LepFileInfo);
 //Si le fichier est trouve alors i est nul et on passe le while sans rien faire.
 //Si le fichier n'est pas trouve alors i n'est pas nul et on boucle indefiniment.
 //Remarque : La fonction delai necessite d'avoir les interruptions actives.
 //           On peut les desactiver apres, mais pas avant.
 while(i)                  //clignotement rapide de la diode d'activite
 {                         //pour signaler un fichier non trouve
  digitalWrite(2, HIGH);   // allumer led activite 
  delay(5);                // temporisation
  digitalWrite(2, LOW);    // eteindre led activite 
  delay(50);               // temporisation
 }
 
 // send CMD18 (multiblock read)
 noInterrupts();                          // desactiver les interruptions
 uint32_t offset = LepFileInfo.ActSector; // offset = secteur
 if (SD_type != SD_CARD_TYPE_SDHC)        // si carte non SDHC
     offset <<= 9;                        // offset = octet
 SD_CardCommand(18, offset);              // lance CMD18
 niveau = HIGH;                           // signal a 1 pour detection lep
 digitalWrite(1, niveau);                 // initialisation sortie
 activite = LOW;                          // signal a 0 pour led d'activite
 digitalWrite(2, activite);               // eteindre led activite

 while(count < LepFileInfo.Size)    // tant qu'il reste des octets
 {
  // attente octet 0xfe de debut de bloc
  while(SD_SpiReadByte() != 0xfe); 

  //traitement d'un bloc de 512 octets lus sur la carte SD 
  for(i = 0; i < 512; i++)
  {
   if(digitalRead(0) == HIGH)      // si le moteur est arrete,
   {                               // pour que le LEP soit detecte,
    digitalWrite(1, HIGH);         // mettre le signal en sortie a 1
    digitalWrite(2, LOW);          // eteindre la led d'activite
    while(digitalRead(0) == HIGH); // attendre le MOTOR ON
   }
   count++;                        // nombre d'octets lus 
   octet = SD_SpiReadByte();       // lecture d'un octet
   delai = abs(octet);             // initialisation delai
   if(octet == 0) delai = 127;     // absence de signal (127 unites)
   delai *= UNITE;                 // conversion en microsecondes
   if(octet > 0) niveau = HIGH;    // creneau positif
   if(octet < 0) niveau = LOW;     // creneau negatif
   digitalWrite(1, niveau);        // signal en sortie
   //if(i == 511) delai -= 49;       // compensation temps chgt bloc 
   delayMicroseconds(delai);       // temporisation
  }

  //lecture des deux octets de CRC
  SD_SpiReadByte();                // lecture octet CRC1
  SD_SpiReadByte();                // lecture octet CRC2
  
  //clignotement diode d'activite
  activite = (activite == LOW) ? HIGH : LOW;
  digitalWrite(2, activite);        
 }
 digitalWrite(2, 0);               // eteindre led activite 
 interrupts();                     //activer les interruptions
}

/**************************************************************************\
* Flash toutes les deux secondes apres la fin de fichier
\**************************************************************************/
void loop(void) {
//la lecture est arrivee en fin de fichier
//clignotement lent de la diode d'activite
digitalWrite(2, HIGH);   // allumer led activite 
delay(100);              // temporisation
digitalWrite(2, LOW);    // eteindre led activite 
delay(1900);             // temporisation
}

/**************************************************************************\
* Set CS High 
* Sends also one dummy byte to ensure MISO goes high impedance
\**************************************************************************/
void SD_SetCSHigh()
{
 digitalWrite(SD_CSPin, HIGH);
 SD_SpiSendByte(0xff);
}

/**************************************************************************\
* Sends a raw byte to the SPI - \param[in] b The byte to sent.
\**************************************************************************/
void SD_SpiSendByte(uint8_t b)
{
 SPDR = b;
 while(!(SPSR & (1 << SPIF))); /* wait for byte to be shifted out */
 SPSR &= ~(1 << SPIF);
}

/**************************************************************************\
* Send a command to the memory card which responses with a R1 response 
* (and possibly others).
* \param[in] command The command to send.
* \param[in] arg The argument for command.
* \returns The command answer.
\**************************************************************************/
uint8_t SD_CardCommand(uint8_t cmd, uint32_t arg) 
{
 uint8_t response;
 uint8_t crc;
 uint16_t t0;
      
 // select card
 digitalWrite(SD_CSPin, LOW);

 // wait up to timeout if busy
 t0 = ((uint16_t)millis());
 while (SD_SpiReadByte() != 0xFF)
  if ((((uint16_t)millis()) - t0) >= SD_COMMAND_TIMEOUT) break;

 // send command
 SD_SpiSendByte(cmd | 0x40);

 // send argument
 SD_SpiSendByte((arg >> 24) & 0xff);
 SD_SpiSendByte((arg >> 16) & 0xff);
 SD_SpiSendByte((arg >>  8) & 0xff);
 SD_SpiSendByte((arg >>  0) & 0xff);
  
 // send CRC, only required for commands 0 and 8
 crc = 0xFF;
 if (cmd == SD_CMD0) crc = 0x95;  // correct crc for CMD0 with arg 0
 if (cmd == SD_CMD8) crc = 0x87;  // correct crc for CMD8 with arg 0X1AA
 SD_SpiSendByte(crc);

 // skip stuff byte for stop read
 if (cmd == SD_CMD12) SD_SpiReadByte();

 // wait for response
 for(uint8_t i = 0; i < 100; ++i)
 {
  response = SD_SpiReadByte();
  if(response != 0xff) break;
 }
 return response;
}

/**************************************************************************\
* Send an application specific command which responses with a R1 response 
* (and possibly others).
* \param[in] command The command to send.
* \param[in] arg The argument for command.
* \returns The command answer.
\**************************************************************************/
uint8_t SD_CardACommand(uint8_t cmd, uint32_t arg)
{
 SD_CardCommand(SD_CMD55, 0);
 return SD_CardCommand(cmd, arg);
}

/**************************************************************************\
 * Initialize the SD memory card.
 * Power up the card, set SPI mode.
 * Detects the card version (V1, V2, SDHC), sets sector length to 512.
 * \return Zero if successfull, errorcode otherwise
\**************************************************************************/
uint8_t SD_Init()
{
 uint8_t status;
 uint16_t t0 = ((uint16_t)millis());
 uint32_t arg;

 /* Setup ports */
 pinMode(SD_CSPin, OUTPUT);
 digitalWrite(SD_CSPin, HIGH);
 pinMode(MISO, INPUT);
 pinMode(SCK, OUTPUT);
 pinMode(MOSI, OUTPUT);
 pinMode(SS, OUTPUT);
  
 digitalWrite(SCK, LOW);
 digitalWrite(MOSI, LOW);
 digitalWrite(SS, HIGH);

 /*
 * SPI configuration: 
 * - enable uC for SPI master
 * - typical no interrupts are used for SPI
 * - data order: MSB is transmitted first
 * - clock polarity: CLK is low when idle
 * - clock phase: 1-0 > Sample, 0-1 > Setup
 * - clock frequency: less than 400kHz 
 *   (will be switched to higher value after initialization)
 */
 /* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
 SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
        (1 << SPE)  | /* SPI Enable */
        (0 << DORD) | /* Data Order: MSB first */
        (1 << MSTR) | /* Master mode */
        (0 << CPOL) | /* Clock Polarity: SCK low when idle */
        (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
        (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
        (1 << SPR0);
 SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */
  
 // must supply min of 74 clock cycles with CS high.
 SD_SetCSHigh();
 for (uint8_t i = 0; i < 10; i++) SD_SpiSendByte(0xFF);

 // command to go idle in SPI mode
 while ((SD_CardCommand(SD_CMD0, 0)) != SD_IDLE_STATE)
  if ((((uint16_t)millis()) - t0) > SD_INIT_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_CMD0);}
  
 // check SD version ( 2.7V - 3.6V + test pattern )
 SD_type = 0;
 if ((SD_CardCommand(SD_CMD8, 0x1AA) & SD_ILLEGAL_COMMAND)) SD_type = SD_CARD_TYPE_SD1;
    // Not done here: Test if SD or MMC card here using CMD55 + CMD1
 else
 {
  // only need last byte of r7 response
  SD_SpiReadByte();
  SD_SpiReadByte();
  status = SD_SpiReadByte();
  if ((status & 0x01) == 0) // card operation voltage range doesn't match
  {SD_SetCSHigh(); return(SD_ERROR_VOLTMATCH);}
  if (SD_SpiReadByte() != 0xAA) {SD_SetCSHigh(); return(SD_ERROR_CMD8);}
  SD_type = SD_CARD_TYPE_SD2;
 }
  
 // Turn CRC option off
 SD_CardCommand(SD_CMD59, 0);
  
 // initialize card and send host supports SDHC if SD2
 arg = (SD_type == SD_CARD_TYPE_SD2) ? 0X40000000 : 0;
 while ((SD_CardACommand(SD_ACMD41, arg)) != SD_READY_STATE) // check for timeout
  if ((((uint16_t)millis()) - t0) > SD_INIT_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_ACMD41);}
  
 // if SD2 read OCR register to check for SDHC card
 if (SD_type == SD_CARD_TYPE_SD2)
 {
  if (SD_CardCommand(SD_CMD58, 0)) {SD_SetCSHigh(); return(SD_ERROR_CMD58);}
  // other implementation test only against 0x40 for SDHC detection...
  if ((SD_SpiReadByte() & 0xC0) == 0xC0) SD_type = SD_CARD_TYPE_SDHC;
  // discard rest of ocr - contains allowed voltage range
  SD_SpiReadByte();
  SD_SpiReadByte();
  SD_SpiReadByte();
 }

 // set block size to 512 bytes
 if(SD_CardCommand(SD_CMD16, 512)) {SD_SetCSHigh(); return(SD_ERROR_CMD16);}
 SD_SetCSHigh();
 SD_SpiSetHighSpeed();
 return 0;
}

/**************************************************************************\
* Initialize the file system .
* Does the lower level initialization and * tries to find the boot sector 
* of the first FAT16 or FAT32 partition and parse it.
* Workbuf must hold at least 512 bytes.
* Workbuf will be used later also for following functions:
* - SD_SearchFile
* - SD_Dir
* \return Zero if successful, error code otherwise
\**************************************************************************/
uint8_t SD_Init_FileSystem()
{
 uint8_t  retval;
 uint8_t  PartType;
 uint16_t temp16;
 uint32_t temp32;
    
 SD_FAT.PartType = SD_PARTTYPE_UNKNOWN;
    
 // Try init SD-Card
 retval = SD_Init();
 if(retval) return(retval);
    
 // ==== MBR (partition table) access here =====
    
 // Read sector 0 
 retval = SD_ReadBlock(0);
 if(retval) return(retval);

 // Test for signature (valid not only for MBR, but FAT Boot Sector as well!)
 if((SD_buffer[0x1fe] != 0x55) || (SD_buffer[0x1ff] != 0xaa)) return(SD_ERROR_INVAL_SECT0);
    
 // Store most important MBR values for first partition
 PartType = SD_buffer[0x1be + 0x04];
 SD_FAT.BootSectorStart =  (uint32_t)SD_buffer[0x1be + 0x08] 
                        | ((uint32_t)SD_buffer[0x1be + 0x09] << 8UL)
                        | ((uint32_t)SD_buffer[0x1be + 0x0a] << 16UL)
                        | ((uint32_t)SD_buffer[0x1be + 0x0b] << 24UL);
    
    // Check MBR values for plausibility
    if(  ((SD_buffer[0x1be] & 0x7f) == 0)
      && ((PartType == 0x04) || (PartType == 0x06) || (PartType == 0x0B) 
           || (PartType == 0x0C) || (PartType == 0x0E)) )  
    {
        // MBR seems to contain valid FAT16/FAT32 partition entry
        SD_FAT.PartType = ((PartType == 0x0B) || (PartType == 0x0C)) ? SD_PARTTYPE_FAT32 : SD_PARTTYPE_FAT16;
    }
    else
    {
        // MBR seems to contain not an valid entry, so try for super-floppy now
        SD_FAT.BootSectorStart = 0UL;
        SD_FAT.PartType = SD_PARTTYPE_SUPERFLOPPY;
    }
    
    // ====== FAT access here ======
    
    // Read Boot-Sector and test for signature
    retval = SD_ReadBlock(SD_FAT.BootSectorStart);
    if(retval) return(retval);  

    // Test for signature (valid not only for MBR, but FAT Boot Sector as well!)
    if((SD_buffer[0x1fe] != 0x55) || (SD_buffer[0x1ff] != 0xaa)) return(SD_ERROR_INVAL_BS);
    
    // Plausibility checks for FAT
    if((SD_buffer[0x0b] != 0x00) || (SD_buffer[0x0c] != 0x02) || (SD_buffer[0x15] != 0xf8)) return(SD_ERROR_INVAL_BS);

    // Read fields that are same for FAT16 and FAT32
    SD_FAT.SecPerClus = SD_buffer[0x0d];
    SD_FAT.RsvdSecCnt = (uint16_t)SD_buffer[0x0e] | ((uint16_t)SD_buffer[0x0f]<<8U);
    if((SD_FAT.SecPerClus == 0) || (SD_FAT.RsvdSecCnt == 0)) return(SD_ERROR_INVAL_BS);
    SD_FAT.NumFATs = SD_buffer[0x10];
    SD_FAT.RootEntryCount = (uint16_t)SD_buffer[0x11] | ((uint16_t)SD_buffer[0x12]<<8U);
    
    temp16 = (uint16_t)SD_buffer[0x13] | ((uint16_t)SD_buffer[0x14]<<8U);
    temp32 = (uint32_t)SD_buffer[0x20] | ((uint32_t)SD_buffer[0x21]<<8U) | ((uint32_t)SD_buffer[0x22]<<16U) | ((uint32_t)SD_buffer[0x23]<<24U);
    SD_FAT.TotalSec  = temp16 ? temp16 : temp32;
    
    temp16 = (uint16_t)SD_buffer[0x16] | ((uint16_t)SD_buffer[0x17]<<8U);
    temp32 = (uint32_t)SD_buffer[0x24] | ((uint32_t)SD_buffer[0x25]<<8U) | ((uint32_t)SD_buffer[0x26]<<16U) | ((uint32_t)SD_buffer[0x27]<<24U);
    SD_FAT.SecPerFAT  = temp16 ? temp16 : temp32;
    
    // Calculate start sectors
    SD_FAT.FatStart = SD_FAT.BootSectorStart + (uint32_t)SD_FAT.RsvdSecCnt;
    SD_FAT.RootDirStart = SD_FAT.FatStart + SD_FAT.NumFATs * (uint32_t)SD_FAT.SecPerFAT;
    
    // Data area starts at cluster #2
    SD_FAT.DataStart = SD_FAT.RootDirStart+ ((32 * (uint32_t)SD_FAT.RootEntryCount + 511)/512) - (2 * SD_FAT.SecPerClus);
    
    // determine shift that is same as multiply by SD_FAT.SecPerClus
    SD_FAT.ClusterSizeShift = 0;
    while (SD_FAT.SecPerClus != (1 << SD_FAT.ClusterSizeShift)) {
      // error if not power of 2
      if (SD_FAT.ClusterSizeShift++ > 7) return(SD_ERROR_INVAL_BS);
    }  
    
     // Calculate number and shifting of clusters
    // total data blocks
    SD_FAT.ClusterCount = SD_FAT.TotalSec - (SD_FAT.DataStart - SD_FAT.BootSectorStart);
    // divide by cluster size to get cluster count
    SD_FAT.ClusterCount >>= SD_FAT.ClusterSizeShift;  
    
    // determine if FAT16 or FAT32 (only by cluster count as done by M$)
    if (SD_FAT.ClusterCount < 4085) {
        // this would be FAT12, which is not supported
        SD_FAT.PartType = SD_PARTTYPE_UNKNOWN;
        return(SD_ERROR_FAT12);
    } else if (SD_FAT.ClusterCount < 65525) {
        SD_FAT.PartType = SD_PARTTYPE_FAT16;
        SD_FAT.ClusterEndMarker = 0xfff8UL;
    } else {
        temp32 = (uint32_t)SD_buffer[0x2c] | ((uint32_t)SD_buffer[0x2d]<<8U) | ((uint32_t)SD_buffer[0x2e]<<16U) | ((uint32_t)SD_buffer[0x2f]<<24U);
        SD_FAT.RootDirStart = SD_Cluster2Sector(temp32);
        SD_FAT.PartType = SD_PARTTYPE_FAT32;
        SD_FAT.ClusterEndMarker = 0xffffff8UL;
    }
      
    return 0;
}

/**************************************************************************\
* Set SPI for full operation speed (up to 25 MHz).
* Will be called after first part of card 
* initialization was successful.
\**************************************************************************/
void SD_SpiSetHighSpeed(void)
{
 SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 */
 SPSR |= (1 << SPI2X);         /* Doubled Clock Frequency: f_OSC / 2 */
}

/**************************************************************************\
* Receives a raw byte from the SPI.
* \returns The byte which should be read.
\**************************************************************************/
uint8_t SD_SpiReadByte()
{
 SPDR = 0xff; /* send dummy data for receiving some */
 while(!(SPSR & (1 << SPIF)));
 SPSR &= ~(1 << SPIF);
 return SPDR;
}

/**************************************************************************\
* Read a 512 byte block from an SD card.
* \param[in] blockNumber Logical block to be read.
* \param[out] dst Pointer to the location that will receive the data.
* \return 0 is returned for success, error code otherwise
\**************************************************************************/
uint8_t SD_ReadBlock(uint32_t blockNumber) 
{
  uint8_t status;
  uint16_t t0;

 // use address if not SDHC card
 if (SD_type != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
 if (SD_CardCommand(SD_CMD17, blockNumber)) {SD_SetCSHigh(); return(SD_ERROR_CMD17);}

 // wait for start block token
 t0 = ((uint16_t)millis());
 while ((status = SD_SpiReadByte()) == 0xFF)
  if ((((uint16_t)millis()) - t0) > SD_READ_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_READ_TIMEOUT);}
 if (status != SD_DATA_START_BLOCK) {SD_SetCSHigh(); return(SD_ERROR_READ);}
  
 // transfer data
 SPDR = 0xFF;
 for (uint16_t i = 0; i < 512; i++)
 {
  while (!(SPSR & (1 << SPIF)));
  SD_buffer[i] = SPDR;
  SPDR = 0xFF;
 }
 while (!(SPSR & (1 << SPIF)));
 SD_buffer[512] = SPDR;

 // discard CRC
 SD_SpiReadByte();
 SD_SpiReadByte();
 SD_SetCSHigh();

 return 0;
}

/**************************************************************************\
* Returns the first sector of a given cluster
\**************************************************************************/
uint32_t SD_Cluster2Sector(uint32_t cluster)
{
 return((cluster << SD_FAT.ClusterSizeShift) + SD_FAT.DataStart);
}

/**************************************************************************\
* Search a file in the directory.
* Filename must be 8.3 format, terminated by \0 (can not access ".." now...)
* Works only over one cluster of directory information. 
* If SD_ERROR_DIR_EOC is returned call function again with next cluster number. 
* Set cluster to 0 to access root directory.
* Deleted files and long name entries are not shown generally.
* Only files are printed that has their attributes set/unset regarding maskSet/maskUnset.
* Examples for maskSet, maskUnset:
*  Ouput everything:           0x00, 0x00
*  Shortname files only:       0x00, 0x18
*  Shortname files and dirs:   0x00, 0x08
*  Shortname dirs:             0x10, 0x08
*  Volume name:                0x08, 0x10
* Mask bits: B7 = 0, B6 = 0, B5 = archive, B4 = directory, 
*            B3 = volume name, B2 = system, B1 = hidden, B0 = read only
* If file is found, fileinfo gets filled with file attributes, 
* file size in bytes and first cluster.
*  return Zero if successfully, error code otherwise
\**************************************************************************/
uint8_t SD_SearchFile(uint8_t *filename, const uint32_t cluster, const uint8_t maskSet, const uint8_t maskUnset, SD_File_t *fileinfo)
{
 uint16_t maxsect = SD_FAT.SecPerClus;
 uint32_t startsect = SD_Cluster2Sector(cluster);
 char     fnentry[12];

 if((SD_FAT.PartType != SD_PARTTYPE_FAT16) && (SD_FAT.PartType != SD_PARTTYPE_FAT32)) return(SD_ERROR_FAT_NOT_INIT);
 if(cluster == 0)
 {
  startsect = SD_FAT.RootDirStart; // Set root dir sector
  if(SD_FAT.PartType == SD_PARTTYPE_FAT16) maxsect = (uint16_t)((32 * (uint32_t)SD_FAT.RootEntryCount + 511)/512);
 }
    
 // convert filename to space-filled uppercase format
 for(uint8_t i = 0; i < 11; i++) fnentry[i] = ' ';
 for(uint8_t i = 0; i < 9; i++)
 {
  uint8_t c = *filename++;
  if((c < 0x20) || (c == '.')) break;
  if((c>='a') && (c<='z')) c -= 0x20;  // to upper case
  fnentry[i] = c;
 }
 for(uint8_t i = 8; i < 11; i++)
 {
  uint8_t c = *filename++;
  if(c < 0x20) break;
  if((c>='a') && (c<='z')) c -= 0x20;  // to upper case
  fnentry[i] = c;
 }
 fnentry[11] = 0;
 //Serial.println(fnentry);
    
 // go through sectors
 for(uint16_t i = 0; i<maxsect; i++)
 {
  uint8_t retval = SD_ReadBlock(startsect + i);
  if(retval) return(retval);
        
  for(uint16_t j = 0; j<512; j+=32)
  {
   uint8_t attrib;
   if(SD_buffer[j] == 0) return(SD_ERROR_FILE_NOT_FOUND);    // Last entry when first character of filename == 0
   if(SD_buffer[j] == 0xe5) continue;  // Skip deleted files
   if(SD_buffer[j] == 0x05) SD_buffer[j] = 0xE5;
            
   attrib = SD_buffer[j+0x0b];
            
   // Test masks (skip long file name entries also)
   if(((attrib & maskSet) == maskSet) && ((attrib & maskUnset) == 0) && (attrib != 0x0f))
   {
    uint16_t k;
                
    // compare filename
    for(k = 0; k < 11; k++) if(SD_buffer[j+k] != fnentry[k]) break;
    if(k >= 11)
    {
     // found it
     fileinfo->Attributes = attrib;
     fileinfo->Size = (uint32_t)SD_buffer[j+0x1c] | (((uint32_t)SD_buffer[j+0x1d])<<8) 
                  | (((uint32_t)SD_buffer[j+0x1e])<<16) | (((uint32_t)SD_buffer[j+0x1f])<<24);
     if(SD_FAT.PartType == SD_PARTTYPE_FAT16)
      {fileinfo->FirstCluster = (uint32_t)SD_buffer[j+0x1a] | (((uint32_t)SD_buffer[j+0x1b])<<8);}
     else
      {fileinfo->FirstCluster = (uint32_t)SD_buffer[j+0x1a] | (((uint32_t)SD_buffer[j+0x1b])<<8) 
                            | (((uint32_t)SD_buffer[j+0x14])<<16) | (((uint32_t)SD_buffer[j+0x15])<<24);} 
                    
     // Initialize some things
     fileinfo->ActSector = SD_Cluster2Sector(fileinfo->FirstCluster);
     fileinfo->ActBytePos = 0;
     return(0);
    }
   }
  }
 }
 if(SD_FAT.PartType == SD_PARTTYPE_FAT16) return(SD_ERROR_FILE_NOT_FOUND);
 return(SD_ERROR_DIR_EOC);
}
Remarque : Il n'y a strictement aucune différence à l'exécution, par rapport à la version originale. C'est seulement une simplification du code, laissant plus de place disponible en mémoire pour des ajouts personnels.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Carl »

Avec le CPC464, c'est du 100% sans aucun problème !
Pour faire la promo du SDLEP for CPC464, voici un ZIP avec des dizaines de jeux 8)
(271 Mo sur une carte SD)

pack CPC SDLEP.zip
https://download.system-cfg.com/f.php?h=1DyHrRM-&d=1

Code : Tout sélectionner

3D Starstrike	1985	
4 QUATTRO SKILLS		CODEMASTERS
?		ADVENTURAS AD
ABADIA DEL CRIMEN (LA)	1988	OPERA SOFT
ACADEMY : TAU CETI II	1989	SUMMIT
ADVANCED PINBALL SIMULATOR		CODEMASTERS
AFTEROIDS	19??	ZIGURAT
AGENT X 2	1987	MASTERTRONIC
AIR COBRA	1987	
Airwolf		Encore
Alex Higgins World Snooker	1985	Amsoft
ALIEN	1985	AMSOFT
ALIEN 8	1985	RICOCHET
ALIEN BREAK-IN	1984	AMSOFT
ALIENS	1986	RICOCHET
AMAUROTE	1987	M.A.D.
ARCADE FLIGHT SIMULATOR	1988	CODEMASTERS
ARKANOID	1987	IMAGINE
ARNHEM	1985	CCS
Astro Attack	1984	Amsoft
Astro Attack	1984	Amsoft
ATON	1987	A.G.D
ATV SIMULATOR	1988	CODEMASTERS
AU REVOIR MONTY	1987	GREMLIN GRAPHICS
AVENTURA ORIGINAL	1989	ADVENTURAS AD
AVENTURA ORIGINAL	1989	ADVENTURAS AD
Back To The Future	1986	Electric Dreams
BAD DUDES VS DRAGON NINJA	1988	IMAGINE SOFTWARE LTD
Bard's Tale (The)	1988	Electronic Arts
Barry McGuigan's Boxing	1985	Activision
Barry McGuigan's Boxing	1985	Activision
BATALLA DE INGLATERRA/BATTLE OF BRITAIN	1985	P.S.S
BATMAN	19??	OCEAN SOFTWARE LTD
BEACH HEAD	1986	U.S GOLD
BETA 2515	1987	GENESIS SOFT
Bigfoot	1988	Codemasters
BLAGGER		AMSOFT
BLOODWYCH	1989	IMAGEWORKS
BMX FREESTYLE/FREESTYLE BMX SIMULATOR	19??	CODEMASTERS LTD
BMX SIMULATOR 2		CODEMASTERS
BOUNDER	1986	GREMLIN GRAPHICS
BRAINACHE	1987	CODEMASTERS
BRIDGE-IT	1984	AMSOFT
BRUCE LEE	1984	US GOLD, DATASOFT
CAMELOT WARRIORS		MASTERTRONIC
CAMELOT WARRIORS	1986	DINAMIC SOFTWARE
CAVES OF DOOM		
CAVES OF DOOM (THE)	1985	MASTERTRONIC
CENTRE COURT	1984	EPICSOFT
Classic Adventure	1984	Amsoft
CLASSIC ARCADIA	1988	BUBBLE BUS
Climb-it	1984	Tynesoft
Cluedo		
COLONY	1987	MASTERTRONIC LTD
COMMANDO	1985	ELITE
Computer Scrabble	1985	Amstrad
CONFUZION		INCENTIVE SOFTWARE
CONTINENTAL CIRCUS	1989	VIRGIN GAMES
Corridor Conflict	?	The Power House
COUNT DUCKULA	1989	ALTERNATIVE SOFTWARE
Crossfire	1989	Atlantis Software
CYBERNOID 2	1988	HEWSON CONSULTANTS
DALEY THOMPSON'S OLYMPIC CHALLENGE	1988	OCEAN SOFTWARE LTD
DAM BUSTERS	1988	POWER HOUSE
DAN DARE		RICOCHET
Dandy	1986	Electric Dreams Software
DANGER MOUSE - IN MAKIN' WHOOPEE		ALTERNATIVE
DARK STAR	1984	FIREBIRD SOFTWARE
DEATH STALKER	1988	CODEMASTERS
Deathsville	1986	Bubble Bus Software
DEFLEKTOR	1987	GREMLIN GRAPHICS
DIZZY		CODEMASTERS
DIZZY - PRINCE OF THE YOLKFOLK	1990	CODEMASTERS
DONKEY KONG	1986	OCEAN SOFTWARE LTD
DRILLER	1987	HIT SQUAD
DROIDS	1988	RICOCHET
Dungeons, Amethysts, Alchemists 'N' Everythin'		Atlantis
E-MOTION	1988	ERBE/US GOLD
Emilio Butragueño Fútbol	1988	TOPO SOFT
ESCAPE FROM SINGE'S CASTLE		ENCORE
EXOLON	1987	HEWSON CONSULTANTS
F.A. CUP FOOTBALL	1986	RICOCHET
FANTASY WORLD DIZZY		CODEMASTERS
FANTASY WORLD DIZZY	1989	CODEMASTERS
FEUD		BULLDOG
FLIMBO'S QUEST	1990	KIXX
FLYSPY	1986	MASTERTRONIC LTD
FORMULA 1 SIMULATOR		
Freedom Fighter		The Power House
Freedom Fighter		The Power House
FROST BYTE	1986	MIKROGEN
FRUIT MACHINE	1984	AMSOFT
Fruit Machine Simulator 2		Codemasters
Galactic Plague (The)		Amsoft
GALACTIC PLAGUE (THE)	1984	AMSOFT
GALIVAN	1988	OCEAN
GARY LINEKER'S SUPERSTAR SOCCER	198?	GREMLIN
GARY LINEKERS SUPERSTAR FOOTBALL	1987	GREMLIN GRAPHICS LTD
GENGHIS KHAN		
Ghost Hunters		Codemasters
GHOSTBUSTERS	????	RICOCHET
GLIDER RIDER	1986	QUICKSILVA LTD
GOONIES	1986	US GOLD,DATASOFT
GRAND PRIX SIM 2		CODEMASTERS
GRAND PRIX SIMULATOR	198?	CODE MASTERS LTD
Green Beret		Imagine
GROWING PAINS OF ADRIAN MOLE (THE)	1987	RICOCHET
Grumpy Gumphrey Supersleuth	1987	Gremlin Graphics
H.A.T.E.(HOSTILE ALL TERRAIN ENCOUNTER)	1989	GREMLIN GRAPHICS
Hacker	1985	Mastertronic (Ricochet);ACTIVISION
HACKER		RICOCHET
Hard Drivin'	1989	Domark Ltd.
HARRIER ATTACK	1984	AMSOFT
HAUNTED HEDGES	1984	AMSOFT
HAUNTED HEDGES	1984	AMSOFT
HEAVY ON THE MAGIK		REBOUND
HIGH STREEL	1987	ARCANA LTD
HOPPING MAD	1988	ELITE
HUMPREY	19??	ZIGURAT
Hunchback		Amsoft
Hunchback		Amsoft
HUNCHBACK - THE ADVENTURE	1986	OCEAN LTD
HUNDRA		MASTERTRONIC
HYPERBOWL	1986	MASTERTRONIC LTD
HYPERSPORTS	1984	IMAGINE
IK+		Activision (UK) Ltd
Impossible Mission		U.S. Gold
INTO THE EAGLES NEST	1988	PLAYERS
JACK THE NIPPER 2: COCONUT CAPERS	1987	GREMLIN GRAPHICS LTD
JET SET WILLY - THE FINAL FRONTIER	1985	SOFTWARE PROJECTS LTD
Jewels Of Darkness - Trilogy	1986	Rainbird/Firebird
JOE BLADE	1987	PLAYERS
JOE BLADE 2	1988	PLAYERS
KARNOV	1988	ACTIVISION, ELECTRIC DREAMS
Kikstart 2 + Course Designer	1987	Mastertronic
KILLAPEDE	1986	PLAYERS
KNIGHT TYME	1986	MASTERTRONIC
KNIGHT TYME	1986	MASTERTRONIC
Kung-Fu	1986	Bug Byte
KUNG-FU MASTER	1987	US GOLD
KWIK SNAX	1990	CODEMASTERS
LIGHTFORCE	1986	FASTER THAN LIGHT
MADMIX	1988	TOPO SOFT
MAGIC LAND DIZZY	1990	CODEMASTERS
MARAUDER	1988	HEWSON CONSULTANTS LTD
MARTIANOIDS	1987	A.C.G
Mask II		Gremlin Graphics Software Ltd.
MASTER'S OF THE UNIVERSE - THE MOVIE		KIXX
MASTERCHESS	1984	AMSOFT
Masters Of The Universe - The Movie	1986	Gremlin Graphics Software Ltd.
MATCH DAY 2	1988	OCEAN
MAX	1987	GENESIS SOFT
METROPOLIS	1987	TOPOSOFT
MIAMI VICE	1986	HIT SQUAD, OCEAN
MIG BUSTERS	1990	PLAYERS PREMIER
MISSION GENOCIDE	1987	FIREBIRD SOFTWARE
MISTERIO DEL NILO (EL)	1987	MADE IN SPAIN
MONOPOLY	198?	AMSTRAD
MOTO CROSS SIMULATOR	1988	CODEMASTERS
MOVIE	1986	IMAGINE SOFTWARE LTD
Mr. Freeze	1984	FireBird
Mr. Wong's Loopy Laundry	1984	Amsoft
Munch-it	1985	Tynesoft
N.O.M.A.D	1986	Amsoft
Nakamoto	?	The Power House
NEBULUS	1988	HEWSON CONSULTANTS LTD
NETHERWORLD	1988	HEWSON
NIGHT RAIDER	1988	GREMLIN GRAPHICS LTD
NINJA MASSACRE	1988	CODEMASTERS
Nocturne	1986	The Power House
NONAMED		RICOCHET
NORTH STAR	1987	GREMLIN GRAPHICS
Number 1	1986	Bug Byte
OH MUMMY	1984	AMSOFT
OH MUMMY	1984	AMSOFT
Olli & Lissa - The Ghost of Shilmore Castle	1987	Firebird Software
ONE MAN AND HIS DROID	1985	MASTERTRONIC LTD
OPERATION HANOI	1990	PLAYERS PREMIER LTD
OPERATION HORMUZ	1987	ALTERNATIVE SOFTWARE LTD
PacLand	198?	Grandslam Entertainments Ltd.
PACMANIA	1988	GRANDSLAM
PANIC DIZZY		CODEMASTERS
POWERPLAY, THE GAME OF THE GODS (SPANISH)	1986	ARCANA SOFTWARE DESIGN
PRO GOLF	1987	ATLANTIS
PRO POWERBOAT SIMULATOR	1989	CODEMASTERS
PRO SKI SIMULATOR	198?	CODE MASTERS LTD
QUEST FOR THE GOLDEN EGG CUP		MASTERTRONIC
RADIUS		PLAYERS
RADZONE	1986	MASTERTRONIC
RAID		AMERICANA
RAID OVER MOSCOW	1986	U.S GOLD
RALLY 2	1984	AMSOFT & LORICIELS
RAMPAGE	1987	ACTIVISION
RASTERSCAN	1987	MASTERTRONIC LTD
RATAS DEL DESIERTO/DESERT RATS	1985	CCS
REFLEX	1987	PLAYERS
RESCUE ON FRACTALUS	1989	MASTERTRONIC, LUCASFILM GAMES
ROBIN OF SHERWOOD: THE TOUCHSTONES OF RHIANNON	1984	ADVENTURE INTERNATIONAL U.K.
ROCKSTAR: ATE MY HAMSTER		CODEMASTERS
Rocky Horror Show	1988	Alternative Software Ltd.
Roland In The Caves		Amsoft
ROLAND IN THE CAVES	?	AMSOFT
ROLAND IN TIME		
ROLAND IN TIME	1984	AMSOFT
Roland On The Ropes		Amsoft
ROLAND ON THE ROPES	?	AMSOFT
Roland On The Run	1984	AMSOFT
Rooster Run		Samurai Software
Saboteur II	1987	Elite System Limited
SACRED ARMOUR OF ANTIRIAD		SILVERBIRD
SAS COMBAT SIMULATOR	1988	CODEMASTERS
SATAN	1990	DYNAMIC
SAVAGE	198?	FIREBIRD
SCARED ARMOUR OF ANTIRIAD (THE)	1986	PALACE SOFTWARE LTD
SCARED ARMOUR OF ANTIRIAD (THE)/ARMADURA SACRADA DE ANTIRIAD (LA)	1986	PALACE SOFTWARE LTD
SCOOBY DOO IN THE CASTLE MYSTERY	1986	ELITE SYSTEMS LTD
SENTINEL	1987	FIREBIRD
SEYMOUR AT THE MOVIES		CODEMASTERS
SHARKEY'S MOLL	1991	ZEPPELIN GAMES
Shockway Rider		Faster Than Light
SIR FRED	19??	MADE IN SPAIN
SKWEEK	1989	LORICIELS
Snoopy	1989	The Edge / Softek International
SOCCER BOSS	198?	ALTERNATIVE
Soldier Of Light (Xain'd Sleena)	1989	RAD
SOUL OF A ROBOT/NONTERRAQUEOUS 2	1985	MASTERTRONIC LTD
Soviet Fighter Mig 29		Codemasters
SPACE HAWKS	1984	AMSOFT
SPEED KING	1986	MASTERTRONIC LTD
SPELLBOUND	1986	MASTERTRONIC
SPELLBOUND DIZZY	1991	CODEMASTERS
SPIELBOX 1	1989	VEB MIKROELEKTRONIK
SPIELBOX 2	1989	VEB MIKROELEKTRONIK
SPIELBOX 5	1989	VEB MIKROELEKTRONIK
SPIELEBOX 15	1990	VEB MIKROELEKTRONIK
Spindizzy	1986	Electric Dreams
Spy Hunter	1986	KIXX (budget, original is Amsoft)
SPY VS SPY	1985	BEYOND SOFTWARE
Spy Vs Spy III - Arctic Antics	1987	Hi-Tec Software
Star Wars	1987	Domark Ltd.
Star Wars - Return Of The Jedi	1984	Domark Ltd.
Star Wars - The Empire Strikes Back	1988	Domark Ltd
Starion	1985	Melbourne House
STREET MACHINE	1986	POWER HOUSE
Subsunk	1985	FireBird
Subway Vigilante	1989	Players
Super Gran	1985	Tynesoft
SUPER HERO	1988	CODEMASTERS
SUPERTED	1990	ALTERNATIVE SOFTWARE
SWEEVO'S WORLD		REBOUND
TARZAN	1986	MARTECH
TAU CETI		RICOCHET
TEATRO DE EUROPA/THEATRE EUROPE	1985	
TEMPEST	1986	MASTERTRONIC RICOCHET
TEMPEST	1986	ELECTRIC DREAMS
TERRA COGNITA	1984	CODEMASTERS
TETRIS	1986	MIRRORSOFT LTD
THANATOS	1986	DURELL SOFTWARE
The Magic Sword	1984	Database Publications
The Munsters		Alternative Software Limited
THE NEVER ENDING STORY	1985	OCEAN LTD
THE QUEST FOR THE GOLDEN EGGCUP	1988	MASTERTRONIC
THING!	1988	PLAYERS
TOMY: EN EL SLALOM	1987	GENESIS SOFT
TOOBIN'	1988	HIT SQUAD
TRACK SUIT MANAGER	?	GOLIATH GAMES
TRAIL BLAZER	1986	GREMLIN GRAPHICS
TREASURE ISLAND DIZZY	198?	CODE MASTERS LTD
TREBLE CHAMPIONS	1989	CHALLENGE SOFTWARE
Trollie Wallie	1986	Players
TURBO THE TORTOISE	1992	CODEMASTERS
TWIN TURBO V8	1988	CODEMASTERS
URIDIUM	1987	HEWSON CONSULTANTS LTD
VAMPIRE	198?	CODE MASTERS LTD
VENOM STRIKES BACK	1988	GREMLIN GRAPHICS
Very Big Cave Adventure, The	1986	CRL
WAR ZONE	1984	CCS WAR GAMES
WAREWOLVES OF LONDON	1986	MASTERTRONIC
WAY OF THE EXPLODING FIST (THE)	1986	RICOCHET
Way Of The Exploding Fist (The)	1985	Melbourne House
WELLS AND FARGO	1988	TOPO SOFT
Werewolves of London	1988	Mastertronic
WILD WEST SEYMOUR	1992	CODEMASTERS
World Series Baseball	1985	Amsoft
Worm in Paradise, The	1985	Level 9 Computing
Wrath Of Olympus	1986	The Power House
Xeno	1986	B.D.L.
XEVIOUS	1987	US GOLD
YABBA DABBA DOO!	1988	BUG BYTE/GRANDSLAM
ZUB	1986	M.A.D.
ZYNAPS	1987	HEWSON CONSULTANTS
ZYNAPS	1987	HEWSON
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Carl »

J'ai eu quelques jours de repos et j'ai donc pu faire quelques nouveaux tests :

Philips VG8000 ok
Philips VG8010 ok
Philips VG8020 ok
Amstrad 464 ok
Amstrad 6128 ok
Spectrum 48K ok
Spectrum 128 ok
Spectrum +2A ok
Spectrum +3 ok ( attention utiliser jack stéréo)

et depuis le début des essais :
Matra Alice 4K ok
Matra Alice 32 ok
Matra Alice 90 ok
Tandy MC10 ok
VG5000 ok
EXL 100 ok

Carl
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Daniel »

Au fur et à mesure des tests, je mets à jour la liste de compatibilité à la page http://dcmoto.free.fr/bricolage/sdlep-reader/index.html

A priori, il n'y a pas d'obstacle pour faire fonctionner SDLEP-READER avec tous les ordinateurs connus, en ajoutant le potentiomètre de réglage de niveau. Le seul cas où une difficulté peut apparaître est un système où le magnétophone décode le signal enregistré sur la bande (comme les Thomson TO). Le problème n'est pas insoluble, il y aura toujours une solution, semblable à celle utilisée pour les TO.

Ceci dit, le système ne semble intéresser personne, je ne comprends pas bien pourquoi. Avec la plupart des ordinateurs on peut utiliser un baladeur ou autre appareil audio avec des fichiers .wav, mais les fichiers .LEP ont un avantage énorme : leur taille est environ 30 fois plus petite que celle du fichier .wav. L'autre avantage est spécifique à la gamme Thomson TO : aucun baladeur ou liaison directe avec un PC ne permet de charger une image de cassette sans le magnétophone d'origine de la machine. SDLEP-READER le permet.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par 6502man »

le problème c'est que les utilisateurs d'autres machines, préfèrent certainement utiliser les supports plus rapide comme les disquettes ou cartouches !

Car attendre plusieurs minutes pour jouer à un jeu, on à l'impression de jouer sur XBOX ONE et pas sur un ordinateur des annèes 80 :lol: :lol:

Blague à part, tu devrais promouvoir ton système sur d'autres forum, peut être que tu auras plus de succès, après il faut voir aussi que sur les machines plus connus il existe déjà pas mal de systèmes d'émulation D7 ou K7 !

D'ailleurs quelles machines n'ont pas eu de lecteur de disquettes ou très rare ?

Ce qui me viens à l’esprit (en dehors de ceux déjà testé par Carl) :
- Oric 1 & Atmos (lecteur disquette peu répandu à l'époque, 99,99% de la logithèque sur K7), cartouche inexistantes.
- Acorn Electron (Lecteur de disquette peu répandu à l'époque, 99,99% de la logithèque sur K7), cartouche inexistantes. *
- Acorn Atom. *
- Hector/Victor BR et HR
- Laser 200 à 500 (Lecteur de disquette peu répandu à l'époque, 99,99% de la logithèque sur K7), cartouche inexistantes. *
- Pencil II (Lecteur de disquette peu répandu à l'époque, 99,99% de la logithèque sur K7), cartouche inexistantes. *
-PHC25.
- SHARP MZ *
- Spectravidéo SV-318 /328 (Lecteur de disquette peu répandu à l'époque, logithèque sur K7 et cartouches ).
- Ordinateurs Russe
....

* = "A confirmer"
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Répondre