Fusion_C and HTIMI

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

By ducasp

Champion (366)

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

07-04-2020, 14:37

DarkSchneider wrote:

Without more details, this is how I set the H.TIMI routine before moving to IM2:

TIMI equ 0FD9FH
RAMAD0 equ 0F341H
RAMAD1 equ 0F342H
RAMAD2 equ 0F343H
RAMAD3 equ 0F344H

; set H.TIMI
public isrset@
isrset@:
	di
	; TIMI
	ld hl, TIMI
	ld de, oldtim
	ld bc, 5
	ldir
	ld a, 0F7H
	ld (TIMI), a
	ld a, (RAMAD1)
	ld (TIMI+1), a
	ld hl, newtim@
	ld (TIMI+2), hl
	ld a, 0c9h
	ld (TIMI+4), a
	ei
	ret

; restore H.TIMI
public isrrst@
isrrst@:
	di
	; TIMI
	ld hl, oldtim
	ld de, TIMI
	ld bc, 5
	ldir
	ei
	ret

oldtim:
	ret
	ret
	ret
	ret
	ret

At newtim, remember to put at the end:
;public newtim@
newtim@:
...
	jp oldtim

Instead RAMAD1 you could use the one which the code is located, but usually all the segments point to the same RAM slot, not involving DOS2 segment functions (that's another story). By this way it works (tested) even when located at page 0, as the system will call the ISR, and the ISR will use the hook, doing the inter-slot by itself.

Hey Eric,

I think you should try to use DarkSchneider example, I think his idea is best for a C library as it is generic enough to not need any specific addressing on the interrupt function. Cool

By ducasp

Champion (366)

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

07-04-2020, 18:30

By the way, based on DarkSchneider example, I've made a concept code for interrupt.s, interrupt.c and the library header

https://drive.google.com/open?id=1inY5kp2QYKCJtnjxVaNr4GbV56...

I've ditched the register function, just passing the interrupt function as parameter to InitInterruptHandler.

Also, since it is using the hook, it is way, waaaaay easier, no need to proccess anything or save registers as BIOS do that for us.

But I couldn't test it and there is a chance it is not 100% ok, do not know why, but if I compile the library it won't work anymore and I get the SDCC linker crashing with my lib, hopefully this is a good start point.

P.s.: based it on HKEY.I hook, as it works on any interrupt which makes more sense than HTIM.I that hooks to the VDP interrupt only.

By thegeps

Hero (555)

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

07-04-2020, 19:05

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

By ducasp

Champion (366)

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

07-04-2020, 20:35

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.

By ericb59

Paladin (986)

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

08-04-2020, 09:31

Thank you DarkSchneider and Ducasp, I will test that LOL!

By ericb59

Paladin (986)

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

08-04-2020, 10:47

Hi Ducasp
I'm able to include the new interrupt in the library, and compil programs without crash.

But, It seems that the MSX crash when I introduce a Bios Call function. example

static unsigned int count = 0;

/* --------------------------------------------------------- */
void my_interrupt( void ) {

  if( IsVsync() == 0 ) return;

  count++;  
}

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

  prev_count = 0;
  while( prev_count < 600 ) {

    DisableInterrupt();
    prev_count = count;
    
   
    EnableInterrupt();
    Locate(10,1);
    printf( "%d\n\r", prev_count );
  }
  EndInterruptHandler();
  return 0;
}

When I use the Locate function the MSX crash.
I also tried to put the Locate in the "DisableInterrupt's block", but it do the same.

By thegeps

Hero (555)

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

08-04-2020, 13:08

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

By ducasp

Champion (366)

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

08-04-2020, 17:07

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

By ducasp

Champion (366)

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

08-04-2020, 17:10

ericb59 wrote:

Hi Ducasp
I'm able to include the new interrupt in the library, and compil programs without crash.

But, It seems that the MSX crash when I introduce a Bios Call function. example

static unsigned int count = 0;

/* --------------------------------------------------------- */
void my_interrupt( void ) {

  if( IsVsync() == 0 ) return;

  count++;  
}

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

  prev_count = 0;
  while( prev_count < 600 ) {

    DisableInterrupt();
    prev_count = count;
    
   
    EnableInterrupt();
    Locate(10,1);
    printf( "%d\n\r", prev_count );
  }
  EndInterruptHandler();
  return 0;
}

When I use the Locate function the MSX crash.
I also tried to put the Locate in the "DisableInterrupt's block", but it do the same.

There was a silly bug, instead of saving C9 that was in A after the hook RST 30 it was saving HL and thus this was causing some registers to change as result of the content o HL that made it an instruction to change E contents.... Eek!

Fixed that on my google drive, just download the latest version of interrupt.s and it should work fine now. Tongue

By thegeps

Hero (555)

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

08-04-2020, 20:34

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

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