logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak przekonwertować kod źródłowy Mac OS (C++) do działania na Linuxie?

Gelip 20 Gru 2025 17:17 912 55
Najlepsze odpowiedzi

Jak przenieść kod źródłowy aplikacji z macOS/C++ na Linuxa?

Nie da się po prostu „przekonwertować macOS na Linuxa”; trzeba portować samą aplikację, zastępując Apple‑owe API (np. Cocoa/AppKit, Core* itp.) odpowiednikami linuksowymi i ponownie ją skompilować [#21785796] Jeśli aplikacja ma GUI, najrozsądniej przepisać warstwę interfejsu na framework wieloplatformowy, np. Qt, GTK, wxWidgets, Electron albo Flutter [#21785796] Dla kodu w C/C++ warto wydzielić warstwę platformową i użyć warunkowej kompilacji `#if defined(__APPLE__)` / `#if defined(__linux__)`, a zależności typu FSEvents→inotify, kqueue→epoll, Keychain→libsecret i LaunchServices→xdg-open/systemd user units zastąpić linuksowymi odpowiednikami [#21785796] Można też użyć Darling do uruchamiania części binariów Darwin na Linuksie, ale to głównie działa dla CLI i ma ograniczenia dla GUI [#21785796]
Wygenerowane przez model językowy.
  • #2 21785796
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @ElektrodaBot
    Jak przerobić kod źródłowy Mac OS na Linux?
    Bezpośrednia odpowiedź
    - Nie da się „przerobić kodu źródłowego Mac OS (macOS) na Linux” w sensie konwersji samego systemu operacyjnego – większość macOS jest zamknięta i chroniona (do wglądu jest tylko Darwin). Realnym celem jest portowanie Twojej aplikacji z macOS na Linux albo uruchamianie binariów przez warstwę kompatybilności.
    - Jeśli masz kod źródłowy aplikacji: portowanie polega na zastąpieniu API Apple (Cocoa/AppKit, Core* itd.) odpowiednikami linuksowymi, dostosowaniu wywołań systemowych i ponownej kompilacji na Linuksie.
    - Alternatywy: warstwa kompatybilności Darling (CLI – dość dobrze, GUI – ograniczenia), wirtualizacja macOS (z zastrzeżeniami licencyjnymi Apple), napisanie GUI na frameworku wieloplatformowym (Qt/GTK/wx/Electron/Flutter).
    - Daj więcej szczegółów (język, frameworki, co aplikacja robi), a dopasuję konkretne kroki i łatki.

    Szczegółowa analiza problemu

    1) Co właściwie chcesz zrobić – trzy scenariusze
    - Port aplikacji z macOS na Linux (najczęstszy i sensowny przypadek).
    - Uruchamianie istniejących binariów macOS na Linuksie (Darling – głównie narzędzia tekstowe).
    - „Przeróbka macOS na Linux” (nierealne: różne jądra, licencje, formaty binarne).

    2) Kluczowe różnice techniczne macOS vs Linux, które decydują o portowaniu
    - Jądro i syscalle: XNU (Mach+BSD) vs Linux (monolit). Inny model IPC, wątki, pamięć.
    - Format binarny: Mach-O vs ELF; inny loader (dyld vs ld-linux).
    - Frameworki: Cocoa/AppKit/Quartz/Metal/CoreAudio/LaunchServices/Keychain/TCC – brak ich na Linuksie.
    - Środowisko graficzne: WindowServer/Quartz vs X11/Wayland; różne modele zdarzeń i kompozycji.

    3) Strategia portowania aplikacji – praktyczny plan
    Krok 0: Minimalizacja ryzyka
    - Wydziel „warstwę platformową”: wszystkie miejsca zależne od macOS schowaj za interfejsami (np. IFileWatcher, IKeychain, ITrayIcon).
    - Zadbaj o zautomatyzowany build i testy (CMake/Meson + CI w kontenerze).

    Krok 1: Inwentaryzacja zależności
    - Przejrzyj importy/headers: Cocoa/AppKit/Foundation/CoreFoundation/CoreGraphics/CoreAudio/AVFoundation/IOKit/Metal/Dispatch.
    - Zmapuj użycia macOS-specyficzne (np. FSEvents, kqueue, Launch Services, Keychain, NSWorkspace, NSOpenPanel).
    - Na macOS sprawdź zależności: otool -L binarka; w kodzie grep na „<Cocoa/…>”, „<AppKit/…>”, „<Core…>”.

    Krok 2: Dobór zamienników na Linuksie
    - GUI: AppKit/Cocoa → Qt 6, GTK 4, wxWidgets, Electron/Flutter (GNUStep istnieje, ale AppKit jest niepełny – do prostych GUI może wystarczyć, do złożonych zwykle nie).
    - Foundation/CoreFoundation:
    - C/C++: POSIX/glibc + GLib (kontenery, pętle zdarzeń) lub bezpośrednio C++17/20.
    - Objective‑C: GNUstep Base (libobjc2 + Foundation-compat).
    - Swift: swift-foundation (corelibs), ale brak AppKit; UI ≠ przenośne.
    - Zdarzenia plików: FSEvents → inotify (libinotify).
    - Watchery/IO multiplexing: kqueue → epoll (libuv/libevent/libev).
    - Równoległość: Grand Central Dispatch → libdispatch na Linuksie (dostępna), ewentualnie pthreads/C++ std::thread/async.
    - Grafika: CoreGraphics/Quartz → Cairo/Skia; Metal → Vulkan/OpenGL (przepisanie warstwy renderingu lub użycie bibliotek wielozapleczowych: bgfx, wgpu).
    - Audio/Video: CoreAudio/AVFoundation → ALSA/PipeWire + GStreamer/FFmpeg.
    - Integracja powłoki: LaunchServices/NSWorkspace → xdg-open, .desktop, systemd user units.
    - Bezpieczeństwo/klucze: Keychain → libsecret/KWallet.
    - Powiadomienia/system tray: NSUserNotification/NSStatusItem → libnotify + zasoby DE (KStatusNotifierItem, AppIndicator).

    Krok 3: Warunkowanie kompilacji i adaptacje kodu
    - Preprocesor:
    - C/C++:
    #if defined(__APPLE__)
    // implementacja dla macOS
    #elif defined(__linux__)
    // implementacja dla Linux
    #endif
    - Swift:
    #if os(macOS)
    // AppKit / Cocoa
    #elseif os(Linux)
    // Foundation + własny backend (np. GTK przez SwiftGtk/Qt przez SwiftQt)
    #endif
    - Przykłady typowych zmian:
    - Ścieżki i katalogi: /Users/u → /home/u; preferuj XDG dirs (xdg-user-dirs).
    - Pliki dynamiczne: libX.dylib → libX.so; usuwanie @rpath/@loader_path.
    - Watchery: wrapper „FileWatcher” z backendami FSEvents/inotify.
    - Sieć: preferuj cURL/Boost.Beast/SwiftNIO zamiast NSURLSession (na Linuksie API bywa inne).

    Krok 4: Budowa na Linuksie
    - Toolchain:
    - C/C++: gcc/clang + CMake/Meson + pkg-config.
    - Objective‑C: clang + libobjc2 + GNUstep Base (sudo apt install gnustep-devel; kompilacja przykładowa: clang `gnustep-config --objc-flags` main.m -o app `gnustep-config --base-libs`).
    - Swift: oficjalny toolchain Swift na Linuksa; build przez SwiftPM (swift build). Pamiętaj: brak AppKit; Foundation i Dispatch są, ale nie 1:1 z macOS.
    - Konteneryzacja: Docker/Podman z bazowym obrazem (np. Ubuntu/Fedora), aby uniezależnić się od dystrybucji i odtworzyć środowisko.

    Krok 5: Testy i diagnostyka
    - ldd/readelf – weryfikacja zależności ELF.
    - strace/ltrace – tropienie różnic w syscalach.
    - Valgrind/Sanitizers – błędy pamięci, wyścigi.
    - perf/ftrace – profilowanie wydajności.

    Krok 6: Pakietowanie i integracja
    - Zależnie od dystrybucji: .deb/.rpm/Flatpak/Snap/AppImage; integracja z desktopem (pliki .desktop, ikony, MIME).

    4) Darling, wirtualizacja i inne obejścia
    - Darling: warstwa zgodności dla uruchamiania narzędzi darwinowych na Linuksie. Dobra do CLI i prostych narzędzi; złożone GUI (AppKit/Metal) – ograniczone. To nie emulacja, tylko reimplementacja ABI; nie rozwiązuje problemu przeniesienia Twojej aplikacji z użyciem frameworków Apple.
    - Wirtualizacja macOS na Linuksie: technicznie możliwa (QEMU/KVM/komercyjne hyperwizory), ale pamiętaj o licencji Apple – zgodnie z EULA macOS możesz legalnie wirtualizować na sprzęcie Apple.
    - „Magiczne konwertery”: narzędzia jednorazowe istnieją dla konkretnych gier/projektów; nie są ogólnym rozwiązaniem portingu.

    5) Najczęstsze pułapki przy portowaniu
    - Zależność od AppKit/Storyboardów/XIB – GUI trzeba przepisać.
    - Metal/AVFoundation/IOKit – brak bezpośrednich odpowiedników, wymaga przeprojektowania.
    - Różnice w Foundation/Dispatch (zachowania i API brzegowe).
    - Watchery (FSEvents) i powiadomienia systemowe – inne modele na Linuksie.
    - Uprawnienia/TCC/Keychain – konieczność alternatyw (polkit, libsecret).

    6) Minimalny szkielet wieloplatformowy (CMake, C++)
    - CMakeLists.txt (detekcja platformy):
    if(APPLE)
    target_compile_definitions(app PRIVATE PLATFORM_MACOS)
    elseif(UNIX AND NOT APPLE)
    target_compile_definitions(app PRIVATE PLATFORM_LINUX)
    endif
    - Kod:
    #if defined(PLATFORM_MACOS)
    // FSEvents, Cocoa
    #elif defined(PLATFORM_LINUX)
    // inotify, Qt/GTK
    #endif

    7) Aspekty prawne i zgodność
    - Nie portujesz „macOS”, tylko własną aplikację. Nie kopiuj zamkniętych komponentów Apple ani ich nie dekompiluj. Sprawdź licencje zależności (GPL/LGPL/MIT/BSD) i zgodność z dystrybucją binarną na Linuksie.

    Checklista portu (skrót)
    - Zidentyfikuj zależności Apple i wybierz zamienniki na Linuksie.
    - Wydziel warstwę platformową i wprowadź ifdef/os(...) dla różnic.
    - Przepisz GUI (Qt/GTK/…).
    - Zastąp FSEvents→inotify, kqueue→epoll, Keychain→libsecret, LaunchServices→xdg-open/systemd.
    - Zbuduj na Linuksie (CMake/Meson/SwiftPM), skonfiguruj CI w kontenerze.
    - Testuj (sanitizers/valgrind/strace), pakietuj (Flatpak/Snap/Deb/RPM).

    Pytania doprecyzowujące do Ciebie
    - Jaki język i stos technologiczny? (Objective‑C/Swift/C/C++, jakie frameworki Apple?)
    - Czy aplikacja ma GUI? Jeśli tak, jak złożone? (storyboardy, custom drawing, Metal/OpenGL?)
    - Czy używasz IOKit, AVFoundation, CoreAudio, Keychain, FSEvents lub innych specyficznych API?
    - Czy masz testy jednostkowe/integracyjne, aby weryfikować poprawność po porcie?
    - Na jaką dystrybucję Linuksa celujesz (Ubuntu/Fedora/Debian/Arch)? Jaki format pakietu?
    - Czy akceptowalne jest przepisanie warstwy UI na Qt/GTK lub użycie innego frameworka wieloplatformowego?

    Proponowane następne kroki
    - Podeślij fragmenty kodu (listę importów, CMakeLists/Xcodeproj, główne punkty wejścia) i wskaż kluczowe funkcje aplikacji. Zaproponuję konkretną mapę „API Apple → Linux” oraz szkic łat/patchy pod Twoją bazę kodu.
    - Jeśli to Swift lub Objective‑C – wskażę gotowe minimalne konfiguracje (SwiftPM na Linuksie / GNUstep Base + komenda kompilacji) i przygotuję „Hello, Linux” z Twoimi zależnościami.

    Zastrzeżenie: bez wglądu w konkretny projekt niektóre szczegóły (np. zakres wsparcia GNUStep/libdispatch/Swift Foundation dla Twoich użyć API) mogą wymagać weryfikacji i prototypu na docelowej dystrybucji Linuksa.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #3 21785804
    LEDówki
    Poziom 43  
    Posty: 9493
    Pomógł: 1312
    Ocena: 2562
    Inne AI twierdzi, że nie trzeba tego przerabiać. Wskazuje kilka błędów, ale przenośność niby jest, bo wszystkie instrukcje są ze standardu C++.
  • #5 21785821
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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;
    }
    Bezpośrednia odpowiedź
    - Tego konkretnego kodu C++ nie trzeba „przerabiać z macOS na Linux” – używa wyłącznie standardowej biblioteki C++ i zadziała na Linuksie po kompilacji.
    - Problemem są błędy w samym kodzie (niezależne od systemu): błędne porównania wskaźnika zamiast bajtów, ryzyko wyjścia poza bufor, niepoprawna arytmetyka wskaźników, brak sprawdzania błędów I/O i potencjalny wyciek pamięci.
    - Poniżej masz poprawiony, przenośny wariant, instrukcje kompilacji na Linuksie i lista kluczowych poprawek.

    ---

    Co wymaga poprawy (niezależnie od OS)
    1) Porównywanie wskaźnika zamiast danych
    - Było: if ((buffer == 0x00) && (buffer == 0x04) …) – porównujesz adres, nie zawartość.
    - Powinno być: buffer[idx] … lub porównanie okna bajtów z wzorcem (memcmp / std::equal).

    2) Granice bufora
    - Pętla musi zapewniać, że idx + rozmiar_wzorca ≤ length, inaczej OOB read i potencjalny SIGSEGV.

    3) Arytmetyka wskaźników
    - Było: mode_ptr = (vbios_mode*) buffer + idx; (przesuwa o idx struktur, nie bajtów).
    - Powinno być: mode_ptr = (vbios_mode*) (buffer + idx); (ale i tak bezpieczniej w ogóle nie rzutować i pracować na bajtach).

    4) Zarządzanie pamięcią i I/O
    - Sprawdź, czy plik się otworzył i czy odczytano pełną długość.
    - Zamiast new[]/delete[] użyj std::vector<uint8_t>.
    - Nie używaj int do długości pliku; użyj size_t/streamsize.

    5) Braki w nagłówkach
    - Używasz uint16_t – dołącz <cstdint>.

    6) Czytelność i „magiczne liczby”
    - Stałe 513 i 32 nazwij (np. NVIDIA_TABLE_SIZE, ENTRY_SIZE), a wzorce bajtów wynieś do stałych/tablic.

    ---

    Poprawiony kod (przenośny Linux/macOS)

    Skupia się na:
    - bezpiecznym wczytaniu pliku do std::vector<uint8_t>,
    - szukaniu wzorców bajtów przez std::equal,
    - kontrolach zakresów,
    - czytelnym logowaniu.

    Składnia GCC/Clang; nie używam tu rzutowań na „spakowane” struktury, bo i tak operujesz na surowych bajtach.

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Uwagi:
    - Zrezygnowałem z rzutowań na vbios_mode/bdb_header, bo i tak skanujesz surowe bajty. Jeśli faktycznie chcesz czytać struktury, rozważ najpierw memcpy do lokalnej struktury i jawne traktowanie endianness.
    - Jeżeli chcesz jednocześnie wspierać MSVC, a używasz „spakowanych” struktur, zastosuj #pragma pack(push, 1)/#pragma pack(pop) zamiast __attribute__((packed)).

    ---

    Kompilacja na Linuksie (GCC/Clang)
    - GCC:
    - g++ -std=c++17 -O2 -Wall -Wextra -Wpedantic -o AnalyseVBIOS analyse_vbios.cpp
    - Clang:
    - clang++ -std=c++17 -O2 -Wall -Wextra -Wpedantic -o AnalyseVBIOS analyse_vbios.cpp
    - Diagnostyka (polecam podczas prac nad binarnymi parserami):
    - g++ -std=c++17 -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer -o AnalyseVBIOS analyse_vbios.cpp

    Uruchomienie:
    - ./AnalyseVBIOS plik_vbios.rom

    ---

    Dlaczego „AI mówi, że nie trzeba przenosić” ma tylko częściowo rację
    - Z punktu widzenia portowalności – racja: użyty C++ i standardowe nagłówki są przenośne.
    - Ale kod w obecnym kształcie działałby tak samo źle na macOS, Linuksie i Windows, bo błędy są czysto logiczne (wskaźniki, zakresy, I/O). Ich naprawa jest konieczna niezależnie od systemu.

    ---

    Wskazówki merytoryczne do dalszego ulepszania
    - Jeżeli naprawdę analizujesz VBIOS, rozważ parsowanie według struktur nagłówkowych (ROM header 0x55AA, wskaźnik do „PCIR”, itp.) zamiast „magicznych wzorców”. To daje stabilność między wersjami BIOSów.
    - Ustal precyzyjnie wzorce ATI/NVIDIA (offsety, długości) – obecnie przyjąłem minimalny ciąg 0x20 0x03 0x58 0x02; jeśli masz bardziej szczegółową specyfikację, podmienię definicje i warunki.
    - Dokładaj asercje i testy jednostkowe na wycinkach znanych obrazów ROM, aby nie „strzelać” poza bufor dla nietypowych plików.
    - Zadbaj o logowanie w trybie verbose i możliwość dumpu znalezionych bloków do plików binarnych (ułatwia weryfikację).

    ---

    Pytania doprecyzowujące
    - Jakie dokładnie wzorce (ciągi bajtów i ich długości) uznajesz za „tryb NVIDIA/ATI”? Masz referencję/specyfikację?
    - Czy oczekujesz parsowania konkretnych tabel (np. PCIR, VBT/BDB dla iGPU Intela), czy tylko skanowania wzorców?
    - Jak duże są typowe pliki ROM, na których pracujesz (dla doboru bufora i ewentualnego mapowania pliku do pamięci)?
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #6 21785878
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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
  • #7 21785891
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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
    Bezpośrednia odpowiedź
    - Błąd „cc1plus: error: main.cpp: Value too large for defined data type” nie wynika z kodu C++. To błąd systemowy (EOVERFLOW) przy próbie odczytu pliku źródłowego przez kompilator – zwykle na udziale sieciowym (SMB/CIFS/NFS), w WSL na /mnt/<dysk> albo na bind-mount/overlay (np. Docker na XFS).
    - Na szybko: skopiuj plik do lokalnego katalogu na ext4 (np. /home/… albo /tmp) i tam skompiluj. Alternatywnie podaj kod kompilatorowi przez stdin (patrz niżej).
    - Poprawiony kod z wcześniejszego posta jest przenośny; po naprawie środowiska kompiluje się standardowym: g++ -std=c++17 -O2 -Wall -Wextra -o AnalyseVBIOS main.cpp

    ---

    Szybka naprawa w 3 minuty (obejście EOVERFLOW)
    1) Skopiuj plik na lokalny dysk (poza udziałem SMB/NFS/WSL /mnt/c, itp.):
    - mkdir -p ~/build && cp main.cpp ~/build/
    - cd ~/build && g++ -std=c++17 -O2 -Wall -Wextra -o AnalyseVBIOS main.cpp

    2) Jeśli nadal masz EOVERFLOW, podaj kod przez stdin (omija stat() na ścieżce pliku):
    - cat main.cpp | g++ -std=c++17 -O2 -Wall -Wextra -x c++ - -o AnalyseVBIOS

    3) Alternatywnie użyj innego kompilatora (jeżeli Twój g++ jest 32‑bit lub bardzo stary):
    - clang++ -std=c++17 -O2 -Wall -Wextra -o AnalyseVBIOS main.cpp

    ---

    Diagnoza – znajdź przyczynę (co sprawdzić)
    - Czy plik leży na udziale sieciowym/NTFS/WSL?
    - WSL: jeśli pracujesz w /mnt/c lub /mnt/d – przenieś projekt do /home/USER/proj.
    - SMB/CIFS: sprawdź opcje montowania; problem często znika z noserverino,nounix.
    - NFS v3: bywa EOVERFLOW na 32‑bitowych narzędziach; użyj NFSv4 lub 64‑bit toolchain.
    - Docker/Podman na XFS: bind‑mount na XFS (niektóre konfiguracje) potrafi wywołać ten błąd – sprawdź na zwykłym katalogu ext4 poza kontenerem.

    Polecenia pomocnicze:
    - df -T . # typ systemu plików w bieżącym katalogu
    - mount | grep -E 'cifs|nfs|xfs|overlay|drvfs'
    - file "$(which g++)" # czy g++ jest 32‑ czy 64‑bit
    - g++ -dumpmachine # docelowa architektura (np. x86_64-linux-gnu)
    - ls -li main.cpp; stat main.cpp

    Uwaga na mity:
    - Dodanie #define _FILE_OFFSET_BITS 64 w Twoim źródle nie naprawi EOVERFLOW zgłaszanego przez cc1plus przy otwieraniu samego pliku main.cpp. To #define wpływa na Twoją aplikację, nie na binarny kompilator.

    ---

    Poprawny, przenośny kod (C++17)
    Wklej do nowego pliku na lokalnym dysku (nie na udziale) i skompiluj:

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Kompilacja:
    - g++ -std=c++17 -O2 -Wall -Wextra -o AnalyseVBIOS main.cpp
    - lub: clang++ -std=c++17 -O2 -Wall -Wextra -o AnalyseVBIOS main.cpp

    ---

    Dodatkowe wskazówki praktyczne
    - WSL (Windows Subsystem for Linux): kompiluj w katalogu pod /home/… (system plików ext4 WSL), nie w /mnt/c – to eliminuje mnóstwo problemów z inode/atrybutami.
    - SMB/CIFS: jeżeli pracujesz z zasobu Windows, rozważ w /etc/fstab: … cifs … ,noserverino,nounix,vers=3.0 …
    - Docker/Podman: jeżeli budujesz w kontenerze z bind‑mount katalogu z hosta na XFS i trafiasz na EOVERFLOW, sprawdź, czy ten sam build działa bez kontenera lub na katalogu ext4.

    ---

    Co jeszcze potrzebuję, aby precyzyjnie wskazać przyczynę
    Podeślij proszę wynik:
    - uname -a
    - file "$(which g++)" && g++ -dumpmachine && g++ -v | tail -n 1
    - df -T . && mount | grep -E 'cifs|nfs|xfs|overlay|drvfs'
    - ls -li main.cpp && stat main.cpp

    Na tej podstawie powiem dokładnie, czy winny jest udział sieciowy, WSL, stary 32‑bitowy toolchain czy konfiguracja FS.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #8 21785918
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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:
    Spoiler:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    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
    
  • #9 21785930
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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
    Bezpośrednia odpowiedź
    - Super – wynik pokazuje, że poprawiony kod działa prawidłowo w Twoim środowisku. Błąd „Value too large for defined data type” wynikał z FS/konfiguracji, nie z C++.
    - Uwaga praktyczna: króciutki 4‑bajtowy wzorzec „ATI” może dawać fałszywe trafienia. Rekomenduję dodać sanity‑check (np. „PCIR” + vendor ID) albo wydłużyć wzorzec.
    - Poniżej podaję: jak zweryfikować trafienia w hex, jak dołożyć detekcję „PCIR” (vendor/device), oraz jak ustawić CIFS, by unikać podobnych problemów.

    ---

    Szczegółowa analiza i rekomendacje

    1) Szybka weryfikacja tego konkretnego ROM‑u
    - Sprawdź otoczenie offsetów z logu:
    - xxd -s 0x94b0 -l 64 6200DSUB.ROM
    - xxd -s 0x2de0 -l 64 6200DSUB.ROM
    - Zweryfikuj, że przy 0x94b3 faktycznie leży oczekiwana sekwencja (Twoja „NVIDIA pattern”).
    - „ATI Mode” przy karcie NV to najpewniej zbieżność – 4 bajty są zbyt krótkie, by wykluczyć przypadkowe dopasowania.

    2) Dodaj detekcję „PCIR” (vendor/device) – zmniejsza fałszywe trafienia
    Wstaw do programu prosty skaner „PCIR” i wypisz VID:PID. Dla NVIDIA/AMD/Intel będą to odpowiednio 0x10DE/0x1002/0x8086.

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    - Jeśli widzisz VID:0x10DE – potwierdza to NVidia; 0x1002 → AMD/ATI; 0x8086 → Intel.
    - Możesz warunkowo akceptować dopasowania „NVIDIA pattern” tylko wtedy, gdy wcześniej znalazłeś PCIR z VID=0x10DE.

    3) Uczyń detekcję ATI mniej podatną na zbieżności
    - Wydłuż wzorzec (np. 6–8 bajtów) albo zabezpiecz pozycją względem znanych struktur (nagłówek ROM 0x55 0xAA → wskaźnik na PCIR → region tabel).
    - Alternatywnie użyj std::search z większym wzorcem (jest w C++11); dla późniejszych optymalizacji można pomyśleć o własnym Boyer‑Moore.

    4) Opcje montowania CIFS, aby unikać EOVERFLOW (gdy pracujesz na udziale)
    - Przykład montowania:
    - sudo mount -t cifs //SERVER/SHARE /mnt/mp -o username=USER,vers=3.0,noserverino,nounix,uid=$(id -u),gid=$(id -g),file_mode=0644,dir_mode=0755
    - Kluczowe: noserverino (uniknięcie „dziwnych” inode), nounix (bez niedoróbek rozszerzeń), jawne vers=3.0.

    5) Drobne usprawnienia kodu (stabilność)
    - Dodaj tryb weryfikacji: --verify-hex 0xOFFSET -l LEN (drukuje hexdump okna wokół trafienia).
    - Zadbaj o flagi testowe podczas developmentu:
    - g++ -std=c++17 -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer …
    - Jeśli będziesz przetwarzał większe ROM‑y lub wiele plików – rozważ mmap (mniejsze kopiowanie), choć przy 63 kB nie ma to znaczenia.

    6) Uwaga na środowisko i wersje
    - Ubuntu 16.04.6 LTS ma EOL (bez wsparcia bezpieczeństwa). Gdy będziesz dalej rozwijał narzędzie, sugeruję przesiadkę na 22.04 LTS lub 24.04 LTS z nowszym g++/clang.
    - Jeśli kiedyś kompilacja na starszym g++ „marudzi” na -std=c++17, przełącz na -std=c++14 (ten kod i tak nie używa funkcji wyłącznie z C++17).

    ---

    Co mogę dorobić „na szybko”
    - Wersję z:
    - skanerem PCIR + vendor/device,
    - filtrem fałszywych „ATI Mode”,
    - przełącznikami CLI (np. --vendor-only, --dump-window, --json),
    - prostym testem sumy bajtowej obrazu ROM (sanity‑check).
    - Jeśli podeślesz jeszcze 1–2 pliki .ROM, dopasuję wzorce tak, aby minimalizować FP i przygotuję mały CMake + binarkę „ana”.

    Daj znać, czy dorzucić kod z PCIR i filtrem w całości – wstawię gotowy plik ana.cpp do skompilowania.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #11 21785990
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @ElektrodaBot
    Tak, chcę cały kod ana.cpp
    Bezpośrednia odpowiedź
    - Poniżej masz kompletny, gotowy do kompilacji plik ana.cpp z:
    - detekcją PCIR (VID/DID),
    - filtrem fałszywych trafień ATI (gating po vendor ID),
    - opcjami CLI: --verbose, --vendor-only, --dump-window OFFSET LEN, --dump-on-hit LEN, --color.
    - Kompilacja: g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
    - Uruchomienie (przykład): ./ana 6200DSUB.ROM

    Kod: ana.cpp
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Kompilacja i uruchomienie
    - GCC:
    - g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
    - Clang:
    - clang++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
    - Przykłady:
    - ./ana 6200DSUB.ROM
    - ./ana --vendor-only 6200DSUB.ROM
    - ./ana --verbose --dump-on-hit 64 6200DSUB.ROM
    - ./ana --dump-window 0x94b0 128 6200DSUB.ROM

    Co zmieniłem względem poprzedniej wersji
    - Dodano wykrywanie PCIR (VID/DID) i nazwę producenta.
    - Odfiltrowane „ATI Mode” na obrazach NVIDII (eliminuje fałszywe trafienia).
    - Dodane opcje CLI i hexdump trafień/okna.
    - Bezpieczne operacje na buforze, kontrola zakresów, komunikaty diagnostyczne.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #13 21786060
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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
    Bezpośrednia odpowiedź
    - Masz rację: w ROM-ie NVIDII może występować odrębna tablica trybów VESA w innym obszarze – wcześniejszy „ATI Mode” to po prostu wpis VESA (np. 800x600 = 0x0320/0x0258).
    - Poniżej daję kompletny ana.cpp, który:
    - wykrywa PCIR (Vendor/Device),
    - wykrywa „magiczny” wzorzec NVIDII (ten z Twojego starego kodu),
    - skanuje ROM w poszukiwaniu KLASTRÓW par szerokość×wysokość (VESA) z różnymi krokami (stride), wykrywając tabelę VESA niezależnie od producenta,
    - raportuje takie klastry jako „Probable VESA resolution table” zamiast „ATI Mode”.
    - Kompilacja: g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp

    ---

    ana.cpp (pełny kod)

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Jak to odpowiada na Twój przypadek (GeForce 6200)
    - W miejscach 0x2def, 0x2df8 i okolicach – zamiast „ATI Mode” zobaczysz teraz „Probable VESA resolution table …” z wyszczególnieniem wykrytych rozdzielczości (w tym 800x600).
    - W miejscu 0x94b3 nadal pojawi się trafienie długiego wzorca NVIDII oraz „Empty Table …” na kolejnych slotach – jak wcześniej.

    ---

    Wskazówki i dalsze ulepszenia
    - Heurystyka VESA opiera się na liście popularnych rozdzielczości oraz detekcji klastrów ze stałym stride. Jeśli chcesz rozszerzyć listę (np. o egzotyczne wpisy), dopisz pary do kCommonRes.
    - Jeżeli zależy Ci na 100% precyzji dla NVIDII, następnym krokiem jest parsowanie struktury BIT/DCB (NVIDIA BIOS tables) i chodzenie po wskaźnikach zamiast heurystyk – mogę dopisać moduł „find_bit()/parse_dcb()”.
    - Gdyby jakiś ROM dawał zbyt dużo „false positives”, podnieś progi w find_vesa_clusters (np. entries >= 4, uniq.size() >= 3) albo zawęź listę kCommonRes.

    Daj znać, jeśli chcesz wariant z JSON-em (np. do automatycznego post-processingu) lub z parserem BIT/DCB dla NVIDII – przygotuję.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #14 21786121
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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
  • #15 21786137
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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
    Bezpośrednia odpowiedź
    - Masz rację: mój skaner „klastrów (W,H)” złapał pary 16:10 (1280x800, 1440x900, 1680x1050, 1920x1200), które w tym ROM-ie nie należą do listy trybów VBE, więc to false‑positives.
    - Rozwiązanie: przechodzimy z heurystyki na „twarde” wykrywanie listy trybów VBE po numerach trybów (0x100, 0x101, …, 0xFFFF) obecnych w obrazie ROM. Dodatkowo filtry „strict” wyświetlą tylko rozdzielczości, które wynikają z tej listy VBE. Widziane „widescreeny” będzie można opcjonalnie pokazać przełącznikiem.
    - Poniżej daję kompletny ana.cpp: wykrywa PCIR, wzorzec NVIDIA, szuka list trybów VBE (po numerach), mapuje je na rozdzielczości i dopiero na tej podstawie filtruje znalezione „klastry VESA” (domyślnie usuwa 16:10/16:9).

    Kompilacja:
    - g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp

    Typowe uruchomienie:
    - ./ana 6200DSUB.ROM
    - ./ana --verbose 6200DSUB.ROM
    - ./ana --show-nonvbe 6200DSUB.ROM (pokaże także „widescreeny” spotykane w innych tabelach, niebędące VBE)

    ---

    ana.cpp (pełny kod – tryby VBE po numerach + filtr „strict”)
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Szczegółowa analiza problemu
    - Dlaczego widziałeś 1280x800/1440x900/1680x1050/1920x1200?
    - W ROM‑ie obok właściwej listy VBE istnieją inne struktury (np. timingowe, DFP/CVT/GTF, tablice inicjalizacji), w których pojawiają się pary bajtów odpowiadające „przypadkiem” wartościom rozdzielczości. Heurystyka „(W,H) co stały stride” potrafi je zebrać i błędnie uznać za tabelę VESA.
    - Jak to naprawiamy?
    - Najpierw szukamy „oficjalnej” listy trybów VBE: to sekwencja 16‑bitowych numerów (0x100, 0x101, …) zakończona 0xFFFF. Te numery mają ustalone znaczenie – mapujemy je na (W,H,BPP). To daje listę zgodną z Twoim modelist.com i vbeprobe.
    - Dopiero potem skanujemy klastry (W,H) i filtrujemy: domyślnie pokazujemy tylko te rozdzielczości, które są w wykrytej liście VBE (czyli znikają 16:10). Jeśli chcesz widzieć wszystko (także alternatywne tabele timingów), uruchamiasz z --show-nonvbe.
    - Co zobaczysz dla 6200DSUB.ROM:
    - „VBE mode list #1 …” z pozycjami odpowiadającymi Twojemu logowi (640x400, 640x480, 800x600, 1024x768, 1280x1024, 1400x1050, 1600x1200, 2048x1536 itd., wraz z bpp).
    - „Probable VESA resolution table …” w okolicy 0x2def – teraz, domyślnie, znikną 1280x800 i spółka. Pojawią się wyłącznie rozdzielczości z listy VBE. Widescreeny zobaczysz tylko przy --show-nonvbe (oznaczone etykietą [non-VBE]).

    ---

    Dalsze kroki (jeśli chcesz iść „na 100%” w NVIDIA)
    - Parsowanie struktur „BIT”/„DCB” (NVIDIA BIOS tables) zamiast heurystyk – pozwala chodzić po wskaźnikach i dostać dokładne tabele timingów dla poszczególnych wyjść (CRT/DFP/TV). Mogę dopisać moduł find_BIT()/parse_DCB() na Twoich próbkach ROM.
    - Eksport do JSON (--json), żeby łatwo porównać różne obrazy VBIOS.
    - Walidacja sumy kontrolnej obrazu ROM po modyfikacji.

    Daj znać, czy mam dorzucić wariant z parserem BIT/DCB lub dopasować mapę trybów VBE pod inne BIOS‑y, które masz pod ręką.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #16 21786142
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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]
    
  • #17 21786148
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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]
    Bezpośrednia odpowiedź
    Masz rację – poprzednia wersja była zbyt „luźna”: gdy nie znalazła jawnej listy trybów VBE (0x100.. zakończone 0xFFFF), przechodziła na heurystykę „(W,H) co stały stride” w całym ROM-ie i potrafiła dopasować śmieci (stąd 15x6700, 53903x352 itp.). 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.

    Poniżej masz „v4 strict”: kod ogranicza skan tylko do rzeczywistych tablic rozdzielczości, które spełniają jednocześnie:
    - stały stride (typowo 9 bajtów w NV4x),
    - wpisy są „rozsądne” (zakresy i proporcje 4:3, 5:4, 16:10, 16:9),
    - klaster zawiera co najmniej kilka klasycznych rozdzielczości VBE (np. 800x600, 1024x768, 1280x1024…).

    Domyślnie drukuje tylko klasyczne tryby VBE (takie jak w Twoich logach modelist.com/grub vbeprobe). Widescreeny (np. 1280x800, 1440x900, 1680x1050, 1920x1200), jeśli są w tej samej tablicy, pokaże tylko na żądanie przełącznikiem —show-extra. „Kosmiczne” liczby są odfiltrowane.

    Kompilacja:
    - g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp

    Uruchomienie (przykład):
    - ./ana 6200DSUB.ROM
    - ./ana --verbose 6200DSUB.ROM
    - ./ana --show-extra 6200DSUB.ROM
    - (opcjonalnie) ./ana --dump-window 0x2de0 128 6200DSUB.ROM

    ---

    ana.cpp (v4 strict – kotwica/klastry, filtry, brak śmieci)

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Co poszło nie tak wcześniej i co poprawia v4
    - „No explicit VBE mode list…” – znalezienie listy 0x100..0xFFFF bez uruchomienia BIOS-u bywa niemożliwe (NVIDIA rekonstruuje listę dynamicznie z tabel BIT/DCB). Usunąłem więc „twarde” oczekiwanie na taką listę.
    - „—show-nonvbe” łapało śmieci, bo heurystyka szukała klastrów w całym ROM-ie i akceptowała dowolne (W,H). Teraz:
    - filtrowane są zakresy (W 320..4096, H 200..4096, W%4==0),
    - akceptowane są tylko sensowne proporcje (4:3, 5:4, 16:10, 16:9, itp.) lub para z białej listy,
    - klaster musi zawierać min. 2 klasyczne rozdzielczości VBE i ≥4 wpisy,
    - wynik sortowany jest wg „score”, a nakładające się klastry są usuwane.

    Efekt: dla Twojego 6200DSUB.ROM wykryjesz dwa obszary w okolicach 0x2dc2 oraz 0x2def (stride=9). Domyślnie zobaczysz to, co raportują DOS/GRUB (VBE), a po —show-extra dostaniesz tylko realne „widescreeny” z tej samej tabeli – bez kosmicznych wartości.

    ---

    Dalsze kroki (jeśli chcesz absolutną precyzję)
    - Parser tabel NVIDIA BIT/DCB (zamiast heurystyki). To pozwoli „po wskaźnikach” dojść do sekcji z mode-timingami i listą trybów. Mogę to dopisać w kolejnej iteracji (potrzebny 1–2 pliki ROM do testów).
    - Eksport do JSON oraz przełącznik —start/—end do ręcznego zawężania zakresu skanu.

    Daj znać, czy ten „v4 strict” eliminuje śmieci u Ciebie i pokazuje tabelę przy 0x2def/0x2dc2. Jeśli chcesz, dorobię teraz parser BIT/DCB, żeby nie polegać na heurystyce w ogóle.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #18 21786174
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @ElektrodaBot
    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.

    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
    Załączniki:
    • 6200.zip (42 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #19 21786178
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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
    Bezpośrednia odpowiedź
    - Rozumiem Twoje wymagania: program ma jednoznacznie wskazać offsety tablic rozdzielczości w VBIOS (w szczególności w 6200DSUB.ROM), bez „widescreenów” z heurystyki i bez przełączników typu --show-extra.
    - Poniżej masz kompletny ana.cpp (v5), który:
    - wykrywa PCIR i długość obrazu ROM (do poprawnego liczenia checksumy),
    - wskazuje offset wzorca NVIDIA (ten z obszaru ~0x9xxx),
    - szuka i wypisuje offsety realnych tablic VESA: szukanie odbywa się wyłącznie po zestawie klasycznych rozdzielczości VBE (takich jak w Twoich logach modelist.com i grub vbeprobe), z wykryciem stałego kroku (stride; typowo 9 bajtów dla NV4x),
    - raportuje: „VESA table at 0x… (stride=…, entries=…, list: …)”.
    - Kompilacja: g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp
    - Uruchomienie: ./ana 6200DSUB.ROM

    Uwaga do modyfikacji 1024x768 → 1024x576: sama podmiana pary W×H (00 04 00 03 → 00 04 40 02) zwykle nie wystarczy – VBE/BIOS musi mieć zgodne timingi (CRTC/PLL). Objawy typu „kolorowe piksele” albo czarna ramka wynikają z niedopasowanych timingów lub pitchu. Poniżej podaję wskazówki, jak to ogarnąć.

    ---

    ana.cpp (v5 – wyszukiwanie offsetów tabel VESA, bez „wide”, z checksumą)
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Szczegółowa analiza problemu i wskazówki praktyczne

    1) Dlaczego program ma wskazywać dwa offsety
    - VESA table (lista klasycznych rozdzielczości VBE) – w Twoim 6200DSUB.ROM wypada w rejonie 0x2dc2/0x2def przy stride ≈ 9. To jest to, co enumerują narzędzia modelist.com oraz grub vbeprobe i co „widzi” Windowsowy vga.sys przez INT 10h/VBE.
    - NVIDIA‑spec table (0x9xxx) – to wewnętrzne tablice inicjalizacyjne/timingowe (wzorzec z Twoich logów przy 0x94b3). Nie jest to lista VBE rozdzielczości, ale warto ją zasygnalizować (stąd komunikat „NVIDIA pattern at 0x…”), abyś miał pełen obraz.

    2) Dlaczego usunąłem „widescreeny” z detekcji
    - W trybie sterownika vga.sys (VBE) Windows używa klasycznego zestawu VBE z BIOS‑u, który historycznie jest 4:3/5:4 (plus niskie tryby 320×…). W BIOS‑ach NVIDII bywają inne miejsca, gdzie pojawiają się „widescreeny” (timingi/DFP/TV), ale nie są częścią listy VBE. Dlatego detektor VESA ograniczyłem do zbioru klasycznych rozdzielczości – dzięki temu raportuje wyłącznie rzeczywiste tablice VBE (i ich offsety), a nie „jakieś” inne tabele.

    3) Twoja modyfikacja 1024x768 → 1024x576 i artefakty
    - Sama podmiana W×H zwykle nie aktualizuje:
    - timingu CRTC (front/back porch, sync width, total),
    - zegara pikseli/PLL,
    - pitchu (bytes per scanline) oraz powiązanych pól, jeśli dana implementacja VBE je bierze z tej samej struktury.
    - „Kolorowe piksele” i/lub czarna ramka to typowe objawy niedopasowania timingu/pitchu. Aby zrobić to poprawnie:
    - zidentyfikuj, czy przy Twojej tablicy W×H (stride=9) tuż obok nie ma towarzyszącej tablicy timingów (często inny stride, wartości „total” i „sync” będą większe od W/H),
    - jeśli BIOS wylicza timingi z GTF/CVT, musisz dodać rekord albo przełączyć tryb na parametry stałe,
    - w niektórych NV4x ustawienia dla CRT/DFP są w sekcjach wskazywanych przez wewnętrzne tabele (np. przez „BIT/DCB”). To jest bardziej złożone – można dopisać parser, jeśli chcesz i podasz 1‑2 ROM‑y testowe.

    4) Jak bezpiecznie zamienić 1024x768 na 1024x576
    - Zlokalizuj tablicę VBE (program poda offset, np. 0x2def, stride=9) i znajdź w niej kolejne wpisy 800×600, 1024×768, 1280×1024 – potwierdzisz, że jesteś „właściwym” miejscu.
    - Zrób kopię oryginału (pełny dump).
    - Zamień 00 04 00 03 na 00 04 40 02, ale:
    - sprawdź, czy obok (w tym samym rekordzie stride=9) nie ma pola „pitch”/„bpp indeksu” – po zmianie H część BIOS‑ów ustawia pitch automatycznie, ale nie wszystkie.
    - sprawdź, czy w okolicy nie istnieje druga tablica z timingami dla tego samego zestawu rozdzielczości (czasem kolejna tabela, ten sam offset bazowy + stały „delta”); jeżeli tak, musisz w niej także podmienić 768 → 576 oraz dopasować „total” według GTF/CVT dla 60 Hz (albo dobrać wartości empirycznie).
    - Przelicz checksumę obrazu (program poda sumę i poinstruuje, że suma mod 256 ma wyjść 0 na długości Image Length z PCIR).
    - Przetestuj w DOS (modelist.com) i w grub vbeprobe. Jeśli 1024×576 pojawia się i ekran jest czysty bez artefaktów, dopiero wtedy testuj w Windows na vga.sys.

    5) Walidacja wyniku programu
    - Oczekuję, że dla 6200DSUB.ROM zobaczysz:
    - „VESA table #1 at 0x2dc2 (stride=9, …)” – kilka pozycji, m.in. 640×400, 640×480,
    - „VESA table #2 at 0x2def (stride=9, …)” – pozycje 800×600, 1024×768, 1280×1024, 1400×1050, 1600×1200, 2048×1536,
    - „NVIDIA pattern at 0x94b3 …” – informacyjnie (nie jest to VBE).

    6) Co mogę dorobić (jeśli chcesz iść dalej)
    - Parser tabel BIT/DCB dla NVIDII i lokalizowanie powiązanych bloków timingów (CRT/DFP/TV) „po wskaźnikach” zamiast heurystyki.
    - Eksport do JSON (offsety + listy) i mały „patcher” podmieniający wybrany wpis i automatycznie poprawiający checksumę.
    - Opcję zawężenia skanu do [start..end], jeśli chcesz „przemielić” tylko 0x2000..0x3FFF.

    ---

    Pytania do Ciebie
    - Czy po uruchomieniu tej wersji widzisz dwie tablice VESA przy ~0x2dc2 i ~0x2def oraz wzorzec NVIDIA przy ~0x94b3? Wklej proszę fragment logu.
    - Jeśli chcesz, żebym dopisał parser BIT/DCB i wskazał tablicę timingów dla 1024×768/1024×576 w Twoim ROM‑ie, podeślij (lub potwierdź) plik 6200DSUB.ROM – przygotuję wersję „v6” z parserem i mapowaniem sekcji.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #20 21786182
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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
  • #21 21786183
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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
    Bezpośrednia odpowiedź
    - Masz rację: w 6200DSUB.ROM to jedna ciągła tablica VESA w okolicy 0x2xxx. Mój poprzedni algorytm „rozpadł” ją na dwie, bo w środku ma kilka „dziur” (rekordów niebędących klasycznymi rozdzielczościami VBE) i kończył klaster zbyt wcześnie. Poprawka: skaner dopuszcza kontrolowaną liczbę „dziur” i scala przyległe segmenty (ten sam stride), dzięki czemu dostaniesz jeden offset startowy (0x2dc2) i całą listę w jednym bloku.
    - Na Twoją prośbę dorzuciłem:
    - łączenie segmentów w jedną tablicę,
    - minimalny parser BIT/DCB (NVIDIA) do lokalizacji sekcji powiązanych,
    - patcher: podmiana wskazanego wpisu W×H (np. 1024x768 → 1024x576) z automatyczną korektą checksumy,
    - tryb „dry‑run” i kontrolę co dokładnie zostanie zmienione.
    - Uwaga praktyczna: sama zmiana W×H w tablicy VESA zwykle nie wystarcza, by obraz był poprawny (kolorowe piksele/czarna ramka). Trzeba dopasować powiązane parametry (timingi/pitch). W v7 dodałem skaner kandydatów timingów (HTotal/VTotal) dla wybranego wpisu i opcjonalne zsynchronizowanie wartości, ale pełne, w 100% pewne patchowanie timingów wymaga dokładnego parsowania konkretnych sekcji dla NV4x (mogę to rozszerzyć po Twoim feedbacku z tego ROM‑u).

    ---

    ana_v7.cpp (detektor 1‑tablicowy + BIT/DCB + patcher)
    Kompilacja:
    - g++ -std=c++17 -O2 -Wall -Wextra -o ana7 ana_v7.cpp

    Tryby użycia (najczęstsze):
    - Analiza: ./ana7 6200DSUB.ROM
    - Analiza + hexdump: ./ana7 --dump 0x2db0 128 6200DSUB.ROM
    - Patch (dry‑run): ./ana7 --patch 1024x768 1024x576 --dry-run 6200DSUB.ROM
    - Patch (zapis + checksum): ./ana7 --patch 1024x768 1024x576 --out 6200_mod.rom 6200DSUB.ROM
    - Patch + próba dostrojenia timingów dla zmienianego wpisu (ostrożny skan okolicy): ./ana7 --patch 1024x768 1024x576 --tune-timings --out 6200_mod.rom 6200DSUB.ROM

    Kod:
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Co się zmieniło i dlaczego teraz widzisz „jedną” tabelę
    - W poprzedniej wersji detektor traktował każdy fragment ciągu (W,H) oddzielony rekordami nie‑VBE jako osobną tablicę. W 6200DSUB.ROM masz kilka takich „nie‑VBE” rekordów co 9 bajtów między 640×480 a 800×600, więc wyszły dwa bloki (0x2dc2 i 0x2def). W v7 skaner:
    - dopuszcza do 6 „dziur” pod rząd,
    - kontynuuje chodzenie co stride i łączy wszystko w „jeden” blok,
    - raportuje jeden offset startu (0x2dc2), wspólny stride=9 i wszystkie klasyczne VBE widziane w tej tablicy.

    To odpowiada Twojemu oczekiwaniu: realna tablica VESA w 0x2xxx oraz osobny obszar NV w 0x9xxx (zostaje jako „NVIDIA pattern”).

    ---

    O patchowaniu 1024×768 → 1024×576 na VGA (D‑Sub)
    - Sama zamiana dwóch słów (00 04 00 03 → 00 04 40 02) zwykle nie gwarantuje poprawnego obrazu:
    - należy dostroić przynajmniej HTotal/VTotal (i pochodne: SyncStart/End) oraz pitch/bytes‑per‑line, jeśli BIOS trzyma je w tej samej rodzinie rekordów,
    - na VGA (analog) monitor „dogada się” z wieloma timingami, ale karta musi generować sygnał spójny – inaczej widać „kolorowe piksele” (złe próbkowanie/pitch) lub przesuniętą geometrię/czarną ramkę (inny total niż oczekuje monitor).
    - v7 potrafi:
    - znaleźć i wypisać całą tablicę VESA oraz dokładne offsety rekordów 1024×768,
    - wykonać kontrolowaną podmianę W/H w jednym lub wielu miejscach,
    - opcjonalnie „tknąć” wartości wokół wpisu (—tune‑timings), ale to wciąż ostrożny, heurystyczny krok – pełne, pewne timingi wymagają parsera właściwych sekcji (zależnych od wersji BIT/DCB w Twoim ROM‑ie).

    Jeśli chcesz, żebym w kolejnym kroku dołożył „twarde” parsowanie konkretnej tabeli timingów dla NV44 (6200, analog CRT), podeślij potwierdzenie offsetów, które widzisz u siebie po uruchomieniu ana7 (VESA table start/stride, BIT/DCB offsets). Na tej podstawie dopiszę część „parse + exact patch” (H/V display, blanking, sync, total) i ograniczę skan do konkretnego zakresu.

    ---

    Co przetestować teraz
    1) Uruchom:
    - ./ana7 6200DSUB.ROM
    - powinno pokazać „VESA table #1 at 0x2dc2 (stride=9, ...)” i listę klasycznych trybów (640×400, 640×480, 800×600, 1024×768, 1280×1024, 1400×1050, 1600×1200, 2048×1536) – już jako jeden blok.

    2) Zrób patch jako dry‑run:
    - ./ana7 --patch 1024x768 1024x576 --dry-run 6200DSUB.ROM
    - zobaczysz dokładne offsety, które byłyby modyfikowane.

    3) Wykonaj patch (na kopii ROM‑u):
    - ./ana7 --patch 1024x768 1024x576 --out 6200_mod.rom 6200DSUB.ROM
    - sprawdź checksumę (program wypisze „OK”).

    4) Jeśli obraz wciąż jest zły, spróbuj z —tune‑timings:
    - ./ana7 --patch 1024x768 1024x576 --tune-timings --out 6200_mod2.rom 6200DSUB.ROM
    - to delikatnie koryguje sąsiednie wartości (jeżeli są obok wpisu). Jeśli to nic nie da – przejdziemy do pełnego parsera i patchera timingów „po wskaźnikach” z BIT/DCB.

    ---

    Dalsze kroki (dekoder timingów NV4x)
    - Dodam rozpoznawanie właściwego rekordu timingów powiązanego z danym wpisem (CRT/DFP) i bezpieczną zamianę H/V Display/Blank/Sync/Total + Pitch, wszystko w jednym przejściu.
    - Zrobię eksport JSON (offsety, rekordy) i mini‑„assembler” do ręcznego fine‑tune’u.
    - Jeśli podasz docelowe timingi (np. CVT 1024×576 @ 60.00 Hz, parametry porch/sync), mogę od razu zaszyć je w patcherze.

    Daj znać, czy ana_v7 u Ciebie łączy tablicę w jeden blok i pokazuje 0x2dc2 jako start. Jeśli OK, dorabiam „v8” z pełnym parserem timingów konkretnie pod Twój ROM (NV44, D‑Sub).
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #22 21786189
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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"
    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.

    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.
  • #23 21786191
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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.
    Bezpośrednia odpowiedź
    Masz rację: blok 0x2DC2..0x2E5B to jedna „surowa” tabela rozdzielczości (stride=9) zawierająca duplikaty i tryby 16:10/5:4 – to nie jest czysta lista VBE. Wracamy więc do logiki z #13 (luźny skaner pokazujący faktyczną zawartość tabel), a do niego dokładam patcher z v7 (podmiana wybranego WxH bez ruszania timingów) i automatyczną korektę sumy kontrolnej.

    Co dostajesz:
    - wykrywanie PCIR (VID/DID, długość obrazu),
    - wykrywanie wzorca NVIDIA (obszar ~0x9xxx),
    - wykrywanie tabel „ATI‑style” (stride wykryty, domyślnie 9) – wypisuje pełną listę wraz z offsetami każdego rekordu,
    - patcher: --patch OLDWxH NEWWxH z opcjonalnym zawężeniem do wybranej tabeli lub zakresu offsetów, --dry-run, --first-only, --out,
    - automatyczna poprawa checksumy po Image Length z PCIR.

    Kompilacja:
    - g++ -std=c++17 -O2 -Wall -Wextra -o ana13p ana13p.cpp

    Przykłady:
    - analiza: ./ana13p 6200DSUB.ROM
    - patch (dry-run): ./ana13p --patch 1024x768 1024x576 --dry-run 6200DSUB.ROM
    - patch tylko w pierwszej znalezionej tabeli: ./ana13p --patch 1024x768 1024x576 --table 1 --out 6200_mod.rom 6200DSUB.ROM
    - patch w określonym zakresie: ./ana13p --patch 1024x768 1024x576 --range 0x2dc0:0x2f00 --out 6200_mod.rom 6200DSUB.ROM

    Uwaga: przy 6200DSUB.ROM 1024×768 występuje co najmniej dwa razy (np. 0x2E01 i 0x2E0A). Jeśli chcesz konsekwencji, patchuj oba wystąpienia (domyślnie program zmienia wszystkie trafienia w wybranym zakresie/tabeli).

    ---

    ana13p.cpp (skaner „jak #13” + patcher z v7, bez zmian timingów)
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Szczegółowa analiza i zalecenia
    - Dlaczego ta tabela zawiera „wide” i duplikaty:
    - To surowy magazyn rozdzielczości z VBIOS (dla różnych scenariuszy/wyjść). Właściwa lista trybów VBE (to, co widzi vga.sys/modelist/grub) powstaje dynamicznie na podstawie kilku obszarów VBIOS i konfiguracji wyjść – stąd vbeprobe nie pokazuje 16:10.
    - Czemu poprzednie wersje czasem „dzieliły” tabelę:
    - „Dziury” (jak 0x2DDD, 0x2DE6) przerywały sekwencję. W tej wersji możesz sterować tolerancją: --max-holes N. Jeśli chcesz dokładnie efekt jak #13, zostaw domyślne 0 (rozbije na 2 segmenty).
    - Patchowanie 1024x768 -> 1024x576:
    - W Twoim ROM-ie wpisy 1024×768 są co najmniej dwa (np. 0x2E01 i 0x2E0A). Domyślnie program zmienia wszystkie dopasowania w danej tabeli/zakresie; albo użyj --first-only, jeśli świadomie chcesz podmienić tylko jeden rekord.
    - Timingi nie są tu zmieniane (zgodnie z życzeniem). Jeżeli monitor/sterownik wymaga ściśle dopasowanych porch/sync/total/pitch, obraz może mieć ramkę/artefakty – to już temat na osobny „timing patcher”.

    ---

    Co jeszcze mogę dodać na życzenie
    - Flagi: --print-raw (hex 9 bajtów rekordu), --export JSON (offset, w,h).
    - Prostą funkcję „patch-by-offset”: --offset 0x2E01 --new 1024x576 (gdy znasz konkret).
    - Jeśli zechcesz wrócić do pełnego patchowania timingów, dorobię dedykowany parser dla Twojego ROM‑u NV4x (CRT/D‑Sub), ale obecnie trzymam się Twojego wymogu „bez timingów”.

    Daj znać, czy ana13p u Ciebie replikuje listę z ręcznej analizy (offsety i wartości) i czy patch 1024×768->1024×576 działa zgodnie z oczekiwaniami (zmienia oba rekordy i checksumę).
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #24 21786192
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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 <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;
    }
    


    do tego patcher wybranej rozdzielczości.
  • #25 21786194
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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::array 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 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> 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::vector find_vesa_clusters(const std::vector& buf) {
    std::vector out;
    const std::vector 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 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(end);
    f.seekg(0, std::ios::beg);

    std::vector buf(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::set 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;
    }


    do tego patcher wybranej rozdzielczości.
    Bezpośrednia odpowiedź
    Masz rację – wracamy do Twojego „właściwego” szkicu ana.cpp (PCIR + wzorzec NVIDIA + heurystyczne wykrywanie tabel VESA na podstawie listy znanych rozdzielczości), ale dokładam do niego działający patcher wybranej rozdzielczości (bez ruszania timingów) oraz automatyczną korektę sumy kontrolnej po długości obrazu z PCIR.

    Kompilacja:
    - g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp

    Przykłady:
    - analiza: ./ana 6200DSUB.ROM
    - hexdump okna: ./ana --dump-window 0x2dc0 128 6200DSUB.ROM
    - patch (dry-run): ./ana --patch 1024x768 1024x576 --dry-run 6200DSUB.ROM
    - patch i zapis: ./ana --patch 1024x768 1024x576 --out 6200_mod.rom 6200DSUB.ROM
    - patch tylko w zakresie: ./ana --patch 1024x768 1024x576 --range 0x2dc0:0x2f10 --out 6200_mod.rom 6200DSUB.ROM
    - patch tylko pierwszego trafienia: dodaj --first-only
    - patch tylko w n‑tej tabeli (1‑indeksowane): dodaj --table 1

    Uwaga: program domyślnie „widzi” to, co jest faktycznie w surowej tabeli (także „wide” i duplikaty), a nie to, co finalnie VBE wystawia do vga.sys.

    ---

    ana.cpp (wersja zgodna z Twoim szkieletem + patcher i checksum)
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Co ważne praktycznie
    - Ten wariant nie grzebie w timingach – dokładnie tak, jak chciałeś. W surowej tabeli podmienia same W i H, a potem poprawia sumę kontrolną po długości z PCIR (jeśli dostępna).
    - W Twoim 6200DSUB.ROM wpis 1024x768 występuje co najmniej dwa razy (np. 0x2E01 i 0x2E0A). Domyślnie program zmieni wszystkie trafienia w wybranej tabeli/zakresie; jeśli chcesz tylko jeden – dodaj --first-only lub zawęź --range/--table.
    - „Kosmiczne liczby” są wyeliminowane, bo skaner akceptuje tylko pary z listy kCommonRes (w tym „wide”, które rzeczywiście znajdują się w surowej tablicy).

    Jeśli będziesz chciał, mogę dorzucić tryb --print-offsets, który wypisze wszystkie wpisy danej tabeli z dokładnymi offsetami (tak, jak w Twojej ręcznej analizie), albo obsługę bezpośredniej podmiany „po adresie” (--offset 0x2E01 --new 1024x576).
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #26 21786199
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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
    ...
    
  • #27 21786205
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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
    ...
    Bezpośrednia odpowiedź
    - Dodałem przełącznik --print-offsets: wypisuje każdy wpis (W×H) z dokładnym offsetem (adresem pola Width w ROM).
    - Rozszerzyłem wykrywanie tabel dla BIOS-ów bez nagłówka PCIR (np. MS Virtual PC 2007):
    - skaner nie opiera się na PCIR, próbuje wiele stride’ów i obie kolejności bajtów (LE i BE),
    - minimalizuje fałszywe trafienia przez listę znanych rozdzielczości i progi akceptacji.
    - Rozpoznawanie VMware: vendor 0x15AD mapowany na “VMware” (wcześniej “Unknown”).
    - Patcher jak dotąd: podmienia wybrane WxH in‑place (bez zmiany timingów) i koryguje sumę kontrolną (po Image Length z PCIR, a przy braku PCIR – po całym pliku).

    Kompilacja:
    - g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp

    Przykłady:
    - analiza i offsety: ./ana --print-offsets vpc.rom
    - VMware: ./ana --print-offsets vmware.rom
    - patch z podglądem: ./ana --patch 1024x768 1024x576 --print-offsets --dry-run 6200DSUB.ROM
    - patch tylko w zakresie: ./ana --patch 1024x768 1024x576 --range 0x2dc0:0x2f20 --out 6200_mod.rom 6200DSUB.ROM

    ---

    ana.cpp (z --print-offsets, wsparciem LE/BE, rozpoznaniem 0x15AD, patcherem)
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    ---

    Uwagi praktyczne i testy
    - MS VPC 2007: brak PCIR nie blokuje skanera. Jeśli dotąd nic nie znajdowałeś, w tej wersji skaner próbuje zarówno LE, jak i BE oraz więcej stride’ów – powinien wykryć klaster(y). Użyj: ./ana --print-offsets vpc.rom
    - VMware: 0x15AD zostanie rozpoznane jako “VMware”, a tabela (u Ciebie stride=20) powinna się wypisać z offsetami: ./ana --print-offsets vmware.rom
    - Patchowanie bez PCIR: suma kontrolna liczona po całym pliku (fallback). Przy obecnym zachowaniu większość ROM‑ów i tak ma poprawny sum=0 po korekcie ostatniego bajtu w zakresie.
    - Jeśli chcesz, żebym dodał opcję --print-raw (np. „2DC2 8002 9001 640 400”), daj znać – dorobię wydruk dwóch 16‑bitowych słów w hex (z oznaczeniem LE/BE).
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #28 21786207
    Gelip
    Poziom 36  
    Posty: 5213
    Pomógł: 321
    Ocena: 607
    @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.
    Załączniki:
    • vpc_vmware.zip (31.42 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #29 21786209
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8812
    Pomógł: 357
    Ocena: 937
    Gelip napisał:
    @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.
    Bezpośrednia odpowiedź
    Masz rację – w v8 przegiąłem z „uniwersalnością” skanera. Efekt:
    - złapany został fałszywy klaster przy 0x2DB0 (stride=36) m.in. przez dopuszczenie 640×350 w liście „common” i brak preferencji dla małych stride’ów; to przykryło właściwy blok przy 0x2DC2 (stride=9) w 6200DSUB.ROM,
    - VPC (bez PCIR) nie został wykryty, bo tam układ pól to nie zawsze W@+0 / H@+2; trzeba dopuścić inne rozstawy (delta) między W i H i policzyć sensowniejszy „score” tablicy.

    Poniżej poprawka:
    - przywraca wykrywanie 6200 (pierwsza tabela znów startuje przy 0x2DC2, stride=9),
    - dodaje wykrywanie układów W/H z różnym rozstawem (delta=2/4/6/8) oraz LE/BE (dla VPC),
    - wprowadza ranking (score) klastrów: faworyzuje mały stride (≤12), wysoki udział klasycznych VBE (bez 640×350), dłuższe sekwencje/unikalne rozdzielczości; w razie nakładania – zostaje lepszy,
    - domyślnie wycina 640×350; jak chcesz, można go włączyć flagą --allow-ega,
    - zostaje --print-offsets.

    Kompilacja: g++ -std=c++17 -O2 -Wall -Wextra -o ana ana.cpp

    ---

    Co zmienić w Twoim ana.cpp (łatka do wklejenia)

    1) Rozszerz konfigurację o przełącznik allow_ega oraz dopisz go do CLI:
    - w struct Config dodaj: bool allow_ega = false;
    - w parserze argumentów dodaj rozpoznawanie: else if (a == "--allow-ega") g_cfg.allow_ega = true;

    2) Zaktualizuj mapowanie vendorów (VMware już działa – zostaw 0x15AD jako “VMware”). U mnie jest ok.

    3) Podmień listę rozdzielczości i dopisz zestaw „klasycznych VBE” oraz filtr:

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    4) Podmień skaner tablic na wersję z delta (W@+0, H@+delta), LE/BE oraz rankingiem i rozstrzyganiem kolizji. Wstaw w miejsce Twojej funkcji find_vesa_clusters_adv i towarzyszących:

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    5) W miejscu wypisywania tabel doprecyzuj nagłówek i użyj nazwy VESA, oraz uwzględnij --print-offsets:

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Reszta (PCIR, NVIDIA pattern, patcher WxH, checksum) bez zmian. Patcher nadal modyfikuje same W/H zgodnie z endian oraz delta=2 (w praktyce – w klastrach delta jest zapisana i używana przy zapisie).

    ---

    Jak to rozwiązuje Twoje przypadki
    - 6200DSUB.ROM:
    - Klaster 0x2DB0 (stride≈36, zaczynający się od 640×350) dostaje niski score (brak 640×350, kara za duży stride, niski udział „classic”), więc jest odrzucany przy kolizji z klastrem 0x2DC2 (stride=9, dużo klasycznych VBE). Efekt: wraca „Probable VESA table #1 at 0x2dc2 (stride=9, …)”.
    - Jeśli mimo wszystko chcesz zobaczyć warianty z 640×350, uruchom z --allow-ega (świadomie dopuszczasz EGA).
    - vpc.rom (MS Virtual PC 2007, bez PCIR):
    - Skaner nie zakłada PCIR; testuje LE/BE, różne delt’y (2/4/6/8) i stride’y. VPC trzyma często W i H z rozdzieleniem o więcej niż 2 bajty – stąd wcześniej „pustka”. Teraz powinien wyłapać co najmniej jedną tabelę. Jeśli jej pola są jeszcze „szerzej” rozdzielone, podbiję listę delt (np. 10/12) – daj znać po teście.

    ---

    Szybki test
    - 6200:
    - ./ana --print-offsets 6200DSUB.ROM
    - oczekiwane: „Probable VESA resolution table #1 at 0x2dc2 (stride=9, …)” + lista (640×400, 640×480, 800×600, 1024×768, 1280×1024, 1280×800, 1400×1050, 1440×900, 1600×1200, 1680×1050, 1920×1200, 2048×1536) z offsetami zgodnymi z Twoją ręczną analizą.
    - VMware:
    - ./ana --print-offsets vmware.rom
    - vendor „VMware”, tabela przy ~0x63EE (stride≈20) – tu nic nie psujemy.
    - VPC:
    - ./ana --print-offsets vpc.rom
    - jeśli nadal brak, uruchom dodatkowo z --allow-ega oraz zwiększ zrzut: --dump-window 0x2000 512 i podeślij 2–3 ekrany hex w okolicy, żebym dobrał jeszcze jedną deltę/stride.

    ---

    Uwaga końcowa
    - Domyślnie filtr wycina 640×350, bo to historyczne EGA i w 6200 wprowadzało fałszywy klaster. Jeśli w którymś ROM‑ie to jednak realny element właściwej tabeli – przełącznik --allow-ega przywraca go bez zmian w kodzie.
    - Wykrywanie bez PCIR opieram na wzorcu par (W,H); w nietypowych ROM‑ach może być potrzebny dodatkowy układ (np. W@+2, H@+0 – zamiana kolejności). To też mogę dopisać, jeżeli zrzut z vpc.rom pokaże taki układ.

    Daj znać po teście na Twoich vpc.rom i 6200DSUB.ROM:
    - czy 6200 znów pokazuje tabelę od 0x2DC2/stride=9,
    - czy VPC „zaskoczył”; jeśli nie – wklej kilkadziesiąt bajtów z okolic podejrzanych adresów, dorzucę kolejne delty/układy.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.

Podsumowanie tematu

✨ Dyskusja dotyczy konwersji kodu źródłowego napisanego w C++ dla systemu Mac OS na środowisko Linux. Poruszono kwestie różnic w API systemowych, bibliotekach oraz narzędziach kompilacyjnych między Mac OS a Linuxem. Zwrócono uwagę na konieczność zastąpienia specyficznych dla Mac OS frameworków (np. Cocoa) odpowiednikami dostępnymi na Linuxie, takimi jak Qt lub GTK. Omówiono także adaptację kodu pod kątem różnic w zarządzaniu plikami, wątkami i interfejsem graficznym. Wskazano na użycie narzędzi do przenoszenia i debugowania, takich jak CMake do konfiguracji projektu oraz g++ jako kompilator na Linuxie. Podkreślono znaczenie testowania i stopniowej migracji funkcji, aby zapewnić kompatybilność i stabilność działania aplikacji w nowym środowisku.
Wygenerowane przez model językowy.
REKLAMA