Add constants for fast path resume copying
[coreboot.git] / util / vgabios / int10.c
1 #include <stdio.h>
2 #include "test.h"
3 #include "pci.h"
4
5 void x86emu_dump_xregs(void);
6 extern ptr current;
7 extern int verbose;
8
9
10 #ifndef _PC
11 /*
12  * This is derived from a number of PC system BIOS'es.  The intent here is to
13  * provide very primitive video support, before an EGA/VGA BIOS installs its
14  * own interrupt vector.  Here, "Ignored" calls should remain so.  "Not
15  * Implemented" denotes functionality that can be implemented should the need
16  * arise.  What are "Not Implemented" throughout are video memory accesses.
17  * Also, very little input validity checking is done here.
18  */
19 int int42_handler()
20 {
21 #if 0
22         if (verbose && X86_AH != 0x0e) {
23                 printf("int%x\n", current->num);
24                 x86emu_dump_xregs();
25         }
26
27         switch (X86_AH) {
28         case 0x00:
29                 /* Set Video Mode                                     */
30                 /* Enter:  AL = video mode number                     */
31                 /* Leave:  Nothing                                    */
32                 /* Implemented (except for clearing the screen)       */
33                 {               /* Localise */
34                         int i;
35                         u16 ioport, int1d, regvals, tmp;
36                         u8 mode, cgamode, cgacolour;
37
38                         /*
39                          * Ignore all mode numbers but 0x00-0x13.  Some systems also ignore
40                          * 0x0B and 0x0C, but don't do that here.
41                          */
42                         if (X86_AL > 0x13)
43                                 break;
44
45                         /*
46                          * You didn't think that was really the mode set, did you?  There
47                          * are only so many slots in the video parameter table...
48                          */
49                         mode = X86_AL;
50                         ioport = 0x03D4;
51                         switch (MEM_RB(0x0410) & 0x30) {
52                         case 0x30:      /* MDA */
53                                 mode = 0x07;    /* Force mode to 0x07 */
54                                 ioport = 0x03B4;
55                                 break;
56                         case 0x10:      /* CGA 40x25 */
57                                 if (mode >= 0x07)
58                                         mode = 0x01;
59                                 break;
60                         case 0x20:      /* CGA 80x25 (MCGA?) */
61                                 if (mode >= 0x07)
62                                         mode = 0x03;
63                                 break;
64                         case 0x00:      /* EGA/VGA */
65                                 if (mode >= 0x07)       /* Don't try MDA timings */
66                                         mode = 0x01;    /* !?!?! */
67                                 break;
68                         }
69
70                         /* Locate data in video parameter table */
71                         int1d = MEM_RW(0x1d << 2);
72                         regvals = ((mode >> 1) << 4) + int1d;
73                         cgacolour = 0x30;
74                         if (mode == 0x06) {
75                                 regvals -= 0x10;
76                                 cgacolour = 0x3F;
77                         }
78
79             /** Update BIOS Data Area **/
80
81                         /* Video mode */
82                         MEM_WB(0x0449, mode);
83
84                         /* Columns */
85                         tmp = MEM_RB(mode + int1d + 0x48);
86                         MEM_WW(0x044A, tmp);
87
88                         /* Page length */
89                         tmp = MEM_RW((mode & 0x06) + int1d + 0x40);
90                         MEM_WW(0x044C, tmp);
91
92                         /* Start Address */
93                         MEM_WW(0x044E, 0);
94
95                         /* Cursor positions, one for each display page */
96                         for (i = 0x0450; i < 0x0460; i += 2)
97                                 MEM_WW(i, 0);
98
99                         /* Cursor start & end scanlines */
100                         tmp = MEM_RB(regvals + 0x0B);
101                         MEM_WB(0x0460, tmp);
102                         tmp = MEM_RB(regvals + 0x0A);
103                         MEM_WB(0x0461, tmp);
104
105                         /* Current display page number */
106                         MEM_WB(0x0462, 0);
107
108                         /* CRTC I/O address */
109                         MEM_WW(0x0463, ioport);
110
111                         /* CGA Mode register value */
112                         cgamode = MEM_RB(mode + int1d + 0x50);
113                         MEM_WB(0x0465, cgamode);
114
115                         /* CGA Colour register value */
116                         MEM_WB(0x0466, cgacolour);
117
118                         /* Rows */
119                         MEM_WB(0x0484, (25 - 1));
120
121                         /* Programme the mode */
122                         outb(ioport + 4, cgamode & 0x37);       /* Turn off screen */
123                         for (i = 0; i < 0x10; i++) {
124                                 tmp = MEM_RB(regvals + i);
125                                 outb(ioport, i);
126                                 outb(ioport + 1, tmp);
127                         }
128                         outb(ioport + 5, cgacolour);    /* Select colour mode */
129                         outb(ioport + 4, cgamode);      /* Turn on screen */
130                 }
131                 break;
132
133         case 0x01:
134                 /* Set Cursor Type                                    */
135                 /* Enter:  CH = starting line for cursor              */
136                 /*         CL = ending line for cursor                */
137                 /* Leave:  Nothing                                    */
138                 /* Implemented                                        */
139                 {               /* Localise */
140                         u16 ioport = MEM_RW(0x0463);
141
142                         MEM_WB(0x0460, X86_CL);
143                         MEM_WB(0x0461, X86_CH);
144
145                         outb(ioport, 0x0A);
146                         outb(ioport + 1, X86_CH);
147                         outb(ioport, 0x0B);
148                         outb(ioport + 1, X86_CL);
149                 }
150                 break;
151
152         case 0x02:
153                 /* Set Cursor Position                                */
154                 /* Enter:  BH = display page number                   */
155                 /*         DH = row                                   */
156                 /*         DL = column                                */
157                 /* Leave:  Nothing                                    */
158                 /* Implemented                                        */
159                 {               /* Localise */
160                         u16 offset, ioport;
161
162                         MEM_WB((X86_BH << 1) + 0x0450, X86_DL);
163                         MEM_WB((X86_BH << 1) + 0x0451, X86_DH);
164
165                         if (X86_BH != MEM_RB(0x0462))
166                                 break;
167
168                         offset = (X86_DH * MEM_RW(0x044A)) + X86_DL;
169                         offset += MEM_RW(0x044E) << 1;
170
171                         ioport = MEM_RW(0x0463);
172                         outb(ioport, 0x0E);
173                         outb(ioport + 1, offset >> 8);
174                         outb(ioport, 0x0F);
175                         outb(ioport + 1, offset & 0xFF);
176                 }
177                 break;
178
179         case 0x03:
180                 /* Get Cursor Position                                */
181                 /* Enter:  BH = display page number                   */
182                 /* Leave:  CH = starting line for cursor              */
183                 /*         CL = ending line for cursor                */
184                 /*         DH = row                                   */
185                 /*         DL = column                                */
186                 /* Implemented                                        */
187                 {               /* Localise */
188                         X86_CL = MEM_RB(0x0460);
189                         X86_CH = MEM_RB(0x0461);
190                         X86_DL = MEM_RB((X86_BH << 1) + 0x0450);
191                         X86_DH = MEM_RB((X86_BH << 1) + 0x0451);
192                 }
193                 break;
194
195         case 0x04:
196                 /* Get Light Pen Position                             */
197                 /* Enter:  Nothing                                    */
198                 /* Leave:  AH = 0x01 (down/triggered) or 0x00 (not)   */
199                 /*         BX = pixel column                          */
200                 /*         CX = pixel row                             */
201                 /*         DH = character row                         */
202                 /*         DL = character column                      */
203                 /* Not Implemented                                    */
204                 {               /* Localise */
205                         printf("int%x - Get Light Pen Position. "
206                                "Function not implemented.\n", current->num);
207                         x86emu_dump_xregs();
208                         X86_AH = X86_BX = X86_CX = X86_DX = 0;
209                 }
210                 break;
211
212         case 0x05:
213                 /* Set Display Page                                   */
214                 /* Enter:  AL = display page number                   */
215                 /* Leave:  Nothing                                    */
216                 /* Implemented                                        */
217                 {               /* Localise */
218                         u16 start, ioport = MEM_RW(0x0463);
219                         u8 x, y;
220
221                         /* Calculate new start address */
222                         MEM_WB(0x0462, X86_AL);
223                         start = X86_AL * MEM_RW(0x044C);
224                         MEM_WW(0x044E, start);
225                         start <<= 1;
226
227                         /* Update start address */
228                         outb(ioport, 0x0C);
229                         outb(ioport + 1, start >> 8);
230                         outb(ioport, 0x0D);
231                         outb(ioport + 1, start & 0xFF);
232
233                         /* Switch cursor position */
234                         y = MEM_RB((X86_AL << 1) + 0x0450);
235                         x = MEM_RB((X86_AL << 1) + 0x0451);
236                         start += (y * MEM_RW(0x044A)) + x;
237
238                         /* Update cursor position */
239                         outb(ioport, 0x0E);
240                         outb(ioport + 1, start >> 8);
241                         outb(ioport, 0x0F);
242                         outb(ioport + 1, start & 0xFF);
243                 }
244                 break;
245
246         case 0x06:
247                 /* Initialise or Scroll Window Up                     */
248                 /* Enter:  AL = lines to scroll up                    */
249                 /*         BH = attribute for blank                   */
250                 /*         CH = upper y of window                     */
251                 /*         CL = left x of window                      */
252                 /*         DH = lower y of window                     */
253                 /*         DL = right x of window                     */
254                 /* Leave:  Nothing                                    */
255                 /* Not Implemented                                    */
256                 {               /* Localise */
257                         printf("int%x: Initialise or Scroll Window Up - "
258                                "Function not implemented.\n", current->num);
259                         x86emu_dump_xregs();
260                 }
261                 break;
262
263         case 0x07:
264                 /* Initialise or Scroll Window Down                   */
265                 /* Enter:  AL = lines to scroll down                  */
266                 /*         BH = attribute for blank                   */
267                 /*         CH = upper y of window                     */
268                 /*         CL = left x of window                      */
269                 /*         DH = lower y of window                     */
270                 /*         DL = right x of window                     */
271                 /* Leave:  Nothing                                    */
272                 /* Not Implemented                                    */
273                 {               /* Localise */
274                         printf("int%x: Initialise or Scroll Window Down - "
275                                "Function not implemented.\n", current->num);
276                         x86emu_dump_xregs();
277
278                 }
279                 break;
280
281         case 0x08:
282                 /* Read Character and Attribute at Cursor             */
283                 /* Enter:  BH = display page number                   */
284                 /* Leave:  AH = attribute                             */
285                 /*         AL = character                             */
286                 /* Not Implemented                                    */
287                 {               /* Localise */
288                         printf
289                             ("int%x: Read Character and Attribute at Cursor - "
290                              "Function not implemented.\n", current->num);
291                         x86emu_dump_xregs();
292
293                         X86_AX = 0;
294                 }
295                 break;
296
297         case 0x09:
298                 /* Write Character and Attribute at Cursor            */
299                 /* Enter:  AL = character                             */
300                 /*         BH = display page number                   */
301                 /*         BL = attribute (text) or colour (graphics) */
302                 /*         CX = replication count                     */
303                 /* Leave:  Nothing                                    */
304                 /* Not Implemented                                    */
305                 {               /* Localise */
306                         printf
307                             ("int%x: Write Character and Attribute at Cursor - "
308                              "Function not implemented.\n", current->num);
309                         x86emu_dump_xregs();
310
311                 }
312                 break;
313
314         case 0x0a:
315                 /* Write Character at Cursor                          */
316                 /* Enter:  AL = character                             */
317                 /*         BH = display page number                   */
318                 /*         BL = colour                                */
319                 /*         CX = replication count                     */
320                 /* Leave:  Nothing                                    */
321                 /* Not Implemented                                    */
322                 {               /* Localise */
323                         printf("int%x: Write Character at Cursor - "
324                                "Function not implemented.\n", current->num);
325                         x86emu_dump_xregs();
326
327                 }
328                 break;
329
330         case 0x0b:
331                 /* Set Palette, Background or Border                  */
332                 /* Enter:  BH = 0x00 or 0x01                          */
333                 /*         BL = colour or palette (respectively)      */
334                 /* Leave:  Nothing                                    */
335                 /* Implemented                                        */
336                 {               /* Localise */
337                         u16 ioport = MEM_RW(0x0463) + 5;
338                         u8 cgacolour = MEM_RB(0x0466);
339
340                         if (X86_BH) {
341                                 cgacolour &= 0xDF;
342                                 cgacolour |= (X86_BL & 0x01) << 5;
343                         } else {
344                                 cgacolour &= 0xE0;
345                                 cgacolour |= X86_BL & 0x1F;
346                         }
347
348                         MEM_WB(0x0466, cgacolour);
349                         outb(ioport, cgacolour);
350                 }
351                 break;
352
353         case 0x0c:
354                 /* Write Graphics Pixel                               */
355                 /* Enter:  AL = pixel value                           */
356                 /*         BH = display page number                   */
357                 /*         CX = column                                */
358                 /*         DX = row                                   */
359                 /* Leave:  Nothing                                    */
360                 /* Not Implemented                                    */
361                 {               /* Localise */
362                         printf("int%x: Write Graphics Pixel - "
363                                "Function not implemented.\n", current->num);
364                         x86emu_dump_xregs();
365
366                 }
367                 break;
368
369         case 0x0d:
370                 /* Read Graphics Pixel                                */
371                 /* Enter:  BH = display page number                   */
372                 /*         CX = column                                */
373                 /*         DX = row                                   */
374                 /* Leave:  AL = pixel value                           */
375                 /* Not Implemented                                    */
376                 {               /* Localise */
377                         printf("int%x: Write Graphics Pixel - "
378                                "Function not implemented.\n", current->num);
379                         x86emu_dump_xregs();
380
381                         X86_AL = 0;
382
383                 }
384                 break;
385
386         case 0x0e:
387                 /* Write Character in Teletype Mode                   */
388                 /* Enter:  AL = character                             */
389                 /*         BH = display page number                   */
390                 /*         BL = foreground colour                     */
391                 /* Leave:  Nothing                                    */
392                 /* Not Implemented                                    */
393                 /* WARNING:  Emulation of BEL characters will require */
394                 /*           emulation of RTC and PC speaker I/O.     */
395                 /*           Also, this recurses through int 0x10     */
396                 /*           which might or might not have been       */
397                 /*           installed yet.                           */
398                 {               /* Localise */
399 #ifdef PARANOID
400                         printf("int%x: Write Character in Teletype Mode - "
401                                "Function not implemented.\n", current->num);
402                         x86emu_dump_xregs();
403 #endif
404                         printf("%c", X86_AL);
405                 }
406                 break;
407
408         case 0x0f:
409                 /* Get Video Mode                                     */
410                 /* Enter:  Nothing                                    */
411                 /* Leave:  AH = number of columns                     */
412                 /*         AL = video mode number                     */
413                 /*         BH = display page number                   */
414                 /* Implemented                                        */
415                 {               /* Localise */
416                         X86_AH = MEM_RW(0x044A);
417                         X86_AL = MEM_RB(0x0449);
418                         X86_BH = MEM_RB(0x0462);
419                 }
420                 break;
421
422         case 0x10:
423                 /* Colour Control (subfunction in AL)                 */
424                 /* Enter:  Various                                    */
425                 /* Leave:  Various                                    */
426                 /* Ignored                                            */
427                 break;
428
429         case 0x11:
430                 /* Font Control (subfunction in AL)                   */
431                 /* Enter:  Various                                    */
432                 /* Leave:  Various                                    */
433                 /* Ignored                                            */
434                 break;
435
436         case 0x12:
437                 /* Miscellaneous (subfunction in BL)                  */
438                 /* Enter:  Various                                    */
439                 /* Leave:  Various                                    */
440                 /* Ignored.  Previous code here optionally allowed    */
441                 /* the enabling and disabling of VGA, but no system   */
442                 /* BIOS I've come across actually implements it.      */
443                 break;
444
445         case 0x13:
446                 /* Write String in Teletype Mode                      */
447                 /* Enter:  AL = write mode                            */
448                 /*         BL = attribute (if (AL & 0x02) == 0)       */
449                 /*         CX = string length                         */
450                 /*         DH = row                                   */
451                 /*         DL = column                                */
452                 /*         ES:BP = string segment:offset              */
453                 /* Leave:  Nothing                                    */
454                 /* Not Implemented                                    */
455                 /* WARNING:  Emulation of BEL characters will require */
456                 /*           emulation of RTC and PC speaker I/O.     */
457                 /*           Also, this recurses through int 0x10     */
458                 /*           which might or might not have been       */
459                 /*           installed yet.                           */
460                 {               /* Localise */
461                         printf("int%x: Write String in Teletype Mode - "
462                                "Function not implemented.\n", current->num);
463                         x86emu_dump_xregs();
464
465                 }
466                 break;
467
468         default:
469                 /* Various extensions                                 */
470                 /* Enter:  Various                                    */
471                 /* Leave:  Various                                    */
472                 /* Ignored                                            */
473                 break;
474         }
475 #endif
476         return 1;
477 }
478 #endif