1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

Номер текущей строки CRT-луча

Тема в разделе "WASM.DOS/BIOS/Vesa/ports", создана пользователем Jin X, 6 сен 2018.

  1. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    332
    Адрес:
    Кольца Сатурна
    Всех категорически приветствую!

    Кто-нибудь знает, возможно ли прочитать из портов графического адаптера (VGA в частности) номер текущей строки (линии), на которой находится луч?
    Задача такая: вешаю обработчик на таймер (IRQ 0) и настраиваю частоту таймера как мне надо (чтобы он вызывался ≈ на каждой строке, на которой находится луч, либо раз в 5 строк). Процедура таймера совершает разные манипуляции (как банальный пример, рисует градиентную полосу с помощью настройки палитры). Зачем таймер? Чтобы параллельно можно было рисовать что-то ещё, а не тупо крутить цикл чтения порта 3DAh для трассировки луча :)
    Читаю RBIL, ничего по поводу чтения номера линии не нахожу (есть намёки, но всё не то, но мало ли?)

    Если такой возможности всё-таки нет, то как можно хотя бы понять, что начался новый фрейм? Причём даже при относительно низкой частоте таймера (к примеру, 1 срабатываение на 5 строк). Если проверять бит вертикального ретрейса, то при низкой частоте таймера можно проскочить этот момент (ретрейс длится довольно малое кол-во времени, буквально пару строк... и кстати говоря, окончание ретрейса не говорит о том, что луч находится в видимой области экрана). Бит горизонтального ретрейса включается на всё время отсутствия луча в области экрана.
    Выглядит примерно так (последовательные чтения из порта):
    Код (Text):
    1. V H - биты вертикального и горизонтального ретрейса
    2. ---
    3. 0 0 - луч в видимой области
    4. 0 1 - идёт горизонтальный ретрейс \
    5. 0 0 - видимая область              \ это повторяется
    6. 0 0 - видимая область              / для каждой строки
    7. 0 0 - видимая область             /
    8. 0 1 - луч вышел за область экрана (он находится снизу или сверху)
    9. 0 1 - луч за областью экрана
    10. 0 1 - луч за областью экрана
    11. 0 1 - луч за областью экрана
    12. 1 1 - вертикальный ретрейс
    13. 1 1 - вертикальный ретрейс
    14. 1 1 - вертикальный ретрейс
    15. 0 1 - луч пока ещё за областью экрана
    16. 0 1 - луч пока ещё за областью экрана
    17. 0 1 - луч пока ещё за областью экрана
    18. 0 1 - луч пока ещё за областью экрана
    19. 0 1 - луч пока ещё за областью экрана
    20. 0 0 - снова началась видимая область
    Если проверять H-бит на повторы, то может оказаться так, что нам просто "везёт" нарываться на несколько горизонтальных ретрейсов подряд между видимыми линиями, а не между кадрами.
    Что можно придумать для такого случая? Может, есть какой-то отдельный бит какого-то другого порта, с помощью которого можно узнать, что луч находится за кадром (ниже или выше)?
     
    Последнее редактирование: 6 сен 2018
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.327
    Адрес:
    Fryazino
    CR18 Line Compare Register
    Read/Write at I/O address 3B5h/3D5h with 3B4h/3D4h set to index 18h
    7 6 5 4 3 2 1 0
    Line Compare Bits 7-0
    7-0 Line Compare Bits 7-0
    This register provides the 8 least significant bits of a 10-bit value that specifies the scan line at which
    the memory address counter restarts at the value of 0. Bit 6 of the Maximum Scan Line Register
    (CR09) supplies the most significant bit, and bit 4 of the Overflow Register (CR07) supplies the second
    most significant bit.
    Normally, this 10-bit value is set to specify a scan line after the last scan line of the active display area.
    When this 10-bit value is set to specify a scan line within the active display area, it causes that scan line
    and all subsequent scan lines in the active display area to display video data starting at the very first
    byte of the frame buffer. The result is what appears to be a screen split into a top and bottom part, with
    the image in the top part being repeated in the bottom part.
    When used in cooperation with the Start Address High Register (CR0C) and the Start Address Low
    Register (CR0D), it is possible to create a split display, as described earlier, but with the top and bottom
    parts displaying different data. The top part will display whatever data exists in the frame buffer
    starting at the address specified in the two start address registers (CR0C and CR0D), while the bottom
    part will display whatever data exists in the frame buffer starting at the first byte of the frame buffer.
     
  3. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    332
    Адрес:
    Кольца Сатурна
    Pavia, это не то. Для чего этот регистр мне нужен?
     
  4. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.327
    Адрес:
    Fryazino
    В нём хранится номер текущей строки. Ровно то что вы и просили.
     
  5. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    332
    Адрес:
    Кольца Сатурна
    Pavia, нет, не хранится. Я проверял, там постоянное значение.
    К тому же, в описании сказано, что это совсем другое.
     
  6. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.327
    Адрес:
    Fryazino
    Jin X, тогда других универсальных способов нету. Все остальные сводятся к PM и написанию драйверов под каждую видеокарту.