Изучение основных принципов организации и обслуживания аппаратных прерываний в ОС DOS и QNX, страница 6

#include <sys/neutrino.h>

//для обработки ошибок

#include <errno.h>

//для работы с сигналами

#include <signal.h>

//для работы с портом клавиатуры

#include <hw/inout.h>

#include <time.h>

//обработчик прерывания от клавиатуры

const struct sigevent* klav_int (void *area, int id);

void SIGUSR1_time(int signo);

struct sigevent klav_exit;

struct sigevent klav_time;

int main (void) {

      int inter_id;

      time_t cur_time;

      char buffer [30];

      cur_time=time(NULL);

      strftime(buffer,30,"Today is %D",localtime(&cur_time));

      printf("%s\n",buffer);

      //обработчики сигналов

      signal (SIGUSR1, SIGUSR1_time);

      //запрос на использование привиллегированного ввода/вывода

      //(для возможности использования прерываний)

      ThreadCtl(_NTO_TCTL_IO,0);

      //макрос для определения типа  "сигнал" структуры sigevent

      SIGEV_SIGNAL_INIT(&klav_exit,SIGKILL);

      SIGEV_SIGNAL_INIT(&klav_time,SIGUSR1);

      //подключние обработчика прерывания

      inter_id=InterruptAttach(1, klav_int, NULL,0,0);

      //проверка на наличие ошибок

      if (inter_id == -1) {

            printf("%s\n",strerror(errno));

            return 1;

      }

      while (1) {

            InterruptWait(NULL,NULL);

      }

}

const struct sigevent *klav_int (void *area, int id) {

      int code;

      code=in8(0x60);

      if (code == 1)    //код???!!!

            return &klav_exit;

      else if (code == 20)

            return &klav_time;

      return NULL;

}

void SIGUSR1_time (int sig_no)

{

time_t cur_time;

char buffer [30];

cur_time=time(NULL);

strftime(buffer,30,"Now is %T",localtime(&cur_time));

printf("%s\n",buffer);

}

Результаты испытаний:

# ./date_time2.out

Today is 01/01/02

Now is 08:59:12

Now is 08:59:13

Now is 08:59:13

Now is 08:59:14

Killed

#

Текст программы для DOS:

;запись символа из параметра #2 в видеобуфер со смещением заданным в параметре #1

print macro

      push  ax, ds, es  ;сохранение используемых ресурсов

      mov   ax, 0b800h  ; адрес сегмента текстовой видеопамяти

            mov  es, ax            ; равен 0B800h,

      mov   di, #1            ;смещение

      mov   ah, 0fh           ;цвет

      mov   al, #2            ;выводимый символ

      mov   es:[di], ax ;запись цвета и кода символа непосредственно в                                     ;видеобуфер

      pop   es, ds, ax  ;восстановление ресурсов

#em

;преобразование параметра #2 в ASCII код и вывод его в видеобуфер со смещением #1

print_sm macro

      push  ax, cx            ;сохранение используемых ресурсов

      mov   al, #2            ;

      mov   cl, al            ;

      and   cl, 0f            ;маскирование для выделения младшего разряда

      add   cl, 030           ;преобразование его в ASCII код

      sar   al, 4       ;сдвиг на 4 разряда

      mov   ch, al           

      and   ch, 0f            ;маскирование

      add   ch, 030           ;преобразование в ASCII код

      print #1, ch            ;запись результата в

      print #1+2, cl    ;видеобуфер

      pop   cx, ax            ;восстановление ресурсов

#em

      jmp   main

old_addr    dd    ?

flag        db    0