Цель работы – изучение архитектуры системных устройств персонального компьютера и приемов их программирования на языке ассемблера.

 

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

·           внутренней организации системных устройств ПК,

·           методов программирования системных и периферийных устройств ПК,

·           использования отладчиков программного обеспечения

 

Функциональные узлы системной платы

IBM PC-совместимого компьютера

 

Системная плата персонального компьютера соответствующего платформе IBM PC традиционно содержит ряд функциональных уз­лов, которые с самого начала имели подробное открытое описание и в дальнейшем обязательно воспроизводились всеми изготовителями системных плат, поскольку использовались огромным количеством системных и прикладных программ. В первых моделях IBM PC эти узлы реализовывались на отдельных микросхемах. В настоящее время большинство их функций интегрированы в БИС набора микросхем (чипсета) системной платы. Среди этих узлов основными являются следующие.

 

§         Схемы предоставления системных ресурсов — памяти, ввода-вывода, прерываний, прямого доступа к памяти.

§         Микросхемы ROM BIOS с программным кодом начального тестирования, запуска и функций ввода-вывода.

§         Системный таймер, реализованный на микросхемах 8253 или 8254, использовавшийся как генератор запросов регенерации памяти, интервальный таймер и тональный генератор для динамика.

§         Системный порт AT, предназначенный для управления звуком и немаскируемыми прерываниями.

§         Канал управления звуком — логическая схема, использующая тональный сигнал таймера и программно-управляемые биты системного порта.

§         Последовательный интерфейс клавиатуры, реализуемый с помощью микроконтроллера 8042.

§         Память конфигурации и часы-календарь — CMOS RTC (real-time clock).

 

Хотя элементная база системной платы изменилась, но программная модель этих узлов, сохранилась. Рассмотрим их подробнее.

 

Системный порт

Восьмибитный системный порт с адресом 61h выполняет следующие функции:

§         управление звуком, сохранившее полную совместимость с XT;

§         разрешение и идентификация источников немаскируемых прерываний

Старшие 4 бита порта допускают только чтение (R), младшие 4 бита — чте­ние и запись (R/W).

Назначение бит системного порта AT (061h):

бит 7 R (только чтение) — РСК — ошибка четности ОЗУ или сигнал SERR# [1] на шине PCI;

бит 6 R — IOCHK — ошибка контроля на шине ISA (сигнал 10СНК#);

бит 5 R — Т20 — выход 2 счетчика 8254;

бит 4 R — RFD — регенерация памяти;

бит 3 R/W (чтение/запись) — EIC — разрешение контроля шины ISA;

бит 2 R/W — ERP — разрешение контроля ОЗУ и сигнала SERR# шины PCI;

бит 1 R/W — SPK — управление звуком;

бит 0 R/W - T2G - вход GATE 2 счетчика 8254.

 

Системный таймер (8253/8254)

Во всех моделях PC используется трехканальный счетчик-таймер, выполняю­щий следующие функции:

§         генерацию прерываний от системных часов, вызывающих инкремент счетчика системного времени в ячейке 40:006Е BIOS Data Area (области данных BIOS);

§         генерацию запросов на регенерацию памяти;

§         генерацию звуковых сигналов.

 

В качестве счетчиков-таймеров в XT применялась микросхема i8253, а в AT — более быстродействующая i8254, которая с процессорами 80286 могла работать без тактов ожидания. На современных системных платах те же функции берет на себя чипсет, сохраняя программную совместимость с 8253/8254. Микросхемы 8253 и 8254 представляют собой трехканальные программируемые счетчики-таймеры (рис. 1) с независимыми входами CLK – вход счетных импульсов и GATE – вход разрешения счета и выходом OUT, изменяющим состояние по окончании счета


[1] Символ # в конце обозначения сигнала или вывода микросхемы означает, что активным значением этого сигнала является логический «0»

Внутренние счетчики микросхемы имеют разрядность 16 бит, но общение с ними возможно только 8-битными операциями. При этом можно задавать значение только младшего байта счетчика (LSB - least significant bit), только старшего (MSB - most significant bit) или обоих (LSB/MSB), причем сначала передается младший, а потом старший байт. Программирование микросхемы осуществляется записью байт в управляющий регистр по отдельности для каждого канала. Назначение регистров счетчиков-таймеров приведено в таблице 1. Все каналы работают в режиме генерации импульсов, в канале 2 используется управляющий вход GATE, высокий уровень которого разрешает счет (формирование выходного сигнала, см. ниже). Счет для каналов 0 и 1 разрешен постоянно. Входная частота для всех каналов 1,19318 МГц.

Таблица 1 Регистры счетчиков-таймеров

Порт, R/W

Назначение

Параметры

040 RW

Счетчик 0 — системные часы

Генерация IRQO каждые 54,936 мс — частота 18,206 Гц.

Режим 011, LSB/MSB, Binary, константа счетчика=0 (соответствует коэффициенту деления 65536)

041 RW

Счетчик 1 — регенерация памяти

DRQO для XT, логика регенерации — для AT.

Режим 010, LSB, Binary, константа счетчика -12h (18)

042 RW

Счетчик 2 — генератор звука.

Вход GATE от бита 0 порта В 8255 (061).

Режим 011, LSB/MSB, Binary, значение счетчика определяет высоту тона

043 W

Управляющий регистр

Биты 7, 6 — выбор счетчика 0, 1,2.

Биты 5, 4 — режим обращения:

00 — защелка текущего значения,

01 — LSB — только младший байт,

10 — MSB — только старший байт,

11 — LSB/MSB — сначала младший, затем старший байты.

Биты 3-1 — режим счетчика:

000 — прерывание по счетчику,

001 — ждущий мультивибратор (одновибратор),

х10 — генератор коротких импульсов заданной частоты,

x11 — генератор меандра,

100 — счетчик событий с разрешением,

101 — счетчик событий с перезапуском.

Бит 0 — режим счета

0 = Binary (двоичный счет),

1 = BCD — (двоично-десятичный счет)

 

 

Канал управления звуком (PC Speaker)

Cтандартный канал управления звуком PC Speaker рассчитан на подключение высокоомного малогабаритного динамика. Логическая схема канала приведена на рис. 2. Звук формируется из тонального сигнала от второго канала таймера, работой которого можно программно управлять. Частоту сигнала (тон) можно изменять, программируя коэффициент деления счетчика. Кроме того, разрешая/запрещая формирование сигнала программно-управляемым битом 1 системного порта 61h, можно подавать сигналы определенной длительности. Такой способ формирования звука мало загружает даже процессор 8086/88 и позволяет исполнять незамысловатые мелодии, причем и в фоновом режиме, посылая команды из очереди по прерываниям от системного таймера. А с учетом физиологии слуха (инерционности восприятия) быстрым переключением частот можно достигать эффекта псевдомногоголооия. Таймер генерирует выходной сигнал при высоком уровне на входе GATE2 (при единичном значении бита 0 порта 61h). При низком уровне на входе GATE2 таймер формирует высокий уровень на выходе.

Рис. 1. Канал управления звуком

Более интересные звуки можно извлекать, используя принцип широтно-импульсной модуляции, программно осуществляемый через бит 1 порта 61h. При этом на входе GATE таймера должен быть низкий уровень (бит 0 порта 61h должен быть нулевым), чтобы на выходе OUT2 установился высокий уровень. В этом случае динамик играет роль фильтра нижних частот (инерционного звена) демодулятора.

 

 

Порядок выполнения лабораторной работы

1. Внимательно изучите исходный код процедуры sound по первому листингу, приведенному в приложении. Просмотрите текст других подпрограмм и общую структуру модуля в файле «sound.asm».

 

2. По табл.1 проверьте правильность задания байта, записываемого в управляющий регистр (порт 43h) счетчика-таймера:

используемый счетчик – 210 = (10)2

режим обращения – запись двух байт младшего и старшего – (11)2

режим работы – генерация меандра – (011)2

режим счета – двоичный (0)2

 

3. Найдите шестнадцатеричный код частоты системного генератора 1193180 Гц. Подставьте два старших байта этого в команду задания старших байт делимого (регистр dx), а два младших байта – в команду задания младших байт делимого (регистр ax). Деление этого числа на заданную частоту звучания, передаваемую через регистр di, обеспечит определение периода генерируемого меандра на выходе счетчика.

 

4. Запустите программу на трансляцию, компоновку и выполнение. Для выполнения всех трех этапов обработки программы одной командой подготовьте командный файл, например, с именем TALR.BAT, содержащий три строки текста

..\tasm\tasm.exe /l %1.asm

..\tasm\utilites\tlink %1.obj

%1.exe

В приведенной записи этого файла полагалось, что папка (каталог) с файлами турбо ассемблера и папка с вашими рабочими файлами расположены на одной в одной и той же папке верхнего уровня, а папка utilites с программой компоновщиком tlink.exe вложена в папку tasm. Для обработки исходной программы запустите командный файл непосредственно в сеансе DOS или с помощью файлового менеджера (Norton Commander, Volkov Commader, FAR Commander):

talr имявашейпрограммыбезрасширения

 

5. Запишите время выполнения программы, выведенное на дисплей. Если в течение времени выполнения программы системное время перешло границу минут и выведенное число секунд неправдоподобно велико, запустите готовую программу на выполнение еще раз. Добейтесь чтобы время выполнения программы (время звучания звукового сигнала), составило 10 с +/- 0.1 с. Для этого в тело цикла создающего требуемую задержку вставьте необходимое количество команд JCXZ $+2 (переход на адрес следующей команды, если содержимое регистра CX равно 0, т.е. безусловный переход на следующую команду). Эта команда обычно используется для формирования задержки, поскольку ее выполнение требует 9 тактов процессора 8086, что больше чем у большинства других, а сама команда занимает в памяти всего два байта.

Добившись приближенного к 10 с времени звучания сигнала (в пределах 8 – 13 с), найдите точное значение количества повторений цикла задержки. Требуемое значение находится из пропорции

__Tзв__

30000

=

_ 10 _ ,

X

где Tзв – фактическое время звучания,

X – требуемое число повторений цикла.

Подставьте полученное число в команду, помеченную меткой wt: и снова запустите программу на обработку. При наличии камертона или абсолютного слуха проверьте частоту звучания сигнала 440 Гц. При отклонении частоты от заданной в процедуре beep проверьте правильность перевода частоты системного генератора в шестнадцатиричную форму и правильность записи команд загрузки этого числа в регистры (dx, ax). Запишите число команд задержки и число повторений цикла задержки, обеспечивающие 10-секундное звучание сигнала.

 

6. Изучите исходный код подпрограмм файла «playsnd.asm». Перенесите в сокращенный вариант процедуры sound этого модуля параметры, определяющие частоту системного генератора и длительность звучания сигнала 0.01 с, найденные при запуске предыдущей программы.

 

7. Получите у преподавателя или воспользуйтесь своим вариантом нотной записи музыкального фрагмента. Составьте таблицу частот (в герцах) и соответствующую ей таблицу длительностей звучания всех нот (в единицах равных 0.01 с) музыкального фрагмента. Для составления этих таблиц воспользуйтесь таблицей частот звучания нот семи октав, приведенной в приложении. При определении частоты звучания ноты также можно воспользоваться формулой

Fi = Fk 2(i-k)/12 или Fi = 440 2(i-46)/12,

где i – номер ноты в таблице, Fk – известная частота звучания ноты с номером k, (i-k) – количество полутонов музыкального звукоряда между нотами i и k (в октаве – 12 полутонов, а частоты одноименных нот соседних октав отличаются вдвое).

Длительность звучания целой ноты полагается равной 2 с, то есть двести 0.01-секундных интервалов, половинной ноты – 1 с (100 интервалов) и т.д. Паузы кодируются тоном частотой 30000 Гц, заведомо не слышимой ухом, соответствующей длительности.

 

8. Запишите содержание составленных таблиц в качестве аргументов операторов определения данных freq dw и time dw модуля playsnd.asm. Окончание таблицы частот обозначается 2-байтовым завершающим словом, состоящим из одних единиц (0ffffh). Число слов в таблице частот с учетом завершающего слова должно быть на единицу больше числа слов в таблице длительностей. При повторении нескольких подряд идущих значений в таблицах частот или длительностей при записи пользуйтесь оператором повторения данных dup.

 

9. Запустите файл playsnd.asm на обработку с помощью командного файла:

talr playsnd.

Если воспроизведенная встроенным динамиком ПК мелодия содержит ошибки, то проверьте правильность кодировки и записи таблиц частот и длительностей.

Исходный код подпрограмм файла «sound.asm»
Структура вызовов подпрограмм и расположения данных.

 

; Генерация сигнала заданной частоты и длительности

astack segment stack

            dw 48 dup (?)                ; стек размером 96 байт

astack  ends

adata    segment

buffer    db 'time=   .  ',' sec  $'    ; область памяти для вывода на дисплей времени звучания

hsecs   db ?                             ;  место для записи сотых долей секунды текущего времени

secs     db ?                             ;  место для записи секунд текущего времени

tmp      db ?                             ;  место временного хранения управляющего слова системного порта

adata    ends

start     segment

            assume cs:start,ds:adata,ss:astack,es:adata

;

sound   proc

; Генерация сигнала длительностью 1/100 сек.

; с частотой, передаваемой в регистре [DI]

            push ax

            push bx

            push cx

            push dx

            push di

            mov al,0B6h     ; задание номера счетчика и выбор режима его работы

            out 43h,al

            mov dx,0010h  ; вместо 0010h подставьте значение двух старших байта входной частоты

            mov ax,1000h  ; вместо 1000h подставьте два младших байта входной частоты в Гц

            div di                ; вычисление длительности периода

            out 42h,al         ; запись в счетчик младшего байта периода

            jcxz $+2           ; задержка

            jcxz $+2

            mov al,ah

            out 42h,al         ; запись в счетчик старшего байта периода

            in al,61h           ; сохранение текущего управляющего слова

            mov tmp,al        ;  ...в ячейке tmp

            or al,3               ; включение...

            out 61h,al         ;   ...таймера

 

            mov ah,2ch       ; запрос системного времени

            int 21h             

            mov secs,dh

            mov hsecs,dl

 

wt:       mov cx,30000  ;  вместо 30000 подставьте точное количество повторения цикла

spkon:  jcxz $+2           ;  вставьте нужное

            jcxz $+2           ;                              количество

            loop spkon      ;                                                команд задержки

            dec bx

            jnz wt

            mov al,tmp

            out 61h,al         ; выключение таймера

            mov ah,2ch       ; запрос системного времени

            int 21h

            sub dl,hsecs     ; вычисление сотых долей секунды

            jnc sub_sec

            add dl,100

            dec dh

sub_sec:sub dh,secs    ; вычисление секунд звучания

            mov secs,dh

            mov al,dl

            cbw

            lea di,buffer+9

            call convert       ; преобразование сотых секунды в ASCII-код

            mov al,secs

            cbw

            lea di,buffer+6

            call convert       ; преобразование секунд в ASCII-код

            mov ah,9

            mov dx,offset buffer

            int 21h              ; вывод результатов на экран

            pop di

            pop dx

            pop cx

            pop bx

            pop ax

            ret

sound   endp

 

convert proc near

; Преобразование числа в ASCII-код

; [AX] - преобразуемое число,

; [DS]:[DI] - адрес буфера для размещения ASCII-кода

            push ax            ; сохраняем число

            mov al,'0'           ; заполняем...

            mov cx,2           ;   2 байта буферной...

            rep stosb          ;   области нулями

            pop ax              ; восстанавливаем число

            mov cx,10         ; записываем основание системы счисления

conloop:xor dx,dx          ; очищаем старший байт делимого

            div cx               ; делим [DX,AX] на 10

            add dl,30h         ; превращаем цифру остатка в ASCII-код

            dec di               ; продвигаем указатель буфера на 1 байт назад

            mov [di],dl         ; записываем в буфер ASCII-код цифры

            cmp ax,0          ; результат деления на 10 нулевой?

            jnz conloop       ; возврат, если результат ненулевой

            ret

convert endp

 

beep     proc far

; запуск процедуры sound

            push ds

            sub ax,ax

            push ax

            mov bx,adata

            mov ds,bx

            mov es,bx

            mov bx,1000     ; задаем длительность 1000 * 0.01 = 10 с

            mov di,440        ; задаем частоту 440 Гц  (звук Ля первой октавы)

            call sound

            ret

beep     endp

start     ends

            end beep


Исходный код подпрограмм файла «playsnd.asm»

 

; Программа проигрывания мелодии, заданной таблицей частот, которая 

; расположена по адресу freq и таблицей длительностей нот – по адресу time

;

; Структура вызова подпрограмм и расположения данных

;       __________       __________       __________      __ ___ __

;      |  proc    |     |  proc    |     |  proc    |    |         |

;      |  melody  |---->|  play    |<--->|  sound   |--->| динамик |

;      |__________|     |__________|     |__________|    |__ ___ __|

;                            Δ

;                            |

;                        ____V_____

;                       |  adata   |

;                       | segment  |

;                       |__________|

;

;

;       

astack  segment para stack 'stack'

            db 64 dup(?)

astack  ends

adata    segment para 'data'

;

;           Таблица частот:

freq       dw 330,294,262,294,3 dup(330)

            dw 3 dup(294),330,392,392,0ffffh

;

;           Таблица длительностей:

time      dw 6 dup(25),50

            dw 2 dup(25,25,50)

;

adata    ends

;

acode   segment

            assume ds:adata, cs:acode, ss:astack

play proc near

; Проигрывание мелодии с параметрами, заданными в регистрах:

; [SI] - адрес таблицы частот, заканчивающейся байтом 0FFFFH

; [BP] - адрес таблицы длительностей в 1/100 сек.

; целая_нота=200, 1/2=100, 1/4=50, 1/8=25, 1/16=12

            push bx

            push di

            push si

            push bp

zvuk:   mov di,[si]          ; загрузка частоты ноты из таблицы

            cmp di,0ffffh      ; проверка на достижение конца

            je  end_play      ; условный выход из цикла

            mov bx,ds:[bp]  ; загрузка длительности ноты

            call sound         ; вызов генератора звука

            add si,2                        ; продвижение по таблице частот

            add bp,2           ; продвижение по таблице длительностей

            jmp zvuk           ; переход к следующей ноте

end_play: pop bp

            pop si

            pop di

            pop bx

            ret

play endp

 

 

 

 

 

sound proc near

; Генерация сигнала заданной частоты и длительности

; [DI] - частота сигнала в Гц

; [BX] - длительность сигнала в 1/100 сек.

            push ax

            push bx

            push cx

            push dx

            push di

            mov al,0B6h     ; задание номера счетчика и выбор режима его работы

            out 43h,al

            mov dx,0010h  ; вместо 0010h подставьте значение двух старших байта входной частоты

            mov ax,1000h  ; вместо 1000h подставьте два младших байта входной частоты в Гц

            div di

            out 42h,al

            jcxz $+2

            jcxz $+2

            mov al,ah

            out 42h,al

            in al,61h

            mov dl,al

            or al,3

            out 61h,al

wt:       mov cx,30000  ;  вместо 30000 указать точное количество повторения цикла

spkon:  jcxz $+2           ;  вставить нужное

            jcxz $+2           ;                              количество

            loop spkon      ;                                                команд задержки

            dec bx                                 

            jnz wt

            mov al,dl

            out 61h,al

            pop di

            pop dx

            pop bx

            pop cx

            pop ax

            ret

sound   endp

 

 

 

melody proc far

; Запуск процедуры "play" и задание...

; адресов таблиц частот и длительностей

            push ds

            sub ax,ax

            push ax

            mov ax,adata

            mov ds,ax

            lea si,freq

            lea bp,ds:time

            call play

            ret

melody             endp

acode   ends

            end melody      

 

Таблица 2. Частота нот хроматической гаммы

До

До#

Ре

Ре#

Ми

Фа

Фа#

Соль

Соль#

Ля

Ля#

Си

Октава

1

2

3

4

5

6

7

8

9

10

11

12

Контроктава

33

35

37

39

41

44

46

49

52

55

58

62

13

14

15

16

17

18

19

20

21

22

23

24

Большая

65

69

73

78

82

87

92

98

104

110

117

123

25

26

27

28

29

30

31

32

33

34

35

36

Малая

131

139

147

156

165

175

185

196

208

220

233

247

37

38

39

40

41

42

43

44

45

46

47

48

Первая

262

277

294

311

330

349

370

392

415

440

466

494

49

50

51

52

53

54

55

56

57

58

59

60

Вторая

523

554

587

622

659

698

740

784

831

880

932

988

61

62

63

64

65

66

67

68

69

70

71

72

Третья

1047

1109

1175

1245

1319

1397

1480

1568

1661

1760

1865

1976

73

74

75

76

77

78

79

80

81

82

83

84

Четвертая

2093

2217

2349

2489

2637

2794

2960

3136

3322

3520

3729

3951

 Точка рядом с нотой увеличивает ее длительность на половину.