⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modes.cpp

📁 nucleus_arm.rar
💻 CPP
字号:
#include <support.h>
#include <string.h>
#include <stdio.h>
#include <video/graphic.h>
#include <video/fonts.h>

#define pokeb(S,O,V)		( *(char*) ( ( S ) * 16 + ( O ) ) = ( V ) ) 
#define pokew(S,O,V)		( *(short*) ( ( S ) * 16 + ( O ) ) = ( V ) )  
#define peekb(S,O)			(*(unsigned char *)( ((unsigned)( S ) * 16) + ( O )))  
#define	_vmemwr(DS,DO,S,N)	_dosmemputb(S, N, 16uL * (DS) + (DO))

/*****************************************************************************
VGA REGISTER DUMPS FOR VARIOUS TEXT MODES

()=to do
	40x25	(40x30)	40x50	(40x60)
	(45x25)	(45x30)	(45x50)	(45x60)
	80x25	(80x30)	80x50	(80x60)
	(90x25)	90x30	(90x50)	90x60
*****************************************************************************/

static void dump(unsigned char *regs, unsigned count)
{
	unsigned i;

	i = 0;
	printf("\t");
	for(; count != 0; count--)
	{
		printf("0x%02X,", *regs);
		i++;
		if(i >= 8)
		{
			i = 0;
			printf("\n\t");
		}
		else
			printf(" ");
		regs++;
	}
	printf("\n");
}

void dump_regs(unsigned char *regs)
{
	printf("unsigned char g_mode[] =\n");
	printf("{\n");
/* dump MISCELLANEOUS reg */
	printf("/* MISC */\n");
	printf("\t0x%02X,\n", *regs);
	regs++;
/* dump SEQUENCER regs */
	printf("/* SEQ */\n");
	dump(regs, SEQ_C);
	regs += SEQ_C;
/* dump CRTC regs */
	printf("/* CRTC */\n");
	dump(regs, CRT_C);
	regs += CRT_C;
/* dump GRAPHICS CONTROLLER regs */
	printf("/* GC */\n");
	dump(regs, GRA_C);
	regs += GRA_C;
/* dump ATTRIBUTE CONTROLLER regs */
	printf("/* AC */\n");
	dump(regs, ATT_C);
	regs += ATT_C;
	printf("};\n");
}

void read_regs(unsigned char *regs)
{
	unsigned i;

/* read MISCELLANEOUS reg */
	*regs = inportb(MIS_R);
	regs++;
/* read SEQUENCER regs */
	for(i = 0; i < SEQ_C; i++)
	{
		outportb(SEQ_I, i);
		*regs = inportb(SEQ_D);
		regs++;
	}
/* read CRTC regs */
	for(i = 0; i < CRT_C; i++)
	{
		outportb(CRT_I, i);
		*regs = inportb(CRT_D);
		regs++;
	}
/* read GRAPHICS CONTROLLER regs */
	for(i = 0; i < GRA_C; i++)
	{
		outportb(GRA_I, i);
		*regs = inportb(GRA_D);
		regs++;
	}
/* read ATTRIBUTE CONTROLLER regs */
	for(i = 0; i < ATT_C; i++)
	{
		(void)inportb(IS1_R);
		outportb(ATT_I, i);
		*regs = inportb(ATT_R);
		regs++;
	}
/* lock 16-color palette and unblank display */
	(void)inportb(IS1_R);
	outportb(ATT_I, 0x20);
}

static void set_plane(unsigned p)
{
	unsigned char pmask;

	p &= 3;
	pmask = 1 << p;
#if 0
/* set read plane */
	outportb(GRA_I, 4);
	outportb(GRA_D, p);
/* set write plane */
	outportb(SEQ_I, 2);
	outportb(SEQ_D, pmask);
#else
	outportw(GRA_I, (p << 8) | 4);
	outportw(SEQ_I, (pmask << 8) | 2);
#endif
}
/*****************************************************************************
VGA framebuffer is at A000:0000, B000:0000, or B800:0000
depending on bits in GC 6
*****************************************************************************/
static unsigned get_fb_seg(void)
{
	unsigned seg;

	outportb(GRA_I, 6);
	seg = inportb(GRA_D);
	seg >>= 2;
	seg &= 3;
	switch(seg)
	{
	case 0:
	case 1:
		seg = 0xA000;
		break;
	case 2:
		seg = 0xB000;
		break;
	case 3:
		seg = 0xB800;
		break;
	}
	return seg;
}

static void vmemwr(unsigned dst_off, unsigned char *src, unsigned count)
{
	_vmemwr(get_fb_seg(), dst_off, src, count);
}

