IRQ interupt

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.
User avatar
Dbug
Site Admin
Posts: 2389
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug » Thu Oct 25, 2007 8:53 pm

Chema wrote: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...
Yep, even a simple thing like changing 8 bytes can give magnificent results :)

Imagine, you are doing a strategy game, and the compute needs to think... for a while... too long perhaps...

All you need is a small IRQ that will animage one of the characters in the reconfigurable data, to display a small animated clock, a bouncing ball, etc...

Low cost, great effect :)

captain
Private
Posts: 3
Joined: Tue Jan 27, 2009 12:06 pm

install_irq_handler polling too fast?

Post by captain » Tue Jan 27, 2009 12:15 pm

Hi all,

I have the following code setup to use the install_irq_handler function.
The results are not what I expected in that I get an output of:

AAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB...

The char B is then displayed forever.
I was expecting a few A chars displayed.
I have tried to modify the irq.s file to see if I can change the 6522 registers to adjust the latch setting of the T1 timer but this has had no effect.

Any ideas?
I am working on an oric adventure game and need some simple animation handler. when I say simple I really mean it! Only two frames of simple UDG changes.

I am aware that the code below is probably rather heavy when using the printf command...

Thank you in advance.

#include <lib.h>

#include "display.h"

void irq(int test)
{
printf("%B");
}

void main()
{
char a='1';
install_irq_handler(irq);
while (a='1') {
printf("%A");
}
}

User avatar
Chema
Game master
Posts: 2078
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: install_irq_handler polling too fast?

Post by Chema » Tue Jan 27, 2009 12:55 pm

captain wrote:

Code: Select all

#include <lib.h>

#include "display.h"

void irq(int test)
{
	printf("%B");
}

void main()
{	
	char a='1';
	install_irq_handler(irq);
	while (a='1') {
		printf("%A");
	}
}
Mmmm.. maybe I am overlooking something here (just answering in a couple of seconds at work), but what is the purpose of the '%' in the printf("%A")? I would expect printf("A") and printf("B") to just print A's and B's...

I don't remember any format specifier for A or B, but it might interfere with the output of the function...

captain
Private
Posts: 3
Joined: Tue Jan 27, 2009 12:06 pm

Re: install_irq_handler polling too fast?

Post by captain » Tue Jan 27, 2009 1:01 pm

It was a mistake I had in the code.
It seems to be ignored and the output just prints A and B
I have recompiled it with just A and B but get the same result.

Hey thank you for a reply.
This thread has not seen and life for a while it seems...

User avatar
Chema
Game master
Posts: 2078
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: install_irq_handler polling too fast?

Post by Chema » Thu Jan 29, 2009 7:40 pm

captain wrote: Hey thank you for a reply.
This thread has not seen and life for a while it seems...
The whole forum is quite silent, but it does not mean that nobody reads it. Some of us usualy do, so don't hesitate to post any question. Maybe late, but you will most surely get a response.

About our problem. Not sure why but it seems that installing the irq just makes the main function stop responding.

Try this:

Code: Select all

#include <stdio.h>

void irq() 
{ 
  printf("B");
} 

void main() 
{    
   chain_irq_handler(irq); 
   while (1) { 
     printf("A");
   } 
} 
It prints A's and B's, but also spaces appear sometimes, so it is somewhat strange. Maybe it would be a good idea to disable interrupts while inside your function to avoid any undesired operation? That should be done in asm, of course. I guess that only happens when you call ROM routines (as printf does).

If you use a direct poke such as in:


Code: Select all

char * p=(char *)0xbbff;

void irq() 
{ 
   *p='B';  
} 

void main() 
{    
   chain_irq_handler(irq); 
   while (1) { 
      *p='A';
   } 
} 
You will see alternating A's and B's just below the number 3 in the 1983 date in the Oric welcome screen. It seems slow, but i guess it is because screen refreshing isn't quick enough to catch every change.

Anyway the above code does NOT work if you call install_irq_handler, but I guess it should. No idea what is going on here. It just print B's as with printfs. It seems as if the main code stopped working. Should analyze at the generated asm, but maybe Dbug could help on this.

Cheers.

captain
Private
Posts: 3
Joined: Tue Jan 27, 2009 12:06 pm

irq

Post by captain » Fri Jan 30, 2009 9:42 am

Hey thank you for the response.
I'm pleased to see my screen filled with A's and B's

If I modify the program and remove the main() loop to drop back to BASIC when the program quits the keyboard handler works for about 2 seconds then seems to go dead.
Reading through some docs I suppose this is because the IRQ handler has intefered with the keyboard handler code and therefore the vector for the handler is no longer being processed. I wonder if it would be possible to add another chain command to include the default keyboard handler vector?

I expect without this change my program would need to monitor the memory locaiton of the last key pressed rather than use the getchar() funciton.

Anyway... Looks like there is life in my 6522 after all so I will have a play and see what happens.

Thanx again...

User avatar
Chema
Game master
Posts: 2078
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: irq

Post by Chema » Tue Feb 03, 2009 10:08 am

captain wrote: If I modify the program and remove the main() loop to drop back to BASIC when the program quits the keyboard handler works for about 2 seconds then seems to go dead.
Reading through some docs I suppose this is because the IRQ handler has intefered with the keyboard handler code and therefore the vector for the handler is no longer being processed. I wonder if it would be possible to add another chain command to include the default keyboard handler vector?
Mmmm... I don't know what might be going on, but I assume that exiting C and getting back to BASIC while a C function is running as Interrupt Service routine might not be a good idea. I know that C uses page zero to implement registers and temporal variables as well as pointers to the C stack, which is kept in main memory. However once you exit... who knows.

There is no such thing as keyboard handler vector or other nice vectors as such. I think there is a service routine in the ROM which is called to handle all this, so if you are using chain_irq_vector it should be calling both that routine and your function. You also cannot change the pace at which IRQs occur. You can, however, have a variable to count the number of IRQs and act accordingly.

As allways it is nearly a must to write the routine in asm to be sure it works.
I expect without this change my program would need to monitor the memory locaiton of the last key pressed rather than use the getchar() funciton.
I think I do not get the point of this sentence. I think the getchar function calls a ROM routine which does exactly this: see if a key was pressed and return the code or wait if it is not the case. The actual keyboard scanning is done in the default IRQ (please somebody explain this). Other C functions as keyb (is it implemented?) return inmediately both if a key is pressed or not.

FYI what I do in asm is having a ProcessKeyboard function which calls the ROM (though a page 2 pointer, I think) to see if a key is pressed and do what is needed. If a key is not pressed it returns inmediately:

Code: Select all

         jsr $023B ; Get key
       	 bpl return
If a keyb function is not implemented, you can directly call that routine. Addint such a function in C shouldn't be too difficult, as $023B returns in reg A the keycode (in ascii, IIRC, so directly as a char). If the return value is negative, then no key was pressed.

Cheers

User avatar
Dbug
Site Admin
Posts: 2389
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug » Tue Feb 03, 2009 10:58 pm

About implementing an irq handler in C, the problem is really that it is running in parallel of the other code, and the whole stuff is not design to handle parallel execution. There is a gazillion of variables in zero pages that are used by the compiler, and if both "printf()" and "while" are using the same temporary variables, the result of what happen in the interrupt is most likely to be not what you are expecting :)

The easiest way to find out, is to look at the "linked.s" in your osdk/tmp folder, and check the generated code for "main" and "irq", if they both use "tmp1" and "reg1", etc... it's not going to work.

JamesD
Flight Lieutenant
Posts: 352
Joined: Tue Nov 07, 2006 7:38 am

Post by JamesD » Sun May 24, 2009 8:18 pm

Code: Select all

#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
So... how do we turn off the VIA timer?
Or are you going to make me look up the VIA docs?
Is there a way to read the previous settings so they can be restored later?
<edit>
Never mind, I found the VIA docs and some Oric programming info.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest