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 > Disk Drive Interrupts
2007-08-18 13:51
Conrad

Registered: Nov 2006
Posts: 849
Disk Drive Interrupts

Hello there.

May I ask if it's possible to get your own interrupt routines running on the disk drive using the VIA timer registers?

Since the drive also has an IRQ vector at $fffe/ffff, I've been trying to get my own IRQ routine to run using timer 1, but unfortunately no luck.

Here's the drive source of the IRQ routine I'm using:
DC_IRQ
	pha
	txa
	pha             
	tya
	pha
	
	bit $180D       ; interrupt from timer 1? (bit 6)
	bvc DC_IRQ_	; no, skip.

	lda $1c00       ; Flash LED to make sure irq runs.
	eor #$08
	sta $1c00

DC_IRQ_
        pla
        tay
        pla             
        tax
        pla
        rti

(This code is similar to the one stored in disk ROM)


I also have FFFF/FFFE vector set at this code location (DC_IRQ).

The problem is I'm not sure which VIA registers to set to enable timer 1 IRQ. I tried setting $180d, $180e and other IRQ related registers (also executing SEI before hand and CLI afterwards) but still nothing.

Could someone please help me which registers to set properly ?

I'm only doing this for tests BTW, just to see if it's possible to do. I'm testing it on 1541-I/II drives.

Cheers if you can help!
Owen.
2007-08-18 14:25
TNT
Account closed

Registered: Oct 2004
Posts: 189
How do you change $fffe/$ffff when they are in ROM?

1581 and 1571 jump through a RAM vector ($0192 and $02a9 respectively? You'd better to check that!), but with 1541 there is no such indirect jump.
2007-08-18 14:53
Conrad

Registered: Nov 2006
Posts: 849
oh damn!! I didn't know those were read-only (unlike fffe/ffff in c64 memory) That'll be the reason why it isn't working.

Oh well. TNT, thanks very much for pointing that out. :)

Is there any other possible way to set one up?
2007-08-19 10:09
TNT
Account closed

Registered: Oct 2004
Posts: 189
No, there are no RAM vectors in 1541 which you could redirect.
2007-08-20 13:23
JackAsser

Registered: Jun 2002
Posts: 2014
To emulate the behavior a bit you could disable all interrupts (SEI) and at appropriate places in the code, poll the timer and jump to the handler manually using the very same BIT $180D.
2007-08-20 17:19
tlr

Registered: Sep 2003
Posts: 1790
You can get a routine (buffer that is) called on interrupt (IRQ) by placing the $d0 job code (jump) on the required buffer. Higher buffer number has higher priority.

Look here:
http://unusedino.de/ec64/technical/aay/c1541/ro41fe67.htm
http://unusedino.de/ec64/technical/aay/c1541/ro41f2b0.htm
http://unusedino.de/ec64/technical/aay/c1541/ro41f36e.htm
2007-08-20 19:24
Conrad

Registered: Nov 2006
Posts: 849
Okay, after a few tests it seems I've got an IRQ to work along side an outside routine. It works on the 1541 I and II at least, because it seems to fail on all other drives, but obviously that's expected since the other drives has different specifications.

After reading closely at the ROM code tlr posted, I've coded up a routine in buffer 4 ($0700) that is executed with jobcode #$d0 - buffer 4 because like tlr said, it's the highest priority. The jobcode is executed through the IRQ interrupt by the ROM routine at $FE67 as normal - however, the routine in $0700 also resets $1c0c so that it runs over and over again, just like IRQs on the c64.

Here's the test code set up in $0500 - the code OUTSIDE the irq and by which is executed via M-E command:
!pseudopc $0500 {

DriveCode_START
	sei		;Set interrupt flag

	lda #$04	;Set buffer number to #$04 (buffer 4)
	sta $3f		;
	
	lda #$d0	;Set jobcode $d0 (jump)
	sta $04		;$04 = Jobcode for buffer 4
	
	lda #$00	;Set irq timer rates...
	sta $1c04	;
	lda #$80	;These can be altered at any rate
	sta $1c05	;except $1c05 must NOT be #$00
	
	lda #$01	;Set up a random counter to use
	sta $1b		;for test.
		
	cli		;Clear int. flag

	;Outside-irq code here...

	;Turn on rotate motor to allow head movement
	lda $1c00
	ora #$04
	sta $1c00

DC_MoveHead		;Loop location

	lda $1b		;See if counter is negative
	bpl *-2		;Loop back if not.
	
	and #$7f	;Set it back to positive
	sta $1b		;
	
	;Move head outwards...
	lda $1c00
	and #$fd	;Probably not the most
	;ora #$00	;efficient way, but it
	ora #$02	;works ;)
	sta $1c00
	;inc $1c00
	;inc $1c00
	dec $1c00
	dec $1c00

	jmp DC_MoveHead		;Jump back to loop
}


Next is the code executed in buffer 4 ($0700) which us called via job code #$d0 in disk ROM code:
!pseudopc $0700 {

	lda $1c00	;Flash LED
	eor #$08	;
	sta $1c00	;
	
	inc $1b		;Increase the counter.
			;Value in counter will eventually
			;be a negative number, checked
			;by the outside IRQ code.

	lda $1c0c	;erase bit 1 in $1c0c
	and #$fd	;CA2 = %??0 
	sta $1c0c

	ldx $49		;Restore the stack pointer
	txs		;executed from the disk ROM
			;($49 was used to store pointer)

	rts		;Return from job code

DriveCode_END
}


NOTE: Somewhere in drive ROM IRQ, zeropage $49 was used to store the current stack pointer, so I had to restore it so that IRQ wouldn't mess up (relating to the code in $FE67)

So basically, the following test code does this:

- In the IRQ routine ($0700-), the LED flashes on and off and increases a temporary counter. It then returns from interrupt.

- In the outside routine ($0500-), it checks if the temp counter has reached a negative ($80-$ff) and loops back if not. If negative number, then the drive head is moved by one track and the temp counter is set back to positive (so that the code does not move head forever.)

I hope that wasn't too winded for you lot, but because of your helpful advice I've managed to get it working, so thank you very much for that! :)

BTW, since I'm quite a novice in drive coding I'm not too sure how critical this code can be towards disk-loading routines, but still... it seems to work after a few tests.
2007-08-22 07:56
Krill

Registered: Apr 2002
Posts: 2980
What will this lead to, if i may ask? :)

And yes, you must not interrupt disk access by interrupts, or you'll face weird behaviour and lots of retries.
2007-08-22 09:33
tlr

Registered: Sep 2003
Posts: 1790
Krill is correct, you can not have interrupt during disk accesses because disk accesses are time critical code.

However setting the hook up correctly will let you have an interrupt running that automatically gets stalled by a disk access or IEC interrupt.
Just let the $d0 hookroutine do what you need to do, and then make sure it returns to the rest of the interrupt routine after it's done. You can use any buffer because you want the real jobs to be executed anyway.

FDC mode (where the jobs are executed) is just code that runs in the timer interrupt context IIRC, so interrupts are automatically disabled during disk accesses.
IEC interrupts have priority because they are checked first in the interrupt handler.

If you want to have a different timer speed, you probably want to make sure the job code checking gets called at the normal interval by means of a counter.

This could be used for installing a led PWM running in the background of normal operations, or even some naughty code resident in the drive up to drive reset...
2007-08-22 10:28
Krill

Registered: Apr 2002
Posts: 2980
Okay, but what are you actually coding there? :)
2007-08-22 10:50
Graham
Account closed

Registered: Dec 2002
Posts: 990
Why don't you just use jobcode #$E0 for moving the head? It's easy and safe to use on every drive mechanic.
 
... 4 posts hidden. Click here to view all posts....
 
Previous - 1 | 2 - Next
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
E$G/HF ⭐ 7
MaD ][/Starship
Ben Breton/Absence o..
jicas/Patagonia
Guests online: 125
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
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 Logo Graphicians
1 t0m3000  (10)
2 Sander  (9.8)
3 Mermaid  (9.5)
4 Facet  (9.4)
5 Shine  (9.4)

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