- •Декомпозиция задачи ввода данных в озу
- •Структуры данных
- •Разработка структуры данных программы для ввода данных в озу
- •Алгоритмизация программы
- •Подходы к алгоритмизации
- •Иерархическая организация алгоритма
- •Алгоритмизация программы для ввода данных в озу
- •1. Модуль "Тестовый контроль озу по шд" (dTstContr)
- •2. Модуль "Тестовый контроль озу по ша" (aTstContr)
- •3. Модуль "Вывод сообщений об ошибках" (ErMesOut)
- •4. Модуль "Ввод режимов" (ModeInput)
- •5. Модуль "Вывод сообщения о типе ввода" (InTpMesOut)
- •6. Модуль "Ввод с клавиатуры" (KbdInput)
- •7. Модуль "Контроль ввода с клавиатуры" (KbdInContr)
- •8. Модуль "Преобразование очередной цифры" (NxtDigTrf)
- •9. Модуль "Формирование информации" (InfoForm)
- •10. Модуль "Формирование массивов отображения" (DispForm)
- •11. Модуль "Вывод числовой информации" (NumInfOut)
- •12. Модуль "Функциональная подготовка" (FuncPrep)
- •3.4.4. Кодирование программы
- •Реализация логических конструкций структурного программирования
- •Кодирование программы для ввода данных в озу
- •3.4.5. Тестирование и отладка программы
- •3.4.6. Занесение программы на рабочий носитель
- •3.4.7. Оформление документации на программу
- •3.5. Проектирование аппаратных средств
- •3.5.1. Схемотехническое проектирование процессора
- •3.5.2. Схемотехническое проектирование памяти
- •Банкирование памяти
- •Организация банков памяти
- •Проектирование запоминающих устройств
- •3.5.3. Схемотехническое проектирование интерфейса
- •Организация ввода/вывода данных
- •3.5.4. Тестирование и настройка аппаратных средств
- •Тестирование статическими сигналами
- •Свободный прогон микропроцессора
- •3.6. Комплексная отладка микропроцессорной системы
- •Заключение
- •Список рекомендуемых источников
Кодирование программы для ввода данных в озу
Пример 3.10.
Выполнить кодирование программы работы устройства для ввода данных в ОЗУ.
Для решения поставленной задачи необходимо использовать результаты проектирования программы, полученные в примерах 3.1 3.4. При этом принятое кодирование данных представлено в таблице 3.1, а алгоритмы программы и программных модулей на рис. 3.24 3.37. Из их анализа следует, что многие модули выполняют ввод/вывод данных, что требует разработки архитектуры ввода/вывода проектируемого устройства для их кодирования. Архитектура ввода данных приведена на рис. 3.44, а архитектура вывода на рис. 3.45.
Для уменьшения аппаратурных затрат двоичные индикаторы "Тип ввода" ("Адрес"/"Данные") подключены к свободным разрядам Q7,Q6 клавиатурного порта вывода KbdPort. Клавиатурный порт ввода имеет то же имя KbdPort (тот же адрес), что и клавиатурный порт вывода, т. к. обращение к ним осуществляется разными управляющими сигналами (см. рис. 3.44,а).
Состояние управляющих переключателей вводится через порт ввода ModePort с нулевым кодированием активных значений (см. рис. 3.44,б).
В связи с использованием статической индикации каждый из знакосинтезирующих индикаторов дисплеев "Адрес" и "Данные" подключен к отдельному порту вывода. При этом порт младшего разряда дисплея "Адрес" имеет имя (адрес) ADispPort, а дисплея "Данные" DDispPort. Адреса портов более старших разрядов последовательно увеличиваются на 1 относительно адреса младшего порта (см. рис. 3.45,а).
Рис. 3.44. Архитектура ввода устройства для ввода данных в ОЗУ:
а) ввод с клавиатуры; б) ввод управляющих переключателей
а) б)
Рис. 3.45. Архитектура вывода устройства для ввода данных в ОЗУ:
а) вывод на индикаторы дисплеев; б) таблица преобразования
Свечение сегмента индикатора в приведенной схеме вызывается нулевым значением управляющего сигнала. С учетом этого в таблице на рис. 3.45,б представлены управляющие 7-сегментные коды, обеспечивающие отображение соответствующего графического знака в разряде дисплея. При этом отображаемые символы шестнадцатиричных цифр приведены в колонке Hex в стандартном начертании. Эта таблица используется для преобразования двоичного кода отображаемой 16-ричной цифры из формата 8 4 2 1 в семисегментный код.
Имея алгоритмы программы и программных модулей (см. рис. 3. – 3.37), структуру данных (см. табл. 3.1) и архитектуру ввода/вывода (см. рис. 3.44, 3.45), можно полностью разработать исходный текст проектируемой программы.
;ПРОГРАММА РАБОТЫ УСТРОЙСТВА ДЛЯ ВВОДА ДАННЫХ В ОЗУ
NAME DataInputProgram
; ОПИСАНИЕ ПОИМЕНОВАННЫХ КОНСТАНТ
-
KbdPort = 0
; Адреса портов
ModePort = 1
; архитектуры
AdispPort = 2
; ввода/вывода
DdispPort = 6
NMAX = 50
; Константа подавления дребезга
; ОПИСАНИЕ ДАННЫХ
Data1 |
|
SEGMENT AT 1000h |
|
|
|
Mode |
DB |
? |
; Структура |
|
InType |
DB |
? |
; данных |
|
AddrInc |
DB |
? |
; программы |
|
AddrDec |
DB |
? |
|
|
KbdImage |
DB |
4 DUP(?) |
|
|
NextDig |
DB |
? |
|
|
Addr |
DW |
? |
|
|
BufData |
DB |
? |
|
|
DataDisp |
DB |
2 DUP(?) |
|
|
AddrDisp |
DB |
4 DUP(?) |
|
|
EmpKbd |
DB |
? |
|
|
KbdErr |
DB |
? |
|
|
RAMErrD |
DB |
? |
|
|
RAMErrA |
DB |
? |
|
; ОПИСАНИЕ СЛУЖЕБНЫХ ЯЧЕЕК
|
ATstBuff |
DW |
17 DUP(?) |
; Буфер адресного теста |
|
MesBuff |
DB |
? |
; Буфер сообщения "Тип ввода" |
|
OldAddrModif |
DB |
? |
; Буфер старой модификации |
Data1 |
|
ENDS |
|
; адреса |
Data2 |
|
SEGMENT AT 2000h |
|
|
|
RAMData |
DW |
32768 DUP(?) |
; Формируемые данные |
Data2 |
|
ENDS |
|
|
; ОПИСАНИЕ СТЕКА
Stack |
|
SEGMENT AT 1000h |
|
|
|
|
ORG |
100h |
; Смещение за зону данных |
|
|
DW |
10 DUP(?) WORD |
|
|
StkTop |
LABEL |
|
|
Stack |
|
ENDS |
|
|
; ОПИСАНИЕ ВЫПОЛНЯЕМЫХ ДЕЙСТВИЙ
Code SEGMENT
ASSUME CS:Code, DS:Data1, ES:Data2, SS:Stack
; ОПИСАНИЕ ПРОГРАММНЫХ МОДУЛЕЙ
; Модуль "Функциональная подготовка"
-
FuncPrep
PROC
NEAR
; ГСА по рис. 3.37
MOV
InType, 0
; Тип ввода = "Адрес"
MOV
KbdErr, 0
; Очистка флага ошибки
; ввода с клавиатуры
MOV
BX, 0
; Очистка адреса
MOV
Addr, BX
MOV
AL, ES:[BX]
;Чтение байта из RAMData
; по нулевому адресу
MOV
BufData, AL
; Запись байта в буфер
MOV
OldAddrModif, 18h
; Старые команды"+1", "1"
; отсутствуют
RET
FuncPrep
ENDP
; 1. Модуль "Тестовый контроль ОЗУ по ШД"
-
DtstContr
PROC
NEAR
; ГСА по рис. 3.26
; Подготовка
MOV
RAMErrD, 0
; Сброс флага ошибки
LEA
BX, RAMData
; Загрузка адреса и
MOV
CX, LENGTH RAMData
; счетчика циклов
DTC2:
MOV
AX, ES:[BX]
; Сохранение ячейки
MOV
ES:[BX], 5555h
; Запись в ячейку
CMP
ES:[BX], 5555h
; Записано ?
JNE
DTC1
; Переход, если нет
MOV
ES:[BX], 0AAAAh
; Запись в ячейку
CMP
ES:[BX], 0AAAAh
; Записано ?
JNE
DTC1
; Переход, если нет
MOV
ES:[BX], AX
; Восстановление ячейки
ADD
BX, 2
; Модификация адреса
LOOP
DTC2
; Все ячейки ? Переход,
; если нет
JMP
SHORT DTC3
; На выход
DTC1:
MOV
RAMErrD, 0FFh
; Установка флага ошибки
DTC3:
RET
DTstContr
ENDP
; 2. Модуль "Тестовый контроль ОЗУ по ША"
-
ATstContr
PROC
NEAR
; ГСА по рис. 3.27
; Подготовка к записи
MOV
RAMErrA, 0
; Сброс флага ошибки
MOV
BX, 0
; Загрузка адреса ячейки влияния
STC
; и счетчика циклов
LEA
SI, ATstBuff
; Загрузка адреса буфера
ATC1:
MOV
AX, [BX]
; Сохранение ячейки
MOV
[SI], AX
; влияния
MOV
AX, BX
; Запись адреса в ячейку влияния
XOR
AL, AH
MOV
[BX], AL
ADD
SI, 2
; Модификация адреса буфера
RCL
BX, 1
; Модификация адреса ячейки
; влияния и счетчика циклов
OR
BX, BX
; Все ячейки влияния ?
JNZ
ATC1
; Переход, если нет
; Подготовка к анализу
MOV
BX, 0
; Загрузка адреса ячейки влияния
STC
; и счетчика циклов
LEA
SI, ATstBuff
; Загрузка адреса буфера
ATC3:
MOV
DL, [BX]
; Чтение из ячейки влияния
MOV
AX, BX
; Содержимое = адресу ?
XOR
AL, AH
CMP
AL, DL
JNE
ATC2
; Переход, если нет
MOV
AX, [SI]
; Восстановление ячейки
MOV
[BX], AX
; влияния
ADD
SI, 2
; Модификация адреса буфера
RCL
BX, 1
; Модификация адреса ячейки
; влияния и счетчика циклов
OR
BX, BX
; Все ячейки влияния ?
JNZ
ATC3
; Переход, если нет
JMP
SHORT ATC4
; На выход
ATC2:
MOV
RAMErrA, 0FFh
; Установка флага ошибки
ATC4:
RET
ATstContr
ENDP
;3. Модуль "Вывод сообщений об ошибках"
-
ErMesOut
PROC
NEAR
; ГСА по рис. 3.28
CMP
KbdErr, 0FFh
; Ошибка клавиатуры ?
JZ
EMO1
; Переход, если да
CMP
RAMErrD, 0FFh
; Ошибка ОЗУ по ШД ?
JZ
EMO2
; Переход, если да
CMP
RAMErrA, 0ffh
; Ошибка ОЗУ по ША ?
JNZ
EMO3
; Переход, если нет
; Вывод сообщения об отказе ОЗУ по ША "ErОП A"
-
CALL
ErrRAM
; Вывод сообщения ErОП
MOV
AL, 11h
; Вывод знака А
OUT
DDispPort, AL
JMP
SHORT EMO3
; На выход
; Вывод сообщения об отказе ОЗУ по ШД "ErОП d"
-
EMO2:
CALL
ErrRAM
; Вывод сообщения ErОП
MOV
AL, 85h
; Вывод знака d
OUT
DDispPort, AL
JMP
SHORT EMO3
; На выход
; Вывод сообщения об ошибке ввода с клавиатуры "Err НБ"
-
EMO1:
MOV
AL, 61h
; Вывод знака E
OUT
ADispPort + 3, AL
MOV
AL, 0F5h
; Вывод знака r
OUT
ADispPort + 2, AL
OUT
ADispPort + 1, AL
; Вывод знака r
MOV
AL, 0FFh
; Гашение знака
OUT
ADispPort, AL
MOV
AL, 91h
; Вывод знака H
OUT
DDispPort + 1, AL
MOV
AL, 41h
; Вывод знака Б
OUT
DDispPort, AL
EMO3:
RET
ErMesOut
ENDP
; Подмодуль "Вывод сообщения ErОП"
-
ErrRAM
PROC
MOV
AL, 61h
; Вывод знака E
OUT
ADispPort + 3, AL
MOV
AL, 0F5h
; Вывод знака r
OUT
ADispPort + 2, Al
MOV
AL, 03h
; Вывод знака О
OUT
ADispPort + 1, AL
MOV
AL, 13h
; Вывод знака П
OUT
ADispPort, AL
MOV
AL, 0FFh
; Гашение знака
OUT
DDispPort + 1, AL
RET
ErrRAM
ENDP
; 4. Модуль "Ввод режимов"
-
ModeInput
PROC
NEAR
; ГСА по рис. 3.29,а
; Подготовка
MOV
Mode, 0
; Режим = "Ввод"
MOV
AddrInc, 0
; Сброс флагов
MOV
AddrDec, 0
; модификации адреса
IN
AL, ModePort
; Ввод переключателей
MOV
DX, ModePort
; Передача параметра
CALL
VibrDestr
; Гашение дребезга
TEST
AL, 01h
; "Режим" = "Просмотр"?
JNZ
MI1
; Переход, если нет
MOV
Mode, 0FFh
; Режим = "Просмотр"
JMP
SHORT MI2
MI1
TEST
AL, 02h
; "Тип ввода" = "Адрес"?
JZ
MI2
; Переход, если да
TEST
AL, 04h
; "Тип ввода" = "Данные"?
JNZ
MI3
; Переход, если нет
MOV
InType, 0FFh
; Тип ввода = "Данные"
JMP
SHORT MI3
MI2:
MOV
InType, 0
; Тип ввода = "Адрес"
MI3:
MOV
AH, OldAddrModif
; Чтение старых значений
; сигналов "+1", "1"
MOV
OldAddrModif, AL
; Сохранение текущих
; значений сигналов "+1","1"
XOR
AL, AH
; Выделение ПФ сигналов
AND
AL, AH
; "+1","1"
TEST
AL, 08h
; ПФ"Адрес" = "+1"?
JNZ
MI4
; Переход, если нет
MOV
AddrInc, 0FFh
; Модификация адреса = "+1"
MI4:
TEST
AL, 10h
; ПФ"Адрес" = "1"?
JNZ
MI5
; Переход, если нет
MOV
AddrDec, 0FFh
; Модификация адреса = "1"
MI5:
RET
ModeInput
ENDP
; Подмодуль "Гашение дребезга"
-
VibrDestr
PROC
; ГСА по рис. 3.29,в
VD1:
MOV
AH, AL
; Сохранение исходного состояния
MOV
BH, 0
; Сброс счетчика повторений
VD2:
IN
AL, DX
; Ввод текущего состояния
CMP
AH, AL
; Текущее состояние = исходному?
JNE
VD1
; Переход, если нет
INC
BH
; Инкремент счетчика повторений
CMP
BH, NMAX
; Конец дребезга?
JNE
VD2
; Переход, если нет
MOV
AL, AH
; Восстановление местоположения
RET
; данных
VibrDestr
ENDP
; 5. Модуль "Вывод сообщения о типе ввода"
-
InTpMesOut
PROC
NEAR
; ГСА по рис. 3.30
MOV
AL, 40H
; Сообщение
; "Тип ввода" = "Адрес"
CMP
InType, 0
; Тип ввода = "Адрес"?
JE
ITMO1
; Переход, если да
MOV
AL, 80h
; Сообщение
; "Тип ввода" = "Данные"
ITMO1:
MOV
MesBuff, AL
; Сохранение сообщения
; "Тип ввода"
OR
AL, 0Fh
; Вывод сообщения
OUT
KbdPort, AL
; "Тип ввода"
RET
InTpMesOut
ENDP
; 6. Модуль "Ввод с клавиатуры"
-
KbdInput
PROC
NEAR
; ГСА по рис. 3.31
; Подготовка
LEA
SI, KbdImage
; Загрузка адреса,
MOV
CX, LENGTH KbdImage
; счетчика циклов и
MOV
BL, 0FEh
; номера исходной строки
KI4:
MOV
AL, BL
; Выбор строки
AND
AL, 3Fh
; Объединение номера с
OR
AL, MesBuff
; сообщением "Тип ввода"
OUT
KbdPort, AL
; Активация строки
IN
AL, KbdPort
; Ввод строки
AND
AL, 0Fh
; Включено?
CMP
AL, 0Fh
JZ
KI1
; Переход, если нет
MOV
DX, KbdPort
; Передача параметра
CALL
VibrDestr
; Гашение дребезга
MOV
[SI], AL
; Запись строки
KI2:
IN
AL, KbdPort
; Ввод строки
AND
AL, 0Fh
; Выключено?
CMP
AL, 0Fh
JNZ
KI2
; Переход, если нет
CALL
VibrDestr
; Гашение дребезга
JMP
SHORT KI3
KI1:
MOV
[SI], AL
; Запись строки
KI3:
INC
SI
; Модификация адреса
ROL
BL, 1
; и номера строки
LOOP
KI4
; Все строки? Переход,
; если нет
RET
KbdInput
ENDP
; 7. Модуль "Контроль ввода с клавиатуры"
-
KbdInContr
PROC
NEAR
; ГСА по рис. 3.32
; Подготовка
LEA
BX, KbdImage
; Загрузка адреса
MOV
CX, 4
; и счетчика строк
MOV
EmpKbd, 0
; Очистка флагов
MOV
KbdErr, 0
MOV
DL, 0
; и накопителя
KIC2:
MOV
AL, [BX]
; Чтение строки
MOV
AH, 4
; Загрузка счетчика битов
KIC1:
SHR
AL, 1
; Выделение бита
CMC
; Подсчет бита
ADC
DL, 0
DEC
AH
; Все биты в строке?
JNZ
KIC1
; Переход, если нет
INC
BX
; Модификация адреса строки
LOOP
KIC2
; Все строки? Переход, если нет
CMP
DL, 0
; Накопитель = 0?
JZ
KIC3
; Переход, если да
CMP
DL, 1
; Накопитель = 1?
JZ
KIC4
; Переход, если да
MOV
KbdErr, 0FFh
; Установка флага ошибки
JMP
SHORT KIC4
KIC3:
MOV
EmpKbd, 0FFh
; Установка флага
; пустой клавиатуры
KIC4:
RET
KbdInContr
ENDP
; 8. Модуль "Преобразование очередной цифры"
-
NxtDigTrf
PROC
NEAR
; ГСА по рис. 3.33
CMP
EmpKbd, 0ffh
; Пустая клавиатура?
JZ
NDT1
; Переход, если да
CMP
KbdErr, 0FFh
; Ошибка клавиатуры?
JZ
NDT1
; Переход, если да
; Подготовка
LEA
BX, KbdImage
; Загрузка адреса
MOV
DX, 0
; Очистка накопителей
; кода строки и столбца
NDT3:
MOV
AL, [BX]
; Чтение строки
AND
AL, 0Fh
; Выделение поля клавиатуры
CMP
AL, 0Fh
; Строка активна?
JNZ
NDT2
; Переход, если да
INC
DH
; Инкремент кода строки
INC
BX
; Модификация адреса
JMP
SHORT NDT3
NDT2:
SHR
AL, 1
; Выделение бита строки
JNC
NDT4
; Бит активен? Переход, если да
INC
DL
; Инкремент кода столбца
JMP
SHORT NDT2
NDT4:
MOV
CL, 2
; Формирование двоичного
SHL
DH, CL
; кода цифры
OR
DH, DL
MOV
NextDig, DH
; Запись кода цифры
NDT1:
RET
NxtDigTrf
ENDP
; 9. Модуль "Формирование информации"
-
InfoForm
PROC
NEAR
; ГСА по рис. 3.34
MOV
AL, KbdErr
; Есть ошибки?
OR
AL, RAMErrD
OR
AL, RAMErrA
JNZ
InF1
; Переход, если да
CMP
EmpKbd, 0FFh
; Пустая клавиатура?
JNE
InF2
; Переход, если нет
MOV
BX, Addr
; Чтение адреса
CMP
AddrInc, 0FFh
; Инкремент адреса?
JNE
InF3
; Переход, если нет
INC
BX
; Инкремент адреса
JMP
SHORT InF4
InF3:
CMP
AddrDec, 0ffh
; Декремент адреса?
JNE
InF1
; Переход, если нет
DEC
BX
; Декремент адреса
InF4:
CMP
Mode, 0
; Режим = "Ввод"?
JNE
InF5
; Переход, если нет
MOV
DL, BufData
; Чтение данных из буфера
MOV
SI, Addr
; Запись данных
MOV
ES:[SI], DL
; по старому адресу
JMP
SHORT InF5
InF2:
CMP
InType, 0
; Тип ввода = "Адрес"?
JNE
InF6
; Переход, если нет
MOV
BX, Addr
; Чтение адреса
MOV
CL, 4
; Сдвиг адреса
SHL
BX, CL
; на тетраду
OR
BL, NextDig
; Включение очередной
; цифры в адрес
InF5:
MOV
DL, ES:[BX]
; Чтение данных по новому адресу
MOV
Addr, BX
; Запись нового адреса
JMP
SHORT InF7
InF6:
MOV
DL, BufData
; Чтение данных из буфера
MOV
CL, 4
; Сдвиг данных на тетраду
SHL
DL, CL
OR
DL, NextDig
; Включение очередной
; цифры в данные
InF7:
MOV
BufData, DL
; Запись новых данных в буфер
InF1:
RET
InfoForm
ENDP
; 10. Модуль "Формирование массива отображения"
-
DispForm
PROC
NEAR
; ГСА по рис. 3.35
; Этот модуль реализован для формирования лишь одного массива ото; бражения. Формирование двух массивов DataDisp и AddrDisp должно ; осуществляться путем его двукратного вызова с передачей ; соответствующих параметров перед каждым вызовом
; Входные параметры:
; BX адрес входных данных
; SI адрес массива отображения
; CH количество цифр в массиве
-
MOV
AL, KbdErr
; Есть ошибки?
OR
AL, RAMErrD
OR
AL, RAMErrA
JNZ
DF1
; Переход, если да
MOV
AX, [BX]
; Чтение данных
DF2:
MOV
DX, AX
; Копирование данных
AND
AL, 0Fh
; Выделение младшей тетрады
MOV
[SI], AL
; Запись в память
MOV
AX, DX
; Восстановление данных
MOV
CL, 4
; Сдвиг данных
SHR
AX, CL
; на тетраду
DEC
CH
; Все цифры
JNZ
DF2
; Переход, если нет
DF1:
RET
DispForm
ENDP
; 11. Модуль "Вывод числовой информации"
-
NumInfOut
PROC
NEAR
; ГСА по рис. 3.36
; Этот модуль реализован для вывода информации из одного массива ; отображения на соответствующий знакосинтезирующий дисплей. Вывод ; информации на оба дисплея ("Адрес", "Данные") должен осуществляться ; путем его двукратного вызова с передачей соответствующих параметров ; перед каждым вызовом.
; Входные параметры:
; SI адрес входного массива отображения
; DX номер младшего порта дисплея
; CX количество выводимых знаков
-
MOV
AL, KbdErr
; Есть ошибки?
OR
AL, RAMErrD
OR
AL, RAMErrA
JNZ
NIO1
; Переход, если да
LEA
BX, TrfTabl
; Загрузка адреса таблицы
; преобразования
NIO2:
MOV
AL, [SI]
; Чтение цифры
XLAT
; Преобразование цифры
OUT
DX, AL
; Вывод цифры в порт
INC
SI
; Модификация адреса
INC
DX
; и номера порта
LOOP
NIO2
; Все цифры? Переход, если нет
NIO1:
RET
NumInfOut
ENDP
; Таблица преобразования (см. рис. 3.45,б)
-
TrfTabl
DB
03h, 9Fh, 25h, 0Dh, 99h, 49h, 41h, 1Fh
DB
01h, 09h, 11h, 0C1h, 63h, 85h, 61h, 71h
; МАКРОУРОВЕНЬ ПРОГРАММЫ ;ГСА по рис. 3.25
-
Start:
; Системная подготовка
MOV
AX, Data1
; Инициализация
MOV
DS, AX
; сегментных
MOV
AX, Data2
; регистров
MOV
ES, AX
MOV
AX, Stack
MOV
SS, AX
LEA
SP, StkTop
; и указателя стека
CALL
FuncPrep
; Функциональная подготовка
Cont:
CALL
DTstContr
; Тест ОЗУ по ШД
CALL
ATstContr
; Тест ОЗУ по ША
CALL
ErMesOut
; Вывод сообщений об ошибках
CALL
ModeInput
; Ввод режимов
CALL
InTpMesOut
; Вывод сообщения о типе ввода
CALL
KbdInput
; Ввод с клавиатуры
CALL
KbdInContr
; Контроль ввода с клавиатуры
CALL
NxtDigTrf
; Преобразование очередной
; цифры
CALL
InfoForm
; Формирование информации
LEA
BX, BufData
; Передача параметров
LEA
SI, DataDisp
; для формирования массива
MOV
CH, 2
; отображения данных
CALL
DispForm
; Формирование массива
; отображения
LEA
BX, Addr
; Передача параметров
LEA
SI, AddrDisp
; для формирования массива
MOV
CH, 4
; отображения адреса
CALL
DispForm
; Формирование массива
; отображения
LEA
SI, DataDisp
; Передача параметров
MOV
DX, DDispPort
; для вывода информации на
MOV
CX, 2
; дисплей "Данные"
CALL
NumInfOut
; Вывод числовой информации
LEA
SI, AddrDisp
; Передача параметров для
MOV
DX, ADispPort
; вывода информации
MOV
CX, 4
; на дисплей "Адрес"
CALL
NumInfOut
; Вывод числовой информации
JMP
Cont
; Замыкание программного кольца
; Две нижеследующих строки необходимы для начального запуска программы ; в составе МПС. Они не используются при работе с программой в составе ; персонального компьютера.
-
ORG
START_OFFSET
; Эти строки обеспечивают
JMP
FAR PTR Start
; начальный запуск программы
; при включении устройства
Code
ENDS
END
Start
Пусковая команда программы JMP FAR PTR Start должна располагаться в ячейках ПЗУ с физическим адресом FFFF0h, который первым появляется на ША после включения питания. Для этого в исходном тексте программы она должна находиться по адресу трансляции с внутрисегментным смещением START_OFFSET, которое с учетом базового (начального) адреса сегмента программного кода обеспечит формирование требуемого пускового физического адреса. Учитывая принцип вычисления физического адреса памяти и размещение ПЗУ в самых старших адресах, можно получить формулу для вычисления смещения STARTOFFSET, которая имеет вид:
STARTOFFSET = VROM 16,
где VROM объем ПЗУ МПС в байтах.
Необходимый объем памяти для размещения программного кода определяется после первоначальной трансляции программы с произвольным числовым значением смещения STARTOFFSET. После этого с учетом используемых ИМС постоянной памяти выбирается объем ПЗУ VROM и точно рассчитывается значение смещения STARTOFFSET. Далее оно вносится в исходный текст программы, и выполняется ее повторная трансляция.
Пример 3.11.
Определить внутрисегментное стартовое смещение STARTOFFSET для программы ввода данных в ОЗУ, если в результате ее первоначальной трансляции объем сегмента программного кода составил 804 байта.
Для размещения сегмента программного кода размером 804 байта целесообразно использовать ПЗУ объемом 2 Кбайт, построенное на ИМС К573РФ5. Отсюда VROM = 2К = 2048. Представляя все числа в 16-ричной форме, получим
VROM = 800h, 16 = 10h, STARTOFFSET = 800h 10h = 7F0h.
В процессе трансляции и компоновки выявляются и исправляются все синтаксические ошибки, содержащиеся в исходном тексте разрабатываемой программы. В результате этого будет получен исходный текст и листинг программы, не содержащие синтаксических ошибок. Однако это отнюдь не значит, что полученная программа свободна от ошибок вообще. Все остальные ошибки выявляются и устраняются на этапе тестирования и отладки программы.