static void vpokeb(unsigned off, unsigned val)
{
	pokeb(get_fb_seg(), off, val);
}

static unsigned vpeekb(unsigned off)
{
	return peekb(get_fb_seg(), off);
}

/*****************************************************************************
write font to plane P4 (assuming planes are named P1, P2, P4, P8)
*****************************************************************************/
static void write_font(unsigned char *buf, unsigned font_height)
{
	unsigned char seq2, seq4, gc4, gc5, gc6;
	unsigned i;

/* save registers
set_plane() modifies GC 4 and SEQ 2, so save them as well */
	outportb(SEQ_I, 2);
	seq2 = inportb(SEQ_D);

	outportb(SEQ_I, 4);
	seq4 = inportb(SEQ_D);
/* turn off even-odd addressing (set flat addressing)
assume: chain-4 addressing already off */
	outportb(SEQ_D, seq4 | 0x04);

	outportb(GRA_I, 4);
	gc4 = inportb(GRA_D);

	outportb(GRA_I, 5);
	gc5 = inportb(GRA_D);
/* turn off even-odd addressing */
	outportb(GRA_D, gc5 & ~0x10);

	outportb(GRA_I, 6);
	gc6 = inportb(GRA_D);
/* turn off even-odd addressing */
	outportb(GRA_D, gc6 & ~0x02);
/* write font to plane P4 */
	set_plane(2);
/* write font 0 */
	for(i = 0; i < 256; i++)
	{
		vmemwr(16384u * 0 + i * 32, buf, font_height);
		buf += font_height;
	}
#if 0
/* write font 1 */
	for(i = 0; i < 256; i++)
	{
		vmemwr(16384u * 1 + i * 32, buf, font_height);
		buf += font_height;
	}
#endif
/* restore registers */
	outportb(SEQ_I, 2);
	outportb(SEQ_D, seq2);
	outportb(SEQ_I, 4);
	outportb(SEQ_D, seq4);
	outportb(GRA_I, 4);
	outportb(GRA_D, gc4);
	outportb(GRA_I, 5);
	outportb(GRA_D, gc5);
	outportb(GRA_I, 6);
	outportb(GRA_D, gc6);
}

/*****************************************************************************
READ AND DUMP VGA REGISTER VALUES FOR CURRENT VIDEO MODE
This is where g_40x25_text[], g_80x50_text[], etc. came from :)
*****************************************************************************/
void dump_state(void)
{
	unsigned char state[VGA_NUM_REGS];

	read_regs(state);
	dump_regs(state);
}

/*****************************************************************************
SET TEXT MODES
*****************************************************************************/
char set_mode_modes(unsigned int mode)
{
	unsigned rows = 80, cols = 25, ht = 8, i = 0;

	printf("Setting mode %d...\n", mode);
	switch(mode)
	{
		case 0:
		case 1: { // text, 16 cols
				write_regs(g_40x25_text);
				cols = 40;
				rows = 25;
				ht = 16;
				} break;
		case 2:
		case 3: { // text, 16 cols
				write_regs(g_80x25_text);
				cols = 80;
				rows = 25;
				ht = 16;
				} break;
		case 4:
		case 5: { // graphics, 4 cols
					vga_set_mode(mode);
				} break;
//		case 6: { // graphics, 2 cols
//				write_regs(g_640x200x2);
//				g_wd = 640;
//				g_ht = 200;
//				g_write_pixel = write_pixel1;
//				} break;
		case 7: { // text, mono (originally)
				write_regs(g_80x25_text);
				cols = 80;
				rows = 25;
				ht = 16;
				} break;
		default: return 0xFF;
	}				
/* set font */
	if(ht >= 16)
		write_font(g_8x16_font, 16);
	else
		write_font(g_8x8_font, 8);
/* tell the BIOS what we've done, so BIOS text output works OK */
	pokew(0x40, 0x4A, cols);	/* columns on screen */
	pokew(0x40, 0x4C, cols * rows * 2); /* framebuffer size */
	pokew(0x40, 0x50, 0);		/* cursor pos'n */
	pokeb(0x40, 0x60, ht - 1);	/* cursor shape */
	pokeb(0x40, 0x61, ht - 2);
	pokeb(0x40, 0x84, rows - 1);	/* rows on screen - 1 */
	pokeb(0x40, 0x85, ht);		/* char height */
/* set white-on-black attributes for all text */
	for(i = 0; i < cols * rows; i++)
		pokeb(0xB800, i * 2 + 1, 7);
	return 0;
}
/*****************************************************************************
DEMO GRAPHICS MODES
*****************************************************************************/
static void demo_graphics(void)
{
	printf("Screen-clear in 16-color mode will be VERY SLOW\n"
		"Press a key to continue\n");
/* 4-color */
	write_regs(g_320x200x4);
	g_wd = 320;
	g_ht = 200;
	g_write_pixel = write_pixel2;
	draw_x();
/* 16-color */
	write_regs(g_640x480x16);
	g_wd = 640;
	g_ht = 480;
	g_write_pixel = write_pixel4p;
	draw_x();
/* 256-color */
	write_regs(g_320x200x256);
	g_wd = 320;
	g_ht = 200;
	g_write_pixel = write_pixel8;
	draw_x();
/* 256-color Mode-X */
	write_regs(g_320x200x256_modex);
	g_wd = 320;
	g_ht = 200;
	g_write_pixel = write_pixel8x;
	draw_x();
/* go back to 80x25 text mode */
	set_mode_modes(7);
}

