blob: bccb3d9954bc66ab07fed6ca7cf8402edc58dff2 [file] [log] [blame]
#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