Цель работы – изучение архитектуры системных устройств персонального компьютера и приемов их программирования на языке ассемблера. Наряду с микропроцессором в состав персонального компьютера входит ряд системных и периферийных устройств, без которых невозможна его нормальная работа. Данная лабораторная работа посвящена изучению
·
внутренней организации системных устройств ПК, · методов программирования системных и периферийных устройств ПК, · использования отладчиков программного обеспечения
|
|||||||||||||||
Функциональные узлы системной платы 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 Регистры счетчиков-таймеров |
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
Канал управления звуком (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зв – фактическое время звучания, 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. Частота нот хроматической гаммы |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Точка рядом с нотой увеличивает ее длительность на половину.