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 > Force a queded IRQ
2017-05-27 08:12
oziphantom

Registered: Oct 2014
Posts: 490
Force a queded IRQ

Is there a way to pogrammatically ( without the CIAs ) to en-queue an IRQ from within an NMI?

BRK will interrupt an NMI.But is there some other trick, maybe some stack fiddling?
 
... 21 posts hidden. Click here to view all posts....
 
2017-05-28 18:05
Oswald

Registered: Apr 2002
Posts: 5094
soci, thats a nice detial, now we know why its 00 :)
2017-05-28 20:19
lft

Registered: Jul 2007
Posts: 369
Quoting Oswald
I think the issue at hand could be solved with a more sane aproach.


This.

Oziphantom, what is the ultimate goal hidden behind your question?
2017-05-29 05:29
Karmic

Registered: Apr 2015
Posts: 66
Yep, I've been trying to wrap my head around this question.

WHY do you need it to behave exactly like a normal IRQ? WHY can't you just jump to your IRQ handler, or use BRK?
2017-05-29 06:45
White Flame

Registered: Sep 2002
Posts: 136
TWW: The IRQ line is actually active low, so it trips an interrupt when it's grounded, not high. Most C64 signals work like this, with a pull-up resistor defaulting lines to 5V, with any number of chips optionally asserting ground, so no conflict between multiple chips asserting a signal will let out the magic smoke.

Quoting oziphantom
Yes that is Standard IRQ behaviour, which is what I'm looking for. I'm pointing out the standard IRQ behaviour to show why you can't just use BBK.

The custom behaviour I'm asking about is "Is there a way to achieve an IRQ in software, such that it behaves in the standard way."


You really need to define what "standard behavior" is and why you want it. The only "proper" standard behavior would be to tell another chip to hold /IRQ low. Again, the interrupted code won't perceive anything no matter which option you take, besides the passage of time. You need to list what effects you want to happen. Are you using the stack droppings left over from the interrupt? Do you want it as fast as possible? Those are about the only 2 scenarios I can think of where any of this matters. And a simple software jump will be the fastest route, leaving the NMI's return information on the stack to use to exit the IRQ.
2017-05-29 07:40
ChristopherJam

Registered: Aug 2004
Posts: 1409
Quoting lft

Oziphantom, what is the ultimate goal hidden behind your question?

Yes, this is sounding a lot like an XY problem to me.
2017-05-29 07:53
oziphantom

Registered: Oct 2014
Posts: 490
Quoting lft
Quoting Oswald
I think the issue at hand could be solved with a more sane aproach.


This.

Oziphantom, what is the ultimate goal hidden behind your question?


Its a way of cheating another thread.

So you have the case where some logic is do be done in the "Main loop", you have some other logic that eats CPU - decompression for example, and you have NMIs

So while you have the main loop, you also want to decompress stuff, this means you need to make your decompression routines ( of which I have a few) be state aware, in that each of their internal loops needs to check ( has nmi told me I need to do a thing ) and then break out, do the thing, come back and carry on decompressing.
Once they have finished decompressing, the main loop resorts back to "wait for nmi to tell me do a thing".

The way to simplify and clean up all of this logic is to re-purpose the IRQ to "do the thing". So when you are decompressing you tell the NMI to handle "do the thing", when you are not decompressing you don't tell the NMI to do it and let the main loop take care of it. When I'm in the case that neither the main loop nor the NMIs are doing the thing duty, then the decompression system can trigger the thing.

to which the logic now looks like thanks to Soci

[nmi handler]
LDA NMIDoThing
LSR
PLA
TAY
PLA
TAX
PLA
BCS _queueIRQ
RTI
_queueIRQ
JMP ($FFFE)

inside the decompression routine
LDA DecompressDoThing
BEQ +
BRK
+

Main Loop
- LDA DoThing
BNE -
BRK
JMP -

Thus the NMI is unchanged, it still happens exactly as it was before with its tight timings, the "fragment" or "thread code" is now written in one way, it saves and restore its registers and ends in an RTI, and its updated from a single Vector location, without any management of special cases, allowing the NMI, decompression, VIC or mainloop logic to be generic and used in all cases, with simple control of who is responsible for doing what. Giving me an effective thread that I can have strict timing control, or loose timing control over as needed, and can be passed around very easily allowing me to make any combination needed for the user experience desired.
2017-05-29 08:11
Oswald

Registered: Apr 2002
Posts: 5094
"So while you have the main loop, you also want to decompress stuff"

this is usually solved in demos with re-entrant irqs. The main effect is jumped to from an irq, which immediately sets a flag saying not to jump here again in next frame from the irq, and then also a CLI, so upcoming irqs will be served. (all irqs must use stack properly and save registers on stack).

the 'main' cpu thread is used by the loader in the remaining frame fragment when all irqs have been returned. that is the main effect finished running, and there's still some time left until the raster irq starts, that initiates it.


a more primitive way I was doing simply adding a byte counter to the loader, and having it rts after every xth byte. or setting a flag if finished.

I also did multitasking, 2 raster irqs exchanged contents of stack. but better virtually halving the stack and only change stack pointer when changing context.
2017-05-29 08:21
oziphantom

Registered: Oct 2014
Posts: 490
The BRK/NMI/IRQ are three faces of the same coin
type   interupt NMI  interupt IRQ  Vector               needs to exit with RTI 
JMP    No            No            whichever you call   No                     
IRQ    No            No            FFFE/F               Yes                    
NMI    Yes           Yes           FFFA/B               Yes                    
BRK    Yes           Yes           FFFE/F               Yes 
So the Standard behaviour I want is the IRQ case. In that is the standard behaviour of the IRQs execution not the Standard behaviour of the IRQ inception.
So outside of an NMI, BRK is a fine substitute for doing an IRQ. Inside an NMI it doesn't substitute for an IRQ.
I'm looking for a way to get the IRQ operation, which is basically to "en-queue" the IRQ on the CPUS "things to do" in a neater way . i.e it gets to the of the NMI and goes "oh yeah I have an IRQ to do as well" *goes and does IRQ*

But I'm not looking for the solution, I'm asking if there is a neater solution.
To which Soci found at this point what I'm going to call the neatest. In that the can use the C flag to "chain" the IRQ onto the end of the NMI. As a PLA will modify N and Z but not C. Any modification of C is restored by the RTI which will do the PLP for you. Thus the C is safe to modify before the stack pulls, and react to it after them. This allows you to transparently and safely jump straight into the IRQ handler, as the stack has now been restored to its "first clock of interrupt state". So no extra handling is needed to handle this "queued interrupt".

And I'm sure the crackers will appreciate such madness being well documented here for them ;)
2017-05-29 10:05
Flavioweb

Registered: Nov 2011
Posts: 463
    * = $080D
    LDA #$7F
    STA $DC0D
    LDA $DC0D
    LDA #$35
    STA $01
    LDA #<NMI_IRQ
    STA $FFFA
    LDA #>NMI_IRQ
    STA $FFFB
;-------------------
MAIN_LOOP
    LDA QUEUED_FLAG
    EOR #$01
    STA QUEUED_FLAG
    JMP MAIN_LOOP
;-------------------
NMI_IRQ
    STA RESTORE_A
QUEUED_FLAG = *+$0001
    LDA #$01
    BEQ NMI_NO_QUEUE
    LDA #>QUEUED_IRQ
    PHA
    LDA #<QUEUED_IRQ
    PHA
    PHP
NMI_NO_QUEUE
    INC $D020
    LDA $DD0D
RESTORE_A = *+$0001
    LDA #$00
    RTI
;-------------------
QUEUED_IRQ
    SEI
    INC $D021
    RTI
;---------------------------------------

The "QUEUED_IRQ" code act as a "normal" IRQ and is queued to a NMI but can be interrupted by a NMI but not by another maskable IRQ...
The QUEUED code will be executed accordingly to "QUEUED_FLAG" value.
Should be something like this?
(Edit: press RESTORE key to fire the NMI...)
2017-05-29 14:39
oziphantom

Registered: Oct 2014
Posts: 490
If you don't need to push the A,X,Y etc in your handler than you can do it that way.
Previous - 1 | 2 | 3 | 4 - 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
morphfrog
Guests online: 150
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 Layers  (9.6)
2 No Listen  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Rainbow Connection  (9.5)
7 Dawnfall V1.1  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top Original Suppliers
1 Derbyshire Ram  (9.7)
2 Fungus  (9.3)
3 Black Beard  (9.2)
4 Baracuda  (9.2)
5 hedning  (9.1)

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