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

      }

      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 == 32)

            return &klav_date;

      else if (code == 20)

            return &klav_time;

      return NULL;

}

void SIGUSR1_date (int sig_no)

{

time_t cur_time;

char buffer [30];

cur_time=time(NULL);

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

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

}

void SIGUSR2_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_time.out

Today is 01/01/02

Now is 08:53:40

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

main:

      ;сохраняем адрес старого обработчика (прерывание №8, от таймера)

      mov   ax, 035 by 9

      int   021

      mov w       old_addr, bx

      mov w old_addr+2, es

      ;загружаем адрес нового обработчика (прерывание №8, от таймера)

      lea   dx, klavIsr

      mov   ax, 025 by 9

      int   021  

      ;ждем нажатия клавиши Esc

wait_esc:

      cmp   flag, 1

      jne   wait_esc

      ;восстанавливаем старый обработчик

      lds   dx, old_addr

      mov   ax, 025 by 9

      int   021

      int   020

;собственный обработчик

klavIsr:

      push  ax, ds, es

      in    al, 60h

      cmp   al, 1

      jne   ch_date

      mov   flag, 1

      jmp   IsrEnd

ch_date:

      cmp   al, 32

      jne   ch_time

      call  dispdate

      jmp   IsrEnd

ch_time:

      cmp   al, 20

      jne   IsrEnd

      call  disptime

IsrEnd:

      pop   ax, ds, es

      ;переход на системный обработчик (cs - нужно??..)

      cs jmp      old_addr