Чтение символов не работает в графическом режиме - PullRequest
2 голосов
/ 02 июня 2019

Я хочу прочитать символ и его атрибут с ah=8 int 10h прерыванием.

Работает в текстовом режиме, но не в графическом режиме (16 цветов 640 х 480).

mov ax,0012h
int 10h       ;graphical mode
int 10h

mov ah,0Ah
mov al,'1'
mov cx,200    ;printing '1' 200 times
mov bx,0
int 10h

mov ah,2
mov dx,0      ;moving cursor to (0,0)
mov bx,0
int 10h

mov bh,0
mov ah,8      ;reading the character
int 10h

Код должен давать AH=07h & AL=31h.

Но этот код всегда дает AH=07h & AL=00h.

Так как я могу использовать этот метод в графическом режиме?

1 Ответ

2 голосов
/ 02 июня 2019

Проблемы в двух словах

  • Запись избыточного int 10h
  • Запрос слишком большого счетчика репликации
  • Вывод черных символов на черном фоне
  • Интерпретация случайного содержимого регистра

Пояснения

... Запись избыточного int 10h

mov ax,0012h
int 10h       ;graphical mode
int 10h

ЭтоНикогда не стоит вызывать функцию API без явного указания номера функции.Вы можете подумать, что в этом примере регистр AX по-прежнему содержит 0012h (поскольку документировано, что функция 00h не возвращает ничего), но это не всегда так.
Я не знаю, почему вы написали эту вторую int 10h,Может быть, вы удалили некоторые дополнительные инструкции и просто забыли удалить эту.Может случиться ...

... Запрос слишком большого числа репликаций

Из моего Руководства по программированию для VGA для BIOS. WriteCharacterOnly 0Ah:

ВГрафические режимы, количество раз для репликации символа, ограничено количеством оставшихся позиций символов справа от позиции курсора до конца строки.

Ваша программа указывает количество репликациииз 200, что намного больше, чем доступные 80 столбцов на экране.Слишком большой запрос приводит к непредсказуемому поведению.
Снимок экрана для emu8086 из вашего предыдущего вопроса уже показывает эту проблему.Посмотрите очень внимательно на верхний левый угол рисунка.

Ниже показано, что мой компьютер [1] показывает, когда я запрашиваю счет репликации 81. После нормального отображения 80 символов, функцияпереносится к левому краю экрана , но также опускается на одну строку развертки (1 пиксель) !Теперь вы можете видеть, что поле символов 8x16 в верхнем левом углу экрана больше не содержит битовый шаблон, который функция BIOS 08h может распознать как действительный символ ASCII, и, следовательно, функция 08h вернется с AL=0.

        x=0    x=7
        |      |
       .........................................
y=0 -  .                                        
       .                                        
       .           **      **      **      **   
       .   **     ***     ***     ***     ***   
       .  ***    ****    ****    ****    ****   
       . ****      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **    ******  ******  ******  ****** 
       . ******                                 
       .                                        
       .                                        
y=15 - .                                        

См. этот комментарий Майкла Петча о возможных различиях в реализации BIOS'ов.Это мудрый программист, который следит за тем, чтобы его программа работала на самых разных машинах.

... Вывод черных символов на черном фоне

При вызове функции BIOS 0Ah WriteCharacterOnly, ' Only ' применяется исключительно к буквенно-цифровым видеорежимам.В графических режимах значение в регистре BL используется для цвета символа.Ваша программа передает 0 (черный) в качестве цвета символа, и BIOS будет использовать его на черном фоне.Это еще одна причина, по которой вы не можете прочитать что-то с экрана.

... Интерпретация случайного содержимого регистра

Из моего Руководства по программированию для VGA для BIOS. ReadAttributeCharacterPair 08h:

Код атрибута не возвращается, когда дисплей находится в одном из графических режимов.

Ваша программа находится в графическом режиме (16 цветов 640х480).Вы не должны интерпретировать значение, которое находится в регистре AH.Это то, что происходит там, так что относитесь к нему как к мусору.На вашем компьютере этот регистр содержал 7, на моем [1] он содержал 5.

Попробуйте вместо этого

Вам не нужно перемещать курсор к вершинеугол экрана, поскольку позиция курсора не была изменена функцией 0Ah.

mov     ax, 0012h  ; BIOS.SetVideoMode 16-color 640x480
int     10h
mov     cx, 80     ; Replication count
mov     bx, 000Eh  ; Display page 0, character color Yellow
mov     ax, 0A31h  ; BIOS.WriteCharacter(Only)
int     10h
mov     bh, 0      ; Display page 0
mov     ah, 08h    ; BIOS.Read(Attribute)Character(Pair)
int     10h        ; -> AL=31h

[1] Phoenix TrustedCore v1.23 VGA BIOS 1264

...