Added SYS_READ implementation
[tpg/acess2.git] / Kernel / drv / vga.c
1 /*
2  * Acess2 VGA Controller Driver
3  */
4 #include <common.h>
5 #include <fs_devfs.h>
6 #include <tpl_drv_video.h>
7 #include <modules.h>
8
9 // === PROTOTYPES ===
10  int    VGA_Install(char **Arguments);
11 Uint64  VGA_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
12  int    VGA_IOCtl(tVFS_Node *Node, int Id, void *Data);
13 Uint16  VGA_int_GetWord(tVT_Char *Char);
14
15 // === GLOBALS ===
16 MODULE_DEFINE(0, 0x000A, VGA, VGA_Install, NULL, NULL);
17 tDevFS_Driver   gVGA_DevInfo = {
18         NULL, "VGA",
19         {
20         .NumACLs = 0,
21         .Size = 80*25*sizeof(tVT_Char),
22         //.Read = VGA_Read,
23         .Write = VGA_Write,
24         .IOCtl = VGA_IOCtl
25         }
26 };
27 Uint16  *gVGA_Framebuffer = (void*)( KERNEL_BASE|0xB8000 );
28
29 // === CODE ===
30 /**
31  * \fn int VGA_Install(char **Arguments)
32  */
33 int VGA_Install(char **Arguments)
34 {
35         Uint8   byte;
36         
37         // Enable Bright Backgrounds
38         inb(0x3DA);     // Reset flipflop
39         outb(0x3C0, 0x30);      // Index 0x10, PAS
40         byte = inb(0x3C1);
41         byte &= ~8;     // Disable Blink
42         outb(0x3C0, byte);      // Write value
43         
44         
45         // Install DevFS
46         DevFS_AddDevice( &gVGA_DevInfo );
47         
48         return 1;
49 }
50
51 /**
52  * \fn Uint64 VGA_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
53  * \brief Writes a string of bytes to the VGA controller
54  */
55 Uint64 VGA_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
56 {
57          int    num = Length / sizeof(tVT_Char);
58          int    ofs = Offset / sizeof(tVT_Char);
59          int    i = 0;
60         tVT_Char        *chars = Buffer;
61         Uint16  word;
62         
63         //ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
64         
65         for( ; num--; i ++, ofs ++)
66         {
67                 word = VGA_int_GetWord( &chars[i] );
68                 gVGA_Framebuffer[ ofs ] = word;
69         }
70         
71         //LEAVE('X', Length);
72         return Length;
73 }
74
75 /**
76  * \fn int VGA_IOCtl(tVFS_Node *Node, int Id, void *Data)
77  * \brief IO Control Call
78  */
79 int VGA_IOCtl(tVFS_Node *Node, int Id, void *Data)
80 {
81         switch(Id)
82         {
83         case DRV_IOCTL_TYPE:    return DRV_TYPE_VIDEO;
84         case DRV_IOCTL_IDENT:   memcpy(Data, "VGA\0", 4);       return 1;
85         case DRV_IOCTL_VERSION: *(int*)Data = 50;       return 1;
86         case DRV_IOCTL_LOOKUP:  return 0;
87         
88         case VIDEO_IOCTL_SETMODE:       return 0;       // Ignored (Text Only ATM)
89         case VIDEO_IOCTL_GETMODE:       return 0;       // Mode 0 only
90         case VIDEO_IOCTL_FINDMODE:      return 0;       // Text Only!
91         case VIDEO_IOCTL_MODEINFO:
92                 if( ((tVideo_IOCtl_Mode*)Data)->id != 0)        return 0;
93                 ((tVideo_IOCtl_Mode*)Data)->width = 80;
94                 ((tVideo_IOCtl_Mode*)Data)->height = 25;
95                 ((tVideo_IOCtl_Mode*)Data)->bpp = 4;
96                 return 1;
97         }
98         return 0;
99 }
100
101 /**
102  * \fn Uint8 VGA_int_GetColourNibble(Uint16 col)
103  * \brief Converts a 12-bit colour into a VGA 4-bit colour
104  */
105 Uint8 VGA_int_GetColourNibble(Uint16 col)
106 {
107         Uint8   ret = 0;
108          int    bright = 0;
109         
110         col = col & 0xCCC;
111         col = ((col>>2)&3) | ((col>>4)&0xC) | ((col>>6)&0x30);
112         bright = ( (col & 2 ? 1 : 0) + (col & 8 ? 1 : 0) + (col & 32 ? 1 : 0) ) / 2;
113         
114         
115         switch(col)
116         {
117         //      Black
118         case 0x00:      ret = 0x0;      break;
119         // Dark Grey
120         case 0x15:      ret = 0x8;      break;
121         // Blues
122         case 0x01:
123         case 0x02:      ret = 0x1;      break;
124         case 0x03:      ret = 0x9;      break;
125         // Green
126         case 0x04:
127         case 0x08:      ret = 0x2;      break;
128         case 0x0C:      ret = 0xA;      break;
129         // Reds
130         case 0x10:
131         case 0x20:      ret = 0x4;      break;
132         case 0x30:      ret = 0xC;      break;
133         // Light Grey
134         case 0x2A:      ret = 0x7;      break;
135         // White
136         case 0x3F:      ret = 0xF;      break;
137         
138         default:
139                 ret |= (col & 0x03 ? 1 : 0);
140                 ret |= (col & 0x0C ? 2 : 0);
141                 ret |= (col & 0x30 ? 4 : 0);
142                 ret |= (bright ? 8 : 0);
143                 break;
144         }
145         return ret;
146 }
147
148 /**
149  * \fn Uint16 VGA_int_GetWord(tVT_Char *Char)
150  * \brief Convers a character structure to a VGA character word
151  */
152 Uint16 VGA_int_GetWord(tVT_Char *Char)
153 {
154         Uint16  ret;
155         Uint16  col;
156         
157         // Get Character
158         if(Char->Ch < 128)
159                 ret = Char->Ch;
160         else {
161                 switch(Char->Ch)
162                 {
163                 default:        ret = 0;        break;
164                 }
165         }
166         
167         col = VGA_int_GetColourNibble(Char->BGCol);
168         ret |= col << 12;
169         
170         col = VGA_int_GetColourNibble(Char->FGCol);
171         ret |= col << 8;
172         
173         return ret;
174 }

UCC git Repository :: git.ucc.asn.au