Русификация BIOS видеокарт GeForce 6-7 и, возможно, более новых серий

Вступление

Ну, во-первых, кому и для чего нужна русификация видеокарты? Ответ: для марсиан! Конкретно, для тех, кто вольно или невольно в текстовом режиме видит русский текст нерусскими буквами. Сразу оговорюсь: все нижеследующее относится именно к текстовому режиму, и не относится к графическому режиму современных операционных систем. Под текстовым режимом подразумевается видеорежим с использованием аппаратного знакогенератора видеокарты, а не текст в Word. Проще говоря, если вы знаете, что такое DOS и командная строка, то это для вас, если нет — не для вас.

Русификация видеокарты решает следующие проблемы (в том числе в графических режимах, если текст выводится стандартными шрифтами BIOS — CGA/EGA/VGA и возможно SVGA графика, например, BGI драйвер Турбо Паскаля):

  1. избавляет от необходимости пользоваться русификаторами экрана в среде DOS (русификация клавиатуры по-прежнему нужна) — это экономит 10-15 кб памяти в пределах первого мегабайта;
  2. BSOD Windows 3.x–ME — программисты из Microsoft написали русский текст там, где часто отказывает любой русификатор, включая стандартный:

    Device=display.sys con=(ega,866,,)
    Mode con cp prep=((866),ega3.cpi)
    Mode con cp select=866

  3. загрузчик и полноэкранный режим DOS-окна Windows 3.x–ME — многие русификаторы (в т.ч. KEYRUS) там глючат;
  4. полноэкранный режим NTVDM — там шрифтами заведует операционная система, но после смены видеорежима она иногда забывает подгрузить их;
  5. текстовые режимы малоизвестных и устаревших операционных систем — сомнительно, что кто-то писал для них русификаторы, или их сложно будет найти в настоящее время;
  6. написание собственных операционных систем, загрузчиков и пр. специфических программ — они могут писать на русском языке, но это пригодно лишь для первичной отладки и либо должно быть отключено в конечных версиях, либо вы должны написать полноценный русификатор, не надеясь на то, что пользователь имеет такую же русифицированную видеокарту;
  7. если найдете еще причину, добавим…

Что она не решает:

  1. WinIce (отладчик) содержит собственный шрифт, и конечно же, не в курсе, что существуют русские буквы. Впрочем, иногда он не в состоянии загрузить даже свой собственный шрифт;
  2. BSOD на NT системах — там текст почти всегда выводится в графическом режиме, просто не всегда теми символами;
  3. некоторые системные BIOS сами загружают в видеокарту свои шрифты (!) для возможности локализации SETUP. Разумеется, после окончания инициализации они сбрасывают свои шрифты. Я лично из любопытства включал свой системный BIOS на японском языке, но на русском его не было;
  4. и многое другое…

Гарантии и копирайты

Сразу оговорюсь: русификация есть перешивка BIOS видеокарты, причем даже не на фирменный, а на модифицированный, со всеми вытекающими последствиями! Т.е. аннулируется гарантия, возможны проблемы с работой видеокарты, в том числе и в нетекстовых режимах. Кроме того, русификация видеоBIOS есть также и обратное конструирование кода, что может быть запрещено в некоторых странах законами об авторском праве! В общем, думайте сами, решайте сами, мое дело — предупредить.

Основы процесса

По умолчанию BIOS видеокарты содержит шрифты с кодовой страницей 437 (CP437, стандартная латиница). Этого достаточно для английского, турецкого, греческого и др. языков. Но символов кириллицы в них нет. В разное время для кириллицы были разработаны кодовые страницы CP866 (DOS), CP1251 (Windows), KOI-8 (Unix) и ряд других, редко используемых.

Русификация BIOS есть подмена шрифтов в BIOS видеокарты, чаще всего на содержащие CP866, но можно взять и любой другой нужный вам набор символов. Уже на этом этапе могут быть варианты:

  • замена только кириллицы — минимально необходимый набор в 64 знака;
  • предыдущий вариант плюс немного эстетики — позволяет скорректировать некоторый набор символов, например убрать «столбы» в псевдографике;
  • замена всех шрифтов — дает наивысшую свободу фантазии.

