From: CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 26-AUG-1989 00:38 To: MRGATE::"ARISIA::EVERHART" Subj: RE: Vax Pascal Question Message-Id: <8908260425.AA13507@crdgw1.ge.com> Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Fri, 25 AUG 89 20:49:41 PDT Received: from Ruby.VCU.EDU by KL.sri.com with TCP; Fri, 25 Aug 89 20:19:35 PDT Date: Fri, 25 Aug 89 22:49 EDT From: FRITZ@Ruby.VCU.EDU Subject: RE: Vax Pascal Question To: INFO-VAX@KL.SRI.COM X-Vms-To: NET%"INFO-VAX@KL.SRI.COM" tank!dwayne%rover.bsd.uchicago.edu@HANDIES.UCAR.EDU writes: >Hey!!!! > > Does any know the appropriate calling mechanism for an ast parameter. > >I'm declaring the thing like this: > >[ASYNCHRONOUS] PROCEDURE uis$set_pointer_ast ( > VD_ID0 : UNSIGNED; > WD_ID0 : UNSIGNED; > %IMMED [UNBOUND, ASYNCHRONOUS] PROCEDURE ASTADR; > ASTPRM : UNSIGNED; > X1 : SINGLE; > Y1 : SINGLE; > X2 : SINGLE; > Y2 : SINGLE; > %IMMED [UNBOUND, ASYNCHRONOUS] PROCEDURE EXITASTADR; > EXITASTPRM : UNSIGNED); EXTERNAL; > >I'm declaring my ast's like this: > >[unbound,ASYNCHRONOUS] PROCEDURE ENT_MENU_AST(slot:integer); > BEGIN > uis$text (VD_ID,1,ITEMS[SLOT],LOCX[SLOT],LOCY[SLOT]); > END; > >[unbound,ASYNCHRONOUS] PROCEDURE EXIT_MENU_AST(slot:integer); > BEGIN > uis$text (VD_ID,0,ITEMS[SLOT],LOCX[SLOT],LOCY[SLOT]); > END; There are two considerations here: persuading Pascal to accept your code, and getting the code to do the right thing. The first may be accomplished in two ways: 1) Declaring the procedure parameters as follows: %IMMED [UNBOUND, ASYNCHRONOUS] PROCEDURE Astadr(Slot: [volatile] integer); Astprm : [volatile] integer; or 2) Putting `%immed' and '%ref' in the call: uis$set_pointer_ast(vd_id,wd_id,%immed Astadr,%ref Slot, x1,y1,x2,y2,%immed Exitastadr,%ref Slot); In your case this will probably not work. Both ways wind up passing the *address* of Slot to uis$set_pointer_ast and thence to the ASTs themselves; if you do something like for j:=0 to max do uis$set_pointer_ast(...,j,...,j); you will wind up with each AST being passed j's address, so each will have the same value of Slot--and that value will be garbage! One way of getting around this is to pass the AST parameter by immediate value: %immed [unbound, asynchronous] procedure Astadr(%immed Slot: integer); %immed Astprm : integer; Unfortunately Pascal does not like you to write procedures that receive parameters by immediate value. You can trick Pascal like so: [unbound,asynchronous] procedure Ent_menu_ast(var fake: [volatile] char); var Slot: integer; begin Slot:=iaddress(fake); uis$text (VD_ID,1,ITEMS[SLOT],LOCX[SLOT],LOCY[SLOT]); end; This pretends that the integer passed by immediate value is the address of a char, then uses iaddress to change this `address' back into the integer it always was. The volatile var parameter discourages Pascal from trying to copy its value to the local stack frame. You would need to pass Ent_menu_ast to to uis$set_pointer_ast with an explicit %immed to override type checking. All of this is of course very unsupported. The other way to do it requires some change in the rest of your program, something like this: type shelf_type = record items: item_type; locX,locY: loc_type end; ... [asynchronous] procedure uis$set_pointer_ast ( ... %immed [unbound, asynchronous] procedure Astadr (var Shelf: [volatile] shelf_type); var Astprm : [volatile] shelf_type; ...); external; ... [unbound,asynchronous] procedure ent_menu_ast( var Shelf: [volatile] shelf_type); begin with Shelf do uis$text(vd_id,1,items,locX,locY); end; ... var stuff: array[0..max] of shelf_type; ... for j:=0 to max do uis$set_pointer_ast(...,stuff[j],...,stuff[j]); Now the address of Stuff[j] is passed to the AST routine, so each AST looks at a different shelf. If uis$text does not change its arguments then Shelf need not be declared var; but it should always be declared volatile, since it will be accessed by an AST routine.