text: /*
   * vesainfo.c
   *
   * Dump information about what VESA graphics modes are supported.
   */
  
  #include <string.h>
  #include <stdio.h>
  #include <console.h>
  #include <com32.h>
  #include <inttypes.h>
  #include "../lib/sys/vesa/vesa.h"
  
  /* Wait for a keypress */
  static void wait_key(void)
  {
      char ch;
      while (fread(&ch, 1, 1, stdin) == 0) ;
  }
  
  static void print_modes(void)
  {
  	static com32sys_t rm;
  	struct vesa_general_info *gi;
  	struct vesa_mode_info *mi;
  	uint16_t mode, *mode_ptr;
  	int lines;
  
  	struct vesa_info *vesa;
  
  	vesa = lmalloc(sizeof(*vesa));
  	if (!vesa) {
  		printf("vesainfo.c32: fail in lmalloc\n");
  		return;
  	}
  	gi = &vesa->gi;
  	mi = &vesa->mi;
  
  	gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
  	rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
  	rm.edi.w[0] = OFFS(gi);
  	rm.es = SEG(gi);
  	__intcall(0x10, &rm, &rm);
  
      if (rm.eax.w[0] != 0x004F) {
  	printf("No VESA BIOS detected\n");
  	goto exit;
      } else if (gi->signature != VESA_MAGIC) {
  	printf("VESA information structure has bad magic, trying anyway...\n");
      }
  
      printf("VBE version %d.%d\n"
  	   "Mode   attrib h_res v_res bpp layout rpos gpos bpos\n",
  	   (gi->version >> 8) & 0xff, gi->version & 0xff);
  
      lines = 1;
  
      mode_ptr = GET_PTR(gi->video_mode_ptr);
  
      while ((mode = *mode_ptr++) != 0xFFFF) {
  	if (++lines >= 23) {
  	    wait_key();
  	    lines = 0;
  	}
  
  	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
  	rm.ecx.w[0] = mode;
  	rm.edi.w[0] = OFFS(mi);
  	rm.es = SEG(mi);
  	__intcall(0x10, &rm, &rm);
  
  	/* Must be a supported mode */
  	if (rm.eax.w[0] != 0x004f)
  	    continue;
  
  	printf("0x%04x 0x%04x %5u %5u %3u %6u %4u %4u %4u\n",
  	       mode, mi->mode_attr, mi->h_res, mi->v_res, mi->bpp,
  	       mi->memory_layout, mi->rpos, mi->gpos, mi->bpos);
      }
  
  exit:
  	lfree(vesa);
  	return;
  }
  
  int main(int argc __unused, char **argv __unused)
  {
      print_modes();
      return 0;
  }
  