5.10.7. Часы реального времени и CMOS-память

В каждом компьютере есть микросхема, отвечающая за поддержку текущей даты и времени. Для того чтобы значения не сбрасывались при каждом выключе­нии питания, на микросхеме расположена небольшая область памяти (от 64 до 128 байт), выполненная по технологии CMOS, позволяющей снизить энергопот­ребление до минимума (фактически энергия в таких схемах затрачивается только на зарядку паразитных емкостей при изменении состояния ячеек Мик­росхема получает питание от аккумулятора, расположенного на материнской пла­те, и не отключается при выключении компьютера. Для хранения собственно времени достаточно всего 14 байт такой энергонезависимой памяти, и остальная ее часть используется BIOS, чтобы хранить различную информацию, необходимую для корректного запуска компьютера. Для общения с CMOS и регистрами RTC выделяются порты ввода-вывода от 70пдо 7Fh, но только назначение портов 70h и 71h одинаково для всех материнских плат.

Порт 70h для записи: индекс для выбора регистра CMOS:

бит 7: прерывание NMI запрещено на время чтения/записи

бит 6: собственно индекс Порт 71Ьдля чтения и записи: данные CMOS

После записи в порт 70h нужно осуществить запись или чтение из порта иначе RTC окажется в неопределенном состоянии. Содержимое регистров CMOS варьируется для разных BIOS, но первые 33h регистра обычно выполняют следу­ющие функции:

00h: RTC: текущая секунда (00-59h или 00-3Bh) - формат выбирается регист­ром OBh, по умолчанию - BCD Olh: RTC: секунды будильника (00-59пили 00-3Bh или OFFh (любая секунда)) 02h: RTC: текущая минута (00-59Ьили 00-3Bh) 03h: RTC: минуты будильника (00-59Ьили 00-3Bh или FFh)

04h: RTC: текущий час:

00- 23h/00-I7h (24-часовой режим)

01- 12h/01-lCh (12-часовой режим до полудня) 81h-92h/81-8Ch (12-часовой режим после полудня)

05h: RTC: часы будильника (то же или FFh, если любой час) 06h: RTC: текущий день недели (1-7, 1 - воскресенье) 07h: RTC: текущий день месяца (01-31h/01h-lFh) 08h: RTC: текущий месяц (01-12h/01-0Ch) 09h: RTC: текущий год (00-99h/00-63h)

Программирование на уровне портов ЩЦЦЯШ

О Ah: RTC: регистр состояния А

бит 7: 1 - часы заняты (происходит обновление)

биты 4-6: делитель фазы (010 - 32 768 кГц - по умолчанию)

биты 3-0: выбор частоты периодического прерывания:

0000 - выключено

ООН - 122 мкс (минимум)

1111 - 500мс

ОНО - 976,562мкс (1024 Гц) OBh: RTC: регистр состояния В

бит 7: запрещено обновление часов' (устанавливают перед записью новых зна­чений в регистры даты и часов) бит 6: вызов периодического прерывания бит 5: вызов прерывания при срабатывании будильника бит 4: вызов прерывания по окончании обновления времени бит 3: включена генерация прямоугольных импульсов бит 2: 1/0: формат даты и времени двоичный/BCD бит 1: 1/0: 24-часовой/12-часовой режим

бит 0:' автоматический переход на летнее время в апреле и октябре ОСЬ только для чтения: RTC: регистр состояния С

бит 7: произошло прерывание

бит 6: разрешено периодическое прерывание

бит 5: разрешено прерывание от будильника

бит 4: разрешено прерывание по окончании обновления часов

ODh только для чтения: регистр состояния D

бит 7: питание RTC/CMOS есть OEh: результат работы POST при последнем старте компьютера:

бит 7: RTC сбросились из-за отсутствия питания CMOS

бит 6: неверная контрольная' сумма CMOS-конфигурации

бит 5: неверная конфигурация

бит 4: размер памяти не совпадает с записанным в конфигурации бит 3: ошибка инициализации первого жесткого диска бит 2: RTC-время установлено неверно (например, 30 февраля) OFh: состояние, в котором находился компьютер перед последней перезагрузкой 00h - Ctr-Alt-Del, 05h - INT 19h, OAh, OBh, OCh -jmp, iret, retf на адрес, хра­нящийся в 0040h:0067h. Другие значения указывают, что перезагрузка про­изошла в ходе POST или в других необычных условиях 10h: тип дисководов (биты 7-4 и 3-0 - типы первого и второго дисковода) - отсутствует 0001b - 360 Кб i ООЮЬ - 1,2 Мб 001 lb-720 Кб ОЮОЬ - 1,44 Мб 0101b - 2,88 Мб

12h: тип жестких дисков (биты 7-4 и 3-0 - типы первого и второго жестких дис­ков, 1111b, если номер типа больше 15) 14Ь: байт состояния оборудования

биты 7-6: число установленных жестких дисков минус один

биты 5-4: тип монитора (00,01,10,11 = EGA/VGA, 40x25 CGA, 80x25 CGA, MDA)

бит 3: монитор присутствует

бит 2: клавиатура присутствует

бит 1: FPU присутствует

бит 0: дисковод присутствует 15h: младший байт размера базовой памяти в килобайтах (80h) 16h: старший байт размера базовой памяти в килобайтах (02h) 17h: младший байт размера дополнительной памяти (выше 1 Мб) в килобайтах 18h: старший байт размера дополнительной памяти (выше 1 Мб) в килобайтах 19h: тип первого жесткого диска, если больше 15

тип второго жесткого диска, если больше 2ЕЫ старший байт контрольной суммы регистров 10h - 2Dh 2Fh: младший байт контрольной суммы регистров 10h - 2Dh 30h: младший байт найденной при POST дополнительной памяти в килобайтах 31h: старший байт найденной при POST дополнительной памяти в килобайтах 32h: первые две цифры года в BCD-формате

Данные о конфигурации, хранящиеся в защищенной контрольной суммой об­ласти, бывают нужны достаточно редко, а для простых операций с часами реаль­ного времени и будильником удобно использовать прерывание BIOS lAh. Одна­ко, программируя RTC на уровне портов, можно активизировать периодическое прерывание - режим, в котором RTC вызывает прерывание IRQ8 с заданной ча­стотой, что позволяет оставить для работы системы, если вас удовлетворя­ет ограниченный выбор частот периодического прерывания. В качестве примера посмотрим, как выполняются чтение и запись в CMOS-память.

; rtctime.asm

;  Вывод на экран текущей даты

и времени из RTC.

start:

.model

tiny

 

 

 

.code

 

 

 

 

,186

 

; Для shr al,4. .

 

 

org

1QQh

; СОМ-программа.

 

 

mov

al.OBh

; CMOS OBh - управляющий

регистр В.

out

70h,al

; Порт 70h - индекс CMOS.

 

 

in

al,71h

; Порт 71h - данные CMOS.

 

 

and

al, 111110111)

Обнулить бит 2 (форма чисел -

BCD)

out

71h,al

; и записать обратно.

 

 

mov

al,32h

: CMOS 32h - две старшие

цифры

года.

call

print_cmos

; Вывод на экран.

 

 

mov

al,9

; CMOS 09h - две младшие

цифры

года.

ш

call

print_cmos

 

 

mov

al,'-'

; Минус.

 

int

29h

; Вывод на

экран.

mov

al,8

;  CMOS 08h

- текущий

call

print_cmos

 

 

mov

al,'-'

; Еще один

минус.

int

29h

 

 

mov

al,7

;  CMOS 07h

- день.

call

print_cmos

 

 

mov

al ' 1

;

 

int

29h

 

 

mov

al,4

;  CMOS 04h

- час.

call

print_cmos

 

 

mov

al, 'h'

; Буква "h

 

int

29h .

 

 

mov

ЗІ ' 1

; Пробел.

 

int •

29h

 

 

mov

al,2

;  CMOS 02h

- минута.

call

print_cmos

 

 

mov

:'

• Двоеточие.

int

29h

 

 

mov

al.Oh

• CMOS OOh

- секунда.

call

print_cmos

 

 

ret

 

 

 

Процедура

Выводит на экран содержимое ячейки CMOS с номером в AL. Считает, что число, читаемое из CMOS, находится в формате BCD.

s

proc near

 

out

70h,al

Послать AL в индексный порт CMOS.

in

al,71h

Прочитать данные.

push

ax

 

shr

al,4

Выделить старшие четыре бита.

add

al, '0'

; Добавить ASCII-код цифры 0.

int

29h

Вывести на экран.

pop

ax

 

and

al.OFh

Выделить младшие четыре бита.

add

al,30h

; Добавить ASCII-код цифры 0.

int

29b

Вывести на экран.

ret

 

 

)S

endp

 

end

start