No właśnie. Jakoś nie mogę ich odtworzyć.. :( Myślałem, że wystarczy tak, jak z przypadku snd zrobić jsr z offsetem 8 (oczywiście wcześniej inicjalizacja z offsetem 0) i wszystko zagra, a tu dupa. Macie gdzieś linka/kod, jak to powinno wyglądać?

2 Ostatnio edytowany przez mkm (2015-03-01 23:06:47)

Hej, musi działać:) poniżej kilka hintów opartych o problemy które ja miewałem:
- musisz mieć rozpakowany plik SNDH a większość jest spakowanych; do rozpakowania uzyj ICE
- init i play jak piszesz; init +0, play +8
- jeśli nadal nie działa to patrz procedure awaryjną poniżej
- zdarzyło mi się trafić na SNDH z playerami które nie backupja rejestrów, więc przed play zbackupuj rejestery dla testu by zweryfikowac czy to nie problem
- czasem player SNDH chce zaalokować pamięc, więc musimy ją zwrócić na starcie by jakaś była dostępna;) zazwyczaj przez to nie działają sndh z samplami o ile nie dasz na poczatku (pierwsze co robi Twoj kod) swojego programu:

            move.l  4(sp),a5                ; address to basepage
            move.l  $0c(a5),d0              ; length of text segment
            add.l   $14(a5),d0              ; length of data segment
            add.l   $1c(a5),d0              ; length of bss segment
            add.l   #$1000,d0               ; length of stackpointer
            add.l   #$100,d0                ; length of basepage
            move.l  a5,d1                   ; address to basepage
            add.l   d0,d1                   ; end of program
            and.l   #-2,d1                  ; make address even
            move.l  d1,sp                   ; new stackspace

            move.l  d0,-(sp)                ; mshrink()
            move.l  a5,-(sp)                ;
            move.w  d0,-(sp)                ;
            move.w  #$4a,-(sp)              ;
            trap    #1                      ;
            lea     12(sp),sp               ;  

- robisz cuda z timer'ami a SNDH wymaga timer'ów i masz problem. o ile robisz podmiany palet itp co pisałes w innym wątku to musisz mieć pewność, że nie używasz tych samych przerwań co muzyka

edit: jeśli nadal masz problem to daj znać to wyślę Ci example

Maciek
--------
Atari 65XE + Ultimate 1MB + Stereo + SIO2SD | Atari 520STE + 4MB + UltraSatan | Atari Falcon 030 + CT60e + 14MB ST + 256MB TT + 68882  + CF + Netusbee | Amiga 500 + 1MB + Gotek | Amiga 600 + 2MB Chip + 8MB Fast + CF

Noo zawsze sobie pamięć na początku alokuje. :) Ale za to nie rozpakowałem pliku, więc chyba tutaj leży mój f**k up. :D Chętnie spojrzę na kod odgrywający muzę na timerze C, bo cosik nie możemy się ostatnio dogadać. :P

4

No tak, jeśli nie rozpakowałeś plików to pewnie to jest przyczyna f**k up'u.
A jesteś pewien, że chcesz to robić na Timer C? Mam taki kod i mogę go odkopać, ale... jeśli tylko tempo pozwala grać raz na ramkę to lepiej to podpiąć na vbl. No chyba, że musisz częsciej....

Maciek
--------
Atari 65XE + Ultimate 1MB + Stereo + SIO2SD | Atari 520STE + 4MB + UltraSatan | Atari Falcon 030 + CT60e + 14MB ST + 256MB TT + 68882  + CF + Netusbee | Amiga 500 + 1MB + Gotek | Amiga 600 + 2MB Chip + 8MB Fast + CF
mkm napisał/a:

No tak, jeśli nie rozpakowałeś plików to pewnie to jest przyczyna f**k up'u.
A jesteś pewien, że chcesz to robić na Timer C? Mam taki kod i mogę go odkopać, ale... jeśli tylko tempo pozwala grać raz na ramkę to lepiej to podpiąć na vbl. No chyba, że musisz częsciej....

Mam już prockę pod vbl, ale chętnie jeszcze przepatrzyłbym kod pod timer C - próbowałem zrobić i coś mi nie działa. :( Chętnie w ramach przypominania/poznawania bebechów STeka zobaczę, jak to powinno wyglądać. Zresztą jak już się timer uruchomi, to można sobie stoper w grze zafundować... :P

6

Ok, wybacz kod wyjęty z większego kontekstu, ale może da jakiś obraz:

initMsxSNDH:
        move.l    #sndhPlayTimerC60,$114.w ; setup tc
        rts

sndhPlayTimerC60:
        sub.w    #SNDH_TC_REPLAY_FREQ,sndhPlayTimerC_tccount        
        bgt.s    sndhPlayTimerC_nocall
        add.w    #200,sndhPlayTimerC_tccount

        move.w    sr,-(sp)
        move.w    #$2500,sr
        movem.l d0-a6,-(a7)    
        jsr SNDH_FILE+8
        movem.l (a7)+,d0-a6
        move.w    (sp)+,sr
sndhPlayTimerC_nocall
        move.l  _old_tc(pc),-(sp)
        rts

sndhPlayTimerC_tccount    ds.w    200

SNDH_TC_REPLAY_FREQ to stała z częstotliwością grania. Kiedyś mi to działało, więc jest szansa że działa nadal;) To jest kod wyciągnięty chyba z jakiś przykładów maxymiser'a - nie pamiętam dokładnie gdzie go znalazłem.

Maciek
--------
Atari 65XE + Ultimate 1MB + Stereo + SIO2SD | Atari 520STE + 4MB + UltraSatan | Atari Falcon 030 + CT60e + 14MB ST + 256MB TT + 68882  + CF + Netusbee | Amiga 500 + 1MB + Gotek | Amiga 600 + 2MB Chip + 8MB Fast + CF

Hmmm... Coś podobnego udało mi się zrobić (i nie wiedzieć czemu nie gra ;)). Widzę, że ustawiasz swoją prockę pod timer C i zostawiasz domyślne systemowe ustawienia zegarów (200Hz). Chętnie podrążyłbym temat i zobaczył całą inicjalizację timera, masz coś takiego?

8 Ostatnio edytowany przez mkm (2015-03-02 10:31:50)

Nie nazwał bym tego swoją procką;) Użyłem jej dla eksperymentów, ale nie ja jestem autorem i nie podejrzewaj mnie to taką wiedzę by napisać coś takiego samemu hehe;)
Tak, tam jest zostawione domyślne 200Hz i z tego jest "syntentyzowane" tyle ile podasz.

Jeśli chodzi o cała inicjalizacje timer'a to.... znalazłem faktycznie skąd ją wziałem - tak, z maxymizer'a. Więc ściagnij sobie go z http://www.preromanbritain.com/maxymiser/download.html i wejdz do katalogu MYM_V133/SOURCE i zobacz PLAY_TC.S - tam masz wszystko.

Edit: aha, pytałem kiedys gwEm czemu to syntetyzuje a nie zmiania freq TC i pisał, że zmiana frq TC jest bardzo ryzykowna ze względu na transmisję z hdd. jeśli restore się nie uda konsekwencje mogą być słabe, ale nie znam detali.

Maciek
--------
Atari 65XE + Ultimate 1MB + Stereo + SIO2SD | Atari 520STE + 4MB + UltraSatan | Atari Falcon 030 + CT60e + 14MB ST + 256MB TT + 68882  + CF + Netusbee | Amiga 500 + 1MB + Gotek | Amiga 600 + 2MB Chip + 8MB Fast + CF

9 Ostatnio edytowany przez Tomasz Wachowiak (2015-03-02 11:35:12)

Dzięki. Wygląda obiecująco. :)
Edit: Kurde, też tylko vector pod timer podają. Nic to, trochę sam pokombinuję.

10

Modyfikacja częstotliwości przerwań / ustawień TC jest ryzykowna, najlepiej jest przechwycić przerwanie, wywołać naszą prockę, a potem skoczyć do starej / systemowej obsługi przerwania. To jest jak w przykładzie z Maxymizera (tylko ten kod poniżej jest jakiś 'lewy').

Robiłem podobnie przy integracji replaya midi w BadMood na flaszkę.

Trzeba też uważać, żeby przerwanie TiC nie wyskoczyło zanim zakończy się poprzednie (jak wykonywanie przerwania będzie trwało zbyt długo, a miałem takie przypadki).

Co do włączania/modyfikacji TiC to zwykle maskuję wszystkie przerwania w sr, wyłączam TiC, ustawiam TiC i dopiero potem go włączam i przywracam sr.

Coś mniej więcej jak poniżej (ustawia TIC domyślnie na 200hz):

move.w    sr,-(sp)    ;save status register
        or.w    #$0700,sr    ;turn off all interupts

stop TiC:
bclr.b    #5,$fffffa15.w        ;set interrupt mask B

ustawianie TiC:
move.l    update,$114.w        ;slap interrupt
        move.b    #246,$fffffa21.w    ; set data
        ori.b     #80,$fffffa1b.w    ; div mode
        bset.b    #5,$fffffa09.w        ; enable TiC
        bset.b    #5,$fffffa15.w        ; set interrupt mask B

;enable interrupts
move.w       (sp)+,sr         ;restore Status Register

=========================================
[www] https://nokturnal.pl
[ 16/32 bit Atari development wiki] https://bus-error.nokturnal.pl

Dzięki za kod. :) Wychodzę z założenie, że im mniej, tym lepiej i na początku programu wyłączam sobie wszystko, co się tylko da. Później w razie konieczności włączam sobie kolejne klocki i timer C będzie mam nadzieję jednym z nich. :)

saulot napisał/a:

Co do włączania/modyfikacji TiC to zwykle maskuję wszystkie przerwania w sr, wyłączam TiC, ustawiam TiC i dopiero potem go włączam i przywracam sr.

Coś mniej więcej jak poniżej (ustawia TIC domyślnie na 200hz):

move.w    sr,-(sp)    ;save status register
        or.w    #$0700,sr    ;turn off all interupts

stop TiC:
bclr.b    #5,$fffffa15.w        ;set interrupt mask B

ustawianie TiC:
move.l    update,$114.w        ;slap interrupt
        move.b    #246,$fffffa21.w    ; set data
        ori.b     #80,$fffffa1b.w    ; div mode
        bset.b    #5,$fffffa09.w        ; enable TiC
        bset.b    #5,$fffffa15.w        ; set interrupt mask B

;enable interrupts
move.w       (sp)+,sr         ;restore Status Register

Hmm... rejestr $fffffa21 dotyczy timeraB, tak samo jak rejestr $fffffa1b :) Czyli de facto włączasz tylko timerC na ustawieniach standardowych :)

13 Ostatnio edytowany przez saulot (2015-03-02 20:09:14)

ugh, to była niefortunna przeklejka ;) ..

powinno być:
        move.l    update,$114.w        ;slap interrupt
        move.b    #246,$fffffa23.w    ; set data
        andi.b     #$0f,$fffffa1d.w     
        ori.b        #$a0,$fffffa1d.w       ; div mode 50
        bset.b    #5,$fffffa09.w        ; enable TiC
        bset.b    #5,$fffffa15.w        ; set interrupt mask B

=========================================
[www] https://nokturnal.pl
[ 16/32 bit Atari development wiki] https://bus-error.nokturnal.pl
saulot napisał/a:

ugh, to była niefortunna przeklejka ;) ..

powinno być:
        move.l    update,$114.w        ;slap interrupt
        move.b    #246,$fffffa23.w    ; set data
        andi.b     #$0f,$fffffa1d.w     
        ori.b        #$a0,$fffffa1d.w       ; div mode 50
        bset.b    #5,$fffffa09.w        ; enable TiC
        bset.b    #5,$fffffa15.w        ; set interrupt mask B

Dzięki za kod. :) Zdążyłem już zrobić małe rozpoznanie i pod rejestr 1d należy wpisać wartość #$40, bo ustawiamy tylko 6 bit (div mode 50), a resztę zerujemy.

Na koniec małe podsumowanie całości i zebranie wszystkich naszych sugestii. Żeby odpalić swój timer C (200Hz), bez oglądania się na system i jego wartości należy:

1. Wyłączyć przerwania
2. Zainstalować sobie pod $114 własną procedurę.
3. Wyczyścić bity 4-6 rejestru kontrolnego timera C i D (adres $fffffa1d, ja czyszczę całość, bo timera D też nie chce mieć odpalonego) - mamy wtedy pewność, że timer będzie wyłączony do momentu jego ponownego uruchomienia.
4. Włączyć przerwania

Jeśli teraz będziemy chcieli załączyć timer C, wpisujemy #$40 pod $fffffa1d, #246 pod $fffffa23, ustawiamy bity 5 w adresach $fffffa09 i $fffffa15.

Procedura przerwania musi kończyć się wyczyszczeniem 5 bitu $fffffa11 no i oczywiście rte

16 Ostatnio edytowany przez saulot (2015-03-02 22:42:25)

To ustawienie bitu #5 w $fffffa11 przed rte nie jest konieczne jak sobie ustawimy bit#3 na 0 pod $FFFA17 . (wersja dla leniwych ;))

Z tym #$a0 to się rzeczywiście walnąłem, za dużo bitów poustawiałem.

=========================================
[www] https://nokturnal.pl
[ 16/32 bit Atari development wiki] https://bus-error.nokturnal.pl
saulot napisał/a:

To ustawienie bitu #5 w $fffffa11 przed rte nie jest konieczne jak sobie ustawimy bit#3 na 0 pod $FFFA17 . (wersja dla leniwych ;))

Wszystko OK, tylko że leniuchy powinny sobie ten bit wyczyścić, a nie ustawić... :P

18

niedokładnie przeczytałeś, napisałem 'ustawić bit#3 na 0' , tym razem nie zrobiłem sobie wioski ;) ..

=========================================
[www] https://nokturnal.pl
[ 16/32 bit Atari development wiki] https://bus-error.nokturnal.pl
saulot napisał/a:

niedokładnie przeczytałeś, napisałem 'ustawić bit#3 na 0' , tym razem nie zrobiłem sobie wioski ;) ..

Hehehehe.. Ale ty podstępny jesteś! :P Rzeczywiście... Ustawić na zero... :D