6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon Apr 29, 2024 7:28 am

All times are UTC




Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Delay routines
PostPosted: Tue Feb 03, 2015 5:55 pm 
Offline
User avatar

Joined: Sun Sep 08, 2013 10:24 am
Posts: 740
Location: A missile silo somewhere under southern England
Hi guys

What do you folks use for delay routines? Primarily, I wish to use it with the LCD module I ahve connected, but this will no doubt come up again.
Currently I use a NOP loop, but I suspect that there is a better way. Perhaps using a VIA timer? Or would adding a real time clock IC be better (interfaced with a VIA) - although that might not be so great if trying to measure milliseconds.


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Tue Feb 03, 2015 6:24 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8155
Location: Midwestern USA
banedon wrote:
What do you folks use for delay routines? Primarily, I wish to use it with the LCD module I ahve connected, but this will no doubt come up again.
Currently I use a NOP loop, but I suspect that there is a better way. Perhaps using a VIA timer? Or would adding a real time clock IC be better (interfaced with a VIA) - although that might not be so great if trying to measure milliseconds.

Using a VIA timer will work, and could be used to generate a jiffy IRQ for general timekeeping purposes. Plus you can readily change the interval rate by merely writing a new value into the timer latch.

In my POC unit, I have a Maxim DS1511 real-time clock that generates a 10ms jiffy IRQ, which gives me a convenient time delay source via a 16 bit down counter that gets updated at one second intervals (there's also a 32 bit interrupt-driven uptime counter). I have another time source in the counter/timer (C/T) that is part of the 26C92 DUART. The C/T is driven from the 3.6864 MHz clock used by the DUART's baud rate generator and can generate intervals as short as 820ns.

My only beef with using a VIA timer for timekeeping purposes is that the timer is synched to the Ø2 clock, rather than a separate time base. Changing the Ø2 frequency will affect anything that is dependent on timer operation.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Tue Feb 03, 2015 8:06 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
Consider three general ranges of delay:
  • super short (like a few microseconds, like you might need for the LCD)
  • medium (like fractions of a second, to time light flashes or key debouncing)
  • long (like many seconds or minutes or hours or longer)

For really short delays, a software delay loop is often the best. In some cases though, software timing loops for delays are not acceptable because the computer has far too much to do to be stopping and twiddling its thumbs for the duration of the delay. That's especially true when it must time several things at once and the timing of one event cannot be allowed to interfere with the timing of other ones.

I use the free-running T1 in a VIA producing regular, evenly spaced interrupts, not to directly time individual events but as a base for an interrupt-driven software real-time clock (RTC) (as BDD was talking about). On my workbench computer, it has 10ms resolution. On various microcontroller projects for work, the resolution has been arbitrary and usually much finer. At each T1 interrupt, you increment the RTC counter variable in RAM. What you do then is that when you begin timing something, you read the RTC counter variable bytes and add the desired time to that, and keep a record of the result in another variable, then let the computer do other useful stuff while waiting for that time to arrive. As you cycle through the various things that need attention, each time it comes back to the routine for the thing you're timing, you compare the current time to the target time and see if you're there yet. If you're not, go do other useful things.

For the longest delays, you can add alarms to the RTC above. I've done this for making measurements every 15 minutes for example and printing them out. The computer is doing something else, and every 15 minutes it takes care of this job and then goes back to what it was doing (which may have other timed processes).

These things are written up in more detail (and probably more clearly as I put more time and care into it), with example code, in my article on simple methods for multitasking without a multitasking OS, at http://wilsonminesco.com/multitask/index.html .

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Wed Feb 04, 2015 3:05 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 387
Location: Minnesota
In a single-tasking environment where you have total control you can do whatever you want. I've used the Time-of-Day (TOD) clock of a 6526 CIA to implement delays lasting seconds during which the computer did nothing but watch to see if the desired time period had elapsed (but it was okay, the program had nothing to do but wait for the period to expire).

One advantage of using hardware instead of software for delays is that it is unaffected by interrupts; an interrupt-driven software "clock" can get thrown off if interrupts are turned off for any length of time. For periods longer than hardware can easily handle, a hybrid approach is to use a hardware timer to correct any slippage in a software clock.


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Wed Feb 04, 2015 6:25 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
The software RTC I spoke of is run by having an interrupt every 10ms from the VIA's free-running T1. The ISR (interrupt service routine) increments the time record in RAM. So although it's software, it is firmly governed by the hardware timer, regardless of other interrupts going too, and you can be running lots of things at once without the RTC slipping. I put the one VIA on NMI\, mostly to cut the polling overhead when the other VIAs and ACIAs are on IRQ\, since I seldom turn off the RTC whereas other interrupt sources are enabled and disabled depending on what I'm doing at the moment. Admittedly I do have to turn it off when I need low jitter on audio digitizing whose samples are timed by another VIA's T1. That problem is minor, but eventually I want to implement an I²C RTC in 8-pin DIP, an NXP PCF8593 which has an alarm interrupt output, unlike the Maxim/Dallas one discussed in another recent topic. Although the VIA used for the RTC time source is on NMI\, you can still turn it off by clearing the T1 interrupt-enable bit in the VIA's IER (interrupt enable register).

For routines for short delays (without an RTC), see the 6502.org wiki page at http://6502org.wikidot.com/software-delay .

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Wed Feb 04, 2015 7:49 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8155
Location: Midwestern USA
GARTHWILSON wrote:
The software RTC I spoke of is run by having an interrupt every 10ms from the VIA's free-running T1. The ISR (interrupt service routine) increments the time record in RAM.

That is very similar to what I do in POC, except the watchdog timer in the DS1511 generates the jiffy IRQ, also at 10ms intervals. Each jiffy IRQ updates a one byte counter that starts at zero. When it reaches $64 (100), the uptime counter, a 32 bit value, is incremented, and the time delay counter, a 16 bit value is decremented. As this is running on a 65C816 in native mode, the processing is succinct, since at most, two R-M-W operations are required to increment the uptime counter. All of this processing is skipped if the IRQ source is not the watchdog timer.

Here's the code that does the timekeeping:

Code:
;—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—
;
;RTC INTERRUPT PROCESSING
;
iirq02   pla                   ;recover RTC control register...
;
;   —————————————————————————————————————————————————————————————————————
;   The control register is read & stored early in the interrupt handler.
;   The read operation automatically clears the pending IRQ.
;   —————————————————————————————————————————————————————————————————————
;
         bit #d11ismsk         ;watchdog interrupt?
         beq iirq03            ;no, skip ahead...
;
;   —————————————————————————————————————————————————————————————————
;   The watchdog timer is the only interrupt source programmed in the
;   in the RTC.  Any other interrupt would be spurious.
;   —————————————————————————————————————————————————————————————————
;
;
;   process time delay counter...
;
         longa                 ;16 bit accumulator & memory
         ldx tdirqct           ;msecs*10 counter (8 bits)
         bne .iirq020          ;not zero, just decrement
;
         lda tdsecct           ;seconds counter
         beq .iirq030          ;done
;
.iirq010 dec tdsecct           ;secs=secs-1
         ldx #hz+1             ;reset msecs
;
.iirq020 dex                   ;msecs=msecs-10
         stx tdirqct           ;new counter value
;
;
;   process uptime counter...
;
.iirq030 ldx utirqct           ;msecs*10 counter
         inx
         cpx #hz               ;reach 1 sec?
         bcc .iirq040          ;no
;
         ldx #0                ;reset msecs*10 counter
         inc utsecct           ;bump uptime LSW...
;
;   ——————————————————————————————————————————————————————————————————
;   LSW is least significant word,  Similarly, MSW is most significant
;   word.
;   ——————————————————————————————————————————————————————————————————
;
         bne .iirq040          ;done with uptime
;
         inc utsecct+s_word    ;bump uptime MSW
;
.iirq040 stx utirqct           ;new msec*10 counter value

All timer values are stored on direct page. In the above code, hz is the jiffy interrupt rate in IRQs per second (100 in this case) and s_word is the size of a 65C816 word in bytes (2 in this case). I never embed values like that directly into instructions, as it's too easy to mistype a number and introduce a pernicious bug.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Wed Feb 04, 2015 8:01 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8155
Location: Midwestern USA
teamtempest wrote:
In a single-tasking environment where you have total control you can do whatever you want. I've used the Time-of-Day (TOD) clock of a 6526 CIA to implement delays lasting seconds during which the computer did nothing but watch to see if the desired time period had elapsed (but it was okay, the program had nothing to do but wait for the period to expire).

Th CIA also had a TOD alarm function, which could be used to interrupt the foreground some time in the future. As was typical of many MOS Technology I/O chip designs, there was a bug associated with TOD alarms, as well as with timer-B interrupts, although not present in all devices. The workaround for the TOD alarm bug was to set the alarm time 0.1 second register to a non-zero value. There was no hardware workaround for the timer-B interrupt bug if it was present.

In the record and file locking code I concocted for use with the Lt. Kernal hard drive subsystem ISAM driver I wrote, I used the TOD's 0.1 seconds register to produce random time delays to detect and prevent contention between workstations on a multiplexed system. The TOD was nudged into action as part of the ISAM driver startup routine and polled in a loop when a delay was needed. The loop polled for a change in the register, which could happen in as little as a few microseconds or could take as long as 100 milliseconds to occur. It all depended on when the polling loop was entered, which gave it a good deal of randomness.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Wed Feb 04, 2015 10:00 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3349
Location: Ontario, Canada
Delay routines, eh? :) Reminds me of the Diablo daisy-wheel printers I reverse-engineered years ago. A fascinating design -- it was amazing how much was achieved using so little! I'm talking about 4 axes of simultaneous motion controlled in real-time by a primitive, discrete-TTL CPU that had no counter/timer and no interrupts. :shock: :!:

The loop (simplified substantially) ran something like this:

  • if necessary, update the print-wheel servo
  • if necessary, update the carriage servo
  • if necessary, issue a pulse to the ribbon-advance stepper motor
  • if necessary, issue a pulse to the paper-advance stepper motor
  • (repeat)

The missing ingredient is regularity. To properly regulate mechanical motion the updates need to be issued at predictable intervals! That won't happen if the loop is free-running (allowed to iterate continuously). The execution time is too widely variable.

One solution would be to rewrite the code for constant execution speed. Take, for example, the test for whether a print-wheel update is required. You either go do the update or go do a delay of equal duration. Same for all the other tasks in the loop -- either do them, or instead do an equivalent delay. In fact the code is full of conditional branches -- far more so than the summary suggests.

Such a scheme might work alright, but no way was there room for all those delay loops! Did I mention the program memory only held 512 instructions?

What they did was reserve one of their 32 bytes of RAM (!) as a sort of accumulator for delay. According to the result of significant conditional branches, the delay byte would have various values added to it -- and the resulting delay was postponed, not immediate.

The one-and-only delay loop was like a fifth task added to the list above. Only once per iteration would there be a pause, during which the CPU would decrement the delay accumulator and repeat until it reached zero. This had the desired effect of enforcing a speed limit on all four tasks. I believe the technique is known as a "paced loop."

On my web site there's more info about the discrete-TTL CPU -- including the actual schematic. Not much to it, but it ran those Diablo printers at 45 characters per second. The noise was like a cross between a weed-eater and a machine gun! :D

-- Jeff


Attachments:
DiabCPUcs 1458x1082.jpg
DiabCPUcs 1458x1082.jpg [ 275.9 KiB | Viewed 3132 times ]

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Thu Feb 05, 2015 10:16 pm 
Offline
User avatar

Joined: Sun Sep 08, 2013 10:24 am
Posts: 740
Location: A missile silo somewhere under southern England
I'll give the vIA timer a go. Just go to get my head around how to program it. :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Fri Feb 06, 2015 4:08 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
I recently worked on a simple BIOS for a 6551 and 6522 and used both timers, one for RTC and one for delays. I posted the BIOS in this post:

viewtopic.php?f=12&t=3045

It might be worth a look, the BIOS contains a extendable interrupt structure as well. The VIA isn't that difficult to code up, good luck.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Fri Feb 06, 2015 11:47 am 
Offline
User avatar

Joined: Sun Sep 08, 2013 10:24 am
Posts: 740
Location: A missile silo somewhere under southern England
Fantastic - many thanks, flooby :).

Can I ask which 6551 you're using?


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Fri Feb 06, 2015 1:40 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
I'm using some Rockwell 65C51P4 chips which work fine (at 4MHz). I also have some older NMOS 6551 (Rockwell, Syntertek, AMI) chips which work and one older W65C51 which I'm running at 10MHz but using a can oscillator for the baud clock as the internal clock is unstable with a crystal.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Fri Feb 06, 2015 6:33 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
floobydust wrote:
I'm using some Rockwell 65C51P4 chips which work fine (at 4MHz). I also have some older NMOS 6551 (Rockwell, Syntertek, AMI) chips which work and one older W65C51 which I'm running at 10MHz but using a can oscillator for the baud clock as the internal clock is unstable with a crystal.

Is that just the WDC part? As I put in tip #12 of the Tip of the Day column (that material is repeated on my website too), the capacitors of approximately 15 to 22 pF from the XTAL terminals of the 6551 ACIA to ground are not just to make the crystal frequency more acurate. If that were all they were for, you'd normally be close enough without them. But if you don't have a capacitor at least on XTAL 1 (the input) when using a crystal connected from XTAL 1 to XTAL 2, spurious components on the internal crystal oscillator's waveform may keep the baud rate generator from working. That was the only problem I've ever had with the '51. When I put the capacitors there 20+ years ago as recommended, it worked perfectly and always has since then, even with hanging a crystal right on the ACIA's pins, without using an external oscillator.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Fri Feb 06, 2015 7:26 pm 
Offline
User avatar

Joined: Sun Sep 08, 2013 10:24 am
Posts: 740
Location: A missile silo somewhere under southern England
floobydust wrote:
I'm using some Rockwell 65C51P4 chips which work fine (at 4MHz). I also have some older NMOS 6551 (Rockwell, Syntertek, AMI) chips which work and one older W65C51 which I'm running at 10MHz but using a can oscillator for the baud clock as the internal clock is unstable with a crystal.


My own build runs at 8MHz (10 is currently giving me some instability) and I want to a RS232 to it so the only choice is a WDC 65C51 - but am put off by the xmit bug. Does yours have this issue?


Top
 Profile  
Reply with quote  
 Post subject: Re: Delay routines
PostPosted: Fri Feb 06, 2015 7:49 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
Last year sometime, WDC sent me a few different LOT number W65C51 chips, all older and none are the same as what is currently shipping. They all seem to have some issues, but one does work quite well provided you use an external oscillator. I did have to add quite a few extra decoupling caps on the supply lines but it's been pretty stable at 10MHz and running for months. I'm thinking the 10MHz limit is more of the EEPROM (Atmel 28C256 150ns), but I need to put one of 70ns PLCC EEPROMs on the carrier I have which will allow me to use that and hopefully will be able to crank it a bit faster.

My board layout has the Xtal cap and regardless, it's unstable with a crystal. I did double up on the can oscillator frequency and am running with 38.4K baud however, which is nice. It interfaces directly to a FTDI UART/USB interface that installs in the DB-9 connector layout. Note that the newer, albeit defective W65C51 chips work fine with the Xtal on my board and the baud clock is very stable, just the fated xmit bit bug.

Also, as Mouser has stock again of the PDIP W65C51 chips, I opted to order one this week... same LOT number, same xmit bug, ugh.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 28 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: