Welcome, Guest. Please login or register.


Author Topic: Lua scriptek fejlesztése (Read 73984 times)

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Lua scriptek fejlesztése
« on: 2009.September.21. 10:17:19 »
Mivel semmi jelét nem láttam annak, hogy rajtam kívül bárki használná, vagy akár csak kipróbálta volna, lehet, hogy a következõ verzióban már nem lesz, illetve az UHU 2.0-s csomagban sem érdemes túl sokat erõltetni a fordítását. Kár, mert szerintem hasznos funkció lett volna
Én csodálni szoktam miket tudsz varázsolni vele! Én is szívesen varázsolnék csak még nem volt idõm elmélyülni benne :cry:  :oops:

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Lua scriptek fejlesztése
« Reply #1 on: 2009.September.23. 16:19:17 »
Én csodálni szoktam miket tudsz varázsolni vele! Én is szívesen varázsolnék csak még nem volt idõm elmélyülni benne :cry:  :oops:

Igen, valószínűnek tartottam, hogy azért nem próbálja ki senki, mert "biztosan bonyolult és nehéz megtanulni" :) Bár a nyelv alapvető használata (változók, műveletek, if/then/else, ciklusok, stb.) valójában egyszerű, ha valaki már ismer más magas szintű nyelveket mint pl. BASIC, Pascal, C, stb., és a meglevő rövidebb scriptek tanulmányozása is segítség lehet. A legegyszerűbb feladatokra - pl. "feltételes töréspont" - ezek alapján talán már néhány perc alatt sikerülhet működő scriptet készíteni.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Re: Lua scriptek fejlesztése
« Reply #2 on: 2009.September.23. 16:22:54 »
Alapvetõen, hogy kell elképzelni ezt a LUA-t? Gyakorlatilag folyamatosan fut az emulátor mellett?

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Lua scriptek fejlesztése
« Reply #3 on: 2009.September.23. 16:48:18 »
Alapvetõen, hogy kell elképzelni ezt a LUA-t? Gyakorlatilag folyamatosan fut az emulátor mellett?

A "Run" gomb lenyomásakor lefut az egész script (feltéve, hogy nem tartalmaz szintaktikai hibákat :)).

Azonban, ha definiál egy "breakPointCallback" nevű függvényt (amelyet - a gépelés megtakarítása céljából - külön erre a célra készített gombbal is be lehet szúrni), akkor az utána minden töréspontnál, illetve a "Step" gomb használatakor a következő Z80 utasításnál lefut. Ennek a függvénynek három paramétere van, a töréspont típusa (utasítás olvasás, I/O írás, stb.), a cím (I/O műveletnél teljes 16 bites cím), és az olvasott vagy írt érték. Egy "boolean" típusú értéket (true vagy false) kell visszaadnia, ez dönti el, hogy megjelenjen-e a debugger ablak; ha true, akkor megjelenik. "Step" módban a false visszatérési érték utasításonkénti futtatásra használható.

A breakPointCallback a "Stop" gomb megnyomásáig marad aktív. Ez a gomb egyben a script által lefoglalt memóriát is felszabadítja, és bezárja az esetleg megnyitott file-okat. A "Run" gomb először mindig elvégzi a "Stop" funkcióját is.

Ha a script globális változókat definiál, akkor azok a "Run" után, illetve a breakPointCallback hívásai között is megmaradnak. Ez felhasználható például számlálók, log file, stb. készítésére.

Lehetőség van a memória, I/O portok, és regiszterek olvasására és írására is.

Példa (nem sok értelme van, de talán segíti a fentiek megértését):

Code: Lua
  1. for i = 0, 0x3FFF do
  2.   writeMemoryRaw(0x3F4000 + i, 0x55)
  3. end
  4. c = 0
  5. function breakPointCallback(t, a, v)
  6.   if t == 0 and a == 0x30 then
  7.     c = c + 1
  8.     if c >= 3 then
  9.       c = 0
  10.       return true
  11.     end
  12.     return false
  13.   end
  14.   return true
  15. end

