git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1853 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
		
			
				
	
	
		
			479 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			479 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdio.h>
 | 
						|
#include "test.h"
 | 
						|
#include "pci.h"
 | 
						|
 | 
						|
void x86emu_dump_xregs(void);
 | 
						|
extern ptr current;
 | 
						|
extern int verbose;
 | 
						|
 | 
						|
 | 
						|
#ifndef _PC
 | 
						|
/*
 | 
						|
 * This is derived from a number of PC system BIOS'es.  The intent here is to
 | 
						|
 * provide very primitive video support, before an EGA/VGA BIOS installs its
 | 
						|
 * own interrupt vector.  Here, "Ignored" calls should remain so.  "Not
 | 
						|
 * Implemented" denotes functionality that can be implemented should the need
 | 
						|
 * arise.  What are "Not Implemented" throughout are video memory accesses.
 | 
						|
 * Also, very little input validity checking is done here.
 | 
						|
 */
 | 
						|
int int42_handler()
 | 
						|
{
 | 
						|
#if 0
 | 
						|
	if (verbose && X86_AH != 0x0e) {
 | 
						|
		printf("int%x\n", current->num);
 | 
						|
		x86emu_dump_xregs();
 | 
						|
	}
 | 
						|
 | 
						|
	switch (X86_AH) {
 | 
						|
	case 0x00:
 | 
						|
		/* Set Video Mode                                     */
 | 
						|
		/* Enter:  AL = video mode number                     */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Implemented (except for clearing the screen)       */
 | 
						|
		{		/* Localise */
 | 
						|
			int i;
 | 
						|
			u16 ioport, int1d, regvals, tmp;
 | 
						|
			u8 mode, cgamode, cgacolour;
 | 
						|
 | 
						|
			/*
 | 
						|
			 * Ignore all mode numbers but 0x00-0x13.  Some systems also ignore
 | 
						|
			 * 0x0B and 0x0C, but don't do that here.
 | 
						|
			 */
 | 
						|
			if (X86_AL > 0x13)
 | 
						|
				break;
 | 
						|
 | 
						|
			/*
 | 
						|
			 * You didn't think that was really the mode set, did you?  There
 | 
						|
			 * are only so many slots in the video parameter table...
 | 
						|
			 */
 | 
						|
			mode = X86_AL;
 | 
						|
			ioport = 0x03D4;
 | 
						|
			switch (MEM_RB(0x0410) & 0x30) {
 | 
						|
			case 0x30:	/* MDA */
 | 
						|
				mode = 0x07;	/* Force mode to 0x07 */
 | 
						|
				ioport = 0x03B4;
 | 
						|
				break;
 | 
						|
			case 0x10:	/* CGA 40x25 */
 | 
						|
				if (mode >= 0x07)
 | 
						|
					mode = 0x01;
 | 
						|
				break;
 | 
						|
			case 0x20:	/* CGA 80x25 (MCGA?) */
 | 
						|
				if (mode >= 0x07)
 | 
						|
					mode = 0x03;
 | 
						|
				break;
 | 
						|
			case 0x00:	/* EGA/VGA */
 | 
						|
				if (mode >= 0x07)	/* Don't try MDA timings */
 | 
						|
					mode = 0x01;	/* !?!?! */
 | 
						|
				break;
 | 
						|
			}
 | 
						|
 | 
						|
			/* Locate data in video parameter table */
 | 
						|
			int1d = MEM_RW(0x1d << 2);
 | 
						|
			regvals = ((mode >> 1) << 4) + int1d;
 | 
						|
			cgacolour = 0x30;
 | 
						|
			if (mode == 0x06) {
 | 
						|
				regvals -= 0x10;
 | 
						|
				cgacolour = 0x3F;
 | 
						|
			}
 | 
						|
 | 
						|
	    /** Update BIOS Data Area **/
 | 
						|
 | 
						|
			/* Video mode */
 | 
						|
			MEM_WB(0x0449, mode);
 | 
						|
 | 
						|
			/* Columns */
 | 
						|
			tmp = MEM_RB(mode + int1d + 0x48);
 | 
						|
			MEM_WW(0x044A, tmp);
 | 
						|
 | 
						|
			/* Page length */
 | 
						|
			tmp = MEM_RW((mode & 0x06) + int1d + 0x40);
 | 
						|
			MEM_WW(0x044C, tmp);
 | 
						|
 | 
						|
			/* Start Address */
 | 
						|
			MEM_WW(0x044E, 0);
 | 
						|
 | 
						|
			/* Cursor positions, one for each display page */
 | 
						|
			for (i = 0x0450; i < 0x0460; i += 2)
 | 
						|
				MEM_WW(i, 0);
 | 
						|
 | 
						|
			/* Cursor start & end scanlines */
 | 
						|
			tmp = MEM_RB(regvals + 0x0B);
 | 
						|
			MEM_WB(0x0460, tmp);
 | 
						|
			tmp = MEM_RB(regvals + 0x0A);
 | 
						|
			MEM_WB(0x0461, tmp);
 | 
						|
 | 
						|
			/* Current display page number */
 | 
						|
			MEM_WB(0x0462, 0);
 | 
						|
 | 
						|
			/* CRTC I/O address */
 | 
						|
			MEM_WW(0x0463, ioport);
 | 
						|
 | 
						|
			/* CGA Mode register value */
 | 
						|
			cgamode = MEM_RB(mode + int1d + 0x50);
 | 
						|
			MEM_WB(0x0465, cgamode);
 | 
						|
 | 
						|
			/* CGA Colour register value */
 | 
						|
			MEM_WB(0x0466, cgacolour);
 | 
						|
 | 
						|
			/* Rows */
 | 
						|
			MEM_WB(0x0484, (25 - 1));
 | 
						|
 | 
						|
			/* Programme the mode */
 | 
						|
			outb(ioport + 4, cgamode & 0x37);	/* Turn off screen */
 | 
						|
			for (i = 0; i < 0x10; i++) {
 | 
						|
				tmp = MEM_RB(regvals + i);
 | 
						|
				outb(ioport, i);
 | 
						|
				outb(ioport + 1, tmp);
 | 
						|
			}
 | 
						|
			outb(ioport + 5, cgacolour);	/* Select colour mode */
 | 
						|
			outb(ioport + 4, cgamode);	/* Turn on screen */
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x01:
 | 
						|
		/* Set Cursor Type                                    */
 | 
						|
		/* Enter:  CH = starting line for cursor              */
 | 
						|
		/*         CL = ending line for cursor                */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Implemented                                        */
 | 
						|
		{		/* Localise */
 | 
						|
			u16 ioport = MEM_RW(0x0463);
 | 
						|
 | 
						|
			MEM_WB(0x0460, X86_CL);
 | 
						|
			MEM_WB(0x0461, X86_CH);
 | 
						|
 | 
						|
			outb(ioport, 0x0A);
 | 
						|
			outb(ioport + 1, X86_CH);
 | 
						|
			outb(ioport, 0x0B);
 | 
						|
			outb(ioport + 1, X86_CL);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x02:
 | 
						|
		/* Set Cursor Position                                */
 | 
						|
		/* Enter:  BH = display page number                   */
 | 
						|
		/*         DH = row                                   */
 | 
						|
		/*         DL = column                                */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Implemented                                        */
 | 
						|
		{		/* Localise */
 | 
						|
			u16 offset, ioport;
 | 
						|
 | 
						|
			MEM_WB((X86_BH << 1) + 0x0450, X86_DL);
 | 
						|
			MEM_WB((X86_BH << 1) + 0x0451, X86_DH);
 | 
						|
 | 
						|
			if (X86_BH != MEM_RB(0x0462))
 | 
						|
				break;
 | 
						|
 | 
						|
			offset = (X86_DH * MEM_RW(0x044A)) + X86_DL;
 | 
						|
			offset += MEM_RW(0x044E) << 1;
 | 
						|
 | 
						|
			ioport = MEM_RW(0x0463);
 | 
						|
			outb(ioport, 0x0E);
 | 
						|
			outb(ioport + 1, offset >> 8);
 | 
						|
			outb(ioport, 0x0F);
 | 
						|
			outb(ioport + 1, offset & 0xFF);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x03:
 | 
						|
		/* Get Cursor Position                                */
 | 
						|
		/* Enter:  BH = display page number                   */
 | 
						|
		/* Leave:  CH = starting line for cursor              */
 | 
						|
		/*         CL = ending line for cursor                */
 | 
						|
		/*         DH = row                                   */
 | 
						|
		/*         DL = column                                */
 | 
						|
		/* Implemented                                        */
 | 
						|
		{		/* Localise */
 | 
						|
			X86_CL = MEM_RB(0x0460);
 | 
						|
			X86_CH = MEM_RB(0x0461);
 | 
						|
			X86_DL = MEM_RB((X86_BH << 1) + 0x0450);
 | 
						|
			X86_DH = MEM_RB((X86_BH << 1) + 0x0451);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x04:
 | 
						|
		/* Get Light Pen Position                             */
 | 
						|
		/* Enter:  Nothing                                    */
 | 
						|
		/* Leave:  AH = 0x01 (down/triggered) or 0x00 (not)   */
 | 
						|
		/*         BX = pixel column                          */
 | 
						|
		/*         CX = pixel row                             */
 | 
						|
		/*         DH = character row                         */
 | 
						|
		/*         DL = character column                      */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf("int%x - Get Light Pen Position. "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
			X86_AH = X86_BX = X86_CX = X86_DX = 0;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x05:
 | 
						|
		/* Set Display Page                                   */
 | 
						|
		/* Enter:  AL = display page number                   */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Implemented                                        */
 | 
						|
		{		/* Localise */
 | 
						|
			u16 start, ioport = MEM_RW(0x0463);
 | 
						|
			u8 x, y;
 | 
						|
 | 
						|
			/* Calculate new start address */
 | 
						|
			MEM_WB(0x0462, X86_AL);
 | 
						|
			start = X86_AL * MEM_RW(0x044C);
 | 
						|
			MEM_WW(0x044E, start);
 | 
						|
			start <<= 1;
 | 
						|
 | 
						|
			/* Update start address */
 | 
						|
			outb(ioport, 0x0C);
 | 
						|
			outb(ioport + 1, start >> 8);
 | 
						|
			outb(ioport, 0x0D);
 | 
						|
			outb(ioport + 1, start & 0xFF);
 | 
						|
 | 
						|
			/* Switch cursor position */
 | 
						|
			y = MEM_RB((X86_AL << 1) + 0x0450);
 | 
						|
			x = MEM_RB((X86_AL << 1) + 0x0451);
 | 
						|
			start += (y * MEM_RW(0x044A)) + x;
 | 
						|
 | 
						|
			/* Update cursor position */
 | 
						|
			outb(ioport, 0x0E);
 | 
						|
			outb(ioport + 1, start >> 8);
 | 
						|
			outb(ioport, 0x0F);
 | 
						|
			outb(ioport + 1, start & 0xFF);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x06:
 | 
						|
		/* Initialise or Scroll Window Up                     */
 | 
						|
		/* Enter:  AL = lines to scroll up                    */
 | 
						|
		/*         BH = attribute for blank                   */
 | 
						|
		/*         CH = upper y of window                     */
 | 
						|
		/*         CL = left x of window                      */
 | 
						|
		/*         DH = lower y of window                     */
 | 
						|
		/*         DL = right x of window                     */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf("int%x: Initialise or Scroll Window Up - "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x07:
 | 
						|
		/* Initialise or Scroll Window Down                   */
 | 
						|
		/* Enter:  AL = lines to scroll down                  */
 | 
						|
		/*         BH = attribute for blank                   */
 | 
						|
		/*         CH = upper y of window                     */
 | 
						|
		/*         CL = left x of window                      */
 | 
						|
		/*         DH = lower y of window                     */
 | 
						|
		/*         DL = right x of window                     */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf("int%x: Initialise or Scroll Window Down - "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x08:
 | 
						|
		/* Read Character and Attribute at Cursor             */
 | 
						|
		/* Enter:  BH = display page number                   */
 | 
						|
		/* Leave:  AH = attribute                             */
 | 
						|
		/*         AL = character                             */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf
 | 
						|
			    ("int%x: Read Character and Attribute at Cursor - "
 | 
						|
			     "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
 | 
						|
			X86_AX = 0;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x09:
 | 
						|
		/* Write Character and Attribute at Cursor            */
 | 
						|
		/* Enter:  AL = character                             */
 | 
						|
		/*         BH = display page number                   */
 | 
						|
		/*         BL = attribute (text) or colour (graphics) */
 | 
						|
		/*         CX = replication count                     */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf
 | 
						|
			    ("int%x: Write Character and Attribute at Cursor - "
 | 
						|
			     "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x0a:
 | 
						|
		/* Write Character at Cursor                          */
 | 
						|
		/* Enter:  AL = character                             */
 | 
						|
		/*         BH = display page number                   */
 | 
						|
		/*         BL = colour                                */
 | 
						|
		/*         CX = replication count                     */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf("int%x: Write Character at Cursor - "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x0b:
 | 
						|
		/* Set Palette, Background or Border                  */
 | 
						|
		/* Enter:  BH = 0x00 or 0x01                          */
 | 
						|
		/*         BL = colour or palette (respectively)      */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Implemented                                        */
 | 
						|
		{		/* Localise */
 | 
						|
			u16 ioport = MEM_RW(0x0463) + 5;
 | 
						|
			u8 cgacolour = MEM_RB(0x0466);
 | 
						|
 | 
						|
			if (X86_BH) {
 | 
						|
				cgacolour &= 0xDF;
 | 
						|
				cgacolour |= (X86_BL & 0x01) << 5;
 | 
						|
			} else {
 | 
						|
				cgacolour &= 0xE0;
 | 
						|
				cgacolour |= X86_BL & 0x1F;
 | 
						|
			}
 | 
						|
 | 
						|
			MEM_WB(0x0466, cgacolour);
 | 
						|
			outb(ioport, cgacolour);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x0c:
 | 
						|
		/* Write Graphics Pixel                               */
 | 
						|
		/* Enter:  AL = pixel value                           */
 | 
						|
		/*         BH = display page number                   */
 | 
						|
		/*         CX = column                                */
 | 
						|
		/*         DX = row                                   */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf("int%x: Write Graphics Pixel - "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x0d:
 | 
						|
		/* Read Graphics Pixel                                */
 | 
						|
		/* Enter:  BH = display page number                   */
 | 
						|
		/*         CX = column                                */
 | 
						|
		/*         DX = row                                   */
 | 
						|
		/* Leave:  AL = pixel value                           */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		{		/* Localise */
 | 
						|
			printf("int%x: Write Graphics Pixel - "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
 | 
						|
			X86_AL = 0;
 | 
						|
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x0e:
 | 
						|
		/* Write Character in Teletype Mode                   */
 | 
						|
		/* Enter:  AL = character                             */
 | 
						|
		/*         BH = display page number                   */
 | 
						|
		/*         BL = foreground colour                     */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		/* WARNING:  Emulation of BEL characters will require */
 | 
						|
		/*           emulation of RTC and PC speaker I/O.     */
 | 
						|
		/*           Also, this recurses through int 0x10     */
 | 
						|
		/*           which might or might not have been       */
 | 
						|
		/*           installed yet.                           */
 | 
						|
		{		/* Localise */
 | 
						|
#ifdef PARANOID
 | 
						|
			printf("int%x: Write Character in Teletype Mode - "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
#endif
 | 
						|
			printf("%c", X86_AL);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x0f:
 | 
						|
		/* Get Video Mode                                     */
 | 
						|
		/* Enter:  Nothing                                    */
 | 
						|
		/* Leave:  AH = number of columns                     */
 | 
						|
		/*         AL = video mode number                     */
 | 
						|
		/*         BH = display page number                   */
 | 
						|
		/* Implemented                                        */
 | 
						|
		{		/* Localise */
 | 
						|
			X86_AH = MEM_RW(0x044A);
 | 
						|
			X86_AL = MEM_RB(0x0449);
 | 
						|
			X86_BH = MEM_RB(0x0462);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x10:
 | 
						|
		/* Colour Control (subfunction in AL)                 */
 | 
						|
		/* Enter:  Various                                    */
 | 
						|
		/* Leave:  Various                                    */
 | 
						|
		/* Ignored                                            */
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x11:
 | 
						|
		/* Font Control (subfunction in AL)                   */
 | 
						|
		/* Enter:  Various                                    */
 | 
						|
		/* Leave:  Various                                    */
 | 
						|
		/* Ignored                                            */
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x12:
 | 
						|
		/* Miscellaneous (subfunction in BL)                  */
 | 
						|
		/* Enter:  Various                                    */
 | 
						|
		/* Leave:  Various                                    */
 | 
						|
		/* Ignored.  Previous code here optionally allowed    */
 | 
						|
		/* the enabling and disabling of VGA, but no system   */
 | 
						|
		/* BIOS I've come across actually implements it.      */
 | 
						|
		break;
 | 
						|
 | 
						|
	case 0x13:
 | 
						|
		/* Write String in Teletype Mode                      */
 | 
						|
		/* Enter:  AL = write mode                            */
 | 
						|
		/*         BL = attribute (if (AL & 0x02) == 0)       */
 | 
						|
		/*         CX = string length                         */
 | 
						|
		/*         DH = row                                   */
 | 
						|
		/*         DL = column                                */
 | 
						|
		/*         ES:BP = string segment:offset              */
 | 
						|
		/* Leave:  Nothing                                    */
 | 
						|
		/* Not Implemented                                    */
 | 
						|
		/* WARNING:  Emulation of BEL characters will require */
 | 
						|
		/*           emulation of RTC and PC speaker I/O.     */
 | 
						|
		/*           Also, this recurses through int 0x10     */
 | 
						|
		/*           which might or might not have been       */
 | 
						|
		/*           installed yet.                           */
 | 
						|
		{		/* Localise */
 | 
						|
			printf("int%x: Write String in Teletype Mode - "
 | 
						|
			       "Function not implemented.\n", current->num);
 | 
						|
			x86emu_dump_xregs();
 | 
						|
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	default:
 | 
						|
		/* Various extensions                                 */
 | 
						|
		/* Enter:  Various                                    */
 | 
						|
		/* Leave:  Various                                    */
 | 
						|
		/* Ignored                                            */
 | 
						|
		break;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
#endif
 |