Чем выше степень свободы, тем жестче требования к имеющемуся BIOS видеокарты — прошивка, терпящая издевательство первого уровня, может не вытерпеть последующие…

Русифицировать можно те карты, в прошивке которых можно выделить хоть немного места под новый блок шрифтов, или которые позволяют без нареканий заменить уже имеющийся. Старые карты с малым объемом программного кода содержали шрифты в чистом виде, неупакованными, и их русификация при любой глубине была элементарной. На сайте МИР NVIDIA доступна программа RVBEdit (автор Ray Adams), позволяющая заменить шрифты в BIOS видеокарт на базе GeForce 256 — 4 Ti несколькими движениями мыши.

Новые BIOS разрослись настолько, что их размер превысил 64 килобайта. Хотя организация IBM PC позволяет выделить для видеоBIOS до 128 Кб (см. ниже), производители, видимо, сочли невыгодным ставить 128 Кб чипы EEPROM, и решили упаковать шрифты с 10 Кб (по другим данным, с 6) до 3 Кб, плюс распаковщик. Современные карты все равно имеют 128 Кб чипы, но шрифты так и остались упакованными. Естественно, если бы был известен код фирменного упаковщика (возможно, что он и не один), было бы проще. Но как раз его мы и не знаем…

Как результат, чтобы заменить шрифты, нужно:

  1. отыскать адрес, куда они распаковываются;
  2. отыскать код распаковщика;
  3. проанализировать этот код, что он делает, чем и как оперирует;
  4. найти, где этот код заканчивается (как правило, он вместе с шрифтами расположен в самом конце прошивки, но после него еще могут оставаться разные данные);
  5. определить, сколько места остается до конца памяти чипа, т.е. до ближайшей границы 64 либо 128 Кб;
  6. исходя из результатов пунктов 4 и 5, разработать стратегию русификации;
  7. подготовить свои шрифты в соответствии с выбранной стратегией;
  8. попытаться реализовать стратегию (не исключено, что ее придется поменять).

Инструментарий

Вот список утилит, которые нам точно понадобятся: hiew, nvflash и nvflash для Windows, набор моих вспомогательных программ: grb, bsum, fpaq, funp.bin (это бинар, а не программа!). Можно еще воспользоваться IDA, но я обошелся без него. Все программы можно скачать по ссылкам в конце статьи.

Начало начал

Нет, начинаем мы не с hiew! Первое, что нам нужно сделать — сохранить имеющуюся прошивку. Это делается утилитой nvflash:

nvflash –save mybios.rom

или короче:

nvflash –b mybios.rom

где mybios — имя файла, в который сохраняется прошивка, расширение должно быть .rom, в противном случае вы не сможете использовать сохраненную прошивку.

Сохранили? Теперь вам нужно научиться прошивать ее обратно. При этом вы должны исходить из наихудшего предположения о полной неработоспособности вашей видеокарты. Поэтому я настоятельно советую вам не рисковать без наличия либо второй видеокарты с шиной PCI (старой шины, для старых видеокарт, в новых материнских платах туда обычно устанавливаются модемы и звуковые карты) или шины PCI-Express, если на вашей материнской плате два и более таких слота, либо иметь встроенную видеокарту, которая без проблем работает вместе с прошиваемой, и это лучше проверить заранее.

На этом этапе у меня была проблема: в моей системе DOS-версия утилиты nvflash отказывалась прошивать неработоспособную видеокарту, если была установлена вторая карточка (S3 Trio64 PCI), как основная (в соответствии с FAQ), и единственный монитор был подключен к ней — невозможно было восстановить исходную прошивку. nvflash выдавала следующее:

NOTE: Unconfigured display adapter found, device not accessible:
GeForce 7600 GS (10DE,02E1,1043,8237) H:--:NRM B:01,AGP,D:00,F:00
ERROR: No NVIDIA display adapters found
Exit Code: 2

Однако, Windows-версия nvflash срабатывала всегда, но она работает только в Windows семейства NT! Отсюда вывод:

  • Если мы прошиваем заведомо рабочую карту предположительно рабочей прошивкой, лучше использовать DOS-версию nvflash;
  • Если мы прошиваем заведомо НЕрабочую карту с запоротым нами (или не нами) BIOS, лучше сразу использовать NT-версию nvflash, но для этого требуется, чтобы загружалась операционная система (с использованием интегрированного в чипсет материнской платы видеоядра или дополнительной видеокарты).

Ключи запуска у обеих утилит одинаковые, для прошивки нужно запускать БЕЗ ключей:

nvflash mybios.rom

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

Русификация ASUS N7600GS Silent 256

Так как BIOS видеокарт разных поколений и производителей может сильно различаться, для русификации каждого требуется свой подход. Далее идет подробное описание процесса русификации BIOS нескольких карточек, и вам нужно внимательно читать написанное и следовать принципу «делай, как я».

ASUS N7600GS Silent 256 (моя видеокарта, с которой все и начиналось) — относительно простой случай. Делаем первую копию, с оригинальной прошивки — new1.rom. Так нужно делать после каждого удачного шажка. Т.е. получилось что-то — копируем удачный new1.rom в new2.rom и дальнейшие опыты проводим уже с ним. Опять получилось — делаем new3.rom, и т.д. пока не дойдем до совершенства. Не получилось — безжалостно стираем неудачный файл и начинаем с предыдущего. Только так!!!

Итак, у нас есть new1.rom. Запускаем hiew и смотрим его дамп:

00000000: 55 AA 78 EB-4B 37 34 30-30 E9 4C 19-77 CC 56 49 UêxûK7400ùL w¦VI
00000010: 44 45 4F 20-0D 00 00 00-B8 00 19 11-00 00 49 42 DEO ¬ IB
00000020: 4D 20 56 47-41 20 43 6F-6D 70 61 74-69 62 6C 65 M VGA Compatible
00000030: 01 00 00 00-80 10 94 8D-30 32 2F 30-37 2F 30 37 À ÔÍ02/07/07
============
0000EFD0: FF FF FF FF-FF FF FF FF-FF FF FF FF-FF FF FF FF
0000EFE0: FF FF FF FF-FF FF FF FF-FF FF FF FF-FF FF FF FF
0000EFF0: FF FF FF FF-FF FF FF FF-FF FF FF FF-FF FF FF 9C Ü

Здесь нужно пояснить формат блока BIOS (любого «культурного», не только видеокарты, этот формат описан еще в первой документации на IBM PC):

  • 0000: 55 AA — это сигнатура, если ее не будет, системный BIOS проигнорирует этот блок: «БИ-БИ, это что ты мне подсунул?», и результатом будет черный экран;
  • 0002: ХХ — очень важный байт, счетчик размера блока BIOS; сам размер есть 512 х ХХ = от 512 байт до 128 Кб;
  • bububu: xx — последний байт блока, такой, чтоб контрольная сумма по модулю 256 всех байтов в блоке, заданном байтом 0002, равнялась нулю. Если контрольная сумма не нулевая, результат будет такой же, как и при неверной сигнатуре;
  • 0003: jmp туда-то — точка входа в BIOS, сюда передается управление системным BIOS по команде callf. Возврат из BIOS соответствующий — retf.

С анализа готового распакованного BIOS начинается самое интересное. Считывается он с адресов C0000h—XXXXXh утилитой grb. Она создает файл grb.bin там же, где лежит сама. Этот файл и есть образ рабочего (т.е. уже загруженного и настроенного) BIOS видеокарты. Естественно, что шрифты в нем уже распакованные. Поэтому нужно отыскать, где оные начинаются. В этом нам поможет тот факт, что обычно шрифты начинаются с размера 8х8, и первые два символа с кодами 00h & 01h стандартные, и их можно рассматривать как сигнатуру:

0000C442: 00 00 00 00-00 00 00 00-7E 81 A5 81-BD 99 81 7E ~ÁåÁ-ÙÁ~

Найдя ее и посмотрев окрестности, убеждаемся, мы действительно нашли нужную точку. Итак, шрифты распаковываются по адресу C442h. Открываем new1.rom и ищем ссылки на этот адрес (разумеется, она может быть не одна, и выбор нужной зависит исключительно от опыта и таланта хакера):

0000EDF8: 6660 pushad
0000EDFA: 0E push cs
0000EDFB: 1F pop ds
0000EDFC: 8D3642C4 lea si,[0C442]
0000EE00: C7069DED0703 mov w,[0ED9D],00307 ;" "
0000EE06: 8D3EE4DF lea di,[0DFE4]
0000EE0A: 8D2EBEE5 lea bp,[0E5BE]
0000EE0E: E8AEFF call 00000EDBF --- (1)
0000EE11: C7069DED0F04 mov w,[0ED9D],0040F ;" "
0000EE17: 8D3E11E6 lea di,[0E611]
0000EE1B: 8D2E4BED lea bp,[0ED4B]
0000EE1F: E89DFF call 00000EDBF --- (2)
0000EE22: 6661 popad
0000EE24: E95349 jmp 00000377A --- (3)

Вот оно! Очевидно, EDBFh — распаковщик, читающий упакованные шрифты с адресов DFE4h, E5BEh, E611h, ED4Bh и записывающий их на адрес C442h, а сам распаковщик лежит прямо за шрифтами. Хотя код вызывается с адреса CB7Fh, после распаковки управление передается безусловным jmp 377Ah, потому что вызвавший код будет затерт распакованными шрифтами.

Имеем: для русификации достаточно после штатной распаковки записать по адресу C442h наш шрифт. Шрифт можно позаимствовать из файла ega3.cpi или iso.cpi из комплекта операционных систем Microsoft (DOS/Windows 3.x/Windows 9x) или из других источников (например, из русификатора keyrus, чтобы получить его шрифты, выполните исполняемый файл как keyrus.com /files). Но вот как его записать в BIOS? Полный комплект шрифтов 8х8 + 8х16 занимает 6 Кб = 1800h, а у нас остаток пространства BIOS только 10000h – EE20h = 11E0h. Решений может быть несколько:

  • записать половину шрифтов, символы с 80h по FFh (требуется C00h свободного места);
  • записать целиком новые шрифты поверх стандартных, сжав их и заменив распаковщик.

Для начала пробуем первый способ. Раздуваем BIOS до 64 Кб ровно (байт 0003 = 80h), записываем по адресам F000h половинки наших шрифтов (8х8, затем 8х16) и дополняем штатный распаковщик нашим:

0000EE22: cld
0000EE23: mov di,0c842
0000EE25: mov si,0f000
0000EE28: mov cx,00400
0000EE2a: repe movsb
0000EE2c: mov di,0d442
0000EE2e: mov si,0f400
0000EE30: mov cx,00800
0000EE32: repe movsb
0000EE34: popad
0000EE36: jmp 00000377A

Теперь нужно пересчитать контрольную сумму. Выделяем в блок весь файл, кроме последнего байта! Выбираем команду CryBlk, вводим:

1: add bl,al
2: loop 1

Запускаем, смотрим содержимое BL, вычисляем 100h-BL, записываем его вместо последнего байта (разумеется, потом мне это надоело, и я создал утилиту bsum, которая делает все это сама).

Прошиваем, перезагружаемся (не забудьте отключить имеющийся русификатор). Работает! Но вот беда — не все русифицировалось. Остались символы С, Ы, Э, Ю, л, м… Это не проблема! Копируем new1.rom в new2.rom, и дальше работаем уже с новым файлом. Ищем данные (откуда дровишки? Из лесу, вестимо…):

00002678: 1D 00 00 00-00 00 24 66-FF 66 24 00-00 00 00 00 $f f$

ссылку на них:

00003809: 0E push cs
0000380A: 07 pop es
0000380B: BF7826 mov di,02678 ;"&x"
0000380E: B710 mov bh,010 ;" "
00003810: C3 retn

и ссылку на этот код:

000040CF: E837F7 call 000003809 --- (1)
000040D2: 2ADB sub bl,bl
000040D4: E87FF7 call 000003856 --- (2)
000040D7: E80AF7 call 0000037E4 --- (3)
000040DA: EB0B jmps 0000040E7 --- (4)
000040DC: E8D1F6 call 0000037B0 --- (5)
000040DF: 893E0C01 mov [010C],di
000040E3: 8C060E01 mov [010E],es
000040E7: C3 retn

