/* =====> ASM_LINK.C */ /* TIPC Scheme '84 Runtime Support - Linkage to non-Scheme Routines (C) Copyright 1984,1985 by Texas Instruments Incorporated. All rights reserved. Author: John C. Jensen Installation: Texas Instruments Incorporated, Dallas, Texas Division: Central Research Laboratories Cost Center: Computer Science Laboratory Project: Computer Architecture Branch Date Written: 20 June 1985 Last Modification: 18 October 1985 */ #include "scheme.h" asm_link(n_args, arg1, arg2, arg3, arg4, arg5, arg6, arg7) int n_args; /* the number of actual arguments */ int arg1[2],arg2[2],arg3[2],arg4[2],arg5[2],arg6[2],arg7[2]; { int i; /* the usual index variable */ int page,disp; /* page and displacement components of a pointer */ long *p[7]; /* pointers to arguments */ int **ptr; /* pointer to current argument register address */ double result_value; /* return area for result */ double *result; /* pointer to result returned */ int return_code = 0; /* return_code to send back to Scheme support */ int stat; /* status returned from called procedure */ int str_len[7]; /* length of dynamically allocated strings */ long integers[7]; int chars[7]; double flonums[7]; char *strings[7]; char *string_asciz(); double get_flo(); ENTER(asm_link); /* null out string pointers */ for (i = 0; i < 7; i++) { p[i] = NULL; strings[i] = NULL; str_len[i] = 0; } /* create a C version of each argument */ result = &result_value; ptr = &arg1; for (i = n_args-1; i >= 0; i--, ptr++) { page = CORRPAGE((*ptr)[C_PAGE]); disp = (*ptr)[C_DISP]; switch (ptype[page]) { case STRTYPE*2: strings[i] = string_asciz(*ptr); str_len[i] = get_word(page,disp+1); if (str_len[i] < 0) /* Adjust for small strings */ str_len[i] = str_len[i] + BLK_OVHD + 1; else str_len[i] = str_len[i] - BLK_OVHD + 1; p[i] = (long *) strings[i]; break; case BIGTYPE*2: case FIXTYPE*2: if (int2long(integers+i, *ptr)) goto bad_arg; p[i] = (long *) (integers+i); break; case FLOTYPE*2: flonums[i] = get_flo(page, disp); p[i] = (long *) (flonums+i); break; case CHARTYPE*2: chars[i] = get_char(page,disp); p[i] = (long *) (chars+i); break; bad_arg: default: return(1); } /* end: switch (ptype[page]) */ } /* end: for (i = 0; i < n_args; i++, ptr++) */ /* all arguments ready-- call the interface routine */ stat = link(&result,p[0],p[1],p[2],p[3],p[4],p[5],p[6]); /* fetch result returned from low level return and make it a Scheme object */ ptr = ((int **) &arg1) + (n_args - 1); switch (stat) { case 1: /* 't or 'nil */ if (*((int *) result)) { (*ptr)[C_PAGE] = T_PAGE*2; (*ptr)[C_DISP] = T_DISP; } else { (*ptr)[C_PAGE] = (*ptr)[C_DISP] = 0; } case 0: /* no value returned */ break; case 2: /* integer */ long2int(*ptr, *((long *) result)); break; case 3: /* flonum */ alloc_flonum(*ptr, *result); break; case 4: /* character */ (*ptr)[C_PAGE] = SPECCHAR*2; (*ptr)[C_DISP] = *((char *) result); break; case 5: /* string */ alloc_string(*ptr, result); break; default: /* error */ return_code = 1; } /* end: switch (stat) */ /* release memory allocated to character strings */ for (i = 0; i < 7; i++) { if (strings[i]) if (rlsmem(strings[i], str_len[i])) rlsmem_error(rtn_name); } return(return_code); } /* end of function: asm_link(n_args, arg1, arg2, ... , arg7) */