START
_______________

Atari 16-bit

Floppy Drive
DIN14-IDC34
adapter


ACSI-SCSI interface

Video digitizer faST

MegaSTe SCSI
internal interface


ST RAMcart

Peter Putnik's
ACSI-CF Interface


Sack's PC-speed
remake project


Vortex AT-ONCE
remake project


Sack's AT-speed
remake project


MagicSAC+
remake project


ICD ST Hard Drive
Adapter BD
remake project


ICD Advantage SCSI+
remake project


ICD AdSCSI Micro
remake project


Realtime
Clocks


Matrix M110
GAL Pack


ICD Advantage SCSI
remake project


ICD Micro MegaSTe
adaptation project


Emagic LOG3
Interface remake


C-Lab Combiner
remake

 

ATARI ST RAMcart  

Projekt czynię ogólnodostępnym. Proszę jednakże o poszanowanie moich praw
 jako twórcy i niewykorzystywanie komercyjne zaprezentowanego rozwiązania.

Ważna informacja (13.09.2023):

     Użytkownicy zgłosili po pewnym czasie używania RAMcarta problem ze znikaniem
danych, bądź zmianą pojedynczych bitów. Po sprawdzeniu i analizie okazało się, że
podczas wyłączania zasilania komputera mogą powstawać nieustalone poziomy na
liniach sterujących pamięci będących w stanie standby. Te stany najprawdopodobniej powodowały błędy...
     Poprawka polega na wymianie rezystora R1 o wartości 4k7 na rezystor wartości 15k
oraz dołączeniu pomiędzy linię CE2 pamięci rezystora R9 o wartości 10k do masy. Ta
poprawka powoduje poprzez utworzenie dzielnika napięcia podawanie wysokiego
poziomu na linię CE2 i jednocześnie w trakcie wyłączania bardzo szybkie zablokowanie
układów RAM i w rezultacie dane pozostają nienaruszone. Równolegle do rezystora R9
jest dołączony przycisk (tact-switch), naciskanie którego w trakcie uruchomienia
komputera spowoduje zablokowanie startu cartridge..

Pliki projektu również zostały poprawione (schemat i GERBER)

-----------------------------------------

     Chciałem zaprojektować i zbudować takie urządzenie od bardzo dawna. Jednakże
w przeszłych czasach budowanie tego na układach TTL w obudowach DIP oraz, może
użycie układów GAL i tak spowodowałyby powstanie "potwora" monstrualnej wielkości,
co w praktyce zniechęcałoby kogokolwiek do jego budowy. Powszechna dostępność
układów CPLD i FPGA produkcji Xilinx i Altera umożliwiły poważne zminiaturyzowanie
sprzętu i zbudowanie go w warunkach amatorskich (z pewnymi zastrzeżeniami).

     Poniżej zaprezentuję kilka zdjęć zmontowanego i uruchomionego prototypu. Układ został zaprojektowany "w głowie" i "na papierze". Nie używałem programów do symulacji
działania układów logicznych. Wszelkie prace prototypowe sprowadzały się do nanoszenia poprawek w firmware układu Xilinx XC95144XL w miarę postępu prac.


     RAMcart ST w trakcie budowy na tle schematu


     Prototyp RAMcart ST strona górna (TOP) widoczne są przeróbki sprzętowe, które
są już wprowadzone na ostateczny projekt PCB


     Prototyp RAMcart ST strona spodnia (BOTTOM)


     Prototyp RAMcart ST w slocie komputera w trakcie zapisu danych
 

     Opis układu

     Idea powstania jest prosta. Chciałem zbudować kartridż w taki sposób aby uniknąć
wiekokrotnego programowania i kasowania pamięci EPROM, co zabiera zawsze dosyć
dużo czasu w procesie powstawania oprogramowania - testy i debug zajmują zwykle go najwięcej i w związku z tym trzeba było to zmienić. Wiadomym jest, że CART port
komputerów Atari ST jest obszarem wyłącznie do odczytu (pilnuje tego układ GLUE) i
nie jest możliwe w standardowy sposób zapisanie w obszar $FA0000-FBFFFF jakichś
danych ponieważ skutek jest zawsze ten sam: dwie bomby. czyli BUS ERROR.

     Wymyśliłem dosyć niekonwencjonalne podejście do tego problemu. Inspiracją tego
był obecny w świecie Atari ST od długiego czasu projekt ośmiobitowego interfejsu I/O
funkcjonującego na porcie CART.

     Poniżej prezentuję schemat układu zawarty w CPLD Xilinx XC95144XL


     Przyjąłem jako wstępne założenia, że obszar $FAXXXX ma spełniać rolę sterowania,
a obszar $FBXXXX będzie obszarem transferu danych. Uruchomienie zapisu sprowadza
się do odczytu serii danych spod konkretnych adresów. tak samo sterowanie funkcjami
RAMCARTa również polega na odczycie danych spod konkretnych adresów.

     Projekt powstał w środowisku XILINX WEBISE 14.7 ->
pliki projektu

     Istotne dane organizacji sprzętu:

     $FAXXNN - sterowanie RAMcart poprzez odczyt adresów.

     bit 1 - przełączenie na RAM LOWER (bajt niższy danej - dostęp LDS)
     bit 2 - przełączenie na RAM UPPER  (bajt wyższy danej - dostęp UDS)
     bit 3 - reset układu, przełączenie w tryb odczytu
     bit 4 - przełączenie układu w tryb zapisu
     bit 5 - zezwolenie impuls zapisu -
wersja 1.20
     bit 6 - zakaz impuls zapisu - wersja 1.20
     bit 7 - zerowanie licznika adresów

     Sterowanie odbywa się poprzez ustawienie bitu w stan 1

     $FBNNXX - transfer danych na starszym bajcie adresu

     [ NN - dana zapisywana, XX - nieistotne ]

     Po włączeniu zasilania urządzenie jest ustawione w tryb odczytu i zachowuje się
jak standardowy kartridż Atari ST. Aby przełączyć i zainicjalizować układ do zapisu
należy wykonać nastepującą sekwencję odblokowującą (string: tOri).

(piszę w konwencji GFA Basic):

     u=PEEK(&HFA0008) - bit 3 = 1 - CART RESET
     u=PEEK(&HFA7400) - mała litera t
     u=PEEK(&HFA4F00) - duża litera O
     u=PEEK(&HFA7200) - mała litera r
     u=PEEK(&HFA6900) - mała litera i
     u=PEEK(&HFA0004) - przełączenie na RAM UPPER (starszy bajt)
     u=PEEK(&HFA0080) - zerowanie licznika adresów RAMcarta.
     u=PEEK(&HFA0010) - bit 4 = 1 - CART WRITE

     Po wykonaniu powyższej sekwencji (niekoniecznie GFA Basic, może być Pascal,
Assembler, cokolwiek byle odczytywac dane w taki sposób jak powyżej) - kartridż
zostanie przełączony w tryb zapisu. Przełączenie to powoduje wysterowanie muxów
linii adresowych w taki sposób, że zostają one dołączone do 16 bitowego licznika
binarnego sterowanego z linii /ROM3 portu CART. Równocześnie jest odpowiednio
wysterowana pamięć RAM oraz zostają przygotowane bufory I/O.

     W tym momencie mamy już możliwość zapisywania danych do RAM urządzenia, co
najprościej da się wykonać w poniższy sposób:

     ' ustawiamy adres skąd pobieramy dane
     a=adres_bufora
    
' zapis starszego bajtu w pętli
     for i=0 to 131070 step 2   ' pobieramy co drugi bajt (starszy)
        dana=PEEK(a+i)
        adres=&HFB0000+256*dana
' dana jest przesyłana na starszym bajcie
     w=PEEK(adres)
     next i
     '
    
' przełączenie RAM na LOWER (bajt młodszy)
    
u=PEEK(&HFA0002)
    
'zerowanie licznika adresów RAMcarta.
     u=PEEK(&HFA0080)
     ' zapis młodszego bajtu w pętli
     for i=1 to 131071 step 2   ' pobieramy co drugi bajt (młodszy)
        dana=PEEK(a+i)
        adres=&HFB0000+256*dana
     w=PEEK(adres)
     next i
    
' reset RAMCART i przełączenie w odczyt
     u=PEEK(&HFA0008)
     '
     end

     Nie jest konieczne ładowanie pełnych 128kB. Ilość danych do załadowania jest
zawsze określana przez użytkownika w zależności od potrzeb. Należy pamiętać,
że zapis pamięci RAM jest zawsze dokonywany liniowo, po skasowaniu licznika adresów - od adresu 0. Można także zapisywać dowolne miejsca w pamięci odliczając
odpowiednią ilość impulsów od stanu 0 licznika.

     Mozliwe, że w jakiejś przyszłości napiszę kawałek poważnieszego software w GFA
Basicu albo assemblerze. Jest to uzależnione od mojego wolnego czasu. Poniżej do
pobrania paczka prostego software w GFA Basic do kasowania i zapisu RAMcarta.

GFA software RAMCART wersja 1.00

     Oczywiście do bufora należy wcześniej załadować odpowiednią zawartość, czyli
właściwe dane (obraz) działającego kartridża, ewentualnie cokolwiek co chciałoby się
zachować na później - pamięć RAM zastosowana w projekcie - CS18LV10245CCR70
ma wyjątkowo niski pobór prądu w trybie standby (kilka uA), co przekłada się na długą
żywotność wlutowanej w płytkę baterii litowej 3V.


     Na płytce znajduja się elementy sygnalizacyjne - cztery diody LED:
     niebieska - zasilanie układu z komputera
     czerwona - zapis
     zielona - RAM Up - pamięć bajtu starszego
     żółta - RAM Low - pamięć bajtu młodszego

     Diody czerwona, zielona i żółta są uruchamiane tylko w trakcie zapisu.
     Brak świecenia tych diod sygnalizuje tryb odczytu danych.

     Przełącznik suwakowy dwupozycyjny przełącza dwa banki 128kB RAM do
     wykorzystania dla dwóch obrazów kartridży.

     Zwora umożliwia odłączenie napięcia baterii z układu podtrzymania zawartości
     i w ten sposób skasowanie całości RAM.

    
Pliki projektu:

     Schemat układu format EAGLE
    
Pliki GERBER do wykonania PCB
    
Pliki projektu Xilinx WebISE 14.7
    
Firmware XC95144XL wersja 1.00

     Dodatkowo dołączam znalezione w sieci obrazy kartridży z plikami w formacie STC jak i ROM (najprawdopodobniej obrazy ROM):
    
    
LLS
    
Explorer
    
Ultimate Ripper 1.2
    
ST Test 4.4

     W sieci można znaleźć trochę innych obrazów ROM Cartridge, jednak przeważnie
w formacie STeem. Bez problemu da się przywrócić oryginalną wielkość oraz format
pliku poprzez odjęcie pierwszych czterech bajtów mających wartość 0. Po takim
przeformatowaniu można użyć dane do załadowania pamięci RAMcarta i powinno
hulać.

DODATEK (UPDATE)

     Dodałem nową funkcjonalność w układzie, która umożliwia wykonanie selektywnego zapisu poprzez dodanie dwóch bitów sterujących - zezwolenia i zakazu impulsu zapisu.

     Odczyt spod adresu $FA0020 zezwala impulsy zapisu
     Odczyt spod adresu $FA0040 zakazuje impulsy zapisu

    
Firmware wersja 1.20

     Pliki projektu Xilinx WebISE 14.7 - wersja 1.20

     Konstrukcja programowa GFA Basic:

     u=PEEK(&HFA0008) - bit 3 = 1 - CART RESET
     u=PEEK(&HFA7400) - mała litera t
     u=PEEK(&HFA4F00) - duża litera O
     u=PEEK(&HFA7200) - mała litera r
     u=PEEK(&HFA6900) - mała litera i
     u=PEEK(&HFA0004) - przełączenie na RAM UPPER (starszy bajt)
     u=PEEK(&HFA0080) - zerowanie licznika adresów RAMcarta.
     u=PEEK(&HFA0010) - bit 4 = 1 - CART WRITE

    ' ustawiamy adres skąd pobieramy dane
     a=adres_bufora
    
' zezwolenie impuls zapisu
     u=PEEK(&HFA0020)
    
' zapis starszego bajtu w pętli
     for i=0 to 131070 step 2   ' pobieramy co drugi bajt (starszy)
        dana=PEEK(a+i)
        adres=&HFB0000+256*dana
' dana jest przesyłana na starszym bajcie
     w=PEEK(adres)
     next i
     '
    
' przełączenie RAM na LOWER (bajt młodszy)
    
u=PEEK(&HFA0002)
    
'zerowanie licznika adresów RAMcarta.
     u=PEEK(&HFA0080)
     ' zapis młodszego bajtu w pętli
     for i=1 to 131071 step 2   ' pobieramy co drugi bajt (młodszy)
        dana=PEEK(a+i)
        adres=&HFB0000+256*dana
     w=PEEK(adres)
     next i
    
' zakaz impuls zapisu
     u=PEEK(&HFA0040)
    
' reset RAMCART i przełączenie w odczyt
     u=PEEK(&HFA0008)
     '
     end

     Przykładowe programy w GFA Basic -> Programy testowe wersja 1.20

     Program ładujący pliki do RAMcarta (tOri)-> CARTLOAD.PRG (GFA Basic)

     Program ładujący RAMcart - autor Peter Putnik wersja 1.20 (assembler)

     Manual written by PP:

    RAMCART1.PRG

Utility for write and read Tori RAMcart adapter for cartridge port of Atari ST and
compatibles.

Button LOAD IMAGE FILE & WRITE does what it says, so will open file selector and
after selection will write content of file to RAM of adapter. Condition is that size of file
is 131072 bytes, or exactly 128 KB. Why not accepting shorter files, when often active
content is much shorter ? Well, I saw many times not good sized Atari ST cartridge
ROM images online. And reason was not size of active content, just someone was
shallow. So, better if users take care about proper size of cartridge ROM/RAM and
adjust file size by need - normally it is padding with value $FF until 128 KB point - easy
with some Hex editor (HxD for instance).

Button READ & WRITE INTO FILE will read content of selected half and write to file,
with name given in file selector. Size is always 131072 bytes.

Now EXIT-ing writing of this usage manual :-)

   PP, Nov. 2020

     Instrukcja obsługi jest prosta. Sama obsługa zaś intuicyjna. Program Petera Putnika jest bardzo szybki - całkowicie napisany w assemblerze. Mój program w kompilowanym
GFA Basic jest w porównaniu do jego jak ślimak :) POLECAM soft PP.

     Najprostsze zastosowanie funkcjonalności zezwolenia i zakazu impulsu,to dostęp do
dowolnego adresu i zmiany danych mimo zastosowania wyłącznie liniowego dostepu
do pamięci. Jest to okupione zużyciem dodatkowego czasu na manipulacje, ale to
poważne uelastycznienie możliwości sprzętu, co może być bardzo przydatne przy
wnoszeniu poprawek bezpośrednio w RAMcart.

W skrócie:

     0. Przygotować RAMcart do zapisu sekwencją startową
     1. Należy ustawić zakaz impulsu zapisu
     2. Należy odliczyć potrzebną do osiągnięcia żądanego adresu liczbę impulsów
     3. Należy ustawić zezwolenie impulsu zapisu
     4. W standardowy dla RAMcarta sposób dostarczyć dane do pamięci
     5. Należy ustawić zakaz impulsu zapisu
     6. Przełączyć na odczyt.

Zaprezentowałem to z grubsza w programie C_WRFF_N.LST gdzie wypełniam obszar
jednej strony od adresu $400 daną &HF1F5

     Ze względu na to, że w projekcie wystepuje duże zagęszczenie ścieżek oraz spory
stopień skomplikowania - najlepiej zlecić wykonanie PCB w jakimś chińskim zakładzie
produkującym takie rzeczy. Załączone gerbery spełniaja wymagania firmy JLCPCB. Tam
znalazłem najtańsze w chwili obecnej możliwości otrzymania dobrej jakości płytek.

     Wskazane jest posiadanie umiejętności lutowania "gęstych" układów scalonych.
Zastosowany układ CPLD jest w obudowie TQFP100 z rastrem 0,5mm.

     Ewentualne zapytania proszę kierować na forum Atari Area: nick tOri