C64Power Forum
Archiwum => Meonlawel => Wątek zaczęty przez: BagoZonde w 17 Listopada 2010, 18:26
-
Witam!
Dzięki pomocy tutaj na forum jak i własnym dociekaniu, udało mi się zaimplementować w assemblerze program, który odtwarza muzykę np: spod $8000 na przerwaniu - PRG z Goat Trackera.
Mam pytanie, czy wiecie czy istnieje możliwość dodania dodatkowych efektów dźwiękowych na tym czwartym \'tajemniczym\' kanale, który można wykorzystać.
Chodzi mi o dodanie drobnych efektów dźwiękowych do gry, którą piszę - jak klik czy \'power chord\' po kliknięciu na
jakąś opcję.
Zapewne słabo szukałem mimo kilku książek i zasobów internetu.
Z góry dzięki za pomoc, choćby nakierowanie.
-
chodzi ogolnie o bombardowanie rejestru glosnosci. raczej nie wykorzystasz tego racjonalnie bo to mocno obciaza procka oraz sypie sie jesli w muzyce wykorzystywane sa filtry. W starszych goatach byly na pewno do wyboru playery typu \'game\' gdzie jeden z kanalow mozna bylo wykorzystac jako sfx, nie sprawdzalem jak w nowszych GT.
poszukaj o odtwarzaniu sampli na rej. glosnosci sida ($d418)
-
Dzięki za odpowiedź.
Do napisania tego postu na forum właśnie zdeterminowało mnie to, że próba wykorzystania $D418 \'szarpie\' muzykę i właśnie zniekształca dźwięki na filtrach, o których wspomniałeś. SFX pyrka jedynie.
Generalnie do testów w czasie odtwarzania muzyki przepisałem na szybko w assembler pewien basicowy program - efekt strzału. Działa ok osobno, ale razem z muzyką słychać tylko pyrkanie tego dźwięku (muzyka dzielnie znosi ten \'dodatek\') i szarpanie filtrów. Napisałem to do testów na takim pseudo - timerze biorącym wartość spod $A2 żeby spowolnić generowanie SFX ale mimo tego dźwięk SFX jest ucinany właśnie przez przerwanie - choć trwać powinien w pętli pare sekund. Wkleję ten programik, choć nie wiem czy jest sens:
LDX #$0F
LOOP:
STX $D418
DEX
LDA #$81
STA $D404
LDA #$0F
STA $D405
LDA #$28
STA $D401
LDA #$C8
STA $D400
TIMER:
LDA $A2
BNE TIMER
CPX #$0B
BCS LOOP
LDA #$00
STA $D404
STA $D405
powyższy kod wykonywany jest cały czas w pętli.
Wygląda więc na to, że SFX sobie podaruję - wolałbym muzykę na 3-ech kanałach. Chyba, że odpowiedź może znalazłbym w samym module muzycznym, choć brak dokładnej znajomości C64, którego dopiero się uczę - chyba dyskwalifikuje moje \'samotne\' poszukiwania ;).
-
robisz blad w zalozeniach.
napisz sobie procedurke ktora na przerwaniu NMI generuje prostokat (czyli naprzemiennie wrzucasz w nibbel mlodszy d018 wartosci 0 oraz 16)o f powiedzmy 2khz i dopiero potem wlacz muzyke jakas 3 chn przy uzyciu IRQ.
to co zrobiles nie odgrywa tak naprawde na rejestrze glosnosci nic co by mialo sample przypominac ;)
-
Ok dzięki, sprawdzę to. Ten listing, który wklepałem powyżej odgrywa taki a`la strzał - szum. Spróbuję popracować więc nad założeniami. W każdym bądź razie tak czy siak wchodzę tak naprawdę na jakiś kanał czy nie? W muzyce wykorzystuję filtr przeważnie na trzecim kanale.
-
tajemniczy kanal to wlasnie $d418 :) ogolnie odgrywanie sampli polega na zapisywaniu ich (4bit sampli) do mlodszej polowy $d418. ale to jest jak DAC, wiec musisz go bombardowac odpowiednimi czestotliwosciami. wyjscie timera w c64 nie jest podlacozne do wejscia sida - gdyby tak bylo, to faktycznie mozna by sztucznie otrzymac dodatkowy kanal na ktorym bez udzialu procka mozna by robic prostokat,a tak to musisz \'machac\' wartoscia $d418 z duza czestotliwoscia.
tutaj masz przyklady konkretne:
http://codebase64.org/doku.php?id=base:sid_programming
rozdzial `Samples aka Digis`
Ty w swoim kodzie natomiast bardzo rzadko wpisujesz do do $d418 - to nie zadziala po porstu, najwyzej raz na jakis czas uslyszysz jakis \'pierd\'. co i tak nie zmienia faktu ze odtwarzanie czegos takiego mocno obciaza procka bo kazda probka musi byc wczytana i wpiana do $d418, a w przypadku sida prmitywny efekt dzwiekowy to tylko kilka wpisow do reejstru i syntezator sie zajmie wszystkim sam (to niestety nie jest amiga z 25kanalowym kontrolerem DMA i wspoldzielonym CHIP RAM.... gdzie odtwarzanie MODow jest praktycznie w 100% sprzetowe i nie obciaza cpu)
-
chociaz ogolnie chyba odwolam to co napsialem jeszcze razp rzejrzalem kod.. y tam chyba robisz przebieg piloksztalnty w ostatecznosci ale nie wiem z jakas czestotliwoscia. generalnie najpierw sprobouj wygenerowac jakikolwiek dzwiek na $d418 (NMI) a potem sporbouj przy tym odtwarzac normlana 3kanalowa muzyke (IRQ).
-
Dzięki rafvte, na razie walczę z tym, żeby w ogóle jakieś NMI zrobić. O ile IRQ łyknąłem w jeden wieczór to NMI jest jeszcze dla mnie jakąś magią. Jam świeżak w assie, jednomiesięczny ;). Wiem tylko, żeby wrzucić wektor do własnej procedury pod $0318 i $0319. Książki nt. assemblera delikatnie NMI omijają z daleka ;). Może co do literatury nie trafiłem na tą \'Jedyną\' ;).
-
przyklad o tytule \'nmi sample player\' powinien Ci duzo rozjasnic
-
Właśnie ten przykład mnie trochę przeraził jako, że nie korzystam z dobrodziejstw turboassemblerów a piszę w surowym assemblerze na monitorze Action Replay 7.5. Rozkminię to NMI, kwestia czasu. Pod IRQ tego podpinać nie ma co? Nie miałem zbyt wiele czasu by się tym pobawić więc pytam.
Offtopicowo zaś inna rzecz jeszcze wczoraj mi nie \'pojszła\' po myśli. Chciałem zrobić screen blink na pewien czas, ale niestety po wyłączeniu ekranu nie działa mi jego ponowne włączenie.
Za bazę wziąłem to: bit 4 pod $D011 (53265) w zależności od tego czy jest 0 czy 1 - wyłącza lub włącza ekran.
Poke`owanie działa, zaś moje przełożenie tego pod ass już nie bardzo:
POKE 53265, PEEK(53265) AND 239
LDA $D011 : AND #$EF : STA $D011
POKE 53265, PEEK(53265) OR 16
LDA $D011 : ORA #$10 : STA $D011
Co ciekawe raz uruchomiony programik napisany pod assemblerem poprawnie mi wyłączył ekran, poczekał na jakiś klawisz i po naciśnięciu włączył ekran z powrotem, a ponowne uruchomienie wyłączyło ekran, ale już po wciśnięciu klawisza nie włączyło ekranu z powrotem.
-
pewnie jakiś zwis.
-
Racja Kisiel, to zwis, bo nawet przerwanie programu i wpisanie po omacku poke nie przywraca ekranu. Pytanie tylko dlaczego, skoro - no chyba przecież - ten sam program napisany pod BASIC przełącza mi ekran na blink 5 razy a nawet 100 (stu nie sprawdzałem ;)).
-
nie hardkoruj w monitorze skoro sa asemblery! ;d
-
BagoZonde najprościej to tak mogłoby wyglądać. Spacją dajesz on/off.
.C:c000 20 19 C0 JSR $C019
.C:c003 AD 11 D0 LDA $D011
.C:c006 29 EF AND #$EF
.C:c008 8D 11 D0 STA $D011
.C:c00b 20 19 C0 JSR $C019
.C:c00e AD 11 D0 LDA $D011
.C:c011 09 10 ORA #$10
.C:c013 8D 11 D0 STA $D011
.C:c016 4C 00 C0 JMP $C000
.C:c019 A9 EF LDA #$EF
.C:c01b CD 01 DC CMP $DC01
.C:c01e D0 FB BNE $C01B
.C:c020 CD 01 DC CMP $DC01
.C:c023 F0 FB BEQ $C020
.C:c025 60 RTS
.C:c026 4C 03 C0 JMP $C003
-
i jeszcze to, bo lepiej widać co i jak ;)
.org $c000
start jsr klawisz
;--------------------------------------- --------
off lda $d011
and #$ef
sta $d011
;--------------------------------------- --------
jsr klawisz
on lda $d011
ora #$10
sta $d011
jmp start
;--------------------------------------- --------
klawisz lda #$ef
cmp $dc01
bne klawisz+2
cmp $dc01
beq klawisz+7
rts
;--------------------------------------- --------
jmp off
;--------------------------------------- --------
-
no to dodaj sei.
-
Dzięki uka za kod. Nie różnił się on praktycznie niczym w porównaniu do mojego poza jedną rzeczą, której nie rozumiem.
W moim przypadku zczytywałem naciśnięcie klawisza poprzez JSR $FFE4 czyli GETIN.
Innymi słowy taka oto prymitywna procedurka:
LDA $D011
AND #$EF
STA $D011
LOOP:
JSR $FFE4
BEQ LOOP
LDA $D011
ORA #$10
STA $D011
RTS
...zadziała raz, a za drugim razem już ekranu nie wróci, nie wiem dlaczego.
Co do monitora, wiem, że bardzo dużo zachodu z tym, jednakże żaden z uruchamianych assemblerów nie poszedł mi poprawnie pod VICE. Jaki moglibyście polecić, cross assemblery raczej odpadają choć kto wie.
-
Co do assemblera jestem laikiem, ale instynkt mi podpowiada, że JSR $FFE4 po włączeniu czy wyłączeniu ekranu czeka na input z jakiegoś innego źródła niż klawiatura i to jest ten problem. Właśnie na tym stanąłem w projekcie, który piszę - próbowałem dodać wyłączeniu screenu i potem włączenie. Tam z kolei przy pierwszym uruchomieniu ekran się pojawia, ale zamarza właśnie na tym JSR $FFE4 prawdopodobnie.
-
Tak, to JSR $FFE4 powodował zawieszenie programu. Cała pętla stawała właśnie w tym miejscu mimo tego, że jeżeli żaden klawisz nie był naciśnięty - powinna wykonywać się dalsza część pętli. Spróbuję więc przerobić wszystko na ten $DC01 a o JSR $FFE4 muszę głębiej poczytać. Macie pojęcie co takiego może się gryźć>?
Odnośnie bombardowania kanału głośności - będę te tajniki zgłębiał na dniach.
-
Z tym JSR $FFE4 chyba się trochę poddaję. A wszystko chyba tak naprawdę dotyczy emulatora Vice. Nie mogę się doczekać, by sprawdzić to na prawdziwym sprzęcie - choć chciałbym, by chodziło to też pod emulatorem. Taki prosty kod:
0900 JSR $FFE4
0903 CMP #$11
0905 BNE $0900
0907 RTS
zawiesza mi przy drugim uruchomieniu z monitora (G 0900) a z kolei wywołanie SYS 2304 nie zawiesza.
Mimo wszystko nie mogę wprowadzić do programu wyłączania ekranu na chwilę i ponowne jego włączanie. Zaś co do $DC00 i $DC01 - to działało by to chyba znakomicie z tego co widzę - ale jak odróżnić tam naciśnięcie kursora w górę od kursora w dół? I analogicznie: kursora w lewo z kursorem w prawo.
-
cmp $DC01 to bezpośrednie odwołanie do układu CIA z którym sprzężona jest klawiatura. Przy czym żeby wiedzieć konkretnie który klawisz ma być \'wykrywany\' to trzeba jeszcze wziaść pod uwagę drugi z portów danych ($DC00). DC01 - rząd DC00 kolumna w matrycy klawiatury.
<br><br>
tutaj jest rozpiska: http://sta.c64.org/cbm64kbdlay.html
<br><br>
Druga sprawa, to wydaje mi się że Twój kod jest jak najbardziej ok. Poprostu komenda sys zapisuje adres powrotu z podprogramu (coś jak JSR) i po rts jest gdzie wrocić a goto z monitora to takie chamskie przestawienie wskaźnika instrukcji (PC) po którym przy rts program skacze w cholere ;)
-
No to sobie po brejkowałem :P
-
Dzięki uka za brejki ;). Time-brejki ;).
Odnośnie $DC01 to rozumiem działanie tego, z tym, że powiedz mi jak np: odczytać wciśnięcie konkretnego klawisza kursora?
Akurat w głównym menu mojego projektu opcje wybiera się kursorami w górę i w dół. Jeżeli więc do $DC00 wrzucę $FE to odczytam z $DC01 przy wciśnięciu klawisza góra lub dół - tą samą wartość czyli dla kolumny $7F. Trochę bez sensu więc. To samo dotyczy klawiszy lewo/prawo. Jest na to jakaś rada?
Dodatkowo w tym menu można także się posługiwać joystickiem w porcie 2 czyli brane są wartości spod $DC00.
Wolałbym więc JSR $FFE4.
-
c000 SEI
c001 LDY #$0E
c003 STY $D020
c006 LDA #$FE
c008 STA $DC00 ;sprawdz czy jest wcisniety kursor lewo/prawo
c00b LDA #$FB
c00d CMP $DC01
c010 BNE $C00D
c012 LDY #$02
c014 LDA #$FD ;sprawdz czy jest tez wcisniety shift
c016 STA $DC00
c019 LDA #$7F
c01b CMP $DC01
c01e BNE $C003
c020 LDY #$01
c022 JMP $C003
rozgraniczenie lewego prawego kursora (bez uwzglednienia shift lock`a). Bedą sie zmieniac kolory ramki w zaleznosci od kierunku.
-
No tak! Przestawiłem się na myślenie, że klawisz kursora to klawisz kursora, a przecież na C64 mamy SHIFTa. Tak to jest jak się siedzi na emulatorze.
-
Wracając do głównego tematu tego wątku, zacząłem mocniej wczytywać się w te digisy i NMI zarazem. Powiedzcie mi jedną rzecz, bo osiwieją mi od myślenia wszystkie włosy: do $d418 muszę zapodać starszy bit miejsca, gdzie znajduje się sample?
lda sample
and #15
sta $d418
Jeżeli tak, to czy ten sample może być zwyczajnym ustawieniem dla kanału #3 takich wartości jak FREQ, ADSR, PULSEWIDTH? Musi się też gdzieś kończyć. Hmm...