Аппаратное обеспечение IBM PC
Антипереполнение
Антипереполнение возникает тогда, когда результат слишком мал для его представления в формате приемника результата операции, но все же отличен от нуля. Например, если делается попытка преобразовать наименьшее положительное число с расширенной точностью в формат числа с двойной или одинарной точностью.
Если вы используете числа только с двойной или одинарной точностью, а для хранения промежуточных результатов используете формат с расширенной точностью, особый случай антипереполнения, как правило, не возникает.
Арифметические команды
Сопроцессор использует шесть основных типов арифметических команд:
Fxxx | Первый операнд берется из верхушки стека (источник), второй - следующий элемент стека. Результат выполнения команды записывается в стек. |
Fxxx память | Источник берется из памяти, приемником является верхушка стека ST(0). Указатель стека ST не изменяется, команда действительна только для операндов с одинарной и двойной точностью. |
Fixxx память | Аналогично предыдущему типу команды, но операндами могут быть 16- или32-битовые целые числа. |
Fxxx ST, ST(i) | Для этого типа регистр ST(i) является источником, а ST(0) - верхушка стека - приемником. Указатель стека не изменяется. |
Fxxx ST(i), ST | Для этого типа регитр ST(0) является источником, а ST(i) - приемником. Указатель стека не изменяется. |
FxxxP ST(i), ST | Регистр ST(i) - приемник, регистр ST(0) - источник. После выполнения команды источник ST(0) извлекается из стека. |
Строка "xxx" может принимать следующие значения:
ADD Сложение
SUB Вычитание
SUBR Обратное вычитание, уменьшаемое и вычитаемое меняются местами
MUL Умножение
DIV Деление
DIVR Обратное деление, делимое и делитель меняются местами
Кроме основных арифметических команд имеются дополнительные арифметические команды:
FSQRT | Извлечение квадратного корня |
FSCALE | Масштабирование на степень числа 2 |
FPREM | Вычисление частичного остатка |
FRNDINT | Округление до целого |
FXTRACT | Выделение порядка числа и мантиссы |
FABS | Вычисление абсолютной величины числа |
FCHS | Изменение знака числа |
По команде FSQRT вычисленное значение квадратного корня записывается в верхушку стека ST(0).
Команда FSCALE изменяет порядок числа, находящегося в ST(0). По этой команде значение порядка числа ST(0) складывается с масштабным коэффициентом, который должен быть предварительно записан в ST(1). Действие этой команды можно представить следующей формулой:
ST(0) = ST(0) * 2n, где -215 <= n <= +215
В этой формуле n - это ST(1).
Команда FPREM вычисляет остаток от деления делимого ST(0) на делитель ST(1). Знак результата равен знаку ST(0), а сам результат получается в вершине стека ST(0).
Действие команды заключается в сдвигах и вычитания, аналогично "ручному" делению "в столбик". После выполнения команды флаг C2 регистра состояния может принимать следующие значения:
0 | остаток от деления, полученный в ST(0), меньше делителя ST(1), команда завершилась полностью; |
1 | ST(0) содержит частичный остаток, программа должна еще раз выполнить команду для получения точного значения остатка. |
Команда RNDINT округляет ST(0) в соответствии с содержимым поля RC управляющего регистра.
Команда FABS вычисляет абсолютное значение ST(0). Аналогично, команда FCHS изменяет знак ST(0) на противоположный.
АРИФМЕТИЧЕСКИЙ СОПРОЦЕССОР
12.1.
12.2.
12.3.
12.4.
12.5.
12.6.
Последнее устройство, которое мы опишем в этом томе - арифметический сопроцессор Intel 8087/80287/80387. Это устройство подключено непосредственно к центральному процессору и предназначено для выполнения операций над числами в формате с плавающей точкой (вещественные числа) и длинными целыми числами.
Арифметический сопроцессор значительно (в десятки раз) ускоряет вычисления, связанные с вещественными числами. Он может вычислять такие функции, как синус, косинус, тангенс, логарифмы и т.д. Разумеется, что с помощью сопроцессора можно выполнять и простейшие арифметические операции сложения, вычитания, умножения и деления.
Основная область применения арифметического сопроцессора - научные расчеты и машинная графика. Некоторые пакеты САПР, например, Autocad версии 10, отказывается работать, если в машине отсутствует сопроцессор. Более современный процессор Intel 80486 содержит встроенный арифметический сопроцессор, совместимый с 80387 (и даже немного более мощный).
Сопроцессор запускается центральным процессором. После запуска он выполняет все вычисления самостоятельно и параллельно с работой центрального процессора. Если центральный процессор выдает очередную команду сопроцессору в момент времени, когда тот еще не закончил выполнение предыдущей команды, центральный процессор переводится в состояние ожидания. Если же сопроцессор ничем не занят, центральный процессор, выдав команду сопроцессору, продолжает свою работу, не дожидаясь завершения вычисления. Впрочем, есть специальные средства синхронизации (команда FWAIT).
Как программировать сопроцессор?
Команды, предназначенные для выполнения сопроцессором, записываются в программе как обычные машинные команды центрального процессора. Но все эти команды начинаются байта, соответствующего команде центрального процессора ESC.
Встретив такую команду, процессор передает ее на выполнение сопроцессору, а сам продолжает выполнение программы со следующей команды.
Ассемблерные мнемоники всех команд сопроцессора начинаются с буквы F, например: FADD, FDIV, FSUB и т.д. Команды сопроцессора могут адресоваться к операндам, аналогично обычным командам центрального процессора. операндами могут быть либо данные, расположенные в основной памяти компьютера, либо внутренние регистры сопроцессора.
Возможны все виды адресации данных, используемые центральным процессором.
Прежде чем начать обсуждение команд, выполняемых сопроцессором, приведем форматы используемых данных. Как мы уже говорили, сопроцессор может работать либо с данными в формате с плавающей точкой, либо с целыми числами. В следующем разделе мы рассмотрим используемые форматы чисел с плавающей точкой или форматы вещественных чисел.
Целые числа
Арифметический сопроцессор наряду с вещественными числами способен обрабатывать и целые числа. Он имеет команды, выполняющие преобразования целых чисел в вещественные и обратно.
Возможно четыре формата целых чисел:
целое число;
короткое целое число;
длинное целое число;
упакованное десятичное число.
Целое число занимает два байта. Его формат полностью соответствует используемому центральным процессором. Для представления отрицательных чисел используется дополнительный код. Короткое целое и длинное целое имеют аналогичные форматы, но занимают, соответственно, 4 и 8 байтов.
Упакованное десятичное число занимает 10 байтов. Это число содержит 18 десятичных цифр, расположенных по две в каждом байте. Знак упакованного десятичного числа находится в старшем бите самого левого байта. Остальные биты старшего байта должны быть равны 0.
Существуют команды сопроцессора, которые преобразуют числа в формат упакованных десятичных чисел из внутреннего представления в расширенном вещественном формате. Если программа делает попытку преобразования в упакованный формат денормализованных чисел, нечисел, бесконечности и т.п., в результате получается неопределенность. Неопределенность в упакованном формате представляет из себя число, в котором два старших байта содержат единицы во всех разрядах. Содержимое остальных восьми байтов произвольно. При попытке использовать такое упакованное число в операциях фиксируется ошибка.
Мы подробно рассмотрели формат представления вещественных чисел и отметили, что в этом формате для представления отрицательных чисел используется специальный знаковый бит. Для целых чисел используется дополнительный код.
В дополнительном коде положительные числа содержат нуль в самом старшем бите числа:
0XXX XXXX XXXX XXXX
Для получения отрицательного числа в дополнительном коде из положительного надо инвертировать каждый бит числа и затем прибавить к числу единицу.
Например, число +5 в дополнительном коде выглядит следующим образом:
0000 0000 0000 0101 = +5
Для получения числа - 5 вначале инвертируем значение каждого бита:
1111 1111 1111 1010
Теперь прибавим к полученному числу +1:
1111 1111 1111 1011 = -5
Приведем возможные варианты представления целых чисел:
Нуль -------------------¬ ¦ 0...0 ¦ L-------------------
Наименьшее положительное число -------------------¬ ¦ 0...1 ¦ L-------------------
Наибольшее отрицательное число -------------------¬ ¦ 1...1 ¦ L-------------------
Наибольшее положительное число -------------------¬ ¦ 01...1 ¦ L-------------------
Наименьшее отрицательное число -------------------¬ ¦ 10...01 ¦ L------------------- Неопределенность -------------------¬ ¦ 10...00 ¦ L-------------------
Упакованное десятичное число имеет следующий вид:
¦1-й байт ¦ Девять байтов ¦ +--T------+---T---T---T---T---+ ¦Зн¦000000¦n17¦n16¦...¦n1 ¦n0 ¦ L--+------+---+---+---+---+----
На этом рисунке n0...n17 означают разряды десятичного числа. Они могут изменяться в пределах от 0000 до 1001, т.е. от 0 до 9 в десятичной системе счисления.
Теперь, после того как мы рассмотрели форматы данных, с которыми может работать арифметический сопроцессор, можно перейти к изучению внутренних регистров сопроцессора.
Численные регистры
Мы будем обозначать численные регистры как ST0 - ST7. Они приведены на следующем рисунке:
80 бит ----------------------------------------------------¬ ST0 ¦ ¦ +---------------------------------------------------+ ST1 ¦ ¦ +---------------------------------------------------+ ST2 ¦ ¦ +---------------------------------------------------+ ST3 ¦ ¦ +---------------------------------------------------+ ST4 ¦ ¦ +---------------------------------------------------+ ST5 ¦ ¦ +---------------------------------------------------+ ST6 ¦ ¦ +---------------------------------------------------+ ST7 ¦ ¦ L----------------------------------------------------
Численные регистры используются как стек. Регистр состояния в поле ST содержит номер численного регистра, являющего вершиной стека. При выполнении команд в качестве операнда могут выступать численные регистры. В этом случае номер указанного в команде регистра прибавляется к содержимому поля ST регистра состояния и таким образом определяется используемый регистр. Большинство команд после выполнения увеличивают поле ST регистра состояния, как бы записывая результаты своей работы в стек численных регистров.
Вы можете использовать регистры как массив, но в этом случае необходимо заботится о постоянстве поля ST регистра состояния, так как в противном случае номера численных регистров будут изменяться.
Деление на нуль
Этот особый случай возникает при попытке выполнить деление конечного ненулевого числа на нуль.
В афинном режиме при делении конечных (положительных или отрицательных) чисел на нуль (положительный или отрицательный) в качестве результата возвращается бесконечность. Знак этой бесконечности зависит от знака делимого и от знака нуля. Например, при делении положительного ненулевого числа на положительный нуль получается положительная бесконечность, при делении положительного ненулевого числа на отрицательный нуль - отрицательная бесконечность.
В проективном режиме, а также при попытке деления нуля на нуль возникает особый случай недействительной операции, который будет рассмотрен ниже.
Денормализованный операнд
Мы уже говорили о том, что сопроцессор использует операнды в нормализованной форме. Однако при выполнении операции может оказаться, что результат слишком мал по абсолютной величине для представления его в нормализованной форме. Можно было бы считать такой результат нулевым, однако это привело бы к снижению точности вычислений или даже к грубым ошибкам. Например, вычисляется следующее выражение:
(y-x)+x;
Если разность (y-x) вызывает антипереполнение и в качестве результата берется нулевое значение, то после вычисления всего выражения получится x. Если же пойти на расширение диапазона представления чисел за счет снижения точности и сформировать результат вычисления разности (y-x) как денормализованное число, выражение будет вычислено правильно и в результате получится y.
Таким образом, иногда целесообразно замаскировать особый случай денормализованного операнда и использовать денормализованные числа. Однако при попытке деления на ненормализованное число или извлечения из него квадратного корня фиксируется особый случай недействительной операции.
Извлечение из стека
FSTP память -> ST(0), вещественный формат FISTP память -> ST(0), целый формат FBSTP память -> ST(0), десятичный формат
Команды извлечения чисел из стека выполняют действие, обратное только что описанному. Содержимое численного регистра, номер которого определяется полем ST регистра состояния, преобразуется в необходимый формат и записывается в ячейки оперативной памяти, заданные операндом команды.
После записи содержимое поля ST увеличивается на единицу. Эти действия аналогичны выполняемым командой POP центрального процессора.
В зависимости от команды (FSTP, FISTP или FBSTP) производится преобразование формата (из расширенного в вещественный, целый или десятичный, соответственно). В процессе преобразования для команд FSTP и FISTP выполняется округление в соответствии с содержимым поля RC регистра управления. Для команды FBSTP округление всегда выполняется следующим образом - прибавляется число 0.5, затем дробная часть результата отбрасывается.
Команды сравнений чисел
В процессорах 8086/80286/80386 команды условных переходов выполняются в соответствии с установкой отдельных битов регистра флагов процессора. В арифметическом сопроцессоре существуют специальные команды сравнений, по результатам выполнения которых устанавливаются биты кодов условий в регистре состояния:
FCOM | Сравнение |
FICOM | Целочисленное сравнение |
FCOMP | Сравнение и извлечение из стека |
FICOMP | Целочисленное сравнение и извлечение из стека |
FCOMPP | Сравнение и двойное извлечение из стека |
FTST | Сравнение операнда с нулем |
FXAM | Анализ операнда |
Команда FCOM вычитает содержимое операнда, размещенного в оперативной памяти, из верхушки стека ST(0). Результат вычитания никуда не записывается и указатель верхушки стека ST не изменяется.
Обозначим операнд команды сравнения как "x". В следующей таблице приведем значения битов кодов условия после выполнения команды "FCOM x":
C3 | C0 | Условие |
0 | 0 | ST(0) > x |
0 | 1 | ST(0) < x |
1 | 0 | ST(0) = x |
1 | 1 | ST(0) и x не сравнимы. |
Последняя комбинация возникает при попытке сравнения нечисел, неопределенностей или бесконечностей, а также в некоторых других случаях.
Команда FICOM работает с 16- или 32-битовыми числами, в остальном она аналогична команде FCOM.
Команды FCOMP и FICOMP аналогичны, соответственно, командам FCOM и FICOM, за исключением того, что после выполнения операнд извлекается из стека.
Команда FCOMPP выполняет те же действия, что и FCOM, но она после выполнения извлекает из стека оба операнда, участвовавших в сравнении.
Для сравнения операнда с нулем предназначена команда FTST. После ее выполнения коды условий устанавливаются в соответствии со следующей таблицей:
C3 | C0 | Условие |
0 | 0 | ST(0) > 0 |
0 | 1 | ST(0) < 0 |
1 | 0 | ST(0) = 0 |
1 | 1 | ST(0) и 0 не сравнимы. |
Команда FXAM анализирует содержимое ST(0). После ее выполнения устанавливаются коды условий, по которым можно судить о знаке числа, о его конечности или бесконечности, нормализованности и т.д.
Бит C1 содержит знак анализируемого числа:
C1 | Знак числа |
0 | положительное число; |
1 | отрицательное число. |
C0 | Конечность/бесконечность числа |
0 | конечное число; |
1 | бесконечное число. |
C3 | C2 | Описание числа |
0 | 0 | Ненормализованное число |
0 | 1 | Нормализованное число |
1 | 0 | Нулевое число |
1 | 1 | Число денормализовано |
C3 | C2 | Описание числа |
0 | 0 | Нечисло |
0 | 1 | Бесконечное число |
1 | 0 | Пустое число |
1 | 1 | Пустое число |
---T-T-T-T-T-T-T--¬ ¦B ¦C3¦ ¦ST¦ ¦C2¦C1¦C0¦ L--+--+--+--+--+--+--+---
---T-T-T-T-T-T-T--¬ ¦SF¦ZF¦ ¦AF¦ ¦PF¦ ¦CF¦ L--+--+--+--+--+--+--+---
Например, в следующем фрагменте программы выполняется переход к метке error, если операнды несравнимы:
fcom fstsw ax sahf je error
Копирование данных
FST память -> ST(0), вещественный формат FIST память -> ST(0), целый формат FBST память -> ST(0), десятичный формат (только 80387, 80486)
Эти команды пересылают данные из верхушки стека в область памяти, указанную операндом команды. При этом содержимое указателя стека (поля ST) не изменяется.
Команда FST в качестве операнда может использовать ссылку на численный регистр ST(i), поэтому вы можете использовать эту команду для копирования верхушки стека в любой другой численный регистр.
При записи данных в оперативную память выполняется преобразование формата (в вещественный для FST, в целый для FIST и в десятичный для FBST.
Для сопроцессора 80286 вместо отсутствующей команды FBST можно выполнить следующие две команды, которые приведут к такому же результату:
FLD ST(0) FBSTP dec_number
Недействительная операция
Этот особый случай возникает при попытке выполнения таких запрещенных команд, как деление нуля на нуль, извлечения корня из отрицательного числа, обращение к несуществующему регистру сопроцессора или при попытке использования в качестве операндов команд нечисел, неопределенностей или бесконечности (для трансцендентных функций).
Неточный результат
В результате выполнения некоторых операций может возникнуть такая ситуация, когда невозможно точно представить результат. Например, при результатом деления числа 1.0 на 3.0 является бесконечная периодическая двоичная дробь 0.010101... Такое число не может быть представлено точно ни в одном формате вещественных чисел.
Обычно неточный результат является результатом округления и может не рассматриваться как ошибка.
Обмен
FXCH ST(i) -> ST(0), ST(0) -> ST(i)
Команда выполняет обмен содержимым верхушки стека ST(0) и численного регистра, указанного в качестве операнда команды.
Обработка особых случаев
В арифметическом сопроцессоре имеются два механизма обработки ошибок, возникающих при выполнении различных команд. Первый механизм основан на генерации так называемого прерывания особого случая (INT10h). Это прерывание вырабатывается в том случае, когда происходит какая-нибудь ошибка (например, деление на нуль) при условии, что соответствующие биты масок особых случаев в регистре управления не установлены. При втором способе обработки ошибок все особые случаи маскируются (соответствующие биты управляющего регистра устанавливаются в единицу) и в случае ошибки сопроцессор в качестве результата возвращает некоторое заранее известное особое значение (нечисло, неопределенность или бесконечность).
Программист может выбирать между этими способами обработки ошибок, маскируя или разрешая прерывание по особому случаю. Если прерывание особого случая замаскировано, можно предложить следующий способ обнаружения ошибки:
сбросить флажки особых случаев в регистре сосотояния;
выполнить одну или несколько команд сопроцессора;
проверить состояние флажков особых случаев в регистре состояния, в частности, бит суммарной ошибки ES;
если какой-либо флажок установлен, вызвать программу обработки ошибочной ситуации;
в программе обработки ошибочной ситуации можно сбросить флажки особых случаев, записав соответствующее значение в регистр состояния.
Кроме того, после выполнения команды полезно проверить получившийся результат на принадлежность к множеству особых значений.
Рассмотрим возможные особые случаи сопроцессора в реальном режиме.
Переполнение
Если результат выполнения операции слишком велик и не может быть представлен в формате приемника результата, фиксируется особый случай переполнения.
Этот особый случай обязательно произойдет, например, при сложении максимального числа расширенной точности самим с собой или при преобразовании этого числа в формат с двойной или одинарной точностью.
Так как для хранения промежуточных результатов используется 80-битовое представление, при выполнении операций над числами с одинарной или двойной точностью переполнения, как правило, не происходит. Огромный диапазон чисел с расширенной точностью гарантирует правильность представления больших по абсолютной величине результатов операций с числами одинарной и двойной точности.
Программирование сопроцессора
Используя языки высокого уровня, такие как Си или Паскаль, вы можете даже и не знать, что созданная вами программа использует для вычислений арифметический сопроцессор. При установке системы программирования QuickC или C 6.0 вам предоставляется возможность выброа одного из трех вариантов стандартной библиотеки:
библиотека эмулятора;
библиотека, рассчитанная на наличие сопроцессора;
библиотека альтернативной математики.
Первый вариант (библиотека эмулятора) используется по умолчанию. Программы, которые создаются с использованием эмулятора, будут работать как при наличии в системе сопроцессора, так и при его отсуствии. В последнем случае вычисления с плавающей точкой выполняются специальными подпрограмами, которые присоединяются к вашей программе на этапе редактирования. Ваша программа сама определит факт наличия (или отсуствия) сопроцессора и выберет соответствующий способ выполнения вычислений - либо с использованием сопроцесора, либо с использованием подпрограмм эмуляции сопроцессора.
Все что вам нужно для работы с библиотекой эмуляции - это просто выбрать ее при установке системы программирования. Это самый простой способ программирования сопроцессора, когда вам, вообще говоря, совсем не надо его программировать - всю работу по использоанию сопроцессора выполнят модули библиотеки эмуляции.
Второй вариант библиотеки рассчитан на наличие сопроцессора. Если сопроцессора нет, программа работать не будет. Но если известно, что сопроцессор есть (например, процессор 80486 всегда содержит блок арифметики), то вам имеет смысл использовать именно этот вариант как самый быстродействующий.
Третий вариант не использует сопроцессор совсем. Все вычисления выполняются специальными подпрограммами, входящими в состав библиотеки альтернативной математики и подключающимися к вашей программе автоматически на этапе редактирования.
К сожалению, есть программы, в которых использование библиотеки эмуляции невозможно или крайне затруднительно:
резидентные программы;
драйверы;
программы, предъявляющие жесткие требования к точности и скорости вычислений.
В случае с резидентными программами невозможность использования библиотеки эмулятора вызвана тем, что после оставления программы резидентной в памяти, например, функцией _dos_keep(), она теряет доступ к модулям эмуляции. Механизм вызова программ эмуляции основан на использовании прерываний с номерами 34h...3Eh. Перед тем как оставить программу резидентной, функция _dos_keep() восстанавливает содержимое этих векторов, делая невозможным доступ резидентной программе к модулям эмулятора. Да и самих этих модулей уже нет в памяти - на их место может быть загружена новая программа.
Поэтому руководство по Си рекомендует для резидентных программ использовать библиотеку альтернативной математики. Но эта библиотека, увы, не использует сопроцессор.
Ситуация с драйверами аналогична - драйверы, как правило, составляются на языке ассемблера, поэтому средства эмуляции библиотек Си недоступны.
Выходом может быть непосредственное программирование сопроцессора на языке ассемблера. При этом вы можете полностью использовать все возможности сопроцессора и добиться от программы наибольшей эффективности вычислений.
Какие средства можно использовать для составления программ для сопроцессора?
Обычно это или ассемблер MASM (возможно использование TASM), либо интегрированная среда разработки QuickC версии 2.01, содержащая встроенный Quick Assembler.
Приведем пример самой простой программы, подготовленный для трансляции программой Quick Assemler. Эта программа выполняет вычисления по следующей несложной формуле:
z = x + y;
Значения x и y задаются в виде констант:
.MODEL TINY
.STACK 100h
.DATA
; Здесь находятся константы с одинарной ; точностью x и y
x dd 1.0 y dd 2.0
; Резервируем четыре байта для результата
z dd ?
.CODE .STARTUP
; Записываем в стек численных регистров ; значение x
fld x
; Складываем содержимое верхушки стека ; с константой y
fadd y
; Записываем результат в ячейку z
fstp z
; Завершаем работу программы и ; возвращаем управление операционной системе
.EXIT 0
END
Как убедиться в том, что программа работает правильно?
Для этого мы используем отладчик CodeView, содержащий очень удобные средства отладки программ, работающих с арифметическим сопроцессором.
Запустим отладчик CodeView, передав ему в качестве параметра имя приведенной выше программы:
cv test87.com
После того, как отладчик запустится, откройте окно регистров сопроцессора, нажав комбинацию клавиш Alt-V-7:
После этого на в нижней части экрана появится окно регистров сопроцессора:
Пусть вас не смущает то, что в этом окне пока не показывается состояние регистров сопроцессора. Нажмите клавишу F8, выполнив один шаг программы. Окно сопроцессора будет содержать следующую информацию:
Теперь вы видите содержимое регистров управления и состояния (cControl, cStatus), регистра тегов (cTag), регистров указателей команд и данных (Instr Ptr, Data Ptr), код выполняемой команды (Opcode). Отображается также содержимое стека численных регистров (Stack), но пока это поле пустое, так как все численные регистры отмечены в регистре тегов как пустые (код 11).
Нажмите еще раз клавишу F8, выполнив следующую команду программы. Эта команда запишет в стек численных регистров значение переменной x:
Теперь в области регистров стека показано содержимое регистра cST(0), причем как в двоичном виде, так и с использованием экспоненциальной (научной) нотации.
Как и следовало ожидать, регистр ST(0) содержит величину 1.0.
Выполним еще одну команду, прибавляющую к содержимому ST(0) значение 2.0 из переменной y. Теперь регистр ST(0) содержит величину 3.0:
Последняя команда выталкивает из стека хранящееся там значение (3.0) и записывает его в переменную z. Теперь стек численных регистров снова пуст:
Отладчик CodeView обладает мощными средствами динамического просмотра состояния сопроцессора. Однако этот отладчик невозможно использовать для отладки драйверов. Мы уже говорили вам о проблемах, возникающих при отладке драйверов, в первом томе "Библиотеки системного программиста".
Там же нами была предложена методика отладки драйверов, основанная на включении в исходный текст драйвера подпрограмм, выводящих на экран содержимое регистров центрального процессора или областей памяти. Мы привели исходный текст подпрограммы ntrace, которая выводит на экран содержимое всех регистров центрального процессора.
Если ваш драйвер использует сопроцессор, вам, вероятно, потребуется также содержимое регистров сопроцессора. Приведем текст подпрограммы ntrace87, которая наряду с содержимым регистров центрального процессора, выводит содержимое регистров арифметического сопроцессора:
include sysp.inc
.MODEL tiny .CODE
PUBLIC ntrace87
;========================================== ; Процедура выводит на экран содержимое ; всех регистров центрального процессора ; и сопроцессора. Затем она ожидает нажатия на ; любую клавишу. ; После возвращения из процедуры ; все регистры восстанавливаются, в том ; числе регистры сопроцессора.
ntrace87 proc near
; Сохраняем в стеке регистры, ; содержимое которых будет изменяться
pushf push ax push bx push cx push dx push ds push bp
mov bp,sp
push cs pop ds
; Сохраняем полное состояние сопроцессора
fsave cs:regs_87
; Выводим сообщение об останове
mov dx,offset cs:trace_msg @@out_str
; Выводим содержимое всех регистров
mov ax,cs ; cs call Print_word @@out_ch ':' mov ax,[bp]+14 ; ip call Print_word
@@out_ch 13,10,13,10,'A','X','=' mov ax,[bp]+10 call Print_word
@@out_ch ' ','B','X','=' mov ax,[bp]+8 call Print_word
@@out_ch ' ','C','X','=' mov ax,[bp]+6 call Print_word
@@out_ch ' ','D','X','=' mov ax,[bp]+4 call Print_word
@@out_ch ' ','S','P','=' mov ax,bp add ax,16 call Print_word
@@out_ch ' ','B','P','=' mov ax,[bp] call Print_word
@@out_ch ' ','S','I','=' mov ax,si call Print_word
@@out_ch ' ','D','I','=' mov ax,di call Print_word
@@out_ch 13,10,'D','S','=' mov ax,[bp]+2 call Print_word
@@out_ch ' ','E','S','=' mov ax,es call Print_word
@@out_ch ' ','S','S','=' mov ax,ss call Print_word
@@out_ch ' ','F','=' mov ax,[bp]+12 call Print_word
; Выводим содержимое регистров сопроцессора
lea dx,cs:r87_msg @@out_str
; Выводим содержимое управляющего регистра
@@out_ch 'C','N','T','R','='
mov ax, cs:regs_87.cr call Print_word
; Выводим содержимое регистра состояния
@@out_ch ' ','S','T','A','T','E','='
mov ax, cs:regs_87.sr call Print_word
; Выводим содержимое регситра тегов
@@out_ch ' ','T','A','G','='
mov ax, cs:regs_87.tg call Print_word
; Выводим содержимое указателя адреса
@@out_ch ' ','C','M','D','A','D','R','='
mov ax, cs:regs_87. cmdhi and ah, 0f0h mov al, ah mov cl, 4 ror al, cl call Print_byte mov ax, cs:regs_87.cmdlo call Print_word @@out_ch ' '
; Выводим содержимое указателя операнда
@@out_ch ' ','O','P','R','A','D','R','='
mov ax, cs:regs_87.oprhi and ah, 0f0h mov al, ah mov cl, 4 ror al, cl call Print_byte mov ax, cs:regs_87.oprlo call Print_word
; Выводим содержимое непустых численных регистров
lea dx,cs:nr_msg @@out_str
mov cx, 8 ; количество регистров - 8 mov dx, 0 ; индекс текущего регистра mov bx, cs:regs_87.tg ; содержимое регистра тегов
; Цикл по стеку численных регистров
nreg_loop:
; Проверяем поле регистра тегов, соответствующее ; текущему обрабатываемому численному регистру
mov ax, bx and ax, 0c000h cmp ax, 0c000h
; Если это поле равно 11B, считаем, что данный ; численный регистр пуст, переходим к следующему
je continue
; Выводим на экран содержимое численного регистра
call Print_numreg
continue:
; Сдвигаем содержимое регистра тегов для ; обработки поля, соответствующего следующему ; регистру.
rol bx, 1 rol bx, 1 inc dx ; увеличиваем индекс текущего регистра
loop nreg_loop
lea dx,cs:hit_msg @@out_str
; Ожидаем нажатия на любую клавишу
mov ax,0 int 16h
; Восстанавливаем содержимое регистров
frstor cs:regs_87
pop bp pop ds pop dx pop cx pop bx pop ax popf
ret
trace_msg db 13,10,'>---- BREAK ----> At address ','$' hit_msg db 13,10,'Hit any key...','$' r87_msg db 13,10,13,10,'Coprocessor state:',13,10,'$' nr_msg db 13,10,'Numeric Registers:',13,10,'$'
regs_87 db 94 dup(?) ten db 10
ntrace87 endp
;========================================== ; Процедура выводит на экран содержимое ; численного регистра с номером, заданным ; в регистре al
Print_numreg proc near push cx push bx
; Выводим обозначение численного регистра
push dx @@out_ch 'S','T','(' pop dx mov al, dl call Print_byte push dx @@out_ch ')','=' pop dx
; Выводим содержимое численного регистра в ; шестнадцатеричном формате
mov cx, 10 ; счетчик байтов в числе с ; расширенной точностью mov bp, 10 ; первоначальное смещение ; к старшему байту числа
; Смещение к полю первого численного регистра ; в области сохранения
mov bx, offset cs:regs_87.st0
; Вычисляем смещение старшего байта численного ; регистра, номер которого задан в регистре DX
mov ax, dx imul cs:ten add bx, ax dec bx
; Выводим в цикле 10 байтов числа
pr_lp: push bx
add bx, bp mov al, cs:[bx] call Print_byte pop bx
dec bp loop pr_lp
push dx @@out_ch 13,10 pop dx
pop bx pop cx ret
Print_numreg endp
;========================================== ; Процедура выводит на экран содержимое AL
Print_byte proc near
push ax push bx push dx
call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl
pop dx pop bx pop ax ret Print_byte endp
;========================================== ; Процедура выводит на экран содержимое AX
Print_word proc near
push ax push bx push dx
push ax mov cl,8 rol ax,cl call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl
pop ax call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl
pop dx pop bx pop ax ret Print_word endp
Byte_to_hex proc near ;-------------------- ; al - input byte ; dx - output hex ;-------------------- push ds push cx push bx
lea bx,tabl mov dx,cs mov ds,dx
push ax and al,0fh xlat mov dl,al
pop ax mov cl,4 shr al,cl xlat mov dh,al
pop bx pop cx pop ds ret
tabl db '0123456789ABCDEF' Byte_to_hex endp
end
Работа программы основана на использовании команды FSAVE, сохраняющей в памяти содержимое всех регистров сопроцессора. Область сохранения описывается следующей структурой, определенной в файле sysp.inc:
State87 struc cr dw ? sr dw ? tg dw ? cmdlo dw ? cmdhi dw ? oprlo dw ? oprhi dw ? st0 dt ? st1 dt ? st2 dt ? st3 dt ? st4 dt ? st5 dt ? st6 dt ? st7 dt ? State87 ends
Для демонстрации возможностей ntrace87 мы немного изменили нашу первую программу, работающую с сопроцессором - после каждой комадны сопроцессора вставили вызов ntrace87:
.MODEL tiny DOSSEG
EXTRN ntrace87:NEAR
.STACK 100h
.DATA x dd 1.0 y dd 2.0 ; Резервируем четыре байта для результата
z dd ?
.CODE .STARTUP
push cs pop ds
; Записываем в стек численных регистров ; значение x call ntrace87
fld x call ntrace87
; Складываем содержимое верхушки стека ; с константой y
fadd y call ntrace87
; Записываем результат в ячейку z
fstp z call ntrace87
; Завершаем работу программы и ; возвращаем управление операционной системе
quit: .EXIT 0
END
В процессе работы этой программы на каждом шаге на экран выводится дамп содержимого регистров центрального процессора и сопроцессора (пустые численные регистры не отображаются):
>---- BREAK ----> At address 2314:0105
AX=0000 BX=0000 CX=00FF DX=2314 SP=FFFE BP=091C SI=0100 DI=FFFE DS=2314 ES=2314 SS=2314 F=7202
Coprocessor state: CNTR=037F STATE=4000 TAG=FFFF CMDADR=023256 OPRADR=02365E Numeric Registers:
Hit any key... >---- BREAK ----> At address 2314:010D
AX=0000 BX=0000 CX=00FF DX=2314 SP=FFFE BP=091C SI=0100 DI=FFFE DS=2314 ES=2314 SS=2314 F=7202
Coprocessor state: CNTR=037F STATE=7800 TAG=3FFF CMDADR=023246 OPRADR=02365E Numeric Registers: ST(00)=3FFF8000000000000000
Hit any key... >---- BREAK ----> At address 2314:0115
AX=0000 BX=0000 CX=00FF DX=2314 SP=FFFE BP=091C SI=0100 DI=FFFE DS=2314 ES=2314 SS=2314 F=7202
Coprocessor state: CNTR=037F STATE=7800 TAG=3FFF CMDADR=02324E OPRADR=023662 Numeric Registers: ST(00)=4000C000000000000000
Hit any key... >---- BREAK ----> At address 2314:011D
AX=0000 BX=0000 CX=00FF DX=2314 SP=FFFE BP=091C SI=0100 DI=FFFE DS=2314 ES=2314 SS=2314 F=7202
Coprocessor state: CNTR=037F STATE=4000 TAG=FFFF CMDADR=023256 OPRADR=023666 Numeric Registers:
Hit any key...
Регистр состояния
Поля регистра состояния сопроцессора 8087 показаны на следующем рисунке:
15 14 13-11 10 9 8 7 6 5 4 3 2 1 0 ---T-T-----T-T-T-T-T-T-T---T-T-T-T--¬ ¦B ¦C3¦ ST ¦C2¦C1¦C0¦IR¦XX¦PE¦UE ¦OE¦ZE¦DE¦IE¦ L--+--+-----+--+--+--+--+--+--+---+--+--+--+---
Регистр состояния сопроцессоров 80287/80387 и сопроцессора, входящего в состав процессора 80486, имеет немного другой формат:
15 14 13-11 10 9 8 7 6 5 4 3 2 1 0 ---T--T-----T--T-T-T-T-T--T--T---T---T--T-----¬ ¦B ¦C3¦ ST ¦C2¦C1¦C0¦ES¦XX¦PE¦UE ¦OE¦ZE¦DE¦IE¦ L--+--+-----+--+--+--+--+--+--+---+--+--+--+---
В обоих форматах биты 0...5 - флажки особых случаев. Они устанавливаются всегда при возникновении особых случаев, даже замаскированных установкой в 1 соответствующих битов регистра управления.
Приведем таблицу флажков особых случаев:
IE | недействительная операция; |
DE | денормализованный результат; |
ZE | деление на нуль; |
OE | переполнение; |
UE | антипереполнение; |
PE | неточный результат. |
Для того, чтобы сбросить установившийся флажок, программа должна явным образом установить его в нуль, выполнив команду записи в регистр состояния.
Назначение бита 7 регистра состояния различно для сопроцессора 8087 и сопроцессоров 80287/80387.
Для сопроцессора 8087 этот бит обозначается IR и содержит флаг запроса прерывания при возникновении незамаскированного особого случая. В этом случае флаг устанавливается в 1.
Сопроцессоры 80287/80387 используют бит 7 в качестве флага суммарной ошибки, который устанавливается в 1 при возникновении незамаскированного особого случая.
Биты C0, C1, C2, C3 - это коды условий. Они определяются по результату выполнения команд сравнения и команды нахождения остатка. Мы расскажем о них при описании соответствующих команд сопроцессора.
Поле ST занимает три бита 11...13 и содержит номер численного регистра, являющегося вершиной стека численных регистров.
Бит B - бит занятости. Он устанавливается в 1, когда процессор выполняет команду или когда происходит прерывание от сопроцессора. Если сопроцессор свободен, бит занятости установлен в 0.
Регистр тегов
Этот регистр разделен на восемь двухбитовых полей, которые мы обозначим как TAG0...TAG7. Каждое поле относится к своему численному регистру:
-----T----T----T----T----T----T----T----¬ ¦TAG0¦TAG1¦TAG2¦TAG3¦TAG4¦TAG5¦TAG6¦TAG7¦ L----+----+----+----+----+----+----+-----
Поля регистра тегов классифицируют содержимое "своего" численного регистра:
00 | регистр содержит действительное ненулевое число; |
01 | в регистре находится нуль; |
10 | регистр содержит недействительное число (нечисло, бесконечность, неопределенность); |
11 | пустой неинициализированный регистр. |
Например, если все регистры сопроцессора были пустые, а затем в стек численных регистров было занесено одно действительное ненулевое значение, содержимое регистра тегов будет 3FFFh.
Регистр управления
Регистр управления для сопроцессора 8087 показан на следующем рисунке:
15-13 12 11-10 9-8 7 6 5 4 3 2 1 0 ---------T-T-----T-----T---T---T---T---T---T---T---T---¬ ¦XXXXXXXX¦IC¦ RC ¦ PC ¦IEM¦XXX¦PM ¦UM ¦OM ¦ZM ¦DM ¦IM ¦ L--------+--+-----+-----+---+---+---+---+---+---+---+----
Регистр управления сопроцессоров 80287/80387 и сопроцессора, входящего в состав процессора 80486, имеет аналогичный формат, за исключением того, что бит 7 в нем не используется:
15-13 12 11-10 9-8 7-6 5 4 3 2 1 0 ---------T-T-----T-----T--------T---T---T---T---T---T---¬ ¦XXXXXXXX¦IC¦ RC ¦ PC ¦XXXXXXXX¦PM ¦UM ¦OM ¦ZM ¦DM ¦IM ¦ L--------+--+-----+-----+--------+---+---+---+---+---+----
Биты 0...5 - маски особых случаев. Особые случаи иногда возникают при выполнении команд сопроцессора, например, при делении на нуль, переполнении и т.д. Если все биты масок особых случаев равны нулю, особый случай вызывает прерывание центрального процессора INT 10h (обратите внимание, что это прерывание используется BIOS для работы с дисплейным адаптером). Если же особые случаи замаскированы установкой соответствующих битов в единичное состояние, прерывание не вырабатывается, а в качестве результата возвращается особое значение - бесконечность, нечисло и т.д.
Приведем таблицу масок особых случаев:
IM | маска недействительной операции; |
DM | маска денормализованного результата; |
ZM | маска деления на нуль; |
OM | маска переполнения; |
UM | маска антипереполнения; |
PM | маска особого случая при неточном результате; |
IEM | маскирование одновременно всех особых случаев вне зависимости от установки битов 0...5 регистра управления, этот бит действителен только для сопроцессора 8087 |
Подробнее особые случаи и условия их возникновения будут описаны позже, когда мы займемся ошибками при выполнении команд в сопроцессоре.
Поле PC управляет точностью вычислений в сопроцессоре:
00 | использование расширенной точности, этот режим устанавливается при инициализации сопроцессора; |
10 | округление результата до двойной точности; |
00 | округление результата до одинарной точности. |
Искусственное ухудшение точности вычислений не приводит к ускорению работы программы. Режимы с пониженной точностью предназначены для эмуляции процессоров, использующих двойную и одинарную точность, соответственно.
Двух битовое поле RC задает режим округления при выполнении операций с вещественными числами:
00 | округление к ближайшему числу, этот режим устанавливается при инициализации сопроцессора; |
01 | округление в направлении к отрицательной бесконечности; |
10 | округление в направлении к положительной бесконечности; |
11 | округление в направлении к нулю. |
Округление в направлении к ближайшему числу.
-беск.<-o-<<-x-------o---- 0 -----o-----x->>-o---->+беск.
Округление в направлении к отрицательной бесконечности.
-беск.<-o-<<-x-------o---- 0 -----o--<<---x-o---->+беск.
Округление в направлении к положительной бесконечности.
-беск.<-o-x-->>-----o---- 0 -----o------x->>-o---->+беск.
Округление в направлении к нулю.
-беск.<-o-x-->>-----o---- 0 -----o--<<----x-o---->+беск.
Для наибольшего уменьшения ошибок вычислений наиболее целесообразно использовать режим округления в направлении к ближайшему числу. Режим округления в направлении к нулю используется при моделировании целочисленной арифметики.
Остальные два режима округления используют в интервальной арифметике. Для получения наиболее точного результата каждая команда (операция) выполняется два раза - первый раз с округлением в направлении к отрицательной бесконечности, второй раз - в направлении к положительной бесконечности. Точный результат лежит между полученными значениями. Заметьте, что здесь речь идет только об отелных операциях, но не о том, чтобы выполнить всю программу вычислений вначале с одним режимом округления, а затем с другим.
Поле IC регистра управления предназначен для управления бесконечностью:
0 проективный режим; 1 афинный режим.
В проективном режиме существует только одна бесконечность, она не имеет знака:
Бесконечность -----------------> <-----------------¬ ¦ ¦ ¦ ¦ ¦ ¦ L---------------- 0 ------------------
В афинном режиме имеется две бесконечности - положительная и отрицательная:
-бесконечность + бесконечность <-------------------------- 0 ---------------------------->
Афинный режим допускает выполнение многих операций с бесконечностями - сложение, умножение и т.д.
Регистры сопроцессора
Арифметический сопроцессор содержит восемь численных 80-битовых регистров, предназначенных для хранения промежуточных результатов вычислений, регистра управления, регистра состояния, регистра тегов, регистра указателя команды и регистра указателя операнда.
Регистры указателя команды и указателя операнда
Регистры указателя команды и указателя операнда предназначены для обработки особых случаев, возникающих при выполнении команд в сопроцессоре.
В сопроцессоре 8087 указатель команды содержит 20-разрядный адрес команды, вызвавшей особый случай и код выполняемой в этот момент операции. Адрес команды здесь указывается без учета предшествующих команде префиксов:
---------------------------------------------------¬ ¦Адрес команды (0...15) ¦ +------------------------T-T-----------------------+ ¦Адрес команды (16...19) ¦X¦ Код операции (0...10) ¦ L------------------------+-+------------------------
Сопроцессоры 80287/80387 в реальном режиме работы имеют такой же формат регистра указателя команд, однако этот указатель показывает на первый префикс команды, вызвавшей особый случай.
Защищенный режим работы центрального процессора и сопроцессора выходит за рамки данной книги, однако для полноты изложения приведем формат указателей и для этого режима. В защищенном режиме адрес состоит из селектора (в какой-то степени соответствует сегментной компоненте адреса реального режима) и смещения. Формат указателя команды для защищенного режима представлен на следующем рисунке:
---------------------------------------------------¬ ¦ Смещение команды ¦ +--------------------------------------------------+ ¦ Селектор команды ¦ L---------------------------------------------------
Код операции здесь отсутствует, но его легко получить, пользуясь адресом команды.
Если при возникновении особого случая использовался операнд, находящийся в оперативной памяти, его адрес записывается в регистр указателя операнда. Приведем форматы этого регистра для реального и защищенного режимов работы.
Формат указателя операнда для реального режима:
---------------------------------------------------¬ ¦ Адрес операнда (0...15) ¦ +-------------------------------T------------------+ ¦ Адрес операнда (16...19) ¦XXXXXXXXXXXXXXXXXX¦ L-------------------------------+-------------------
Формат указателя операнда для защищенного режима:
---------------------------------------------------¬ ¦ Смещение операнда ¦ +--------------------------------------------------+ ¦ Селектор операнда ¦ L---------------------------------------------------
Система команд сопроцессора
Возможны три формата команд сопроцессора, аналогичные форматам команд центральных процессоров 8086/80286/80386. Это команды с обращением к оперативной памяти, команды с обращением к одному из численных регистров и команды без операндов, заданных явным образом.
Команды с обращением к памяти могут занимать от двух до четырех байтов, в зависимости от способа адресации операнда, находящегося в памяти:
¦1 байт ¦1 байт ¦1 байт ¦1 байт ¦ +-----T----+---T----T---+-----------+-----------+ ¦11011¦КОП1¦MOD¦КОП2¦R/M¦ Смещение1 ¦ Смещение2 ¦ L-----+----+---+----+---+-----------+------------
Первые пять битов соответствуют команде центрального процессора ESC. Поля КОП1 и КОП2 определяют выполняемую команду, т.е. содержат код операции. Поля MOD и R/M вместе с полями "Смещение1" и "Смещение2" задают адрес операнда в памяти аналогично тому, как это происходит в процессорах 8086/80286/80386. Однако есть и отличия, связанные с возможностью адресации численных регистров сопроцессора.
Приведем таблицу, показывающую зависимость способа адресации от содержимого полей MOD и R/M:
-----T----------------------------------------------¬ ¦Поле¦ Поле MOD ¦ ¦R/M +---------T---------------T----------------T---+ ¦ ¦ 00 ¦ 01 ¦ 10 ¦11 ¦ +----+---------+---------------+----------------+---+ ¦000 ¦(bx)+(si)¦(bx)+(si)+disp8¦(bx)+(si)+disp16¦ST0¦ ¦001 ¦(bx)+(di)¦(bx)+(di)+disp8¦(bx)+(di)+disp16¦ST1¦ ¦010 ¦(bp)+(si)¦(bp)+(si)+disp8¦(bp)+(si)+disp16¦ST2¦ ¦011 ¦(bp)+(di)¦(bp)+(di)+disp8¦(bp)+(di)+disp16¦ST3¦ ¦100 ¦ (si) ¦ (si)+disp8 ¦ (si)+disp16 ¦ST4¦ ¦101 ¦ (di) ¦ (di)+disp8 ¦ (di)+disp16 ¦ST5¦ ¦110 ¦ disp16 ¦ (bp)+disp8 ¦ (bp)+disp16 ¦ST6¦ ¦111 ¦ (bx) ¦ (bx)+disp8 ¦ (bx)+disp16 ¦ST7¦ L----+---------+---------------+----------------+----
Если в таблице указаны значения смещения disp8 или disp16, это означает, что в команде присуствует один или два байта смещения, соответственно.
Если поле MOD содержит значение 11, возможна адресация численных регистров ST0...ST1. При этом команда не содержит байтов смещения.
Формат команды с обращением к численному регистру приведен на следующем рисунке:
¦1 байт ¦1 байт ¦ +-----T----+---T----T---+ ¦11011¦КОП1¦11 ¦КОП2¦STi¦ L-----+----+---+----+----
Видно, что это есть частный случай предыдущей команды, в которой поле MOD содержит значение 11 и отсутствуют байты смещения.
Самый простой формат имеют команды без явного обращения к операндам:
¦1 байт ¦1 байт ¦ +-----T----+---T--------+ ¦11011¦КОП1¦11 ¦ КОП2 ¦ L-----+----+---+---------
Разумеется, если вы пишете программу для сопроцессора на языке ассемблера, вы можете использовать мнемоническое обозначение команд. Все мнемоники команд сопроцесора начинаются с буквы F, поэтому их легко отличить от команд процессоров 8086/80286/80386/80486.
Все команды сопроцессора можно разделить на несколько групп:
команды пересылки данных;
арифметические команды;
команды сравнений чисел;
трансцендентные команды;
управляющие команды.
Команды пересылки данных предназначены для загрузки чисел из оперативной памяти в численные регитры, записи данных из численных регистров в операивную память, копирования данных из одного численного регистра в другой.
Арифметические команды выполняют такие операции, как сложение, вычитание, умножение, деление, извлечение квадратного корня, нахождение частичного остатка, округление и т.п.
Команды сравнения сравнивают вещественные и целые числа, выполняют анализ чисел.
Трансцендентные команды предназначены для вычисления различных тригонометрических, логорифмических, показательных и гиперболических функций - sin(), cos(), tg() и т.п.
Последняя группа команд - управляющие команды - обеспечивают установку режима работы арифметического сопроцессора, его сброс и инициализацию, перевод сопроцессора в защищенный режим работы и т.д.
Следующие разделы будут посвящены детальному описанию различных групп команд сопроцессора.
Трансцендентные команды
Трансцендентные команды предназначены для вычисления таких функций, как тригонометрические (sin, cos, tg,...), обратные тригонометрические (arcsin, arccos,...), показательные (xy, 2x, 10x, ex), гиперболические (sh, ch, th,...), обратные гиперболические (arsh, arch, arcth,...).
В следующей таблице приведены все трансцендентные команды сопроцессора:
FPTAN | Вычисление частичного тангенса |
FPATAN | Вычисление частичного арктангенса |
FYL2X | Вычисление y*log2(x) |
FYL2XP1 | Вычисление y*log2(x+1) |
F2XM1 | Вычисление 2x-1 |
FCOS | Вычисление cos(x) (только 80387/80486) |
FSIN | Вычисление sin(x) (только 80387/80486) |
FSINCOS | Вычисление sin(x) и cos(x) одновременно (только 80387/80486) |
Команда FPTAN вычисляет частичный тангенс ST(0), размещая в стеке такие два числа x и y, что y/x = tg(ST(0)).
После выполнения команды число y располагается в ST(0), а число x включается в стек сверху (т.е. записывается в ST(1)). Аргумент команды FPTAN должен находится в пределах:
0 <= ST(0) <= pi/4
Пользуясь полученным значением частичного тангенса, можно вычислить другие тригонометрические функции по следующим формулам:
sin(z) = 2*(y/x) / (1 + (y/x)2) cos(z) = (1 - (y/x)2) / (1 + (y/x)2) tg(z/2) = y/x; ctg(z/2) = x/y; cosec(z) = (1 + (y/x)2) / 2*(y/x) sec(z) = (1 + (y/x)2) / (1 - (y/x)2)
В этой таблице z - значение, находившееся в ST(0) до выполнения команды FPTAN, x и y - значения в регистрах ST(0) и ST(1), соответственно.
Команда FPATAN вычисляет частичный арктангенс z=arctg(ST(0)/ST(1))=arctg(x/y).
Перед выполнением команды числа x и y располагаются в ST(0) и ST(1), сответственно. Аргументы команды FPATAN должен находится в пределах:
0 < y < x
Результат записывается в ST(0).
Команда FYL2X вычисляет выражение y*log2(x), операнды x и y размещаются, соответственно, в ST(0) и ST(1). Операнды извлекаются из стека, а результат записывается в стек. параметр x должен быть положительным числом.
Пользуясь результатом выполнения этой команды, можно вычислить следующим образом логарифмические функции:
log2(x) = FYL2(x) loge(x) = loge(2) * log2(x) = FYL2X(loge(2), x) = = FYL2X(FLDLN2, x) log2(x) = log10(2) * log2(x) = FYL2X (log10(2), x) = = FYL2X(FLDLG2, x)
Функция FYL2XP1 вычисляет выражение y*log2(x+1), где x соответствует ST(0), а y - ST(1). Результат записывается в ST(0), оба операнда выталкиваются из стека и теряются.
На операнд x накладывается ограничение:
0 < x < 1 - 1/sqrt(2)
Команда F2XM1 вычисляет выражение 2x-1, где x - ST(0). Результат записывается в ST(0), параметр должен находится в следующих пределах:
0 <= x <= 0,5
Команда FCOS вычисляет cos(x) (только для 80387/80486). Параметр x должен находится в ST(0), туда же записывается результат выполнения команды.
Команда FSIN аналогична команде FCOS, но вычисляет значение косинуса ST(0).
Команда FSINCOS вычисляет одновременно значения синуса и косинуса параметра ST(0). Значение синуса записывается в ST(1), косинуса - в ST(0).
На этом мы закончим описание трансцендентных команд сопроцессора и перейдем к управляющим командам.
Управляющие команды
Управляющие команды предназначены для работы с нечисловыми регистрами сопроцессора. Некоторые команды имеют альтернативные варианты. Мнемоники этих команд могут начинаться с FN или с F. Первый вариант соответствует командам "без ожидания". Для команд "без ожидания" процессор не проверяет, занят ли сопроцессор выполнением команды, т.е. бит занятости B не проверяется. Численные особые случаи также игнорируются.
Варианты команд "с ожиданием" действуют также, как и обычные команды сопроцессора.
Приведем таблицу управляющих команд сопроцессора:
FNSTCW (FSTCW) Записать управляющее слово FLDCW Загрузить управляющее слово FNSTSW (FSTSW) Записать слово состояния FNSTSW AX (FSTSW AX) Записать слово состояния в AX, не поддерживается сопроцессором 8087 FNCLEX (FCLEX) Сбросить особые случаи FNINIT (FINIT) Инициализировать сопроцессор FNSTENV (FSTENV) Записать среду FLDENV Загрузить среду FNSAVE (FSAVE) Записать полное состояние FRSTOR Восстановить полное состояние FINCSTP Увеличить указатель стека на 1 FDECSTP Уменьшить указатель стека на 1 FFREE Освободить регистр FNOP Холостая команда, нет операции FSETPM Установить защищенный режим работы
Команда FNSTCW записывает содержимое управляющего регистра в оперативную память.
Команда FLDCW загружает управляющий регистр данными из оперативной памяти и обычно используется для изменения режима работы сопроцессора.
Команда FNSTSW записывает содержимое регистра состояния в оперативную память. Команда FNSTSW AX записывает содержимое этого регистра в регистр AX центрального процессора для его последующего анализа командами условных переходов.
Сопроцессор 8087 не имеет варианта команды FSTSW AX, поэтому приходится вначале записывать регистр состояния в память, а затем в регистр флагов процессора 8086.
Команда FNCLEX сбрасывает флаги особых случаев в регистре состояния сопроцессора. Кроме того, сбрасываются биты ES и B.
Команда FNINIT инициализирует регистр состояния, управляющий регистр и регистр тегов в соответствии со следующей таблицей:
Регистр Устанавливаемый режим работы
Управляющий Проективная бесконечность, округление к ближайшему, расширенная точность, все особые случаи замаскированы.
Состояния B=0 (бит занятости сброшен), код условия не определен, ST=ES=0, флаги особых случаев установлены в нуль.
Тегов Все поля регистра тегов содержат значение 11 (пустой регистр).
Команда FNSTENV записывает в память содержимое всех регистров, кроме численных, в следующем формате:
------------------------¬ ¦ Управляющий регистр ¦ +-----------------------+ ¦ Регистр состояния ¦ +-----------------------+ ¦ Регистр тегов ¦ +-----------------------+ ¦ ¦ +- Указатель команды -+ ¦ ¦ +-----------------------+ ¦ ¦ +- Указатель операнда -+ ¦ ¦ L------------------------
Команда FLDENV предназначена для загрузки регистров, сохраненных ранее командой FNSTENV. Обе эти команды полезны в программах обработки особых случаев.
Команды FNSAVE и FRSTOR действуют аналогично командам FNSTENV и FLDENV, но они дополнительно сохраняют и восстанавливают содержимое численных регистров. Формат области сохранения регистров, занимающей 94 байта, приведен на следующем рисунке:
------------------------¬ ¦ Управляющий регистр ¦ +-----------------------+ ¦ Регистр состояния ¦ +-----------------------+ ¦ Регистр тегов ¦ +-----------------------+ ¦ ¦ +- Указатель команды -+ ¦ ¦ +-----------------------+ ¦ ¦ +- Указатель операнда -+ ¦ ¦ +-----------------------+-------------------------------¬ ¦ ST(0) ¦ +-------------------------------------------------------+ ¦ ST(1) ¦ +-------------------------------------------------------+ ¦ ST(2) ¦ +-------------------------------------------------------+ ¦ ST(3) ¦ +-------------------------------------------------------+ ¦ ST(4) ¦ +-------------------------------------------------------+ ¦ ST(5) ¦ +-------------------------------------------------------+ ¦ ST(6) ¦ +-------------------------------------------------------+ ¦ ST(7) ¦ L--------------------------------------------------------
Команды FINCSTP и FDECSTP, соответственно, увеличивают и уменьшают на 1 указатель стека SP.
Команда FFREE ST(i) помечает численный регистр ST(i) как пустой, записывая в соответствующее поле регистра тегов значение 11.
Команда FNOP не производит никаких действий.
Команда FSETPM переводит сопроцессор в защищенный режим работы. Подробное рассмотрение защищенного режима работы выходит за рамки данной книги.
Вещественные числа
Прежде чем говорить о форматах вещественных числе, используемых сопроцессором, вспомним о числах с плавающей точкой, встречающихся в научных расчетах.
В общем виде эти числа можно записать следующим образом:
(знак)(мантисса)*10(знак)(порядок)
Например: -1.35*105
Здесь знак - это минус, мантисса - 1.35, порядок - 5. Порядок тоже может иметь знак. В этом представлении чисел для вас вряд ли есть что либо новое. Вспомним также такое понятие, как норамализованное представление чисел:
если целая часть мантиссы числа состоит из одной, не равной нулю, цифры, то число с плавающей точкой называется нормализованным.
В чем преимущества использования нормализованных чисел? В том, что для фиксированной разрядной сетки числа (т.е. для фиксированного количества цифр в числе) нормализованные числа имеют наибольшую точность. Кроме того, нормализованное представление исключает неоднозначность - каждое число с плавающей точкой может быть представлено различными (ненормализованными) способами:
123.5678*105 = 12.35678*106 = 1.235678*107 = 0.1235678*108
Для тех, кто программировал на языках высокого уровня, знакомо следующее представление чисел с плавающей точкой:
(знак)(мантисса)E(знак)(порядок)
Например, -5.35E-2 означает число -5.35*10-2. Такое представление называется научной нотацией.
Сопроцессор 8087/80287/80387 может работать с вещественными числами в трех форматах:
одинарной точности;
двойной точности;
расширенной точности.
Эти числа занимают в памяти, соответственно, 4, 8 или 10 байтов:
Одинарная точность
1 бит 8 бит 23 бита ---T-------T--------------------¬ ¦Зн¦Порядок¦ Мантисса ¦ L--+-------+---------------------
Двойная точность 1 бит 11 бит 52 бита ---T---------T--------------------------------¬ ¦Зн¦ Порядок ¦ Мантисса ¦ L--+---------+---------------------------------
Расширенная точность 1 бит 15 бит 64 бита ---T-------------T------------------------------------¬ ¦Зн¦ Порядок ¦ Мантисса ¦ L--+-------------+-------------------------------------
В любом представлении старший бит "Зн" определяет знак вещественного числа:
0 - положительное число;
1 - отрицательное число.
Все равные по абсолютному значению положительные и отрицательные числа отличаются только этим битом. В остальном числа с разным знаком полностью симметричны. Для представления отрицательных чисел здесь не используется дополнительный код, как это сделано в центральном процессоре.
Арифметический сопроцессор работает с нормализованными числами, поэтому поле мантиссы содержит мантиссу нормализованного числа.
Так как здесь используется двоичное представление чисел, сформулируем определение нормализованного числа для двоичного представления:
если целая часть мантисса числа в двоичном представлении равна 1, то число с плавающей точкой называется нормализованным.
Так как для нормализованного двоичного числа целая часть всегда равна единице, то эту единицу можно не хранить. Именно так и поступили разработчики арифметического сопроцессора - в форматах одинарной и двойной точности целая часть мантиссы не хранится. Таким образом экономится один бит памяти.
Для наглядности представим мантиссу числа в следующей форме:
n.nnnnnnnnnn...n
Здесь символом n обозначается либо 0, либо 1. Нормализованные числа в самой левой позиции содержат 1, поэтому их можно изобразить еще и в таком виде:
1.nnnnnnnnnn...n
Представление с расширенной точностью используется сопроцессором для выполнения всех операций. И даже более - все операции с числами сопроцессор выполняет над числами только в формате с расширенной точностью. В этом формате хранится и "лишний" бит целой части нормализованного числа.
Основная причина использования для вычислений расширенной точности - предохранение программы от возможной потери точности вычислений, связанной с большими различиями в порядках чисел, участвующих в арифметических операциях.
Поле порядка - это степень числа 2, на которую умножается мантисса, плюс смещение, равное 127 для одинарной точности, 1023 - для двойной точности и 16383 - для расширенной точности.
Для того, чтобы определить абсолютное значение числа с плавающей точкой, можно воспользоваться следующими формулами:
одинарная точность: 1.(цифры мантиссы)*2(P-127)
двойная точность: 1.(цифры мантиссы)*2(P-1023)
расширенная точность: 1.(цифры мантиссы)*2(P-16383)
Знак числа, как мы уже говорили, определяется старшим битом.
Приведем конкретный пример. Пусть мы имеем число с одинарной точностью, которое в двоичном виде выглядит следующим образом:
1 01111110 11000000000000000000000
Для этого числа знаковый бит равен 1 (отрицательное число), порядок равен 126, мантисса - 11 (в двоичной системе счисления).
Значение этого числа равно:
1.11 * 2(126-127) = -1.75 * 2-1 = -0,875
Рассмотрим теперь различные особые случаи представления вещественных чисел.
Нуль - это такое число, у которого порядок и мантисса равны нулю. Нуль может иметь положительный или отрицательный знаки, которые игнорируются в операциях сравнения. Таким образом, имеется два нуля - положительный и отрицательный.
Наименьшее положительное число - это число, которое имеет нулевой знаковый бит, значение порядка, равное 1, и значение мантиссы, равное нулю. В зависимости от представления наименьшее положительное число имеет следующие значения: 1,17*10-38 (одинарная точность), 2.23*10-308 (двойная точность), 3.37*10-4932 (расширенная точность).
Наибольшее отрицательное число - полностью совпадает с наименьшим положительным числом, но имеет бит знака, установленный в 1.
Наибольшее положительное число -это число, которое имеет нулевой знаковый бит, поле порядка, в котором все биты кроме самого младшего, равны 1, и содержит единицы во всех разрядах мантиссы. В зависимости от представления наибольшее положительное число имеет следующие значения: 3.37*1038 (одинарная точность), 1.67*10308 (двойная точность), 1.2*104932 (расширенная точность).
Наименьшее отрицательное число - полностью совпадает с наибольшим положительным числом, но имеет бит знака, установленный в 1.
Положительная и отрицательная бесконечность - это число содержит все единицы в поле порядка и все нули в поле мантиссы. В зависимости от состояния знакового бита может быть положительная и отрицательная бесконечности. Бесконечность может получиться, например, как результат деления конечного числа на нуль.
Нечисло - содержит все единицы в поле порядка и любое значение в поле мантиссы. Нечисло может возникнуть в результате выполнения неправильной операции при замаскированных особых случаях (ошибкам при работе с сопроцессоре будет посвящен отдельный раздел этой главы).
Неопределенность - содержит в поле порядка все единицы, а в поле мантиссы - число 1000..0 (для одинарной и двойной точности) или 11000..0 (для расширенной точности, так как в этом формате хранится старший бит мантиссы).
Для большей наглядности сведем все возможные представления вещественных чисел в таблицу:
Положительный нуль --T---------T------------------¬ ¦0¦ 0...0 ¦ 0...0 ¦ L-+---------+-------------------
Отрицательный нуль --T---------T------------------¬ ¦1¦ 0...0 ¦ 0...0 ¦ L-+---------+-------------------
Наименьшее положительное число --T---------T------------------¬ ¦0¦ 0...01 ¦ 0...0 ¦ L-+---------+-------------------
Наибольшее отрицательное число --T---------T------------------¬ ¦1¦ 0...01 ¦ 0...0 ¦ L-+---------+-------------------
Наибольшее положительное число --T---------T------------------¬ ¦0¦ 11...10 ¦ 1...1 ¦ L-+---------+-------------------
Наименьшее отрицательное число --T---------T------------------¬ ¦1¦ 11...10 ¦ 1...1 ¦ L-+---------+-------------------
Положительная бесконечность --T---------T------------------¬ ¦0¦ 1...1 ¦ 0...0 ¦ L-+---------+-------------------
Отрицательная бесконечность --T---------T------------------¬ ¦1¦ 1...1 ¦ 0...0 ¦ L-+---------+-------------------
Нечисло --T---------T------------------¬ ¦1¦ 1...1 ¦ х...х ¦ L-+---------+-------------------
Неопределенность --T---------T------------------¬ ¦1¦ 1...1 ¦ 10...0 ¦ L-+---------+-------------------
Загрузка констант
FLDZ 0 -> ST(0) - Загрузить нуль FLD1 1 -> ST(0) - Загрузить единицу FLDPI "Пи" -> ST(0) - Загрузить число "пи". FLDLG2 log102 -> ST(0) - Загрузить log102 FLDLN2 loge2 -> ST(0) - Загрузить loge2 FLDL2T loge10 -> ST(0) - Загрузить loge10 FLDL2E log2e -> ST(0) - Загрузить log2e
Гораздо быстрее загружать константы с помощью специальных команд, чем использовать команды загрузки данных из оперативной памяти.
Запись в стек
FLD ST(0) <- память, вещественный формат FILD ST(0) <- память, целый формат FBLD ST(0) <- память, десятичный формат
Команды FLD, FILD, FBLD загружают в вершину стека вещественное, целое и десятичное числа, соответственно.
При выполнении этих команд операнд считывается из оперативной памяти, преобразуется в формат с расширенной точностью. Затем поле ST регистра состояния уменьшается на единицу и выполняется запись операнда в численный регистр, определяемый новым значением поля ST. Т.е. операнд записывается в стек численных регистров, а указатель стека - поле ST - уменьшается на единицу. По своему действию эти команды напоминают команду PUSH центрального процессора.
Непосредственно перед загрузкой численного регистра проверяется содержимое поля TAG0. Если это содержимое не равно 11 (пустой регистр), в регистре состояния устанавливается флаг IE (недействительная операция) и вырабатывается прерывание (если в регистре управления не установлена маска IM - маска недействительной операции).
ОБЗОР ЛИТЕРАТУРЫ
Undocumented DOS
Andrew Schulman, Raymond J. Michels, Jim Kyle, Tim Paterson, David Maxey, Ralf Brown
ISBN 0-201-57064-5 QA76.76.O63U53 1990 005.4'46-dc20 90-46992 Second Printing, February 1991
679 стр.
Книга посвящена использованию недокументированных прерываний MS-DOS версии до 4.01 включительно. В книге разъясняются причины отсутствия в документации по операционной системе информации о некоторых прерываниях и структурах данных. Кроме того, показана важность этих прерываний. Программы пользователя могут вполне безопасно использовать некоторые недокументированные особенности операционной системы без риска потери совместимости со следующими версиями MS-DOS.
В книге рассмотрен механизм управления памятью в MS-DOS, процесс загрузки и инициализации драйверов.
Описана внутренняя структура файловой системы, множество недокументированных прерываний и структур данных, связанных с файловой системой. Описаны особенности работы с файловой системой в сети.
Отдельная глава посвящена составлению резидентных программ. Показано, что без использования недокументированных прерываний невозможно составить правильно работающую резидентную программу.
Описана работа командного интерпретатора MS-DOS, приведена информация, необходимая для разработки собственного командного интерпретатора.
Описаны прерывания, необходимые для разработки отладчиков программ, таких как Code View и DEBUG. Большой раздел посвящен отладке программ в среде WINDOWS.
К книге прилагаются дискеты, содержащие исходные тексты всех программ и справочную базу данных. В справочной базе данных собрана информация о недокументированных прерываниях и структурах данных. В частности, описан интерфейс с WINDOWS, с различным сетевым программным обеспечением.
Advanced DOS Memory resident utilities, interrupts, and disk managment with MS- and PC-DOS
Michael I. Hyman Second Edition MIS INC, 1988 ISBN 0-943518-83-0
Эта книга содержит достаточно подробное описание логической структуры диска в MS-DOS (версии 3.30 и более ранних версий).
В первой части книги описана работа с файлами и каталогами на уровне прерываний MS-DOS, структура таблицы разделов диска.
Вторая часть книги посвящена использованию прерываний в программах, составленных на языке ассемблера. Отдельная глава посвящена видеосистеме компьютера (которая будет рассмотрена нами в следующем томе "Библиотеки системного программиста"). В этой части книги приведена информация об использовании клавиатуры, мыши и светового пера, более подробные сведения о файловой системе MS-DOS. Вводится понятие расширенной и дополнительной памяти. Для дополнительной памяти описываются несколько функций прерывания INT 67h, обслуживающего запросы к этой памяти.
Третья часть книги содержит информацию, полезную при составлении резидентных программ.
Книга содержит большое количество программ на языках ассемблера и Паскаль.
Superchargin Your PC
Lewis Perdue Brkley, California 94710 ISBN 0-07-881000-0
Книга посвящена модернизации аппаратного обеспечения персонального компьютера. Описано подключение разнообразных периферийных устройств, таких как дополнительные дисководы, модемы, и т.д. Описаны процедура подключения дополнительной оперативной памяти, принципы объединения компьютеров в сети. Приводятся сведения об использовании параллельного принтерного порта и последовательного порта RS-232S. Многочисленные рисунки и фотографии облегчают работу с книгой.
Микропроцессоры и микропроцессорные комплекты интегральных микросхем, том 2
Под ред. В.А. Шаханова, Москва, "Радио и связь", 1988 г. ББК 32.852 М59 УДК 681.325.5-181.4:621.3.049.771.14(03) ISBN 5-256-00373-9
В этом справочнике описано несколько микросхем серии К1810, в частности, контроллер прерываний КР1810ВН59А, совместимый с используемыми в персональных компьютерах IBM PC/XT/AT контроллерами 8259А.
Приведены форматы команд и внутренних регистров контроллера, описано функционирование контроллера в различных режимах.
Микропроцессорный комплект К1810
Под редакцией Ю.М. Казаринова. Москва, "Высшая школа", 1990 г. ББК 32.973 М59 УДК 681.34 ISBN 5-06-000821-5
В книге приведены справочные данные на микросхемы серии К1810. Наибольшую ценность для программиста представляет описание микросхем центрального процессора К1810ВМ86 (аналог Intel 8086), арифметического сопроцессора К1810ВМ87 (аналог Intel 8087), интервального таймера К1810ВИ54 (аналог таймера Intel 8254), контроллера прямого доступа к памяти К1810ВТ37 (аналог Intel 8237). Книгу можно рекомендовать системным программистам в качестве справочника по программированию перечисленных выше микросхем.
Архитектура микропроцессора 80286
С.П. Морс, Д.Д. Алберт Москва, "Радио и связь", 1990 г. ББК 32.97 М80 УДК 681.325.5-181.4
В книге подробно описаны архитектура и система команд процессора Intel 80286, арифметического сопроцессора Intel 80287. Рассматриваются реальный и защищенный режимы работы процессора и сопроцессора, большое внимание уделяется организации работы мультизадачного программного обеспечения.
Введение в схемотехнику ПЭВМ IBM PC/AT
Левкин Г.Н., Левкина В.Е. Москва, издательство МГПИ, 1991 г. УДК 781.3 Л71 ISBN 5-7043-0562-8
Описывается схемотехника первоначального варианта компьютера IBM AT. Книга содержит описание микросхем 80286 (центральный процессор), 82284 (тактовый генератор), 82288 (шинный контроллер). Описание ориентировано скорее на разработчиков аппаратных средств, чем на программистов, так как в книге ничего не сказано о программировании описанных микросхем.
Приведена принципиальная схема материнской платы компьютера IBM AT и часть листинга BIOS, имеющая отношение к самопроверке компьютера при включении питания и сбросе. Листинг снабжен подробными комментариями и позволяет проследить процесс инициализации отдельных подсистем компьютера.
Персональные ЭВМ IBM PC и XT
Л. Скэнлон Москва, "Радио и связь", 1991 ББК 32.973 С46 УДК 681.322-181.4 ISBN 5-256-00956-7
В книге рассмотрены вопросы программирования на языке ассемблера для персональных компьютеров IBM PC/XT. Приводятся сведения как по языку ассемблера, так и по аппаратному обеспечению персонального компьютера. Книга доступна для тех, кто только начинает использовать язык ассемблера. К сожалению, отсутствуют сведения по программированию широко распространенного компьютера IBM AT - следующей модели персональных компьютеров после IBM XT.
Альтернативная таблица кодировки
В настоящее время существует несколько вариантов кодировки русских букв (кириллицы) для операционной системы MS-DOS - основная, альтернативная, минская и т.д. Они отличаются, в основном, расположением русских букв и символов псевдографики. Однако наибольшее распространение получила альтернативная таблица кодировки, особенно после того, как в 1989 году эта таблица была принята IBM в качестве стандартной для Советского Союза. Локализованная версия MS-DOS 4.01 содержит соответствующую кодовую страницу:
Арифметические команды
FADD Сложение вещественных чисел
st(0) <- st(0) + st(1)
FADD src Сложение вещественных чисел
st(0) <- st(0) + src (mem32/mem64)
FADD st(i),st Сложение вещественных чисел
st(i) <- st(i) + st(1)
FADDP st(i),st Сложение вещественных чисел с извлечением из стека численных регистров
st(i) <- st(i) + st(1)
FIADD src Сложение целых чисел
st(0) <- st(0) + src (mem16/mem32)
FSUB Вычитание вещественных чисел
st(0) <- st(0) - st(1)
FSUB src Вычитание вещественных чисел
st(0) <- st(0) - src
FSUB st(i),st Вычитание вещественных чисел
st(i) <- st(i) - st(1)
FSUBP st(i),st Вычитание вещественных чисел с извлечением из стека численных регистров
st(i) <- st(i) - st(1)
FSUBR st(i),st Вычитание вещественных чисел обратное
st(0) <- st(i) - st(0)
FSUBRP st(i),st Вычитание вещественных чисел обратное с извлечением из стека численных регистров
st(0) <- st(i) - st(0)
FISUB src Вычитание целых чисел
st(0) <- st(0) - src (mem16/mem32)
FISUBR src Вычитание целых чисел обратное
st(0) <- src (mem16/mem32) - st(0)
FMUL Умножение вещественных чисел
st(0) <- st(0) * st(1)
FMUL st(i) Умножение вещественных чисел
st(0) <- st(0) * st(i)
FMUL st(i),st Умножение вещественных чисел
st(i) <- st(0) * st(i)
FMULP st(i),st Умножение вещественных чисел с извлечением из стека численных регистров
st(i) <- st(0) * st(i)
FIMUL src Умножение целых чисел
st(0) <- st(0) * src (mem16/mem32)
FDIV Деление вещественных чисел
st(0) <- st(0) / st(1)
FDIV st(i) Деление вещественных чисел
st(0) <- st(0) / st(i)
FDIV st(i),st Деление вещественных чисел
st(i) <- st(0) / st(i)
FDIVP st(i),st Деление вещественных чисел с извлечением из стека численных регистров
st(i) <- st(0) / st(i)
FIDIV src Деление целых чисел
st(0) <- st(0) / src (mem16/mem32)
FDIVR st(i),st Деление вещественных чисел обратное
st(0) <- st(i) / st(0)
FDIVRP st(i),st Деление вещественных чисел обратное с извлечением из стека численных регистров
st(0) <- st(i) / st(0)
FIDIVR src Деление целых чисел обратное
st(0) <- src (mem16/mem32) / st(0)
FSQRT Извлечение квадратного корня
st(0) <- v st(0)
FSCALE Масштабирование на степень числа 2
st(0) <- 2 | st(0)
FXTRACT Извлечение экспоненты
st(0) <- значение экспоненты st(0)
FPREM Вычисление частичного остатка
st(0) <- st(0) MOD st(1)
FPREM1 Вычисление частичного остатка в стандарте IEEE, только для 80486
st(0) <- st(0) MOD st(1)
FRNDINT Округление до ближайшего целого
st(0) <- INT(st(0))
FABS Вычисление абсолютного значения
st(0) <- ABS(st(0))
FCHS Изменение знака
st(0) <- -st(0)
Частоты нот для второй октавы
В этой таблице приведены частоты нот для второй октавы.
При повышении (понижении) тона на октаву частота соответствующей ноты умножается (делится) на 2.
Нота | Частота, Гц |
До | 261,7 |
До-диез | 277,2 |
Ре | 293,7 |
Ре-диез | 311,1 |
Ми | 329,6 |
Фа | 349,2 |
Фа-диез | 370,0 |
Соль | 392,0 |
Соль-диез | 415,3 |
Ля | 440,0 |
Ля-диез | 466,2 |
Си | 493,9 |
Форматы данных сопроцессора
Одинарная точность
1 бит 8 бит 23 бита ---T-------T--------------------¬ ¦Зн¦Порядок¦ Мантисса ¦ L--+-------+---------------------
Двойная точность 1 бит 11 бит 52 бита ---T---------T--------------------------------¬ ¦Зн¦ Порядок ¦ Мантисса ¦ L--+---------+---------------------------------
Расширенная точность 1 бит 15 бит 64 бита ---T-------------T------------------------------------¬ ¦Зн¦ Порядок ¦ Мантисса ¦ L--+-------------+-------------------------------------
В любом представлении старший бит "Зн" определяет знак вещественного числа: 0 - положительное число; 1 - отрицательное число. Возможные значения вещественных чисел: Положительный нуль --T---------T------------------¬ ¦0¦ 0...0 ¦ 0...0 ¦ L-+---------+-------------------
Отрицательный нуль --T---------T------------------¬ ¦1¦ 0...0 ¦ 0...0 ¦ L-+---------+-------------------
Наименьшее положительное число --T---------T------------------¬ ¦0¦ 0...01 ¦ 0...0 ¦ L-+---------+-------------------
Наибольшее отрицательное число --T---------T------------------¬ ¦1¦ 0...01 ¦ 0...0 ¦ L-+---------+-------------------
Наибольшее положительное число --T---------T------------------¬ ¦0¦ 11...10 ¦ 1...1 ¦ L-+---------+-------------------
Наименьшее отрицательное число --T---------T------------------¬ ¦1¦ 11...10 ¦ 1...1 ¦ L-+---------+-------------------
Положительная бесконечность --T---------T------------------¬ ¦0¦ 1...1 ¦ 0...0 ¦ L-+---------+-------------------
Отрицательная бесконечность --T---------T------------------¬ ¦1¦ 1...1 ¦ 0...0 ¦ L-+---------+-------------------
Нечисло --T---------T------------------¬ ¦1¦ 1...1 ¦ х...х ¦ L-+---------+-------------------
Неопределенность --T---------T------------------¬ ¦1¦ 1...1 ¦ 10...0 ¦ L-+---------+------------------- Возможные значения целых чисел: Нуль -------------------¬ ¦ 0...0 ¦ L-------------------
Наименьшее положительное число -------------------¬ ¦ 0...1 ¦ L-------------------
Наибольшее отрицательное число -------------------¬ ¦ 1...1 ¦ L-------------------
Наибольшее положительное число -------------------¬ ¦ 01...1 ¦ L-------------------
Наименьшее отрицательное число -------------------¬ ¦ 10...01 ¦ L------------------- Неопределенность -------------------¬ ¦ 10...00 ¦ L------------------- Упакованное десятичное число: ¦1-й байт ¦ Девять байтов ¦ +--T------+---T---T---T---T---+ ¦Зн¦000000¦n17¦n16¦...¦n1 ¦n0 ¦ L--+------+---+---+---+---+----
Графические команды
ESC K n1 n2 Выбор графического режима с одинарной плотностью
1Bh 4Bh n1 n2
Команда устанавливает графический 8-битовый режим одинарной плотности. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC L n1 n2 Выбор графического режима с двойной плотностью
1Bh 4Ch n1 n2
Команда устанавливает графический 8-битовый режим двойной плотности, печать будет выполняться с низкой скоростью. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC Y n1 n2 Выбор скоростного графического режима с двойной плотностью
1Bh 59h n1 n2
Команда устанавливает графический 8-битовый режим двойной плотности, печать будет выполняться с высокой скоростью. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC Z n1 n2 Выбор графического режима с учетверенной плотностью
1Bh 5Ah n1 n2
Команда устанавливает графический 8-битовый режим учетверенной плотности. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC * Печать в графическом режиме
1Bh 2Ah m n1 n2
Полный формат команды графической печати:
ESC "*" m n1 n2 data
В этой команде параметр m задает режим печати:
m Режим
0 Одинарная плотность, 60 точек на дюйм, 8-битовая графика
1 Двойная плотность, 120 точек на дюйм, 8-битовая графика
2 Двойная плотность, печать с высокой, скоростью, 120 точек на дюйм, 8-битовая графика
3 Учетверенная плотность, 240 точек на дюйм, 8-битовая графика
4 Режим CRT I, плотность 80 точек на дюйм, 8-битовая графика
6 Режим CRT II, плотность 90 точек на дюйм, 8-битовая графика
32 Одинарная плотность, 60 точек на дюйм, 24-битовая графика
33 Двойная плотность, 120 точек на дюйм, 24-битовая графика
38 Режим CRT III, плотность 90 точек на дюйм, 24-битовая графика
39 Тройная плотность, 180 точек на дюйм, 24-битовая графика
40 Шестикратное увеличение плотности, 360 точек на дюйм, 24-битовая графика ESC ? s n Переназначение графических режимов
1Bh 3Fh s n
Команда позволяет заменить один графический режим на другой. Параметр s - это символ (K, L, Y, Z), который назначается графическому режиму, заданному параметром n (0...6).
ESC K n1 n2 Выбор графического режима с одинарной плотностью
1Bh 4Bh n1 n2 Epson, IBM
Команда устанавливает графический 8-битовый режим одинарной плотности. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC L n1 n2 Выбор графического режима с двойной плотностью
1Bh 4Ch n1 n2 Epson, IBM
Команда устанавливает графический 8-битовый режим двойной плотности, печать будет выполняться с низкой скоростью. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC Y n1 n2 Выбор скоростного графического режима с двойной плотностью
1Bh 59h n1 n2 Epson, IBM
Команда устанавливает графический 8-битовый режим двойной плотности, печать будет выполняться с высокой скоростью. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC Z n1 n2 Выбор графического режима с учетверенной плотностью
1Bh 5Ah n1 n2 Epson, IBM
Команда устанавливает графический 8-битовый режим учетверенной плотности. Общее количество столбцов в графической строке при этом составит n1 + (n2 * 256). ESC * Печать в графическом режиме
1Bh 2Ah m n1 n2 Epson
Полный формат команды графической печати:
ESC "*" m n1 n2 data
В этой команде параметр m задает режим печати:
m Режим
0 Одинарная плотность, 60 точек на дюйм, 8-битовая графика
1 Двойная плотность, 120 точек на дюйм, 8-битовая графика
2 Двойная плотность, печать с высокой, скоростью, 120 точек на дюйм, 8-битовая графика
3 Учетверенная плотность, 240 точек на дюйм, 8-битовая графика
4 Режим CRT I, плотность 80 точек на дюйм, 8-битовая графика
5 Режим плоттера, плотность 72 точек на дюйм, масштаб 1:1, 8-битовая графика
6 Режим CRT II, плотность 90 точек на дюйм, 8-битовая графика
7 Режим плоттера, плотность 144 точек на дюйм, масштаб 1:1, 8-битовая графика ESC ? s n Переназначение графических режимов
1Bh 3Fh s n Epson
Команда позволяет заменить один графический режим на другой. Параметр s - это символ (K, L, Y, Z), который назначается графическому режиму, заданному параметром n (0...6). ESC ^ Выбор 9-битового графического режима
1Bh 5Eh m n1 n2 Epson
Команда позволяет использовать для графической печати все 9 иголок печатающей головки. Параметр m определяет плотность печати:
0 - одинарная плотность; 1 - двойная плотность.
Параметры n1 и n2 определяют общую длину графической строки (т.е. количество распечатываемых столбцов). Эта длина вычисляется по формуле: n1+(n2*256). В 9-битовом графическом режиме на каждый столбец требуются два байта графических данных.
H регистр состояния A
7 6 5 4 3 2 1 0 T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ LT+T+-+T+T+-+-+T- ¦ L=T=- L=====¦= переключатель скорости (установлен в 0110) ¦ L=========== 22-разрядный делитель (установлен в 010) L=============== Флаг обновления, 0 означает готовность данных для чтения.
H регистр состояния B
7 6 5 4 3 2 1 0 T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ LT+T+T+T+T+T+T+T- ¦ ¦ ¦ ¦ ¦ ¦ ¦ L= 1 - использование летнего времени ¦ ¦ ¦ ¦ ¦ ¦ ¦ (daylight savings enable); ¦ ¦ ¦ ¦ ¦ ¦ ¦ 0 - стандартное время (установлен в 0) ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L=== 12 или 24-часовой режим. 0 - 12-часовой ¦ ¦ ¦ ¦ ¦ ¦ режим (установлен в 1) ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L===== режим данных BCD. 1 - двоичный, 0 - BCD. ¦ ¦ ¦ ¦ ¦ (установлен в 0) ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L======= разрешение прямоугольной волны. ¦ ¦ ¦ ¦ 1 - включение прямоугольной волны. ¦ ¦ ¦ ¦ (установлен в 0) ¦ ¦ ¦ ¦ ¦ ¦ ¦ L========= разрешение прерывания по окончанию ¦ ¦ ¦ изменения данных (установлен в 0) ¦ ¦ ¦ ¦ ¦ L=========== разрешение прерывания будильника ¦ ¦ (установлен в 0) ¦ ¦ ¦ L============= разрешение периодических прерываний ¦ (установлен в 0) ¦ L=============== Флаг обновления, 0 означает готовность данных для чтения КМОП-памяти.
0cH регистр состояния C. Биты состояния прерывания, их можно только читать.
0dH регистр состояния D. Если бит 7 равен 0, это означает, что разрядился аккумулятор, питающий КМОП-память.
Обработка слов
ESC a n Выравнивание для качественного (LQ) набора символов
1Bh 61h n
Параметр n может принимать следующие значения:
0 - выравнивание влево; 1 - выравнивание по центру; 2 - выравнивание вправо; 3 - полное выравнивание. По умолчанию при инициализации принтера выбирается режим выравнивания влево. Полное выравнивание выполняется после заполнения буфера печати. При этом распечатываемый текст может содержать символы горизонтальной табуляции HT и возврата на одну позицию BS только тогда, когда задан режим выравнивания влево (n=0). Если используется полное выравнивание, параграфы текста не должны содержать символы возврата каретки. ESC SP n Выбор расстояния между символами
1Bh 20h n
Команда позволяет увеличить расстояние между символами по сравнению с тем, которое было задано в сетке при разработке начертания символов. Параметр n, значение которого должно лежать в пределах 0...127, задает количество точек, добавляемых справа к каждому символу. Одна точка соответствует 1/120 дюйма в черновом режиме и 1/180 дюйма в качественном и пропорциональном режимах.
ESC a n Выравнивание для качественного (LQ) набора символов
1Bh 61h n Epson
Параметр n может принимать следующие значения:
0 - выравнивание влево; 1 - выравнивание по центру; 2 - выравнивание вправо; 3 - полное выравнивание. По умолчанию при инициализации принтера выбирается режим выравнивания влево. Полное выравнивание выполняется после заполнения буфера печати. При этом распечатываемый текст может содержать символы горизонтальной табуляции HT и возврата на одну позицию BS только тогда, когда задан режим выравнивания влево (n=0). Если используется полное выравнивание, параграфы текста не должны содержать символы возврата каретки. ESC SP n Выбор расстояния между символами
1Bh 20h n Epson
Команда позволяет увеличить расстояние между символами по сравнению с тем, которое было задано в сетке при разработке начертания символов. Параметр n, значение которого должно лежать в пределах 0...127, задает количество точек, добавляемых справа к каждому символу. Одна точка соответствует 1/120 дюйма.
Порт 37Ah.
Порт управления принтером, доступен для чтения и записи:
7 6 5 4 3 2 1 0 T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ ¦ ¦ ¦ LT+-+T+T+T+T+T+T- L=T=- ¦ ¦ ¦ ¦ L= строб данных, принимает значение 1 при ¦ ¦ ¦ ¦ ¦ выводе байта, подключен к 1 контакту ¦ ¦ ¦ ¦ ¦ разъема, STROBE; ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L=== автоматический перевод строки после ¦ ¦ ¦ ¦ символа "возврат каретки" CR, контакт 14, ¦ ¦ ¦ ¦ AUTO LineFeed; ¦ ¦ ¦ ¦ ¦ ¦ ¦ L===== сброс принтера, активный уровень - 0, ¦ ¦ ¦ контакт 16, INIT; ¦ ¦ ¦ ¦ ¦ L======= выбор принтера для работы, контакт 17, ¦ ¦ SLCT IN; ¦ ¦ ¦ L========= разрешение прерывания от принтера, ¦ IRQ Enable; ¦ L============= равно 0.
Если прерывания от принтера разрешены, они вырабатываются, когда сигнал готовности принтера ACK (контакт разъема10) принимает уровень логического 0.
Порт 378h.
Этот порт предназначен для записи выводимого на принтер байта данных. Возможно также чтение только что записанного байта.
Порт 379h
Порт состояния принтера, доступен только для чтения:
7 6 5 4 3 2 1 0 T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ ¦ ¦ ¦ LT+T+T+T+T+T+-+T- ¦ ¦ ¦ ¦ ¦ L===¦= установлены в 0; ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L======= сигнал ошибки, активный уровень - 0, ¦ ¦ ¦ ¦ контакт разъема - 15, ERROR; ¦ ¦ ¦ ¦ ¦ ¦ ¦ L========= принтер выбран, контакт 13, SLCT; ¦ ¦ ¦ ¦ ¦ L=========== конец бумаги, контакт 12, PE; ¦ ¦ ¦ L============= готовность принтера, активный уровень - 0, ¦ контакт разъема - 10, ACK; ¦ L=============== 0 - принтер занят, находится в состоянии offline или произошла ошибка, контакт 11, BUSY.
ПРИЛОЖЕНИЕ
14.1.
14.2.
14.3.
14.4.
14.5.
14.6.
14.7.
14.8.
14.9.
14.10.
14.11.
14.12.
14.13.
Разводка разъема последовательного порта
Приведем разводку разъема порта последовательной передачи данных DB25P:
Номер контакта Назначение контакта Вход или выход
1 Защитное заземление -
2 Передаваемые данные Выход (Transmitted Data)
3 Принимаемые данные Вход (Received Data)
4 Запрос для передачи Выход (Request to send, RTS)
5 Сброс для передачи Вход (Clear to Send, CTS)
6 Готовность данных Вход (Data Set Ready, DSR)
7 Сигнальное заземление -
8 Детектор принимаемого Вход с линии сигнала (Data Carrier Detect, DCD)
9-19 Не используется
20 Готовность выходных Выход данных (Data Terminal Ready, DTR)
21 Не используется
22 Индикатор вызова Вход (Ring Indicator, RI)
23-25 Не используется
Приведем также разводку разъема порта последовательной передачи данных DB9P:
Номер Назначение Вход или выход контакта контакта
1 Детектор принимаемого Вход с линии сигнала (Data Carrier Detect, DCD)
2 Принимаемые данные Вход (Received Data)
3 Передаваемые данные Выход (Transmitted Data)
4 Готовность выходных Выход данных (Data Terminal Ready, DTR)
5 Сигнальное заземление -
6 Готовность данных Вход (Data Set Ready, DSR)
7 Запрос для передачи Выход (Request to send, RTS)
8 Сброс для передачи Вход (Clear to Send, CTS)
9 Индикатор вызова Вход (Ring Indicator, RI)
Разводка разъемов принтерного порта
Таблица назначения контактов разъемов принтерного порта (контакт PC) на компьютере и контактов разъема непосредственно на принтере (контакт принтера):
Контакт Контакт Назначение Вход/выход PC принтера
1 1 Строб (STROBE) Выход, инверсия
2 2 Данные, бит 0 Выход
3 3 Данные, бит 1 Выход
4 4 Данные, бит 2 Выход
5 5 Данные, бит 3 Выход
6 6 Данные, бит 4 Выход
7 7 Данные, бит 5 Выход
8 8 Данные, бит 6 Выход
9 9 Данные, бит 7 Выход
10 10 Подтверждение, ACK Вход, инверсия
11 11 Занятость, BUSY Вход
12 12 Конец бумаги, PE Вход
13 13 Выбор, SLCT Вход
14 14 Авт. перевод Выход, инверсия строки, Auto Line Feed
15 32 Ошибка, ERROR Вход, инверсия
16 31 Сброс принтера, Выход, инверсия INIT
17 36 Принтер выбран, Выход, инверсия SLCT IN
18-25 16,17, Земля - 19-30,33
Регистры часов реального времени
Регистр | Назначение |
0 | счетчик секунд |
1 | регистр секунд будильника | ||
2 | счетчик минут | ||
3 | регистр минут будильника | ||
4 | счетчик часов | ||
5 | регистр часов будильника | ||
6 | счетчик дней недели (1 - воскресенье) | ||
7 | счетчик дней месяца | ||
8 | счетчик месяцев | ||
9 | счетчик лет (последние две цифры текущего года) |
Содержимое файла sysp.h
/* SYSP.H - include-файл для примеров, приведенных в книге */
/** *.Name FP_MAKE * *.Title Макро для составления FAR-указателя * *.Descr Макро составляет FAR-указатель, пользуясь * значениями сегмента и смещения * *.Params FP_MAKE(seg,off) * seg - сегмент; * off - смещение * *.Return FAR-указатель seg:off **/
#define FP_MAKE(seg,off) ((void far *) \ ((((unsigned long) (unsigned)(seg)) << 16L) | \ ((unsigned long) (unsigned) (off))))
/* Структура векторной таблицы связи DOS */
#pragma pack(1)
typedef struct _CVT_ { unsigned mcb_seg; void far *dev_cb; void far *file_tab; void far *clock_dr; void far *con_dr; unsigned max_btbl; void far *disk_buf; void far *drv_info; void far *fcb_tabl; unsigned fcb_size; unsigned char num_bdev; unsigned char lastdriv; } CVT;
/* Блок управления памятью MCB */
typedef struct _MCB_ { unsigned char type; unsigned owner; unsigned size; char reserve[11]; } MCB;
/* Префикс программного сегмента PSP */
typedef struct _PSP_ { unsigned char int20h[2]; unsigned mem_top; unsigned char reserv1; unsigned char call_dsp[5]; void far *term_adr; void far *cbrk_adr; void far *crit_err; unsigned parn_psp; unsigned char file_tab[20]; unsigned env_seg; void far *ss_sp; unsigned max_open; void far *file_tba; unsigned char reserv2[24]; unsigned char disp[3]; unsigned char reserv3[9]; unsigned char fcb1[16]; unsigned char fcb2[20]; unsigned char p_size; unsigned char parm[127]; } PSP;
/* Блок управления устройством DOS */
typedef struct _DDCB_ { unsigned char drv_num; unsigned char drv_numd; unsigned sec_size; unsigned char clu_size; unsigned char clu_base; unsigned boot_siz; unsigned char fat_num; unsigned max_dir; unsigned data_sec; unsigned hi_clust; unsigned char fat_size; char reserv1; unsigned root_sec; void far *drv_addr; unsigned char media; unsigned char acc_flag; struct _DDCB_ far *next; unsigned reserv2; unsigned built; } DDCB;
/* Управляющий блок DOS для файлов */
typedef struct _DFCB_ { unsigned handl_num; unsigned char access_mode; unsigned reserv1; unsigned dev_info; void far *driver; unsigned first_clu; unsigned time; unsigned date; unsigned long fl_size; unsigned long offset; unsigned reserv2; unsigned reserv7; unsigned reserv3; char reserv4; char filename[11]; char reserv5[6]; unsigned ownr_psp; unsigned reserv6; unsigned last_clu; char reserv8[4]; } DFCB;
/* Таблица файлов DOS */
typedef struct _DFT_ { struct _DFT_ far *next; unsigned file_count; DFCB dfcb; } DFT;
/* Управляющий блок дискового буфера BCB */
typedef struct _BCB_ { struct _BCB_ far *next; unsigned char drive; unsigned char flag; unsigned sect_num; unsigned reserv1; DDCB far *ddcb; unsigned reserv2; } BCB;
/* Информация о диске */
typedef struct _DINFO_ { char path[64]; unsigned reserv1; unsigned reserv2; unsigned char reserv3; DDCB far *ddcb; unsigned cdir_clu; unsigned reserv4; unsigned reserv5; unsigned reserv6; unsigned char reserv7[7]; } DINFO;
/* Заголовок EXE-программы */
typedef struct _EXE_HDR_ { unsigned signature; unsigned part_pag; unsigned file_size; unsigned rel_item; unsigned hdr_size; unsigned min_mem; unsigned max_mem; unsigned ss_reg; unsigned sp_reg; unsigned chk_summ; unsigned ip_reg; unsigned cs_reg; unsigned relt_off; unsigned overlay; } EXE_HDR;
/* таблица расположения сегментов EXE-программы */
typedef struct _RELOC_TAB_ { unsigned offset; unsigned segment; } RELOC_TAB;
/* конфигурация дисковой подсистемы */
typedef struct _DISK_CONFIG_ { int n_floppy; int n_hard; int t_floppy1; int t_floppy2; int t_hard1; int t_hard2; } DISK_CONFIG;
/* таблица параметров дискеты */
typedef struct _DPT_ { unsigned char srt_hut; unsigned char dma_hlt; unsigned char motor_w; unsigned char sec_size; unsigned char eot; unsigned char gap_rw; unsigned char dtl; unsigned char gap_f; unsigned char fill_char; unsigned char hst; unsigned char mot_start; } DPT;
/* таблица параметров диска */
typedef struct _HDPT_ { unsigned max_cyl; unsigned char max_head; unsigned srwcc; unsigned swpc; unsigned char max_ecc; unsigned char dstopt; unsigned char st_del; unsigned char fm_del; unsigned char chk_del; unsigned char reserve[4]; } HDPT;
/* Элемент таблицы разделов */
typedef struct _PART_ENTRY_ { unsigned char flag; unsigned char beg_head; unsigned beg_sec_cyl; unsigned char sys; unsigned char end_head; unsigned end_sec_cyl; unsigned long rel_sec; unsigned long size; } PART_ENTRY;
/* Главная загрузочная запись */
typedef struct _MBOOT_ { char boot_prg[0x1be]; PART_ENTRY part_table[4]; unsigned char signature[2]; } MBOOT;
/* Расширенный блок параметров BIOS */
typedef struct _EBPB_ { unsigned sectsize; char clustsize; unsigned ressecs; char fatcnt; unsigned rootsize; unsigned totsecs; char media; unsigned fatsize; unsigned seccnt; unsigned headcnt; unsigned hiddensec_low; unsigned hiddensec_hi; unsigned long drvsecs; } EBPB;
/* Загрузочная запись для MS-DOS 4.01 */
typedef struct _BOOT_ { char jmp[3]; char oem[8]; EBPB bpb; char drive; char reserved; char signature; unsigned volser_lo; unsigned volser_hi; char label[11]; char fat_format[8]; char boot_code[450];
} BOOT;
/* Время последнего обновления файла */
typedef struct _FTIME_ { unsigned sec : 5, min : 6, hour : 5; } FTIME;
/* Дата последнего обновления файла */
typedef struct _FDATE_ { unsigned day : 5, month : 4, year : 7; } FDATE;
/* Дескриптор файла в каталоге */
typedef struct _FITEM_ { char name[8]; char ext[3]; char attr; char reserved[10]; FTIME time; FDATE date; unsigned cluster_nu; unsigned long size; } FITEM;
/* Формат трека для GENERIC IOCTL */
typedef struct _TRK_LY_ { unsigned no; unsigned size; } TRK_LY;
/* Параметры устройства для GENERIC IOCTL */
typedef struct _DPB_ {
char spec; char devtype; unsigned devattr; unsigned numofcyl; char media_type;
EBPB bpb; char reserved[6];
unsigned trkcnt; TRK_LY trk[100];
} DPB;
/* Параметры для форматирования функцией GENERIC IOCTL */
typedef struct _DPB_FORMAT_ {
char spec; unsigned head; unsigned track;
} DPB_FORMAT;
/* Параметры для чтения/записи функцией GENERIC IOCTL */
typedef struct _DPB_WR_ {
char spec; unsigned head; unsigned track; unsigned sector; unsigned sectcnt; void _far *buffer;
} DPB_WR;
/* Идентификатор BIOS */
typedef struct _BIOS_ID_ {
char date[8]; unsigned reserve; char pc_type;
} BIOS_ID;
// Состояние мыши
typedef struct _MOUSE_STATE_ {
unsigned bottoms; unsigned x; unsigned y;
} MOUSE_STATE;
typedef struct _SYSTIMER_ {
char hour; char min; char sec; unsigned year; char month; char day; char daylight_savings;
} SYSTIMER;
#pragma pack()
void far *get_cvt(void); /* получить адрес векторной таблицы связи */ CVT far *get_mcvt(void); /* получить адрес векторной таблицы связи */
MCB far *get_fmcb(CVT far *); /* получить адрес первого MCB */ MCB far *get_nmcb(MCB far *); /* получить адрес следующего MCB */
DDCB far *get_fddcb(CVT far *); /* получить адрес первого DDCB */ DDCB far *get_nddcb(DDCB far *); /* получить адрес следующего DDCB */ DDCB far *get_ddcb(unsigned char); /* получить адрес DDCB для диска */
DFT far *get_fdft(CVT far *); /* получить адрес первой DFT */ DFT far *get_ndft(DFT far *); /* получить адрес следующей DFT */
BCB far *get_fbcb(CVT far *); /* получить адрес первого BCB */ BCB far *get_nbcb(BCB far *); /* получить адрес следующего BCB */
int get_exeh(EXE_HDR *,RELOC_TAB **, FILE *); /* прочитать заголовок EXE */
char unsigned pc_model(void); /* получить модель компьютера */ void disk_cfg(DISK_CONFIG*); /* определить конфигурацию дисковой подсистемы */ DPT _far *get_dpt(void); /* получить адрес DPT */ HDPT _far *get_hdp1(void); /* получить адрес первой HDPT */ HDPT _far *get_hdp2(void); /* получить адрес второй HDPT */
BIOS_ID _far *getbiosi(void); /* получить адрес идентификатора BIOS */
int ms_init(int *); // Инициализация мыши void ms_on(void); // Включение курсора void ms_off(void); // Выключение курсора void ms_setcr(int, int); // Установка курсора int ms_querp(MOUSE_STATE *, int); // Определение состояния мыши // при нажатии на клавишу void ms_rangx(int xmin, int xmax); // Задать диапазон // перемещений курсора // по горизонтали void ms_rangy(int ymin, int ymax); // Задать диапазон //перемещений курсора // по вертикали void ms_gform(int xt, int yt, char _far *form); // определение //формы курсора // в графическом режиме void ms_tform(int type, int mask1, int mask2); // определение // формы курсора // в текстовом режиме MOUSE_STATE *ms_querm(MOUSE_STATE *state); // определение // относительного // перемещения в миках void ms_seth(int mask, void (far *hand)()); // установка // драйвера событий
// Системные часы реального времени
#define RTC_GET_TIME 2 #define RTC_SET_TIME 3 #define RTC_GET_DATE 4 #define RTC_SET_DATE 5 #define RTC_SET_ALARM 6 #define RTC_CLEAR_ALARM 7
int timer(char, SYSTIMER *); // работа с часами // реального времени void tm_delay(int); // формирование задержки по таймеру void tm_sound(int, int); // формирование тона заданнной // длительности с использованием // таймера
void rnd_set(int); // инициализация генератора // случайных чисел int rnd_get(void); // получение случайного числа
typedef struct _AUX_MODE_ {
union {
struct { unsigned char len : 2, // длина символа stop : 1, // число стоп-битов parity : 2, // контроль четности stuck_parity : 1, // фиксация четности en_break_ctl : 1, // установка перерыва dlab : 1; // загрузка регистра делителя } ctl_word;
char ctl;
} ctl_aux;
unsigned long baud; // скорость передачи данных
} AUX_MODE;
int aux_init(AUX_MODE *, int, int); // инициализация // асинхронного адаптера
void aux_stat(AUX_MODE *, int); // определение режима // асинхронного адаптера void aux_outp(char, int); // вывод символа в // асинхронный адаптер char aux_inp(int); // ввод символа из асинхронного // адаптера
// Прототипы функций для работы с расширенной // памятью.
unsigned XMM_Installed();
long XMM_Version(void); long XMM_RequestHMA(unsigned); long XMM_ReleaseHMA(void); long XMM_GlobalEnableA20(void); long XMM_GlobalDisableA20(void); long XMM_EnableA20(void); long XMM_DisableA20(void); long XMM_QueryA20(void); long XMM_QueryLargestFree(void); long XMM_QueryTotalFree(void); long XMM_AllocateExtended(unsigned); long XMM_FreeExtended(unsigned); long XMM_MoveExtended(struct XMM_Move *); long XMM_LockExtended(unsigned); long XMM_UnLockExtended(unsigned); long XMM_GetHandleLength(unsigned); long XMM_GetHandleInfo(unsigned); long XMM_ReallocateExtended(unsigned,unsigned); long XMM_RequestUMB(unsigned); long XMM_ReleaseUMB(unsigned);
struct XMM_Move { unsigned long Length; unsigned short SourceHandle; unsigned long SourceOffset; unsigned short DestHandle; unsigned long DestOffset; };
// Прототипы функций для работы с дополнительной // памятью.
int ems_init(void); int ems_stat(void); int ems_fram(unsigned *); int ems_page(unsigned *, unsigned *); int ems_open(int, int *); int ems_clos(int *); int ems_map(int, int, int); int ems_ver(char *);
Содержимое файла sysp.inc
; ; Это макроопределение печатает символы на экране ; @@out_ch MACRO c1,c2,c3,c4,c5,c6,c7,c8,c9,c10 mov ah,02h IRP chr,<c1,c2,c3,c4,c5,c6,c7,c8,c9,c10> IFB <chr> EXITM ENDIF mov dl,chr int 21h ENDM ENDM
@@out_str MACRO mov ah,9 int 21h ENDM
; Макро для выдачи звукового сигнала
BEEP MACRO mov bx,0 mov ax, 0E07h int 10h ENDM
State87 struc cr dw ? sr dw ? tg dw ? cmdlo dw ? cmdhi dw ? oprlo dw ? oprhi dw ? st0 dt ? st1 dt ? st2 dt ? st3 dt ? st4 dt ? st5 dt ? st6 dt ? st7 dt ? State87 ends
Сравнение
FCOM Сравнение вещественных чисел
Установка флагов по результатам операции st(0) - st(1)
FCOM op Сравнение вещественных чисел
Установка флагов по результатам операции st(0) - op (mem32/mem64)
FCOMP op Сравнение вещественных чисел с извлечением из стека
Установка флагов по результатам операции st(0) - op (mem32/mem64)
FCOMPP Сравнение вещественных чисел с двойным извлечением из стека численных регистров
Установка флагов по результатам операции st(0) - st(1)
FICOM op Сравнение целых чисел
Установка флагов по результатам операции st(0) - op (mem16/mem32)
FICOMP op Сравнение целых чисел с извлечением из стека численных регистров
Установка флагов по результатам операции st(0) - op (mem16/mem32)
FTST Сравнение с нулем
Сравнивается st(0) и 0.0
FUCOM st(i) Неупорядоченное сравнение (только 80486)
Содержимое st(0) сравнивается с st(i)
FUCOMP st(i) Неупорядоченное сравнение (только 80486) с извлечением из стека численных регистров
Содержимое st(0) сравнивается с st(i)
FUCOMPP st(i) Неупорядоченное сравнение (только 80486) с двойным извлечением из стека численных регистров
Содержимое st(0) сравнивается с st(i)
FXAM Проверка верхушки стека
По состоянию st(0) устанавливаются коды условий
Таблица расширенного ASCII-кода:
г--------T--------------T--------------T-------------¬ ¦ F1 3b¦ Shift-F1 54¦ Ctrl-F1 5e ¦ Alt-F1 68 ¦ ¦ F2 3c¦ Shift-F2 55¦ Ctrl-F2 5f ¦ Alt-F2 69 ¦ ¦ F3 3d¦ Shift-F3 56¦ Ctrl-F3 60 ¦ Alt-F3 6a ¦ ¦ F4 3e¦ Shift-F4 57¦ Ctrl-F4 61 ¦ Alt-F4 6b ¦ ¦ F5 3f¦ Shift-F5 58¦ Ctrl-F5 62 ¦ Alt-F5 6c ¦ ¦ F6 40¦ Shift-F6 59¦ Ctrl-F6 63 ¦ Alt-F6 6d ¦ ¦ F7 41¦ Shift-F7 5a¦ Ctrl-F7 64 ¦ Alt-F7 6e ¦ ¦ F8 42¦ Shift-F8 5b¦ Ctrl-F8 65 ¦ Alt-F8 6f ¦ ¦ F9 43¦ Shift-F9 5c¦ Ctrl-F9 66 ¦ Alt-F9 70 ¦ ¦ F10 44¦ Shift-F10 5d¦ Ctrl-F10 67 ¦ Alt-F10 71 ¦ L--------¦--------------¦--------------¦-------------- г----------T----------T-------------T-------------¬ ¦ Alt-A 1e¦ Alt-P 19¦ Alt-3 7a¦ Down Dn 50¦ ¦ Alt-B 30¦ Alt-Q 10¦ Alt-4 7b¦ Left <- 4b¦ ¦ Alt-C 2e¦ Alt-R 13¦ Alt-5 7c¦ Right -> 4d¦ ¦ Alt-D 20¦ Alt-S 1f¦ Alt-6 7d¦ Up Up 48¦ ¦ Alt-E 12¦ Alt-T 14¦ Alt-7 7e¦ End 4f¦ ¦ Alt-F 21¦ Alt-U 16¦ Alt-8 7f¦ Home 47¦ ¦ Alt-G 22¦ Alt-V 2f¦ Alt-9 80¦ PgDn 51¦ ¦ Alt-H 23¦ Alt-W 11¦ Alt-- 82¦ PgUp 49¦ ¦ Alt-I 17¦ Alt-X 2d¦ Alt-= 83¦ ¦ ¦ Alt-J 24¦ Alt-Y 15¦ ¦ ^Left 73¦ ¦ Alt-K 25¦ Alt-Z 2c¦ NUL 03¦ ^Right 74¦ ¦ Alt-L 26¦ ¦ Shift-Tab 0f¦ ^End 75¦ ¦ Alt-M 32¦ Alt-0 81¦ Ins 52¦ ^Home 77¦ ¦ Alt-N 31¦ Alt-1 78¦ Del 53¦ ^PgDn 76¦ ¦ Alt-O 18¦ Alt-2 79¦ ^PrtSc 72¦ ^PgUp 84¦ L----------¦----------¦-------------¦--------------
Таблица скан-кодов клавиш, имеющихся только на 101-клавишной клавиатуре:
г-------------T------------------T------------------¬ ¦ F11 85¦ Alt-Bksp 0e ¦ Alt- Д / a4¦ ¦ F12 86¦ Alt-Enter 1c ¦ Alt- Д * 37¦ ¦ Shft-F11 87¦ Alt-Esc 01 ¦ Alt- Д - 4a¦ ¦ Shft-F12 88¦ Alt-Tab a5 ¦ Alt- Д + 4e¦ ¦ Ctrl-F11 89¦ Ctrl-Tab 94 ¦ Alt- Д Enter a6¦ ¦ Ctrl-F12 8a¦ ¦ ¦ ¦ Alt-F11 8b¦ Alt-up Up 98 ¦ Ctrl- Д / 95¦ ¦ Alt-F12 8c¦ Alt-down Dn a0 ¦ Ctrl- Д * 96¦ ¦ Alt-[ 1a¦ Alt-left <- 9b ¦ Ctrl- Д - 8e¦ ¦ Alt-] 1b¦ Alt-right -> 9d ¦ Ctrl- Д + 90¦ ¦ Alt-; 27¦ ¦ ¦ ¦ Alt-' 28¦ Alt-Delete a3 ¦ Ctrl- Д Up [8] 8d¦ ¦ Alt-` 29¦ Alt-End 9f ¦ Ctrl- Д 5 [5] 8f¦ ¦ Alt-\ 2b¦ Alt-Home 97 ¦ Ctrl- Д Dn [2] 91¦ ¦ Alt-, 33¦ Alt-Insert a2 ¦ Ctrl- Д Ins[0] 92¦ ¦ Alt-. 34¦ Alt-PageUp 99 ¦ Ctrl- Д Del[.] 93¦ L-------------¦------------------¦-------------------
Таблица скан-кодов для клавиатуры IBM PC/XT:
----------T----------T------------T-------------T---------------¬ ¦01 Esc ¦12 E ¦23 H ¦34 . > ¦45 NumLock ¦ ¦02 1 ! ¦13 R ¦24 J ¦35 / ? ¦46 ScrollLock¦ ¦03 2 @ ¦14 T ¦25 K ¦36 Shft(прав)¦47 Home [7] ¦ ¦04 3 # ¦15 Y ¦26 L ¦37 * PrtSc ¦48 Up [8] ¦ ¦05 4 $ ¦16 U ¦27 ; : ¦38 Alt ¦49 PgUp [9] ¦ ¦06 5 % ¦17 I ¦28 " ' ¦39 Пробел ¦4a K - ¦ ¦07 6 ^ ¦18 O ¦29 ` ~ ¦3a CapsLock¦4b <- [4] ¦ ¦08 7 & ¦19 P ¦2a Shft(лев)¦3b F1 ¦4c [5] ¦ ¦09 8 * ¦1a [ { ¦2b \ | ¦3c F2 ¦4d -> [6] ¦ ¦0a 9 ( ¦1b ] } ¦2c Z ¦3d F3 ¦4e K + ¦ ¦0b 0 ) ¦1c Enter¦2d X ¦3e F4 ¦4f End [1] ¦ ¦0c - _ ¦1d Ctrl ¦2e C ¦3f F5 ¦50 Dn [2] ¦ ¦0d + = ¦1e A ¦2f V ¦40 F6 ¦51 PgDn [3] ¦ ¦0e Bksp¦1f S ¦30 B ¦41 F7 ¦52 Ins [0] ¦ ¦0f Tab ¦20 D ¦31 N ¦42 F8 ¦53 Del [.] ¦ ¦10 Q ¦21 F ¦32 M ¦43 F9 ¦ ¦ ¦11 W ¦22 G ¦33 , < ¦44 F10 ¦ ¦ L---------¦----------¦------------¦-------------¦----------------
Таблицы символов
ESC t n Выбор таблицы символов
1Bh 74h n
Данная команда выбирает одну из таблиц, описывающих начертание символов для символов с кодами от 128 до 255, т.е. для правой половины кодовой таблицы ASCII. Можно выбрать таблицу, содержащую символы курсива (только латинские буквы), расширенную графическую таблицу фирмы Epson или таблицу, определенную пользователем:
0 - таблица с символами курсива (Italics character table); 1 - расширенная графическая таблица Epson; 2 - таблица, определенная пользователем.
После загрузки в принтер русских (или других пользовательских) шрифтов необходимо задать режим n=2. ESC 4 Использование курсива
1Bh 34h
После получения этой команды принтер печатает весь текст курсивом для любой таблицы символов, за исключением символов псевдографики расширенной таблицы Epson. ESC 5 Отмена использования курсива
1Bh 35h
Команда отменяет печать курсивом. ESC R n Выбор национального набора символов
1Bh 52h n
В зависимости от параметра n выбирается национальный набор символов:
0 - США; 7 - Испания, набор 1; 1 - Франция; 8 - Япония; 2 - Германия; 9 - Норвегия; 3 - Англия; 10 - Дания, набор 2; 4 - Дания, набор 1; 11 - Испания, набор 2; 5 - Швеция; 12 - Латинская Америка. 6 - Италия; ESC & Определение символов
1Bh 26h 00h n1 n2 d0 d1 d2 data
Полный формат команды для переопределения символов в принтере Epson LQ-2550:
ESC "&" "0" n1 n2 d0 d1 d2 data
Параметры n1 и n2 задают диапазон кодов ASCII символов, начертание которых необходимо переопределить. Их назначение такое же, как и для 9-игольчатых принтеров Epson. Если вы переопределяете только один символ, эти два параметра должны быть одинаковыми. Далее следуют три байта данных, которые задают ширину символа и размер свободного пространства вокруг символа. Параметр d0 задает количество свободных столбцов слева от символа, параметр d2 определяет количество свободных столбцов справа от символа. Параметр d1 определяет ширину символа в столбцах сетки.Изменяя ширину символа и размер свободного пространства вокруг него можно формировать пропорциональные наборы символов. В следующей таблице приведены максимальные значения для параметров d0, d1, d2 для различных наборов символов:
Набор d1 d0+d1+d2
Черновой 9 12
Качественный, 29 36 10 символов на дюйм
Качественный, 23 30 12 символов на дюйм
Пропорциональный 37 42
После параметра d2 следует последовательность байтов, описывающих символ, т.е. образец для символа. Для задания одного столбца сетки требуется три байта, поэтому для определения одного символа вы должны задать (d1 * 3) байтов данных. ESC : 0 n 0 Копирование символов из ПЗУ в ОЗУ
1Bh 3Ah 00h n 00h
Команда выполняет копирование заданного параметром n набора символов из постоянного запоминающего устройства принтера в его оперативную память. После этого можно переопределить начертание части символов командой "ESC&". Возможные значения для параметра n:
0 - Roman; 1 - Sans Serif; 2 - Courier; 3 - Prestige; 4 - Script; 5 - OCR-B; 6 - OCR-A. ESC % n Выбор набора символов, заданного пользователем
1Bh 25h n
Команда позволяет переключать используемый набор символов. В зависимости от значения параметра n будет использоваться либо стандартный набор символов принтера, либо наор символов, определенный пользователем при помощи команды "ESC &". Возможные значения параметра n:
0 - используется стандартный набор символов; 1 - используется набор символов, определенный пользователем. ESC 6 Разрешение печати символов с кодами 128...159
1Bh 36h
После приема этой команды при использовании расширенной графической таблицы Epson символы с кодами от 128 до 159 будут интерпретироваться принтером как символы, а не как управляющие коды. ESC 7 Запрещение печати символов с кодами 128...159
1Bh 37h
После приема этой команды при использовании расширенной графической таблицы Epson символы с кодами от 128 до 159 будут интерпретироваться принтером как управляющие коды. Этот режим устанавливается по умолчанию при инициализации принтера.
Для включения переопределенных символов в работу необходимо выдать принтеру команду ESC I. ESC : 0 n 0 Копирование символов из ПЗУ в ОЗУ
1Bh 3Ah 00h n 00h Epson
Команда выполняет копирование заданного параметром n набора символов из постоянного запоминающего устройства принтера в его оперативную память. После этого можно переопределить начертание части символов командой "ESC &". Возможные значения для параметра n:
0 - Roman; 1 - Sans Serif. ESC % n Выбор набора символов, заданного пользователем
1Bh 25h n Epson
Команда позволяет переключать используемый набор символов. В зависимости от значения параметра n будет использоваться либо стандартный набор символов принтера, либо наор символов, определенный пользователем при помощи команды "ESC &". Возможные значения параметра n:
0 - используется стандартный набор символов; 1 - используется набор символов, определенный пользователем. ESC 6 Разрешение печати символов с кодами 128...159
1Bh 36h Epson, IBM
После приема этой команды при использовании расширенной графической таблицы Epson символы с кодами от 128 до 159 будут интерпретироваться принтером как символы, а не как управляющие коды. ESC 7 Запрещение печати символов с кодами 128...159
1Bh 37h Epson, IBM
После приема этой команды при использовании расширенной графической таблицы Epson символы с кодами от 128 до 159 будут интерпретироваться принтером как управляющие коды. Этот режим устанавливается по умолчанию при инициализации принтера.
Управление цветом
ESC r n Определение цвета печати
1Bh 72h n
В зависимости от значения параметра n печать будет выполнена одним из следующих цветов:
0 - черный; 1 - малиновый; 2 - циан; 3 - фиолетовый; 4 - желтый; 5 - красный; 6 - зеленый.
Управление печатающей головкой и перемещением бумаги
CR(13) Возврат каретки
0Dh
Команда вызывает распечатку содержимого буфера данных принтера, после чего головка переводится в начало текущей строки. CAN(24) Отмена печати строки
18h
Весь текст из распечатываемой строки удаляется. Команда не влияет на управляющий коды, находящиеся в этой строке. FF(12) Подача бумаги на один лист
0Ch
Команда вызыывает распечатывание содержимого буфера принтера, вслед за этим происходит подача бумаги вперед на один лист (в соответствии с установленной длиной листа). ESC C n Установить длину листа бумаги в строках
1Bh 43h n
Команда устанавливает длину листа бумаги, равной n строкам. Используется установленное ранее расстояние между строками. Допустимые значения параметра n лежат в пределах 1...127 строк. ESC C 0 n Установить длину листа бумаги в дюймах
1Bh 43h 00h n
Комнда устанавливает длину листа бумаги, равную n дюймам. Значение n должно находиться в пределах 1...22 дюйма. ESC N n Установить режим пропуска перфорации
1Bh 4Eh n
В этой команде параметр n - это количество строк, пропускаемых принтером между последней строкой страницы и первой строкой следующей страницы. Значение n должно находиться в пределах 1...127 строк. ESC O Отмена режима пропуска перфорации
1Bh 4Fh
Эта команда отменяет режим пропуска перфорации, установленный командой "ESC N n". LF(10) Перевод строки
0Ah
Команда вызывает распечатку содержимого буфера данных принтера, после чего головка переводится в начало следующей строки (бумага продвигается впереж на одну строку). ESC 0 Выбор межстрочного интервала, равного 1/8 дюйма
1Bh 30h
Расстояние между текстовыми строками устанавливается равным 1/8 дюйма. ESC 2 Выбор межстрочного интервала, равного 1/6 дюйма
1Bh 32h
Расстояние между текстовыми строками устанавливается равным 1/6 дюйма. Это значение используется по умолчанию при включении питания принтера. ESC 3 n Выбор межстрочного интервала, равного n/180 дюйма
1Bh 33h n
Расстояние между текстовыми строками устанавливается равным n/180 дюймов. Значение n должно находиться в пределах 0...255. ESC + n Выбор межстрочного интервала, равного n/360 дюйма
CR(13) Возврат каретки
0Dh Epson, IBM
Команда вызывает распечатку содержимого буфера данных принтера, после чего головка переводится в начало текущей строки. CAN(24) Отмена печати строки
18h Epson, IBM
Весь текст из распечатываемой строки удаляется. Команда не влияет на управляющий коды, находящиеся в этой строке. FF(12) Подача бумаги на один лист
0Ch Epson, IBM
Команда вызыывает распечатывание содержимого буфера принтера, вслед за этим происходит подача бумаги вперед на один лист (в соответствии с установленной длиной листа). ESC C n Установить длину листа бумаги в строках
1Bh 43h n Epson, IBM
Команда устанавливает длину листа бумаги, равной n строкам. Используется установленное ранее расстояние между строками. Допустимые значения параметра n лежат в пределах 1...127 строк. ESC C 0 n Установить длину листа бумаги в дюймах
1Bh 43h 00h n Epson, IBM
Комнда устанавливает длину листа бумаги, равную n дюймам. Значение n должно находиться в пределах 1...22 дюйма. ESC N n Установить режим пропуска перфорации
1Bh 4Eh n Epson, IBM
В этой команде параметр n - это количество строк, пропускаемых принтером между последней строкой страницы и первой строкой следующей страницы. Значение n должно находиться в пределах 1...127 строк. ESC O Отмена режима пропуска перфорации
1Bh 4Fh Epson, IBM
Эта команда отменяет режим пропуска перфорации, установленный командой "ESC N n". ESC 4 Установка верхней границы листа
1Bh 34h IBM
Текущая строка становится верхней строкой листа. LF(10) Перевод строки
0Ah Epson, IBM
Команда вызывает распечатку содержимого буфера данных принтера, после чего головка переводится в начало следующей строки (бумага продвигается впереж на одну строку). ESC 0 Выбор межстрочного интервала, равного 1/8 дюйма
1Bh 30h Epson, IBM
Расстояние между текстовыми строками устанавливается равным 1/8 дюйма. ESC 1 Выбор межстрочного интервала, равного 7/72 дюйма
1Bh 31h Epson, IBM
Расстояние между текстовыми строками устанавливается равным 7/72 дюйма. ESC 2 Выбор межстрочного интервала, равного 1/6 дюйма
1Bh 2Bh n
Расстояние между текстовыми строками устанавливается равным n/360 дюймов. Значение n должно находиться в пределах 0...255. ESC A n Выбор межстрочного интервала, равного n/60 дюйма
1Bh 41h n
Расстояние между текстовыми строками устанавливается равным n/60 дюймов. Значение n должно находиться в пределах 0...85. ESC J n Проброс бумаги на расстояние n/180 дюймов
1Bh 4Ah n
Бумага продвигается вперед на расстояние, равное n/180 дюймов. Команда выполняется немедленно и не вызывает перемещений печатающей головки. VT(11) Вертикальная табуляция
0Bh
Бумага продвигается до следующего символа табуляции в канале, выбранном командой "ESC /". Если не выбран никакой канал, по умолчанию используется нулевой. Если вертикальная табуляция не установлена, бумага продвигается вперед на одну строку. ESC B n1 n2 ... 0 Установка вертикальной табуляции
1Bh 42h n1 n2 ... 00h
Команда позволяет задать до 16 положений для вертикальной табуляции. Параметры n1, n2, ... задают позиции для табуляции. Они должны указываться в порядке возрастания. Последний параметр всегда должен быть равен 0 - это признак конца последовательности параметров. Табуляция устанавливается в нулевом канале. ESC b c n1 n2 ... 0 Установка вертикальной табуляции в канале
1Bh 62h c 1n n2 ... 00h
Команда аналогична команде "ESC B", за исключением того, что необходимо указывать параметр c - номер выбираемого канала для вертикальной табуляции. Значение параметра c должно находиться в пределах 0...7. ESC / c Выбор канала для вертикальной табуляции
1Bh 2Fh c
Команда выбирает канал c для работы с командами VT вертикальной табуляции. Значение параметра c должно находиться в пределах 0...7. ESC l n Установка левой границы
1Bh 6Ch n
Устанавливается левая граница листа. В левой части листа оставляется n пустых столбцов символов текущей ширины. Если командв выдается для пропорционального набора символов, в качестве ширины для установки левой границы берется значение 10 символов на дюйм (10 pitch). ESC Q n Установка правой границы
1Bh 51h n
Устанавливается правая граница листа. В правой части листа оставляется n пустых столбцов символов текущей ширины. Если командв выдается для пропорционального набора символов, в качестве ширины для установки правой границы берется значение 10 символов на дюйм (10 pitch). BS(8) Возврат на одну позицию
08h
Команда вызывает распечатку содержимого буфера печати, после чего печатающая головка возвращается на одну позицию назад (но не за левую границу, установленную командой "ESC l". Если этот код выводится на принтер сразу после печати строки в графическом режиме, печатающая головка возвращается к началу только что напечатанной графической строки. ESC $ n1 n2 Установка абсолютной позиции для печати
1Bh 24h n1 n2
Команда задает расстояние от левой границы листа до того места, откуда будет продолжена печать символов. Для вычисления расстояния используется следующая формула: n1 + (n2 * 256). Расстояние задается в единицах, эквивалентных 1/60 доли дюйма. ESC \ n1 n2 Установка относительной позиции для печати
1Bh 5Ch n1 n2
Команда задает расстояние от текущей позиции печатающей головки до того места, откуда будет продолжена печать символов. Для вычисления расстояния используется следующая формула: n1 + (n2 * 256). Расстояние задается в единицах, эквивалентных 1/120 доли дюйма для чернового режима и 1/180 доли дюйма для качественного и пропорционального. HT(9) Горизонтальная табуляция
09h
Печатающая головка продвигается до следующего символа горизонтальной табуляции. По умолчанию для одного символа табуляции используется интервал в 8 символов текущего размера. ESC D n1 n2 ... 0 Установка горизонтальной табуляции
1Bh 44h n1 n2 ... 00h
Команда позволяет задать до 32 положений для горизонтальной табуляции. Параметры n1, n2, ... задают позиции для табуляции. Они должны указываться в порядке возрастания. Последний параметр всегда должен быть равен 0 - это признак конца последовательности параметров. Команда "ESC D 0" сбрасывает все позиции горизонтальной табуляции. ESC x n Выбор черновой или качественной печати
1Bh 78h n
Параметр n определяет режим печати следующим образом:
0 - черновой режим печати; 1 - качественный (LQ) режим печати. ESC k n Выбор стиля печати
1Bh 6Bh n
Команда действительна только для режима качественной печати. Параметр n задает стиль:
0 - Roman; 1 - Sans Serif; 2 - Courier; 3 - Prestige; 4 - Script; 5 - OCR-B; 6 - OCR-A. ESC ! n Выбор режима работы принтера
1Bh 21h n
Команда позволяет задать комбинацию различных режимов работы принтера. Можно по отдельности задавать размер символов (10 или 12 символов на дюйм), набор символов (пропорциональный, сжатый, выделенный и т.д.). Отдельные биты байта параметра n задают режим работы принтера следующим образом:
7 6 5 4 3 2 1 0 --T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ LT+T+T+T+T+T+T+T- ¦ ¦ ¦ ¦ ¦ ¦ ¦ L= 0 - размер символа 10 pitch ¦ ¦ ¦ ¦ ¦ ¦ ¦ 1 - размер символа 12 pitch ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L=== пропорциональный шрифт ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L===== сжатый шрифт ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L======= выделенный шрифт ¦ ¦ ¦ ¦ ¦ ¦ ¦ L========= использование двух проходов ¦ ¦ ¦ ¦ ¦ L=========== двойная высота ¦ ¦ ¦ L============= использование курсива ¦ L=============== использование подчеркивания
ESC P Выбор размера символа в 10 pitch
1Bh 50h
Эта команда задает размер символа, равный 10 pitch, или 10 символов на дюйм. Такой размер устанавливается по умолчанию при инициализации принтера. ESC M Выбор размера символа в 12 pitch
1Bh 4Dh
Эта команда задает размер символа, равный 12 pitch, или 12 символов на дюйм. ESC g Выбор размера символа в 15 pitch
1Bh 67h
Эта команда задает размер символа, равный 15 pitch, или 15 символов на дюйм. Этот режим несовместим с режимом сжатой печати. ESC p n Включение/выключение пропорционального режима
1Bh 70h n
В пропорциональном режиме разные символы имеют различную ширину, что благоприятно сказывается на читаемости текста. Например, букава "i" уже, чем "W". Параметр n может принимать следующие значения:
0 - выключение пропорционального режима; 1 - включение пропорционального режима. SI(15) Выбор режима сжатой печати
0Fh
В этом режиме символы имеют примерно на 60 процентов меньшую ширину, чем в нормальном режиме. Режим сжатой печати не совместим с пропорциональным режимом. ESC SI Выбор режима сжатой печати
1Bh 0Fh
Команда полностью аналогична предыдущей командe "SI". DC2(18) Отмена режима сжатой печати
12h
Отменяется режим сжатой печати, установленный ранее командами ESC SI или SI. SO(14) Печать с двойной шириной
0Eh
В этом режиме ширина каждого распечатываемого символа увеличивается в два раза. Режим печати с двойной шириной отменяется командой возврата каретки или командой DC4. ESC SO Печать с двойной шириной
1Bh 0Eh
Команда полностью аналогична предыдущей командe "SO". ESC W n Включение/выключение режима печати с двойной высотой
1Bh 77h n
В режиме печати с двойной высотой высота каждого распечатываемого символа увеличивается в два раза. Возможные значения параметра n:
0 - выключение режима печати с двойной высотой; 1 - включение режима печати с двойной высотой. DC4(20) Отмена режима печати с двойной шириной
14h
Команда отменяет действие команд "ESC SO" или "SO", но не действует, если режим печати с двойной шириной задан командами "ESC W" или "ESC !". ESC W n Включение/выключение режима печати с двойной шириной
1Bh 57h n
В режиме печати с двойной шириной ширина каждого распечатываемого символа увеличивается в два раза. Возможные значения параметра n:
0 - выключение режима печати с двойной шириной; 1 - включение режима печати с двойной шириной. ESC E Установка режима печати с выделением
1Bh 45h
Распечатываемые символы выглядят "толще" за счет того, что каждая точка печатается дважды. ESC F Отмена режима печати с выделением
1Bh 46h
Команда отменяет действие команды "ESC E". ESC G Установка режима двойной печати
1Bh 47h
В режиме двойной печати каждая строка печатается дважды, поэтому текст выглядит ярче. Скорость печати уменьшается в два раза. ESC H Отмена режима двойной печати
1Bh 48h
Команда отменяет действие команды "ESC G". ESC S 0 Печать верхнего индекса
1Bh 53h 00h
Символы распечатываются выше обычного уровня, занимая верхние две трети сетки. ESC S 1 Печать нижнего индекса
1Bh 53h 01h
Символы распечатываются ниже обычного уровня, занимая нижние две трети сетки. ESC T Отмена печати верхнего или нижнего индекса
1Bh 54h
Команда отменяет действие любой из команд, задающих режим печати индекса - "ESC S 0" или "ESC S 1". ESC - n Включение/выключение режима подчеркивания
1Bh 2Dh n
В зависимости от значения параметра n все символы (и пробелы тоже) печатаются с подчеркиванием или без подчеркивания:
0 - выключение режима подчеркивания; 1 - включение режима подчеркивания. ESC q n Выбор стиля распечатываемых символов
1Bh 71h n
В зависимости от значения параметра n все символы, кроме имеющих коды от B0h до DFh и символа с кодом F5h распечатываются с использованием следующих стилей:
0 - обычный стиль; 1 - контурное (outline) начертание символов; 2 - использование тени (стиль shadow); 3 - комбинация контурного начертания и тени.
1Bh 32h Epson, IBM
Расстояние между текстовыми строками устанавливается равным 1/6 дюйма. Это значение используется по умолчанию при включении питания принтера. ESC 2 Выбор межстрочного интервала командой "ESC A n"
1Bh 32h IBM
После приема принтером этой команды межстрочный интервал устанавливается таким, каким он был задан в команде "ESC A n". ESC 3 n Выбор межстрочного интервала, равного n/216 дюйма
1Bh 33h n Epson, IBM
Расстояние между текстовыми строками устанавливается равным n/216 дюймов. Значение n должно находиться в пределах 0...255. ESC A n Выбор межстрочного интервала, равного n/72 дюйма
1Bh 41h n Epson
Расстояние между текстовыми строками устанавливается равным n/72 дюймов. Значение n должно находиться в пределах 0...85. ESC A n Выбор межстрочного интервала, равного n/72 дюйма
1Bh 41h n IBM
Расстояние между текстовыми строками устанавливается равным n/72 дюймов. Значение n должно находиться в пределах 0...85. Для того, чтобы эта команда включилась в работу, принтер должен принять команду "ESC 2". ESC J n Проброс бумаги на расстояние n/216 дюймов
1Bh 4Ah n Epson, IBM
Бумага продвигается вперед на расстояние, равное n/216 дюймов. Команда выполняется немедленно и не вызывает перемещений печатающей головки. Диапазон допустимых значений n - 0...255. ESC 5 Переключение режима автоматического перевода строки
1Bh 35h n IBM
Если включен режим автоматического перевода строки, то принтер переводит строку после приема символа возврата каретки CR, без дополнительного символа перевода каретки LF. Возможные значения параметра n:
0 - выключить автоматический перевод строки; 1 - включить автоматический перевод строки. VT(11) Вертикальная табуляция
0Bh Epson, IBM
Бумага продвигается до следующей позиции вертикальной табуляции. Если вертикальная табуляция не установлена, бумага продвигается вперед на одну строку. ESC B n1 n2 ... 0 Установка вертикальной табуляции
1Bh 42h n1 n2 ... 00h Epson, IBM
Команда позволяет задать до 16 положений для вертикальной табуляции. Параметры n1, n2, ... задают позиции для табуляции. Они должны указываться в порядке возрастания. Последний параметр всегда должен быть равен 0 - это признак конца последовательности параметров. ESC b c n1 n2 ... 0 Установка вертикальной табуляции в канале
1Bh 62h c 1n n2 ... 00h Epson
Команда аналогична команде "ESC B", за исключением того, что необходимо указывать параметр c - номер выбираемого канала для вертикальной табуляции. Значение параметра c должно находиться в пределах 0...7. ESC / c Выбор канала для вертикальной табуляции
1Bh 2Fh c Epson
Команда выбирает канал c для работы с командами VT вертикальной табуляции. Значение параметра c должно находиться в пределах 0...7. ESC l n Установка левой границы
1Bh 6Ch n Epson
Устанавливается левая граница листа. В левой части листа оставляется n пустых столбцов символов текущей ширины. Если командв выдается для пропорционального набора символов, в качестве ширины для установки левой границы берется значение 10 символов на дюйм (10 pitch). ESC Q n Установка правой границы
1Bh 51h n Epson
Устанавливается правая граница листа. В правой части листа оставляется n пустых столбцов символов текущей ширины. Если командв выдается для пропорционального набора символов, в качестве ширины для установки правой границы берется значение 10 символов на дюйм (10 pitch). ESC X Установка левой и правой границы листа
1Bh 58h n1 n2 IBM
Левая граница устанавливается в n1, правая в n2. Используется текущая ширина символов. BS(8) Возврат на одну позицию
08h Epson, IBM
Команда вызывает распечатку содержимого буфера печати, после чего печатающая головка возвращается на одну позицию назад (но не за левую границу, установленную командой "ESC l". После команд "ESC a 2" и "ESC a 3" эта команда игнорируется. Если команда BS выводится на принтер сразу после печати строки в графическом режиме, печатающая головка возвращается к началу только что напечатанной графической строки. ESC $ n1 n2 Установка абсолютной позиции для печати
1Bh 24h n1 n2 Epson, IBM
Команда задает расстояние от левой границы листа до того места, откуда будет продолжена печать символов. Для вычисления расстояния используется следующая формула: n1 + (n2 * 256). Расстояние задается в единицах, эквивалентных 1/60 доли дюйма. ESC \ n1 n2 Установка относительной позиции для печати
1Bh 5Ch n1 n2 Epson
Команда задает расстояние от текущей позиции печатающей головки до того места, откуда будет продолжена печать символов. Для вычисления расстояния вначале надо вычислить требуемое смещение в точках. Если надо определить смещение влево, полученное значение следует вычесть из числа 65536. Общее количество точек вычисляется по формуле: n1 + (n2 * 256). HT(9) Горизонтальная табуляция
09h Epson, IBM
Печатающая головка продвигается до следующего символа горизонтальной табуляции. ESC D n1 n2 ... 0 Установка горизонтальной табуляции
1Bh 44h n1 n2 ... 00h Epson, IBM
Команда позволяет задать до 32 положений для горизонтальной табуляции. Параметры n1, n2, ... задают позиции для табуляции. Они должны указываться в порядке возрастания. Последний параметр всегда должен быть равен 0 - это признак конца последовательности параметров. Команда "ESC D 0" сбрасывает все позиции горизонтальной табуляции. После включения питания (или приема команды инициализации "ESC @" каждому символу табуляции при печати будет соответствовать восемь пробелов. ESC R Отмена табуляции
1Bh 52h IBM
Отменяется одновременно горизонтальная и вертикальная табуляция. ESC x n Выбор черновой или качественной печати
1Bh 78h n Epson
Параметр n определяет режим печати следующим образом:
0 - черновой режим печати; 1 - качественный (NLQ) режим печати.
В качественном режиме печати используются наборы символов Roman или Sans Serif. ESC k n Выбор стиля печати
1Bh 6Bh n Epson
Команда действительна только для режима качественной печати. Параметр n задает стиль:
0 - Roman; 1 - Sans Serif. ESC ! n Выбор режима работы принтера
1Bh 21h n Epson
Команда позволяет задать комбинацию различных режимов работы принтера. Можно по отдельности задавать размер символов (10 или 12 символов на дюйм), набор символов (пропорциональный, сжатый, выделенный и т.д.). Отдельные биты байта параметра n задают режим работы принтера следующим образом:
7 6 5 4 3 2 1 0 --T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ LT+T+T+T+T+T+T+T- ¦ ¦ ¦ ¦ ¦ ¦ ¦ L= 0 - размер символа 10 pitch ¦ ¦ ¦ ¦ ¦ ¦ ¦ 1 - размер символа 12 pitch ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L=== пропорциональный шрифт ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L===== сжатый шрифт ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L======= выделенный шрифт ¦ ¦ ¦ ¦ ¦ ¦ ¦ L========= использование двух проходов ¦ ¦ ¦ ¦ ¦ L=========== двойная высота ¦ ¦ ¦ L============= использование курсива ¦ L=============== использование подчеркивания
ESC I n Выбор шрифта
1Bh 49h n IBM
В зависимости от параметра n выбирается один из следующих шрифтов:
0 обычное качество, 10 символов на дюйм;
1 обычное качество, 12 символов на дюйм;
2 качественный шрифт Sans Serif;
3 качественный шрифт Roman;
4 шрифт обычного качества, определенный пользователем, 10 символов на дюйм;
5 шрифт обычного качества, определенный пользователем, 12 символов на дюйм;
6 качественный шрифт, определенный пользователем, 10 символов на дюйм;
7 качественный шрифт, определенный пользователем, 12 символов на дюйм;
ESC P Выбор размера символа в 10 pitch
1Bh 50h Epson
Эта команда задает размер символа, равный 10 pitch, или 10 символов на дюйм. Такой размер устанавливается по умолчанию при инициализации принтера. ESC M Выбор размера символа в 12 pitch
1Bh 4Dh Epson
Эта команда задает размер символа, равный 12 pitch, или 12 символов на дюйм. DC2(18) Выбор размера символа в 10 pitch
12h IBM
Эта команда задает размер символа, равный 10 pitch, или 10 символов на дюйм. Команда отменяет ранее установленный режим сжатой печати. ESC : Выбор размера символа в 12 pitch
1Bh 3Ah IBM
Эта команда задает размер символа, равный 10 pitch, или 12 символов на дюйм. ESC p n Включение/выключение пропорционального режима
1Bh 70h n Epson
В пропорциональном режиме разные символы имеют различную ширину, что благоприятно сказывается на читаемости текста. Например, букава "i" уже, чем "W". Параметр n может принимать следующие значения:
0 - выключение пропорционального режима; 1 - включение пропорционального режима. ESC P n Включение/выключение пропорционального режима
1Bh 50h n IBM
Параметр n может принимать следующие значения:
0 - выключение пропорционального режима; 1 - включение пропорционального режима. SI(15) Выбор режима сжатой печати
0Fh Epson, IBM
В этом режиме символы имеют примерно на 60 процентов меньшую ширину, чем в нормальном режиме. Режим сжатой печати не совместим с пропорциональным режимом. ESC SI Выбор режима сжатой печати
1Bh 0Fh Epson, IBM
Команда полностью аналогична предыдущей командe "SI". DC2(18) Отмена режима сжатой печати
12h Epson
Отменяется режим сжатой печати, установленный ранее командами ESC SI или SI. SO(14) Печать с двойной шириной
0Eh Epson, IBM
В этом режиме ширина каждого распечатываемого символа увеличивается в два раза. Режим печати с двойной шириной отменяется командой возврата каретки или командой DC4. ESC SO Печать с двойной шириной
1Bh 0Eh Epson, IBM
Команда полностью аналогична предыдущей командe "SO". ESC W n Включение/выключение режима печати с двойной высотой
1Bh 77h n Epson, IBM
В режиме печати с двойной высотой высота каждого распечатываемого символа увеличивается в два раза. Возможные значения параметра n:
0 - выключение режима печати с двойной высотой; 1 - включение режима печати с двойной высотой. DC4(20) Отмена режима печати с двойной шириной
14h Epson, IBM
Команда отменяет действие команд "ESC SO" или "SO", но не действует, если режим печати с двойной шириной задан командами "ESC W" или "ESC !". ESC W n Включение/выключение режима печати с двойной шириной
1Bh 57h n Epson
В режиме печати с двойной шириной ширина каждого распечатываемого символа увеличивается в два раза. Возможные значения параметра n:
0 - выключение режима печати с двойной шириной; 1 - включение режима печати с двойной шириной. ESC [ @ Печать с двойной высотой и двойной шириной
1Bh 5Bh 40h n1 n2 m1 m2 m3 m4 IBM
Команда позволяет управлять высотой и шириной распечатываемых символов. Параметры n2, m1, m2 должны быть равны 0, параметр n1 должен быть равен 4. Параметр m3 влияет на высоту символов и количество пробрасываемых по команде LF строк:
1 стандартная высота, текущий режим перевода строки;
2 двойная высота, обычный режим перевода строки;
16 текущая высота, одна строка на один LF;
17 стандартная высота, одна строка на один LF;
18 двойная высота, одна строка на один LF;
32 текущая высота, две строки на один LF;
33 стандартная высота, две строки на один LF;
34 двойная высота, две строки на один LF;
Параметр m4 влияет на ширину символов:
1 стандартная ширина; 2 двойная ширина. ESC E Установка режима печати с выделением
1Bh 45h Epson, IBM
Распечатываемые символы выглядят "толще" за счет того, что каждая точка печатается дважды. ESC F Отмена режима печати с выделением
1Bh 46h Epson, IBM
Команда отменяет действие команды "ESC E". ESC G Установка режима двойной печати
1Bh 47h Epson, IBM
В режиме двойной печати каждая строка печатается дважды, поэтому текст выглядит ярче. Скорость печати уменьшается в два раза. ESC H Отмена режима двойной печати
1Bh 48h Epson, IBM
Команда отменяет действие команды "ESC G". ESC S 0 Печать верхнего индекса
1Bh 53h 00h Epson, IBM
Символы распечатываются выше обычного уровня, занимая верхние две трети сетки. ESC S 1 Печать нижнего индекса
1Bh 53h 01h Epson, IBM
Символы распечатываются ниже обычного уровня, занимая нижние две трети сетки. ESC T Отмена печати верхнего или нижнего индекса
1Bh 54h Epson, IBM
Команда отменяет действие любой из команд, задающих режим печати индекса - "ESC S 0" или "ESC S 1". ESC - n Включение/выключение режима подчеркивания
1Bh 2Dh n Epson, IBM
В зависимости от значения параметра n все символы (и пробелы тоже) печатаются с подчеркиванием или без подчеркивания:
0 - выключение режима подчеркивания; 1 - включение режима подчеркивания. ESC _ n Включение/выключение режима перечеркивания
1Bh 2Dh n IBM
В зависимости от значения параметра n все символы печатаются перечеркнутыми или нет:
0 - выключение режима перечеркивания; 1 - включение режима перечеркивания.
Управление принтером
ESC @ Инициализация принтера
1Bh 40h
Выполняется сброс принтера в исходное состояние, если происходила печать строки, то при инициализации эта печать отменяется. DC1(17) Выбор принтера для работы
11h
Возвращает принтер в выбранное (активное) состояние, если раньше он был переведен в неактивное состояние командой DC3. Эта команда не выполняет никаких действий, если принтер находится в состоянии OFF LINE DC3(19) Перевод принтера в неактивное состояние
13h
Переводит принтер в неактивное состояние до получения принтером команды DC1 выбора принтера для работы. Если принтер переведен в неактивное состояние, его нельзя перевести в состояние ON LINE при помощи соответствующей клавиши на лицевой панели. DEL(127) Удаление символа
7Fh
Удаляет последний переданный в принтер символ. Эта команда не действует на управляющие коды. ESC < Печать в одном направлении
1Bh 3Ch
Переключает принтер в режим печати в одном направлении, т.е. принтер печатает только тогда, когда печатающая головка движется в одну сторону. Команда задает режим только для одной строки, символ возврата каретки отменяет печать только в одном направлении. ESC U n Включение/выключение режима печати в одном направлении
1Bh 55h n
В зависимости от параметра n режим печати только в одном направлении может включаться либо отключаться:
n = 1 режим включен; n = 0 режим выключен. ESC EM n Управление податчиком бумаги
1Bh 19h n
Эта команда распознается принтером только в том случае, если принтер оборудован податчиком бумаги (Cut Sheet Feeder). Возможные значения параметра n:
1 Загрузка бумаги из кармана BIN1 2 Загрузка бумаги из кармана BIN2 R Проброс листа бумаги без загрузки нового.
BEL(7) Выдача звукового сигнала
07h
Если выдать эту команду на принтер, громкоговоритель принтера издаст звуковой сигнал. Эта команда может быть использована для предупреждения оператора, например, о том, что кончилась бумага.
Управление старшим битом данных
Старший бит данных MSB (Most Significant Bit) - это бит 7 байтов, посылаемых программой в принтер. Обычно вам не надо изменять значение старшего бита данных, более того, команды управления старшим битом не действуют в графическом режиме или при переопределении символов.
ESC = Установка MSB в 0
1Bh 3Dh
Для всех выводимых на принтер данных старший бит принудительно устанавливается в 0. Этот режим используется при работе принтера с такими компьютерами, которые всегда посылают на принтер данные со старшим битом, установленным в 1. ESC > Установка MSB в 1
1Bh 3Eh
Для всех выводимых на принтер данных старший бит принудительно устанавливается в 1. ESC # Отмена управления MSB
1Bh 23h
Отменяется действие введенных ранее команд управления MSB "ESC =" или "ESC >"
Управляющие команды
FINIT Инициализация арифметического сопроцессора
FSTSW AX Запись слова состояния
AX <- MSW
FSTSW dest Запись слова состояния
dest (mem16) <- MSW
FLDCW src Загрузка управляющего слова
CW <- src (mem16)
FSTCW dest Запись управляющего слова
dest (mem16) <- CW
FCLEX Сброс флагов особых случаев
FSTENV dest Запись содержимого всех регистров сопроцессора, кроме численных
FLDENV src Загрузка содержимого всех регистров сопроцессора, кроме численных
FSAVE dest Запись содержимого всех регистров сопроцессора
FRSTOR src Загрузка содержимого всех регистров сопроцессора
FINCSTP Увеличение указателя стека численных регистров на 1
st(6) <- st(5) st(5) <- st(4) st(4) <- st(3) st(3) <- st(2) st(2) <- st(1) st(1) <- st(0) st(0) <- пустой
FDECSTP Уменьшение указателя стека численных регистров на 1
st(0) <- st(1) st(1) <- st(2) st(2) <- st(3) st(3) <- st(4) st(4) <- st(5) st(5) <- st(6) st(6) <- st(7) st(7) <- пустой
FFREE Освобождение регистра st(i)
Команда помечает численный регистр st(i) как неинициализированный, записывая в соответствующее поле регистра тегов значение 11
FNOP Холостая команда
st(0) <- st(0)
WAIT/FWAIT Синхронизация центрального процессора и арифметического сопроцессора
Центральный процессор будет находиться в состоянии ожидания до тех пор, пока сопроцессор не завершит выполнение текущей команды.
FSETPM Установить защищенный режим работы
Процессор переходит в защищенный режим работы, возврат в реальный режим возможен только при сбросе сопроцессора.
Загрузка данных в стек
FLD src Загрузка вещественного числа
st(0) <- src (mem32/mem64/mem80)
FILD src Загрузка целого числа
st(0) <- src (mem16/mem32/mem64)
FBLD src Загрузка десятичного числа
st(0) <- src (mem80)
Запись данных
FST dest Запись вещественного числа
dest <- st(0) (mem32/mem64)
FSTP dest Запись вещественного числа с извлечением его из стека численных регистров
dest <- st(0) (mem32/mem64/mem80)
FIST dest Запись целого числа
dest <- st(0) (mem32/mem64)
FISTP dest Запись целого числа с извлечением его из стека численных регистров
dest <- st(0) (mem16/mem32/mem64)
FBST dest Запись десятичного числа
dest <- st(0) (mem80)
FBSTP dest Запись десятичного числа с извлечением его из стека численных регистров
dest <- st(0) (mem80)