CS318 - Pintos
Pintos source browser for JHU CS318 course
vga.c
Go to the documentation of this file.
1 #include "devices/vga.h"
2 #include <round.h>
3 #include <stdint.h>
4 #include <stddef.h>
5 #include <string.h>
6 #include "devices/speaker.h"
7 #include "threads/io.h"
8 #include "threads/interrupt.h"
9 #include "threads/vaddr.h"
10 
11 /** VGA text screen support. See [FREEVGA] for more information. */
12 
13 /** Number of columns and rows on the text display. */
14 #define COL_CNT 80
15 #define ROW_CNT 25
16 
17 /** Current cursor position. (0,0) is in the upper left corner of
18  the display. */
19 static size_t cx, cy;
20 
21 /** Attribute value for gray text on a black background. */
22 #define GRAY_ON_BLACK 0x07
23 
24 /** Framebuffer. See [FREEVGA] under "VGA Text Mode Operation".
25  The character at (x,y) is fb[y][x][0].
26  The attribute at (x,y) is fb[y][x][1]. */
27 static uint8_t (*fb)[COL_CNT][2];
28 
29 static void clear_row (size_t y);
30 static void cls (void);
31 static void newline (void);
32 static void move_cursor (void);
33 static void find_cursor (size_t *x, size_t *y);
34 
35 /** Initializes the VGA text display. */
36 static void
37 init (void)
38 {
39  /* Already initialized? */
40  static bool inited;
41  if (!inited)
42  {
43  fb = ptov (0xb8000);
44  find_cursor (&cx, &cy);
45  inited = true;
46  }
47 }
48 
49 /** Writes C to the VGA text display, interpreting control
50  characters in the conventional ways. */
51 void
52 vga_putc (int c)
53 {
54  /* Disable interrupts to lock out interrupt handlers
55  that might write to the console. */
56  enum intr_level old_level = intr_disable ();
57 
58  init ();
59 
60  switch (c)
61  {
62  case '\n':
63  newline ();
64  break;
65 
66  case '\f':
67  cls ();
68  break;
69 
70  case '\b':
71  if (cx > 0)
72  cx--;
73  break;
74 
75  case '\r':
76  cx = 0;
77  break;
78 
79  case '\t':
80  cx = ROUND_UP (cx + 1, 8);
81  if (cx >= COL_CNT)
82  newline ();
83  break;
84 
85  case '\a':
86  intr_set_level (old_level);
87  speaker_beep ();
88  intr_disable ();
89  break;
90 
91  default:
92  fb[cy][cx][0] = c;
93  fb[cy][cx][1] = GRAY_ON_BLACK;
94  if (++cx >= COL_CNT)
95  newline ();
96  break;
97  }
98 
99  /* Update cursor position. */
100  move_cursor ();
101 
102  intr_set_level (old_level);
103 }
104 
105 /** Clears the screen and moves the cursor to the upper left. */
106 static void
107 cls (void)
108 {
109  size_t y;
110 
111  for (y = 0; y < ROW_CNT; y++)
112  clear_row (y);
113 
114  cx = cy = 0;
115  move_cursor ();
116 }
117 
118 /** Clears row Y to spaces. */
119 static void
120 clear_row (size_t y)
121 {
122  size_t x;
123 
124  for (x = 0; x < COL_CNT; x++)
125  {
126  fb[y][x][0] = ' ';
127  fb[y][x][1] = GRAY_ON_BLACK;
128  }
129 }
130 
131 /** Advances the cursor to the first column in the next line on
132  the screen. If the cursor is already on the last line on the
133  screen, scrolls the screen upward one line. */
134 static void
135 newline (void)
136 {
137  cx = 0;
138  cy++;
139  if (cy >= ROW_CNT)
140  {
141  cy = ROW_CNT - 1;
142  memmove (&fb[0], &fb[1], sizeof fb[0] * (ROW_CNT - 1));
143  clear_row (ROW_CNT - 1);
144  }
145 }
146 
147 /** Moves the hardware cursor to (cx,cy). */
148 static void
149 move_cursor (void)
150 {
151  /* See [FREEVGA] under "Manipulating the Text-mode Cursor". */
152  uint16_t cp = cx + COL_CNT * cy;
153  outw (0x3d4, 0x0e | (cp & 0xff00));
154  outw (0x3d4, 0x0f | (cp << 8));
155 }
156 
157 /** Reads the current hardware cursor position into (*X,*Y). */
158 static void
159 find_cursor (size_t *x, size_t *y)
160 {
161  /* See [FREEVGA] under "Manipulating the Text-mode Cursor". */
162  uint16_t cp;
163 
164  outb (0x3d4, 0x0e);
165  cp = inb (0x3d5) << 8;
166 
167  outb (0x3d4, 0x0f);
168  cp |= inb (0x3d5);
169 
170  *x = cp % COL_CNT;
171  *y = cp / COL_CNT;
172 }
find_cursor
static void find_cursor(size_t *x, size_t *y)
Reads the current hardware cursor position into (*X,*Y).
Definition: vga.c:159
uint8_t
unsigned char uint8_t
Definition: stdint.h:20
COL_CNT
#define COL_CNT
VGA text screen support.
Definition: vga.c:14
cls
static void cls(void)
Clears the screen and moves the cursor to the upper left.
Definition: vga.c:107
intr_level
intr_level
Interrupts on or off?
Definition: interrupt.h:8
GRAY_ON_BLACK
#define GRAY_ON_BLACK
Attribute value for gray text on a black background.
Definition: vga.c:22
string.h
cx
static size_t cx
Current cursor position.
Definition: vga.c:19
speaker.h
intr_set_level
enum intr_level intr_set_level(enum intr_level level)
Enables or disables interrupts as specified by LEVEL and returns the previous interrupt status.
Definition: interrupt.c:81
ptov
static void * ptov(uintptr_t paddr)
Returns kernel virtual address at which physical address PADDR is mapped.
Definition: vaddr.h:72
vga.h
uint16_t
unsigned short int uint16_t
Definition: stdint.h:23
speaker_beep
void speaker_beep(void)
Briefly beep the PC speaker.
Definition: speaker.c:48
move_cursor
static void move_cursor(void)
Moves the hardware cursor to (cx,cy).
Definition: vga.c:149
init
static void init(void)
Initializes the VGA text display.
Definition: vga.c:37
memmove
void * memmove(void *dst_, const void *src_, size_t size)
Copies SIZE bytes from SRC to DST, which are allowed to overlap.
Definition: string.c:24
newline
static void newline(void)
Advances the cursor to the first column in the next line on the screen.
Definition: vga.c:135
interrupt.h
outw
static void outw(uint16_t port, uint16_t data)
Writes the 16-bit DATA to PORT.
Definition: io.h:83
ROW_CNT
#define ROW_CNT
Definition: vga.c:15
round.h
stdint.h
intr_disable
enum intr_level intr_disable(void)
Disables interrupts and returns the previous interrupt status.
Definition: interrupt.c:104
x
static char x
Verifies that mapping over the data segment is disallowed.
Definition: mmap-over-data.c:9
outb
static void outb(uint16_t port, uint8_t data)
Writes byte DATA to PORT.
Definition: io.h:66
vga_putc
void vga_putc(int c)
Writes C to the VGA text display, interpreting control characters in the conventional ways.
Definition: vga.c:52
ROUND_UP
#define ROUND_UP(X, STEP)
Yields X rounded up to the nearest multiple of STEP.
Definition: round.h:6
inited
static bool inited
Already initialized?
Definition: random.c:21
fb
static uint8_t(* fb)[COL_CNT][2]
Framebuffer.
Definition: vga.c:27
clear_row
static void clear_row(size_t y)
Clears row Y to spaces.
Definition: vga.c:120
inb
static uint8_t inb(uint16_t port)
Reads and returns a byte from PORT.
Definition: io.h:9
io.h
vaddr.h
cy
static size_t cy
Definition: vga.c:19
stddef.h