]> 4ch.mooo.com Git - 16.git/blob - 16/tauron/C_SRC/MODES.CPP
added another library ^^
[16.git] / 16 / tauron / C_SRC / MODES.CPP
1 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
2 //=-                                                                         -=\r
3 //=-                   Tauron VGA Utilities Version 3.0                      -=\r
4 //=-                      Released September 20, 1998                        -=\r
5 //=-                                                                         -=\r
6 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
7 //=- Copyright (c) 1997, 1998 by Jeff Morgan  =-= This code is FREE provided -=\r
8 //=- All Rights Reserved.                     =-= that you put my name some- -=\r
9 //=-                                          =-= where in your credits.     -=\r
10 //=- DISCLAIMER:                              =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
11 //=- I assume no responsibility whatsoever for any effect that this package, -=\r
12 //=- the information contained therein or the use thereof has on you, your   -=\r
13 //=- sanity, computer, spouse, children, pets or anything else related to    -=\r
14 //=- you or your existance. No warranty is provided nor implied with this    -=\r
15 //=- source code.                                                            -=\r
16 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
17 #include <stdlib.h>\r
18 #include <stdio.h>\r
19 #include <conio.h>\r
20 #include <dos.h>\r
21 #include "tauron.h"\r
22 #include "modes_c.inc"\r
23 #include "palette.inc"\r
24 \r
25 void setpalette4();\r
26 void setpalette16();\r
27 void setpalette256();\r
28 Vmode Mode;\r
29 \r
30 #define SEQ_ADDR                                0x03C4\r
31 #define GRACON_ADDR                     0x03CE\r
32 #define CRTC_ADDR                       0x03D4\r
33 \r
34 void ReadBIOSfont(int fontnum, int bytesperchar)\r
35 {\r
36    char far *biosfont,*vidmem;\r
37    struct REGPACK reg;\r
38    unsigned char oldmode,oldmisc,oldmem,oldmask;\r
39    unsigned char newmode,newmisc,newmem;\r
40 \r
41    // get the location of the font stroed in BIOS\r
42    reg.r_ax = 0x1130;\r
43    reg.r_bx = fontnum << 8;\r
44    intr(0x10, &reg);\r
45 \r
46    // Make a pointer to the font\r
47    biosfont = (char far *)MK_FP( reg.r_es, reg.r_bp);\r
48    vidmem = (char far *)MK_FP( 0xA000, 0x0000);\r
49 \r
50    // Store the OLD 'Mode Register' value\r
51    outportb(GRACON_ADDR,5);\r
52    oldmode = inportb(GRACON_ADDR+1);\r
53    // Store the OLD 'Miscellaneous Register' value\r
54    outportb(GRACON_ADDR,6);\r
55    oldmisc = inportb(GRACON_ADDR+1);\r
56    // Store the OLD 'Mask Map' value\r
57    outportb(SEQ_ADDR,2);\r
58    oldmask = inportb(SEQ_ADDR+1);\r
59    // Store the OLD 'Memory Mode' value\r
60    outportb(SEQ_ADDR,4);\r
61    oldmem = inportb(SEQ_ADDR+1);\r
62 \r
63    // Write the NEW 'Mode Register' value\r
64    newmode = (oldmode & 0xFC);\r
65    outport(GRACON_ADDR, (newmode << 8) | 0x05);\r
66    // Write the NEW 'Miscellaneous Register' value\r
67    newmisc = ((oldmisc & 0xF1)|4);\r
68    outport(GRACON_ADDR, (newmisc << 8) | 0x06);\r
69    // Write the NEW 'Mask Map' value\r
70    outport(SEQ_ADDR, 0x0402);\r
71    // Write the NEW 'Memory Mode' value\r
72    newmem = (oldmem | 4);\r
73    outport(SEQ_ADDR, (newmem << 8) | 0x04);\r
74 \r
75    // Copy the font from BIOS\r
76    for (int i = 0; i < 256; i++)\r
77    {\r
78       for (int j = 0; j < bytesperchar; j++)\r
79       {\r
80          *vidmem++ = *biosfont++;\r
81       }\r
82       for (int k = 0; k < 32-bytesperchar; k++)\r
83       {\r
84          *vidmem++ = 0x00;\r
85       }\r
86    }\r
87 \r
88    // Write the OLD 'Mode Register' value\r
89    outport(GRACON_ADDR, (oldmode << 8) | 0x05);\r
90    // Write the OLD 'Miscellaneous Register' value\r
91    outport(GRACON_ADDR, (oldmisc << 8) | 0x06);\r
92    // Write the OLD 'Mask Map' value\r
93    outport(SEQ_ADDR,(oldmask << 8) | 0x02);\r
94    // Write the OLD 'Memory Mode' value\r
95    outport(SEQ_ADDR, (oldmem << 8) | 0x04);\r
96 }\r
97 \r
98 void SetMode(unsigned int regs)\r
99 {\r
100    asm {\r
101    MOV SI, regs\r
102 \r
103    // Send MISC regs\r
104    MOV DX,MISC_ADDR\r
105    MOV AL,[SI]\r
106    OUT DX,AL\r
107    INC SI\r
108 \r
109    MOV DX,STATUS_ADDR\r
110    MOV AL,[SI]\r
111    OUT DX,AL\r
112    INC SI\r
113 \r
114    // Send SEQ regs\r
115    MOV CX,0\r
116 REG_LOOP:\r
117    MOV DX,SEQ_ADDR\r
118    MOV AL,CL\r
119    OUT DX,AL\r
120 \r
121    MOV DX,SEQ_ADDR\r
122    INC DX\r
123    MOV AL,[SI]\r
124    OUT DX,AL\r
125 \r
126    INC SI\r
127    INC CX\r
128    CMP CL,5\r
129    JL REG_LOOP\r
130 \r
131    // Clear Protection bits\r
132    MOV AH,0EH\r
133    MOV AL,11H\r
134    AND AH,7FH\r
135    MOV DX,CRTC_ADDR\r
136    OUT DX,AX\r
137 \r
138    // Send CRTC regs\r
139    MOV CX,0\r
140 REG_LOOP2:\r
141    MOV DX,CRTC_ADDR\r
142    MOV AL,CL\r
143    OUT DX,AL\r
144 \r
145    MOV DX,CRTC_ADDR\r
146    INC DX\r
147    MOV AL,[SI]\r
148    OUT DX,AL\r
149 \r
150    INC SI\r
151    INC CX\r
152    CMP CL,25\r
153    JL REG_LOOP2\r
154 \r
155    // Send GRAPHICS regs\r
156    MOV CX,0\r
157 REG_LOOP3:\r
158    MOV DX,GRACON_ADDR\r
159    MOV AL,CL\r
160    OUT DX,AL\r
161 \r
162    MOV DX,GRACON_ADDR\r
163    INC DX\r
164    MOV AL,[SI]\r
165    OUT DX,AL\r
166 \r
167    INC SI\r
168    INC CX\r
169    CMP CL,9\r
170    JL REG_LOOP3\r
171 \r
172    MOV DX,STATUS_ADDR\r
173    IN AL,DX\r
174 \r
175    // Send ATTRCON regs\r
176    MOV CX,0\r
177 REG_LOOP4:\r
178    MOV DX,ATTRCON_ADDR\r
179    IN AX,DX\r
180 \r
181    MOV AL,CL\r
182    OUT DX,AL\r
183 \r
184    MOV AL,[SI]\r
185    OUT DX,AL\r
186 \r
187    INC SI\r
188    INC CX\r
189    CMP CL,21\r
190    JL REG_LOOP4\r
191 \r
192    MOV AL,20H\r
193    OUT DX,AL\r
194    }\r
195 }\r
196 \r
197 void SetVideoMode(int mode)\r
198 {\r
199    Mode.mode = mode;\r
200    if (mode == MODE00H)                        // 40 x 25 x 16\r
201    {\r
202       SetMode((unsigned int)&mode00h);\r
203       setpalette16();\r
204       ReadBIOSfont(6,16);\r
205 \r
206       Mode.width = 40;\r
207       Mode.height = 25;\r
208       Mode.width_bytes = 1000;\r
209       Mode.colors = 16;\r
210       Mode.attrib = TVU_TEXT;\r
211    }\r
212    else if (mode == MODE03H)                   // 80 x 25 x 16\r
213    {\r
214       SetMode((unsigned int)&mode03h);\r
215       setpalette16();\r
216       ReadBIOSfont(6,16);\r
217 \r
218       Mode.width = 80;\r
219       Mode.height = 25;\r
220       Mode.width_bytes = 2000;\r
221       Mode.colors = 16;\r
222       Mode.attrib = TVU_TEXT;\r
223    }\r
224    else if (mode == MODE04H)                   // 320 x 200 x 4\r
225    {\r
226       SetMode((unsigned int)&mode04h);\r
227       setpalette4();\r
228 \r
229       Mode.width = 320;\r
230       Mode.height = 200;\r
231       Mode.width_bytes = 8192;\r
232       Mode.colors = 4;\r
233       Mode.attrib = TVU_GRAPHICS;\r
234    }\r
235    else if (mode == MODE06H)                    // 640 x 200 x 2\r
236    {\r
237       SetMode((unsigned int)&mode06h);\r
238 \r
239       Mode.width = 640;\r
240       Mode.height = 200;\r
241       Mode.width_bytes = 8192;\r
242       Mode.colors = 2;\r
243       Mode.attrib = TVU_GRAPHICS;\r
244    }\r
245    else if (mode == MODE07H)                    // 80 x 25 x 2\r
246    {\r
247       SetMode((unsigned int)&mode07h);\r
248 \r
249       Mode.width = 80;\r
250       Mode.height = 25;\r
251       Mode.width_bytes = 2000;\r
252       Mode.colors = 2;\r
253       Mode.attrib = TVU_TEXT | TVU_MONOCHROME;\r
254    }\r
255    else if (mode == MODE0DH)                    // 320 x 200 x 16\r
256    {\r
257       SetMode((unsigned int)&mode0Dh);\r
258       setpalette16();\r
259 \r
260       Mode.width = 320;\r
261       Mode.height = 200;\r
262       Mode.width_bytes = 8000;\r
263       Mode.colors = 16;\r
264       Mode.attrib = TVU_GRAPHICS | TVU_PLANAR;\r
265    }\r
266    else if (mode == MODE0EH)                    // 640 x 200 x 16\r
267    {\r
268       SetMode((unsigned int)&mode0Eh);\r
269       setpalette16();\r
270 \r
271       Mode.width = 640;\r
272       Mode.height = 200;\r
273       Mode.width_bytes = 16000;\r
274       Mode.colors = 16;\r
275       Mode.attrib = TVU_GRAPHICS | TVU_PLANAR;\r
276    }\r
277    else if (mode == MODE0FH)                    // 640 x 350 x 2\r
278    {\r
279       SetMode((unsigned int)&mode0Fh);\r
280 \r
281       Mode.width = 640;\r
282       Mode.height = 350;\r
283       Mode.width_bytes = 28000;\r
284       Mode.colors = 2;\r
285       Mode.attrib = TVU_GRAPHICS | TVU_MONOCHROME;\r
286    }\r
287    else if (mode == MODE10H)                    // 640 x 350 x 16\r
288    {\r
289       SetMode((unsigned int)&mode10h);\r
290       setpalette16();\r
291 \r
292       Mode.width = 640;\r
293       Mode.height = 350;\r
294       Mode.width_bytes = 28000;\r
295       Mode.colors = 16;\r
296       Mode.attrib = TVU_GRAPHICS | TVU_PLANAR;\r
297    }\r
298    else if (mode == MODE11H)                    // 640 x 480 x 2\r
299    {\r
300       SetMode((unsigned int)&mode11h);\r
301 \r
302       Mode.width = 640;\r
303       Mode.height = 480;\r
304       Mode.width_bytes = 38400u;\r
305       Mode.colors = 2;\r
306       Mode.attrib = TVU_GRAPHICS | TVU_PLANAR;\r
307    }\r
308    else if (mode == MODE12H)                    // 640 x 480 x 16\r
309    {\r
310       SetMode((unsigned int)&mode12h);\r
311       setpalette16();\r
312 \r
313       Mode.width = 640;\r
314       Mode.height = 480;\r
315       Mode.width_bytes = 38400u;\r
316       Mode.colors = 16;\r
317       Mode.attrib = TVU_GRAPHICS | TVU_PLANAR;\r
318    }\r
319    else if (mode == MODE13H)                    // 320 x 200 x 256\r
320    {\r
321       SetMode((unsigned int)&mode13h);\r
322       setpalette256();\r
323 \r
324       Mode.width = 320;\r
325       Mode.height = 200;\r
326       Mode.width_bytes = 64000u;\r
327       Mode.colors = 256;\r
328       Mode.attrib = TVU_GRAPHICS;\r
329    }\r
330    else if (mode == CHAIN4)                     // unchained 320 x 200 x 256\r
331    {\r
332       SetMode((unsigned int)&modeC4);\r
333       setpalette256();\r
334 \r
335       Mode.width = 320;\r
336       Mode.height = 200;\r
337       Mode.width_bytes = 16000;\r
338       Mode.colors = 256;\r
339       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
340    }\r
341    else if (mode == MODE_X)                     // unchained 320 x 240 x 256\r
342    {\r
343       SetMode((unsigned int)&modeC4);\r
344 \r
345       outportb(MISC_ADDR,0xE3);\r
346       // turn off write protect\r
347       outport(CRTC_ADDR,0x2C11);\r
348       // vertical total\r
349       outport(CRTC_ADDR,0x0D06);\r
350       // overflow register\r
351       outport(CRTC_ADDR,0x3E07);\r
352       // vertical retrace start\r
353       outport(CRTC_ADDR,0xEA10);\r
354       // vertical retrace end AND wr.prot\r
355       outport(CRTC_ADDR,0xAC11);\r
356       // vertical display enable end\r
357       outport(CRTC_ADDR,0xDF12);\r
358       // start vertical blanking\r
359       outport(CRTC_ADDR,0xE715);\r
360       // end vertical blanking\r
361       outport(CRTC_ADDR,0x0616);\r
362 \r
363       setpalette256();\r
364       Mode.width = 320;\r
365       Mode.height = 240;\r
366       Mode.width_bytes = 19200;\r
367       Mode.colors = 256;\r
368       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
369    }\r
370    else if (mode == MODE_A)                     // unchained 320 x 350 x 256\r
371    {\r
372       SetMode((unsigned int)&modeC4);\r
373 \r
374       // turn off double scanning mode\r
375       outportb(CRTC_ADDR,9);\r
376       outportb(CRTC_ADDR+1,inportb(CRTC_ADDR+1) & ~0x1F);\r
377       // change the vertical resolution flags to 350\r
378       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0x80);\r
379       // turn off write protect\r
380       outport(CRTC_ADDR,0x2C11);\r
381       // vertical total\r
382       outport(CRTC_ADDR,0xBF06);\r
383       // overflow register\r
384       outport(CRTC_ADDR,0x1F07);\r
385       // vertical retrace start\r
386       outport(CRTC_ADDR,0x8310);\r
387       // vertical retrace end AND wr.prot\r
388       outport(CRTC_ADDR,0x8511);\r
389       // vertical display enable end\r
390       outport(CRTC_ADDR,0x5D12);\r
391       // start vertical blanking\r
392       outport(CRTC_ADDR,0x6315);\r
393       // end vertical blanking\r
394       outport(CRTC_ADDR,0xBA16);\r
395 \r
396       setpalette256();\r
397       Mode.width = 320;\r
398       Mode.height = 350;\r
399       Mode.width_bytes = 28000u;\r
400       Mode.colors = 256;\r
401       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
402    }\r
403    else if (mode == MODE_B)                     // unchained 320 x 400 x 256\r
404    {\r
405       SetMode((unsigned int)&modeC4);\r
406       // turn off double scanning mode\r
407       outportb(CRTC_ADDR,9);\r
408       outportb(CRTC_ADDR+1,inportb(CRTC_ADDR+1) & ~0x1F);\r
409       // change the vertical resolution flags to 400\r
410       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0x40);\r
411 \r
412       setpalette256();\r
413       Mode.width = 320;\r
414       Mode.height = 400;\r
415       Mode.width_bytes = 32000;\r
416       Mode.colors = 256;\r
417       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
418    }\r
419    else if (mode == MODE_C)                     // unchained 320 x 480 x 256\r
420    {\r
421       SetMode((unsigned int)&modeC4);\r
422 \r
423       // turn off double scanning mode\r
424       outportb(CRTC_ADDR,9);\r
425       outportb(CRTC_ADDR+1,inportb(CRTC_ADDR+1) & ~0x1F);\r
426       // change the vertical resolution flags to 480\r
427       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0xC0);\r
428       // turn off write protect\r
429       outport(CRTC_ADDR,0x2C11);\r
430       // vertical total\r
431       outport(CRTC_ADDR,0x0D06);\r
432       // overflow register\r
433       outport(CRTC_ADDR,0x3E07);\r
434       // vertical retrace start\r
435       outport(CRTC_ADDR,0xEA10);\r
436       // vertical retrace end AND wr.prot\r
437       outport(CRTC_ADDR,0xAC11);\r
438       // vertical display enable end\r
439       outport(CRTC_ADDR,0xDF12);\r
440       // start vertical blanking\r
441       outport(CRTC_ADDR,0xE715);\r
442       // end vertical blanking\r
443       outport(CRTC_ADDR,0x0616);\r
444 \r
445       setpalette256();\r
446       Mode.width = 320;\r
447       Mode.height = 480;\r
448       Mode.width_bytes = 38400u;\r
449       Mode.colors = 256;\r
450       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
451    }\r
452    else if (mode == MODE_D)                     // unchained 360 x 200 x 256\r
453    {\r
454       SetMode((unsigned int)&mode13h);\r
455 \r
456       // Turn off Chain 4\r
457       outport(SEQ_ADDR,0x0604);\r
458       // Activate a synchronous reset\r
459       outport(SEQ_ADDR,0x0100);\r
460       // Select 28 mhz pixel clock\r
461       outportb(MISC_ADDR,0xE7);\r
462       // Release synchronous reset\r
463       outport(SEQ_ADDR,0x0300);\r
464 \r
465       // change the vertical resolution flags to 400\r
466       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0x40);\r
467 \r
468       // turn off write protect\r
469       outport(CRTC_ADDR,0x2C11);\r
470 \r
471       outport(CRTC_ADDR,0x6B00);\r
472       outport(CRTC_ADDR,0x5901);\r
473       outport(CRTC_ADDR,0x5A02);\r
474       outport(CRTC_ADDR,0x8E03);\r
475       outport(CRTC_ADDR,0x5E04);\r
476       outport(CRTC_ADDR,0x8A05);\r
477       outport(CRTC_ADDR,0x0008);\r
478       outport(CRTC_ADDR,0xC009);\r
479       outport(CRTC_ADDR,0x000A);\r
480       outport(CRTC_ADDR,0x000B);\r
481       outport(CRTC_ADDR,0x000C);\r
482       outport(CRTC_ADDR,0x000D);\r
483       outport(CRTC_ADDR,0x000E);\r
484       outport(CRTC_ADDR,0x000F);\r
485       outport(CRTC_ADDR,0xAC11);\r
486       outport(CRTC_ADDR,0x2D13);\r
487       outport(CRTC_ADDR,0x0014);\r
488       outport(CRTC_ADDR,0xE317);\r
489       outport(CRTC_ADDR,0xFF18);\r
490 \r
491       setpalette256();\r
492       Mode.width = 360;\r
493       Mode.height = 200;\r
494       Mode.width_bytes = 18000u;\r
495       Mode.colors = 256;\r
496       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
497    }\r
498    else if (mode == MODE_E)                     // unchained 360 x 240 x 256\r
499    {\r
500       SetMode((unsigned int)&mode13h);\r
501 \r
502       // Turn off Chain 4\r
503       outport(SEQ_ADDR,0x0604);\r
504       // Activate a synchronous reset\r
505       outport(SEQ_ADDR,0x0100);\r
506       // Select 28 mhz pixel clock\r
507       outportb(MISC_ADDR,0xE7);\r
508       // Release synchronous reset\r
509       outport(SEQ_ADDR,0x0300);\r
510 \r
511       // change the vertical resolution flags to 480\r
512       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0xC0);\r
513 \r
514       // turn off write protect\r
515       outport(CRTC_ADDR,0x2C11);\r
516 \r
517       outport(CRTC_ADDR,0x6B00);\r
518       outport(CRTC_ADDR,0x5901);\r
519       outport(CRTC_ADDR,0x5A02);\r
520       outport(CRTC_ADDR,0x8E03);\r
521       outport(CRTC_ADDR,0x5E04);\r
522       outport(CRTC_ADDR,0x8A05);\r
523       outport(CRTC_ADDR,0x0D06);\r
524       outport(CRTC_ADDR,0x3E07);\r
525       outport(CRTC_ADDR,0x0008);\r
526       outport(CRTC_ADDR,0xC009);\r
527       outport(CRTC_ADDR,0x000A);\r
528       outport(CRTC_ADDR,0x000B);\r
529       outport(CRTC_ADDR,0x000C);\r
530       outport(CRTC_ADDR,0x000D);\r
531       outport(CRTC_ADDR,0x000E);\r
532       outport(CRTC_ADDR,0x000F);\r
533       outport(CRTC_ADDR,0xEA10);\r
534       outport(CRTC_ADDR,0xAC11);\r
535       outport(CRTC_ADDR,0xDF12);\r
536       outport(CRTC_ADDR,0x2D13);\r
537       outport(CRTC_ADDR,0x0014);\r
538       outport(CRTC_ADDR,0xE715);\r
539       outport(CRTC_ADDR,0x0616);\r
540       outport(CRTC_ADDR,0xE317);\r
541       outport(CRTC_ADDR,0xFF18);\r
542 \r
543       setpalette256();\r
544       Mode.width = 360;\r
545       Mode.height = 240;\r
546       Mode.width_bytes = 21600;\r
547       Mode.colors = 256;\r
548       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
549    }\r
550    else if (mode == MODE_F)                     // unchained 360 x 350 x 256\r
551    {\r
552       SetMode((unsigned int)&mode13h);\r
553 \r
554       // Turn off Chain 4\r
555       outport(SEQ_ADDR,0x0604);\r
556       // Activate a synchronous reset\r
557       outport(SEQ_ADDR,0x0100);\r
558       // Select 28 mhz pixel clock\r
559       outportb(MISC_ADDR,0xE7);\r
560       // Release synchronous reset\r
561       outport(SEQ_ADDR,0x0300);\r
562 \r
563       // change the vertical resolution flags to 350\r
564       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0x80);\r
565 \r
566       // turn off write protect\r
567       outport(CRTC_ADDR,0x2C11);\r
568 \r
569       outport(CRTC_ADDR,0x6B00);\r
570       outport(CRTC_ADDR,0x5901);\r
571       outport(CRTC_ADDR,0x5A02);\r
572       outport(CRTC_ADDR,0x8E03);\r
573       outport(CRTC_ADDR,0x5E04);\r
574       outport(CRTC_ADDR,0x8A05);\r
575       outport(CRTC_ADDR,0xBF06);\r
576       outport(CRTC_ADDR,0x1F07);\r
577       outport(CRTC_ADDR,0x0008);\r
578       outport(CRTC_ADDR,0x4009);\r
579       outport(CRTC_ADDR,0x000A);\r
580       outport(CRTC_ADDR,0x000B);\r
581       outport(CRTC_ADDR,0x000C);\r
582       outport(CRTC_ADDR,0x000D);\r
583       outport(CRTC_ADDR,0x000E);\r
584       outport(CRTC_ADDR,0x000F);\r
585       outport(CRTC_ADDR,0x8310);\r
586       outport(CRTC_ADDR,0x8511);\r
587       outport(CRTC_ADDR,0x5D12);\r
588       outport(CRTC_ADDR,0x2D13);\r
589       outport(CRTC_ADDR,0x0014);\r
590       outport(CRTC_ADDR,0x6315);\r
591       outport(CRTC_ADDR,0xBA16);\r
592       outport(CRTC_ADDR,0xE317);\r
593       outport(CRTC_ADDR,0xFF18);\r
594 \r
595       setpalette256();\r
596       Mode.width = 360;\r
597       Mode.height = 350;\r
598       Mode.width_bytes = 31500;\r
599       Mode.colors = 256;\r
600       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
601    }\r
602    else if (mode == MODE_G)                     // unchained 360 x 400 x 256\r
603    {\r
604       SetMode((unsigned int)&mode13h);\r
605 \r
606       // Turn off Chain 4\r
607       outport(SEQ_ADDR,0x0604);\r
608       // Activate a synchronous reset\r
609       outport(SEQ_ADDR,0x0100);\r
610       // Select 28 mhz pixel clock\r
611       outportb(MISC_ADDR,0xE7);\r
612       // Release synchronous reset\r
613       outport(SEQ_ADDR,0x0300);\r
614 \r
615       // change the vertical resolution flags to 400\r
616       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0x40);\r
617 \r
618       // turn off write protect\r
619       outport(CRTC_ADDR,0x2C11);\r
620 \r
621       outport(CRTC_ADDR,0x6B00);\r
622       outport(CRTC_ADDR,0x5901);\r
623       outport(CRTC_ADDR,0x5A02);\r
624       outport(CRTC_ADDR,0x8E03);\r
625       outport(CRTC_ADDR,0x5E04);\r
626       outport(CRTC_ADDR,0x8A05);\r
627       outport(CRTC_ADDR,0x0008);\r
628       outport(CRTC_ADDR,0x4009);\r
629       outport(CRTC_ADDR,0x000A);\r
630       outport(CRTC_ADDR,0x000B);\r
631       outport(CRTC_ADDR,0x000C);\r
632       outport(CRTC_ADDR,0x000D);\r
633       outport(CRTC_ADDR,0x000E);\r
634       outport(CRTC_ADDR,0x000F);\r
635       outport(CRTC_ADDR,0xAC11);\r
636       outport(CRTC_ADDR,0x2D13);\r
637       outport(CRTC_ADDR,0x0014);\r
638       outport(CRTC_ADDR,0xE317);\r
639       outport(CRTC_ADDR,0xFF18);\r
640 \r
641       setpalette256();\r
642       Mode.width = 360;\r
643       Mode.height = 400;\r
644       Mode.width_bytes = 36000u;\r
645       Mode.colors = 256;\r
646       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
647    }\r
648    else if (mode == MODE_H)                     // unchained 360 x 480 x 256\r
649    {\r
650       SetMode((unsigned int)&mode13h);\r
651 \r
652       // Turn off Chain 4\r
653       outport(SEQ_ADDR,0x0604);\r
654       // Activate a synchronous reset\r
655       outport(SEQ_ADDR,0x0100);\r
656       // Select 28 mhz pixel clock\r
657       outportb(MISC_ADDR,0xE7);\r
658       // Release synchronous reset\r
659       outport(SEQ_ADDR,0x0300);\r
660 \r
661       // change the vertical resolution flags to 480\r
662       outportb(MISC_ADDR,(inportb(0x3CC) & ~0xC0) | 0xC0);\r
663 \r
664       // turn off write protect\r
665       outport(CRTC_ADDR,0x2C11);\r
666 \r
667       outport(CRTC_ADDR,0x6B00);\r
668       outport(CRTC_ADDR,0x5901);\r
669       outport(CRTC_ADDR,0x5A02);\r
670       outport(CRTC_ADDR,0x8E03);\r
671       outport(CRTC_ADDR,0x5E04);\r
672       outport(CRTC_ADDR,0x8A05);\r
673       outport(CRTC_ADDR,0x0D06);\r
674       outport(CRTC_ADDR,0x3E07);\r
675       outport(CRTC_ADDR,0x0008);\r
676       outport(CRTC_ADDR,0x4009);\r
677       outport(CRTC_ADDR,0x000A);\r
678       outport(CRTC_ADDR,0x000B);\r
679       outport(CRTC_ADDR,0x000C);\r
680       outport(CRTC_ADDR,0x000D);\r
681       outport(CRTC_ADDR,0x000E);\r
682       outport(CRTC_ADDR,0x000F);\r
683       outport(CRTC_ADDR,0xEA10);\r
684       outport(CRTC_ADDR,0xAC11);\r
685       outport(CRTC_ADDR,0xDF12);\r
686       outport(CRTC_ADDR,0x2D13);\r
687       outport(CRTC_ADDR,0x0014);\r
688       outport(CRTC_ADDR,0xE715);\r
689       outport(CRTC_ADDR,0x0616);\r
690       outport(CRTC_ADDR,0xE317);\r
691       outport(CRTC_ADDR,0xFF18);\r
692 \r
693       setpalette256();\r
694       Mode.width = 360;\r
695       Mode.height = 480;\r
696       Mode.width_bytes = 43200u;\r
697       Mode.colors = 256;\r
698       Mode.attrib = TVU_GRAPHICS | TVU_UNCHAINED;\r
699    }\r
700    else if (mode == MODE_I)                     // 640 x 400 x 16\r
701    {\r
702       SetMode((unsigned int)&mode10h);\r
703       asm {\r
704 \r
705          MOV DX,03CCH\r
706          IN AL,DX\r
707          AND AL,03FH\r
708          OR AL,40H\r
709 \r
710          MOV DX,03C2H\r
711          OUT DX,AL\r
712 \r
713          MOV DX,CRTC_ADDR\r
714          MOV AX,9C10H\r
715          OUT DX,AX\r
716 \r
717          MOV AX,8311H\r
718          OUT DX,AX\r
719 \r
720          MOV AX,8F12H\r
721          OUT DX,AX\r
722 \r
723          MOV AX,9615H\r
724          OUT DX,AX\r
725 \r
726          MOV AX,0B916H\r
727          OUT DX,AX\r
728       }\r
729       setpalette16();\r
730       Mode.width = 640;\r
731       Mode.height = 400;\r
732       Mode.width_bytes = 32000;\r
733       Mode.colors = 16;\r
734       Mode.attrib = TVU_GRAPHICS | TVU_PLANAR;\r
735    }\r
736    else if (mode == MODE_J)                    // 80 x 43 x 16\r
737    {\r
738       SetMode((unsigned int)&modeJ);\r
739       ReadBIOSfont(3,8);\r
740 \r
741       Mode.width = 80;\r
742       Mode.height = 43;\r
743       Mode.width_bytes = 3440;\r
744       Mode.colors = 16;\r
745       Mode.attrib = TVU_TEXT;\r
746    }\r
747    else if (mode == MODE_K)                    // 80 x 50 x 16\r
748    {\r
749       SetMode((unsigned int)&modeK);\r
750       ReadBIOSfont(3,8);\r
751 \r
752       Mode.width = 80;\r
753       Mode.height = 50;\r
754       Mode.width_bytes = 4000;\r
755       Mode.colors = 16;\r
756       Mode.attrib = TVU_TEXT;\r
757    }\r
758    else if (mode == MODE_L)                    // 40 x 43 x 16\r
759    {\r
760       SetMode((unsigned int)&modeL);\r
761       ReadBIOSfont(3,8);\r
762 \r
763       Mode.width = 40;\r
764       Mode.height = 43;\r
765       Mode.width_bytes = 4000;\r
766       Mode.colors = 16;\r
767       Mode.attrib = TVU_TEXT;\r
768    }\r
769    else if (mode == MODE_M)                    // 40 x 50 x 16\r
770    {\r
771       SetMode((unsigned int)&modeM);\r
772       ReadBIOSfont(3,8);\r
773 \r
774       Mode.width = 40;\r
775       Mode.height = 50;\r
776       Mode.width_bytes = 4000;\r
777       Mode.colors = 16;\r
778       Mode.attrib = TVU_TEXT;\r
779    }\r
780 }\r
781 \r
782 void setpal(int color, char r, char g, char b)\r
783 {\r
784    asm {\r
785    // Send color\r
786    MOV AX,color\r
787    MOV DX,03C8H\r
788    OUT DX,AL\r
789 \r
790    // Write R value\r
791    MOV DX,03C9H\r
792    MOV AL,r\r
793    OUT DX,AL\r
794 \r
795    // Write G value\r
796    MOV DX,03C9H\r
797    MOV AL,g\r
798    OUT DX,AL\r
799 \r
800    // Write B value\r
801    MOV DX,03C9H\r
802    MOV AL,b\r
803    OUT DX,AL\r
804    }\r
805 }\r
806 \r
807 void setpalette4()\r
808 {\r
809    setpal( 0,  0,  0,  0);\r
810    setpal( 1,  0, 42, 42);\r
811    setpal( 2, 42,  0, 42);\r
812    setpal( 3, 63, 63, 63);\r
813 }\r
814 \r
815 void setpalette16()\r
816 {\r
817    int j = 0;\r
818    for (int i = 0; i < 48; i+=3)\r
819    {\r
820       setpal(j, Pal[i], Pal[i+1], Pal[i+2]);\r
821       j++;\r
822    }\r
823 }\r
824 \r
825 void setpalette256()\r
826 {\r
827    int j = 0;\r
828    for (int i = 0; i < 768; i+=3)\r
829    {\r
830       setpal(j, Pal[i], Pal[i+1], Pal[i+2]);\r
831       j++;\r
832    }\r
833 }\r