rayzor
diff src/vbe.c @ 0:2a5340a6eee4
rayzor first commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 05 Apr 2014 08:46:27 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/vbe.c Sat Apr 05 08:46:27 2014 +0300 1.3 @@ -0,0 +1,153 @@ 1.4 +#include <stdio.h> 1.5 +#include <string.h> 1.6 +#include "vbe.h" 1.7 +#include "dpmi.h" 1.8 + 1.9 +/* VGA DAC registers used for palette setting in 8bpp modes */ 1.10 +#define VGA_DAC_STATE 0x3c7 1.11 +#define VGA_DAC_ADDR_RD 0x3c7 1.12 +#define VGA_DAC_ADDR_WR 0x3c8 1.13 +#define VGA_DAC_DATA 0x3c9 1.14 + 1.15 +#define MODE_LFB (1 << 14) 1.16 + 1.17 + 1.18 +struct vbe_info *vbe_get_info(void) 1.19 +{ 1.20 + static unsigned short info_block_seg; 1.21 + static struct vbe_info *info; 1.22 + struct dpmi_real_regs regs; 1.23 + 1.24 + if(!info) { 1.25 + /* allocate 32 paragraphs (512 bytes) */ 1.26 + info_block_seg = dpmi_alloc(32); 1.27 + info = (struct vbe_info*)(info_block_seg << 4); 1.28 + } 1.29 + 1.30 + memcpy(info->sig, "VBE2", 4); 1.31 + 1.32 + memset(®s, 0, sizeof regs); 1.33 + regs.es = info_block_seg; 1.34 + regs.eax = 0x4f00; 1.35 + 1.36 + dpmi_real_int(0x10, ®s); 1.37 + 1.38 + return info; 1.39 +} 1.40 + 1.41 +struct vbe_mode_info *vbe_get_mode_info(int mode) 1.42 +{ 1.43 + static unsigned short mode_info_seg; 1.44 + static struct vbe_mode_info *mi; 1.45 + struct dpmi_real_regs regs; 1.46 + 1.47 + if(!mi) { 1.48 + /* allocate 16 paragraphs (256 bytes) */ 1.49 + mode_info_seg = dpmi_alloc(16); 1.50 + mi = (struct vbe_mode_info*)(mode_info_seg << 4); 1.51 + } 1.52 + 1.53 + memset(®s, 0, sizeof regs); 1.54 + regs.es = mode_info_seg; 1.55 + regs.eax = 0x4f01; 1.56 + regs.ecx = mode; 1.57 + regs.es = mode_info_seg; 1.58 + 1.59 + dpmi_real_int(0x10, ®s); 1.60 + if(regs.eax & 0xff00) { 1.61 + return 0; 1.62 + } 1.63 + 1.64 + return mi; 1.65 +} 1.66 + 1.67 +int vbe_set_mode(int mode) 1.68 +{ 1.69 + struct dpmi_real_regs regs; 1.70 + 1.71 + memset(®s, 0, sizeof regs); 1.72 + regs.eax = 0x4f02; 1.73 + regs.ebx = mode; 1.74 + dpmi_real_int(0x10, ®s); 1.75 + 1.76 + if(regs.eax == 0x100) { 1.77 + return -1; 1.78 + } 1.79 + return 0; 1.80 +} 1.81 + 1.82 +int vbe_set_palette_bits(int bits) 1.83 +{ 1.84 + struct dpmi_real_regs regs; 1.85 + 1.86 + memset(®s, 0, sizeof regs); 1.87 + regs.eax = 0x4f08; 1.88 + regs.ebx = bits << 8; /* bits in bh */ 1.89 + dpmi_real_int(0x10, ®s); 1.90 + 1.91 + if((regs.eax >> 8) & 0xff == 3) { 1.92 + return -1; 1.93 + } 1.94 + return regs.ebx >> 8 & 0xff; /* new color bits in bh */ 1.95 +} 1.96 + 1.97 +/* TODO: implement palette setting through the VBE2 interface for 1.98 + * non-VGA displays (actually don't). 1.99 + */ 1.100 +void vbe_set_palette(int idx, int *col, int count, int bits) 1.101 +{ 1.102 + int i, shift = 8 - bits; 1.103 + 1.104 + __asm { 1.105 + mov dx, VGA_DAC_ADDR_WR 1.106 + mov eax, idx 1.107 + out dx, al 1.108 + } 1.109 + 1.110 + for(i=0; i<count; i++) { 1.111 + unsigned char r = *col++; 1.112 + unsigned char g = *col++; 1.113 + unsigned char b = *col++; 1.114 + 1.115 + if(shift) { 1.116 + r >>= shift; 1.117 + g >>= shift; 1.118 + b >>= shift; 1.119 + } 1.120 + 1.121 + __asm { 1.122 + mov dx, VGA_DAC_DATA 1.123 + mov al, r 1.124 + out dx, al 1.125 + mov al, g 1.126 + out dx, al 1.127 + mov al, b 1.128 + out dx, al 1.129 + } 1.130 + } 1.131 +} 1.132 + 1.133 +static unsigned int get_mask(int sz, int pos) 1.134 +{ 1.135 + unsigned int i, mask = 0; 1.136 + 1.137 + for(i=0; i<sz; i++) { 1.138 + mask |= 1 << i; 1.139 + } 1.140 + return mask << pos; 1.141 +} 1.142 + 1.143 +void print_mode_info(FILE *fp, struct vbe_mode_info *mi) 1.144 +{ 1.145 + fprintf(fp, "resolution: %dx%d\n", mi->xres, mi->yres); 1.146 + fprintf(fp, "color depth: %d\n", mi->bpp); 1.147 + fprintf(fp, "mode attributes: %x\n", mi->mode_attr); 1.148 + fprintf(fp, "bytes per scanline: %d\n", mi->scanline_bytes); 1.149 + fprintf(fp, "number of planes: %d\n", (int)mi->num_planes); 1.150 + fprintf(fp, "number of banks: %d\n", (int)mi->num_banks); 1.151 + fprintf(fp, "mem model: %d\n", (int)mi->mem_model); 1.152 + fprintf(fp, "red bits: %d (mask: %x)\n", (int)mi->rmask_size, get_mask(mi->rmask_size, mi->rpos)); 1.153 + fprintf(fp, "green bits: %d (mask: %x)\n", (int)mi->gmask_size, get_mask(mi->gmask_size, mi->gpos)); 1.154 + fprintf(fp, "blue bits: %d (mask: %x)\n", (int)mi->bmask_size, get_mask(mi->bmask_size, mi->bpos)); 1.155 + fprintf(fp, "framebuffer address: %x\n", mi->fb_addr); 1.156 +}