Deprecate VESA support.
This is in favor of bootloader-assisted mode switching. Grub has a wonderful option we will exploit to set the video mode. My laptop supports a couple of 32-bit video modes, which is nice, because I'm not support 24-bit modes. I'm not sure whether the super-sketchy video memory locator will work in the real world, but we'll find out sometime soon.
This commit is contained in:
parent
8dec80deb9
commit
5ce042f2d8
32
README.md
32
README.md
@ -181,38 +181,6 @@ ToAruOS contains additional software with the following copyright notices:
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* The real-mode 8086 emulation provided for VESA support is distributed under the following license:
|
||||
|
||||
Copyright 2010 John Hodge (thePowersGang). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation
|
||||
are those of the authors and should not be interpreted as representing
|
||||
official policies, either expressed or implied, of the author.
|
||||
|
||||
* As of January 23, 2012, the repository also contains the [DejaVu fonts](http://dejavu-fonts.org/wiki/Main_Page) package, which is a set of public-domain modifications of the Bitstream Vera font set, which is released under this license:
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream
|
||||
|
@ -297,7 +297,7 @@ extern int detect_cpu();
|
||||
/* Video Drivers */
|
||||
/* BOCHS / QEMU VBE Driver */
|
||||
extern void graphics_install_bochs(uint16_t, uint16_t);
|
||||
extern void graphics_install_vesa(uint16_t x, uint16_t y);
|
||||
extern void graphics_install_preset(uint16_t, uint16_t);
|
||||
extern void bochs_set_csr(int x, int y);
|
||||
extern int bochs_get_csr_x();
|
||||
extern int bochs_get_csr_y();
|
||||
|
@ -1,45 +0,0 @@
|
||||
#ifndef VESA_H
|
||||
#define VESA_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t Offset;
|
||||
uint16_t Segment;
|
||||
} t_farptr;
|
||||
|
||||
struct VesaControllerInfo {
|
||||
char Signature[4]; // == "VBE2"
|
||||
uint16_t Version; // == 0x0300 for Vesa 3.0
|
||||
t_farptr OemString; // isa vbeFarPtr
|
||||
uint8_t Capabilities[4];
|
||||
t_farptr Videomodes; // isa vbeParPtr
|
||||
uint16_t TotalMemory;// as # of 64KB blocks
|
||||
};
|
||||
|
||||
struct VesaModeInfo {
|
||||
uint16_t attributes;
|
||||
uint8_t winA, winB;
|
||||
uint16_t granularity;
|
||||
uint16_t winsize;
|
||||
uint16_t segmentA, segmentB;
|
||||
t_farptr realFctPtr;
|
||||
uint16_t pitch; // bytes per scanline
|
||||
|
||||
uint16_t Xres, Yres;
|
||||
uint8_t Wchar, Ychar, planes, bpp, banks;
|
||||
uint8_t memory_model, bank_size, image_pages;
|
||||
uint8_t reserved0;
|
||||
|
||||
uint8_t red_mask, red_position;
|
||||
uint8_t green_mask, green_position;
|
||||
uint8_t blue_mask, blue_position;
|
||||
uint8_t rsv_mask, rsv_position;
|
||||
uint8_t directcolor_attributes;
|
||||
|
||||
uint32_t physbase; // your LFB address ;)
|
||||
uint32_t reserved1;
|
||||
uint16_t reserved2;
|
||||
};
|
||||
#endif
|
||||
|
@ -69,8 +69,8 @@ parse_args(
|
||||
if (!strcmp(argp[1],"qemu")) {
|
||||
/* Bochs / Qemu Video Device */
|
||||
graphics_install_bochs(x,y);
|
||||
} else if (!strcmp(argp[1],"vesa")) {
|
||||
graphics_install_vesa(x,y);
|
||||
} else if (!strcmp(argp[1],"preset")) {
|
||||
graphics_install_preset(x,y);
|
||||
} else {
|
||||
kprintf("Unrecognized video adapter: %s\n", argp[1]);
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
Copyright 2010 John Hodge (thePowersGang). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those of the
|
||||
authors and should not be interpreted as representing official policies, either expressed
|
||||
or implied, of the author.
|
2420
kernel/v8086/rme.c
2420
kernel/v8086/rme.c
File diff suppressed because it is too large
Load Diff
@ -1,329 +0,0 @@
|
||||
/*
|
||||
* Realmode Emulator Plugin
|
||||
* - By John Hodge (thePowersGang)
|
||||
*
|
||||
* This code is published under the FreeBSD licence
|
||||
* (See the file COPYING for details)
|
||||
*
|
||||
* ---
|
||||
* Core Emulator Include
|
||||
*/
|
||||
#ifndef _RME_H_
|
||||
#define _RME_H_
|
||||
|
||||
/**
|
||||
* \file rme.h
|
||||
* \brief Realmode Emulator Header
|
||||
* \author John Hodge (thePowersGang)
|
||||
*
|
||||
* \section using Using RME
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Enable the use of size overrides
|
||||
* \note Disabling this will speed up emulation, but may cause undefined
|
||||
* behavior with some BIOSes.
|
||||
*
|
||||
* If set to -1, size overrides will cause a \#UD
|
||||
*/
|
||||
#define USE_SIZE_OVERRIDES 0
|
||||
|
||||
/**
|
||||
* \brief Size of a memory block
|
||||
* \note Feel free to edit this value, just make sure it stays a power
|
||||
* of two.
|
||||
*/
|
||||
#define RME_BLOCK_SIZE 0x1000
|
||||
|
||||
/**
|
||||
* \brief Magic return Instruction Pointer
|
||||
*/
|
||||
#define RME_MAGIC_IP 0xFFFF
|
||||
/**
|
||||
* \brief Magic return Code Segment
|
||||
*/
|
||||
#define RME_MAGIC_CS 0xFFFF
|
||||
|
||||
/**
|
||||
* \brief Error codes returned by ::RME_Call and ::RME_CallInt
|
||||
*/
|
||||
enum eRME_Errors
|
||||
{
|
||||
RME_ERR_OK, //!< Exited successfully
|
||||
RME_ERR_INVAL, //!< Bad paramater passed to emulator
|
||||
RME_ERR_BADMEM, //!< Emulator accessed invalid memory
|
||||
RME_ERR_UNDEFOPCODE, //!< Undefined opcode
|
||||
RME_ERR_DIVERR, //!< Divide error
|
||||
RME_ERR_BUG, //!< Bug in the emulator
|
||||
|
||||
RME_ERR_LAST //!< Last Error
|
||||
};
|
||||
|
||||
typedef union uGPR
|
||||
{
|
||||
#if USE_SIZE_OVERRIDES == 1
|
||||
uint32_t D;
|
||||
#endif
|
||||
uint16_t W;
|
||||
struct {
|
||||
uint8_t L;
|
||||
uint8_t H;
|
||||
} B;
|
||||
} tGPR;
|
||||
|
||||
/**
|
||||
* \brief Emulator state structure
|
||||
*/
|
||||
typedef struct sRME_State
|
||||
{
|
||||
//! \brief General Purpose Registers
|
||||
//! \{
|
||||
tGPR AX, CX, DX, BX, SP, BP, SI, DI;
|
||||
|
||||
//! \}
|
||||
|
||||
//! \brief Segment Registers
|
||||
//! \{
|
||||
uint16_t SS; //!< Stack Segment
|
||||
uint16_t DS; //!< Data Segment
|
||||
uint16_t ES; //!< Extra Segment
|
||||
//! \}
|
||||
|
||||
//! \brief Program Counter
|
||||
//! \{
|
||||
uint16_t CS; //!< Code Segment
|
||||
uint16_t IP; //!< Instruction Pointer
|
||||
//! \}
|
||||
|
||||
uint16_t Flags; //!< State Flags
|
||||
|
||||
/**
|
||||
* \brief Emulator's Memory
|
||||
*
|
||||
* The ~1MiB realmode address space is broken into blocks of
|
||||
* ::RME_BLOCK_SIZE bytes that can each point to different areas
|
||||
* of memory.
|
||||
* NOTE: There is no write protection on these blocks
|
||||
* \note A value of NULL in a block indicates that the block is invalid
|
||||
* \note 0x110000 bytes is all that is accessable using the realmode
|
||||
* segmentation scheme (true max is 0xFFFF0+0xFFFF = 0x10FFEF)
|
||||
*/
|
||||
uint8_t *Memory[0x110000/RME_BLOCK_SIZE]; // 1Mib,64KiB in 256 4 KiB blocks
|
||||
|
||||
/**
|
||||
* \brief High-Level Emulation Callback
|
||||
* \param State Emulation state at the interrupt
|
||||
* \param IntNum Interrupt number
|
||||
* \return 1 if the call was handled, 0 if it should be emulated
|
||||
*
|
||||
* Called on all in-emulator INT calls
|
||||
*/
|
||||
int (*HLECallbacks[256])(struct sRME_State *State, int IntNum);
|
||||
|
||||
int InstrNum; //!< Total executed instructions
|
||||
|
||||
// --- Decoder State ---
|
||||
/**
|
||||
* \brief Decoder State
|
||||
* \note Should not be touched except by the emulator
|
||||
*/
|
||||
struct {
|
||||
int OverrideSegment;
|
||||
int bOverrideOperand;
|
||||
int bOverrideAddress;
|
||||
int IPOffset;
|
||||
} Decoder;
|
||||
} tRME_State;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Creates a blank RME instance
|
||||
*/
|
||||
extern tRME_State *RME_CreateState(void);
|
||||
|
||||
/**
|
||||
* \brief Calls an interrupt
|
||||
* \param State State returned from ::RME_CreateState
|
||||
* \param Num Interrupt number
|
||||
*/
|
||||
extern int RME_CallInt(tRME_State *State, int Num);
|
||||
|
||||
/**
|
||||
* \brief Executes the emulator until RME_MAGIC_CS:RME_MAGIC_IP is reached
|
||||
* \param State State returned from ::RME_CreateState
|
||||
*/
|
||||
extern int RME_Call(tRME_State *State);
|
||||
|
||||
/**
|
||||
* \brief Prints contents of the state's registers to debug
|
||||
* \param State State returned from ::RME_CreateState
|
||||
*/
|
||||
extern void RME_DumpRegs(tRME_State *State);
|
||||
|
||||
/*
|
||||
* Definitions specific to the internals of the emulator
|
||||
*/
|
||||
#ifdef _RME_C_
|
||||
|
||||
/**
|
||||
*/
|
||||
enum gpRegs
|
||||
{
|
||||
AL, CL, DL, BL,
|
||||
AH, CH, DH, BH
|
||||
};
|
||||
|
||||
enum sRegs
|
||||
{
|
||||
SREG_ES,
|
||||
SREG_CS,
|
||||
SREG_SS,
|
||||
SREG_DS
|
||||
};
|
||||
|
||||
#define OPCODE_RI(name, code) name##_RI_AL = code|AL, name##_RI_BL = code|BL,\
|
||||
name##_RI_CL = code|CL, name##_RI_DL = code|DL,\
|
||||
name##_RI_AH = code|AH, name##_RI_BH = code|BH,\
|
||||
name##_RI_CH = code|CH, name##_RI_DH = code|DH,\
|
||||
name##_RI_AX = code|AL|8, name##_RI_BX = code|BL|8,\
|
||||
name##_RI_CX = code|CL|8, name##_RI_DX = code|DL|8,\
|
||||
name##_RI_SP = code|AH|8, name##_RI_BP = code|CH|8,\
|
||||
name##_RI_SI = code|DH|8, name##_RI_DI = code|BH|8
|
||||
|
||||
enum opcodes {
|
||||
ADD_MR = 0x00, ADD_MRX = 0x01,
|
||||
ADD_RM = 0x02, ADD_RMX = 0x03,
|
||||
ADD_AI = 0x04, ADD_AIX = 0x05,
|
||||
|
||||
OR_MR = 0x08, OR_MRX = 0x09,
|
||||
OR_RM = 0x0A, OR_RMX = 0x0B,
|
||||
OR_AI = 0x0C, OR_AIX = 0x0D,
|
||||
|
||||
AND_MR = 0x20, AND_MRX = 0x21,
|
||||
AND_RM = 0x22, AND_RMX = 0x23,
|
||||
AND_AI = 0x24, AND_AIX = 0x25,
|
||||
|
||||
SUB_MR = 0x28, SUB_MRX = 0x29,
|
||||
SUB_RM = 0x2A, SUB_RMX = 0x2B,
|
||||
SUB_AI = 0x2C, SUB_AIX = 0x2D,
|
||||
|
||||
XOR_MR = 0x30, XOR_MRX = 0x31,
|
||||
XOR_RM = 0x32, XOR_RMX = 0x33,
|
||||
XOR_AI = 0x34, XOR_AIX = 0x35,
|
||||
|
||||
CMP_MR = 0x38, CMP_MRX = 0x39,
|
||||
CMP_RM = 0x3A, CMP_RMX = 0x3B,
|
||||
CMP_AI = 0x3C, CMP_AIX = 0x3D,
|
||||
|
||||
DEC_A = 0x48|AL, DEC_B = 0x48|BL,
|
||||
DEC_C = 0x48|CL, DEC_D = 0x48|DL,
|
||||
DEC_Sp = 0x48|AH, DEC_Bp = 0x48|CH,
|
||||
DEC_Si = 0x48|DH, DEC_Di = 0x48|BH,
|
||||
|
||||
INC_A = 0x40|AL, INC_B = 0x40|BL,
|
||||
INC_C = 0x40|CL, INC_D = 0x40|DL,
|
||||
INC_Sp = 0x40|AH, INC_Bp = 0x40|CH,
|
||||
INC_Si = 0x40|DH, INC_Di = 0x40|BH,
|
||||
|
||||
DIV_R = 0xFA, DIV_RX = 0xFB,
|
||||
DIV_M = 0xFA, DIV_MX = 0xFB,
|
||||
|
||||
|
||||
INT3 = 0xCC, INT_I = 0xCD,
|
||||
IRET = 0xCF,
|
||||
|
||||
MOV_MoA = 0xA2, MOV_MoAX = 0xA3,
|
||||
MOV_AMo = 0xA0, MOV_AMoX = 0xA1,
|
||||
OPCODE_RI(MOV, 0xB0),
|
||||
MOV_MI = 0xC6, MOV_MIX = 0xC7,
|
||||
MOV_MR = 0x88, MOV_MRX = 0x89,
|
||||
MOV_RM = 0x8A, MOV_RMX = 0x8B,
|
||||
MOV_RS = 0x8C, MOV_SR = 0x8E,
|
||||
MOV_MS = 0x8C, MOV_SM = 0x8E,
|
||||
|
||||
MUL_R = 0xF6, MUL_RX = 0xF7,
|
||||
MUL_M = 0xF6, MUL_MX = 0xF7,
|
||||
|
||||
NOP = 0x90,
|
||||
XCHG_AA = 0x90, XCHG_AB = 0x90|BL,
|
||||
XCHG_AC = 0x90|CL, XCHG_AD = 0x90|DL,
|
||||
XCHG_ASp = 0x90|AH, XCHG_ABp = 0x90|CH,
|
||||
XCHG_ASi = 0x90|DH, XCHG_ADi = 0x90|BH,
|
||||
XCHG_RM = 0x86,
|
||||
|
||||
NOT_R = 0xF6, NOT_RX = 0xF7,
|
||||
NOT_M = 0xF6, NOT_MX = 0xF7,
|
||||
|
||||
|
||||
IN_AI = 0xE4, IN_AIX = 0xE5,
|
||||
IN_ADx = 0xEC, IN_ADxX = 0xED,
|
||||
OUT_IA = 0xE6, OUT_IAX = 0xE7,
|
||||
OUT_DxA = 0xEE, OUT_DxAX = 0xEF,
|
||||
|
||||
POP_AX = 0x58|AL, POP_BX = 0x58|BL,
|
||||
POP_CX = 0x58|CL, POP_DX = 0x58|DL,
|
||||
POP_SP = 0x58|AH, POP_BP = 0x58|CH,
|
||||
POP_SI = 0x58|DH, POP_DI = 0x58|BH,
|
||||
POP_ES = 7|(SREG_ES<<3),
|
||||
POP_SS = 7|(SREG_SS<<3), POP_DS = 7|(SREG_DS<<3),
|
||||
POP_MX = 0x8F,
|
||||
POPA = 0x61, POPF = 0x9D,
|
||||
|
||||
PUSH_AX = 0x50|AL, PUSH_BX = 0x50|BL,
|
||||
PUSH_CX = 0x50|CL, PUSH_DX = 0x50|DL,
|
||||
PUSH_SP = 0x50|AH, PUSH_BP = 0x50|CH,
|
||||
PUSH_SI = 0x50|DH, PUSH_DI = 0x50|BH,
|
||||
// PUSH_MX = 0xFF, // - TODO: Check (maybe 0x87)
|
||||
PUSH_ES = 6|(SREG_ES<<3), PUSH_CS = 6|(SREG_CS<<3),
|
||||
PUSH_SS = 6|(SREG_SS<<3), PUSH_DS = 6|(SREG_DS<<3),
|
||||
PUSH_I8 = 0x6A, PUSH_I = 0x68,
|
||||
PUSHA = 0x60, PUSHF = 0x9C,
|
||||
|
||||
RET_N = 0xC3, RET_iN = 0xC2,
|
||||
RET_F = 0xCB, RET_iF = 0xCA,
|
||||
|
||||
CALL_MF = 0xFF, CALL_MN = 0xFF,
|
||||
CALL_N = 0xE8, CALL_F = 0x9A,
|
||||
CALL_R = 0xFF,
|
||||
|
||||
JMP_MF = 0xFF, JMP_N = 0xE9,
|
||||
JMP_S = 0xEB, JMP_F = 0xEA,
|
||||
|
||||
LES = 0xC4,
|
||||
LDS = 0xC5,
|
||||
LEA = 0x8D,
|
||||
|
||||
CLC = 0xF8, STC = 0xF9,
|
||||
CLI = 0xFA, STI = 0xFB,
|
||||
CLD = 0xFC, STD = 0xFD,
|
||||
|
||||
TEST_RM = 0x84, TEST_RMX = 0x85,
|
||||
TEST_AI = 0xA8, TEST_AIX = 0xA9,
|
||||
|
||||
MOVSB = 0xA4, MOVSW = 0xA5,
|
||||
CMPSB = 0xA6, CMPSW = 0xA7,
|
||||
STOSB = 0xAA, STOSW = 0xAB,
|
||||
LODSB = 0xAC, LODSW = 0xAD,
|
||||
SCASB = 0xAE, SCASW = 0xAF,
|
||||
INSB = 0x6C, INSW = 0x6D,
|
||||
OUTSB = 0x6E, OUTSW = 0x6F,
|
||||
|
||||
// --- Unimplementeds
|
||||
FPU_ARITH = 0xDC,
|
||||
|
||||
// --- Overrides
|
||||
OVR_ES = 0x26,
|
||||
OVR_CS = 0x2E,
|
||||
OVR_SS = 0x36,
|
||||
OVR_DS = 0x3E,
|
||||
|
||||
REPNZ = 0xF2, REP = 0xF3,
|
||||
LOOPNZ = 0xE0, LOOPZ = 0xE1,
|
||||
LOOP = 0xE2
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,256 +0,0 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*
|
||||
* Bochs VBE / QEMU vga=std Graphics Driver
|
||||
*/
|
||||
|
||||
#include <system.h>
|
||||
#include <fs.h>
|
||||
#include <types.h>
|
||||
#include <vesa.h>
|
||||
#include <logging.h>
|
||||
|
||||
#define PROMPT_FOR_MODE 0
|
||||
|
||||
/* Friggin' frick, this should be a config option
|
||||
* because it's 4096 on some instances of Qemu,
|
||||
* ie the one on my laptop, but it's 2048 on
|
||||
* the EWS machines. */
|
||||
#define BOCHS_BUFFER_SIZE 2048
|
||||
#define PREFERRED_VY 4096
|
||||
#define PREFERRED_B 32
|
||||
|
||||
uint16_t bochs_resolution_x = 0;
|
||||
uint16_t bochs_resolution_y = 0;
|
||||
uint16_t bochs_resolution_b = 0;
|
||||
|
||||
/*
|
||||
* Address of the linear frame buffer.
|
||||
* This can move, so it's a pointer instead of
|
||||
* #define.
|
||||
*/
|
||||
uint8_t * bochs_vid_memory = (uint8_t *)0xE0000000;
|
||||
|
||||
uintptr_t current_scroll = 0;
|
||||
|
||||
void
|
||||
bochs_set_y_offset(uint16_t y) {
|
||||
outports(0x1CE, 0x9);
|
||||
outports(0x1CF, y);
|
||||
current_scroll = y;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
bochs_current_scroll() {
|
||||
return current_scroll;
|
||||
}
|
||||
|
||||
uintptr_t
|
||||
bochs_get_address() {
|
||||
return (uintptr_t)bochs_vid_memory;
|
||||
}
|
||||
|
||||
static void finalize_graphics(uint16_t x, uint16_t y, uint16_t b) {
|
||||
bochs_resolution_x = x;
|
||||
bochs_resolution_y = y;
|
||||
bochs_resolution_b = b;
|
||||
}
|
||||
|
||||
void
|
||||
graphics_install_bochs(uint16_t resolution_x, uint16_t resolution_y) {
|
||||
blog("Setting up BOCHS/QEMU graphics controller...");
|
||||
outports(0x1CE, 0x00);
|
||||
uint16_t i = inports(0x1CF);
|
||||
if (i < 0xB0C0 || i > 0xB0C6) {
|
||||
return;
|
||||
}
|
||||
outports(0x1CF, 0xB0C4);
|
||||
i = inports(0x1CF);
|
||||
/* Disable VBE */
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x00);
|
||||
/* Set X resolution to 1024 */
|
||||
outports(0x1CE, 0x01);
|
||||
outports(0x1CF, resolution_x);
|
||||
/* Set Y resolution to 768 */
|
||||
outports(0x1CE, 0x02);
|
||||
outports(0x1CF, resolution_y);
|
||||
/* Set bpp to 32 */
|
||||
outports(0x1CE, 0x03);
|
||||
outports(0x1CF, PREFERRED_B);
|
||||
/* Set Virtual Height to stuff */
|
||||
outports(0x1CE, 0x07);
|
||||
outports(0x1CF, PREFERRED_VY);
|
||||
/* Re-enable VBE */
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x41);
|
||||
|
||||
/* XXX: Massive hack */
|
||||
uint32_t * text_vid_mem = (uint32_t *)0xA0000;
|
||||
text_vid_mem[0] = 0xA5ADFACE;
|
||||
|
||||
for (uintptr_t fb_offset = 0xE0000000; fb_offset < 0xFF000000; fb_offset += 0x01000000) {
|
||||
/* Enable the higher memory */
|
||||
for (uintptr_t i = fb_offset; i <= fb_offset + 0xFF0000; i += 0x1000) {
|
||||
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
|
||||
}
|
||||
|
||||
/* Go find it */
|
||||
for (uintptr_t x = fb_offset; x < fb_offset + 0xFF0000; x += 0x1000) {
|
||||
if (((uintptr_t *)x)[0] == 0xA5ADFACE) {
|
||||
bochs_vid_memory = (uint8_t *)x;
|
||||
goto mem_found;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mem_found:
|
||||
finalize_graphics(resolution_x, resolution_y, PREFERRED_B);
|
||||
bfinish(0);
|
||||
}
|
||||
|
||||
#include "../v8086/rme.h"
|
||||
|
||||
void
|
||||
graphics_install_vesa(uint16_t x, uint16_t y) {
|
||||
blog("Setting up VESA video controller...");
|
||||
|
||||
/* VESA Structs */
|
||||
struct VesaControllerInfo *info = (void*)0x10000;
|
||||
struct VesaModeInfo *modeinfo = (void*)0x9000;
|
||||
|
||||
/* 8086 Emulator Status */
|
||||
tRME_State *emu;
|
||||
void * lowCache;
|
||||
lowCache = malloc(RME_BLOCK_SIZE);
|
||||
memcpy(lowCache, NULL, RME_BLOCK_SIZE);
|
||||
emu = RME_CreateState();
|
||||
emu->Memory[0] = lowCache;
|
||||
for (int i = RME_BLOCK_SIZE; i < 0x100000; i += RME_BLOCK_SIZE) {
|
||||
emu->Memory[i/RME_BLOCK_SIZE] = (void*)i;
|
||||
}
|
||||
int ret, mode;
|
||||
|
||||
/* Find modes */
|
||||
uint16_t * modes;
|
||||
memcpy(info->Signature, "VBE2", 4);
|
||||
emu->AX.W = 0x4F00;
|
||||
emu->ES = 0x1000;
|
||||
emu->DI.W = 0;
|
||||
ret = RME_CallInt(emu, 0x10);
|
||||
if (info->Version < 0x200 || info->Version > 0x300) {
|
||||
bfinish(2);
|
||||
kprintf("\033[JYou have attempted to use the VESA/VBE2 driver\nwith a card that does not support VBE2.\n");
|
||||
kprintf("\nSystem responded to VBE request with version: 0x%x\n", info->Version);
|
||||
|
||||
STOP;
|
||||
}
|
||||
modes = (void*)FP_TO_LINEAR(info->Videomodes.Segment,info->Videomodes.Offset);
|
||||
|
||||
uint16_t best_x = 0;
|
||||
uint16_t best_y = 0;
|
||||
uint16_t best_b = 0;
|
||||
uint16_t best_mode = 0;
|
||||
|
||||
for (int i = 1; modes[i] != 0xFFFF; ++i) {
|
||||
emu->AX.W = 0x4F01;
|
||||
emu->CX.W = modes[i];
|
||||
emu->ES = 0x0900;
|
||||
emu->DI.W = 0x0000;
|
||||
RME_CallInt(emu, 0x10);
|
||||
#if PROMPT_FOR_MODE
|
||||
kprintf("%d = %dx%d:%d\n", i, modeinfo->Xres, modeinfo->Yres, modeinfo->bpp);
|
||||
}
|
||||
|
||||
kprintf("Please select a mode: ");
|
||||
char buf[10];
|
||||
kgets(buf, 10);
|
||||
mode = atoi(buf);
|
||||
#else
|
||||
if ((abs(modeinfo->Xres - x) < abs(best_x - x)) && (abs(modeinfo->Yres - y) < abs(best_y - y))) {
|
||||
best_mode = i;
|
||||
best_x = modeinfo->Xres;
|
||||
best_y = modeinfo->Yres;
|
||||
best_b = modeinfo->bpp;
|
||||
}
|
||||
}
|
||||
for (int i = 1; modes[i] != 0xFFFF; ++i) {
|
||||
emu->AX.W = 0x4F01;
|
||||
emu->CX.W = modes[i];
|
||||
emu->ES = 0x0900;
|
||||
emu->DI.W = 0x0000;
|
||||
RME_CallInt(emu, 0x10);
|
||||
if (modeinfo->Xres == best_x && modeinfo->Yres == best_y) {
|
||||
if (modeinfo->bpp > best_b) {
|
||||
best_mode = i;
|
||||
best_b = modeinfo->bpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_b < 24) {
|
||||
kprintf("!!! Rendering at this bit depth (%d) is not currently supported.\n", best_b);
|
||||
STOP;
|
||||
}
|
||||
|
||||
|
||||
mode = best_mode;
|
||||
|
||||
#endif
|
||||
|
||||
emu->AX.W = 0x4F01;
|
||||
if (mode < 100) {
|
||||
emu->CX.W = modes[mode];
|
||||
} else {
|
||||
emu->CX.W = mode;
|
||||
}
|
||||
emu->ES = 0x0900;
|
||||
emu->DI.W = 0x0000;
|
||||
RME_CallInt(emu, 0x10);
|
||||
|
||||
emu->AX.W = 0x4F02;
|
||||
emu->BX.W = modes[mode];
|
||||
RME_CallInt(emu, 0x10);
|
||||
|
||||
uint16_t actual_x = modeinfo->Xres;
|
||||
uint16_t actual_y = modeinfo->Yres;
|
||||
uint16_t actual_b = modeinfo->bpp;
|
||||
|
||||
bochs_vid_memory = (uint8_t *)modeinfo->physbase;
|
||||
|
||||
if (!bochs_vid_memory) {
|
||||
uint32_t * herp = (uint32_t *)0xA0000;
|
||||
herp[0] = 0xA5ADFACE;
|
||||
|
||||
/* Enable the higher memory */
|
||||
for (uintptr_t i = 0xE0000000; i <= 0xE0FF0000; i += 0x1000) {
|
||||
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
|
||||
}
|
||||
for (uintptr_t i = 0xF0000000; i <= 0xF0FF0000; i += 0x1000) {
|
||||
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
|
||||
}
|
||||
|
||||
|
||||
/* Go find it */
|
||||
for (uintptr_t x = 0xE0000000; x < 0xE0FF0000; x += 0x1000) {
|
||||
if (((uintptr_t *)x)[0] == 0xA5ADFACE) {
|
||||
bochs_vid_memory = (uint8_t *)x;
|
||||
goto mem_found;
|
||||
}
|
||||
}
|
||||
for (uintptr_t x = 0xF0000000; x < 0xF0FF0000; x += 0x1000) {
|
||||
if (((uintptr_t *)x)[0] == 0xA5ADFACE) {
|
||||
bochs_vid_memory = (uint8_t *)x;
|
||||
goto mem_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
mem_found:
|
||||
|
||||
/*
|
||||
* Finalize the graphics setup with the actual selected resolution.
|
||||
*/
|
||||
finalize_graphics(actual_x, actual_y, actual_b);
|
||||
bfinish(0);
|
||||
}
|
||||
|
132
kernel/video/lfb.c
Normal file
132
kernel/video/lfb.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*
|
||||
* Bochs VBE / QEMU vga=std Graphics Driver
|
||||
*/
|
||||
|
||||
#include <system.h>
|
||||
#include <fs.h>
|
||||
#include <types.h>
|
||||
#include <logging.h>
|
||||
|
||||
#define PREFERRED_VY 4096
|
||||
#define PREFERRED_B 32
|
||||
|
||||
uint16_t bochs_resolution_x = 0;
|
||||
uint16_t bochs_resolution_y = 0;
|
||||
uint16_t bochs_resolution_b = 0;
|
||||
|
||||
/*
|
||||
* Address of the linear frame buffer.
|
||||
* This can move, so it's a pointer instead of
|
||||
* #define.
|
||||
*/
|
||||
uint8_t * bochs_vid_memory = (uint8_t *)0xE0000000;
|
||||
|
||||
uintptr_t current_scroll = 0;
|
||||
|
||||
void
|
||||
bochs_set_y_offset(uint16_t y) {
|
||||
outports(0x1CE, 0x9);
|
||||
outports(0x1CF, y);
|
||||
current_scroll = y;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
bochs_current_scroll() {
|
||||
return current_scroll;
|
||||
}
|
||||
|
||||
uintptr_t
|
||||
bochs_get_address() {
|
||||
return (uintptr_t)bochs_vid_memory;
|
||||
}
|
||||
|
||||
static void finalize_graphics(uint16_t x, uint16_t y, uint16_t b) {
|
||||
bochs_resolution_x = x;
|
||||
bochs_resolution_y = y;
|
||||
bochs_resolution_b = b;
|
||||
}
|
||||
|
||||
void
|
||||
graphics_install_bochs(uint16_t resolution_x, uint16_t resolution_y) {
|
||||
blog("Setting up BOCHS/QEMU graphics controller...");
|
||||
outports(0x1CE, 0x00);
|
||||
uint16_t i = inports(0x1CF);
|
||||
if (i < 0xB0C0 || i > 0xB0C6) {
|
||||
return;
|
||||
}
|
||||
outports(0x1CF, 0xB0C4);
|
||||
i = inports(0x1CF);
|
||||
/* Disable VBE */
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x00);
|
||||
/* Set X resolution to 1024 */
|
||||
outports(0x1CE, 0x01);
|
||||
outports(0x1CF, resolution_x);
|
||||
/* Set Y resolution to 768 */
|
||||
outports(0x1CE, 0x02);
|
||||
outports(0x1CF, resolution_y);
|
||||
/* Set bpp to 32 */
|
||||
outports(0x1CE, 0x03);
|
||||
outports(0x1CF, PREFERRED_B);
|
||||
/* Set Virtual Height to stuff */
|
||||
outports(0x1CE, 0x07);
|
||||
outports(0x1CF, PREFERRED_VY);
|
||||
/* Re-enable VBE */
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x41);
|
||||
|
||||
/* XXX: Massive hack */
|
||||
uint32_t * text_vid_mem = (uint32_t *)0xA0000;
|
||||
text_vid_mem[0] = 0xA5ADFACE;
|
||||
|
||||
for (uintptr_t fb_offset = 0xE0000000; fb_offset < 0xFF000000; fb_offset += 0x01000000) {
|
||||
/* Enable the higher memory */
|
||||
for (uintptr_t i = fb_offset; i <= fb_offset + 0xFF0000; i += 0x1000) {
|
||||
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
|
||||
}
|
||||
|
||||
/* Go find it */
|
||||
for (uintptr_t x = fb_offset; x < fb_offset + 0xFF0000; x += 0x1000) {
|
||||
if (((uintptr_t *)x)[0] == 0xA5ADFACE) {
|
||||
bochs_vid_memory = (uint8_t *)x;
|
||||
goto mem_found;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mem_found:
|
||||
finalize_graphics(resolution_x, resolution_y, PREFERRED_B);
|
||||
bfinish(0);
|
||||
}
|
||||
|
||||
void graphics_install_preset(uint16_t w, uint16_t h) {
|
||||
blog("Graphics were pre-configured (thanks, bootloader!), locating video memory...");
|
||||
uint16_t b = 32; /* If you are 24 bit, go away, we really do not support you. */
|
||||
|
||||
/* XXX: Massive hack */
|
||||
uint32_t * herp = (uint32_t *)0xA0000;
|
||||
herp[0] = 0xA5ADFACE;
|
||||
|
||||
for (uintptr_t fb_offset = 0xE0000000; fb_offset < 0xFF000000; fb_offset += 0x01000000) {
|
||||
/* Enable the higher memory */
|
||||
for (uintptr_t i = fb_offset; i <= fb_offset + 0xFF0000; i += 0x1000) {
|
||||
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
|
||||
}
|
||||
|
||||
/* Go find it */
|
||||
for (uintptr_t x = fb_offset; x < fb_offset + 0xFF0000; x += 0x1000) {
|
||||
if (((uintptr_t *)x)[0] == 0xA5ADFACE) {
|
||||
bochs_vid_memory = (uint8_t *)x;
|
||||
goto mem_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mem_found:
|
||||
finalize_graphics(w,h,b);
|
||||
bfinish(0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user