Enterprise Forever

:HUN => Konvertálás => CPC-ről => Topic started by: IstvanV on 2010.May.06. 18:46:11

Title: Cybernoid
Post by: IstvanV on 2010.May.06. 18:46:11
A pixel adatokat még konvertálni kell, hogy a színek megfelelőek legyenek:
  [attachurl=#]
  [attachurl=#]
  [attachurl=#]
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.06. 21:44:27
A pixel adatokat még konvertálni kell, hogy a színek megfelelõek legyenek:
Izgalmas! Jól hallom, hogy a hang sztereó?
Title: Re: Cybernoid
Post by: Lacika on 2010.May.06. 22:24:15
Izgalmas! Jól hallom, hogy a hang sztereó?

Hoppá, ez fel sem tűnt!
Tényleg az!
Title: Re: Cybernoid
Post by: Lacika on 2010.May.06. 22:25:00
Pontszámtábla mentés lesz?  :oops:
Title: Re: Cybernoid
Post by: szipucsu on 2010.May.06. 22:36:07
A pixel adatokat még konvertálni kell, hogy a színek megfelelõek legyenek:
Így is már szép színes!  :smt041

Azt hiszem, ezzel rekord dõlt meg. :D Egy hónapon belül két konverzió: Exolon és Cybernoid. Ha anno az A-Stuidó és a többiek is így csinálták volna, nyereségesebb is lett volna az egész és több jó program lett volna akkor EP-ra.
Title: Re: Cybernoid
Post by: Lacika on 2010.May.06. 22:41:56
Így is már szép színes!  :smt041

Kicsit talán túl színes...  :ds_icon_cheesygrin:
Valami techno-s kék tónusú színkompozíciót képzelnék el. Nem láttam CPC-n, hogy néz ki.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.06. 22:57:18
Valami techno-s kék tónusú színkompozíciót képzelnék el. Nem láttam CPC-n, hogy néz ki.

ep128emu snapshot (a monitorban 'G 200'-t kell beírni, hogy elinduljon):
  [attachurl=#]

Pontszámtábla mentés lesz?  :oops:

Mintha eredetileg nem lett volna - de azért megpróbálhatom beépíteni, ha a fontosabb teendők (pl. színek javítása) már kész vannak. Valószínűleg csalásokat is érdemes lesz megvalósítani, mert a játék elég nehéznek tűnik :)
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.07. 01:12:11
Még nincs kész, de valamivel már jobban néz ki:
  [attachurl=#]
  [attachurl=#]
  [attachurl=#]

Izgalmas! Jól hallom, hogy a hang sztereó?

Ezt az AY emulációm eddig is tudta, csak az Exolon-ban és Stunt Car Racer-ben nem engedélyeztem. A forráskódjukban azonban egyszerűen be lehet kapcsolni a sztereó hangot, csak azok a játékok nem szólnak úgy igazán jobban.
Title: Re: Cybernoid
Post by: geco on 2010.May.07. 10:08:24
Nagyon szép, a hangja is tuti :), és már alig lehet átalakítandó pixel is, kb az 5. képernyőig jutottam el, addig két átalakítandó dologgal találkoztam.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.07. 13:57:00
Pontszámtábla mentés lesz?  :oops:

Már kész van az is :) Csak akkor engedélyezett, ha van EXDOS, és nincs bekapcsolva semmilyen csalás. Ezek egyébként a következők lehetnek:
  M: örökélet
  ,: 9 élet 4 helyett
 .: sebezhetetlenség

A Cybernoid 2 nagyon hasonló, ezért az átírása remélhetőleg könnyű lesz.
Title: Re: Cybernoid
Post by: szipucsu on 2010.May.07. 14:27:31
Még nincs kész, de valamivel már jobban néz ki:
Esetleg még olyat lehetne, hogy játék közben csak a zenét ki lehessen kapcsolni és csak hangeffektek lennének?
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.07. 14:31:23
Nagyon szép, a hangja is tuti :), és már alig lehet átalakítandó pixel is, kb az 5. képernyőig jutottam el, addig két átalakítandó dologgal találkoztam.

Csalással már sikerült minden pályára eljutni, így remélhetőleg a pixel kereső script megtalált mindent. Igaz, úgy látszik, a pixel adatok egy nagy, összefüggő területen vannak, és talán a megmaradt "lyukak" helyén is olyan grafika (vagy karakter) lehet, ami a játékban valamiért nem fordult elő (vagy nem találtam meg minden rajzoló rutint ? :oops:).
Title: Re: Cybernoid
Post by: Lacika on 2010.May.07. 15:44:21
Szépen néz ki!
A játék még nehezebb, mint Spectrum-on, egy két cheat jól fog jönni  :ds_icon_cheesygrin:
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.07. 23:36:00
Ez elvileg már teljes verzió (persze a hibákat nem lehet kizárni :oops:):
  [attachurl=#]
  [attachurl=#]

Csalás (lásd fent), pontszámtábla töltés/mentés (magnós gépeken vagy csalással nem :)), és remélhetőleg már minden pixel konvertálva.
Title: Re: Cybernoid
Post by: Lacika on 2010.May.08. 09:06:47
Csalás (lásd fent), pontszámtábla töltés/mentés (magnós gépeken vagy csalással nem :)), és remélhetőleg már minden pixel konvertálva.

Ahogy végigrobogtam sérthetetlenséggel a színek mindenhol szépek voltak, nem láttam "kirívó" részletet.
Várjuk a második rész!  :oops: Az Spectrumon könnyebb mint az első rész...
Title: Re: Cybernoid
Post by: szipucsu on 2010.May.08. 11:18:44
Ez elvileg már teljes verzió (persze a hibákat nem lehet kizárni :oops:):
Nekem kb. 5. próbálkozásra jelent meg a címképernyõ és indult el a játék. A legtöbbször indulás helyett lefagyott. :(
EXOS 2.3, BASIC 2.1, Iview és EPfileio van a szegmenseken, ha esetleg számít.

Egyébként jó a játék!

Title: Re: Cybernoid
Post by: szipucsu on 2010.May.08. 11:22:39
Még azt lenne jó megcsinálni, hogy a pontszámtábla-mentéses játékoknál ne csak a lemezre/file-ba mentsen az emulátor, hanem töltse is fel valahova az elért eredményt és akkor itt valahol meg lehetne tekinteni, ki mennyi pontot gyûjtött össze ezekben a játékokban. :D
Ehhez, gondolom, itt a szerveren is kéne valami cucc, hogy ne a kimentett pontszámtábla kerüljön fel, hanem az elért eredményeket még külön rendezze sorba.

UI: Egy apró hiányosságot észrevettem: amikor pajzsot használunk, nem villog a figura a sérthetetlenség idejére. De lehet, ez a CPC-s verzióban így van, csak a spectrumos verzióban villog.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.08. 11:56:54
Nekem kb. 5. próbálkozásra jelent meg a címképernyõ és indult el a játék. A legtöbbször indulás helyett lefagyott. :(

Ez nem biztos, hogy a program hibája. Valamiért az EXOS 0 (reset) hívás néha lefagy. Ez összefügghet azzal, hogy a vissztéréskor engedélyezett lehet a megszakítás, pedig az EXOS leírás alapján mindig tiltottnak kellene lennie. A hibás működés nem fordul elő a C=40h hívásnál (memória felszabadítása), tehát az valószínűleg nem is fagy le, véletlenszerűen fordul elő C=10h esetén (csatornák bezárása, eszközök újrainicializálása), és többnyire engedélyezett a megszakítás C=20h (csatornák bezárása, eszközök újrainicializálása, periférialánc újraépítése) után. Ami egyben azt is jelenti, hogy az 5-ös fejlécű programok indításakor az automatikus C=20h-s reset miatt engedélyezett a megszakítás, pedig a veremmutató érvénytelen (tehát a legjobb, ha a program azonnal DI vagy LD SP, nnnn utasítással kezdődik).
Így lehet, hogy olyankor történik megszakítás az EXOS reset közben vagy után, amikor nem lenne szabad (pl. nincs érvényes veremmutató). A lefagyás gyakorisága függhet az időzítéstől, például hogy egy 5-ös fejécű program mennyi idő alatt töltődik be.

Érdemes kipróbálni ezt a rövid programot, amely egy idő után lefagy:
Code: ZiLOG Z80 Assembler
  1. l1:     di
  2.         ld sp, 100h
  3.         ld c, 20h
  4.         exos 0
  5.         jr l1

Először azt hittem, hogy a hibát az okozhatja, hogy egyes bővítő eszközök (pl. DISK: és FILE:) EXOS hívásokat végeznek az inicializálás közben, ami engedélyezi a megszakítást, de a hiba valójában akkor is előfordul, ha az EXOS 2.1-en kívül semmilyen ROM nincs a rendszerben (de ha van EXDOS, akkor mintha gyakoribb lenne a lefagyás). Ez tehát EXOS bug is lehet, amit esetleg javítani is lehetne (EXOS 2.32 :)) ?


UI: Egy apró hiányosságot észrevettem: amikor pajzsot használunk, nem villog a figura a sérthetetlenség idejére. De lehet, ez a CPC-s verzióban így van, csak a spectrumos verzióban villog.

Nem villog CPC-n se (ezt a fenti snapshot file-al egyszerűen meg is nézheted), tehát nem lehet pontosan tudni, mikor fogy el :)
UI.: az FTP-re még régebben feltöltöttem egy "cpc_games.7z" file-t, amelyben 870 játék található "ep128emu kompatibilis" .cdt formátumban, köztük például a Cybernoid 1-2 is.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.08. 14:59:52
Valószínűleg nem érdekel senkit, de itt a betöltő forráskódja is:
  [attachurl=#]
Ez tartalmaz EXOS kompatibilis memóriakezelést, LPT generálást (egyszerű táblázat alapján több függőleges terület is lehet a képen, külön video móddal, palettával, margókkal, és CRTC sor és memória kezdőcímmel), billentyűzet emulációt (lekérdezhető csak egy sor, vagy mind a 10 egyszerre egy táblázatba), és AY emulációt (szintén lehetséges a regisztereket egyenként vagy táblázatból írni).

Segédprogram 16 színű paletta konvertálásához:
  [attachurl=#]
  [attachurl=#]
Optimalizált palettát és BIAS-t keres (de az utóbbi lehet a felhasználó által megadott fix érték is), átrendezi a palettaszínek sorrendjét (azonban megadhatók "fix" színek, amelyeknek a pozíciója a palettán nem változhat), és pixel konvertáló táblázatot ír bináris, assembler, vagy Lua formátumban.
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.08. 15:02:55
Valószínûleg nem érdekel senkit
Dehogynem!
Title: Re: Cybernoid
Post by: szipucsu on 2010.May.08. 16:38:40
A CPC-s Cybernoid mikor menti el a pontszámtáblát? Emulátorban ez a SHIFT+F11-féle resetre történik? Sima F11-es resetre nem mentette el.
Mûködik EPfileio-val is a pontszámtábla-mentés?
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.08. 16:43:48
A CPC-s Cybernoid mikor menti el a pontszámtáblát? Emulátorban ez a SHIFT+F11-féle resetre történik? Sima F11-es resetre nem mentette el.
Mûködik EPfileio-val is a pontszámtábla-mentés?

Az eredeti CPC-s verzió nem menti. Ha az EP-s átiratot értetted, akkor normál resetnél (F11) van csak mentés, mert egyébként a hidegindítás miatt erre a programnak nincs esélye :) Ha mégsem menti, az vagy azért van, mert nincs EXDOS a rendszerben, vagy csalást választottál az indításnál.
FileIO-val is működik, ha van EXDOS, de a FILE: az alapértelmezett eszköz.
Title: Re: Cybernoid
Post by: Lacika on 2010.May.08. 17:26:33
Valószínűleg nem érdekel senkit, de itt a betöltő forráskódja is:

Sajnos érdemben nem tudok hozzászólni, de a letölthető file-ba beraktam.
Title: Re: Cybernoid
Post by: szipucsu on 2010.May.08. 20:18:29
FileIO-val is mûködik, ha van EXDOS, de a FILE: az alapértelmezett eszköz.
Akkor megvan, mi volt a bibi, emulátorban nem használok EXDOS-t.

Bonyolult lenne megcsinálni, hogy az emulátor az elmentett pontszámtáblát fel is töltse valahova? A szerveren pedig olyan alkalmazás kéne, ami a feltöltött pontszámtáblákból összeállít egyetlen pontszámtáblát az elért legjobb eredmények alapján. Bár lehet, nem sokan élnének a lehetõséggel, de esetleg motiválná a felhasználókat az emulátor és a játékok használatára. :D
Title: Re: Cybernoid
Post by: Lacika on 2010.May.08. 20:29:48
Bonyolult lenne megcsinálni, hogy az emulátor az elmentett pontszámtáblát fel is töltse valahova? A szerveren pedig olyan alkalmazás kéne, ami a feltöltött pontszámtáblákból összeállít egyetlen pontszámtáblát az elért legjobb eredmények alapján. Bár lehet, nem sokan élnének a lehetõséggel, de esetleg motiválná a felhasználókat az emulátor és a játékok használatára. :D

Nemcsak bonyolult lenne szerintem de felesleges is, a másodpercenkénti snapshot mentések világában.
Title: Re: Cybernoid
Post by: geco on 2010.May.09. 09:15:08
Valószínűleg nem érdekel senkit, de itt a betöltő forráskódja is:

Segédprogram 16 színű paletta konvertálásához:
Optimalizált palettát és BIAS-t keres (de az utóbbi lehet a felhasználó által megadott fix érték is), átrendezi a palettaszínek sorrendjét (azonban megadhatók "fix" színek, amelyeknek a pozíciója a palettán nem változhat), és pixel konvertáló táblázatot ír bináris, assembler, vagy Lua formátumban.
Dehogynem, le is töltöttem :D
Paletta-, és BIASkereső meg király, a megfelelő paletta megtalálásával eltöltöttem legalább 2 órát mindig, hacsak nem 4színű volt a program :D (bár a Head Over Heelsnek a betöltőképe 16 színű volt)
Title: Re: Cybernoid
Post by: geco on 2010.May.09. 09:24:25
EP64-esíteni nem lehet a Cybernoidot? Igaz nagy meló,lehet nem éri meg, ha nincs elég szabad hely az LPT-nek, a Wec Le Mans-szal is szívtam eleget, mire egy olyan forráskódot sikerült generálni a játék disassembly listájából, ami szabadon változtatható, és így a grafika EP-síthető (a képernyő egymás követő sorai a memóriában is egymás mögött vannak), az LPT meg 12-ére esik össze.
Az N&S-nél is ezzel szívok, ezért pihentetem egy kicsit, ott viszont muszáj, mert egyébként nem menne, csak bővítős gépen. :(
Title: Re: Cybernoid
Post by: MrPrise on 2010.May.09. 13:32:22
Bonyolult lenne megcsinálni, hogy az emulátor az elmentett pontszámtáblát fel is töltse valahova? A szerveren pedig olyan alkalmazás kéne, ami a feltöltött pontszámtáblákból összeállít egyetlen pontszámtáblát az elért legjobb eredmények alapján. Bár lehet, nem sokan élnének a lehetõséggel, de esetleg motiválná a felhasználókat az emulátor és a játékok használatára. :D
Ehhez az kellene hogy az emulátor tudja azonosítani a játékost. Azaz a fórumos felhasználónevet és jelszót be kellene kérnie.
A csalást nem tudom hogy lehetne kiküszöbölni. Esetleg csak úgy fogadnánk el a pontszámot ha az illető a demót is feltölti (vagy az emulátor a pontszámmal együtt ezt is feltöltené) amivel felállította a rekordot. Így ellenőrizhető lenne a hitelessége.
Az ellenőrzést szavazással lehetne talán a legegyszerűbben megoldani, feltételezve, hogy elég sokan meg akarják nézni a rekordkísérletet. Bárki aki letölti a demót, szavazhat, hogy el lehet-e fogadni a pontszámot és mondjuk 5 v 10 szavazat után a pontszám el lesz fogadva és látható lesz az oldalon. Ebből következik, hogy feltölteni csak olyan pontszámot lehetne ami nagyobb mint az aktuális rekord az adott játékban.
Na persze a játékot is tudni kell azonosítani. Ehhez majd kellene a PrgDb amit csinálok...  :oops:
Title: Re: Cybernoid
Post by: szipucsu on 2010.May.09. 13:43:01
Szerintem egyszerûbb lenne a játékos azonosítása helyett, ha azt a nevet töltené fel az emulátor, amit a játékos beír. Ha pl. valaki nem a saját nevét írja be, az vessen magára.
Csalásnál amúgy sincs pontszámtábla mentés, ezt esetleg az tudná kicselezni, aki eligazodik az emulátor forráskódjában és tetszõleges értéket és nevet tud így feltöltetni vele.
Szóval arra gondolok, hogy magát a pontszámtáblát az emulátor töltse fel (olyan játékban, ahol van pontszámtábla mentés), és a szerven egy program összerendezi az egészet úgy, hogy a már feltöltött pontszámokhoz képest az újabb pontszám is a megfelelõ helyére kerüljön. Persze a legideálisabb az lenne, ha a játék betöltése után is eleve a netrõl kéri le az emulátor a pontszámtáblát, de ez azért már túlzás lenne.

Tehát az emulátorba kéne beépíteni valamit, ami beazonosítja azokat a játékokat, melyeknél van ponttábla mentés, és a pontszámtáblákat a megfelelõ helyre feltölti, a szerveren pedig egy program kéne, ami a sok ponttáblából összegyúr egyetlen egyet. Ez lenne a lényege.

Aztán lehet, hogy ez már nagyon elszállt dolog. :D
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.09. 14:00:38
Várjuk a második rész!

:mrgreen:

[attachurl=#]
[attachurl=#]
[attachurl=#]

Összehasonlításképpen az eredeti CPC-s verzió:

[attachurl=#]

És néhány változat különböző TONE_AND_NOISE_MODE AY emuláció paraméterrel - melyikkel a legjobb a hang (a fenti tömörített "normál" verziót is beleértve) ?

[attachurl=#]
[attachurl=#]
[attachurl=#]
[attachurl=#]
[attachurl=#]
Title: Re: Cybernoid
Post by: nyuzga on 2010.May.09. 14:42:08
Jó lett. A csikózós betöltő, különösen tetszik :lol:
Title: Re: Cybernoid
Post by: Lacika on 2010.May.09. 15:29:22
És néhány változat különböző TONE_AND_NOISE_MODE AY emuláció paraméterrel - melyikkel a legjobb a hang (a fenti tömörített "normál" verziót is beleértve) ?

Határozottan a 220-as a legjobb! Betömöríted azt (és a forráskódját is felrakod)?
Title: Re: Cybernoid
Post by: geco on 2010.May.09. 16:16:24
Szerintem a betömörítettnek a legjobbak a hangjai, kivéve a robbanást, az a 220-asban a legjobb.
A CPC-s verziót meg most töltöm :D
Title: Re: Cybernoid
Post by: geco on 2010.May.09. 16:31:44
Megnéztem :D, tartom magam az előbbiekhez, a tömörített verziónak a hangja hasonlít legjobban a CPC-shez, helyenként még jobb is, a 220-asban a robbanások nagyon jók. Valamilyen torzítást használsz?
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.09. 16:45:05
Megnéztem :D, tartom magam az előbbiekhez, a tömörített verziónak a hangja hasonlít legjobban a CPC-shez, helyenként még jobb is, a 220-asban a robbanások nagyon jók. Valamilyen torzítást használsz?

Az egyes verziók között az az eltérés, hogy mi történik akkor, ha egy csatornán egyszerre van négyszögjel és zaj (ezt a program nem tudja emulálni, tehát más effektussal helyettesíti):
  - az elsőben csak a zajgenerátor hallható (az 5 bites AY frekvencia EP-re konvertálva, 17 bites polinom számlálóval)
  - a cyber220.com a négyszögjel frekvenciáját használja, de 5 bites polinom számlálóval torzítva (ugyanezt használtam az Exolon-ban, és Attus is)
  - a cyber230.com ugyanez, csak 17 bites polinom számlálóval 5 bites helyett (ami a gyakorlatban torzítás helyett "normál" zajt jelent)
  - a cyber280.com szintén négyszögjel frekvenciát használ, de polinom számláló helyett gyűrűmodulációval torzítva (ezek alapján talán kitalálható a file nevek jelentése :))

Egyébként egyszerűen lehet kísérletezni: a forráskód elején át kell írni a "COMPRESSED_PRG"-t 1-ről 0-ra (így a csomagolás elkerülhető), illetve a "TONE_AND_NOISE_MODE"-t (ez a 1277. sorban van, de egyszerű kereséssel is meg lehet találni) beállítani:
  - 0: négyszögjel frekvencia torzítás nélkül (azaz csak négyszögjel)
  - 1: zaj frekvencia 17 bites torzítással (azaz csak zaj)
  - >=16: négyszögjel frekvencia, az A1h/A3h/A5h port felső négy bitje a megadott érték lesz (pl. 80h = gyűrűmoduláció); érdemes megjegyezni, hogy az A6h port 10h-ra van állítva, ezért 4, 5, vagy 17 bites polinom számlálót lehet választani
A cybnoid2.s sjasm-el fordítható.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.09. 17:07:42
Határozottan a 220-as a legjobb! Betömöríted azt (és a forráskódját is felrakod)?

[attachurl=#]
[attachurl=#]

A korábbi 655 byte-os CYBNOID2.COM file használható ezzel is, mert az csak egy DL2 betöltő. A forráskódban csak a már említett TONE_AND_NOISE_MODE sor változott.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.09. 18:07:07
Paletta-, és BIASkereső meg király, a megfelelő paletta megtalálásával eltöltöttem legalább 2 órát mindig, hacsak nem 4színű volt a program :D (bár a Head Over Heelsnek a betöltőképe 16 színű volt)

Példa a használatára: Cybernoid 2 konvertálása:
  [attachurl=#]
Ez a CPC snapshot közvetlenül a játék betöltődése után készült, amint éppen a 0100h címre ugrana, ahol a főprogram kezdődik, de itt megállítottam egy végtelen ciklusban (tehát G 100 monitor parancsra elindulna a játék). A paletta a 3A1h-3B0h területen található:

m 3a1 3b0
>03A1  14 0B 1C 13 15 16 0D 0A  :........
>03A9  0E 1D 0C 00 19 12 17 07  :........


A játék futása közben így is kiíratható:

io 20 2f
O 0020  14 0B 1C 13 15 16 0D 0A
O 0028  0E 1D 0C 00 19 12 17 07


A paletta konvertáló program futtatása:

cpccolor.exe =0x14 0x0B:10 0x1C 0x13 0x15 0x16 0x0D 0x0A 0x0E 0x1D:0.1 0x0C 0x00
             0x19 0x12 0x17 0x07 -pixelmapfmt 2 -pixelmap pixeltable.lua
CPC palette:
   0: 20 (Black         ): mapped to  0 (0x00), err = 0.0000
   1: 11 (Bright White  ): mapped to  1 (0xFF), err = 0.0000
   2: 28 (Red           ): mapped to  2 (0x01), err = 0.0497
   3: 19 (Bright Cyan   ): mapped to 14 (0x96), err = 0.1538
   4: 21 (Bright Blue   ): mapped to  4 (0x24), err = 0.0000
   5: 22 (Green         ): mapped to  8 (0x90), err = 0.0597
   6: 13 (Bright Magenta): mapped to  6 (0x6D), err = 0.0000
   7: 10 (Bright Yellow ): mapped to  7 (0xDB), err = 0.0000
   8: 14 (Orange        ): mapped to  3 (0x6B), err = 0.1637
   9: 29 (Mauve         ): mapped to  6 (0x6D), err = 0.3494
  10: 12 (Bright Red    ): mapped to  5 (0x49), err = 0.0000
  11:  0 (White         ): mapped to 13 (0x95), err = 0.1047
  12: 25 (Pastel Green  ): mapped to 15 (0x97), err = 0.0787
  13: 18 (Bright Green  ): mapped to 10 (0x92), err = 0.0000
  14: 23 (Sky Blue      ): mapped to 12 (0x94), err = 0.1639
  15:  7 (Pink          ): mapped to  3 (0x6B), err = 0.0981
Enterprise palette: 0x00, 0xFF, 0x01, 0x6B, 0x24, 0x49, 0x6D, 0xDB
Enterprise bias:    18 (0 to 31) / 0x90 (0 to 0xF8)


Az első színnél a '=' azt jelenti, hogy ez a szín nem helyezhető át a palettán (tehát a 00h byte-ok nem változnak a konvertálás után), a ':' utáni számmal pedig az adott szín fontosságát lehet állítani (alapértelmezés szerint mind 1.0), azaz itt a 10.0 érték miatt fontos, hogy a "Bright White" szín pontos legyen (mert egyébként valamilyen világos szürkészöld szín lenne), a - játékban gyakorlatilag sehol nem használt - "Mauve" szín pedig nem lényeges, ezért az 0.1-re van állítva (látható is, hogy annál lett a legnagyobb a hiba). A '-pixelmapfmt 2' Lua táblázat formátumot választ, a '-pixelmap' pedig a kimeneti file nevét. További használható paraméterek is vannak, ezeket a 'cpccolor.exe' paraméterek nélküli futtatásával lehet listázni.

A konvertálás például az alábbi scripttel végezhető:

Code: Lua
  1. dofile("/tmp/pixeltable.lua")
  2.  
  3. function pixelConv(a)
  4.   writeMemoryRaw(a, pixelConvTable[readMemoryRaw(a) + 1])
  5. end
  6.  
  7. pixelConv(0x13B2)
  8. pixelConv(0x13B7)
  9. for i = 0x5AA6, 0xAE95 do
  10.   pixelConv(i)
  11. end

Itt a dofile()-nál természetesen a táblázat file tényleges helyét kell megadni (Windowson az esetleges \ karakterek helyett \\-t írva), de a táblázat akár egyszerűen be is másolható a dofile() helyére. Amint látható, pixel adatok a 13B2h, 13B7h (ezek a kódban vannak és a játékos "lézer" lövéseinek a pixelei) címeken, illetve 5AA6h-AE95h területen találhatók. Ezeknek a megtalálása fontos része az átírásnak (a Spectrumos attribútumokhoz hasonlóan), itt most éppen elég egyszerű volt.

A működőképes átirathoz már csak ezeket a változtatásokat kellett elvégezni:

Code: Diff
  1. @@ -26,25 +26,46 @@
  2.  .   0031  D9           EXX
  3.  .   0032  21 2B 00     LD    HL, 002B
  4.  .   0035  71           LD    (HL), C
  5.  .   0036  18 08        JR    0040
  6. -.   0038  C3 39 B9     JP    B939
  7. -.   003B  C9           RET
  8. +.   0038  00           NOP
  9. +.   0039  00           NOP
  10. +.   003A  00           NOP
  11. +.   003B  00           NOP
  12.  .   003C  00           NOP
  13.  .   003D  00           NOP
  14.  .   003E  00           NOP
  15.  .   003F  00           NOP
  16. -.   0040  CA 22 F3     JP    Z, F322
  17. -.   0043  21 00 C0     LD    HL, C000
  18. -.   0046  11 00 A0     LD    DE, A000
  19. -.   0049  01 FF 1F     LD    BC, 1FFF
  20. -.   004C  ED B0        LDIR
  21. -.   004E  21 00 C0     LD    HL, C000
  22. -.   0051  11 01 C0     LD    DE, C001
  23. -.   0054  01 FF 3F     LD    BC, 3FFF
  24. -.   0057  36 00        LD    (HL), 00
  25. -.   0059  ED B0        LDIR
  26. -.   005B  C3 5B 00     JP    005B
  27. +.   0040  00           NOP
  28. +.   0041  00           NOP
  29. +.   0042  00           NOP
  30. +.   0043  00           NOP
  31. +.   0044  00           NOP
  32. +.   0045  00           NOP
  33. +.   0046  00           NOP
  34. +.   0047  00           NOP
  35. +.   0048  00           NOP
  36. +.   0049  00           NOP
  37. +.   004A  00           NOP
  38. +.   004B  00           NOP
  39. +.   004C  00           NOP
  40. +.   004D  00           NOP
  41. +.   004E  00           NOP
  42. +.   004F  00           NOP
  43. +.   0050  00           NOP
  44. +.   0051  00           NOP
  45. +.   0052  00           NOP
  46. +.   0053  00           NOP
  47. +.   0054  00           NOP
  48. +.   0055  00           NOP
  49. +.   0056  00           NOP
  50. +.   0057  00           NOP
  51. +.   0058  00           NOP
  52. +.   0059  00           NOP
  53. +.   005A  00           NOP
  54. +.   005B  00           NOP
  55. +.   005C  00           NOP
  56. +.   005D  00           NOP
  57.  .   005E  00           NOP
  58.  .   005F  1A           LD    A, (DE)
  59.  .   0060  06 0A        LD    B, 0A
  60.  .   0062  00           NOP
  61. @@ -371,14 +392,17 @@
  62.  .   029C  85           ADD   A, L
  63.  .   029D  6F           LD    L, A
  64.  .   029E  F1           POP   AF
  65.  .   029F  C9           RET
  66. -.   02A0  C5           PUSH  BC
  67. -.   02A1  D5           PUSH  DE
  68. -.   02A2  E5           PUSH  HL
  69. -.   02A3  21 00 00     LD    HL, 0000
  70. -.   02A6  11 00 00     LD    DE, 0000
  71. -.   02A9  ED B0        LDIR
  72. +.   02A0  F5           PUSH  AF
  73. +.   02A1  C5           PUSH  BC
  74. +.   02A2  0B           DEC   BC
  75. +.   02A3  79           LD    A, C
  76. +.   02A4  B0           OR    B
  77. +.   02A5  C2 A2 02     JP    NZ, 02A2
  78. +.   02A8  C1           POP   BC
  79. +.   02A9  F1           POP   AF
  80. +.   02AA  C9           RET
  81.  .   02AB  E1           POP   HL
  82.  .   02AC  D1           POP   DE
  83.  .   02AD  C1           POP   BC
  84.  .   02AE  C9           RET
  85. @@ -477,50 +501,102 @@
  86.  .   033E  D8           RET   C
  87.  .   033F  3C           INC   A
  88.  .   0340  C9           RET
  89.  .   0341  F3           DI  
  90. -.   0342  01 0D BC     LD    BC, BC0D
  91. -.   0345  ED 49        OUT   (C), C
  92. -.   0347  01 00 BD     LD    BC, BD00
  93. -.   034A  ED 49        OUT   (C), C
  94. -.   034C  01 0C BC     LD    BC, BC0C
  95. -.   034F  ED 49        OUT   (C), C
  96. -.   0351  01 30 BD     LD    BC, BD30
  97. -.   0354  ED 49        OUT   (C), C
  98. -.   0356  01 01 BC     LD    BC, BC01
  99. -.   0359  ED 49        OUT   (C), C
  100. -.   035B  01 20 BD     LD    BC, BD20
  101. -.   035E  ED 49        OUT   (C), C
  102. -.   0360  01 02 BC     LD    BC, BC02
  103. -.   0363  ED 49        OUT   (C), C
  104. -.   0365  01 2B BD     LD    BC, BD2B
  105. -.   0368  ED 49        OUT   (C), C
  106. -.   036A  01 06 BC     LD    BC, BC06
  107. -.   036D  ED 49        OUT   (C), C
  108. -.   036F  01 18 BD     LD    BC, BD18
  109. -.   0372  ED 49        OUT   (C), C
  110. -.   0374  01 07 BC     LD    BC, BC07
  111. -.   0377  ED 49        OUT   (C), C
  112. -.   0379  01 1D BD     LD    BC, BD1D
  113. -.   037C  ED 49        OUT   (C), C
  114. -.   037E  06 7F        LD    B, 7F
  115. -.   0380  0E 10        LD    C, 10
  116. -.   0382  ED 49        OUT   (C), C
  117. -.   0384  0E 54        LD    C, 54
  118. -.   0386  ED 49        OUT   (C), C
  119. -.   0388  21 A1 03     LD    HL, 03A1
  120. -.   038B  0E 00        LD    C, 00
  121. -.   038D  16 10        LD    D, 10
  122. -.   038F  ED 49        OUT   (C), C
  123. -.   0391  7E           LD    A, (HL)
  124. -.   0392  23           INC   HL
  125. -.   0393  F6 40        OR    40
  126. -.   0395  ED 79        OUT   (C), A
  127. -.   0397  0C           INC   C
  128. -.   0398  15           DEC   D
  129. -.   0399  20 F4        JR    NZ, 038F
  130. -.   039B  01 8C 7F     LD    BC, 7F8C
  131. -.   039E  ED 49        OUT   (C), C
  132. +.   0342  C9           RET
  133. +.   0343  C9           RET
  134. +.   0344  C9           RET
  135. +.   0345  C9           RET
  136. +.   0346  C9           RET
  137. +.   0347  C9           RET
  138. +.   0348  C9           RET
  139. +.   0349  C9           RET
  140. +.   034A  C9           RET
  141. +.   034B  C9           RET
  142. +.   034C  C9           RET
  143. +.   034D  C9           RET
  144. +.   034E  C9           RET
  145. +.   034F  C9           RET
  146. +.   0350  C9           RET
  147. +.   0351  C9           RET
  148. +.   0352  C9           RET
  149. +.   0353  C9           RET
  150. +.   0354  C9           RET
  151. +.   0355  C9           RET
  152. +.   0356  C9           RET
  153. +.   0357  C9           RET
  154. +.   0358  C9           RET
  155. +.   0359  C9           RET
  156. +.   035A  C9           RET
  157. +.   035B  C9           RET
  158. +.   035C  C9           RET
  159. +.   035D  C9           RET
  160. +.   035E  C9           RET
  161. +.   035F  C9           RET
  162. +.   0360  C9           RET
  163. +.   0361  C9           RET
  164. +.   0362  C9           RET
  165. +.   0363  C9           RET
  166. +.   0364  C9           RET
  167. +.   0365  C9           RET
  168. +.   0366  C9           RET
  169. +.   0367  C9           RET
  170. +.   0368  C9           RET
  171. +.   0369  C9           RET
  172. +.   036A  C9           RET
  173. +.   036B  C9           RET
  174. +.   036C  C9           RET
  175. +.   036D  C9           RET
  176. +.   036E  C9           RET
  177. +.   036F  C9           RET
  178. +.   0370  C9           RET
  179. +.   0371  C9           RET
  180. +.   0372  C9           RET
  181. +.   0373  C9           RET
  182. +.   0374  C9           RET
  183. +.   0375  C9           RET
  184. +.   0376  C9           RET
  185. +.   0377  C9           RET
  186. +.   0378  C9           RET
  187. +.   0379  C9           RET
  188. +.   037A  C9           RET
  189. +.   037B  C9           RET
  190. +.   037C  C9           RET
  191. +.   037D  C9           RET
  192. +.   037E  C9           RET
  193. +.   037F  C9           RET
  194. +.   0380  C9           RET
  195. +.   0381  C9           RET
  196. +.   0382  C9           RET
  197. +.   0383  C9           RET
  198. +.   0384  C9           RET
  199. +.   0385  C9           RET
  200. +.   0386  C9           RET
  201. +.   0387  C9           RET
  202. +.   0388  C9           RET
  203. +.   0389  C9           RET
  204. +.   038A  C9           RET
  205. +.   038B  C9           RET
  206. +.   038C  C9           RET
  207. +.   038D  C9           RET
  208. +.   038E  C9           RET
  209. +.   038F  C9           RET
  210. +.   0390  C9           RET
  211. +.   0391  C9           RET
  212. +.   0392  C9           RET
  213. +.   0393  C9           RET
  214. +.   0394  C9           RET
  215. +.   0395  C9           RET
  216. +.   0396  C9           RET
  217. +.   0397  C9           RET
  218. +.   0398  C9           RET
  219. +.   0399  C9           RET
  220. +.   039A  C9           RET
  221. +.   039B  C9           RET
  222. +.   039C  C9           RET
  223. +.   039D  C9           RET
  224. +.   039E  C9           RET
  225. +.   039F  C9           RET
  226.  .   03A0  C9           RET
  227.  .   03A1  14           INC   D
  228.  .   03A2  0B           DEC   BC
  229.  .   03A3  1C           INC   E
  230. @@ -668,39 +744,59 @@
  231.  .   0457  FF           RST   38
  232.  .   0458  FF           RST   38
  233.  .   0459  FF           RST   38
  234.  .   045A  FF           RST   38
  235. -.   045B  21 51 04     LD    HL, 0451
  236. -.   045E  01 0E F4     LD    BC, F40E
  237. -.   0461  ED 49        OUT   (C), C
  238. -.   0463  06 F6        LD    B, F6
  239. -.   0465  ED 78        IN    A, (C)
  240. -.   0467  E6 30        AND   30
  241. -.   0469  4F           LD    C, A
  242. -.   046A  F6 C0        OR    C0
  243. -.   046C  ED 79        OUT   (C), A
  244. -.   046E  ED 49        OUT   (C), C
  245. -.   0470  04           INC   B
  246. -.   0471  3E 92        LD    A, 92
  247. -.   0473  ED 79        OUT   (C), A
  248. -.   0475  C5           PUSH  BC
  249. -.   0476  CB F1        SET   6, C
  250. -.   0478  06 F6        LD    B, F6
  251. -.   047A  ED 49        OUT   (C), C
  252. -.   047C  06 F4        LD    B, F4
  253. -.   047E  ED 78        IN    A, (C)
  254. -.   0480  77           LD    (HL), A
  255. -.   0481  23           INC   HL
  256. -.   0482  0C           INC   C
  257. -.   0483  79           LD    A, C
  258. -.   0484  E6 0F        AND   0F
  259. -.   0486  FE 0A        CP    0A
  260. -.   0488  20 EE        JR    NZ, 0478
  261. -.   048A  C1           POP   BC
  262. -.   048B  3E 82        LD    A, 82
  263. -.   048D  ED 79        OUT   (C), A
  264. -.   048F  05           DEC   B
  265. -.   0490  ED 49        OUT   (C), C
  266. +.   045B  11 51 04     LD    DE, 0451
  267. +.   045E  CD 60 03     CALL  0360
  268. +.   0461  06           DEFB  06
  269. +.   0462  C9           RET
  270. +.   0463  C9           RET
  271. +.   0464  C9           RET
  272. +.   0465  C9           RET
  273. +.   0466  C9           RET
  274. +.   0467  C9           RET
  275. +.   0468  C9           RET
  276. +.   0469  C9           RET
  277. +.   046A  C9           RET
  278. +.   046B  C9           RET
  279. +.   046C  C9           RET
  280. +.   046D  C9           RET
  281. +.   046E  C9           RET
  282. +.   046F  C9           RET
  283. +.   0470  C9           RET
  284. +.   0471  C9           RET
  285. +.   0472  C9           RET
  286. +.   0473  C9           RET
  287. +.   0474  C9           RET
  288. +.   0475  C9           RET
  289. +.   0476  C9           RET
  290. +.   0477  C9           RET
  291. +.   0478  C9           RET
  292. +.   0479  C9           RET
  293. +.   047A  C9           RET
  294. +.   047B  C9           RET
  295. +.   047C  C9           RET
  296. +.   047D  C9           RET
  297. +.   047E  C9           RET
  298. +.   047F  C9           RET
  299. +.   0480  C9           RET
  300. +.   0481  C9           RET
  301. +.   0482  C9           RET
  302. +.   0483  C9           RET
  303. +.   0484  C9           RET
  304. +.   0485  C9           RET
  305. +.   0486  C9           RET
  306. +.   0487  C9           RET
  307. +.   0488  C9           RET
  308. +.   0489  C9           RET
  309. +.   048A  C9           RET
  310. +.   048B  C9           RET
  311. +.   048C  C9           RET
  312. +.   048D  C9           RET
  313. +.   048E  C9           RET
  314. +.   048F  C9           RET
  315. +.   0490  C9           RET
  316. +.   0491  C9           RET
  317.  .   0492  C9           RET
  318.  .   0493  0E 00        LD    C, 00
  319.  .   0495  79           LD    A, C
  320.  .   0496  21 00 C0     LD    HL, C000
  321. @@ -2083,12 +2179,19 @@
  322.  .   0D09  36 00        LD    (HL), 00
  323.  .   0D0B  01 06 00     LD    BC, 0006
  324.  .   0D0E  09           ADD   HL, BC
  325.  .   0D0F  18 B8        JR    0CC9
  326. -.   0D11  3E C3        LD    A, C3
  327. -.   0D13  32 38 00     LD    (0038), A
  328. -.   0D16  21 1D 0D     LD    HL, 0D1D
  329. -.   0D19  22 39 00     LD    (0039), HL
  330. +.   0D11  C9           RET
  331. +.   0D12  C9           RET
  332. +.   0D13  C9           RET
  333. +.   0D14  C9           RET
  334. +.   0D15  C9           RET
  335. +.   0D16  C9           RET
  336. +.   0D17  C9           RET
  337. +.   0D18  C9           RET
  338. +.   0D19  C9           RET
  339. +.   0D1A  C9           RET
  340. +.   0D1B  C9           RET
  341.  .   0D1C  C9           RET
  342.  .   0D1D  F5           PUSH  AF
  343.  .   0D1E  C5           PUSH  BC
  344.  .   0D1F  D5           PUSH  DE
  345. @@ -2101,11 +2204,12 @@
  346.  .   0D28  C5           PUSH  BC
  347.  .   0D29  D5           PUSH  DE
  348.  .   0D2A  E5           PUSH  HL
  349.  .   0D2B  01 00 F5     LD    BC, F500
  350. -.   0D2E  ED 78        IN    A, (C)
  351. -.   0D30  1F           RRA
  352. -.   0D31  D2 3E 0D     JP    NC, 0D3E
  353. +.   0D2E  C3 34 0D     JP    0D34
  354. +.   0D31  00           NOP
  355. +.   0D32  00           NOP
  356. +.   0D33  00           NOP
  357.  .   0D34  21 50 0D     LD    HL, 0D50
  358.  .   0D37  34           INC   (HL)
  359.  .   0D38  CD 8E B1     CALL  B18E
  360.  .   0D3B  CD 5B 04     CALL  045B
  361. @@ -33961,25 +34065,37 @@
  362.  .   B25F  CD 8D B2     CALL  B28D
  363.  .   B262  2A 85 B4     LD    HL, (B485)
  364.  .   B265  22 7B B4     LD    (B47B), HL
  365.  .   B268  CD 33 B4     CALL  B433
  366. -.   B26B  AF           XOR   A
  367. -.   B26C  21 84 B4     LD    HL, B484
  368. -.   B26F  11 0D F4     LD    DE, F40D
  369. -.   B272  42           LD    B, D
  370. -.   B273  ED 59        OUT   (C), E
  371. -.   B275  01 C0 F6     LD    BC, F6C0
  372. -.   B278  ED 49        OUT   (C), C
  373. -.   B27A  ED 79        OUT   (C), A
  374. -.   B27C  42           LD    B, D
  375. -.   B27D  4E           LD    C, (HL)
  376. -.   B27E  2B           DEC   HL
  377. -.   B27F  ED 49        OUT   (C), C
  378. -.   B281  01 80 F6     LD    BC, F680
  379. -.   B284  ED 49        OUT   (C), C
  380. -.   B286  ED 79        OUT   (C), A
  381. -.   B288  1D           DEC   E
  382. -.   B289  F2 72 B2     JP    P, B272
  383. +.   B26B  11 84 B4     LD    DE, B484
  384. +.   B26E  CD 60 03     CALL  0360
  385. +.   B271  12           DEFB  12
  386. +.   B272  C9           RET
  387. +.   B273  C9           RET
  388. +.   B274  C9           RET
  389. +.   B275  C9           RET
  390. +.   B276  C9           RET
  391. +.   B277  C9           RET
  392. +.   B278  C9           RET
  393. +.   B279  C9           RET
  394. +.   B27A  C9           RET
  395. +.   B27B  C9           RET
  396. +.   B27C  C9           RET
  397. +.   B27D  C9           RET
  398. +.   B27E  C9           RET
  399. +.   B27F  C9           RET
  400. +.   B280  C9           RET
  401. +.   B281  C9           RET
  402. +.   B282  C9           RET
  403. +.   B283  C9           RET
  404. +.   B284  C9           RET
  405. +.   B285  C9           RET
  406. +.   B286  C9           RET
  407. +.   B287  C9           RET
  408. +.   B288  C9           RET
  409. +.   B289  C9           RET
  410. +.   B28A  C9           RET
  411. +.   B28B  C9           RET
  412.  .   B28C  C9           RET
  413.  .   B28D  22 85 B4     LD    (B485), HL
  414.  .   B290  DD 7E 10     LD    A, (IX+10)
  415.  .   B293  B7           OR    A

A betöltőképhez még külön palettát és BIAS-t kerestem, amely más, mint a játékban, és a fent leírthoz hasonló módon konvertáltam a pixeleket.
Title: Re: Cybernoid
Post by: geco on 2010.May.09. 22:29:31
Köszönöm szépen a palettakonverziós progi leírását, jól fog még jönni :D, csak térjek vissza a CPC-s programokhoz, le is mentettem az utókornak ;)
A színkonvertálásra írtam egy assembly kódot anno, amibe csak a 16 színt kellett behelyezni, abban a sorrendben, ahogy majd EP-n fog kinézni, meg megadni a kezdőcímet, és a végét, betölteni a file-t és go, majd mentés, lehet kipróbálom majd a LUA-s színkonverziót is.
Nem is kellett sok helyen belenyúlni a programba :), ha jól emlékszem, akkor az Exolon is ennyi, ha nem kevesebb túrkálást kívánt, sőt még a pixel adatok is egy kupacban voltak, 1-2 dolog volt csak máshol, isten áldja meg a Hewsont :D, ha nehezebb lett volna, tuti elakadok, úgy, mint az Alien Attacknál (annak estem neki először, még az assemblyvel is csak ismerkedve), de aztán csak meglett az is :D
Title: Re: Cybernoid
Post by: Lacika on 2010.May.09. 22:33:34
Cybernoid 1-2 felkerült a disk image-ekre (16-os lemez). Bármelyik EXOS-as, resetnél pontszámtáblát elmenti de ezután nem tud szabályosan kilépni. (2.1-es, 2.32-es EXOS-al is.)
Ha floppy-t használok (mármint igazit), akkor ki tud lépni. Ezt nem értem...
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.09. 22:52:23
Cybernoid 1-2 felkerült a disk image-ekre (16-os lemez). Bármelyik EXOS-as, resetnél pontszámtáblát elmenti de ezután nem tud szabályosan kilépni. (2.1-es, 2.32-es EXOS-al is.)
Ha floppy-t használok (mármint igazit), akkor ki tud lépni. Ezt nem értem...

Ez nem lehet véletlenül valamilyen EXOS 0 fagyás ? Most ellenőriztem, ha van ASMON ROM a rendszerben, akkor még a 2.32 is le tud fagyni. Egyébként nem látom, hogy itt mi akadhat el (különösen attól függően, hogy a floppy igazi-e :)) - eltekintve a 'JP C00Dh' után már az EXOS ROM-ban következő 'LD C, 20h : EXOS 0'-tól:

Code: ZiLOG Z80 Assembler
  1. resetRoutine:
  2.         di
  3.         ld    sp, 0100h
  4.         ld    a, 0ffh
  5.         out   (0b2h), a
  6.         ld    hl, resetRoutine
  7.         ld    (0bff8h), hl
  8.         ld    hl, (0bff4h)
  9.         set   7, h
  10.         set   6, h
  11.         call  setLPTAddress & 3fffh
  12. .l1:    jr    .l3                       ; * replaced with JR +00
  13.         ld    a, (cpcSegments & 3fffh)  ; to enable saving high score table
  14.         out   (0b1h), a
  15.         xor   a
  16.         ld    de, highScoreFileName
  17.         exos  2
  18.         or    a
  19.         jr    nz, .l2
  20.         ld    de, 719ah                 ; save high score table
  21.         ld    bc, 0061h
  22.         exos  8
  23. .l2:    xor   a
  24.         exos  3
  25.         di
  26. .l3:    ld    a, (origZPSegment)
  27.         or    a
  28.         jr    z, .l4
  29.         out   (0b1h), a
  30.         ld    hl, 0000h
  31.         ld    de, 4000h
  32.         ld    bc, zpFreeSpaceBegin
  33.         ldir
  34.         ld    (0bffch), a
  35.         out   (0b0h), a
  36.         xor   a
  37.         ld    (origZPSegment), a
  38. .l4:    ld    c, 40h
  39.         exos  0
  40.         di
  41.         ld    a, 01h
  42.         out   (0b3h), a
  43.         ld    a, 06h
  44.         jp    0c00dh
Title: Re: Cybernoid
Post by: Lacika on 2010.May.10. 08:04:40
Ez nem lehet véletlenül valamilyen EXOS 0 fagyás ? Most ellenőriztem, ha van ASMON ROM a rendszerben, akkor még a 2.32 is le tud fagyni.

Amikor 2.1-es EXOS-al néztem, alap konfig volt, ASMON nélkül.
Ami még eszembe jutott: talán az kavarhat be, hogy a "lemezeken" a több, apróbb file-ból álló programokat rakom előre, és utána EPDOS-ból ORDER-el rendezem? Más tippem nincs, ha hazamegyek kipróbálom.
Title: Re: Cybernoid
Post by: Lacika on 2010.May.10. 17:51:21
Amikor 2.1-es EXOS-al néztem, alap konfig volt, ASMON nélkül.
Ami még eszembe jutott: talán az kavarhat be, hogy a "lemezeken" a több, apróbb file-ból álló programokat rakom előre, és utána EPDOS-ból ORDER-el rendezem? Más tippem nincs, ha hazamegyek kipróbálom.

Lehet, hogy emulátor bug?
Ha az image-ből kimásolom lemezre, akkor működik. Teljesen "steril" imgage-be bemásolom, mentés után nem indul újra.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.10. 18:18:32
Code: ZiLOG Z80 Assembler
  1. .l3:    ld    a, (origZPSegment)
  2.         ...
  3.         ld    (origZPSegment), a

Mégis a játék betöltőjében van a hiba: itt a változóhoz rossz lapon/szegmensen próbál hozzáférni a program ("origZPSegment & 3fffh"-ra cserélve javítható). :oops: Hamarosan feltöltök javított file-okat.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.10. 23:40:16
Javítás:
  [attachurl=#]
  [attachurl=#]
  [attachurl=#]
  [attachurl=#]
A korábbi tömörített verziók .com file-jai továbbra is használhatók, illetve a .prg-k DL2-vel is betölthetők. Mindkét játéknál TONE_AND_NOISE_MODE=1 hang van, de fordíthatok más (pl. 20h) beállítással is. Kisebb jelentőségű változtatás, hogy a Cybernoid 1 is a második rész újabb betöltő verzióját használja.
Title: Re: Cybernoid
Post by: Lacika on 2010.May.11. 07:57:16
Mindkét játéknál TONE_AND_NOISE_MODE=1 hang van

Ez volt a cyber220.com?
 :oops:
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.11. 11:02:59
Ez volt a cyber220.com?
 :oops:

Nem, ez az a mód, amit az első átiratokban használtam mindkét játéknál. A cyber220.com TONE_AND_NOISE_MODE=20h-val készült, amint azt a file név is jelzi.
Title: Re: Cybernoid
Post by: Lacika on 2010.May.11. 11:36:17
Nem, ez az a mód, amit az első átiratokban használtam mindkét játéknál. A cyber220.com TONE_AND_NOISE_MODE=20h-val készült, amint azt a file név is jelzi.

Felraknál egy olyan változatot a második részből? :oops:
Úgy sokkal jobbak a robbanás / lövés hangjai.
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.11. 12:01:33
Esetleg beállíthatóra lehetne csinálni? Pl amikor a csalást kérdi, akkor a funkcióbillentyûket nyomogatva.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.11. 23:13:45
Esetleg beállíthatóra lehetne csinálni? Pl amikor a csalást kérdi, akkor a funkcióbillentyûket nyomogatva.

A játék közben állítható az F1, F2, F5, F7, és F8 billentyűkkel:
  [attachurl=#]
  [attachurl=#]
  [attachurl=#]
  [attachurl=#]

Forráskód választható hang mód nélkül (az előző verzióhoz képest kisebb változtatásokkal):
  [attachurl=#]
  [attachurl=#]
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.11. 23:26:35
A játék közben állítható az F1, F2, F5, F7, és F8 billentyûkkel:
Király! Bárcsak 20 évvel ezelõtt is ilyen support lett volna az EP játékokhoz!
Title: Re: Cybernoid
Post by: Lacika on 2010.May.12. 08:13:39
A játék közben állítható az F1, F2, F5, F7, és F8 billentyűkkel:
 

Játék közben???  :smt041
Nem is gondoltam volna, hogy ezt meg lehet csinálni...
Full-extrás arcade!
Title: Re: Cybernoid
Post by: Lacika on 2010.May.12. 18:12:23
A játék közben állítható az F1, F2, F5, F7, és F8 billentyűkkel:

AZ F8-al elérhető mód miben különbözik a többitől?
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.12. 18:33:02
AZ F8-al elérhető mód miben különbözik a többitől?

F8-ra négyszögjel van felüláteresztő szűrővel és gyűrűmodulációval; az F7 csak gyűrűmoduláció.
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.12. 19:19:40
F8-ra négyszögjel van felüláteresztõ szûrõvel és gyûrûmodulációval; az F7 csak gyûrûmoduláció.
Esetleg lehetne kérni egy Enterpress cikk pótló hozzászólást errõl az egész AY emuláció témáról?

Én ott tartok, mint amit az SpV-ben írtak annak idején  :oops:
Quote
A zene átírása már keményebb dió. Az AY-3-8912 regisztereinek leírása a SINCLAIR SPECTRUM JÁTÉK ÉS PROGRAM V. c. kötetében található (LSI ATSz. 1988.). A feladat az hogy olyan szubrutint készítsünk, amely a megfelelõ AY és DAVE regisztereket egymáshoz rendeli. Ezt a problémát még egyedüli és üdvözítõ módon nem sikerült megoldani.

A problémák:
• Hardware burkológörbe. Na ez az, ahol még nem Sikerült igazi áttörést végrehajtani. Szomorú tény, de ebben jobb az AY chip. Sajnos a "XENON" címû játék ENTERPRISE zenéje csak nyomokban emlékeztet az eredetire.

• Zajgenerátor. Abban az esetben, ha egy csatornán csak zaj szol, akkor majdnem teljes mértékben emulálható a zajeffekt. Ha egy csatornán egyszerre szól a zaj és a tiszta hang, akkor egyenlõre megáll a tudományunk.

Mindenesetre ha jól gondolom (hallom) akkor érdemes lenne egyes korábbi 128-as átíratokban upgradelni az AY rutint István félére!
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.13. 00:30:38
Hardware burkológörbe. Na ez az, ahol még nem Sikerült igazi áttörést végrehajtani. Szomorú tény, de ebben jobb az AY chip. Sajnos a "XENON" címû játék ENTERPRISE zenéje csak nyomokban emlékeztet az eredetire

A burkológörbe megszakításból emulálható. Természetesen ez elfogyaszt némi CPU időt, és nagyobb burkológörbe frekvencia esetén a minőség sem tökéletes, de gyakran elfogadható eredményt lehet elérni. CPC átiratoknál jól használható a 300 Hz-es megszakítás, de ha fontos a minőség, akkor CPC és Spectrum átiratnál is lehet 1 kHz-es megszakításból emulálni a burkológörbét (ilyenkor kisebb problémát jelent, ha a játék HALT utasításokat használ időzítésre) - így még a Wec Le Mans motorhangja is, ha nem is tökéletes, de azért felismerhető. Az is megoldható, hogy ne minden 1 kHz-es megszakítás frissítse a burkológörbét, hanem csak például minden negyedik (rosszabb minőség, de kisebb CPU fogyasztás).

Quote
Ha egy csatornán egyszerre szól a zaj és a tiszta hang, akkor egyenlõre megáll a tudományunk

Valóban :oops: Ezt úgy oldottam meg, hogy fordításkor választhatóan csak négyszögjel vagy csak zaj legyen ilyenkor, vagy négyszögjel valamilyen torzítással (mint pl. az Exolon-ban).

Quote
Esetleg lehetne kérni egy Enterpress cikk pótló hozzászólást errõl az egész AY emuláció témáról?

Egyelőre ennyit sikerült leírni (remélhetőleg nem túl sok hibával), de ez később még kiegészíthető további információval:

Rövid AY regiszter leírás:

0: A csatorna négyszögjel frekvencia alsó 8 bit
1 (b0-b3): A csatorna négyszögjel frekvencia felső 4 bit
2: B csatorna négyszögjel frekvencia alsó 8 bit
3 (b0-b3): B csatorna négyszögjel frekvencia felső 4 bit
4: C csatorna négyszögjel frekvencia alsó 8 bit
5 (b0-b3): C csatorna négyszögjel frekvencia felső 4 bit

  frekvencia = F / N
  F = 62500 Hz CPC-n, F = 110840.47 Hz Spectrum 128-on
  N = a megadott 12 bites frekvencia érték (ha 0 vagy 1, akkor az osztó 1)

6 (b0-b4): zajgenerátor frekvencia (0-31, ha 0 vagy 1, akkor az osztó 1)
  N / F másodpercenként a következő művelet történik:
    - a 17 bites belső regiszter 1 bittel balra léptetődik
    - a 0. bit új értéke a léptetés előtti 16. és 13. bit között végzett
      XNOR művelet eredménye
    - a zajgenerátor kimenete a léptetés utáni 16. bit lesz
  Ez 131071 hosszúságú álvéletlenszám sorozatot generál (azért nem 131072,
  mert a 17 bites regiszter nem lehet 1FFFFh, akkor ugyanis végtelen
  ciklusban csak 1 lenne a kimenet; a kezdőérték 0FFFFh) - a lényeg, hogy
  a zajgenerátor nagyjából megfelel a DAVE 17 bites polinom számlálójának,
  bár a bitsorozat nem ugyanaz.

7 (b0-b5): mixer
  b0: A csatorna négyszögjel engedélyezése (0 = igen)
  b1: B csatorna négyszögjel engedélyezése (0 = igen)
  b2: C csatorna négyszögjel engedélyezése (0 = igen)
  b3: A csatorna zaj engedélyezése (0 = igen)
  b4: B csatorna zaj engedélyezése (0 = igen)
  b5: C csatorna zaj engedélyezése (0 = igen)

  Ha egy csatornán nincs semmi engedélyezve, akkor a csatorna kimenete
  '1' bit, azaz magas, amit például digitális hang lejátszására is fel
  lehet használni. Ezt az '1' szintet az adott csatorna négyszöggenerátora
  vagy a zajgenerátor is "lehúzhatja" nullára, ha engedélyezve van. Tehát
  négyszögjel+zaj esetén a két hang között AND művelet történik, ami
  egyfajta gyűrűmodulációnak tekinthető, de nem azonos a DAVE XNOR
  gyűrűmodulációjával.

8 (b0-b4): A csatorna hangerő / burkológörbe engedélyezés
9 (b0-b4): B csatorna hangerő / burkológörbe engedélyezés
10 (b0-b4): C csatorna hangerő / burkológörbe engedélyezés
  Ha a 4. bit 0, akkor az alsó 3 bit közvetlenül határozza meg a
  hangerőt, egyébként a hangerőt a burkológörbe verérli, és a 0-3. bitnek
  nincs hatása. A hangerő értékeknek az amplitúdó nem lineáris függvénye:
     0: 0.0000   4: 0.0423   8: 0.1691  12: 0.5704
     1: 0.0137   5: 0.0618   9: 0.2647  13: 0.6873
     2: 0.0205   6: 0.0847  10: 0.3527  14: 0.8482
     3: 0.0291   7: 0.1369  11: 0.4499  15: 1.0000

11: burkológörbe frekvencia alsó 8 bit
12: burkológörbe frekvencia felső 8 bit
  A burkológörbe generátor kimenete N / F másodperc időegységenként
  változik, ha N = 0 vagy 1, az 1 / F másodpercet jelent.

13 (b0-b3): burkológörbe mód / újraindítás
  Ennek a regiszternek az írása újraindítja a burkológörbét az elejéről.
  Az egyes bitek jelentése:
    0: hold
       ha ez 1, akkor az első periódus (16 időegység) után a burkológörbe
       generátor megáll, és a kimenet 0 lesz, ha az "alternate" és
       "attack" bitek értéke azonos vagy a "continue" bit 0, egyébként 15
    1: alternate
       folyamatos burkológörbe (continue = 1, hold = 0) esetén azt
       határozza meg, hogy mi történik, amikor a számláló 0 vagy 15
       elérése után túlcsordul:
         0: AND 15 (fűrészjel)
         1: az utolsó (0 vagy 15) kimenet ismétlődik, és az irány
            ellentétes lesz, azaz ...13, 14, 15, 15, 14, 13..., illetve
            ...2, 1, 0, 0, 1, 2... (háromszögjel)
    2: attack
       0: a burkológörbe 15-ről indul és csökken
       1: a burkológörbe 0-ról indul és növekszik
    3: continue
       ha ez 0, akkor az első periódus (16 időegység) után a burkológörbe
       generátor megáll, és a kimenet 0 lesz; a "hold" és "alternate"
       biteknek ilyenkor nincs hatása


Amint látható, a 0-5 regiszterek nagyjából megfelelnek a DAVE A0h-A5h portjainak, de a DAVE négyszögjel frekvenciája eltérő módon számítható:
  125000 / (N + 1)      (ha a BFh I/O port 1. bitje 0)
  83333.33 / (N + 1)    (ha a BFh I/O port 1. bitje 1)
Ezek az értékek 4 MHz-es gépre érvényesek, egyébként az órajellel arányosan nagyobbak.

Zajgenerátornak felhasználható a DAVE első három csatornája is 17 bites polinom számlálóval (ehhez az A6h portra 10h-t kell írni, ami felcseréli a 7 és 17 bites számlálót, azaz így az 1-3. csatorna használhatja a 17 bites, a 4. (nem használt) csatorna pedig a 7 bites számlálót). Figyelni kell azonban arra, hogy a zajgenerátort ez a négyszögjel frekvenciájának a kétszeresével mintavételezi, azaz a fel- és lefutó élnél is.

Ezek alapján a Spectrum és CPC frekvencia értékek így közelíthetők:
  Spectrum négyszögjel: N * 1.125 - 1
  Spectrum zaj:         N * 2.25 - 1
  CPC négyszögjel:      N * 2 - 1
  CPC zaj:              N * 4 - 1
A Spectrumnál az 1.125 ugyan nem egészen pontos, de az eltérés kisebb, mint 0.25%, és ez az arány egyszerűen számítható néhány Z80 utasítással.
Spectrum négyszögjel frekvencia konverzió (HL -> AL):
Code: ZiLOG Z80 Assembler
  1.         ld    b, h
  2.         ld    a, l
  3.         sra   b
  4.         rra
  5.         sra   b
  6.         rra
  7.         sra   b
  8.         rra
  9.         adc   a, l
  10.         ld    l, a
  11.         dec   hl
  12.         ld    a, b
  13.         adc   a, h
  14.         cp    10h
  15.         jr    nc, .l3                   ; overflow ?
  16. .l1:    ...
  17. .l3:    inc   l
  18.         inc   a
  19.         jr    z, .l1
  20.         ld    l, 0ffh
  21.         ld    a, 0fh
  22.         jp    .l1
Spectrum zaj frekvencia konverzió (A -> A):
Code: ZiLOG Z80 Assembler
  1.         cp    1
  2.         adc   a, 0
  3.         ld    h, a
  4.         rra
  5.         sla   h
  6.         rra
  7.         adc   a, h
  8.         dec   a
Ezek figyelnek a túlcsordulásra, a "speciális" N=0 esetre, ami azonos az N=1-el, és még arra is, hogy az eredmény ne lefelé legyen kerekítve, hanem a pontos (tört) értékhez a legközelebb legyen. Mindkét esetben a kód feltételezi, hogy a felső, AY által nem támogatott bitek 0-ra vannak állítva.
A CPC jóval egyszerűbb. Négyszögjel (HL -> AL):
Code: ZiLOG Z80 Assembler
  1.         add   hl, hl
  2.         dec   hl
  3.         ld    a, h
  4.         cp    10h
  5.         jr    nc, .l3                   ; overflow ?
  6. .l1:    ...
  7. .l3:    inc   l
  8.         inc   a
  9.         jr    z, .l1
  10.         ld    l, 0ffh
  11.         ld    a, 0fh
  12.         jp    .l1
Ez ugyan nem egészen jó, mert a 0 frekvenciát 0-ra konvertálja, pedig 1-re kellene. De mivel normál esetben (torzítás nélkül) egyik sem hallható, ez talán nem jelent komolyabb problémát. De egyszerűen javítható is az INC L helyére LD L, 1-et írva.
CPC zaj (A -> A):
Code: ZiLOG Z80 Assembler
  1.         cp    1
  2.         adc   a, 0
  3.         add   a, a
  4.         add   a, a
  5.         dec   a

A hangerőt egyszerű táblázattal lehet konvertálni (de ha nem fontos, hogy pontos legyen, megfelelhet a 4-el való szorzás is):
Code: ZiLOG Z80 Assembler
  1.         defb   0,  1,  2,  3,  4,  5,  6,  9
  2.         defb  12, 17, 22, 28, 36, 44, 53, 63
Title: Re: Cybernoid
Post by: geco on 2010.May.13. 08:43:59
Hardware burkológörbe. Na ez az, ahol még nem Sikerült igazi áttörést végrehajtani. Szomorú tény, de ebben jobb az AY chip. Sajnos a "XENON" címû játék ENTERPRISE zenéje csak nyomokban emlékeztet az eredetire.
Az már nálam is ment, igaz 50Hz volt a maximum frekvencia, de az az alatti frekvenciával ellátott burkológörbéket jól kezelte, bele is futottam egy programba, ami magasabb frekvenciájú burkológörbét használ, el is gondolkoztam, hogy beteszem István AY emuját, majd előtte kiderítem, hogy befér-e, és a tökéletesebb emuláció miatt lassabb-e.
Title: Re: Cybernoid
Post by: geco on 2010.May.13. 08:48:48
Valóban :oops: Ezt úgy oldottam meg, hogy fordításkor választhatóan csak négyszögjel vagy csak zaj legyen ilyenkor, vagy négyszögjel valamilyen torzítással (mint pl. az Exolon-ban).
Azt az opciót nem tetted bele, hogyha négyszögjel és zaj szól eccerre, akkor választható lenne az is, hogy szól a négyszögjel, és mellette a 31kHz-es zaj? Van pár program, aminél ez elég jó utánzás lenne, ahol a zajcsatornán cintányérszerű hang szól.
Title: Re: Cybernoid
Post by: geco on 2010.May.13. 09:06:54
Ezt az '1' szintet az adott csatorna négyszöggenerátora
  vagy a zajgenerátor is "lehúzhatja" nullára, ha engedélyezve van. Tehát
  négyszögjel+zaj esetén a két hang között AND művelet történik, ami
  egyfajta gyűrűmodulációnak tekinthető, de nem azonos a DAVE XNOR
  gyűrűmodulációjával.

Zajgenerátornak felhasználható a DAVE első három csatornája is 17 bites polinom számlálóval (ehhez az A6h portra 10h-t kell írni, ami felcseréli a 7 és 17 bites számlálót, azaz így az 1-3. csatorna használhatja a 17 bites, a 4. (nem használt) csatorna pedig a 7 bites számlálót). Figyelni kell azonban arra, hogy a zajgenerátort ez a négyszögjel frekvenciájának a kétszeresével mintavételezi, azaz a fel- és lefutó élnél is.
Nagyon tetszik a leírás, van egy csomó olyan dolog a leírtak között, amit a doksikban nem is láttam, igaz a felét lehet akkor se értettem volna, ha látom :D
Hogy derítetted ki, hogy zaj+hang esetén AND-eli a hangokat, a hengerő nem lineáris?
Én az A6h portot 1-3-as értékkel írtam a zajhoz, attól függően, hogy melyik csatornán volt zaj, ez nem jó, vagy miért választottad a polinom számlálós megoldást?
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.13. 09:30:54
Ezek alapján a Spectrum és CPC frekvencia értékek így közelíthetõk:
  Spectrum négyszögjel: N * 1.125 - 1
  Spectrum zaj:         N * 2.25 - 1
  CPC négyszögjel:      N * 2 - 1
  CPC zaj:              N * 4 - 1
A Spectrumnál az 1.125 ugyan nem egészen pontos, de az eltérés kisebb, mint 0.25%, és ez az arány egyszerûen számítható néhány Z80 utasítással.
Na ezzel se foglalkoztak az általam látott AY rutinok.
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.13. 14:10:27
Azt az opciót nem tetted bele, hogyha négyszögjel és zaj szól eccerre, akkor választható lenne az is, hogy szól a négyszögjel, és mellette a 31kHz-es zaj?

Én az A6h portot 1-3-as értékkel írtam a zajhoz, attól függően, hogy melyik csatornán volt zaj, ez nem jó, vagy miért választottad a polinom számlálós megoldást?

Mindkét kérdésre alapvetően ugyanaz a válasz: jóval egyszerűbb volt úgy megoldani, hogy az AY három csatornájának közvetlenül feleljen meg a DAVE első három csatornája, és ne kelljen a csatornákat dinamikusan foglalni (figyelembe véve azokat a lehetőségeket, hogy például egyszerre több csatornán is lehet engedélyezve zaj - akár úgy is, hogy az egyiken van burkológörbe, a másikon pedig nincs, illetve tovább bonyolítja a helyzetet a sztereó hang, és figyelni kell azt, hogy mikor van szabad csatorna zajgenerátor órajelnek, és mikor kell a 31.25 kHz-et használni). Így a négyszögjel+zaj problémától eltekintve egyszerű és gyors kóddal lehetett elfogadhatóan pontos és az AY hardver működéséhez közeli emulációt megvalósítani.

Quote
Van pár program, aminél ez elég jó utánzás lenne, ahol a zajcsatornán cintányérszerű hang szól.

Ilyenkor valóban nem működik túl jól, mert az alapértelmezett (1-es) módban a cintányér "elfedi" az adott csatornán a négyszögjelet, a torzításokkal pedig a négyszögjel a cintányér idejére alacsony frekvenciájú zajjá változik :oops: (az első talán kevésbé zavaró). A gyűrűmoduláció még akár viszonylag elfogadható eredményt is adhat, ha a négyszögjel+zaj véletlenül éppen a B csatornán van (mert akkor a gyűrűmoduláció forrása a zajcsatorna lesz) - esetleg ha ez mindig ugyanazon a csatornán történik, akkor az emulációban meg lehetne keverni a csatornák sorrendjét, hogy a "problémás" csatorna kerüljön a DAVE második hanggenerátorára.
A DAVE zajcsatornájának a fent említett dinamikus használatához gyakorlatilag újra kellene írni az AY emulátort.

Quote
Nagyon tetszik a leírás, van egy csomó olyan dolog a leírtak között, amit a doksikban nem is láttam, igaz a felét lehet akkor se értettem volna, ha látom :D
Hogy derítetted ki, hogy zaj+hang esetén AND-eli a hangokat, a hengerő nem lineáris?

A hangerő táblázatot több helyen lehet látni például különböző PC-s CPC és Spectrum emulátorokban (kisebb eltérésekkel, az alkatrészek szórása és mérési pontatlanságok miatt), de talán az eredeti AY dokumentáció is említi, hogy nem lineáris, csak nem jó értékeket adtak meg. Az itt látható táblázat a FUSE Spectrum emulátorból van. Az AND műveletet szintén más emulátorokban láttam, de mivel azt, hogy az alapértelmezett (tiltott négyszögjel és zaj) szint magas, több helyen is említik (pl. Wikipedia), könnyen lehet rá következtetni, ugyanis az AND művelet egyszerűbb hardvert igényel, mint a két jelet rendesen (összeadással vagy nagy frekvenciájú időosztással) keverni. A zajgenerátor algoritmus is megtalálható különböző más emulátorokban (itt (http://bulba.untergrund.net/elect_e.htm) is található például egy rövid x86 assembler rutin).
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.13. 14:39:50
A legutóbb berakott funkcióbillentyûs fejlesztésnél pontosan miket is kapcsolgatunk?
Title: Re: Cybernoid
Post by: geco on 2010.May.13. 14:48:14
Értettem, és köszönöm :)
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.13. 16:23:40
A legutóbb berakott funkcióbillentyûs fejlesztésnél pontosan miket is kapcsolgatunk?

A TONE_AND_NOISE_MODE beállítását.
Leírás az exolon.s-ben található Spectrum 128-as AY emulátor kódhoz (1. rész, a hozzászólások méretének korlátozása miatt):

Code: ZiLOG Z80 Assembler
  1.     macro ayVolTableMacro
  2. ayVolumeTable:
  3.         defb   0,  1,  2,  3,  4,  5,  6,  9
  4.         defb  12, 17, 22, 28, 36, 44, 53, 63
  5.     endm
  6.  
  7.         align 16
  8.  
  9. ayTablesBegin:
  10.  
  11.     if (ayTablesBegin & 0030h) != 0010h
  12.         ayVolTableMacro
  13.  
  14.         assert  ($ & 000fh) == 0
  15.     endif
  16.  
  17. ayRegisterMaskTable:
  18.         defb  0ffh, 00fh, 0ffh, 00fh, 0ffh, 00fh, 01fh, 0ffh
  19.         defb  01fh, 01fh, 01fh, 0ffh, 0ffh, 00fh, 0ffh, 0ffh
  20.  
  21.         assert  ($ & 000fh) == 0
  22.  
  23. ayRegWriteTable:
  24.         defb  low (ayRegisterWrite.l3 - (ayRegisterWrite.l1 + 2))
  25.         defb  low (ayRegisterWrite.l3 - (ayRegisterWrite.l1 + 2))
  26.         defb  low (ayRegisterWrite.l4 - (ayRegisterWrite.l1 + 2))
  27.         defb  low (ayRegisterWrite.l4 - (ayRegisterWrite.l1 + 2))
  28.         defb  low (ayRegisterWrite.l6 - (ayRegisterWrite.l1 + 2))
  29.         defb  low (ayRegisterWrite.l6 - (ayRegisterWrite.l1 + 2))
  30.         defb  low (ayRegisterWrite.l7 - (ayRegisterWrite.l1 + 2))
  31.         defb  low (ayRegisterWrite.l5 - (ayRegisterWrite.l1 + 2))
  32.         defb  low (ayRegisterWrite.l9 - (ayRegisterWrite.l1 + 2))
  33.         defb  low (ayRegisterWrite.l10 - (ayRegisterWrite.l1 + 2))
  34.         defb  low (ayRegisterWrite.l11 - (ayRegisterWrite.l1 + 2))
  35.         defb  low (ayRegisterWrite.l12 - (ayRegisterWrite.l1 + 2))
  36.         defb  low (ayRegisterWrite.l12 - (ayRegisterWrite.l1 + 2))
  37.         defb  low (ayRegisterWrite.l16 - (ayRegisterWrite.l1 + 2))
  38.         defb  low (ayRegisterWrite.l8 - (ayRegisterWrite.l1 + 2))
  39.         defb  low (ayRegisterWrite.l8 - (ayRegisterWrite.l1 + 2))
  40.  
  41.         assert  ($ & 000fh) == 0
  42.  
  43. ayRegisters:
  44.         defb  00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  45.         defb  00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
  46.  
  47.         assert  ($ & 000fh) == 0
  48.  
  49.     if (ayTablesBegin & 0030h) == 0010h
  50.         ayVolTableMacro
  51.  
  52.         assert  ($ & 000fh) == 0
  53.     endif

Ezekben a táblázatokban található az AY hangerőnek megfelelő DAVE hangerő (ayVolumeTable), az egyes AY regiszterekben ténylegesen használt bitek AND maszkja (ayRegisterMaskTable), a regiszterek írásakor használt ugrótáblázat (ayRegWriteTable, lásd lent), és a regiszterek aktuális értéke (ayRegisters). A táblázatok 16-al osztható címre vannak igazítva (align 16) az egyszerűbb és gyorsabb elérés érdekében, ezen kívül a sorrendjük változhat a memóriában, hogy lehetőség legyen további optimalizálásra:

 00h:  ayVolumeTable   ayRegisterMaskTable   ayRegWriteTable   ayRegisters
  10h:  ayRegisterMaskTable  ayRegWriteTable  ayRegisters     | ayVolumeTable
  20h:  ayVolumeTable   ayRegisterMaskTable | ayRegWriteTable   ayRegisters
  30h:  ayVolumeTable | ayRegisterMaskTable   ayRegWriteTable   ayRegisters


A 00h..30h az első táblázat kezdőcímének az alsó 6 bitje, a '|' pedig a 64 byte-os határt jelzi. Íráskor a táblázatokat ayRegisterMaskTable, ayRegisters, ayRegWriteTable sorrendben kell használni. Amint látható, az első két esetben az ayRegisters címe egyszerű SET 5 művelettel számítható, utána pedig az ayRegWriteTable RES 4 művelettel. A harmadik esetben először ADD 20h-ra van szükség, de utána továbbra is használható a RES 4. A negyediknél pedig SET 5 után XOR 30h következik.

Ezzel az (általában nem használt) rutinnal olvashatók a regiszterek (a regiszter száma az A-ban adható meg, és az A-ban adja vissza az értéket):
Code: ZiLOG Z80 Assembler
  1. ayRegisterRead:
  2.         and   0fh
  3.         or    low ayRegisters
  4.         ld    (.l1 + 1), a
  5. .l1:    ld    a, (ayRegisters)          ; *
  6.         or    a
  7.         ret

Az írás természetesen már bonyolultabb:
Code: ZiLOG Z80 Assembler
  1. ayRegisterWrite:
  2.         push  af
  3.         push  bc
  4.         push  hl
  5.         and   0fh
  6.         or    low ayRegisterMaskTable
  7.         ld    l, a
  8.         ld    h, high ayRegisterMaskTable
  9.     if ayRegisters == (ayRegisterMaskTable | 0020h)
  10.         ld    a, c
  11.         and   (hl)
  12.         set   5, l
  13.     else
  14.       if ((ayRegisters ^ ayRegisterMaskTable) & 0ff00h) == 0
  15.         add   a, low (ayRegisters - ayRegisterMaskTable)
  16.         ld    b, a
  17.         ld    a, c
  18.         and   (hl)
  19.         ld    l, b
  20.       else
  21.         ld    a, c
  22.         and   (hl)
  23.         ld    bc, ayRegisters - ayRegisterMaskTable
  24.         add   hl, bc
  25.       endif
  26.     endif
  27.         cp    (hl)
  28.         jr    z, .l2                    ; register not changed ?
  29.         ld    (hl), a
  30.     if ayRegWriteTable == (ayRegisters & 0ffefh)
  31.         res   4, l
  32.     else
  33.         ld    a, l
  34.         xor   low (ayRegWriteTable ^ ayRegisters)
  35.         ld    l, a
  36.     endif
  37.         ld    a, (hl)
  38.         ld    (.l1 + 1), a
  39. .l1:    jr    .l8                       ; *
  40. .l2:    ld    a, l
  41.         xor   low (ayRegisters + 13)
  42.         jr    z, .l16                   ; envelope restart ?
  43.         pop   hl
  44.         pop   bc
  45.         pop   af
  46.         ret

Itt az A a regiszter száma, a C pedig az új érték. Amint látható, először az ayRegisterMaskTable segítségével AND művelet történik, hogy a nem használt bitek mindig 0-ra legyenek állítva, majd az új és az előző érték összehasonlítása. Ha nem változott, akkor nincs semmi teendő, kivéve, ha a regiszter a 13-as, mert a burkológörbét ilyenkor újra kell indítani (.l16). Egyébként tárolódik az új érték, és az ayRegWriteTable ugrótáblázat alapján elvégezhető az adott regiszternek megfelelő művelet (pl. frekvencia változtatása). A különböző feltételesen fordított részek a fent említett optimalizálást valósítják meg.

A regiszterek írása sorban:

Code: ZiLOG Z80 Assembler
  1. .l3:    call  setChannelAFreq           ; tone generator A frequency
  2.         pop   hl
  3.         pop   bc
  4.         pop   af
  5.         ret
  6. .l4:    call  setChannelBFreq           ; tone generator B frequency
  7.         pop   hl
  8.         pop   bc
  9.         pop   af
  10.         ret
  11. .l5:    call  setChannelAFreq           ; mixer
  12.         call  setChannelBFreq
  13. .l6:    call  setChannelCFreq           ; tone generator C frequency
  14.         pop   hl
  15.         pop   bc
  16.         pop   af
  17.         ret

Ez a 0-5. és 7. regiszter. A mixer (7-es regiszter) változtatásakor mindhárom csatornán újraállítja a frekvenciát, ugyanis a négyszögjel/zaj engedélyezésnek csak az adott csatorna DAVE frekvencia regisztereire (A0h-A5h) van hatása:
  egyik sem:        0000h (nem hallható)
  csak négyszögjel: négyszögjel frekvencia
  csak zaj:         zaj frekvencia + 3000h (17 bites polinom számláló)
  mindkettő:        változhat a TONE_AND_NOISE_MODE-tól függően (lásd lent)
A 0-5. regiszternél természetesen csak az adott csatorna frekvenciája frissítődik.

A csatorna frekvencia állításának a megvalósítása Spectrum 128-hoz:
Code: ZiLOG Z80 Assembler
  1. setChannelAFreq:
  2.         ld    c, 0a0h
  3.         ld    a, (ayRegisters + 7)
  4.         ld    hl, (ayRegisters)
  5.         jp    setChannelFrequency
  6.  
  7. setChannelBFreq:
  8.         ld    c, 0a2h
  9.         ld    a, (ayRegisters + 7)
  10.         rrca
  11.         ld    hl, (ayRegisters + 2)
  12.         jp    setChannelFrequency
  13.  
  14. setChannelCFreq:
  15.         ld    c, 0a4h
  16.         ld    a, (ayRegisters + 7)
  17.         rrca
  18.         rrca
  19.         ld    hl, (ayRegisters + 4)
  20.  
  21. setChannelFrequency:
  22.     if TONE_AND_NOISE_MODE == 0
  23.         rrca
  24.         jr    nc, setToneGenFrequency   ; tone generator enabled ?
  25.         and   04h
  26.         jr    z, setNoiseGenFreq        ; noise generator enabled ?
  27.     endif
  28.     if TONE_AND_NOISE_MODE == 1
  29.         bit   3, a
  30.         jr    z, setNoiseGenFreq        ; noise generator enabled ?
  31.         rrca
  32.         jr    nc, setToneGenFrequency   ; tone generator enabled ?
  33.     endif
  34.     if TONE_AND_NOISE_MODE > 15
  35.         and   09h
  36.         jr    z, setToneGenAsNoise      ; tone + noise generator enabled ?
  37.         srl   a
  38.         jr    nc, setToneGenFrequency   ; tone generator only ?
  39.         jr    z, setNoiseGenFreq        ; noise generator only ?
  40.     endif
  41.         xor   a                         ; channel disabled
  42.         out   (c), a
  43.         inc   c
  44.         out   (c), a
  45.         ret
  46.  
  47.     if TONE_AND_NOISE_MODE > 15
  48. setToneGenAsNoise:
  49.         ld    a, TONE_AND_NOISE_MODE
  50.         defb  0feh                      ; = CP nn
  51.     endif
  52.  
  53. setToneGenFrequency:
  54.     if TONE_AND_NOISE_MODE > 15
  55.         xor   a
  56.         ld    (.l1 + 1), a
  57.     endif
  58.         ld    b, h
  59.         ld    a, l
  60.         sra   b
  61.         rra
  62.         sra   b
  63.         rra
  64.         sra   b
  65.         rra
  66.         adc   a, l
  67.         ld    l, a
  68.         dec   hl
  69.         ld    a, b
  70.         adc   a, h
  71.         cp    10h
  72.         jr    nc, .l3                   ; overflow ?
  73. .l1:
  74.     if TONE_AND_NOISE_MODE > 15
  75.         or    00h                       ; * non-zero for tone + noise
  76.     endif
  77. .l2:    out   (c), l
  78.         inc   c
  79.         out   (c), a
  80.         ret
  81. .l3:    inc   l
  82.         inc   a
  83.         jr    z, .l1
  84.         ld    l, 0ffh
  85.         ld    a, 0fh
  86.         jp    .l1
  87.  
  88. setNoiseGenFreq:
  89.         ld    a, (ayRegisters + 6)
  90.         cp    1
  91.         adc   a, 0
  92.         ld    h, a
  93.         rra
  94.         sla   h
  95.         rra
  96.         adc   a, h
  97.         dec   a
  98.         out   (c), a
  99.         inc   c
  100.         ld    a, 30h
  101.         out   (c), a
  102.         ret

Ezek elvégzik a már említett frekvencia konverziót, és a mixer regiszter bitjeitől függően kerül sor 0 frekvencia, négyszögjel frekvencia, vagy zaj beállítására. A négyszögjel+zaj speciális eset, ezt szabályozza a TONE_AND_NOISE_MODE paraméter:
  0: csak négyszögjel
  1: csak zaj
  >15: négyszögjel frekvencia torzítással

Vissza a többi regiszter írásához:

Code: ZiLOG Z80 Assembler
  1. .l7:    ld    a, (ayRegisters + 7)      ; noise generator frequency
  2.     if TONE_AND_NOISE_MODE != 1
  3.         xor   07h
  4.         ld    b, a
  5.         and   09h
  6.     else
  7.         ld    b, a
  8.         and   08h
  9.     endif
  10.         call  z, setChannelAFreq
  11.     if TONE_AND_NOISE_MODE != 1
  12.         ld    a, b
  13.         and   12h
  14.     else
  15.         bit   4, b
  16.     endif
  17.         call  z, setChannelBFreq
  18.     if TONE_AND_NOISE_MODE != 1
  19.         ld    a, b
  20.         and   24h
  21.     else
  22.         bit   5, b
  23.     endif
  24.         call  z, setChannelCFreq
  25. .l8:    pop   hl
  26.         pop   bc
  27.         pop   af
  28.         ret

Ez a - meglepően bonyolultra sikerült - zaj frekvencia beállítás. Az .l8 címke azokhoz a regiszterekhez van fenntartva, amelyeknek az írásakor nem történik semmi. Az egyes csatornák frekvenciájának a frissítése csak akkor történik meg, ha ott ténylegesen van is zaj, ez pedig függhet a TONE_AND_NOISE_MODE-tól: ha az 1, akkor a négyszögjel bitektől (7-es regiszter b0-b2) függetlenül csak a zaj engedélyezését kell figyelni, egyébként akkor van zaj, ha a zaj engedélyezett, de a négyszögjel nem (ez valamivel bonyolultabb eset). A setChannelFreq rutinok nem rontják el a B regisztert zaj esetén, így az itt felhasználható volt a mixer regiszter tárolására.

A hangerő regiszterek írása:

Code: ZiLOG Z80 Assembler
  1. .l9:    ld    a, (ayRegisters + 8)      ; channel A amplitude / envelope enable
  2.         ld    c, 0a8h
  3.         jp    setChannelAmplitude
  4. .l10:   ld    a, (ayRegisters + 9)      ; channel B amplitude / envelope enable
  5.         ld    c, 0a9h
  6.         jp    setChannelAmplitude
  7. .l11:   ld    a, (ayRegisters + 10)     ; channel C amplitude / envelope enable
  8.     if ENABLE_STEREO == 0
  9.         ld    c, 0aah
  10.     else
  11.         ld    c, 0aeh
  12.     endif
  13.         jp    setChannelAmplitude

Ez eddig nem túl érdekes, a tényleges hangerő beállítást a setChannelAmplitude végzi. C-ben az adott csatorna bal hangerő portja van, kivéve a C csatornát sztereó módban, mert akkor a C csatorna csak a jobb oldalon hallható. Ez a hangerő állító rutin:

Code: ZiLOG Z80 Assembler
  1. setChannelAmplitude:
  2.     if NO_ENVELOPE_IRQ == 0
  3.         di
  4.     endif
  5.         cp    10h
  6.         jr    c, .l1
  7.     if NO_ENVELOPE_IRQ == 0
  8.         ld    a, (envelopeInterrupt.l3 + 1)
  9.     else
  10.         xor   a
  11.     endif
  12. .l1:    or    low ayVolumeTable
  13.         ld    l, a                      ; H = high ayRegWriteTable
  14.     if ((ayVolumeTable ^ ayRegWriteTable) & 0ff00h) != 0
  15.       if ayVolumeTable > ayRegWriteTable
  16.         inc   h
  17.       else
  18.         dec   h
  19.       endif
  20.     endif
  21.         ld    a, (hl)
  22.     if ENABLE_STEREO != 0
  23.         bit   0, c
  24.         jr    z, .l2
  25.         ld    b, a
  26.         srl   b
  27.         srl   b
  28.         sub   b
  29.     endif
  30.         out   (c), a
  31.         set   2, c
  32. .l2:    out   (c), a
  33.     if NO_ENVELOPE_IRQ == 0
  34.         ld    hl, (ayRegisters + 8)
  35.         ld    a, (ayRegisters + 10)
  36.         ld    bc, 70h + (envelopeEnableTable & 0ff00h)
  37.         and   c
  38.         add   a, a
  39.         or    h
  40.         and   c
  41.         add   a, a
  42.         or    l
  43.         and   c
  44.         rrca
  45.         rrca
  46.         rrca
  47.         rrca
  48.         or    low envelopeEnableTable
  49.         ld    c, a
  50.         ld    a, (bc)
  51.         ld    (envelopeInterrupt.l8 - 1), a
  52.     endif
  53.         pop   hl
  54.         pop   bc
  55.         pop   af
  56.     if NO_ENVELOPE_IRQ == 0
  57.         ei
  58.     endif
  59.         ret

Burkológörbe emulációnál átmenetileg letiltja a megszakítást, mert egyébként a hangerő és a burkológörbe engedélyezésének az állítása közötti megszakítás problémát okozhatna. Ez a rutin egyébként az ayRegisterWrite-ból is visszatér, ezért vannak a POP utasítások a végén.
Először a hangerőt állítja be, tiltott burkológörbe esetén az alsó 4 bit, egyébként a burkológörbe aktuális állapota (envelopeInterrupt.l3 + 1, vagy 0 ha nincs burkológörbe emuláció) alapján, a már említett hangerő konvertáló táblázatot használva. Mivel a híváskor a H regiszterben még mindig az ayRegWriteTable felső 8 bitje van, ez kisebb optimalizálást tesz lehetővé ('ld h, high ayVolumeTable' megtakarítása). Mono módban a hangerőt egyszerűen kiírja mindkét portra, sztereó hangnál viszont a csatornától függően vagy csak az egyik oldalra kerül hang (A = bal, C = jobb), vagy mindkettőre (B) 75% szinten, hogy ez ne legyen sokkal hangosabb, mint az A és C csatorna.
Ha a burkológörbe emuláció engedélyezett, akkor még a megszakítási rutinban frissíteni kell, hogy melyik csatorna használja a burkológörbét. Erre a célra használható a 8 elemű és 8 byte-ra igazított envelopeEnableTable, amely egy ugrótábla JR utasításhoz:
Code: ZiLOG Z80 Assembler
  1. envelopeEnableTable:
  2.         defb  low (envelopeInterrupt.l9 - envelopeInterrupt.l8)
  3.         defb  low (envelopeInterrupt.l8 - envelopeInterrupt.l8)
  4.         defb  low (envelopeInterrupt.l11 - envelopeInterrupt.l8)
  5.         defb  low (envelopeInterrupt.l10 - envelopeInterrupt.l8)
  6.         defb  low (envelopeInterrupt.l13 - envelopeInterrupt.l8)
  7.         defb  low (envelopeInterrupt.l12 - envelopeInterrupt.l8)
  8.         defb  low (envelopeInterrupt.l15 - envelopeInterrupt.l8)
  9.         defb  low (envelopeInterrupt.l14 - envelopeInterrupt.l8)

Van még további 3 írható regiszter, de ezeknek csak burkológörbe emulációval van jelentősége. Az első kettő a burkológörbe frekvencia:

Code: ZiLOG Z80 Assembler
  1. .l12:
  2.     if NO_ENVELOPE_IRQ == 0
  3.         ld    hl, (ayRegisters + 11)    ; envelope generator frequency
  4.         ld    a, h
  5.         or    a
  6.         jr    nz, .l13
  7.         ld    a, MIN_ENV_FREQVAL
  8.         cp    l
  9.         jr    c, .l13
  10.         ld    l, a                      ; limit envelope frequency
  11. .l13:   ld    (envelopeInterrupt.l2 + 1), hl
  12.         pop   hl
  13.         pop   bc
  14.         pop   af
  15.         ret
  16.     else
  17.         jr    .l8
  18.     endif

Ez csak tárolja az új frekvenciát az IRQ rutinban egy 'LD BC, n' utasítás paraméterének, de egyben korlátozza is egy minimális értékre, mert a túl gyors burkológörbe problémákat okozhatna.

Az utolsó írható regiszter pedig a burkológörbe mód és újraindítás:

Code: ZiLOG Z80 Assembler
  1. .l16:
  2.     if NO_ENVELOPE_IRQ == 0
  3.         di                              ; envelope generator mode / restart
  4.         ld    hl, (envelopeInterrupt.l2 + 1)
  5.         ld    (envelopeInterrupt.l1 + 1), hl
  6.         ld    a, 38h                    ; = JR C, +nn
  7.         ld    (envelopeInterrupt.l2 - 2), a     ; enable envelope
  8.         ld    a, (ayRegisters + 13)
  9.         or    low envelopeModeTable
  10.         ld    l, a
  11.         ld    h, high envelopeModeTable
  12.         and   04h
  13.         ld    a, (hl)
  14.         ld    (envelopeInterrupt.l5 + 1), a
  15.         ld    hl, 3c00h                 ; INC A, state = 0
  16.         jr    nz, .l17                  ; attack ?
  17.         ld    hl, 3d0fh                 ; DEC A, state = 15
  18. .l17:   ld    (envelopeInterrupt.l3 + 1), hl    ; assume eInt.l4 = eInt.l3 + 2
  19.         ld    a, l
  20.         or    low ayVolumeTable
  21.         ld    l, a
  22.         jp    envelopeInterrupt.l7
  23.     else
  24.         jr    .l8
  25.     endif

Itt a következők történnek:
  - a frekvencia számláló inicializálása a frekvencia értékkel
  - a burkológörbe engedélyezése (ha korábban már lefutott a burkológörbe, akkor - a CPU fogyasztás csökkentése céljából - egy feltételes JR utasítás feltétel nélkülire változott, amit most vissza kell állítani)
  - a burkológörbe mód beállítása, amely egy JR utasítás módosítását jelenti ugrótáblázat alapján
  - a kezdeti hangerő (15 vagy 0) és irány (DEC A vagy INC A) beállítása az 'attack' bittől függően
  - a DAVE hangerő regisztereinek beállítása - ezt takarékos módon a kód az IRQ rutinba való beleugrással oldja meg, amely egyben a POP és EI műveleteket is elvégzi
Természetesen ezek közben a megszakítások tiltottak, hogy az IRQ rutint ne zavarja meg a futása közben a sok kód módosítás.
Az ugrótáblázat, amely 16 byte hosszú és 16 byte-ra igazított, a burkológörbe módokhoz:
Code: ZiLOG Z80 Assembler
  1. envelopeModeTable:
  2.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  3.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  4.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  5.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  6.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  7.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  8.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  9.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  10.         defb  low (envelopeInterrupt.l19 - (envelopeInterrupt.l5 + 2))
  11.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
  12.         defb  low (envelopeInterrupt.l20 - (envelopeInterrupt.l5 + 2))
  13.         defb  low (envelopeInterrupt.l17 - (envelopeInterrupt.l5 + 2))
  14.         defb  low (envelopeInterrupt.l19 - (envelopeInterrupt.l5 + 2))
  15.         defb  low (envelopeInterrupt.l17 - (envelopeInterrupt.l5 + 2))
  16.         defb  low (envelopeInterrupt.l20 - (envelopeInterrupt.l5 + 2))
  17.         defb  low (envelopeInterrupt.l18 - (envelopeInterrupt.l5 + 2))
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.13. 16:25:20
Leírás az exolon.s-ben található Spectrum 128-as AY emulátor kódhoz (2. rész):

A burkológörbe emuláció 1 kHz-es megszakításból történik. Ennek a belépési pontja 0038h címen van:

Code: ZiLOG Z80 Assembler
  1.         phase 0038h
  2.  
  3.         push  af
  4.         in    a, (0b4h)
  5.         and   02h
  6.         jp    nz, envelopeInterrupt
  7.         ld    a, 31h
  8.         out   (0b4h), a
  9.         ei
  10.         jp    0000h
  11.  
  12.         dephase

Itt a B4h port 1. bitje alapján dönthető el, hogy 1 kHz-es megszakítás történt-e. Ha igen, akkor azonnal ugrik a burkológörbe emulátor rutinra. Egyébként törli a video megszakítást (5. bit), engedélyezi a video (4. bit) és 1 kHz-es (0. bit) megszakítást, majd a játék megszakítási rutinjára ugrik (a szinte biztosan az elején található PUSH AF utasítást átlépve). Előbb azonban engedélyezi a megszakításokat, hogy az esetleg lassú rutin futása közben is tovább működhessen a burkológörbe emuláció. A JP utasításhoz természetesen az adott játéktól függő címet kell írni a 0000h helyére.

Következik a burkológörbe emulátor rutin, amely így kezdődik:

Code: ZiLOG Z80 Assembler
  1. envelopeInterrupt:
  2.         ld    a, 13h
  3.         out   (0b4h), a
  4.     if ENV_SRATE_DIV > 1
  5. .lsrd1: ld    a, 0                      ; *
  6.         add   a, (256 + (ENV_SRATE_DIV / 2)) / ENV_SRATE_DIV
  7.         ld    (.lsrd1 + 1), a
  8.         jr    c, .lsrd2
  9.         pop   af
  10.         ei
  11.         ret
  12. .lsrd2:
  13.     endif

Törli az 1 kHz-es megszakítást (1. bit), és engedélyezi a video (4. bit) és 1 kHz-es (0. bit) megszakítást. Lehetőség van az 1 kHz-es megszakítás leosztására is, amellyel CPU idő takarítható meg rosszabb minőség árán.

Code: ZiLOG Z80 Assembler
  1.         push  bc
  2.         push  hl
  3. .l1:    ld    hl, 0000h                 ; * envelope counter
  4.         ld    bc, 010000h - (((110840 * ENV_SRATE_DIV) + 500) / 1000)
  5.         add   hl, bc
  6.         jr    c, .l16                   ; * JR if envelope is stopped
  7. .l2:    ld    bc, 0ffffh                ; * envelope frequency
  8. .l3:    ld    a, 0                      ; * envelope state (0 to 15)
  9. .l4:    dec   a                         ; * envelope direction (INC A or DEC A)
  10.         cp    10h
  11. .l5:    jr    nc, .l18                  ; * envelope mode
  12. .l6:    add   hl, bc
  13.         jr    nc, .l4
  14.         ld    (.l3 + 1), a
  15.         ld    (.l1 + 1), hl
  16.         or    low ayVolumeTable
  17.         ld    l, a
  18. .l7:    ld    h, high ayVolumeTable
  19.         ld    a, (hl)
  20.         pop   hl
  21.         jr    .l9                       ; * envelope enable mode
  22. .l8:    ...
  23. .l16:   ld    (.l1 + 1), hl
  24.         pop   hl
  25.         pop   bc
  26.         pop   af
  27.         ei
  28.         ret

Itt az .l1-nél található számláló minden burkológörbe megszakításnál csökken. A 110840 az AY frekvenciák számításánál használt konstans (ami 62500 CPC-n), az 1000 az emuláció "órajele" osztás előtt, az 500 pedig annak a fele kerekítéshez. CPC-nél a 300 Hz-es megszakítást használva ezeket át kell írni 300-ra és 150-re. Ha a számláló nem csordul túl (vagy ha a burkológörbe már lefutott és a JR C utasítás helyére JR került), akkor .l16-nál az új érték egyszerűen tárolódik, és a rutin visszatér.
Túlcsordulás esetén a számláló újratöltésére, és a burkológörbe állapot (0-15) frissítésére kerül sor. Érdemes megfigyelni, hogy nagy burkológörbe frekvenciánál a kód egyszerre többet is tud lépni a burkológörbe állapoton; ezért van a frekvencia korlátozása, hogy ez a ciklus ne lassulhasson le nagyon. Ha a burkológörbe állapot is túlcsordul, akkor a módtól függően ezek történhetnek:

Code: ZiLOG Z80 Assembler
  1. .l17:   ld    l, low (ayVolumeTable + 15)       ; envelope modes 11 and 13
  2.         defb  01h                       ; = LD BC, nnnn
  3. .l18:   ld    l, low ayVolumeTable      ; envelope modes 0 to 7, 9, and 15
  4.         ld    a, 18h                    ; = JR +nn
  5.         ld    (.l2 - 2), a              ; stop envelope
  6.         jp    .l7
  7. .l19:   and   0fh                       ; envelope modes 8 and 12
  8.         jp    .l6
  9. .l20:   ld    a, (.l4)                  ; envelope modes 10 and 14
  10.         rrca
  11.         jr    c, .l21                   ; direction was DEC A ?
  12.         ld    a, 3dh
  13.         ld    (.l4), a                  ; direction = DEC A
  14.         ld    a, 15
  15.         jp    .l6
  16. .l21:   ld    a, 3ch
  17.         ld    (.l4), a                  ; direction = INC A
  18.         xor   a
  19.         jp    .l6

Az új kimenetnek megfelelően a DAVE hangerő regisztereket is be kell állítani, tehát a táblázatból olvasott konvertált hangerő a 8-9. regiszterekben beállított módtól függően a DAVE A8h-AFh portjaira kerülhet:

Code: ZiLOG Z80 Assembler
  1. .l8:    out   (0a8h), a                 ; envelope on channel A only
  2.     if ENABLE_STEREO == 0
  3.         out   (0ach), a
  4.     endif
  5. .l9:    pop   bc
  6.         pop   af
  7.         ei
  8.         ret
  9. .l10:   out   (0a8h), a                 ; envelope on channels A and B
  10.     if ENABLE_STEREO == 0
  11.         out   (0ach), a
  12.     endif
  13. .l11:
  14.     if ENABLE_STEREO != 0
  15.         ld    c, a                      ; envelope on channel B only
  16.         srl   c
  17.         srl   c
  18.         sub   c
  19.     endif
  20.         out   (0a9h), a
  21.         out   (0adh), a
  22.         pop   bc
  23.         pop   af
  24.         ei
  25.         ret
  26. .l12:   out   (0a8h), a                 ; envelope on channels A and C
  27.     if ENABLE_STEREO == 0
  28.         out   (0ach), a
  29.     endif
  30. .l13:
  31.     if ENABLE_STEREO == 0
  32.         out   (0aah), a
  33.     endif
  34.         out   (0aeh), a                 ; envelope on channel C only
  35.         pop   bc
  36.         pop   af
  37.         ei
  38.         ret
  39. .l14:   out   (0a8h), a                 ; envelope on channels A, B, and C
  40.     if ENABLE_STEREO == 0
  41.         out   (0ach), a
  42.     endif
  43. .l15:
  44.     if ENABLE_STEREO == 0
  45.         out   (0aah), a
  46.     endif
  47.         out   (0aeh), a                 ; envelope on channels B and C
  48.     if ENABLE_STEREO != 0
  49.         ld    c, a
  50.         srl   c
  51.         srl   c
  52.         sub   c
  53.     endif
  54.         out   (0a9h), a
  55.         out   (0adh), a
  56.         pop   bc
  57.         pop   af
  58.         ei
  59.         ret

Végül az AY emuláció inicializálása:

Code: ZiLOG Z80 Assembler
  1. ayReset:
  2.         di
  3.         ld    hl, ayRegisters - 1
  4.         ld    bc, 10afh
  5.         xor   a
  6. .l1:    inc   hl
  7.         out   (c), a
  8.         ld    (hl), a
  9.         dec   c
  10.         djnz  .l1
  11.         res   3, l                      ; register 7
  12.         ld    (hl), 3fh
  13.     if NO_ENVELOPE_IRQ == 0
  14.         ld    (envelopeInterrupt.l3 + 1), a
  15.         ld    a, 18h                    ; = JR +nn
  16.         ld    (envelopeInterrupt.l2 - 2), a
  17.         ld    hl, MIN_ENV_FREQVAL
  18.         ld    (envelopeInterrupt.l2 + 1), hl
  19.         ld    a, low (envelopeInterrupt.l9 - envelopeInterrupt.l8)
  20.         ld    (envelopeInterrupt.l8 - 1), a
  21.         ld    hl, irqCodeBegin
  22.         ld    de, 0038h
  23.         ld    c, low (irqCodeEnd - irqCodeBegin)
  24.         ldir
  25.     endif
  26.         ld    a, 0ch
  27.         out   (0bfh), a
  28.         ld    a, 10h
  29.         out   (0a6h), a                 ; use 17-bit noise generator
  30.     if NO_ENVELOPE_IRQ == 0
  31.         ld    a, 33h
  32.         out   (0b4h), a                 ; enable 1 kHz and video interrupts
  33.         ei
  34.     endif
  35.         ret

Itt az A6h portra írt 10h-t érdemes említeni, amely felcseréli a 7 és 17 bites polinom számlálókat. Így a DAVE első három csatornáján az utóbbi használható.

A CPC-s betöltőben az AY emulátor kissé eltér a frekvencia konverzió módosítása és a 300 Hz-es megszakítás használatának lehetősége miatt. Ezen kívül ott van olyan rutin, amely mind a 14 regisztert írja egyszerre egy táblázatból - ez gyorsabb, mint az ayRegisterWrite-ot 14-szer hívni, és a CPC-s programok gyakran használnak ilyen megoldást 50 Hz-es megszakításból.
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.13. 16:44:34
Ezen kívül ott van olyan rutin, amely mind a 14 regisztert írja egyszerre egy táblázatból - ez gyorsabb, mint az ayRegisterWrite-ot 14-szer hívni, és a CPC-s programok gyakran használnak ilyen megoldást 50 Hz-es megszakításból.
Ilyen rutin a Spectrumos-os verzióhoz is kéne, ott is gyakran csinálnak ilyet a programok!
Title: Re: Cybernoid
Post by: IstvanV on 2010.May.13. 16:47:43
Ilyen rutin a Spectrumos-os verzióhoz is kéne, ott is gyakran csinálnak ilyet a programok!

Szerintem azt minimális változtatással (eltérő PUSH utasítások az .l3 után) be lehet másolni a cybrnoid.s-ből.
Title: Re: Cybernoid
Post by: Zozosoft on 2010.May.18. 23:33:42
Játszogattam az új Cybernoidokkal, sokkal szebb mint a Spectrumos. Kár, hogy anno nem volt ismert a CPC nálunk, sokkal szebb átiratok születhettek volna.