ballerup@diku.dk (Per Goetterup) (01/06/91)
CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) writes: => In article <1991Jan4.145541.17737@odin.diku.dk>, I wrote: => ... => > I'm having some rather weird problems with a program of mine => >which needs to get something updated on the screen no matter what => >else the program might be doing. => > I'm using interrupt 1C (User Timer Tick) to call my procedure which => >by the way DOESN'T call DOS (common error) - it only modifies the screen => >memory. => > The problem is not to get it to work (it does) but what => >happens next. I start it up by saving the old vector then => >re-assigning it to point at my handler (procedure). This does indeed => >work and the screen get modified as it should while my is running => >happily along. So far so good. Then something might happen because => >sometimes the computer simply stops in the middle of the program and => >lock up (refusing warm-boots), other times it runs all the way to => > => [remainder deleted] => Your description (sans code) doesn't indicate whether you are => providing for a repeat of the interrupt while you are servicing it. => I.e., if you are still inside your routine when another 1C or 08 => call occurs, what happens? While I don't think this question => addresses the problem with lockups that occur after exiting your => program, it may yield clues to some of the other behavior you => describe. I think you're right Karl. I didn't provide for the possibility that another interrupt might occur while I was servicing the previous interrupt, thus creating a recursive routine that fast messed the stack up completely. One of the answers I got indicated this and I've tried it. Now everything runs, if it runs, because now the program either will run flawlessly until (intended) termination when it (again) freezes the machine, or it will crash on my very first append-to-pointer-chain call. This last action ONLY happens when run from an EXE-file (as far as I've seen). I've tried to see if I somehow didn't reach the point where I reset the vector to its old value, by simply omitting the reset to see what happens, and still the machine crashed at the end of the program, only now the interrupt kept on running, updating the screen! - The machine still refused warm-boots! - What happens here? I've created a small test program that, using a simple clock, tests the various solutions I get or think of. Unfortunately I didn't bring it with me today, but I can provide it if nessesary. I've also got suggestions (from elsewhere) to use interrupt 16h (keyboard I/O) which gets called every time the machine isn't too busy doing hard CPU or disk work. Anybody got expirences in using this??? Also, when should I call the old service routine from within my new one? - First, last or in the middle? All help very appreciated! Per. PS: I'm using an IBM PS/2 model 80 (386) running PC-DOS 3.30 and TP 6.0 -- | Per Gotterup | "The most merciful thing in the | | Student, DIKU (Dept. of Comp. Sci.) | world, I think, is the inability | | University of Copenhagen, Denmark | of the human mind to correlate all | | Internet: ballerup@freja.diku.dk | its contents." - H.P. Lovecraft - |
ftpam1@acad3.alaska.edu (MUNTS PHILLIP A) (01/08/91)
In article <1991Jan6.150656.8281@odin.diku.dk>, ballerup@diku.dk (Per Goetterup) writes... [much deleted] >Also, when should I call the old service routine from within my new one? - >First, last or in the middle? Unless you run your program from another that uses INT 1CH, there won't BE any old routine. The vector points to an IRET in ROM on my machine (286 with DOS 3.3) unless changed by the user program. If you are simply running one program from DOS, just point the vector to an interrupt procedure in the TP6 program. You should reset the vector in an exit routine (Programmer's Guide p. 247), not just at the end of the main program. Otherwise, abnormal program exit (like HALT, run time error, or ^C) will hash DOS for you by leaving vectors pointing into never never land (where your program used to be). If you are nesting programs that use INT 1CH, you will need to carefully consider what you want to happen before chaining the INT 1CH interrupt procedures. Should you decide to chain, you should do it at the end of the interrupt procedure, after saved registers have been unstacked (but leave flags and return address) and before the final IRET, which should be replaced by a long jump to the original service procedure. This all requires a lot of inline machine code to get the stack in the right state before the long jump. If you think this is bad, just wait until you try ^C and/or BREAK handlers. Philip Munts N7AHL NRA Extremist, etc. University of Alaska, Fairbanks
dave@tygra.ddmi.com (David Conrad) (01/09/91)
In article <1991Jan6.150656.8281@odin.diku.dk> ballerup@diku.dk (Per Goetterup) writes: >I've also got suggestions (from elsewhere) to use interrupt 16h (keyboard >I/O) which gets called every time the machine isn't too busy doing hard CPU >or disk work. Anybody got expirences in using this??? This is not true. 16h is called by the running program to get keystrokes from the keyboard or to check to see if any are waiting in the buffer. It's called as often as the running program calls it - no more and no less. This is usually fairly frequently, but can be arbitrarily infrequent if the program is busy, or worse, stuck. There is an interrupt which is called when the computer is idle, 28h, called the DOS Idle interrupt. The only place I know of this being called from is interrupt 21h function 1, get keyboard input. DOS calls 28h in a loop while waiting for keystrokes. If a program does its input via the BIOS (16h) instead of DOS (21h) then 28h won't normally be called. >Also, when should I call the old service routine from within my new one? - >First, last or in the middle? Last. You want to do a far jump to the old handler instead of an iret to exit your handler. The old handler will either do the iret or a far jump to an even 'older' handler. Somewhere down the line the iret will be done (otherwise the computer wouldn't have been working before you installed your handler). Exiting your handler in this way allows all the handlers which are chained to the interrupt to 'see' it and get their crack at servicing it. This makes your handler 'well behaved'. >-- >| Per Gotterup | "The most merciful thing in the | >| Student, DIKU (Dept. of Comp. Sci.) | world, I think, is the inability | >| University of Copenhagen, Denmark | of the human mind to correlate all | >| Internet: ballerup@freja.diku.dk | its contents." - H.P. Lovecraft - | -- David R. Conrad dave@tygra.ddmi.com uunet!tygra!dave -- = CAT-TALK Conferencing Network, Computer Conferencing and File Archive = - 1-313-343-0800, 300/1200/2400/9600 baud, 8/N/1. New users use 'new' - = as a login id. AVAILABLE VIA PC-PURSUIT!!! (City code "MIDET") = E-MAIL Address: dave@DDMI.COM
dave@tygra.ddmi.com (David Conrad) (01/09/91)
In article <1991Jan8.034315.15222@ims.alaska.edu> ftpam1@acad3.alaska.edu writes: >In article <1991Jan6.150656.8281@odin.diku.dk>, ballerup@diku.dk (Per Goetterup) writes... > >>Also, when should I call the old service routine from within my new one? - >>First, last or in the middle? > > Unless you run your program from another that uses INT 1CH, there won't >BE any old routine. The vector points to an IRET in ROM on my machine (286 >with DOS 3.3) unless changed by the user program. The iret in ROM *is* the old routine. Nothing wrong with chaining to the default handler and letting it do the iret for you. Safest way to do it. >Should you decide to chain, you should do it at the end of the >interrupt procedure, after saved registers have been unstacked (but leave flags >and return address) and before the final IRET, which should be replaced by a >long jump to the original service procedure. This all requires a lot of >inline machine code to get the stack in the right state before the long jump. Once you've popped anything (registers, locals) you pushed onto the stack, it should be in the right state for the far jump. And you have to pop what you pushed anyway. You just don't get to let Turbo generate the code for you. I'd write an interrupt handler in asm to begin with, anyway. >Philip Munts N7AHL >NRA Extremist, etc. >University of Alaska, Fairbanks -- David R. Conrad dave@tygra.ddmi.com -- = CAT-TALK Conferencing Network, Computer Conferencing and File Archive = - 1-313-343-0800, 300/1200/2400/9600 baud, 8/N/1. New users use 'new' - = as a login id. AVAILABLE VIA PC-PURSUIT!!! (City code "MIDET") = E-MAIL Address: dave@DDMI.COM
reino@cs.eur.nl (Reino de Boer) (01/10/91)
dave@tygra.ddmi.com (David Conrad) writes: >>Also, when should I call the old service routine from within my new one? - >>First, last or in the middle? >Last. Except when taking over the timer interrupt(s) ? >>-- >>| Per Gotterup | "The most merciful thing in the | >-- >David R. Conrad dave@tygra.ddmi.com uunet!tygra!dave -- Reino R. A. de Boer "We want to build the right product right, right?" Erasmus University Rotterdam ( Informatica ) e-mail: reino@cs.eur.nl