Welcome, Guest. Please login or register.


Author Topic: Assembly programozás (Read 254521 times)

Offline ergoGnomik

  • EP addict
  • *
  • Posts: 1291
  • Country: hu
  • Stray cat from Commodore alley
Re: Assembly programozás
« Reply #645 on: 2013.November.04. 12:00:04 »
Quote from: IstvanV
A különbség attól is függ, hogy Plus/4-en engedélyezett-e a képernyő. Ha nem (az egész kép keret), akkor a fenti 2.2-es "Z80 lassulást" feltételezve 3.73 MHz-es (várakozás nélküli) Z80-nak felel meg, egyébként csak 2.51 MHz-esnek.

Egyes programok gyorsulást érnek el azzal, hogy a gépet NTSC módba kapcsolják, amivel 5 / 4 arányú "overclock" lehetséges. Így azonban nincs használható video kimenet, és a szabálytalan órajelet valószínűleg nem célszerű hosszabb ideig használni.

Létezik azonban "lassú" mód is, amelyben a CPU mindig egyszeres sebességgel fut (886723.75 Hz = ~1.95 MHz-es Z80). Ennek kikapcsolt képernyőnél lehet értelme, ha konstans sebességre és pontos időzítésre van szükség (például 1541 "turbó" töltőknél).
Hát, ez az itteni úri közönséget valószínűleg meglehetősen kevéssé érdekli, én meg ismerem ezeket a lehetőségeket. Én csak annyit próbáltam volna kihozni a dologból, hogy ha valakinek van hozzá energiája, akkor szabványos konfiguráció mellett is feltehetően megoldható a "wave converter" stílusú hangkeltés EP-on.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Re: Assembly programozás
« Reply #646 on: 2013.November.04. 12:10:23 »
Quote from: ergoGnomik
Hát, ez az itteni úri közönséget valószínűleg meglehetősen kevéssé érdekli
Engem érdekelnek a szomszéd tábor érdekességei is. Pl. izgi ez a képkikapcsolás, ilyenről eddig csak ZX81-en hallottam.

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Assembly programozás
« Reply #647 on: 2013.November.04. 13:24:39 »
Quote from: geco
Hát valójában csak azt teszteltem, hogy milyen frekin kell tolni a hangot, hogy ne torzítson, ez lett 20Khz, a gyűrűmodot nem néztem, igaz nem is tudtam volna :D Alacsonyabb sebességű playbacknél egyre rosszabb.
Az ideális megoldás talán a SID órajelének a 64-ed része lenne, azaz C64 esetén 15394.51 Hz (250000 / 16 = 15625 Hz-es DAVE megszakítás, vagy 259 4 MHz-es Z80 ciklus / hangminta), Plus/4-nél pedig 13855.06 Hz (250000 / 18 = 13889 Hz-es DAVE megszakítás, vagy 288 4 MHz-es Z80 ciklus / hangminta). De ehhez nagyon kevés az idő, ha nem csak nagyon egyszerű emuláció kellene, akkor célszerűbb lenne ennek a felével próbálkozni.

