Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdarg>
- #include "GPU.h"
- #include "PSX.h"
- #include "Raster.h"
- void GPU::reset(PSX* psx) {
- _psx = psx;
- vram.fill(RGB_555(0x3, 0, 0x3));
- frame = 0;
- _rect_tex_flip_x = false;
- _rect_tex_flip_y = false;
- _vblank_interrupt = false;
- _vram_to_cpu_in_progress = false;
- _gp0_get_parameters = false;
- _gp0_vram_upload = false;
- _gp0_param_count = 0;
- _gp0_buffer.fill(0);
- _gpu_read_value = 0;
- _gp0_buff_idx = 0;
- _display_area_vram_x = 0;
- _display_area_vram_y = 0;
- _display_area_horiz_start = 0;
- _display_area_horiz_end = 0;
- _display_area_vert_start = 0;
- _display_area_vert_end = 0;
- _tex_win_mask_x = 0;
- _tex_win_mask_y = 0;
- _tex_win_off_x = 0;
- _tex_win_off_y = 0;
- _draw_area_top = 0;
- _draw_area_left = 0;
- _draw_area_bottom = 0;
- _draw_area_right = 0;
- _draw_offset_x = 0;
- _draw_offset_y = 0;
- _line_tick = 0;
- _line = 0;
- _clock_frac = 0;
- stat.reset();
- vram_upload_state.reset();
- vram_download_state.reset();
- _current_gp0_cmd = 0;
- _currentCLUT = 0;
- _tri_count = 0;
- }
- void GPU::do_save_state(SaveState &state) {
- state.add(vram);
- state.add(frame);
- state.add(_rect_tex_flip_x);
- state.add(_rect_tex_flip_y);
- state.add(_vblank_interrupt);
- state.add(_vram_to_cpu_in_progress);
- state.add(_gp0_get_parameters);
- state.add(_gp0_vram_upload);
- state.add(_gp0_param_count);
- state.add(_gp0_buffer);
- state.add(_gpu_read_value);
- state.add(_gp0_buff_idx);
- state.add(_display_area_vram_x);
- state.add(_display_area_vram_y);
- state.add(_display_area_horiz_start);
- state.add(_display_area_horiz_end);
- state.add(_display_area_vert_start);
- state.add(_display_area_vert_end);
- state.add(_tex_win_mask_x);
- state.add(_tex_win_mask_y);
- state.add(_tex_win_off_x);
- state.add(_tex_win_off_y);
- state.add(_draw_area_top);
- state.add(_draw_area_left);
- state.add(_draw_area_bottom);
- state.add(_draw_area_right);
- state.add(_draw_offset_x);
- state.add(_draw_offset_y);
- state.add(_line_tick);
- state.add(_line);
- state.add(_clock_frac);
- state.add(stat);
- state.add(vram_upload_state);
- state.add(vram_download_state);
- state.add(_current_gp0_cmd);
- state.add(_tri_count);
- state.add(_currentCLUT);
- }
- void GPU::panic(const char *fmt, ...) {
- char* buff = _psx->panic_message_buffer;
- sprintf(buff, "[GPU] Panic: ");
- buff += strlen(buff);
- va_list myargs;
- va_start(myargs, fmt);
- vsprintf(buff, fmt, myargs);
- va_end(myargs);
- buff += strlen(buff);
- sprintf(buff, "\n\ncurrent cmd: 0x%x\n", _current_gp0_cmd);
- for(u32 i = 0; i < std::min(_gp0_param_count, _gp0_buff_idx); i++) {
- buff += strlen(buff);
- sprintf(buff, " [%02d] 0x%08x\n", i, _gp0_buffer[i]);
- buff += strlen(buff);
- }
- _psx->panic();
- }
- u32 GPU::get_stat() {
- stat.interlace_field = true; // todo, why do I need this?
- switch(stat.dma_direction) {
- case 0:
- stat.data_request = false;
- break;
- case 1:
- stat.data_request = true;
- break;
- case 2:
- stat.data_request = true;
- break;
- case 3:
- stat.data_request = true; // todo, only set this if command has been sent
- break;
- default:
- panic("unknown dma direction %d", stat.dma_direction);
- break;
- }
- stat.ready_for_cmd = true;
- stat.ready_for_vram_download = true; // todo, don't always set
- stat.ready_for_dma = true;
- if(_line < 242) { // todo, is this actually in blank?
- if(stat.v_res && stat.interlace_enable) {
- stat.even_odd = (frame & 1);
- } else {
- stat.even_odd = (_line & 1);
- }
- } else {
- stat.even_odd = false;
- }
- return stat.data;
- }
- void GPU::step(u32 cyc) {
- u32 frac_clock_ratio = (7.f / 11.f) * 0x10000;
- u32 frac_cycles = _clock_frac + cyc * frac_clock_ratio;
- _clock_frac = frac_cycles & 0xffff;
- _line_tick += (frac_cycles >> 16);
- u32 oldLine = _line;
- _line += _line_tick / 3412;
- if(_line != oldLine) {
- _psx->timer.h_blank();
- }
- _line_tick = (_line_tick % 3412);
- if(_line > 263) {
- if(stat.interlace_enable) {
- if((_line / 263) & 1) {
- stat.interlace_field = true;
- } else {
- stat.interlace_field = false;
- }
- }
- _line = (_line % 263);
- frame++;
- }
- bool inBlank = _line >= 242; // todo, is this actually true?
- if(!_vblank_interrupt && inBlank) {
- _psx->cpu.interrupt(InterruptKind::VBLANK);
- }
- _vblank_interrupt = inBlank;
- }
- constexpr u32 gp0_polygon_parameter_count[0x20] = {
- 4, 0, 4, 0, 7, 7, 7, 7, 5, 0, 5, 0, 9, 9, 9, 9,
- 6, 0, 6, 0, 9, 0, 9, 0, 8, 0, 8, 0, 12, 0, 12, 0
- };
- constexpr u32 gp0_rectangle_parameter_count[0x20] = {
- 3, 0, 3, 0, 4, 4, 4, 4, 2, 0, 2, 0, 0, 0, 0, 0,
- 2, 0, 2, 3, 3, 3, 3, 2, 2, 0, 2, 0, 3, 3, 3, 3
- //0 1 2 3 4 5 6 7 8
- };
- void GPU::GP0(u32 cmd) {
- if(_gp0_vram_upload) {
- vram_upload_state.remain--;
- u32 addr = 1024 * vram_upload_state.yc + vram_upload_state.xc;
- u16 px1 = cmd;
- u16 px2 = cmd >> 16;
- vram[addr] = px1;
- vram_upload_state.xc++;
- if(vram_upload_state.xc >= vram_upload_state.xl) {
- vram_upload_state.xc = vram_upload_state.x0;
- vram_upload_state.yc++;
- }
- addr = 1024 * vram_upload_state.yc + vram_upload_state.xc;
- vram[addr] = px2;
- vram_upload_state.xc++;
- if(vram_upload_state.xc >= vram_upload_state.xl) {
- vram_upload_state.xc = vram_upload_state.x0;
- vram_upload_state.yc++;
- }
- if(!vram_upload_state.remain) {
- _gp0_vram_upload = false;
- if(_gp0_get_parameters) {
- panic("leaving vram upload with pending parameter upload");
- }
- }
- } else {
- if(_gp0_get_parameters) {
- _gp0_buffer[_gp0_buff_idx++] = cmd;
- if(_gp0_buff_idx == _gp0_param_count) {
- if(_current_gp0_cmd >= 0x20 && _current_gp0_cmd < 0x40) {
- // done with polygon!
- gp0_render_poly(_gp0_buffer.data(), _current_gp0_cmd);
- _gp0_get_parameters = false;
- } else if(_current_gp0_cmd >= 0x60 && _current_gp0_cmd < 0x80) {
- // done with rectangle
- gp0_render_rect(_gp0_buffer.data(), _current_gp0_cmd);
- _gp0_get_parameters = false;
- } else if(_current_gp0_cmd == 0xa0) {
- // begin VRAM upload!
- gp0_a0_cpu_to_vram(_gp0_buffer.data());
- _gp0_get_parameters = false;
- } else if(_current_gp0_cmd == 0xc0) {
- // begin VRAM download
- gp0_c0_vram_to_cpu(_gp0_buffer.data());
- _gp0_get_parameters = false;
- } else if(_current_gp0_cmd == 2) {
- gp0_02_fill_rectangle(_gp0_buffer.data());
- _gp0_get_parameters = false;
- } else if(_current_gp0_cmd == 0x80) {
- gp0_80_copy_rectangle(_gp0_buffer.data());
- _gp0_get_parameters = false;
- }
- else {
- panic("An unknown GP0 command has finished executing! 0x%x", _current_gp0_cmd);
- }
- }
- } else {
- _current_gp0_cmd = (cmd >> 24) & 0xff;
- if(_current_gp0_cmd >= 0x20 && _current_gp0_cmd < 0x40) {
- _gp0_get_parameters = true;
- u32 param_cnt = gp0_polygon_parameter_count[_current_gp0_cmd - 0x20];
- if(!param_cnt) {
- panic("GP0 command of 0x%x (cmd 0x%08x) is an invalid polygon command", _current_gp0_cmd, cmd);
- }
- _gp0_buffer[0] = cmd;
- _gp0_param_count = param_cnt; // must be > 0, nothing takes 1 parameter.
- _gp0_buff_idx = 1;
- } else if(_current_gp0_cmd >= 0x60 && _current_gp0_cmd < 0x80) {
- _gp0_get_parameters = true;
- u32 param_cnt = gp0_rectangle_parameter_count[_current_gp0_cmd - 0x60];
- if(!param_cnt) {
- panic("GP0 command of 0x%x (cmd 0x%08x) is an invalid rectangle command", _current_gp0_cmd, cmd);
- }
- _gp0_buffer[0] = cmd;
- _gp0_param_count = param_cnt; // must be > 0, nothing takes 1 parameter.
- _gp0_buff_idx = 1;
- }
- else if(_current_gp0_cmd >= 0xe1 && _current_gp0_cmd <= 0xe6) {
- gp0_attribute_cmd(cmd, _current_gp0_cmd);
- } else if(_current_gp0_cmd == 0 || _current_gp0_cmd == 1) {
- // do nothing
- } else if(_current_gp0_cmd == 2) {
- _gp0_get_parameters = true;
- _gp0_buffer[0] = cmd;
- _gp0_param_count = 3; // must be > 0, nothing takes 1 parameter.
- _gp0_buff_idx = 1;
- } else if(_current_gp0_cmd == 0xa0) {
- // CPU to VRAM upload
- _gp0_get_parameters = true;
- _gp0_param_count = 2;
- _gp0_buff_idx = 0;
- } else if(_current_gp0_cmd == 0xc0) {
- // vram to CPU
- _gp0_get_parameters = true;
- _gp0_param_count = 2;
- _gp0_buff_idx = 0;
- } else if(_current_gp0_cmd == 0x80) {
- _gp0_get_parameters = true;
- _gp0_param_count = 3;
- _gp0_buff_idx = 0;
- }
- else {
- panic("unknown GP0 command %d (0x%x)", _current_gp0_cmd, _current_gp0_cmd);
- }
- }
- }
- }
- void GPU::gp0_attribute_cmd(u32 cmd, u8 id) {
- switch(id) {
- case 0xe1: // draw mode
- stat.tex_page_x = cmd & 0xf;
- stat.tex_page_y = ((cmd >> 4) & 1);
- stat.semi_transparency_mode = ((cmd >> 5) & 3);
- stat.tex_page_color_mode = (cmd >> 7) & 3;
- stat.dither = ((cmd >> 9) & 1);
- stat.draw_to_display_area = ((cmd >> 10) & 1);
- stat.tex_disable = ((cmd >> 11) & 1);
- _rect_tex_flip_x = ((cmd >> 12) & 1);
- _rect_tex_flip_y = ((cmd >> 13) & 1);
- break;
- case 0xe2: // texture window
- _tex_win_mask_x = cmd & 0x1f;
- _tex_win_mask_y = (cmd >> 5) & 0x1f;
- _tex_win_off_x = ((cmd >> 10) & 0x1f);
- _tex_win_off_y = ((cmd >> 15) & 0x1f);
- break;
- case 0xe3: // draw area top left
- _draw_area_top = (cmd >> 10) & 0x3ff;
- _draw_area_left = (cmd & 0x3ff);
- break;
- case 0xe4: // draw area bottom right
- _draw_area_bottom = (cmd >> 10) & 0x3ff;
- _draw_area_right = (cmd & 0x3ff);
- break;
- case 0xe5: // draw offset (must be sign extended!)
- {
- u16 x = (cmd & 0x7ff);
- u16 y = (cmd >> 11) & 0x7ff;
- _draw_offset_x = ((s16)(x << 5)) >> 5;
- _draw_offset_y = ((s16)(y << 5)) >> 5;
- }
- break;
- case 0xe6:
- stat.set_mask_bit = cmd & 1;
- stat.use_mask_bit = cmd & 2;
- break;
- default:
- panic("unknown GP0 attribute command %d (0x%x)", id, id);
- }
- }
- void GPU::gp0_render_poly(u32 *cmd, u8 id) {
- (void)cmd;
- bool raw_tex = (id & (1 << 0));
- bool semi_trans = id & (1 << 1);
- bool texture = id & (1 << 2);
- bool quad = id & (1 << 3);
- bool shade = id & (1 << 4);
- raster_dither = shade || (texture && !raw_tex);
- if(!raw_tex && !shade && !texture) {
- // group 1 polys
- GpuColorAttr rgb = cmd[0];
- raster_rgb[0] = rgb.r();
- raster_rgb[1] = rgb.g();
- raster_rgb[2] = rgb.b();
- GpuVertexAttr verts[4] = {cmd[1], cmd[2], cmd[3], cmd[4]};
- Triangle<0> tri;
- for(u32 i = 0; i < 3; i++) {
- tri.verts[i] = GpuVertex<0>({verts[i].x(), verts[i].y()});
- }
- // render triangle
- raster<0, false, false>(tri, semi_trans, raw_tex);
- if(quad) {
- tri.verts[0] = GpuVertex<0>({verts[3].x(), verts[3].y()});
- }
- raster<0, false, false>(tri, semi_trans, raw_tex);
- } else if(texture && !shade) {
- // group 2 polys
- GpuColorAttr rgb = cmd[0];
- raster_rgb[0] = rgb.r();
- raster_rgb[1] = rgb.g();
- raster_rgb[2] = rgb.b();
- GpuVertexAttr verts[4] = {cmd[1], cmd[3], cmd[5], cmd[7]};
- GpuCLUTAttr clut(cmd[2]);
- GpuTexpageAttr tpage(cmd[4]);
- GpuTexcoordAttr tc[4] = {cmd[2], cmd[4], cmd[6], cmd[8]};
- _currentCLUT = clut.addr();
- stat.tex_page_x = tpage.x();
- stat.tex_page_y = tpage.y();
- stat.semi_transparency_mode = tpage.transparency();
- stat.tex_page_color_mode = tpage.color_depth();
- stat.tex_disable = tpage.tex_disable();
- Triangle<2> tri;
- for(u32 i = 0; i < 3; i++) {
- tri.verts[i] = GpuVertex<2>({verts[i].x(), verts[i].y(), tc[i].u(), tc[i].v()});
- }
- raster<2, false, true>(tri, semi_trans, raw_tex);
- if(quad) {
- tri.verts[0] = GpuVertex<2>({verts[3].x(), verts[3].y(), tc[3].u(), tc[3].v()});
- }
- raster<2, false, true>(tri, semi_trans, raw_tex);
- } else if(!raw_tex && !texture && shade) {
- GpuColorAttr rgb[4] = {cmd[0], cmd[2], cmd[4], cmd[6]};
- GpuVertexAttr verts[4] = {cmd[1], cmd[3], cmd[5], cmd[7]};
- Triangle<3> tri;
- for(u32 i = 0; i < 3; i++) {
- tri.verts[i] = GpuVertex<3>({verts[i].x(), verts[i].y(), rgb[i].r(), rgb[i].g(), rgb[i].b()});
- }
- raster<3, true, false>(tri, semi_trans, raw_tex);
- if(quad) {
- tri.verts[0] = GpuVertex<3>({verts[3].x(), verts[3].y(), rgb[3].r(), rgb[3].g(), rgb[3].b()});
- }
- raster<3, true, false>(tri, semi_trans, raw_tex);
- } else if(!raw_tex && texture && shade) {
- GpuColorAttr rgb[4] = {cmd[0], cmd[3], cmd[6], cmd[9]};
- GpuVertexAttr verts[4] = {cmd[1], cmd[4], cmd[7], cmd[10]};
- GpuTexcoordAttr tc[4] = {cmd[2], cmd[5], cmd[8], cmd[11]};
- GpuCLUTAttr clut(cmd[2]);
- GpuTexpageAttr tpage(cmd[5]);
- _currentCLUT = clut.addr();
- stat.tex_page_x = tpage.x();
- stat.tex_page_y = tpage.y();
- stat.semi_transparency_mode = tpage.transparency();
- stat.tex_page_color_mode = tpage.color_depth();
- stat.tex_disable = tpage.tex_disable();
- Triangle<5> tri;
- for(u32 i = 0; i < 3; i++) {
- tri.verts[i] = GpuVertex<5>({verts[i].x(), verts[i].y(), rgb[i].r(), rgb[i].g(), rgb[i].b(), tc[i].u(), tc[i].v()});
- }
- raster<5, true, true>(tri, semi_trans, raw_tex);
- if(quad) {
- tri.verts[0] = GpuVertex<5>({verts[3].x(), verts[3].y(), rgb[3].r(), rgb[3].g(), rgb[3].b(), tc[3].u(), tc[3].v()});
- }
- raster<5, true, true>(tri, semi_trans, raw_tex);
- }
- else {
- panic("don't know how to render polygon 0x%x", id);
- }
- }
- void GPU::gp0_render_rect(u32 *cmd, u8 id) {
- // todo dither?
- raster_dither = false;
- bool raw_tex = (id & (1 << 0));
- bool semi_trans = id & (1 << 1);
- bool texture = id & (1 << 2);
- u8 size_type = (id >> 3) & 3;
- if(texture) {
- GpuColorAttr rgb(cmd[0]);
- GpuVertexAttr corner(cmd[1]);
- GpuTexcoordAttr tex(cmd[2]);
- GpuCLUTAttr clut(cmd[2]);
- _currentCLUT = clut.addr();
- // todo, only load if we need colors?
- raster_rgb[0] = rgb.r();
- raster_rgb[1] = rgb.g();
- raster_rgb[2] = rgb.b();
- u16 x_size;
- u16 y_size;
- switch(size_type) {
- case 0:
- x_size = cmd[3] & 0xffff;
- y_size = cmd[3] >> 16;
- break;
- case 3:
- x_size = 16;
- y_size = 16;
- break;
- default:
- panic("unknown size of textured rectangle %d (cmd 0x%x)", size_type, _current_gp0_cmd);
- return;
- }
- if(x_size >= 1024 || y_size >= 512) {
- panic("rectangle of size %d %d is not supported", x_size, y_size);
- }
- Triangle<2> tri;
- tri.verts[0] = GpuVertex<2>({corner.x(), corner.y(), tex.u(), tex.v()});
- tri.verts[1] = GpuVertex<2>({corner.x() + x_size, corner.y(), tex.u() + x_size, tex.v()});
- tri.verts[2] = GpuVertex<2>({corner.x(), corner.y() + y_size, tex.u(), tex.v() + y_size});
- raster<2, false, true>(tri, semi_trans, raw_tex);
- tri.verts[0] = GpuVertex<2>({corner.x() + x_size, corner.y() + y_size, tex.u() + x_size, tex.v() + y_size});
- raster<2, false, true>(tri, semi_trans, raw_tex);
- } else {
- panic("untextured rectangle is not supported");
- }
- }
- void GPU::gp0_02_fill_rectangle(u32 *cmd) {
- RGB_888 rgb = cmd[0];
- u8 r = rgb.r >> 3;
- u8 g = rgb.g >> 3;
- u8 b = rgb.b >> 3;
- u32 x_start = (cmd[1] & 0xffff); // in size of 16 bits
- u32 y_start = (cmd[1] >> 16);
- u32 x_size = (cmd[2] & 0xffff);
- u32 y_size = (cmd[2] >> 16);
- x_start = (x_start & 0x3ff);
- y_start = (y_start & 0x1ff);
- x_size = ((x_size & 0x3ff) + 0xf) & (~0xf);
- y_size = y_size & 0x1ff;
- for(u32 y = y_start; y < y_start + y_size; y++) {
- for(u32 x = x_start; x < x_start + x_size; x++) {
- if(x >= 1024 || y >= 512) {
- panic("invalid fill rectangle @ %d %d\n", x,y);
- }
- // draw!
- vram[(y * 1024) + x] = r + (((u32)g) << 5) + (((u32)b) << 10);
- }
- }
- }
- void GPU::gp0_80_copy_rectangle(u32 *cmd) {
- u32 src_x = (cmd[0] & 0xffff);
- u32 src_y = (cmd[0] >> 16);
- u32 dst_x = (cmd[1] & 0xffff);
- u32 dst_y = (cmd[1] >> 16);
- u32 x_size = (cmd[2] & 0xffff);
- u32 y_size = (cmd[2] >> 16);
- // todo check these, and maybe mask starts too
- x_size = ((x_size & 0x3ff) + 0xf) & (~0xf);
- y_size = y_size & 0x1ff;
- for(u32 y = 0; y < y_size; y++) {
- for(u32 x = 0; x < x_size; x++) {
- u32 src = (y + src_y) * 1024 + x + src_x;
- u32 dst = (y + dst_y) * 1024 + x + dst_x;
- vram[dst] = vram[src];
- }
- }
- }
- void GPU::gp0_a0_cpu_to_vram(u32 *cmd) {
- u32 size = cmd[1];
- u32 width = size & 0xffff;
- u32 height = size >> 16;
- u32 imgPixels = width * height;
- u32 destX = cmd[0] & 0xffff;
- u32 destY = (cmd[0] >> 16);
- vram_upload_state.x0 = destX;
- vram_upload_state.y0 = destY;
- vram_upload_state.xc = destX;
- vram_upload_state.yc = destY;
- vram_upload_state.xl = destX + width;
- imgPixels = (imgPixels + 1) & (~1);
- vram_upload_state.remain = imgPixels / 2;
- _gp0_vram_upload = true;
- }
- void GPU::gp0_c0_vram_to_cpu(u32 *cmd) {
- u32 size = cmd[1];
- u32 width = size & 0xffff;
- u32 height = size >> 16;
- u32 imgPixels = width * height;
- u32 destX = cmd[0] & 0xffff;
- u32 destY = (cmd[0] >> 16);
- vram_download_state.x0 = destX;
- vram_download_state.y0 = destY;
- vram_download_state.xc = destX;
- vram_download_state.yc = destY;
- vram_download_state.xl = destX + width;
- imgPixels = (imgPixels + 1) & (~1);
- vram_download_state.remain = imgPixels / 2;
- _vram_to_cpu_in_progress = true;
- }
- void GPU::GP1(u32 cmd) {
- u32 op = (cmd >> 24) & 0xff;
- switch(op) {
- case 0: gp1_00_reset_gpu(); break;
- case 1: gp1_01_reset_cmd_buffer(); break;
- case 2: gp1_02_ack_irq(); break;
- case 3: gp1_03_display_enable(cmd); break;
- case 4: gp1_04_dma_direction(cmd); break;
- case 5: gp1_05_display_area_start(cmd); break;
- case 6: gp1_06_horiz_display_range(cmd); break;
- case 7: gp1_07_vert_display_range(cmd); break;
- case 8: gp1_08_display_mode(cmd); break;
- case 0x10: // todo, this
- break;
- default:
- panic("unknown GP1 command %d (0x%x)", op, op);
- }
- }
- u32 GPU::GPUREAD() {
- if(_vram_to_cpu_in_progress) {
- vram_download_state.remain--;
- u32 addr = 1024 * vram_download_state.yc + vram_download_state.xc;
- u32 result = *(u32*)(&vram[addr]);
- vram_download_state.xc+=2;
- if(vram_download_state.xc >= vram_download_state.xl) {
- vram_download_state.xc = vram_download_state.x0;
- vram_download_state.yc++;
- }
- if(!vram_download_state.remain) {
- _vram_to_cpu_in_progress = false;
- printf("[GPU] download complete!\n");
- // printf(" just wrote %d %d\n", gp0Upload.xc, gp0Upload.yc);
- }
- return result;
- } else {
- return _gpu_read_value;
- }
- }
- void GPU::gp1_00_reset_gpu() {
- gp1_01_reset_cmd_buffer();
- gp1_02_ack_irq();
- gp1_03_display_enable(1);
- gp1_04_dma_direction(GPU_DIR_OFF);
- gp1_05_display_area_start(0);
- // 06, 07
- _display_area_horiz_start = 0x200;
- _display_area_horiz_end = 0xc00;
- _display_area_vert_start = 0x10;
- _display_area_vert_end = 0x100;
- gp1_08_display_mode(0);
- for(u32 i = 0; i < 6; i++) {
- gp0_attribute_cmd(0, 0xe1 + i);
- }
- }
- void GPU::gp1_01_reset_cmd_buffer() {
- _gp0_get_parameters = false;
- _gp0_param_count = 0;
- }
- void GPU::gp1_02_ack_irq() {
- stat.irq = false;
- }
- void GPU::gp1_03_display_enable(u32 cmd) {
- stat.display_disable = cmd & 1;
- }
- void GPU::gp1_04_dma_direction(u32 cmd) {
- stat.dma_direction = cmd & 3;
- if(stat.dma_direction == GPU_DIR_BAD) {
- panic("set bad dma direction");
- }
- }
- void GPU::gp1_05_display_area_start(u32 cmd) {
- union r {
- bit_field<u32, u32, 0, 10> x;
- bit_field<u32, u32, 10, 9> y;
- u32 data;
- };
- r reg;
- reg.data = cmd;
- _display_area_vram_x = reg.x & (~1); // clear lowest bit.
- _display_area_vram_y = reg.y;
- }
- void GPU::gp1_06_horiz_display_range(u32 cmd) {
- _display_area_horiz_start = cmd & 0xfff;
- _display_area_horiz_end = ((cmd >> 12) & 0xfff);
- }
- void GPU::gp1_07_vert_display_range(u32 cmd) {
- _display_area_vert_start = (cmd & 0x3ff);
- _display_area_vert_end = ((cmd >> 10) & 0x3ff);
- }
- void GPU::gp1_08_display_mode(u32 cmd) {
- stat.h_res_1 = cmd & 3;
- stat.v_res = (cmd >> 2) & 1;
- stat.pal_mode = (cmd >> 3) & 1;
- stat.display_area_color_depth = (cmd >> 4) & 1;
- stat.interlace_enable = (cmd >> 5) & 1;
- stat.h_res_2 = (cmd >> 6) & 1;
- stat.reverse_flag = (cmd >> 7) & 1;
- if(stat.reverse_flag) {
- panic("reverse flag set");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement