eobish

annotate src/dos/vbe.c @ 7:6a350c554e46

started DOS port
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 19 Jan 2015 15:49:14 +0200
parents
children
rev   line source
nuclear@7 1 #include <stdio.h>
nuclear@7 2 #include <string.h>
nuclear@7 3 #include "vbe.h"
nuclear@7 4 #include "dpmi.h"
nuclear@7 5
nuclear@7 6 /* VGA DAC registers used for palette setting in 8bpp modes */
nuclear@7 7 #define VGA_DAC_STATE 0x3c7
nuclear@7 8 #define VGA_DAC_ADDR_RD 0x3c7
nuclear@7 9 #define VGA_DAC_ADDR_WR 0x3c8
nuclear@7 10 #define VGA_DAC_DATA 0x3c9
nuclear@7 11
nuclear@7 12 #define MODE_LFB (1 << 14)
nuclear@7 13
nuclear@7 14
nuclear@7 15 struct vbe_info *vbe_get_info(void)
nuclear@7 16 {
nuclear@7 17 static unsigned short info_block_seg;
nuclear@7 18 static struct vbe_info *info;
nuclear@7 19 struct dpmi_real_regs regs;
nuclear@7 20
nuclear@7 21 if(!info) {
nuclear@7 22 /* allocate 32 paragraphs (512 bytes) */
nuclear@7 23 info_block_seg = dpmi_alloc(32);
nuclear@7 24 info = (struct vbe_info*)(info_block_seg << 4);
nuclear@7 25 }
nuclear@7 26
nuclear@7 27 memcpy(info->sig, "VBE2", 4);
nuclear@7 28
nuclear@7 29 memset(&regs, 0, sizeof regs);
nuclear@7 30 regs.es = info_block_seg;
nuclear@7 31 regs.eax = 0x4f00;
nuclear@7 32
nuclear@7 33 dpmi_real_int(0x10, &regs);
nuclear@7 34
nuclear@7 35 return info;
nuclear@7 36 }
nuclear@7 37
nuclear@7 38 struct vbe_mode_info *vbe_get_mode_info(int mode)
nuclear@7 39 {
nuclear@7 40 static unsigned short mode_info_seg;
nuclear@7 41 static struct vbe_mode_info *mi;
nuclear@7 42 struct dpmi_real_regs regs;
nuclear@7 43
nuclear@7 44 if(!mi) {
nuclear@7 45 /* allocate 16 paragraphs (256 bytes) */
nuclear@7 46 mode_info_seg = dpmi_alloc(16);
nuclear@7 47 mi = (struct vbe_mode_info*)(mode_info_seg << 4);
nuclear@7 48 }
nuclear@7 49
nuclear@7 50 memset(&regs, 0, sizeof regs);
nuclear@7 51 regs.es = mode_info_seg;
nuclear@7 52 regs.eax = 0x4f01;
nuclear@7 53 regs.ecx = mode;
nuclear@7 54 regs.es = mode_info_seg;
nuclear@7 55
nuclear@7 56 dpmi_real_int(0x10, &regs);
nuclear@7 57 if(regs.eax & 0xff00) {
nuclear@7 58 return 0;
nuclear@7 59 }
nuclear@7 60
nuclear@7 61 return mi;
nuclear@7 62 }
nuclear@7 63
nuclear@7 64 int vbe_set_mode(int mode)
nuclear@7 65 {
nuclear@7 66 struct dpmi_real_regs regs;
nuclear@7 67
nuclear@7 68 memset(&regs, 0, sizeof regs);
nuclear@7 69 regs.eax = 0x4f02;
nuclear@7 70 regs.ebx = mode;
nuclear@7 71 dpmi_real_int(0x10, &regs);
nuclear@7 72
nuclear@7 73 if(regs.eax == 0x100) {
nuclear@7 74 return -1;
nuclear@7 75 }
nuclear@7 76 return 0;
nuclear@7 77 }
nuclear@7 78
nuclear@7 79 int vbe_set_palette_bits(int bits)
nuclear@7 80 {
nuclear@7 81 struct dpmi_real_regs regs;
nuclear@7 82
nuclear@7 83 memset(&regs, 0, sizeof regs);
nuclear@7 84 regs.eax = 0x4f08;
nuclear@7 85 regs.ebx = bits << 8; /* bits in bh */
nuclear@7 86 dpmi_real_int(0x10, &regs);
nuclear@7 87
nuclear@7 88 if((regs.eax >> 8) & 0xff == 3) {
nuclear@7 89 return -1;
nuclear@7 90 }
nuclear@7 91 return regs.ebx >> 8 & 0xff; /* new color bits in bh */
nuclear@7 92 }
nuclear@7 93
nuclear@7 94 /* TODO: implement palette setting through the VBE2 interface for
nuclear@7 95 * non-VGA displays (actually don't).
nuclear@7 96 */
nuclear@7 97 void vbe_set_palette(int idx, int *col, int count, int bits)
nuclear@7 98 {
nuclear@7 99 int i, shift = 8 - bits;
nuclear@7 100
nuclear@7 101 __asm {
nuclear@7 102 mov dx, VGA_DAC_ADDR_WR
nuclear@7 103 mov eax, idx
nuclear@7 104 out dx, al
nuclear@7 105 }
nuclear@7 106
nuclear@7 107 for(i=0; i<count; i++) {
nuclear@7 108 unsigned char r = *col++;
nuclear@7 109 unsigned char g = *col++;
nuclear@7 110 unsigned char b = *col++;
nuclear@7 111
nuclear@7 112 if(shift) {
nuclear@7 113 r >>= shift;
nuclear@7 114 g >>= shift;
nuclear@7 115 b >>= shift;
nuclear@7 116 }
nuclear@7 117
nuclear@7 118 __asm {
nuclear@7 119 mov dx, VGA_DAC_DATA
nuclear@7 120 mov al, r
nuclear@7 121 out dx, al
nuclear@7 122 mov al, g
nuclear@7 123 out dx, al
nuclear@7 124 mov al, b
nuclear@7 125 out dx, al
nuclear@7 126 }
nuclear@7 127 }
nuclear@7 128 }
nuclear@7 129
nuclear@7 130 static unsigned int get_mask(int sz, int pos)
nuclear@7 131 {
nuclear@7 132 unsigned int i, mask = 0;
nuclear@7 133
nuclear@7 134 for(i=0; i<sz; i++) {
nuclear@7 135 mask |= 1 << i;
nuclear@7 136 }
nuclear@7 137 return mask << pos;
nuclear@7 138 }
nuclear@7 139
nuclear@7 140 void print_mode_info(FILE *fp, struct vbe_mode_info *mi)
nuclear@7 141 {
nuclear@7 142 fprintf(fp, "resolution: %dx%d\n", mi->xres, mi->yres);
nuclear@7 143 fprintf(fp, "color depth: %d\n", mi->bpp);
nuclear@7 144 fprintf(fp, "mode attributes: %x\n", mi->mode_attr);
nuclear@7 145 fprintf(fp, "bytes per scanline: %d\n", mi->scanline_bytes);
nuclear@7 146 fprintf(fp, "number of planes: %d\n", (int)mi->num_planes);
nuclear@7 147 fprintf(fp, "number of banks: %d\n", (int)mi->num_banks);
nuclear@7 148 fprintf(fp, "mem model: %d\n", (int)mi->mem_model);
nuclear@7 149 fprintf(fp, "red bits: %d (mask: %x)\n", (int)mi->rmask_size, get_mask(mi->rmask_size, mi->rpos));
nuclear@7 150 fprintf(fp, "green bits: %d (mask: %x)\n", (int)mi->gmask_size, get_mask(mi->gmask_size, mi->gpos));
nuclear@7 151 fprintf(fp, "blue bits: %d (mask: %x)\n", (int)mi->bmask_size, get_mask(mi->bmask_size, mi->bpos));
nuclear@7 152 fprintf(fp, "framebuffer address: %x\n", mi->fb_addr);
nuclear@7 153 }