Autor Wątek: FDD35 rev.3  (Przeczytany 17186 razy)

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #15 dnia: 2023.04.13, 06:42:00 »
Do opisania został jeszcze tryb BOOT. Po włączeniu zasilania banki domyślnie dostają adresy od 0 do 3 w RAM.
Po resecie (obojętnie czy od zasilania czy z przycisku), pierwsze 8 KB jest czytane z ROM o numerze zawartym w banku 0.
W tym czasie 8 KB RAM w banku 0 jest niedostępne (tak jest w oryginale i tego nie będę zmieniał).
Po wyjściu z trybu BOOT (bit 6 rejestru pomocniczego FDC ustawiany na 1) wraca "normalne" adresowanie, które opisałem wcześniej.

Ponieważ rejestry banków nie są kasowane resetem z przycisku, jest możliwość zamiany procedury startującej.
System nie musi być ładowany z dyskietki, ale na przykład z któregoś z banków ROM (ktoś kiedyś pytał o CP/M ładowany z ROM ;) ).

A w sumie co mi tam:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity FDDX is
  Port (
-- inputs
    CLK16      : in  std_logic;                        -- wejście generatora 16 MHz
    nRESET     : in  std_logic;                        -- /RESET
    nPwrOn     : in  std_logic;                        -- kasowanie rejestrów konfiguracyjnych po włączeniu zasilania
    nBUSGE     : in  std_logic;                        -- /BUSGE - przekazanie sterowania zewnętrznemu układowi
    IROM       : in  std_logic;                        -- IROM - odłączenie wewnętrznej pamięci ROM
    nRFSH      : in  std_logic;                        -- /RFSH
    nIORQ      : in  std_logic;                        -- /IORQ
    nMREQ      : in  std_logic;                        -- /MREQ
    nRD        : in  std_logic;                        -- /RD
    nWR        : in  std_logic;                        -- /WR
    AL         : in  std_logic_vector(7 downto 4);     -- A4..A7
    AH         : in  std_logic_vector(15 downto 13);   -- A13..A15
    nMixDrive  : in  std_logic;                        -- /MixDrive - napędy C i D jako druga strona dyskietki A i B
    nTurbo     : in  std_logic;                        -- /Turbo CPU_CLK = 8 MHz
    nHD        : in  std_logic;                        -- /HD obsługa dysków HD
    nUINT      : in  std_logic;                        -- /UINT obsługa przerwań UART
    INTRQ      : in  std_logic;                        -- FDC INT in
    TxRDY      : in  std_logic_vector (1 downto 0);    -- UART Tx Ready
    TxE        : in  std_logic_vector (1 downto 0);    -- UART Tx End
    RxRDY      : in  std_logic_vector (1 downto 0);    -- UART Rx Ready
    BRKDET     : in  std_logic_vector (1 downto 0);    -- UART Break Detected
--  bidirectional
    DB         : inout  std_logic_vector (7 downto 0); -- D0..D7
-- outputs
    RESET      : out std_logic;                        -- RESET dla WD2123
    CLK_CPU    : out std_logic;                        -- CLK dla CPU
    CLK_FDC    : out std_logic;                        -- CLK dla FDC
    CLK4       : out std_logic;                        -- CLK 4 MHz na wyjście Ext CLK
    MA         : out std_logic_vector (18 downto 14);  -- MA14..MA18
    nROMCS     : out std_logic;                        -- /ROM CS
    nRAMCS     : out std_logic;                        -- /RAM CS
    nOUT       : out std_logic;                        -- /OUT
    nIN        : out std_logic;                        -- /IN
    nFDC       : out std_logic;                        -- FDC CS
    nDDEN      : out std_logic;                        -- FDC DDEN
    nINT       : out std_logic;                        -- FDC INT out
    nRS1       : out std_logic;                        -- UART CS1
    nRS2       : out std_logic;                        -- UART CS2
    nRS3       : out std_logic;                        -- UART CS3
    nDRV       : out std_logic_vector (3 downto 0);    -- /SEL0../SEL3
    nSide      : out std_logic;                        -- /SIDE1
    nInUse     : out std_logic;                        -- /INUSE
    LED_Turbo  : out std_logic;                        -- LED Turbo mode
    LED_HD     : out std_logic;                        -- LED HD mode
    LED_InUse  : out std_logic);                       -- LED InUse
