RayeR
CZ, 05.12.2020, 00:26 |
Turbo C - ISR chaining? (Developers) |
Hi, is there some helper function/macro in Borland BC/TC for chaining ISR (DJGPP has such feature)? I'd like to hook and let my ISR code be called first, without modifying registers and when done call the old ISR with original registers. Problem is that BC automatically saves and restores all registers in ISR in its prolog/epilog code and when i do
ISR()
{
mycode;
oldisr();
}
then oldisr gets changed registers by my code and registers that oldisr sets are vanished by epilog code that restores all, so I'd need to call it in order
ISR()
{ // epilog save regs
mycode;
} // epilog restore regs
oldisr(); // call old ISR with original regs
I prefer to do as much as possible in C and avoid ASM but if BC/TC have any helper I'll have to do ASM. BTW can BC/TC do naked function? --- DOS gives me freedom to unlimited HW access. |
tkchia
05.12.2020, 07:09
@ RayeR
|
Turbo C - ISR chaining? |
Hello RayeR,
> Hi, is there some helper function/macro in Borland BC/TC for chaining ISR
> (DJGPP has such feature)? I'd like to hook and let my ISR code be called
> first, without modifying registers and when done call the old ISR with
> original registers. Problem is that BC automatically saves and restores all
Turbo C++ 3.0 and Borland C++ 3.1 apparently have a _chain_intr function which does this, though I have not tried it myself.
_chain_intr is also in Open Watcom, but not in Turbo C 2.x.
Thank you! --- https://gitlab.com/tkchia · https://codeberg.org/tkchia · 😴 "MOV AX,0D500H+CMOS_REG_D+NMI" |
alexfru
USA, 05.12.2020, 09:48
@ RayeR
|
Turbo C - ISR chaining? |
> Hi, is there some helper function/macro in Borland BC/TC for chaining ISR
> (DJGPP has such feature)? I'd like to hook and let my ISR code be called
> first, without modifying registers and when done call the old ISR with
> original registers. Problem is that BC automatically saves and restores all
> registers in ISR in its prolog/epilog code and when i do
> ISR()
> {
> mycode;
> oldisr();
> }
> then oldisr gets changed registers by my code and registers that oldisr
> sets are vanished by epilog code that restores all, so I'd need to call it
> in order
> ISR()
> { // epilog save regs
> mycode;
> } // epilog restore regs
> oldisr(); // call old ISR with original regs
>
> I prefer to do as much as possible in C and avoid ASM but if BC/TC have any
> helper I'll have to do ASM. BTW can BC/TC do naked function?
There's something that may let you access the registers on the stack:
This seems to work with Turbo C++ 1.01:
#include <dos.h>
#include <stdio.h>
typedef struct {
int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,fl;
} IREGS;
void interrupt far isr(IREGS ir)
{
ir.ax = ~ir.ax;
}
int main(void)
{
struct REGPACK regs;
int i;
setvect(0, isr);
memset(®s, 0, sizeof regs);
for (i = 0; i < 4; i++)
{
regs.r_ax = i;
intr(0, ®s);
printf("%04X\n", regs.r_ax);
}
return 0;
}
OW has something similar:
#include <i86.h>
void __interrupt int10(union INTPACK r)
{
...
}
Please check documentation and look this up in more detail.
With this you should be able to examine and modify the return address on the stack and make your ISR "chain" to another. |
RayeR
CZ, 06.12.2020, 18:25
@ tkchia
|
Turbo C - ISR chaining? |
> Turbo C++ 3.0 and Borland C++ 3.1 apparently have a
> _chain_intr
Thaks, it works as expexted. I couldn't find it because I search only for "chain" without underscore at the begining so BC help show nothing relevant. --- DOS gives me freedom to unlimited HW access. |
RayeR
CZ, 06.12.2020, 18:29
@ alexfru
|
Turbo C - ISR chaining? |
> With this you should be able to examine and modify the return address on
> the stack and make your ISR "chain" to another.
It's always better to avoid this dirty hacks that depends on ABI. Seems that many C compilers (at least we know DJGPP, BC, OWC) provides clean solution with chain_something function/macro... --- DOS gives me freedom to unlimited HW access. |
alexfru
USA, 07.12.2020, 06:32
@ RayeR
|
Turbo C - ISR chaining? |
> > With this you should be able to examine and modify the return address on
> > the stack and make your ISR "chain" to another.
>
> It's always better to avoid this dirty hacks that depends on ABI. Seems
> that many C compilers (at least we know DJGPP, BC, OWC) provides clean
> solution with chain_something function/macro...
What you want is bound to be one kind of dirty hack or another. It's not standard in any way (not de jure standard C, not de facto standard MSDOS C). You can write proper assembly code for this but you told us you didn't want to. |
tom
Germany (West), 07.12.2020, 14:42 (edited by tom, 07.12.2020, 22:11)
@ alexfru
|
Turbo C - ISR chaining? |
> > > With this you should be able to examine and modify the return address
> on
> > > the stack and make your ISR "chain" to another.
> >
> > It's always better to avoid this dirty hacks that depends on ABI. Seems
> > that many C compilers (at least we know DJGPP, BC, OWC) provides clean
> > solution with chain_something function/macro...
>
> What you want is bound to be one kind of dirty hack or another. It's not
> standard in any way (not de jure standard C,
of course not. 'standard C' runs everywhere; '__interrupt' works only on DOS.
> not de facto standard MSDOS C.
whatever standard MSDOS C you are referring to, MSC has had this from version 1.0. WATCOM as well.
having __interrupt but not chain_intr() is just unlikely.
edited to add: Borland compilers (TC, TCPP, BC) indeed seem to have missed this function (and of course SmallC, smallerC, C-- never had this. but I wouldn't call them 'standard' in any way). which made the __interrupt functions able to function as COMx handlers, but not able as multiplex (int 2f) function handlers. |