Itt a "for" ciklus az elején azonnal lefut a Run gomb megnyomásakor, és az FDh szegmenst feltölti 55h byte-okkal. Ezen kívül a script definiál egy "c" változót, 0 kezdőértékkel.
A breakPointCallback függvény utána minden töréspontnál lefut. Ha a típus 0 (Z80 utasítás olvasás) és a cím 30h, akkor csak minden harmadik esetben jelenik meg a debugger ablak (a "c" számláló miatt), egyébként mindig.

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Re: Lua scriptek fejlesztése
« Reply #4 on: 2009.September.23. 16:58:28 »
Áhá! Lassan kezd derengeni :-)

Offline Ferro73

  • EP lover
  • *
  • Posts: 967
  • Country: hu
Re: Lua scriptek fejlesztése
« Reply #5 on: 2009.September.23. 18:10:19 »
és ha a debugger elöjön akkor az emu a Z80 PC  regisztert és minden mást felfüggeszt ?



akkor lehet hibakeresésre is használni pl rejtett zxrom hivások keresésére.

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Lua scriptek fejlesztése
« Reply #6 on: 2009.September.23. 18:35:47 »
és ha a debugger elöjön akkor az emu a Z80 PC  regisztert és minden mást felfüggeszt ?

Igen, amíg a debugger ablak látható vagy Lua kód fut, az emuláció leáll.

Offline Ferro73

  • EP lover
  • *
  • Posts: 967
  • Country: hu
Re: Lua scriptek fejlesztése
« Reply #7 on: 2009.September.23. 18:55:09 »
Az nem jó azt nem lehet megcsinálni fut a lua háttében/debug bezár lua fut/ futtatom az emuban a programot és a program meghiv egy zxrom cimet 0-3fffh között és akkor elöugrik a debug.

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Lua scriptek fejlesztése
« Reply #8 on: 2009.September.23. 19:08:38 »
Az nem jó azt nem lehet megcsinálni fut a lua háttében/debug bezár lua fut/ futtatom az emuban a programot és a program meghiv egy zxrom cimet 0-3fffh között és akkor elöugrik a debug.

Ezt nem egészen értem. Mindenesetre ahhoz, hogy 0 és 3fffh közötti cím hívására megjelenjen a debugger ablak, elég "0000-3fffx"-et beírni a töréspontoknál.

Offline Ferro73

  • EP lover
  • *
  • Posts: 967
  • Country: hu
Re: Lua scriptek fejlesztése
« Reply #9 on: 2009.September.23. 19:17:44 »
A lua csak akkor fut ha benvan/megnyitvan/ a debugger ablak?

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Lua scriptek fejlesztése
« Reply #10 on: 2009.September.23. 19:27:28 »
A lua csak akkor fut ha benvan/megnyitvan/ a debugger ablak?

A Lua script főprogramja a debugger ablak Run gombjának a megnyomásakor fut le.
Utána az emulátor a breakPointCallback fügvényt hívja meg (ha van ilyen) akkor, amikor a debugger töréspont miatt megjelenne. Ha ez a függvény false értéket ad vissza, akkor a Z80 kód futása folytatódik, és a debugger nem jelenik meg.

Offline Ferro73

  • EP lover
  • *
  • Posts: 967
  • Country: hu
Re: Lua scriptek fejlesztése
« Reply #11 on: 2009.September.23. 19:36:45 »
Akkor van lua /breakPointCallback fügvénnyel ellátva/ programom betöltöma debuggerbe RUN a debugger eltünik folytatodik a Z80-as  következö kódja az emu ellenörzi a breakPointCallback fügvényt hanem TRUE akkor jöhet a következö Z80-as kód és megint a breakPointCallback fügvényt hanem TRUE akkor jöhet a következö Z80-as kód és megint......

Ha jól értelmezem

Offline Zozosoft

  • Global Moderator
  • EP addict
  • *
  • Posts: 14723
  • Country: hu
    • http://enterprise.iko.hu/
