X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fdos%2Fgfx.c;h=80d965b819ae821bd88af8b535092319682a904e;hb=56142c5f75e9464ce20f7b9e49e868e3997b76b3;hp=c686e3540483555b5f859ead590100f3b7772e51;hpb=7fbad1ef859d78626b6080a2813d8dbfc49a6dfc;p=retrobench diff --git a/src/dos/gfx.c b/src/dos/gfx.c index c686e35..80d965b 100644 --- a/src/dos/gfx.c +++ b/src/dos/gfx.c @@ -1,12 +1,13 @@ -#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)) @@ -19,6 +20,9 @@ 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; @@ -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; @@ -237,6 +244,7 @@ void *set_video_mode(int idx, int nbuf) 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