atarionline.pl Player RMT - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1:
       
      CommentAuthorKaz
    • CommentTime20 Jun 2009
     
    Pytanie od Asala:

    "Czy wie ktos może, w jaki sposób można programowo wyciszyć granie ścieżkek 1-3, ale tak, by grała wciąż ścieżka 4? Jest to potrzebne do tego, aby można było w grze włączać i wyłączać muzykę z zachowaniem SFX.

    Przeanalizowałem załączone przykłady do RMT, ale nie umiem tego zrobić inaczej, niż poprzez reinicjację całego modułu. Czy zna ktos może prostszą metodę?"
    • 2: CommentAuthormarok
    • CommentTime20 Jun 2009
     
    O ile rozumuje poprawnie, wystarczyloby dodanie w kodzie zrodlowym playera w miejsce tuz przed zaladowaniem do rejestrow pokeya, kodu typu AND byte.
    Gdzie byte zamiennie wynosiloby #$ff i #$f0 (wyciszenie).
    Dla trzech kanalow mono bylyby to trzy takie miejsca w kodzie.
    • 3: CommentAuthormarok
    • CommentTime20 Jun 2009
     
    ldy #$ff
    v_audctl equ *-1
    lda trackn_audf+0
    and byte
    ldx trackn_audc+0
    sta $d200
    stx $d201
    lda trackn_audf+1
    and byte
    ldx trackn_audc+1
    sta $d200+2
    stx $d201+2
    lda trackn_audf+2
    and byte
    ldx trackn_audc+2
    sta $d200+4
    stx $d201+4
    • 4: CommentAuthorasal
    • CommentTime20 Jun 2009
     
    Czy nie ma innej metody? Czy trzeba koniecznie zmieniać kod playera? Ja na razie efekt wyciszania osiągnąłem poprzez reinicjację modułu na pustej, zapętlonej ścieżce. A na kanale 4 odgrywam sobie SFX-y.
    • 5: CommentAuthormarok
    • CommentTime20 Jun 2009
     
    Sposob jaki opisales dowodzi ze nie trzeba zmieniac kodu playera. Moim zdaniem jest to bardzo rozsadne rozwiazanie i nie przypuszczam (chociaz slabo sie znam) zeby istnial inny, lepszy sposob (pod jakim wzgledem mialby byc lepszy?).
    • 6: CommentAuthorasal
    • CommentTime20 Jun 2009
     
    Tylko, że mój sposób ma pewien mankament - gdy chcemy wznowić muzykę na kanałach 1-3 i inicjujemy od nowa moduł od ścieżki 0, muzyka zaczyna grać od początku a nie od miejsca na którym się poprzednio skończyło. Pewnie jednak bez grzebania w kodzie nie da się tego obejść.
    • 7: CommentAuthormarok
    • CommentTime20 Jun 2009
     
    Jesli ma to byc dokladnie to samo miejsce to rozwiazanie moze byc trudniejsze. Jesli jednak ma to byc tylko mniej wiecej to samo miejsce muzyczki wystarczy chyba zapamietac linie songu w momencie zamierzonego wstrzymania muzyczki i przy ponownej inicjacji playera wymusic odgrywanie od tej zapamietanej lub nastepnej (w zaleznosci od koncepcji) linii.

    Jesli celem mialoby byc dokladnie to samo miejsce, to przedstawie pewne teoretyczne (moze bledne) rozwiazanie.
    Moga w pamieci rezydowac dwie muzyczki z wlasnymi playerami przy czym tylko jedna z nich winna zawierac wszystkie dane wlasciwe dla muzyczki czyli zapis paternow, linii song i instrumenty uzywane w muzyczce oraz do SFX, natomiast druga mialaby zawierac jedna pusta linie song odgrywana w petli oraz zestaw instrumentow do SFX.
    Uzyskanie zamierzonego celu polegalo by na czasowej deaktywacji wywolan playera dla pierwszej muzyczki w przerwaniu (poprzez pominiecie rozkazu jsr rmt_play), wyciszeniu kanalow pokeya (wywolanie rozkazu jsr player+9) oraz aktywacji wywolan playera dla drugiej muzyczki (pustej) w przerwaniu.
    Byc moze mozliwe byloby nawet obslugiwanie rownoczesnie dwoch playerow obu muzyczek bez koniecznosci przelaczania sie miedzy nimi (a tylko z czasowa deaktywacja pierwszej z nich) skoro kanaly pokeya uzywane przez oba playery nie bylyby wspolne (pierwsza muzyczka nie zajmowalaby sie wowczas zupelnie obsluga SFX i nie uzywala 4 kanalu pokeya).
    Deaktywacja wywolania playera spowoduje, ze wszsystkie rejestry, wskazniki i dane pozostana niezmienione (zamrozone) do czasu ponownego jego wywolania, co gwarantuje efekt o jaki mialoby chodzic.
    • 8: CommentAuthormarok
    • CommentTime22 Jun 2009
     
    Pierwszy sposob osiagniecia reinicjacji muzyczki od miejsca w ktorym ta zostala zatrzymana (chodzi o ten mniej dokladny z poprzedniego mojego wpisu) dziala w przykladzie w zalaczniku.
    Zmiany objely jedynie program obslugujacy player rmt i efekty SFX (sfx.a65) bez ingerencji w sam kod playera.

    Dodatkowy kod przedstawia sie mniej wiecej tak:
    ;* init part

    lda #0
    sta songLine

    ;* subroutines

    msxOff
    lda p_song
    sec
    sbc MODUL+8+6
    php
    IFT TRACKS>4
    lsr @
    EIF
    lsr @
    lsr @
    sta songLine
    plp
    lda p_song+1
    sbc MODUL+8+7
    lsr @
    IFT TRACKS>4
    ror @
    EIF
    ror @
    ror @
    ora songLine
    ; sbc #0
    sta songLine

    lda #emptySongLine
    ldx #<MODUL
    ldy #>MODUL
    jmp RASTERMUSICTRACKER

    msxOn
    lda songLine
    ldx #<MODUL
    ldy #>MODUL
    jmp RASTERMUSICTRACKER


    Wiekszosc zmiennych nawiazuje do tych z kodu zrodlowego playera rmt (i stad nie trzeba ich definiowac przy wspolnej asemblacji tego kodu i playera). Natomiast doszla zmienna "songLine" (najlepiej na stronie zerowej) i etykieta "emptySongLine" (zgodnie z zalozeniem ma to byc linia song ktora nic nie gra i jest zapetlona, trzeba ja zdefiniowac w zaleznosci od muzyczki).
    Procedury msxOff i msxOn wywoluje sie jsr'em.
    • 9:
       
      CommentAuthormiker
    • CommentTime22 Jun 2009
     
    Fajnie jakby ktos dorobił taką "odpalarkę" playera RMT do użycia pod BASIC-iem/TB na przerwanku VBL, np. w postaci:
    I=USR(ares muzyczki, linia w songu, adres playera) - uruchomienie
    I=USR(adres playera) - wyłączenie grania (i przerwania też), np. żeby móc na powrót używać stacji dysków/innych urządzeń
    ...czyli podobny sposób jak w CMCu to było. Głupie? ;)
    • 10:
       
      CommentAuthorKaz
    • CommentTime23 Jun 2009
     
    No wlasnie, ja juz o to prosilem kilku koderow, ale zdaje sie, ze na razie nie mieli czasu.
    • 11:
       
      CommentAuthorlarek
    • CommentTime23 Jun 2009
     
    Miker, wcale nie głupie i już myślałem nad tym. Na myśleniu niestety się skończyło :(
    • 12: CommentAuthormarok
    • CommentTime23 Jun 2009
     
    Metoda licznych prob i bledow udalo sie uzyskac wydaje mi sie w pelni odpowiadajace zalozeniom dzialanie odgrywaczki, co oznacza ze mozna teraz powrocic do odtwarzanej muzyczki dokladnie w to samo miejsce.
    Wymagalo to jednak wprowadzenia minimalnych uzupelnien do kodu playera RMT (rmtplayr.a65) i pewnej wstawki do pliku pelniacego funkcje konfiguracyjna wobec kodu playera - rmt_feat.a65.

    Szczegoly.
    Zmiany w rmtplayr.a65
    Nowy kod od etykiety rmt_p2
    rmt_p2
    IFT FEAT_PAUSE
    lda v_speed
    beq rmt_p3
    EIF

    Dodana linia (dowolne miejsce) deklaracji nowej etykiety.
    FEAT_PAUSE	equ 1


    W odgrywaczce trzeba zrobic co ponizej (nawiazanie do zmiennych z playera RMT)
    lda v_bspeed
    ldy v_speed
    beq waitkey2
    ldx <TRACKS-1
    lda #0
    waitkey3
    sta trackn_volume,x
    dex
    bpl waitkey3
    waitkey2
    sta v_speed
    • 13: CommentAuthorvega
    • CommentTime23 Jun 2009
     
    O fajnie:) właśnie to potrzebowałem jak pisałem BOMB JAKE ale wtedy nie chciało mi się szukać rozwiązania i zostawiłem tak, że wznowienie muzy było zawsze od początku.
    • 14:
       
      CommentAuthorKaz
    • CommentTime24 Jun 2009
     
    Brawo Marok!
    • 15: CommentAuthorvega
    • CommentTime24 Jun 2009 zmieniony
     
    a ten kod:

    lda v_bspeed
    ldy v_speed
    beq waitkey2
    ldx <TRACKS-1
    lda #0
    waitkey3
    sta trackn_volume,x
    dex
    bpl waitkey3
    waitkey2
    sta v_speed



    to gdzie właściwie wpisać? wykrywam wciśnięcie klawisza 'M' i wykonanie tego kodu nic nie daje...muza dalej gra
    • 16:
       
      CommentAuthorKaz
    • CommentTime24 Jun 2009 zmieniony
     
    Vega, uzywaj znacznikow [ code ], [ /code ] - bedzie czytelniejsze. Pozwolilem sobie dodac to w Twoim poscie.
    • 17: CommentAuthormarok
    • CommentTime24 Jun 2009
     
    vega:
    Przypuszczam, ze robisz wszystko jak trzeba (kod przynalezy do glownej czesci programu). Jezeli nie dziala, to albo program nie chce dzialac z kazda muzyczka (zwyczajnie jest zly i wymaga zmiany) albo moze player do RMT nie zostal dobrze zasemblowany (trzeba sprawdzic czy te dodatkowe 5 bajtow rzeczywiscie sa, z racji asemblacji warunkowej).
    Byc moze muzyczka zmienia regularnie tempo w utworze i to jest problemem. Zrobie pozniej kilka testow i poinformuje jak program dziala z roznymi muzyczkami.
    W tej sytuacji przepraszam jesli ten kod okazuje sie nieskuteczny, za to rowniez ze dokladnie nie przetestowalem, wczesniej uprzedzajac o potencjalnych problemach.
    • 18: CommentAuthormarok
    • CommentTime24 Jun 2009
     
    Dzwieki przeciagniete w czasie (dlugo wybrzmiewajace) moga byc nieslyszane po tym jak granie muzyczki zostanie przywrocone po pauzie, co jest efektem nieporzadanym. To odnosnie poprzednio prezentowanej wersji. Ponizej znajduje sie wersja poprawiona (juz bez tego mankamentu).
    lda v_bspeed
    ldx <TRACKS-1
    ldy v_speed
    beq waitkey2
    waitkey3
    lda trackn_volume,x
    sta c_trackn_volume,x
    lda #0
    sta trackn_volume,x
    dex
    bpl waitkey3
    waitkey2
    sta v_speed
    bmi loop
    waitkey4
    lda c_trackn_volume,x
    sta trackn_volume,x
    dex
    bpl waitkey4
    bmi loop

    ;*
    c_trackn_volume equ * ; :TRACKS brk


    Nizej proba funkcji USR w Basic'u (konflikt playera RMT na stronie zerowej z Basic'iem powoduje ze trudno tak wyznaczyc zmienne ze strony zerowej playera RMT by ten nie kolidowal z Basic'iem). Pewnie bedzie trzeba poprawiac. Podaje, aby ewentualnie potestowac.
    fr0	equ $d4
    cnt equ $e0 ;fr1

    org $600
    ; opt h-

    usr
    ldy #idxOldVbl
    pla
    bne usr1

    lda (fr0),y
    beq retUsr
    tax
    dey
    lda (fr0),y
    tay
    lda #7
    jmp $e45c
    retUsr
    rts
    usr1
    cmp #4
    bcs retUsr
    sta cnt
    lda $225
    sta (fr0),y
    dey
    lda $224
    sta (fr0),y

    pla
    ldy #idxJmpIniPlr
    sta (fr0),y
    ldy #idxJsrPlyPlr
    sta (fr0),y

    lda #idxVblank
    adc fr0
    tay
    ldx fr0+1
    bcc *+3
    inx
    lda #7
    jsr $e45c

    pla
    dec cnt
    beq retUsr

    pla
    tay
    pla
    tax
    lda #0
    dec cnt
    beq *+4
    pla
    pla
    jmp $ff00
    idxJmpIniPlr equ *-1-usr
    idxVblank equ *-usr
    jsr $ff03
    idxJsrPlyPlr equ *-1-usr
    dta b($4c),a(0) ;jmp a
    idxOldVbl equ *-1-usr
    end

    I=USR(adres procedury USR, adres playera, adres muzyczki, numer pozycji)
    W teorii procedura powinna zachowywac sie jak ponizej:
    Wersja pelna (z czterema argumentami) - inicjacja playera i odgrywanie od podanej pozycji songu.
    Wersja z trzema - jak wyzej ale od pozycji 0 songu.
    Wersja z dwoma - powinno odmrozic odgrywanie playera w miejscu poprzednio zakonczonym muzyczki (czysta teoria).
    Wersja z jednym argumentem - wylaczenie playera.

    Potrzebnych jest ok. 17 bajtow na stronie zerowej. Basic podobno korzysta z przestrzeni $80-$ff, a dos i system z $00-$80.
    • 19: CommentAuthormono
    • CommentTime25 Jun 2009 zmieniony
     
    Wg Zientary ( ->link<- w dodatku B ) bajty $CB-$D1 można wykorzystać, bo Atari BASIC z nich nie korzysta. Pytanie jak z innymi BASICami?
    Można by też próbować korzystać tymczasowo z buforów magnetofonu ($0400..$047F), drukarki ($03C0..$03E7 zdaje się) i edytora ekranowego ($0480..$04FF zdaje się) - adresy trzeba by sprawdzić, bo nie pamiętam z głowy.
    • 20: CommentAuthormarok
    • CommentTime26 Jun 2009 zmieniony
     
    mono: Dziekuje za wskazowke, ktora okazala sie przydatna.
    Korzystalem z ksiazki pana Zientary, ale jakos umknela mi informacja o wolnych bajtach na stronie zerowej.

    Funkcja USR wydaje sie juz dzilac. Ponizej pelny listing.

    fr0	equ $d4
    cnt equ 205
    Arc equ 203

    tis equ 205
    x0tis equ 7
    x1tis equ 18

    org $600
    ; opt h-

    usr
    ldy #idxOldVbl
    pla
    bne usr1

    lda (fr0),y
    beq retUsr
    tax
    dey
    lda (fr0),y
    tay
    lda #7
    jsr $e45c
    jmp $ff09
    idxJmpSilPlr equ *-1-usr
    popUsr
    tax

    pla
    pla
    dex
    bne *-3
    retUsr
    rts
    usr1
    cmp #4
    bcs popUsr
    sta cnt
    lda $225
    sta (fr0),y
    dey
    lda $224
    sta (fr0),y

    pla
    ldy #idxJsrIniPlr
    sta (fr0),y
    ldy #idxJsrPlyPlr
    sta (fr0),y
    ldy #idxJmpSilPlr
    sta (fr0),y

    lda #idxArc
    adc fr0
    sta Arc
    lda fr0+1
    adc #0
    sta Arc+1

    lda #idxVblank
    adc fr0
    tay
    ldx fr0+1
    bcc *+3
    inx

    lda $14
    cmp $14
    bcs *-2
    lda #7
    jsr $e45c

    pla
    dec cnt
    beq retUsr

    ldy #x0tis
    usr_v3
    lda (Arc),y
    tax
    lda tis,y
    sta (Arc),y
    stx tis,y
    dey
    bpl usr_v3

    pla
    tay
    pla
    tax
    lda #0
    dec cnt
    beq *+4
    pla
    pla
    jsr $ff00
    idxJsrIniPlr equ *-1-usr
    ldy #x0tis
    usr_v4
    lda (Arc),y
    tax
    lda tis,y
    sta (Arc),y
    stx tis,y
    dey
    bpl usr_v4
    rts
    idxVblank equ *-usr
    ldy #x1tis
    usr_v1
    lda (Arc),y
    tax
    lda tis,y
    sta (Arc),y
    stx tis,y
    dey
    bpl usr_v1
    jsr $ff03
    idxJsrPlyPlr equ *-1-usr
    ldy #x1tis
    usr_v2
    lda (Arc),y
    tax
    lda tis,y
    sta (Arc),y
    stx tis,y
    dey
    bpl usr_v2
    dta b($4c),a(0) ;jmp a
    idxOldVbl equ *-1-usr
    idxArc equ *-usr
    end



    Zalacznik dla potwierdzenia i ulatwienia sprawdzania czy tak rzeczywiscie jest. Trzeba uwazac aby nie dopuscic do uruchomienia playera/muzyczki bez wczesniejszego jego zamkniecia o ile byl juz wlaczany.
    • 21: CommentAuthormarok
    • CommentTime26 Jun 2009
     
    Jeszcze jeden zalacznik. Ilustracja dzialania kodu (wersji poszerzonej, podanej w jednym z poprzednich wpisow) do wstrzymywania i wznawiania odgrywania muzyczki. Muzyczka w zalaczniku ma zmienne tempo.
    • 22: CommentAuthormarok
    • CommentTime27 Jun 2009 zmieniony
     
    W temacie USR dla playera RMT.

    Nie do konca potrafie przeksztalcic wlasciwy kod funkcji USR rezydujacy na 6 stronie pamieci (chodzi o zrzut stanu pamieci emulatora dostepny w jednym z zalacznikow) do postaci ciagu kodow ascii zapisanych w zmiennej (o co pewnie chodzi). Moge jedynie zaoferowac taka oto pomoc w kodzie basica ktora wyrzuci na ekran w postaci takiego ciagu zawartosc obszaru pamieci o ktory nam chodzi. Dalej nie bardzo sobie radze. Mam nadzieje ze pozostala czesc zadania komus uda sie wykonac bez wiekszego trudu.

    FOR I=1536 TO I+(16*11):B=PEEK(I):? CHR$(27);CHR$(B);
    :NEXT I:FOR I=I TO I+20:? CHR$(0);:NEXT I

    • 23:
       
      CommentAuthormiker
    • CommentTime27 Jun 2009
     
    Spoko, marok, nie musi być w zmiennej. Jeżeli będzie to użyte pod Turbo BASICiem, to można część asemblerową procki wczytać binarnie przez BGET/BLOAD a potem już tylko odpalić przez USR. W każdym razie dzięki za podjęcie się zadania. :)
    • 24:
       
      CommentAuthorsikor
    • CommentTime27 Jun 2009
     
    O ile dobrze rozumiem, to plik *.RMT ma budowę dwublokową (przynajmniej tak pokazuje super packer). Jest to adres muzyczki i adres playera (w tej kolejności), czy mam rację?
    Jak tylko w usr podam adres playera - komp się niestety zawiesza (pod turbo basiciem).
    Przykładowe moje wywołanie:
    I=USR($600,$44B4,$4000,0)
    Bez zera na końcu czy z dowolną inną liczbą też się zawiesza. Podanie w odwrotnej kolejności (według adresów RMT) po prostu powoduje ciszę. Procedurę skopiowałem z tekstu powyżej i skompilowałem madsem.
    Także - niestety chyba jeszcze nie działa ;( (przynajmniej z TB XL).
    • 25: CommentAuthormarok
    • CommentTime27 Jun 2009
     
    sikor: dzieki za odzew i probe weryfikacji dzialania.
    Odnosnie TB rzeczywiscie widze teraz ze nie dziala (wersja 2.0 TB). Powodem jest player RMT a dokladnie jego zbyt niski adres asemblacji, ktory koliduje najwyrazniej z programem TB, czy jego danymi.

    Plik *.RMT ma budowe jednoblokowa. Od $4000 w tym przypadku (jest to tez adres sugerowany w zrodle RMT, z tego tez wzgledu mozna sadzic najbardziej rozpowszechniony).
    Tak samo jest z drugim czlonem, czyli player'em do RMT, ktory jest zasemblowany pod adres $3400 i tu widze ze jest to za nisko jak dla TB.
    Oczekuje wiec propozycji pod jakimi adresami najlepiej zasemblowac zarowno player, jak i muzyczke (RMT).

    Powinno byc:
    I=USR(adres procedury USR, adres playera, adres muzyczki, numer pozycji)
    W tym przypadku (ale wiemy ze nie zadziala bo kolizja pamieci playera RMT z TB):
    I=USR($600,$3400,$4000,0)

    >Procedurę skopiowałem z tekstu powyżej i skompilowałem madsem.

    No wiec to jeszcze nie wystarczy, bo poza tym ze trzeba zarowno skompilowac muzyczke i player (o czym wiesz), trzeba to zrobic jeszcze uwzgledniajac przesuniecie danych na stronie zerowej w procedurze playera RMT o dwa bajty w gore pamieci z 203 do 205 (o czym moze nie wiesz). Mozna to zrobic podmieniajac "p_tip org 203" na "p_tip org 205" w pliku zrodlowym playera i dopiero teraz kompilowac, uwzgledniajac jednak zmiane adresu playera w gore pamieci, czyli z $3400 w jakies bezpieczne miejsce (trzeba tez wiedziec ze player wykorzystuje kilka stron pamieci bezposrednio ponizej swojego adresu asemblacji na swoje potrzeby).

    >Także - niestety chyba jeszcze nie działa ;( (przynajmniej z TB XL)
    Mam nadzieje ze zassales to i sprawdziles czy dziala, bo mi tak (tylko microsoft basic):
    ->link<-

    W kazdym razie Sikor wielkie dzieki za odzew.

    Jeszcze do Mikera:
    Podobniez dzieki za slowo w sprawie. Informacja cenna. Postaram sie wypuscic kompilacje zdatna do strawienia w TB (chodzi mi o konkretny przyklad muzyczki).
    • 26: CommentAuthormono
    • CommentTime27 Jun 2009 zmieniony
     
    Jeśli macie możliwość ładowania danych binarnych w trakcie działania programu w TBXL, to może rozsądnie byłoby kompilować muzykę i player na samą górę pamięci - aż pod sam BASIC (BASIC startuje zdaje się od $A000) i obniżać przed załadowaniem RAMTOP:

    10 POKE 106,PEEK(106)-n: GRAPHICS x

    gdzie:
    n - liczba stron pamięci o jaki obniża się szczyt pamięci zajmowanej przez program w BASICu
    x - wybrany tryb graficzny - instrukcja GRAPHICS wymagana, żeby ekran S: i edytor E: został przeinicjalizowany, ponieważ system lokuje go właśnie na szczycie pamięci.

    Oczywiście znając adres od którego będzie sobie siedziała muzyka i player można do RAMTOP wpisać po prostu starszy bajt adresu. Przykładowo dla muzyki ulokowanej w $8000 i playera ulokowanego w $9000 do RAMTOP wpisujemy 128 ($80):

    10 POKE 106,128: GRAPHICS 0

    Zawartość RAMTOP jest inicjalizowana po RESET a inicjalizacja edytora E: zniszczy zawartość pamięci dlatego też muzykę i player należy załadować podczas uruchamiania programu w BASICu.
    • 27:
       
      CommentAuthorsikor
    • CommentTime27 Jun 2009
     
    mono: niegłupi pomysł
    marok: możesz zamieścić pliki źródłowe oprócz stanu emulatora - nie chce mi się wycinać danych... (znaczy się - pliki po kompilacji będą o.k.)
    • 28:
       
      CommentAuthormiker
    • CommentTime27 Jun 2009
     
    Ale, ale!
    RMT potrafi zapisać plik z muzyką od dowolnego adresu. File -> Export as -> Stripped RMT itd.
    • 29: CommentAuthormarok
    • CommentTime27 Jun 2009 zmieniony
     
    sikor: to nie jest konieczne, bo:

    wystarcza bardzo drobne zmiany w oryginale (podaje wszystkie zeby bylo jasne),
    rmtplayr.a65:
    PLAYER		equ nowyadresplayera ;bylo $3400
    ;* dalsze linie zostawiamy w spokoju, az do..
    org 205 ;bylo 203
    p_tis * ta linia wyglada tak jak w oryginale (podana dla orientacji
    ; przy okazji widac ze w poprzednim wpisie pomylilem nazwe tej zmiennej na p_tip)

    ;* i to wszystkie zmiany w rmtplayr.a65 (chyba ze o czyms zapomnialem ;))


    Warto przy wyznaczaniu nowego adresu playera uwzglednic ten jego kod:
    IFT TRACKS>4
    org PLAYER-$400+$40
    ELS
    org PLAYER-$400+$e0
    EIF

    Co oznacza w przypadku playera skompilowanego na potrzeby odgrywania w mono ze caly player wraz z danymi zajmuje pamiec juz od (w oryginale) $3400-$400+$e0=$30e0, a w stereo $3040.

    Plik *.rmt skompilowany pod adres wynikajacy z potrzeb.
    • 30:
       
      CommentAuthorsikor
    • CommentTime27 Jun 2009
     
    O.K. Potwierdzam - działa w miarę o.k. Znaczy się - chyba nieco mi fałszuje, ale może taką muzę do testów wybrałem. Skompilowałem sobie playera pod $8000, wersję stereo (wybrałem do kompilacji stereomode equ 3).
    Super robota - teraz trzeba potrenować, ale muzyczki w RMT już się da używać :)
    Dokładne wywołanie u mnie: X=USR($600,$8000,$4000,0)
    w ZAŁACZNIKU PLAYEREK SKOMPILOWANY POD $8000 - DLA TYCH, KTÓRZY SOBIE SAMI NIE SKOMPILUJĄ.
    P.S.
    Nie mogę uploadować pliku *.xex ==>

    Napotkano pewne problemy
    You are not allowed to upload (rmt8000STEREO.XEX) the requested file type: application/atari
    Czyli - mam brak uprawnień. Jak ktoś zainteresowany - proszę na priva (ale pewnie będę dostępny dopiero jutro...)
    • 31: CommentAuthormarok
    • CommentTime27 Jun 2009
     
    Sikor: Dobrze slyszec.
    Odnosnie falszowania to najprawdopodobniej chodzi wlasnie o muzyczke, a dokladniej o fakt, ze player jest skompilowany w wersji bardziej okrojonej niz tego wymaga wlasnie muzyczka (zastosowane instrumenty itp.). Poprzez pewne poprawki w pliku konfiguracyjnym rmt_feat.a65 jak mi sie wydaje mozna rzecz wyprostowac.
    Dzieki Sikor.
    • 32:
       
      CommentAuthorKaz
    • CommentTime27 Jun 2009
     
    • 33: CommentAuthormarok
    • CommentTime27 Jun 2009
     
    Niestety mi na emulatorze program Sikora zawarty w ATR'ce, ten napisany w TB nie dziala. Jeszcze nie wiem dlaczego, ale spiesze doniesc (bo pewnie nie tylko mnie).
    Dodatkowo musze stwierdzic, ze zasadniczo zdanie zawarte w komentarzu programu jakoby korzystal on z prostej ale jednak modyfikacji playera RMT Rastera, nie jest prawdziwe. Zaprawde, o ile sie orientuje, a chyba moge to z dosc duza doza przekonania twierdzic, wykorzystywane w przedstawionym programie procedury, w tym i player RMT nie zawieraja zadnej nawet najmniejszej modyfikacji w stosunku do oryginalu.
    Natomiast domyslam sie skad takie przypuszczenie. Ten watek dyskusji na forum dotyczy dwoch mini projektow. Tak jak tego dotyczacego zaprojektowania funkcji USR oraz drugi odnoszacy sie do opracowania metody czasowego wstrzymywania odgrywania muzyczki w programie napisanym w calosci w asemblerze. W tym drugim projekcie rzeczywiscie dopuscilem sie 5-cio bajtowej modyfikacji kodu playera, ale ta rzecz nie odnosi sie do pierwszego projektu. Chociaz mozliwe jest osiagniecie podobnego efektu czyli zatrzymania czasowego muzyczki, uzyskane jest to na innej zasadzie. Roznica polega miedzy innymi na tym, ze w przypadku drugiego projektu mozliwe jest wykorzystanie SFX w trakcie gdy muzyka przestaje grac (korzystajac z procedur playera i instrumentow muzyczki), a dla tej funkcji USR jest to niemozliwe.

    Sorry za wyklad, ale moze komus sie to przyda.
    • 34:
       
      CommentAuthorsikor
    • CommentTime28 Jun 2009
     
    Marok: program napisany w TB działą, tylko najpierw załaduj procki Zrób tak:
    1. załaduj Turbo Basic
    2. wgraj plik RMTPLAY.TB (load...)
    3. Wgraj wszystkie moduły (BLOAD"D:PLAY.COM" BLOAD"D:RMTST.COM" BLOAD"D:SMELLS.RMT"). tAJEMNICA POLISZYNELA TKWII W TYM, ŻE DANE MUSISZ MIEĆ WGRANE, ABY ZADZIAŁAŁO (sorki, caps wciśnięty), bo inaczej Ci nie zagra ;). A funkcji wgrywania w programie nie ma, bo robiłem faila ;)
    • 35: CommentAuthormarok
    • CommentTime28 Jun 2009
     
    Sikor: "zapomnialem" o trzecim punkcie recepty. Teraz dziala.

    Mam jeszcze takie oczekiwanie, ze komentarz odnoszacy sie do modyfikacji playera zniknie w oficjalnej wersji programu (o ile taka bedzie).
    • 36:
       
      CommentAuthorsikor
    • CommentTime28 Jun 2009
     
    Marok: tak, zniknie. Postaram się w wolnej chwili "skompilować" dwa playerki w bezpiecznych miejscach pamięci (muszę się przyjrzeć pamięci nieco, bo na przykład procka musiała zniknąć z szóstej strony - używa jej skompilowany Turbo Basic) w wersji dla muzyczek mono i stereo. To dla tych, którzy sobie sami nie skompilują, a chcieli by używać z Turbo Basiciem czy innymi programami.
    • 37:
       
      CommentAuthorKaz
    • CommentTime28 Jun 2009
     
    Przydalaby sie instrukcja krok po kroku - jak skorzystac, jakie sa wymagania, co trzeba zrobic i miec.

    Tak, zeby zielony czlowiek, ktory siadzie do Turbo Basica, po przeczytaniu mogl stosujac metode z instrukcji zrobic co trzeba czyli odegrac plik RMT w swoim programie.
    • 38:
       
      CommentAuthorsikor
    • CommentTime29 Jun 2009
     
    Hejka! Tu playery do testów, artek poszedł do KAZa, mam nadzieję, że umieści.
    Procedura USR wszędzie pod adresem $8F85, playery pod $9500, muzyczki umieśćcie sobie sami (testowe pod $7000) - zwracam uwagę, że ustawiono standardowo pod $4000 nie będą chodzić pod TB. Playery powinny spokojnie chodzić też pod innymi językami programowania niż Turbo Basic XL.
    Wywołanie:
    X=USR($8F85,$9500,adres_muzyczki,[pozycja_w_songu])
    Życzę miłej zabawy! (Aha: w miarę prawidłowo odgrywane tylko muzyczki 1x na ramkę)
    • 39: CommentAuthormarok
    • CommentTime30 Jun 2009
     
    Sikor: potrzebuje objasnienia jak dziala w bacis'u funkcja LOCATE. Mozesz podac nizej jej opis? (moze to miec pewien zwiazek z tematem)

    Mam jeszcze uwage techniczna do moderatorow strony jak przypuszczam. Zauwazylem ze w niektorych miejscach przywolywanego przeze mnie kodu brakuje czesci danych w rodzaju $nn (nn to numer szesnastkowy).
    Dwa zauwazone przypadki:
    fr0 equ [powinno byc jeszcze $d4]
    org PLAYER-$400+[powinno byc jeszcze $e0]
    • 40:
       
      CommentAuthorKaz
    • CommentTime30 Jun 2009 zmieniony
     
    Tutaj podrecznik Zientary na temat Turbo Basica XL:

    ->link<-

    A tutaj interesujacy Cie fragment:

    • 41:
       
      CommentAuthorCosi
    • CommentTime30 Jun 2009
     
    marok: Dzięki za sygnał. Okazuje się, że w PHP jest błąd, który przy okazji robi ładną dziurę w zabezpieczeniach ;-) Teraz powinno wszystko grać - do następnego błędu ;-P
    • 42: CommentAuthormarok
    • CommentTime30 Jun 2009
     
    Cosi: Widze, ze dziala. Blyskawiczna reakcja charakterystyczna dla sprawnego programisty. :)
    • 43:
       
      CommentAuthorCosi
    • CommentTime30 Jun 2009
     
    Oj, bo się zarumienię ;-)
    • 44: CommentAuthormarok
    • CommentTime30 Jun 2009 zmieniony
     
    W sprawie USR.

    Stablicowanie do zmiennej kodu USR mozliwe jest za pomoca nastepujacych czynnosci:
    1. Wczytanie do pamieci zasemblowanego kodu USR (w przykladzie pod adres 1536),
    2. Wczytanie ponizej przedstawionego programu w basic'u i uruchomienie.
    3. Zatwierdzenie powstalych linii DATA.

    Od teraz powinna poprawnie dzialac kombinacja:
    I=USR(ADR(PMV$), adres_playera, adres_muzyczki, numer_muzyczki).

    0 GRAPHICS 0:? CHR$(125):X=2:Y=1:DIM PMV$(198)
    1 FOR I=1536 TO I+197:B=PEEK(I):? CHR$(27);CHR$(B);:LOCATE X,Y,Z:
    PMV$(I-1535)=CHR$(Z):X=X+1:IF X>39 THEN X=2:Y=Y+1
    2 NEXT I:INPUT L
    3 N=39-PEEK(82)-7:J=L
    4 IF J>9 THEN N=N-1:J=J/10:GOTO 4
    5 FOR I=1 TO 198:IF INT((I-1)/N)=(I-1)/N THEN ? :? L;" DATA ";:L=L+1
    6 ? CHR$(27);PMV$(I,I);:NEXT I

    • 45: CommentAuthormarok
    • CommentTime1 Jul 2009
     
    Jeszcze uzupelniajac.
    Kiedy juz procedura USR znajdzie sie w liniach data, mozna stamtad przejac ja do zmiennej tekstowej za pomoca ponizszego kodu w basic'u.

    7 DIM C$(198),H$(N):X=1
    8 READ H$:C$(X,X+N-1)=H$:X=X+N:IF X+N<198 THEN 8
    9 READ H$:C$(X,198)=H$(1,199-X)



    Czyli oprocz kodu powyzej wystarczaja nam linie data wygenerowane kodem podanym w poprzednim wpisie oraz zdefiniowanie zmiennej N w powyzszym kodzie. Zmienna N musi zawierac wartosc rowna tej jaka uzyskala po wykonaniu kodu z poprzedniego wpisu (rownac sie ma ona liczbie znakow w linii data, wiec mozna to policzyc samemu). Dla poprawnosci dzialania nie potrzebna jest natomiast obecnosc w pamieci procedury USR (jest ona zapisana w liniach data).
    W kodzie programu wywolanie procedury ma postac:
    I=USR(ADR(C$), adr_playr, adr_muz, poz_muz).

    Wazna uwaga. Wywolywanie procedury USR poza programem, czyli w trybie natychmiastowym prowadzi do zawieszenia komputera, w momencie kiedy nastepuje proba wydania nastepnego polecenia interpretorowi (zmienia sie adres procedury umieszczonej w zmiennej, co powoduje ze obsluga przerwania skacze w zle miejsce pamieci).
    W programie wlasciwym (w numerowanych liniach) spodziewam sie ze uzywanie procedury USR (uwzgledniajac fakt ze mamy do czynienia z obluga przerwania, odbywajaca sie w trybie ciaglym) jest bezpieczne, ale pewnosci wcale nie mam.

    To chyba wyczerpuje temat (jesli nie, prosze informowac o problemach pozostajacych do pokonania).
    • 46: CommentAuthormarok
    • CommentTime2 Jul 2009
     
    Jeszcze cos jednak chcialbym dopisac.

    Mozna trzymac procedure USR w DATA i ja docelowo przerzucic gdzies w stale, bezpieczne miejsce pamieci, tym samym niwelujac wszelkie ryzyka przesuniecia sie w pamieci stablicowanej zmiennej tekstowej.
    Dzieki takiemu zabiegowi osiagamy to co poprzez fizyczne wczytanie USR pod wybrany adres, ale, i to jest caly plus tej sytuacji, nie musimy togo robic, bo dane te zostana tam przepisane z linii DATA.

    Podam dodatkowa linie kodu dla jasnosci jak to zrobic.
    10 FOR I=1 TO LEN(C$):POKE 1535+I,ASC(C$(I)):NEXT I

    Czyli aby uruchomic funkcje USR ulokowana w bezpiecznym miejscu pamieci, bez koniecznosci jej doczytywania z nosnika zewnetrznego osobno poza samym programem, nalezy posiadac linie DATA uzyskane liniami kodu 0-6 (funkcja USR musi byc wowczas obecna w pamieci).
    Nastepnie (wowczas juz w pamieci funkcja USR nie musi rezydowac) wykonac kod od linii 6 do 10, przy czym musza byc dolaczone jeszcze linie DATA. Ta czesc kodu nalezec ma do programu wlasciwego.

    Podobne czynnosci mozna wykonac, mysle sobie, (korzystajac z podobnego ale bardziej zlozonego kodu ze wzgledu na wielkosc danych) przerzucajac z linii DATA zapisanych w programie w miejsce pamieci przeznaczenia, danych tak samej muzyczki jak i playera, tym samym pozbywajac sie potrzeby doczytywania tych danych osobno do programu w basic'u.

    Po pierwsze jednak to znacznie trudniejsze do napisania (biorac pod uwage wielkosc bloku danych do przepisania i chyba koniecznosc podzielenia calosci tych danych na mniejsze kawalki), mozemy zalozyc bardzo czasochlonne w wykonaniu przez program w basic'u oraz to, ze wykorzystane w posrednictwie transferu z linii DATA pod wlasciwe miejsce pamieci, zmienne tekstowe niepotrzebnie beda zalegac pamiec przeznaczona na program basic'a. Nie wiem jak mozna byloby sie ich pozbyc z pamieci po wykorzystaniu w transferze.
    • 47: CommentAuthormono
    • CommentTime2 Jul 2009 zmieniony
     
    Dotykając problemu trzymania kodu w DATA i C$ - przecież można wygenerować linie kodu w postaci:
    10 DIM C$(2000)
    20 C$="kod 0..99"
    30 C$(101)="kod 100..199"
    40 C$(201)="kod 200..299"
    ...

    Trzeba by chyba tylko escapować EOL (155) za pomocą:
    ...
    50 C$(201)="kod 200..249":C$(251)=CHR$(155):C$(252)="kod 251..299"
    ...

    bo chyba nie da się go umieścić zwyczajnie w linii BASICa.
    Wtedy chyba problem z redundancją kodu w pamięci odpadnie? Oczywiście procedura w zmiennej C$ musi być pisana bez użycia bezwzględnych skoków.
    JMP można co prawda obejść za pomocą serii skoków względnych B**, lecz z JSR jest już nieco więcej zachodu:
    ; czytamy zawartość PC!
    ; zakładamy, że obsługa BRK
    ; po zrobieniu czego jej tam trzeba
    ; wróci do nas
    sei
    brk
    addr equ *
    tsx
    ldy $100,x
    dex
    lda $100,x
    tax
    cli
    ; XY zawiera adres addr
    sty $cb
    stx $cc

    Skok bezwzględny do addr może więc zostać wykonany za pomocą JMP ($00CB); JSR do addr może być wywołany trickiem:
    pha
    pha
    php
    pha
    txa
    pha
    tsx
    inx
    inx
    inx
    inx
    lda $cb
    sec
    sbc #1
    sta $100,x
    dex
    lda $cc
    sbc #0
    sta $100,x
    pla
    tax
    pla
    plp
    rts

    Dzięki temu bez problemu można do wywoływanej procedury przekazywać wszystkie rejestry i flagi procesora. Jeśli nie potrzebujemy dbać o X i CF, kod się znacznie uprości.
    Każdy skok bezwzględny (JMP, JSR) należy jednak wtedy przeliczyć względem bazy zapisanej w $CB..$CC.

    Edit: Zamiast serii DEX/INX można też uprościć kod, ale nie zadziała on w przypadku przepełnienia stosu:
    sei
    brk
    addr equ *
    tsx
    lda $00ff,x ;to MUSI być adresowanie Q a nie Z
    ldy $0100,x
    cli
    sty $cb
    sta $cc

    i ewentualnie wtedy:
    pha
    pha
    ldy $cc
    ldx $cb
    bne *+3
    dey
    dex
    txa
    tsx
    sta $0100,x
    tya
    sta $00ff,x ;adresowanie Q
    rts
    • 48: CommentAuthormarok
    • CommentTime2 Jul 2009
     
    mono: Dziekuje za podzielenie sie sposobem obejscia ograniczen wynikajacych z przemieszczalnosci kodu przy potrzebie zastosowania instrukcji JMP i JSR. Moze w przyszlosci bede potrzebowal takiej lekcji pogladowej (lub ktokolwiek inny) do zastosowania wprost lub inspiracji przy pracach nad wlasnym sposobem.
    Niemniej do zastosowania w tym przypadku (przemieszczalny kod USR oraz ustalone adresy playera i muzyczki) to nie jest mi potrzebne.

    Kod funkcji USR (tej do odgrywania muzyczki w RMT) jest juz przystosowany do przeniesienia w dowolne miejsce pamieci (tam bylem zmuszony np. zrezygnowac z instrukcji JSR mimo ze bylaby mi sie przydala i rozpisac tym samym jej dzialanie na powtarzalne fragmenty).
    Kod playera nie zamierzam przeredagowywac w podany sposob bo i pewnie nie dal bym rady, po drugie ile by taki kod zajmowal miejsca i czasu procesora wykonywany po niezbednych zmianach, i po trzecie, najwazniejsze, nie jest to niezbedne ani nawet potrzebne, by player przystosowac do wspolpracy z basic'iem.

    Ale rozumiem ze rozwazamy rzecz teoretycznie. Tutaj mam niewiele do powiedzenia (skomentowania, odniesienia sie krytycznie do przedstawionego kodu), poza chyba tym ze juz ten kod byc moze widzialem prezentowany na siostrzanym forum (atariarea) i ze zapamietalem z dyskusji najprawdopodobniej z Draco, ze trzeba w takiej sytuacji zalozyc, ze przerwanie programowe brk nie wykonuje zadnego kodu mogacego zaklocic zawartosc tak rejestrow jak i stosu. Co jest istotnym zastrzezeniem, o ktorym mozna niepamietac.

    Wracajac do USR (to juz mniej do mono, ale ogolna uwaga). Wiem juz ze kod w basic'u ktory przestawilem do transeru danych z pamieci do zmiennej tekstowej i z powrotem, jest dalece nieoptymalny i ze spodziewam sie napisac taki, ktory swobodnie umozliwi taki transfer, takze w przypadku obszernych blokow danych.
    • 49: CommentAuthormono
    • CommentTime2 Jul 2009
     
    @marok: Nie unoś się :) Nie chodziło o udzielanie komukolwiek lekcji tym bardziej, że każdy sam sobie takie sposoby prędzej czy później opracowuje.
    Wątek z AA gdzieś musiałem przegapić inaczej podałbym tylko linka.
    Zastrzeżenia do BRK, jak i nieoptymalności są oczywiście zrozumiałe (można by uściślać jeszcze konieczność blokady NMI, ale chyba nie ma takiej potrzeby).
    • 50: CommentAuthormarok
    • CommentTime3 Jul 2009
     
    Zauwazylem wlasnie, ze uzycie USR w opcji z trzema argumentami nie dziala i po sprawdzeniu pod monitorem emulatora co jest tego przyczyna, okazalo sie, ze niestety zawinila kolizja na stronie zerowej z playerem. Poprzednio przesunelismy adres zmiennych playera w tym obszarze pamieci o dwie pozycje z 203 na 205. Aby funkcja USR dzialala prawidlowo przy wywolaniu z trzema argumentami trzeba jeszcze przesunac ten adres o jedna pozycje, czyli na 206.

    Ale to nie wszystko.
    Nizej kod w basic'u do wklepania. Jest to realizacja zapowiedzi, ze postaram sie przedstawic bardziej optymalne rozwiazanie problemu przenoszenia danych z pamieci do linii DATA i z powrotem. Korzystajac z tego kodu mozna przenosic bez przeszkod duze obszary danych (wiec takze player i muzyczke).

    0 GOTO 32758:REM TRANS D->M
    1 DIM D$(108):A=1536-1:M=1536+197
    2 READ D$:FOR I=1 TO LEN(D$):POKE A+I,ASC(D$(I)):NEXT I:A=A+LEN(D$):IF A<M THEN 2
    32758 REM TRANS M->D
    32760 A=1536:L=10000
    32761 M=1536+197:DIM H$(1):X=(40-PEEK(82))*3-13:IF A+X>M THEN X=M-A:IF X<0 THEN END
    32762 ? L;" DATA ";:FOR N=0 TO X:H$=CHR$(PEEK(A+N)):? CHR$(27);H$;:NEXT N
    32763 A=A+N:L=L+1:? :? "32759 A=";A;":L=";L;":G.32761":? "RUN";:FOR X=0 TO 5:? CHR$(28);:NEXT X



    Komentarz do powyzszego.
    Piewsze wywolanie spowoduje uzyskanie linii DATA z obszaru pamieci okreslonego zmiennymi A i M (pierwszy i ostatni bajt przepisywanego obszaru pamieci). Okreslajac wartosc poczatkowa zmiennej L ustalamy pierwsza linie DATA zawierajaca dane z przepisywanego obszaru pamieci.
    Program wyrzuca trzy linie do zatwierdzenia przez uzytkownika. Pierwsza jest linia DATA, druga linia wyznaczajaca nowe wielkosci zmiennych A i L. Trzecia to instrukcja RUN.
    Uzytkownik ma wiec za zadanie trzykrotnie potwierdzic returnem akceptacje dla uzyskanych rezultatow dzialania programu i czekac az ten powtarzajac ta procedure sam nie skonczy napotkawszy na ostatni bajt z przepisywanego obszaru pamieci.

    Jesli juz ten etap bedziemy mieli za soba, mozemy skasowac linie 0, aby przesledzic dzialanie tej czesci programu, ktora odpowiada za funkcje odwrotna, tj. przepisanie z linii DATA do obszaru pamieci. Pamietamy tylko aby inicjowane wartosci A i M byly identyczne jak w poprzedniej czesci programu.