using DEF FN(a,b,c$)=USR C_file

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
cborn
Well known member
Posts: 309
Joined: Tue Oct 06, 2020 7:45 pm

Re: using DEF FN(a,b,c$)=USR C_file

Post by cborn »

my elias implementation via deffn
https://spectrumcomputing.co.uk/forums/ ... 84#p142284

it should grow out to an zx based zx0
stefano
Well known member
Posts: 2183
Joined: Mon Jul 16, 2007 7:39 pm

Re: using DEF FN(a,b,c$)=USR C_file

Post by stefano »

> I noticed that most argc commands are "hand made" aka special build in the main.

This is true in most of the early C compilers, includig the TRS80, the MSDOS, the CP/M and the DEC/VAX world.
I think it was a consequence of the shell limits, in example the wildcard expansion was managed by the C language with non standard tricks.
cborn
Well known member
Posts: 309
Joined: Tue Oct 06, 2020 7:45 pm

Re: using DEF FN(a,b,c$)=USR C_file

Post by cborn »

Hi
on spectrumcomputing paradigmsghifter suggested to use a malloc construction, but apperently i mis some thing
maybe its just the command line, or i mis a library, or i just dont get it(probably)
oldstr and newstr both remain 1 byte in length ???
the name result is from defstr
my attempt with reallac blackens the screen and halts

Code: Select all

/*
DEFFN_088
zcc +zx -vn -lm DEFFN_088.c -oDEFFN_088 -DAMALLOC -lndos -create-app -Cz --noloader
  --list --c-code-in-asm
*/

// using
// ZX Spectrum Basic
// (Z80 assembly , possibly)
// classic C

// ZX Basic
//   1 DEF FN z()=USR VAL "32768"
//   2 DEF FN x(x,x,x)=x+x+x OR USR VAL"32768"
//   5 DEF FN a$(a,b$,c)=STR$ USR VAL "32768"
//   6 DEF FN b(x,z$,y,a,a$)=USR VAL "32768"
//  10 CLEAR VAL "32767": LOAD ""CODE: LET x$="ZX"
//  15 CLS : LET Z$= FN a$(1,STR$ 128,65535)
//  20 PAUSE 0: BORDER 1: CLS : RANDOMIZE FN b(1,x$,3,4,"5")
//  25 PAUSE 0: BORDER 2: CLS : RANDOMIZE FN z()
//  30 PAUSE 0: BORDER 3: CLS : PRINT '''''' FN x(3,VAL x$,1)


// using the basic system variable DEFADR which points into the basic listing itself, and Not in the variable block
// at invoking the FN call the ZX Rom routine places the real value of the placeholder inside the LISTing.
// this is a 5byte, 1+4 mantisse, format as used internaly. to extract the value it should be placed on the FP_stack aka membot
// and tricker the correct routine in ZX ROM. even strings are formated with this 5 bytes POINTER
// internally the DEF FN statement needs 7 bytes per used variable plus 1 extra if its a string, for the '$' sign
// and an additional byte for the comma separator
// DEF FN a(a$)= ...
// DEF FN a( a + '$' + 0x0e + 0x?? + 0x?? +0x?? +0x?? +0x?? ) = ...8 bytes
// DEF FN a$(a,b$)=..
// DEF FN a$( a + 0x0e + 0x?? + 0x?? +0x?? +0x?? +0x?? + ',' + b +'$' + 0x0e + 0x?? + 0x?? +0x?? +0x?? +0x?? )= 7+1+8 bytes



#include <stdio.h>
#include <stdlib.h>
#include "spectrum.h"   // TK_DEF_FN = 206 = token of DEF FN


// #define NDEBUG
//#include <assert.h>



__at(23563) unsigned int DEFADR ;    // sysvar


unsigned char *defname[]="\0\0\0" ;
unsigned char *amount="\0" ;
//unsigned char *valstr="\0\0\0" ; // [2]


extern unsigned char* oldstr=" ";
extern unsigned char* newstr=" ";

char addstr(unsigned char ramchr){

printf("%s !!",newstr);
printf("%s !!",oldstr);

//newstr = (char*)realloc(" ",((strlen(oldstr)+1)*sizeof(char)));
newstr = (char*)malloc(((strlen(oldstr)+1)*sizeof(char)));
//assert(strlen(newstr) > 0);
newstr = oldstr;
// free(oldstr);
// strcat(newstr, ramchr);
newstr[strlen(newstr)]='\0' ;

//oldstr = (char*)realloc(" ",(strlen(newstr)*sizeof(char)));
oldstr = (char*)malloc((strlen(newstr)*sizeof(char)));
oldstr = newstr;

// free(newstr);
printf("%s !!",newstr);
printf("%s !!",oldstr);
}


int dargc() {

unsigned int *sysadr , bytecount=0 ;
unsigned char *sysvalue, x=0 , ramchr='\0' ;

//strcpy(valstr,defname) ;
amount='\0' ;

sysadr   = &DEFADR ;
sysvalue = *sysadr ;

ramchr   = *sysvalue ;

while (ramchr != TK_DEF_FN ) {
       ramchr = *--sysvalue ;
      } //*sysvalue points to TK_DEF_FN
printf("%4d",x);
while (ramchr != '(')      {
       ramchr = *++sysvalue ;
       addstr(ramchr);
       // valstr[x]=ramchr ;
       defname[x++]=ramchr ;
printf("%4d %s ",x,defname);
      }

if (x==1) {addstr(' ');
       //valstr[x]=' ';  // make a 2 bytes defname
       defname[x++]=' ';
printf("%4d %s ",x,defname);
          }

defname[x]='\0' ; //after 'while' correct last step
addstr('\0');
//valstr[x]='\0' ;
++amount ;
bytecount= x ;  // x=1 or 2
printf("%4d %s ",x,defname);

while (ramchr !=')' ) {

//  printf("_%6d_ ",strlen(valstr));
addstr(ramchr);
//  valstr = (char*)realloc(valstr, strlen(valstr) + 7 ) ;
//  valstr[strlen(valstr)]='\0';

  printf("_%6d__",strlen(newstr),newstr );
  ramchr = *++sysvalue ; // 1st time step over '('


  if ((ramchr >='A' && ramchr <='Z') || (ramchr >='a' && ramchr <='z')) 
     {
      bytecount++ ;  // varname is 1 byte
      addstr(ramchr);
//      valstr[x++]=ramchr;
      ramchr = *++sysvalue ;

      if (ramchr !='$' && ramchr !=14 ) /* return bytecount */ return -1  ;

      if (ramchr =='$') {
         bytecount++ ;  // varname is 2 bytes
         addstr(ramchr);
//         valstr[x++]=ramchr;
         ramchr = *++sysvalue ;
         } else { addstr(' ');
                //valstr[x++]=' ';
                }

      if (ramchr !=14 && ramchr !=')' ) /*return bytecount*/ return -2 ;

      // fetch internal value (1+4 mantise) here
int y=0;
      for (y=0 ; y<=7;y++) {
          bytecount++ ;
          ramchr = *++sysvalue ;
      addstr(ramchr);
//          valstr[x++]=ramchr;
          }

      addstr('\0');
//     valstr[x]='\0' ;
     ++sysvalue ; //step over ','
     ++amount ;

     printf("newstrlen %d  -%c-\n" ,strlen(newstr) ,newstr[0] );

  } else { return bytecount ; }  //end if 'A'
}//end while  ')'

return bytecount /* return -4*/ ;
}


int main() {

unsigned int bytecount ;

bytecount = dargc() ;

//printf("valstrlen %s\n",valstr);

printf("defname  :%s\n"
       "amount   :%5d\n"
       "bytecount:%5d\n"
       ,defname,amount,bytecount);

printf("%s\n",newstr);
printf("%s\n",oldstr);

return 0;
}
Post Reply