1 /*
2  * Copyright (c) 2006-2007 Ali Mashtizadeh
3  */
4 
5 #include <stdbool.h>
6 #include <stdint.h>
7 
8 #include <sys/cdefs.h>
9 #include <sys/kdebug.h>
10 
11 #include <machine/amd64.h>
12 #include <machine/pmap.h>
13 
14 #include "vgacons.h"
15 
16 static short *VideoBuffer = (short *)(0x000B8000 + MEM_DIRECTMAP_BASE);
17 static int CurrentX = 0;
18 static int CurrentY = 0;
19 static int SizeX = 80;
20 static int SizeY = 25;
21 static unsigned char TextAttribute = 0x70; /* Grey on Black */
22 
23 #define VGA_BASE 0x370
24 
25 #define VGA_ATC_INDEX       0x00 + VGA_BASE
26 #define VGA_ATC_DATA        0x01 + VGA_BASE
27 #define VGA_SEQ_INDEX       0x02 + VGA_BASE
28 #define VGA_SEQ_DATA        0x05 + VGA_BASE
29 #define VGA_PAL_RADDR       0x07 + VGA_BASE
30 #define VGA_PAL_WADDR       0x08 + VGA_BASE
31 #define VGA_PAL_DATA        0x09 + VGA_BASE
32 #define VGA_GDC_INDEX       0x0E + VGA_BASE
33 #define VGA_GDC_DATA        0x0F + VGA_BASE
34 
35 static uint8_t ModeBuffer[6];
36 
LockDisplay(void)37 void LockDisplay(void)
38 {
39 }
40 
UnlockDisplay(void)41 void UnlockDisplay(void)
42 {
43 }
44 
EnterFontMode(void)45 void EnterFontMode(void)
46 {
47     // Save VGA State
48     outb(VGA_SEQ_INDEX,0x02);
49     ModeBuffer[0] = inb(VGA_SEQ_DATA);
50 
51     outb(VGA_SEQ_INDEX,0x04);
52     ModeBuffer[1] = inb(VGA_SEQ_DATA);
53 
54     outb(VGA_GDC_INDEX,0x04);
55     ModeBuffer[2] = inb(VGA_GDC_DATA);
56 
57     outb(VGA_GDC_INDEX,0x05);
58     ModeBuffer[3] = inb(VGA_GDC_DATA);
59 
60     outb(VGA_GDC_INDEX,0x06);
61     ModeBuffer[4] = inb(VGA_GDC_DATA);
62 
63     outb(VGA_ATC_INDEX,0x10);
64     ModeBuffer[5] = inb(VGA_ATC_DATA);
65 
66     // Setup Font Mode
67 }
68 
ExitFontMode(void)69 void ExitFontMode(void)
70 {
71     // Restore VGA State
72 }
73 
74 
VGA_Init(void)75 void VGA_Init(void)
76 {
77     int i = 0;
78 
79     for (i = 0;i < SizeX * SizeY;i++)
80     {
81         VideoBuffer[i] = (TextAttribute << 8) | ' ';
82     }
83 
84     CurrentX = 0;
85     CurrentY = 0;
86 
87     /*
88      * At initialization the video memory is located at 0xB8000.
89      * We will map the memory after memory management has been
90      * initialized.
91      */
92 }
93 
VGA_LateInit(void)94 void VGA_LateInit(void)
95 {
96     // Map in video memory
97     // Set VideoBuffer pointer
98 }
99 
VGA_ScrollDisplay(void)100 void VGA_ScrollDisplay(void)
101 {
102     int i,j;
103     for (i = 1; i < SizeY; i++)
104     {
105         for (j = 0; j < SizeX; j++)
106         {
107             VideoBuffer[(i-1)*SizeX+j] = VideoBuffer[i*SizeX+j];
108         }
109     }
110     for (j = 0; j < SizeX; j++)
111         VideoBuffer[(SizeY-1)*SizeX+j] = (TextAttribute << 8) | ' ';
112     return;
113 }
114 
VGA_Putc(short c)115 void VGA_Putc(short c)
116 {
117     c |= (TextAttribute << 8);
118     switch (c & 0xFF)
119     {
120         case '\b':
121 	    if (CurrentX > 0) {
122 		CurrentX--;
123 		VideoBuffer[CurrentX + CurrentY * SizeX] = 0x20 | (TextAttribute << 8);
124 	    }
125 	    break;
126         case '\n':
127             if (CurrentY >= (SizeY - 1)) {
128                 VGA_ScrollDisplay();
129             } else {
130                 CurrentY++;
131             }
132             CurrentX = 0;
133             break;
134         case '\r':
135             break;
136         case '\t':
137             VGA_Putc(' ');
138             VGA_Putc(' ');
139             VGA_Putc(' ');
140             VGA_Putc(' ');
141             break;
142         default:
143             VideoBuffer[CurrentX + CurrentY * SizeX] = c;
144             CurrentX++;
145             if (CurrentX == SizeX)  {
146                 if (CurrentY >= (SizeY - 1)) {
147                     VGA_ScrollDisplay();
148                 } else {
149                     CurrentY++;
150                 }
151                 CurrentX = 0;
152             }
153             break;
154     }
155 }
156 
VGA_Puts(const char * str)157 void VGA_Puts(const char *str)
158 {
159     const char *p = str;
160     while (*p != '\0')
161         VGA_Putc(*p++);
162 }
163 
Panic(const char * str)164 void Panic(const char *str)
165 {
166     VGA_Puts(str);
167     __asm__("int3");
168     while (1)
169     {
170         __asm__("hlt");
171     }
172 }
173 
174