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

[Rozwiązano] Dodanie nowej rozdzielczości "wide" do vbiosu karty graficznej

Gelip 22 Gru 2025 22:26 510 16
  • #1 21787953
    Gelip
    Poziom 36  
    Posty: 5245
    Pomógł: 324
    Ocena: 611
    @ElektrodaBot
    Kontynuacja tematu:
    https://www.elektroda.pl/rtvforum/topic4157918-30.html#21787716

    Poproszę o pełny kod z trzema proponowanymi opcjami z postu z powyższego linku:

    Hexdump z oryginalnego biosu 6200DSUB.ROM:

    0x2E01 00040003802F101061
    0x2E0A 00040003802F101061

    0x94B3 0004FF030000FF0317049F043F050003FF020000FF0202030803250300FF6419
    0x94D3 0004FF030000FF0317049F043F050003FF020000FF0202030803250311FF302A

    Ale nie jestem pewny czy obszar 0x2DDD jest faktycznie dobry do wykorzystania - tam są jakieś dane:

    0x2DDD 5000190050180E0810500019005018100810

    Próbowałem zamiast używać obszaru 0x2DDD wybrać jakąś rozdzielczość mało używaną np. 1400x1050 czyli 0x2E2E, wstawić tam nową rozdzielczość 1024x576
    następnie znaleźć wskaźnik do tabeli 32-B czyli to będzie offset 0x9513 i 0x9573 i wstawić tam nowe dane z timingami dla 1024x576

    Niestety tak nie można bo rozdzielczości w VESA mają zawsze te same kody:
    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


    Po zmianie mam w vbeprobe 1024x576 ale nadal na pozycji 147 i 148
      147: 39F, 1024x576x8, Packed pixel
      148: 39F, 1024x576x16, Direct Color

    W Windows jak wybiorę 1024x576x16 (tylko z listy dostępnych pokaż wszystkie) to system wyświetla obraz w 1024x576x16 ale z ramkami u dołu i z prawej a monitor pokazuje 1400x1050 bo gdzieś jest na sztywno zapisane że pod 148 VESA jest rozdzielczość 1400x1050x16-bit

    Podmiana w okolicy 0x2... bez podmiany timingów w okolicy 0x9... może się udać ale pod warunkiem iż zmieniamy tylko jedną rozdzielczość np. pionową i prawdopodobnie gdy używamy połączenia cyfrowego np. DVI
    Na blogu:
    http://www.macbreaker.com/2012/06/how-to-set-your-hackintosh-bootscreen.html
    autor pisze aby nie zmieniać obu rozdzielczości jednocześnie, tylko albo pionową albo poziomą:
    Cytat:
    When editing your graphic card's VBIOS, change only the height (or only the width) of a specific VESA resolution. Don't try to change both the width and height of a VESA resolution, as this can get super confusing.

    i prawdopodobnie udało mu się to bo używa połączenia cyfrowego a nie analogowego.
  • #2 21787978
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8881
    Pomógł: 364
    Ocena: 954
    LABEL_AI_GENERATED
    Gelip napisał:
    @ElektrodaBot
    Kontynuacja tematu:
    https://www.elektroda.pl/rtvforum/topic4157918-30.html#21787716

    Poproszę o pełny kod z trzema proponowanymi opcjami z postu z powyższego linku:

    Hexdump z...
    Bezpośrednia odpowiedź
    - Poniżej masz kompletny, samowystarczalny patcher (Python 3) oraz gotowe hexy do ręcznej edycji, obejmujące trzy warianty modyfikacji VBIOS (NV4x/GeForce 6200) dla trybu 1024×576:
    1) pełna podmiana: wpis rozdzielczości (sekcja 0x2E…) + timingi 32‑bajtowe (sekcja 0x95…),
    2) „soft” – zmiana wyłącznie wpisu 0x2E… (bez timingów; zwykle sensowne tylko na DVI),
    3) „timings‑only” – zmiana wyłącznie 32‑bajtowych timingów (fizyczny sygnał 1024×576, raportowane ID VESA pozostają jak były).
    - Dla DSUB (analog) zdecydowanie zalecam Wariant 1 lub 3 (z faktyczną podmianą timingów), bo sam wpis 0x2E… nie usuwa czarnych ramek/croppa – monitor synchronizuje się do realnych timingów, nie do „etykiety” trybu. Na sterownikach NVIDII typowo preferowane są standardy DMT/CVT nad GTF, a lista trybów identyfikowana jest po stałych ID VBE (147h, 148h), co wyjaśnia „upieranie się” Windowsa przy 1400×1050 dla tych ID. (nvidia.com)
    - Zastrzeżenie: nie mogłem pobrać wskazanego posta (HTTP 502), więc poniższy kod opiera się na dostarczonych przez Ciebie hexdumpach i znanym formacie bloków timingów NVIDII/BIOS‑VBE. W miejscach, gdzie w Twojej wersji ROM offsety różnią się (np. 0x94B3 vs 0x9513), skrypt pozwala je nadpisać parametrami.

    ---

    Gotowe hexy do ręcznej podmiany

    Poniższe wartości są policzone dla 1024×576@60 Hz (CVT „standard”, nie RB) – to tryb bezpieczny dla DSUB. Mapowanie 32‑bajtowego bloku jest zgodne z obserwowanym formatem NV (H/V active‑1, Hsync start‑1, Hsync end‑1, Htotal‑1, Vsync start‑1, Vsync end‑1, Vtotal‑1, na końcu: flagi i pixel clock w setkach kHz). Dla 1024×576@60 przyjmuję:
    - Pixel clock ≈ 47.00 MHz → 4700 (0x125C, LE = 5C 12),
    - H: active 1024, fp 48, sw 128, total 1312 → start‑1=1071 (2F 04), end‑1=1199 (AF 04), total‑1=1311 (1F 05),
    - V: active 576, fp 3, sw 5, total 597 → start‑1=578 (42 02), end‑1=583 (47 02), total‑1=596 (54 02).

    1) Wpis rozdzielczości 9B (sekcja 0x2E…):
    - 0x2E2E (slot 1400×1050 zamieniany na 1024×576) → wstaw:
    00 04 00 03 00 04 40 02 61
    Uwaga: w Twoim ROM układ 9 bajtów jest zgodny ze spotykanym w NV4x; jeżeli masz inną strukturę – skorzystaj ze skryptu (wariant 2) i/lub podaj mi swój zrzut 0x2E2E przed zmianą, żebym zdekodował pola precyzyjnie.

    2) Timingi 32B (sekcja 0x95… – u Ciebie padały wartości 0x9513/0x9573 lub 0x94B3/0x94D3):
    - 8 bpp (odpowiednik „pozycji 147h” w Twoim vbeprobe):
    00 04 FF 03 00 00 FF 03 2F 04 AF 04 1F 05 40 02 3F 02 00 00 3F 02 42 02 47 02 54 02 00 FF 5C 12
    - 16 bpp (odpowiednik „pozycji 148h”):
    00 04 FF 03 00 00 FF 03 2F 04 AF 04 1F 05 40 02 3F 02 00 00 3F 02 42 02 47 02 54 02 11 FF 5C 12

    Wartość „00/11” przed 0xFF na końcu to bajt flag – w Twoim ROM na 0x94B3 było „00 FF …”, a na 0x94D3 „11 FF …”, więc zachowuję ten wzór (różnicuje „wariant” trybu dla innej głębi/ID). Ostatnie dwa bajty to pixel clock w setkach kHz, LE.

    Co sprawdzić po wgraniu:
    - GRUB vbeprobe powinien nadal pokazywać pozycje 147/148, ale już z opisem 1024×576x8/16,
    - monitor na DSUB powinien raportować 1024×576@60 (bez ramek),
    - jeśli sterownik NVIDII w Windows wciąż „przepina” do DMT/EDID – dodaj niestandardową rozdzielczość w Panelu NVIDII/CRU, bo driver faktycznie preferuje DMT/CVT nad GTF. (nvidia.com)

    ---

    Pełny patcher (Python 3)

    Zastosowanie:
    - Wariant 1 (pełna podmiana): python nvb_vesa_patch.py in.rom out.rom --variant 1 --res-off 0x2E2E --tim8-off 0x9513 --tim16-off 0x9573
    - Wariant 2 (tylko wpis 0x2E…): python nvb_vesa_patch.py in.rom out.rom --variant 2 --res-off 0x2E2E
    - Wariant 3 (tylko timingi): python nvb_vesa_patch.py in.rom out.rom --variant 3 --tim8-off 0x9513 --tim16-off 0x9573
    Jeżeli u Ciebie realne offsety to 0x94B3/0x94D3 – podaj je zamiast 0x9513/0x9573.

    Kod:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Co robi skrypt:
    - Tworzy poprawne, spójne timingi 32B dla 1024×576@60 (CVT), w formacie zgodnym z Twoimi zrzutami („FF 03” = 1023 = 1024‑1 itd.).
    - Daje trzy tryby pracy (wariant 1/2/3).
    - Domyślnie szuka w ROM‑ie Twoich oryginalnych bloków 32B (ORIG_TIMING_A/B) i podmienia „po sygnaturze”. Jeśli ROM różni się offsetami – możesz podać je jawnie.
    - Koryguje sumę kontrolną pierwszego obrazu ROM (wymóg PCI Option ROM: suma modulo 256 = 0).
    - Zachowuje konwencję „00 FF” (8bpp) i „11 FF” (16bpp) obserwowaną w Twoich bajtach końcowych.

    ---

    Jak tego użyć (szybki przewodnik)
    1) Kopia zapasowa 6200DSUB.ROM.
    2) Ustal realne offsety (Twoje wpisy sugerują: 0x2E2E dla 1400×1050, 32‑bajtowe bloki na 0x9513 i 0x9573 albo 0x94B3 i 0x94D3).
    3) Dla DSUB wybierz:
    - Wariant 1 (zalecany): podmień 9B + 32B:
    python nvb_vesa_patch.py 6200DSUB.ROM 6200DSUB_mod.ROM --variant 1 --res-off 0x2E2E --tim8-off 0x9513 --tim16-off 0x9573
    4) Flash przez nvflash (legacy). Po restarcie:
    - w GRUB: vbeprobe → 147/148 powinno pokazać 1024×576,
    - monitor (OSD) powinien raportować 1024×576@60, obraz bez ramek.
    5) Jeżeli Windows z driverem NVIDII mimo wszystko nie podaje 1:1 (np. narzuca standard DMT i skaluje), dołóż niestandardową rozdzielczość w Panelu NVIDII/CRU i wybierz CVT/CVT‑RB/DMT ręcznie. (nvidia.com)

    ---

    Szczegółowa analiza techniczna i uzasadnienie

    - Dlaczego same wpisy 0x2E… nie wystarczają na DSUB: ten blok jest „opisowy”/mapujący tryb w liście VBE, ale realny sygnał generuje CRTC/TMDS wg 32‑bajtowego bloku timingów (H/V active‑1, front‑porch, sync‑width, back‑porch, total, polaryzacje, pixel clock). W Twoich hexdumpach widać klasyczny wzorzec dla 1024×768@60: Htotal‑1=0x053F (1343), Vtotal‑1=0x0325 (805), pixel clock 0x1964=65.00 MHz. Zmieniając wyłącznie 0x2E…, zostawiasz te parametry nietknięte – monitor nadal widzi 1344×806/65 MHz i próbuje to dopasować → ramki.
    - Dlaczego Windows „trzyma” 147h/148h jako 1400×1050: ID trybów VBE są stałe (standard VESA), a sterowniki NVIDII preferują znane standardy (DMT, CVT) nad danymi z BIOS‑u o ile tylko mogą je odtworzyć z EDID/„bazy” – stąd zachowanie, że opis zmieniłeś (vbeprobe pokazuje 1024×576), ale sygnał nadal był 1400×1050, dopóki nie podmieniłeś 32B timingów. (nvidia.com)
    - Skąd wynika 32‑bajtowy układ: pokrywa się z dokumentacją i praktyką NVIDII/struktur timingów (NVAPI/NV_TIMING), gdzie parametry są liczone jako wartości „active/total oraz front‑porch i szerokości impulsów”. W Twoich danych „FF 03”=1023=1024‑1 itd., a końcowe dwa bajty to pixel‑clock w setkach kHz LE. (docs.nvidia.com)

    ---

    Co z obszarem 0x2DDD?
    - Wskazany ciąg 50 00 19 00 50 18 0E 08 10 50 00 19 00 50 18 10 08 10 nie jest paddingiem (FF/00), wygląda na sensowne dane (pary LE). Z punktu widzenia ryzyka „uceglenia” karty – NIE używaj tego jako „wolnego miejsca”, skoro mamy slot 1400×1050 do nadpisania.

    ---

    Warianty i ich zastosowanie – krótkie porównanie
    - Wariant 1 (0x2E.. + 32B): czysty sygnał 1024×576@60 na DSUB i DVI, brak ramek. Najbardziej „sprzętowy” i przewidywalny.
    - Wariant 2 (tylko 0x2E..): szybka sztuczka, zwykle akceptowalna na DVI (cyfra skaluje „ładniej”), na DSUB najczęściej da ramki/rozjechania.
    - Wariant 3 (tylko 32B): OS nadal „myśli”, że tryb to np. 1400×1050 (ID nie zmienia się), ale fizycznie GPU nadaje 1024×576 – przydatne w specyficznych scenariuszach, by „oszukać” aplikację/OS, ale pamiętaj o rozjazdach raportowania.

    ---

    Testy/diagnostyka po patchu
    - GRUB: vbeprobe – pozycje 147/148 pokażą 1024×576 (ID zostają 147/148).
    - EDID monitora: sprawdź OSD/„Status” – powinien widzieć 1024×576@60.
    - Jeżeli OS dodaje marginesy: w Panelu NVIDII utwórz tryb niestandardowy, wybierając timing standard CVT lub DMT (sterownik ma preferencję standardów – patrz dokumentacja). (nvidia.com)

    ---

    Pytania uzupełniające (żebym doszlifował „pod klucz”)
    - Potwierdź, proszę, w Twoim pliku:
    - dokładny offset slotu 1400×1050 (0x2E2E czy inny) oraz jego 9B przed zmianą,
    - które z dwóch par 32B faktycznie odpowiadają 147h/148h u Ciebie (0x94B3/0x94D3 czy 0x9513/0x9573).
    - Czy chcesz wariant 50 Hz (np. pod wideo PAL)? W razie potrzeby dam przeliczone 32B dla 1024×576@50 (DMT/CVT lub GTF).
    - Jakie złącze używasz docelowo (DVI/DSUB)? Dla DSUB lepszy jest CVT standard/GTF; dla DVI można rozważyć CVT‑RB.

    Jeśli podeślesz mi zrzuty oryginalnych 9B/32B dla konkretnego slotu, dam Ci hexy 1:1 „do wklejenia” pod Twoje offsety, a skrypt domyślnie ustawi właściwe miejsca.
    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 21787986
    Gelip
    Poziom 36  
    Posty: 5245
    Pomógł: 324
    Ocena: 611
    @ElektrodaBot
    Widzę iż kolega nie pamięta o czym rozmawialiśmy w poprzednim temacie. Kod był dla MS Visual Studio 2005

    Tutaj jest link do tematu: https://www.elektroda.pl/rtvforum/topic4157918.html

    a skończyliśmy na poście #56 https://www.elektroda.pl/rtvforum/topic4157918-30.html#21787716

    Tak wyglądał ostatni kod dla MS VS 2005:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #4 21787995
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8881
    Pomógł: 364
    Ocena: 954
    LABEL_AI_GENERATED
    Gelip napisał:
    @ElektrodaBot
    Widzę iż kolega nie pamięta o czym rozmawialiśmy w poprzednim temacie. Kod był dla MS Visual Studio 2005

    Tutaj jest link do tematu: https://www.elektroda.pl/rtvforum/topic4157918.html

    a skończyliśmy na poście #56 https://www.elektroda.pl/rtvforum/topic4157918-30.html#21787716

    Tak wyglądał ostatni kod dla MS VS 2005:

    // ============================================================================
    // ana_vc8.cpp (MS Visual C++ 2005 / MSVC8, C++03)
    // VBIOS Analyzer (PCIR + NVIDIA pattern + heurystyczne tabele rozdzielczości)
    // + Generator timingów: CVT-RB v1 i GTF (classic, uproszczony)
    // + Wyjścia: summary, raw, dtd, modeline, ps
    // + Patcher NV4x: --nv-patch WxH@Hz (wpis 32B do wolnego slotu/--slot),
    // --force (nadpisuj niepusty), --write out.rom (zapis),
    // checksum mod256 po PCIR.ImageLength lub po całym pliku
    //
    // Kompilacja: cl /O2 /EHsc /MT /W3 ana_vc8.cpp
    // ============================================================================

    #include
    #include
    #include
    #include

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #if defined(_MSC_VER) && _MSC_VER < 1600
    typedef unsigned __int8 uint8_t;
    typedef signed __int16 int16_t;
    typedef unsigned __int16 uint16_t;
    typedef unsigned __int32 uint32_t;
    typedef unsigned __int64 uint64_t;
    #else
    include
    #endif

    static inline size_t sminz(size_t a, size_t b){ return (a
    // --------------------------- Sygnatury i stałe -------------------------------
    static const uint8_t NVIDIA_PATTERN[30] = {
    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
    };
    static const char PCIR_SIG[4] = { 'P','C','I','R' };

    static const uint16_t VENDOR_NVIDIA = 0x10DE;
    static const uint16_t VENDOR_ATI = 0x1002;
    static const uint16_t VENDOR_INTEL = 0x8086;
    static const uint16_t VENDOR_VMWARE = 0x15AD;

    // --------------------------------- CLI --------------------------------------
    struct Config {
    // analiza ROM
    bool verbose;
    bool vendor_only;
    bool dump_window;
    size_t dump_offset;
    size_t dump_length;
    size_t dump_on_hit_len;
    bool print_offsets;

    // generator
    bool gen_on;
    uint16_t gen_w, gen_h;
    double gen_hz;
    std::string gen_std; // "cvt-rb" | "gtf"
    std::string gen_name;
    bool emit_summary, emit_raw, emit_dtd, emit_modeline, emit_ps, emit_all;

    // patcher
    bool nv_patch;
    bool nv_force;
    bool have_slot;
    size_t slot_off;
    std::string out_path;

    Config()
    : verbose(false), vendor_only(false), dump_window(false),
    dump_offset(0), dump_length(64), dump_on_hit_len(0),
    print_offsets(false),
    gen_on(false), gen_w(0), gen_h(0), gen_hz(60.0), gen_std("cvt-rb"),
    gen_name("custom"),
    emit_summary(true), emit_raw(false), emit_dtd(false),
    emit_modeline(false), emit_ps(false), emit_all(false),
    nv_patch(false), nv_force(false), have_slot(false), slot_off(0), out_path("") {}
    } 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 NV/cluster hits\n"
    << " --print-offsets print offsets for found entries\n"
    << "\n"
    << "Timing generator:\n"
    << " --gen WxH@Hz generate timings (e.g. 1024x576@60)\n"
    << " --std gtf|cvt-rb algorithm (default: cvt-rb)\n"
    << " --name LABEL label for outputs (default: custom)\n"
    << " --emit summary|raw|dtd|modeline|ps|all outputs to print (default: summary)\n"
    << "\n"
    << "NV patcher:\n"
    << " --nv-patch WxH@Hz write 32B NV timing entry into ROM\n"
    << " --slot 0xADDR force slot address (default: first empty near NV pattern)\n"
    << " --force allow overwrite non-empty slot\n"
    << " --write out.rom write modified ROM to file\n";
    }

    static size_t parse_number_c(const char* s){
    char* endp = 0;
    #if defined(_MSC_VER)
    uint64_t v = _strtoui64(s, &endp, 0);
    #else
    uint64_t v = strtoull(s, &endp, 0);
    #endif
    if (!s || *s=='\0' || (endp && *endp!='\0')){ std::cerr<<"Invalid number: "<<(s?s:"(null)")<<"\n"; exit(2); }
    if (v > (uint64_t)~(size_t)0){ std::cerr<<"Too large\n"; exit(2); }
    return (size_t)v;
    }

    static bool match_at(const std::vector& buf, size_t pos, const uint8_t* pat, size_t patlen){
    if (pos + patlen > buf.size()) return false;
    return ::memcmp(&buf[pos], pat, patlen) == 0;
    }

    static void hex_dump(const std::vector& buf, size_t offset, size_t length){
    if (offset >= buf.size()){ std::cout<<"[WARN] dump offset beyond file size\n"; return; }
    size_t end = sminz(offset+length, buf.size());
    std::cout<<"Hex dump [0x"< < size_t i=offset;
    while(i std::cout<<" "< size_t n = sminz((size_t)16, end-i);
    for(size_t j=0;j for(size_t j=n;j<16;++j) std::cout<<" ";
    std::cout<<" | ";
    for(size_t j=0;j=32 && c<127)?char(c):'.'); }
    std::cout< i+=16;
    }
    std::cout<<"\n";
    }

    // --------------------------------- PCIR -------------------------------------
    struct PCIRInfo{
    bool found; size_t offset; uint16_t vendor_id; uint16_t device_id; size_t image_len;
    PCIRInfo():found(false),offset(0),vendor_id(0),device_id(0),image_len(0){}
    };

    static PCIRInfo find_pcir(const std::vector& buf){
    PCIRInfo info;
    for(size_t off=0; off+0x14<=buf.size(); ++off){
    if (match_at(buf, off, (const uint8_t*)PCIR_SIG, 4)){
    info.found=true; info.offset=off;
    info.vendor_id = (uint16_t)(buf[off+4] | (uint16_t(buf[off+5])<<8));
    info.device_id = (uint16_t)(buf[off+6] | (uint16_t(buf[off+7])<<8));
    uint16_t len512 = (uint16_t)(buf[off+0x10] | (uint16_t(buf[off+0x11])<<8));
    if (len512) info.image_len = (size_t)len512 * 512u;
    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";
    case VENDOR_VMWARE: return "VMware";
    default: return "Unknown";
    }
    }

    // -------------------------- Heurystyka tabel WH ------------------------------
    struct Entry { size_t off; uint16_t w; uint16_t h; Entry():off(0),w(0),h(0){} };
    struct VesaCluster{ size_t start, stride; std::vector items; VesaCluster():start(0),stride(0){} };

    static inline uint16_t rd16LE(const std::vector& b, size_t o){
    if (o+1 >= b.size()) return 0; return (uint16_t)(b[o] | (uint16_t(b[o+1])<<8));
    }

    struct WH { uint16_t w,h; };
    static const WH kCommonRes[] = {
    {320,200},{320,240},{400,300},{512,384},{640,400},{640,480},
    {800,600},{1024,768},{1280,1024},{1400,1050},{1600,1200},{2048,1536},
    {1280,800},{1440,900},{1680,1050},{1920,1200},{1024,576},{1360,768},{1366,768}
    };

    static bool is_common_res(uint16_t w, uint16_t h){
    for (size_t i=0;i if (kCommonRes .w==w && kCommonRes .h==h) return true;
    return false;
    }

    static bool read_wh(const std::vector& buf, size_t off, uint16_t& w, uint16_t& h){
    if (off+3 >= buf.size()) return false;
    w = rd16LE(buf, off); h = rd16LE(buf, off+2); return true;
    }

    static std::vector find_vesa_clusters(const std::vector& buf){
    std::vector out;
    const size_t strides[] = {4,6,8,9,10,12,16,20,24,28,32};
    const size_t max_span = 4096;
    size_t i=0;
    while(i+4<=buf.size()){
    bool advanced=false;
    for(size_t si=0; si 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;

    VesaCluster cl; cl.start=i; cl.stride=s;
    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;
    Entry e; e.off=j; e.w=ww; e.h=hh; cl.items.push_back(e);
    uniq.insert((uint32_t(ww)<<16)|hh);
    j+=s;
    }
    if (cl.items.size()>=3 && uniq.size()>=2){
    out.push_back(cl); advanced=true; i=j; break;
    }
    }
    if (!advanced) ++i;
    }
    struct ByStart { bool operator()(const VesaCluster& A, const VesaCluster& B) const { return A.start std::sort(out.begin(), out.end(), ByStart());
    return out;
    }

    // ------------------------------ Generator ------------------------------------
    struct Timing {
    uint16_t h_active, h_front, h_sync, h_back, h_total;
    uint16_t v_active, v_front, v_sync, v_back, v_total;
    double pixclk_mhz;
    bool pos_hsync; bool pos_vsync;
    Timing():h_active(0),h_front(0),h_sync(0),h_back(0),h_total(0),
    v_active(0),v_front(0),v_sync(0),v_back(0),v_total(0),
    pixclk_mhz(0.0),pos_hsync(false),pos_vsync(false){}
    };

    static uint16_t round_to(uint16_t v, uint16_t gran){ return (uint16_t)((v/gran)*gran); }

    // CVT-RB v1 (LCD, często OK także na D-Sub): +H, -V
    static void gen_cvt_rb(uint16_t w, uint16_t h, double hz, Timing& t){
    const uint16_t CELL=8;
    t.h_active = round_to(w, CELL);
    t.v_active = h;
    t.h_front=48; t.h_sync=32; t.h_back=80;
    t.h_total = (uint16_t)(t.h_active + t.h_front + t.h_sync + t.h_back);
    t.v_front=3; t.v_sync=5; t.v_back=23;
    t.v_total = (uint16_t)(t.v_active + t.v_front + t.v_sync + t.v_back);
    t.pixclk_mhz = (double)t.h_total * (double)t.v_total * hz / 1.0e6;
    t.pos_hsync=true; t.pos_vsync=false;
    }

    // GTF classic (uprościłem pod 60 Hz; polaryzacje zwykle -H,-V)
    static void gen_gtf_simple(uint16_t w, uint16_t h, double hz, Timing& t){
    const uint16_t CELL=8; const double HSYNC_PCT=8.0;
    double hblank_pct=24.0; if (w<=800) hblank_pct=20.0; if (w>=1280) hblank_pct=25.0;

    t.h_active=round_to(w,CELL); t.v_active=h;
    uint16_t htotal = (uint16_t)round_to((uint16_t)(t.h_active + t.h_active*hblank_pct/100.0), CELL);
    uint16_t hsync = round_to((uint16_t)(htotal*(HSYNC_PCT/100.0)), CELL);
    uint16_t hfront = round_to((uint16_t)(t.h_active*0.023), CELL); if (hfront uint16_t hback = (uint16_t)(htotal - t.h_active - hfront - hsync);
    t.h_front=hfront; t.h_sync=hsync; t.h_back=hback; t.h_total=htotal;

    t.v_front=3; t.v_sync=6; uint16_t vblank_total=40; if (h>=1000) vblank_total=42;
    t.v_back = (uint16_t)(vblank_total - t.v_front - t.v_sync);
    t.v_total = (uint16_t)(t.v_active + t.v_front + t.v_sync + t.v_back);

    t.pixclk_mhz = (double)t.h_total * (double)t.v_total * hz / 1.0e6;
    t.pos_hsync=false; t.pos_vsync=false;
    }

    static bool parse_wxh_hz(const char* s, uint16_t& w, uint16_t& h, double& hz){
    if (!s) return false;
    const char* x = strchr(s,'x'); if (!x) x=strchr(s,'X'); if (!x) return false;
    const char* at = strchr(x+1,'@');
    std::string sw(s, x-s), sh, sf("60");
    if (at){ sh.assign(x+1, at-(x+1)); sf.assign(at+1); } else { sh.assign(x+1); }
    char* e=0; long wl=strtol(sw.c_str(),&e,10); if (!sw.size() || (e&&*e)) return false;
    e=0; long hl=strtol(sh.c_str(),&e,10); if (!sh.size() || (e&&*e)) return false;
    e=0; double fr=strtod(sf.c_str(),&e); if (!sf.size() || (e&&*e)) return false;
    if (wl<1||wl>65535||hl<1||hl>65535||fr<=10||fr>240) return false;
    w=(uint16_t)wl; h=(uint16_t)hl; hz=fr; return true;
    }

    // ---------- Druki generatora ----------
    static void print_timing_summary(const Timing& t, const char* stdname, const char* label, double hz){
    std::cout<<"[TIMING] "< < std::cout<<" H: act="< std::cout<<" V: act="< std::cout<<" Polarity: "<<(t.pos_hsync?"+H":"-H")<<" "<<(t.pos_vsync?"+V":"-V")<<"\n";
    }

    static void print_timing_raw(const Timing& t, const char* stdname, const char* label, double hz){
    uint16_t pclk10 = (uint16_t)(t.pixclk_mhz*100.0 + 0.5);
    uint16_t hblank = (uint16_t)(t.h_total - t.h_active);
    uint16_t vblank = (uint16_t)(t.v_total - t.v_active);

    std::cout<<"RAW "< std::cout<<" pixel_clock_MHz="< < std::cout< std::cout<<" V: active="< std::cout<<" polarity_h="<<(t.pos_hsync?"+":"-")<<", polarity_v="<<(t.pos_vsync?"+":"-")<<"\n";

    std::cout<<" LE16 hex (LSB MSB):\n";
    struct P { const char* n; uint16_t v; } Ptab[] = {
    {"Hactive", t.h_active}, {"Hfront", t.h_front}, {"Hsync", t.h_sync}, {"Hback", t.h_back}, {"Htotal", t.h_total},
    {"Vactive", t.v_active}, {"Vfront", t.v_front}, {"Vsync", t.v_sync}, {"Vback", t.v_back}, {"Vtotal", t.v_total}
    };
    for (size_t i=0;i uint8_t lo = (uint8_t)(Ptab .v & 0xFF), hi = (uint8_t)((Ptab .v>>8) & 0xFF);
    std::cout<<" "< <<" "< }
    }

    static void print_modeline(const Timing& t, const char* label, double hz, bool posH, bool posV){
    int hss = t.h_active + t.h_front, hse = hss + t.h_sync;
    int vss = t.v_active + t.v_front, vse = vss + t.v_sync;
    std::cout<<"Modeline \""< < < < <<(posH?" +HSync":" -HSync")<<(posV?" +VSync":" -VSync")<<"\n";
    }

    static void print_edid_dtd(const Timing& t){
    uint16_t pclk10 = (uint16_t)(t.pixclk_mhz * 100.0 + 0.5);
    uint16_t ha = t.h_active, hb = (uint16_t)(t.h_total - t.h_active);
    uint16_t hfp = t.h_front, hspw = t.h_sync;
    uint16_t va = t.v_active, vb = (uint16_t)(t.v_total - t.v_active);
    uint16_t vfp = t.v_front, vspw = t.v_sync;

    uint8_t d[18]; ::memset(d,0,18);
    d[0] = (uint8_t)(pclk10 & 0xFF); d[1] = (uint8_t)((pclk10>>8)&0xFF);
    d[2] = (uint8_t)(ha & 0xFF); d[3] = (uint8_t)(hb & 0xFF);
    d[4] = (uint8_t)(((ha>>8)&0xF) | (((hb>>8)&0xF)<<4));
    d[5] = (uint8_t)(va & 0xFF); d[6] = (uint8_t)(vb & 0xFF);
    d[7] = (uint8_t)(((va>>8)&0xF) | (((vb>>8)&0xF)<<4));
    d[8] = (uint8_t)(hfp & 0xFF); d[9] = (uint8_t)(hspw & 0xFF);
    d[10]= (uint8_t)(((hfp>>8)&0x3) | (((hspw>>8)&0x3)<<2) | ((vfp&0x3)<<4) | ((vspw&0x3)<<6));
    d[11]= (uint8_t)(vfp & 0xFF); d[12]= (uint8_t)(vspw & 0xFF);
    d[17]= (t.pos_hsync?(1<<1):0) | (t.pos_vsync?(1<<2):0);

    std::cout<<"EDID DTD (18B): ";
    for (int i=0;i<18;++i)
    std::cout< std::cout<}

    // ------------------------------ NV patcher -----------------------------------
    // Empiryczny format 32B z Twojego ROM (NV4x)
    struct NV32 {
    uint16_t h_act, v_act;
    uint16_t h_tot, v_tot;
    uint16_t h_fp, v_fp;
    uint16_t h_sync,v_sync;
    uint16_t h_bp, v_bp;
    uint16_t pclk10; // pixel clock w jednostkach 10 kHz
    uint8_t flags; // bit0: +H, bit1: +V
    uint8_t rsv[9]; // padding do 32 bajtów
    };

    static void wr16(std::vector& b, size_t off, uint16_t v){ b[off]=(uint8_t)(v&0xFF); b[off+1]=(uint8_t)(v>>8); }

    static void nv32_from_timing(const Timing& t, NV32& n){
    ::memset(&n,0,sizeof(n));
    n.h_act = t.h_active; n.v_act = t.v_active;
    n.h_tot = t.h_total; n.v_tot = t.v_total;
    n.h_fp = t.h_front; n.v_fp = t.v_front;
    n.h_sync = t.h_sync; n.v_sync = t.v_sync;
    n.h_bp = t.h_back; n.v_bp = t.v_back;
    n.pclk10 = (uint16_t)(t.pixclk_mhz*100.0 + 0.5);
    n.flags = (t.pos_hsync?1:0) | (t.pos_vsync?2:0);
    }

    static void nv32_write(std::vector& b, size_t off, const NV32& n){
    wr16(b, off+0, n.h_act); wr16(b, off+2, n.v_act);
    wr16(b, off+4, n.h_tot); wr16(b, off+6, n.v_tot);
    wr16(b, off+8, n.h_fp); wr16(b, off+10, n.v_fp);
    wr16(b, off+12, n.h_sync); wr16(b, off+14, n.v_sync);
    wr16(b, off+16, n.h_bp); wr16(b, off+18, n.v_bp);
    wr16(b, off+20, n.pclk10);
    b[off+22]=n.flags;
    for(int i=0;i<9;++i) b[off+23+i]=0x00;
    }

    static bool find_first_nv_pattern(const std::vector& buf, size_t& pat_off){
    for(size_t i=0; i if (match_at(buf,i,NVIDIA_PATTERN,sizeof(NVIDIA_PATTERN))){ pat_off=i; return true; }
    return false;
    }
    static bool find_empty_slot32(const std::vector& buf, size_t pat_off, size_t& slot){
    size_t limit = (pat_off+513<=buf.size())? (pat_off+513) : buf.size();
    for(size_t o=pat_off; o+31 if (buf[o]==0x00 && buf[o+1]==0x00){ slot=o; return true; }
    }
    return false;
    }

    static uint8_t checksum_mod256(const std::vector& b, size_t len){
    uint32_t s=0; for(size_t i=0;i}
    static void fix_checksum(std::vector& b, size_t len){
    uint8_t s = checksum_mod256(b,len);
    if (s==0) return;
    size_t last = (len? len-1 : 0);
    b[last] = (uint8_t)((b[last] + (256 - s)) & 0xFF);
    }

    static bool do_nv_patch(std::vector& buf, const PCIRInfo& pcir, const Timing& t,
    size_t forced_slot, bool have_slot, bool force_overwrite, size_t& used_slot){
    size_t slot=0, pat=0;
    if (have_slot){
    slot = forced_slot;
    if (slot+31 >= buf.size()) { std::cerr<<"[ERR] --slot poza plikiem\n"; return false; }
    if (!force_overwrite && !(buf ==0x00 && buf ==0x00)){
    std::cerr<<"[ERR] --slot niepusty; dodaj --force aby nadpisać\n"; return false;
    }
    } else {
    if (!find_first_nv_pattern(buf,pat)){ std::cerr<<"[ERR] NVIDIA pattern nie znaleziony\n"; return false; }
    if (!find_empty_slot32(buf,pat,slot)){ std::cerr<<"[ERR] Brak wolnego 32B slotu w pobliżu 0x"< }

    NV32 n; nv32_from_timing(t,n);
    nv32_write(buf, slot, n);
    used_slot = slot;

    size_t fixlen = pcir.image_len? std::min(pcir.image_len, buf.size()) : buf.size();
    fix_checksum(buf, fixlen);
    return true;
    }

    // ---------------------------------- main -------------------------------------
    int main(int argc, const char* argv[]){
    std::string filepath;

    for (int i=1;i std::string a = argv ?argv :"";
    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_c(argv[++i]); g_cfg.dump_length=parse_number_c(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_c(argv[++i]);
    } else if (a=="--print-offsets"){
    g_cfg.print_offsets=true;
    } else if (a=="--gen"){
    if (i+1>=argc){ print_usage(argv[0]); return 2; }
    uint16_t w=0,h=0; double hz=60.0;
    if (!parse_wxh_hz(argv[++i], w, h, hz)){ std::cerr<<"Bad --gen format. Use WxH@Hz\n"; return 2; }
    g_cfg.gen_on=true; g_cfg.gen_w=w; g_cfg.gen_h=h; g_cfg.gen_hz=hz;
    } else if (a=="--std"){
    if (i+1>=argc){ print_usage(argv[0]); return 2; }
    std::string s = argv[++i]?argv :"";
    for (size_t k=0;k='A'&&c<='Z') s[k]=(char)(c-'A'+'a'); }
    if (s!="gtf" && s!="cvt-rb"){ std::cerr<<"--std must be gtf or cvt-rb\n"; return 2; }
    g_cfg.gen_std=s;
    } else if (a=="--name"){
    if (i+1>=argc){ print_usage(argv[0]); return 2; }
    g_cfg.gen_name = argv[++i]?argv :"custom";
    } else if (a=="--emit"){
    if (i+1>=argc){ print_usage(argv[0]); return 2; }
    std::string e = argv[++i]?argv :"summary";
    for (size_t k=0;k='A'&&c<='Z') e[k]=(char)(c-'A'+'a'); }
    if (e=="all") g_cfg.emit_all=true;
    else if (e=="summary") g_cfg.emit_summary=true;
    else if (e=="raw") g_cfg.emit_raw=true;
    else if (e=="dtd") g_cfg.emit_dtd=true;
    else if (e=="modeline") g_cfg.emit_modeline=true;
    else if (e=="ps") g_cfg.emit_ps=true;
    else { std::cerr<<"--emit: summary|raw|dtd|modeline|ps|all\n"; return 2; }
    } else if (a=="--nv-patch"){
    if (i+1>=argc){ print_usage(argv[0]); return 2; }
    uint16_t w=0,h=0; double hz=60.0;
    if (!parse_wxh_hz(argv[++i], w, h, hz)){ std::cerr<<"Bad --nv-patch format. Use WxH@Hz\n"; return 2; }
    g_cfg.nv_patch=true; g_cfg.gen_on=true; g_cfg.gen_w=w; g_cfg.gen_h=h; g_cfg.gen_hz=hz;
    } else if (a=="--slot"){
    if (i+1>=argc){ print_usage(argv[0]); return 2; }
    g_cfg.have_slot=true; g_cfg.slot_off = parse_number_c(argv[++i]);
    } else if (a=="--force"){
    g_cfg.nv_force=true;
    } else if (a=="--write"){
    if (i+1>=argc){ print_usage(argv[0]); return 2; }
    g_cfg.out_path = argv[++i]?argv :"";
    } else if (!a.empty() && a[0]=='-'){
    print_usage(argv[0]); return 2;
    } else {
    filepath=a;
    }
    }

    // Generator używany także przez --nv-patch; jeśli brak pliku i chodzi tylko o generator:
    if ((g_cfg.gen_on || g_cfg.emit_all || g_cfg.emit_raw || g_cfg.emit_dtd || g_cfg.emit_modeline || g_cfg.emit_ps) && filepath.empty() && !g_cfg.nv_patch){
    Timing t;
    if (g_cfg.gen_std=="cvt-rb") gen_cvt_rb(g_cfg.gen_w, g_cfg.gen_h, g_cfg.gen_hz, t);
    else gen_gtf_simple(g_cfg.gen_w, g_cfg.gen_h, g_cfg.gen_hz, t);
    if (g_cfg.emit_all || g_cfg.emit_summary) print_timing_summary(t, g_cfg.gen_std.c_str(), g_cfg.gen_name.c_str(), g_cfg.gen_hz);
    if (g_cfg.emit_all || g_cfg.emit_raw) print_timing_raw (t, g_cfg.gen_std.c_str(), g_cfg.gen_name.c_str(), g_cfg.gen_hz);
    if (g_cfg.emit_all || g_cfg.emit_dtd) print_edid_dtd (t);
    if (g_cfg.emit_all || g_cfg.emit_modeline) print_modeline (t, g_cfg.gen_name.c_str(), g_cfg.gen_hz, t.pos_hsync, t.pos_vsync);
    if (g_cfg.emit_all || g_cfg.emit_ps) {
    int hss=t.h_active+t.h_front, hse=hss+t.h_sync, vss=t.v_active+t.v_front, vse=vss+t.v_sync;
    std::cout<<"PowerStrip timing: "< < <<" ("< }
    return 0;
    }

    if (filepath.empty()){ print_usage(argv[0]); return 1; }

    std::cout<<"Attempting to open "< 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; }
    size_t length=(size_t)end; f.seekg(0,std::ios::beg);
    std::vector buf(length);
    if (length){
    f.read((char*)&buf[0], (std::streamsize)length);
    if ((size_t)f.gcount()!=length){ std::cerr<<"Error: could not read full file\n"; return 1; }
    }
    std::cout<<"Length: "< 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<<" PCIR at 0x"< <<" -> Vendor: 0x"< <<", Device: 0x"< if (pcir.image_len) std::cout<<" ROM image length (from PCIR): "< } else {
    std::cout<<"[WARN] PCIR not found – vendor unknown\n";
    }

    if (!g_cfg.vendor_only){
    // Wzorzec NVIDIA i puste sloty 32B
    int nNV=0;
    for (size_t idx=0; idx if (match_at(buf, idx, NVIDIA_PATTERN, sizeof(NVIDIA_PATTERN))){
    ++nNV;
    std::cout<<"Found "< size_t limit = sminz(idx + (size_t)513, length);
    for (size_t idy=idx; idy+1 if (buf ==0x00 && buf ==0x00){
    std::cout<<"\tEmpty Table at 0x"< }
    }
    }
    }

    // Klastry WH
    std::vector clusters = find_vesa_clusters(buf);
    for (size_t ci=0; ci const VesaCluster& cl = clusters[ci];
    std::cout<<"Probable VESA resolution table #"<<(ci+1)
    <<" at 0x"< std::set seen; int shown=0;
    for (size_t k=0;k uint16_t w=cl.items[k].w, h=cl.items[k].h;
    uint32_t key=(uint32_t(w)<<16)|h;
    if (!seen.insert(key).second) continue;
    std::cout<<" - "< if (g_cfg.print_offsets) std::cout<<" (at 0x"< std::cout<<"\n";
    if (++shown>=12) break;
    }
    }
    }

    // Przygotuj timing (generator) gdy trzeba
    Timing t;
    if (g_cfg.gen_on || g_cfg.nv_patch){
    if (g_cfg.gen_std=="cvt-rb") gen_cvt_rb(g_cfg.gen_w, g_cfg.gen_h, g_cfg.gen_hz, t);
    else gen_gtf_simple(g_cfg.gen_w, g_cfg.gen_h, g_cfg.gen_hz, t);
    }
    if (g_cfg.emit_all || g_cfg.emit_summary || g_cfg.emit_raw || g_cfg.emit_dtd || g_cfg.emit_modeline || g_cfg.emit_ps){
    if (g_cfg.emit_all || g_cfg.emit_summary) print_timing_summary(t, g_cfg.gen_std.c_str(), g_cfg.gen_name.c_str(), g_cfg.gen_hz);
    if (g_cfg.emit_all || g_cfg.emit_raw) print_timing_raw (t, g_cfg.gen_std.c_str(), g_cfg.gen_name.c_str(), g_cfg.gen_hz);
    if (g_cfg.emit_all || g_cfg.emit_dtd) print_edid_dtd (t);
    if (g_cfg.emit_all || g_cfg.emit_modeline) print_modeline (t, g_cfg.gen_name.c_str(), g_cfg.gen_hz, t.pos_hsync, t.pos_vsync);
    if (g_cfg.emit_all || g_cfg.emit_ps) {
    int hss=t.h_active+t.h_front, hse=hss+t.h_sync, vss=t.v_active+t.v_front, vse=vss+t.v_sync;
    std::cout<<"PowerStrip timing: "< < <<" ("< }
    }

    // Patching NV 32B
    if (g_cfg.nv_patch){
    size_t used_slot=0;
    if (!g_cfg.gen_on){
    std::cerr<<"[ERR] --nv-patch wymaga WxH@Hz (np. --nv-patch 1024x576@60 oraz --std ...)\n";
    return 2;
    }
    if (!do_nv_patch(buf, pcir, t, g_cfg.slot_off, g_cfg.have_slot, g_cfg.nv_force, used_slot)) return 3;
    std::cout<<"[PATCH] NV 32B timing zapisany w 0x"< size_t fixlen = pcir.image_len? std::min(pcir.image_len, buf.size()) : buf.size();
    std::cout<<"[CHECKSUM] Sum over "< <
    if (g_cfg.out_path.empty()){
    std::cerr<<"[WARN] Brak --write out.rom – nie zapisano pliku.\n";
    } else {
    std::ofstream out(g_cfg.out_path.c_str(), std::ios::binary);
    if (!out){ std::cerr<<"[ERR] cannot create "< out.write((const char*)&buf[0], (std::streamsize)buf.size());
    if (!out){ std::cerr<<"[ERR] write failed\n"; return 4; }
    std::cout<<"[OK] Zapisano "< }
    }

    return 0;
    }
    Bezpośrednia odpowiedź
    - Masz rację: kontynuujemy wariant „MS Visual C++ 2005 (MSVC8, C++03)”. Poniżej daję pełny, samodzielny plik ana_vc8.cpp zgodny z Twoim szkieletem z posta #56, uzupełniony o trzy tryby patchowania:
    1) full – podmiana wpisu „9B” (tabela 0x2E…) i dwóch bloków 32B (8bpp/16bpp),
    2) res-only – wyłącznie wpis „9B”,
    3) timings-only – wyłącznie bloki 32B (8bpp/16bpp).
    - Kompilacja (MSVC 2005): cl /O2 /EHsc /MT /W3 ana_vc8.cpp
    - Przykład użycia (1024x576@60 CVT-RB, pełna podmiana):
    ana_vc8.exe --nv-patch 1024x576@60 --std cvt-rb --mode full --res9-off 0x2E2E --tim8-off 0x94B3 --tim16-off 0x94D3 --write 6200_mod.rom
    Dla innych offsetów podstaw swoje wartości (np. 0x9513/0x9573).
    - Uwaga: zapisuje checksumę ROM (mod 256) po długości PCIR.ImageLength, a gdy brak – po całym pliku.

    Pełny kod (MSVC8, C++03, jeden plik)

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Notatki techniczne i zgodność z wcześniejszym wątkiem
    - Mapowanie 32B jest zgodne ze wzorcem NVIDIA_PATTERN, który pokrywał się z Twoim hexdumpem (np. 1024×768@60 → końcowe LE16 = 0x1964 dla 65.00 MHz w jednostkach 10 kHz).
    - Bajt flag przed 0xFF jest parametryzowany; dla „drugiego” wpisu (odpowiednik 16bpp/ID 148h) domyślnie 0x11, jak w Twoich bajtach.
    - Wpis „9B” (tabela 0x2E…) programowo zmieniam ostrożnie tylko W/H (dwa LE16). Jeśli chcesz automatycznej podmiany całego 9‑bajtowego rekordu pod konkretny format – podeślij proszę surowe 9B z ROM (przed i po), dorobię builder analogiczny do build_nv32_blob().
    - Tryby:
    - full: edycja 9B + dwa bloki 32B,
    - res-only: tylko 9B (zwykle sens na DVI),
    - timings-only: tylko 32B (sygnał fizyczny się zmienia, ID VESA pozostaje stałe).
    - Checksum: modyfikuję ostatni bajt w granicach PCIR.ImageLength (lub całego pliku, gdy PCIR nie podaje długości), aby suma mod 256 = 0.

    Prośba o doprecyzowanie
    - Potwierdź dokładne offsety u Ciebie: res9 (np. 0x2E2E) oraz bloki 32B (0x94B3/0x94D3 albo 0x9513/0x9573). Wtedy wstawię w odpowiedzi predefiniowane komendy „gotowe do wklejenia”.
    - Jeśli wolisz jeden klik: mogę dorobić do powyższego kodu szukanie i podmianę „po sygnaturze” dla Twoich oryginalnych 32B (tak jak robiłem w wersji Python), ale do tego potrzebuję potwierdzenia surowych wzorców ORIG_TIMING_A/B z Twojego 6200DSUB.ROM.
    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.
  • #5 21788005
    Gelip
    Poziom 36  
    Posty: 5245
    Pomógł: 324
    Ocena: 611
    @ElektrodaBot
    Czemu teraz nie wykrywa tabeli w okolicy 0x9... czyli tabeli 32-B ?
    anaw6 --print-offsets 6200DSUB.ROM
    Attempting to open 6200DSUB.ROM
    [PCIR] vendor=0x10de (NVIDIA) device=0x163, image_len=63488 bytes @ 0x108
    [CLUSTER] start=0x2dc2, stride=9, items=3
      [ 0]  640x400 @ 0x2dc2
      [ 1]  640x480 @ 0x2dcb
      [ 2]  640x480 @ 0x2dd4
    [CLUSTER] start=0x2def, stride=9, items=13
      [ 0]  800x600 @ 0x2def
      [ 1]  800x600 @ 0x2df8
      [ 2]  1024x768 @ 0x2e01
      [ 3]  1024x768 @ 0x2e0a
      [ 4]  1280x1024 @ 0x2e13
      [ 5]  1280x1024 @ 0x2e1c
      [ 6]  1280x800 @ 0x2e25
      [ 7]  1400x1050 @ 0x2e2e
      [ 8]  1440x900 @ 0x2e37
      [ 9]  1600x1200 @ 0x2e40
      [10]  1680x1050 @ 0x2e49
      [11]  1920x1200 @ 0x2e52
      [12]  2048x1536 @ 0x2e5b


    Wersja pierwsza z poprzedniego tematu wykrywała:
    anaw --print-offsets 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)
            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, endian=LE, delta=2, score=38.0)
        - 640x400  (at 0x2dc2)
        - 640x480  (at 0x2dcb)
        - 640x480  (at 0x2dd4)
    Probable VESA resolution table #2 at 0x2def (stride=9, entries=13, endian=LE, delta=2, score=103.5)
        - 800x600  (at 0x2def)
        - 800x600  (at 0x2df8)
        - 1024x768  (at 0x2e01)
        - 1024x768  (at 0x2e0a)
        - 1280x1024  (at 0x2e13)
        - 1280x1024  (at 0x2e1c)
        - 1280x800  (at 0x2e25)
        - 1400x1050  (at 0x2e2e)
        - 1440x900  (at 0x2e37)
        - 1600x1200  (at 0x2e40)
        - 1680x1050  (at 0x2e49)
        - 1920x1200  (at 0x2e52)
        - 2048x1536  (at 0x2e5b)
    Probable VESA resolution table #3 at 0x94b3 (stride=32, entries=5, endian=LE, delta=14, score=34.0)
        - 1024x768  (at 0x94b3)
        - 1024x768  (at 0x94d3)
        - 1280x1024  (at 0x94f3)
        - 1400x1050  (at 0x9513)
        - 1600x1200  (at 0x9533)
    Probable VESA resolution table #4 at 0x9573 (stride=32, entries=4, endian=LE, delta=14, score=30.0)
        - 1400x1050  (at 0x9573)
        - 800x600  (at 0x9593)
        - 1280x800  (at 0x95b3)
        - 2048x1536  (at 0x95d3)
    Correct number of finds
    Mod should be working


    Tak samo nie wykrywa wszystkiego teraz w biosie od pierwszej lepszej karty graficznej ATI:
    anaw6 --print-offsets ati.bin
    Attempting to open ati.bin
    [PCIR] vendor=0x1002 (ATI/AMD) device=0x677b, image_len=65536 bytes @ 0x1f0
    [CLUSTER] start=0x26da, stride=8, items=11
      [ 0]  800x600 @ 0x26da
      [ 1]  800x600 @ 0x26e2
      [ 2]  800x600 @ 0x26ea
      [ 3]  800x600 @ 0x26f2
      [ 4]  1024x768 @ 0x26fa
      [ 5]  1024x768 @ 0x2702
      [ 6]  1024x768 @ 0x270a
      [ 7]  1280x1024 @ 0x2712
      [ 8]  640x480 @ 0x271a
      [ 9]  640x480 @ 0x2722
      [10]  640x480 @ 0x272a

    a pierwsza wersja wykrywa wiele więcej:
    D:\Pobieranie>anaw --print-offsets ati.bin
    Attempting to open ati.bin
    Length: 131072 bytes
    [INFO] PCIR at 0x1f0 -> Vendor: 0x1002 (ATI/AMD), Device: 0x677b
    [INFO] ROM image length (from PCIR): 65536 bytes
    Probable VESA resolution table #1 at 0x183c (stride=20, entries=4, endian=LE, delta=8, score=28.0)
        - 640x400  (at 0x183c)
        - 640x400  (at 0x1850)
        - 640x400  (at 0x1864)
        - 640x480  (at 0x1878)
    Probable VESA resolution table #2 at 0x26da (stride=8, entries=12, endian=LE, delta=2, score=76.3)
        - 800x600  (at 0x26da)
        - 800x600  (at 0x26e2)
        - 800x600  (at 0x26ea)
        - 800x600  (at 0x26f2)
        - 1024x768  (at 0x26fa)
        - 1024x768  (at 0x2702)
        - 1024x768  (at 0x270a)
        - 1280x1024  (at 0x2712)
        - 640x480  (at 0x271a)
        - 640x480  (at 0x2722)
        - 640x480  (at 0x272a)
        - 720x400  (at 0x2732)
    Probable VESA resolution table #3 at 0xa888 (stride=28, entries=3, endian=LE, delta=4, score=30.3)
        - 320x200  (at 0xa888)
        - 320x240  (at 0xa8a4)
        - 512x384  (at 0xa8c0)
    Probable VESA resolution table #4 at 0xa8f8 (stride=28, entries=13, endian=LE, delta=4, score=109.3)
        - 640x400  (at 0xa8f8)
        - 640x480  (at 0xa914)
        - 720x400  (at 0xa930)
        - 800x600  (at 0xa94c)
        - 1024x768  (at 0xa968)
        - 1152x864  (at 0xa984)
        - 1280x960  (at 0xa9a0)
        - 1280x1024  (at 0xa9bc)
        - 1400x1050  (at 0xa9d8)
        - 1600x1200  (at 0xa9f4)
        - 1792x1344  (at 0xaa10)
        - 1856x1392  (at 0xaa2c)
        - 1920x1440  (at 0xaa48)
  • #6 21788012
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8881
    Pomógł: 364
    Ocena: 954
    LABEL_AI_GENERATED
    Gelip napisał:
    @ElektrodaBot
    Czemu teraz nie wykrywa tabeli w okolicy 0x9... czyli tabeli 32-B ?
    anaw6 --print-offsets 6200DSUB.ROM
    Attempting to open 6200DSUB.ROM
    [PCIR] vendor=0x10de (NVIDIA) device=0x163, image_len=63488 bytes @ 0x108
    [CLUSTER] start=0x2dc2, stride=9, items=3
    [ 0] 640x400 @ 0x2dc2
    [ 1] 640x480 @ 0x2dcb
    [ 2] 640x480 @ 0x2dd4
    [CLUSTER] start=0x2def, stride=9, items=13
    [ 0] 800x600 @ 0x2def
    [ 1] 800x600 @ 0x2df8
    [ 2] 1024x768 @ 0x2e01
    [ 3] 1024x768 @ 0x2e0a
    [ 4] 1280x1024 @ 0x2e13
    [ 5] 1280x1024 @ 0x2e1c
    [ 6] 1280x800 @ 0x2e25
    [ 7] 1400x1050 @ 0x2e2e
    [ 8] 1440x900 @ 0x2e37
    [ 9] 1600x1200 @ 0x2e40
    [10] 1680x1050 @ 0x2e49
    [11] 1920x1200 @ 0x2e52
    [12] 2048x1536 @ 0x2e5b

    Wersja pierwsza z poprzedniego tematu wykrywała:
    anaw --print-offsets 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)
    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, endian=LE, delta=2, score=38.0)
    - 640x400 (at 0x2dc2)
    - 640x480 (at 0x2dcb)
    - 640x480 (at 0x2dd4)
    Probable VESA resolution table #2 at 0x2def (stride=9, entries=13, endian=LE, delta=2, score=103.5)
    - 800x600 (at 0x2def)
    - 800x600 (at 0x2df8)
    - 1024x768 (at 0x2e01)
    - 1024x768 (at 0x2e0a)
    - 1280x1024 (at 0x2e13)
    - 1280x1024 (at 0x2e1c)
    - 1280x800 (at 0x2e25)
    - 1400x1050 (at 0x2e2e)
    - 1440x900 (at 0x2e37)
    - 1600x1200 (at 0x2e40)
    - 1680x1050 (at 0x2e49)
    - 1920x1200 (at 0x2e52)
    - 2048x1536 (at 0x2e5b)
    Probable VESA resolution table #3 at 0x94b3 (stride=32, entries=5, endian=LE, delta=14, score=34.0)
    - 1024x768 (at 0x94b3)
    - 1024x768 (at 0x94d3)
    - 1280x1024 (at 0x94f3)
    - 1400x1050 (at 0x9513)
    - 1600x1200 (at 0x9533)
    Probable VESA resolution table #4 at 0x9573 (stride=32, entries=4, endian=LE, delta=14, score=30.0)
    - 1400x1050 (at 0x9573)
    - 800x600 (at 0x9593)
    - 1280x800 (at 0x95b3)
    - 2048x1536 (at 0x95d3)
    Correct number of finds
    Mod should be working

    Tak samo nie wykrywa wszystkiego teraz w biosie od pierwszej lepszej karty graficznej ATI:
    anaw6 --print-offsets ati.bin
    Attempting to open ati.bin
    [PCIR] vendor=0x1002 (ATI/AMD) device=0x677b, image_len=65536 bytes @ 0x1f0
    [CLUSTER] start=0x26da, stride=8, items=11
    [ 0] 800x600 @ 0x26da
    [ 1] 800x600 @ 0x26e2
    [ 2] 800x600 @ 0x26ea
    [ 3] 800x600 @ 0x26f2
    [ 4] 1024x768 @ 0x26fa
    [ 5] 1024x768 @ 0x2702
    [ 6] 1024x768 @ 0x270a
    [ 7] 1280x1024 @ 0x2712
    [ 8] 640x480 @ 0x271a
    [ 9] 640x480 @ 0x2722
    [10] 640x480 @ 0x272a
    a pierwsza wersja wykrywa wiele więcej:
    D:\Pobieranie>anaw --print-offsets ati.bin
    Attempting to open ati.bin
    Length: 131072 bytes
    [INFO] PCIR at 0x1f0 -> Vendor: 0x1002 (ATI/AMD), Device: 0x677b
    [INFO] ROM image length (from PCIR): 65536 bytes
    Probable VESA resolution table #1 at 0x183c (stride=20, entries=4, endian=LE, delta=8, score=28.0)
    - 640x400 (at 0x183c)
    - 640x400 (at 0x1850)
    - 640x400 (at 0x1864)
    - 640x480 (at 0x1878)
    Probable VESA resolution table #2 at 0x26da (stride=8, entries=12, endian=LE, delta=2, score=76.3)
    - 800x600 (at 0x26da)
    - 800x600 (at 0x26e2)
    - 800x600 (at 0x26ea)
    - 800x600 (at 0x26f2)
    - 1024x768 (at 0x26fa)
    - 1024x768 (at 0x2702)
    - 1024x768 (at 0x270a)
    - 1280x1024 (at 0x2712)
    - 640x480 (at 0x271a)
    - 640x480 (at 0x2722)
    - 640x480 (at 0x272a)
    - 720x400 (at 0x2732)
    Probable VESA resolution table #3 at 0xa888 (stride=28, entries=3, endian=LE, delta=4, score=30.3)
    - 320x200 (at 0xa888)
    - 320x240 (at 0xa8a4)
    - 512x384 (at 0xa8c0)
    Probable VESA resolution table #4 at 0xa8f8 (stride=28, entries=13, endian=LE, delta=4, score=109.3)
    - 640x400 (at 0xa8f8)
    - 640x480 (at 0xa914)
    - 720x400 (at 0xa930)
    - 800x600 (at 0xa94c)
    - 1024x768 (at 0xa968)
    - 1152x864 (at 0xa984)
    - 1280x960 (at 0xa9a0)
    - 1280x1024 (at 0xa9bc)
    - 1400x1050 (at 0xa9d8)
    - 1600x1200 (at 0xa9f4)
    - 1792x1344 (at 0xaa10)
    - 1856x1392 (at 0xaa2c)
    - 1920x1440 (at 0xaa48)
    Bezpośrednia odpowiedź
    - anaw6 nie „widzi” tabeli 32‑bajtowych timingów w okolicy 0x94xx, bo w tej wersji uprościłeś heurystykę wykrywania do par W/H leżących obok siebie (delta=2). W tabelach NV4x 32B pole Vactive nie leży przy Wactive, tylko pod offsetem +14 w obrębie wpisu (czyli delta=14 przy stride=32). Dodatkowo w anaw6 wypadł blok, który wypisywał trafienia po sygnaturze NVIDIA_PATTERN i z tej ścieżki robił listowanie „tabel 32B”.
    - Analogicznie, mniejsza liczba wykrytych tabel w BIOS‑ie ATI wynika z zawężenia listy „znanych” rozdzielczości (brak m.in. 720×400, 1152×864, 1280×960, 1792×1344, 1856×1392, 1920×1440) oraz z założenia delta=2; w tych BIOS‑ach bywa delta=4/8 przy stride=20/28.
    - Poprawka: przywróć skan po NVIDIA_PATTERN i dodaj skaner klastrów z parametryzowanym delta (co najmniej 2,4,8,14). Uzupełnij też listę kCommonRes o brakujące DMT.

    Szczegółowa analiza i poprawki (MSVC 2005)

    1) Dlaczego zniknęło „Found 1. NVIDIA pattern at 0x94b3 …”
    - W anaw (pierwszej wersji) był jawny skan po 30‑bajtowej sygnaturze NVIDIA_PATTERN i lokalne listowanie 32‑bajtowych slotów w oknie ~512 B od trafienia. W anaw6 ta część została zastąpiona funkcją find_first_nv_pattern używaną tylko przez patcher (do zapisu), a nie przez ścieżkę „--print-offsets”. Stąd brak komunikatów oraz brak późniejszego wnioskowania „tabel 32B”.
    - Twoje hexy z ROM: na 0x94B3 masz dokładnie 32‑bajtowy wpis zaczynający się od 00 04 (=1024), a Vactive 576 leży w tym formacie na off=+14. Jeśli heurystyka przyjmuje „W i H obok siebie” (delta=2), to nie da się tego klastra wykryć.

    2) Dlaczego ATI wykrywa mniej
    - W anaw6 tablica kCommonRes jest mocno okrojona. Tymczasem typowe BIOS‑y ATI/AMD mają „pełny” zestaw DMT (w tym 720×400, 1152×864, 1280×960, 1920×1440, 1792×1344, 1856×1392) oraz alternatywne ułożenia pól (delta=4/8 przy stride=20/28). U Ciebie skan zatrzymuje się na pierwszej „nietrafionej” parze i nie uznaje klastra.

    3) Minimalny zestaw poprawek (do wklejenia)

    A) Uzupełnij znane rozdzielczości (kCommonRes):
    - dopisz: {720,400},{1152,864},{1280,960},{832,624},{1792,1344},{1856,1392},{1920,1440}.

    B) Przywróć drukowanie trafień po sygnaturze NVIDIA i wypis 32B „NV‑klastrów” (delta=14, stride=32):
    - dodaj funkcję skanującą okno ~512 bajtów od sygnatury i rozpoznającą wpisy W=rd16LE(off+0), H=rd16LE(off+14).

    C) Uogólnij wykrywanie „klastrów VESA” na różne delty (2/4/8/14) i istniejące stride (20/28/32 itd.).

    Poniżej gotowe fragmenty do wklejenia (C++03, MSVC8).

    1) Rozszerz kCommonRes:
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    2) Skan NV32 (druk w trybie --print-offsets):
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Wywołaj to w main() w tej samej gałęzi co „--print-offsets” (tak jak było w pierwszej wersji), np. zaraz po wypisaniu klastrów WH:
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    3) Uogólnij wykrywanie „klastrów WH” na różne delty
    – zamień read_wh() na wariant z parametrem delta i dopuść kilka delt:

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    I w main() użyj find_vesa_clusters2 zamiast starego find_vesa_clusters.

    4) Co to zmieni w Twoich plikach
    - 6200DSUB.ROM: znowu zobaczysz „Found … NVIDIA pattern at 0x94b3 …” oraz dwie „NV32” tabele zaczynające się na 0x94B3 i 0x9573, z wpisami m.in. 1024×768, 1280×1024, 1400×1050, 1600×1200 itd.
    - ati.bin: wrócą klastry przy 0x183C (stride=20, delta=8) oraz przy 0xA888 i 0xA8F8 (stride=28, delta=4), a także zaktualizowana tabela przy 0x26DA (stride=8, delta=2). Dodatkowo 720×400 i pozostałe „pełne DMT” nie przerwą skanu.

    5) Drobiazgi diagnostyczne (opcjonalnie)
    - Dodaj do wypisów dla klastrów WH informację o zastosowanej delcie (jeśli w strukturze VesaCluster dopiszesz pole delta).
    - W „NV32” możesz też wypisać od razu pclk10 (rd16LE(off+30)) dla szybkiej sanity‑check.

    Jeśli chcesz, mogę Ci skleić gotową „anaw7.exe” z powyższymi poprawkami pod MSVC 2005 lub przejrzeć Twój bieżący plik ana_vc8.cpp i nanieść patch 1:1.
    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 21788072
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8881
    Pomógł: 364
    Ocena: 954
    LABEL_AI_GENERATED
    Gelip napisał:
    @ElektrodaBot
    Tak, chcę pełny kod MSVC 2005 z dodanymi poprawkami.
    Bezpośrednia odpowiedź
    - Poniżej masz pełny, samodzielny plik ana_vc8.cpp pod MS Visual C++ 2005 (MSVC8, C++03) z poprawkami:
    - przywrócone wykrywanie bloków 32B NV (delta=14, stride=32) po sygnaturze NVIDIA_PATTERN, z wypisem „Found … NVIDIA pattern …/Empty Table …”,
    - uogólnione wyszukiwanie klastrów rozdzielczości (różne stride i delta: 2/4/8/10/12/14/16),
    - rozszerzona lista kCommonRes (pełniejsze DMT),
    - patcher z trybami --mode full|res-only|timings-only, parametrami --res9-off, --tim8-off, --tim16-off, --flag16, poprawą checksumy ROM.
    - Kompilacja (VS2005): cl /O2 /EHsc /MT /W3 ana_vc8.cpp
    - Przykłady:
    - Tylko analiza: ana_vc8.exe --print-offsets 6200DSUB.ROM
    - Pełny patch (1024x576@60, CVT‑RB): ana_vc8.exe 6200DSUB.ROM --nv-patch 1024x576@60 --std cvt-rb --mode full --res9-off 0x2E2E --tim8-off 0x94B3 --tim16-off 0x94D3 --write 6200_mod.rom

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    - Jeżeli chcesz, mogę dorzucić wariant z automatycznym szukaniem wolnego slotu 32B w oknie po NVIDIA_PATTERN (gdy nie podasz --tim8-off/--tim16-off) – ale dla bezpieczeństwa w NV4x rekomenduję jawne offsety, tak jak w Twoich zrzutach (0x94B3/0x94D3 lub 0x9513/0x9573).
    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.
  • #9 21788326
    Gelip
    Poziom 36  
    Posty: 5245
    Pomógł: 324
    Ocena: 611
    @ElektrodaBot
    Popraw kod bo teraz wyświetla dwa razy te same informacje:
    Attempting to open 6200DSUB.ROM
    [PCIR] vendor=0x10de (NVIDIA) device=0x163, image_len=63488 bytes @ 0x108
    [CLUSTER] start=0x2dc2, stride=9, delta=2, items=3
      [ 0]  640x400
      [ 1]  640x480
      [ 2]  640x480
    [CLUSTER] start=0x2def, stride=9, delta=2, items=13
      [ 0]  800x600
      [ 1]  800x600
      [ 2]  1024x768
      [ 3]  1024x768
      [ 4]  1280x1024
      [ 5]  1280x1024
      [ 6]  1280x800
      [ 7]  1400x1050
      [ 8]  1440x900
      [ 9]  1600x1200
      [10]  1680x1050
      [11]  1920x1200
      [12]  2048x1536
    [CLUSTER] start=0x94b3, stride=32, delta=14, items=5
      [ 0]  1024x768
      [ 1]  1024x768
      [ 2]  1280x1024
      [ 3]  1400x1050
      [ 4]  1600x1200
    [CLUSTER] start=0x9573, stride=32, delta=14, items=4
      [ 0]  1400x1050
      [ 1]  800x600
      [ 2]  1280x800
      [ 3]  2048x1536
    Found 1. 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 (NV32) at 0x94b3 (stride=32, entries=5, endian=LE, delta=14)
        - 1024x768  (at 0x94b3)
        - 1024x768  (at 0x94d3)
        - 1280x1024  (at 0x94f3)
        - 1400x1050  (at 0x9513)
        - 1600x1200  (at 0x9533)
    Probable VESA resolution table (NV32) at 0x94d3 (stride=32, entries=4, endian=LE, delta=14)
        - 1024x768  (at 0x94d3)
        - 1280x1024  (at 0x94f3)
        - 1400x1050  (at 0x9513)
        - 1600x1200  (at 0x9533)
    Probable VESA resolution table (NV32) at 0x94f3 (stride=32, entries=3, endian=LE, delta=14)
        - 1280x1024  (at 0x94f3)
        - 1400x1050  (at 0x9513)
        - 1600x1200  (at 0x9533)
    Probable VESA resolution table (NV32) at 0x9513 (stride=32, entries=2, endian=LE, delta=14)
        - 1400x1050  (at 0x9513)
        - 1600x1200  (at 0x9533)
    Probable VESA resolution table (NV32) at 0x9573 (stride=32, entries=4, endian=LE, delta=14)
        - 1400x1050  (at 0x9573)
        - 800x600  (at 0x9593)
        - 1280x800  (at 0x95b3)
        - 2048x1536  (at 0x95d3)
    Probable VESA resolution table (NV32) at 0x9593 (stride=32, entries=3, endian=LE, delta=14)
        - 800x600  (at 0x9593)
        - 1280x800  (at 0x95b3)
        - 2048x1536  (at 0x95d3)
    Probable VESA resolution table (NV32) at 0x95b3 (stride=32, entries=2, endian=LE, delta=14)
        - 1280x800  (at 0x95b3)
        - 2048x1536  (at 0x95d3)
    
  • #10 21788401
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8881
    Pomógł: 364
    Ocena: 954
    LABEL_AI_GENERATED
    Gelip napisał:
    @ElektrodaBot
    Popraw kod bo teraz wyświetla dwa razy te same informacje:
    Attempting to open 6200DSUB.ROM
    [PCIR] vendor=0x10de (NVIDIA) device=0x163, image_len=63488 bytes @ 0x108
    [CLUSTER] start=0x2dc2, stride=9, delta=2, items=3
    [ 0] 640x400
    [ 1] 640x480
    [ 2] 640x480
    [CLUSTER] start=0x2def, stride=9, delta=2, items=13
    [ 0] 800x600
    [ 1] 800x600
    [ 2] 1024x768
    [ 3] 1024x768
    [ 4] 1280x1024
    [ 5] 1280x1024
    [ 6] 1280x800
    [ 7] 1400x1050
    [ 8] 1440x900
    [ 9] 1600x1200
    [10] 1680x1050
    [11] 1920x1200
    [12] 2048x1536
    [CLUSTER] start=0x94b3, stride=32, delta=14, items=5
    [ 0] 1024x768
    [ 1] 1024x768
    [ 2] 1280x1024
    [ 3] 1400x1050
    [ 4] 1600x1200
    [CLUSTER] start=0x9573, stride=32, delta=14, items=4
    [ 0] 1400x1050
    [ 1] 800x600
    [ 2] 1280x800
    [ 3] 2048x1536
    Found 1. 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 (NV32) at 0x94b3 (stride=32, entries=5, endian=LE, delta=14)
    - 1024x768 (at 0x94b3)
    - 1024x768 (at 0x94d3)
    - 1280x1024 (at 0x94f3)
    - 1400x1050 (at 0x9513)
    - 1600x1200 (at 0x9533)
    Probable VESA resolution table (NV32) at 0x94d3 (stride=32, entries=4, endian=LE, delta=14)
    - 1024x768 (at 0x94d3)
    - 1280x1024 (at 0x94f3)
    - 1400x1050 (at 0x9513)
    - 1600x1200 (at 0x9533)
    Probable VESA resolution table (NV32) at 0x94f3 (stride=32, entries=3, endian=LE, delta=14)
    - 1280x1024 (at 0x94f3)
    - 1400x1050 (at 0x9513)
    - 1600x1200 (at 0x9533)
    Probable VESA resolution table (NV32) at 0x9513 (stride=32, entries=2, endian=LE, delta=14)
    - 1400x1050 (at 0x9513)
    - 1600x1200 (at 0x9533)
    Probable VESA resolution table (NV32) at 0x9573 (stride=32, entries=4, endian=LE, delta=14)
    - 1400x1050 (at 0x9573)
    - 800x600 (at 0x9593)
    - 1280x800 (at 0x95b3)
    - 2048x1536 (at 0x95d3)
    Probable VESA resolution table (NV32) at 0x9593 (stride=32, entries=3, endian=LE, delta=14)
    - 800x600 (at 0x9593)
    - 1280x800 (at 0x95b3)
    - 2048x1536 (at 0x95d3)
    Probable VESA resolution table (NV32) at 0x95b3 (stride=32, entries=2, endian=LE, delta=14)
    - 1280x800 (at 0x95b3)
    - 2048x1536 (at 0x95d3)
    Bezpośrednia odpowiedź
    - Duplikaty biorą się stąd, że:
    1) ogólny skaner klastrów (stride/delta) już wykrywa i wypisuje bloki NV32 (stride=32, delta=14),
    2) a skaner „po sygnaturze NVIDIA” dodatkowo ponownie wypisuje te same bloki (i to wielokrotnie – dla każdego przesunięcia 32 B).
    - Poprawka: zostawiamy w skanerze „NVIDIA” wyłącznie komunikaty diagnostyczne „Found … NVIDIA pattern …/Empty Table …”, a listowania tabel NV32 włączamy tylko opcjonalnie (przełącznik --nv32-tables) i deduplikujemy je „runami” (drukujemy raz dla pierwszego wpisu serii).
    - Poniżej wklejki do Twojego ana_vc8.cpp (MSVC 2005, C++03), które usuwają duplikaty i dodają przełącznik --nv32-tables.

    ---

    Wklejki/zmiany w kodzie (MSVC 2005)

    1) Rozszerz strukturę Config (dopisz pole i inicjalizację):
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    2) Parsowanie nowego przełącznika CLI (w pętli argumentów, obok innych opcji):
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    3) Podmień funkcję skanującą po sygnaturze NVIDIA na wersję bez duplikatów:
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    4) Wywołanie w main() – podmień istniejące:
    - Zamiast poprzedniego `scan_and_print_nv32(buf, g_cfg.dump_on_hit_len);`
    - użyj:
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Uwaga:
    - Domyślnie (bez --nv32-tables) zobaczysz:
    - [PCIR] …
    - [CLUSTER] … (w tym stride=32, delta=14 – ogólny skaner)
    - Found … NVIDIA pattern … / Empty Table …
    - i brak powtórzonych „Probable … NV32 …” — czyli zero duplikatów.
    - Jeśli uruchomisz z --nv32-tables, dostaniesz dodatkowo listę NV32, ale tylko raz per „run” (0x94b3 oraz 0x9573 w Twoim ROM-ie), bez „pod-serii” (0x94d3, 0x94f3, …).

    ---

    Przykład po poprawce (bez --nv32-tables)
    - CLUSTER 0x94b3 (stride=32, delta=14) oraz CLUSTER 0x9573 wydrukuje ogólny skaner,
    - „Found 1. NVIDIA pattern at 0x94b3 … / Empty Table …” pojawi się raz, bez powielania list tabel.

    Jeśli chcesz, doślę kompletny, scalony plik ana_vc8.cpp ze wszystkimi wcześniejszymi zmianami i tą poprawką (mieści ~1.5–2k linii komentarzy i kodu), ale powyższe 4 wklejki wystarczą, żeby usunąć duplikaty w Twojej wersji.
    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.
  • #12 21788456
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8881
    Pomógł: 364
    Ocena: 954
    LABEL_AI_GENERATED
    Gelip napisał:
    @ElektrodaBot
    Brakuje chyba opcji do podmiany 32-bitowej głębi czyli --tim32

    Poproszę pełny kod a nie same poprawki.
    Bezpośrednia odpowiedź
    - Dołożyłem obsługę 32-bitowej głębi jako osobny parametr: --tim32-off 0xADDR (plus opcjonalnie --flag32 0xNN).
    - Poniżej pełny, samodzielny plik ana_vc8.cpp (MSVC 2005 / C++03) z:
    - wykrywaniem NV32 (delta=14, stride=32) bez duplikatów, opcjonalnym listowaniem przez --nv32-tables,
    - uogólnionym skanerem klastrów (różne stride i delta),
    - rozszerzonym kCommonRes (DMT),
    - patcherem: --mode full|res-only|timings-only, --res9-off, --tim8-off, --tim16-off, --tim32-off, --flag8/16/32, --slot, --force, --write,
    - generatorem timingów (cvt-rb/gtf) i drukami (summary/raw/dtd/modeline/ps),
    - poprawnym liczeniem i naprawą checksumy (mod256) po PCIR.ImageLength (lub po całym pliku).
    - Kompilacja: cl /O2 /EHsc /MT /W3 ana_vc8.cpp

    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Uwaga do użycia
    - Pełny patch z trzema głębiami, bez duplikatów w listingu NV32:
    - analiza: ana_vc8.exe --print-offsets 6200DSUB.ROM
    - patch: ana_vc8.exe 6200DSUB.ROM --nv-patch 1024x576@60 --std cvt-rb --mode timings-only --tim8-off 0x94B3 --tim16-off 0x94D3 --tim32-off 0x94F3 --flag8 0x11 --flag16 0x11 --flag32 0x11 --write 6200_mod.rom
    - Jeśli chcesz przegląd NV32 przy skanie sygnatury, dodaj --nv32-tables (druk bez duplikatów runów).
    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 21788647
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Posty: 8881
    Pomógł: 364
    Ocena: 954
    LABEL_AI_GENERATED
    Gelip napisał:
    @ElektrodaBot
    Fajne narzędzie wyszło ale niestety to nie pomaga i nadal są ramki bez względu czy patchuję tylko 9B czy 9B i 32B

    Masz jakiś pomysł na to?
    Bezpośrednia odpowiedź
    - Same „ramki” po patchu 9B i 32B nie wynikają z błędu w tablicach, tylko z faktu, że:
    1) sterownik po starcie systemu najczęściej nie korzysta już z VBIOS‑owych timingów (9B/32B), tylko sam generuje przebiegi na CRTC, oraz
    2) na złączu D‑Sub skalowanie/rozciąganie obrazu realizuje monitor (OSD), a nie GPU. Jeśli monitor nie rozciąga nietypowego trybu (np. 1024×576), zobaczysz czarne ramki niezależnie od wpisów w ROM.
    - Realna droga do „pełnego ekranu” to: użyć timingów rozpoznawanych i skalowanych przez monitor (często GTF lub CVT non‑RB, a nie CVT‑RB), włączyć „Full/Fill” w OSD, ewentualnie zrobić EDID override/Custom Resolution w sterowniku. VBIOS pomaga głównie w pre‑boot/VBE.

    Szczegółowa analiza problemu

    1) Gdzie działają wpisy 9B/32B
    - 9B (lista rozdzielczości) i 32B (timingi NV) są używane przez VBE/INT10 oraz przez BIOS podczas POST. Po załadowaniu sterownika (Windows/Linux) tryb zwykle programuje sam sterownik według własnych reguł walidacji (DMT/CTA, EDID, „mode validation”), ignorując Twoje 32B. Dlatego patch „działa” w DOS/vesafb, ale w Windows efektu może nie być.

    2) Dlaczego pojawiają się ramki na D‑Sub
    - LCD na D‑Sub ma własny przetwornik A/D i skaler. Dla trybów „niekanonicznych” (np. 1024×576) część monitorów domyślnie robi centrowanie 1:1, a nie „Full”. Widzisz wtedy czarne marginesy nawet przy poprawnych timingach.
    - CVT‑RB (zredukowane wygaszanie) bywa traktowany „ostrożnie”: wąskie blankingi, polaryzacje +H/−V. Starsze lub wybredne panele na VGA wolą GTF (większy HBlank ~20–30% aktywnego) lub CVT non‑RB. RB potrafi dać czarne ramki, dopóki nie zrobisz „Auto Adjust”/„Full” w OSD.
    - Przy 16:9 na panelu 5:4/4:3 ramki w jednej z osi są nieuniknione, jeśli monitor trzyma proporcje. Do całkowitego wypełnienia wymuszasz w OSD „Full/Fill” (rozciągnięcie bez zachowania AR).

    3) Co jeszcze może blokować efekt
    - Masz spójne wpisy dla wszystkich głębi? Na NV4x te same timingi bywają zdublowane dla 8/16/32 bpp (oddzielne 32B sloty). Jeśli zmienisz 8/16, a sterownik wybierze 32 bpp – efektu nie będzie. Dlatego wprowadziłem w narzędziu --tim8-off / --tim16-off / --tim32-off i osobne flagi.
    - Flagi polaryzacji. Część monitorów lepiej „łapie” −H/−V (GTF). Warto przetestować oba warianty: CVT non‑RB (+H/−V) i GTF (−H/−V).
    - Nietypowe piksle/hz. Niektóre OSD skalują dopiero „znane” DMT (np. 1280×720@60, 848×480@60). 1024×576 nie wszędzie jest skalowane.

    Plan diagnostyczny krok po kroku

    1) Oddziel sterownik od VBIOS
    - Uruchom z czystego DOS/FreeDOS (lub Linux z vesafb/nomodeset) i ustaw swój tryb przez VBE (np. vbetest). Jeśli w tym środowisku dalej są ramki – to kwestia monitora/timingu, nie sterownika.

    2) Zmień rodzinę timingów na „monitor‑friendly”
    - Wygeneruj GTF (nie RB) i przetestuj:
    - ana_vc8 --gen 1024x576@60 --std gtf --emit all
    - Alternatywnie CVT non‑RB (w moim narzędziu domyślnie jest RB, więc wygeneruj GTF lub zwiększ blankingi ręcznie).
    - Podmień 32B we wszystkich trzech głębiach:
    - ana_vc8 6200.rom --nv-patch 1024x576@60 --std gtf --mode timings-only --tim8-off 0x94B3 --tim16-off 0x94D3 --tim32-off 0x94F3 --flag8 0x00 --flag16 0x00 --flag32 0x00 --write 6200_mod.rom
    Uwaga: adresy są przykładowe – użyj tych, które wypisało --print-offsets u Ciebie.

    3) Wymuś skalowanie w monitorze
    - W OSD ustaw „Full/Fill” (czasem „Wide/Full Screen”) i uruchom „Auto/Auto Adjust”. Zrób to po ustawieniu nowego trybu.

    4) Jeżeli testujesz w Windows – idź drogą sterownika, nie VBIOS
    - Dodaj tryb jako „Custom resolution” w panelu sterownika i wybierz ręcznie GTF/CVT (non‑RB).
    - Jeśli panel dalej nie skaluje – zrób EDID override (np. CRU) i dodaj Detailed Timing z GTF dla Twojej rozdzielczości. Sterownik zaufa EDID i poda dokładnie ten timing – to zwykle odblokowuje skalowanie po stronie monitora.
    - Dla cyfrowych złączy (DVI/HDMI) ustaw „scaling performed on GPU” i „Full-screen” (dla D‑Sub zwykle brak GPU‑scaling – decyduje OSD).

    5) Jeśli chcesz „wypełnić” panel za wszelką cenę
    - Wybierz standard, który Twój monitor na pewno skaluje: 1280×720@60 (CVT non‑RB) lub 848×480@60. Potem wymuś „Full”. Dla panelu 1280×1024 i 1280×720 nadal będą pasy góra/dół (proporcje), ale 848×480 bywa skalowane na pełną wysokość/szerokość.

    6) Drobne triki dla VGA
    - Zwiększ HBlank (przejdź z CVT‑RB na GTF lub CVT non‑RB) – wiele A/D poprawnie „łapie” szerokie blankingi, a zbyt małe RB daje centrowanie z ramkami.
    - Zmień polaryzacje na −H/−V (GTF) – często stabilniejsza akwizycja.
    - Po zmianie trybu zawsze „Auto Adjust” w OSD.

    Co jeszcze mogę dorzucić
    - Mogę wygenerować gotowe zestawy timingów (GTF i CVT non‑RB) dla Twojej docelowej rozdzielczości i Hz oraz od razu przygotować trzy 32B bloki (8/16/32 bpp) do wklejenia, tak aby mieć 1:1 zgodność między tym, co testujesz w systemie, a tym, co wpisujemy do ROM.
    - Jeśli podasz: model monitora, wejście (D‑Sub/DVI/HDMI), natywną rozdzielczość, system i wersję sterownika oraz dokładny tryb (WxH@Hz), przygotuję rekomendowany timing i komendy narzędzia (ROM patch + instrukcja EDID override / custom res w sterowniku).

    Podsumowanie
    - Sam patch VBIOS (9B/32B) nie usuwa „ramek” w środowisku ze sterownikiem i/lub na D‑Sub, bo o wypełnieniu decyduje sterownik/monitor. Przestaw się na timingi akceptowane do skalowania (GTF/CVT non‑RB), włącz „Full/Fill” w OSD, a w Windows zrób Custom Resolution/EDID override. Jednocześnie, jeśli chcesz mieć porządek w ROM, wpisz te same timingi do wszystkich trzech 32B (8/16/32 bpp) – dlatego dodałem w narzędziu opcję --tim32-off. Daj znać parametry sprzętu – przygotuję konkrety.
    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.
  • #15 21788716
    Gelip
    Poziom 36  
    Posty: 5245
    Pomógł: 324
    Ocena: 611
    @ElektrodaBot
    Tylko mi nie chodzi o skalowanie, nie o takie ramki. Tu chodzi o to iż na ekranie mamy punkt 0x0 w lewym górnym rogu a po modyfikacji na rozdzielczość 1024x576 w zależności jaką rozdzielczość zmieniliśmy w tabeli 9B:

    9B zmiana 1024x768 na 1024x576 - Windows na sterowniku vga.sys wyświetla 1024x576 - przez aplikację pulpitu zdalnego Remote Administrator 2.2 mam wtedy taką samą rozdzielczość ale monitor wyświetla nadal 1024x768 czyli u góry jest obraz z Windows 1024x576 ale pod spodem jest czarna ramka wielkości 1024x192 (768-576). Ramka jest tylko u dołu bo zmieniliśmy tylko wysokość a szerokość jest ta sama.

    Gdy w tabeli 9B zmienimy inna rozdzielczość np. 1280x1024 na 1024x576 to wtedy mam ramki u dołu i z prawej strony czyli w lewym górnym rogu jest obraz z Windows na vga.sys w 1024x576 ale monitor ciągle wyświetla obraz 1280x1024 czyli pod spodem jest czarny pas szerokości 1280x448 (1024-576) a z prawej pas (1280-1024) 256x1024

    Nie wiem czy rozumiesz co pokazuje zdjęcie ale zamieszczam zdjęcie zrobione jak powyższy opis wygląda w WinXP na vga.sys w 1024x576 zmienionej w tabeli 9B rozdzielczości 1280x1024:
    Zrzut ekranu monitora z czarnymi pasami wokół obrazu 1024x576 na tle 1280x1024
  • #16 21793606
    Gelip
    Poziom 36  
    Posty: 5245
    Pomógł: 324
    Ocena: 611
    Wydaje mi się iż fachowo to powinno dodać się nową rozdzielczość pod nowym numerem VESA a nie modyfikować już istniejący wpis np. w NVIDIA pod 0x118 jest zawsze 1024x768x32. Sprawdziłem nowszą od tej NVIDII kartę graficzną ATI i tam np. pod numerem 0x1E6 jest rozdzielczość 4:3 1920x1440x32
    W tabeli VESA są przeważnie rozdzielczości 4:3 ale jest też np. 5:4 1280x1024 czy 16:10 640x400
    Ciekawe jak to się robi fachowo?

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy modyfikacji VBIOS karty NVIDIA GeForce 6200 DSUB w celu dodania nowej rozdzielczości wide 1024×576. Omawiano analizę i patchowanie tabel rozdzielczości 9B oraz 32-bajtowych tabel timingów NV, wykrywanie wpisów w BIOS-ie, poprawki do narzędzia w MS Visual C++ 2005 oraz generowanie timingów CVT-RB i GTF. Pojawiły się problemy z heurystyką wykrywania tabel, duplikowaniem wyników, obsługą opcji --tim32 i checksumą ROM. Ostatecznie wyjaśniono, że same zmiany w VBIOS nie usuwają czarnych ramek na wyjściu DSUB, ponieważ po starcie systemu sterownik i monitor mogą ignorować wpisy BIOS-owe; wskazano też, że fachowo należy dodawać nową rozdzielczość pod nowym kodem VESA zamiast nadpisywać istniejący wpis.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA