Advertisement
dykow

Kernel

Oct 6th, 2017
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.92 KB | None | 0 0
  1. //#include "src/screen.h"
  2. //#include "src/keyboard.h"
  3. #include <stddef.h>
  4. #include <stdint.h>
  5.  
  6. //basic checks to make sure about using x86-elf cross-compiler correctly
  7. #if defined(__linux__)
  8.     #error "This code must be compiled with a cross-compiler"
  9. #elif !defined(__i386__)
  10.     #error "This code must be compiled with an x86-elf compiler"
  11. #endif
  12.  
  13. #define KBKEYLIST_H
  14. #define KB_ESCAPE 0x01
  15. #define KB_1 0x02
  16. #define KB_2 0x03
  17. #define KB_3 0x04
  18. #define KB_4 0x05
  19. #define KB_5 0x06
  20. #define KB_6 0x07
  21. #define KB_7 0x08
  22. #define KB_8 0x09
  23. #define KB_9 0x0A
  24. #define KB_0 0x0B
  25. #define KB_SYMBOL1 0x0C /* - */
  26. #define KB_SYMBOL2 0x0D /* = */
  27. #define KB_BACKSPACE 0x0E
  28. #define KB_TAB 0x0F
  29. #define KB_Q 0x10
  30. #define KB_W 0x11
  31. #define KB_E 0x12
  32. #define KB_R 0x13
  33. #define KB_T 0x14
  34. #define KB_Y 0x15
  35. #define KB_U 0x16
  36. #define KB_I 0x17
  37. #define KB_O 0x18
  38. #define KB_P 0x19
  39. #define KB_SYMBOL3 0x1A /* [ */
  40. #define KB_SYMBOL4 0x1B /* ] */
  41. #define KB_ENTER 0x1C
  42. #define KB_LCONTROL 0x1D
  43. #define KB_A 0x1E
  44. #define KB_S 0x1F
  45. #define KB_D 0x20
  46. #define KB_F 0x21
  47. #define KB_G 0x22
  48. #define KB_H 0x23
  49. #define KB_J 0x24
  50. #define KB_K 0x25
  51. #define KB_L 0x26
  52. #define KB_SYMBOL5 0x27 /* ; */
  53. #define KB_SYMBOL6 0x28 /* ' */
  54. #define KB_SYMBOL7 0x29 /* ` */
  55. #define KB_LSHIFT 0x2A
  56. #define KB_SYMBOL8 0x2B /* \ */
  57. #define KB_Z 0x2C
  58. #define KB_X 0x2D
  59. #define KB_C 0x2E
  60. #define KB_V 0x2F
  61. #define KB_B 0x30
  62. #define KB_N 0x31
  63. #define KB_M 0x32
  64. #define KB_SYMBOL9 0x33 /* , */
  65. #define KB_SYMBOL10 0x34 /* . */
  66. #define KB_SYMBOL11 0x35 /* / */
  67. #define KB_RSHIFT 0x36
  68. #define KB_NUMPAD_MULT 0x37
  69. #define KB_LALT 0x38
  70. #define KB_SPACE 0x39
  71. #define KB_CAPSLOCK 0x3A
  72. #define KB_F1 0x3B
  73. #define KB_F2 0x3C
  74. #define KB_F3 0x3D
  75. #define KB_F4 0x3E
  76. #define KB_F5 0x3F
  77. #define KB_F6 0x40
  78. #define KB_F7 0x41
  79. #define KB_F8 0x42
  80. #define KB_F9 0x43
  81. #define KB_F10 0x44
  82. #define KB_NUMLOCK 0x45
  83. #define KB_SCROLLLOCK 0x46
  84. #define KB_NUMPAD7 0x47
  85. #define KB_NUMPAD8 0x48
  86. #define KB_NUMPAD9 0x49
  87. #define KB_NUMPAD_MINUS 0x4A
  88. #define KB_NUMPAD4 0x4B
  89. #define KB_NUMPAD5 0x4C
  90. #define KB_NUMPAD6 0x4D
  91. #define KB_NUMPAD_PLUS 0x4E
  92. #define KB_NUMPAD1 0x4F
  93. #define KB_NUMPAD2 0x50
  94. #define KB_NUMPAD3 0x51
  95. #define KB_NUMPAD0 0x52
  96. #define KB_NUMPAD_DOT 0x53
  97.  
  98. #define KB_SYMBOL12 0x56
  99. #define KB_F11 0x57
  100. #define KB_F12 0x58
  101.  
  102. #define KB_NUMPAD_ENTER 0x9C
  103. #define KB_RCONTROL 0x9D
  104. #define KB_NUMPAD_DIV 0xB5
  105. #define KB_ALTGR 0xB8
  106. #define KB_HOME 0xC7
  107. #define KB_UP 0xC8
  108. #define KB_PAGEUP 0xC9
  109. #define KB_LEFT 0xCB
  110. #define KB_RIGHT 0xCD
  111. #define KB_END 0xCF
  112. #define KB_DOWN 0xD0
  113. #define KB_PAGEDOWN 0xD1
  114. #define KB_INSERT 0xD2
  115. #define KB_DELETE 0xD3
  116.  
  117. // Receives a 8/16/32-bit value from an I/O location
  118. static uint8_t inb(uint16_t port)
  119. {
  120.         uint8_t ret;
  121.         asm volatile ( "inb %1, %0"
  122.                                      : "=a"(ret)
  123.                                      : "Nd"(port) );
  124.         return ret;
  125. }
  126.  
  127. // Sends a 8/16/32-bit value on a I/O location
  128. static inline void outb(uint16_t port, uint8_t val)
  129. {
  130.         asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
  131.         /* There's an outb %al, $imm8  encoding, for compile-time constant port numbers that fit in 8b.  (N constraint).
  132.          * Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint).
  133.          * The  outb  %al, %dx  encoding is the only option for all other cases.
  134.          * %1 expands to %dx because  port  is a uint16_t.  %w1 could be used if we had the port number a wider C type */
  135. }
  136.  
  137.  
  138. // This is the x86's VGA textmode buffer. To display text, we write data to this memory location
  139. volatile uint16_t* vga_buffer = (uint16_t*)0xB8000;
  140. // By default, the VGA textmode buffer has a size of 80x25 characters
  141. const int VGA_COLS = 80;
  142. const int VGA_ROWS = 25;
  143.  
  144. //starts displaying text in the top-left of the screen (column = 0, row = 0)
  145. int term_col = 0;
  146. int term_row = 0;
  147. uint8_t term_color = 0x0F; // Black background, White foreground
  148.  
  149. //The keyboard handling needed!!!
  150. //This function allows to chose terminal color
  151. /*void terminal_color(const char* str)
  152. {
  153.         for(size_t i=0; stri[i] != '\0', i++)   // Keep placing characters until we hit the null-terminating character ('\0')
  154.  
  155. }*/
  156.  
  157. // This function initiates the terminal by clearing it
  158. void term_init()
  159. {
  160.     // Clear the textmode buffer
  161.     for (int col = 0; col < VGA_COLS; col ++)
  162.     {
  163.         for (int row = 0; row < VGA_ROWS; row ++)
  164.         {
  165.             // The VGA textmode buffer has size (VGA_COLS * VGA_ROWS).
  166.             // Given this, we find an index into the buffer for our character
  167.             const size_t index = (VGA_COLS * row) + col;
  168.             // Entries in the VGA buffer take the binary form BBBBFFFFCCCCCCCC, where:
  169.             // - B is the background color
  170.             // - F is the foreground color
  171.             // - C is the ASCII character
  172.             vga_buffer[index] = ((uint16_t)term_color << 8) | ' '; // Set the character to blank (a space character)
  173.         }
  174.     }
  175. }
  176.  
  177. // This function places a single character onto the screen
  178. void term_putc(char c)
  179. {
  180.     // Remember - we don't want to display ALL characters!
  181.     switch (c)
  182.     {
  183.     case '\n': // Newline characters should return the column to 0, and increment the row
  184.         {
  185.             term_col = 0;
  186.             term_row ++;
  187.             break;
  188.         }
  189.  
  190.     default: // Normal characters just get displayed and then increment the column
  191.         {
  192.             const size_t index = (VGA_COLS * term_row) + term_col; // Like before, calculate the buffer index
  193.             vga_buffer[index] = ((uint16_t)term_color << 8) | c;
  194.             term_col ++;
  195.             break;
  196.         }
  197.     }
  198.  
  199.     // if we get past the last column? We need to reset the column to 0, and increment the row to get to a new line
  200.     if (term_col >= VGA_COLS)
  201.     {
  202.         term_col = 0;
  203.         term_row ++;
  204.     }
  205.  
  206.     // if we get past the last row we need to reset both column and row to 0 in order to loop back to the top of the screen
  207.     if (term_row >= VGA_ROWS)
  208.     {
  209.         term_col = 0;
  210.         term_row = 0;
  211.     }
  212. }
  213.  
  214. // Prints an entire string onto the screen, only string given in the argument
  215. void term_print(const char* str)
  216. {
  217.     for (size_t i = 0; str[i] != '\0'; i ++) // Keep placing characters until we hit the null-terminating character ('\0')
  218.         term_putc(str[i]);
  219. }
  220.  
  221. //Provides the scancode from kb controller
  222. //volatile uint16_t* kbuff = (uint16_t*)0x60;
  223. char getScancode(){
  224.     char c=0;
  225.     do {
  226.     if(inb(0x60) != c){
  227.         c=inb(0x60);
  228.         if(c>0)
  229.         outb(0x60, 0x0);
  230.         return c;
  231.         }
  232.     }while(1);
  233.     }
  234.  
  235.  
  236. //transfroms scancodes to chars
  237. char getchar()
  238. {
  239. while(1)
  240. switch (getScancode()) {
  241.             case KB_1:  return '1';
  242.                 break;
  243.             case KB_2:  return '2';
  244.                 break;
  245.             case KB_3:  return '3';
  246.                 break;
  247.             case KB_4:  return '4';
  248.                 break;
  249.             case KB_5:  return '5';
  250.                 break;
  251.             case KB_6:  return '6';
  252.                 break;
  253.             case KB_7:  return 'X';
  254.                 break;
  255.             case KB_8:  return '8';
  256.                 break;
  257.             case KB_9:  return '9';
  258.                 break;
  259.             case KB_0:  return '0';
  260.                 break;
  261.             case KB_Q:  return 'Q';
  262.                 break;
  263.             case KB_W:  return 'W';
  264.                 break;
  265.             case KB_E:  return 'E';
  266.                 break;
  267.             case KB_R:  return 'R';
  268.                 break;
  269.             case KB_T:  return 'T';
  270.                 break;
  271.             case KB_Y:  return 'Y';
  272.                 break;
  273.             case KB_U:  return 'U';
  274.                 break;
  275.             case KB_I:  return 'I';
  276.                 break;
  277.             case KB_O:  return 'O';
  278.                 break;
  279.             case KB_P:  return 'P';
  280.                 break;
  281.             case KB_A:  return 'A';
  282.                 break;
  283.             case KB_S:  return 'S';
  284.                 break;
  285.             case KB_D:  return 'D';
  286.                 break;
  287.             case KB_F:  return 'F';
  288.                 break;
  289.             case KB_G:  return 'G';
  290.                 break;
  291.             case KB_H:  return 'H';
  292.                 break;
  293.             case KB_J:  return 'J';
  294.                 break;
  295.             case KB_K:  return 'K';
  296.                 break;
  297.             case KB_L:  return 'L';
  298.                 break;
  299.             case KB_Z:  return 'Z';
  300.                 break;
  301.             case KB_X:  return 'X';
  302.                 break;
  303.             case KB_C:  return 'C';
  304.                 break;
  305.             case KB_V:  return 'V';
  306.                 break;
  307.             case KB_B:  return 'B';
  308.                 break;
  309.             case KB_N:  return 'N';
  310.                 break;
  311.             case KB_M:  return 'M';
  312.     }
  313. }
  314.  
  315. void kb_print() //shows the character on display
  316. {
  317.     char chara = getchar(); // Pressed key value
  318.     term_putc(chara);
  319. }
  320.  
  321. void kernel_main()
  322. {
  323.     term_init();
  324.  
  325.     term_print("It works!!!\n");
  326.  
  327.     while(1){
  328.     kb_print();
  329.     }
  330. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement