6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri May 10, 2024 7:47 am

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Countdown prog
PostPosted: Mon Nov 18, 2002 5:17 pm 
Offline

Joined: Mon Nov 18, 2002 5:04 pm
Posts: 3
:shock: <- that's how I look !

Hello you guys!

I wonder if any of you guys can help me.

I have to make a homework, a tiny programme, which counts down a time and gives a beep at the end of the countdown using an IRQ service routine.

Conditions are:

The user should be able to enter a time in Hex-format e.g. 0F:59:1F (HH:MM:SS). Not valid inputs are supposed to prompt the user for a valid time. An invalid time could be 10:88:FF for example.

The rest of the programme should be easy. When the counter reaches 00:00:00 a sound should be produced using an IRQ Service Routine. The same Sound should be played (okay, play is maybe not the right expression for a pc-speaker-beep :D ) when pressing F10, also via the IRQ Service Routine.

I have problems with the programme because I don't know how to program the countdown. Does anyone have such a programme or can ne1 help me with that programmepart ?

Pleeze :?

Thanx in advance

Dansen

PS: I would be very pleased if anyone was able to create the programme within some minutes an post it here :wink:


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 18, 2002 6:40 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Are you sure that is the assignment? It would not make sense to do the beep as an ISR (Interrupt Service Routine) unless the timing were taken care of entirely in hardware that interrupts the processor only when the complete time has elapsed. The IRQ would be more appropriate for running an ISR every time a counter in a peripheral IC (like the 6522) times out, which may be 25 times per second or more. That way your program can remain productive doing other things while simultaneously keeping accurate time. Using the IRQ this way is much easier than doing a timing loop entirely in software. When the time reaches the desired value, you branch to the beep routine. Is this the assignment? What kind of peripheral ICs are you using with timer/counters?

Garth


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 18, 2002 7:23 pm 
Offline

Joined: Mon Nov 18, 2002 5:04 pm
Posts: 3
Hi Garth!

No, our task is exactly as described above. We're not using any peripherie, we have a private-programmed emulator for the 6502. And the alert shall be in a ISR as desribed, being run when the timer reaches 00:00:00 or when F10 is pressed on the keyboard.

Dennis


Top
 Profile  
Reply with quote  
 Post subject: Re: Countdown prog
PostPosted: Tue Nov 19, 2002 10:04 am 
Offline

Joined: Tue Sep 03, 2002 12:58 pm
Posts: 298
My guess would be that there's an interrupt coming at regular intervals. You're to decrement the counter on each interrupt, and trigger a beep when it reaches zero.

Is the interrupt set up for you, or do you have to initialise some simulated hardware yourself?

How do you produce the beep? There must be some simulated hardware to do it. Does writing to a particular location do it, or must you write a series of zeros and ones at the right frequency?

How is the start time input? Is it entered through a simulated keypad, or sitting in memory when you start?

And are you doing the same course as Pete, a couple of threads down? :-)

For decrementing the counter, I'd do something along the lines of

LDA #59
LDX seconds
DEX
STX seconds
BNE done
STA seconds
LDX minutes
DEX
STX minutes
BNE done
STA minutes
LDX hours
DEX
STX hours
done:

Pretty simple - read the current value, decrement it. If it is now negative, set it back to 60 and decrement the next value (so 1:23:00 goes to 1:22:59)

Note: there's a deliberate error in that code (and possibly a few unintentional ones too :-) so don't try to use it as it is. Work out what's wrong and fix it.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 19, 2002 11:40 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Maybe it's supposed to be an exercise in futility for the sake of learning why not to do it that way!

Suppose a clock speed of 4MHz, and 2-byte variable SECONDS in ZP:

Code:
                    ; number of cycles
                    ; (clock periods)
RUN_TMR:LDA    #93         ; 2
 rt3$:   LDX   #99         ; 2
 rt2$:    LDY  #87         ; 2
 rt1$:     DEY             ; 2
          BNE  rt1$        ; 3 usually
          DEX              ; 2
         BNE   rt2$        ; 3 usually
         DEA               ; 2
        BNE    rt3$        ; 3 usually, but 2 on one occurrence/second

                                  ; DEC_SEC usually takes 13 cycles
DEC_SEC:LDA    SECONDS     ; 3
        BEQ    ds1$        ; 2 usually
        DEC    SECONDS     ; 5
        BRA    RUN_TMR     ; 3
 ;-----------------
 ds1$:  LDA    SECONDS+1   ; 3
        BEQ    SOUND_ALARM ; 2 usually
        DEC    SECONDS+1   ; 5
        DEC    SECONDS     ; 5
        BRA    RUN_TMR     ; 3
 ;------------------
SOUND_ALARM:
        BRK
        BRK
   ; (continues here after software interrupt)
 ;----------------------------


Branches require 3 clock periods (750ns @ 4MHz) if the branch is taken, otherwise 2 (500ns @ 4MHz).  To avoid trying to compensate time for too many conditional branches (where the compensation itself has more conditional branches), it will be best to first convert the HH:MM:SS to a 16-bit number of seconds, which you store in SECONDS (low byte first) before running RUN_TMR.  This will give the finest control over the counting speed.  16 bits here is good for over 18 hours.

Every second, you have about 3.26 microseconds in DEC_SEC, meaning you'll need another 999,996.74, or 3,999,987 cycles at 4MHz in RUN_TMR.  Unfortunately, the A-X-Y set of nested loops above is off by a whopping .1%.  You might get it closer by trying other values to load the registers with, or expanding the loops with NOPs, or not have all loops nested; but the granularity might not allow you to get accuracy that we consider acceptable for a watch.  This is a very, very impractical, unreasonable way to try to accomplish the purpose!!!!

Furthermore, the microprocessor has no way to generate its own IRQ.  There is no reason to.  BRK, the software interrupt is similar, but has more-or-less outlived its usefulness.  BRK was mainly for patching PROMs back when they either could not be erased and reprogrammed, or the re-assembly and programming time just took too long.

By far, the better way to do the job is as John and I said, to have a hardware interrupt at regular intervals.  Every time there's an interrupt, the ISR advances the counter one step and compares to the desired value.  When that value is reached, the action is taken.  This way the accuracy is exactly that of the crystal, even if the computer spends most of its time doing something useful while waiting for the precise time to do the scheduled job.

See my 6502 interrupts primer.

Garth

_________________
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:
PostPosted: Wed Nov 20, 2002 11:42 am 
Offline

Joined: Mon Nov 18, 2002 5:04 pm
Posts: 3
Hello John, hello Garth

>My guess would be that there's an interrupt coming at regular intervals. >You're to decrement the counter on each interrupt, and trigger a beep >when it reaches zero.

Okay let's see! The countdown is supposed to go down only once. The Program should end after that.

>Is the interrupt set up for you, or do you have to initialise some >simulated hardware yourself?

We're using an emulator which has the following operation-system-jumps:

ClrScr @ $E000
CrLf @ $E003
WriteChr @ $E006
WriteNib @ $E009
WriteByt @ $E00C
Cursor @ $E012
ReadChr @ $E01E
ReadByt @ $E021
KeyTest @ $E033
Vmodus @ $E015 (switches between Text and Graphics Mode)
Sound @ $E070 (to produce a sound in Hz XREG = Hibyte ,YREG = LOWBYTE)
NoSound @ $E073 (to quit sound)

If you're interested I could mail you the emulator and some progs we've made so far...

>How do you produce the beep? There must be some simulated hardware >to do it. Does writing to a particular location do it, or must you write a >series of zeros and ones at the right frequency?

s.a.

>How is the start time input? Is it entered through a simulated keypad, or >sitting in memory when you start?

via the keyboard of the personal computer

>And are you doing the same course as Pete, a couple of threads >down? :-)

Yes Sir, Pete is my programming-partner

>For decrementing the counter, I'd do something along the lines of
>
>(Some useful Code I hope ;-))
>

>Pretty simple - read the current value, decrement it. If it is now >negative, set it back to 60 and decrement the next value (so 1:23:00 >goes to 1:22:59)

Sounds very good to me :-)

>Note: there's a deliberate error in that code (and possibly a few >unintentional ones too :-) so don't try to use it as it is. Work out what's >wrong and fix it.

I'll try :P

Thank you for your help so far !!!

Dansen


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 20, 2002 7:26 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
>>My guess would be that there's an interrupt coming at regular
>>intervals. You're to decrement the counter on each interrupt, and
>>trigger a beep when it reaches zero.
>
>Okay let's see! The countdown is supposed to go down only once. The
>Program should end after that.

Hello Dansen,

I think you are confusing the roles of hardware and software. You are thinking of having the software do the timing, generating an interrupt (which normally comes from hardware) to beep at the right time. What John is saying is that the timing is much better done in hardware, using a counter that pulls the IRQ\ line low to generate an interrupt at regular intervals, usually in the range of one per second to a thousand per second. The processor responds to every interrupt by advancing the time variables the appropriate amount, and comparing to see if their new values match the time that the beep should be produced. If they match, a branch is taken to go to the beep routine. The branch is in software, not hardware. It does not affect the IRQ\ input, nor does it use any other kind of interrupt. If only one beep is desired and there is no further need to keep time, the stream of interrupts can then be stopped by writing to a register in the peripheral IC, whether it is a 6522 or something else. Even though you only wanted one beep, there may have been thousands or millions of interrupts before the beep. It's easy to set up the hardware timer to interrupt the processor at accurate intervals.

Garth


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 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: