123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "../port/error.h"
- #include "ureg.h"
- #define Image IMAGE
- #include <draw.h>
- #include <memdraw.h>
- #include <cursor.h>
- #include "screen.h"
- #define WORD(p) ((p)[0] | ((p)[1]<<8))
- #define LONG(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))
- #define PWORD(p, v) (p)[0] = (v); (p)[1] = (v)>>8
- #define PLONG(p, v) (p)[0] = (v); (p)[1] = (v)>>8; (p)[2] = (v)>>16; (p)[3] = (v)>>24
- extern void realmode(Ureg*);
- static uchar*
- vbesetup(Ureg *u, int ax)
- {
- ulong pa;
-
- pa = PADDR(RMBUF);
- memset(u, 0, sizeof *u);
- u->ax = ax;
- u->es = (pa>>4)&0xF000;
- u->di = pa&0xFFFF;
- return (void*)RMBUF;
- }
- static void
- vbecall(Ureg *u)
- {
- u->trap = 0x10;
- realmode(u);
- if((u->ax&0xFFFF) != 0x004F)
- error("vesa bios error");
- }
- static void
- vbecheck(void)
- {
- Ureg u;
- uchar *p;
- p = vbesetup(&u, 0x4F00);
- strcpy((char*)p, "VBE2");
- vbecall(&u);
- if(memcmp((char*)p, "VESA", 4) != 0)
- error("bad vesa signature");
- if(p[5] < 2)
- error("bad vesa version");
- }
- static int
- vbegetmode(void)
- {
- Ureg u;
- vbesetup(&u, 0x4F03);
- vbecall(&u);
- return u.bx;
- }
- static uchar*
- vbemodeinfo(int mode)
- {
- uchar *p;
- Ureg u;
- p = vbesetup(&u, 0x4F01);
- u.cx = mode;
- vbecall(&u);
- return p;
- }
- static void
- vesalinear(VGAscr* scr, int, int)
- {
- int i, mode, size;
- uchar *p;
- ulong paddr;
- Pcidev *pci;
- vbecheck();
- mode = vbegetmode();
- /* bochs loses the top bits - cannot use this
- if((mode&(1<<14)) == 0)
- error("not in linear graphics mode");
- */
- mode &= 0x3FFF;
- p = vbemodeinfo(mode);
- if(!(WORD(p+0) & (1<<4)))
- error("not in VESA graphics mode");
- if(!(WORD(p+0) & (1<<7)))
- error("not in linear graphics mode");
- paddr = LONG(p+40);
- size = WORD(p+20)*WORD(p+16);
- size = PGROUND(size);
- /*
- * figure out max size of memory so that we have
- * enough if the screen is resized.
- */
- pci = nil;
- while((pci = pcimatch(pci, 0, 0)) != nil){
- if(pci->ccrb != 3)
- continue;
- for(i=0; i<nelem(pci->mem); i++)
- if(paddr == (pci->mem[i].bar&~0x0F)){
- if(pci->mem[i].size > size)
- size = pci->mem[i].size;
- goto havesize;
- }
- }
- /* no pci - heuristic guess */
- if(size < 4*1024*1024)
- size = 4*1024*1024;
- else
- size = ROUND(size, 1024*1024);
- havesize:
- vgalinearaddr(scr, paddr, size);
- }
- VGAdev vgavesadev = {
- "vesa",
- 0,
- 0,
- 0,
- vesalinear,
- 0,
- 0,
- 0,
- 0,
- 0,
- };
|