On 21 Oct 2004 at 1:45, James Hunkins wrote: > 1) how can I make an executable piece of code generated with C68 into > an Executable thing that I can load into memory and link into the thing > list
When making FiFi, I had such a problem quite some time ago. What I wanted was for the user to be able to load FiFi via LRESPR (instead of exec) and then have the thing set up all by itself. I've included the assembler file to do that, perhaps you can adjust it and prepend it your code? However, I don't know to what extent C68 writes truly relocatable code, or needs some kind of relocator to be run as the first part of it (??) which would really be a big problem for things that aren't "executed" as such (??). > 2) how would I pass parameters to it? This could have been a problem. IIRC, the normal keywords to execute things don't allow you pass parameters to them. The way to do it would be to set up a job and pass it the parameters on the stack, in the normal way done by EX etc... Again, a long time ago I wrote something like that (EXEP), perhaps it is of use to you - appended. > 3) do I have to generate separate data space for each instance of an > executable being used or would the normal C variables be isolated from > different calls to the same executable code. I don't know the C compiler well enough for that; but I don't think it will have separate vars for the programs - they would all "share" the same variables. That can be good or bad, depending on what you want . If in doubt, go for a separate dataspace. Hope this helps Wolfgang (NB - I make no guarantee that the code works, even though the fifi one has been in use for ages IIRC EXEP also worked OK).
The following section of this message contains a file attachment prepared for transmission using the Internet MIME message format. If you are using Pegasus Mail, or any other MIME-compliant system, you should be able to save it or view it from within your mailer. If you cannot, please ask your system administrator for assistance. ---- File information ----------- File: thing.asm Date: 21 Oct 2004, 14:55 Size: 2476 bytes. Type: Program-source
******************************************************************* * * syntax: EXEP thingname$ [{,#chan,#chan.....}][;options$] * optional channel * optional options$ * NOTE the separators: , or ; * same for EXEP_W * syntax: result= EXEPF(thingname$ {,#chan,#chan.....}{;options$}) * optional channel * optional options$ * same for EXEPF_W * result is the error passed back... * these will EXEcute the thing, passing it the parameters on stack * * #chan MUST be preceded by the # * * * v. 1.03 1996 Apr 01 13:15:41 * * W. Lenerz 1992 * ******************************************************************* section file_bas xref use_thg xref free_thg xref get_thvect xref do_vect xref get_str xref get_str2 xref rt_int ; returns integer xref gu_achp xref gu_rchp XDEF fexw XDEF fexf XDEF fexfw XDEF fex fexfw BSR.S fexw BRA.S fexf2 fexf BSR.S fex ; do the work now fexf2 MOVE.W D0,D4 ; return parameter JMP rt_int ; return an integer fexw MOVEQ #-1,D7 BRA.S fex2 fex MOVEQ #0,D7 fex2 MOVEQ #0,D5 ; preset no channel CMP.L A3,A5 BEQ fxbp MOVEM.L A3/A5,-(A7) ; keep pointer to prameters MOVEQ #6,D4 ; D4 will hold bytes to add loop1 ADDQ.L #8,A3 CMP.L A3,A5 ; only one param (thing name) ? BEQ.S nothing ; yes ->... MOVE.B -7(A6,A3.L),D1 ; type byte ANDI.B #%01110000,D1 ; filter separator MOVE.B D1,D2 ; keep CMP.B #%00010000,D1 ; was separator ','? BNE.S opt_string ; no, so must be options string->... BTST #7,1(A6,A3.L) ; yes was ',' so was it preceded by #? BEQ fxbp2 ; no, so error! ADDQ.W #4,D4 ; one more channel BRA.S loop1 ; find out how many bytes we need opt_string CMP.B #%00100000,D2 ; was separator ';'? BNE fxbp2 ; no! error->... nothing MOVEQ #100,D0 BSR gu_achp BNE fexout2 ; leave if error MOVE.L (A7),A3 ; ptr to pram MOVEQ #100,D0 ; max length of thing name BSR get_str ; get this string (thing name) now MOVE.L A0,A5 ; A5 = my space thex1 BSR use_thg ; try to use this thing BNE free_sp2 ; ooops MOVEQ #-15,D0 CMP.L #1,4(A1) ; is thing executable? BNE free_sp2 ; no, so pb ; the thing is found and executable execth MOVE.L (A7),A3 ; start param MOVE.L 4(A7),D0 ; end of params (A5) SUBQ.L #8,D0 ; point to string now CMP.L A3,D0 BEQ.S no_str ; MOVE.L D0,A3 ; MOVE.L A1,A4 ; A4 = thing BSR get_str2 ; get parameter string BEQ fxbp3 ; if null length: error EXG A4,A1 ; A1 = thing, A4 = string MOVE.W D0,D7 ; D7.W = string length ADDQ.W #3,D0 BCLR #0,D0 ADD.W D0,D4 no_str MOVE.L A1,D5 ; keep pointer to thing MOVE.L $C(A1),D2 MOVE.L $10(A1),D3 ; data & code space ADD.L D4,D3 ADDQ.L #1,D3 BCLR #0,D3 ; make even MOVE.L D4,D6 ; keep this - total length MOVE.L D3,D4 ADD.L D2,D4 ; D4 = total length of job MOVE.L $14(A1),D0 ; where do we start ? BEQ.S at_head ; at header ADD.L D0,A1 ; point to code BRA.S do_it at_head SUB.L A1,A1 ; start at copy of header, please do_it MOVEQ #0,D1 ; is owned by job 0 MOVEQ #1,D0 TRAP #1 ; create this job, D1 = JOB ID TST.L D0 BNE freethg ; free thing & return to caller MOVE.L D5,A1 ; A1= this thing MOVE.L A0,D5 : D5 points to start of code for this job MOVE.L $C(A1),D0 ; thing name length ADD.L 8(A1),A1 ; A1 now points to header thexlp1 MOVE.B (A1)+,(A0)+ SUBQ.L #1,D0 BGE.S thexlp1 ; transfer header MOVE.L D1,-(A7) ; job ID of new job MOVE.L A5,A0 BSR free_thg ; free this thing now MOVE.L (A7),D1 MOVEQ #-1,D3 MOVEQ #$28,D0 BSR do_vect ; use thing now by new job MOVE.L A5,A0 BSR gu_rchp ; release memory now MOVE.L (A7)+,D1 ; D1 = JOB ID MOVEM.L (A7)+,A3/A5 MOVE.L D5,A1 ; point to start of code MOVE.L A1,A2 ADD.L D4,A2 ; A2 points to top of stack SUB.L D6,A2 ; point to stack now MOVE.L A2,-12(A1) CLR.L (A2) MOVEQ #0,D4 LEA 2(A2),A1 loop3 ADDQ.L #8,A3 CMP.L A3,A5 BEQ.S endpars BSR.S get_chans ; this will return a channel ID in A0 ; and test equal if this was a channel ; else will fail test BLT.S endpars BNE.S do_str ADDQ.W #1,(A2) ; show one more channel MOVE.L A0,(A1)+ ; put channel on stack BRA.S loop3 do_str MOVEQ #0,D0 MOVE.W D7,D0 ; D7 = string length BEQ.S epok MOVE.W D7,(A1)+ ; onto stack SUBQ.W #1,D7 loop2 MOVE.B (A6,A4.L),(A1)+ ADDQ.L #1,A4 DBF D7,loop2 ; copy string onto stack MOVE.B 1(A6,A3.L),D7 ; type of this variable ANDI.B #$F,D7 SUBQ.W #1,D7 ; was it a string variable? BNE.S epok ; no ->... ADDQ.W #3,D0 ; yes so ajust maths stack BCLR #0,D0 ADD.L D0,$58(A6) epok MOVEQ #0,D0 ; show no error endpars MOVE.L D0,D6 MOVEQ #32,D2 ; priority MOVEQ #0,D3 SWAP D7 MOVE.W D7,D3 nc_com MOVEQ #$A,D0 TRAP #1 ; activate job TST.L D6 BEQ.S out2 err MOVE.L D6,D0 out RTS out2 CMP.L #-1,D0 ; if any error returned from job, BEQ.S out ; other than -1 or -2, leave w/o error CMP.L #-2,D0 BEQ.S out BRA.S err fxbp2 ADDQ.L #8,A7 ; get rid of A3 & A5 fxbp MOVEQ #-15,D0 RTS fxbp3 MOVEQ #-15,D0 freethg MOVE.L D0,D7 MOVE.L A5,A0 BSR free_thg MOVE.L D7,D0 free_sp2 MOVE.L A5,A0 BSR gu_rchp fexout2 ADDQ.L #8,A7 RTS get_chans BTST #4,-7(A6,A3.L) ; was it ','? BEQ.S fxend ; no, so leave BTST #7,1(A6,A3.L) ; was it # ? BEQ.S fxbp ; no, so error MOVEM.L D1/D2/D4/A1/A2/A5,-(A7) LEA 8(A3),A5 MOVE.L $58(A6),A1 MOVE.W $112,A2 JSR (A2) ; get ONE integer MOVEM.L (A7)+,D1/D2/D4/A1/A2/A5 BNE.S endgc MOVE.L $58(A6),A0 MOVE.W (A6,A0.L),D0 ; ADDQ.L #2,$58(A6) ; reset maths stack getchan MOVE.L $30(A6),A0 ; A0=Dƒbut table canaux Basic MULU #$28,D0 ; ADD.L D0,A0 ; ƒlƒment voulu dans la table CMP.L $34(A6),A0 ; si supƒrieur, on est sorti de la BGE.S fxnf ; table, donc erreur 'not found' MOVE.L 0(A6,A0.L),D0 ; ID canal dans D5. Si<0, le canal est BLT.S fxnf ; fermƒ MOVE.L D0,A0 ; A0=ID canal MOVEQ #0,D0 endgc RTS fxnf MOVEQ #-6,D7 ; signaler erreur 'not found' RTS fxend MOVEQ #1,D0 RTS procs DC.W 2 DC.W fex-* DC.B 4,'EXEP' DC.W fexw-* DC.B 6,'EXEP_W' DC.W 0,2 DC.W fexf-* DC.B 5,'EXEPF' DC.W fexfw-* DC.B 7,'EXEPF_W' DC.L 0 end
_______________________________________________ QL-Users Mailing List http://www.quanta.org.uk/mailing.htm