Компьютер - электронное устройство, которое не заменит человека до тех пор, пока не научится смеяться шуткам начальника и сваливать свои собственные ошибки на соседний компьютер.





      AT хранит информацию о конфигурации в микросхеме MC146818 фирмы Motorola, вместе с часами реального времени. Он вовсе не имеет микросхемы 8255, хотя для управления микросхемой таймера и приема данных с клавиатуры используются те же самые адреса пор- тов. Микросхема имеет 64 регистра, пронумерованных от 00 до 3FH. Для чтения регистра нужно сначала послать его номер в порт с адресом 70H, а затем прочитать его через порт 71H. Различные параметры конфигурации обсуждаются на последующих страницах. Приведем здесь только краткую сводку:

      Номер регистра Использование
      10H тип накопителя НГМД
      12H тип накопителя фиксированного диска
      14H периферия
      15H память на системной плате (младший байт)
      16H память на системной плате (старший байт)
      17H общая память (младший байт)
      18H общая память (старший байт)
      30H память сверх 1 мегабайта (младший байт)
      31H память сверх 1 мегабайта (старший байт)


      Высокий уровень.

      В данной книге имеется множество примеров доступа к этим пор- там. Ниже приводится программа на Бейсике, устанавливающая число дисковых накопителей, присоединенных к IBM PC. Прежде чем прочи- тать два старших бита порта A, бит 7 порта B должен быть установ- лен в 1. Существенно, что Вы должны вернуть значение этого бита назад в 0 перед дальнейшей работой, иначе клавиатура будет запер- та и для восстановления работоспособности машины Вам придется выключить ее. Бейсик не позволяет двоичное представление чисел, что затрудняет работу с цепочками битов. Простая подпрограмма может заменить любое целое вплоть до 255 (максимальное значение, которое может принимать номер порта) на восьмисимвольную двоичную строку. После этого строковая функция MID$ позволяет вырезать нужные биты для анализа. Основы битовых операций в Бейсике описа- ны в приложении Б.
100 A = INP(&H61) 'получаем значение из порта B 110 A = A OR 128 'устанавливаем бит 7 120 OUT &H61,A 'посылаем байт назад в порт B 130 B = INP(&H60) 'получаем значение из порта A 140 A = A AND 128 'сбрасываем бит 7 150 OUT &H61,A 'восстанавливаем значение порта B 160 GOSUB 1000 'преобразуем в двоичную строку 170 NUMDISK$ = RIGHT$(B$,1) 'получаем нулевой бит 180 IF D$ = 1 THEN NUMDISK = 0: GOTO 230 'нет дисков 190 C$ = LEFT$(B$,2) 'берем два старших бита строки 200 TALLEY = 0 'переменная для числа дисков 210 IF RIGHT$(C$,1) = "1" THEN TALLEY = 2 'берем старший бит 220 IF LEFT$(C$,1) = "1" THEN TALLEY = TALLEY + 1 'и младший 230 TALLEY = TALLEY + 1 'счет начинается с 1, а не с 0
      'теперь имеем число накопителей 1000 '''Подпрограмма преобразования байта в двоичную строку 1010 B$ = "" 'заводим строку 1020 FOR N = 7 TO 0 STEP -1 'проверка очередной степени 2 1030 Z = B - 2^N ' 1040 IF Z >= 0 THEN B = Z: B$ = B$+"1" ELSE B$ = B$+"0" 1050 NEXT 'повторяем для каждого бита 1060 RETURN 'все закончено

      Низкий уровень.

      Ассемблерная программа получает число имеющихся дисковых нако- пителей тем же способом, что и в вышеприведенном примере, но более просто. Напоминаем, что нельзя забывать о восстановлении первоначального значения в порте B.

      IN AL,61H ;получаем значение из порта B
      OR AL,10000000B ;устанавливаем бит 7 в 1
      OUT 61H,AL ;заменяем байт
      IN AL,60H ;получаем значение из порта A
      MOV CL,6 ;подготовка для сдвига AL
      SHR AL,CL ;сдвигаем 2 старших бита на 6 позиций
      INC AL ;начинаем счет с 1, а не с 0
      MOV NUM_DRIVES,AL ;получаем число накопителей
      IN AL,61H ;подготовка к восстановлению порта B
      AND AL,01111111B ;сбрасываем бит 7
      OUT 61H,AL ;восстанавливаем байт


1.1.2 Определение типа IBM PC.



      Имеются проблемы совместимости между различными типами IBM PC. Для того чтобы программа могла работать на любом из IBM PC, ис- пользуя все его возможности, необходимо чтобы она могла опреде- лить тип машины, в которую она загружена. Эта информация содер- жится во втором с конца байте памяти по адресу FFFFE в ROM-BIOS, с использованием следующих ключевых чисел.

      Компьютер Код
      PC FF
      XT FE
      PCjr FD
      AT FC

      Высокий уровень.

      В Бейсике надо просто использовать PEEK для чтения значения:
100 DEF SEG = &HF000 'указываем на верхние 64K памяти 110 X = PEEK(&HFFFE) 'читаем второй с конца байт 120 IF X = &HFD THEN ... '... тогда это PCjr

      Низкий уровень.

      В языке ассемблера:
;--- Определение типа компьютера:
      MOV AX,0F000H ;указывает ES на ПЗУ
      MOV ES,AX ;
      MOV AL,ES:[0FFFEH] ;получаем байт
      CMP AL,0FDH ;это PCjr?
      JE INITIALIZE_JR ;переходим на инициализацию


1.1.3 Определение версии MS DOS.



      По мере развития MS DOS к ней добавлялись новые возможности, многие из которых существенно облегчают написание определенных частей программы по сравнению с предыдущими версиями. Чтобы иметь гарантию что программа будет работать с любой версией MS DOS она должна использовать только функции, доступные в MS DOS 1.0. В системе предусмотрено прерывание, возвращающее номер версии MS DOS. Это число может использоваться для проверки выполнимости Вашей программы. Минимально, программа может при старте выдавать сообщение об ошибке, сообщая что ей нужна другая версия MS DOS.