KVC@ENGVAX.UUCP ("Kevin Carosso") (11/01/86)
[VMS V4.4, VAX Ada V1.0] VAX Ada has a mechanism that allows you to use VMS ASTs within Ada programs by treating the AST as an event that can be handled by an ACCEPT statement in a rendezvous. This is documented in the Ada doc set, with examples. The screen manager (SMG$) package has a facility called SMG$ENABLE_UNSOLICITED_INPUT which "detects unsolicited input and calls an AST routine in response". Unfortunately, ENABLE_UNSOLICITED_INPUT cannot be used with the VAX Ada mechanism described above. You will get unhandled exceptions in the Ada run-time library and bomb out with "ERRONEOUS PROGRAM". It turns out that the problem is traced to the fact that the SMG package calls the "AST routine" with an argument list that does not conform to the description of an AST argument list as documented in the System Services reference manual. Normally, an AST routine is called by VMS with 5 arguments. SMG adds one argument of it's own to the *beginning* of the list of arguments and calls your AST routine with 6. Normally this is not a problem, but since the Ada run-time library fiddles with the argument list to handle task scheduling at the rendezvous, it breaks completely and gets an access violation attempting to access an address through the argument which contains the value of the PSL. I believe that SMG is broken because it claims to call an AST routine but does not pass an argument list for an AST routine, as documented in section 5.4 of the "System Services Reference Manual" and section 7.3.2 of "VAX/VMS Internals and Data Structures" Here is a very simple-minded fix I whipped up to get around this problem for simple cases. It could be expanded to handle arbitrary numbers of pasteboards. /Kevin Carosso kvc%engvax.uucp@csvax.caltech.edu Hughes Aircraft Co. --------------- ADA_SMG_BUG.MAR -------------------- .Title ADA_SMG_BUG ;++ ; ; A little code to get around that fact that the SMG routine ; SMG$ENABLE_UNSOLICITED_INPUT calls the AST routine with 6 arguments ; and VAX Ada AST handlers in a rendezvous can only handle 5 arguments. ; ; Written by Kevin Carosso @ Hughes Aircraft, SCG/CTC, 31-OCT-1986 (boo!) ; ; Note that this code is non-reentrant and can only be called once ; to set up an unsolicited input on one pasteboard. Also, the ; pasteboard ID is NOT passed to the AST handler, since you've only ; get one anyway. We'll return SS$_BADPARAM if we are called more ; than once without being disabled. ; ; You should use the matching routine SMG_DISABLE_UNSOLICITED_INPUT_5 ; so that we clean up properly. You can then enable an unsolicited ; input for another AST handler and/or another pasteboard. ; ;-- .Psect ADA_SMG_BUG_DATA, noexe, rd, wrt real_AST_routine: .long 0 ; Space for saving real AST handler .Psect ADA_SMG_BUG_CODE, exe, rd, nowrt .Entry SMG_ENABLE_UNSOLICITED_INPUT_5, ^M<> movzwl #SS$_BADPARAM, r0 tstl real_AST_routine ; Make sure we haven't been used. bneq done movl 8(ap), real_AST_routine ; Save his routine's address moval AST_intercept, 8(ap) ; Put our intercept into arg block callg (ap), G^SMG$ENABLE_UNSOLICITED_INPUT done: ret .Entry SMG_DISABLE_UNSOLICITED_INPUT_5, ^M<> clrl real_AST_routine ; Make sure we can get used again. callg (ap), G^SMG$DISABLE_UNSOLICITED_INPUT ret .Entry AST_intercept, ^M<> pushl 24(ap) ; Set up the args we really want pushl 20(ap) pushl 16(ap) pushl 12(ap) pushl 8(ap) calls #5, @real_AST_routine ; and call the real handler ret .End