?? wuyao_avalon_lcd_controller.c
字號:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "wuyao_avalon_lcd_controller.h"
#include "io.h"
#include "sys/alt_alarm.h"
#include "sys/alt_cache.h"
#include "system.h"
#include "priv/alt_file.h"
// VGA device list (usualy just one)
ALT_LLIST_HEAD(vga_dev_list);
// General use buffer. Must only use locally
char fast_buffer[1024 * 3];
/******************************************************************
* Function: vga_dev_init
*
* Purpose: HAL device driver initialization.
* Called by alt_sys_init.
*
******************************************************************/
int vga_dev_init ( vga_controller_dev* vga )
{
int ret_code = 0;
ret_code = vga_device_register( &(vga->dev) );
return ret_code;
}
/******************************************************************
* Function: alt_vga_open_dev
*
* Purpose: Opens the VGA controller for use.
* Returns a file descriptor for the controller
*
******************************************************************/
alt_dev* alt_vga_open_dev(const char* name)
{
alt_dev* dev = (alt_dev*)alt_find_dev(name, &vga_dev_list);
return dev;
}
/******************************************************************
* Function: alt_vga_close_dev
*
* Purpose: Closes the VGA controller.
*
******************************************************************/
void alt_vga_close_dev(alt_dev* fd)
{
return;
}
/******************************************************************
* Function: vga_init_no_interrupt
*
* Purpose: Initializes the VGA controller for the Lancelot VGA
* daughterboard. Gets memory for the frame buffer, sets
* the resolution of the frame buffer, resets the VGA
* controller hardware, gives the controller the base
* address of the frame buffer, then enables
* the controller. Interrupts are NOT enabled.
*
******************************************************************/
vga_frame_buffer_struct* vga_init_no_interrupt ( vga_controller_dev* vga, int buffer_location)
{
vga_frame_buffer_struct* vga_frame_buffer;
int bytes_per_pixel, bytes_per_frame;
// We'll need these values more than once, so let's pre-calculate them.
bytes_per_pixel = vga->color_depth >> 3;
bytes_per_frame = (( vga->width * vga->height ) * bytes_per_pixel);
// Allocate our frame buffers
if( buffer_location == HEAP )
{
vga_frame_buffer = (vga_frame_buffer_struct*) alt_uncached_malloc(sizeof (vga_frame_buffer_struct));
vga_frame_buffer->vga_frame0 = (vga_frame_array*) alt_uncached_malloc(( bytes_per_frame ));
// If we're double-buffering, grab an extra buffer, if not, just make
// both pointers point to the same buffer.
if(vga->frame_buffers == 2)
{
vga_frame_buffer->vga_frame1 = (vga_frame_array*) alt_uncached_malloc(( bytes_per_frame ));
}
else
{
vga_frame_buffer->vga_frame1 = vga_frame_buffer->vga_frame0;
}
}
else
{
vga_frame_buffer = (vga_frame_buffer_struct*)buffer_location;
vga_frame_buffer->vga_frame0 = (vga_frame_array*)(buffer_location + sizeof(vga_frame_buffer_struct));
// If we're double-buffering, grab an extra buffer, if not, just make
// both pointers point to the same buffer.
if(vga->frame_buffers == 2)
{
vga_frame_buffer->vga_frame1 = (vga_frame_buffer->vga_frame0 + bytes_per_frame);
}
else
{
vga_frame_buffer->vga_frame1 = vga_frame_buffer->vga_frame0;
}
}
vga_frame_buffer->width = vga->width;
vga_frame_buffer->height = vga->height;
vga_frame_buffer->color_depth = vga->color_depth;
vga_frame_buffer->frame_buffers = vga->frame_buffers;
vga_frame_buffer->bytes_per_frame = bytes_per_frame;
vga_frame_buffer->bytes_per_pixel = (vga->color_depth / 8);
vga_frame_buffer->vga_controller_base = vga->base_addr;
//Clear all frame buffers to black
vga_clear_screen( vga_frame_buffer, BLACK_8 );
vga_flip_frame_buffers( vga_frame_buffer );
vga_clear_screen( vga_frame_buffer, BLACK_8 );
IOWR_32DIRECT( vga->base_addr, 0, 0x0 ); /* Reset the VGA controller */
IOWR_32DIRECT( vga->base_addr, 4, ( int )vga_frame_buffer->vga_frame0 ); /* Where our frame buffer starts */
IOWR_32DIRECT( vga->base_addr, 8, ( ( vga->width * vga->height ) * bytes_per_pixel ) ); /* amount of memory needed */
IOWR_32DIRECT( vga->base_addr, 0, 0x1 ); /* Set the go bit. */
return ( vga_frame_buffer );
}
int vga_flip_frame_buffers( vga_frame_buffer_struct* vga_frame_buffer )
{
vga_frame_array* temp_frame;
int ret_code;
if( vga_frame_buffer->frame_buffers == 2 )
{
temp_frame = vga_frame_buffer->vga_frame0;
vga_frame_buffer->vga_frame0 = vga_frame_buffer->vga_frame1;
vga_frame_buffer->vga_frame1 = temp_frame;
IOWR_32DIRECT( vga_frame_buffer->vga_controller_base, 4, ( int )vga_frame_buffer->vga_frame0 );
ret_code = 0;
}
else
{
ret_code = 1;
}
return(ret_code);
}
int vga_stop ( vga_controller_dev* vga )
{
IOWR_32DIRECT( vga->base_addr, 0, 0x0 ); /* Reset the VGA controller */
return (0);
}
void vga_scroll_string_quit(vga_text_scroll_struct* scroll)
{
free(scroll->string);
free(scroll);
}
vga_text_scroll_struct* vga_scroll_string_init(int hbegin, int vbegin, int hend, int f_color, int b_color, char* font, int ms_delay, char *string)
{
vga_text_scroll_struct* scroll;
scroll = malloc(sizeof (vga_text_scroll_struct));
scroll->hbegin = hbegin;
scroll->vbegin = vbegin;
scroll->hend = hend;
scroll->f_color = f_color;
scroll->b_color = b_color;
scroll->string = malloc(strlen(string)+2);
strcpy(scroll->string, string);
scroll->font = font;
scroll->ms_delay = ms_delay;
scroll->ticks_at_last_move = alt_nticks();
scroll->text_scroll_index = 0;
scroll->text_scroll_started = 0;
scroll->window_width = scroll->hend - scroll->hbegin;
scroll->length_of_string = strlen(string);
scroll->string_points = scroll->length_of_string * 8;
scroll->scroll_points = (scroll->window_width + scroll->string_points);
return(scroll);
}
int vga_scroll_string(vga_text_scroll_struct* scroll, vga_frame_buffer_struct* vga_frame_buffer)
{
int x_start, x_end, x_index, string_x_index, string_char_index, char_row, char_column;
char character, column_mask;
char* font_char_ptr;
char pixels_to_move_by = 1;
// If it's time to move the scroll..
if (alt_nticks() >= (scroll->ticks_at_last_move + ((alt_ticks_per_second() * (scroll->ms_delay)) / 1000))) {
scroll->ticks_at_last_move = alt_nticks();
// Track where we are in the scroll.
if(scroll->text_scroll_started == 0) {
scroll->text_scroll_index = 0;
scroll->text_scroll_started = 1;
} else if(scroll->text_scroll_index >= scroll->scroll_points) {
scroll->text_scroll_started = 0;
} else {
scroll->text_scroll_index += pixels_to_move_by;
}
//Find out where we start
if (scroll->text_scroll_index < scroll->window_width) {
x_start = scroll->hbegin + scroll->window_width - scroll->text_scroll_index;
} else {
x_start = scroll->hbegin;
}
//Find out where we end
if (scroll->string_points > scroll->text_scroll_index) {
x_end = scroll->hend;
} else {
x_end = (scroll->hend - scroll->text_scroll_index + scroll->string_points);
}
// Write the string segment a column (x) at a time
for(x_index = x_start; x_index < x_end; x_index++) {
// Find the x index we're at within the string
// If first part of string hasnt yet reached left side of scroll window
if (scroll->text_scroll_index < scroll->window_width) {
string_x_index = (x_index - x_start);
} else {
string_x_index = scroll->text_scroll_index - scroll->window_width + x_index - x_start;
}
//Find the character we're supposed to be writing
string_char_index = (string_x_index / 8);
character = scroll->string[string_char_index];
char_column = (string_x_index % 8);
column_mask = (((unsigned int)0x80) >> char_column);
font_char_ptr = (scroll->font + ((character - 0x20) * FONT_10PT_ROW));
//We have all the data now, so let's write a column
for(char_row = 0; char_row < 11; char_row++) {
// If the font table says this pixel is on, then set it to the foreground color
if (*(font_char_ptr + char_row) & column_mask) {
vga_set_pixel(x_index, scroll->vbegin + char_row, scroll->f_color, vga_frame_buffer);
// Otherwise, set it to the background color.
} else {
vga_set_pixel(x_index, scroll->vbegin + char_row, scroll->b_color, vga_frame_buffer); //background color
}
}
}
// Erase the leftover column (x) of the last string we wrote.
vga_draw_line(x_end, scroll->vbegin, x_end, scroll->vbegin + 10, 1, scroll->b_color, vga_frame_buffer);
// Log what time we moved the scroll.
}
return(0);
}
/******************************************************************
* Function: vga_move_block
*
* Purpose: Moves a block around the screen, backfilling with
* the backfill_color parameter.
*
******************************************************************/
int vga_move_block(int xbegin, int ybegin, int xend, int yend, int x_distance, int y_distance, int backfill_color, vga_frame_buffer_struct* vga_frame_buffer)
{
int read_x, read_y, write_x, write_y;
short temp_pixel;
if(x_distance <= 0 && y_distance <= 0) {
//Move by rows because they are contiguous in memory (could help speed if in SDRAM)
for (read_y = ybegin; read_y < yend; read_y++) {
write_y = read_y + y_distance;
for(read_x = xbegin; read_x < xend; read_x++) {
write_x = read_x + x_distance;
temp_pixel = vga_get_pixel(read_x, read_y, vga_frame_buffer);
vga_set_pixel(write_x, write_y, temp_pixel, vga_frame_buffer);
if(read_x >= xend + x_distance || read_y >= yend + y_distance)
{
vga_set_pixel(read_x, read_y, backfill_color, vga_frame_buffer);
}
}
}
}
return (0);
}
/******************************************************************
* Function: vga_print_string
*
* Purpose: Prints a string to the specified location of the screen
* using the specified font and color.
* Calls vga_print_char
*
******************************************************************/
int vga_print_string(int horiz_offset, int vert_offset, int color, char *font, vga_frame_buffer_struct* vga_frame_buffer, char string[])
{
int i = 0;
int original_horiz_offset;
original_horiz_offset = horiz_offset;
// Print until we hit the '\0' char.
while (string[i]) {
//Handle newline char here.
if (string[i] == '\n') {
horiz_offset = original_horiz_offset;
vert_offset += 12;
i++;
continue;
}
// Lay down that character and increment our offsets.
vga_print_char (horiz_offset, vert_offset, color, string[i], font, vga_frame_buffer);
i++;
horiz_offset += 8;
}
return (0);
}
/******************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -