Prośba o przepisanie kilku linijek z C++ na Delphi.

1

Witam.

W związku że mowa jest o 2 różnych językach nie wiedziałem gdzie to zamieścić.
Jeśli to zły dział proszę Moderatora o przeniesienie.

Piszę sobie program (emulator NES) w delphi na podstawie kodu z C++.
Stanąłem na pewnej funkcji której nie mogę przetłumaczyć.

template<unsigned bitno, unsigned nbits=1, typename T=u8>
struct RegBit
{
    T data;
    enum { mask = (1u << nbits) - 1u };
    template<typename T2>
    RegBit& operator=(T2 val)
    {
        data = (data & ~(mask << bitno)) | ((nbits > 1 ? val & mask : !!val) << bitno);
        return *this;
    }
    operator unsigned() const { return (data >> bitno) & mask; }
    RegBit& operator++ ()     { return *this = *this + 1; }
    unsigned operator++ (int) { unsigned r = *this; ++*this; return r; }
};

Nie mogę tego wyczuć. Wygląda mi to na jakąś funkcje rekurencyjną.
Odwołanie do tego wygląda tak (polecenie union znam dodaję to tylko aby rozjaśnić obraz):

    union scrolltype
    {
        RegBit<3,16,u32> raw;       // raw VRAM address (16-bit)
        RegBit<0, 8,u32> xscroll;   // low 8 bits of first write to 2005
        RegBit<0, 3,u32> xfine;     // low 3 bits of first write to 2005
        RegBit<3, 5,u32> xcoarse;   // high 5 bits of first write to 2005
        RegBit<8, 5,u32> ycoarse;   // high 5 bits of second write to 2005
        RegBit<13,2,u32> basenta;   // nametable index (copied from 2000)
        RegBit<13,1,u32> basenta_h; // horizontal nametable index
        RegBit<14,1,u32> basenta_v; // vertical   nametable index
        RegBit<15,3,u32> yfine;     // low 3 bits of second write to 2005
        RegBit<11,8,u32> vaddrhi;   // first write to 2006 (with high 2 bits set to zero)
        RegBit<3, 8,u32> vaddrlo;   // second write to 2006
    } scroll, vaddr;

Przykładowe wywołanie:

scroll.xscroll = 0x1F

Jeśli ktoś mógłby to przetłumaczyć na delphi był bym bardzo wdzięczny (oczywiście tylko pierwszy blok kodu z resztą sobie poradzę).
Bardzo proszę o pomoc i życzę Wesołych Świąt.

0

Jeśli ktoś mógłby to przetłumaczyć na delphi był bym bardzo wdzięczny (oczywiście tylko pierwszy blok kodu z resztą sobie poradzę).
Pierwszy blok kodu jest właśnie nieistotny. Jest przede wszystkim nieprzetłumaczalny na Delphi z powodu użycia szablonów.

Powinieneś się skupić na drugim fragmencie, a zwłaszcza komentarzach do niego. Poszczególnym bitom typu scrolltype nadano konkretne nazwy, np:

        RegBit<0, 8,u32> xscroll;   // low 8 bits of first write to 2005

co oznaczają poszczególne liczby w RegBit<> widać tutaj:

template<unsigned bitno, unsigned nbits=1, typename T=u8> struct RegBit

czyli xscroll ma bitno=0, nbits=8, i typ "u32".

Można się domyślać, że xscroll to 8 bitów począwszy od bitu 0 (czyli 8 najmłodszych bitów) całej wartości scrolltype.

Piszę sobie program (emulator NES) w delphi na podstawie kodu z C++.
A dlaczego nie na podstawie dokumentacji NES-a?

0

Czyli rozumiem że cała funkcja to tylko linia

data = (data & ~(mask << bitno)) | ((nbits > 1 ? val & mask : !!val) << bitno);

W takim wypadku jak inicjalizowana jest zmienna data?
Która zmienna jest wynikiem działania funkcji? Czyżby to była zmienna data?
Czy na pewno mogę pominąć końcówkę funkcji? Wildze tam jakieś inkrementacje.

Pisze na podstawie gotowego programu bo po co wyważać otwarte drzwi? Dokumentację układu MOS6502 mam już za sobą. po prostu chce oprogramować jakiś prosty układ aby móc pobawić się prostym asemblerem.

0

Skup się naprawdę na drugim fragmencie kodu. Zmienne scroll i vaddr to 32-bitowe liczby bez znaku, w których poszczególne bity mają pewne znaczenie. Przykładowo

RegBit<13,2,u32> basenta;

dwa bity począwszy od bitu 13 (czyli bity 13 i 14) to jakieś „basenta”.

W Delphi takie rzeczy można osiągnąć przez operacje bitowe i przesunięcia. w C++ opakowano te operacje w typ (nie funkcję) RegBit, dzięki czemu zautomatyzowano ten proces. Ty możesz zrobić funkcję, która będzie modyfikowała albo zwracala konkretne bity podanej liczby.

Która zmienna jest wynikiem działania funkcji? Czyżby to była zmienna data?
Nie ma „wyniku działania funkcji”, bo nie ma funkcji. Ale linijka którą zacytowałeś (w której jest obliczana wartość data) jest rzeczywiście kluczowa.

wywołanie

scroll.xscroll = 0x1F

powoduje wykonanie operatora RegBit& operator=(T2 val), gdzie val jest równe 0x1F, a data to xscroll, ale ponieważ całe scroll jest unią, równie dobrze można powiedzieć że data to scroll.

1 użytkowników online, w tym zalogowanych: 0, gości: 1