601

(126 odpowiedzi, napisanych Fabryka - 8bit)

Pajero: Sprytne. Aczkolwiek nawet do pracy samodzielnej radziłbym skorzystać z jakiegoś systemu kontroli wersji. Taki git nie wymaga serwera i wszystko jest trzymane lokalnie. Twój skrypt zamiast robić kopię pliku mógłby robić automatycznego commita do repozytorium. Plus tego jest taki,  że historia zmian pliku/plików jest z dokładnością do wiersza i za pomocą dostępnych narzędzi bardzo wygodnie można przeglądać, porównywać kolejne wersje. Oczywiście cofnięcie się do konkretnej wersji też jest trywialne :)

602

(126 odpowiedzi, napisanych Fabryka - 8bit)

Proszę nie używać liczby mnogiej, bo propozycja jest tylko moja i dziękuję za krytykę :)
Propozycję pseudorozkazu "sys" uzasadniam domniemaną trywialnością implementacji i prostotą użycia, ale po argumencie Foxa uświadomiłem sobie, że w takim rozwiązaniu zewnętrzny program wołany byłby przy każdej asemblacji, podczas gdy rozwiązanie z plikami pośrednimi sterowane make lub odpowiednikiem minimalizuje liczbę wywołań, co jest oczywistym plusem w przypadku skomplikowanych generatorów. Ostatecznie zły pomysł.

A pseudorozkaz "gen"? Ideą jest minimalizowanie liczby zastrzeżonych słów kluczowych będących nośnikami jakichś wartości, które można w przeciwnym razie mnożyć w nieskończoność, a za jego pomocą niejako rezerwujemy na nie osobną niekolidującą przestrzeń nazw.

Wciąż także nie wydaje mi się, aby podstawowe makra (data, itd) nie mogły być realizowane automatycznie np za pomocą takiego generatora. Konieczność instalowania środowiska dlatego, że autor kodu źródłowego napisał sobie linuksowego wsada generującego coś, co może być w samym asemblerze wydaje mi się nadużyciem.

603

(126 odpowiedzi, napisanych Fabryka - 8bit)

Miałem odpisać na maila, ale widzę wątek, to napiszę tutaj. Może ktoś będzie miał lepszy pomysł.

Zastanowiłem się nad tym i jest w tym trochę racji, żeby udostępnić taką wbudowaną funkcjonalność.
Narzędzia, z którymi się spotkałem zawierają takie makra. Przykłady

- C/C++: http://gcc.gnu.org/onlinedocs/cpp/Stand ... acros.html
- NASM: http://www.nasm.us/xdoc/2.11/html/nasmd ... ction-4.12
- Coś podobnego ma nawet Free Pascal: http://www.freepascal.org/docs-html/prog/progap7.html

Pewnie wiele innych też.

Zaproponowane przez Ciebie rozwiązanie ma taki problem, że nie jest przenośne: nie jestem w stanie zrobić projektu, w którym będę wstawiał np. datę assemblacji tak, aby każdy mógł to skompilować na dowolnym systemie. Musiałbym pisać osobny zestaw skryptów dla Windowsa i dla Linuksa.

Nie wiem ile w tym jest sensu, ale przyszło mi do głowy pewne generyczne rozwiązanie: pseudorozkaz GEN("description"), który pełniłby rolę uniwersalnego generatora zastępującego swoje ciało wygenerowanym napisem na podstawie podanego opisu. Można byłoby dla pełności zaimplementować w nim część istniejących pseudorozkazów:

gen("rnd(0,33,256)")  ;losowa liczba
gen('date("F j, Y, g:i a")')           ;data, np. formatowana jak w PHP: March 10, 2001, 5:16 pm
gen("line")           ;aktualny numer assemblowanego wiersza
gen("count")          ;kolejna liczba zwiększana o jeden przy następnym wywołaniu

Idąc za ciosem można byłoby dodać drugi pseudorozkaz, który nawet przydałby się mi:  SYS("command", [args...]), który odpalałby nowy proces o podanej nazwie i wstawiał w miejsce swojego ciała zawartość zwróconego standardowego wyjścia:

.he sys("SuperTableGenerator", 42)

Rezultat: wynik jakiegoś programu generującego super tablice ("SuperTableGenerator.exe") jako ciąg wartości szesnastkowych przyjmującego jeden argument.

Oczywiście "sys" byłby zależny od systemu, ale stanowiłby niezłą furtkę dla prostego generowanie zawartości. Ja często piszę skrypty w ruby, które generują mi jakieś dane, tylko teraz generuję plik binarny, któremu robię "ins", a tu można byłoby generować dane wprost.

W przypadku wielu przebiegów można byłoby cachować wartości wygenerowane przy pierwszym przebiegu.

Z tymi 16 bitami z pełnymi konsekwencjami to trochę przesada. Mimo szczerych chęci nie nazwałbym 65c816 w pełni 16 bitowym. To taki 8/16. Nie ma 16 bitowego "feelu". Programując go ma się raczej poczucie takiego Z80 (też ma 16 bitowe rejestry) albo 6809 (który ma bardzo zbliżony "layout"). Porównaj to sobie do takiego 8086, którego 16 bitowość jest już inherentna.
Jasne, że 816-tka ma 24-bity przestrzeni adresowej, ale to jest raczej danie 8-bitowcowi okienka na 16-to bitowy świat, przez które zagląda do większej pamięci...

605

(279 odpowiedzi, napisanych Fabryka - 8bit)

Sikor: Nie pierdziel z tą mikropłytą. To, że z różnych względów tak się nie stało, nie znaczy, że w Atari nie mógł oficjalnie wylądować 65c816. O serii komputerów Apple II słyszałeś? Ostatni z serii Apple IIGS miał na pokładzie 65c816. Miał standardowo 256 kB RAM (z oficjaną możliwością rozbudowy do 8MB). Wydaje mi się, że Applowcy raczej sikali po nogach zamiast krzyczeć, że to już nie jest Apple.
Uważam, że w czasach oryginalnej świetności sprzęt o działaniu Rapidusa mógł powstać i powstałby jakby było to opłacalne biznesowo. Rapidus wg mnie jest rozszerzeniem modelowym: komputer startuje jako zwykłe (w praktyce 100% kompatybilne) Atari, a turbo włącza się odpowiednią kombinacją klawiszy przy resecie (chyba, że z konfiguracji wybierzesz, żeby startował od razu jako turbo). W trybie turbo dobrze napisane programy dla oryginalnego Atari działają szybciej, a programy dedykowane potrafią więcej. To jest coś, czego można spodziewać się po nowszym modelu sprzętu w danej linii i tak możemy Rapidusa traktować.

606

(126 odpowiedzi, napisanych Fabryka - 8bit)

syscall: Tak się składa, że każdy koder pisze w którymś momencie swojej kariery jakiegoś asemblera. 90% nie kończy, a z tych ukończonych tylko dwa używa ktoś poza autorem.
Wiem, bo sam teraz piszę swojego trzeciego z rzędu asemblera, ale się z tym nie obnoszę, bo pewnie znowu trafi do tych 90% :)
Zalecam więc trochę pokory, bo jaki mads jest każdy widzi, ale jest ukończony i działający na tyle, że używa go większość atarowskiego światka.

607

(4 odpowiedzi, napisanych Sprzęt - 8bit)

Zdaje się, że to akurat można dość łatwo sprawdzić: http://visual6502.org/JSSim/index.html

608

(22 odpowiedzi, napisanych Zloty)

21. Rozbijanie płyty, ale na QuST 98. Dwóch od lewej to Solo i Tiger.
58. Rozbijania ciąg dalszy. Tleniony blondynek w środku to Solo. Z prawej jest Tiger i ja chwytający się za głowę :)
90. Po rozbiciu. Od lewej Roland, Tiger, Solo
73. Blondynek w pasiastej koszuli to oczywiście Solo
41. A tu trochę starszy, więc to na pewno jakiś późniejszy zlot.
76. Pet koduje tu Sheola :)

609

(8 odpowiedzi, napisanych Bałagan)

Można spróbować na jana. vcproj jest XMLem. Zerkając do niego można wyczaić jakie ścieżki includów były ustawione przy kompilowaniu (a więc jakie biblioteki były użyte) oraz jakie liby były potrzebne. Spróbuj skompilować wszystkie *.cpp ustawiając te includy i liby. Jak to nie przejdzie, to pewnie program ma jakieś nietrywialne windowsowe zależności i ogólnie będzie ciężko.

610

(8 odpowiedzi, napisanych Bałagan)

W robocie utrzymuję konfigurację windowsową (visual) i linuksową (gcc makefile) sporego projektu i dorobiłem się kilku automatów, ale w ogólności nie każdy projekt visuala da się trywialnie przerobić na coś strawnego na linuksie. Jeżeli to nic tajnego, to mógłbym na to zerknąć ( laoo ( at ) icomp . pl )

611

(23 odpowiedzi, napisanych Bałagan)

No faktycznie żyleta. Kuszące, szczególnie, że będę niedługo potrzebował, a z mojego easycapa specjalnie zadowolony nie jestem.

612

(42 odpowiedzi, napisanych Bałagan)

saulot: Pytasz o jakich dokumentach mówię? Odpowiadam, że chociażby o jedynym normatywnym, czyli "Standard for Programming Language C++" generowanym przez WG21. Zerknij sobie tu. Ostatni working draft sprzed standardu C++11 ma numer N3242. Jeśli do niego zerkniesz, to zauważysz, że na 1300 stron, 400 jest o języku, a 900 o bibliotece. Najbardziej kluczowym aspektem tej biblioteki jest nacisk na programowanie generyczne (stąd np podział na kontenery i algorytmy). Można napisać niezależne biblioteki podążające tym tropem, czego przykładem jest np boost. Qt jednak skrzętnie od wielu lat ignoruje kierunek, w którym rozwija się C++ opierając swój framework na zupełnie innych założeniach bardziej zbliżonych do języków zarządzanych, a nawet dynamicznych, które są sprzeczne z inherentną statycznością C++.

Stąd moje twierdzenie, że Qt nie używa standardowego C++.

613

(42 odpowiedzi, napisanych Bałagan)

C++ to język + biblioteka standardowa. Wystarczy zerknąć do dokumentów standaryzacyjnych. QT to nie biblioteka C++, tylko framework zbudowany na bazie języka C++ zastępujący jego bibliotekę standardową na wzór frameworków Javy czy .NET. Jest przy tym bardzo wirusowy starając się dostarczać swoje rozwiązania na każdy problem, które są niekompatybilne z tymi ustandaryzowanymi. Do kogoś zaczynającego od początku, to jest fajne, ale dla kogoś, kto zna C++ korzystanie z QT przyprawia o wymioty.

614

(42 odpowiedzi, napisanych Bałagan)

Tak całkiem teoretycznie to nie jest takie środowiska wcale potrzebne. Program napisany pod Visual Studio używający np Qt po przekompilowaniu na linuksa powinien po prostu zadziałać, o ile napisało się go oczywiście dostatecznie przenośnie, ale Qt jest frameworkiem, który dostarcza praktycznie wszystko, więc jak ktoś chce, to nie musi poza niego wychodzić.

615

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Osobno można ustawiać szerokość akumulatora oraz rejestrów indeksowych. To działa tylko w trybie natywnym 65c816.

616

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Używam tych makr. Tutaj akurat chodzi o hint dla asemblera (deklarację) jaka jest spodziewana szerokość rejestrów w danym miejscu, tak, aby asembler mógł wygenerować błąd, jeśli obliczona przez niego szerokość będzie różna, czyli np. (w pseudokodzie):

regA 16  ;rozkaz przełączający akumulator na 16 bitów
.a8 ; deklaracja, że w tym miejscu akumulator ma rozmiar 8 bitów -> ERROR

albo

.proc Prodecura
.a16 ;deklaracja 16-bitowego akumulatora.
...
.endp

...

.a8   ;deklaracja 8-bitowego akumulatora.
jsr Procedura  ;skok do procedury z kontekstu 8-bitowego akumulatora.
                Procedura deklaruje szerokość na 16-btów -> ERROR
...

617

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Wiedziałem, że gdzieś widziałem już coś takiego, tylko nie wiedziałem gdzie :)

Ej. A może koledze chodzi po prostu o wgranie programu w BASICu (który ma na PC w postaci pliku tekstowego) do atari, żeby pojawił się w tam jako program (czyli LIST, RUN... te sprawy)?

619

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Jeszcze tego nie próbowałem. Sprawdzę, jak to działa.

Nie wiem jak dokładnie masz zrealizowane te śledzenie, bo to nie jest trywialna sprawa, ale dość silnym mechanizmem mogłoby być śledzenie szerokości rejestrów na poziomie procedur (teraz trochę pofantazjuję):
- W samej deklaracji procedury, lub jako pierwszy pseudorozkaz (coś ala .a8x16, .a16x8 itd) mogłaby być deklaracja jaka szerokość rejestrów obowiązuje na wejściu.
- Wewnątrz procedury byłoby normalne śledzenie szerokości zaczynając od zadeklarowanego stanu początkowego.
- błędy byłyby generowane przy próbie użycia innej szerokości (tak jak już masz to zaimplementowane) ORAZ podczas próby wywołania procedury, która ma zadeklarowaną inną wstępną szerokość niż aktualna szerokość w miejscu wywołania.

Wyobrażam sobie, że jest to osiągalne, bo można byłoby wywołanie procedury traktować jako instrukcję wrażliwą na szerokość argumentu (taki lda #) z taką szerokością, jaka jest w danej procedurze deklaracja.

620

(22 odpowiedzi, napisanych Programowanie - 8 bit)

O! Super! Wiedziałem TeBe, że można na Ciebie liczyć :)

Jak zrobi się opt h- (w przykładzie jest przypadkowo h+), to generowany plik jest identyczny jak z AlfAssemblera.

621

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Faktycznie. Na zrobienie  lda.w #( label & $ffff ) nie wpadłem. Zastosuję.

Na ORG powyżej $FFFF można mieć dwa sposoby:

  • Zezwalać na takiego orga tylko przy opt h-

  • Zastosować nagłówek AlfAssemblera zaproponowany przez Draco, czyli $FBFB

622

(22 odpowiedzi, napisanych Programowanie - 8 bit)

OK. O tym nie myślałem. Nie wiem czy stosunek trudność do zysków jest opłacalny, żeby się za to zabrać. A format COMa position-independent, którego trzeba po prostu załadować pod dowolny adres, potrzebuje przynajmniej nagłówka sygnalizującego niezależność od adresu oraz długość bloku. Czegoś takiego nie ma, bo na 6502 nie było to sensowne, a na 65c816 już tak.

623

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Draco: Format ładowania w dowolne miejsce mógłby być przydatny, gdyż kod 816-tki może być relokowalny bez żadnej ingerencji (aczkolwiek programowanie kodu relokowalnego jest trochę uciążliwe). Trzeba byłoby tylko wymyślić sposób na powiadamianie kodu, gdzie zostały załadowane jego dane (coś a'la bloki RUN i INIT?).

Trzeba utworzyć jakiś komitet standaryzacyjny i podyskutować nad takimi rzeczami przed konkretną implementacją w konkretnych systemach :)


TeBe: Te fragmenty w dokumentacji znam, ale nie tłumaczą one np. jak otrzymać 16 młodszych bitów z adresu 24-bitowego.

624

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Operatory < ! > wydają się sensowne. Asembler powinien tylko wypisywać warning gdy żaden operator nie jest użyty (programista oczywiście może wiedzieć o co mu chodzi, ale tutaj wg mnie lepiej być dosłownym, bo to zmniejsza okazję do błędu).

Mads ma 24 bitowe adresowanie, nie potrafi tylko ustawić adresu asemblacji na adres spoza banku zerowego. Nie potrafi tego ani dyrektywa ORG, ani .SEGDEF. Odkryłem jednak, że potrafi to blok .PROC, któremu można ustawić dowolny 24-bitowy adres. Gdy już myślałem, że jest to rozwiązanie, okazało się, że z 24-bitowego adresu nie można (albo raczej nie potrafię) wyciągnąć 16 bitowego offsetu w segmencie i taki kod się nie kompiluje:

    opt h- c+

    org $0000

    .proc test, [$010000 + *]
label    lda.w #label
    .endp
label    lda.w #label
test.asm (6) ERROR: Value out of range

O nagłówku $FBFB dobrze wiedzieć. Szukałem czegoś takiego. Sprawdziłem i działa poprzez dodanie nagłówka z dwoma 24-bitowymi adresami do każdego bloku. Aczkolwiek wydaje mi się, że adres końca wystarczyłby 16 bitowy, ale to już szczegół.

Co do asemblerów, to w grę wchodzą tylko cross-assemblery (mam już środowisko do budowania itd). Co jest w madsie, a niema tego (nie znalazłem) nigdzie indziej, to idea procedur (bloki .PROC), która po podrasowaniu bardzo dobrze może wpisywać się w schemat programowania 65c816. Blok .PROC grupuje fragment kodu w logiczną całość z lokalnymi etykietami, a przekazywanie parametrów może być zrealizowane za pomocą stosu 65c816. Np. "engine" do deklarowania parametrów procedury mógłby służyć do śledzenia zawartości stosu. Np takie procedury mogłyby być tożsame:

    .proc sum1 ( .BYTE par1,par2 )
    lda pra1
    clc
    adc par2
    rts
    .endp


    .proc sum2
    lda 2,s
    clc
    adc 1,s
    rts
    .endp

Dodatkowo procedury można byłoby wzbogacić o chociażby specyfikację stanu procesora jaki w niej obowiązuje (długość rejestrów) i asembler mógłby śledzić czy stan jest spójny pomiędzy wywołaniami (niby nie daje to żadnych gwarancji, ale pomaga przy zachowaniu konwencji, no i tak, wiem, że mechanizmy śledzenia to nic nowego :)).

625

(22 odpowiedzi, napisanych Programowanie - 8 bit)

Nie było to rozgłaszane, ale nie jest tajemnicą, że piszę diagnostykę i firmware dla pasiowej karty turbo. Przez te kilka tygodni zdążyłem się przekonać, że 65c816 w pełnej przestrzeni adresowej jest diabelnie trudnym procesorem do oprogramowania w asemblerze. Główną trudność stanowi jego kontekstowość, o której trzeba pamiętać pisząc każdy fragment kodu:

  • w zależności od stanu procesora rozkazy natychmiastowe mogą łykać 8 lub 16 bitów operandu,

  • w zależności od okoliczności ten sam adres logiczny może wskazywać na rózne adresy fizyczne, np. lda $00 to adresowanie zerostronicowe (direct) więc adres fizyczny to D + $00, lub adresowanie absolutne, które adresuje pamięć w banku danych (niekoniecznie tożsamym z bankiem zerowym) oraz adresowanie długie, które to dopiero zaadresuje komórkę o fizycznym adresie $000000.

  • "strona zerowa" jest ruchoma i indeksowanie 16-bitowe może trafić gdzie indziej niż to wynika z kodu, bo $00,X nie wskazuje na adres X, tylko D + X.

  • równocześnie można operować na trzech różnych bankach: zerowym, banku danych, banku programu, przez co takie sta *+4 nie zawsze trafia w operand następnego rozkazu.

O co zatem mi chodzi? O to, że składnia asemblera 6502 ma się nijak do programowania 65c816 i straciłem sumarycznie wiele godzin z powodu błędów wynikłych z nawyku programowania 6502. O wiele za dużo, szczególnie, że w części z nich z pewnocią mógłby pomóc asembler. Założyłem ten wątek, bo nie jestem 100% pewny jakie rozwiązanie byłoby najlepsze i może ktoś będzie miał jakieś fajne pomysły i spostrzeżenia.

Skrajnym rozwiązaniem byłoby zaproponowanie składni niekompatybilnej z dotychczasową, ale wadą byłaby konieczność nauki asemblera od nowa. Rozwiązaniem pośrednim i najprostszym mógłby być jakiś tryb "strict" istniejącej składni. Najważniejsze co byłoby niezbędne w tym trybie to wyłączenie optymalizacji długości operandu oraz obligatoryjne specyfikowanie długości. Byłoby więcej pisania, ale to zdecydowanie mniejsze zło od głupich pomyłek, bo przecież każdy z tych rozkazów robi coś innego:

0000 A5 00           lda.b 0
0002 AD 00 00        lda.w 0
0005 AF 00 00 00     lda.l 0

0009 A9 00           lda.b #0
000B A9 00 00        lda.w #0

i przy braku specyfikacji długości w zależności od tego jaki operand wpadnie to wygeneruje się inny rozkaz.


Następna rzecz, której brakuje mi w madsie, to możliwość nadawania adresu asemblacji poza bankiem zerowym. ORG przyjmuje tylko adres z przedziału $0000 do $ffff i napisanie kodu dedykowanego bankowi np $f0 nastręcza niemałych trudności (kilka godzin szukałem błędu, którym był skok jsl, który trafiał do banku zerowego).

To nie rozwiązuje wszystkich problemów, ale przynajmniej te najważniejsze.

Ogólnie spostrzeżenia mam takie, że karta turbo z 65c816 i 16 MB RAMu to już nie atari ;)
Jak widać programuje się to zupełnie inaczej i daje zupełnie inne możliwości. Pamięć atari w banku zerowym może być traktowana coś a la pamięć CHIP w amigach, i opłaca się go używać tylko do pamięci ekranu a kod i dane można trzymać wyżej, ale to wymaga szerokiej infrastruktury w postaci formatu plików wykonywalnych dedykowanych wysokim bankom i systemu operacyjnego, który to wszystko obsłuży.
No i dość dobrze pasowałby tu kompilator wysokiego poziomu, bo 816 ma tryby adresowania wspierające pracę z kompilatorami (np., adresowanie względem wskaźnika stosu) i jak ma się tak dużo pamięci, to nie trzeba optymalizować na rozmiar.