acmfiu@serss0.fiu.edu (ACMFIU) (01/13/91)
I have the following inline asm function to handle HeartBeat interrupts. my
main purpose for using it is to catch keypresses and pause control of the
program in progess. Then, I just wait for another keypress. Also, if the
user presses oa-period, then the program should immediately end, regardless
of where it is.
However, when i oa-period 3/4 times, the computer crashes. can anyone
suggest a better (i.e. WORKING) solution to my problem.
asm void
check_key (void)
{
dcl 0
count: dcw 10
dcw 0xa55a
phb
phk
plb
php
rep #0x30
lda #10
sta count
sep #0x20
lda >0xe0c000
bpl end
cmp #0xae
bne wait
lda >0xe0c025
and #0x80
beq wait
rep #0x20
lda >0xe0c010
jsl raise_signal
bra end
wait: lda >0xe0c010
rdkey: lda >0xe0c000
bpl rdkey
lda >0xe0c010
end: rep #0x20
plp
plb
dcb 0x6b
}
void
raise_signal (void)
{
raise (SIGTERM);
}
void
bye (int sig)
{
fclose (global_file);
DelHeartBeat (check_key);
exit (1);
}
int
main (int argc, char **argv)
{
signal (SIGTERM, bye);
SetHeartBeat (check_key);
<blah>
}
-----------------------
albert chin ... acmfiu@fiu.eduAABENSON@MTUS5.BITNET (01/13/91)
Well, I'm assuming you're using Orca or APW C? Why not make a tool call to SetVector (I think that's the name) to patch "keyboard interrupts," and then make another call to IntSource to enable "Keyboard Interrupts." I put this in quotation marks, because there isn't such a thing, but it is simulated by the firmware by using the Heartbeat Queue and VBL interrupts. - Andrew. (aabenson@balance.cs.mtu.edu or aabenson@mtu.edu)
acmfiu@serss0.fiu.edu (ACMFIU) (01/18/91)
Awhile back I posted a message concerning HeartBeat interrupts. I wanted to,
when a key was pressed, pause my program and, if oa-period was pressed,
terminate the program. Thanks to Tim Meekins and Jawaid Bazyar for their
responses. I have come up with the following code, although their remains to
be one bug.
int
main (void)
{
char *kybdvector;
<blah>
EMStartup (blah);
kybdvector = GetVector (kybdIntHnd);
SetVector (kybdIntHnd, check_key);
<blah>
bye ();
}
void
bye (void)
{
SetVector (kybdIntHnd, kybdvector);
EMShutDown ();
Close (0); /* close all files */
exit (1);
}
asm void
check_key (void)
{
rep #$30 /* just to make sure */
php
phb
phk
plb
jsl incbusyflag
lda $e0c000
bpl end
cmp #"."
bne wait
lda $<wherever oa status is>
cmp #<is oa key pressed>
bne wait
pha /* space for result */
pushlong #bye
_SchAddTask
pla /* i KNOW it worked */
bra end
wait pha
pushlong #pause
_SchAddTask
pla
end plb
plp
jsl decbusyflag
rtl
}
asm void
pause (void)
{
lda $e0c000
wait lda $e0c010
bpl wait
lda $e0c000
rtl
}
What I basically do is startup the Event Manager which automatically makes
keyboard interrupts available (ala IntSource) and then I modify the interrupt
handler that the Event Manger uses for the keyboard interrupts to my own.
When I run my program, pressing any key appropriately causes the program to
pause, then I press the key again and it resumes execution. The problem comes
with oa-period. When I press it, the program ends and I'm back in the shell.
however, when I run it again, NO key I press does anything. It's like the
keyboard interrupts were disabled. If I press "AAAAAAAAAAAAAAA", they will
appear on the command line AFTER the program is finished executing.
My question is, how in the world do keyboard interrupts get disabled from
the above code (the above code is not 100% correct but you should get the
idea). Since I get the keyboard interrupt vector used by the Event Manager
and restore it before I EMShutDown(), how does it get corrupted?
I also used the above code without the Event Manager. Using the Misc Tool
Set you can do it via:
IntSource (kybdEnable);
kybdvector = GetVector (kybdIntHnd);
SetVector (kybdIntHnd, check_key);
<foo>
SetVector (kybdIntHnd, kybdvector);
exit (0);
Any ideas?
albert