УКНЦ Худяков Практика работы с ПП

Материал из Emuverse

Худяков Р.К.

ПРАКТИКА РАБОТЫ С ПЕРИФЕРИЙНЫМ ПРОЦЕССОРОМ УКНЦ

Статья в журнале "ИНФО" 1993 г., № 1.

Основной целью создания ЭВМ УКНЦ было ее применение в ходе
учебного процесса в школах, но  доступность и относительно низкая
стоимость сделали ее популярной и для частных пользователей.
   Особенностью ее архитектуры является наличие дополнительного
процессора. В принципе в корпусе УКНЦ собрано два микрокомпьютера,
каждый из которых оснащен собственным ОЗУ и набором собственных устройств.
Такая архитектура позволила резко разгрузить центральный процессор, кото-
рый выполняет в основном функции управления локальной сетью, а такие
функции, как вывод информации на экран и печать, а так же работу с
внешними накопителями информации переложить на периферийный процессор.
Методика работы с центральным процессором не вызывает затруднений.

	В данной статье дано описание практической работы с некоторыми
устройствами магистрали периферийного процессора ЭВМ УКНЦ.

	Прежде чем программа будет работать в ОЗУ ПП ее нужно туда загрузить.
Остановимся на этом поподробнее. Формат массива параметров (далее МП )
изображен на рис. 1

MASSIV:	.Byte	0	;В этом байте будет содержаться код ошибки или 0
COMAND:	.Byte	0	;Команда (01-ВЫДЕЛИТЬ ПАМЯТЬ,02-ОСВОБОДИТЬ ПАМЯТЬ
			;	    10-ЧТЕНИЕ,20-ЗАПИСЬ,30-ПУСК)
TYPDEV:	.Word	32	;Устройство-периферийный процессор
ADR$PP:	.Word	0	;Адрес ОЗУ ПП
ADR$CP:	.Word	0	;Адрес ОЗУ ЦП
LENGTH:	.Word	0	;Длина программы в словах (не байтах !)
ADRMAS:	.Word	MASSIV	;Слово всегда содержит начальный адрес массива
	.Word	401	;Стоповый элемент (используется при передаче)

Рис. 1

Команды "ВЫДЕЛИТЬ ПАМЯТЬ","ОСВОБОДИТЬ ПАМЯТЬ","ЧТЕНИЕ","ЗАПИСЬ","ПУСК"

Для правильного выполнения команды "ВЫДЕЛИТЬ ПАМЯТЬ" поле COMAND МП
должен содержать код 01,TYPDEV код 32,а поле LENGTH длину загружаемой
программы. Значение остальных полей значения не имеет.
После пересылки МП в поле ADR$PP ПП возвращает адрес , начиная с которого
после команды "ЗАПИСЬ" и будет размещена пересылаемая программа.
При повторном запросе выделение памяти производится из оставшейся свободной.
Если размер программы превосходит размер свободной памяти в ПП,
то в поле LENGTH МП возвращается длина свободной памяти,а поле MASSIV
не будет равно нулю.

	Для команды "ОСВОБОДИТЬ ПАМЯТЬ" полe COMAND должно содержать код 02,
а поля ADR$PP и LENGTH - те же параметры которые задавались при
выделении данного сегмента. Иначе команда не будет выполнена,а поле
MASSIV будет содержать ненулевое значение.

	Для команд "ЧТЕНИЕ"("ЗАПИСЬ") поле COMAND содежит соответственно
коды 10(20),а поле ADR$CP aдрес ОЗУ ЦП откуда (куда) будет
пересылаться программа.

	Для команды "ПУСК" поле COMAND содержит код 30,а поле ADR$PP
стартовый адрес программы. Сама программа должна быть оформлена
как подпрограмма (заканчиваться RTS PC),и быть перемещаемой,
так как место ее размещения заранее неизвестно.

На рис. 2 приведена подпрограмма загрузки МП в ПП.

ZAGR:	.Enable	LSB		;
	MOV	#ADRMAS,R0	;Адрес МП в R0
	MOV	#5,R1		;
	BR	1$		;Передать четыре байта (два слова
2$:	MOVB	(R0)+,@#176676	;поле ADRMAS и слово содержащее 401
1$:	TSTB	@#176674	;
	BPL	.-4		;
	SOB	R1,2$		;
	RTS	PC		;Вернуться

рис. 2

Подпрограмма передает по каналу К2 адрес массива параметров и два бай-
та завершения передачи нормализующие состояние канала.

На рис. 3 приведена "полная" подпрограмма загрузки программы,
ее пуска и затем освобождения памяти ПП по окончанию работы.

ZAGPP:	.Enable	LSB
	MOVB	#1,СOMAND	;Отработать команду "ВЫДЕЛИТЬ ПАМЯТЬ"
	MOV	(R5),OCP	;Через R5 передается табличка из
	CALL	ZAGR		;двух слов. 1-е длина программы
				;2-е ее начальный адрес в ОЗУ ЦП
	TSTB	MASSIV		;A памяти хватит ?
	BEQ	1$		;Да.
	MOV	#NOMEM,R0	;Выведем сообщение об ошибке
	EMT	351		;"Не хватает памяти"
	CMP	(R5)+,(R5)+	;Увеличим R5 на четыре
	SEC			;Установим признак ошибки
	BR	2$		;И на выход
				;
1$:	MOVB	#20,COMAND	;Отработать "ЗАПИСЬ"
	MOV	(R5)+,LENGTH	;Из таблички 1-е слово в LENGTH,
	MOV	(R5)+,ADR$CP	;а 2-е в ADR$CP
	CALL	ZAGR		;
	MOVB	#30,COMAND	;Отработать "ПУСК"
	CALL	ZAGR		;
	MOVB	#2,COMAND	;Отработать "ОСВОБОДИТЬ ПАМЯТЬ"
	MOV	-4(R5),ADR$CP	;
	CALL	ZAGR		;
2$:	RTS	R5		;Вернуться

рис. 3

   Формат вызова подпрограммы на рис. 4

 .MACRO	$ZAGPP	STADR,ENDADR

	JSR	R5,ZAGPP
	.WORD	<ENDADR-STADR/2>,STADR

 .ENDM	$ZAGPP

  А это полностью законченая программа

	.TITLE	MYPROG

START:	$ZAGPP	STARTPP,ENDPP	;Загрузить программу
	EMT	350		;Выход в монитор

	  ;Здесь находятся сами подпрограммы,сообщения и массив параметров

STARTPP: INC	(PC)+		;Эту программу можно заменить любой другой
	.WORD	0		;---*---*---*---*---*---*---*---*---*---*-
	RTS	PC		;Вернуться в ЦП
ENDPP:
	.END	START

рис. 4

   Итак программа в ПП загружена. Работа с регистрами внешних
устройств не отличается от обычной. Адресное пространство ОЗУ ПП
имеет диапазон 0-77777 , ПЗУ ПП - 100000-177777, то есть
32 кбайт ОЗУ и 32 кбайт ПЗУ. Так же как и ЦП , ПП имеет свой
пультовый отладчик , облегчающий отладку программ (вход в него
осуществляется из меню установок одновременным нажатием клавиш
<УПР> и <@>). Работать с ним нужно так же , как и с пультовым
отладчиком в центральном процессоре.
Давайте лучше поговорим о дополнительных возможностях которые могут
быть использованы только при помощи ПП , при разработке программ.
Начнем со средств отображения.
Для начала "пощелкаем" палитрой. В УКНЦ любой цвет выводимый на
экран можно представить любым другим (например поменять местами
красный на зеленый и(или) фиолетовый на бирюзовый и т.д.,хоть
черный на белый и наоборот). Допустим Вы поменяли синий
на белый. Теперь все , что Вы запишете в голубой план на экране появит-
ся белым цветом,причем,если какая либо другая программа не изменит
значения соответствующей ячейки памяти,то даже после выхода в мони-
тор ,все ,что по идее должно было бы отображаться на экране голубым,
будет отображаться белым,включая любую графическую информацию.
Следует заметить , что замена цветов происходит очень быстро
(практически мгновенно), на этом можно построить интересные эффекты.

	Формат ячеек управления аппаратным отображением на рис. 5
Каждый из цветов представлен четырьмя битами.
.SWT
АДРЕС - |0000|0000|0000|0000|   АДРЕС+2 - |0000|0000|0000|0000|
	белый желт фиол красн		  бирюз зел голуб черн

   Таких пар ячеек  - 4 . Их назначение приведено в табл. 1

Каждая из четырех тетрад в каждом слове представлена соответственно
(побитно слева направо) -
Яркость цвета. 1-100% яркости , 0-50% яркости
Красный цвет   1-красный есть , 0-красного нет
Зеленый цвет   1-зеленый есть , 0-зеленого нет
Голубой цвет   1-голубой есть , 0-голубого нет

Здесь следует заметить одну деталь. На машинах з-да "КВАНТ"
литеры 5 из схемы контроллера цветного монитора удалена
ИС 155ЛП9 , поэтому изменения яркостного бита ни к чему не
приводят, а на почти половине машин з-да "СЭМЗ" ИС 155ЛП9
заменена на ИС 155ЛН2 поэтому в яркостный бит для получения
100% яркости нужно записать 0 , а для 50% - 1 , но опять
же все выше сказанное справедливо только для цветного монитора.
На отображение градаций яркости на черно-белом мониторе этот
бит не влияет.
Так же последние полтора года изменена схема подключения
цветного монитора (поменяны между собой выходы красного зеленого цветов).
Это тоже следует иметь ввиду.
___________________________________________
!   АДРЕС    ! ГДЕ БУДУТ ИЗМЕНЯТЬСЯ ЦВЕТА !
+-----------------------------------------+
! 2400,2402  !   Верхняя служебная строка !
! 2470,2472  !   Собственно сам экран     !
! 4700,4702  !   Меню установок           !
! 6750,6752  !   Нижняя служебная строка  !
-------------------------------------------

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

	MOV	#2470,R0	;Адрес палитры экрана в R0
	MOV	(R0),-(SP)	;Запомнить в стеке текущее значение
	MOV	2(R0),-(SP)	;палитры
	CLR	(R0)		;Выключить экран
	CLR	2(R0)		;(все цвета на экране представить черным)
				;
	MOV	#100000,@#177010;
	MOV	#30.,R1		;
2$:	MOV	#20.,R2		;
1$:	MOVB	#377,@#177012	;Нарисовать квадратик
	INC	@#177010	;
	SOB	R2,1$		;
	ADD	#<80.-20.>,@#177010 ;
	SOB	R1,2$		;
				;
	MOV	#1,R1		;"Щелкаем" палитру.
3$:	MOV	R1,R3		;
	.REPT	4		;Четыре раза ASL R3
	ASL	R3		;
	.ENDR			;
	BIC	#360,(R0)	;
	BIS	R3,(R0)		;Квадратик отображается
	CLR	R2		;Цветами от голубого до белого
	SOB	R2,.		;<-задержка
	SOB	R2,.		;<-задержка
	INC	R1		;
	CMP	#8.,R1		;
	BNE	3$		;
				;
	MOV	(SP)+,2(R0)	;Возвращаем предыдущие значения
	MOV	(SP)+,(R0)	;Ячейкам
	RTS	PC		;Возврат

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

	MOV	PC,R0		;
	ADD	#SOOB-.,R0	;Вычислить адрес сообщения
	MOV	R0,AMT		;
	MOV	PC,R0		;
	ADD	#SOOB1-.,R0	;То же
	MOV	R0,AMT1		;
				;
	MOV	#135230,@#2400	;Разрешить вывод на экран всех цветов
	MOV	#177334,@#2402	;для верхней служебной строки
	MOV	#135230,@#6750	;То же сделать и для нижней
	MOV	#177334,@#6752	;
				;
	MOV	#1,@#22614	;Цвет символов в верхней строке - голубой
	MOV	#3,@#23106	;Цвет символов в нижней строке - бирюзовый
				;
	MOV	#63146,@#22620	;Цвет знакоместа в верхней строке - желтый
	MOV	#52525,@#22622	;
				;
	MOV	#52525,@#23112	;Цвет знакоместа в нижней строке - фиолетовый
	MOV	#42104,@#23114	;
				;
	MOV	#67,@#2372	;Верхняя строка в формате - 4 (10Х24)
	MOV	#47,@#6742	;Нижняя строка в формате - 3 (20Х24)
				;
	EMT	52		;Вывести сообщение в верхнюю строку
AMT:	.WORD	0		;Здесь находится адрес сообщения
	EMT	56		;Вывести сообщение в нижнюю строку
AMT1:	.WORD	0		;Здесь находится адрес второго сообщения
	RTS	PC		;Возврат в ЦП

SOOB:	.ASCIZ	<40.>/"ТЕХНОКОМ"/
SOOB1:	.ASCIZ	<40.>"    ПРЕДСТАВЛЯЕТ    "
	.EVEN

   Ячейки с адресами 2400,2402 (6750,6752) отвечают за палитру вывода для
верхней (нижней) служебной строки. Их формат был описан выше.
   В ячейках 22614,23106 хранится цвет символа в формате 0-черный
1-голубой,2-зеленый,...,7-белый, а в ячейках 23112,23114 цвет знакоместа
в формате регистра кода цвета фона (177020,177022). Формат этих регистров
будет рассмотрен ниже. Следует заметить ,что в исходном состоянии после
включения питания голубой план для вывода в служебные строки заблокирован.

Пример программы с изменением палитры вывода.

	MOV	PC,R0		;Вычислить адрес сообщения
	ADD	#SOOB-.,R0	;
	MOV	R0,AMT		;
	MOV	PC,R0		;То же
	ADD	#SOOB1-.,R0	;
	MOV	R0,AMT1		;
	EMT	52		;Вывести "ТЕХНОКОМ" в верхнюю строку
AMT:	.WORD	0		;Здесь адрес сообщения
	EMT	56		;Вывести "ПРЕДСТАВЛЯЕТ" в нижнюю строку
AMT1:	.WORD	0		;Здесь адрес второго сообщения
				;
	MOV	#67,@#2372	;Формат верхней строки - 4 (10Х24)
	MOV	#47,@#6742	;Формат нижней строки - 3 (20Х24)
	MOV	#135236,@#2400	;Для верхней строки представляем желтый цвет
	MOV	#174734,@#2402	;голубым, а черный желтым
	MOV	#135235,@#6750	;Для нижней строки представляем желтый цвет
	MOV	#175734,@#6752	;бирюзовым, а черный фиолетовым
	RTS	PC		;Возврат

SOOB:	.ASCIZ	<40.>/"ТЕХНОКОМ"/
SOOB1:	.ASCIZ	<40.>"    ПРЕДСТАВЛЯЕТ    "
	.EVEN

   Требования при выводе текстовой информации в служебные строки таковы:
первый байт любого сообщения это байт позиционирования,
а сам текст сообщения должен быть восьмибитным, т.к. коды <РУС> и <ЛАТ>
(<16> и <17> восьм.) при печати не отрабатываются.

	Теперь немного о выводе графической информации из ПП.
Есть целая группа регистров существенно облегчающая этот процесс. Перечис-
лим их.

177016 (Запись/Чтение) - Регистр кода цвета точки
Формат - Число от 0 до 7 (цвет точки)

177024 (Запись)- Регистр октета точки
Формат - Восьмеричное число от 0 до 377 (восемь бит - восемь точек на экране
	бит содежит 1 - точка зажжена , 0 - погашена)

177020 - Регистр кода цвета фона. Планы 0-1
177022 - Регистр кода цвета фона. Планы 1-2
Формат - Оба регистра представляют собой единое целое

  4    3    2    1    - номер точки в октете
!0000!0000!0000!0000! - 177020
  RGB  RGB  RGB  RGB  - красный,зеленый,голубой планы

  8    7    6    5    - номер точки в октете
!0000!0000!0000!0000! - 177022
  RGB  RGB  RGB  RGB  - красный,зеленый,голубой планы

Старший бит каждой тетрады не используется.

Допустим нужно получить на экране такой байт, чтобы первая точка
была черной, вторая голубой, третья зеленой, четвертая бирюзовой, ...... ,
восьмая белой. 

Для этого нужно записать в 177020 число 0011 0010 0001 0000
(двоичное) , а в 177022 - 0111 0110 0101 0100 (двоичное).

177026 - Регистр маски планов
Формат - Число от 0 до 7 (один или несколько планов в которые нужно зап-
	ретить запись информации).

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

	MOV	#^B0011001000010000,@#177020
		 ;Загрузить регистр кода цвета
	MOV	#^B0111011001010100,@#177022
		 ;фона по принципу 1-я точка
			;черная , восьмая - белая
	MOV	#100000,@#177010
		 ;Загрузить адрес планов в регистр адреса
				;планов.
	MOV	#<264.*80.>,R1	;В R1 общее число байтов экранной зоны
1$:	CLR	@#177024	;"Чистим" текущий октет
	INC	@#177010	;Увеличим на 1 адрес в планах
	SOB	R1,1$		;Все это в цикле

		;НА ЭКРАНЕ ВИДНЫ ЦВЕТНЫЕ ПОЛОСКИ

	MOV	#^B0100010101100111,@#177020
		 ;Загрузить другие значения
	MOV	#^B0000000100100011,@#177022
		 ;цвета фона
				;
	MOV	PC,R2		;
	ADD	#SPRITE-.,R2	;Адрес спрайта в R2
	MOV	#100000,@#177010 ;Адрес в планах - 100000
	MOV	#7,@#177016	;Выводить будем белым
	MOV	#11,R0		;Размеры спрайта Y - 11, X - 21
3$:	MOV	#21,R1		;

	;ЭТУ ЧАСТЬ ВЫДЕЛИМ

2$:	MOVB	(R2)+,@#177024	;Байты из которых состоит спрайт по
				;порядку на экран
	;КОНЕЦ ВЫДЕЛЕННОЙ ЧАСТИ

	INC	@#177010	;Увеличим адрес в планах на 1
	SOB	R1,2$		;Следующий байт на экран
	ADD	#<80.-21>,@#177010 ;Отступить для вывода следующей строки
	SOB	R0,3$		;спрайта.
	RTS	PC		;Возврат

	;НИЖЕ ДАН САМ СПРАЙТ

SPRITE:	.Byte 377,7,377,37,36,36,74,170,340,77,360,340,201,377,300,3,17
	.Byte 61,6,6,30,30,6,30,60,60,140,140,140,300,200,201,3,7
	.Byte 60,0,6,0,60,3,30,60,30,300,140,60,140,0,203,207,7
	.Byte 60,0,6,0,340,1,30,60,30,300,140,30,140,0,203,315,6
	.Byte 60,0,376,1,300,0,370,77,30,300,340,17,140,0,203,171,6
	.Byte 60,0,6,0,340,1,30,60,30,300,140,30,140,0,203,61,6
	.Byte 60,0,6,0,60,3,30,60,30,300,140,60,140,0,203,1,6
	.Byte 60,0,6,30,30,6,30,60,60,140,140,140,300,200,201,1,6
	.Byte 170,0,377,37,36,36,74,170,340,77,360,340,201,377,300,3,217
	.Even
ENDPRG:				;Конец программы в ПП

   Вывод информации на экран может быть двух видов - с прорисовкой
новой информации по старому фону и со стиранием старой информации.
Чтобы рисовать по старому фону нужно к регистру 177024 адресоваться
байтно (MOVB) , а со стиранием - словно (MOV). Чтобы в приведенном
выше примере обеспечить прорисовку со стиранием нужно выделенную
часть программы заменить на следующую:
.SWT
2$:	MOVB	(R2)+,R3
	MOV	R3,@#177024	;Байты из которых состоит спрайт по

   Как видно , с помощью этой группы регистров можно существенно повысить
скорость выода графики , однако иногда и этой скорости не хватает.
Можно еще в несколько раз ее увеличть , используя нерегистровый (прямой)
доступ к видеоОЗУ. Но об этом в следующий раз.

   Теперь немного о музыке , которую можно извлекать из УКНЦ.
Звук из динамика УКНЦ можно получить при помощи регистров 177710 и 177716.
В регистре 177716 разряды с 7 по 12 позволяют получить звуки с частотой
от 60 Гц до 64 кГц при частоте программируемого таймера 2,4,8 и 16
микросекунд.
Приведем таблицу соответствия комбинаций разрядов 8-16 регистра 177716 и
разрядов 1,2 регистра 177710.

----------------------------------------------------------------
!        РАЗРЯДЫ РЕГ. 177716       ! ЧАСТОТА ЗВУКОВОГО СИГНАЛА !
!     7     ! 12 ! 11 ! 10 ! 9 ! 8 !			       !
----------------------------------------------------------------
! ПРОГРАММНО!    !    !    !   !   !			       !
!ФОРМИРУЕТСЯ!  0 !  0 !  0 ! 0 ! 0 ! СООТВЕТСТВУЕТ ПРОГРАММЕ   !
----------------------------------------------------------------
!           !  0 !  0 !  0 ! 0 ! 1 !         60 Гц             !
!           !  0 !  0 !  0 ! 1 ! 0 !        250 Гц             !
!     1     !  0 !  0 !  1 ! 0 ! 0 !        500 Гц             !
!           !  0 !  1 !  0 ! 0 ! 0 !         1 кГц             !
!           !  1 !  0 !  0 ! 0 ! 0 !         8 кГц             !
----------------------------------------------------------------
!     0     !     ЗВУК ОТКЛЮЧЕН    !			       !
----------------------------------------------------------------
!     1     ! КОМБИНАЦИЯ ЛОГИЧЕСКИХ! СБОРКА СЕТКИ ЧАСТОТ ПО "И"!
!           !       ЗНАЧЕНИЙ       !			       !
----------------------------------------------------------------
! ПРОГРАММНО!    !    !    !   !   ! СБОРКА СЕТКИ ЧАСТОТ ПО "И"!
!ФОРМИРУЕТСЯ!  * !  * !  * ! * ! * ! ПРОМОДУЛИРОВАНА ПРОГРАММОЙ!
----------------------------------------------------------------

   Внесем ясность. Частоты звука приведены для тактовой частоты таймера
16 мкс. Если же тактовая частота равна 8 мкс , то значения частот звука
в правой колонке увеличатся в 2 раза (соответственно для 4 мкс в 4 раза, а
для 2 мкс в 8 раз).


Если разряды 8-12 содежат 0 , то частота звука будет зависеть от того
с какой скоростью 7 разряд переключается из 0 в 1. Здесь способ извлече-
ния звука прост. Меняя значение загружаемое для задержки мы управляем
высотой звука. Программа , которая приведена ниже работает именно по
этому принципу.

	BIS	#6,@#177710	;Тактовая чатота таймера 16 мкс
	BIC	#17400,@#177716	;Очистить разряды с 8 по 12
	MOV	#200,R0		;Установить в R0  7 разряд 
1$:	XOR	R0,@#177716 ;Если он есть,то снять его и наоборот
	MOV	#<от этого числа зависит высота звука>,R1 ;
	SOB	R1,.		;Задержка именно на этом числе
	BR	1$		;Бесконечный цикл

   Этот способ имеет существенный недостаток. На разных машинах
высота звука будет "плавать",т.к. быстродействие ПП меняется от
машины к машине из-за разброса параметров элементной базы.
Устранить данный недостаток можно собирая "свои" частоты из набора
стандартных. Так как сама сборка ведется по "И", ( одна частота
модулирует собой другую ) то можно управляя частотой программируемого
таймера и комбинируя значения разрядов 8-12 регистра 177716 добиваться
исполнения несложных мелодий.

-----------------------------------------------
!РАЗРЯДЫ РЕГ. 177710! ПЕРИОД ТАКТОВОЙ ЧАСТОТЫ !
!    2    !    1    !			      !
-----------------------------------------------
!    0    !    0    !   2 микросекунды        !
!    0    !    1    !   4 микросекунды        !
!    1    !    0    !   8 микросекунды        !
!    1    !    1    !   16 микросекунд        !
-----------------------------------------------

   Данный способ позволяет получить стабильный звук , но его недостаток
очевиден. Крайне трудно получить требуемые ноты. Гораздо лучше исполь-
зовать программируемый таймер в "чистом" виде в режиме прерываний.
Достоинства данного способа: чистый стабильный звук, подбор частоты
до единиц герц и наконец легкость практической реализации. Действитель-
но , раз можно плавно менять высоту звука и его длительнось (это реали-
зуется на другом таймере - сетевом) , то уже можно исполнять довольно
сложные мелодии. Для облегчения задачи приведем значения частот звучания
нот двух октав в герцах.

  1-ая октава
	До - 130,8
	До-диез,Ре-бемоль - 138,6
	Ре - 146,8
	Ре-диез,Ми-бемоль - 155,6
	Ми - 164,8
	Фа - 174,6
	Фа-диез,Соль-бемоль - 185,0
	Соль - 196,0
	Соль-диез,Ля-бемоль - 207,7
	Ля - 220,0
	Ля-диез,Си-бемоль - 233,1
	Си - 246,9
	Среднее До - 261,7
  2-ая октава
	До-диез,Ре-бемоль - 277,2
	Ре - 293,7
	Ре-диез,Ми-бемоль - 311,1
	Ми - 329,6
	Фа - 349,2
	Фа-диез,Соль-бемоль - 370,0
	Соль - 392,0
	Соль-диез,Ля-бемоль - 415,3
	Ля - 440,0
	Ля-диез,Си-бемоль - 466,2
	Си - 493,9
	Среднее До - 523,3

   Пример программы иллюстрирующий применение программируемого таймера.

	MOV	PC,R0		;Вычислить адрес программы обработки
	ADD	#POP-.,R0	;прерываний от программируемого таймера
	MOV	R0,@#304	;Загрузить этот адрес в вектор прерывания
	MOV	PC,R0		;Вычислить адрес программы обработки
	ADD	#POPT-.,R0	;прерываний от сетевого таймера
	MOV	R0,@#100	;Загрузить этот адрес в вектор прерывания
	MOV	PC,R0		;Вычислить начальный адрес массива с
	ADD	#MUZON-.,R0	;музыкой
	MOV	R0,ADRESS	;Загрузить этот адрес в ячейку ADRESS
	MOV	R0,EADRES	;Вычислить и загрузить в ячейку EADRES
	ADD	#<EP-MUZON>,EADRES ;конечный адрес массива с музыкой
	BIS	#107,@#177710	;Установить период тактовой частоты
	RTS	PC		;программируемого таймера 16 мкс и
				;разрешить прерывания от него

				;ПРОГРАММА ОБРАБОТКИ ПРЕРЫВАНИЙ ОТ 
POPT:	.ENABLE	LSB		;СЕТЕВОГО ТАЙМЕРА
	DEC	(PC)+		;Уменьшить на 1 содержимое ячейки COUNT
COUNT:	.WORD	50.		;50 тиков - это 1 секунда (длит. ноты)
	BNE	1$		;Если секунда не истекла , то на выход
	MOV	@ADRESS,TON+2	;Сыграть очередную ноту из массива
	ADD	#2,ADRESS	;Перейти на следующую ноту
	CMP	EADRES,ADRESS	;А не конец ли массива ?
	BNE	2$		;
	SUB	#<EP-MUZON>,ADRESS ;Да . Вернемся к началу
2$:	MOV	#50.,COUNT	;1 секунда в COUNT
1$:	JMP	@#174612	;Выход из прерывания

				;ПРОГРАММА ОБРАБОТКИ ПРЕРЫВАНИЙ ОТ 
POP:	.ENABLE	LSB		;ПРОГРАММИРУЕМОГО ТАЙМЕРА
	TST	@#177714	;Очистить регистр текущего значения
				;пр. тайм.
	MOV	R0,-(SP)	;Сохранить в стеке R0
	MOV	#200,R0		;Загрузить число 200 в R0
	XOR	R0,@#177716	;7 разряд если есть - снять , и наоборот
	MOV	(SP)+,R0	;Восстановить R0
TON:	MOV	#0,@#177712	;Загрузить текущее значение ячейки TON+2
				;в буферный регистр прогр. таймера
	RTI			;Возврат из прерывания

ADRESS:	.WORD	0		;Ячейка хранения начального адреса массива
EADRES:	.WORD	0		;Ячейка хранения конечного адреса массива

	;Далее следует сам массив с музыкой

MUZON:	.WORD	478.	;Нота До первой октавы
	.WORD	426.	;Нота Ре первой октавы
	.WORD	379.	;Нота Ми первой октавы
	.WORD	358.	;Нота Фа первой октавы
	.WORD	319.	;Нота Соль первой октавы
	.WORD	284.	;Нота Ля первой октавы
	.WORD	253.	;Нота Си первой октавы
	.WORD	239.	;Срединное До
	.WORD	213.	;Нота Ре второй октавы
	.WORD	190.	;Нота Ми второй октавы
	.WORD	179.	;Нота Фа второй октавы
	.WORD	159.	;Нота Соль второй октавы
	.WORD	142.	;Нота Ля второй октавы
	.WORD	127.	;Нота Си второй октавы
	.WORD	119.	;Нота До второй октавы

EP:				;Конец программы в ПП

   Эта программа проигрывает указанные ноты по порядку в цикле. Значения
чисел соответствующие реальным звуковым частотам рассчитываются по формуле
A/F, где A число соответствующее тактовой частоте программируемого таймера
( для периода 16 мкс А=62500, для 8 мкс A=125000, для 4 мкс A=250000, для
2 мкс A=500000 (все значения десятичные)), а F - частота которую требуется
получить. В заключеие обратим внимание на то , что буферный регистр
программируемого таймера (177712) 12-ти а не 16-ти разрядный. Об этом сле-
дует помнить при загрузке данных в регистр.