🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #31566

Re: TRAP handler question

#31566
From: David Beckemeyer
Date: Mon, 28 Mar 1988 23:22
103 lines
4946 bytes
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!"
Technical Details
Message-ID: <197@bdt.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!lll-winken!lll-lcc!unisoft!gethen!bdt!david
References: <3738@watcgl.waterloo.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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