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 00:06
       
      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 02:06
       
      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 12:06
       
      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 15:06
       
      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 16:06
       
      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 17:06
       
      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 23:06
       
      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 22:06
       
      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 22:06
       
      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 01:06
       
      No wlasnie, ja juz o to prosilem kilku koderow, ale zdaje sie, ze na razie nie mieli czasu.
      • 11:
         
        CommentAuthorlarek
      • CommentTime23 Jun 2009 18:06
       
      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 23:06
       
      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 23:06
       
      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 00:06
       
      Brawo Marok!
      • 15: CommentAuthorvega
      • CommentTime24 Jun 2009 00:06 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 00:06 zmieniony
       
      Vega, uzywaj znacznikow [ code ], [ /code ] - bedzie czytelniejsze. Pozwolilem sobie dodac to w Twoim poscie.
      • 17: CommentAuthormarok
      • CommentTime24 Jun 2009 09:06
       
      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 23:06
       
      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 10:06 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 12:06 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 12:06
       
      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 00:06 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 07:06
       
      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 12:06
       
      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 12:06
       
      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 13:06 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 13:06
       
      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 13:06
       
      Ale, ale!
      RMT potrafi zapisać plik z muzyką od dowolnego adresu. File -> Export as -> Stripped RMT itd.
      • 29: CommentAuthormarok
      • CommentTime27 Jun 2009 14:06 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 14:06
       
      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 16:06
       
      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 18:06
       
      • 33: CommentAuthormarok
      • CommentTime27 Jun 2009 21:06
       
      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 09:06
       
      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 10:06
       
      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 11:06
       
      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 16:06
       
      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 23:06
       
      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 10:06
       
      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 10:06 zmieniony
       
      Tutaj podrecznik Zientary na temat Turbo Basica XL:

      ->link<-

      A tutaj interesujacy Cie fragment:

      • 41:
         
        CommentAuthorCosi
      • CommentTime30 Jun 2009 12:06
       
      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 12:06
       
      Cosi: Widze, ze dziala. Blyskawiczna reakcja charakterystyczna dla sprawnego programisty. :)
      • 43:
         
        CommentAuthorCosi
      • CommentTime30 Jun 2009 12:06
       
      Oj, bo się zarumienię ;-)
      • 44: CommentAuthormarok
      • CommentTime30 Jun 2009 17:06 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 10:07
       
      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 10:07
       
      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 11:07 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 12:07
       
      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 13:07
       
      @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 00:07
       
      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.