示例#1
0
文件: vbe.c 项目: 0ida/coreboot
void vbe_set_graphics(void)
{
	u8 rval;

	vbe_info_t info;
	rval = vbe_info(&info);
	if (rval != 0)
		return;

	DEBUG_PRINTF_VBE("VbeSignature: %s\n", info.signature);
	DEBUG_PRINTF_VBE("VbeVersion: 0x%04x\n", info.version);
	DEBUG_PRINTF_VBE("OemString: %s\n", info.oem_string_ptr);
	DEBUG_PRINTF_VBE("Capabilities:\n");
	DEBUG_PRINTF_VBE("\tDAC: %s\n",
			 (info.capabilities & 0x1) ==
			 0 ? "fixed 6bit" : "switchable 6/8bit");
	DEBUG_PRINTF_VBE("\tVGA: %s\n",
			 (info.capabilities & 0x2) ==
			 0 ? "compatible" : "not compatible");
	DEBUG_PRINTF_VBE("\tRAMDAC: %s\n",
			 (info.capabilities & 0x4) ==
			 0 ? "normal" : "use blank bit in Function 09h");

	mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE;
	vbe_get_mode_info(&mode_info);
	vbe_set_mode(&mode_info);

#if CONFIG_BOOTSPLASH
	unsigned char *framebuffer =
		(unsigned char *) le32_to_cpu(mode_info.vesa.phys_base_ptr);
	DEBUG_PRINTF_VBE("FRAMEBUFFER: 0x%p\n", framebuffer);

	struct jpeg_decdata *decdata;

	/* Switching Intel IGD to 1MB video memory will break this. Who
	 * cares. */
	// int imagesize = 1024*768*2;

	unsigned char *jpeg = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
						    "bootsplash.jpg",
						    CBFS_TYPE_BOOTSPLASH,
						    NULL);
	if (!jpeg) {
		DEBUG_PRINTF_VBE("Could not find bootsplash.jpg\n");
		return;
	}
	DEBUG_PRINTF_VBE("Splash at %p ...\n", jpeg);
	dump(jpeg, 64);

	decdata = malloc(sizeof(*decdata));
	int ret = 0;
	DEBUG_PRINTF_VBE("Decompressing boot splash screen...\n");
	ret = jpeg_decode(jpeg, framebuffer, 1024, 768, 16, decdata);
	DEBUG_PRINTF_VBE("returns %x\n", ret);
#endif
}
示例#2
0
status_t
vesa_set_display_mode(vesa_info& info, uint32 mode)
{
	if (mode >= info.shared_info->vesa_mode_count)
		return B_ENTRY_NOT_FOUND;

	// Prepare vm86 mode environment
	struct vm86_state vmState;
	status_t status = vm86_prepare(&vmState, 0x20000);
	if (status != B_OK) {
		dprintf(DEVICE_NAME": vesa_set_display_mode(): vm86_prepare failed\n");
		return status;
	}

	// Get mode information
	struct vbe_mode_info modeInfo;
	status = vbe_get_mode_info(vmState, info.modes[mode].mode, &modeInfo);
	if (status != B_OK) {
		dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n");
		goto out;
	}

	// Set mode
	status = vbe_set_mode(vmState, info.modes[mode].mode);
	if (status != B_OK) {
		dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n");
		goto out;
	}

	if (info.modes[mode].bits_per_pixel <= 8)
		vbe_set_bits_per_gun(vmState, info, 8);

	// Map new frame buffer if necessary

	status = remap_frame_buffer(info, modeInfo.physical_base, modeInfo.width,
		modeInfo.height, modeInfo.bits_per_pixel, modeInfo.bytes_per_row,
		false);
	if (status == B_OK) {
		// Update shared frame buffer information
		info.shared_info->current_mode.virtual_width = modeInfo.width;
		info.shared_info->current_mode.virtual_height = modeInfo.height;
		info.shared_info->current_mode.space = get_color_space_for_depth(
			modeInfo.bits_per_pixel);
	}

out:
	vm86_cleanup(&vmState);
	return status;
}
示例#3
0
void *vg_init(unsigned short mode) {


	vbe_mode_info_t config;

	if ( vbe_set_mode(VBE_MODE, mode) == 1) //set graphic mode
		return NULL;

	if (vbe_get_mode_info(mode, &config) != 0) //get vbe info
	{
		return NULL;
	}

	h_res = config.XResolution; //store X Resolution
	v_res = config.YResolution; //store Y Resolution
	bits_per_pixel = config.BitsPerPixel; //store Bits Per Pixel
	vram_size = (config.XResolution * config.YResolution * config.BitsPerPixel) / 8; //store the size of the vram


	int r;
	struct mem_range mr;

	/* Allow memory mapping */

	mr.mr_base = (config.PhysBasePtr);
	mr.mr_limit = mr.mr_base + (config.XResolution * config.YResolution * config.BitsPerPixel) / 8;

	if( OK != (r = sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr)))
		panic("video_txt: sys_privctl (ADD_MEM) failed: %d\n", r);

	/* Map memory */

	video_mem = vm_map_phys(SELF, (void *)mr.mr_base, (config.XResolution * config.YResolution * config.BitsPerPixel) / 8);

	if(video_mem == MAP_FAILED)
		panic("video_txt couldn't map video memory");


	if (video_mem == NULL)
	{
		printf("vg_init: Error!\n");
		vg_exit();
		return NULL;
	}
	return config.PhysBasePtr;
}
示例#4
0
文件: vbe.c 项目: 0ida/coreboot
static u32
vbe_get_info(void)
{
	u8 rval;
	int i;

	// XXX FIXME these need to be filled with sane values

	// get a copy of input struct...
	screen_info_input_t input;
	// output is pointer to the address passed as argv[4]
	screen_info_t local_output;
	screen_info_t *output = &local_output;
	// zero input
	memset(&input, 0, sizeof(screen_info_input_t));
	// zero output
	memset(&output, 0, sizeof(screen_info_t));

	vbe_info_t info;
	rval = vbe_info(&info);
	if (rval != 0)
		return rval;

	DEBUG_PRINTF_VBE("VbeSignature: %s\n", info.signature);
	DEBUG_PRINTF_VBE("VbeVersion: 0x%04x\n", info.version);
	DEBUG_PRINTF_VBE("OemString: %s\n", info.oem_string_ptr);
	DEBUG_PRINTF_VBE("Capabilities:\n");
	DEBUG_PRINTF_VBE("\tDAC: %s\n",
			 (info.capabilities & 0x1) ==
			 0 ? "fixed 6bit" : "switchable 6/8bit");
	DEBUG_PRINTF_VBE("\tVGA: %s\n",
			 (info.capabilities & 0x2) ==
			 0 ? "compatible" : "not compatible");
	DEBUG_PRINTF_VBE("\tRAMDAC: %s\n",
			 (info.capabilities & 0x4) ==
			 0 ? "normal" : "use blank bit in Function 09h");

	// argv[4] may be a pointer with enough space to return screen_info_t
	// as input, it must contain a screen_info_input_t with the following content:
	// byte[0:3] = "DDC\0" (zero-terminated signature header)
	// byte[4:5] = reserved space for the return struct... just in case we ever change
	//             the struct and don't have reserved enough memory (and let's hope the struct
	//             never gets larger than 64KB)
	// byte[6] = monitor port number for DDC requests ("only" one byte... so lets hope we never have more than 255 monitors...
	// byte[7:8] = max. screen width (OF may want to limit this)
	// byte[9] = required color depth in bpp
	if (strncmp((char *) input.signature, "DDC", 4) != 0) {
		printf
		    ("%s: Invalid input signature! expected: %s, is: %s\n",
		     __func__, "DDC", input.signature);
		return -1;
	}
	if (input.size_reserved != sizeof(screen_info_t)) {
		printf
		    ("%s: Size of return struct is wrong, required: %d, available: %d\n",
		     __func__, (int) sizeof(screen_info_t),
		     input.size_reserved);
		return -1;
	}

	vbe_ddc_info_t ddc_info;
	ddc_info.port_number = input.monitor_number;
	vbe_get_ddc_info(&ddc_info);

#if 0
	DEBUG_PRINTF_VBE("DDC: edid_tranfer_time: %d\n",
			 ddc_info.edid_transfer_time);
	DEBUG_PRINTF_VBE("DDC: ddc_level: %x\n", ddc_info.ddc_level);
	DEBUG_PRINTF_VBE("DDC: EDID: \n");
	CHECK_DBG(DEBUG_VBE) {
		dump(ddc_info.edid_block_zero,
		     sizeof(ddc_info.edid_block_zero));
	}
#endif
/* This could fail because of alignment issues, so use a longer form.
	*((u64 *) ddc_info.edid_block_zero) != (u64) 0x00FFFFFFFFFFFF00ULL
*/
	if (ddc_info.edid_block_zero[0] != 0x00 ||
	    ddc_info.edid_block_zero[1] != 0xFF ||
	    ddc_info.edid_block_zero[2] != 0xFF ||
	    ddc_info.edid_block_zero[3] != 0xFF ||
	    ddc_info.edid_block_zero[4] != 0xFF ||
	    ddc_info.edid_block_zero[5] != 0xFF ||
	    ddc_info.edid_block_zero[6] != 0xFF ||
	    ddc_info.edid_block_zero[7] != 0x00 ) {
		// invalid EDID signature... probably no monitor

		output->display_type = 0x0;
		return 0;
	} else if ((ddc_info.edid_block_zero[20] & 0x80) != 0) {
		// digital display
		output->display_type = 2;
	} else {
		// analog
		output->display_type = 1;
	}
	DEBUG_PRINTF_VBE("DDC: found display type %d\n", output->display_type);
	memcpy(output->edid_block_zero, ddc_info.edid_block_zero,
	       sizeof(ddc_info.edid_block_zero));
	i = 0;
	vbe_mode_info_t mode_info;
	vbe_mode_info_t best_mode_info;
	// initialize best_mode to 0
	memset(&best_mode_info, 0, sizeof(best_mode_info));
	while ((mode_info.video_mode = info.video_mode_list[i]) != 0xFFFF) {
		//DEBUG_PRINTF_VBE("%x: Mode: %04x\n", i, mode_info.video_mode);
		vbe_get_mode_info(&mode_info);

		// FIXME all these values are little endian!

		DEBUG_PRINTF_VBE("Video Mode 0x%04x available, %s\n",
				 mode_info.video_mode,
				 (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x1) ==
				 0 ? "not supported" : "supported");
		DEBUG_PRINTF_VBE("\tTTY: %s\n",
				 (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x4) ==
				 0 ? "no" : "yes");
		DEBUG_PRINTF_VBE("\tMode: %s %s\n",
				 (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x8) ==
				 0 ? "monochrome" : "color",
				 (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x10) ==
				 0 ? "text" : "graphics");
		DEBUG_PRINTF_VBE("\tVGA: %s\n",
				 (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x20) ==
				 0 ? "compatible" : "not compatible");
		DEBUG_PRINTF_VBE("\tWindowed Mode: %s\n",
				 (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x40) ==
				 0 ? "yes" : "no");
		DEBUG_PRINTF_VBE("\tFramebuffer: %s\n",
				 (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x80) ==
				 0 ? "no" : "yes");
		DEBUG_PRINTF_VBE("\tResolution: %dx%d\n",
				 le16_to_cpu(mode_info.vesa.x_resolution),
				 le16_to_cpu(mode_info.vesa.y_resolution));
		DEBUG_PRINTF_VBE("\tChar Size: %dx%d\n",
				 mode_info.vesa.x_charsize, mode_info.vesa.y_charsize);
		DEBUG_PRINTF_VBE("\tColor Depth: %dbpp\n",
				 mode_info.vesa.bits_per_pixel);
		DEBUG_PRINTF_VBE("\tMemory Model: 0x%x\n",
				 mode_info.vesa.memory_model);
		DEBUG_PRINTF_VBE("\tFramebuffer Offset: %08x\n",
				 le32_to_cpu(mode_info.vesa.phys_base_ptr));

		if ((mode_info.vesa.bits_per_pixel == input.color_depth)
		    && (le16_to_cpu(mode_info.vesa.x_resolution) <= input.max_screen_width)
		    && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x80) != 0)	// framebuffer mode
		    && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x10) != 0)	// graphics
		    && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x8) != 0)	// color
		    && (le16_to_cpu(mode_info.vesa.x_resolution) > le16_to_cpu(best_mode_info.vesa.x_resolution)))	// better than previous best_mode
		{
			// yiiiihaah... we found a new best mode
			memcpy(&best_mode_info, &mode_info, sizeof(mode_info));
		}
		i++;
	}

	if (best_mode_info.video_mode != 0) {
		DEBUG_PRINTF_VBE
		    ("Best Video Mode found: 0x%x, %dx%d, %dbpp, framebuffer_address: 0x%x\n",
		     best_mode_info.video_mode,
		     best_mode_info.vesa.x_resolution,
		     best_mode_info.vesa.y_resolution,
		     best_mode_info.vesa.bits_per_pixel,
		     le32_to_cpu(best_mode_info.vesa.phys_base_ptr));

		//printf("Mode Info Dump:");
		//dump(best_mode_info.mode_info_block, 64);

		// set the video mode
		vbe_set_mode(&best_mode_info);

		if ((info.capabilities & 0x1) != 0) {
			// switch to 8 bit palette format
			vbe_set_palette_format(8);
		}
		// setup a palette:
		// - first 216 colors are mixed colors for each component in 6 steps
		//   (6*6*6=216)
		// - then 10 shades of the three primary colors
		// - then 10 shades of grey
		// -------
		// = 256 colors
		//
		// - finally black is color 0 and white color FF (because SLOF expects it
		//   this way...)
		// this resembles the palette that the kernel/X Server seems to expect...

		u8 mixed_color_values[6] =
		    { 0xFF, 0xDA, 0xB3, 0x87, 0x54, 0x00 };
		u8 primary_color_values[10] =
		    { 0xF3, 0xE7, 0xCD, 0xC0, 0xA5, 0x96, 0x77, 0x66, 0x3F,
			0x27
		};
		u8 mc_size = sizeof(mixed_color_values);
		u8 prim_size = sizeof(primary_color_values);

		u8 curr_color_index;
		u32 curr_color;

		u8 r, g, b;
		// 216 mixed colors
		for (r = 0; r < mc_size; r++) {
			for (g = 0; g < mc_size; g++) {
				for (b = 0; b < mc_size; b++) {
					curr_color_index =
					    (r * mc_size * mc_size) +
					    (g * mc_size) + b;
					curr_color = 0;
					curr_color |= ((u32) mixed_color_values[r]) << 16;	//red value
					curr_color |= ((u32) mixed_color_values[g]) << 8;	//green value
					curr_color |= (u32) mixed_color_values[b];	//blue value
					vbe_set_color(curr_color_index,
						      curr_color);
				}
			}
		}

		// 10 shades of each primary color
		// red
		for (r = 0; r < prim_size; r++) {
			curr_color_index = mc_size * mc_size * mc_size + r;
			curr_color = ((u32) primary_color_values[r]) << 16;
			vbe_set_color(curr_color_index, curr_color);
		}
		//green
		for (g = 0; g < prim_size; g++) {
			curr_color_index =
			    mc_size * mc_size * mc_size + prim_size + g;
			curr_color = ((u32) primary_color_values[g]) << 8;
			vbe_set_color(curr_color_index, curr_color);
		}
		//blue
		for (b = 0; b < prim_size; b++) {
			curr_color_index =
			    mc_size * mc_size * mc_size + prim_size * 2 + b;
			curr_color = (u32) primary_color_values[b];
			vbe_set_color(curr_color_index, curr_color);
		}
		// 10 shades of grey
		for (i = 0; i < prim_size; i++) {
			curr_color_index =
			    mc_size * mc_size * mc_size + prim_size * 3 + i;
			curr_color = 0;
			curr_color |= ((u32) primary_color_values[i]) << 16;	//red
			curr_color |= ((u32) primary_color_values[i]) << 8;	//green
			curr_color |= ((u32) primary_color_values[i]);	//blue
			vbe_set_color(curr_color_index, curr_color);
		}

		// SLOF is using color 0x0 (black) and 0xFF (white) to draw to the screen...
		vbe_set_color(0x00, 0x00000000);
		vbe_set_color(0xFF, 0x00FFFFFF);

		output->screen_width = le16_to_cpu(best_mode_info.vesa.x_resolution);
		output->screen_height = le16_to_cpu(best_mode_info.vesa.y_resolution);
		output->screen_linebytes = le16_to_cpu(best_mode_info.vesa.bytes_per_scanline);
		output->color_depth = best_mode_info.vesa.bits_per_pixel;
		output->framebuffer_address =
		    le32_to_cpu(best_mode_info.vesa.phys_base_ptr);
	} else {
		printf("%s: No suitable video mode found!\n", __func__);
		//unset display_type...
		output->display_type = 0;
	}
	return 0;
}
示例#5
0
文件: gfx.c 项目: harnold/ducks
int gfx_init(int mode)
{
    struct vbe_info info;
    struct vbe_mode_info mode_info;

    if (gfx_check_vbe_info(&info) != 0)
        return -1;

    if (gfx_check_vbe_mode_info(&info, mode, &mode_info) != 0)
        return -1;

    vga_get_mode(&gfx_saved_vga_mode);
    gfx_mode_info.mode = gfx_saved_vga_mode;

    if (vbe_set_mode(mode, VBE_LINEAR_FRAMEBUFFER | VBE_CLEAR_DISPLAY_MEMORY) != 0) {
        error("Setting VBE mode %Xh failed", mode);
        goto failure;
    }

    gfx_mode_info.mode = mode;
    gfx_mode_info.x_resolution = mode_info.x_resolution;
    gfx_mode_info.y_resolution = mode_info.y_resolution;
    gfx_mode_info.page_size = mode_info.bytes_per_scanline * mode_info.y_resolution;

    if (mode_info.phys_base_ptr <= 0xFFFFF) {
        error("Unsupported hardware configuration: Framebuffer in real-mode memory "
              "(physical base address = %Xh)", mode_info.phys_base_ptr);
        goto failure;
    }

    if (dpmi_map_physical_address(mode_info.phys_base_ptr,
                                  2 * gfx_mode_info.page_size,
                                  &gfx_framebuffer_address) != 0) {
        error("Mapping graphics card framebuffer to memory failed");
        goto failure;
    }

    if (vbe_set_display_start(0, 0, VBE_WAIT_FOR_RETRACE) != 0) {
        error("Setting display start failed");
        goto failure;
    }

    init_image(&gfx_buffer_1,
               gfx_mode_info.x_resolution,
               gfx_mode_info.y_resolution,
               (uint8_t *) gfx_framebuffer_address);

    init_image(&gfx_buffer_2,
               gfx_mode_info.x_resolution,
               gfx_mode_info.y_resolution,
               gfx_buffer_1.data + gfx_mode_info.page_size);

    gfx_front_buffer = &gfx_buffer_1;
    gfx_back_buffer = &gfx_buffer_2;

    gfx_check_refresh_rate();
    gfx_reset_clip_rect();

    return 0;

failure:

    gfx_exit();
    return -1;
}
示例#6
0
文件: vesa.c 项目: andrewbird/dosemu2
void do_vesa_int()
{
  int err_code = VBE_ERROR_GENERAL_FAIL;

#if 0
  v_printf(
    "VBE: function 0x%02x, bx = 0x%04x cx = 0x%04x, dx = 0x%04x, es = 0x%04x, di = 0x%04x\n",
    (unsigned) _AL, (unsigned) _BX, (unsigned) _CX, (unsigned) _DX, (unsigned) _ES, (unsigned) _DI
  );
#endif

  switch(_AL) {
    case 0x00:		/* return VBE controller info */
      err_code = vbe_info(SEGOFF2LINEAR(_ES, _DI));
      break;

    case 0x01:		/* return VBE mode info */
      err_code = vbe_mode_info(_CX, SEGOFF2LINEAR(_ES, _DI));
      break;

    case 0x02:		/* set VBE mode */
      err_code = vbe_set_mode(_BX);
      break;

    case 0x03:		/* get current VBE mode */
      err_code = vbe_get_mode();
      break;

    case 0x04:		/* save/restore state */
      err_code = vbe_save_restore(_DL, _CX, SEGOFF2LINEAR(_ES, _BX));
      break;

    case 0x05:		/* display window control (aka set/get bank) */
      err_code = vbe_display_window(_BH, _BL, _DL /* must be _DX !!!*/);
      break;

    case 0x06:		/* set/get logical scan line length */
      err_code = vbe_scan_length(_BL, _CX);
      break;

    case 0x07:		/* set/get display start */
      err_code = vbe_display_start(_BL, _CX, _DX);
      break;

    case 0x08:		/* set/get DAC palette format */
      err_code = vbe_dac_format(_BL, _BH);
      break;

    case 0x09:		/* set/get palette data */
      err_code = vbe_palette_data(_BL, _CX, _DX, SEGOFF2LINEAR(_ES, _DI));
      break;

    case 0x0a:		/* return VBE PM interface */
      err_code = vbe_pm_interface(_BL);
      break;

    case 0x10:		/* set/get display power state */
      err_code = vbe_power_state(_BL, _BH);
      break;

    default:
      err_code = VBE_ERROR_UNSUP;
#ifdef DEBUG_VBE
      v_printf(
        "VBE: unsupported function 0x%02x, retval = %d, bx = 0x%04x cx = 0x%04x, dx = 0x%04x, es = 0x%04x, di = 0x%04x\n",
        (unsigned) _AL, err_code, (unsigned) _BX, (unsigned) _CX, (unsigned) _DX, (unsigned) _ES, (unsigned) _DI
      );
#endif
  }

 if(err_code >= 0) {
   _AL = 0x4f;
   _AH = (unsigned char) err_code;
 }
}
示例#7
0
void isr_exception_handler(struct regs *r)
{
//Check if it is an exception
    if (r->int_no < 32)
    {

    /*
    //Red screen of death!
        video_setdriver(video_vgatext_getdriver(),0);
        cli_setrect(0);
        cli_settextcolour(0x4F);cli_cls();
        cli_positioncursor(0,0);
        cli_puts("An exception has occurred.\nException: (");
        cli_putu32(r->int_no, 10);
        cli_puts(") - ");
        cli_puts(exception_messages[r->int_no]);
        cli_puts("\n\nSystem Halted.\n\n");

        //Put error code
        cli_puts("Technical Information:\n\nError Code:  ");
        cli_putu32(r->err_code,16);

        //Put registers
        cli_puts("\nRegs:        EAX: ");cli_putu32(r->eax,16);
        cli_puts("\n             EBX: ");cli_putu32(r->ebx,16);
        cli_puts("\n             ECX: ");cli_putu32(r->ecx,16);
        cli_puts("\n             EDX: ");cli_putu32(r->edx,16);

        cli_puts("\n             ESI: ");cli_putu32(r->esi,16);
        cli_puts("\n             EDI: ");cli_putu32(r->edi,16);

        cli_puts("\n             ESP: ");cli_putu32(r->esp,16);
        cli_puts("\n             EBP: ");cli_putu32(r->ebp,16);

        cli_puts("\n              CS: ");cli_putu32(r->cs,16);
        cli_puts("\n              DS: ");cli_putu32(r->ds,16);
        cli_puts("\n              ES: ");cli_putu32(r->es,16);
        cli_puts("\n              FS: ");cli_putu32(r->fs,16);
        cli_puts("\n              GS: ");cli_putu32(r->gs,16);
        cli_puts("\n              SS: ");cli_putu32(r->ss,16);

        cli_puts("\n             EIP: ");cli_putu32(r->eip,16);
	*/
        //Endless loop
        vbe_set_mode(0x3,0);
        console_error();
        console_puts_protected("\nAn exception has occurred.\nException: (0x");
        console_putu32_protected(r->err_code, 16);
        console_puts_protected(") - ");
        console_puts_protected(isr_exception_messages[r->int_no]);
        console_puts_protected("\n\nSystem Halted.\n\n");

        //Put error code
        console_puts_protected("Technical Information:\n\nError Code:  ");
        console_putu32_protected(r->err_code,16);

        //Put registers
        console_puts_protected("\nRegs:        EAX: 0x");console_putu32_protected(r->eax,16);
        console_puts_protected("\n             EBX: 0x");console_putu32_protected(r->ebx,16);
        console_puts_protected("\n             ECX: 0x");console_putu32_protected(r->ecx,16);
        console_puts_protected("\n             EDX: 0x");console_putu32_protected(r->edx,16);

        console_puts_protected("\n             ESI: 0x");console_putu32_protected(r->esi,16);
        console_puts_protected("\n             EDI: 0x");console_putu32_protected(r->edi,16);

        console_puts_protected("\n             ESP: 0x");console_putu32_protected(r->esp,16);
        console_puts_protected("\n             EBP: 0x");console_putu32_protected(r->ebp,16);

        console_puts_protected("\n              CS: 0x");console_putu32_protected(r->cs,16);
        console_puts_protected("\n              DS: 0x");console_putu32_protected(r->ds,16);
        console_puts_protected("\n              ES: 0x");console_putu32_protected(r->es,16);
        console_puts_protected("\n              FS: 0x");console_putu32_protected(r->fs,16);
        console_puts_protected("\n              GS: 0x");console_putu32_protected(r->gs,16);
        console_puts_protected("\n              SS: 0x");console_putu32_protected(r->ss,16);

        console_puts_protected("\n             EIP: 0x");console_putu32_protected(r->eip,16);

        for(;;)
            __asm__ __volatile__ ("hlt");
    }
}