Page 1 of 2

Delay loops in asembly

Posted: Wed Aug 29, 2018 4:48 am
by Atlantis
I am trying to add HD44780 character display to my 6502 project.
Currently I do not have any timer which could be used for convenient time keeping and implementation of delay loops - it will be added with the next I/O board. Until then I need some workaround, because initialization routine of HD44780 requires several waiting periods, before busy flag becomes accessible.

Is there a easy way to calculate how much time simple loop takes to complete on specific 6502 CPU, clocked with specific frequency? And then execute that loop as many times as necessary? Simply speaking i need an equivalent of delay_us() and delay_ms() functions.

Re: Delay loops in asembly

Posted: Wed Aug 29, 2018 5:34 am
by BigEd
Is there an easy way? Well, you need to count cycles. You can do that by hand, looking up cycle counts in documentation, or you can run a suitable simulator like visual6502, or (possibly) Kowalski's emulator.

Or, perhaps someone has already done the work... here's a usenet posting:
Quote:
For my usual loop:

Code: Select all

        ldy  #ycnt   ; (2 cycles)
        ldx  #xcnt   ; (2 cycles)
delay   dex          ; (2 cycles)
        bne  delay   ; (3 cycles in loop, 2 cycles at end)
        dey          ; (2 cycles)
        bne  delay   ; (3 cycles in loop, 2 cycles at end)
To convert from cycles to milliseconds, you need to know the clock frequency of your 6502.

Re: Delay loops in asembly

Posted: Wed Aug 29, 2018 5:57 am
by JenniferDigital
Don't forget that the times required for the HD44780 and compatibles, as far as I can remember are minimum times, so it's ok to be a few cycles over. Also, there's the busy flag you can use after initialisation. That will allow your code to run as fast as the display will allow.

Re: Delay loops in asembly

Posted: Wed Aug 29, 2018 6:02 am
by GARTHWILSON
Atlantis wrote:
I am trying to add HD44780 character display to my 6502 project.
Ed addressed the delay part, so I'll add a note about how to get a reliable reset on this type of display. We wasted a lot of time at work trying to get the LCD going consistently before someone faxed us an ap. note about this. (This was before the internet.) You can see it in my code at http://wilsonminesco.com/6502primer/LCDcode.asm, part of which is for the LCD-feeding circuit in the circuit potpourri page of my 6502 primer, at http://wilsonminesco.com/6502primer/potpourri.html#LCD .

Re: Delay loops in asembly

Posted: Wed Aug 29, 2018 6:27 am
by Atlantis
DigitalDunc wrote:
Don't forget that the times required for the HD44780 and compatibles are as far as I can remember are minimum times, so it's ok to be a few cycles over. Also, there's the busy flag ypu can use after initialisation. That will allow your code to run as fast as the display will allow.
I am going to use busy flag during normal operation. But delays are still needed for init/reset process.

Re: Delay loops in asembly

Posted: Wed Aug 29, 2018 10:23 pm
by BigDumbDinosaur
BigEd wrote:
or you can run a suitable simulator like visual6502, or (possibly) Kowalski's emulator.
The Kowalski simulator can report the execution time of a program, and by using the "step-in" function to execute the code immediately before the loop, it is possible to stop execution, reset the cycle count and then let the simulator run the rest of the code at full speed to complete the loop.

Re: Delay loops in asembly

Posted: Thu Aug 30, 2018 4:55 am
by BigEd
BigEd wrote:
... to count cycles... you can run a suitable simulator like visual6502, or (possibly) Kowalski's emulator..
(The reason I added "(possibly)" was that I'd a feeling we previously spotted one or two inaccuracies in Kowalski's cycle counting. It might be that these don't affect a given program, it might be they don't make a big enough difference, and it might be that Daryl's fixed it all up and his rebuild will do the job perfectly. Hence "possibly".)

Re: Delay loops in asembly

Posted: Fri Aug 31, 2018 5:19 am
by dclxvi
BigEd wrote:
Or, perhaps someone has already done the work...
For a simple, medium length, delay, I've used this:

Code: Select all

{               } ; delay 9*(256*A+Y)+8 cycles
{               } ; assumes that the BCS does not cross a page boundary
{               } ;
{ 8000 C0 01    } .1 CPY # 1 ; 2
{ 8002 88       }    DEY     ; 2
{ 8003 E9 00    }    SBC # 0 ; 2
{ 8005 D0 F9    }    BCS =.1 ; 3
A and Y are the high and low bytes (respectively) of a 16-bit value; multiply that 16-bit value by 9, then add 8 and you get the cycle count. So the delay can range from 8 to 589832 cycles, with a resolution of 9 cycles. One of the nice things about this code is that it's easy to figure out what values to put in A and Y when you want a delay of, e.g. (approximately) 10000 cycles.

Also, a good exercise for beginners is to analyze this routine and understand how it works (what, for example, is the purpose of the CPY?), and verify that the cycle count formula is correct.

Re: Delay loops in asembly

Posted: Fri Aug 31, 2018 5:27 am
by barrym95838
dclxvi wrote:

Code: Select all

{               } ; delay 9*(256*A+Y)+8 cycles
{               } ; assumes that the BCS does not cross a page boundary
{               } ;
{ 8000 C0 01    } .1 CPY # 1 ; 2
{ 8002 88       }    DEY     ; 2
{ 8003 E9 00    }    SBC # 0 ; 2
{ 8005 D0 F9    }    BCS =.1 ; 3
That level of efficiency causes my brain to do a little happy dance. Nicely done, sir!

Re: Delay loops in asembly

Posted: Fri Aug 31, 2018 5:36 am
by BigDumbDinosaur
BigEd wrote:
BigEd wrote:
... to count cycles... you can run a suitable simulator like visual6502, or (possibly) Kowalski's emulator..
(The reason I added "(possibly)" was that I'd a feeling we previously spotted one or two inaccuracies in Kowalski's cycle counting. It might be that these don't affect a given program, it might be they don't make a big enough difference, and it might be that Daryl's fixed it all up and his rebuild will do the job perfectly. Hence "possibly".)
I think Daryl's latest revision (1.2.14a) addressed the cycle count inaccuracies.

Re: Delay loops in asembly

Posted: Fri Aug 31, 2018 8:17 am
by GARTHWILSON
barrym95838 wrote:
That level of efficiency causes my brain to do a little happy dance. Nicely done, sir!
Yes! Bookmarked.

Re: Delay loops in asembly

Posted: Fri Aug 31, 2018 9:04 am
by BigEd
BigDumbDinosaur wrote:
I think Daryl's latest revision (1.2.14a) addressed the cycle count inaccuracies.
Great! Here's a link to the thread: (Probably that thread is the best place to link these days, now Daryl aka 8BIT has taken the reins.)

Re: Delay loops in asembly

Posted: Wed Sep 05, 2018 2:40 pm
by cbmeeks
GARTHWILSON wrote:
before someone faxed us an ap. note about this. (This was before the internet.)
It's always fun walking into a store and finding a young person working there and ask them if they have a fax machine. The puzzled looks are priceless.

Like that time my kid first saw a payphone and wondered what it was. LOL

Re: Delay loops in asembly

Posted: Fri Sep 07, 2018 1:55 am
by BigDumbDinosaur
cbmeeks wrote:
GARTHWILSON wrote:
before someone faxed us an ap. note about this. (This was before the internet.)
It's always fun walking into a store and finding a young person working there and ask them if they have a fax machine. The puzzled looks are priceless.

Like that time my kid first saw a payphone and wondered what it was. LOL
I've got a Stromberg-Carlson type 500 dial phone from the 1960s. The first time our oldest grandson saw it he was completely baffled by that round thing with the holes in it on the phone's face. :shock:

OT: telephony nostalgia

Posted: Fri Sep 07, 2018 10:33 am
by BigEd
Hey, if you don't know how to operate the round thing, you can always dial by hook-flashing... defeats dial-locks too! So I hear.

In fact, that could be a useful application for a delay loop.