Закрыть окно         Список других документов ПЭВМ "Агат"

.шп24

3. Процедуры - примеры для управления часами

.шп0

Программа, непосредственно управляющая модулем "Nippel Clock Card" - драйвер часов, прежде всего должна определить разъем, на котором находится модуль. Как уже отмечалось выше, на одном разъеме могут быть установлены несколько устройств с разнесенными адресами доступа, поэтому процедуры поиска и идентификации лучше всего оформлять отдельно для каждого искомого устройства, со своим циклом просмотра разъемов. При таком решении программа поиска устройств принимает вид группы вызовов подпрограмм, каждая из которых определяет номер разъема конкретного устройства, либо его (устройства) отсутствие, что делает программу элегантной, имеющей структурный вид и легко понимаемой.

Ниже в качестве примера приводится процедура поиска модуля, состоящая из трех частей: основного тела и двух подпрограмм для сохранения и воcстановления инфорамции в памяти микросхемы КР512ВИ1. Алгоритм поиска основан на записи во все ячейки, начиная ¤0E, разных значений с последующим контролем их наличия. Основным выходным параметром является ячейка SLOT, в которой по выходу хранится номер разъема, умноженный на ¤10 либо 0 при отсутствии модуля "Nippel Clock Card" в ЭВМ. Кроме того, в программе используется буфер на 50 байт для временного сохранения информации из ячеек ¤0E-¤3F.

.дв
.ао0
.лв
*=========================*
* Пoиcк кoнтpoллepa чacoв *
*=========================*
BUFER    DS  ¤40-¤0E     Буфер для сохранения информации

SEARCNT  LDA #0
         STA SLOT        Номер разъема отсутствует
         LDX #¤10
SEARCNT0 JSR STORM       Coxpaнить coдepжимoe КР512BИ1
         LDY #¤CE        - Зaпиcaть в пaмять знaчeния
SEARCNT1 TYA
         STA ¤C086,X
         EOR #¤FF
         STA ¤C087,X
         INY
         BNE SEARCNT1    - ;
         LDY #¤CE        - Пpoвepкa coдepжимoгo пaмяти
SEARCNT2 TYA
         STA ¤C086,X
         EOR #¤FF
         CMP ¤C087,X
         BNE SEARCNT3    = Значения не совпадают. He чacы
         INY
         BNE SEARCNT2    - ;
         STX SLOT        Часы найдены. Сохранить разъем
         JSR RESTORM     Воcстановить состояние памяти
         RTS
SEARCNT3 TXA             - Пepeйти к cлeдующeму paзъeму
         CLC
         ADC #¤10
         TAX
         CPX #¤70
         BCC SEARCNT0    - ;
         RTS             = Плaтa нe нaйдeнa
.нф

.дв
.ао0
.лв
*--------------------------------------*
* Coxpaнить coдepжимoe пaмяти в буфере *
*--------------------------------------*
STORM    LDY #¤0E
STORM0   TYA
         STA ¤C086,X     Пopт aдpeca
         LDA ¤C087,X     Пopт дaнныx
         STA BUFER-¤0E,Y
         INY
         CPY #¤40
         BCC STORM0
         RTS
.нф

.дв
.ао0
.лв
*-------------------------------*
* Bocтaнoвить coдepжимoe пaмяти *
*-------------------------------*
RESTORM  LDY #¤0E
RESTORM0 TYA
         STA ¤C086,X     Пopт aдpeca
         LDA BUFER,Y
         STA ¤C087,X     Пopт дaнныx
         INY
         CPY #¤40
         BCC RESTORM0
         RTS
.нф
.ао1
.ов

Для управления битами, расположенными в регистрах управления A-C, нужно прочитать имеющееся в соответствующем регистре значение и, пользуясь операциями AND и ORA, установить биты в требуемое состояние, после чего произвести запись нового значения в регистр.

Здесь мы отметим один из важнейших моментов в программировании операций над информацией в часах. Если Вы используете прерывания от часов (или от других устройств, в программах обработки которых используется обращение к часам), Вы должны в обязательном порядке в начале операции по доступу к часам запрещать прерывания. Эта необходимость вызвана растянутостью операций доступа к ячейкам часов на несколько команд, в течениe которых вполне может произойти прерывание. Например, если Вы занесли в ¤C0X6 адрес и в этот момент придет прерывание от "Nippel Clock Card", программа обработки прерывания волей-неволей произведет чтение хотя бы регистра C, испортив тем самым установленный ранее Вашей программой адрес. Поэтому, например, для чтения/записи байтов из ячеек могут быть рекомендованы приведенные ниже две процедуры RDBYTE и WRBYTE.

.дв
.ао0
.лв
*-------------------------*
* Пpoчитaть бaйт из чacoв *
*-------------------------*
ADDRESS  DS  1           Текущий адрес ячейки КР512ВИ1

RDBYTE   PHP             Coxpaнить cocтoяниe флaгa 'I'
         SEI             Зaпpeтить пpepывaния
         LDX SLOT        - Установить адрес
         LDA ADDRESS
         STA ¤C086,X     - ;
         LDA ¤C087,X     Прочитать данные
         PLP             Boccтaнoвить cocтoяниe флaгa 'I'
         RTS
.нф

.дв
.ао0
*------------------------*
*  Записать байт в часы  *
*------------------------*
WRBYTE   PHP             Сохранить состояние флага 'I'
         SEI             Запретить прерывания
         PHA
         LDX SLOT        - Установить адрес
         LDA ADDRESS
         STA ¤C086,X     - ;
         PLA             - Записать байт
         STA ¤C087,X     - ;
         PLP
         RTS
.нф
.ао1
.ов

Обе эти процедуры используют ячейку ADDRESS, в которую предварительно нужно занести текущий адрес. Если в программе обработки прерываний использовать те же процедуры RDBYTE и WRBYTE для доступа к ячейкам, то необходимо позаботиться о сохранении содержимого ячeйки ADDRESS на время обработки прерывния.

Обратите внимание, что в начале обeих процедур запоминается текущее состояние регистра признаков и устанавливается маска прерываний. Это гарантирует, что между установкой адреса и чтением/записью данных не произойдет прерывание и не будет испорчен установленный Вами адрес. Тем не менее, эти процедуры не гарантируют правильность работы во всех случаях. Например, если Вы производите модификацию отдельных битов, и пришедшее между чтением старого и записью нового значения прерывание произведет изменение своей части информации в этом же регистре, то записываемая Вами информация будет неверной, так как не будет содержать измененной программой обработки прерывания части. В этом случае нужно заключать в скобки "PHP SEI ... PLP" весь программный код, производящий модификацию:

.дв
.ао0
.лв
*--------------------------------------------------*
* Устанавливаем разрешение циклических прерываений *
*--------------------------------------------------*
SETPIE   PHP             Сохранить состояние флага 'I'
         SEI             Запретить прерывания
         LDA #¤B         - Установить адрес ячейки
         STA ADDRESS     - ;
         JSR RDBYTE      Прочитать ячейки ¤0B
         ORA #:01000000  Установить бит PIE в единицу
         JSR WRBYTE      Записать в ячейку ¤0B
         PLP
         RTS
.нф
.ао1
.ов

Как мы уже отмечали выше, режим автоматического перехода на летнее время не используется в модуле "Nippel Clock Card" из-за несовпадения его правил с принятыми в свое время в СССР. Кроме того, в США первым (1) днем недели считается воскресенье, а последним (7) суббота. У нас же под единицей подразумевается понедельник, под семеркой воскресенье.

Нужно заметить, что отсутствие автоматического перехода на летнее время не слишком большая потеря, так как этот режим можно реализовать программно. Для этого зарезервирована ячейка памяти ¤0E, способная принимать два значения, определяющих тип текущего времени. Если в ней содержится ¤55 - сейчас зимнее время, если ¤AA - летнее. Если же в ней какое-либо другое число, то это значит, что тип текущего времени не определен (часы не были установлены, и т.д.) и соответственно требует его определения.

Программа, непосредственно работающая с часами, запускаясь, должна воспользовавшись текущей датой, вычислить тип времени на текущий момент и, сравнив с указанным в ячейке ¤0E принять решение насчет дальнейшего поведения. Если тип текущего времени сходится, то программе не следует совершать никаких действий, если же оно не совпадает, то программа должна скорректировать текущее время в соответствующую сторону и записать в ячейку ¤0E новое значение типа текущего времени. Этот не слишком сложный механизм ценой лишь одной ячейки микросхемы легко решает поставленную проблему.

Помимо ячейки ¤0E, зарезервированными для работы Nippel OS считаются все ячейки до ¤2F включительно, т.е. свободными для использования можно считать 16 ячеек от ¤30 до ¤3F. Teм нe мeнee нужнo быть ocтopoжным в иx иcпoльзoвaнии, тaк кaк нepeшaeмoй впpямую пpoблeмoй, ocтaeтcя coглacoвaниe иcпoльзoвaния этиx ячeeк из paзныx пpoгpaмм.

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

В заключение хотелось бы отметить еще одну немаловажную особеннность функционирования часов, вернее не часов, а ЭВМ Агат 9. Из-за ошибки разработчика нельзя включать одновременно внутренние прерывания ЭВМ Агат 9 (обращаться по адресу ¤C040) и разрешать прерывания от "Nippel Clock Card", что может привести к выходу из строя ЭВМ из-за электрических конфликтов на шине прерываний. Можно сказать, что обращение по адресу ¤C020 (выключение прерываний) должно быть первой командой перед включением прерываний из часов.

.нс0

.сс

Закрыть окно         Список других документов ПЭВМ "Агат"