Autorem citovaného textu je Defor
Přejít na původní příspěvek
Oznámení
Sbalit
Aktuálně žádná oznámení.
Assembler - všeobecná logika
Sbalit
X
-
Jenom k tomuhle:
-
Pokud chceš, aby tvůj program načítal data ze zařízení, které má nějaký svůj file-system (disketa, harddisk, ...), musí ti běžet OS. Nesmíš ho vypínat tak, jak se to u demáčů a her obvykle dělalo (zakázání přerušení, DMA atd.). Někdy se to myslím dělalo tak, že hra odstavila OS a když chtěla načítat z diskety, zase ho zapla. Ale tohle nikdy nebylo bezpečné a asi to fungovalo jen někde kolem éry A500, kdy všichni měli tak maximálně disketové jednotky. Myslím, že později v době HDD, se aspoň ten systém "odstavoval" regulérně přes exec.library (nějaké ty funkce Forbid/Permit apod.).
Jak se tedy načítalo z disketové jednotky ve "zlatých starých časech"? Jelikož demáče kompletně odstavily OS, kompletně převzaly kontrolu nad HW, musely se používat nesystémové track-loader rutiny. Někdy k tomu došlo hned při bootování diskety a na disketě tak vlastně byl jen ten standardní boot-sector. Track-loadery myslím byly většinou napsané tak, že uživatel řekl kolik sektorů dat se z diskety má načíst (a od kterého sektoru) a rutina to udělala. Někdy byly synchronní, někdy asynchronní. Bylo na uživateli, aby svá data nějak dostal na patřičné sektory a jeho program musel vědět, odkud mají data načítat a kam do paměti. Myslím, že se autoři moc nezatěžovali nějakým "file systémem". Někdo do toho vložil víc úsilí a tak vznikly alternativní "DOSy" - zmínil jsi Sanity Operating System (SOS), ve kterém si udělali vlastní file-system.
Jsou i nějaké track-loadery, které umí používat OFS (nebo FFS?) na disketách. Prý je takový k dispozici někde na EAB od Rosse. V diskuzích je o něm opakovaně zmínka, ale já ho nenašel (nemám přístup na The Zone). Měl by asi fungovat tak, že uživatel normálně na disketu nahraje soubory a track-loader bez přispění OS soubory (podle názvu) umí načíst. Určitě velmi pohodlné, ale nezkoušel jsem.
K dispozici je celkem nedávný systém od Leonarda - LDOS. https://github.com/arnaud-carre/ldos
Systém je hlavně udělán k tomu, aby načítal separátní exáče (opět bez přispění OS), rozbalil je, naalokoval paměť (udělal relokaci) a spustil. Ale myslím, že v něm je možnost i načítat datové soubory (víc https://github.com/arnaud-carre/ldos...dos/kernel.inc). Ale myslím, že neumí používat žádný stávající file-system, takže image diskety se musí nejdřív vytvořit v nějakém jeho toolu.
Je tu i alternativní cesta, kdy máš ve svém exe všechna data sbalená nějakým packerem a tvůj program je postupně v paměti rozbaluje. Samozřejmě nevýhodou je, že se ti všechna data musí nejdřív vlézt do paměti a navíc musíš mít dost volné paměti, abys do ní mohl rozbalovat. Záleží na situaci. Hodně menších demáčů (one-file demo) to tak ale dělá, protože je to jednodušší než řešit track-loadery (jako např. naše Mindsurfin'- používal jsem LZ4).
P.S.: Pokud se nechceš babrat s boot-sectorem, tak je možné si udělat normálně exáč, dát ho na bootující disketu, pustit pří bootu v startup-sequenci a na disketu si dát data na sektory, které jsou jinak prázdné (je třeba si zjistiti, které to jsou!). Tvůj program pak odstaví systém a track-loader rutinou si pak kdykoliv z těch sektorů taháš data. Disketa se tak na pohled jeví, že je "systémová" (je tam s/startup-sequence, tvůj exáč i standardní systémový bootblock), ale data pochopitelně v systému nejsou vidět. Takže musíš lidi instruovat, aby si kopírovali disketu celou (resp. ADF)Naposledy upravil Defor; 26.03.2024, 14:23:24.
Vložit komentář:
-
Defor
K tem skoum, že potrebuji 32 bitovy skok na navesti (a nestaci 16 bitovy skok) pouziti rozdeleni SECTION CODE / DATA tohle mi nevyresilo, aby jsem mohl pouzit pouze PC relativni 16 bitovy skok. Mozna si to myslel ve smyslu proc mi to nabiha az napodruhe pri 1 MB CHIP RAM, ale to bylo opravdu asi na hraně s pametovou narocnosti programu. Ja tam par veci jiz mam pridanych a jiz to na 1 MB CHIP nenabiha vubec (ani napodruhe). Musi byt alespon 512 SLOW RAM k 1 MB CHIP RAM. Jiz mam nahrubo rozdelene sekvence CODE / DATA, je to tak urcite lepsi. Nevim napriklad, jestli ma nejaky smysl udelat pro kazdy MOD sekvenci pro DATA zvlast, ze by kazdy MOD mel sve sekvence data, ale ted to mam tak, ze mam 1 sekvence data a pod tim vsechny MODy.
Premyslel jsem jak snizit pametovou narocnost, tedy nacitat data postupne. U nacteni souboru / MODu se da definovat, kolik se z nej ma nacist z jeho celkove delky, ale to muj problem neresi. Na netu, hlavne EABu se tvari, ze se to resi jen tzv. track loaderom, neboli programem, ktery nacita data z diskety postupne a taky se tvari, ze to takhle jde resit pouze z diskety a ze tohle omezeni nejde obejit, ze by to slo udelat treba z HDD, neboli aby byl track loader ktery by nacital data postupne z HDD. Jeden programator tam psal, že to resi maximalni komprimaci ve FAST / SLOW RAM a postupne nacita data do CHIP RAM. Co muze byt rozumny kompromis toho vseho, aby si mohl nacitat data i z HDD a ne pouze z diskety nejakym track loaderom. Ty si tam sam na fore EAB doporucoval sve oblimene Sanity (track loader) nekdy v roce 2021.
Svuj track loader tam ma i Photon, ktery si celkem ostatni chvalili. Rad bych jej sprovoznil, ale tak nejak zatim nerozumim tomu principu jak to pouzit s exe souborem, ze ktereho se budou data nacitat postupne, nebo to dat primo do kodu a jak to propojit s mym programem.
Ze zacatku mne napadala i alternativa mit vice mensich exe a mit je mezi sebou nejak propojeny nejakym skriptovacim jazykem, kde by se odchytila pouze po ukonceni jednoho exe promenna, ktera by urcovala, ktere exe se opet spusti, ale to asi nebude stastna volba... .
V příloze je zpakovany track loader od Photon-a, kod hazu i primo do vlakna... .
DDE5-BootLoader.zip
Code:*** BootLoader.S by Photon *** ;NOTE: PC-relative code is PREFERRED. ;To write to disk in Asm-One, use the command WS0 Boot 0 2 followed by CC0 LoaderVars =$100 ;Useful variables, see CPUinfo: Loader =$120 ;start of load script MyUserStack=$7fffc ;SSP is at a safe place, but set user ;stack. MFMsync =$4489 ;AmigaDOS standard sync marker. MFMlen =12980 ;Legacy trackdata read length in bytes ShortWt:MACRO ;CPU-independent nop;nop replacement tst.w (a6) ENDM *** Boot Block starts here *** Boot: dc.b 'DOS',0 dc.l 0,880 BootCode: ;gathers some data, turns off OS, copies itself to $100 *--- Fetch system info ---* move.l 4.w,a6 ;execbase (will soon be destroyed) move.l 294(a6),d4 ;CPUinfo in lowest byte for your use. sub.l a4,a4 ;VBR will always be 0 when booting ;from floppy. No GetVBR needed. *--- Fastmem available? ---* move.l #$20004,d1 ;fast+largest jsr -216(a6) ;AvailMem() move.l d0,d5 sub.l #2048,d5 ;leave room for stacks to grow moveq #4,d1 jsr -198(a6) ;AllocMem() and.l #-8,d0 move.l d0,a5 ;Start Address *--- OS off ---* ;you're nice'n all, but now you die. lea $dff002,a6 ;Loader uses this custom base addr tst.w (a6) ;wait out blitter .wblit: btst #6,(a6) bne.s .wblit move.l #$7fff7fff,d1 move.l d1,$9a-2(a6) ;disable interrupts & req move.w d1,$9c-2(a6) ;play it again Sam sub.w #$20,d1 ;don't affect Sprite DMA until Vblank move.w d1,$96-2(a6) ;disable DMA lea MyUserStack,a7 ;some safe place compatible with ;platform requirements *--- Copy rest of code/data to fixed address ---* lea CopyStart(PC),a0 lea (LoaderVars).w,a1 moveq #(BootE-CopyStart)/8,d2 .copyl: move.l (a0)+,(a1)+ move.l (a0)+,(a1)+ dbf d2,.copyl JMP (Loader).w ;Info from Exec passed in 4 registers ******************** $100.w ******************** CopyStart: CPUinfo: dc.l 0 ;$100 FastMemSize: dc.l 0 ;$104 SysVBR: dc.l 0 ;$108 FastMemStart: dc.l 0 ;$10c MFMcyl: dc.w 0 MFMhead: dc.w 0 MFMdrv: dc.w 0 MFMchk: dc.l 0 dc.w 0 ;reserved for your use. LoadVector: bra.w LoadMFMB ;for external calls, JSR ($11c).w LoadScript: ;At $120, sysinfo in 4 regs, a6=$dff002 lea CPUinfo(PC),a3 ;Use this for PC-rel in a pinch. movem.l d4/d5/a4/a5,(a3) bsr.s WaitEOF lea NullCop(PC),a0 move.l a0,$80-2(a6) ;blank copper move.w #$87d0,$96-2(a6) ;enable DMA (sprites enabled when used) *--- load first part ---* lea $42000,a0 ;to dest addr moveq #2,d0 ;from sector 2 move.w #-9,d1 ;load 9 sectors (- to trigger Step0) jsr ($11c).w ;call LoadVector, and return when done. lea $dff000,a6 ;restore plain custombase addr for demo JMP (a0) ;start demo. ;or use JSR and continue loading script here. *** MFMLoader.S by Photon *** ;requires a6=$dff002 WaitEOF: btst #0,5-2(a6) beq.s WaitEOF .w1: cmp.b #$37,6-2(a6) bne.s .w1 .w2: cmp.b #$37,6-2(a6) ;wait for last PAL line, $138 beq.s .w2 rts LoadMFMB: ;load sectors.a0=dst,d0=startsec.W,d1=nrsecs.W(-=Step0) MOVEM.L D0-D7/A0-A6,-(SP) lea $bfd100,a4 bsr MotorOn tst.w d1 ;if neg length,then Step0 first bpl.s .NoSt0 neg.w d1 .St0: btst #4,$f01(a4) ;head on cyl 0? beq.s .Rdy0 bsr.s StepOut bra.s .St0 .Rdy0: lea MFMcyl(PC),a1 clr.w (a1) .NoSt0: and.l #$ffff,d0 divu #22,d0 ;startcyl sub.w MFMcyl(PC),d0 ;delta-step beq.s .StRdy bmi.s .StOut subq.w #1,d0 .StIn: bsr.s StepIn dbf d0,.StIn bra.s .StRdy .StOut: not.w d0 ;=neg+sub#1 .StOutl:bsr.s StepOut dbf d0,.StOutl .StRdy: swap d0 ;startsec within cyl cmp.w #11,d0 blt.s .Head0 sub.w #11,d0 bra.s .Head1 .Head0: bset #2,(a4) lea MFMhead(PC),a1 clr.w (a1) bsr LoadTrak ;read track+decode beq.s .End .Head1: bclr #2,(a4) ;Head 1 lea MFMhead(PC),a1 move.w #1,(a1) bsr LoadTrak ;read track+decode beq.s .End bsr.s StepIn ;1 cyl forward bra.s .Head0 .End: bsr.s MotorOff MOVEM.L (SP)+,D0-D7/A0-A6 RTS StepOut: bset #1,(a4) lea MFMcyl(PC),a1 subq.w #1,(a1) ShortWt bclr #0,(a4) ShortWt bset #0,(a4) bsr.s StepWt RTS StepIn: bclr #1,(a4) lea MFMcyl(PC),a1 addq.w #1,(a1) ShortWt bclr #0,(a4) ShortWt bset #0,(a4) bsr.s StepWt RTS StepWt: moveq #67,d6 ;wait >3 ms LeaveLine: .loop1: move.b 6-2(a6),d7 .loop2: cmp.b 6-2(a6),d7 beq.s .loop2 dbf d6,.loop1 RTS MotorOn: move.w MFMdrv(PC),d7 addq.w #3,d7 or.b #$78,(a4) bset d7,(a4) ShortWt bclr #7,(a4) ;turns motor on ShortWt bclr d7,(a4) ShortWt .DiskR: btst #5,$f01(a4) ;wait until motor running bne.s .DiskR RTS MotorOff: move.w MFMdrv(PC),d7 addq.w #3,d7 bset d7,(a4) ShortWt bset #7,(a4) ShortWt bclr d7,(a4) RTS LoadTrak: ;load track+decode.a0=dst,d0=secoffs,d1=secsleft MOVE.W D0,-(SP) MOVE.W D1,-(SP) lea (MFMbuf).w,a1 move.w #2,$9c-2(a6) ;Clr Req move.l a1,$20-2(a6) move.w #$8210,$96-2(a6) ;DskEna move.w #MFMsync,$7e-2(a6) move.w #$9500,$9e-2(a6) move.w #$4000,$24-2(a6) move.w #$8000+MFMlen/2,$24-2(a6) ;DskLen(12980)+DmaEn move.w #$8000+MFMlen/2,$24-2(a6) ;start reading MFMdata .Wrdy: btst #1,$1f-2(a6) ;wait until data read beq.s .Wrdy move.w d0,d2 add.w d1,d2 ;highest sec# (d0=lowest) cmp.w #11,d2 ble.s .NoOvr moveq #11,d2 .NoOvr: sub.w d0,d2 ;nrsecs move.l #$55555555,d3 ;and-const move.w d2,d1 subq.w #1,d1 ;loopctr .FindS: cmp.w #MFMsync,(a1)+ ;search for a sync word bne.s .FindS cmp.b (a1),d3 ;search for 0-nibble bne.s .FindS move.l (a1)+,d4 ;decode fmtbyte/trk#,sec#,eow# move.l (a1)+,d5 and.w d3,d4 and.w d3,d5 add.w d4,d4 or.w d5,d4 lsr.w #8,d4 ;sec# sub.w d0,d4 ;do we want this sec? bmi.s .Skip cmp.w d2,d4 blt.s .DeCode .Skip: lea 48+1024(a1),a1 ;nope bra.s .FindS .DeCode:lea 40(a1),a1 ;found a sec,skip unnecessary data move.l a1,d6 lea MFMchk(PC),a1 clr.l (a1) move.l d6,a1 move.l (a1)+,d6 ;decode data chksum.L move.l (a1)+,d5 and.l d3,d6 and.l d3,d5 add.l d6,d6 or.l d5,d6 ;chksum lea 512(a1),a2 add.w d4,d4 ;x512 lsl.w #8,d4 lea (a0,d4.w),a3 ;dest addr for this sec moveq #127,d7 .DClup: move.l (a1)+,d4 move.l (a2)+,d5 and.l d3,d4 and.l d3,d5 eor.l d4,d6 ;EOR with checksum eor.l d5,d6 ;EOR with checksum add.l d4,d4 or.l d5,d4 move.l d4,(a3)+ dbf d7,.DClup ;chksum should now be 0 if correct lea MFMchk(PC),a1 or.l d6,(a1) ;or with track total chksum move.l a2,a1 dbf d1,.FindS ;decode next sec MOVE.W (SP)+,D1 MOVE.W (SP)+,D0 move.l MFMchk(PC),d3 ;track total chksum OK? bne LoadTrak ;no,retry moveq #0,d0 ;set to start of track move.w d2,d3 add.w d3,d3 lsl.w #8,d3 add.w d3,a0 sub.w d2,d1 ;sub #secs loaded RTS NullCop: dc.w $1fc,0 dc.w $100,$0200 dc.w $96,$0020 ;ensure sprite DMA is off until needed dc.w $ffdf,$fffe dc.l -2 BootE: *** Boot Block ends here *** dc.b "BootLoader by Photon/Scoopex" ;pad with random bytes blk.b 1024,0 ;MFMbuf is placed here after bootblock end, $3c0.w or so when copied. MFMbuf =LoaderVars+(BootE-CopyStart) MFMbufE =MFMbuf+MFMlen ;lowest free address. $372e for a full bootblock. END
Přiložené souboryNaposledy upravil Lisiak; 25.03.2024, 13:01:45.
Vložit komentář:
-
Hudebni rutinu teď načítám externě, aby jsem mel uklizeno v casti pro program. Nic jsem nestudoval jak se to dela. Pouzil jsem INCLUDE a fungovalo to. Tedy prvni zakladni verze. Pak jsem lepe rozlozil, co bude v casti hudebni rutiny a co bude lepsi nechat v casti pro program, tedy 2 soubory se zdrojovým kodem. Zamerne to delam stylem, jak bych si predstavoval, aby to fungovalo v nejake hre. Proto jsem casti kodu, kde se testuje stisk klaves dal do programu. V tehle casti pro testovani stisku klaves je ale i prima navaznost na hudebni rutinu. S tim jsem i pocital, ze to nebudu delat uplne čistě, ale to je muj zamer, protoze si muzu dovolit jednodussi logiku, nez je v programu, kde nevite, jake MODy se budou hrat, ale to ja vim.
Uplne nahore v programu je Photon-ův kod, ktery odstavuje a na konci vraci system. Pak je kod pro test stisku klaves. Teď je to šípka nahuru a dolu pro vyber hrajiciho MODu. ESC a leve tlacitko mysi pro ukonceni programu. A pak nasleduje kod ve kterem volam hudebni rutinu. V casti PROGRAM za testem stisku klaves bude dalsi kod pro program ktery jeste vznikne. Timhle se sikove vyuzije po programovve strance "pauza", ktera se i tak v hudebni rutine musi delat.
Prvni na co se skáče po odstaveni systemu je navesti "programCycle". Pomoci BSR se nacte podprogram/hudebni rutina "playMod" v hudebni rutine mam na spravnem miste RTS = navrat z podprogramu / hudebni rutiny (2.zdrojovy kod) do programu (1.zdrojovy kod) a vykona se skok pomoci BRA na navesti program = test stisku klaves. Pak se skace na navesti "programContinue" a opet se vracime do hudebni rutiny pomoci BSR a "playMod2". Dokonci se nam 1 cely cyklus hudebni rutiny a ted to dulezite, pokracuje se v novem cyklu az do jiz zpomenuteho prikazu RTS na spravnem miste v hudebni rutine. Tohle RTS v hudebni rutine je tedy spolecne pro BSR "playMod" i "playMod2". Asi to neni uplne cisty, ale umim si predstavit i vetsi prasarny v programovani a u mne je to v ramci moznosti v pohode. Za BSR "playMod2" jsme po RTS v hudebi rutine opet pred testovanim klaves. Proto pomoci BRA "nextCycle" skaceme na "program" a i si ted uvedomuji, ze bych misto BRA "nextCycle" mohl napsat hned "program" a radek s navestim "nextCycle" BRA "program" vubec nepouzit. Takhle, jak to mam ted je to asi trosku nazornejsi... .
- Poděkování 2
Vložit komentář:
-
Všiml jsem si, že jde něčeho dosáhnout, co jsem si myslel. že nejde a je to fakt blbost a jen o tom, že jsem s tím nepracoval a proto mne to nenapadlo a musel mně nasměrovat cizí kód. Nechci teď psát co to je, ale donutilo mně to na chvíli se koukat do cizího kódu a i když již vím, v čem je řešení, koukám do cizího kódu zatím ještě dál.
Chvíli mi docvakávalo, jak je myšlena adresace viz níže, protože jsem chvíli přehlížel instrukci LEA, pak mi to hned samozřejmě došlo. Je to celkem šikovné navýšení adresy bez ADD s použitím hodnoty a i když instrukci LEA nepovažuji za rychlíka, tak možná pořád rychlejší, nebo alespoň šikovnější (to je o zvyku) způsob, jak navýšit adresu / pointer.
Doposud pro mne známá klasika:
ADD #40, a0
Z cizího ukázkového kódu od SKID ROW:
LEA 40(a0), a0
ADD by mohlo mít navrch při nižších navýšeních adresy při použití ADDQ
Neměřeno a nepočítáno na takty, pardon
- Poděkování 1
Vložit komentář:
-
Soucasny stav kodu me hudebi rutiny hrajici MODy. Prehraje ciste MODy bez efektu pri pouziti zakladni rychlosti hrani 1-20 hexa. Optimalizovano pro 4 MODy, ktere prehraje správně. Pouzity ASM-Pro v1.18
V příloze zdrojovy kod.
playMod127_CDS.zip
- Poděkování 2
Vložit komentář:
-
Vidím, že od tvých začátků hraní si v Pythonu jsi už celkem hodně někde jinde
- Poděkování 3
Vložit komentář:
-
Vcera jsem doplnil efekt volume slide do dalsich 3 hudebnich kanalu. Ale primarne mam radost, ze se mi povedlo si uvolnit kompletne 1 adresovy reistr a to A4, ktery pouziju pro funkci cyklovani hrajiciho samplu, pokud se bude opakovat jen jeho mensi část.
Pro uvolneni registru A4 jsem pridal casovac pro to, ktery pattern se hraje. K adrese s potrebnymi daty je celkem snadny pristup a zaroven se s casovacem pro pattern pracuje v nizke frekvenci v ramci kodu. Na casovac jsem si vyhradil predposledni bajt v registru D4. V poslednim bajtu mam casovac pro odhrání 1 patternu (64 radku v trackeru) a v nejnizsich 2 bajtech mam casovac pro zpracovani konkretnich kanalů v kodu pomoci ktereho delam skoky na kod pro konkretni hudebni kanal, tedy zpracovava se vzdy pouze 1 kanal ze 4 v jedne programove smyčce a jsou v nem hodnoty 0 nebo 4,8 a 12.
Popsana cast kodu pro praci, ktery pattern V MODu se bude hrat jako dalsi, kdyz dohraje prave hrajici pattern.
V kodu mam v A1 pointer na prave hrajici MOD, ten si davam do pracoviho adresare A0 (pak mam pracovni adrsare jeste D0 a D1). Na 952. bajtu je prvni bajt ze 128 s informaci, kterym cislem patternu se zacina skladba hrat, pripocti k A0. Obsah vyse popsane D4 davam do pracovniho adresare D0. Swapem davam casovac pro hrajici pattern do nejnizsiho bajtu. AND je jedinou instrukci z upravy na kterou jsem zapomel a pak pridal. Vyssi bajt ze 2 bajtu musim nulovat, protoze ADD musi byt v rozsahu nejmene 2 bajtu (puvodne jsem pouzil rozsah 1 bajtu a po chybe pridal AND pred instrukci ADD). Nuluji D0. Cislo hrajiciho patternu do D0 pomoci (a0)+, a pokud se nehraje prave posledni pattern (nepresunul jsem 1 bajt o odnote 00 hexa), skoc na navesti songPosition. Navis casovac pro cislo hrajiciho patternu o 1 (vse potrebne jiz mame v D0 tedy muzeme). Delka 1 patternu ma 1024 bajtu. Vynasob cislo hrajicih patternu cislem 1024. Ale jeste 1 věc. Uplne prvni pattern nam v MODu hraje na 1084 bajtu. Pripocti k D0 jeste 1084 bajtu a v D0 mame prave spranou pozici hrajiciho patternu. Z adresy na A2 ctu data z patternu. Dej adresu zacatku hrajiciho modu z A1 do A2. Pripocti spravnou pozici nově hrajiciho patternu do A2 a jdeme na nove hrajici uplne prvni radek spravneho patternu
Po radku v kodu "bne songPosition":
Jdeme hrat skladbu MODu od začátku. Vynuluj bajt s casovacem pro cislo hrajiciho patternu. Dej do pomocneho registru A0 zacatek hraji skladby MODu. Pripocti 952 bajtu pro spravnou pozici informace, ktery pattern se hraje v MODu jako uplne prvni (nemusi to byt vzdy prvni pattern). Cislo hrajiciho patternu dej do pomocneho registru D0. Adresu pro stopovani hrajicich samplu v patternech vrat na zacatek (tohle jsem si pridal já). A pokracuje se dal v jiz popsanem kodu
- Poděkování 1
Vložit komentář:
-
Jen taková drobnost,
předpříprava pro praci s hlasitosti a zadani primych skoku i kdyz vyuziju minimum z tech moznych efektu a i to nebudou efekty zpracovány na takove urovni jakou ma nejaky tracker i tak prime skoky vuci stylu nudloveho kodu vnimam jako lepsi alternativu. Lepe jsem zpracoval praci s tempem, kdy jiz jsou pro tempo zpracovany data k tomu opravdu urcene. (nezpracovani v nejnizsim bajtu stavu F1 az FFh a i 00 jsem odchytil co ma jinou funkci ktera dosti mozna jen tak v MODu pouzita nebude a s tempem nema nic spolecneho, riskovat to nebudu a ten 1 BEQ (prT0) navic čert vem
Takový vtipný moment, kdyz jsem tam nemel k tem nevyuzitym navestim ty RTSka a mne to hralo blbě. Jsem si rikal, zkusim je tam radši dát...
EDIT:
Práce s hlasitostí dokončena. Čekalo mně 1 překvapení, kdy jsem v závěru v programu neměl chybu, ale prace s hlasitosti byla v jeji urovni vyrazne snizena. Po tom, co jsem dal do 1 hudebniho kanalu rucně a ne z MODu maximalni hlasitost hral kanal maximalni hlasitosti, pak jsem dopsany kod dal do poznamky a jiz mi zacala hrat spravna uroven hlasitosti i z MODu. To je ten případ ...a zkoušeli jste to vypnout a zapnout?
Jak bude cas pridam zacyklovani hrajiciho samplu v miste jinem nez je jeho zacatek a efekt volume slide, ktery ja osobne povazuji za nejzasadnejsi, pokud se nebudeme bavit o chiptune hudbe.
EDIT2 (12.listopad):
Zpracoval jsem prednastaveny parametr pro jemne doladeni tonu samplu (finetune), pro MOD je to v rozsahu -8 až +7.
Začal jsem se v tom štourat, až jsem to nakonec aplikoval
Nejvtipnější na tom byly rozcházející se hodnoty pro odečet od periody (výšky tónu), tedy hodnota A až F se zvyšuje a číslo odečtu se snižuje. Pomohla mi negace v bajtu hodnoty A až F a navýšení o 1.
Code:not.b D1 and.b #$0f, D1 addq #1,D1
Code:Offset Bytes Description ------ ----- ----------- 44 1 Lower four bits are the finetune value, stored as a signed four bit number. The upper four bits are not used, and should be set to zero. Value: Finetune: 0 0 1 +1 2 +2 3 +3 4 +4 5 +5 6 +6 7 +7 8 -8 9 -7 A -6 B -5 C -4 D -3 E -2 F -1
Naposledy upravil Lisiak; 12.11.2023, 10:48:44.
- Poděkování 1
Vložit komentář:
-
Dnes jsem dokončil práci s patterny, tedy již hraju skladbu v její celkovych 2 patternech. Z 1 kanalu jiz hraji 2 kanaly (všechny kanaly již naprogramovany jen postupne pridavam, jak se mi to libi v poslechu). V druhem pridanem kanalu se mi ne vzdy nacetl sampl do HW registru, tak jsem klasicky pridal zpomaleni pomoci casovace CIA mezi ukonceni DMA prenosu a nactenim samplu. CIA mam na hodnote zatim 10 hexa. Sample se ted jiz nacitaji zatim vsechny. Toto zpomaleni jsem pridal pro vsechny hudebni kanaly. CIA časovač s 10 hexa jsem dal do podprogramu. Skladba se na jeji konci v hrani vrati na zacatek. Dovolil jsem si zjednodusit tuhle funkci na podminku, kdy neni umozneno pouzit posledni mozny pattern co umoznuje format MOD, ale to je 128.pattern, tak mi to asi nijak nevadi. Jednoduse na te pozici testuji pomoci jiz pouziteho MOVE nulový bajt, který mi oznacuje poslední vyuzity pattern v skladbe.
Jak bude čas, zpracuji praci s hlasitostí, kterou doposud beru jen jako prednastavenou z formatu MOD, ale ne ze samotneho radku patternu.
Naposledy upravil Lisiak; 07.11.2023, 13:56:52.
- Poděkování 2
Vložit komentář:
-
Tak dnes jsem primárně dohledal 1 chybu, kvuli ktere mi MOD nehrál jak mel. Tou chybou bylo o 1 sampl posunute parametre pro delku samplu a prednastavenou hlasitost samplu. Tak jsem nejdříve hodnotu zpracovaneho samplu ponizil o 1 a ted jak jsem si k tomu sedl udeal drobnou upravu, ktera mne hned dodatecne napadla, jen jsem jiz na to nemel cas a to, ze jsem ponizil zaverecny skok na tyhle data. Ten skok se zadavat musi, tedy jsem jen snizil cislo pro dany skok a usetril tak 1 instrukci s odectem 1 o kterou jsem ponižoval hodnotu hrajiciho samplu, ktera je zadana primo v MODu a tedy tuhle hodnotu z programu ponizit jako ten primy skok v programu na data v MODu.
Pridal jsem v kodu data pro ztlumovani samplu a s kazdym radkem patternu z MODu se nacita i 1 bajt primo z programu ktery říká, jestli se ma nejaky sampl ztlumit aby nehrál. Tedy na 1 pattern pripada 64 bajtů. Tohle reseni je mozne jen kdyz vite, ktere skladby chcete hrat. Takhle se da jednoduse samotny format MODu rozsirovat o nejake dodatecne funkce, ale to ted nemam v planu a to ztlumovani samplu je nutnosti a zatim jednoduche a ucelne reseni. V tehle jednoduche skladbe je treba v 1 hudebnim kanalu v 1 patternu skladajiciho se ze 64 radku ztlumit dodatecne sampl na 2 mistech. Oproti starsi rutine hrajici muj format musim sampl ztlumovat o 1 radek v patternu drive, co znamena, ze tahle hudebni rutina hrajici format MOD je rychlesi, minimalne prozatim, ale i bude rychlejsi.
Ode dneška hraji 1 hudebni kanal v 1 patternu celkem verne (bez efektů), tak mam celkem radost. Ostatní příště
- Poděkování 2
Vložit komentář:
-
dotaz 2:
V odkaze " Bit Manipulation Instruction Execution Times"
Čo je myslené tým rozdelením dynamic a static?
Nejak som toto nedohladal.
Static tady znamená, že je číslo bitu pomocí osmi bitů obsaženo přímo v kódu instrukce (např. btst.l #3,d0).
Dynamic znamená, že je číslo bitu uloženo v operandu (např. btst.l d1,d0).
Kódování bitových instrukcí třeba zde
Naposledy upravil Defor; 31.10.2023, 17:24:48.
- Poděkování 2
Vložit komentář:
-
Autorem citovaného textu je ObiWanKen Přejít na původní příspěvekTak SWAP je isto rychlejsie ako MOVEM. To uz je na tebe ktory sposob si vyberies. Ja si orientacne pozeram cas tu:
https://oldwww.nvg.ntnu.no/amiga/MC6...000timing.HTML
EDIT:
dotaz 1:
V odkaze "Standard Instruction Execution Times"
nerozumiem poznamke:
** The base time of six clock periods is increased to eight
if the effective address mode is register direct or
immediate (effective address time should also be added)
Počet taktov v tabule je teda úplný, alebo sa tam ešte niečo pripočítáva?
dotaz 2:
V odkaze " Bit Manipulation Instruction Execution Times"
Čo je myslené tým rozdelením dynamic a static?
Nejak som toto nedohladal.
Autorem citovaného textu je sailor Přejít na původní příspěvek
řekla bych že je to takto:
- pokud <ea>= register direct, tj. An nebo Dn, místo 6 ticků je to 8, ale effective address time je v tomto případě =0
tj. ADD.L Ax,An ... ADD.L Dx,An .. ADD.L Ax,Dn a ADD.L Dx,Dn bude vždy =8.
- pokud <ea>= register indirect, například (An), je to takto:
ADD.L (Ax),Dn = 8 base + 4 ( délka výpočtu ea (An)) = 12
připočtená hodnota může být 0 až 10, podle té první tabulky - Effective Address Calculation Times
@ALL: Do hudebni rutiny jsem dnes pridal timer pro 1 pattern a zahral jej v zakladu. Jsou to takove useknute tony a sample. Kdyz pridam timer pro rychlost hrani skladby, melo by se to zlepsit, ale nevyresi se uplne vse a premyslim, že soubezne s radky patternu skladby budu spracovavat po 1 bajtu na 1 radek patternu data zvlast jiz v kodu. Bude tam pouze info o tom, kdy ztlumit sampl, pokud ho bude treba ztlumit. Pokud to pak budu mit vyladeny, mohl bych to vlozit primo do MODu, protoze ta informace by byla v casti, kam se zapisuje vyska tonu pro sampl a v ten moment tam budou vzdy same nuly, ale k tomuhle reseni se zatim nechystam.
Zatim mam v programu stale 4 promenne ve 2 datovych registrech, na kazdou promennou 2 bajty, v dalsim datovem registru 4 bajty dat z patternu MODu a 3 adresove registre so stalymi adresami na pattern, sample a dodatocne data k samplům. Pomocne promenne 3 datove a 1 adresovy registr.
Dnes mne vyškolila instrukce DBF, kde jsem predpokladal, ze po opusteni programove smycky mi necha v datovem registry nulu, ale ono nastava opet snizeni, tedy v ramci 2 bajtu tam bude hodnota FFFF hexa, pokud tedy chceme nastavit hodnotu rychlou instrukci ADDQ.w, musí se dát +1 vůči hodnotě kterou chceme nastavitNaposledy upravil Lisiak; 29.10.2023, 16:55:24.
- Poděkování 1
Vložit komentář:
-
Autorem citovaného textu je Defor Přejít na původní příspěvekJen jsem se na to podíval z rychlíku.
Myslím, že používání or.l a and.l na nastavování nebo mazání jednoho bitu v datovém registru je pomalejší než k tomu použít instrukce bset.l a bclr.l.
Tohle je fajn a již používám (použitý zatím BSET). I instrukci BCHG (překlopení bitu) jsem v minulosti programoval a tedy to dělal složitě
@ALL: V rámci programování nové hudební rutiny hrající MODy jsem se drobátko potrápil se správným načtením samplů z MODu, ale přesně tohle jsem předpokládal, že to nedám napoprvé. Nicméně dnes, jak jsem si sedl k programování se to již tváří rozumně a já si dle všeho zahrál první řádek z prvního patternu správně. Zaměřil jsem se teď hlavně na práci se samply a ostatní je poslechově zatím taky ok. Přidal jsem zatím přeci jen 1 datový register jako pomocnou proměnnou. Tedy registre pro pomocnou proměnnou v kódu jsou: D0, D1 a nově ted i D2. Pomocný adresový registr je zatím jeden a to A0.
- Poděkování 1
Vložit komentář:
Vložit komentář: