466
|
1 <appendix>
|
|
2 <title>Interfacing to Basic09</title>
|
|
3 <para>
|
468
|
4 The object code generated by the Microware C Compiler can be made
|
|
5 callable from the BASIC09 "RUN" statement. Certain portions of a
|
|
6 BASIC09 program written in C can have a drmatic effect on execution
|
|
7 speed. To effectively utilize this feature, one must be familiar
|
|
8 with both C and BASIC09 internal data representation and procedure
|
|
9 calling protocol.
|
466
|
10 </para>
|
|
11
|
554
|
12 <section>
|
|
13 <title>Example 1 - Simple Integer Aritmetic Case</title>
|
|
14 <para>
|
|
15 This first example illustrates a simple case. Write a C function to
|
|
16 add an integer value to three integer variables.
|
|
17 <screen>
|
|
18 build bt1.c
|
|
19 ? addints(cnt,value,s1,arg1,s2,arg2,s2,arg3,s4)
|
|
20 ? int *value,*arg1,*arg2,*arg3;
|
|
21 ? {
|
|
22 ? *arg1 += *value;
|
|
23 ? *arg2 += *value;
|
|
24 ? *arg3 += *value;
|
|
25 ? }
|
|
26 ?
|
|
27 </screen>
|
|
28 </para>
|
|
29 <para>
|
|
30 That's the C function. The name of the function is "addints". The
|
|
31 name is information for C and c.link; BASIC09 will not know anything
|
|
32 about the name. Page 9-13 of the BASIC09 Reference manual describes
|
|
33 how BASIC09 passes parameters to machine language modules. Since
|
|
34 BASIC09 and C pass parameters in a similar fashion, it is easy to
|
|
35 access BASIC09 values. The first parameter on the BASIC09 stack is
|
|
36 a two-byte count of the number of following parameter pairs. Each
|
|
37 pair consists of an address and size of value. For most C
|
|
38 functions, the parameter count and pair size is not used. The
|
|
39 address, however, is the useful piece of information. The address
|
|
40 is declared in the C function to always be a "pointer to..." type.
|
|
41 BASIC09 always passes addresses to procedures, even for constant
|
|
42 values. The arguments cnt, s1, s2, s3 and s4 are just place holders
|
|
43 to indicate the presence of the parameter count and argument sizes
|
|
44 on the stack. These can be used to check validity of the passed
|
|
45 arguments if desired.
|
|
46 </para>
|
|
47 <para>
|
|
48 The line "int *value,*arg1,*arg2,*arg3" declares the parameters (in
|
|
49 this case all "pointers to int"), so the compiler will generate the
|
|
50 correct code to access the BASIC09 values. The remaining lines
|
|
51 increment each arg by the passed value. Notice that a simple
|
|
52 arithmetic operation is performed here (addition), so C will not
|
|
53 have to call a library function to do the operation.
|
|
54 </para>
|
|
55 <para>
|
|
56 To compile this function, the following C compiler command line is
|
|
57 used:
|
|
58 <informalexample>
|
|
59 <para>
|
|
60 cc2 bt1.c -rs
|
|
61 </para>
|
|
62 </informalexample>
|
|
63 CC2 uses the Level-Two compiler. Replace cc2 with cc1 if you are
|
|
64 using the Level-One compiler. The -r option causes the compiler to
|
|
65 leave bt1.r as output, ready to be linked. The -s option suppresses
|
|
66 the call to the stack-checking function. Since we will be making a
|
|
67 module for BASIC09, cstart.r will not be used. Therefore, no
|
|
68 initialized data, static data, or stack checking is allowed. More
|
|
69 on this later.
|
|
70 </para>
|
|
71 <para>
|
|
72 The bt1.r file must now be converted to a loadable module that
|
|
73 BASIC09 can link to by using a special linking technique as follows:
|
|
74 <informalexample>
|
|
75 <para>
|
|
76 c.link bt1.r -b=addints -o=addints
|
|
77 </para>
|
|
78 </informalexample>
|
|
79 This command tells the linker to read bt1.r as input. The option
|
|
80 "-b=addints" tells the linker to make the output file a module that
|
|
81 BASIC09 can link to and that the function "addints" is to be the
|
|
82 entrypoint in the module. You may give many input files to c.link
|
|
83 in this mode. It resolves references in the normal fashion. The
|
|
84 name given to the "-b=" option indicates which of the functions is
|
|
85 to be entered directly by the BASIC09 RUN command. The option
|
|
86 "-o=addints" says what the name of the output file is to be, in this
|
|
87 case "addints". This name should be the name used in the BASIC09
|
|
88 RUN command to call the C procedure. The name given in "-o="
|
|
89 option is the name of the procedure to RUN. The "-b=" option is
|
|
90 merely information to the linker so it can fill in the correct
|
|
91 module entrypoint offset.
|
|
92 </para>
|
|
93
|
|
94 <para>
|
|
95 Enter the following BASIC09 program:
|
|
96 <programlisting>
|
|
97 PROCEDURE btest
|
|
98 DIM i,j,k:INTEGER
|
|
99 i=1
|
|
100 j=132
|
|
101 k=-1033
|
|
102 RUN addints(4,i,j,k)
|
|
103 PRINT i,j,k
|
|
104 END
|
|
105 </programlisting>
|
|
106 When this procedure is RUN, it should print:
|
|
107 <screen>
|
|
108 5 136 -1029
|
|
109 </screen>
|
|
110 indicating that our C function worked!
|
|
111 </para>
|
557
|
112 </section>
|
565
|
113
|
|
114 <section>
|
|
115 <title>Example 2 - More Complex Integer Aritmetic Case</title>
|
|
116 <para>
|
|
117 </para>
|
|
118 </section>
|
|
119
|
|
120 <section>
|
|
121 <title>Example 3 - Simple String Manipulation</title>
|
|
122 <para>
|
|
123 </para>
|
|
124 </section>
|
|
125
|
|
126 <section>
|
|
127 <title>Example 4 - Quicksort</title>
|
|
128 <para>
|
|
129 The next example programs demonstrate how one might implement a
|
|
130 quicksort written in C to sort some BASIC09 data.
|
|
131 </para>
|
|
132 <para>
|
|
133 C integer quicksort program:
|
|
134 </para>
|
|
135 <programlisting>
|
|
136 #define swap(a,b) { int t; t=a; a=b; b=t; }
|
|
137
|
|
138 /* qsort to be called by BASIC09:
|
|
139 dim d(100):INTEGER any size INTEGER array
|
|
140 run cqsort(d,100) calling qsort.
|
|
141 */
|
|
142
|
|
143 qsort(argcnt,iarray,iasize,icount,icsiz)
|
|
144 int argcnt, /* BASIC09 argument count */
|
|
145 iarrary[], /* Pointer to BASIC09 integer array */
|
|
146 iasize, /* and it's size */
|
|
147 *icount, /* Pointer to BASIC09 (sort count) */
|
|
148 icsiz; /* Size of integer */
|
|
149 {
|
|
150 sort(iarray,0,*icount); /* initial qsort partition */
|
|
151 }
|
|
152
|
|
153 /* standard quicksort algorithm from Horowitz-Sahni */
|
|
154 static sort(a,m,n)
|
|
155 register int *a,m,n;
|
|
156 {
|
|
157 register i,j,x;
|
|
158
|
|
159 if(m < n) {
|
|
160 i = m;
|
|
161 j = n + 1;
|
|
162 x = a[m];
|
|
163 for(;;) {
|
|
164 do i += 1; while(a[i] < x); /* left partition */
|
|
165 do j -= 1; while(a[j] > x); /* right partition */
|
|
166 if(i < j)
|
|
167 swap(a[i],a[j]) /* swap */
|
|
168 else break;
|
|
169 }
|
|
170 swap(a[m],a[j]);
|
|
171 sort(a,m,j-1); /* sort left */
|
|
172 sort(a,j+1,n); /* sort right */
|
|
173 }
|
|
174 }
|
|
175 </programlisting>
|
|
176 <para>
|
|
177 The BASIC09 program is:
|
|
178 </para>
|
|
179 <programlisting>
|
|
180 PROCEDURE sorter
|
|
181 DIM i,n,d(1000):INTEGER
|
|
182 n=1000
|
|
183 i=RND(-(PI))
|
|
184 FOR i=1 to n
|
|
185 d(i):=INT(RND(1000))
|
|
186 NEXT i
|
|
187 PRINT "Before:"
|
|
188 RUN prin(1,n,d)
|
|
189 RUN qsortb(d,n)
|
|
190 PRINT "After:"
|
|
191 RUN prin(1,n,d)
|
|
192 END
|
|
193
|
|
194 PROCEDURE prin
|
|
195 PARAM n,m,d(1000):INTEGER
|
|
196 DIM i:INTEGER
|
|
197 FOR i=n TO m
|
|
198 PRINT d(i); " ";
|
|
199 NEXT i
|
|
200 PRINT
|
|
201 END
|
|
202 </programlisting>
|
|
203 </section>
|
466
|
204 </appendix>
|