end FDDX;

architecture Behavioral of FDDX is

attribute NOREDUCE: string;

signal BNK0    : std_logic_vector (5 downto 0);        -- rejestr banku segmentu 0 (0000-3FFF), bit 5: 0=RAM, 1=odczyt ROM, zapis RAM
signal BNK1    : std_logic_vector (5 downto 0);        -- rejestr banku segmentu 1 (4000-7FFF)
signal BNK2    : std_logic_vector (5 downto 0);        -- rejestr banku segmentu 2 (8000-BFFF)
signal BNK3    : std_logic_vector (5 downto 0);        -- rejestr banku segmentu 3 (C000-FFFF)
signal CONF    : std_logic_vector (2 downto 0);        -- rejestr konfiguracji CLK, INT
signal REGD    : std_logic_vector (7 downto 0);        -- rejestr wyboru napędów
signal REGC    : std_logic_vector (1 downto 0);        -- rejestr dzielnika CLK
signal RD      : std_logic;
signal WR      : std_logic;
signal IORQ    : std_logic;
signal MREQF   : std_logic;                            -- MREQ and not RFSH
signal portOUT : std_logic;                            -- zapis        #20
signal portIN  : std_logic;                            -- odczyt       #20
signal portE0  : std_logic;                            -- zapis/odczyt #E0 zapis REGD, odczyt status przerwań UART
signal portFDC : std_logic;                            -- zapis/odczyt #C0..#C3
signal portRS1 : std_logic;                            -- zapis/odczyt #80..#81 i #A0..#A1
signal portRS2 : std_logic;                            -- zapis/odczyt #40..#41 i #60..#61
signal portRS3 : std_logic;                            -- zapis/odczyt #00..#01
signal portCTL : std_logic;                            -- zapis/odczyt #D0, bit 0: Turbo, bit 1: HD, bit 2: MixDrive (tylko odczyt)
signal portBNK : std_logic;                            -- zapis        #F0, bit 7,6: segment 0..3, bit 5: 0=RAM, 1=ROM, bit 4..0: nr banku
signal ROMCS   : std_logic;
signal RAMCS   : std_logic;       

attribute NOREDUCE of CLK16   : signal is "TRUE";
attribute NOREDUCE of CLK_CPU : signal is "TRUE";
attribute NOREDUCE of CLK_FDC : signal is "TRUE";
attribute NOREDUCE of CLK4    : signal is "TRUE";
attribute NOREDUCE of RESET   : signal is "TRUE";

