Újabb script magyarázat (hátha érdekel valakit
![Smiley :)](/Smileys/phpbb/smiley.gif)
). Ezúttal a
dtftimer.lua, amely az 1-es csatorna megnyitása és bezárása közötti időt méri:
totalTime = 0.0
clearBreakPoints()
timerOn = false
prvState = 0
for i = 0, 0xFFFF do
setBreakPoint(4, i, 3)
end
setBreakPoint(6, 0xA7, 3)
Inicializálás: a
totalTime változó az 1-es csatorna megnyitása után összesen eltelt időt számolja majd másodpercekben. A
timerOn azt jelzi, hogy az időmérés éppen fut-e, az 1-es csatorna megnyitásáig
false marad. A
prvState pedig az 1 kHz-es DAVE időzítő előző állapota (0 vagy 1).
Minden lehetséges címre Z80 utasítás olvasás töréspont kerül, így a breakPointCallback() függvény biztosan elég gyakran fut le ahhoz, hogy az időzítő minden állapotváltozását érzékelje.
Az A7H I/O port írását szintén figyelni kell:
function breakPointCallback(t, a, v)
if t == 6 then
if AND(a, 0xFF) == 0xA7 then
if AND(v, 0x60) >= 0x40 and timerOn then
timerOn = false
clearBreakPoints()
mprint("ERROR: sound generator IRQ is not supported")
return true
end
end
Ennek a portnak az írása megváltoztathatja az időzítő sebességét. A hanggenerátor megszakítást (5. és 6. bit 10B vagy 11B) azonban a script nem támogatja, tehát abban az esetben hibával leáll.
elseif a == 0x0030 then
returnAddr = OR(readMemory(getSP()), SHL(readMemory(getSP() + 1), 8))
exosFunc = readMemory(returnAddr)
chanNum = getA()
if exosFunc == 1 and chanNum == 1 and not timerOn then
timerOn = true
totalTime = 0.0
return false
elseif exosFunc == 3 and chanNum == 1 and timerOn then
timerOn = false
clearBreakPoints()
mprint(string.format("%.3f seconds", totalTime))
return true
end
end
Itt történik az EXOS csatorna megnyitás és bezárás hívások figyelése. A veremből kiolvassa a visszatérési címet, majd onnan az EXOS hivás kódját. Ha ez 1, és az A regiszter (csatornaszám) is 1, és az időmérés még nem fut, akkor az elindulhat 0 időtől kezdve. Egyébként ha EXOS 3 hívás van az 1-es csatornára és fut az időmérés, akkor a töréspontok törlése után - hogy a breakPointCallback() ne hívódjon meg újra - kiírható a mért idő. A
string.format-nál a
%.3f azt jelenti, hogy a paramétert (
totalTime) lebegőpontos számként kell kiírni fix 3 tizedesjegy pontossággal.
curState = AND(readIOPort(0xB4), 1)
if curState ~= prvState then
prvState = curState
tickTime = 0.001
timerMode = AND(readIOPort(0xA7), 0x60)
if timerMode >= 0x40 then
timerOn = false
clearBreakPoints()
mprint("ERROR: sound generator IRQ is not supported")
return true
end
Ez pedig az időmérés: a B4H port 0. bitjének (az 1 kHz/50 Hz/hanggenerátor időzítő aktuális állapota) a változását érzékeli. Ha ez megtörténik, akkor elmenti az új állapotot a
prvState-be, és az A7H és BFH port alapján megpróbálja kiszámítani, hogy mennyi idő telt el. A hanggenerátor megszakítás mód itt is hibát eredményez, egyébként az alapértelmezés 1 ms.
if timerMode == 0x20 then
tickTime = 0.02
end
if AND(readIOPort(0xBF), 0x02) ~= 0 then
tickTime = tickTime * 1.5
end
totalTime = totalTime + tickTime
end
return false
end
Ha az A7H port 5. és 6. bitje 01B, akkor a megszakítás sebessége csak 50 Hz (20 ms). A BFH port 1. bitjének beállítása (12 MHz-es rendszer órajel feltételezése) esetén az időegységet a másfélszeresére kell növelni. Ez végül hozzáadható az eltelt időhöz (
totalTime), és a függvény visszatér a debugger ablak megjelenítése nélkül.
Az eredeti verzióban egyébként volt egy hiba: BFH port helyett B4H volt
![ds_icon_redface :oops:](/Smileys/phpbb/ds_icon_redface.gif)
Kicseréltem javítottra.