儲存庫 vbox 的更動 34849
- 時間撮記:
- 2010-12-9 上午12:05:15 (14 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Devices/Graphics/DevVGA.cpp
r34404 r34849 67 67 * Only works when VBE_NEW_DYN_LIST is defined! */ 68 68 #define VRAM_SIZE_FIX 69 70 /** Some fixes to ensure that logical scan-line lengths are not overwritten. */71 #define KEEP_SCAN_LINE_LENGTH72 69 73 70 /** Check buffer if an VRAM offset is within the right range or not. */ … … 948 945 949 946 if (s->vbe_index <= VBE_DISPI_INDEX_NB) { 947 bool fRecalculate = false; 950 948 Log(("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val)); 951 949 switch(s->vbe_index) { … … 970 968 break; 971 969 case VBE_DISPI_INDEX_XRES: 972 if (val <= VBE_DISPI_MAX_XRES) { 970 if (val <= VBE_DISPI_MAX_XRES) 971 { 973 972 s->vbe_regs[s->vbe_index] = val; 974 #ifdef KEEP_SCAN_LINE_LENGTH 975 s->vbe_line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP], val); 976 /* XXX: support weird bochs semantics ? */ 977 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = calc_line_width(s->vbe_regs[VBE_DISPI_INDEX_BPP], s->vbe_line_offset); 978 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; 979 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; 980 s->vbe_start_addr = 0; 981 #endif /* KEEP_SCAN_LINE_LENGTH defined */ 973 fRecalculate = true; 982 974 } 983 975 break; 984 976 case VBE_DISPI_INDEX_YRES: 985 if (val <= VBE_DISPI_MAX_YRES) {977 if (val <= VBE_DISPI_MAX_YRES) 986 978 s->vbe_regs[s->vbe_index] = val; 987 #ifdef KEEP_SCAN_LINE_LENGTH988 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = val;989 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;990 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;991 s->vbe_start_addr = 0;992 #endif /* KEEP_SCAN_LINE_LENGTH defined */993 }994 979 break; 995 980 case VBE_DISPI_INDEX_BPP: … … 999 984 val == 16 || val == 24 || val == 32) { 1000 985 s->vbe_regs[s->vbe_index] = val; 1001 #ifdef KEEP_SCAN_LINE_LENGTH 1002 s->vbe_line_offset = calc_line_pitch(val, s->vbe_regs[VBE_DISPI_INDEX_XRES]); 1003 /* XXX: support weird bochs semantics ? */ 1004 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = calc_line_width(val, s->vbe_line_offset); 1005 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; 1006 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; 1007 s->vbe_start_addr = 0; 1008 #endif /* KEEP_SCAN_LINE_LENGTH defined */ 986 fRecalculate = true; 1009 987 } 1010 988 break; … … 1048 1026 cb = s->vbe_regs[VBE_DISPI_INDEX_XRES] * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); 1049 1027 cb *= s->vbe_regs[VBE_DISPI_INDEX_YRES]; 1050 #ifndef KEEP_SCAN_LINE_LENGTH 1051 if ( !s->vbe_regs[VBE_DISPI_INDEX_XRES] 1052 || !s->vbe_regs[VBE_DISPI_INDEX_YRES] 1053 || cb > s->vram_size) 1054 { 1055 AssertMsgFailed(("XRES=%d YRES=%d cb=%d vram_size=%d\n", 1056 s->vbe_regs[VBE_DISPI_INDEX_XRES], s->vbe_regs[VBE_DISPI_INDEX_YRES], cb, s->vram_size)); 1057 return VINF_SUCCESS; /* Note: silent failure like before */ 1058 } 1059 #else /* KEEP_SCAN_LINE_LENGTH defined */ 1060 if ( !s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] 1028 uint16_t cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH]; 1029 if (!cVirtWidth) 1030 cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_XRES]; 1031 if ( !cVirtWidth 1061 1032 || !s->vbe_regs[VBE_DISPI_INDEX_YRES] 1062 1033 || cb > s->vram_size) … … 1066 1037 return VINF_SUCCESS; /* Note: silent failure like before */ 1067 1038 } 1068 #endif /* KEEP_SCAN_LINE_LENGTH defined */1069 1070 #ifndef KEEP_SCAN_LINE_LENGTH1071 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =1072 s->vbe_regs[VBE_DISPI_INDEX_XRES];1073 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =1074 s->vbe_regs[VBE_DISPI_INDEX_YRES];1075 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;1076 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;1077 1078 s->vbe_line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP],1079 s->vbe_regs[VBE_DISPI_INDEX_XRES]);1080 s->vbe_start_addr = 0;1081 #endif /* KEEP_SCAN_LINE_LENGTH not defined */1082 1039 1083 1040 /* clear the screen (should be done in BIOS) */ 1084 1041 if (!(val & VBE_DISPI_NOCLEARMEM)) { 1042 uint16_t cY = RT_MIN(s->vbe_regs[VBE_DISPI_INDEX_YRES], 1043 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]); 1044 uint16_t cbLinePitch = s->vbe_line_offset; 1085 1045 memset(s->CTX_SUFF(vram_ptr), 0, 1086 s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);1046 cY * cbLinePitch); 1087 1047 } 1088 1048 … … 1093 1053 s->cr[0x13] = s->vbe_line_offset >> 3; 1094 1054 /* width */ 1095 s->cr[0x01] = ( s->vbe_regs[VBE_DISPI_INDEX_XRES]>> 3) - 1;1055 s->cr[0x01] = (cVirtWidth >> 3) - 1; 1096 1056 /* height (only meaningful if < 1024) */ 1097 1057 h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; … … 1150 1110 #endif /* IN_RING3 */ 1151 1111 case VBE_DISPI_INDEX_VIRT_WIDTH: 1152 {1153 int w, h, line_offset;1154 1155 if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])1156 return VINF_SUCCESS;1157 w = val;1158 line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP], w);1159 h = s->vram_size / line_offset;1160 /* XXX: support weird bochs semantics ? */1161 if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])1162 return VINF_SUCCESS;1163 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;1164 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;1165 s->vbe_line_offset = line_offset;1166 }1167 break;1168 1112 case VBE_DISPI_INDEX_X_OFFSET: 1169 1113 case VBE_DISPI_INDEX_Y_OFFSET: 1170 1114 { 1171 int x;1172 1115 s->vbe_regs[s->vbe_index] = val; 1173 s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET]; 1174 x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET]; 1175 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) 1176 s->vbe_start_addr += x >> 1; 1177 else 1178 s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); 1179 s->vbe_start_addr >>= 2; 1116 fRecalculate = true; 1180 1117 } 1181 1118 break; … … 1201 1138 default: 1202 1139 break; 1140 } 1141 if (fRecalculate) 1142 { 1143 uint16_t cBPP = s->vbe_regs[VBE_DISPI_INDEX_BPP]; 1144 uint16_t cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH]; 1145 uint16_t cX = s->vbe_regs[VBE_DISPI_INDEX_XRES]; 1146 uint16_t offX = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET]; 1147 uint16_t offY = s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET]; 1148 if (!cBPP || !cX) 1149 return VINF_SUCCESS; /* Not enough data has been set yet. */ 1150 uint32_t cbLinePitch = calc_line_pitch(cBPP, cVirtWidth); 1151 if (!cbLinePitch) 1152 cbLinePitch = calc_line_pitch(cBPP, cX); 1153 Assert(cbLinePitch != 0); 1154 uint16_t cVirtHeight = s->vram_size / cbLinePitch; 1155 uint32_t offStart = cbLinePitch * offY; 1156 if (cBPP == 4) 1157 offStart += offX >> 1; 1158 else 1159 offStart += offX * ((cBPP + 7) >> 3); 1160 offStart >>= 2; 1161 s->vbe_line_offset = RT_MIN(cbLinePitch, s->vram_size); 1162 s->vbe_start_addr = RT_MIN(offStart, s->vram_size); 1163 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = cVirtHeight; 1203 1164 } 1204 1165 } … … 2047 2008 2048 2009 int rc; 2010 AssertReturn(cx, VERR_INVALID_PARAMETER); 2011 AssertReturn(cy, VERR_INVALID_PARAMETER); 2012 AssertPtrReturn(s, VERR_INVALID_POINTER); 2013 AssertReturn(s->line_offset, VERR_INTERNAL_ERROR); 2049 2014 #if 0 //def VBOX_WITH_VDMA 2050 2015 /* @todo: we get a second resize here when VBVA is on, while we actually should not */ … … 2061 2026 #endif 2062 2027 { 2028 /* Silently skip the resize and if the values are not valid, and 2029 * forceably disable VBE and blank the screen. */ 2030 if (s->start_addr * 4 + s->line_offset * cy < s->vram_size) 2063 2031 /* Take into account the programmed start address (in DWORDs) of the visible screen. */ 2064 rc = s->pDrv->pfnResize(s->pDrv, cBits, s->CTX_SUFF(vram_ptr) + s->start_addr * 4, s->line_offset, cx, cy); 2032 rc = s->pDrv->pfnResize(s->pDrv, cBits, s->CTX_SUFF(vram_ptr) + s->start_addr * 4, s->line_offset, cx, cy); 2033 else 2034 { 2035 s->vbe_regs[VBE_DISPI_INDEX_ENABLE] &= ~VBE_DISPI_ENABLED; 2036 s->ar_index &= ~0x20; 2037 s->pDrv->pfnLFBModeChange(s->pDrv, false); 2038 /* Try again with the changes we have just made, but still set 2039 * s->last_* to avoid a loop. */ 2040 rc = VERR_TRY_AGAIN; 2041 } 2065 2042 } 2066 2043 … … 2072 2049 s->last_height = cy; 2073 2050 2074 if (rc == VINF_VGA_RESIZE_IN_PROGRESS )2051 if (rc == VINF_VGA_RESIZE_IN_PROGRESS || rc == VERR_TRY_AGAIN) 2075 2052 return rc; 2076 2053 AssertRC(rc);
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器