Egy rövid példa (talán jobban is lehetett volna optimalizálni):
Code: ZiLOG Z80 Assembler
  1. .l1:    ld      bc, 0000h               ; * frequency 1 (= SID_freq/4)   10
  2.         add     ix, bc                  ;                                25
  3.         ld      a, ixh                  ;                                33
  4.         ld      l, a                    ;                                37
  5. .l2:    ld      h, high triangleTable   ; * waveform 1                   44
  6.         ld      l, (hl)                 ;                                51
  7. .l3:    ld      h, high volumeTable     ; * amplitude 1                  58
  8.         ld      a, (hl)                 ;                                65
  9.         out     (0a8h), a               ;                                76
  10. .l4:    ld      bc, 0000h               ; * frequency 2 (= SID_freq/4)   86
  11.         add     iy, bc                  ;                               101
  12.         ld      a, iyh                  ;                               109
  13.         ld      l, a                    ;                               113
  14. .l5:    ld      h, high triangleTable   ; * waveform 2                  120
  15.         ld      l, (hl)                 ;                               127
  16. .l6:    ld      h, high volumeTable     ; * amplitude 2                 134
  17.         ld      a, (hl)                 ;                               141
  18.         out     (0adh), a               ;                               152
  19. .l7:    ld      bc, 0000h               ; * frequency 3 (= SID_freq/4)  162
  20.         ex      de, hl                  ;                               166
  21.         add     hl, bc                  ;                               177
  22.         ex      de, hl                  ;                               181
  23.         ld      l, e                    ;                               185
  24. .l8:    ld      h, high triangleTable   ; * waveform 3                  192
  25.         ld      l, (hl)                 ;                               199
  26. .l9:    ld      h, high volumeTable     ; * amplitude 3                 206
  27.         ld      a, (hl)                 ;                               213
  28.         out     (0aah), a               ;                               224

Ez nem elég gyors ahhoz, hogy C64-es SID emulációt megszakításban valósítson meg, Plus/4 esetén pedig közel 100%-os CPU fogyasztása lenne. A főprogramban futtatva azonban elég lenne az idő; a DTM lejátszó is ilyen megoldást használ. Így a paraméterek módosítását kellene (video) megszakításból végezni, ami torzítaná a hangot. Azonban felszabadulna a hanggenerátorok frekvenciája, amit polinom számlálóval zaj emulációra lehetne használni - erre egyébként a fenti kód digitális lejátszással nem lenne képes, vagy legalábbis nem túl jó minőségben.

A mintavételezési frekvencia csökkentésével maradhatna idő effektusokra (szinkron, gyűrűmoduláció), illetve a lejátszó rutin hang megszakításba építésére.
« Last Edit: 2013.November.04. 13:42:54 by IstvanV »

Offline geco

  • EP addict
  • *
  • Posts: 7082
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #648 on: 2013.November.04. 13:54:35 »
Valami ilyesmire gondoltam én is, hogy főprogramban menne a hangkeltés, a DTM playerhez hasonlóan, és 256 bájton lennének eltárolva a minták, ismétlődve, arra gondoltam még, hogy mind a 15 hangmagassághoz lenne alap háromszög, és fűrészjel is eltárolva, a négyszögjelen még nem gondolkoztam :lol: , és ezeket 50 Hz-es megszakításból birizgálni.

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
Re: Assembly programozás
« Reply #649 on: 2013.November.04. 14:17:32 »
Quote from: Zozosoft
Engem érdekelnek a szomszéd tábor érdekességei is. Pl. izgi ez a képkikapcsolás, ilyenről eddig csak ZX81-en hallottam.

:) Azert erdekes lenne EP-n is, mert ugye ha a Nick-nek nem kene a videoram (fel lehetne fuggeszteni, hogy hozzaferjen), akkor addig mehetne a CPU-nak teljesen. Tehat EP-nel is okozna kulonbseget azert. ZX81 az mas teszta, ott eleg nagy kulonbseget okozna, mert - ha jol tudom - a video jel generalis felig-meddig (?) software-bol van, ott meg szignifikansabb a kulonbseg talan? Amugy preciz idozites miatt C64-nel is szokas letiltani a kepernyot (sot, defaulte magnorol toltes kozben le is kapcsol = keretszinu lesz az egesz kepernyo). De ugye egy 65xx rendszer busz idozitese nemikepp szorosabb, illetve C64 eseten amugy is macera a sprite-ok es egyeb dolog miatt (sot, valojaban a VIC-II adatbusza 12 bit szeles meglepo modon, 4 bit az kulon SRAM-ra megy ebbol - colour RAM - kulonben nem ferne bele semmifele idozitesbe, hiszen pl Nick-el ellentetben kepes hw text modban karakterenkent kulon szint is kezelni). Plus 4 eseten nem tudom pontosan hogy van ez a TED-del (ott imho nincs kulon colour SRAM) de talan pont ezert ott meg az orajellel is faragni kell, hogy beleferjen? Vagy hasonlo ...

(persze a konkret implementacio mas, C64-en orajel ciklusokat "lophat" el a VIC, +4-nel - afaik - viszont az orajel frekvencia van valtoztatva, EP-nel pedig ugye az orajellel jatszanak ismet, csak kisse maskeppen, de ezt Zozo ugyis jobban tudja)
« Last Edit: 2013.November.04. 14:38:55 by lgb »

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Assembly programozás
« Reply #650 on: 2013.November.04. 14:49:35 »
Quote from: geco
arra gondoltam még, hogy mind a 15 hangmagassághoz lenne alap háromszög, és fűrészjel is eltárolva
A 15 hangmagasság itt pontosan mit is jelent ? :oops: A hangmintákat több változatban tárolni anti-aliasing céljából van például értelme, de elsősorban csak PC-n, egy 8 bites lejátszón a "tökéletes" minőség kevésbé lényeges.

Quote from: geco
a négyszögjelen még nem gondolkoztam :lol:
Négyszögjelnél a kitöltési tényező módosításához (PWM) hasznos lenne több hangmintát tárolni. Például 32 lehetséges értékhez 8 KB területen (a SID ugyan ennél nagyobb felbontást tud, de a 32 is jobb a semminél). Ez a megoldás pazarolja a memóriát, viszont CPU időt takarít meg, amiből meglehetősen kevés van.

Offline ergoGnomik

  • EP addict
  • *
  • Posts: 1291
  • Country: hu
  • Stray cat from Commodore alley
Re: Assembly programozás
« Reply #651 on: 2013.November.04. 15:02:04 »
Gondolom geco hangmagasság helyett amplitúdóra gondolt. +4-en a négyszögjel kitöltési tényezőjét azt hiszem úgy modulálták, hogy a szokásos számú minta helyett másfélszer akkora terület volt foglalva és a kitöltési tényezőtől függően máshol (később) kezdték a kiolvasást. Így, bár több terület kell hozzá, mint a másik hullámformáknál, de mégsem annyira pazarló. Egyébként ott a lejátszási frekvencia sem volt ennyire magas, és bár hi-fi minőségről nem beszélhettünk :ds_icon_cheesygrin:, azért nagyjából rá lehetett ismerni mi is volt a 64-es eredeti.

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Assembly programozás
« Reply #652 on: 2013.November.04. 15:08:06 »
Quote from: lgb
Plus 4 eseten nem tudom pontosan hogy van ez a TED-del (ott imho nincs kulon colour SRAM) de talan pont ezert ott meg az orajellel is faragni kell, hogy beleferjen? Vagy hasonlo ...
A Plus/4 valamivel bonyolultabb:
- teljes, kétszeres sebességű órajelnél 114 ciklus egy 57 karakteres sor (1.7734475 MHz frekvencia)
- ez azonban a gyakorlatban nem lehetséges, mert 5 ciklusra minden sorban szükség van DRAM frissítéshez; így a legjobb esetben marad 109 ciklus (némi trükközéssel "letiltható" a frissítés, de ez adatvesztést eredményez)
- ha a képernyő aktív, akkor 204 sorban (ez 4 sorral a 25 karakter magas látható terület előtt kezdődik) 44 karakter időtartamra csak egyszeres sebességű az órajel
- ez 4 karakterrel a video adat olvasása előtt kezdődik, amit a 40 karakter pixeleinek az olvasása követ, majd végül az 5 karakteres DRAM frissítés; tehát a CPU számára marad 65 ciklus
- mivel nincs külön SRAM a színekhez, karakterenként két sorban történik DMA az attribútumok olvasásához, ebből egy az előző karakter 7. (utolsó) sorában a szín információhoz, egy pedig az aktuális karakter 0. (első) sorában a karakter kódokhoz
- DMA alatt 43 ciklus időre teljesen leáll a CPU, azokban a ciklusokban történik az attribútumok olvasása, amik egyébként egyszeres sebességű módban szabadok lettek volna
- a 43 ciklusból az utolsó 40 a tényleges olvasás, az első 3 azért van, hogy a CPU-nak legyen ideje megállni. Írás közben ugyanis erre nincs lehetőség, és a legrosszabb esetben 3 írási ciklus történik egymás után (PC és állapot regiszter mentése megszakításkor)
- tehát a DMA-s sorokban, amelyekből normál esetben 50 található a képernyőn, további 40-43 (de legyakrabban 43) ciklus veszik el, és marad 22-25
- a kétszeres sebességű módot letiltva minden sorban 57 ciklus áll rendelkezésre a CPU számára, kivéve DMA esetén, amikor csak 14-17 marad

