Простая установка палитры
Основные фрагменты подпрограммы отделены друг от друга комментарием. В примере 4.6 используются все регистры общего назначения, поэтому первая команда pusha сохраняет их содержимое в стеке. Следующие четыре команды формируют данные для запроса на позиционирование файла. В регистр ai записывается код 2, являющийся признаком перемещения указателя в заданную позицию, а в пару регистров cx:dx – смещение этой позиции от конца файла (отрицательное число 769). Затем происходит обращение к DOS (int 2ih) для исполнения запроса. Если при позиционировании зафиксирована ошибка, то команда jc spexit выполнит переход на метку spexit для завершения подпрограммы с установленным С-разрядом.
В случае успешного позиционирования в буфер обмена считываются 769 байтов, содержащих признак ось или ОАП и собственно палитру. Для чтения используется подпрограмма readf, текст которой был приведен в примере 3.23. После чтения нулевой байт буфера обмена содержит код типа палитры. Он помещается в регистр ai и анализируется. Если код равен OAh, то масштабирование исключается. Если код равен ось, то нужно выполнить масштабирование палитры. Если код отличается от ОАП и och, то устанавливается С-разряд и происходит возврат из подпрограммы.
Для масштабирования палитры в регистр сх записывается ее размер и выполняется цикл сдвигов содержимого каждого байта на 2 разряда вправо.
Начиная с команды, имеющей метку spal, формируются исходные данные для функции B10S, устанавливающей палитру. В регистр es надо записать значение сегмента буфера обмена (содержимое регистра fs), а в регистр dx – адрес начала палитры в этом сегменте (1). Номер первого устанавливаемого DAC-регистра равен нулю, а количество устанавливаемых ODC-регистров равно 256. В регистр ах помещается код запроса (ioi2h) и происходит обращение к B10S (int 10h). После возвращения из BIOS надо восстановить исходное содержимое регистра es, сохраненное в стеке.
Палитра установлена и подпрограмму можно было бы завершить. Однако в процессе ее выполнения изменилась исходная позиция файла, и ее надо восстановить. В противном случае перед построением рисунка потребуются лишние действия, связанные с определением и изменением текущей позиции файла.
Образ рисунка отстоит на 80h байтов от начала файла. Поэтому в примере в регистры ai и сх записывается 0, а в регистр dx код 80h. После позиционирования восстанавливается содержимое регистров (команда рора) и происходит возврат из подпрограммы. Если при позиционировании возникнет ошибка, то произойдет возврат с установленным С-разрядом.
При выходе из описанной подпрограммы С-разряд будет установлен не только при ошибках позиционирования файла, но и при отсутствии кодов OAh или ось перед палитрой. В основной программе уже невозможно определить причину ошибки. Если она важна, то в подпрограмме можно сформировать дополнительные признаки, уточняющие характер ошибки.
После успешной установки палитры можно приступать к построению рисунка на экране. Выбор способа построения зависит от содержимого байта 2 заголовка файла. Если он очищен, то образ рисунка не сжат и для вывода на экран используется подпрограмма BigDraw (см. пример 3.22). Если же байт 2 заголовка содержит единицу, то образ рисунка упакован и для распаковки при выводе на экран применяется подпрограмма PackDrw (см. пример 3.26).
Таким образом, к этому моменту вы располагаете всей информацией, необходимой для работы с файлами стандарта PCX, содержащими рисунки, использующие палитру. О работе с файлами этого же стандарта, но не использующими палитру, мы поговорим в главе 7.
Замечание
При установке палитры описанным способом она просто копируется в регистры цвета видеокарты. Это допустимо в тех случаях, когда на экране будет находиться только тот рисунок, для которого предназначена установленная палитра. Если же рисунок добавляется к уже существующим, то при смене палитры, почти наверняка, изменятся цвета той части изображения, которая не занята новым рисунком. Поэтому, в общем случае, описанная процедура недопустима и при установке палитры должны быть приняты меры для сохранения исходной картинки, находящейся на экране.