- Start rosapps rearrange and cleanup process.
[reactos.git] / rosapps / applications / sysutils / utils / pice / module / vga.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7 vga.c
8
9 Abstract:
10
11 VGA HW dependent draw routines
12
13 Environment:
14
15 Kernel mode only
16
17 Author:
18
19 Klaus P. Gerlicher
20 Reactos Port by Eugene Ingerman
21
22 Revision History:
23
24 04-Aug-1998: created
25 15-Nov-2000: general cleanup of source files
26
27 Copyright notice:
28
29 This file may be distributed under the terms of the GNU Public License.
30
31 --*/
32
33 ////////////////////////////////////////////////////
34 // INCLUDES
35 ////
36 #include "remods.h"
37 #include "precomp.h"
38
39 //#include <asm/io.h>
40 //#include <linux/ctype.h>
41
42
43 ////////////////////////////////////////////////////
44 // PROTOTYPES
45 ////
46 extern void pice_save_current_registers(void);
47 extern void pice_restore_current_registers(void);
48 extern void pice_set_mode_3_80x50(void);
49 extern void pice_set_mode_3_80x25(void);
50
51 extern UCHAR cGraphTable[8*256];
52
53 // storage for original VGA font
54 UCHAR cGraphTable2[16*256];
55
56 ////////////////////////////////////////////////////
57 // DEFINES
58 ////
59 #define VGA_EXTENDED // define this for 80x50 console mode
60
61 #ifndef VGA_EXTENDED
62 #define SCREEN_BUFFER_SIZE (80*25*2)
63 #else
64 #define SCREEN_BUFFER_SIZE (80*50*2)
65 #endif
66
67 /* Port addresses of control regs */
68 #define MISCOUTPUT 0x3c2
69 #define FEATURECONTROL 0x3da
70 #define SEQUENCER 0x3c4
71 #define CRTC 0x03d4
72 #define GRAPHICS 0x3ce
73 #define ATTRIBS 0x03c0
74 #define PELADDRESSWRITE 0x3c8
75 #define PELDATAREG 0x3c9
76
77 /* Number of regs on the various controllers */
78
79 #define MAXSEQ 5
80 #define MAXCRTC 0x19
81 #define MAXGRAPH 0x9
82 #define MAXATTRIB 0x015
83
84 ////////////////////////////////////////////////////
85 // GLOBALS
86 ////
87 // used for HERCULES text and VGA text mode
88 WINDOW wWindowVga[4]=
89 #ifndef VGA_EXTENDED
90 {
91 {1,3,1,0,FALSE},
92 {5,4,1,0,FALSE},
93 {10,9,1,0,FALSE},
94 {20,4,1,0,FALSE}
95 };
96 #else // VGA_EXTENDED
97 {
98 {1,3,1,0,FALSE},
99 {5,4,1,0,FALSE},
100 {10,24,1,0,FALSE},
101 {35,14,1,0,FALSE}
102 };
103 #endif // VGA_EXTENDED
104
105 PUCHAR pScreenBufferVga;
106 PUCHAR pScreenBufferSaveVga = NULL;
107 PUCHAR pScreenBufferTempVga;
108 PUCHAR pScreenBufferHardwareVga;
109 PUCHAR pFontBufferVga = NULL;
110
111 UCHAR offset_a = 0;
112 UCHAR offset_c = 0,offset_d = 0;
113 UCHAR offset_e = 0,offset_f = 0;
114
115 struct _attr
116 {
117 union
118 {
119 struct
120 {
121
122 UCHAR fgcol : 4;
123 UCHAR bkcol : 3;
124 UCHAR blink : 1;
125 }bits;
126 UCHAR Asuchar;
127 }u;
128 }attr;
129
130 unsigned char oldgraphicsmode;
131 unsigned char oldgraphicsmisc;
132 unsigned char oldsqregmapmask;
133 unsigned char oldsqregmemory;
134 unsigned char oldgraphicssetresetenable;
135 unsigned char oldgraphicsreadmapsel;
136
137 unsigned char read_vga_reg(int port, int reg)
138 {
139 outportb(port,reg);
140 return(inportb(port+1));
141 }
142
143 void write_vga_reg(int port, unsigned char reg, unsigned char value)
144 {
145 outportb(port,reg);
146 outportb(port+1,value);
147 }
148
149 /* Registers within controllers */
150 #define VREND 0x11
151 #define GRREGSETRESET 0
152 #define GRREGENABLESETRESET 1
153 #define GRREGREADMAPSEL 4
154 #define SQREGMAPMASK 2
155 #define SQREGMEMORY 4
156 #define GRREGWRMODE 5
157 #define GRREGMISC 6
158
159 void map_font_memory(void)
160 {
161 oldgraphicssetresetenable = read_vga_reg(GRAPHICS, GRREGENABLESETRESET);
162 oldgraphicsmode = read_vga_reg(GRAPHICS, GRREGWRMODE);
163 oldgraphicsmisc = read_vga_reg(GRAPHICS, GRREGMISC);
164 oldgraphicsreadmapsel = read_vga_reg(GRAPHICS, GRREGREADMAPSEL);
165 oldsqregmapmask = read_vga_reg(SEQUENCER, SQREGMAPMASK);
166 oldsqregmemory = read_vga_reg(SEQUENCER, SQREGMEMORY);
167
168
169 /* Make sure set/reset enable is off */
170 write_vga_reg(GRAPHICS,GRREGENABLESETRESET,0);
171 /* Select read plane 2 */
172 write_vga_reg(GRAPHICS,GRREGREADMAPSEL,0x02);
173 /* Make sure write and read mode = 0 */
174 write_vga_reg(GRAPHICS,GRREGWRMODE,0x00);
175 /* Set mapping to 64K at a000:0 & turn off odd/even at the graphics reg */
176 write_vga_reg(GRAPHICS,GRREGMISC, 0x04);
177 /* Set sequencer plane to 2 */
178 write_vga_reg(SEQUENCER,SQREGMAPMASK, 0x04);
179 /* Turn off odd/even at the sequencer */
180 write_vga_reg(SEQUENCER,SQREGMEMORY, 0x07);
181 }
182
183 void unmap_font_memory(void)
184 {
185 write_vga_reg(GRAPHICS,GRREGENABLESETRESET,oldgraphicssetresetenable);
186 write_vga_reg(GRAPHICS,GRREGWRMODE,oldgraphicsmode);
187 write_vga_reg(GRAPHICS,GRREGREADMAPSEL,oldgraphicsreadmapsel);
188 write_vga_reg(GRAPHICS,GRREGMISC, oldgraphicsmisc);
189 write_vga_reg(SEQUENCER,SQREGMAPMASK, oldsqregmapmask);
190 write_vga_reg(SEQUENCER,SQREGMEMORY, oldsqregmemory);
191 }
192
193 /* Font and palette constants */
194 #define BYTESPERFONT 8
195 #define FONTENTRIES 256
196 #define FONTBUFFERSIZE 8192
197
198 void save_font(UCHAR* graph_table)
199 {
200 PUCHAR FontBase = pFontBufferVga;
201 int i,j;
202 map_font_memory();
203
204 for (i=0; i < FONTENTRIES; i++)
205 for (j=0; j < 16; j++)
206 graph_table[i*16+j] = FontBase[i*32+j];
207
208 unmap_font_memory();
209 }
210
211 void load_font(UCHAR* graph_table,int bEnter)
212 {
213 PUCHAR FontBase = pFontBufferVga;
214 int i,j;
215 map_font_memory();
216
217 if(bEnter)
218 {
219 #ifdef VGA_EXTENDED
220 for (i=0; i < FONTENTRIES; i++)
221 for (j=0; j < 8; j++)
222 FontBase[i*32+j] = graph_table[i*BYTESPERFONT+j];
223 #else // VGA_EXTENDED
224 for (i=0; i < FONTENTRIES; i++)
225 for (j=0; j < 16; j++)
226 FontBase[i*32+j] = graph_table[i*BYTESPERFONT+(j/2)] << (j&1);
227 #endif // VGA_EXTENDED
228 }
229 else
230 {
231 for (i=0; i < FONTENTRIES; i++)
232 for (j=0; j < 16; j++)
233 FontBase[i*32+j] = graph_table[i*16+j];
234 }
235
236 unmap_font_memory();
237 }
238
239 //*************************************************************************
240 // SetForegroundColorVga()
241 //
242 //*************************************************************************
243 void SetForegroundColorVga(ECOLORS col)
244 {
245 attr.u.bits.fgcol = col;
246 attr.u.bits.blink = 0;
247 }
248
249 //*************************************************************************
250 // SetBackgroundColorVga()
251 //
252 //*************************************************************************
253 void SetBackgroundColorVga(ECOLORS col)
254 {
255 attr.u.bits.bkcol = col;
256 attr.u.bits.blink = 0;
257 }
258
259 //*************************************************************************
260 // PrintGrafVga()
261 //
262 //*************************************************************************
263 void PrintGrafVga(ULONG x,ULONG y,UCHAR c)
264 {
265 ((PUSHORT)pScreenBufferVga)[y*GLOBAL_SCREEN_WIDTH + x] = (USHORT)((attr.u.Asuchar<<8)|c);
266 }
267
268 //*************************************************************************
269 // ShowCursor()
270 //
271 // show hardware cursor
272 //*************************************************************************
273 void ShowCursorVga(void)
274 {
275 ENTER_FUNC();
276
277 bCursorEnabled=TRUE;
278
279 outb_p(0x0a,0x3d4);
280 outb_p(inb_p(0x3d5)&~0x20,0x3d5);
281
282 LEAVE_FUNC();
283 }
284
285 //*************************************************************************
286 // HideCursorVga()
287 //
288 // hide hardware cursor
289 //*************************************************************************
290 void HideCursorVga(void)
291 {
292 ENTER_FUNC();
293 bCursorEnabled=FALSE;
294
295 outb_p(0x0a,0x3d4);
296 outb_p(inb_p(0x3d5)|0x20,0x3d5);
297
298 LEAVE_FUNC();
299 }
300
301 //*************************************************************************
302 // CopyLineTo()
303 //
304 // copy a line from src to dest
305 //*************************************************************************
306 void CopyLineToVga(USHORT dest,USHORT src)
307 {
308 PUSHORT p = (PUSHORT)pScreenBufferVga;
309
310 ENTER_FUNC();
311
312 PICE_memcpy(&p[dest*GLOBAL_SCREEN_WIDTH],&p[src*GLOBAL_SCREEN_WIDTH],GLOBAL_SCREEN_WIDTH*sizeof(USHORT));
313
314 LEAVE_FUNC();
315 }
316
317 //*************************************************************************
318 // InvertLineVga()
319 //
320 // invert a line on the screen
321 //*************************************************************************
322 void InvertLineVga(ULONG line)
323 {
324 ULONG i;
325 PUSHORT p = (PUSHORT)pScreenBufferVga;
326 USHORT attr;
327
328 if(line < GLOBAL_SCREEN_HEIGHT)
329 {
330 attr = p[line*GLOBAL_SCREEN_WIDTH]>>8;
331 attr = ((attr & 0x07)<<4) | ((attr & 0xF0)>>4);
332 attr <<= 8;
333 for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
334 p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0x00FF) | attr;
335 }
336 }
337
338 //*************************************************************************
339 // HatchLineVga()
340 //
341 // hatches a line on the screen
342 //*************************************************************************
343 void HatchLineVga(ULONG line)
344 {
345 ULONG i;
346 PUSHORT p = (PUSHORT)pScreenBufferVga;
347
348 if(line < GLOBAL_SCREEN_HEIGHT)
349 {
350 for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
351 p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0xF0FF) | 0x0c00;
352 }
353 }
354
355 //*************************************************************************
356 // ClrLineVga()
357 //
358 // clear a line on the screen
359 //*************************************************************************
360 void ClrLineVga(ULONG line)
361 {
362 ULONG i;
363 PUSHORT p = (PUSHORT)pScreenBufferVga;
364
365 if(line < GLOBAL_SCREEN_HEIGHT)
366 {
367 for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
368 p[line*GLOBAL_SCREEN_WIDTH + i] = (USHORT)((attr.u.Asuchar<<8) | 0x20);
369 }
370 }
371
372 //*************************************************************************
373 // PrintLogoVga()
374 //
375 //*************************************************************************
376 void PrintLogoVga(BOOLEAN bShow)
377 {
378 NOT_IMPLEMENTED();
379 }
380
381 //*************************************************************************
382 // PrintCursorVga()
383 //
384 // emulate a blinking cursor block
385 //*************************************************************************
386 void PrintCursorVga(BOOLEAN bForce)
387 {
388 static ULONG count=0;
389 USHORT charoffset;
390 UCHAR data;
391 ULONG x=wWindow[OUTPUT_WINDOW].usCurX,y=wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY;
392
393 if( count++>250 )
394 {
395 count=0;
396
397 charoffset = (y* GLOBAL_SCREEN_WIDTH + x);
398
399 outb_p(0x0e,0x3d4);
400 data=(UCHAR)((charoffset>>8)&0xFF);
401 outb_p(data,0x3d5);
402
403 outb_p(0x0f,0x3d4);
404 data=(UCHAR)(charoffset & 0xFF);
405 outb_p(data,0x3d5);
406 }
407 }
408
409 //*************************************************************************
410 // SaveGraphicsVga()
411 //
412 //*************************************************************************
413 void SaveGraphicsStateVga(void)
414 {
415 UCHAR data;
416
417 // save current regs
418 pice_save_current_registers();
419
420 // unprotect crtc regs 0-7
421 outb_p(0x11,0x3d4);
422 data = inb_p(0x3d5);
423 outb_p(data & 0x7F,0x3d5);
424
425 // save current font
426 save_font(cGraphTable2);
427
428 // restore original regs
429 #ifdef VGA_EXTENDED
430 pice_set_mode_3_80x50();
431 #else
432 pice_set_mode_3_80x25();
433 #endif
434
435 // load a font
436 load_font(cGraphTable,1);
437
438 // copy the screen content to temp area
439 PICE_memcpy(pScreenBufferTempVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
440 // copy the console to the screen
441 PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferVga,SCREEN_BUFFER_SIZE);
442 // save original pointer
443 pScreenBufferSaveVga = pScreenBufferVga;
444 // pScreenBufferVga now points to screen
445 pScreenBufferVga = pScreenBufferHardwareVga;
446 }
447
448 //*************************************************************************
449 // RestoreGraphicsStateVga()
450 //
451 //*************************************************************************
452 void RestoreGraphicsStateVga(void)
453 {
454 UCHAR data;
455
456 // unprotect crtc regs 0-7
457 outb_p(0x11,0x3d4);
458 data = inb_p(0x3d5);
459 outb_p(data & 0x7F,0x3d5);
460
461 // restore original regs
462 pice_restore_current_registers();
463
464 // load a font
465 load_font(cGraphTable2,0);
466
467 pScreenBufferVga = pScreenBufferSaveVga;
468 // copy screen to the console
469 PICE_memcpy(pScreenBufferVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
470 // copy the temp area to the screen
471 PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferTempVga,SCREEN_BUFFER_SIZE);
472 }
473
474 //*************************************************************************
475 // ConsoleInitVga()
476 //
477 // init terminal screen
478 //*************************************************************************
479 BOOLEAN ConsoleInitVga(void)
480 {
481 BOOLEAN bResult = FALSE;
482 PUSHORT p;
483 PHYSICAL_ADDRESS FrameBuffer;
484 PHYSICAL_ADDRESS FontBuffer;
485
486
487 ENTER_FUNC();
488
489 ohandlers.CopyLineTo = CopyLineToVga;
490 ohandlers.PrintGraf = PrintGrafVga;
491 ohandlers.ClrLine = ClrLineVga;
492 ohandlers.InvertLine = InvertLineVga;
493 ohandlers.HatchLine = HatchLineVga;
494 ohandlers.PrintLogo = PrintLogoVga;
495 ohandlers.PrintCursor = PrintCursorVga;
496 ohandlers.SaveGraphicsState = SaveGraphicsStateVga;
497 ohandlers.RestoreGraphicsState = RestoreGraphicsStateVga;
498 ohandlers.ShowCursor = ShowCursorVga;
499 ohandlers.HideCursor = HideCursorVga;
500 ohandlers.SetForegroundColor = SetForegroundColorVga;
501 ohandlers.SetBackgroundColor = SetBackgroundColorVga;
502
503 ihandlers.GetKeyPolled = KeyboardGetKeyPolled;
504 ihandlers.FlushKeyboardQueue = KeyboardFlushKeyboardQueue;
505
506 SetWindowGeometry(wWindowVga);
507
508 GLOBAL_SCREEN_WIDTH = 80;
509 #ifndef VGA_EXTENDED
510 GLOBAL_SCREEN_HEIGHT = 25;
511 #else // VGA_EXTENDED
512 GLOBAL_SCREEN_HEIGHT = 50;
513 #endif // VGA_EXTENDED
514
515 attr.u.Asuchar = 0x07;
516
517 // the real framebuffer
518 FrameBuffer.u.LowPart = 0xB8000;
519 pScreenBufferHardwareVga = MmMapIoSpace(FrameBuffer,SCREEN_BUFFER_SIZE,MmNonCached);
520
521 //The real font buffer
522 FontBuffer.u.LowPart = 0xA0000;
523 pFontBufferVga = MmMapIoSpace(FontBuffer,FONTBUFFERSIZE,MmNonCached);
524
525 // the console
526 pScreenBufferVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
527 // the save area
528 pScreenBufferTempVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
529
530 if(pScreenBufferVga)
531 {
532 DPRINT((0,"VGA memory phys. 0x000b0000 mapped to virt. 0x%x\n",pScreenBufferVga));
533
534 bResult = TRUE;
535
536 p = (PUSHORT)pScreenBufferVga;
537
538 PICE_memset(pScreenBufferVga,0x0,SCREEN_BUFFER_SIZE);
539
540 DPRINT((0,"VGA memory cleared!\n"));
541
542 EmptyRingBuffer();
543
544 DPRINT((0,"ConsoleInitVga() SUCCESS!\n"));
545 }
546
547 LEAVE_FUNC();
548
549 return bResult;
550 }
551
552 //*************************************************************************
553 // ConsoleShutdownVga()
554 //
555 // exit terminal screen
556 //*************************************************************************
557 void ConsoleShutdownVga(void)
558 {
559 ENTER_FUNC();
560
561 if(pScreenBufferVga)
562 {
563 PICE_free(pScreenBufferVga);
564 PICE_free(pScreenBufferTempVga);
565 MmUnmapIoSpace(pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
566 MmUnmapIoSpace(pFontBufferVga,FONTBUFFERSIZE);
567 }
568
569 LEAVE_FUNC();
570 }
571
572