Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!unisoft!gethen!bdt!david From: david@bdt.UUCP (David Beckemeyer) Newsgroups: comp.sys.atari.st Subject: Re: TRAP handler question Message-ID: <197@bdt.UUCP> Date: 28 Mar 88 23:22:54 GMT References: <3738@watcgl.waterloo.edu> Reply-To: david@bdt.UUCP (David Beckemeyer) Organization: Beckemeyer Development Tools, Oakland, CA Lines: 102 In article <3738@watcgl.waterloo.edu> jafischer@lily.waterloo.edu (Jonathan A. Fischer) writes: > This will undoubtedly reveal the vast storehouse of ignorance I have >at my fingertips, but here goes anyway... > > Since "Tempus" came out, it seems that countless programmers took it >as a personal challenge to write some screen routines that were as fast. >Myself included. Well, writing the printing routines wasn't much trouble (a >nice intro to 68000 assembly language programming, I felt), but in trying to >hook the thing into the GEMDOS trap handler so that it catches Cconws() calls, >I've come across a pretty strange bug. Hopefully someone can help me out. > > I use oldvect = Setexc(...) to point TRAP #1 to my trap handler with >no problem. In the trap handler, I check 6(sp) for the function number. This >is where the problem is... >============================================================================== >fp_handler_: > cmpi.w $9,6(sp) / Never results in "true" condition. > beq is_Cconws > > movea.l oldvect,a0 / Not Cconws(), so jump to GEMDOS. > jmp (a0) > >is_Cconws: > move.l (sp),4(sp) / Overwrite GEMDOS function number with return > lea 4(sp),sp / address. > jmp fastprt / Jump to the fast print routine. >============================================================================== I don't want Jonathon to feel as though I'm flaming him. This is a posting that hopefully everybody will find informative. First, besides from the "bug" you're describing, it's never gonna work to catch Cconws() like this (as you mention), but I'll get to that later. GEMDOS is entered via a TRAP #1 instruction. The 68000 has a supervisor and user mode, each with separate stacks. The 68000 exception stack frame (like from an Interrupt or Trap) looks like this: (sp) -> word SR (status register) 2(sp) -> long return PC (program return address) When an exception is generated, the 68000 pushes the SR register and the current PC onto the supervisor stack, regardless of whether the processor was running in user or supervisor mode at the time. SP (or A7) addresses the Supervisor stack when the trap handler is entered. There is a bit in the SR on the stack that indicates which mode the CPU was running in. It can be checked like this: btst.b #5,(sp) bne in_super in_user: move.l usp,a0 * arguments are on User Stack bra go_on in_super: lea 6(sp),a0 * arguments are on Supervisor Stack go_on: cmp.w #9,(a0) * look at GEMDOS func. code beq is_Conws The above code will load the A0 register with a pointer to the GEMDOS arguments (including the function #). For Cconws() that means: (a0) -> word 9 (Conws func. code) 2(a0) -> long address of string to print. And now for the real problem.... > Actually, I'll probably end up using a different method, since this >will only speed up Cconws(), and a lot of programmers use Bconout(1, character) >in a loop, since it's faster than Cconws(). Ideally, I'd like to have ALL >screen text output (non-VDI) go through the fastprt() routine. If someone can >tell me how to do this (without checking explicitly for one of Cconout(), >Cconws(), Bconout(1, ch), and Fwrite() to stdout), then I'd appreciate it. > > (And yes, I know I'll have to add a test for stdout being redirected to >a file.) Exactly. Cconws() does NOT simply mean "print to the screen". It means "write a string to GEMDOS standard output (handle 1)". You can't just catch the Cconws() call to make a real output handler. You must deal with anything that uses handle 1, including watching for redirection with Fforce(), or Fwrite()'s to handle 1. Catching Bconout(2, c) and Bcostat(2) is probably the best solution to catching all non VDI characters. It's clean, but you will have to interpret the vt-52 escape codes if you want to remain compatible. The trap handling idea above will work in a similar manner to catch the Bios (trap #13) calls. Catching the BIOS calls will have the best chance for compatibility with the most programs. Messing around at the GEMDOS level could cause lot's of things to break. The vt-52 escape codes that the ST uses are documented in the Atari "Hitchhikers Guide to the BIOS". -- David Beckemeyer | "Yuh gotta treat people jes' like yuh Beckemeyer Development Tools | do mules. Don't try to drive 'em. Jes' 478 Santa Clara Ave, Oakland, CA 94610 | leave the gate open a mite an' let 'em UUCP: ...!ihnp4!hoptoad!bdt!david | bust in!"