begin
  RD      <= not nRD;
  WR      <= not nWR;
  IORQ    <= not nIORQ and nBUSGE;
  MREQF   <= not nMREQ and nRFSH and nBUSGE;
 
  portOUT <= IORQ and  WR        and not AL(7) and not AL(6) and     AL(5) and not AL(4); -- #20
  portIN  <= IORQ and        RD  and not AL(7) and not AL(6) and     AL(5) and not AL(4); -- #20
  portRS1 <= IORQ and (WR or RD) and     AL(7) and not AL(6)               and not AL(4); -- #80, #A0
  portRS2 <= IORQ and (WR or RD) and not AL(7) and     AL(6)               and not AL(4); -- #40, #60
  portRS3 <= IORQ and (WR or RD) and not AL(7) and not AL(6) and not AL(5) and not AL(4); -- #00
  portFDC <= IORQ and (WR or RD) and     AL(7) and     AL(6) and not AL(5) and not AL(4); -- #C0
  portE0  <= IORQ and                    AL(7) and     AL(6) and     AL(5) and not AL(4); -- #E0   
  portCTL <= IORQ and                    AL(7) and     AL(6) and not AL(5) and     AL(4); -- #D0
  portBNK <= IORQ and                    AL(7) and     AL(6) and     AL(5) and     AL(4); -- #F0
 
  REGDlatch : process (nRESET, nPwrOn, nWR)
  begin
    if (nRESET = '0' or nPwrOn = '0') then
      REGD <= "00000000";
    elsif (portE0 = '1' and nWR'event and nWR = '1') then
      REGD <= DB;
    end if;
  end process;
 
  CONFlatch : process (nRESET, nPwrOn, nTurbo, nHD, nUINT, nWR)
  begin
    if (nRESET = '0' and nPwrOn = '0') then 
      CONF(0) <= not nTurbo;
      CONF(1) <= not nHD;
      CONF(2) <= not nUINT;
    elsif (portCTL = '1' and nWR'event and nWR = '0') then
      CONF <= DB(2 downto 0);
    end if;
  end process;
 
  STATread : process (nMixDrive, nPwrOn, nTurbo, nHD, nUINT, TxRDY, TxE, RxRDY, BRKDET, nRD)
  begin
    if ((portCTL = '1' or (portE0 = '1' and CONF(2) = '1')) and nRD = '0') then
      DB(7) <= (portCTL and not nMixDrive) or (portE0 and CONF(2) and BRKDET(1));
      DB(6) <= (portCTL and not nUINT)     or (portE0 and CONF(2) and RxRDY(1));
      DB(5) <= (portCTL and not nHD)       or (portE0 and CONF(2) and TxE(1));
      DB(4) <= (portCTL and not nTurbo)    or (portE0 and CONF(2) and TxRDY(1));
      DB(3) <= (portCTL and not REGD(5))   or (portE0 and CONF(2) and BRKDET(0));
      DB(2) <= (portCTL and CONF(2))       or (portE0 and CONF(2) and RxRDY(0));
      DB(1) <= (portCTL and CONF(1))       or (portE0 and CONF(2) and TxE(0));
      DB(0) <= (portCTL and CONF(0))       or (portE0 and CONF(2) and TxRDY(0));
    end if;
  end process;

  BANKlatch : process (nRESET, nPwrOn, nWR, DB, AH, BNK0, BNK1, BNK2, BNK3)
  begin
    if (nRESET = '0' and nPwrOn = '0') then
      BNK0 <= "000000";
      BNK1 <= "000001";
      BNK2 <= "000010";
      BNK3 <= "000011";
    elsif (portBNK = '1' and nWR'event and nWR = '0') then
      case DB(7 downto 6) is
        when "00"   => BNK0 <= DB(5 downto 0);
        when "01"   => BNK1 <= DB(5 downto 0);
        when "10"   => BNK2 <= DB(5 downto 0);
        when others => BNK3 <= DB(5 downto 0);
      end case;
    end if;
    case AH(15 downto 14) is
      when "00"   => MA <= BNK0(4 downto 0);
      when "01"   => MA <= BNK1(4 downto 0);
      when "10"   => MA <= BNK2(4 downto 0);
      when others => MA <= BNK3(4 downto 0);
    end case;
  end process;
 
  MemorySelect : process (AH, BNK0, BNK1, BNK2, BNK3, REGD, MREQF, RD, WR)
  begin
    if (REGD(6) = '0') then -- BOOT
      ROMCS <= MREQF and RD and not AH(15) and not AH(14) and not AH(13);
      RAMCS <= MREQF and (WR or RD) and AH(15) and AH(14) and AH(13);
    else
      case AH(15 downto 14) is
        when "00"   => ROMCS <= MREQF and RD and BNK0(5);
                       RAMCS <= MREQF and (WR or (RD and not BNK0(5)));
        when "01"   => ROMCS <= MREQF and RD and BNK1(5);
                       RAMCS <= MREQF and (WR or (RD and not BNK1(5)));
        when "10"   => ROMCS <= MREQF and RD and BNK2(5);
                       RAMCS <= MREQF and (WR or (RD and not BNK2(5)));
        when others => ROMCS <= MREQF and RD and BNK3(5);
                       RAMCS <= MREQF and (WR or (RD and not BNK3(5)));
      end case;
    end if;
  end process;
 
  ClockDivider : process (CLK16, CONF, REGC)
  begin
    if (CLK16'event and CLK16 = '1') then
      if (REGC = "11") then
        REGC <= "00";
      else
        REGC <= REGC + 1;
      end if;
    end if;
    if (CONF(1) = '1') then -- dyskietki HD
      CLK_FDC <= not CLK16;   -- 16 MHz
      CLK_CPU <= not REGC(0); -- 8 MHz wymuszone turbo CPU
    else
      CLK_FDC <= not REGC(0); -- 8 MHz
      if (CONF(0) = '1' ) then -- turbo CPU
        CLK_CPU <= not REGC(0); -- 8 MHz
      else
        CLK_CPU <= not REGC(1); -- 4 MHz
      end if;
    end if;
    CLK4 <= REGC(1);
  end process;
 
  DRVout : process (nMixDrive, REGD)
  begin
    if (nMixDrive = '0') then
      nDRV(0) <= REGD(0) and REGD(2);
      nDRV(1) <= REGD(1) and REGD(3);
      nDRV(2) <= not nMixDrive;
      nDRV(3) <= not nMixDrive;
      nSide   <= REGD(2) and REGD(3) and REGD(4);
    else
      nDRV    <= REGD(3 downto 0);
      nSide   <= REGD(4);
    end if;
  end process;
 
  RESET      <= not nRESET;
  nROMCS     <= not ROMCS and IROM;
  nRAMCS     <= not RAMCS;
  nINT       <= not (INTRQ or (CONF(2) and (TxRDY(0) or TxE(0) or RxRDY(0) or BRKDET(0) or TxRDY(1) or TxE(1) or RxRDY(1) or BRKDET(1))));
  nOUT       <= not portOUT;
  nIN        <= not portIN;
  nFDC       <= not portFDC;
  nDDEN      <= REGD(5);
  nRS1       <= not portRS1;
  nRS2       <= not portRS2;
  nRS3       <= not portRS3;
  nInUse     <= REGD(7);
  LED_Turbo  <= CONF(0);
  LED_HD     <= CONF(1);
  LED_InUse  <= not REGD(7);

end Behavioral;
« Ostatnia zmiana: 2023.04.13, 07:01:43 wysłana przez pear »
ZX/Enterprise/CPC/Robotron/C128D

KWF

  • Moderator
  • *****
  • Wiadomości: 6838
  • Miejsce pobytu:
    trzecia planeta od Słońca
  • "I co ja robię tu, u-u, co Ty tutaj robisz ..."
    • PCBway
Odp: FDD35 rev.3
« Odpowiedź #16 dnia: 2023.04.13, 08:03:25 »
@pear: bardzo dobra robota i ciekawe nowe funkcje. Tylko czy żadna z nich nie pogryzie się z istniejącym oprogramowaniem? 
KWF
-----
R Tape loading error 0:1
Moje zabawki: https://github.com/McKlaud76

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #17 dnia: 2023.04.13, 08:13:51 »
Nie powinno się pogryźć. Adresowanie zostało oryginalne.
Jedyna zmiana, to dodatkowa linia A4 w dekodowaniu portów.
Czy to zaszkodzi ? Wyjdzie w praniu.

Przy okazji. Czy jak wystawiam dane na szynę danych to tam powinno być nRD'event (zapis do rejestru i wystawienie na zewnątrz) czy samo nRD='0' (wystawienie sygnału z bufora) ?
Nie robiłem dotąd dwukierunkowych sygnałów w VHDL.
ZX/Enterprise/CPC/Robotron/C128D

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #18 dnia: 2023.04.13, 10:45:23 »
Doczytałem o portach dwukierunkowych, poprawiłem (trzeba było dodać stan "Z").
Trochę zoptymalizowałem i zmieściła się dodatkowa zworka i bit w konfiguracji do przełączania Flash do zapisu w trakcie pracy (wtedy nie ma cienia na RAM).
Bity 3 i 7 przy odczycie rejestru konfiguracji zmieniły znaczenie na obsługę /FlashWriteEnable.

Zostały 2 nóżki, 2 makrocele i zwolniło się trochę logiki (zostało 10 niewykorzystanych bloków funkcjonalnych).
ZX/Enterprise/CPC/Robotron/C128D

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #19 dnia: 2023.04.14, 06:45:13 »
Zrobiłem pierwszą przymiarkę do płytki. Niestety przybyło drugie tyle buforóŵ do napędów.
Wydłużenie płytki o te kilka centymetrów brakujących do długości przeciętnego napędu to za mało.
Zmieni się więc format na Mini ITX. I tak będzie potrzebna obudowa na zmieszczenie wszystkich napędów i solidny zasilacz. No i odpadnie rysowanie obudowy i czekanie 3 dni na wydruk.
Skoro ITX, to muszę jeszcze doprojektować jakiś sensowny układ do załączania zasilacza. Ma ktoś jakieś sprawdzone rozwiązanie (start na przycisk, wyłączenie po przytrzymaniu przycisku kilka sekund) ?
ZX/Enterprise/CPC/Robotron/C128D

KWF

  • Moderator
  • *****
  • Wiadomości: 6838
  • Miejsce pobytu:
    trzecia planeta od Słońca
  • "I co ja robię tu, u-u, co Ty tutaj robisz ..."
    • PCBway
Odp: FDD35 rev.3
« Odpowiedź #20 dnia: 2023.04.14, 07:06:39 »
Może taki gotowiec: https://www.analog.com/media/en/technical-documentation/data-sheets/2955fa.pdf

Nie trzeba wyważać otwartych drzwi.
KWF
-----
R Tape loading error 0:1
Moje zabawki: https://github.com/McKlaud76

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #21 dnia: 2023.04.14, 08:45:03 »
Dlatego pytam, żeby niczego nie wyważać.
Fajny układ, czegoś takiego szukałem.
Jednym przyciskiem załatwi włączanie zasilania i ręczny reset.
Dzięki.
ZX/Enterprise/CPC/Robotron/C128D

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #22 dnia: 2023.04.15, 15:59:58 »
Wstępny draft rozmieszczenia elementów. Płytka w formacie Mini ITX (170x170 mm, otwory montażowe zgodnie ze specyfikacją standardu).
Teraz wszystko się mieści, a nawet jest dość luźno i przewiewnie.
ZX/Enterprise/CPC/Robotron/C128D

trojacek

  • *****
  • Wiadomości: 6846
  • Miejsce pobytu:
    Warszawa
Odp: FDD35 rev.3
« Odpowiedź #23 dnia: 2023.04.15, 16:07:53 »
O, i o to się partia biła! ;)
Śliczne :)

Maryjan

  • *****
  • Wiadomości: 6666
  • Miejsce pobytu:
    Skarżysko-Kam.
  • Scotch whiskey and West Highland Terrier
Odp: FDD35 rev.3
« Odpowiedź #24 dnia: 2023.04.15, 18:34:19 »
To teraz trasowanie na dwóch warstwach :)
"Co miałem powiedzieć - przeczytałem..." Nikodem Dyzma

KWF

  • Moderator
  • *****
  • Wiadomości: 6838
  • Miejsce pobytu:
    trzecia planeta od Słońca
  • "I co ja robię tu, u-u, co Ty tutaj robisz ..."
    • PCBway
Odp: FDD35 rev.3
« Odpowiedź #25 dnia: 2023.04.15, 22:07:50 »
Zgrabnie wyszło.
KWF
-----
R Tape loading error 0:1
Moje zabawki: https://github.com/McKlaud76

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #26 dnia: 2023.04.25, 05:35:55 »
Płytka wydziergana bez autoroutera, ale lubię jak ścieżki są poprowadzone regularnie, a nie chaotycznie gdzie popadnie.
Ponieważ ten układ do sterowania zasilaczem ATX w pojedynczych sztukach, owszem jest dostępny, ale w cenach dla mnie nieakceptowalnych jak za wyłącznik, powstała jeszcze druga płytka.
Za cenę tego scalaka, ze szpargałów w garażu zmontuję sobie moduł (a'la SO DIMM). Będzie więcej pola do zabawy ;)

W międzyczasie dotarły CPLD. Wszystkie czyściutkie, pięknie pomalowane i z jednej serii ... Taa, programator miał jednak inne zdanie.
Szczęśliwie wewnątrz wszystkie są Xillinxami XC9752, ale z trzech różnych serii. Oczywiście wszystkie używane, a nie nowe, ale do tego już przywykłem.
Z 10 sztuk: 3 są takie jak powinny być; kolejne 2 są starszego typu, ale stosując sztuczkę udaje się je zaprogramować przez kabel USB; pozostałe są jeszcze starsze i nie nadają się do programowania kablem USB, a że na razie nie mam odpowiedniego adaptera, to nie wiem czy całkiem sprawne.

Do końca tygodnia powinienem dopieścić płytki i posłać do produkcji.
ZX/Enterprise/CPC/Robotron/C128D

KWF

  • Moderator
  • *****
  • Wiadomości: 6838
  • Miejsce pobytu:
    trzecia planeta od Słońca
  • "I co ja robię tu, u-u, co Ty tutaj robisz ..."
    • PCBway
Odp: FDD35 rev.3
« Odpowiedź #27 dnia: 2023.04.25, 06:13:21 »
Ładnie.

Tak, ten scalak nie jest tani, ale jeśli policzysz wszystkie części na dodatkową płytkę, czas i prąd poświęcony na zaprojektowanie, zaprogramowanie i składanie dodatkowego modułu, to scalak może wyjść taniej. Na Ali leży po 30-40 dolców za 10 sztuk. ;) RS Polska ma po 34 zł za sztukę (w detalu) i są dostępne. A wykorzystany przez Ciebie AT89C2051 jest po 12 zł u dużych dystrybutorów. Moim zdaniem skórka za wyprawkę. No ale ja nie lubię dodatkowych uP, które trzeba dodatkowo programować. No może ATtiny jestem w stanie przeboleć, ale 8051?

CPLD z Chin to loteria. Mam kilka XC9536/72, sygnatura mówi, że są programowalne przez USB, ale za żadne skarby nie chcą się programować, pomimo sztuczek i zaklęć (http://www.blunk-electronic.de//ise/howto_erase_XC9500.pdf).

Tak z ciekawości, czy piszesz też nowy ROM lub patcha do TOSa, który wykorzysta wszystkie dodatkowe "bajery"?
KWF
-----
R Tape loading error 0:1
Moje zabawki: https://github.com/McKlaud76

pear

  • *****
  • Wiadomości: 5511
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: FDD35 rev.3
« Odpowiedź #28 dnia: 2023.04.25, 07:07:22 »
Moim zdaniem skórka za wyprawkę. No ale ja nie lubię dodatkowych uP, które trzeba dodatkowo programować.
Napisałem, że będzie więcej zabawy :) Poza tym zalega mi co najmniej listwa AT89C2051, których już raczej do niczego poważnego nie wykorzystam.
Oprócz tego złącze modułu zaprojektowałem w takim układzie, że zamiast niego można wstawić ... zworki i wyłącznik.

Tak z ciekawości, czy piszesz też nowy ROM lub patcha do TOSa, który wykorzysta wszystkie dodatkowe "bajery"?
Cały projekt opiera się na tym, że nie trzeba niczego nowego napisać, żeby go uruchomić. W teorii powinien zadziałać na tym oprogramowaniu, które już istnieje.
Jeśli ktoś zechce wykorzystać nowe możliwości, to trzeba będzie dopisać nowy kawał kodu. Ale coś mi się zdaje, że trojacek od dawna ostrzy sobie na to zęby ;)
« Ostatnia zmiana: 2023.04.25, 07:21:03 wysłana przez pear »
ZX/Enterprise/CPC/Robotron/C128D

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4540
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: FDD35 rev.3
« Odpowiedź #29 dnia: 2023.04.25, 19:48:32 »
Ciekawy projekt! Trzymam kciuki.