Fusion_C and HTIMI

Страница 4/4
1 | 2 | 3 |

By ducasp

Champion (366)

Аватар пользователя ducasp

08-04-2020, 21:00

thegeps wrote:
ducasp wrote:
thegeps wrote:
ducasp wrote:
thegeps wrote:

You have to save AF registers at the start of your hooked routine and restore them before exiting. ISR doesn't do it. Then it would be ok

Not needed, the code for Interrupt pushes hl/de/bc/af, exchange registers and AF for their shadow registers, push all those registers again, push ix, iy and then call the HKEY.I hook. Wink You can easily check this using either BlueMSX or OpenMSX debuggers on several machines.

You mean the Fusion-C code for interrupt, I suppose. Because ISR doesn't do it

Either BIOS or DOS when handling RST 38 (interrupt) will save all registers before executing H.KEYI interrupt hook, and will return all those saved registers before returning from that interrupt. Again, if you don't believe, just step through using OpenMSX / BlueMSX on any MSX type available. Tongue

Ok, it was a misunderstanding: just because you referred to DarkSchneider code and there was involved HTIMI and not HKEY, so as you know, during HTIMI you can use EI but you have to preserve register A. I was talking about it

Yes, sure.

I've changed because I don't think H.TIMI is a good choice for an example / library code for interrupts, let's say someone has an interface and want to create a C program that works with that interface interrupt, H.TIMI will not work, but if someone wants to use the VDP 60Hz interrupt, they can just check if the interrupt came from VDP, like Fusion-C example does.

By ducasp

Champion (366)

Аватар пользователя ducasp

09-04-2020, 00:14

By the way, the example will crash on MSX1 due to the use of the IsVsync macro, that reads status register 0 and check for its 8th bit using VDPstatusNi which works only on v9938 on...

Taking it out the example will work on MSX1 as well, but ofcourse, other interrupts (drive, other interfaces, etc) will trigger the counter as well, so, in such case, if anyone needs fusion-c and a "reliable" 60 or 50 Hz interrupt to time, the only way would be to change the interrupt code to suit your needs, using H.TIMI hook and doing like thegeps said, pushing AF before calling the registered function and popping it before jumping to the saved hook area.

By ericb59

Paladin (986)

Аватар пользователя ericb59

09-04-2020, 11:48

Ok it works better.
But ... It seems all Keyboard input functions do not work well when this interrupt is on.
All Inkey(), WaitKey(), GetKeyMatrix() functions do not received values... Is it normal ?

By ericb59

Paladin (986)

Аватар пользователя ericb59

09-04-2020, 11:55

Well, in fact what i've said above is false. The problem comes from the isVsynch wait. There is no update because all process are waiting Vsynch.

By ducasp

Champion (366)

Аватар пользователя ducasp

09-04-2020, 13:38

ericb59 wrote:

Well, in fact what i've said above is false. The problem comes from the isVsynch wait. There is no update because all process are waiting Vsynch.

Yeah, by reading S0 you clear the interrupt status and keyboard is not read by bios/dos anymore, this should be done only if you are substituting the whole interrupt. This is not an issue of the hook, but of what is being done by the example during the hook.

By ducasp

Champion (366)

Аватар пользователя ducasp

09-04-2020, 15:59

Just have stepped through and as I believed, in this case you will loose the interrupt everytime because of clearing the VDP status register, and thus, all functions related to it. BIOS will save registers, call the hook, and then call its interrupt handler. So the BIOS interrupt handler will see that the 8th bit of VDP S0 is cleared and not run.

The previous code was replacing RST 38 by itself, which is not good because if BIOS gets paged in before the interrupt, you won't handle the interrupt (as 38 will contain bios interrupt handler). It also will have the same effect (if you read VDP S0 during your interrupt handling, it will clear, further processing won't see the VDP.

So, my belief is that the best is to just remove the vdp macro out of the example. And if anyone wants a specific VDP interrupt code instead of catching all interrupts, then it would be best to have a separate vdpint.s and vdpint.c to show the usage of H.TIMI hook....

I've updated the examples and fusion_c header and added the VdpInt example as well functions to the lib, so it is up to the user to choose if they want to hook to VDP Interrupts (60 or 50Hz "timer") or if they need to hook to all interrupts (check if your peripheral has interrupted).

Hope this will work for everyone. Wink

By ericb59

Paladin (986)

Аватар пользователя ericb59

10-04-2020, 10:52

thank you ducasp

By fregarni

Supporter (16)

Аватар пользователя fregarni

12-04-2020, 10:43

Thanks to all, I'll try it with ducasp's code.

By ericb59

Paladin (986)

Аватар пользователя ericb59

18-05-2020, 11:57

Hello

I just find another way to init an interrupt handler.
Using the MSX-DOS INT38

After some testing, it seems it do does not work properly with other big ASM routines like FX or PT3 Players, But perhaps theses routine must be tweak for this purpose ?

what do you think of this all-specialists ?


#include "fusion-c/header/msx_fusion.h"
#include 


unsigned int * vector;                          // Define a pointer


static unsigned int count = 0;

/* --------------------------------------------------------- */
void my_interrupt( void ) __critical __interrupt
{
  count++;  
}

/* --------------------------------------------------------- */
int main( void ) {
  unsigned int prev_count;
  unsigned int saveVector;

  saveVector=(*(unsigned int *)0x0039);        
 
  vector = (unsigned int *) 0x0039;      // Assign the pointer to the Dos Int38


  Cls();

  printf("DOS Interrupt test, hold ESC to exit...\r\n");
  
  *vector = (unsigned int) my_interrupt;   // Modify the pointer to go to my ow,n routine

  prev_count = 0;
  while( prev_count < 600 ) {
    
     if (prev_count != count)
     {
     
        prev_count = count;
     
        Locate(10,2);
        printf( "%d\n\r", prev_count );     

     }
     if (Inkey()==0x1b)
           break;
  }

  *vector = (unsigned int) saveVector;    // REturn to Normal Interrupt

  Locate(1,3);
  printf("Done!\r\n");
  Exit(0);
}

Страница 4/4
1 | 2 | 3 |