+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <conio.h>
+#include <dos.h>
+#include "video.h"
+#include "3dgfx.h"
+
+void update(void);
+void wait_vsync(void);
+void handle_key(int key);
+void interrupt timer_intr();
+
+static int quit;
+static unsigned char *fb;
+
+static volatile unsigned long nticks;
+
+static void interrupt (*prev_timer_intr)();
+
+int main(void)
+{
+ long rate, nframes = 0;
+ long tstart, tdur;
+
+ if(!(fb = malloc(64000))) {
+ fprintf(stderr, "failed to allocate framebuffer\n");
+ return 1;
+ }
+
+ init_video();
+
+ prev_timer_intr = _dos_getvect(0x1c);
+ _dos_setvect(0x1c, timer_intr);
+ _disable();
+ tstart = nticks;
+ _enable();
+
+ for(;;) {
+ while(kbhit()) {
+ int c = getch();
+ handle_key(c);
+ if(quit) goto end;
+ }
+
+ update();
+ nframes++;
+ }
+
+end:
+ _disable();
+ tdur = nticks - tstart;
+ _enable();
+ _dos_setvect(0x1c, prev_timer_intr);
+
+ close_video();
+ free(fb);
+
+ rate = nframes * 100 * 18 / tdur;
+ printf("%ld frames in %ld sec, rate: %ld.%ld\n", nframes, tdur / 18,
+ rate / 100, rate % 100);
+ return 0;
+}
+
+void update(void)
+{
+ memset(fb, 0, 64000);
+
+ wait_vsync();
+ memcpy((void*)0xa0000, fb, 64000);
+}
+
+void handle_key(int key)
+{
+ switch(key) {
+ case 27:
+ quit = 1;
+ break;
+ }
+}
+
+void interrupt timer_intr()
+{
+ nticks++;
+ _chain_intr(prev_timer_intr);
+}