From 61720e925d2624cfae9b596413de9f55b508ce62 Mon Sep 17 00:00:00 2001 From: giomba Date: Sun, 15 Oct 2023 15:09:10 +0200 Subject: [PATCH] Add busy loop delay module. --- src/delay.asm | 35 +++++++++++++++++++++++++++++++++++ src/delay.h | 25 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/delay.asm create mode 100644 src/delay.h diff --git a/src/delay.asm b/src/delay.asm new file mode 100644 index 0000000..1870081 --- /dev/null +++ b/src/delay.asm @@ -0,0 +1,35 @@ +SECTION code + +PUBLIC _delay_loop +_delay_loop: + ; function prologue: use IX to index parameters passed on the stack + push ix ; 15 + ld ix,$0000 ; 14 + add ix,sp ; 15 + + ; save scratch registers + push af ; 11 + push de ; 11 + + ; load loop counter into DE + ld d,(ix+$05) ; 19 + ld e,(ix+$04) ; 19 + + ; delay loop (24 × n) +_delay_loop_loop: + dec de ; 6 + ld a,d ; 4 + or e ; 4 + jp nz,_delay_loop_loop ; 10 + + ; restore scratch registers + pop de ; 10 + pop af ; 10 + + ; restore IX + pop ix ; 14 + + ret + + + diff --git a/src/delay.h b/src/delay.h new file mode 100644 index 0000000..08956e8 --- /dev/null +++ b/src/delay.h @@ -0,0 +1,25 @@ +#ifndef CEDA_DELAY_H +#define CEDA_DELAY_H + +/* + Assuming a Z80 CPU running at 4MHz, the chosen assembly loop + permits busy loops withing the following specs: + + min: 37 us + max: 393253 ms + precision: 6 us + + For example, to wait for 50 us use the following. + This will actually busy wait for 47 us due to precision losses. + delay_us(US_TO_LOOPS(50)); +*/ + +#include + +#define CPU_FREQ 4000000UL // 4 MHz + +#define US_TO_LOOPS(t) ((((t)*CPU_FREQ / 1000000UL) - 148) / 24) + +void delay_loop(uint16_t loops); + +#endif // CEDA_DELAY_H