#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include "cdpmi.h"
#include "gfx.h"
#include "vbe.h"
#include "vga.h"
vmptr->gmask = calc_mask(minf.gsize, minf.gpos);
vmptr->bmask = calc_mask(minf.bsize, minf.bpos);
}
- vmptr->fb_addr = minf.fb_addr;
+ if(minf.attr & VBE_ATTR_LFB) {
+ vmptr->fb_addr = minf.fb_addr;
+ } else {
+ vmptr->bank_size = (uint32_t)minf.bank_size * 1024;
+ if(!vmptr->bank_size) {
+ vmptr->bank_size = 65536;
+ }
+ }
vmptr->max_pages = minf.num_img_pages;
printf("%04x: ", vbe.modes[i]);
fflush(stdout);
vbe_init_ver = VBE_VER_MAJOR(vbe.ver);
- if(vbe_init_ver < 2) {
- fprintf(stderr, "VBE 2.0 required. Upgrade your video card or run univbe.\n");
- free(vmodes);
- vmodes = 0;
- return -1;
- }
return 0;
}
printf("pgcount: %d, pgsize: %d, fbsize: %d\n", pgcount, pgsize, fbsize);
printf("phys addr: %p\n", (void*)vm->fb_addr);
-
- vpgaddr[0] = (void*)dpmi_mmap(vm->fb_addr, fbsize);
- if(!vpgaddr[0]) {
- fprintf(stderr, "failed to map framebuffer (phys: %lx, size: %d)\n",
- (unsigned long)vm->fb_addr, fbsize);
- set_text_mode();
- return 0;
- }
- //memset(vpgaddr[0], 0xaa, fbsize);
-
- printf("vaddr: %p\n", vpgaddr[0]);
fflush(stdout);
- if(pgcount > 1) {
- vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
- fbidx = 1;
- page_flip(FLIP_NOW); /* start with the second page visible */
+ if(vm->fb_addr) {
+ vpgaddr[0] = (void*)dpmi_mmap(vm->fb_addr, fbsize);
+ if(!vpgaddr[0]) {
+ fprintf(stderr, "failed to map framebuffer (phys: %lx, size: %d)\n",
+ (unsigned long)vm->fb_addr, fbsize);
+ set_text_mode();
+ return 0;
+ }
+ memset(vpgaddr[0], 0xaa, fbsize);
+
+ if(pgcount > 1) {
+ vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
+ fbidx = 1;
+ page_flip(FLIP_NOW); /* start with the second page visible */
+ } else {
+ fbidx = 0;
+ vpgaddr[1] = 0;
+ }
} else {
- fbidx = 0;
+ vpgaddr[0] = (void*)0xa0000;
vpgaddr[1] = 0;
}
return vpgaddr[0];
static struct video_mode *vmode;
+static void swap_lfb(void *pixels);
+static void swap_banked(void *pixels);
+
int main(int argc, char **argv)
{
+ void *fb_buf;
struct video_mode *vmodes;
- int vmidx;
+ int vmidx, status = 0;
init_logger("game.log");
}
vmode = vmodes + vmidx;
+ if(vmode->fb_addr) {
+ swap_buffers = swap_lfb;
+ } else {
+ swap_buffers = swap_banked;
+ }
+
fb_width = vmode->xsz;
fb_height = vmode->ysz;
- fb_size = (vmode->xsz * vmode->bpp / 8) * vmode->ysz;
+ fb_size = vmode->pitch * vmode->ysz;
+
+ if(!(fb_buf = malloc(fb_size + vmode->pitch * 2))) {
+ fprintf(stderr, "failed to allocate framebuffer\n");
+ status = -1;
+ goto break_evloop;
+ }
+ fb_pixels = (char*)fb_buf + vmode->pitch;
reset_timer();
}
break_evloop:
+ free(fb_buf);
set_text_mode();
cleanup_video();
kb_shutdown();
- return 0;
+ return status;
}
static void draw(void)
{
int i, j;
- uint16_t *pptr = vmem;
+ uint16_t *pptr = fb_pixels;
for(i=0; i<fb_height; i++) {
for(j=0; j<fb_width; j++) {
*pptr++ = chess ? 0xff00 : 0x00ff;
}
}
+
+ swap_buffers(fb_pixels);
}
-void swap_buffers(void *pixels)
+static void swap_lfb(void *pixels)
{
wait_vsync();
memcpy(vmem, pixels, fb_size);
}
+
+static void swap_banked(void *pixels)
+{
+ int i, sz;
+ unsigned int pending;
+ unsigned char *pptr = pixels;
+ uint32_t offs = 0;
+
+ wait_vsync();
+
+ /* assume window is always at 0 at the beginning */
+ pending = fb_size;
+ while(pending > 0) {
+ sz = pending > vmode->bank_size ? vmode->bank_size : pending;
+ memcpy(vmem, pptr, sz);
+ pptr += sz;
+ pending -= sz;
+ vbe_setwin(0, ++offs);
+ }
+
+ vbe_setwin(0, 0);
+}