IRQ interupt
IRQ interupt
Hello,
Sorry do not write english !!!
Est ce que quelqu'un connaitrait le moyen de generer une interruption IRQ sous Oric version ATMOS ?
Pour l'integrer dans un programme ASM !!!
J'ai beau chercher dans les docs que j'ai, mais j'ai rien trouve ?
Tchao.
Sorry do not write english !!!
Est ce que quelqu'un connaitrait le moyen de generer une interruption IRQ sous Oric version ATMOS ?
Pour l'integrer dans un programme ASM !!!
J'ai beau chercher dans les docs que j'ai, mais j'ai rien trouve ?
Tchao.
Salut, une IRQ c'est une interruption matérielle, donc normalement ça ne se génère pas de façon logicielle...
Sur le 6502, on peut toutefois utiliser l'instruction BRK, qui simule "presque" l'apparition d'une IRQ (la différence est minime: un bit est différent dans les flags sauvés sur la pile). Mais souvent, le code appelé par l'interruption vérifie justement la valeur de ce bit pour savoir s'il s'agit d'une interruption matérielle (IRQ) ou logicielle (BRK), c'est le cas par exemple avec le traitement d'interruption de l'OS Sedoric. Si on veut vraiment provoquer une interruption IRQ, il faut demander à des périphériques de le faire, par exemple on peut programmer un compteur de temps sur le VIA pour qu'il se termine "tout de suite" et provoque ainsi une IRQ...
A+
Fabrice
[ENGLISH]
6502man asks how to generate an IRQ on the Oric...
An IRQ is an hardware interrupt, caused by a peripheral, so normally a program doesn't generate an IRQ. However, the 6502 has a BRK instruction that "nearly" generates an IRQ, only a single bit differs in the saved flags on the stack. So, if the interrupt handler doesn't make the difference, it's ok, but often it does, like does the interrupt handler of the Sedoric OS. In this case, the only way to have an IRQ is to ask a peripheral to generate one, for example you can program a VIA timer to elapse straight away.
Sur le 6502, on peut toutefois utiliser l'instruction BRK, qui simule "presque" l'apparition d'une IRQ (la différence est minime: un bit est différent dans les flags sauvés sur la pile). Mais souvent, le code appelé par l'interruption vérifie justement la valeur de ce bit pour savoir s'il s'agit d'une interruption matérielle (IRQ) ou logicielle (BRK), c'est le cas par exemple avec le traitement d'interruption de l'OS Sedoric. Si on veut vraiment provoquer une interruption IRQ, il faut demander à des périphériques de le faire, par exemple on peut programmer un compteur de temps sur le VIA pour qu'il se termine "tout de suite" et provoque ainsi une IRQ...
A+
Fabrice
[ENGLISH]
6502man asks how to generate an IRQ on the Oric...
An IRQ is an hardware interrupt, caused by a peripheral, so normally a program doesn't generate an IRQ. However, the 6502 has a BRK instruction that "nearly" generates an IRQ, only a single bit differs in the saved flags on the stack. So, if the interrupt handler doesn't make the difference, it's ok, but often it does, like does the interrupt handler of the Sedoric OS. In this case, the only way to have an IRQ is to ask a peripheral to generate one, for example you can program a VIA timer to elapse straight away.
irq
Merci pour la reponse.
Justement comment acceder au VIA en ASM, dans le but de temporiser un programme pour le rendre fluide, par exemple pour un scrolling ?
D'autres part je n'est pas trouve de registre type 'RASTER' sur Oric !
En fait lorsque je code mon prog, je n'est aucun moyen de savoir si je suis en fin de balayage ecran ou non, ce qui n'est pas tres pratique, notamment pour rendre l'affichage fluide.
Car si on n'affiche plus ou moins de choses le processeur prendra donc plus ou moins de cycle a le faire, et on ne pourras pas attendre un balayage ce qui risque de rendre le tous saccade !
Voila.
[English]
Thanks for the answer.
How to access the VIA to temporise a program in order to make it a bit more smoother in the animation, for example in a scrolling ?
I did not found any 'raster' register in the oric.
When I code I have no way to know where I am relatively to the electron beam, so this is very hard to make a smooth display, because depending of what the processor is doing it takes more or less time to do things, and thus looks chopy.
Justement comment acceder au VIA en ASM, dans le but de temporiser un programme pour le rendre fluide, par exemple pour un scrolling ?
D'autres part je n'est pas trouve de registre type 'RASTER' sur Oric !
En fait lorsque je code mon prog, je n'est aucun moyen de savoir si je suis en fin de balayage ecran ou non, ce qui n'est pas tres pratique, notamment pour rendre l'affichage fluide.
Car si on n'affiche plus ou moins de choses le processeur prendra donc plus ou moins de cycle a le faire, et on ne pourras pas attendre un balayage ce qui risque de rendre le tous saccade !
Voila.
[English]
Thanks for the answer.
How to access the VIA to temporise a program in order to make it a bit more smoother in the animation, for example in a scrolling ?
I did not found any 'raster' register in the oric.
When I code I have no way to know where I am relatively to the electron beam, so this is very hard to make a smooth display, because depending of what the processor is doing it takes more or less time to do things, and thus looks chopy.
Salut
Hi
Il n'y a aucun registre sur l'oric permettanr de savoir où se trouve la position du balayage. On peut bidouiller (hardware) entre la prise K7 et la prise péritel pour obtenir l'information, mais ca n'est évidement pas disponible en standard.
There is no register on the oric to know where the electron beam is. We can get this information by hacking with the SCART and TAPE sockets, but obviously it's not something available on all the machines.
De toute façon on ne peut pas non plus faire de double écran, donc l'animation reste problématique a faire proprement même avec la bidouille en question.
Anyway, there is no double buffering on the oric, so geting a clean animation remains a challenge even with such a hack.
Reste le VIA.
L'idée est de programmer un timer pour se déclancher toutes les 1/50ème de seconde. Personnelement moi j'utilise un code similare à celui-ci.
Then we have the VIA.
The idea is to setup a timer to trigger every 1/50th of a second. I use a code similar to that one:
Installation de l'IRQ - Installing IRQ
Et la routine de synchronisation - The synchronisation code
C'est pas extremement élégant, mais ca marche.
Par contre je ne suis par sur que 19968 soit la meilleur valeur.
This is not very nice looking, but this works.
Anyway I am not sure that 19968 is the best possible value.
Hi
Il n'y a aucun registre sur l'oric permettanr de savoir où se trouve la position du balayage. On peut bidouiller (hardware) entre la prise K7 et la prise péritel pour obtenir l'information, mais ca n'est évidement pas disponible en standard.
There is no register on the oric to know where the electron beam is. We can get this information by hacking with the SCART and TAPE sockets, but obviously it's not something available on all the machines.
De toute façon on ne peut pas non plus faire de double écran, donc l'animation reste problématique a faire proprement même avec la bidouille en question.
Anyway, there is no double buffering on the oric, so geting a clean animation remains a challenge even with such a hack.
Reste le VIA.
L'idée est de programmer un timer pour se déclancher toutes les 1/50ème de seconde. Personnelement moi j'utilise un code similare à celui-ci.
Then we have the VIA.
The idea is to setup a timer to trigger every 1/50th of a second. I use a code similar to that one:
Installation de l'IRQ - Installing IRQ
La routine d'interruption elle même - The IRQ routine#define VBLVIA 19968
sei
lda #<VBLVIA
sta $306
lda #>VBLVIA
sta $307
lda #0
sta _VblCounter
lda #<_VBLIrq
sta $0245
lda #>_VBLIrq
sta $0246
cli
Code: Select all
_VBLIrq
bit $304
inc _VblCounter
rti
Code: Select all
_VSync
loop_wait
lda _VblCounter
beq loop_wait
lda #0
sta _VblCounter
rts
Par contre je ne suis par sur que 19968 soit la meilleur valeur.
This is not very nice looking, but this works.
Anyway I am not sure that 19968 is the best possible value.
19968 = 64*312 is the precise number of cycles of the screen raster.Par contre je ne suis par sur que 19968 soit la meilleur valeur.
Anyway I am not sure that 19968 is the best possible value.
However, to get an interrupt every 19968 cycles, you must program the VIA timer with a value of 19966, because the VIA adds two cycles to each count (19966, 19965, 19964,.... , 2, 1, 0, -1, 19966, 19965, 19964,...).
Cheers,
Fabrice
Exactly what I need !Dbug wrote:Ok, you want a simple callback function called every 50th of a second to do something ?waskol wrote:Hello
How can you manage to include this tip in an animation with the OSDK, in C ?
You can already do that using the functions in irq.s:
install_irq_handler
chain_irq_handler
uninstall_irq_handler
Then, the structure of my program should be basically like this :
am I right ?
Code: Select all
void main()
{
install_irq_handler
...
while (animate==1) {
//Chain twice
chain_irq_handler;
chain_irq_handler;
//Then display next frame
Display_frame();
}
...
uninstall_irq_handler;
}
Maybe I am wrong, surely Dbug can tell, but I think it is not correct.waskol wrote:Then, the structure of my program should be basically like this :am I right ?Code: Select all
void main() { install_irq_handler ... while (animate==1) { //Chain twice chain_irq_handler; chain_irq_handler; //Then display next frame Display_frame(); } ... uninstall_irq_handler; }
I suppose install_irq_handler needs a pointer to a function, so it is called every interrupt (@100Hz). chain_irq_handler simply adds another function to the chain, so both are called in order. The call is done by the system (thus they are callbacks), so what you want to do is:
Code: Select all
void animate_frame()
{
// do whatever
}
main()
{
install_irq_handler(animate_frame);
...
}
However this would run "outside" the control of the main function, so maybe you want this other approach:
Code: Select all
char ticks;
void f()
{
ticks=1;
}
main()
{
install_irq_handler(f);
while (whatever) do
{
if (ticks)
{
// run animation
ticks=0;
}
}
}
This is a rough approach, of course, as you would need to control if your irq is being called more than once during your animation stage (maybe disable interrupts) or while you are doing other things... A better approach would be having your program stopped until a certain numbers of irq calls are made.
Simply make f do ticks++ and include a wait loop before your animation:
Code: Select all
ticks=0;
// HALT until irq happens NUM_TICKS times
while (ticks<NUM_TICKS){ }
ticks=0;
Finaly, chain_irq_handler(f2) would add another function (f2) that will be called after f at each irq.
Cheers
off couuuuuuuurrrrrrrrrrrssssssssseeeeeee !!!
chema, now I understand so many things a bit better with your explanation.
I was wondering if there was any callback event to manage and how to manage it in this case. You gave me the answer I needed to the question I was not able to ask.
So many thanks.
Now, I will try to experiment a little bit with this
chema, now I understand so many things a bit better with your explanation.
I was wondering if there was any callback event to manage and how to manage it in this case. You gave me the answer I needed to the question I was not able to ask.
So many thanks.
Now, I will try to experiment a little bit with this
Well... thanks. I am not used to hear my explanations are clearwaskol wrote: chema, now I understand so many things a bit better with your explanation.
Anyway I was just guessing, so many details can be wrong. As I said surely Dbug can bring more light to this.
However managing interrupts is quite tricky IMHO, and I would do it in asm whenever possible (maybe write a small set of routines which can be called from C, such as halt(), which would wait for an interrupt, or halt(char n), to wait for a number of irqs to occur.
Surely people used to work with irqs can help, such as Twilighte or Dbug.
Finaly (again) everything would be marvelous if your program runs continuously doing whatever and updating some variables so that a display() routine performs the animation as an irq callback depending on the value of those variables (and if they changed). They can operate in "paralell" to say it somehow, and the program logic is separated from the visual display matters...
Cheers.
My experience with this type of routine is on other computers but a couple things here...
1. If you can eventually convert you interrupt handler to assembly you'll definitely save some clock cycles.
2. I usually use:
That way I know if I've missed any ticks doing something time consuming and have to compensate to catch up.
If you are animating something and it moves every so many ticks then you're counter is sure to be accurate and you don't really need to keep count outside the interrupt... just check if ticks > your trigger value.
1. If you can eventually convert you interrupt handler to assembly you'll definitely save some clock cycles.
2. I usually use:
Code: Select all
void f()
{
ticks++;
}
If you are animating something and it moves every so many ticks then you're counter is sure to be accurate and you don't really need to keep count outside the interrupt... just check if ticks > your trigger value.