Strange bug in ISR

DOS specific questions.
Post Reply
Cpcdos
Posts: 207
Joined: Mar 06, 2013 13:52
Location: France - LYON 69003
Contact:

Strange bug in ISR

Post by Cpcdos »

Hello all! :-)

I would to know, why my ISR timer is stopped when i change my screen resolution ?

My code example (FreeBASIC\examples\DOS\isrtimer.bas) :

Code: Select all

#include "dos/dpmi.bi"
#include "dos/go32.bi"

type FnIntHandler as function cdecl( byval as uinteger) as integer

declare function fb_isr_set cdecl alias "fb_isr_set"( _
	byval irq_number as uinteger, _
    byval pfnIntHandler as FnIntHandler, _
    byval size as uinteger, _
    byval stack_size as uinteger = 0) as integer

declare function fb_isr_reset cdecl alias "fb_isr_reset"( _
	byval irq_number as uinteger ) as integer

declare function fb_isr_get cdecl alias "fb_isr_get"( _
	byval irq_number as uinteger ) as FnIntHandler


dim shared isr_data_start as byte
dim shared timer_ticks as integer
dim shared old_isr as FnIntHandler
dim shared isr_data_end as byte

private function isr_timer cdecl( byval irq_number as uinteger) as integer
    timer_ticks += 1
    locate 1, 1 : print " Timer:" & timer_ticks

    if old_isr<>0 then
        function = old_isr( irq_number )
    else
        function = 0   ' FALSE = we don't want to abort ISR handling
               '         IOW: call the old ISR handler
    end if
end function
private sub isr_timer_end cdecl()
end sub

if _go32_dpmi_lock_data( @isr_data_start, @isr_data_end - @isr_data_start )<>0 then
    print "Failed to lock data"
    end 1
end if

old_isr = fb_isr_get( 0 )

dim as byte ptr ptr_end = cast( byte ptr, @isr_timer_end )
dim as byte ptr ptr_start = cast( byte ptr, @isr_timer )
if 0 = fb_isr_set( 0, @isr_timer, ptr_end - ptr_start, 16384 ) then
    print "Failed to lock ISR"
    end 1
end if

locate 3, 2 : print "Press ENTER to change in 800x600"

sleep
screenres 800, 600, 16
locate 3, 2 : Print "Perfect!"
sleep

fb_isr_reset( 0 )

print timer_ticks
end
After "screenres 800, 600, 16" ----> TIMER ---> BLOCKED :(

For resolve my problem, i create a another ISR

Code: Select all

old_isr = fb_isr_get( 1 )

dim as byte ptr ptr_end = cast( byte ptr, @isr_timer_end )
dim as byte ptr ptr_start = cast( byte ptr, @isr_timer )
if 0 = fb_isr_set( 1, @isr_timer, ptr_end - ptr_start, 16384 ) then
    print "Failed to lock ISR"
    end 1
end if
But i can't do this when I change ervery time my screen resolution! :/

Can you help me ?
Best regards
jamjamason
Posts: 20
Joined: Jul 17, 2012 18:51

Re: Strange bug in ISR

Post by jamjamason »

Had a similar problem where the SLEEP command was unloading my interrupt handler from the interrupt vector table. I didn't find a solution to it, nor an explanation for why it happened. I just had to stop using SLEEP.

If you find out anything, let me know!
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Strange bug in ISR

Post by MichaelW »

As far as I know, at least under some conditions, fbgfx hooks the timer interrupt and reprograms system timer 0 to increase the interrupt rate and timer resolution. You can verify if this is the problem by comparing the interrupt vector address before you change the screen resolution to that after.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Strange bug in ISR

Post by D.J.Peters »

If I remeber my right in the old DOS days
if a interrupt vector was set you saved the address and installed your own
and after your own was executed you called the vector you found before.

Sorry if I'm wrong but it was a kind of interrupt chain.

Joshy
Cpcdos
Posts: 207
Joined: Mar 06, 2013 13:52
Location: France - LYON 69003
Contact:

Re: Strange bug in ISR

Post by Cpcdos »

Hi,
I have resolved my problem, I just wrote a C ISR library with GCC (.a) and use

Code: Select all

extern "c" lib "MyLib"
in Fb
and this work :-)
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

Re: Strange bug in ISR

Post by DOS386 »

> would to know, why my ISR timer is stopped when i change my screen resolution ?

Because SCREEN installs it's own ISR and increases the PIT frequency: http://sourceforge.net/p/fbc/code/ci/ma ... /gfx_dos.c

> where the SLEEP command was unloading my interrupt handler

Funny. Seems to redirect to "fb_Delay" and "usleep": http://sourceforge.net/p/fbc/code/ci/ma ... ys_delay.c

See also (TIMER can cause disk accesses: http://www.freebasic.net/wiki/wikka.php ... KeyPgTimer http://sourceforge.net/p/fbc/code/ci/ma ... me_timer.c).

> and this work

:-) (or activate your ISR __AFTER__ SREENRES and remove it __BEFORE__ "SCREEN 0").
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Strange bug in ISR

Post by MichaelW »

You can hook the DOS Interrupt 21h vector and wait for the FreeBASIC runtime to change the system timer 0 (IRQ0) interrupt vector, then arrange for your handler as well as the FreeBASIC runtime handler to be called, both at the required rate.
Post Reply