Создание текстуры командой XOR На ассемблере в графическом режиме VGA
Как сгенерировать интересную текстуру при помощи всего одной команды?! Ну хорошо, команд будет немного больше.
В качестве каркаса я использовал тот-же код, что и раньше. Если коротко, что делает программа:
Устанавливает графический режим VGA с разрешением 320×200 точек и 256 цветов.
Записывает палитру-градиент от чёрного к синему.
Отрисовывает текстуру на весь экран.
Ждёт нажатия клавиши.
Собственно шаг номер три, а именно процедура drawtex (79-99 строки), содержит в себе два цикла.
Первый цикл для каждой из 200 линий экрана хранит свой счётчик в регистре DX. Второй, для каждой из 320 точек линии, хранит свой счётчик в регистре CX. В сердце этих циклов находится команда XOR.
Команда XOR выполняет операцию исключающего ИЛИ между всеми битами двух операндов. Если сравниваемые биты равны, то результат будет 0. И если сравниваемые биты отличаются, то результат будет 1.
0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0
В качестве операндов используются счётчики циклов из регистров DX и CX, по сути координаты X и Y. А результат используется как индекс палитры-градиента, и записывается в экранную область по своим координатам.
org100h;------------------------------------------------------------------------------; XOR.ASMmov ax,0013h; Выбираем режим 320x200 256 цветовint10h; Видеосервис: Установка видеорежимаpush0A000h; Отправляем в стэк адрес сегмента видеопамятиpop es ; Извлекаем адрес сегмента видеопамяти в ESxor di,di ; Обнуляем смещение от начала сегмента видеопамятиcall palset ; Записываем цвета палитрыcall drawtex ; Вызываем генерацию текстурыxor ah,ah ; Выбираем режим ожидания ввода AH = 00hint16h; Сервис клавиатуры: пауза до нажатия на клавишуmov ax,0003h; Выбираем текстовый режим 80x25 16 цветовint10h; Видеосервис: Установка видеорежимаint20h; Выходим в DOS;------------------------------------------------------------------------------; Функция записи цветов в таблицу палитрыpalset:
mov dx,03c8h; В DX будет храниться адрес порта ЦАП для управления палитройxor ax,ax ; Обнуляем аккумуляторout dx,al ; Записываем в порт 03c8h индекс 0-го элемента палитрыinc dx ; Увеличивает адрес порта на 1mov cx,256; Устанавливаем счётчик цикла по всем 256 цветам палитрыmov bx,pal ; В BX будет адрес начала сгенерированных данных палитрыps_l1:
mov al,[bx] ; Берём содержимое байта из BXout dx,al ; Записываем его в порт 03c9h это будет Rinc bx ; Смещаем указатель адреса данных палитры на 1mov al,[bx] ; Берём содержимое байта из BXout dx,al ; Записываем его в порт 03c9h это будет Ginc bx ; Смещаем указатель адреса данных палитры на 1mov al,[bx] ; Берём содержимое байта из BXout dx,al ; Записываем его в порт 03c9h это будет Binc bx ; Смещаем указатель адреса данных палитры на 1loop ps_l1 ; Повторяем пока не запишутся все цветаret; Возврат;------------------------------------------------------------------------------; Палитраpal:
repeat64; Чёрный -> Синийdb0,0,%-1; от 0,0,0 до 0,0,63end repeat
repeat64; Синий -> db0,%-1,63; от 0,0,63 до 0,63,63end repeat
repeat64; Чёрный -> Синийdb0,0,%-1; от 0,0,0 до 0,0,63end repeat
repeat64; Синий -> db0,%-1,63; от 0,0,63 до 0,63,63end repeat
;------------------------------------------------------------------------------; Функция генерации текстурыdrawtex:
xor di, di ; Обнуляем смещениеmov dx, 200; Цикл для 200 линийvertloop:
mov cx, 320; Цикл для 320 точекhorloop:
mov ax, cx ; Копируем содержимое CX в аккумуляторxor ax, dx ; И ксорим с DX, здесь вся «магия»!stosb; Записываем содержимое регистра AL в байт по адресу ES:DIloop horloop ; Повторяем для каждой точки строкиdec dx
jnz vertloop ; Повторяем для каждой линииret; Возврат