static unsigned char reverse_bits(unsigned char arg)
{
	unsigned char ret_val = 0;

	if(arg & 0x01)
		ret_val |= 0x80;
	if(arg & 0x02)
		ret_val |= 0x40;
	if(arg & 0x04)
		ret_val |= 0x20;
	if(arg & 0x08)
		ret_val |= 0x10;
	if(arg & 0x10)
		ret_val |= 0x08;
	if(arg & 0x20)
		ret_val |= 0x04;
	if(arg & 0x40)
		ret_val |= 0x02;
	if(arg & 0x80)
		ret_val |= 0x01;
	return ret_val;
}

/*****************************************************************************
512-CHARACTER FONT
*****************************************************************************/
static void font512(void)
{
/* Turbo C++ 1.0 seems to 'lose' any data declared 'static const' */
	/*static*/ const char msg1[] = "!txet sdrawkcaB";
	/*static*/ const char msg2[] = "?rorrim a toG";
/**/
	unsigned char seq2, seq4, gc4, gc5, gc6;
	unsigned font_height, i, j;

/* start in 80x25 text mode */
	set_mode_modes(7);
/* code pasted in from write_font():
save registers
set_plane() modifies GC 4 and SEQ 2, so save them as well */
	outportb(SEQ_I, 2);
	seq2 = inportb(SEQ_D);

	outportb(SEQ_I, 4);
	seq4 = inportb(SEQ_D);
/* turn off even-odd addressing (set flat addressing)
assume: chain-4 addressing already off */
	outportb(SEQ_D, seq4 | 0x04);

	outportb(GRA_I, 4);
	gc4 = inportb(GRA_D);

	outportb(GRA_I, 5);
	gc5 = inportb(GRA_D);
/* turn off even-odd addressing */
	outportb(GRA_D, gc5 & ~0x10);

	outportb(GRA_I, 6);
	gc6 = inportb(GRA_D);
/* turn off even-odd addressing */
	outportb(GRA_D, gc6 & ~0x02);
/* write font to plane P4 */
	set_plane(2);
/* this is different from write_font():
use font 1 instead of font 0, and use it for BACKWARD text */
	font_height = 16;
	for(i = 0; i < 256; i++)
	{
		for(j = 0; j < font_height; j++)
		{
			vpokeb(16384u * 1 + 32 * i + j,
				reverse_bits(
					g_8x16_font[font_height * i + j]));
		}
	}
/* restore registers */
	outportb(SEQ_I, 2);
	outportb(SEQ_D, seq2);
	outportb(SEQ_I, 4);
	outportb(SEQ_D, seq4);
	outportb(GRA_I, 4);
	outportb(GRA_D, gc4);
	outportb(GRA_I, 5);
	outportb(GRA_D, gc5);
	outportb(GRA_I, 6);
	outportb(GRA_D, gc6);
/* now: sacrifice attribute bit b3 (foreground intense color)
use it to select characters 256-511 in the second font */
	outportb(SEQ_I, 3);
	outportb(SEQ_D, 4);
/* xxx - maybe re-program 16-color palette here
so attribute bit b3 is no longer used for 'intense' */
	for(i = 0; i < sizeof(msg1); i++)
	{
		vpokeb((80 * 8  + 40 + i) * 2 + 0, msg1[i]);
/* set attribute bit b3 for backward font */
		vpokeb((80 * 8  + 40 + i) * 2 + 1, 0x0F);
	}
	for(i = 0; i < sizeof(msg2); i++)
	{
		vpokeb((80 * 16 + 40 + i) * 2 + 0, msg2[i]);
		vpokeb((80 * 16 + 40 + i) * 2 + 1, 0x0F);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -