It is currently Mon Oct 20, 2014 4:49 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Tue Sep 20, 2011 10:54 am 
Offline
 Profile

Joined: Fri Nov 07, 2008 2:28 pm
Posts: 65
I've got an interrupt routine at this vector

IRQ1V = $0204

and I'd like to have it called faster than it is at the moment.

I'm guessing I have to load a timer value somewhere - but I'm not sure where.
Also what value is the system default?

Thanks

- PJ


Top
 
PostPosted: Tue Sep 20, 2011 11:19 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
IRQ1V will be entered on *any* interrupt which is enabled - not just the timers (of which there are 4!), but also other periodic things like VSync, and non-periodic things like keyboard interrupts or the analogue to digital converter finishing a conversion.

So, the first thing your interrupt code needs to do is check if the interrupt has come from the thing you're interested in (e.g. a timer), then you have to acknowledge the interrupt (otherwise as soon as your IRQ routine exits, it'll generate another interrupt immediately), and then you can do whatever update you need.

The Beeb OS uses timer 1 of the System VIA as a 100Hz timer (for processing sound, keyboard, system timers, and probably some other stuff). While you could alter the period of this timer, it's probably best to leave it alone, otherwise other things in the OS might start to go wrong.

The best thing is to choose a timer of your own in the User VIA, and use that as your interval timer. The way the OS would like you to do this is to intercept IRQ2V (which is entered for unknown interrupts) and service the interrupt there.

Suppose you wanted an interrupt to occur at 60Hz (60 times a second) for some reason. Timer 1 of the User VIA can be set to automatically reload and generate an interrupt with a given period. Here's how you'd set up the timer:

Code:
\ Set interval time in microseconds
interval = 1000000/60

SEI

\ Disable all User VIA interrupts
LDA #&7F
STA &FE6E

\ Enable just Timer 1 interrupt
LDA #&C0
STA &FE6E

\ Set Timer 1 to free-run mode
LDA #&40
STA &FE6B

\ Set Timer 1 interval
LDA #(interval-2) MOD 256
STA &FE64
LDA #(interval-2) DIV 256
STA &FE65

\ Set IRQ2V
LDA #irqhandler MOD 256
STA &206
LDA #irqhandler DIV 256
STA &207

CLI
RTS

Code:
\ Example IRQ handler

.irqhandler
\ Check if it's our interrupt
LDA &FE6D
AND #&40
BEQ exit

\ Acknowledge interrupt
STA &FE6D

\
\ Do something here
\

.exit
LDA &FC
RTI


Well, that's more or less the trick. Hope that's some help!


Top
 
PostPosted: Tue Sep 20, 2011 1:39 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
IRQ2V can have horrible latency, so IRQ1V is best if you want the timer to be reasonably accurate. The irq handler would be the same as for IRQ2V, but instead of lda $fc/rti you'd jump to the previous IRQ1V handler.


Top
 
PostPosted: Sat Sep 24, 2011 12:19 pm 
Offline
 Profile

Joined: Fri Nov 07, 2008 2:28 pm
Posts: 65
Thanks for that - that exactly what I wanted to know.
Although it doesn't seem to work.

Assuming I want the main 100hz interrupt to go at 400Hz I tried this:

speed = (1000000/400)

LDA #LO(speed)
STA &FE44
LDA #HI(speed)
STA &FE45

( I tried &fe64 as well but I figured I really wanted to change the system via so tried the &fe44 address)

The intsub was like this already:


.intsub:
LDA &FC ;//[44EF] A5 FC
PHA ;//[44F1] 48
LDA &FE4D ;//[44F2] AD 4D FE
STA &FE4D ;//[44F5] 8D 4D FE

...


PLA
RTI ;//[452C] 40


Top
 
PostPosted: Sat Sep 24, 2011 1:38 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
What exactly do you want to do? You realise that changing the system timer to run at 400Hz will make the system clocks, sound and everything else run 4 times as fast?

Also, this IRQ handler doesn't look so good - it's not checking the source of the interrupt, which is ok if you *only* have a timer interrupt enabled, but if you have anything else going on, such as VSync, it'll cause your interrupt code to be executed an extra time every 1/50th of a second.

Of course all this is fine if you're not returning control to the OS IRQ handler at any point.


Top
 
PostPosted: Sun Oct 02, 2011 4:25 pm 
Offline
 Profile

Joined: Fri Nov 07, 2008 2:28 pm
Posts: 65
I have a SID music playing program where the music player is called by the main timer interrupt - I want to speed up the music a little - I don't use any other BBC hardware except for checking the keys so I was thinking changing the rate of the main timer shouldn't break anything - speeding it up by 400% was just a test so I could definitely hear the difference - I probably just want to speed it up something like 120%.
However those changes didn't seem to make any difference - I wonder if something else is setting the timer delay back to its default? It's not exactly clear if I should be setting $FE4X or $FE6X but I did try both.

- PJ


Top
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


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:  
cron