1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Пожалуйста, внимательно прочитайте правила раздела.
  3. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Кодерский уголок

Тема в разделе "Мастерская", создана пользователем Dimouse, 10 сен 2006.

  1. Dimouse King of Mice

    Dimouse

    Администратор Переводчик

    Регистрация:
    18 апр 2003
    Сообщения:
    35.151
    В соответствии с назначением раздела, в этой теме предполагается обсуждать конкретные вопросы, которые у вас возникают при создании своих программ (в частности - игр), помогать другим, размещать полезные ссылки на статьи и материалы, которые могут пригодиться другим.

    Что здесь не допускается:
    - беспорядочный флуд на всевозможные темы, в том числе общие обсуждения языков программирования без конкретики (карается по статье "флуд и оффтопик" *),
    - разжигания на темы "что лучше, Си или Си++ и чем они отличаются?", "какой язык программирования лучше X или Y?" и т.п. (карается по статье "флейм и участие в холиварах" *),
    - мерение пиписьками в стиле "я лучше программирую" или "ты не умеешь программировать" (карается по статье "оскорбление участников и их взглядов" *).

    Всё это допускается в специально созданной теме "Беседка для программистов или «Бутерброд с кодом».

    * по усмотрению модератора также возможно применение блокировки в данной теме.

    Оригинальное сообщение
     
    Последнее редактирование модератором: 24 ноя 2014
    CY8R4Y нравится это.
  2.  
  3. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    С управлением размером буфера подсказали и разобрался.
    Код:
    HRESULT subhook_c::DecideBufferSize( IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties ) {
      HRESULT hr;
      int new_bufsize = g_max_subtitle_size;
      ALLOCATOR_PROPERTIES previous;
    // сначала отрабатываем штатный:
      if ( FAILED( hr = CTransInPlaceFilter::DecideBufferSize( pAlloc, pProperties ) ) )
        return ( hr );
    #ifndef NDEBUG // [
      new_bufsize = 16384; // только чтобы проверить идею
    #endif // ]
      if ( pProperties->cbBuffer < new_bufsize ) { // мало - увеличиваем:
        pProperties->cbBuffer = new_bufsize;
    // пробуем:
        if ( FAILED( hr = pAlloc->SetProperties( pProperties, &previous ) ) )
          return ( hr );
    // проверяем:
        if ( previous.cbBuffer < pProperties->cbBuffer )
          return ( E_FAIL );
      }
      return ( hr );
    }
    Вроде работает, никто никуда не падает.
     
  4. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    И снова вопрос про таймер! Можно ли вместо перехвата обработчика просто перепрограммировать другой канал (не нулевой) на нужную мне частоту, а затем просто считывать оттуда значения?
     
  5. Bato-San Чеширский волк-киборг

    Bato-San

    Регистрация:
    24 июн 2010
    Сообщения:
    14.136
    Geryon, можно. Но не нужно. Ибо ты не учитываешь время затрачиваемое на такие действия вне прерывания и толпу прерываний между этими действиями.
     
  6. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Эээ... Какими действиями?
     
  7. Bato-San Чеширский волк-киборг

    Bato-San

    Регистрация:
    24 июн 2010
    Сообщения:
    14.136
    Geryon, прерывание прилетает условноточно по границе временного интервала железки. Программная же проверка без прерывания от данной железки не выравнивается ни на что. Учитывая, что ты пишешь на псях, а не на асме и такты не считаешь - у тебя будет офигеть какая "оптимизация" в плане времени выполнения.

    Не то что бы это совсем уж невозможно, особенно для доса, но не спектрум всё же.
     
  8. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    А чем тогда может помочь обработчик прерывания?
     
  9. Bato-San Чеширский волк-киборг

    Bato-San

    Регистрация:
    24 июн 2010
    Сообщения:
    14.136
    Geryon, ты чем прочитал предыдущий пост ? Написано же чем. Прям в первой фразе. А в конце написано почему без него получится фигня скорее всего.

    Если я правильно понимаю задачу - твоему драйверу охота делать что то через определённое время. Притом время очень небольшое и с высокой точностью таймера. Иначе зачем огород с таймером городить ? Ведь можно и часы читать. А коли нужна высокая точность - значит обрботчик дожен получать пинка точно в нужный момент и тратить на обработку не больше чем запланировано.
     
  10. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Задача следующая: библиотека libsidplayfp что-то там внутри себя эмулирует и вызывает метод драйвера ::clock, в коем методе известно, сколько прошло циклов C64 с момента прошлого вызова метода.

    Я переделывал драйвер SSI-2001 из драйвера HardSID. Так вот, в этом HardSID есть внутренний таймер, который используется для корректного независимого от скорости CPU воспроизведения:

    Код:
    void HardSID::clock()
    {
        if (!m_handle)
            return;
    
        event_clock_t cycles = m_context->getTime(m_accessClk, EVENT_CLOCK_PHI1);
        m_accessClk += cycles;
    
        while (cycles > 0xffff)
        {
            ioctl(m_handle, HSID_IOCTL_DELAY, 0xffff);
            cycles -= 0xffff;
        }
        if (cycles)
            ioctl(m_handle, HSID_IOCTL_DELAY, cycles);
    }
    
    Можно предположить, что HardSID поддерживает только 16-битные значения задержки, отсюда выверты с 0xffff.

    А у SSI-2001 никаких внутренних таймеров нет, поэтому надо как-то решать за счет таймера самого компа.

    Автор библиотеки рекомендовал поступить так:

    Но в том и беда, что для Unix есть usleep(), для Windows - QueryPerformanceCounter(), а для доса придется как-то выкручиваться.
     
    Последнее редактирование: 9 фев 2015
  11. Bato-San Чеширский волк-киборг

    Bato-San

    Регистрация:
    24 июн 2010
    Сообщения:
    14.136
    а схема и мануал по программированию у неё есть ?
    И вообще, зачем делать железку эмулирующую другую железку, что бы этой эмуляцией занималась таки внешняя библиотека, которая чудно умеет эмулировать обе железки сразу на любой другой железке ?
     
  12. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Схема - это не разводка платы, а принципиальная схема? Где-то такая была, я могу поискать. Мануал тоже есть, но читать там особо нечего: плата просто позволяет работать с регистрами SID через I/O 280h-29Ch. Это по дефолту, возможны другие значения I/O - например, я использую 2A0h-2BCh, потому что дефолтные настройки конфликтуют с ресурсами материнки. Кроме работы с регистрами SID, плата ничего не умеет (ну, еще там порт джойстика есть).

    Мы (мы пахали...) делали копию/клон железки, а не эмулятор. Эмуляторов и без нас дофига. Копия полностью совместима с оригиналом, и лишена некоторых его недостатков. Например, она не глючит на быстрых машинах, поддерживает кроме 6581 еще и 8580, может переключаться между режимами PAL и NTSC, и еще кое-что по мелочам.

    Вот фото оригинала Innovation SSI-2001 и HardSID:

    7f1ae47c07fb232216f238a3edca95c0.jpg

    Раньше я как-то не обращал внимания на имеющийся на HardSID кварц...
     
    Последнее редактирование: 9 фев 2015
  13. Bato-San Чеширский волк-киборг

    Bato-San

    Регистрация:
    24 июн 2010
    Сообщения:
    14.136
    Geryon, это я из ролика уже знаю (про бла-бла-бла и поддерживает). В принципе штука не сложнее AY8910.

    Я просто не понимаю, что мешает тебе использовать прерывание ?
     
  14. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Тема для меня новая, никогда не использовал прерываний. Видимо, полезу изучать.
     
  15. AxXxB неадекват

    AxXxB

    Хелпер Переводчик

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Если бывает такое, что количество циклов между вызовами больше 0xFFFF, то считывание из таймера не годится - там всего 0xFFFF циклов и помещается. Можно, правда, запустить два канала, чтобы один считал на максимальной частоте, а другой на в 2^n меньшей, тогда общая разрядность будет 16+n бит. Но проще обработчик прерывания повесить с инкрементом сколько-угодно-разрядного значения.

    ---------- Сообщение добавлено в 14:35 ---------- Предыдущее сообщение размещено в 14:32 ----------

    Это проще, чем ты думаешь, всего пару операций надо сделать. С самим таймером даже посложнее работать.
     
  16. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Наверное, бывает, раз авторы решили обработать такую ситуацию.

    Мне бы общую схему хотя бы понять. Получается, что обработчик прерывания инкрементирует какой-то счетчик, а функция задержки следит за этим счетчиком?

    Как это выглядит? Неужели так:

    Код:
    end_counter = custom_counter + delay;
    
    while(custom_counter < end_counter)
    {
       // ждем, пока обработчик сам меняет custom_counter ?
    }
    
     
  17. Bato-San Чеширский волк-киборг

    Bato-San

    Регистрация:
    24 июн 2010
    Сообщения:
    14.136
    Geryon, выглядит это так:


    1. Ты вешаешь свой обработчик поверх IRQ8. Тут своя кухня с запретом прерывания, сохранением адреса старого обработчика, танцами с подготовкой и разрешением прерывания после.
    2. В обработчике происходит только проверка на нужный отрезок времени и кидание нужных данных куда оно тебе надо и отдача управления на предыдущий обработчик по цепочке. Обычно туда весь плеерный блок и засовывается, что бы не мешался под ногами.
    3. В основной программе происходит проверка на окончание работы и в случае такового - удаление своего обработчика и возвращение старого на место.

    Конкретно по таймеру в ненаучно-популярном виде.

    При написании дров под досю рекомендую забыть псю как страшный сон. Даже если надо работать с DPMI.
     
  18. AxXxB неадекват

    AxXxB

    Хелпер Переводчик

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Geryon, тут просто малость непонятно, что именно этот самый ::clock делает. Вроде как он отправляет команду на задержку железки на полученное через m_context->getTime количество циклов, но сам код при этом не задерживается. Так? Если так, то куда деваются значения, передаваемые через ioctl во время задержки, неужели в железке есть их очередь? Если не так, то, выходит, железка задерживает сам проц? Фигня какая-то, в общем. К тому же, непонятно, откуда эти самые циклы берутся в getTime.

    У тебя ведь, наверное, смысл в том, чтобы отправлять какие-то команды на железку через определенное время, не зависящее от скорости процессора. Тогда, если ты пишешь именно драйвер, а не приложение, то задержку использовать бессмысленно - вся система ведь висеть будет. Надо делать что-то "событийное" по прерыванию от таймера.
     
    Bato-San нравится это.
  19. Bato-San Чеширский волк-киборг

    Bato-San

    Регистрация:
    24 июн 2010
    Сообщения:
    14.136
    AxXxB, а тут ещё фокус то в том, что он софтовый эмулятор пытается на хард переориентировать. Без изменения концепции основной библиотеки. Ну это примерно как винамп целиком (вместе с гуями и прочим) повесить на таймерное прерывание в качестве обработчика.
     
  20. AxXxB неадекват

    AxXxB

    Хелпер Переводчик

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Bato-San, вряд ли придется всю библиотеку вешать на прерывание. Главное, разобраться в архитектуре и придумать, куда лучше всего присобачить таймер.
     
  21. Geryon

    Geryon

    Регистрация:
    13 май 2008
    Сообщения:
    1.228
    Не совсем так. HardSID-то поддерживается, значит, и SSI-2001 в конце концов заработает.

    Насчет драйвера - я использовал неудачное слово. Это не драйвер, а модуль, который отвечает за работу с SID в библиотеке. Есть модули-эмуляторы, которые выдают на выход PCM-данные, есть модуль для HardSID, а я делаю модуль для SSI-2001. Поэтому останавливать CPU для ожидания можно.
     
  22. AxXxB неадекват

    AxXxB

    Хелпер Переводчик

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Geryon, а, ну тогда действительно будет примерно так, как ты и писал:
    Код:
    end_counter = custom_counter + delay;
    
    while(custom_counter < end_counter)
    {
       __asm hlt; //просто чтобы не есть лишнюю энергию
    }
     
    Geryon нравится это.
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление