Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Setting up a timer interrupt
2004-03-14 22:48
Hurrican

Registered: Oct 2003
Posts: 10
Setting up a timer interrupt

Hello *.*,

I'm trying to set up a timer interrupt to make something happen at a regular basis (let's say: every 5 seconds). I already managed to do a raster interrupt, but setting up a timer interrupt beats me. After browsing the web I came up with this code:

----------------------8<----------------------8<---------

inittint lda #$7f
sta $dc0d ; disable cia1 int

lda $dc0e
and #$be
sta $dc0e ; stop timer a

lda $dc0f
and #$be
sta $dc0f ; stop timer b

lda #$00
sta $dc05 ; hibyte timer
lda #$ff
sta $dc04 ; lobyte timer

lda #<inthand
sta $0318
lda #>inthand
sta $0319 ; set t-int handler

lda $dc0e
and #$80
ora #$11
ldx #$81

stx $dc0d ; enable timer int
sta $dc0e ; start timer a

loop jmp loop

inthand lda $dc0d ; interrupt-source?
and #%00000001
beq timerint
rti

timerint jsr *fancy_stuff*
rti

----------------------8<----------------------8<---------

After running the program, the interrupt never seems to occur. Now, what's my mistake?

I assume I'm making a fool out of me for asking that question, but that's no problem for me... ;-)
2004-03-15 00:50
Stryyker

Registered: Dec 2001
Posts: 468
read $dc0d after setting it and see if that helps.
2004-03-15 07:29
Cybernator

Registered: Jun 2002
Posts: 154
CIA1 generates IRQ, while CIA2 generates NMI interrupt. Try using the $0314 vector, instead of $0318. Alternatively, use CIA2.
2004-03-15 11:19
yago

Registered: May 2002
Posts: 333

Make sure to sei before setting up interrupt, and to cli to get the interrupt.

This is too obvious, but i sometimes forget the cli, and wonder, why no irq...
2004-03-15 20:02
Hurrican

Registered: Oct 2003
Posts: 10
Thank you very much for the input. I added an SEI at the beginning and a CLI at the end (before the main loop), changed the interrupt vector to $0314 and acknowledged the interrupt after setting it. But now every time I start the Timer A (using STA $DC0E), the program is terminated (blue screen with ready.) and the memory is corrupted. Woaw... ;-)

Should I load a different value into the accu before doing so? Or am I doing another mistake?
2004-03-16 07:38
Hoogo

Registered: Jun 2002
Posts: 105
$314/15 is not the hardware-irq-vector. When an irg occurs, the processor jumps to the adress stored in $FFFE/FF. Some of the usually necessary jobs like pushing registers to the stack are done by the kernel before it uses the software-vector $314/15. These values have tu be pulled from the stack again. When using $315/15 you better do not return with an RTI but jump to $ea31 (keyboard, timer and some kernal-stuff), $ea7e (lda $dc0d..) or $ea81 (only exit, best for you). And I think it should be ...bne timerint
2004-03-18 21:35
Hurrican

Registered: Oct 2003
Posts: 10
Well... Now the program doesn't crash anymore, but no interrupt will occur. I guess I'll have to have a detailed look at the whole code.

Thanks to everyone!
2006-01-10 09:56
MRT
Account closed

Registered: Sep 2005
Posts: 149
try this:

;----------------------------------------------------
SetTimerInterrupt
        ;set NMI vector
        lda #<TCF_SCR_DoNMI_1
        sta $fffa   ;nmi vector lsb
        lda #>TCF_SCR_DoNMI_1
        sta $fffb   ;nmi vector msb
        
        ;set nr of wait cycles
        lda #62
        sta $dd04   ;low-cycle-count
        lda #0
        sta $dd05   ;high-cycle-count
        
        ;enable timerA interrupt
        lda #%10000001
        sta $dd0d
        
;        ;fire the 1-shot timer at 50Hz
;        lda #%10011001
;        sta $dd0e
        
        ;fire the continuous timer at 50Hz
        lda #%10010001
        sta $dd0e
        
        ;done
        rts
        
;----------------------------------------------------
UnsetTimerInterrupt
        ;disable timerA interrupt
        lda #%00000001
        sta $dd0d
        
        ;aknowledge nmi
        lda $dd0d
        
        ;stop the continuous timer at 50Hz
        lda #%10010000
        sta $dd0e
        
        ;done
        rts
        
;----------------------------------------------------


I used your code as a base, but changed all of the $dc0x addresses to $dd0x addresses... and now it works :-)

I don't know why, but this seems to do the trick. Maybe someone else can explain this...

If I use the $dc0x addresses, the vector is at $fffe
and if I use $dd0x addresses, the vector is at $fffa

I like the last one better, because then I can use NMI and IRQ at the same time.
2006-01-10 17:24
Wanderer
Account closed

Registered: Apr 2003
Posts: 478
Quote: $314/15 is not the hardware-irq-vector. When an irg occurs, the processor jumps to the adress stored in $FFFE/FF. Some of the usually necessary jobs like pushing registers to the stack are done by the kernel before it uses the software-vector $314/15. These values have tu be pulled from the stack again. When using $315/15 you better do not return with an RTI but jump to $ea31 (keyboard, timer and some kernal-stuff), $ea7e (lda $dc0d..) or $ea81 (only exit, best for you). And I think it should be ...bne timerint

When using multiple interrupts (eg. setting the IRQ multiple times via $0314/0315) I use $ea81 and $ea31 for the final irq.

eg. IRQ1 INC $d019
lda #<irq2:sta $0314
lda #>irq2:sta $0315
lda #$a0;sta $d012
jmp $ea81

irq2 inc $d019
(stuff)
lda #<irq:sta $0314
lda #>irq:sta $0315
lda #$30:sta $d012
jmp $ea31

I've never really looked into it further as to how many cycles, if any, are saved this way but $EA81 works as long as you us $ea31 for the last interrupt :)

2006-01-11 07:40
Style
Account closed

Registered: Jan 2002
Posts: 17
$0314/$0315 is for gheys

Use the hardware vectors.

2006-01-11 07:45
JackAsser

Registered: Jun 2002
Posts: 2014
@style: When you have graphics at $fffe/$ffff then the kernal vectors prove VERY potent. =) (such as in the case of an AGSP etc.)

So, it's not ONLY for ghays.
2006-01-11 08:50
HCL

Registered: Feb 2003
Posts: 728
I'm not sure $0314-15 works at all, never used them a.f.a.i.can.remember. And.. why try now, after 15 years !? ;).
2006-01-11 09:17
Oswald

Registered: Apr 2002
Posts: 5094
hahaha

I've started with 0314/15, but now Im also unsure wether it would work at all, fffe/ffff is my cosy territory, after all those years 314/15 is scarry :D
2006-01-11 09:38
Krill

Registered: Apr 2002
Posts: 2980
i second jackasser... there are times when the kernal vectors just come in super-handy. :D and yes, of course they work.
2006-01-11 09:42
Compyx

Registered: Jan 2005
Posts: 631
When writing programs like editors, you'll more or less have to use $0314/$0315 to be able to use kernal-routines like GETIN (scanning the keyboard queue).

When you look at $fffe/$ffff you'll see it points to $ff48 which in turn JMP's to ($0314) or ($0316) when bit 4 of P is set (BRK).

So you're basically rerouting the kernal interrupt handler when setting $0314/$0315. There's no need to use $ea31 unless you're using GETIN, $ea81 is sufficient as it pulls A,X and Y from the stack which were pushed on it by $ff48.

Just my 2 cents ;)
2006-01-11 10:40
Ninja

Registered: Jan 2002
Posts: 411
Dunno if your 5-second-interval is the true value, but if it is then one timer won't be enough, as it can just count 65536 cycles. So, either you combine two timers (Timer B counts underruns of Timer A) or you use the Time-of-day-Clock.
2006-01-11 15:26
Graham
Account closed

Registered: Dec 2002
Posts: 990
WHAAAAH no TOD clock please :D inaccurate as hell
2006-01-11 15:57
Oswald

Registered: Apr 2002
Posts: 5094
compyx: you can call yourself SCNKEY, so u can use GETIN. no need for kernal interrupt.
2006-01-11 16:05
Ninja

Registered: Jan 2002
Posts: 411
Well, okay, I assumed that a 5-second-interval could also live with some tolerance, hence mentioning the TOD. If it needs to be more exact, combinig timers is inevitable.
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Mike
A3/AFL
Mr SQL
slimeysmine
celticdesign/G★P/M..
iAN CooG/HVSC
Alakran_64
Mibri/ATL^MSL^PRX
pcollins/Quantum
leonofsgr/Singular C..
Acidchild/Padua
Guests online: 181
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 The Demo Coder  (9.6)
6 Edge of Disgrace  (9.6)
7 What Is The Matrix 2  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.7)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 X-Mas Demo 2024  (9.5)
7 Dawnfall V1.1  (9.5)
8 Rainbow Connection  (9.5)
9 Onscreen 5k  (9.5)
10 Morph  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Triad  (9.3)
Top Fullscreen Graphicians
1 Joe  (9.7)
2 Sulevi  (9.6)
3 The Sarge  (9.6)
4 Veto  (9.6)
5 Facet  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.056 sec.