;Перевод от Mario79 mario79@ezmail.ru Программирование в MenuetOS ========================= 1) Прикладное программирование 1a) Структура прикладной программы 1b) пример на Ассемблере 1c) Использование однородных системных цветов 1d) Свободное окно формы 1e) Потоки 1f) данные в реальном масштабе времени 1) ПРОГРАММИРОВАНИЕ ПРИКЛАДНОЙ ПРОГРАММЫ ДЛЯ MENUET-OS ======================================== 1a) Структура прикладной программы =============================== Программировать для Menuet будет достаточно просто, если понять основную структуру прикладной программы. Здесь предполагается, что у вас уже есть некоторый опыт программирования на ассемблере. MenuetOS API - легкий для обучения набор функций с фактически отсутствием иерархического доступа. Действие прикладной программы основано на событиях. Операционная система передаёт прикладной программе тип события, которое приложение обрабатыват соответственно. Имеется три типа событий, которые приложение обрабатывает по умолчанию: перерисовка окна, keypress (нажатие клавиши) и buttonpress (нажатие кнопки). Блок-схема и структура приложения с заданными по умолчанию событиями: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ДАННЫЕ ЗАГОЛОВКА ; ; ; ;;;;;;::;;;;;;;;;;;;;;;;;;;;;;; START: call draw_window ;;;;;;;;;;;;;;;;::;;;;;;; ; ; ; ЖДАТЬ СОБЫТИЯ ; <----------------------------------------------------------I ; ; I ;;;;;::;;;;;;;;;;;;;;;;;; I I I ;;;;;;;;;;;;;;;;::;;;;;;; I ; ; I ; ; redraw - > call draw_window - > I ; ЧИТАТЬ СОБЫТИЕ ; - > key - > прочитать keypress - > обработка - > I ; ; buttonpress - > прочитать buttonpress - > обработка - > I ;;;;;::;;;;;;;;;;;;;;;;;; Draw_window: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ВЫВЕСТИ СТАТИЧЕСКИЕ ЧАСТИ ОКНА ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ret ОБЛАСТЬ ДАННЫХ: ;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; СТАТИЧЕСКИЕ ДАННЫЕ ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;; ( Конец образа ) 1b) пример на Ассемблере ==================== Детально прокомментированная реализацию на ассемблере вышеупомянутой структуры (1a). Системные вызовы Menuet выполняются вызовом прерывания 'int 0x40', номер функции указывается в регистре eax, в других регистрах при необходимости передаются дополнительные данные. Подробное описание всех системных вызовов, доступных в настоящее время доступных - в разделе (1g) Системные функции. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ПРИМЕР ПРИКЛАДНОЙ ПРОГРАММЫ ; ; ; ; Компилировать с FASM для Menuet ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The header (заголовок) use32 ; транслятор использующий 32 разрядных команды org 0x0 ; базовый адрес кода, всегда 0x0 db 'MENUET01' ; идентификатор 8 байтов для прикладной программы dd 0x01 ; версия верхнего колонтитула dd START ; начало выполнения dd I_END ; размер образа dd 0x100000 ; Объем используемой памяти ; Вы можете обращаться к памяти от 0x0 до ; значения, определенного здесь. Настройка ; кода сделан с селекторами ; установленными в OS. dd 0x7fff0 ; расположите позицию стека в области памяти dd 0x0 ; значение передачи параметров ; Если установлено в значение отличное от нуль, возможно ; параметры переданы в начале. dd 0x0 ; Зарезервировано для иконки ; Область кода START: ; начало выполнения call draw_window ; выведите окно ; После того, как окно выведено, практически имеется главный цикл. ; События распределены отсюда. event_wait: mov eax,10 ; функция 10: ждите до случая int 0x40 ; тип случая возвращен в eax cmp eax,1 ; Случай запроса перерисовки? je red ; Expl.: имелось действие на экране и ; части прикладных программ должны быть повторно выведены. cmp eax,2 ; Случай клавиши в буфере? je key ; Expl.: Пользователь нажал клавишу в то время как ; приложение имеет наверху стек окна. cmp eax,3 ; Случай кнопки в буфере? je button ; Expl.: Пользователь нажал один из ; кнопок прикладной программы. jmp event_wait ; Следующий раздел читает случай и обрабатывает данные. red: ; Драйвер случая перерисовки call draw_window ; Мы вызываем функцию window_draw и jmp event_wait ; переходим назад к event_wait key: ; Драйвер случая Keypress mov eax,2 ; Клавиша возвращена в ah. Клавиша должна быть int 0x40 ; прочитана и очищена от системной очереди. jmp event_wait ; Только читайте клавишу, игнорируйте это и переход к ; event_wait. button: ; Драйвер случая Buttonpress mov eax,17 ; Номер кнопки, определенный в window_draw int 0x40 ; возвращен ah. cmp ах,1 ; кнопка id=1? jne noclose mov eax,-1 ; Функция -1: закрывает эту программу int 0x40 noclose: jmp event_wait ; Это - для игнорируемых событий, полезно ; при дальнейшем развитии ; ********************************************* ; ****** ОПРЕДЕЛЕНИЕ ОКНА И ВЫВЕДЕНИЕ ********* ; ********************************************* ; ; Статические части окна выведены в этой функции. Холст окна может ; быть доступен позже для любых частей этого кода (поток) для отображения ; процессов или зарегистрированных данных, для примера. ; ; Статические части *могут*, быть помещены в пределах fn 12, ebx = 1 и ebx = 2. draw_window: mov eax,12 ; функция 12:сообщить os о windowdraw (статус перерисовки окна) mov ebx,1 ; 1, начало вывода int 0x40 ; ВЫВЕСТИ ОКНО mov eax,0 ; функция 0: определите и выведите окно mov ebx,100*65536+300 ; [x начальный] *65536 + [x размер] mov ecx,100*65536+120 ; [y начальный] *65536 + [y размер] mov edx,0x02ffffff ; цвет рабочей области RRGGBB ; 0x02000000 = тип окна 2 mov esi,0x808899ff ; цвет области заголовка RRGGBB ; 0x80000000 = цвет скользит mov edi,0x008899ff ; цвет рамки RRGGBB int 0x40 ; МЕТКА ОКНА mov eax,4 ; функция 4: запишите текст в окне mov ebx,8*65536+8 ; [x начальный] *65536 + [y начальный] mov ecx,0x00ddeeff ; цвет текста RRGGBB mov edx,labelt ; указатель на начало текста mov esi,labellen-labelt ; длина текста int 0x40 ; УСТАНОВКА КНОПКИ mov eax,8 ; функция 8: определить и вывести кнопку mov ebx,(300-19)*65536+12 ; [x начальный] *65536 + [x размер] mov ecx,5*65536+12 ; [y начальный] *65536 + [y размер] mov edx,1 ; идентификатор кнопки mov esi,0x6677cc ; цвет кнопки RRGGBB int 0x40 mov ebx,25*65536+35 ; выведите текст информации функцией 4 mov ecx,0x224466 mov edx,text mov esi,40 newline: ; текст для ОБЛАСТИ ДАННЫХ mov eax,4 int 0x40 add ebx,10 add edx,40 cmp [edx],byte 'x' jne newline mov eax,12 ; функция 12:сообщить os о windowdraw (статус перерисовки окна) mov ebx,2 ; 2, конец вывода int 0x40 ret ; ********************************************** ; ************* ОБЛАСТЬ ДАННЫХ ***************** ; ********************************************** ; ; Данные могут быть свободно смешаны с кодом в любых частях образа. ; Только информация верхнего колонтитула требуется в начале образа. text: db ' ЭТОТ ПРИМЕР ПРОГРАМЫ ВЫ МОГЛИ ИСПОЛЬЗОВАТЬ, ' db ' A:\EXAMPLE.ASM КОД ПРОКОММЕНТИРОВАН ' db ' И ОЧИЩЕН. СИСТЕМНЫЕ ФУНКЦИИ НАХОДЯТСЯ В ФАЙЛЕ ' db ' SYSFUNCS.TXT И КОМАНДЫ В CMD.TXT ' db ' x 128 x 128 mov ebx, 1 ; вы должны представить это, масштаб по умолчанию - 1:1 mov ecx, 2 ; масштаб установлен в 2^ecx int 0x40 popa ret Shape_reference: ; 32 x 32 (window_size_X + 1) * (window_size_Y + 1) db 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0 db 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0 db 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 db 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0 db 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0 db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0 db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0 db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0 db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0 db 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0 db 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0 db 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 db 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0 db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 ; ********************************************* ; ******* ОПРЕДЕЛЕНИЕ ОКНА И ВЫВЕДЕНИЕ ******** ; ********************************************* draw_window: mov eax,12 ; функция 12:сообщить os о windowdraw (статус перерисовки окна) mov ebx,1 ; 1, начало вывода int 0x40 ; ВЫВЕСТИ ОКНО mov eax,0 ; функция 0: определите и выведите окно mov ebx,100*65536 ; [x начальный] *65536 + [x размер] mov ecx,100*65536 ; [y начальный] *65536 + [y размер] mov bx,слово [x_size] mov cx,слово [y_size] mov edx,0x00cccc00 ; цвет рабочей области RRGGBB, 8- > цвет скользит mov esi,0x00cccc00 ; цвет области заголовка RRGGBB, 8- > цвет скользит mov edi,0x00cccc00 ; цвет рамки RRGGBB int 0x40 ; УСТАНОВКА КНОПКИ mov eax,8 ; функция 8: определить и вывести кнопку mov ebx,78*65536+12 ; [x начальный] *65536 + [x размер] mov ecx,20*65536+12 ; [y начальный] *65536 + [y размер] mov edx,1 ; идентификатор кнопки mov esi,0x5599cc ; цвет кнопки RRGGBB int 0x40 mov eax,12 ; функция 12:сообщить os о windowdraw (статус перерисовки окна) mov ebx,2 ; 2, конец вывода int 0x40 ret ; DATA x_size dd 127 y_size dd 127 I_END: 1e) Потоки =========== Потоковая трансляция MenuetOS имеет некоторые большие преимущества перед высокоуровневыми языками. Если вы сохраняете все переменные в регистрах, вы можете начать много потоков с одним и тем же кодом, с тех пор никакая память не воздействует и не нуждается ни в каком сохранении. Регистры сохранены в сегментах выключателя задачи MenuetOS. Все, что вы должны делать это установить новый стек. Потоки не имеют никаких различий с главным процессом и используют ту же самую область памяти как процесс, который начинает это. Они могут иметь их собственные независимые окна и т.д. Закрытие прикладной программы, всех потоков должно быть закончено со значением по умолчанию (eax = -1) системного вызова. Новая функция в этом примере - create_thread. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ПРИМЕР ПОТОКА ; ; ; ; Компилировать с FASM для Menuet ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; use32 org 0x0 db 'MENUET01' ; идентификатор 8 байтов dd 0x01 ; версия заголовка dd START ; начало кода dd I_END ; размер образа dd 0x100000 ; память для приложения dd 0x80000 ; esp dd 0x0, 0x0 ; I_Param, I_Icon START: ; начало выполнения call draw_window ; сначала, выведите окно event_wait: mov eax, 10 ; ждите здесь случай int 0x40 cmp eax, 1 ; запрос перерисовки? je red cmp eax, 2 ; клавиша в буфере? je key cmp eax, 3 ; кнопка в буфере? je button jmp event_wait red: ; перерисовка call draw_window jmp event_wait key: ; клавиша mov eax,2 ; только читайте это, и игнорировать int 0x40 jmp event_wait button: ; кнопка mov eax,17 ; получите идентификатор int 0x40 cmp ah,1 ; кнопка id=1? jne noclose mov eax,-1 ; закройте эту программу (поток) int 0x40 noclose: cmp ah,2 ; запрос create_thread (cоздать_поток) jne no_thread call create_thread jmp event_wait no_thread: jmp event_wait ; СОЗДАНИЕ ПОТОКА ; ; Все, что мы должны делать, должны дать адрес входа потока в ecx и ; новую позицию стека в edx с функцией eax=51, ebx=1 create_thread: cmp [thread_stack],0xf0000 jge no_new_thread add [thread_stack],0x1000 mov eax, 51 ; thread_create системный вызов mov ebx,1 mov ecx,START mov edx,[thread_stack] int 0x40 no_new_thread: ret thread_stack dd 0x80000 ; ********************************************* ; ******* ОПРЕДЕЛЕНИЕ ОКНА И ВЫВОД ******** ; ********************************************* draw_window: mov eax,12 ; функция 12:сообщить os о windowdraw (статус перерисовки окна) mov ebx,1 ; 1, начало вывода mnt 0x40 ; ВЫВЕСТИ ОКНО mov eax,0 ; функция 0: определите и выведите окно mov ebx,10*65536+300 ; [x начало] *65536 + [x размер] mov ecx,10*65536+140 ; [y начало] *65536 + [y размер] mov esi,[thread_stack] sub esi,0x80000 shr esi,11 shl esi,16 add ebx,esi add ecx,esi mov edx,0x02ffffff ; цвет рабочей области RRGGBB, 8- > цвет скользит mov esi,0x808899ff ; цвет области захвата RRGGBB, 8- > цвет скользит mov edi,0x008899ff ; цвет рамки RRGGBB int 0x40 ; МЕТКА ОКНА mov eax,4 ; функция 4: запишите текст к окну mov ebx,8*65536+8 ; [x начало] *65536 + [y начало] mov ecx,0x00ddeeff ; цвет текста RRGGBB mov edx,labelt ; указатель на текстовое начало mov esi,labellen-labelt ; текстовая длина int 0x40 ; УСТАНОВКА КНОПКИ mov eax,8 ; функция 8: определите и выведите кнопку mov ebx,(300-19) *65536+12 ; [x начало] *65536 + [x размер] mov ecx,5*65536+12 ; [y начало] *65536 + [y размер] mov edx,1 ; идентификатор кнопки mov esi,0x6677cc ; цвет кнопки RRGGBB int 0x40 mov eax,8 ; НОВАЯ КНОПКА ПОТОКА mov ebx,25*65536+128 mov ecx,88*65536+20 mov edx,2 mov esi,0x6677cc int 0x40 mov ebx,25*65536+35 ; вывести текстовую информацию при помощи функции 4 mov ecx,0x224466 mov edx,text mov esi,40 newline: mov eax,4 int 0x40 add ebx,10 add edx,40 cmp [edx],byte 'x' jne newline mov eax,12 ; функция 12:сообщить os о windowdraw (статус перерисовки окна) mov ebx,2 ; 2, конец вывода int 0x40 ret ; ОБЛАСТЬ ДАННЫХ text: db ' ЭТОТ ПРИМЕР СОЗДАЕТ ПОТОКИ, ВЫПОЛНЯЮЩИЕ ' db ' ТОТ ЖЕ САМЫЙ МНОЖИТЕЛЬ КОДА ВРЕМЕНИ. ВСЕ МЫ ' db ' НУЖДАЕМСЯ В НОВОМ СТЕКЕ ДЛЯ КАЖДОГО ПОТОКА. ' db ' ВСЯ ДОЛЯ ПОТОКОВ ТА ЖЕ САМАЯ ПАМЯТЬ. ' db ' ' db ' ' db ' СОЗДАЮТ НОВЫЙ ПОТОК ' db 'x REC DATA (A) SYS_EVENT => READ DATA => PROCESS 1f) Обработка данных в режиме реального времени =============================================== Следующий пример показывает получение обработку данных в режиме реального времени. Приложение сообщает операционной системе порты и типы данных для чтения по специфичному IRQ. Шаги: 1) Зарезервировать область портов I/O 2) Зарезервировать IRQ 3) Запрограммировать IRQ 4) программирует список событий (EVENT) для требуемого IRQ 5) обработка данных 6) вернуться к событиям по умолчанию - освободить IRQ в списке событий 7) освободить IRQ 8) освободить область портов 9) Завершить программу После того, как IRQ запрограммированы, у приложения имеется новое событие для основного цикла событий, номер (IRQ+16). Когда приложение получает событие, операционная система записывает данные, которые приложение может обработать. Таблица, нарисованная ниже показывает основную структуру обработки данных в режиме реального времени Все шаги левее (A) обрабатываются операционной системой и шаги справа от (A) обрабатываются приложением. IRQ OWNER => REC DATA (A) SYS_EVENT => READ DATA => PROCESS 0 TIMER SYS 1 KEYBOARD SYS 2 free -> 3 COM MOUSE SYS/free ?> 4 COM MOUSE SYS/free ?> 5 SOUND BL. SYS 6 FLOPPY SYS 7 free -> 8 free -> 9 free -> 10 free -> 11 free -> 12 PS2 MOUSE SYS/free ?> 13 MATH PR. SYS 14 IDE SYS 15 IDE SYS Пример обработки данных в реальном масштабе времени: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ДАННЫЕ В РЕАЛЬНОМ МАСШТАБЕ ВРЕМЕНИ ; ; ; ; Компилировать с FASM для Menuet ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; use32 org 0x0 db 'MENUET00' ; идентификатор 8 байтов dd 56 ; требуемая версия os dd START ; начало программы dd I_END ; размер образа программы dd 0x100000 ; требуемый объем памяти ; esp = 0x7FFF0 dd 0x00000000 ; reserved = не расширенный заголовок START: ; начало выполнения call draw_window ; сначала выводим окно call program_real_time_data ; программируем OS для получения данных в режиме реального времени call program_com_port ; программируем com-порт для определенного устройства event_wait: mov eax,10 ; ожидаем событие int 0x40 cmp eax,1 ; запрос перерисовки? je red cmp eax,2 ; клавиша в буфере? je key cmp eax,3 ; кнопка в буфере? je button cmp eax,16+4 ; RT: новое событие для ожидаемых данных IRQ[ЗАПРОСА НА ПРЕРЫВАНИЕ] (16+IRQ) je read_rt jmp event_wait ; Следующая часть читает событие и обрабатывает данные. read_rt: ; RT данные mov eax,42 ; Функция 42 возвращает записанные данные для IRQ 4 [ЗАПРОСА НА ПРЕРЫВАНИЕ] mov ebx,4 ; int 0x40 ; OS возвращает записанные данные. ; eax число байтов оставшихся в буфере ; bl данные ; ecx 0 = успех, другой = нет данных в buf. call process_data jmp event_wait red: ; перерисовка call draw_window jmp event_wait key: ; "клавиша" mov eax,2 ; только прочитать и игнорировать int 0x40 jmp event_wait button: ; "кнопка" mov eax,17 ; получить идентификатор int 0x40 cmp ах,1 ; идентификатор кнопки равен 1? (id=1?) jne noclose call free_real_time_data mov eax,-1 ; закрыть эту программу int 0x40 noclose: jmp event_wait program_real_time_data: ; Процедура выборки данных в реальном масштабе времени ; ; 1) резервирует область I/O порта (порта Ввода - вывода) ; 2) резервирует IRQ (ЗАПРОС НА ПРЕРЫВАНИЕ) ; 3) программирует IRQ (ЗАПРОС НА ПРЕРЫВАНИЕ) ; 4) программирует список событий (EVENT) для требуемого IRQ (ЗАПРОСА НА ПРЕРЫВАНИЕ) ; pusha mov eax,46 ; резервирование портов 0x3f0 - 0x3ff mov ebx,0 mov ecx,0x3f0 mov edx,0x3ff int 0x40 mov eax,45 ; резервируем irq 4 mov ebx,0 mov ecx,4 int 0x40 mov eax,44 ; выбор считываемого порта для irq 4 mov ebx,irqtable mov ecx,4 int 0x40 mov eax,40 ; получить данные из com1 с помощью irq 4 mov ebx,0000000000010000b shl 16 + 111b ; после этого мы имеем новое ; событие (16+4) int 0x40 popa ret irqtable: dd 0x3f8+0x01000000 ; 3f8 = порт чтения: 01 = чтение байта, 02 = чтение слова dd 0x0 ; 0x0 = прерывающее чтение для каждого IRQ (ЗАПРОСА НА ПРЕРЫВАНИЕ) dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 dd 0x0 free_real_time_data: ; Освободить используемые ресурсы ; ; 1) получить заданные по умолчанию события ; 2) освободить irq при помощи функции 45,1 ; 3) освободить область порта при помощи функции 46,1 ; pusha mov eax,40 ; заданные по умолчанию события - запретить обработку событий по irq 4 mov ebx,111b int 0x40 mov eax,45 ; освободить irq mov ebx,1 mov ecx,4 int 0x40 mov eax,46 ; освободить порты 0x3f0-0x3ff mov ebx,1 mov ecx,0x3f0 mov edx,0x3ff int 0x40 popa ret ; Следующие функции - для обрабатывающего устройства особых данных. process_data: cmp ebx,80 jne nocd mov eax,19 mov ebx,cdplayer mov ecx,0 int 0x40 nocd: push ebx mov eax,[pos] add eax,1 cmp eax,10*20+1 jb noeaxz mov esi,text+10*4 mov edi,text mov ecx,10*21*4 cld rep movsb mov eax,13 mov ebx,20*65536+260 mov ecx,22*65536+220 mov edx,[wcolor] int 0x40 mov eax,10*19+1 noeaxz: mov [pos],eax pop ebx and ebx,0xff call draw_data ret draw_data: pusha xchg eax,ebx mov ecx,10 shl ebx,2 mov esi,3 newnum: xor edx,edx div ecx add edx,48 mov [ebx+text-1],dl dec ebx dec esi jnz newnum call draw_text popa ret draw_text: pusha mov ebx,25*65536+35 ; вывод информационного текста при помощи функции 4 mov ecx,0xffffff mov edx,text mov esi,40 mov edi,20 newline: mov eax,4 int 0x40 add ebx,10 add edx,40 dec edi jne newline popa ret program_com_port: ; следующий участок кода программирует COM порт для инфракрасного приёмника mov cx,0x3f3+8 mov bl,0x80 mov eax,43 int 0x40 mov cx,0x3f1+8 mov bl,0 mov eax,43 int 0x40 mov cx,0x3f0+8 mov bl,0x30 / 4 mov eax,43 int 0x40 mov cx,0x3f3+8 mov bl,3 mov eax,43 int 0x40 mov cx,0x3f4+8 mov bl,0xB mov eax,43 int 0x40 mov cx,0x3f1+8 mov bl,1 mov eax,43 int 0x40 mov eax,5 mov ebx,100 int 0x40 mov cx,0x3f8 mov bl,'I' mov eax,43 int 0x40 mov eax,5 mov ebx,10 int 0x40 mov cx,0x3f8 mov bl,'R' mov eax,43 int 0x40 ret ; ********************************************* ; ******* ОПРЕДЕЛЕНИЕ ОКНА И ВЫВОД ******** ; ********************************************* draw_window: mov eax,12 ; функция 12:сообщить os о windowdraw (статус перерисовки окна) mov ebx,1 ; 1, начало вывода int 0x40 ; ВЫВЕСТИ ОКНО mov eax,0 ; функция 0: определить и вывести окно mov ebx,100*65536+300 ; [x начало] *65536 + [x размер] mov ecx,100*65536+250 ; [y начало] *65536 + [y размер] mov edx,[wcolor] ; цвет рабочей области RRGGBB, 8- > цвет mov esi,0x8099bbff ; цвет области захвата RRGGBB, 8- > цвет ползунка mov edi,0x00ffffff ; цвет рамки RRGGBB int 0x40 ; МЕТКА ОКНА mov eax,4 ; функция 4: вывод текста в окно mov ebx,8*65536+8 ; [x начало] *65536 + [y начало] mov ecx,0x00ffffff ; цвет текста RRGGBB mov edx,labelt ; указатель на начало строки mov esi,labellen-labelt ; длина текстовой строки int 0x40 ; УСТАНОВКА КНОПКИ mov eax,8 ; функция 8: определить и вывести кнопку mov ebx,(300-19)*65536+12 ; [x начало] *65536 + [x размер] mov ecx,5*65536+12 ; [y начало] *65536 + [y размер] mov edx,1 ; идентификатор кнопки mov esi,0x5599cc ; цвет кнопки RRGGBB int 0x40 call draw_text mov eax,12 mov ebx,2 int 0x40 ret ; ОБЛАСТЬ ДАННЫХ wcolor dd 0x0 pos dd 0x0 cdplayer db 'CDPLAY' labelt db ' ИНФРАКРАСНЫЙ ПРИЁМНИК ДЛЯ IRMAN В COM 1 ' labellen: text: I_END: