Advertisement
limonchik1106

Untitled

May 25th, 2021
2,030
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //https://osdev.fandom.com/ru/wiki/RTC
  2.  
  3. #include <dos.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <conio.h>
  8. #include <io.h>
  9. #include <windows.h>
  10.  
  11.  
  12. struct VIDEO
  13. {
  14.     unsigned char symbol;
  15.     unsigned char attribute;
  16. };
  17. VIDEO far* screen;
  18.  
  19. /* Секунда, минута, час, день, месяц, год */
  20. char date[6];
  21. unsigned int registers[] = { 0x00, 0x02, 0x04, 0x07, 0x08, 0x09 };
  22. unsigned int delayTime = 0;
  23.  
  24.  
  25. void interrupt(*oldTimer)(...);
  26. void interrupt(*oldAlarm) (...);
  27.  
  28.  
  29. void printSymbol(char);
  30. void getTime();
  31. void setTime();
  32. void delay(unsigned int);
  33. void setAlarm();
  34. void resetAlarm();
  35. void inputTime(int);
  36. int bcdToDec(int);
  37. int decToBcd(int);
  38.  
  39.  
  40. void interrupt newTimer(...)
  41. {
  42.     delayTime++;
  43.  
  44.     outp(0x70, 0x0C);
  45.     inp(0x71);
  46.  
  47.     /* Посылаем контроллерам прерываний сигнал end of interruption */
  48.     outp(0x20, 0x20);
  49.     outp(0xA0, 0x20);
  50. }
  51.  
  52. /* Новый обработчик для будильника */
  53. void interrupt newAlarm(...)
  54. {
  55.     screen = (VIDEO far*)MK_FP(0xB800, 0);
  56.     screen += 80 * 10 + 38;
  57.     printSymbol('A');
  58.     printSymbol('L');
  59.     printSymbol('A');
  60.     printSymbol('R');
  61.     printSymbol('M');
  62.     oldAlarm();
  63.     resetAlarm();
  64. }
  65.  
  66.  
  67. int bcdToDec(int bcd)
  68. {
  69.     return ((bcd / 16 * 10) + (bcd % 16));
  70. }
  71.  
  72. int decToBcd(int dec)
  73. {
  74.     return ((dec / 10 * 16) + (dec % 10));
  75. }
  76.  
  77. void printSymbol(char symbol)
  78. {
  79.     screen->symbol = symbol;
  80.     screen->attribute = 0x43;
  81.     screen++;
  82. }
  83.  
  84. void printTime()
  85. {
  86.     char get_date[6];
  87.     /* Названия месяцев */
  88.     screen = (VIDEO far*)MK_FP(0xB800, 0);
  89.     int i = 0;
  90.     for (i = 0; i < 6; i++)
  91.     {
  92.         /* Выбираем нужный регистр */
  93.         outp(0x70, registers[i]);
  94.         /* Считываем значение из нужного регистра в массив */
  95.         get_date[i] = inp(0x71);
  96.     }
  97.  
  98.     /* Переводим считанные значение в десятичную форму */
  99.     int decDate[6];
  100.     for (i = 0; i < 6; i++)
  101.     {
  102.         decDate[i] = bcdToDec(get_date[i]);
  103.     }
  104.  
  105.     /* Выводим на экран в нужном порядке */
  106.     //вывод времени
  107.     for (i = 2; i >= 0; i--)
  108.     {
  109.         printSymbol(decDate[i] / 10 + '0');
  110.         printSymbol(decDate[i] % 10 + '0');
  111.         if (i != 0)
  112.         {
  113.             printSymbol(':');
  114.         }
  115.     }
  116.     //вывод даты
  117.     printSymbol(' ');
  118.     i = 3;
  119.     printSymbol(decDate[i] / 10 + '0');
  120.     printSymbol(decDate[i] % 10 + '0');
  121.     printSymbol('.');
  122.     i = 4;
  123.     printSymbol(decDate[i] / 10 + '0');
  124.     printSymbol(decDate[i] % 10 + '0');
  125.     printSymbol('.');
  126.     printSymbol('2');
  127.     printSymbol('0');
  128.     i = 5;
  129.     printSymbol(decDate[i] / 10 + '0');
  130.     printSymbol(decDate[i] % 10 + '0');
  131.     return;
  132. }
  133.  
  134.  
  135. void interrupt(*oldint08) (...);
  136. void interrupt  newint08(...) { printTime(); oldint08(); }
  137.  
  138.  
  139. void initialize()
  140. {
  141.     oldint08 = getvect(0x08);
  142.     setvect(0x08, newint08);
  143. }
  144.  
  145. void deinitialize()
  146. {
  147.     setvect(0x08, oldint08);
  148. }
  149.  
  150.  
  151.  
  152.  
  153. void setTime()
  154. {
  155.     /* Вводим новое время */
  156.     inputTime(1);
  157.  
  158.     /* Запрещаем прерывания */
  159.     disable();
  160.  
  161.     /* Проверка на доступность значений для чтения и записи */
  162.     unsigned int res;
  163.     do
  164.     {
  165.         outp(0x70, 0xA);
  166.         res = inp(0x71) & 0x80;
  167.     } while (res);
  168.  
  169.     /* Отключаем обновление часов реального времени */
  170.     outp(0x70, 0xB);
  171.     outp(0x71, inp(0x71) | 0x80);
  172.  
  173.     for (int i = 0; i < 6; i++)
  174.     {
  175.         /* Выбираем нужный регистр с индексом registers[i]*/
  176.         outp(0x70, registers[i]);
  177.         /* Подаем в него нужное значение */
  178.         outp(0x71, date[i]);
  179.     }
  180.  
  181.     /* Включаем обновление часов реально времени */
  182.     outp(0x70, 0xB);
  183.     outp(0x71, inp(0x71) & 0x7F);
  184.  
  185.     /* Разрешаем прерывания */
  186.     enable();
  187.     system("cls");
  188. }
  189.  
  190. /* Задержка */
  191. void delay(unsigned int ms)
  192. {
  193.     /* Запрещаем прерывания */
  194.     disable();
  195.  
  196.     /* Устанавливаем новые обработчики прерываний */
  197.     oldTimer = getvect(0x70);
  198.     setvect(0x70, newTimer);
  199.  
  200.     /* Разрешаем прерывания */
  201.     enable();
  202.  
  203.     /* Размаскирование линии сигнала запроса от ЧРВ */
  204.     outp(0xA1, inp(0xA1) & 0xFE);
  205.     /* 0xFE = 11111110, бит 0 в 0, чтобы разрешить прерывания от ЧРВ */
  206.  
  207.     /* Выбираем регистр B */
  208.     outp(0x70, 0xB);
  209.     outp(0x71, inp(0x71) | 0x40);
  210.     /* 0x40 = 01000000, 6-й бит регистра B устанавливаем в 1 для периодического прерывания */
  211.  
  212.     delayTime = 0;
  213.     while (delayTime <= ms);
  214.  
  215.     puts("Delay's end");
  216.     setvect(0x70, oldTimer);
  217.     return;
  218. }
  219.  
  220. /* Установка будильника */
  221. void setAlarm()
  222. {
  223.     inputTime(0);
  224.  
  225.     disable();
  226.  
  227.     unsigned int res;
  228.     do
  229.     {
  230.         outp(0x70, 0xA);
  231.         res = inp(0x71) & 0x80;
  232.     } while (res);
  233.  
  234.     /* Устанавливаем в регистры будильника нужное время */
  235.     outp(0x70, 0x05);
  236.     outp(0x71, date[2]);
  237.  
  238.     outp(0x70, 0x03);
  239.     outp(0x71, date[1]);
  240.  
  241.     outp(0x70, 0x01);
  242.     outp(0x71, date[0]);
  243.  
  244.     /* Выбираем регистр B */
  245.     outp(0x70, 0xB);
  246.     /* Разрешаем прерывание будильника 5-м битом */
  247.     outp(0x71, (inp(0x71) | 0x20));
  248.  
  249.     /* Переопределяем прерывание будильника */
  250.     oldAlarm = getvect(0x4A);
  251.     setvect(0x4A, newAlarm);
  252.     outp(0xA1, (inp(0xA1) & 0xFE));
  253.  
  254.     enable();
  255.     printf("Alarm enabled\n");
  256. }
  257.  
  258. /* Сброс будильника */
  259. void resetAlarm()
  260. {
  261.     if (oldAlarm == NULL)
  262.     {
  263.         return;
  264.     }
  265.  
  266.     disable();
  267.  
  268.     /* Возвращаем старое прерывание */
  269.     setvect(0x4A, oldAlarm);
  270.     //outp(0xA1, (inp(0xA0) | 0x01));
  271.  
  272.     unsigned int res;
  273.     do
  274.     {
  275.         outp(0x70, 0xA);
  276.         res = inp(0x71) & 0x80;
  277.     } while (res);
  278.  
  279.     /* Записываем нулевые значения*/
  280.     outp(0x70, 0x05);
  281.     outp(0x71, 0x00);
  282.  
  283.     outp(0x70, 0x03);
  284.     outp(0x71, 0x00);
  285.  
  286.     outp(0x70, 0x01);
  287.     outp(0x71, 0x00);
  288.  
  289.     outp(0x70, 0xB);
  290.     outp(0x71, (inp(0x71) & 0xDF));
  291.  
  292.     enable();
  293. }
  294.  
  295. void inputTime(int full)
  296. {
  297.     int n;
  298.  
  299.     do {
  300.         fflush(stdin);
  301.         printf("\nInput hours: ");
  302.         scanf("%i", &n);
  303.     } while ((n > 23 || n < 0));
  304.     date[2] = decToBcd(n);
  305.  
  306.     do {
  307.         fflush(stdin);
  308.         printf("Input minutes: ");
  309.         scanf("%i", &n);
  310.     } while (n > 59 || n < 0);
  311.     date[1] = decToBcd(n);
  312.  
  313.     do {
  314.         fflush(stdin);
  315.         printf("Input seconds: ");
  316.         scanf("%i", &n);
  317.     } while (n > 59 || n < 0);
  318.     date[0] = decToBcd(n);
  319.     if (full)
  320.     {
  321.         do {
  322.             fflush(stdin);
  323.             printf("\nInput year: ");
  324.             scanf("%i", &n);
  325.         } while ((n > 99 || n < 0));
  326.         date[5] = decToBcd(n);
  327.         do {
  328.             fflush(stdin);
  329.             printf("\nInput month: ");
  330.             scanf("%i", &n);
  331.         } while ((n > 12 || n < 1));
  332.         date[4] = decToBcd(n);
  333.         do {
  334.             fflush(stdin);
  335.             printf("\nInput date: ");
  336.             scanf("%i", &n);
  337.         } while ((n > 30 || n < 1));
  338.         date[3] = decToBcd(n);
  339.     }
  340. }
  341.  
  342. int main()
  343. {
  344.     initialize();
  345.     int delayMillisecond;
  346.     while (1) {
  347.         printf("\n\n1 - Set time\n2 - Set alarm\n3 - Set delay\n4 - exit\n");
  348.         switch (getch()) {
  349.         case '1':
  350.             system("CLS");
  351.             setTime();
  352.             break;
  353.  
  354.         case '2':
  355.             system("CLS");
  356.             setAlarm();
  357.             break;
  358.  
  359.         case '3':
  360.             system("CLS");
  361.             fflush(stdin);
  362.             printf("\nInput delay in millisecond: ");
  363.             scanf("%d", &delayMillisecond);
  364.             delay(delayMillisecond);
  365.             break;
  366.  
  367.         case '4':
  368.             deinitialize();
  369.             return 0;
  370.         default:
  371.             system("CLS");
  372.             break;
  373.         }
  374.     }
  375.     deinitialize();
  376.     return 0;
  377. }
Advertisement
RAW Paste Data Copied
Advertisement