X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fdos%2Fgfx.c;h=80d965b819ae821bd88af8b535092319682a904e;hb=523febfe756566b414051a392d9ab0e5c1649f49;hp=c8444aafa8898981e99aec9270c7d2d3f32ef1d8;hpb=387c4948b144c51c5b6fcfb8f558c3becf324f70;p=retrobench diff --git a/src/dos/gfx.c b/src/dos/gfx.c index c8444aa..80d965b 100644 --- a/src/dos/gfx.c +++ b/src/dos/gfx.c @@ -1,24 +1,28 @@ -#include #include #include +#include #include "cdpmi.h" #include "gfx.h" #include "vbe.h" #include "vga.h" #include "util.h" + #define SAME_BPP(a, b) \ ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \ ((a) == 32 && (b) == 24) || ((a) == 24 && (b) == 32)) void (*blit_frame)(void*, int); -int resizefb(int x, int y, int bpp); +int resizefb(int x, int y, int bpp, int pitch); static void blit_frame_lfb(void *pixels, int vsync); static void blit_frame_banked(void *pixels, int vsync); static uint32_t calc_mask(int sz, int pos); +static void enable_wrcomb(uint32_t addr, int len); +static void print_mtrr(void); + static struct video_mode *vmodes; static int num_vmodes; @@ -86,7 +90,7 @@ int init_video(void) vmptr->rmask = calc_mask(minf.rsize, minf.rpos); vmptr->gmask = calc_mask(minf.gsize, minf.gpos); vmptr->bmask = calc_mask(minf.bsize, minf.bpos); - vmptr->bpp = vmptr->rbits + vmptr->gbits + vmptr->bbits; + /*vmptr->bpp = vmptr->rbits + vmptr->gbits + vmptr->bbits;*/ } if(minf.attr & VBE_ATTR_LFB) { vmptr->fb_addr = minf.fb_addr; @@ -222,6 +226,9 @@ void *set_video_mode(int idx, int nbuf) blit_frame = blit_frame_lfb; + print_mtrr(); + enable_wrcomb(vm->fb_addr, fbsize); + } else { vpgaddr[0] = (void*)0xa0000; vpgaddr[1] = 0; @@ -230,13 +237,14 @@ void *set_video_mode(int idx, int nbuf) } /* allocate main memory framebuffer */ - if(resizefb(vm->xsz, vm->ysz, vm->bpp) == -1) { + if(resizefb(vm->xsz, vm->ysz, vm->bpp, vm->pitch) == -1) { fprintf(stderr, "failed to allocate %dx%d (%d bpp) framebuffer\n", vm->xsz, vm->ysz, vm->bpp); set_text_mode(); return 0; } + fflush(stdout); return vpgaddr[0]; } @@ -305,3 +313,160 @@ static uint32_t calc_mask(int sz, int pos) } return mask << pos; } + +#define get_msr(msr, low, high) \ + asm volatile( \ + "\r\trdmsr" \ + : "=a"(low), "=d"(high) \ + : "c"(msr)) + +#define set_msr(msr, low, high) \ + asm volatile( \ + "\r\twrmsr" \ + :: "c"(msr), "a"(low), "d"(high)) + +#define MSR_MTRRCAP 0xfe +#define MSR_MTRRDEFTYPE 0x2ff +#define MSR_MTRRBASE(x) (0x200 | ((x) << 1)) +#define MSR_MTRRMASK(x) (0x201 | ((x) << 1)) +#define MTRRDEF_EN 0x800 +#define MTRRCAP_HAVE_WC 0x400 +#define MTRRMASK_VALID 0x800 + +#define MTRR_WC 1 + +static int get_page_memtype(uint32_t addr, int num_ranges) +{ + int i; + uint32_t rlow, rhigh; + uint32_t base, mask; + + for(i=0; i 0) { + if(get_page_memtype(addr, num_ranges) != MTRR_WC) { + return 0; + } + addr += 4096; + len -= 4096; + } + return 1; +} + +static int alloc_mtrr(int num_ranges) +{ + int i; + uint32_t rlow, rhigh; + + for(i=0; i> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; + mask = ~mask & 0xfffff000; + + printf(" ... mask: %08x\n", (unsigned int)mask); + + disable(); + get_msr(MSR_MTRRDEFTYPE, def, rhigh); + set_msr(MSR_MTRRDEFTYPE, def & ~MTRRDEF_EN, rhigh); + + set_msr(MSR_MTRRBASE(mtrr), addr | MTRR_WC, 0); + set_msr(MSR_MTRRMASK(mtrr), mask | MTRRMASK_VALID, 0); + + set_msr(MSR_MTRRDEFTYPE, def | MTRRDEF_EN, 0); + enable(); +} + +static const char *mtrr_names[] = { "N/A", "W C", "N/A", "N/A", "W T", "W P", "W B" }; + +static const char *mtrr_type_name(int type) +{ + if(type < 0 || type >= sizeof mtrr_names / sizeof *mtrr_names) { + return mtrr_names[0]; + } + return mtrr_names[type]; +} + +static void print_mtrr(void) +{ + int i, num_ranges; + uint32_t rlow, rhigh, base, mask; + + get_msr(MSR_MTRRCAP, rlow, rhigh); + num_ranges = rlow & 0xff; + + for(i=0; i