Offline ergoGnomik

  • EP addict
  • *
  • Posts: 1291
  • Country: hu
  • Stray cat from Commodore alley
Re: Assembly programozás
« Reply #653 on: 2013.November.04. 15:11:22 »
Quote from: lgb
... Plus 4 eseten nem tudom pontosan hogy van ez a TED-del (ott imho nincs kulon colour SRAM) de talan pont ezert ott meg az orajellel is faragni kell, hogy beleferjen? Vagy hasonlo ...

(persze a konkret implementacio mas, C64-en orajel ciklusokat "lophat" el a VIC, +4-nel - afaik - viszont az orajel frekvencia van valtoztatva, EP-nel pedig ugye az orajellel jatszanak ismet, csak kisse maskeppen, de ezt Zozo ugyis jobban tudja)
Nos ott tényleg nincs külön színmemória, ezért a képernyőmemória mellé direktben van egy dinamikus színmemória rendelve (pl.: default képernyő kezdőcím $0C00 és az ehhez a karakterhez tartozó szín a $0800 címen van). Ennek hála a 8 bites adatbuszán kétszer annyi adatot kell karaktersoronként átrángatni, mint 64-en. Plusz bónusz a rasztersoronként 57(*2) ciklus a 63-mal szemben. Természetesen a TED ugyan úgy lopogatja a ciklusokat, mint a VIC, cak itt két badline van de legalább a sprite-ok nem zavarnak a képbe. Egyébként szerintem nincs két órajel frekvencia, csak a processzor a kereten sokkal kevesebbet van várakoztatva, mint a látható területen. De ezt IstvanV valószínűleg pontosabban tudja.

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Assembly programozás
« Reply #654 on: 2013.November.04. 15:12:01 »
Quote from: ergoGnomik
+4-en a négyszögjel kitöltési tényezőjét azt hiszem úgy modulálták, hogy a szokásos számú minta helyett másfélszer akkora terület volt foglalva és a kitöltési tényezőtől függően máshol (később) kezdték a kiolvasást.
Ez valóban kevésbé pazarló megoldás, de Z80 CPU-n valamivel lassabb, mert nem áll rendelkezésre a 6502 hatékony indexelt címzése. Azaz nem lehet egyszerűen csak a H regiszterbe írni a táblázat kezdőcímét, az L-be pedig az aktuális fázist, hanem aritmetikai műveletre lenne szükség. De ha ez a (nem nagy mértékű) lassulás nem probléma, akkor így memória takarítható meg, és az effektus felbontása is nagyobb lehet.

Offline geco

  • EP addict
  • *
  • Posts: 7082
  • Country: hu
    • Támogató Támogató
