static void format_info(char* buffer0, char* buffer1, char* buffer2, unsigned size, adv_crtc* crtc) { double HD, HF, HS, HB; double VD, VF, VS, VB; double f; HD = crtc->hde; HF = crtc->hrs - crtc->hde; HS = crtc->hre - crtc->hrs; HB = crtc->ht - crtc->hre; f = 1 / (HD+HF+HS+HB); HD *= f; HF *= f; HS *= f; HB *= f; VD = crtc->vde; VF = crtc->vrs - crtc->vde; VS = crtc->vre - crtc->vrs; VB = crtc->vt - crtc->vre; f = 1 / (VD+VF+VS+VB); VD *= f; VF *= f; VS *= f; VB *= f; snprintf(buffer0, size, "plz clock dsen rtst rten totl disp front sync back pclock"); snprintf(buffer1, size, "h%c %7.3f%5d%5d%5d%5d %6.3f%6.3f%6.3f%6.3f %8.4f", crtc_is_nhsync(crtc) ? '-' : '+', crtc_hclock_get(crtc) / 1E3, crtc->hde, crtc->hrs, crtc->hre, crtc->ht, HD, HF, HS, HB, crtc_pclock_get(crtc) / 1E6); snprintf(buffer2, size, "v%c %7.3f%5d%5d%5d%5d %6.3f%6.3f%6.3f%6.3f%s%s", crtc_is_nvsync(crtc) ? '-' : '+', crtc_vclock_get(crtc), crtc->vde, crtc->vrs, crtc->vre, crtc->vt, VD, VF, VS, VB, crtc_is_doublescan(crtc) ? " doublescan" : "", crtc_is_interlace(crtc) ? " interlace" : ""); }
void crtc_print(char* buffer, unsigned size, const adv_crtc* crtc) { const char* flag1 = crtc_is_nhsync(crtc) ? " -hsync" : " +hsync"; const char* flag2 = crtc_is_nvsync(crtc) ? " -vsync" : " +vsync"; const char* flag3 = crtc_is_doublescan(crtc) ? " doublescan" : ""; const char* flag4 = crtc_is_interlace(crtc) ? " interlace" : ""; *buffer = 0; if (strchr(crtc->name, ' ')!=0) sncatf(buffer, size, "\"%s\"", crtc->name); else sncatf(buffer, size, "%s", crtc->name); sncatf(buffer, size, " %g %d %d %d %d %d %d %d %d%s%s%s%s", (double)crtc->pixelclock / 1E6, crtc->hde, crtc->hrs, crtc->hre, crtc->ht, crtc->vde, crtc->vrs, crtc->vre, crtc->vt, flag1, flag2, flag3, flag4 ); }
adv_error vgaline_mode_set(const vgaline_video_mode* mode) { struct vga_regs regs; log_std_modeline_c(("vgaline: mode_set modeline", mode->crtc.pixelclock, mode->crtc.hde, mode->crtc.hrs, mode->crtc.hre, mode->crtc.ht, mode->crtc.vde, mode->crtc.vrs, mode->crtc.vre, mode->crtc.vt, crtc_is_nhsync(&mode->crtc), crtc_is_nvsync(&mode->crtc), crtc_is_doublescan(&mode->crtc), crtc_is_interlace(&mode->crtc))); if (vgaline_mode_realize(®s, mode)!=0) { return -1; } vga_mode_set(®s); if (mode->is_text) { vgaline_write_line = vgaline_write_line_text; switch (mode->font_y) { case 8 : vga_font_copy(vga_font_bios_8, 8, 0, 1); break; case 14 : vga_font_copy(vga_font_bios_14, 14, 0, 1); break; case 16 : vga_font_copy(vga_font_bios_16, 16, 0, 1); break; } vga_palette_raw_set(vga_palette_bios_text, 0, 256); } else { vgaline_write_line = vgaline_write_line_graph; vga_palette_raw_set(vga_palette_bios_graph, 0, 256); } vgaline_state.mode_active = 1; return 0; }
static int vgaline_mode_text_realize(struct vga_regs* regs, const adv_crtc* crtc, unsigned font_x, unsigned font_y) { unsigned x_div = font_x; unsigned y_mul = crtc_is_doublescan(crtc) ? 2 : 1; unsigned de, bs, rs, re, be, tt; unsigned dotclock; *regs = vga_mode_bios_3; /* Get dot clock (for text mode is equal at dot clock) */ dotclock = vga_dotclock_nearest_get(crtc->pixelclock); /* output horizontal */ video_crtc_realize_h(crtc, &de, &bs, &rs, &re, &be, &tt, x_div); vga_regs_htt_set(regs, tt); vga_regs_hde_set(regs, de); vga_regs_hrs_set(regs, rs); vga_regs_hre_set(regs, re); vga_regs_hbs_set(regs, bs); vga_regs_hbe_set(regs, be); /* output vertical */ video_crtc_realize_v(crtc, &de, &bs, &rs, &re, &be, &tt, y_mul); vga_regs_vtt_set(regs, tt); vga_regs_vde_set(regs, de); vga_regs_vrs_set(regs, rs); vga_regs_vre_set(regs, re); vga_regs_vbs_set(regs, bs); vga_regs_vbe_set(regs, be); /* set char size */ vga_regs_char_size_x_set(regs, font_x); vga_regs_char_size_y_set(regs, font_y); /* set double scan as requested */ vga_regs_doublescan_set(regs, crtc_is_doublescan(crtc)); /* set dot clock */ switch (dotclock) { case VGA_DOTCLOCK_HIGH : vga_regs_dotclock_middle_set(regs, 0); vga_regs_masterclock_input_set(regs, 1); break; case VGA_DOTCLOCK_HIGH/2 : vga_regs_dotclock_middle_set(regs, 1); vga_regs_masterclock_input_set(regs, 1); break; case VGA_DOTCLOCK_LOW : vga_regs_dotclock_middle_set(regs, 0); vga_regs_masterclock_input_set(regs, 0); break; case VGA_DOTCLOCK_LOW/2 : vga_regs_dotclock_middle_set(regs, 1); vga_regs_masterclock_input_set(regs, 0); break; default: return -1; } /* set polarity */ vga_regs_hsync_set(regs, crtc_is_nhsync(crtc)); vga_regs_vsync_set(regs, crtc_is_nvsync(crtc)); /* set scanline length */ vga_regs_offset_set(regs, (crtc->hde + 2 * x_div - 1) / (2 * x_div)); return 0; }
static int vgaline_mode_graph_realize(struct vga_regs* regs, const adv_crtc* crtc) { unsigned x_div = 4; /* 4 pixel for clock in 8 bit mode */ unsigned y_mul = crtc_is_doublescan(crtc) ? 2 : 1; unsigned de, bs, rs, re, be, tt; unsigned dotclock; *regs = vga_mode_bios_13; /* get dot clock */ dotclock = vga_dotclock_nearest_get(crtc->pixelclock * 8 / x_div); /* output horizontal */ video_crtc_realize_h(crtc, &de, &bs, &rs, &re, &be, &tt, x_div); vga_regs_htt_set(regs, tt); vga_regs_hde_set(regs, de); vga_regs_hrs_set(regs, rs); vga_regs_hre_set(regs, re); vga_regs_hbs_set(regs, bs); vga_regs_hbe_set(regs, be); /* output vertical */ video_crtc_realize_v(crtc, &de, &bs, &rs, &re, &be, &tt, y_mul); vga_regs_vtt_set(regs, tt); vga_regs_vde_set(regs, de); vga_regs_vrs_set(regs, rs); vga_regs_vre_set(regs, re); vga_regs_vbs_set(regs, bs); vga_regs_vbe_set(regs, be); /* set char size */ vga_regs_char_size_x_set(regs, 8); /* set char size emulating doublescan */ vga_regs_char_size_y_set(regs, crtc_is_doublescan(crtc) ? 2 : 1); /* reset double scan */ vga_regs_doublescan_set(regs, 0); /* set dot clock */ switch (dotclock) { case VGA_DOTCLOCK_HIGH: vga_regs_dotclock_middle_set(regs, 0); vga_regs_masterclock_input_set(regs, 1); break; case VGA_DOTCLOCK_HIGH/2 : vga_regs_dotclock_middle_set(regs, 1); vga_regs_masterclock_input_set(regs, 1); break; case VGA_DOTCLOCK_LOW : vga_regs_dotclock_middle_set(regs, 0); vga_regs_masterclock_input_set(regs, 0); break; case VGA_DOTCLOCK_LOW/2 : vga_regs_dotclock_middle_set(regs, 1); vga_regs_masterclock_input_set(regs, 0); break; default: return -1; } /* set polarity */ vga_regs_hsync_set(regs, crtc_is_nhsync(crtc)); vga_regs_vsync_set(regs, crtc_is_nvsync(crtc)); /* set scanline length */ vga_regs_offset_set(regs, (crtc->hde + 2 * x_div - 1) / (2 * x_div)); /* set chained/unchained mode */ if (crtc->hde * crtc->vde > 0x10000) { vga_regs_chained_set(regs, 0); } else { vga_regs_chained_set(regs, 1); } return 0; }
adv_error fb_mode_set(const fb_video_mode* mode) { unsigned req_xres; unsigned req_yres; unsigned req_bits_per_pixel; assert(fb_is_active() && !fb_mode_is_active()); log_std(("video:fb: fb_mode_set()\n")); log_std(("video:fb: get old\n")); /* get the current info */ if (fb_getvar(&fb_state.oldinfo, 0) != 0) { error_set("Error getting the variable video mode information.\n"); goto err; } fb_log(0, &fb_state.oldinfo); fb_preset(&fb_state.varinfo, mode->crtc.pixelclock, mode->crtc.hde, mode->crtc.hrs, mode->crtc.hre, mode->crtc.ht, mode->crtc.vde, mode->crtc.vrs, mode->crtc.vre, mode->crtc.vt, crtc_is_doublescan(&mode->crtc), crtc_is_interlace(&mode->crtc), crtc_is_nhsync(&mode->crtc), crtc_is_nvsync(&mode->crtc), mode->index, FB_ACTIVATE_NOW ); log_std(("video:fb: set new\n")); fb_log(0, &fb_state.varinfo); /* save the minimun required data */ req_xres = fb_state.varinfo.xres; req_yres = fb_state.varinfo.yres; req_bits_per_pixel = fb_state.varinfo.bits_per_pixel; /* set the mode */ if (fb_setvar(&fb_state.varinfo) != 0) { error_set("Error setting the variable video mode information.\n"); goto err; } log_std(("video:fb: get new\n")); /* get the fixed info */ if (fb_getfix(&fb_state.fixinfo) != 0) { error_set("Error getting the fixed video mode information.\n"); goto err_restore; } /* get the variable info */ if (fb_getvar(&fb_state.varinfo, mode->index) != 0) { error_set("Error getting the variable video mode information.\n"); goto err_restore; } fb_state.freq = fb_state.varinfo.pixclock; fb_state.freq *= fb_state.varinfo.xres + fb_state.varinfo.left_margin + fb_state.varinfo.right_margin + fb_state.varinfo.hsync_len; fb_state.freq *= fb_state.varinfo.yres + fb_state.varinfo.upper_margin + fb_state.varinfo.lower_margin + fb_state.varinfo.vsync_len; if (fb_state.freq != 0) { fb_state.freq = 1000000000000LL / fb_state.freq; } log_std(("video:fb: frequency %g\n", fb_state.freq)); fb_log(&fb_state.fixinfo, &fb_state.varinfo); /* check the validity of the resulting video mode */ if (req_xres > fb_state.varinfo.xres || req_yres > fb_state.varinfo.yres || req_bits_per_pixel != fb_state.varinfo.bits_per_pixel ) { log_std(("ERROR:video:fb: request for mode %dx%d %d bits resulted in mode %dx%dx %d bits\n", req_xres, req_yres, req_bits_per_pixel, fb_state.varinfo.xres, fb_state.varinfo.yres, fb_state.varinfo.bits_per_pixel)); error_set("Error setting the requested video mode.\n"); goto err_restore; } if (req_xres != fb_state.varinfo.xres || req_yres != fb_state.varinfo.yres ) { /* allow bigger modes */ log_std(("WARNING:video:fb: request for mode %dx%d resulted in mode %dx%dx\n", req_xres, req_yres, fb_state.varinfo.xres, fb_state.varinfo.yres)); } if (fb_setup_color() != 0) { error_set("Error setting the color information.\n"); goto err_restore; } fb_write_line = fb_linear_write_line; fb_state.bytes_per_pixel = (fb_state.varinfo.bits_per_pixel + 7) / 8; fb_state.bytes_per_scanline = fb_state.fixinfo.line_length; fb_state.index = mode->index; fb_state.ptr = mmap(0, fb_state.fixinfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb_state.fd, 0 ); if (fb_state.ptr == MAP_FAILED) { error_set("Error mapping the video memory.\n"); goto err_restore; } fb_state.wait_last = 0; fb_state.wait = fb_wait_detect; /* reset the wait mode */ fb_state.wait_error = 0; fb_state.mode_active = 1; return 0; err_restore: fb_setvar(&fb_state.oldinfo); /* ignore error */ err: return -1; }
static adv_bool test_exe_crtc(int userkey, adv_crtc* crtc) { adv_bool modify = 0; unsigned pred_t; int xdelta; if (crtc->hde % 9 == 0 && crtc->hrs % 9 == 0 && crtc->hre % 9 == 0 && crtc->ht % 9 == 0) xdelta = 9; else xdelta = 8; switch (userkey) { case 'i' : pred_t = crtc->ht; crtc->ht -= crtc->ht % xdelta; crtc->ht -= xdelta; crtc->pixelclock = (double)crtc->pixelclock * crtc->ht / pred_t; modify = 1; break; case 'I' : pred_t = crtc->ht; crtc->ht -= crtc->ht % xdelta; crtc->ht += xdelta; crtc->pixelclock = (double)crtc->pixelclock * crtc->ht / pred_t; modify = 1; break; case 'k' : crtc->vt -= 1; modify = 1; break; case 'K' : crtc->vt += 1; modify = 1; break; case INPUTB_LEFT : crtc->hrs -= crtc->hrs % xdelta; crtc->hrs += xdelta; crtc->hre -= crtc->hre % xdelta; crtc->hre += xdelta; modify = 1; break; case INPUTB_RIGHT : crtc->hrs -= crtc->hrs % xdelta; crtc->hrs -= xdelta; crtc->hre -= crtc->hre % xdelta; crtc->hre -= xdelta; modify = 1; break; case INPUTB_DOWN : crtc->vrs -= 1; crtc->vre -= 1; modify = 1; break; case INPUTB_UP : crtc->vrs += 1; crtc->vre += 1; modify = 1; break; case 'u' : case 'U' : modify = 1; if (crtc_is_nhsync(crtc)) crtc_phsync_set(crtc); else crtc_nhsync_set(crtc); break; case 'j' : case 'J' : modify = 1; if (crtc_is_nvsync(crtc)) crtc_pvsync_set(crtc); else crtc_nvsync_set(crtc); break; case 'e' : crtc->hrs -= crtc->hrs % xdelta; crtc->hrs += xdelta; modify = 1; break; case 'E' : crtc->hrs -= crtc->hrs % xdelta; crtc->hrs -= xdelta; modify = 1; break; case 'r' : crtc->hre -= crtc->hre % xdelta; crtc->hre += xdelta; modify = 1; break; case 'R' : crtc->hre -= crtc->hre % xdelta; crtc->hre -= xdelta; modify = 1; break; case 'y' : crtc->ht -= crtc->ht % xdelta; crtc->ht += xdelta; modify = 1; break; case 'Y' : crtc->ht -= crtc->ht % xdelta; crtc->ht -= xdelta; modify = 1; break; case 'q' : crtc->hde -= crtc->hde % xdelta; crtc->hde += xdelta; modify = 1; break; case 'Q' : crtc->hde -= crtc->hde % xdelta; crtc->hde -= xdelta; modify = 1; break; case 'a' : ++crtc->vde; modify = 1; break; case 'A' : --crtc->vde; modify = 1; break; case 'd' : ++crtc->vrs; modify = 1; break; case 'D' : --crtc->vrs; modify = 1; break; case 'f' : ++crtc->vre; modify = 1; break; case 'F' : --crtc->vre; modify = 1; break; case 'h' : ++crtc->vt; modify = 1; break; case 'H' : --crtc->vt; modify = 1; break; case 'x' : case 'X' : modify = 1; if (crtc_is_doublescan(crtc)) crtc_singlescan_set(crtc); else crtc_doublescan_set(crtc); break; case 'c' : case 'C' : modify = 1; if (crtc_is_interlace(crtc)) crtc_singlescan_set(crtc); else crtc_interlace_set(crtc); break; case 'v' : modify = 1; crtc->pixelclock += 100000; break; case 'V' : modify = 1; crtc->pixelclock -= 100000; break; } return modify; }
static int test_crtc(int x, int y, adv_crtc* crtc, int print_clock, int print_measured_clock, int print_key) { char buffer[256]; snprintf(buffer, sizeof(buffer), "Horz Vert"); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; if (print_clock) { snprintf(buffer, sizeof(buffer), "%4.1f %5.1f %sClock Requested [kHz Hz]", crtc_hclock_get(crtc) / 1E3, crtc_vclock_get(crtc), print_key ? " " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; } if (print_measured_clock) { snprintf(buffer, sizeof(buffer), " %5.1f %sClock Measured [Hz]", video_measured_vclock(), print_key ? " " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; } snprintf(buffer, sizeof(buffer), "%4d %4d %sDisplay End", crtc->hde, crtc->vde, print_key ? "[qa] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; snprintf(buffer, sizeof(buffer), "%4d %4d %sRetrace Start", crtc->hrs, crtc->vrs, print_key ? "[ed] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; if (!(crtc->hde<=crtc->hrs)) { snprintf(buffer, sizeof(buffer), "HDE<=HRS"); draw_string(x, y, buffer, DRAW_COLOR_RED); ++y; } if (!(crtc->vde<=crtc->vrs)) { snprintf(buffer, sizeof(buffer), "VDE<=VRS"); draw_string(x, y, buffer, DRAW_COLOR_RED); ++y; } snprintf(buffer, sizeof(buffer), "%4d %4d %sRetrace End", crtc->hre, crtc->vre, print_key ? "[rf] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; if (!(crtc->hrs<crtc->hre)) { snprintf(buffer, sizeof(buffer), "HRS<HRE"); draw_string(x, y, buffer, DRAW_COLOR_RED); ++y; } if (!(crtc->vrs<crtc->vre)) { snprintf(buffer, sizeof(buffer), "VRE<VRE"); draw_string(x, y, buffer, DRAW_COLOR_RED); ++y; } snprintf(buffer, sizeof(buffer), "%4d %4d %sTotal", crtc->ht, crtc->vt, print_key ? "[yh] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; if (!(crtc->hre<=crtc->ht)) { snprintf(buffer, sizeof(buffer), "HRE<=HT"); draw_string(x, y, buffer, DRAW_COLOR_RED); ++y; } if (!(crtc->vre<=crtc->vt)) { snprintf(buffer, sizeof(buffer), "VRE<=VT"); draw_string(x, y, buffer, DRAW_COLOR_RED); ++y; } snprintf(buffer, sizeof(buffer), " %c %c %sPolarization", crtc_is_nhsync(crtc) ? '-' : '+', crtc_is_nvsync(crtc) ? '-' : '+', print_key ? "[uj] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; snprintf(buffer, sizeof(buffer), " %4s %sDoublescan", crtc_is_doublescan(crtc) ? "on" : "off", print_key ? "[x] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; snprintf(buffer, sizeof(buffer), " %4s %sInterlaced", crtc_is_interlace(crtc) ? "on" : "off", print_key ? "[c] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; if (print_clock) { snprintf(buffer, sizeof(buffer), "%4.2f %sPixelclock [MHz]", (double)crtc->pixelclock / 1E6, print_key ? "[v] " : ""); draw_string(x, y, buffer, DRAW_COLOR_WHITE); ++y; } if (print_key) { ++y; draw_string(x, y, "Q...U Inc horz (SHIFT dec)", DRAW_COLOR_WHITE); ++y; draw_string(x, y, "A...J Inc vert (SHIFT dec)", DRAW_COLOR_WHITE); ++y; draw_string(x, y, "I,K Inc horz/vert size (SHIFT dec)", DRAW_COLOR_WHITE); ++y; draw_string(x, y, "XCV Flip flag", DRAW_COLOR_WHITE); ++y; draw_string(x, y, "ARROWS Center", DRAW_COLOR_WHITE); ++y; } return y; }