home *** CD-ROM | disk | FTP | other *** search
- /*
- pcmode.c
-
- % pc_ mode routines
-
- 7/9/88 by Ted.
-
- OWL 1.1
- Copyright (c) 1988, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 1/31/89 ted Changed pc_ModeSupport so it supports mode 7 even when an
- EGA/VGA is installed.
- 6/29/89 ted Converted pcinfo.asm to C; moved it here from pcinfo.asm.
- 7/12/89 ted Added OSTATIC's and '_func' macros.
- 7/17/89 ted Fixed newbios_modesupport: modebyte = 40 +, not 0x40 +.
- 8/01/89 ted Moved pc_init/restoremode to pcdisp.c.
- */
-
- #include "pcpriv.h"
-
- OSTATIC boolean DIGPRIV ega_modesupport(_arg1(int));
- OSTATIC boolean DIGPRIV ega_ismono(_arg1(byte));
- OSTATIC boolean DIGPRIV newbios(_arg1(void));
- OSTATIC boolean DIGPRIV newbios_modesupport(_arg1(int));
- OSTATIC void DIGPRIV pc_sethflag(_arg1(byte));
- OSTATIC boolean DIGPRIV vga_getinfo(_arg1(byte *bufaddr));
- OSTATIC boolean DIGPRIV ram_testword(_arg2(unsigned, unsigned));
- OSTATIC boolean DIGPRIV cursport_test(_arg1(int));
- /* -------------------------------------------------------------------------- */
-
- void pc_SetMode(mode)
- int mode;
- /*
- Sets the current video mode of the display adapter to the given mode.
- Clears the screen in the new mode.
- */
- {
- OREGS regs;
-
- switch (mode) {
- default:
- if (mode == 0x07) {
- pc_sethflag(PCHFLAG_MONO);
- if (pc_IsHerc()) { /* Restore herc card to text mode */
- herc_settmode();
- }
- }
- else {
- pc_sethflag(PCHFLAG_COLO);
- }
- if (mode == PCMODE_CPQ40) {
- mode = 0x40;
- }
- regs.h.al = (byte)mode;
- regs.h.ah = VIDINT_SETVM;
- regs.h.bh = TEXT_RPAGE;
- oakint86(BIOS_VIDINT, ®s);
- break;
- case PCMODE_EGA43:
- case PCMODE_VGA50:
- pc_sethflag(PCHFLAG_COLO);
-
- /* In case this is a VGA, set the proper number of scanlines */
- /* (EGA will not respond to this call and stay at 350) */
- regs.h.ah = VIDINT_ALTSEL; /* alternate select */
- regs.h.bl = ALTSEL_SETLINES; /* set # of scanlines */
- if (mode == PCMODE_EGA43) {
- regs.h.al = SETLINES_350;
- }
- else {
- regs.h.al = SETLINES_400;
- }
- oakint86(BIOS_VIDINT, ®s);
-
- regs.h.al = 0x03; /* These modes are based on mode 3 */
- regs.h.bh = TEXT_RPAGE;
- regs.h.ah = VIDINT_SETVM; /* reset video mode (see ega docs) */
- oakint86(BIOS_VIDINT, ®s);
-
- regs.h.ah = VIDINT_CHARGEN; /* character generator command */
- regs.h.al = CHARGEN_ROM8X8; /* choose 8x8 cell */
- regs.h.bl = 0;
- oakint86(BIOS_VIDINT, ®s); /* setup 43/50 line */
-
- regs.h.ah = VIDINT_ALTSEL; /* alternate select */
- regs.h.bl = ALTSEL_NEWPRTSCR; /* new print screen routine */
- oakint86(BIOS_VIDINT, ®s); /* setup new prt scrn */
-
- break;
- case PCMODE_HERC0:
- case PCMODE_HERC1:
- herc_setgmode(mode != PCMODE_HERC0);
- break;
- }
- }
- /* -------------------------------------------------------------------------- */
-
- int pc_GetMode()
- /*
- effects: gets the current video mode of the display adapter.
- returns: bits 0-7 return the current video mode.
- bits 8-15 returns the video display width.
- */
- {
- OREGS regs;
- int mode;
- byte rows;
-
- regs.h.ah = VIDINT_GETVM;
- oakint86(BIOS_VIDINT, ®s);
- mode = (int)(regs.h.al & 0x7F); /* knock out hi noclear bit */
-
- /* Check for 43 or 50 line mode */
- if (mode == 0x03) {
- if (pc_IsEGA()) {
- ram_segtomem(0x40, 0x84, &rows, 1); /* Get Rows from BIOS data area */
- if (rows == 43-1) mode = PCMODE_EGA43;
- if (rows == 50-1) mode = PCMODE_VGA50;
- }
- }
- /* Check for herc graphics mode */
- if (mode == 0x05 || mode == 0x06 || mode == 0x07) {
- if (pc_IsHerc()) {
- if (herc_getlines() > 0xF00) {
- ram_segtomem(0x40, 0x49, &rows, 1); /* Get vidmode from BIOS */
- if (rows != 5) {
- mode = PCMODE_HERC0;
- }
- else mode = PCMODE_HERC1;
- }
- }
- }
- /* Check for Compaq mode 40 */
- if (mode == 0x40) {
- mode = PCMODE_CPQ40;
- }
- return(mode);
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_ModeSupport(mode)
- int mode;
- /* Return TRUE if mode is supported on current hardware */
- {
- if (mode == PCMODE_HERC0 || mode == PCMODE_HERC1) {
- return(pc_IsHerc());
- }
- if (mode == PCMODE_CPQ40) {
- return(pc_IsCompaqPlasma() && !pc_IsEGA());
- }
- if (newbios()) { /* vga/mcga bios gives supported modes */
- if (newbios_modesupport(mode)) {
- return(TRUE);
- }
- }
- if (pc_IsEGA()) {
- if (ega_modesupport(mode)) {
- return(TRUE);
- }
- }
- switch(mode) {
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- return(pc_IsCGA());
- case 0x07:
- return(pc_IsMDA());
- default:
- return(FALSE);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_IsHerc()
- {
- return(herc_present());
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_IsMDA()
- {
- return(ram_testword(VID_MONOADDR, 4000) && cursport_test(VID_MDAPORT));
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_IsCGA()
- {
- return(ram_testword(VID_CGAADDR, 16000) && cursport_test(VID_CGAPORT));
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_IsEGA()
- {
- if (!ega_ismono(1)) {
- return(TRUE); /* ega is present, not mono */
- }
- else {
- if (ega_ismono(0)) {
- return(TRUE); /* ega is present */
- }
- }
- return(FALSE); /* ega not present */
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_IsMCGA()
- {
- return(newbios_modesupport(0x13));
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_IsVGA()
- {
- return(newbios_modesupport(0x12));
- }
- /* -------------------------------------------------------------------------- */
-
- boolean pc_IsCompaqPlasma()
- {
- OREGS regs;
-
- if (!pc_IsCompaq()) {
- return(FALSE);
- }
- regs.h.ah = VIDINT_CPQINFO; /* alternate select function */
- regs.h.al = 3;
- oakint86(BIOS_VIDINT, ®s);
-
- return((regs.h.cl & CPQINFO_PLASMABIT) != 0);
- }
- /* -------------------------------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
-
- static void DIGPRIV pc_sethflag(vf)
- byte vf;
- {
- byte hf;
-
- /* Put Hardware Equip Flag Video bits to BIOS data area */
- ram_segtomem(0x40, 0x10, &hf, 1);
- hf &= ~0x30;
- hf |= vf & 0x30;
- ram_memtoseg(0x40, 0x10, &hf, 1);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV ega_ismono(inbh)
- byte inbh;
- {
- OREGS regs;
-
- regs.h.ah = VIDINT_ALTSEL; /* alternate select function */
- regs.h.bl = ALTSEL_GETINFO; /* return ega info */
- regs.h.bh = inbh;
- oakint86(BIOS_VIDINT, ®s);
-
- return(regs.h.bh == 1);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV ega_modesupport(mode)
- int mode;
- {
- switch(mode) {
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x0D:
- case 0x0E:
- case 0x10:
- case PCMODE_EGA43:
- return(!ega_ismono(0));
- case 0x07:
- case 0x0F:
- return(ega_ismono(0));
- default:
- return(FALSE);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV newbios()
- {
- byte info[0x50];
-
- return(vga_getinfo(info));
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV newbios_modesupport(mode)
- int mode;
- {
- byte info[0x50];
- unsigned modebit;
- int modebyte;
-
- if (vga_getinfo(info)) {
- if (mode == PCMODE_EGA43 || mode == PCMODE_VGA50) mode = 0x03;
- if (mode <= 0x13) {
- modebyte = 0x40 + mode/8;
- modebit = 1 << (mode % 8);
- return((boolean)(info[modebyte] & modebit));
- }
- }
- return(FALSE);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV vga_getinfo(buf)
- byte *buf;
- /*
- Load up a 50-byte buffer with vga mode info.
- */
- {
- OREGS regs;
- unsigned seg, offs;
-
- /* Call BIOS get-mode-info function to read info into buf */
- regs.a.esdx = buf;
- regs.x.di = regs.x.dx;
- regs.h.ah = VIDINT_MODEINFO;
- regs.h.al = 0;
- regs.x.bx = 0;
- oakint86es(BIOS_VIDINT, ®s, 0x40);
-
- if (regs.h.al == VIDINT_MODEINFO && regs.x.bx == 0) {
- /* Move extra info into end of buf using pointer from start of buf */
- offs = ((unsigned short *) buf)[0];
- seg = ((unsigned short *) buf)[1];
- ram_segtomem(seg, offs, &buf[0x40], 0x10);
- return(TRUE);
- }
- else return(FALSE);
- }
- /* -------------------------------------------------------------------------- */
- #define TESTVAL 0x56D4
-
- static boolean DIGPRIV ram_testword(seg, offs)
- unsigned seg;
- unsigned offs;
- {
- unsigned saveword, testword, testval;
-
- testval = TESTVAL;
-
- ram_segtomem(seg, offs, (byte *)&saveword, 2);
- if (saveword == testval) testval++;
- testword = testval;
- ram_memtoseg(seg, offs, (byte *)&testword, 2);
- testword = 0; /* kill time, settle bus */
- ram_segtomem(seg, offs, (byte *)&testword, 2);
-
- if (testword == testval) {
- ram_memtoseg(seg, offs, (byte *)&saveword, 2);
- return(TRUE);
- }
- else return(FALSE);
- }
- /* -------------------------------------------------------------------------- */
- #define TESTPOS 4
-
- static boolean DIGPRIV cursport_test(port)
- int port;
- {
- int oaddr, taddr, tpos;
-
- tpos = TESTPOS;
-
- outp(port, 0x0F);
- oaddr = inp(port+1);
-
- if (oaddr == tpos) tpos++;
- taddr = tpos;
-
- outp(port, 0x0F);
- outp(port+1, taddr);
-
- taddr = 0;
- outp(port, 0x0F);
- taddr = inp(port+1);
-
- if (taddr == tpos) {
- outp(port, 0x0F);
- outp(port+1, oaddr);
- return(TRUE);
- }
- else return(FALSE);
- }
- /* -------------------------------------------------------------------------- */
-
-