2015-03-21 22 views
5

Yazılım gecikmesi oluşturmaya çalışıyorum. O kadar kayıt B yüklemek için gereken sabit değerini hesaplamak nasılZ80 Yazılım Gecikmesi

Address Data Opcode Comment  
    1800  06 LD, B Load register B with fix value 
    1801  “ “   Fixed value 
    1802  05 DEC, B Decrement value in register B 
    1803  C2 JP cc Jump to 1802 if value is not 0 
    1804  02 -  Address XX 
    1805  18 -  Address XX 

Benim sorum 0 2 saniye sürer kadar değer kademeli olarak azaltılması süreci: Burada ne yaptığımı örnek bir programdır?

Kılavuzumda, talimatları çalıştırmak için verilen süre bir 4MHz CPU'ya dayanmaktadır, ancak kullandığım Z80 CPU'nun hızı 1,8MHz'dir. Bunu nasıl hesaplayabilirim? Teşekkürler. sizin için gecikme gerekiyordu 1.8MHz tarafından tam olarak 1.800.000 Hz demek

Instruction M Cycles T states 4 MHz E.t 
DEC r    1   4   1.00 
JP cc    3  10 (4,3,3) 2.50 

cevap

3

, sonra 2 saniyelik bir gecikme almak için: PS burada eksiltme (DEC) ve sıçrama (JP cc) manuel talimatlar olduğunu 3,600,000 T-durumu. Geçerli gecikme döngüsünüz yineleme başına 14 T-durumu alır; bu, B için başlangıç ​​değerinizin bir baytta sığmayacak şekilde 3600000/14 == 257143 olması gerektiği anlamına gelir.

8 bitlik bir kayıtla belirleyebileceğiniz en fazla yineleme sayısı 256'dır ve 256 yinelemeli 3.600.000 T durumuna ulaşmak için her yineleme 14.062 T durumu almalıdır. Bu bir büyük döngü gövdesidir.

16 bitlik bir sayaç kullanırsak, biraz daha yönetilebilir hale gelir. 65.536 yinelemede, toplam 3.600.000 T-durumuna ulaşmak için yalnızca iterasyon başına 55 T-durumuna ihtiyaç duyarız. Aşağıda böyle görüneceği ile ilgili bir örnek:

; Clobbers A, B and C 
    ld  bc,#0 
1$: 
    bit  #0,a ; 8 
    bit  #0,a ; 8 
    bit  #0,a ; 8 
    and  a,#255 ; 7 
    dec  bc  ; 6 
    ld  a,c  ; 4 
    or  a,b  ; 4 
    jp  nz,1$ ; 10, total = 55 states/iteration 
    ; 65536 iterations * 55 states = 3604480 states = 2.00248 seconds 
+0

oops. Z80'den beri biraz zaman geçti. –

2

Ben bir optimizasyon ucube biraz değilim, bu yüzden burada (TASM assembler ve benzeri itibaren) Ben en tanıdık olduğum ile sözdizimini kullanarak zaman git :

Instruction opcode timing ld bc,$EE9D ;01EE9D 10cc ex (sp),hl ;E3 19*(256C+B) ex (sp),hl ;E3 19*(256C+B) ex (sp),hl ;E3 19*(256C+B) ex (sp),hl ;E3 19*(256C+B) djnz $ ;10FA 13cc*(256C+B) - 5*C dec c ;0D 4*C jr nz,$-3 ;20F7 12*C-5

Bu kod 12 byte ve 3.600.002 saat devri olduğunu.

EDIT: Cevabımın bir kısmı gitmiş gibi görünüyor! Sorunuzu daha iyi cevaplamak için Z80'niz bir saniyede 1800000 saat döngüsünü işleyebilir, böylece iki katına (3600000) ihtiyacınız vardır. Benim koduyla verilir zamanlamaları kadar eklerseniz elde edersiniz: -5C + 4C + 12C-5

= 5 + (256C

= 10 + (256C + B) (+ 13 19 * 4) + B) 89 + 11C

= 5 + 22795C +)

89B Yani kod zamanlama yaklaşık 157 olan C 3600000/22795 büyük ölçüde bağlıdır, bu nedenle 157 (0x9D ile C başlatmak. Bunu tekrar takarsak, B'yi 237.9775 olarak alırız, bu yüzden bunu 238'e (0xEE) kadar tamamlarız. Bunları takmak, 3600002cc'lik son zamanımızı veya yaklaşık 2.000001 saniyeyi alır. Bu, işlemcinin tam olarak 1,8 MHz hızında çalıştığını varsaymaktadır ki bu da olası değildir.

Ayrıca, kesmeleri kullanabiliyorsanız, saniyede kaç kez ateş ettiğini ve halt \ djnz $-1 gibi bir döngü kullanmayı düşünün. Bu, güç tüketimi açısından çok daha fazla tasarruf sağlar.

+0

"Bu, güç tüketimi açısından çok daha fazla tasarruf ediyor". Bu ifadenin gerçekte doğru olduğundan emin değilsiniz. HALT, maskelenebilir bir kesinti oluşana kadar NOP işlemlerini tekrarlar. Farklı op kodlarının, diğerlerinden daha fazla veya daha az güç tüketimine neden olduğunu düşünmedim. Yine de yanlış olabilirim. –