Re: Lua scriptek fejlesztése
« Reply #12 on: 2009.September.23. 20:14:37 »
A breakPointCallback függvény utána minden töréspontnál lefut.
De ugye jól értem, hogy ezen példa esetén ez magától nem történik meg, hanem kézzel kell töréspontot beállítani?
És ha jól túrom a readme-t, akkor egy teljesen automata LUA-hoz kell az elejére egy setBreakPoint(bptype, addr, priority)?

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Lua scriptek fejlesztése
« Reply #13 on: 2009.September.23. 20:30:48 »
De ugye jól értem, hogy ezen példa esetén ez magától nem történik meg, hanem kézzel kell töréspontot beállítani?

Igen.

Quote
És ha jól túrom a readme-t, akkor egy teljesen automata LUA-hoz kell az elejére egy setBreakPoint(bptype, addr, priority)?

Valóban (itt a bptype-nak 4-nek kellene lennie a Z80 utasítás olvasáshoz). A scriptben beállított vagy törölt töréspontok azonban nem jelennek meg a GUI töréspont szerkesztőben, így az visszaállítható az Apply gombra kattintással.

Offline IstvanV

  • EP addict
  • *
  • Posts: 4822
Re: Lua scriptek fejlesztése
« Reply #14 on: 2009.September.24. 17:09:59 »
Nem tudom, hogy ez hasznos-e valakinek, de itt egy részletesebb leírás a Spectrum programok attribútum és I/O műveleteit figyelő zxiolog.lua script működéséről:

Code: Lua
  1. for i = 0x5800, 0x5AFF do
  2.   setBreakPoint(1, i, 3)
  3.   setBreakPoint(2, i, 3)
  4. end

Ez a ciklus töréspontot állít be 5800h és 5AFFh között - azaz az attribútum területen - minden byte olvasására (bpType=1) és írására (bpType=2) is. A "prioritás" paraméter 3, azaz a legnagyobb.

A "for" ciklus használata részletesebben:
  for VÁLTOZÓ = ÉRTÉK1, ÉRTÉK2[, LÉPÉS] do
    ...
  end

Ha a lépés nincs megadva, akkor az alapértelmezése 1. A változó "local" típusú, azaz csak a ciklusban lesz elérhető, és a kezdőértéke az első paraméter. A ciklusmag addig fut, amíg a változó kisebb vagy egyenlő (ha a lépés pozitív), vagy nagyobb vagy egyenlő (ha a lépés negatív) a második paraméterrel, és minden futása után a változóhoz hozzáadja a lépésnek megadott értéket. A "break" utasítással korábban is ki lehet lépni a ciklusból.

Code: Lua
  1. setBreakPoint(5, 0xFE, 3)
  2. setBreakPoint(6, 0xFE, 3)

I/O olvasás (5) és írás (6) töréspont beállítása az FEh portra, 3-as prioritással. A billentyűzet és hang kezelését figyeli.

Code: Lua
  1. setBreakPoint(4, 0x0000, 3)

Z80 utasítás olvasás (4) töréspont a 0000h címen, a RESET gomb megnyomásához (arra fejeződik majd be a script futása).

Code: Lua
  1. attrReadMap = {}
  2. attrWriteMap = {}
  3. ioFEReadMap = {}
  4. ioFEWriteMap = {}

Ez létrehoz 4 üres táblázatot (tömböt) annak tárolására, hogy milyen címeken történtek ilyen műveletek.

Code: Lua
  1. for i = 0x0000, 0xFFFF do
  2.   attrReadMap[i] = false
  3.   attrWriteMap[i] = false
  4.   ioFEReadMap[i] = false
  5.   ioFEWriteMap[i] = false
  6. end

A fenti ciklus inicializálja a tömböket. A Lua nyelvben a táblázatok címzésére valójában bármilyen adattípus használható, akár törtek vagy szöveg is, és az egyes elemeknek a típusa is tetszőleges lehet (akár ugyanazon a táblázaton belül keverve is). Ezek a táblázatok a 0 és FFFFh közötti egész számokhoz rendelnek "boolean" értéket, amely azt jelzi, hogy az adott Z80 címről történt-e az adott művelet (pl. attribútum írás).

Code: Lua
  1. function breakPointCallback(t, a, v)
  2.   if t == 1 or t == 2 then
  3.     if a >= 0x5800 and a < 0x5B00 then
  4.       if (getMemoryPage(1) == 0xFD or getMemoryPage(1) == 0xFE) and
  5.          getMemoryPage(SHR(getPC(), 14)) >= 0x80 then
  6.         if t == 1 then
  7.           attrReadMap[getPC()] = true
  8.         else
  9.           attrWriteMap[getPC()] = true
  10.         end
  11.       end
  12.       return false
  13.     end

A töréspontok elérésekor meghívandó függvény eleje.
Itt, ha a hozzáférés típusa (t) 1 (memória olvasás) vagy 2 (memória írás), akkor:
  ha a cím (a) 5800h és 5AFFh között van, akkor:
    ha az 1. lapon az FDh vagy FEh szegmens van, és a Z80 programszámláló nem a 0-7Fh szegmenseken van (az SHR() függvény az első megadott paramétert lépteti jobbra a másodiknak megadott számú bittel, ugyanez balra az SHL() lenne; a getMemoryPage() a megadott lapon (0-3) levő szegmenst adja vissza):
      a megfelelő táblázatban megjelöli a programszámláló aktuális pozícióját;
    visszatér false értékkel, azaz nem jelenik meg a debugger ablak

Code: Lua
  1.   elseif t == 5 or t == 6 then
  2.     if AND(a, 0xFF) == 0xFE then
  3.       if getMemoryPage(SHR(getPC(), 14)) >= 0x80 then
  4.         if t == 5 then
  5.           ioFEReadMap[getPC()] = true
  6.         else
  7.           ioFEWriteMap[getPC()] = true
  8.         end
  9.       end
  10.       return false
  11.     end

Az előbbi "if" utasítás folytatása, ezúttal 5 (I/O olvasás) és 6 (I/O írás) típusú hozzáférésekhez:
  ha a cím alsó 8 bitje FEh:
    ha a Z80 programszámláló nem a 0-7Fh szegmenseken van:
      megjelöli a programszámlálónak megfelelő címet az I/O olvasás vagy írás táblázatban;
    visszatér false értékkel, azaz nem jelenik meg a debugger ablak

Code: Lua
  1.   elseif t == 0 and a == 0x0000 then
  2.     clearBreakPoints()
  3.     f = io.open("zxiolog.txt", "w")
  4.     for i = 0x0000, 0xFFFF do
  5.       if attrReadMap[i] then
  6.         f:write(string.format("%04X: AR\n", i))
  7.       end
  8.       if attrWriteMap[i] then
  9.         f:write(string.format("%04X: AW\n", i))
  10.       end
  11.       if ioFEReadMap[i] then
  12.         f:write(string.format("%04X: IOR\n", i))
  13.       end
  14.       if ioFEWriteMap[i] then
  15.         f:write(string.format("%04X: IOW\n", i))
  16.       end
  17.     end
  18.     f:close()
  19.     return true

Végül a RESET figyelése: ha Z80 utasítás olvasás (t=0) történik a 0000h címről, akkor törli a töréspontokat, hogy a script ne fusson le újra, megnyitja a "zxiolog.txt" nevű file-t írásra szöveges módban (bináris file-hoz "w" helyett "wb" kellene), majd kiírja a táblázatok tartalmát.
Az f:write() az "f" file-ba írja a paraméternek megadott szöveg típusú adatot (egy byte (N) írásához f:write(string.char(N)) kellene). A string.format() formázott szöveget hoz létre a megadott (C sprintf() függvényhez hasonló) formátum alapján. A "%04X" azt jelenti, hogy a megfelelő paramétert (i) nagybetűs hexadecimális formában (X), balról nullákkal 4 számjegyre kiegészítve kell kiírni.
Végül bezárja a file-t (f:close()), és true értékkel visszatér, tehát megjelenik a debugger ablak.

Code: Lua
  1.   end
  2.   return true
  3. end

A töréspont típusát vizsgáló "if" utasítás lezárása; ha a töréspont nem a script által figyelt típusú vagy című, akkor true a visszatérési érték, azaz a debugger ablak megjelenik.
« Last Edit: 2009.September.24. 17:13:11 by IstvanV »