From: John Tsiombikas Date: Sun, 25 Jun 2023 03:41:31 +0000 (+0300) Subject: more vbe X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=75aa7ef609cbda625e6c19bc07acf744eb3bfc5a;p=vidsys more vbe --- diff --git a/drv.h b/drv.h index ef8ef30..172f146 100644 --- a/drv.h +++ b/drv.h @@ -15,6 +15,9 @@ struct vid_drvops { extern struct vid_driver *vid_drvlist[MAX_DRV]; extern int vid_numdrv; +extern void *vid_vmem; +extern int vid_vmem_size; + void vid_register_vga(void); /* drv_vga.c */ void vid_register_vbe(void); /* drv_vbe.c */ void vid_register_s3(void); /* drv_s3.c */ diff --git a/drv_vbe.c b/drv_vbe.c index 59ec306..69c89eb 100644 --- a/drv_vbe.c +++ b/drv_vbe.c @@ -4,6 +4,7 @@ #include "vidsys.h" #include "drv.h" #include "vbe.h" +#include "vga.h" #include "cdpmi.h" #define farptr_to_linear(rmaddr) \ @@ -11,18 +12,29 @@ static int init(void); static void cleanup(void); +static struct vid_modeinfo *find_mode(int mode); static int setmode(int mode); static int getmode(void); static const char *memsize_str(long sz); static int get_mode_info(int mode, struct vbe_mode_info *mi); +static int setwin(int wid, int pos); static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info *vbemi); static unsigned int calc_mask(int nbits, int pos); +static void pack(uint32_t *pix, int r, int g, int b); +static void unpack(uint32_t pix, int *r, int *g, int *b); +static void clear(uint32_t color); +static void blitfb_lfb(void *fb, int pitch); +static void blitfb_banked(void *fb, int pitch); +static void flip(int vsync); + static struct vid_driver drv; static struct vid_drvops drvops = {init, cleanup, setmode, getmode}; static unsigned int vbe_ver; static int cur_mode; +static struct vid_modeinfo *cur_mi; +static int cur_pgsize; void vid_register_vbe(void) @@ -46,6 +58,7 @@ static int init(void) struct vid_modeinfo modeinf; cur_mode = -1; + cur_mi = 0; vbe = dpmi_lowbuf(); bufseg = (intptr_t)vbe >> 4; @@ -55,7 +68,7 @@ static int init(void) regs.eax = 0x4f00; regs.es = bufseg; dpmi_rmint(0x10, ®s); - if(regs.eax != 0x4f || memcmp(vbe->sig, "VESA", 4) != 0) { + if((regs.eax & 0xffff) != 0x4f || memcmp(vbe->sig, "VESA", 4) != 0) { fprintf(stderr, "failed to get VBE controller information\n"); return -1; } @@ -114,24 +127,48 @@ static void cleanup(void) drv.num_modes = 0; } +static struct vid_modeinfo *find_mode(int mode) +{ + int i; + for(i=0; ilfb) { + mode |= VBE_MODE_LFB; + } + +retry: regs.eax = 0x4f02; - regs.ebx = mode | VBE_MODE_LFB; + regs.ebx = mode; dpmi_rmint(0x10, ®s); - if(regs.eax != 0x4f) { - regs.eax = 0x4f02; - regs.ebx = mode; - dpmi_rmint(0x10, ®s); - if(regs.eax != 0x4f) { - return -1; + if((regs.eax & 0xffff) != 0x4f) { + if(mode & VBE_MODE_LFB) { + mode &= ~VBE_MODE_LFB; + goto retry; } - cur_mode = mode; + return -1; + } + cur_mode = mode; + + if(!(cur_mi = minf)) return 0; + + cur_pgsize = minf->height * minf->pitch; + + if(mode & VBE_MODE_LFB) { + minf->ops.blitfb = blitfb_lfb; } else { - cur_mode = mode | VBE_MODE_LFB; + minf->ops.blitfb = blitfb_banked; } return 0; } @@ -169,7 +206,7 @@ static int get_mode_info(int mode, struct vbe_mode_info *mi) regs.ecx = mode; regs.es = bufseg; dpmi_rmint(0x10, ®s); - if(regs.eax != 0x4f) { + if((regs.eax & 0xffff) != 0x4f) { return -1; } @@ -177,8 +214,23 @@ static int get_mode_info(int mode, struct vbe_mode_info *mi) return 0; } +static int setwin(int wid, int pos) +{ + struct dpmi_regs regs = {0}; + + regs.eax = 0x4f05; + regs.ebx = wid; + regs.edx = pos; + dpmi_rmint(0x10, ®s); + if((regs.eax & 0xffff) != 0x4f) { + return -1; + } + return 0; +} + static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info *vbemi) { + static int gran_shift; static const struct { int width, height, bpp; } stdmode[] = { {640, 400, 8}, /* 100h */ {640, 480, 8}, /* 101h */ @@ -235,6 +287,26 @@ static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info mi->pitch = vbemi->scanline_bytes; mi->win_size = vbemi->win_size; mi->win_gran = vbemi->win_gran; + + gran_shift = 0; + mi->win_step = 1; + if(mi->win_gran > 0 && mi->win_gran < 64) { + int gran = mi->win_gran; + while(gran < 64) { + gran_shift++; + gran <<= 1; + } + mi->win_step = 1 << gran_shift; + } + + mi->ops.pack = pack; + mi->ops.unpack = unpack; + mi->ops.setpal = vga_setpal; + mi->ops.getpal = vga_getpal; + mi->ops.vsync = vga_vsync; + mi->ops.clear = clear; + mi->ops.blitfb = 0; + mi->ops.flip = flip; return 0; } @@ -248,3 +320,61 @@ static unsigned int calc_mask(int nbits, int pos) } return mask << pos; } + + +static void pack(uint32_t *pix, int r, int g, int b) +{ + *pix = (((uint32_t)r << cur_mi->rshift) & cur_mi->rmask) | + (((uint32_t)g << cur_mi->gshift) & cur_mi->gmask) | + (((uint32_t)b << cur_mi->bshift) & cur_mi->bmask); +} + +static void unpack(uint32_t pix, int *r, int *g, int *b) +{ + *r = (pix & cur_mi->rmask) >> cur_mi->rshift; + *g = (pix & cur_mi->gmask) >> cur_mi->gshift; + *b = (pix & cur_mi->bmask) >> cur_mi->bshift; +} + +static void clear(uint32_t color) +{ +} + +static void blitfb_lfb(void *fb, int pitch) +{ + int i; + unsigned char *dest, *src; + + dest = vid_vmem; + src = fb; + + for(i=0; iheight; i++) { + memcpy(dest, src, cur_mi->pitch); + dest += cur_mi->pitch; + src += pitch; + } +} + +static void blitfb_banked(void *fb, int pitch) +{ + int sz, offs, pending; + unsigned char *pptr = fb; + + /* assume initial window offset at 0 */ + offs = 0; + pending = cur_pgsize; + while(pending > 0) { + sz = pending > 65536 ? 65536 : pending; + memcpy((void*)0xa0000, pptr, sz); + pptr += sz; + pending -= sz; + offs += cur_mi->win_step; + setwin(0, offs); + } + setwin(0, 0); +} + +static void flip(int vsync) +{ + /* TODO */ +} diff --git a/main.c b/main.c index 4b7ad18..ed2377e 100644 --- a/main.c +++ b/main.c @@ -8,13 +8,53 @@ void test8bpp(void); struct vid_modeinfo *vm; void *vmem; +static const char *usage_fmt = "Usage %s: [options]\n" + "Options: \n" + " -s : video resolution\n" + " -b : color depth\n"; + int main(int argc, char **argv) { + int i; int mode; int xres = 320; int yres = 200; int bpp = 8; + for(i=1; i #include #include "vidsys.h" +#include "vga.h" #include "drv.h" #include "cdpmi.h" struct vid_driver *vid_drvlist[MAX_DRV]; int vid_numdrv; +void *vid_vmem; +int vid_vmem_size; + static struct vid_modeinfo **modes, *cur_mode; static int num_modes, max_modes; -static void *vmem; -static int vmem_size; int vid_init(void) { - int i, j; + int i, j, len; + struct vid_modeinfo *vm; vid_numdrv = 0; free(modes); @@ -24,8 +27,8 @@ int vid_init(void) cur_mode = 0; num_modes = max_modes = 0; - vmem = 0; - vmem_size = 0; + vid_vmem = 0; + vid_vmem_size = 0; if(dpmi_init() == -1) { return -1; @@ -57,9 +60,18 @@ int vid_init(void) } printf("found %d modes:\n", num_modes); - for(i=0; idrv->name, modes[i]->modeno, - modes[i]->width, modes[i]->height, modes[i]->bpp); + for(i=0; idrv->name, vm->modeno, + vm->width, vm->height, vm->bpp); + if(i + 1 >= num_modes) { + putchar('\n'); + break; + } + for(j=len; j<40; j++) putchar(' '); + vm = modes[i + 1]; + printf("[%4s] %04x: %dx%d %dbpp\n", vm->drv->name, vm->modeno, + vm->width, vm->height, vm->bpp); } return 0; @@ -73,8 +85,8 @@ void vid_cleanup(void) vid_setmode(3); } - if(vmem >= (void*)0x100000) { - dpmi_munmap(vmem); + if(vid_vmem >= (void*)0x100000) { + dpmi_munmap(vid_vmem); } for(i=0; iops->setmode(mode) == 0) { cur_mode = modes[i]; - if(vmem >= (void*)0x100000) { - assert(vmem_size); - dpmi_munmap(vmem); + if(vid_vmem >= (void*)0x100000) { + assert(vid_vmem_size); + dpmi_munmap(vid_vmem); } if(modes[i]->vmem_addr < 0x100000) { - vmem = (void*)modes[i]->vmem_addr; - vmem_size = 0; + vid_vmem = (void*)modes[i]->vmem_addr; + vid_vmem_size = 0; } else { - vmem = dpmi_mmap(modes[i]->vmem_addr, modes[i]->vmem_size); - vmem_size = modes[i]->vmem_size; + vid_vmem = dpmi_mmap(modes[i]->vmem_addr, modes[i]->vmem_size); + vid_vmem_size = modes[i]->vmem_size; } - return vmem; + return vid_vmem; } } } diff --git a/vidsys.h b/vidsys.h index 34e35ed..bcf7837 100644 --- a/vidsys.h +++ b/vidsys.h @@ -45,7 +45,7 @@ struct vid_modeinfo { uint32_t rmask, gmask, bmask; int rshift, gshift, bshift; int pages; - int win_size, win_gran; + int win_size, win_gran, win_step; uint32_t vmem_addr; size_t vmem_size; int lfb;