Z80 software delay

I am trying to create a software delay. Here is an example of what I am doing:

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 

My question is, how can I calculate the required fixed value to load into register B, so that the process of decreasing the value to 0 takes 2 seconds?

In my guide, the time set to start the instructions is based on a 4 MHz processor, but the Z80 processor that I use has a speed of 1.8 MHz. Any idea how I can calculate this? Thank you PS here are the decrement (DEC) and transition (JP cc) instructions from the manual:

 Instruction M Cycles T states 4 MHz Et DEC r 1 4 1.00 JP cc 3 10 (4,3,3) 2.50 
+5
source share
2 answers

If at 1.8 MHz you mean exactly 1800 000 Hz, then to get a 2 second delay you will need to defer up to 3,600,000 T-states. Your current delay cycle takes 14 T-states per iteration, which means that your initial value for B should be 3600000/14 == 257143, which obviously will not be in one byte.

The largest number of iterations that you could specify with an 8-bit register is 256, and to reach 3,600,000 T-states with 256 iterations, each iteration must take 14,062 T-states. This is one big body of the cycle.

If we use a 16-bit counter, we will begin to become a little more manageable. At 65,536 iterations, we only need 55 T-states per iteration to achieve a total of 3,600,000 T-states. The following is an example of how this might look:

  ; 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 
+3
source

I'm a bit of an optimizer, so here is my move using the syntax that I'm most familiar with (from TASM assembler, etc.):

 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 

This code is 12 bytes and 3600002 clock cycles.

EDIT . It seems like part of my answer is gone! To better answer your question, your Z80 can process 1800000 clock cycles in one second, so you need twice as much (3600000). If you add the timings indicated in my code, you will receive:

= 10 + (256C + V) (19 * 4 + 13) -5C + 4C + 12C-5

= 5 + (256C + V) 89 + 11C

= 5 + 22795C + 89B

Thus, the code time largely depends on C. 3600000/22795 - about 157, so we initialize C with 157 (0x9D). Inserting this back, we get B about 237.9775, so we round up to 238 (0xEE). When connecting these devices, we get a final time of 3600002cc or about 2.000001 seconds. This suggests that the processor runs at exactly 1.8 MHz, which is very unlikely.

Also, if you can use interrupts, find out how many times it fires per second, and use a loop like halt \ djnz $-1 . This saves a lot more in terms of energy consumption.

+2
source

Source: https://habr.com/ru/post/1215821/


All Articles