@ElektrodaBot
Jak przerobić kod źródłowy Mac OS na Linux?
Jak przerobić kod źródłowy Mac OS na Linux?
Spoiler:
Kod: C / C++
Czy wolisz polską wersję strony elektroda?
Nie, dziękuję Przekieruj mnie tamGelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Jak przerobić kod źródłowy Mac OS na Linux?
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Port aplikacji MacOS c++ na Linux:
//Thx to MasterChef topic here http://www.insanelymac.com/forum/index.php?showtopic=154145
#include
#include
#include
using namespace std;
struct bdb_header {
char signature[16]; /**< Always 'BIOS_DATA_BLOCK' */
uint16_t version; /**< decimal */
uint16_t header_size; /**< in bytes */
uint16_t bdb_size; /**< in bytes */
} __attribute__((packed));
typedef struct {
unsigned char mode;
unsigned char bits_per_pixel;
unsigned short resolution;
unsigned char unknown;
} __attribute__((packed)) vbios_mode;
//static void* find_section(bdb_header* bdb, int section_id);
int main(int argc, const char * argv[])
{ if(argc == 1)
{ cout << "No input file specified" << endl << "Please use this syntax: ./AnalyseVBIOS NameOfVBIOSFile.rom" << endl;
return 1;
}
cout << "Attempting to open " << argv[1] << endl;
ifstream vbios(argv[1],ios::binary);
vbios.seekg(0, ios::end);
int length = vbios.tellg();
vbios.seekg(0x0000);
// cout << "sizeof(vbios_mode) = " << sizeof(vbios_mode) << endl;
unsigned char* buffer = new unsigned char[length];
// cout << "length = " << length << endl;
vbios.read((char*)buffer,length);
vbios.close();
vbios_mode* mode_ptr;
//bool isATI;
unsigned long idx = 0;
//unsigned long limit = 0x0B806; //setting it quite generous
cout << "Length:" << length << endl;
//int no =0;
int nNVIDIA=0;
int nATI=0;
while(idx < length && nATI < 5 && nNVIDIA < 3)
{ mode_ptr = (vbios_mode*) buffer+idx ;
idx++;
if((buffer ==0x00)&& (buffer ==0x04)&& (buffer ==0xFF)&& (buffer ==0x03)&& (buffer ==0x00)&& (buffer ==0x00)&& (buffer ==0xFF)&& (buffer ==0x03)&& (buffer ==0x17)&& (buffer ==0x04)&& (buffer ==0x9F)&& (buffer ==0x04)&& (buffer ==0x3F)&& (buffer ==0x05)&& (buffer ==0x00)&& (buffer ==0x03)&& (buffer ==0xFF)&& (buffer ==0x02)&& (buffer ==0x00)&& (buffer ==0x00)&& (buffer ==0xFF)&& (buffer ==0x02)&& (buffer ==0x02)&& (buffer ==0x03)&& (buffer ==0x08)&& (buffer ==0x03)&& (buffer ==0x25)&& (buffer ==0x03)&& (buffer ==0x00)&& (buffer ==0xFF))
//if ((buffer == 0x00) && (buffer ==0x04)&& (buffer ==0x00)&& (buffer ==0x03)) //Searching for 800x600
//{ if ((buffer == 0x58) && (buffer ==0x02))
{
nNVIDIA++;
idx = idx+1;
cout << "Found " << nNVIDIA << ". possible NVIDIA Mode at " <
int idy = idx;
int limit = idx + 513;
while(idy < limit)
{
if ((buffer == 0x00) && (buffer ==0x00))
{
cout << " \t Empty Table at " <}
idy=idy+32;
}
//idx = idx+27;
//}
}
if ((buffer == 0x20) && (buffer ==0x03)) //Searching for 800x600 in ati style
{ if ((buffer == 0x58) && (buffer ==0x02))
{ if (((buffer == 0x20) && (buffer ==0x03))||nATI == 4) //Searching for 800x600 in ati style
{
nATI++;
cout << "Found " << nATI << ". ATI Mode at " <//idx = idx+27;
}
}
}
}
if (nATI == 5 || nNVIDIA == 1) cout << "Correct number of finds" << endl << "Mod should be working" << endl;
return 0;
}
g++ -o analyze main.cpp
cc1plus: error: main.cpp: Value too large for defined data typeGelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Kompiluj kod bo u mnie błędy kompilacji.
Może ktoś skompilować bo u mnie ten sam błąd zarówno gdy próbuję oryginalny lub ten poprawiony przez AI:
g++ -o analyze main.cpp
cc1plus: error: main.cpp: Value too large for defined data type
root@ubuntu:/mnt/mp# nano ana.cpp
root@ubuntu:/mnt/mp# g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
root@ubuntu:/mnt/mp# ./ana 6200DSUB.ROM
Attempting to open 6200DSUB.ROM
Length: 63488 bytes
Found 1. ATI Mode at 0x2def
Found 2. ATI Mode at 0x2df8
Found 1. possible NVIDIA Mode at 0x94b3 (Decimal: 38067)
Empty Table at 0x95f3 (Decimal: 38387)
Empty Table at 0x9613 (Decimal: 38419)
Empty Table at 0x9653 (Decimal: 38483)
Empty Table at 0x9673 (Decimal: 38515)
Empty Table at 0x9693 (Decimal: 38547)
Correct number of finds
Mod should be working
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
OK, skompilowałem poprawiony kod i działa. Zrobiłem to w innym Linuxie niż poprzednio - Ubuntu 16.04.6 LTS bezpośrednio na zamontowanym udziale sieciowym Windows. Wcześniej wprowadziłem kosmetyczne zmiany w kodzie:
To działa. Dziękuję za pomoc:
root@ubuntu:/mnt/mp# nano ana.cpp
root@ubuntu:/mnt/mp# g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
root@ubuntu:/mnt/mp# ./ana 6200DSUB.ROM
Attempting to open 6200DSUB.ROM
Length: 63488 bytes
Found 1. ATI Mode at 0x2def
Found 2. ATI Mode at 0x2df8
Found 1. possible NVIDIA Mode at 0x94b3 (Decimal: 38067)
Empty Table at 0x95f3 (Decimal: 38387)
Empty Table at 0x9613 (Decimal: 38419)
Empty Table at 0x9653 (Decimal: 38483)
Empty Table at 0x9673 (Decimal: 38515)
Empty Table at 0x9693 (Decimal: 38547)
Correct number of finds
Mod should be working
ElektrodaBot napisał:Daj znać, czy dorzucić kod z PCIR i filtrem w całości – wstawię gotowy plik ana.cpp do skompilowania.
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Tak, chcę cały kod ana.cpp
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Kod działa ale nie tak jak trzeba. W wideo biosie NVIDIA 6200DSUB.ROM jest też inna tabela VESA w innym offsecie - tam gdzie wcześniejszy kod wyszukuje offset pod nazwą ATI
root@ubuntu:/mnt/mp# ./ana 6200DSUB.ROM
Attempting to open 6200DSUB.ROM
Length: 63488 bytes
[INFO] PCIR at 0x108 -> Vendor: 0x10de (NVIDIA), Device: 0x163
Found 1. possible NVIDIA Pattern at 0x94b3 (Decimal: 38067)
Empty Table at 0x95f3 (Decimal: 38387)
Empty Table at 0x9613 (Decimal: 38419)
Empty Table at 0x9653 (Decimal: 38483)
Empty Table at 0x9673 (Decimal: 38515)
Empty Table at 0x9693 (Decimal: 38547)
Probable VESA resolution table #1 at 0x2dc2 (stride=9, entries=3)
- 640x400
- 640x480
Probable VESA resolution table #2 at 0x2def (stride=9, entries=13)
- 800x600
- 1024x768
- 1280x1024
- 1280x800
- 1400x1050
- 1440x900
- 1600x1200
- 1680x1050
- 1920x1200
- 2048x1536
Correct number of finds
Mod should be working
C:\modelist.com
100 640 400 8
101 640 480 8
102 800 600 4
103 800 600 8
104 1024 768 4
105 1024 768 8
106 1280 1024 4
107 1280 1024 8
10E 320 200 16
10F 320 200 32
111 640 480 16
112 640 480 32
114 800 600 16
115 800 600 32
117 1024 768 16
118 1024 768 32
11A 1280 1024 16
11B 1280 1024 32
130 320 200 8
131 320 400 8
132 320 400 16
133 320 400 32
134 320 240 8
135 320 240 16
136 320 240 32
13D 640 400 16
13E 640 400 32
145 1600 1200 8
146 1600 1200 16
147 1400 1050 8
148 1400 1050 16
152 2048 1536 32 grub> vbeprobe
VBE version 3.0
100: 39F, 640x400x8, Packed pixel
101: 39F, 640x480x8, Packed pixel
102: 31F, 800x600x4, Planar
103: 39F, 800x600x8, Packed pixel
104: 31F, 1024x768x4, Planar
105: 39F, 1024x768x8, Packed pixel
106: 31F, 1280x1024x4, Planar
107: 39F, 1280x1024x8, Packed pixel
10E: 39F, 320x200x16, Direct Color
10F: 39F, 320x200x32, Direct Color
111: 39F, 640x480x16, Direct Color
112: 39F, 640x480x32, Direct Color
114: 39F, 800x600x16, Direct Color
115: 39F, 800x600x32, Direct Color
117: 39F, 1024x768x16, Direct Color
118: 39F, 1024x768x32, Direct Color
11A: 39F, 1280x1024x16, Direct Color
11B: 39F, 1280x1024x32, Direct Color
130: 39F, 320x200x8, Packed pixel
131: 39F, 320x400x8, Packed pixel
132: 39F, 320x400x16, Direct Color
133: 39F, 320x400x32, Direct Color
134: 39F, 320x240x8, Packed pixel
135: 39F, 320x240x16, Direct Color
136: 39F, 320x240x32, Direct Color
13D: 39F, 640x400x16, Direct Color
13E: 39F, 640x400x32, Direct Color
145: 39F, 1600x1200x8, Packed pixel
146: 39F, 1600x1200x16, Direct Color
147: 39F, 1400x1050x8, Packed pixel
148: 39F, 1400x1050x16, Direct Color
152: 3DB, 2048x1536x32, Direct ColorGelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Tak, ale chyba jest jakiś błąd w kodzie bo znajduje rozdzielczości których chyba nie ma w tabeli VESA np. 1280x800, 1440x900, 1680x1050 i 1920x1200:
Wynik działania programu ana:
root@ubuntu:/mnt/mp# ./ana 6200DSUB.ROM
Attempting to open 6200DSUB.ROM
Length: 63488 bytes
[INFO] PCIR at 0x108 -> Vendor: 0x10de (NVIDIA), Device: 0x163
Found 1. possible NVIDIA Pattern at 0x94b3 (Decimal: 38067)
Empty Table at 0x95f3 (Decimal: 38387)
Empty Table at 0x9613 (Decimal: 38419)
Empty Table at 0x9653 (Decimal: 38483)
Empty Table at 0x9673 (Decimal: 38515)
Empty Table at 0x9693 (Decimal: 38547)
Probable VESA resolution table #1 at 0x2dc2 (stride=9, entries=3)
- 640x400
- 640x480
Probable VESA resolution table #2 at 0x2def (stride=9, entries=13)
- 800x600
- 1024x768
- 1280x1024
- 1280x800
- 1400x1050
- 1440x900
- 1600x1200
- 1680x1050
- 1920x1200
- 2048x1536
Correct number of finds
Mod should be working
Programy modelist.com w MS-DOS i vbeprobe w GRUB4DOS widzą tylko takie rozdzielczości w tabeli VESA w vbiosie karty NVIDIA 6200:
C:\modelist.com
100 640 400 8
101 640 480 8
102 800 600 4
103 800 600 8
104 1024 768 4
105 1024 768 8
106 1280 1024 4
107 1280 1024 8
10E 320 200 16
10F 320 200 32
111 640 480 16
112 640 480 32
114 800 600 16
115 800 600 32
117 1024 768 16
118 1024 768 32
11A 1280 1024 16
11B 1280 1024 32
130 320 200 8
131 320 400 8
132 320 400 16
133 320 400 32
134 320 240 8
135 320 240 16
136 320 240 32
13D 640 400 16
13E 640 400 32
145 1600 1200 8
146 1600 1200 16
147 1400 1050 8
148 1400 1050 16
152 2048 1536 32
grub> vbeprobe
VBE version 3.0
100: 39F, 640x400x8, Packed pixel
101: 39F, 640x480x8, Packed pixel
102: 31F, 800x600x4, Planar
103: 39F, 800x600x8, Packed pixel
104: 31F, 1024x768x4, Planar
105: 39F, 1024x768x8, Packed pixel
106: 31F, 1280x1024x4, Planar
107: 39F, 1280x1024x8, Packed pixel
10E: 39F, 320x200x16, Direct Color
10F: 39F, 320x200x32, Direct Color
111: 39F, 640x480x16, Direct Color
112: 39F, 640x480x32, Direct Color
114: 39F, 800x600x16, Direct Color
115: 39F, 800x600x32, Direct Color
117: 39F, 1024x768x16, Direct Color
118: 39F, 1024x768x32, Direct Color
11A: 39F, 1280x1024x16, Direct Color
11B: 39F, 1280x1024x32, Direct Color
130: 39F, 320x200x8, Packed pixel
131: 39F, 320x400x8, Packed pixel
132: 39F, 320x400x16, Direct Color
133: 39F, 320x400x32, Direct Color
134: 39F, 320x240x8, Packed pixel
135: 39F, 320x240x16, Direct Color
136: 39F, 320x240x32, Direct Color
13D: 39F, 640x400x16, Direct Color
13E: 39F, 640x400x32, Direct Color
145: 39F, 1600x1200x8, Packed pixel
146: 39F, 1600x1200x16, Direct Color
147: 39F, 1400x1050x8, Packed pixel
148: 39F, 1400x1050x16, Direct Color
152: 3DB, 2048x1536x32, Direct Color
[WARN] No explicit VBE mode list found in ROM. Falling back to heuristics only. - 15x6700 [non-VBE]
- 53903x352 [non-VBE]
- 1100x388 [non-VBE]
- 1092x13472 [non-VBE]
- 41747x16409 [non-VBE]
- 34411x20485 [non-VBE]
- 32817x53255 [non-VBE]
- 32780x51916 [non-VBE]
- 1667x2187 [non-VBE]
- 9x52099 [non-VBE]
- 19724x2125 [non-VBE]
- 32771x34502 [non-VBE]
- 25318x11776 [non-VBE]
- 22060x22554 [non-VBE]
- 25132x11776 [non-VBE]
- 22060x22042 [non-VBE]
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Twój opis mi się podoba ale kod nie robi tego co piszesz. Nie znajduje tabeli VESA:
[WARN] No explicit VBE mode list found in ROM. Falling back to heuristics only.
a opcja --show-nonvbe pokazuje głupoty np. - zamieszczam część wyniku:
- 15x6700 [non-VBE]
- 53903x352 [non-VBE]
- 1100x388 [non-VBE]
- 1092x13472 [non-VBE]
- 41747x16409 [non-VBE]
- 34411x20485 [non-VBE]
- 32817x53255 [non-VBE]
- 32780x51916 [non-VBE]
- 1667x2187 [non-VBE]
- 9x52099 [non-VBE]
- 19724x2125 [non-VBE]
- 32771x34502 [non-VBE]
- 25318x11776 [non-VBE]
- 22060x22554 [non-VBE]
- 25132x11776 [non-VBE]
- 22060x22042 [non-VBE]
ElektrodaBot napisał:W wielu BIOS-ach NVIDII realna lista VBE nie występuje wprost w obrazie (jest odtwarzana w runtime z tabel BIT/DCB), więc „brak listy” jest normalny.
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Według mnie w każdym biosie wideo każdej karty graficznej jest realna tabela VESA z rozdzielczościami. W biosie 6200DSUB.ROM są prawdopodobnie dwie tabele - jedna VESA gdzieś w offsecie 0x2xxx a druga jakaś inna gdzieś w offsecie 0x9xxx
Teraz kod nie pokazuje offsetów gdzie są tabele. Po co przełącznik --show-extra ? W systemie Windows na sterowniku vga.sys nie ma do wyboru żadnej rozdzieczości "wide" więc chyba w biosie 6200DSUB.ROM nie ma takich rozdzielczości. Z tego co wiem sterownik Windows vga.sys odczytuje rozdzielczości z tabeli VESA z biosu karty graficznej.
Chcę aby program szukał offsety tabel z rozdzielczościami w różnych wideo biosach. Początkowy kod w tym temacie to robi.
Docelowo chcę właśnie dodać jakąś rozdzieczość "wide" do biosu albo zastąpić jedną 4:3 np. 1024x768 zastąpić 1024x576
Udało mi się to - zastąpiłem wartości HEX w pliku 6200DSUB.ROM w offsecie 0x2E01 i obliczyłem sumę kontrolną:
Zmieniłem 00 04 00 03 na 00 04 40 02
Teraz mam w systemie Windows do wyboru rozdzielczość 1024x576 ale jest wyświetlana z kolorowymi pikselami albo czarną ramką u dołu ekranu.
Załączam oryginalny bios 6200 spakowany do archiwum 6200.zip
Wzorowałem się na tym artykule:
http://www.macbreaker.com/2012/06/how-to-set-your-hackintosh-bootscreen.html
./ana5 6200DSUB.ROM
Attempting to open 6200DSUB.ROM
Length: 63488 bytes
[INFO] PCIR at 0x108 -> Vendor: 0x10de (NVIDIA), Device: 0x163
[INFO] ROM image length (from PCIR): 63488 bytes
Found 1. NVIDIA pattern at 0x94b3 (Decimal: 38067)
VESA table #1 at 0x2dc2 (stride=9, entries=3, unique=2)
- 640x400
- 640x480
VESA table #2 at 0x2def (stride=9, entries=6, unique=3)
- 800x600
- 1024x768
- 1280x1024
[CHECKSUM] Sum over 63488 bytes (mod 256): 0x00
STATUS: OK (PCI ROM checksum valid).
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Tak wygląda wynik działania:
./ana5 6200DSUB.ROM
Attempting to open 6200DSUB.ROM
Length: 63488 bytes
[INFO] PCIR at 0x108 -> Vendor: 0x10de (NVIDIA), Device: 0x163
[INFO] ROM image length (from PCIR): 63488 bytes
Found 1. NVIDIA pattern at 0x94b3 (Decimal: 38067)
VESA table #1 at 0x2dc2 (stride=9, entries=3, unique=2)
- 640x400
- 640x480
VESA table #2 at 0x2def (stride=9, entries=6, unique=3)
- 800x600
- 1024x768
- 1280x1024
[CHECKSUM] Sum over 63488 bytes (mod 256): 0x00
STATUS: OK (PCI ROM checksum valid).
Dlaczego rozbija to na 2 tabele przecież w offsetach 0x2dc2 i 2def to jest chyba ta sama jedna tabela VESA. Druga tabela - nie VESA jest w 0x9xxx
Tak, dodaj do kodu parser tabel i powiązanych timingów oraz patcher podmieniający wybrany wpis. Wideo bios karty 6200 masz w poprzednim poście #18 w załączniku w archiwum 6200.zip - w pliku 6200DSUB.ROM
Jeśli to ważne to karta ma tylko wyjście analogowe DSub
Ręczna analiza:
2DC2 8002 9001 640 400
2DCB 8002 E001 640 480
2DD4 8002 E001 640 480
2DDD
2DE6
2DEF 2003 5802 800 600
2DF8 2003 5802 800 600
2E01 0004 0003 1024 768
2E0A 0004 0003 1024 768
2E13 0005 0004 1280 1024
2E1C 0005 0004 1280 1024
2E25 0005 2003 1280 800
2E2E 7805 1A04 1400 1050
2E37 A005 8403 1440 900
2E40 4006 B004 1600 1200
2E49 9006 1A04 1680 1050
2E52 8007 B004 1920 1200
2E5B 0008 0006 2048 1536ElektrodaBot napisał:W wielu BIOS-ach NVIDII realna lista VBE nie występuje wprost w obrazie (jest odtwarzana w runtime z tabel BIT/DCB), więc „brak listy” jest normalny.
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Teraz łączy w jedną tablicę ale przeanalizowałem ręcznie vbios i wyszło mi coś takiego:
Ręczna analiza:
2DC2 8002 9001 640 400
2DCB 8002 E001 640 480
2DD4 8002 E001 640 480
2DDD
2DE6
2DEF 2003 5802 800 600
2DF8 2003 5802 800 600
2E01 0004 0003 1024 768
2E0A 0004 0003 1024 768
2E13 0005 0004 1280 1024
2E1C 0005 0004 1280 1024
2E25 0005 2003 1280 800
2E2E 7805 1A04 1400 1050
2E37 A005 8403 1440 900
2E40 4006 B004 1600 1200
2E49 9006 1A04 1680 1050
2E52 8007 B004 1920 1200
2E5B 0008 0006 2048 1536
Czyli faktycznie jest dziura w 2DDD i są rozdzielczości 16:10 i 5:4 a nie tylko 4:3, niektóre rozdzielczości po 2 razy a więc to nie jest tabela VESA bo program vbeprobe nie pokazuje rozdzielczości "wide"
I tu miałeś chyba faktycznie rację iż tabela VESA jest budowana na podstawie danych z vbiosu z różnych jego obszarów.
Więc kod z posta #13 dobrze pokazywał zawartość tabel.
Wracamy więc do kodu z #13 ale dodaj ostatnie poprawki z v7 na zmianę wybranej rozdzielczości bez dopasowania timingów bo to nic nie zmienia w pliku biosu.
// ============================================================================
// ana.cpp – VBIOS Analyzer (PCIR + NVIDIA pattern + heurystyczne wykrywanie tabel VESA)
// Kompilacja: g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
// Użycie: ./ana [opcje] plik.rom
//
// Opcje:
// --verbose dodatkowe logi diagnostyczne
// --vendor-only tylko wykrycie PCIR (VID/DID), bez skanowania
// --dump-window OFF LEN hexdump okna (OFF i LEN w dziesiętnej lub 0xHEX)
// --dump-on-hit LEN hexdump LEN bajtów od miejsca trafienia
//
// Opis:
// - „ATI Mode” z pierwotnego kodu był w praktyce wpisem VESA 800x600.
// - Ten program szuka całych tabel VESA: klastrów powtarzających się par (Width,Height)
// w LE, ze stałym krokiem bajtowym (stride) – np. 4/6/8/9/12/16/20/24/32.
// - Dodatkowo wykrywa klasyczny długi wzorzec NVIDII i emituje info o „pustych slotach”.
// ============================================================================
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include <iomanip>
#include <set>
// --------------------------- Wzorce i sygnatury ------------------------------
constexpr std::array<uint8_t,30> NVIDIA_PATTERN = {
0x00,0x04,0xFF,0x03,0x00,0x00,0xFF,0x03,
0x17,0x04,0x9F,0x04,0x3F,0x05,0x00,0x03,
0xFF,0x02,0x00,0x00,0xFF,0x02,0x02,0x03,
0x08,0x03,0x25,0x03,0x00,0xFF
};
constexpr std::array<char,4> PCIR_SIG = {'P','C','I','R'};
constexpr uint16_t VENDOR_NVIDIA = 0x10DE;
constexpr uint16_t VENDOR_ATI = 0x1002;
constexpr uint16_t VENDOR_INTEL = 0x8086;
// Z oryginalnej logiki „pustych slotów” przy trafieniu wzorca NV
constexpr std::size_t NVIDIA_TABLE_SIZE = 513;
constexpr std::size_t NVIDIA_ENTRY_SIZE = 32;
// Typowe rozdzielczości VESA (lista nie jest kompletna, ale do heurystyki wystarczy)
static const std::vector<std::pair<uint16_t,uint16_t>> kCommonRes = {
{320,200},{320,240},{400,300},{512,384},
{640,350},{640,400},{640,480},{720,400},
{800,600},{848,480},{852,480},{856,480},
{960,540},{960,600},
{1024,576},{1024,600},{1024,768},
{1152,864},
{1280,720},{1280,768},{1280,800},{1280,960},{1280,1024},
{1360,768},{1366,768},
{1400,1050},
{1440,900},
{1600,900},{1600,1024},{1600,1200},
{1680,1050},
{1792,1344},{1856,1392},
{1920,1080},{1920,1200},{1920,1440},
{2048,1152},{2048,1536},
{2560,1080},{2560,1440},{2560,1600},{2560,2048},
{2880,1800},
{3440,1440},
{3840,2160},
{4096,2160}
};
// -----------------------------------------------------------------------------
struct Config {
bool verbose = false;
bool vendor_only = false;
bool dump_window = false;
std::size_t dump_offset = 0;
std::size_t dump_length = 64;
std::size_t dump_on_hit_len = 0; // 0 = off
} g_cfg;
static void print_usage(const char* prog) {
std::cout
<< "Usage: " << prog << " [options] file.rom\n"
<< "Options:\n"
<< " --verbose extra diagnostics\n"
<< " --vendor-only only detect PCIR vendor/device\n"
<< " --dump-window OFF LEN hex dump at absolute offset OFF, length LEN\n"
<< " --dump-on-hit LEN hex dump LEN bytes at each pattern hit\n";
}
static std::size_t parse_number(const std::string& s) {
try {
std::size_t pos = 0;
unsigned long long v = std::stoull(s, &pos, 0); // 0 => 0xHEX lub dec
if (pos != s.size()) throw std::invalid_argument("trailing");
return static_cast<std::size_t>(v);
} catch (...) {
std::cerr << "Invalid number: " << s << "\n";
std::exit(2);
}
}
template<typename PatternT>
static bool match_at(const std::vector<uint8_t>& buf, std::size_t pos, const PatternT& pat) {
return (pos + pat.size() <= buf.size())
&& std::equal(pat.begin(), pat.end(), buf.begin() + pos);
}
static void hex_dump(const std::vector<uint8_t>& buf, std::size_t offset, std::size_t length) {
if (offset >= buf.size()) {
std::cout << "[WARN] dump offset beyond file size\n";
return;
}
const std::size_t end = std::min(offset + length, buf.size());
std::cout << "Hex dump [0x" << std::hex << offset << " .. 0x"
<< (end ? end - 1 : 0) << "] (" << std::dec << (end - offset) << " bytes):\n";
for (std::size_t i = offset; i < end; i += 16) {
std::cout << " " << std::hex << std::setw(6) << std::setfill('0') << i << ": ";
for (std::size_t j = 0; j < 16 && (i + j) < end; ++j) {
std::cout << std::setw(2) << std::setfill('0')
<< static_cast<unsigned>(buf[i + j]) << " ";
}
for (std::size_t j = (end > i ? end - i : 0); j < 16; ++j) std::cout << " ";
std::cout << " | ";
for (std::size_t j = 0; j < 16 && (i + j) < end; ++j) {
const char c = static_cast<char>(buf[i + j]);
std::cout << (std::isprint(static_cast<unsigned char>(c)) ? c : '.');
}
std::cout << std::dec << "\n";
}
std::cout << "\n";
}
// ------------------------------- PCIR ----------------------------------------
struct PCIRInfo {
bool found = false;
std::size_t offset = 0;
uint16_t vendor_id = 0;
uint16_t device_id = 0;
};
static PCIRInfo find_pcir(const std::vector<uint8_t>& buf) {
PCIRInfo info;
for (std::size_t off = 0; off + 8 <= buf.size(); ++off) {
if (match_at(buf, off, PCIR_SIG)) {
info.found = true;
info.offset = off;
info.vendor_id = static_cast<uint16_t>(buf[off+4] | (uint16_t(buf[off+5])<<8));
info.device_id = static_cast<uint16_t>(buf[off+6] | (uint16_t(buf[off+7])<<8));
break;
}
}
return info;
}
static const char* vendor_name(uint16_t vid) {
switch (vid) {
case VENDOR_NVIDIA: return "NVIDIA";
case VENDOR_ATI: return "ATI/AMD";
case VENDOR_INTEL: return "INTEL";
default: return "Unknown";
}
}
// ------------------------- Heurystyka tabel VESA ------------------------------
struct VesaCluster {
std::size_t start = 0; // offset startu klastru
std::size_t stride = 0; // krok bajtów między wpisami
std::size_t entries = 0; // liczba wykrytych wpisów (kolejnych)
std::vector<std::pair<uint16_t,uint16_t>> modes; // zebrane pary
};
// szybki zestaw (w,h) -> klucz 32-bit do deduplikacji
static inline uint32_t pack_wh(uint16_t w, uint16_t h) {
return (uint32_t(w) << 16) | uint32_t(h);
}
static bool is_common_res(uint16_t w, uint16_t h) {
// ścisłe dopasowanie do listy – minimalizujemy false-positive
for (const auto& p : kCommonRes) {
if (p.first == w && p.second == h) return true;
}
return false;
}
static bool read_wh(const std::vector<uint8_t>& buf, std::size_t off, uint16_t& w, uint16_t& h) {
if (off + 3 >= buf.size()) return false;
w = uint16_t(buf[off] | (uint16_t(buf[off+1])<<8));
h = uint16_t(buf[off+2] | (uint16_t(buf[off+3])<<8));
return true;
}
// Szuka klastrów par (w,h) z powtarzalnym stride i min. liczbą wpisów
static std::vector<VesaCluster> find_vesa_clusters(const std::vector<uint8_t>& buf) {
std::vector<VesaCluster> out;
const std::vector<std::size_t> strides = {4,6,8,9,10,12,16,20,24,32};
const std::size_t max_span = 4096; // max. rozpiętość pojedynczego klastru
std::size_t i = 0;
while (i + 4 <= buf.size()) {
bool any_cluster = false;
for (std::size_t s : strides) {
uint16_t w=0,h=0;
if (!read_wh(buf, i, w, h)) continue;
if (!is_common_res(w,h)) continue;
// potwierdzaj kolejne wpisy par (w,h) co 's' bajtów
VesaCluster cl;
cl.start = i; cl.stride = s; cl.entries = 0;
std::size_t j = i;
std::set<uint32_t> uniq;
while (j + 4 <= buf.size() && (j - i) <= max_span) {
uint16_t ww=0, hh=0;
if (!read_wh(buf, j, ww, hh)) break;
if (!is_common_res(ww,hh)) break;
cl.modes.emplace_back(ww,hh);
uniq.insert(pack_wh(ww,hh));
cl.entries++;
j += s;
}
// Minimalne progi, żeby uniknąć przypadkowych trafień:
// - co najmniej 3 kolejne wpisy
// - co najmniej 2 różne rozdzielczości w klastrze
if (cl.entries >= 3 && uniq.size() >= 2) {
out.push_back(cl);
any_cluster = true;
if (g_cfg.verbose) {
std::cout << "[DEBUG] VESA cluster at 0x" << std::hex << cl.start
<< " stride=" << std::dec << cl.stride
<< " entries=" << cl.entries << "\n";
}
// przeskocz za ten klaster, by nie raportować setek nałożonych wyników
i = j;
break;
}
}
if (!any_cluster) ++i;
}
return out;
}
// ------------------------------- main ----------------------------------------
int main(int argc, const char* argv[]) {
// CLI
std::string filepath;
for (int i = 1; i < argc; ++i) {
const std::string a = argv[i];
if (a == "--verbose") g_cfg.verbose = true;
else if (a == "--vendor-only") g_cfg.vendor_only = true;
else if (a == "--dump-window") {
if (i + 2 >= argc) { print_usage(argv[0]); return 2; }
g_cfg.dump_window = true;
g_cfg.dump_offset = parse_number(argv[++i]);
g_cfg.dump_length = parse_number(argv[++i]);
} else if (a == "--dump-on-hit") {
if (i + 1 >= argc) { print_usage(argv[0]); return 2; }
g_cfg.dump_on_hit_len = parse_number(argv[++i]);
} else if (!a.empty() && a[0] == '-') {
print_usage(argv[0]); return 2;
} else {
filepath = a;
}
}
if (filepath.empty()) { print_usage(argv[0]); return 1; }
std::cout << "Attempting to open " << filepath << "\n";
// Wczytanie pliku
std::ifstream f(filepath.c_str(), std::ios::binary);
if (!f) { std::cerr << "Error: cannot open file\n"; return 1; }
f.seekg(0, std::ios::end);
std::streamoff end = f.tellg();
if (end < 0) { std::cerr << "Error: tellg() failed\n"; return 1; }
const std::size_t length = static_cast<std::size_t>(end);
f.seekg(0, std::ios::beg);
std::vector<uint8_t> buf(length);
if (length) {
f.read(reinterpret_cast<char*>(buf.data()), static_cast<std::streamsize>(length));
if (f.gcount() != static_cast<std::streamsize>(length)) {
std::cerr << "Error: could not read full file\n"; return 1;
}
}
std::cout << "Length: " << length << " bytes\n";
if (g_cfg.dump_window) {
hex_dump(buf, g_cfg.dump_offset, g_cfg.dump_length);
}
// PCIR
PCIRInfo pcir = find_pcir(buf);
if (pcir.found) {
std::cout << "[INFO] PCIR at 0x" << std::hex << pcir.offset << std::dec
<< " -> Vendor: 0x" << std::hex << pcir.vendor_id
<< " (" << vendor_name(pcir.vendor_id) << ")"
<< ", Device: 0x" << pcir.device_id << std::dec << "\n";
} else {
std::cout << "[WARN] PCIR not found – vendor unknown\n";
}
if (g_cfg.vendor_only) return 0;
// Wzorzec NVIDIA (długi)
int nNVIDIA = 0;
for (std::size_t idx = 0; idx < length; ++idx) {
if (match_at(buf, idx, NVIDIA_PATTERN)) {
++nNVIDIA;
std::cout << "Found " << nNVIDIA << ". possible NVIDIA Pattern at 0x"
<< std::hex << idx << std::dec
<< " (Decimal: " << idx << ")\n";
if (g_cfg.dump_on_hit_len) {
hex_dump(buf, idx, std::min(g_cfg.dump_on_hit_len, length - idx));
}
const std::size_t limit = std::min(idx + NVIDIA_TABLE_SIZE, length);
for (std::size_t idy = idx; idy + 1 < limit; idy += NVIDIA_ENTRY_SIZE) {
if (buf[idy] == 0x00 && buf[idy+1] == 0x00) {
std::cout << "\tEmpty Table at 0x" << std::hex << idy << std::dec
<< " (Decimal: " << idy << ")\n";
}
}
}
}
// Klastry VESA (tu trafimy m.in. to miejsce, które wcześniej etykietowałeś jako „ATI”)
auto clusters = find_vesa_clusters(buf);
int cluster_idx = 0;
for (const auto& cl : clusters) {
++cluster_idx;
std::cout << "Probable VESA resolution table #" << cluster_idx
<< " at 0x" << std::hex << cl.start << std::dec
<< " (stride=" << cl.stride
<< ", entries=" << cl.entries << ")\n";
// Wypisz do 12 pierwszych unikalnych rozdzielczości
std::set<uint32_t> seen;
int shown = 0;
for (const auto& m : cl.modes) {
uint32_t key = pack_wh(m.first,m.second);
if (!seen.insert(key).second) continue;
std::cout << " - " << m.first << "x" << m.second << "\n";
if (++shown >= 12) break;
}
if (g_cfg.dump_on_hit_len) {
hex_dump(buf, cl.start, std::min(g_cfg.dump_on_hit_len, length - cl.start));
}
}
// Podsumowanie w duchu oryginalnego kodu
if ((pcir.vendor_id == VENDOR_NVIDIA && nNVIDIA >= 1) || (!pcir.found && nNVIDIA >= 1)) {
std::cout << "Correct number of finds\nMod should be working\n";
} else if (clusters.empty() && nNVIDIA == 0) {
std::cout << "Warning: no NVIDIA pattern and no VESA clusters found.\n";
}
return 0;
}
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Źle, nie ten kod użyłeś bo pokazuje bzdury i kosmiczne liczby. Ma być ten kod:
// ============================================================================
// ana.cpp – VBIOS Analyzer (PCIR + NVIDIA pattern + heurystyczne wykrywanie tabel VESA)
// Kompilacja: g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
// Użycie: ./ana [opcje] plik.rom
//
// Opcje:
// --verbose dodatkowe logi diagnostyczne
// --vendor-only tylko wykrycie PCIR (VID/DID), bez skanowania
// --dump-window OFF LEN hexdump okna (OFF i LEN w dziesiętnej lub 0xHEX)
// --dump-on-hit LEN hexdump LEN bajtów od miejsca trafienia
//
// Opis:
// - „ATI Mode” z pierwotnego kodu był w praktyce wpisem VESA 800x600.
// - Ten program szuka całych tabel VESA: klastrów powtarzających się par (Width,Height)
// w LE, ze stałym krokiem bajtowym (stride) – np. 4/6/8/9/12/16/20/24/32.
// - Dodatkowo wykrywa klasyczny długi wzorzec NVIDII i emituje info o „pustych slotach”.
// ============================================================================
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// --------------------------- Wzorce i sygnatury ------------------------------
constexpr std::arrayNVIDIA_PATTERN = {
0x00,0x04,0xFF,0x03,0x00,0x00,0xFF,0x03,
0x17,0x04,0x9F,0x04,0x3F,0x05,0x00,0x03,
0xFF,0x02,0x00,0x00,0xFF,0x02,0x02,0x03,
0x08,0x03,0x25,0x03,0x00,0xFF
};
constexpr std::arrayPCIR_SIG = {'P','C','I','R'};
constexpr uint16_t VENDOR_NVIDIA = 0x10DE;
constexpr uint16_t VENDOR_ATI = 0x1002;
constexpr uint16_t VENDOR_INTEL = 0x8086;
// Z oryginalnej logiki „pustych slotów” przy trafieniu wzorca NV
constexpr std::size_t NVIDIA_TABLE_SIZE = 513;
constexpr std::size_t NVIDIA_ENTRY_SIZE = 32;
// Typowe rozdzielczości VESA (lista nie jest kompletna, ale do heurystyki wystarczy)
static const std::vector> kCommonRes = {
{320,200},{320,240},{400,300},{512,384},
{640,350},{640,400},{640,480},{720,400},
{800,600},{848,480},{852,480},{856,480},
{960,540},{960,600},
{1024,576},{1024,600},{1024,768},
{1152,864},
{1280,720},{1280,768},{1280,800},{1280,960},{1280,1024},
{1360,768},{1366,768},
{1400,1050},
{1440,900},
{1600,900},{1600,1024},{1600,1200},
{1680,1050},
{1792,1344},{1856,1392},
{1920,1080},{1920,1200},{1920,1440},
{2048,1152},{2048,1536},
{2560,1080},{2560,1440},{2560,1600},{2560,2048},
{2880,1800},
{3440,1440},
{3840,2160},
{4096,2160}
};
// -----------------------------------------------------------------------------
struct Config {
bool verbose = false;
bool vendor_only = false;
bool dump_window = false;
std::size_t dump_offset = 0;
std::size_t dump_length = 64;
std::size_t dump_on_hit_len = 0; // 0 = off
} g_cfg;
static void print_usage(const char* prog) {
std::cout
<< "Usage: " << prog << " [options] file.rom\n"
<< "Options:\n"
<< " --verbose extra diagnostics\n"
<< " --vendor-only only detect PCIR vendor/device\n"
<< " --dump-window OFF LEN hex dump at absolute offset OFF, length LEN\n"
<< " --dump-on-hit LEN hex dump LEN bytes at each pattern hit\n";
}
static std::size_t parse_number(const std::string& s) {
try {
std::size_t pos = 0;
unsigned long long v = std::stoull(s, &pos, 0); // 0 => 0xHEX lub dec
if (pos != s.size()) throw std::invalid_argument("trailing");
return static_cast(v);
} catch (...) {
std::cerr << "Invalid number: " << s << "\n";
std::exit(2);
}
}
template
static bool match_at(const std::vector& buf, std::size_t pos, const PatternT& pat) {
return (pos + pat.size() <= buf.size())
&& std::equal(pat.begin(), pat.end(), buf.begin() + pos);
}
static void hex_dump(const std::vector& buf, std::size_t offset, std::size_t length) {
if (offset >= buf.size()) {
std::cout << "[WARN] dump offset beyond file size\n";
return;
}
const std::size_t end = std::min(offset + length, buf.size());
std::cout << "Hex dump [0x" << std::hex << offset << " .. 0x"
<< (end ? end - 1 : 0) << "] (" << std::dec << (end - offset) << " bytes):\n";
for (std::size_t i = offset; i < end; i += 16) {
std::cout << " " << std::hex << std::setw(6) << std::setfill('0') << i << ": ";
for (std::size_t j = 0; j < 16 && (i + j) < end; ++j) {
std::cout << std::setw(2) << std::setfill('0')
<< static_cast(buf[i + j]) << " ";
}
for (std::size_t j = (end > i ? end - i : 0); j < 16; ++j) std::cout << " ";
std::cout << " | ";
for (std::size_t j = 0; j < 16 && (i + j) < end; ++j) {
const char c = static_cast(buf[i + j]);
std::cout << (std::isprint(static_cast(c)) ? c : '.');
}
std::cout << std::dec << "\n";
}
std::cout << "\n";
}
// ------------------------------- PCIR ----------------------------------------
struct PCIRInfo {
bool found = false;
std::size_t offset = 0;
uint16_t vendor_id = 0;
uint16_t device_id = 0;
};
static PCIRInfo find_pcir(const std::vector& buf) {
PCIRInfo info;
for (std::size_t off = 0; off + 8 <= buf.size(); ++off) {
if (match_at(buf, off, PCIR_SIG)) {
info.found = true;
info.offset = off;
info.vendor_id = static_cast(buf[off+4] | (uint16_t(buf[off+5])<<8));
info.device_id = static_cast(buf[off+6] | (uint16_t(buf[off+7])<<8));
break;
}
}
return info;
}
static const char* vendor_name(uint16_t vid) {
switch (vid) {
case VENDOR_NVIDIA: return "NVIDIA";
case VENDOR_ATI: return "ATI/AMD";
case VENDOR_INTEL: return "INTEL";
default: return "Unknown";
}
}
// ------------------------- Heurystyka tabel VESA ------------------------------
struct VesaCluster {
std::size_t start = 0; // offset startu klastru
std::size_t stride = 0; // krok bajtów między wpisami
std::size_t entries = 0; // liczba wykrytych wpisów (kolejnych)
std::vector> modes; // zebrane pary
};
// szybki zestaw (w,h) -> klucz 32-bit do deduplikacji
static inline uint32_t pack_wh(uint16_t w, uint16_t h) {
return (uint32_t(w) << 16) | uint32_t(h);
}
static bool is_common_res(uint16_t w, uint16_t h) {
// ścisłe dopasowanie do listy – minimalizujemy false-positive
for (const auto& p : kCommonRes) {
if (p.first == w && p.second == h) return true;
}
return false;
}
static bool read_wh(const std::vector& buf, std::size_t off, uint16_t& w, uint16_t& h) {
if (off + 3 >= buf.size()) return false;
w = uint16_t(buf[off] | (uint16_t(buf[off+1])<<8));
h = uint16_t(buf[off+2] | (uint16_t(buf[off+3])<<8));
return true;
}
// Szuka klastrów par (w,h) z powtarzalnym stride i min. liczbą wpisów
static std::vectorfind_vesa_clusters(const std::vector & buf) {
std::vectorout;
const std::vectorstrides = {4,6,8,9,10,12,16,20,24,32};
const std::size_t max_span = 4096; // max. rozpiętość pojedynczego klastru
std::size_t i = 0;
while (i + 4 <= buf.size()) {
bool any_cluster = false;
for (std::size_t s : strides) {
uint16_t w=0,h=0;
if (!read_wh(buf, i, w, h)) continue;
if (!is_common_res(w,h)) continue;
// potwierdzaj kolejne wpisy par (w,h) co 's' bajtów
VesaCluster cl;
cl.start = i; cl.stride = s; cl.entries = 0;
std::size_t j = i;
std::setuniq;
while (j + 4 <= buf.size() && (j - i) <= max_span) {
uint16_t ww=0, hh=0;
if (!read_wh(buf, j, ww, hh)) break;
if (!is_common_res(ww,hh)) break;
cl.modes.emplace_back(ww,hh);
uniq.insert(pack_wh(ww,hh));
cl.entries++;
j += s;
}
// Minimalne progi, żeby uniknąć przypadkowych trafień:
// - co najmniej 3 kolejne wpisy
// - co najmniej 2 różne rozdzielczości w klastrze
if (cl.entries >= 3 && uniq.size() >= 2) {
out.push_back(cl);
any_cluster = true;
if (g_cfg.verbose) {
std::cout << "[DEBUG] VESA cluster at 0x" << std::hex << cl.start
<< " stride=" << std::dec << cl.stride
<< " entries=" << cl.entries << "\n";
}
// przeskocz za ten klaster, by nie raportować setek nałożonych wyników
i = j;
break;
}
}
if (!any_cluster) ++i;
}
return out;
}
// ------------------------------- main ----------------------------------------
int main(int argc, const char* argv[]) {
// CLI
std::string filepath;
for (int i = 1; i < argc; ++i) {
const std::string a = argv[i];
if (a == "--verbose") g_cfg.verbose = true;
else if (a == "--vendor-only") g_cfg.vendor_only = true;
else if (a == "--dump-window") {
if (i + 2 >= argc) { print_usage(argv[0]); return 2; }
g_cfg.dump_window = true;
g_cfg.dump_offset = parse_number(argv[++i]);
g_cfg.dump_length = parse_number(argv[++i]);
} else if (a == "--dump-on-hit") {
if (i + 1 >= argc) { print_usage(argv[0]); return 2; }
g_cfg.dump_on_hit_len = parse_number(argv[++i]);
} else if (!a.empty() && a[0] == '-') {
print_usage(argv[0]); return 2;
} else {
filepath = a;
}
}
if (filepath.empty()) { print_usage(argv[0]); return 1; }
std::cout << "Attempting to open " << filepath << "\n";
// Wczytanie pliku
std::ifstream f(filepath.c_str(), std::ios::binary);
if (!f) { std::cerr << "Error: cannot open file\n"; return 1; }
f.seekg(0, std::ios::end);
std::streamoff end = f.tellg();
if (end < 0) { std::cerr << "Error: tellg() failed\n"; return 1; }
const std::size_t length = static_cast(end);
f.seekg(0, std::ios::beg);
std::vectorbuf(length);
if (length) {
f.read(reinterpret_cast(buf.data()), static_cast (length));
if (f.gcount() != static_cast(length)) {
std::cerr << "Error: could not read full file\n"; return 1;
}
}
std::cout << "Length: " << length << " bytes\n";
if (g_cfg.dump_window) {
hex_dump(buf, g_cfg.dump_offset, g_cfg.dump_length);
}
// PCIR
PCIRInfo pcir = find_pcir(buf);
if (pcir.found) {
std::cout << "[INFO] PCIR at 0x" << std::hex << pcir.offset << std::dec
<< " -> Vendor: 0x" << std::hex << pcir.vendor_id
<< " (" << vendor_name(pcir.vendor_id) << ")"
<< ", Device: 0x" << pcir.device_id << std::dec << "\n";
} else {
std::cout << "[WARN] PCIR not found – vendor unknown\n";
}
if (g_cfg.vendor_only) return 0;
// Wzorzec NVIDIA (długi)
int nNVIDIA = 0;
for (std::size_t idx = 0; idx < length; ++idx) {
if (match_at(buf, idx, NVIDIA_PATTERN)) {
++nNVIDIA;
std::cout << "Found " << nNVIDIA << ". possible NVIDIA Pattern at 0x"
<< std::hex << idx << std::dec
<< " (Decimal: " << idx << ")\n";
if (g_cfg.dump_on_hit_len) {
hex_dump(buf, idx, std::min(g_cfg.dump_on_hit_len, length - idx));
}
const std::size_t limit = std::min(idx + NVIDIA_TABLE_SIZE, length);
for (std::size_t idy = idx; idy + 1 < limit; idy += NVIDIA_ENTRY_SIZE) {
if (buf[idy] == 0x00 && buf[idy+1] == 0x00) {
std::cout << "\tEmpty Table at 0x" << std::hex << idy << std::dec
<< " (Decimal: " << idy << ")\n";
}
}
}
}
// Klastry VESA (tu trafimy m.in. to miejsce, które wcześniej etykietowałeś jako „ATI”)
auto clusters = find_vesa_clusters(buf);
int cluster_idx = 0;
for (const auto& cl : clusters) {
++cluster_idx;
std::cout << "Probable VESA resolution table #" << cluster_idx
<< " at 0x" << std::hex << cl.start << std::dec
<< " (stride=" << cl.stride
<< ", entries=" << cl.entries << ")\n";
// Wypisz do 12 pierwszych unikalnych rozdzielczości
std::setseen;
int shown = 0;
for (const auto& m : cl.modes) {
uint32_t key = pack_wh(m.first,m.second);
if (!seen.insert(key).second) continue;
std::cout << " - " << m.first << "x" << m.second << "\n";
if (++shown >= 12) break;
}
if (g_cfg.dump_on_hit_len) {
hex_dump(buf, cl.start, std::min(g_cfg.dump_on_hit_len, length - cl.start));
}
}
// Podsumowanie w duchu oryginalnego kodu
if ((pcir.vendor_id == VENDOR_NVIDIA && nNVIDIA >= 1) || (!pcir.found && nNVIDIA >= 1)) {
std::cout << "Correct number of finds\nMod should be working\n";
} else if (clusters.empty() && nNVIDIA == 0) {
std::cout << "Warning: no NVIDIA pattern and no VESA clusters found.\n";
}
return 0;
}
do tego patcher wybranej rozdzielczości.
./ana8 vpc.rom
Attempting to open vpc.rom
Length: 49152 bytes
[WARN] PCIR not found ▒ vendor unknown
Warning: no NVIDIA pattern and no VESA clusters found.
./ana8 vmware.rom
Attempting to open vmware.rom
Length: 32768 bytes
[INFO] PCIR at 0x100 -> Vendor: 0x15ad (Unknown), Device: 0x405
[INFO] ROM image length (from PCIR): 32768 bytes
Probable VESA resolution table #1 at 0x63ee (stride=20, entries=21)
- 640x400
- 640x480
- 800x600
...
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Tak, poproszę o dodanie --print-offsets
Popraw też szukanie tabel w biosach, które nie mają nagłówka PCIR np. MS VPC 2007 oraz aby rozpoznawał bios wideo VMware czyli PCIR 15ad bo teraz jest jako Unknown:
Tak wyglądają wyniki skanowania biosów vpc i vmware:
./ana8 vpc.rom
Attempting to open vpc.rom
Length: 49152 bytes
[WARN] PCIR not found ▒ vendor unknown
Warning: no NVIDIA pattern and no VESA clusters found.
./ana8 vmware.rom
Attempting to open vmware.rom
Length: 32768 bytes
[INFO] PCIR at 0x100 -> Vendor: 0x15ad (Unknown), Device: 0x405
[INFO] ROM image length (from PCIR): 32768 bytes
Probable VESA resolution table #1 at 0x63ee (stride=20, entries=21)
- 640x400
- 640x480
- 800x600
...
Probable resolution table #1 at 0x2db0 (stride=36, entries=5, endian=LE)
- 640x350
- 640x480
- 800x600
- 1280x1024
- 1600x1200
Probable VESA resolution table #1 at 0x2dc2 (stride=9, entries=3)
- 640x400
- 640x480
Probable VESA resolution table #2 at 0x2def (stride=9, entries=13)
- 800x600
- 1024x768
- 1280x1024
- 1280x800
- 1400x1050
- 1440x900
- 1600x1200
- 1680x1050
- 1920x1200
- 2048x1536
Gelip napisał:Bezpośrednia odpowiedź@ElektrodaBot
Działa tylko wykrywanie Vendor VMware
Nie wykrywa tabel w biosie vpc.rom
Coś się popsuło w wyświetlaniu tabel w biosie 6200DSUB.ROM - tylko kilka i jakieś złe bo np. 640x350 ???
Probable resolution table #1 at 0x2db0 (stride=36, entries=5, endian=LE)
- 640x350
- 640x480
- 800x600
- 1280x1024
- 1600x1200
poprzednio wyświetlał dobrze:
Probable VESA resolution table #1 at 0x2dc2 (stride=9, entries=3)
- 640x400
- 640x480
Probable VESA resolution table #2 at 0x2def (stride=9, entries=13)
- 800x600
- 1024x768
- 1280x1024
- 1280x800
- 1400x1050
- 1440x900
- 1600x1200
- 1680x1050
- 1920x1200
- 2048x1536
W załączniku biosy vpc i vmware.