Жмем 2, и оказываемся в патчере:

00003856: 53 push bx
00003857: 55 push bp
00003858: 1E push ds
00003859: 06 push es
0000385A: 8BF7 mov si,di

Забиваем 53h на C3h, снова чиним контрольную сумму, прошиваем и наслаждаемся победой!

Как убрать эффект «столбов»

Для сведения, что это такое. Текстовыми наши режимы называются лишь по организации видеопамяти, т.к. области B800h & B000h (монохромный режим) хранят именно символы, а не их точечные изображения, как в графике. На экране изображение всегда состоит из точек. До VGA существовали еще видеоадаптеры MDA (качественный ч/б текст), CGA & EGA. Они поддерживали эффективные экранные разрешения соответственно 720х350, 640х200 и 640х350, а матрицы символов для них имели размер 9х14, 8х8 и 8х14 точек соответственно. Для совместимости (великое дело!) с EGA, впервые позволявшим программно загружать шрифты, в VGA использовали шрифт шириной 8 точек, но при этом разрешили видеорежимы 720х400 точек. В результате получили качественный текст, в котором использовались символы полной ширины, отпала необходимость оставлять 7-й бит для раздела букв, а дополнительный пробел между буквами получался автоматически.

Проблема «столбов» заключается в том, что т.н. символы заполнения B0h, B1h, B2h, используемые в псевдографике для немонолитной заливки фона, разрабатывались для CGA и пригодны лишь в случае, когда символы вплотную примыкают друг к другу. На VGA же автоматические пробелы между символами, так удобные в других местах, с успехом разделяют по горизонтали и символы заполнения, что и известно визуально как «эффект столбов». Прочие символы псевдографики VGA дорисовывает сам, а эти — нет, т.к. при этом все равно получатся столбы.

Проблема решается заменой стандартных матриц этих символов на специально подогнанные под режим VGA. При этом заливка становится монолитной во всех режимах шириной 720 точек, но эти столбы проявляются уже в CGA/EGA режимах или в любом графическом — там ведь нет автоматических разделителей! Впрочем, я сомневаюсь, что в графическом режиме заполнители вообще нужны.

Итак, подменяем матрицы символов B0h, B1h, B2h на следующие (8х16, матрица 8х8 есть половина матрицы 8х16):

B0 — 49 00 49 00 49 00 49 00 49 00 49 00 49 00 49 00
B1 — 92 49 92 49 92 49 92 49 92 49 92 49 92 49 92 49
B2 — DB 92 DB 92 DB 92 DB 92 DB 92 DB 92 DB 92 DB 92

После этого столбы исчезли.

О шрифте 8х14

Как его увидеть? Переключиться в режим EGA:

MODE CON LINES=43
MODE CON LINES=25

Откуда он берется? Он автоматически генерируется из шрифта 8х16, обрезанием самой верхней и самой нижней строк. Поэтому, подбирая шрифт 8х16, заранее подумайте, как будет выглядеть получившийся из него шрифт 8х14. Он имеет обыкновение появляться в самый неподходящий момент, например, при переключении видеорежима в консоли Windows.

Полная замена шрифтов

Человеку всегда хочется совершенства… Почувствовав вкус победы, мне захотелось большего. Но как подменить все шрифты? Ответ дала сама NVIDIA — шрифты нужно упаковать и записать взамен стандартных, вместе с распаковщиком. Но чем паковать? Шрифты нужно сжать с 6 до максимум 3 Кб. Попытка написать собственный упаковщик дала мизерный результат. Нужен был эффективный пакер с простым линейным распаковщиком. Перерыв половину сайта compression.ru, отыскал-таки пригодный исходник — LZSS Com-Compressor. Попробовал — получилось! Коэффициент сжатия даже выше, чем у оригинального упаковщика NVIDIA. Переработанная и откомпилированная версия этой программы — fpaq.exe + распаковщик funp.bin — прилагаются в числе материалов в конце статьи. Рассмотрим, как ими пользоваться.

