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

Reply via email to