Re: Assembly programozás
« Reply #655 on: 2013.November.04. 15:12:32 »
Quote from: IstvanV
A 15 hangmagasság itt pontosan mit is jelent ? :oops: A hangmintákat több változatban tárolni anti-aliasing céljából van például értelme, de elsősorban csak PC-n, egy 8 bites lejátszón a "tökéletes" minőség kevésbé lényeges.
Bocs, a hangmagasság, a hangerőt akarta jelenteni :lol:
Úgy gondoltam, hogy miden hangerőhöz letárolok 1 3szög, egy fűrészjelsort, ami kitölti 256 byte-ot, és az 50Hz-es megszak állítja, hogy melyiket olvassa, a beolvasott hangerő függvényében. A frekvenciát, meg ugyanolyan addolós módón, mint a DTM playerben.
Quote
Négyszögjelnél a kitöltési tényező módosításához (PWM) hasznos lenne több hangmintát tárolni. Például 32 lehetséges értékhez 8 KB területen (a SID ugyan ennél nagyobb felbontást tud, de a 32 is jobb a semminél). Ez a megoldás pazarolja a memóriát, viszont CPU időt takarít meg, amiből meglehetősen kevés van.
A 32 sztem egész jó is lenne, ugyan nem tudom, hogy a white-fülűeknek mennyire lehet feltűnő a hiány, de a hozzám hasonló botfülűeknek sztem nem nagyon :D
Arra gondoltam, hogy valahogy ciklussal szabályozni ezt a dolgot, de mivel ezt nem teszteltem, ezért lehet hülyeségre gondoltam :lol: , és ez a 32 PWM-ű eltárolt négyszögjel szimpatikus ötlet.

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
Re: Assembly programozás
« Reply #656 on: 2013.November.04. 15:37:46 »
Quote from: IstvanV
Ez valóban kevésbé pazarló megoldás, de Z80 CPU-n valamivel lassabb, mert nem áll rendelkezésre a 6502 hatékony indexelt címzése. Azaz nem lehet egyszerűen csak a H regiszterbe írni a táblázat kezdőcímét, az L-be pedig az aktuális fázist, hanem aritmetikai műveletre lenne szükség. De ha ez a (nem nagy mértékű) lassulás nem probléma, akkor így memória takarítható meg, és az effektus felbontása is nagyobb lehet.

Na ebbe pont beleutkoztem. Mint "gyakorlott" (Z80-hoz kepest legalabbis!) 65xx programozo, hirtelen gondolkodoba is estem a minap, amikor az kellett, hogy egy egy memoriaban tarolt tablazatbol egy register altal (amugy egy byte-ba belefer, sot 7 bitbe is ...) megadott elemet toltsek be. Ez 65xx-n az indexelt cimzes mellett igen egyszeru, Z80-nal viszont eleg kenyelmetlen es lassu, mert csak ugy lehet megoldani, hogy pl 16 bites osszeadassal hozzaadom a tablazat kezdocimet es akkor ugy kiolvasom. Ennel tenyleg nincs jobb/gyorsabb megoldas? :( Gondolkoztam mar az onmodosito kodon is ;) Vegulis vmi (IX+d) eljarassal ha a "d"-nek megfelelo byte-ot atirom, akkor talan megiscsak hatekonyabb lesz (foleg, mivel amugy a tablazat merete 128 byte alatti - mint irtam). Valaki gyakorlottabb Z80 codernek lenne hozzafuznivaloja ehhez? Azt latom, hogy sajna ez Z80-on brutal lassu lesz 65xx-hoz kepest, ha beleszomolom a 16 bites osszeadast is :(
« Last Edit: 2013.November.04. 15:49:58 by lgb »

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Assembly programozás
« Reply #657 on: 2013.November.04. 15:38:30 »
Quote from: geco
Bocs, a hangmagasság, a hangerőt akarta jelenteni :lol:
Úgy gondoltam, hogy miden hangerőhöz letárolok 1 3szög, egy fűrészjelsort, ami kitölti 256 byte-ot, és az 50Hz-es megszak állítja, hogy melyiket olvassa, a beolvasott hangerő függvényében. A frekvenciát, meg ugyanolyan addolós módón, mint a DTM playerben.
Én erre külön táblázatot használtam, ami hanggenerátoronként elfogyaszt 14 ciklust. :oops: Viszont kevesebb memória használatával lehet 15-nél több szint (ami a burkológörbe generátorral előfordulhat), és a sok táblázatos PWM emulációval kombinálva nem lesz elfogadhatatlanul nagy a memória igény. Azaz valami ilyesmire gondoltam:
- 2 * 256 byte táblázat a fűrészjelhez és háromszögjelhez
- 1 * 256 byte táblázat rossz minőségű (rövid ciklusban ismétlődő) "zaj" emulációhoz; a másik megoldás a DAVE 17 bites polinom számlálójának a használata
- 16384 byte táblázat 6 bites hangerőhöz (ha az előző táblázatok csak 6 bites értékeket tartalmaznak, akkor valójában 256 byte-onként 192 byte-os "lyukakat" tartalmazna, amelyeket egyéb célra is fel lehetne használni)
- 8192 byte táblázat 5 bites PWM emulációhoz (tulajdonképpen 8448 byte kellene ahhoz, hogy 0 és 1 között 1/32 lépésekben lehessen állítani a kitöltési tényezőt)
- 32 KB területen még marad 7 KB szabad memória további táblázatokhoz

2 belapozott szegmensen a különböző táblázatok lennének, egyen a kód és egyéb adatok/változók, egyen pedig a lejátszandó zene.

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Assembly programozás
« Reply #658 on: 2013.November.04. 15:43:01 »
Quote from: lgb
Na ebbe pont beleutkoztem. Mint "gyakorlott" (Z80-hoz kepest legalabbis!) 65xx programozo, hirtelen gondolkodoba is estem a minap, amikor az kellett, hogy egy egy memoriaban tarolt tablazatbol egy register altal (amugy egy byte-ba belefer, sot 128 byte-ba is ...) megadott elemet toltsek be. Ez 65xx-n az indexelt cimzes mellett igen egyszeru, Z80-nal viszont eleg kenyelmetlen es lassu, mert csak ugy lehet megoldani, hogy pl 16 bites osszeadassal hozzaadom a tablazat kezdocimet es akkor ugy kiolvasom. Ennel tenyleg nincs jobb/gyorsabb megoldas? :(
A leggyorsabb az, amit már említettem: 256 byte-os határra kell igazítani a táblázatot, és akkor egyszerűen egy regiszterpár alsó regiszterébe kell tölteni az indexet, a felsőbe pedig a táblázat kezdőcímének a felső byte-ját. Kisebb táblázatokat elég a méretüknek megfelelően igazítani, a lényeg, hogy elkerülhető legyen a 16 bites aritmetika, azaz ne keresztezzenek 256 byte-os határt.

Offline lgb

  • EP addict
  • *
  • Posts: 3563
  • Country: hu
  • æðsta yfirmaður
    • http://lgb.hu/
Re: Assembly programozás
« Reply #659 on: 2013.November.04. 15:52:16 »
Quote from: IstvanV
A leggyorsabb az, amit már említettem: 256 byte-os határra kell igazítani a táblázatot, és akkor egyszerűen egy regiszterpár alsó regiszterébe kell tölteni az indexet, a felsőbe pedig a táblázat kezdőcímének a felső byte-ját. Kisebb táblázatokat elég a méretüknek megfelelően igazítani, a lényeg, hogy elkerülhető legyen a 16 bites aritmetika, azaz ne keresztezzenek 256 byte-os határt.

Ok, kossz. Ja es elobb az "1 byte-ba is belefer, sot 128 byte-ba is" az kisse fura fogalmazas volt tolem, termeszetesen ugy ertettem, hogy az index belefer 1 byte-ba, sot 7 bitbe is, azaz a tablazat merete 128 byte alatti. :)