Важная информация

User Tag List

Страница 12 из 17 ПерваяПервая ... 8910111213141516 ... ПоследняяПоследняя
Показано с 111 по 120 из 164

Тема: ROM-плеер на ардуино

  1. #111
    Veteran
    Регистрация
    22.02.2014
    Адрес
    г. Курган
    Сообщений
    1,657
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    301
    Поблагодарили
    212 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Improver Посмотреть сообщение
    Игры с фильтрами/конденсаторами ничего не дают... Но заметил интересную особенность: сигнал с Вектора имеет небольшие задержки в передаче на границе каждого байта, примерно по 5 сэмплов на 96кГц, что равно ~50 мкс. ... Ардуина же напротив, чётко выдерживает все периоды. Вот, думаю, может в этом причина?
    ...
    О, да -- именно так и есть! Сейчас попробовал взять самый первый скетч и добавить туда задержку между байтами, и Вектор стал грузить на скоростях с полупериодом до 176 мкс, такой по скорости сигнал не давал ни один из копировщиков (речь идёт о стандартном формате ROM, не турбо)....
    Тут можно пойти от обратного...
    Вектор грузит и выгружает не по таймеру, а по алгоритму с задержками.
    Соответственно, нужно расписать тайминги команд алгоритма чтения, и будет видно, где какие задержки должны быть для "оптимальной" по скорости загрузки.
    На границе байта задержка нужна для записи принятого байта в память, а при приёме 32 байт ещё и на отрисовку принятой строчки блока (квадратика) на экране. А после приёма всего блока (256Байт) ещё и на проверку все ли строки блока приняты без ошибок. А это "не хухры-мухры", там идёт преобразование адреса принимаемой строки (32Байт в ОЗУ) в адрес на экране, довольно много вычислений. И когда возвращается к приёму следующего байта... а он уже проскочил...
    Но можно нарваться и на то, что в разных загрузчиках, "стандартный формт" может отличаться "авторской оптимизацией"... и тайминги для одного загрузчика не подойдут к таймингам в другом...
    Я так думаю...

    А можно и не маяться и не считать тайминги алгоритма, а просто подключить логгер на сигнал "ЧТВУ" и магнитофонный вход ВВ55. И посмотреть на эти самые тайминги...
    Последний раз редактировалось KTSerg; 11.03.2018 в 07:22.

  2. #112
    Veteran
    Регистрация
    22.02.2014
    Адрес
    г. Курган
    Сообщений
    1,657
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    301
    Поблагодарили
    212 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Посмотрел логером соотношение импульсов на магнитофонном входе и чтение порта.
    При 50мкс задержке между байтами конечно стало лучше. Но при увеличении интервала между байтами до 60мкс, программа стабильно грузится на стандартном заводском загрузчике в Вектор 06Ц.02, при полупериоде таймера... барабанная дробь...в 112мкс...!!!
    Правда для вычисления загрузчиком задержек, я отключаю изменение значения таймера на время меандра. Но вроде и без этого отключения работало.
    Программа в 21КБ грузится за 59сек, и это стандартный загрузчик...

  3. #113
    Master Аватар для Improver
    Регистрация
    06.02.2018
    Адрес
    г. Волгоград
    Сообщений
    975
    Спасибо Благодарностей отдано 
    429
    Спасибо Благодарностей получено 
    396
    Поблагодарили
    221 сообщений
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от svofski Посмотреть сообщение
    Занятно, кто б мог подумать. В Векторе и тут отличились
    Да, почти тридцать лет прошло, а секреты у Вектора ещё остались. :-)

    Таймеру1 можно период менять на ходу. Увеличивать его перед границей байта, потом обратно.
    Это хорошо, что так можно, иначе это было бы сложной проблемой... Так и сделал, и оно работает.

    Цитата Сообщение от KTSerg Посмотреть сообщение
    А можно и не маяться и не считать тайминги алгоритма, а просто подключить логгер на сигнал "ЧТВУ" и магнитофонный вход ВВ55. И посмотреть на эти самые тайминги...
    Можно, при его наличии и если об этом знать заранее. А так, внимательного рассмотрения и измерения wav-ки оказалось достаточно.

    Цитата Сообщение от KTSerg Посмотреть сообщение
    При 50мкс задержке между байтами конечно стало лучше. Но при увеличении интервала между байтами до 60мкс,
    После нескольких экспериментов установил, что для стабильного считывания нужно, чтобы задержка между байтами была в сумме равна около 256 мкс, т.е. при полупериоде 200 мкс в начале байта нужно добавить 56 мкс, 192 мкс -- +64 мкс и т.п.

    По крайней мере, это на ардуино и моих конденсаторах, а сейчас у меня собрана не лучшая схема...

    программа стабильно грузится на стандартном заводском загрузчике в Вектор 06Ц.02, при полупериоде таймера... барабанная дробь...в 112мкс...!!!
    Фантастический результат! Мне такой на Векторе не ".02" не удалось достичь даже близко... Минимум у меня -- 176 мкс, и то в девяти из десяти случаях Вектор не успевает распознать начало записи (00h/55h...).

    Программа в 21КБ грузится за 59сек, и это стандартный загрузчик...
    У меня получилось загрузить тот же 40-ка килобайтный Киберноид за три минуты, таймер при этом был выставлен на 184 мкс. Тоже не плохо, я считаю.

    - - - Добавлено - - -

    Выкладываю улучшенную, по скорости вывода, версию:

    ROM-player_3

    Требования по библиотекам не изменились -- нужны TimerOne, SdFat и LiquidCrystal.
    Код:
    /*
      SD-картридер подключяется к выводам ардуино:
     * MOSI  - D11
     * MISO  - D12
     * CLK   - D13
     * CS    - D10
     
     Выход - D3
     
     Подключение экрана 1602А (LCD Keypad Shield):
     * LCD RS pin     - D8
     * LCD Enable pin - D9
     * LCD D4 pin     - D4
     * LCD D5 pin     - D5
     * LCD D6 pin     - D6
     * LCD D7 pin     - D7
     * LCD R/W pin    - GND
     * LCD 5V pin     - 5V
     
     Кнопки подключаются на вывод A0 (схема LCD Keypad Shield)
     */
    
    // include the library code:
    #include <LiquidCrystal.h>
    #include <SdFat.h>
    #include <TimerOne.h>
    
    // initialize the library with the numbers of the interface pins
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
    
    SdFat sd;
    SdFile romFile;
    
    #define filenameLength    100      // максимальная длина имени файла
    char fileName[filenameLength + 1]; // имя текущего файла
    char sfileName[13];                // короткое имя текущего файла
    int currentFile = 1;               // текущая позиция в директории
    int maxFile = 0;                   // всего позиций в лиректории (файлов и поддиректорий)
    byte isDir = 0;                    // признак того, что текущая позиция -- это директория
    
    byte BLs = 0x01;    // начальный блок
    unsigned int Nbt;   // размер файла, байт
    
    volatile byte BUFF[256];       // буфер данных
    volatile unsigned int CRB = 0; // индекс чтения из буфера
    volatile byte bBit = 15;       // индекс читаемого полубита
    unsigned int CWB = 0;          // индекс записи в буфер
    unsigned int CRB_temp = 0;     // временная переменная для CRB
    
    // Заголовок
    byte SB[27] = { 
      0x4E, 0x4F, 0x44, 0x49, 0x53, 0x43, 0x30, 0x30, // NODISK00
      0x31, 0x34, 0x30, 0x32, 0x31, 0x38,             // дата: 140218
      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // имя программы
      0x20, 0x20, 0x20, 0x00, 0x00 };
    
    volatile int Tpp = 200; // Начальная длительность задержки сигнала в микросекундах (один полупериод)
    volatile int Tb  = 64;  // Дополнительная задержка сигнала на начало байта в микросекундах
    
    const int p = 3; // номер пина, на который будет вывод сигнала
    
    const int BT_none   = 0; // константы -- коды нажатой кнопки
    const int BT_right  = 1;
    const int BT_up     = 2;
    const int BT_down   = 3;
    const int BT_left   = 4;
    const int BT_select = 5;
    
    void setup() {
      pinMode(p, OUTPUT);  // объявляем пин как выход
      digitalWrite(p, LOW);
      pinMode(10, OUTPUT); // CS для SD-картридера
      lcd.begin(16, 2);    // объявляем размер экрана 16 символов и 2 строки
    
      Timer1.initialize(Tpp);               // инициализировать timer1, и установить период Tpp мкс.
      Timer1.attachInterrupt(SendHalfBit);  // прикрепить SendHalfBit(), как обработчик прерывания по переполнению таймера
      Timer1.stop();
    
      while (!sd.begin(10,SPI_FULL_SPEED)){ // SD-карта готова?
        printtext("SD-card failed!",0);
        tone(p, 200, 100); // нет -- включаем на 200 Гц на 100 мс
        delay(3000);       // ждем 3 с
      }
      printtext("SD-card is OK.",0);
    
      sd.chdir();            // устанавливаем корневую директорию SD
      getMaxFile();          // получаем количество файлов в директории
      seekFile();            // переходим к первому файлу в директории
    }
    
    void loop() {
      lcd.setCursor(0, 1); // устанавливаем курсор в позицию 0 в строке 1
      lcd.print(millis()/1000); // выводим количество секунд с момента влючения ардуины -- это для теста...
    
      int button = getPressedButton(); // какая кнопка нажата?
      switch (button)
      {
      case BT_right: // вход в директорию, или запуск файла на воспроизведение
        if(isDir==1) { //Если это директория, то переход в неё
          sd.chdir(fileName, true);
          getMaxFile();
          currentFile=1;
          seekFile();
        } 
        else {         // если не директория -- пробуем воспроизвести файл
          if(romFile.cwd()->exists(sfileName)) {
            printtext("Not ROM-file",1);
            if (Nbt != 0xFFFF) { // проверяем размер файла
              for (int i=0;12;i++){ // цикл по имени файла
                if (sfileName[i]=='.'){                 // ищем точку в имени файла
                  if ((sfileName[i+1]|0x20)=='r') {     // проверяем следующий символ (расширения) == 'r'|'R'
                    if (((sfileName[i+2]|0x20)=='o')|((sfileName[i+2]|0x20)=='0')) {   // == 'o'|'O'|'0'
                      if ((sfileName[i+2]|0x20)!='0') { // проверка на вывод нулевого блока по расширению файла
                        BLs = 0x01; // с первого блока
                      }
                      else { 
                        BLs = 0x00; // с нулевого блока
                      }
                      if ((sfileName[i+3]|0x20)=='m') { // == 'm'|'M'
                        printtext("Playing...",1);
                        int RCrom = PlayROM(sfileName, i);// Передаём короткое имя файла и позицию точки в качестве параметров
                        switch (RCrom)                    // Проверяем код возврата
                        {
                        case 0:
                          printtext("Done.",1);           // Всё закончилось успешно.
                          break;
                        case 1:
                          printtext("Stopped",1);         // Сообщение об остановке
                          while(getPressedButton()!=BT_none) { // Ждём, пока не будет отпущена кнопка
                            delay(50); 
                          }
                          break;
                        default:  
                          printtext("ERROR!",1);          // Сообщение об ошибке
                        }
                        digitalWrite(p, LOW);
                        seekFile();
                      }
                    }
                  }
                  break;
                }
              }
            }
            else {
              printtext("File is too big",1);
            }
          } 
          else {
            printtext("No File Selected",1);
          }
          delay(1000);           // ждем 1 с
          printtext(" ",1);      // очищаем строку 1
        }
        break;
      case BT_left: // возврат в корневую директорию, ремарка ниже:
        //SDFat has no easy way to move up a directory, so returning to root is the easiest way. 
        //each directory (except the root) must have a file called ROOT (no extension)
        sd.chdir(true);
        getMaxFile();
        currentFile=1;
        seekFile();
        break;
      case BT_up: // вверх по файлам в директории
        currentFile--;
        if(currentFile<1) {
          getMaxFile();
          currentFile = maxFile;
        }
        seekFile();
        break;
      case BT_down: // вниз по файлам в директории
        currentFile++;
        if(currentFile>maxFile) { 
          currentFile=1; 
        }
        seekFile();
        break;
      case BT_select: // выход в настройки...
        printtext("Period(mks):",0);
        do {
          while(getPressedButton()!=BT_none) { // Ждём, пока не будет отпущена кнопка
            delay(50); 
          }
          delay(200);
          button = getPressedButton(); // какая кнопка нажата?
          switch (button)
          {
          case BT_up:   
            if (Tpp<400) Tpp += 8;
            break;
          case BT_down:   
            if (Tpp>176) Tpp = Tpp - 8;
            break;
          }
          if (Tpp <= 264) { // Выставляем значение задержки на начало байта Tb
            Tb = 16;                        // для полупериода от 248 до 264
            if (Tpp <= 240) Tb = 264 - Tpp; // для полупериода меньше или равном 240 
          }
          else Tb = 0;                      // для полупериода больше 264
          lcd.setCursor(12,0);
          lcd.print(Tpp);
        } 
        while(button!=BT_select); // Цикл пока не будет снова нажата кнопка select
        seekFile();
        break;
      case BT_none: // ничего не нажато
        break;
      }    
      while(getPressedButton()!=BT_none) { // Ждём, пока не будет отпущена кнопка
        delay(50); 
      }
    }
    
    //=================================================================
    int getPressedButton()  // функция проверки нажатой кнопки
    {
      int buttonValue = analogRead(0);
      if (buttonValue < 100) return BT_right;
      else if (buttonValue < 200) return BT_up;
      else if (buttonValue < 400) return BT_down;
      else if (buttonValue < 600) return BT_left;
      else if (buttonValue < 800) return BT_select;
      return BT_none;
    }
    
    void printtext(char* text, int l) {  // Вывод текста на экран в строке l с очисткой строки
      lcd.setCursor(0,l);
      lcd.print("                ");
      lcd.setCursor(0,l);
      lcd.print(text);
    }
    
    void getMaxFile() { // считаем файлы в текущей директории и сохраняем в maxFile
      romFile.cwd()->rewind();
      maxFile=0;
      while(romFile.openNext(romFile.cwd(),O_READ)) {
        romFile.close();
        maxFile++;
      }
    }
    
    void seekFile() { // переход на позицию в директории, сохранение имени файла и показ его на экране
      romFile.cwd()->rewind();
      for(int i=1;i<currentFile;i++) { // читаем первые файлы до currentFile
        romFile.openNext(romFile.cwd(),O_READ);
        romFile.close();
      }
      romFile.openNext(romFile.cwd(),O_READ); // читаем данные текущего файла
      romFile.getName(fileName,filenameLength);
      romFile.getSFN(sfileName);
      isDir = romFile.isDir();
      if (romFile.fileSize()<=49152) { // проверка размера файла
        Nbt = romFile.fileSize();      // размер файла ОК
      }
      else {
        Nbt = 0xFFFF;                  // слишком большой для загрузки
      }
      romFile.close();
      printtext(sfileName,0);       // вывод имени текущего файла
      if (isDir==1) lcd.print('>'); // если это директория, добавляем в конце символ '>'
    }
    
    int PlayROM(char FName[], int pnt) // функция вывода файла
    {
      delay(1000);           // ждем 1 с
    
      if (romFile.open(FName,O_READ)) { // открываем файл. Открылся?
        byte BLe = Nbt/256; // всего блоков
        byte BLt;           // осталось блоков
        byte Nst;           // номер строки
        byte St;            // выводимый байт
    
        byte CSz = 0x00;    // контрольная сумма заголовка
        byte CSs = 0x00;    // контрольная сумма строки
        byte i;
        byte j;
    
        if (Nbt%256 != 0) BLe++; // корректировка количества блоков, если размер файла не кратен 256
    
        for (i=0; i<=7; i++){                // заносим в SB имя файла
          if (i < pnt) {                     // имя ещё не закончилось?
            if ((FName[i]>=0x61) && (FName[i]<=0x7A)) {
              SB[i+14] = FName[i] - 0x20;    // на заглавные буквы
            }
            else if (FName[i]!=0x7E) {       // не тильда
              SB[i+14] = FName[i];
            }
            else {
              SB[i+14] = '_';                // меняем тильду на подчёркивание, иначе это будет русская "Ч"
            }
          }
          else SB[i+14] = 0x20;              // пробелы
        }
        for (i=1; i<=3; i++){              // заносим в SB расширение файла
          if ((FName[pnt+i]>=0x61) && (FName[pnt+i]<=0x7A)) {
            SB[i+21] = FName[pnt+i] - 0x20;  // на заглавные буквы
          }
          else {
            SB[i+21] = FName[pnt+i];
          }
        }
    
        dir_t d;
        romFile.dirEntry(&d);                    // Считываем дату файла
        uint16_t AAA = FAT_DAY(d.lastWriteDate); // Сохраняем дату файла в заголовке -- день
        SB[8] = (AAA%100)/10 + '0';              // перевод из целого в символ
        SB[9] = AAA%10 + '0';
        AAA = FAT_MONTH(d.lastWriteDate);        // месяц
        SB[10] = (AAA%100)/10 + '0';
        SB[11] = AAA%10 + '0';
        AAA = FAT_YEAR(d.lastWriteDate);         // последние две цифры года
        SB[12] = (AAA%100)/10 + '0';
        SB[13] = AAA%10 + '0';
    
        // Начинаем наполнять буфер
        for (i=0; i<=3; i++){           // преамбула (4*(00H*25+55H*25))
          for (j=0; j<=24; j++){
            BUFF[lowByte(CWB)] = 0x00;
            CWB++;
          }
          for (j=0; j<=24; j++){
            BUFF[lowByte(CWB)] = 0x55;
            CWB++;
          }
        }  
    
        Timer1.setPeriod(Tpp); // Выставляем период таймера
        Timer1.start();           // Запускаем таймер............
    
        for (BLt=BLe; BLt>=1; BLt--){   // Вывод блоков данных в цикле
          CSz = BLs;
          CSz += BLe;
          CSz += BLt;
    
          for (j=0; j<=15; j++) ToBUFF(0x00);// 00h*16
          for (j=0; j<=3; j++)  ToBUFF(0x55);// 55h*4
          ToBUFF(0xE6);                      // E6h*1
          for (j=0; j<=3; j++)  ToBUFF(0x00);// 00h*4
    
          for (j=0; j<=26; j++){             // заголовок блока
            CSz += SB[j];
            ToBUFF(SB[j]);
          }
          ToBUFF(BLs);                       // начальный блок
          ToBUFF(BLe);                       // конечный блок
          ToBUFF(BLt);                       // осталось блоков
    
          lcd.setCursor(12, 1);              // выводим на экран кол-во оставшихся блоков
          lcd.print(BLt);
          lcd.print(" ");
    
          ToBUFF(CSz);                       // контр.сумма заголовка
    
          for (Nst=0x80; Nst<=0x87; Nst++){   // вывод строк (8 шт.)
            for (j=0; j<=3; j++) ToBUFF(0x00);// 00h*4
            ToBUFF(0xE6);                     // E6h*1
            CSs = Nst;
            ToBUFF(Nst);                      // номер строки
            CSs += CSz;
            ToBUFF(CSz);                      // контр.сумма заголовка
    
            // начинаем вывод строки данных
            for (j=0; j<=31; j++){      // цикл на 32 байта
              if (Nbt > 0){             // ещё есть данные?
                St = romFile.read();    // читаем очередной байт из файла
                Nbt--;
              }
              else {                    // нет -- дополняем нулями
                St = 0x00;
              }
              ToBUFF(St);               // передаём считанный байт
              CSs += St;
              if (getPressedButton()!=BT_none) { // кнопка нажата?
                Timer1.stop();          // Останавливаем таймер
                CRB = 0;                // Сбрасываем индексы.
                CWB = 0;
                bBit = 15;
                romFile.close();        // закрываем файл
                return 1;               // выход из ПП с ошибкой 1.
              }
              if (CRB_temp > CWB) {     // проверка -- не обогнало ли чтение запись?
                Timer1.stop();          // Останавливаем таймер
                CRB = 0;                // Сбрасываем индексы.
                CWB = 0;
                bBit = 15;
                romFile.close();        // закрываем файл
                return 2;               // выход из ПП с ошибкой 2.
              }
            }
            ToBUFF(CSs);                // контр.сумма строки
          }  
        }
        romFile.close(); // закрываем файл
    
        for (j=0; j<=31; j++) ToBUFF(0x00);// 00h*32 -- завершение вывода программы (?)
      }
      else tone(p, 200, 300); // нет файла -- включаем на 200 Гц на 300 мс
    
      do{                     // Ждём опустошения буфера
        delay(Tpp/64);        // задержка на вывод 1 байта (~Tpp*16/1000)
        noInterrupts();       // запрет прерываний
        CRB_temp = CRB;       // сохраняем CRB во временную переменную
        interrupts();         // разрешение прерываний
      }
      while (CRB_temp < CWB);
    
      Timer1.stop();  // Останавливаем таймер............
      CRB = 0;        // Сбрасываем индексы.
      CWB = 0;
      bBit = 15;
      return 0;       // выход из ПП с кодом 0.
    }
    
    void ToBUFF(byte SBb){     // Подпрограмма записи байта в буфер
      noInterrupts();               // запрет прерываний
      CRB_temp = CRB;               // сохраняем CRB во временную переменную
      interrupts();                 // разрешение прерываний
      if (CWB > (CRB_temp + 255)) { // Если позиция записи больше, чем позиция чтения + размер буфера - 1
        delay(Tpp);                 // Задержка (Tpp*1000 мкс = Tpp мс = 125 байт)
      }
      BUFF[lowByte(CWB)] = SBb;
      CWB++;
    }
    
    void SendHalfBit() {  // Подпрограмма вывода полубита по циклу таймера
      byte Pd=PORTD;
      if (bBit & 1){      // проверка индекса полубитов на чётность
        if (( (Pd >> p)^( BUFF[lowByte(CRB)] >> (bBit >> 1) ))&1){ // Если состояние порта и выводимый бит разные
          Pd ^= (1 << p); // инвертируем бит в позиции p
        }
      }
      else{               // чётный -- просто инвертируем порт
        Pd ^= (1 << p);   // инвертируем бит в позиции p(=3)
      }
      PORTD = Pd;         // вывод в порт p
      if (bBit > 0) {     // правим счётчики полубитов и байтов
        bBit--;
        if (bBit == 14) Timer1.setPeriod(Tpp); // Выставляем период таймера (биты)
      }
      else{
        bBit = 15;
        CRB++;
        if (CRB > 200) Timer1.setPeriod(Tpp+Tb); // Выставляем увеличенный период таймера (начало байта)
      }
    }
    [свернуть]

    Изменения:
    - сделана дополнительная задержка между байтами при передаче данных, что позволило существенно повысить скорость чтения Вектором.

    Примечание: для увеличения стабильности определения Вектором начала передачи и расчёта скорости, добавление задержек в начальный заголовок передаваемых данных не делается.

    Исходники с библиотеками в одном архиве: ROM-player_3.7z

  4. #114
    Veteran
    Регистрация
    22.02.2014
    Адрес
    г. Курган
    Сообщений
    1,657
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    301
    Поблагодарили
    212 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    ... После нескольких экспериментов установил, что для стабильного считывания нужно, чтобы задержка между байтами была в сумме равна около 256 мкс, т.е. при полупериоде 200 мкс в начале байта нужно добавить 56 мкс, 192 мкс -- +64 мкс и т.п. ...
    До такого я не допетрил, но заметил, что длительность полупериода должна быть кратной 16. Т.е. на 112, 128, 156, 172 ... таймингах нормально грузит, а на значениях между ними, даже с разницей 1-2 единицы от указанных величин, либо вообще не подхватывает, либо быстро ошибку ловит...

  5. #115
    Veteran
    Регистрация
    22.02.2014
    Адрес
    г. Курган
    Сообщений
    1,657
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    301
    Поблагодарили
    212 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Наконец получилось с помощью объединённого ROM-плеера/SD-ROM картриджа считать заводской загрузчик, на SD-карту, не прибегая ни к каким припаиваниям, замыканиям, и прочим аппаратным ухищрениям. Просто загрузил программку, которая слила загрузчик на SD-карту.
    Сравню с имеющимися загрузчиками, может есть отличия...

    От загрузчика kish2 отличается.
    Последний раз редактировалось KTSerg; 11.03.2018 в 22:21.

  6. #116
    Guru
    Регистрация
    07.08.2008
    Адрес
    г. Уфа
    Сообщений
    7,843
    Спасибо Благодарностей отдано 
    654
    Спасибо Благодарностей получено 
    1,818
    Поблагодарили
    1,044 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от KTSerg Посмотреть сообщение
    считать заводской загрузчик, на SD-карту, не прибегая ни к каким припаиваниям, замыканиям, и прочим аппаратным ухищрениям. Просто загрузил программку, которая слила загрузчик на SD-карту.
    Как минимум автостарт же надо было реализовать, чтобы пзу не отключилось (типа как в ROM-REAPER/TURBO-COPY), или как?

  7. #117
    Veteran
    Регистрация
    22.02.2014
    Адрес
    г. Курган
    Сообщений
    1,657
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    301
    Поблагодарили
    212 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от ivagor Посмотреть сообщение
    Как минимум автостарт же надо было реализовать, чтобы пзу не отключилось (типа как в ROM-REAPER/TURBO-COPY), или как?
    Не, нужно было не заставить ПЗУ включиться, а обмануть загрузчик и перехватить управление ДО выключения ПЗУ (до сброса).
    Я тупанул, пошел по прямой дорожке, и потратил почти целый день на войну с загрузчиком, пытаясь перехватить у него управление.
    Не мог понять почему читаю сплошные "00", даже схему изучал, думал, что прочитать инфу, из программы за пределами области памяти загрузчика, нельзя (ошибочное предположение, но другое в голову не приходило). Оказалось, что перед передачей управления моей (загруженной) программе, загрузчик успевал щелкнуть рэлюхой (её управление заведено на схему "сброса"), и ПЗУ отключалось.
    Мог за пол часа, в эмуляторе сделать скриншот загрузочной сетки Вектора, вырезать из него экранную область, дорисовать квадратики в загрузочной сетке, поправить стек в адресах 0xDExxh, прикрепить полученное к своей программе ... и получить результат.

  8. #118
    Guru
    Регистрация
    07.08.2008
    Адрес
    г. Уфа
    Сообщений
    7,843
    Спасибо Благодарностей отдано 
    654
    Спасибо Благодарностей получено 
    1,818
    Поблагодарили
    1,044 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от KTSerg Посмотреть сообщение
    Не, нужно было не заставить ПЗУ включиться, а обмануть загрузчик и перехватить управление ДО выключения ПЗУ (до сброса).
    Насколько я знаю, чисто программно заставить ПЗУ включиться нельзя.
    ROM-REAPER/TURBO-COPY как раз автостартуют, т.е. перехватывают управление до отключения ПЗУ.

  9. #119
    Veteran
    Регистрация
    22.02.2014
    Адрес
    г. Курган
    Сообщений
    1,657
    Спасибо Благодарностей отдано 
    218
    Спасибо Благодарностей получено 
    301
    Поблагодарили
    212 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от ivagor Посмотреть сообщение
    Насколько я знаю, чисто программно заставить ПЗУ включиться нельзя.
    ROM-REAPER/TURBO-COPY как раз автостартуют, т.е. перехватывают управление до отключения ПЗУ.
    Может я его с чем-то путаю, но в картотеке есть описание выгружалки ПЗУ, там нужно в схему Вектора кнопку и диод допаять.

  10. #120
    Guru
    Регистрация
    07.08.2008
    Адрес
    г. Уфа
    Сообщений
    7,843
    Спасибо Благодарностей отдано 
    654
    Спасибо Благодарностей получено 
    1,818
    Поблагодарили
    1,044 сообщений
    Mentioned
    22 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    С кнопкой это ROM-DUMPER
    А чисто программный - ROM-REAPER

Страница 12 из 17 ПерваяПервая ... 8910111213141516 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Портативный AY плеер.
    от Руслан в разделе Звук
    Ответов: 1
    Последнее: 16.04.2014, 08:46
  2. Service rom + 128 basic rom
    от VELESOFT в разделе Оси
    Ответов: 1
    Последнее: 24.03.2013, 04:48
  3. Плеер для pt 3
    от Руслан в разделе Музыка
    Ответов: 25
    Последнее: 14.08.2012, 19:25
  4. Advanced ROM Manager (ROM Switvcher + Prof. ROM)
    от Alex_NEMO в разделе Память
    Ответов: 4
    Последнее: 04.10.2010, 11:43
  5. AY плеер
    от newart в разделе Звук
    Ответов: 19
    Последнее: 20.07.2006, 00:03

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •