forked from KolibriOS/kolibrios
520 lines
28 KiB
Plaintext
520 lines
28 KiB
Plaintext
|
Компилятор языка программирования Oberon-07/16 для
|
|||
|
микроконтроллеров MSP430x{1,2}xx.
|
|||
|
------------------------------------------------------------------------------
|
|||
|
|
|||
|
Параметры командной строки
|
|||
|
|
|||
|
Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
|
|||
|
UTF-8 с BOM-сигнатурой.
|
|||
|
Выход - hex-файл прошивки.
|
|||
|
Параметры:
|
|||
|
1) имя главного модуля
|
|||
|
2) "msp430"
|
|||
|
3) необязательные параметры-ключи
|
|||
|
-out <file_name> имя результирующего файла; по умолчанию,
|
|||
|
совпадает с именем главного модуля, но с расширением ".hex"
|
|||
|
-ram <size> размер ОЗУ в байтах (128 - 2048) по умолчанию 128
|
|||
|
-rom <size> размер ПЗУ в байтах (2048 - 24576) по умолчанию 2048
|
|||
|
-nochk <"ptibcwra"> отключить проверки при выполнении
|
|||
|
-lower разрешить ключевые слова и встроенные идентификаторы в
|
|||
|
нижнем регистре
|
|||
|
-def <имя> задать символ условной компиляции
|
|||
|
|
|||
|
параметр -nochk задается в виде строки из символов:
|
|||
|
"p" - указатели
|
|||
|
"t" - типы
|
|||
|
"i" - индексы
|
|||
|
"b" - неявное приведение INTEGER к BYTE
|
|||
|
"c" - диапазон аргумента функции CHR
|
|||
|
"a" - все проверки
|
|||
|
|
|||
|
Порядок символов может быть любым. Наличие в строке того или иного
|
|||
|
символа отключает соответствующую проверку.
|
|||
|
|
|||
|
Например: -nochk it - отключить проверку индексов и охрану типа.
|
|||
|
-nochk a - отключить все отключаемые проверки.
|
|||
|
|
|||
|
Например:
|
|||
|
|
|||
|
Compiler.exe "C:\example.ob07" msp430 -ram 128 -rom 4096 -nochk pti
|
|||
|
Compiler.exe "C:\example.ob07" msp430 -out "C:\Ex1.hex" -ram 512 -rom 16384
|
|||
|
|
|||
|
В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
|
|||
|
При работе компилятора в KolibriOS, код завершения не передается.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Отличия от оригинала
|
|||
|
|
|||
|
1. Расширен псевдомодуль SYSTEM
|
|||
|
2. В идентификаторах допускается символ "_"
|
|||
|
3. Усовершенствован оператор CASE (добавлены константные выражения в
|
|||
|
метках вариантов и необязательная ветка ELSE)
|
|||
|
4. Расширен набор стандартных процедур
|
|||
|
5. Семантика охраны/проверки типа уточнена для нулевого указателя
|
|||
|
6. Добавлены однострочные комментарии (начинаются с пары символов "//")
|
|||
|
7. Разрешено наследование от типа-указателя
|
|||
|
8. "Строки" можно заключать также в одиночные кавычки: 'строка'
|
|||
|
9. Добавлена операция конкатенации строковых и символьных констант
|
|||
|
10. Добавлены кодовые процедуры
|
|||
|
11. Не реализована вещественная арифметика
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Особенности реализации
|
|||
|
|
|||
|
1. Основные типы
|
|||
|
|
|||
|
Тип Диапазон значений Размер, байт
|
|||
|
|
|||
|
INTEGER -32768 .. 32767 2
|
|||
|
CHAR символ ASCII (0X .. 0FFX) 1
|
|||
|
BOOLEAN FALSE, TRUE 1
|
|||
|
SET множество из целых чисел {0 .. 15} 2
|
|||
|
BYTE 0 .. 255 1
|
|||
|
|
|||
|
2. Максимальная длина идентификаторов - 1024 символов
|
|||
|
3. Максимальная длина строковых констант - 1024 символов (UTF-8)
|
|||
|
4. Максимальная размерность открытых массивов - 5
|
|||
|
5. Процедура NEW заполняет нулями выделенный блок памяти
|
|||
|
6. Локальные переменные инициализируются нулями
|
|||
|
7. В отличие от многих Oberon-реализаций, сборщик мусора и динамическая
|
|||
|
модульность отсутствуют
|
|||
|
8. Тип BYTE в выражениях всегда приводится к INTEGER
|
|||
|
9. Контроль переполнения значений выражений не производится
|
|||
|
10. Ошибки времени выполнения:
|
|||
|
|
|||
|
номер ошибка
|
|||
|
|
|||
|
1 ASSERT(x), при x = FALSE
|
|||
|
2 разыменование нулевого указателя
|
|||
|
3 целочисленное деление на неположительное число
|
|||
|
4 вызов процедуры через процедурную переменную с нулевым значением
|
|||
|
5 ошибка охраны типа
|
|||
|
6 нарушение границ массива
|
|||
|
7 непредусмотренное значение выражения в операторе CASE
|
|||
|
8 ошибка копирования массивов v := x, если LEN(v) < LEN(x)
|
|||
|
9 CHR(x), если (x < 0) OR (x > 255)
|
|||
|
11 неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255)
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Псевдомодуль SYSTEM
|
|||
|
|
|||
|
Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
|
|||
|
ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
|
|||
|
повреждению данных времени выполнения и аварийному завершению программы.
|
|||
|
|
|||
|
PROCEDURE ADR(v: любой тип): INTEGER
|
|||
|
v - переменная или процедура;
|
|||
|
возвращает адрес v
|
|||
|
|
|||
|
PROCEDURE SADR(x: строковая константа): INTEGER
|
|||
|
возвращает адрес x
|
|||
|
|
|||
|
PROCEDURE SIZE(T): INTEGER
|
|||
|
возвращает размер типа T
|
|||
|
|
|||
|
PROCEDURE TYPEID(T): INTEGER
|
|||
|
T - тип-запись или тип-указатель,
|
|||
|
возвращает номер типа в таблице типов-записей
|
|||
|
|
|||
|
PROCEDURE MOVE(Source, Dest, n: INTEGER)
|
|||
|
Копирует n байт памяти из Source в Dest,
|
|||
|
области Source и Dest не могут перекрываться
|
|||
|
|
|||
|
PROCEDURE GET(a: INTEGER;
|
|||
|
VAR v: любой основной тип, PROCEDURE, POINTER)
|
|||
|
v := Память[a]
|
|||
|
|
|||
|
PROCEDURE GET8(a: INTEGER; VAR x: INTEGER, SET, BYTE, CHAR)
|
|||
|
Эквивалентно
|
|||
|
SYSTEM.MOVE(a, SYSTEM.ADR(x), 1)
|
|||
|
|
|||
|
PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER)
|
|||
|
Память[a] := x;
|
|||
|
Если x: BYTE, то значение x будет расширено до 16 бит,
|
|||
|
для записи байтов использовать SYSTEM.PUT8
|
|||
|
|
|||
|
PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR)
|
|||
|
Память[a] := младшие 8 бит (x)
|
|||
|
|
|||
|
PROCEDURE CODE(word1, word2,... : INTEGER)
|
|||
|
Вставка машинного кода,
|
|||
|
word1, word2 ... - целочисленные константы (константные
|
|||
|
выражения) - машинные слова, например:
|
|||
|
SYSTEM.CODE(0D032H, 0010H) (* BIS #16, SR; CPUOFF *)
|
|||
|
|
|||
|
|
|||
|
Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Оператор CASE
|
|||
|
|
|||
|
Синтаксис оператора CASE:
|
|||
|
|
|||
|
CaseStatement =
|
|||
|
CASE Expression OF Сase {"|" Сase}
|
|||
|
[ELSE StatementSequence] END.
|
|||
|
Case = [CaseLabelList ":" StatementSequence].
|
|||
|
CaseLabelList = CaseLabels {"," CaseLabels}.
|
|||
|
CaseLabels = ConstExpression [".." ConstExpression].
|
|||
|
|
|||
|
Например:
|
|||
|
|
|||
|
CASE x OF
|
|||
|
|-1: DoSomething1
|
|||
|
| 1: DoSomething2
|
|||
|
| 0: DoSomething3
|
|||
|
ELSE
|
|||
|
DoSomething4
|
|||
|
END
|
|||
|
|
|||
|
В метках вариантов можно использовать константные выражения, ветка ELSE
|
|||
|
необязательна. Если значение x не соответствует ни одному варианту и ELSE
|
|||
|
отсутствует, то программа прерывается с ошибкой времени выполнения.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Конкатенация строковых и символьных констант
|
|||
|
|
|||
|
Допускается конкатенация ("+") константных строк и символов типа CHAR:
|
|||
|
|
|||
|
str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
|
|||
|
|
|||
|
newline = 0DX + 0AX;
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Проверка и охрана типа нулевого указателя
|
|||
|
|
|||
|
Оригинальное сообщение о языке не определяет поведение программы при
|
|||
|
выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
|
|||
|
Oberon-реализациях выполнение такой операции приводит к ошибке времени
|
|||
|
выполнения. В данной реализации охрана типа нулевого указателя не приводит к
|
|||
|
ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
|
|||
|
значительно сократить частоту применения охраны типа.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Дополнительные стандартные процедуры
|
|||
|
|
|||
|
|
|||
|
COPY (x: ARRAY OF CHAR; VAR v: ARRAY OF CHAR);
|
|||
|
v := x;
|
|||
|
Если LEN(v) < LEN(x), то строка x будет скопирована
|
|||
|
не полностью.
|
|||
|
|
|||
|
LSR (x, n: INTEGER): INTEGER
|
|||
|
Логический сдвиг x на n бит вправо.
|
|||
|
|
|||
|
MIN (a, b: INTEGER): INTEGER
|
|||
|
Минимум из двух значений.
|
|||
|
|
|||
|
MAX (a, b: INTEGER): INTEGER
|
|||
|
Максимум из двух значений.
|
|||
|
|
|||
|
BITS (x: INTEGER): SET
|
|||
|
Интерпретирует x как значение типа SET.
|
|||
|
Выполняется на этапе компиляции.
|
|||
|
|
|||
|
LENGTH (s: ARRAY OF CHAR): INTEGER
|
|||
|
Длина 0X-завершенной строки s, без учета символа 0X.
|
|||
|
Если символ 0X отсутствует, функция возвращает длину
|
|||
|
массива s. s не может быть константой.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Использование регистров общего назначения R4 - R15
|
|||
|
|
|||
|
R4 - R7: регистровый стэк (промежуточные значения выражений)
|
|||
|
R8 - R13: не используются
|
|||
|
R14: указатель кучи
|
|||
|
R15: используется при обработке прерываний
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Вызов процедур и кадр стэка
|
|||
|
|
|||
|
Правила вызова похожи на соглашение cdecl (x86):
|
|||
|
- параметры передаются через стэк справа налево
|
|||
|
- результат, если есть, передается через регистр R4
|
|||
|
- вызывающая процедура очищает стэк
|
|||
|
|
|||
|
Состояние стэка при выполнении процедуры:
|
|||
|
|
|||
|
меньшие адреса <- |var3|var2|var1|PC|arg1|arg2|arg3| -> бОльшие адреса
|
|||
|
|
|||
|
PC - значение регистра PC перед вызовом (адрес возврата)
|
|||
|
argX - параметры в порядке объявления (слева направо)
|
|||
|
varX - локальные переменные в порядке использования в процедуре
|
|||
|
|
|||
|
Размер каждого элемента в стэке (кроме локальных переменных структурных
|
|||
|
типов) - 1 машинное слово (2 байта). Структурные переменные (массивы и
|
|||
|
записи) занимают место в стэке в соответствии с их размером (с учетом
|
|||
|
выравнивания).
|
|||
|
|
|||
|
Размещение локальных переменных зависит от их размеров и порядка
|
|||
|
использования, и в общем случае неопределенно. Если переменная не
|
|||
|
используется явно, то компилятор не выделяет для нее место в стэке.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Скрытые параметры процедур
|
|||
|
|
|||
|
Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
|
|||
|
формальных параметров, но учитываются компилятором при трансляции вызовов.
|
|||
|
Это возможно в следующих случаях:
|
|||
|
|
|||
|
1. Процедура имеет формальный параметр открытый массив:
|
|||
|
PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL);
|
|||
|
Вызов транслируется так:
|
|||
|
Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x))
|
|||
|
2. Процедура имеет формальный параметр-переменную типа RECORD:
|
|||
|
PROCEDURE Proc (VAR x: Rec);
|
|||
|
Вызов транслируется так:
|
|||
|
Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Кодовые процедуры
|
|||
|
|
|||
|
Компилятор поддерживает процедуры, написаные в машинных кодах.
|
|||
|
Синтаксис:
|
|||
|
|
|||
|
PROCEDURE "[code]" имя [ (параметры): ТипРезультата ]
|
|||
|
МашСлово, МашСлово,... МашСлово;
|
|||
|
|
|||
|
";" после заголовка и END "имя" в конце процедуры не ставятся.
|
|||
|
МашСлово - целочисленная константа (в том числе и константное выражение).
|
|||
|
Например:
|
|||
|
|
|||
|
PROCEDURE [code] asr (n, x: INTEGER): INTEGER (* ASR(x, n) -> R4 *)
|
|||
|
4115H, 2, (* MOV 2(SP), R5; R5 <- n *)
|
|||
|
4114H, 4, (* MOV 4(SP), R4; R4 <- x *)
|
|||
|
0F035H, 15, (* AND #15, R5 *)
|
|||
|
2400H + 3, (* JZ L1 *)
|
|||
|
(* L2: *)
|
|||
|
1104H, (* RRA R4 *)
|
|||
|
8315H, (* SUB #1, R5 *)
|
|||
|
2000H + 400H - 3; (* JNZ L2 *)
|
|||
|
(* L1: *)
|
|||
|
|
|||
|
Компилятор автоматически добавляет к такой процедуре команду RET.
|
|||
|
Способ передачи параметров и результата не изменяется.
|
|||
|
|
|||
|
Кодовые процедуры можно использовать также и для добавления в программу
|
|||
|
константных данных:
|
|||
|
|
|||
|
PROCEDURE [code] sqr
|
|||
|
0, 1, 4, 9, 16, 25, 36, 49, 64, 81;
|
|||
|
|
|||
|
Получить адрес такой "процедуры": SYSTEM.ADR(sqr).
|
|||
|
Получить адрес n-го машинного слова: SYSTEM.ADR(sqr) + n * 2.
|
|||
|
|
|||
|
Чтобы использовать кодовые процедуры, необходимо импортировать псевдомодуль
|
|||
|
SYSTEM.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Обработка прерываний
|
|||
|
|
|||
|
При появлении запроса на прерывание, процессор:
|
|||
|
- помещает в стэк значение регистра PC
|
|||
|
- помещает в стэк значение регистра SR
|
|||
|
- очищает регистр SR
|
|||
|
- выполняет переход по адресу IV[priority], где
|
|||
|
IV - таблица векторов прерываний,
|
|||
|
priority - приоритет прерывания (номер элемента в таблице IV) (0..30)
|
|||
|
|
|||
|
Компилятор генерирует код обработки прерываний:
|
|||
|
|
|||
|
; IV[0] = адрес следующей команды
|
|||
|
PUSH #0 ; поместить в стэк приоритет прерывания
|
|||
|
JMP Label ; перейти к обработчику
|
|||
|
|
|||
|
; IV[1] = адрес следующей команды
|
|||
|
PUSH #1 ; поместить в стэк приоритет прерывания
|
|||
|
JMP Label ; перейти к обработчику
|
|||
|
|
|||
|
...
|
|||
|
; IV[priority] = адрес следующей команды
|
|||
|
PUSH #priority ; поместить в стэк приоритет прерывания
|
|||
|
JMP Label ; перейти к обработчику
|
|||
|
|
|||
|
...
|
|||
|
; IV[30] = адрес следующей команды
|
|||
|
PUSH #30 ; поместить в стэк приоритет прерывания
|
|||
|
|
|||
|
Label:
|
|||
|
MOV SP, R15 ; настроить R15 на структуру данных прерывания (см. далее)
|
|||
|
PUSH R4 ; сохранить рабочие регистры (R4 - R7)
|
|||
|
...
|
|||
|
PUSH R7
|
|||
|
PUSH R15 ; передать параметр interrupt в обработчик (см. далее)
|
|||
|
PUSH @R15 ; передать параметр priority в обработчик (см. далее)
|
|||
|
CALL int ; вызвать обработчик (см. далее)
|
|||
|
ADD #4, SP ; удалить из стэка параметры обработчика
|
|||
|
POP R7 ; восстановить рабочие регистры (R7 - R4)
|
|||
|
...
|
|||
|
POP R4
|
|||
|
ADD #2, SP ; удалить из стэка значение priority
|
|||
|
RETI ; возврат из прерывания (восстановить SR и PC)
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Обработка ошибок
|
|||
|
|
|||
|
В случае возникновения ошибки при выполнении программы, будет вызван общий
|
|||
|
обработчик ошибок, который:
|
|||
|
|
|||
|
- запрещает прерывания
|
|||
|
- сбрасывает стэк (во избежание переполнения в процессе обработки ошибки)
|
|||
|
- передает параметры в пользовательский обработчик (см. далее)
|
|||
|
- вызывает пользовательский обработчик (если он назначен)
|
|||
|
- повторно запрещает прерывания
|
|||
|
- выключает CPU и все тактовые сигналы
|
|||
|
|
|||
|
Если выключать CPU не требуется, то пользовательский обработчик может,
|
|||
|
например, перезапустить программу.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Инициализация и финализация программы
|
|||
|
|
|||
|
В начало программы компилятор вставляет код, который:
|
|||
|
- инициализирует регистры SP и R14
|
|||
|
- выключает сторожевой таймер
|
|||
|
- назначает пустой обработчик прерываний
|
|||
|
- сбрасывает обработчик ошибок
|
|||
|
|
|||
|
В конец программы добавляет команду
|
|||
|
BIS #16, SR; выключить CPU
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Структура ОЗУ (RAM)
|
|||
|
|
|||
|
начало -> | спец. переменные | глобальные переменные | куча/стэк | <- конец
|
|||
|
|
|||
|
Компилятор поддерживает размер ОЗУ 128..2048 байт. В нижних адресах
|
|||
|
располагаются специальные переменные, и далее пользовательские глобальные
|
|||
|
переменные. Оставшаяся часть памяти отводится для кучи и стэка (не менее 64
|
|||
|
байта). При старте программы, в регистр R14 записывается адрес начала области
|
|||
|
кучи/стэка, а регистр SP настраивается на конец ОЗУ (начало_ОЗУ + размер_ОЗУ).
|
|||
|
При выделении памяти процедурой NEW, значение регистра R14 увеличивается (если
|
|||
|
есть свободная память). Таким образом, стэк и куча растут навстречу друг
|
|||
|
другу. Проверка переполнения стэка не производится.
|
|||
|
|
|||
|
------------------------------------------------------------------------------
|
|||
|
Структура ПЗУ (RОM)
|
|||
|
|
|||
|
начало -> |код|свободная область|спец. данные|векторы прерываний| <- конец
|
|||
|
|
|||
|
Компилятор поддерживает размер ПЗУ 2048..24576 байт. В верхних адресах
|
|||
|
располагается таблица векторов прерываний (64 байта), адреса 0FFC0H..0FFFFH.
|
|||
|
Непосредственно перед ней размещаются специальные данные. Программный
|
|||
|
код начинается с адреса (10000H - размер_ПЗУ), этот адрес является также и
|
|||
|
точкой входа в программу. Между кодом и спец. данными может оставаться
|
|||
|
свободное пространство. Если размер ПЗУ больше, чем указан при компиляции,
|
|||
|
то перед кодом будет свободная область. Таким способом можно зарезервировать
|
|||
|
нижние сегменты флэш-памяти для записи во время выполнения программы.
|
|||
|
|
|||
|
==============================================================================
|
|||
|
MODULE MSP430
|
|||
|
|
|||
|
CONST
|
|||
|
|
|||
|
биты регистра SR:
|
|||
|
|
|||
|
GIE = {3}
|
|||
|
CPUOFF = {4}
|
|||
|
OSCOFF = {5}
|
|||
|
SCG0 = {6}
|
|||
|
SCG1 = {7}
|
|||
|
|
|||
|
|
|||
|
TYPE
|
|||
|
|
|||
|
TInterrupt = RECORD priority: INTEGER; sr: SET; pc: INTEGER END
|
|||
|
структура данных прерывания
|
|||
|
|
|||
|
priority - приоритет прерывания:
|
|||
|
|
|||
|
адрес приоритет
|
|||
|
0FFFEH 31
|
|||
|
0FFFCH 30
|
|||
|
0FFFAH 29
|
|||
|
...
|
|||
|
0FFC0H 0
|
|||
|
|
|||
|
sr - сохраненное значение регистра SR
|
|||
|
pc - сохраненное значение регистра PC
|
|||
|
|
|||
|
|
|||
|
TTrapProc = PROCEDURE (modNum, modName, err, line: INTEGER);
|
|||
|
Процедура-обработчик ошибок.
|
|||
|
|
|||
|
modNum - номер модуля (в отчете о компиляции:
|
|||
|
compiling (modNum) "modName" )
|
|||
|
modName - адрес имени модуля
|
|||
|
err - номер ошибки
|
|||
|
line - номер строки
|
|||
|
|
|||
|
|
|||
|
TIntProc = PROCEDURE (priority: INTEGER; interrupt: TInterrupt)
|
|||
|
Процедура-обработчик прерываний.
|
|||
|
|
|||
|
priority - приоритет прерывания
|
|||
|
interrupt - структура данных прерывания
|
|||
|
|
|||
|
|
|||
|
PROCEDURE SetTrapProc (TrapProc: TTrapProc)
|
|||
|
Назначить обработчик ошибок.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE SetIntProc (IntProc: TIntProc)
|
|||
|
Назначить обработчик прерываний.
|
|||
|
|
|||
|
Нельзя вызывать эту процедуру с параметром NIL, т. к. для экономии
|
|||
|
тактов, значение адреса обработчика прерываний не проверяется на NIL.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE Restart
|
|||
|
Перезапустить программу.
|
|||
|
При этом: очищается регистр SR, повторно выполняется код инициализации
|
|||
|
программы (см. выше). Всё прочее состояние ОЗУ и регистров устройств
|
|||
|
сохраняется.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE SetIntPC (interrupt: TInterrupt; NewPC: INTEGER)
|
|||
|
interrupt.pc := NewPC
|
|||
|
После возврата из прерывания, регистр PC получит значение NewPC.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE SetIntSR (interrupt: TInterrupt; NewSR: SET)
|
|||
|
interrupt.sr := NewSR
|
|||
|
После возврата из прерывания, регистр SR получит значение NewSR.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE DInt
|
|||
|
Запретить прерывания.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE EInt
|
|||
|
Разрешить прерывания.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE CpuOff
|
|||
|
Выключить CPU (установить бит CPUOFF регистра SR).
|
|||
|
|
|||
|
|
|||
|
PROCEDURE Halt
|
|||
|
Запретить прерывания, выключить CPU и все тактовые сигналы.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE SetSR (bits: SET)
|
|||
|
Установить биты bits регистра SR.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE ClrSR (bits: SET)
|
|||
|
Сбросить биты bits регистра SR.
|
|||
|
|
|||
|
|
|||
|
PROCEDURE GetFreeFlash (VAR address, size: INTEGER)
|
|||
|
Получить адрес и размер свободной области Flash/ROM
|
|||
|
(между кодом и данными).
|
|||
|
|
|||
|
|
|||
|
PROCEDURE Delay (n: INTEGER)
|
|||
|
Задержка выполнения программы на 1000*n тактов,
|
|||
|
но не менее чем на 2000 тактов.
|
|||
|
|
|||
|
|
|||
|
==============================================================================
|