Копируем предыдущий удачный BIOS в new3.rom. Готовим наши шрифты. Можно их подготовить монолитным блоком, для разовой замены всех символов — для этого «склеиваем» шрифты 8х8 и 8х16 (именно в этом порядке!), тогда распаковщик получается предельно простым:

copy /b font8x8.fnt +font8x16.fnt myfonts.fnt

Упаковываем:

fpaq myfonts.fnt myfonts.paq

Команда выдает myfonts.paq — файл с упакованными данными. Эти данные нужно будет записать в прошивку, причем так, чтоб при распаковке они не наехали друг на друга! Мы не будем рисковать и запишем данные там же, где они были изначально, т.е. по DFE4h. Следом за данными (EBA0h) помещаем наш распаковщик (всего 111 байт!), его берем из файла funp.bin:

0000EBA0: FC cld
0000EBA1: AD lodsw
0000EBA2: 8BE8 mov bp,ax
0000EBA4: BA1000 mov dx,00010 ;" "
0000EBA7: D1ED shr bp,1
0000EBA9: 4A dec dx
0000EBAA: 7505 jne 00000EBB1 --- (1)
0000EBAC: AD lodsw

В нем не нужно ничего настраивать, но это сырой код, к нему еще нужно дописать (EC10h) точку входа, чтоб передать ему адреса данных, и сохранить регистры, т.к. распаковщик меняет их содержимое:

  • ds:si → входные (упакованные) данные = cs:DFE4h;
  • es:di → выходные (распакованные) данные = cs:C442h;
  • все регистры, кроме сегментных и стека, уничтожаются;
  • возврат из процедуры — retn.

Обратите внимание, что распаковщику не нужно передавать длину данных, т.к. все информация содержится во входном потоке! Дописываем точку входа:

0000EC10: 6660 pushad
0000EC12: 0E push cs
0000EC13: 1F pop ds
0000EC14: BEE4DF mov si,0DFE4 ;"-ô"
0000EC17: BF42C4 mov di,0C442 ;"-B"
0000EC1A: E883FF call 00000EBA0 --- (1)
0000EC1D: 6661 popad
0000EC1F: E9584B jmp 00000377A --- (2)

и указываем эту точку вместо штатного распаковщика:

0000CB7F: E98E20 jmp 00000EC10 --- (1)
0000CB82: E9F56B jmp 00000377A --- (2)
0000CB85: 60 pusha
0000CB86: 0E push cs
0000CB87: 07 pop es
0000CB88: 8D1E42C4 lea bx,[0C442]
0000CB8C: 8BCB mov cx,bx
0000CB8E: 81C10008 add cx,00800 ;" "
0000CB92: 8BD1 mov dx,cx
0000CB94: 8CC0 mov ax,es

Вот теперь все в порядке, прошивка готова. После проверки приходим к выводу: русифицировать видеокарты можно и нужно.

Русификация BFG 6800 Ultra

BFG 6800 Ultra (первоначально русифицировал BolenB) — интересный случай.

После анализа распакованного BIOS из сравнения с оригиналом следует вывод — привычного алгоритма распаковки «память — память — знакогенератор» здесь нет! Шрифты распаковываются, и полученные данные сразу же программируется в знакогенератор на уровне портов. Но ведь потом они должны как-то быть записаны в память, ведь в распакованном BIOS они есть? Имеем схему «память — знакогенератор — память».

Ну и куда же тут совать наши шрифты? Как и ранее, нужно найти процедуру, записывающую распакованные шрифты из знакогенератора в теневую память. Шрифты распаковываются по адресу CFA2h:

00003578: 8D1EA2CF lea bx,[0CFA2]
0000357C: E84A00 call 0000035C9 --- (1)
0000357F: 8D1EA2CF lea bx,[0CFA2]
00003583: 81C30018 add bx,01800 ;" "
00003587: 8CC8 mov ax,cs
00003589: 8EC0 mov es,ax
----------------
000035C9: 6660 pushad
000035CB: 66B804000000 mov eax,000000004 ;" "
000035D1: B90008 mov cx,00800 ;" "
000035D4: 33D2 xor dx,dx
000035D6: E81300 call 0000035EC --- (1)
000035D9: 53 push bx
000035DA: 5B pop bx
000035DB: 66B806000000 mov eax,000000006 ;" "
000035E1: B90010 mov cx,01000 ;" "
000035E4: 33D2 xor dx,dx
000035E6: E80300 call 0000035EC --- (2)
000035E9: 6661 popad
000035EB: C3 retn

Очевидно, что процедура 35C9h записывает шрифты из знакогенератора видеоадаптера в теневую память! Осталось приклеить к ней наши шрифты. Но вот проблема: стандартный шрифт мы затереть уже не можем, т.к. неизвестно, как это скажется на работоспособности карточки. А места в оригинальной прошивке всего A00h байт — недостаточно даже для половинок наших шрифтов. Решение: упаковать половинки нашим упаковщиком. Имеем: половинка шрифта 8х8 сжимается 400h → 247h, 8х16 — 800h → 31Eh. Суммарный размер 565h — более чем достаточно. Имеем:

00003578: 8D1EA2CF lea bx,[0CFA2]
;переходим на нашу процедуру распаковки
0000357C: E881C0 call 00000F600 --- (1)
0000357F: 8D1EA2CF lea bx,[0CFA2]
00003583: 81C30018 add bx,01800 ;" "
00003587: 8CC8 mov ax,cs
00003589: 8EC0 mov es,ax
----------------
;распаковываем стандартные шрифты
0000F600: E8C63F call 0000035C9 --- (1)
0000F603: 6660 pushad
0000F605: BE8BF6 mov si,0F68B ;"¡Ë"
;0CFA2h+ 0400h
0000F608: BFA2D3 mov di,0D3A2 ;"Lâ"
;распаковываем наши половинки шрифта 8х8 (с символами 80h-FFh)
0000F60B: E80C00 call 00000F61A --- (2)
0000F60E: BED2F8 mov si,0F8D2 ;"°T"
;0CFA2 + 1000h
0000F611: BFA2DF mov di,0DFA2 ;"-â"
;распаковываем наши половинки шрифта 16х8 (с символами 80h-FFh)
0000F614: E80300 call 00000F61A --- (3)
0000F617: 6661 popad
0000F619: C3 retn
--Это распаковщик--
0000F61A: 0E push cs
0000F61B: 1F pop ds
0000F61C: FC cld
0000F61D: AD lodsw

Корректируем контрольную сумму, прошиваем, перезагружаемся (не забудьте отключить имеющийся русификатор). Работает! Но та же проблема — не все русифицировалось, опять выпали символы С, Ы, Э, Ю, л, м… Метод лечения тот же:

seg000:3715 53 push bx
seg000:3716 1E push ds
seg000:3717 06 push es
seg000:3718 8BF7 mov si, di

Меняем 53h на C3h, снова пересчитываем контрольную сумму, прошиваем и получаем полностью русифицированную видеокарту.

Напоследок можно упомянуть, что локализации поддаются не только видеокарты NVIDIA, но и ATI, и многие другие модели видеокарт с программно прошиваемым BIOS. Причем общие подходы к модификации прошивок практически те же. С помощью приведенных примеров и приложенного инструментария вы, уважаемый читатель, можете попрактиковаться на своей модели в таком трудном, увлекательном и полезном занятии, как локализация современных видеокарт. При этом вы освоите ассемблер, не совершая практически ничего общественно опасного, в отличие от некоторых других личностей, изучающих его с целью навредить. Пишите о своих успехах, и мы будем дополнять сей опус вашими подвигами.

Благодарности и материалы

Автор благодарит за помощь в написании статьи участника конференции МИРа NVIDIA: BolenB

Использованные программы и материалы статьи:

  1. Hex-редактор hiew
  2. NVFLASH
  3. BIOS Asus N7600GS
  4. BIOS BFG 6800 Ultra
  5. Мои инструменты и файлы шрифтов

Обсудить статью можно в специальной теме конференции.

 / 
Андрей Никифоров (MERCURY)