# HG changeset patch
# User roug
# Date 1040058496 0
# Node ID 7fb3d02e04b0c4d837cff987333ce6683b3a5c7b
# Parent ac4142f99b2171f1e118523ed47e2155e5aa4691
Appendix C is finished
diff -r ac4142f99b21 -r 7fb3d02e04b0 docs/ccguide/basic09.appendix
--- a/docs/ccguide/basic09.appendix Mon Dec 16 17:08:02 2002 +0000
+++ b/docs/ccguide/basic09.appendix Mon Dec 16 17:08:16 2002 +0000
@@ -16,6 +16,47 @@
127.
+BASIC09 strings are terminated by 0xff (255). C strings are
+terminated by 0x00 (0). If the BASIC09 string is of maximum length,
+the terminator is not present. Therefore, string length as well as
+terminator checks must be performed on BASIC09 strings when
+processing them with C functions.
+
+
+The floating point format used by C and BASIC09 are not directly
+compatible. Since both use a binary floating point format it is
+possible to convert BASIC09 reals to C doubles and vice-versa.
+
+
+Multi-dimensional arrays are stored by BASIC09 in a different manner
+than C. Multi-dimensional arrays are stored by BASIC09 in a column-wise
+manner; C stores them row-wise. Consider the following example:
+
+
+BASIC09 matrix: DIM array(5,3):INTEGER
+The elements in consecutive memory locations (read left to
+right, line by line) are stored as:
+(1,1),(2,1),(3,1),(4,1),(5,1)
+(1,2),(2,2),(3,2),(4,2),(5,2)
+(1,3),(2,3),(3,3),(4,3),(5,3)
+
+C matrix: int array[5][3];
+(1,1),(1,2),(1,3)
+(2,1),(2,2),(2,3)
+(3,1),(3,2),(3,3)
+(4,1),(4,2),(4,3)
+(5,1),(5,2),(5,3)
+
+
+Therefore to access BASIC09 matrix elements in C, the subscripts
+must be transposed. To access element array(4,2) in BASIC09 use
+array[2][4] in C.
+
+
+The details on interfacing BASIC09 to C are best described by
+example. The remainder of this appendix is a mini tutorial
+demonstrating the process starting with simple examples and working
+up to more complex ones.
@@ -69,7 +110,7 @@
cc2 bt1.c -rs
-CC2 uses the Level-Two compiler. Replace cc2 with cc1 if you are
+Cc2 uses the Level-Two compiler. Replace cc2 with cc1 if you are
using the Level-One compiler. The -r option causes the compiler to
leave bt1.r as output, ready to be linked. The -s option suppresses
the call to the stack-checking function. Since we will be making a
@@ -123,12 +164,179 @@
Example 2 - More Complex Integer Aritmetic Case
+The next example shows how static memeory can be used. Take the
+C function from the previous example and modify it to add the number
+of times it has been entered to the increment:
+
+
+buld bt2.c
+? static int entcnt;
+?
+? addints(cnt,cmem,cmemsiz,value,s1,arg1,s2,arg2,s2,arg3,s4)
+? char *cmem;
+? int *value,*arg1,*arg2,*arg3;
+? {
+? #asm
+? ldy 6,s base of static area
+? #endasm
+? int j = *value + entcnt++;
+?
+? *arg1 += j;
+? *arg2 += j;
+? *arg3 += j;
+? }
+?
+
+
+This example differs from the first in a number of ways. The line
+"static in entcnt" defines an integer value name entcnt global to
+bt2.c. The parameter cmem and the line "char *cmen" indicate a
+character array. The array will be used in the C function for
+global/static storage. C accesses non-auto and non-register
+variables indexed off the Y register. cstart.r normally takes care
+of setting this up. Since cstart.r will not be used for this
+BASIC09-callable function, we have to take measures to make sure the
+Y register points to a valid and sufficiently large area of memory.
+The line "ldy 6,s" is assembly language code embedded in C source
+that loads the Y register with the first parameter passed by
+BASIC09. If the first parameter in the BASIC09 RUN statement is an
+array, and the "ldy 6,s" is placed immediately after the
+"{" opening the function body, the offset will always be "6,s". Note the line
+beginning "int j = ...". This line uses an initializer which, in
+this case, is allowed because j is of class "auto".
+No classes but "auto" and "register" can be initialized in BASIC09-callable C
+functions.
+
+
+To compile this function, the following C compiler command line is
+used:
+
+cc2 bt2.c -rs
+
+Again, the -r option leaves bt2.r as output and the -s option
+suppresses stack checking.
+
+
+Normally, the linker considers it to be an error if the "-b=" option
+appears and the final linked module requires a data memory
+allocation. In our case here, we require a data memory allocation
+and we will provide the code to make sure everything is set up
+correctly. The "-t" linker option causes the linker to print the
+total data memory requirement so we can allow for it rather than
+complaining about it. Our linker command line is:
+
+c.link bt2.r -o=addints -b=addints -r
+
+
+
+The linker will respond with "BASIC09 static data size is 2 bytes".
+We must make sure cmem points to at least 2 bytes of memory. The
+memory should be zeroed to conform to C specifications.
+
+
+Enter the following BASIC09 program:
+
+
+PROCEDURE btest
+DIM i,j,k,n;INTEGER
+DIM cmem(10):INTEGER
+FOR i=1 TO 10
+ cmem(i)=0
+NEXT i
+FOR n=1 TO 5
+ i=1
+ j=132
+ k=-1033
+ RUN addints(cmem,4,i,j,k)
+ PRINT i,j,k
+NEXT n
+END
+
+
+This program is similar to the previous example. Our area for data
+memory is a 10-integer array (20 bytes) which is way more than the 2
+bytes for this example. It is better to err on the generous side.
+Cmem is an integer array for convenience in initializing it to zero
+(per C data memory specifications). When the program is run, it
+calls addints 5 times with the same data values. Because addints
+add the number of times it was called to the value, the i,j,k
+values should be 4+number of times called. When run, the program prints:
+
+ 5 136 -1029
+ 6 137 -1028
+ 7 138 -1027
+ 8 139 -1026
+ 9 140 -1025
+
+Works again!
Example 3 - Simple String Manipulation
+This example shows how to access BASIC09 strings through C
+functions. For this example, write the C version of SUBSTR.
+
+
+build bt3.c
+? /* Find substring from BASIC09 string:
+? RUN findstr(A$,B$,findpos)
+? returns in fndpos the position in A$ that B$ was found or
+? 0 if not found. A$ and B$ must be strings, fndpos must be
+? INTEGER.
+? */
+? findstr(cnt,string,strcnt,srchstr,srchcnt,result);
+? char *string,*srchstr;
+? int strcnt, srchcnt, *result;
+? {
+? *result = finder(string,strcnt,srchstr,srchcnt);
+? }
+?
+? static finder(str,strlen,pat,patlen)
+? char *str,*pat;
+? int strlen,patlen;
+? {
+? int i;
+? for(i=1;strlen-- > 0 && *str!=0xff; ++i)
+? if(smatch(str++,pat,patlen))
+? return i;
+? }
+?
+? static smatch(str,pat,patlen)
+? register char *str,*pat;
+? int patlen;
+? {
+? while(patlen-- > 0 && *pat != 0xff)
+? if(*str++ != *pat++)
+? return 0;
+? return 1;
+? }
+?
+
+
+Compile this program:
+
+ cc2 bt3.c -rs
+
+And link it:
+
+ c.link bt3.r -o=findstr -b=findstr
+
+The BASIC09 test program is:
+
+PROCEDURE btest
+DIM a,b:STRING[20]
+DIM matchpos:INTEGER
+LOOP
+INPUT "String ",a
+INPUT "Match ",b
+RUN findstr(a,b,matchpos)
+PRINT "Matched at position ",matchpos
+ENDLOOP
+
+When this program is run, it should print the position where the
+matched string was found in the source string.
@@ -234,7 +442,7 @@
int maxlen;
for (maxlen = maxstr; *str1 == *str2 ;++str1)
- if (maxlen-- >0 || *str2++ == 0xff)
+ if (maxlen-- >0 || *str2++ == 0xff)
return 0;
return (*str1 - *str2);
}
@@ -316,6 +524,143 @@
flmult(cnt,cmemory,cmemsiz,realarg,realsize)
+int cnt; /* number of arguments */
+char *cmemory; /* pointer to some memory for C use */
+double *realarg; /* pointer to real */
+{
+#asm
+ ldy 6,s get static memory address
+#endasm
+
+ double number;
+
+ getbreal(&number,realarg); /* get the BASIC09 real */
+ number *= 2.; /* number times two*/
+ putbreal(realarg,&number); /* give back to BASIC09 */
+
+}
+
+/* getreal(creal,breal)
+ get a 5-byte real from BASIC09 format to C format */
+
+getbreal(creal,breal)
+double *creal,*breal;
+{
+ register char *cr,*br; /* setup some char pointers */
+
+ cr = creal;
+ br = breal;
+#asm
+* At this point U reg contains address of C double
+* 0,s contains address of BASIC09 real
+ ldx 0,s get address of B real
+
+ clra clear the C double
+ clrb
+ std 0,u
+ std 2,u
+ std 4,u
+ stb 6,u
+ ldd 0,x
+ beq g3 BASIC09 real is zero
+
+ ldd 1,x get hi B mantissa
+ and a #$7f clear place for sign
+ std 0,u put hi C matissa
+ ldd 3,x get lo B mantissa
+ andb #$fe mask off sign
+ std 2,u put lo C mantissa
+ lda 4,x get B sign byte
+ lsra shift out sign
+ bcc g1
+ lda 0,u get C sign byte
+ ora #$80 tun on sign
+ sta 0,u put C sign byte
+g1 lda 0,x get B exponent
+ suba #128 excess 128
+ sta 7,u put C exponent
+g3 clra clear carry
+#endasm
+
+}
+
+/* putbreal(breal,creal)
+ put C format double into a 5-byte real from BASIC09 */
+
+putbreal(breal,creal)
+double *breal,*creal;
+{
+ register char *cr,*br; /* setup some pointers */
+
+ cr = creal;
+ br = breal;
+#asm
+* At this point U reg contains address of C double
+* 0,s contains address of BASIC09 real
+ ldx 0,s get address of B real
+
+ lda 7,u get C exponent
+ bne p0 not zero?
+ clra clear the BASIC09
+ clrb real
+ std 0,x
+ std 2,x
+ std 4,x
+ bra p3 and exit
+
+p0 ldd 0,u get hi C mantissa
+ ora #$80 this bit always on for normalized real
+ std 1,x put hi B mantissa
+ ldd 2,u get lo C mantissa
+ std 3,x put lo B mantissa
+ incb round mantissa
+ bne p1
+ inc 3,x
+ bne p1
+ inc 2,x
+ bne p1
+ inc 1,x
+p1 andb #$fe turn off sign
+ stb 4,x put B sign byte
+ lda 0,u get C sign byte
+ lsla shift out sign
+ bcc p2 bra if positive
+ orb #$01 turn on sign
+ stb 4,x put B sign byte
+p2 lda 7,u get C exponent
+ adda #128 less 128
+ sta 0,x put B exponent
+p3 clra clear carry
+#endasm
+}
+
+
+/* replace cstart.r definitions for BASIC09 */
+#asm
+_stkcheck:
+_stkchec:
+ rts
+
+ vsect
+_flacc: rmb 8
+errno: rmb 2
+ endsect
+#endasm
+
+
+BASIC09 calling program:
+
+
+PROCEDURE btest
+DIM a:REAL
+DIM i:INTEGER
+DIM cmemory:STRING[32]
+a=1.
+FOR i=1 TO 10
+ RUN flmult(cmemory,a)
+ PRINT a
+NEXT i
+END
@@ -327,6 +672,30 @@
matmult(cnt,cmemory,cmemsiz,matxaddr,matxsize,scalar,scalsize)
+char *cmemory; /* pointer to some memory for C use */
+int matxaddr[5][3]; /* pointer a double dim integer array */
+int *scalar; /* pointer to integer */
+{
+#asm
+ ldy 6,s get static memory address
+#endasm
+
+ int i,j;
+
+ for(i=0; i<5; ++i)
+ for(j=1; j<3; ++j)
+ matxaddr[j][i] *= *scalar; /* multiply by value */
+}
+#asm
+_stkcheck:
+_stkchec:
+ rts
+
+ vsect
+_flacc: rmb 8
+errno: rmb 2
+ endsect
+#endasm
BASIC09 calling program: