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

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

Post by cborn »

Hi
in zx basic its possible to start an asm routine WITH variables by using a DEF FN structure.
in C its possible to start an commandline function with variables.

does Z88dk has possibilities to create a DEF FN that behaves like the arg[] command?

i use that construction for my eliasgamma routine
https://spectrumcomputing.co.uk/forums/ ... 84#p142284

and now i wonder if there migth be an easy way to recreate cq substitute the commandline as a DEF FN, then a lot off routine become avialable for easy use, even in basic, it would be an BASIC, ASM, C trisome coding
the first set up is easy, but how to connect it afterward ?
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 »

a link with a simular question 11
https://stackoverflow.com/questions/192 ... v-and-argc



MAYBE some like
main ( d_argc , d_arv[] )

{ _asm
ld hl,(DEF_ADR) ; hl = actual RAM location in BASIC listing at position off the DEF FN
ld bc,4 ;
add hl,bc ; adres+4
ld e,(hl) ;
inc hl ; adres+4+1
ld d,(hl) ;
push de
pop hl ; return value in HL ??
end asm
return value;
}

but how to count d_argc ?? AFTER fetching the variable a check has to be made that DEF is ended eg with a bracket ')' ? DEF is BASIC so it could be that simple.
i have NO CLUE how to transfer the hl value into a C integer
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 »

https://www.geeksforgeeks.org/command-l ... -in-c-cpp/

tells me that arg[0] is the name is the routine, i think its nice to use the DEF character as name

the 48k ROM tells that ')' combined with '=' is a correct EOV, end of variables

Code: Select all

;; DEF-FN-6
L1FA6:  CP      $29             ; should close with a ')'
        JR      NZ,L1FBD        ; to DEF-FN-7 if not
                                ; 'Nonsense in BASIC'


        RST     20H             ; get NEXT-CHAR
        CP      $3D             ; is it '=' ?
        JR      NZ,L1FBD        ; to DEF-FN-7 if not 'Nonsense...'
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 »

NOT TESTED AT ALL
its what i think it should be, more or less the first aproach, counting the amount off variable present inside the DEF FN
and finding the "filename" character
if any one wants to participate, your are welcome

Code: Select all

// a.d. 2024 Chris Born

//NOT TESTED AT ALL

// simple first attempt to read the basic DEF FN function with asm for executing a C routine
// ment as future REPLACEMENT for the standard 'argc' and 'argv' or 'arg[]'
// for executing a C file inside a ZX Basic runtime
// there is a max of 26 DEF FN integer() and 26 DEF FN string() as they both have a single character name
// diff between lower or capital chr are ignored

//   10 DEF FN a(a)= USR c_file
//             a(a;12345)= USR c_file;12345

//   20 DEF FN a$(a$,a)= USR c_file
//             a$(A;$1234,a;12345)= USR c_file;12345

// in BASIC values are stored in an 5 byte of 1 mantise + 4 value
// in BASIC a string REFERENCE is a 5 byte of 1 mantise + 2 start + 2 end (or length?)
// this notation STARTS with chr$ 14 as marker, making it an 6 byte notation altogether
// in DEF FN any variable, number or string, is recalculated to this 1+5 bytes notation
// strings aswell since its a reference aka POINTER to the string !!!
// from the start point after the first bracket the values are at 1+1+5+1 distance from each other ( a;12345, b;12345, c;12345 )
// with comma's as separator and the closing bracket at the last comma position                      12345678          1234567 8
// if openbrackets =0 and next value = '=' then then preload is done, ANY other value will be handeld by the basic interpreter and only the USR command is needed to execute the C_file

// the basic interpreter should deliver bugfree source but a check for bugs is better so check the data aswell


int d_argc(){

    char *dargc[4];


                                  // startadres DEF FN   =!
                                  //                 0 123!4;12345, 56)=
              #asm                // FIND eg    DEF FN a$(!a;....., a$)=
              ld hl,(DEF_ADR)     // hl = actual RAM location in BASIC listing at position off the DEF FN
              ld de,amount        // data adres inside asm
              ld bc,4
              ld a,206            // = 'DEF FN'
              cpdr                // lower until DEF FN found
              inc hl              // 1 step for chr$
              ld a,(hl)           // fetch DEF chr$ as NAME
              ld (name),a         // store chr$
              inc hl              //
              ld a,(hl)
              cp '$'              // test for string value
              jr nz,count0        //  $+4
              ld (name+1),a       // store $ aswell
              inc hl              // step over '$' if needed
count0        ex de,hl
              inc (hl)            // amount+1 > the namestring is 1st variable of argc > arg[0] is filename
              ex de,hl

firstbracket: ld a,(hl)           // reload DEF data
              cp '('
              jr nz,error         // not a correct DEF fn, what does the STRUCT do now ??

testend       inc hl
              ld a,(hl)
              cp ')'              // if 1st value is a CLOSE bracket NO VARIABLES are included !!!
                                  // then DEF FN might have no extra functionality for the USR command
              jr z,closed
 
notyet:       ld a,(hl)           // +1 reload DEF data
              cp 64               //    'A'-1
              jr c,error          //    to small
              sub 32              //    make capital chr$
              cp 91               //    'Z'+1  
              jr nc,error         //     to big
              inc hl              // +1
              ld a,(hl)
              cp 14               // only THEN its a 1+5 notation value start marker
              jr nz,error         // no marker found
 
             // correct internal DEF FN variable found
              ld bc,5             // +5
              add hl,bc           // raise 6 bytes to step over value

              ld a,(hl)
              cp ','
              jr nz,error
              inc hl              // +1 = 8 step over ','

count1        ex de,hl
              inc (hl)            // amount+1 > the namestring is 1st variable of argc > arg[0] is filename
              ex de,hl
              jr testend

closed        inc hl
              ld a,(hl)
              cp '='
              jr z,done
error         ld bc,65535        // make here an error message

done:         ret

amount        defb 0
name          defb 0,0,0 // name$ 2 bytes, 'a ' or 'a$' + /0
              #endasm

return *dargc[];    // probably wrong return value
}



main (char * dargc )

{ printf("%2s",*dargc[1]); //string
  printf("%d",*dargc[0]);  // char as int
  return; 
}
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
i started a tread on spectrumcomputing about "DEF FN self test"
https://spectrumcomputing.co.uk/forums/ ... 14#p143114

its a working ASM that looks inside the DEF FN in Basic memory.
it returns with 65535 as error or the value found on "amount" and "name"
but the result can be 3 bytes hence its better to use the adres as pointer.
but that is the C part off this story!

this is the ASM source which still needs some cleaning and optimisation,
any suggestion is welcome

Code: Select all


; DEF FN small self test

; nDEFFNtst_041
; pasmo -d --tap --name nDEFFNtst nDEFFNtst_041.asm nDEFFNtst_041.tap nDEFFNtst_041.symbol
; cat nDEFFNbas.tap nDEFFNtst_041.tap > nDEFtest_041.tap

; NO ORG > 100% relocatable IF FINISED and without the 'print'


;  10 DEF FN a(a,b,c,d,e,f,g,h,i,j)=USR t
;  20 DEF FN a$(a,b,c,d,e,f,g,h,i,j)=STR$ USR t
;  25 DEF FN b$(a,b,c,d$,e,f,g,h$,i,j)=STR$ USR t
;  30 CLEAR VAL "25499": LET t=VAL "25500": LOAD ""CODE t
;  40 LET l=FN a(1,2,3,4,5,6,7,8,9,0): GO SUB VAL "100"
;  50 LET l=VAL (FN a$(1,2,3,4,5,6,7,8,9,0)): GO SUB VAL "100"
;  55 LET x$="hallo"
;  60 LET l=VAL (FN b$(1,2,3,"444",5,6,7,x$,9,0)): GO SUB VAL "100"
;  70 STOP 
; 100 LET l1=INT VAL "l/256": LET l2=l-l1*VAL "256": PRINT l,l1;"  ";l2: RETURN 


; print routine can be removed after prove-of-works
print equ 0

setchan       equ 0x1601   ; ROM openchannel routine for #0 and #2

DEF_ADR       equ 23563    ; sysvar

DEFFN         equ 206
CR            equ 13


here equ 25500


              org here

USR           di
              push bc             ; THIS=USR adres to stack
              exx
              pop bc
              push hl             ; save sysvar
              push bc             ; THIS=USR adres to stack
              jr overdata

amount        defb 0
name          defb 32,32,0        ; name$ 2 bytes, 'a ' or 'a$' + /0

overdata      pop de              ; USR adres to DE

              ld hl,7
              add hl,de
              ex de,hl            ;  DE should point to 'amount'

              xor a
              ld (de),a           ; wipe old data
              inc de
              ld (de),a
              inc de
              ld (de),a
              inc de
              ld (de),a
              dec de
              dec de
              dec de              ; DE should point to 'name'

              ld hl,(DEF_ADR)     ; hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,5
              ld a,DEFFN          ; = 'DEF FN'
              cpdr                ; lower until DEF FN found

              inc hl              ; 1 step for last result

              inc hl              ; 1 step for chr$
              ld a,(hl)           ; fetch DEF chr$ as NAME
              ld (de),a           ; store chr$ in 'name'
IF print
              rst 16
ENDIF
              inc hl              ;
              ld a,(hl) 
              cp '$'              ; test for string value
              jr nz,count0        ; $+4

              inc de              ; adres for '$' if found
              ld (de),a           ; store $ aswell
IF print
              rst 16
ENDIF
              inc hl              ; step over '$'
              dec de              ; step back to 'name'

count0        dec de              ; de= 'amount'
              ex de,hl
              ld (hl),1
              ex de,hl

firstbracket: ld a,(hl)           ; reload DEF data

IF print
              rst 16
              ld a,(hl)
ENDIF

              cp '('
              jr nz,error         ; not a correct DEF FN

testend       inc hl              ; +1
              ld a,(hl)
IF print
              rst 16
              ld a,(hl)
ENDIF
              cp ')'              ; if 1st value is a CLOSE bracket NO VARIABLES are included !!!
                                  ; then DEF FN might have no extra functionality for the USR command
              jr z,closed
 
notyet:       cp 'A'              ;    'A'
              jr c,error          ;     to small

              cp 'Z'+1            ;    'z+1'
              jr c,good           ;

              cp 'a'
              jr c,error          ;     to small

              cp 'z'+1            ;    'z+1'
              jr nc,error           ;
                                  ;  fetch variable chr$name here if needed!!
                                  ;  how? is yr own problem!!

good:

; exx
;ld hl,(defnames)
;ld (hl),a
;inc hl
;ld (defnames),hl
; exx

              inc hl              ;
              ld a,(hl) 
              cp '$'              ; test for string value
              jr nz,n14

; exx
;ld hl,(defnames)
;ld (hl),a
;inc hl
;ld (defnames),hl
; exx

IF print
              rst 16
              ld a,(hl)
ENDIF

              inc hl              ; +1 step over internal '$'

n14           ld a,(hl)
              cp 14               ; only THEN its a 1+5 notation value start marker
              jr nz,error         ; no marker found
 
            ; correct internal DEF FN variable found
              ld bc,6             ; +6
              add hl,bc           ; raise 6 bytes to step over value

              ld a,(hl)
IF print
              rst 16
              ld a,(hl)
ENDIF
              cp ','
              jr z,count1

              cp ')'
              jr z,closed
              jr error

count1        ex de,hl
              inc (hl)            ; amount+1 > the namestring is 1st variable of argc > arg[0] is filename
              ex de,hl
              jr testend

closed        ld a,(de)
              ld b,a
              inc de
              ld a,(de)
              ld c,a

              inc hl
              ld a,(hl)
IF print
              rst 16
              ld a,(hl)
ENDIF
              cp '='
              jr z,done
error         ld bc,65535        ; make here an error message ??
              
done:         ld (errr),bc
IF print
              call write
ENDIF
              pop hl
              exx
              ld bc,(errr)
              ei
              ret

IF print
write         
              ld a,(de)
              ld l,a
              call dec_number

              ld a,2
              call setchan
              ld a,CR
              rst 16
              ld hl,name
              call ploop
              ld hl,number_str
              call ploop
              ld a," "
              rst 16
              ret


ploop:        ld a,(hl)
              and a
              ret z
              inc hl        
              rst 16
              jr ploop
number_str    defb 32,32,32,32,32,0

;http://zxm.speccy.cz/data/Z80%20Bits.html#5.1
; Input: HL = number to convert, DE = location of ASCII string
;Output: ASCII string at (DE) ,0 fast 99 super long in TSTATE, its a 'rotator'

dec_number      ld h,0   ; cut h for 8bit handeling, yet 5 digits in 0's used
          	ld de,number_str
Num2Dec5        ld bc,-10000
	        call Num1
Num2Dec4        ld bc,-1000
	        call Num1
Num2Dec3        ld bc,-100  ;10t
                call Num1   ;17+
Num2Dec2        ld bc,-10   ;10t  2 digits only
                call Num1   ;17+
                ld c,b      ; 4t  0xffff = -1 in 2complement

Num1	        ld a,"0"-1 ; 7t
Num2	        inc a      ;/ 4t
	        add hl,bc  ;/ 7t  add a negative number, CARRY influenced
	        jr c,Num2  ;/12t-5  /(x*(4+7+12)-5) 0=((23))-5   ,9=(10*(23))-5
	        sbc hl,bc  ;15t 
	        ld (de),a  ; 7t
	        inc de     ; 6t
                ret        ;10t
ENDIF


errr            defw 0     ; !!! needed


END here
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 »

the 'clean' version
relocatable and having BC the result

Code: Select all


; DEF FN small self test

; DEFFNselftest_042
; pasmo -d --tap --name DEFFNtst DEFFNselftest_042.asm DEFFNselftest_042.tap DEFFNselftest_042.symbol
; cat nDEFFNbas.tap DEFFNselftest_042.tap > DEFFNtest_042.tap

; NO ORG > 100% relocatable

;  10 DEF FN a(a,b,c,d,e,f,g,h,i,j)=USR t
;  20 DEF FN a$(a,b,c,d,e,f,g,h,i,j)=STR$ USR t
;  25 DEF FN b$(a,b,c,d$,e,f,g,h$,i,j)=STR$ USR t
;  30 CLEAR VAL "25499": LET t=VAL "25500": LOAD ""CODE t
;  40 LET l=FN a(1,2,3,4,5,6,7,8,9,0): GO SUB VAL "100"
;  50 LET l=VAL (FN a$(1,2,3,4,5,6,7,8,9,0)): GO SUB VAL "100"
;  55 LET x$="hallo"
;  60 LET l=VAL (FN b$(1,2,3,"444",5,6,7,x$,9,0)): GO SUB VAL "100"
;  70 STOP 
; 100 LET l1=INT VAL "l/256": LET l2=l-l1*VAL "256": PRINT l,l1;"  ";l2: RETURN 


DEF_ADR       equ 23563    ; sysvar
DEFFN         equ 206



;here equ 25500     ; one ADRES still hardcoded
;              org here

              di
              push bc             ; THIS=USR adres to stack
              exx
              pop bc
              push hl             ; save sysvar
              push bc             ; THIS=USR adres to stack
              jr overdata

amount        defb 0
name          defb 32,32,0        ; name$ 2 bytes, 'a ' or 'a$' + /0

overdata      pop de              ; USR adres to DE

              ld hl,7
              add hl,de
              ex de,hl            ;  DE should point to 'amount'

              xor a
              ld (de),a           ; wipe old data
              inc de
              ld (de),a
              inc de
              ld (de),a
              inc de
              ld (de),a
              dec de
              dec de
              dec de              ; DE should point to 'name'

              ld hl,(DEF_ADR)     ; hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,5
              ld a,DEFFN          ; = 'DEF FN'
              cpdr                ; lower until DEF FN found

              inc hl              ; 1 step for last result

              inc hl              ; 1 step for chr$
              ld a,(hl)           ; fetch DEF chr$ as NAME
              ld (de),a           ; store chr$ in 'name'

              inc hl              ;
              ld a,(hl) 
              cp '$'              ; test for string value
              jr nz,count0        ; $+4

              inc de              ; adres for '$' if found
              ld (de),a           ; store $ aswell

              inc hl              ; step over '$'
              dec de              ; step back to 'name'

count0        dec de              ; de= 'amount'
              ex de,hl
              ld (hl),1
              ex de,hl

firstbracket: ld a,(hl)           ; reload DEF data

              cp '('
              jr nz,error         ; not a correct DEF FN

testend       inc hl              ; +1
              ld a,(hl)

              cp ')'              ; if 1st value is a CLOSE bracket NO VARIABLES are included !!!
                                  ; then DEF FN might have no extra functionality for the USR command
              jr z,closed
 
notyet:       cp 'A'              ;    'A'
              jr c,error          ;     to small

              cp 'Z'+1            ;    'z+1'
              jr c,good           ;

              cp 'a'
              jr c,error          ;     to small

              cp 'z'+1            ;    'z+1'
              jr nc,error           ;
                                  ;  fetch variable chr$name here if needed!!
                                  ;  how? is yr own problem!!

good:         inc hl              ;
              ld a,(hl) 
              cp '$'              ; test for string value
              jr nz,n14

              inc hl              ; +1 step over internal '$'

n14           ld a,(hl)
              cp 14               ; only THEN its a 1+5 notation value start marker
              jr nz,error         ; no marker found
 
            ; correct internal DEF FN variable found
              ld bc,6             ; +6
              add hl,bc           ; raise 6 bytes to step over value

              ld a,(hl)
              cp ','
              jr z,count1

              cp ')'
              jr z,closed
              jr error

count1        ex de,hl
              inc (hl)            ; amount+1 > the namestring is 1st variable of argc > arg[0] is filename
              ex de,hl
              jr testend

closed        ld a,(de)
              ld b,a
              inc de
              ld a,(de)
              ld c,a

              inc hl
              ld a,(hl)
              cp '='
              jr z,done
error         ld bc,65535        ; make here an error message ??
              
done          pop hl
              push bc
              exx
              pop  bc
              ei
              ret
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 »

https://github.com/z88dk/z88dk/wiki/Cal ... urn-values

does this mean i can return the whole answer in a 4 byte sequence
argc = char amount, char name, char name$, char /0
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 »

a last ASM and a first serious failing attempt


i missed a count so i had to addept further
in ASM the USR gives AN error code via BC
the values of 'amount ' and 'name' are stored in DE and HL at return

Code: Select all


; DEF FN small self test

; DEFFNselftest_049
; pasmo -d --tap --name DEFFNtst DEFFNselftest_049.asm DEFFNselftest_049.tap DEFFNselftest_049.symbol
; cat nDEFFNbas.tap DEFFNselftest_049.tap > DEFFNtest_049.tap

; NO ORG > 100% relocatable

;  10 DEF FN a(a,b,c,d,e,f,g,h,i,j)=USR t
;  20 DEF FN a$(a,b,c,d,e,f,g,h,i,j)=STR$ USR t
;  25 DEF FN b$(a,b,c,d$,e,f,g,h$,i,j)=STR$ USR t
;  30 CLEAR VAL "25499": LET t=VAL "25500": LOAD ""CODE t
;  40 LET l=FN a(1,2,3,4,5,6,7,8,9,0): GO SUB VAL "100"
;  50 LET l=VAL (FN a$(1,2,3,4,5,6,7,8,9,0)): GO SUB VAL "100"
;  55 LET x$="hallo"
;  60 LET l=VAL (FN b$(1,2,3,"444",5,6,7,x$,9,0)): GO SUB VAL "100"
;  70 STOP 
; 100 LET l1=INT VAL "l/256": LET l2=l-l1*VAL "256": PRINT l,l1;"  ";l2: RETURN 


DEF_ADR       equ 23563    ; sysvar
DEFFN         equ 206



;here equ 25500
;              org here

              di
              push bc             ; THIS=USR adres to stack
              exx
              pop bc
              push hl             ; save sysvar
              push bc             ; THIS=USR adres to stack
              jr overdata


name          defb 0,0          ; name$ 2 bytes, 'a ' or 'a$'
amount        defb 0,0          ; return value is 32 bits, DEHL

overdata      pop de              ; USR adres to DE

              ld hl,8
              add hl,de
              ex de,hl            ;  DE should point to 'name'

              xor a
              ld (de),a           ; wipe old data
              inc de
              ld (de),a
              inc de
              ld (de),a
              inc de
              ld (de),a
              dec de
              dec de
              dec de              ; DE should point to 'name'

              ld hl,(DEF_ADR)     ; hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,5
              ld a,DEFFN          ; = 'DEF FN'
              cpdr                ; lower until DEF FN found

              inc hl              ; 1 step for last result

              inc hl              ; 1 step for chr$
              ld a,(hl)           ; fetch DEF chr$ as NAME
              ld (de),a           ; store chr$ in 'name'
              inc de              ; adres for '$' if found

              ld a,' '
              ld (de),a           ; store ' ' in 'name$'

              inc hl              ;
              ld a,(hl) 
              cp '$'              ; test for string value
              jr nz,count0        ;
              ld (de),a           ; store '$' instead of ' '
              inc hl              ; step over '$' in deffn data

count0        inc de              ; de= 'amount' = 0
              ex de,hl
              inc (hl)            ; amount+1
              ex de,hl            ; 1 name = 1 variable in argc > arg[0]=DEF FN chr$

firstbracket: ld a,(hl)           ; reload DEF data with or without '$'
              cp '('              ; check open DEF FN
              jr nz,error         ; not a correct DEF FN

testend       inc hl              ; +1
              ld a,(hl)

              cp ')'              ; if 1st value is a CLOSE bracket NO VARIABLES are included !!!
                                  ; then DEF FN might have no extra functionality for the USR command
              jr z,closed
 
notyet:       cp 'A'              ;    'A'
              jr c,error          ;     to small

              cp 'Z'+1            ;    'Z+1'
              jr c,good           ;    

              cp 'a'
              jr c,error          ;     to small

              cp 'z'+1            ;    'z+1'
              jr nc,error           ;
                                  ;  fetch variable chr$name here if needed!!
                                  ;  how? is yr own problem!!

good:         inc hl              ; 'A'-'Z' or 'a'-'z'
              ld a,(hl) 

              cp '$'              ; test for string value
              jr nz,n14

              inc hl              ; +1 step over internal '$'
              ld a,(hl)

n14           cp 14               ; only THEN its a 1+5 notation value start marker
              jr nz,error         ; no marker found
 
            ; correct internal DEF FN variable found
              ld bc,6             ; +6
              add hl,bc           ; raise 6 bytes to step over value

              ld a,(hl)
              cp ','
              jr z,count1

              cp ')'
              jr z,closed
              jr error

count1        ex de,hl
              inc (hl)            ; amount+1
              ex de,hl
              jr testend

closed        ex de,hl            ; last count, needs optimise with 3 spots
              inc (hl)            ; amount+1
              ex de,hl

              inc hl
              ld a,(hl)
              cp '='
              jr z,done
error         ld bc,65535        ; make here an error message ??


done          pop hl      ; sysvar
              push bc     ; error message for USR
              push de     ; name adres
              exx
              pop bc      ; name adres from de
              ld a,(bc)
              ld e,a

              inc bc
              ld a,(bc)
              ld d,a

              inc bc      ; amount adres
              ld a,(bc)
              ld l,a

              inc bc
              ld a,(bc)
              ld h,a

              pop  bc     ; error message for USR

    ; de=CHRname[0] , hl=INT amount
              ei         ; its a dinosaur !!!
              ret

but the C version complains verymuch about some variable names which are the asm lables...

Code: Select all


// DEF FN small self test

// DEFFNselftest_049
// zcc +zx -vn -lm -startup=31 -zorg0x639C DEFFNselftest_049.c -oDEFFNself -lndos -create-app -Cz --noloader --list --c-code-in-asm //-a

// cat nDEFFNbas.tap DEFFNselftest_049.tap > DEFFNtest_049.tap

// NO ORG > 100% relocatable

//  10 DEF FN a(a,b,c,d,e,f,g,h,i,j)=USR t
//  20 DEF FN a$(a,b,c,d,e,f,g,h,i,j)=STR$ USR t
//  25 DEF FN b$(a,b,c,d$,e,f,g,h$,i,j)=STR$ USR t
//  30 CLEAR VAL "25499": LET t=VAL "25500": LOAD ""CODE t
//  40 LET l=FN a(1,2,3,4,5,6,7,8,9,0): GO SUB VAL "100"
//  50 LET l=VAL (FN a$(1,2,3,4,5,6,7,8,9,0)): GO SUB VAL "100"
//  55 LET x$="hallo"
//  60 LET l=VAL (FN b$(1,2,3,"444",5,6,7,x$,9,0)): GO SUB VAL "100"
//  70 STOP 
// 100 LET l1=INT VAL "l/256": LET l2=l-l1*VAL "256": PRINT l,l1//"  ";l2: RETURN 


int  __CALLEE__  d_arg() __naked{



#asm

DEF_ADR       equ 23563    // sysvar
DEFFN         equ 206



//here equ 25500
//              org here

              di
              push bc             // THIS=USR adres to stack
              exx
              pop bc
              push hl             // save sysvar
              push bc             // THIS=USR adres to stack
              jr overdata


name          defb 0,0          // name$ 2 bytes, 'a ' or 'a$'
amount        defb 0,0          // return value is 32 bits, DEHL

overdata      pop de              // USR adres to DE

              ld hl,8
              add hl,de
              ex de,hl            //  DE should point to 'name'

              xor a
              ld (de),a           // wipe old data
              inc de
              ld (de),a
              inc de
              ld (de),a
              inc de
              ld (de),a
              dec de
              dec de
              dec de              // DE should point to 'name'

              ld hl,(DEF_ADR)     // hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,5
              ld a,DEFFN          // = 'DEF FN'
              cpdr                // lower until DEF FN found

              inc hl              // 1 step for last result

              inc hl              // 1 step for chr$
              ld a,(hl)           // fetch DEF chr$ as NAME
              ld (de),a           // store chr$ in 'name'
              inc de              // adres for '$' if found

              ld a,' '
              ld (de),a           // store ' ' in 'name$'

              inc hl              //
              ld a,(hl) 
              cp '$'              // test for string value
              jr nz,count0        //
              ld (de),a           // store '$' instead of ' '
              inc hl              // step over '$' in deffn data

count0        inc de              // de= 'amount' = 0
              ex de,hl
              inc (hl)            // amount+1
              ex de,hl            // 1 name = 1 variable in argc > arg[0]=DEF FN chr$

firstbracket: ld a,(hl)           // reload DEF data with or without '$'
              cp '('              // check open DEF FN
              jr nz,error         // not a correct DEF FN

testend       inc hl              // +1
              ld a,(hl)

              cp ')'              // if 1st value is a CLOSE bracket NO VARIABLES are included !!!
                                  // then DEF FN might have no extra functionality for the USR command
              jr z,closed
 
notyet:       cp 'A'              //    'A'
              jr c,error          //     to small

              cp 'Z'+1            //    'Z+1'
              jr c,good           //    

              cp 'a'
              jr c,error          //     to small

              cp 'z'+1            //    'z+1'
              jr nc,error           //
                                  //  fetch variable chr$name here if needed!!
                                  //  how? is yr own problem!!

good:         inc hl              // 'A'-'Z' or 'a'-'z'
              ld a,(hl) 

              cp '$'              // test for string value
              jr nz,n14

              inc hl              // +1 step over internal '$'
              ld a,(hl)

n14           cp 14               // only THEN its a 1+5 notation value start marker
              jr nz,error         // no marker found
 
            // correct internal DEF FN variable found
              ld bc,6             // +6
              add hl,bc           // raise 6 bytes to step over value

              ld a,(hl)
              cp ','
              jr z,count1

              cp ')'
              jr z,closed
              jr error

count1        ex de,hl
              inc (hl)            // amount+1
              ex de,hl
              jr testend

closed        ex de,hl            // last count, needs optimise with 3 spots
              inc (hl)            // amount+1
              ex de,hl

              inc hl
              ld a,(hl)
              cp '='
              jr z,done
error         ld bc,65535        // make here an error message ??


done          pop hl      // sysvar
              push bc     // error message for USR
              push de     // name adres
              exx
              pop bc      // name adres from de
              ld a,(bc)
              ld e,a

              inc bc
              ld a,(bc)
              ld d,a

              inc bc      // amount adres
              ld a,(bc)
              ld l,a

              inc bc
              ld a,(bc)
              ld h,a

              pop  bc     // error message for USR

    // de=CHRname[0] , hl=INT amount
              ei         // its a dinosaur !!!
              ret

#endasm 

return ;           }


error result off ZCC:

Code: Select all

zcc +zx -vn -lm -startup=31 -zorg0x639C DEFFNselftest_049.c -oDEFFNself -lndos -create-app -Cz --noloader --list --c-code-in-asm
DEFFNselftest_049.c::d_arg::1::1:47: error: syntax error
  ^---- name defb 0,0
DEFFNselftest_049.c::d_arg::1::1:48: error: syntax error
  ^---- amount defb 0,0
DEFFNselftest_049.c::d_arg::1::1:50: error: syntax error
  ^---- overdata pop de
DEFFNselftest_049.c::d_arg::1::1:90: error: syntax error
  ^---- count0 inc de
DEFFNselftest_049.c::d_arg::1::1:99: error: syntax error
  ^---- testend inc hl
DEFFNselftest_049.c::d_arg::1::1:129: error: syntax error
  ^---- n14 cp 14
DEFFNselftest_049.c::d_arg::1::1:144: error: syntax error
  ^---- count1 ex de,hl
DEFFNselftest_049.c::d_arg::1::1:149: error: syntax error
  ^---- closed ex de,hl
DEFFNselftest_049.c::d_arg::1::1:157: error: syntax error
  ^---- error ld bc,65535
DEFFNselftest_049.c::d_arg::1::1:160: error: syntax error
  ^---- done pop hl
DEFFNselftest_049.c::d_arg::1::1:44: error: undefined symbol: overdata
  ^---- overdata
DEFFNselftest_049.c::d_arg::1::1:86: error: undefined symbol: count0
  ^---- count0
DEFFNselftest_049.c::d_arg::1::1:97: error: undefined symbol: error
  ^---- error
DEFFNselftest_049.c::d_arg::1::1:104: error: undefined symbol: closed
  ^---- closed
DEFFNselftest_049.c::d_arg::1::1:107: error: undefined symbol: error
  ^---- error
DEFFNselftest_049.c::d_arg::1::1:113: error: undefined symbol: error
  ^---- error
DEFFNselftest_049.c::d_arg::1::1:116: error: undefined symbol: error
  ^---- error
DEFFNselftest_049.c::d_arg::1::1:124: error: undefined symbol: n14
  ^---- n14
DEFFNselftest_049.c::d_arg::1::1:130: error: undefined symbol: error
  ^---- error
DEFFNselftest_049.c::d_arg::1::1:138: error: undefined symbol: count1
  ^---- count1
DEFFNselftest_049.c::d_arg::1::1:141: error: undefined symbol: closed
  ^---- closed
DEFFNselftest_049.c::d_arg::1::1:142: error: undefined symbol: error
  ^---- error
DEFFNselftest_049.c::d_arg::1::1:147: error: undefined symbol: testend
  ^---- testend
DEFFNselftest_049.c::d_arg::1::1:156: error: undefined symbol: done
  ^---- done
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 »

at least this one does not crash
labels are
label:
WITH colon !
but the RESULT is wrong

Code: Select all


// DEF FN small self test

// DEFFNselftest_051
// zcc +zx -vn -lm -startup=31 -zorg0x639C DEFFNselftest_051.c -oDEFFNselftest_051 -lndos -create-app -Cz --noloader --list --c-code-in-asm //-a

// cat nDEFFNbas.tap DEFFNselftest_051.tap > DEFFNtest_051.tap

// NO ORG > 100% relocatable

//  10 DEF FN a(a,b,c,d,e,f,g,h,i,j)=USR t
//  20 DEF FN a$(a,b,c,d,e,f,g,h,i,j)=STR$ USR t
//  25 DEF FN b$(a,b,c,d$,e,f,g,h$,i,j)=STR$ USR t
//  30 CLEAR VAL "25499": LET t=VAL "25500": LOAD ""CODE t
//  40 LET l=FN a(1,2,3,4,5,6,7,8,9,0): GO SUB VAL "100"
//  50 LET l=VAL (FN a$(1,2,3,4,5,6,7,8,9,0)): GO SUB VAL "100"
//  55 LET x$="hallo"
//  60 LET l=VAL (FN b$(1,2,3,"444",5,6,7,x$,9,0)): GO SUB VAL "100"
//  70 STOP 
// 100 LET l1=INT VAL "l/256": LET l2=l-l1*VAL "256": PRINT l,l1//"  ";l2: RETURN 


int  __CALLEE__  d_arg() __naked{


#asm

DEF_ADR       equ 23563    // sysvar
DEFFN         equ 206



//here equ 25500
//              org here

              di
              push bc             // THIS=USR adres to stack
              exx
              pop bc
              push hl             // save sysvar
              push bc             // THIS=USR adres to stack
              jr overdata


name:         defb 0,0          // name$ 2 bytes, 'a ' or 'a$'
amount:       defb 0,0          // return value is 32 bits, DEHL

overdata:     pop de              // USR adres to DE

              ld hl,8
              add hl,de
              ex de,hl            //  DE should point to 'name'

              xor a
              ld (de),a           // wipe old data
              inc de
              ld (de),a
              inc de
              ld (de),a
              inc de
              ld (de),a
              dec de
              dec de
              dec de              // DE should point to 'name'

              ld hl,(DEF_ADR)     // hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,5
              ld a,DEFFN          // = 'DEF FN'
              cpdr                // lower until DEF FN found

              inc hl              // 1 step for last result

              inc hl              // 1 step for chr$
              ld a,(hl)           // fetch DEF chr$ as NAME
              ld (de),a           // store chr$ in 'name'
              inc de              // adres for '$' if found

              ld a,' '
              ld (de),a           // store ' ' in 'name$'

              inc hl              //
              ld a,(hl) 
              cp '$'              // test for string value
              jr nz,count0        //
              ld (de),a           // store '$' instead of ' '
              inc hl              // step over '$' in deffn data

count0:       inc de              // de= 'amount' = 0
              ex de,hl
              inc (hl)            // amount+1
              ex de,hl            // 1 name = 1 variable in argc > arg[0]=DEF FN chr$

firstbracket: ld a,(hl)           // reload DEF data with or without '$'
              cp '('              // check open DEF FN
              jr nz,error         // not a correct DEF FN

testend:      inc hl              // +1
              ld a,(hl)

              cp ')'              // if 1st value is a CLOSE bracket NO VARIABLES are included !!!
                                  // then DEF FN might have no extra functionality for the USR command
              jr z,closed
 
notyet:       cp 'A'              //    'A'
              jr c,error          //     to small

              cp 'Z'+1            //    'Z+1'
              jr c,good           //    

              cp 'a'
              jr c,error          //     to small

              cp 'z'+1            //    'z+1'
              jr nc,error           //
                                  //  fetch variable chr$name here if needed!!
                                  //  how? is yr own problem!!

good:         inc hl              // 'A'-'Z' or 'a'-'z'
              ld a,(hl) 

              cp '$'              // test for string value
              jr nz,n14

              inc hl              // +1 step over internal '$'
              ld a,(hl)

n14:          cp 14               // only THEN its a 1+5 notation value start marker
              jr nz,error         // no marker found
 
            // correct internal DEF FN variable found
              ld bc,6             // +6
              add hl,bc           // raise 6 bytes to step over value

              ld a,(hl)
              cp ','
              jr z,count1

              cp ')'
              jr z,closed
              jr error

count1:       ex de,hl
              inc (hl)            // amount+1
              ex de,hl
              jr testend

closed:       ex de,hl            // last count, needs optimise with 3 spots
              inc (hl)            // amount+1
              ex de,hl

              inc hl
              ld a,(hl)
              cp '='
              jr z,done
error:        ld bc,65535        // make here an error message ??


done:         pop hl      // sysvar
              push bc     // error message for USR
              push de     // name adres
              exx
              pop bc      // name adres from de
              ld a,(bc)
              ld e,a

              inc bc
              ld a,(bc)
              ld d,a

              inc bc      // amount adres
              ld a,(bc)
              ld l,a

              inc bc
              ld a,(bc)
              ld h,a

              pop  bc     // error message for USR

    // de=CHRname[0] , hl=INT amount
              ei         // its a dinosaur !!!
              ret

#endasm 

return ;           }



int main( d_arg ) {

char name[];
int amount ;

printf ("name %s", name );

return;
}
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 »

:O I HAVE NO CLUE AT ALL, what to do next :O
i tryed an EXTERN and putting the CHAR outside the main, but its just wild guessing
after reading SOME threads about #endasm

this is my last "attempt"
well, it does not crash, and that all i can say,
i realy need a simple example about retrieving a variable from asm to C

if you WANT and see the problem please be so kind to adapt this one a bit
then maybe i know how to do it next time

Code: Select all


// DEF FN small self test

// DEFFNselftest_054
// zcc +zx -vn -lm -startup=31 -zorg0x639C DEFFNselftest_054.c -oDEFFNselftest_054 -lndos -create-app -Cz --noloader --list --c-code-in-asm //  -a

// cat nDEFFNbas.tap DEFFNselftest_054.tap > DEFFNtest_054.tap

// NO ORG > 100% relocatable

//  10 DEF FN a(a,b,c,d,e,f,g,h,i,j)=USR t
//  20 DEF FN a$(a,b,c,d,e,f,g,h,i,j)=STR$ USR t
//  25 DEF FN b$(a,b,c,d$,e,f,g,h$,i,j)=STR$ USR t
//  30 CLEAR VAL "25499": LET t=VAL "25500": LOAD ""CODE t
//  40 LET l=FN a(1,2,3,4,5,6,7,8,9,0): GO SUB VAL "100"
//  50 LET l=VAL (FN a$(1,2,3,4,5,6,7,8,9,0)): GO SUB VAL "100"
//  55 LET x$="hallo"
//  60 LET l=VAL (FN b$(1,2,3,"444",5,6,7,x$,9,0)): GO SUB VAL "100"
//  70 STOP 
// 100 LET l1=INT VAL "l/256": LET l2=l-l1*VAL "256": PRINT l,l1//"  ";l2: RETURN 






unsigned char name1,name2,amount1, amount2;
unsigned int amount ;

int  __CALLEE__  d_arg() __naked{


#asm

DEF_ADR       equ 23563    // sysvar
DEFFN         equ 206


//here equ 25500
//              org here

              di
              push bc             // THIS=USR adres to stack
              exx
              pop bc
              push hl             // save sysvar
;              push bc             // THIS=USR adres to stack
;              jr overdata
;name:         defb 0,0          // name$ 2 bytes, 'a ' or 'a$'
;amount:       defb 0,0          // return value is 32 bits, DEHL
;overdata:     pop de              // USR adres to DE
;              ld hl,8
;              add hl,de
;              ex de,hl            //  DE should point to 'name'

              ld de,_name1
              xor a
              ld (de),a           // wipe old data
              inc de
              ld (de),a
              inc de
              ld (de),a
              inc de
              ld (de),a

              ld de,_name1

              // DE should point to 'name'

              ld hl,(DEF_ADR)     // hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,5
              ld a,DEFFN          // = 'DEF FN'
              cpdr                // lower until DEF FN found

              inc hl              // 1 step for last result

              inc hl              // 1 step for chr$
              ld a,(hl)           // fetch DEF chr$ as NAME
              ld (de),a           // store chr$ in 'name'
              inc de              // adres for '$' if found

              ld a,' '
              ld (de),a           // store ' ' in 'name$'

              inc hl              //
              ld a,(hl) 
              cp '$'              // test for string value
              jr nz,count0        //
              ld (de),a           // store '$' instead of ' '
              inc hl              // step over '$' in deffn data

count0:       inc de              // de= 'amount' = 0
              ex de,hl
              inc (hl)            // amount+1
              ex de,hl            // 1 name = 1 variable in argc > arg[0]=DEF FN chr$

firstbracket: ld a,(hl)           // reload DEF data with or without '$'
              cp '('              // check open DEF FN
              jr nz,error         // not a correct DEF FN

testend:      inc hl              // +1
              ld a,(hl)

              cp ')'              // if 1st value is a CLOSE bracket NO VARIABLES are included !!!
                                  // then DEF FN might have no extra functionality for the USR command
              jr z,closed
 
notyet:       cp 'A'              //    'A'
              jr c,error          //     to small

              cp 'Z'+1            //    'Z+1'
              jr c,good           //    

              cp 'a'
              jr c,error          //     to small

              cp 'z'+1            //    'z+1'
              jr nc,error           //
                                  //  fetch variable chr$name here if needed!!
                                  //  how? is yr own problem!!

good:         inc hl              // 'A'-'Z' or 'a'-'z'
              ld a,(hl) 

              cp '$'              // test for string value
              jr nz,n14

              inc hl              // +1 step over internal '$'
              ld a,(hl)

n14:          cp 14               // only THEN its a 1+5 notation value start marker
              jr nz,error         // no marker found
 
            // correct internal DEF FN variable found
              ld bc,6             // +6
              add hl,bc           // raise 6 bytes to step over value

              ld a,(hl)
              cp ','
              jr z,count1

              cp ')'
              jr z,closed
              jr error

count1:       ex de,hl
              inc (hl)            // amount+1
              ex de,hl
              jr testend

closed:       ex de,hl            // last count, needs optimise with 3 spots
              inc (hl)            // amount+1
              ex de,hl

              inc hl
              ld a,(hl)
              cp '='
              jr z,done
error:        ld bc,65535        // make here an error message ??


done:         pop hl      // sysvar
              push bc     // error message for USR
              push de     // name adres
              exx
              pop bc      // name adres from de
              ld a,(bc)
              ld e,a

              inc bc
              ld a,(bc)
              ld d,a

              inc bc      // amount adres
              ld a,(bc)
              ld l,a

              inc bc
              ld a,(bc)
              ld h,a

              pop  bc     // error message for USR

    // de=CHRname[0] , hl=INT amount
              ei         // its a dinosaur !!!
              ret

#endasm 

return name1 ; 
 }

int main(  char **d_arg ) {

printf ("name %s", name1 );
printf ("name %d", name1 );
printf ("name %f", name1 );

printf ("name %s", *d_arg );
printf ("name %d", *d_arg );
printf ("name %f", *d_arg );

return 0;
}
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 »

i forgot the BASE off C ...

#include <stdlib.h>
#include <stdio.h>

now it has some readables like 'name' on screen !!
but if someone knows what to do, your welcome
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 »

a pure c aproach with 1 magere succesfull number only

it shows a few characters aswell by %s

)= 32768

, BUT imo the ')' should be printed by ramchr as a single value ?
it seems to find 210 and that chr$ not printed by C

Code: Select all

// DEFFN_011
// zcc +zx -vn DEFFN_011.c -o DEFFN_011 -lndos -create-app -Cz -lm

// DEF_ADR       equ 23563    // sysvar
// DEFFN         equ 206

//   5 DEF FN a()= USR 32768
//  10 CLEAR 32768: LOAD ""CODE
//  15 CLS: RANDOMIZE FN a()


#include <stdio.h>

__at(23563) unsigned int DEF_ADR ;


int main() {

unsigned int *sysadr , *adresvalue ;
unsigned int sysvalue ;
unsigned char ramchr ;

sysadr   = &DEF_ADR ;
sysvalue = *sysadr  ; //16bit
ramchr   = *sysadr  ;

printf("sysvalue\n -- %d \n -- %s \n -- %c \n",sysvalue,sysvalue,sysvalue ) ;

printf("ramchr  \n -- %d \n -- %c \n",ramchr,ramchr) ;

return 0;
}
//  using %s gives an 'endless' string until \0

but DOES point out the DEF FN inside BASIC !!
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 »

sysvalue-- ;

its suposed to step back only 1 but does TWO
and by that it passed the DEF FN start!!!

:rolleyes:

eh why does
sysvalue-- ;
lowers 2 bytes ??

Code: Select all

// DEFFN_019
// zcc +zx -vn DEFFN_019.c -o DEFFN_019 -lndos -create-app -Cz -lm

// DEF_ADR       equ 23563    // sysvar
// DEFFN         equ 206

//   5 DEF FN a(a)= USR 32768
//  10 CLEAR 32768: LOAD ""CODE
//  15 CLS: RANDOMIZE FN a(1)


#include <stdio.h>

__at(23563) unsigned int DEF_ADR ;



int main() {

unsigned int *sysadr ;
unsigned int *sysvalue ;
unsigned char ramchr ;

sysadr   = &DEF_ADR ;
sysvalue = *sysadr  ; //16bit

while ( ramchr != 206 ) {
       ramchr   = *sysvalue  ; // 8bit
       sysvalue-- ;
       printf("%c %d    ",ramchr,sysvalue);
       }

printf("sysvalue\n -- %d \n -- %s \n -- %c \n",sysvalue,sysvalue,sysvalue ) ;

printf("ramchr  \n -- %d \n -- %c \n",ramchr,ramchr) ;

return 0;
}

//  using %s gives an 'endless' string until \0

this works ok

Code: Select all

#include <stdio.h>

__at(23563) unsigned int DEF_ADR ;


int main() {

unsigned int *sysadr ;
unsigned int *sysvalue ;
unsigned char ramchr ;

sysadr   = &DEF_ADR ;
sysvalue = *sysadr  ; //16bit
ramchr   = *sysvalue  ; // 8bit

printf("sysvalue\n -- %d \n -- %s \n -- %c \n",sysvalue,sysvalue,sysvalue ) ;

printf("ramchr  \n -- %d \n -- %c \n",ramchr,ramchr) ;

return 0;
}
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 »

am i hacked that
sysvalue-- ;
add 2 instead off 1 ?

Code: Select all

// DEFFN_028
// zcc +zx -vn -lm DEFFN_028.c -o DEFFN_028 -lndos -create-app -Cz --noloader --list --c-code-in-asm

// DEF_ADR       equ 23563    // sysvar
// DEFFN         equ 206

//   5 DEF FN a(a)= USR 32768
//  10 CLEAR 32768: LOAD ""CODE
//  15 CLS: RANDOMIZE FN a(1)


#include <stdio.h>

__at(23563) unsigned int DEF_ADR ;



int main() {

unsigned int *sysadr ;
unsigned int *sysvalue ;
unsigned char ramchr ;

sysadr   = &DEF_ADR ;
sysvalue = *sysadr  ; //16bit
ramchr   = *sysvalue  ; // 8bit

printf("sysvalue\n -- %d \n -- %s \n -- %c \n",sysvalue,sysvalue,sysvalue ) ;
printf("ramchr  \n -- %d \n -- %c \n",ramchr,ramchr) ;


while ( (ramchr = *sysvalue) != 206)
      {
       sysvalue-- ;
       printf("%d %d    ",ramchr,sysvalue) ;
       }

printf("\n");
printf("sysvalue\n -- %d \n -- %s \n -- %c \n",sysvalue,sysvalue,sysvalue ) ;
printf("ramchr  \n -- %d \n -- %c \n",ramchr,ramchr) ;

return 0;
}

//  using %s gives an 'endless' string until \0
You do not have the required permissions to view the files attached to this post.
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 »

hello
i keep trying
an INT ++raises 2 bytes?

meanwhile i have a different question aswell, in thos line i forgot to print the varibale which ARE mentioned,
shouldnt the compiler give a warning like "variable without use in line: xxx"

Code: Select all

if (print) {
           printf("sysvalue :%d   %d\n",sysvalue, ssvlue ) ;
           printf("ramchr   :%d -- %c   rmch: \n",ramchr,ramchr , rmch ,rmch ) ;
           }
i asume the OPEN variable are part of the change in eg lettersize, could that happen?

back to the DEF FN attempt:
if i look at the screen result the RAMCHR result of 206 is SUBSTRACTED from the sysvalue procut
23759 - 206= 23553
??? i never told the complier to add nor substract with ramchr, is that an buffer error some where???
i made a "char" version and a "int" version beside each other, to get whats happening
the ssvlue add 4 to 23755 to 23759 ???
if this is NOT happening at yr computer then i am hacked or my computer has a memory fault.
both possible

mind the differnet USR use

5 DEF FN a$(a)= STR$ USR 32768
10 CLEAR 32768: LOAD ""CODE
15 CLS: RANDOMIZE VAL FN a$(1)


Code: Select all

// DEF_FN__055
// zcc +zx -vn -lm DEF_FN__055.c -o DEFFN__055 -lndos -create-app // -Cz --noloader --list --c-code-in-asm

// DEF_ADR       equ 23563    // sysvar
// DEFFN         equ 206

//   5 DEF FN a$(a)= STR$ USR 32768
//  10 CLEAR 32768: LOAD ""CODE
//  15 CLS: RANDOMIZE VAL FN a$(1)

#include <stdio.h>

__at(23563) unsigned int DEF_ADR ;

unsigned int main() {

unsigned int *sysadr ;
unsigned int *ssvlue ;
unsigned char *sysvalue ;
unsigned char defname[2], dfnme[2], ramchr , rmch ;

char print=1;

sysadr   = &DEF_ADR ;
sysvalue = *sysadr ; //16bit
ramchr   = *sysvalue ; // 8bit

ssvlue = *sysadr  ; //16bit
rmch   = *ssvlue  ; // 8bit


if (print) {
           printf("sysvalue :%d   %d\n",sysvalue, ssvlue ) ;
           printf("ramchr   :%d -- %c   rmch:%d -- %c \n",ramchr,ramchr , rmch ,rmch ) ;
           }

//while ((ramchr=*--sysvalue) != 206)
while (ramchr != 206)
      {
       ramchr = *--sysvalue ;
       rmch = *--ssvlue ;
           if (print) printf("r%d s%d r%d s%d__",ramchr,sysvalue,rmch,ssvlue) ;
       }

if (print) {
           printf("\n");
           printf("sysvalue :%d   %d\n",sysvalue, ssvlue ) ;
           printf("ramchr   :%d -- %c   rmch:%d -- %c \n",ramchr,ramchr , rmch ,rmch ) ;
           }

ramchr = *++sysvalue ;
rmch = *++ssvlue ;

defname[0]=ramchr ;
defname[1]='.' ;
defname[2]='\0' ;

dfnme[0]=rmch ;
dfnme[1]='.' ;
dfnme[2]='\0' ;

ramchr = *++sysvalue ;
rmch = *++ssvlue ;

if (ramchr == '$')    defname[1]=ramchr ;
if (rmch   == '$')      dfnme[1]=rmch   ;


           printf("sysvalue :%d   %d\n",sysvalue, ssvlue ) ;
           printf("ramchr   :%d -- %c   rmch: %d -- %c\n",ramchr,ramchr , rmch ,rmch ) ;
           printf("defname  :%s\n",defname ) ;
           printf("dfnme  :%s\n",dfnme ) ;

return 0 ;
}
You do not have the required permissions to view the files attached to this post.
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 »

one step done, but at a costy 4kb, so for the inline asm i need an extern defname[], apperently

Code: Select all

// DEF_FN_066b
// zcc +zx -vn -lm DEF_FN_066b.c -o DEFFN_066b -lndos -create-app // -Cz --noloader --list --c-code-in-asm

// DEF_ADR       equ 23563    // sysvar
// DEFFN         equ 206

//   5 DEF FN a$(z)= STR$ USR 32768
//  10 CLEAR 32768: LOAD ""CODE
//  15 CLS: RANDOMIZE VAL FN a$(1)


#include <stdio.h>
#include <stdlib.h>


__at(23563) unsigned int DEF_ADR ;

extern unsigned char *defname[]="..." ;



unsigned char *DEFFN() {

unsigned int *sysadr ;
         int x ;

unsigned char *sysvalue ;

unsigned char ramchr ;

char print=1;

sysadr   = &DEF_ADR  ;
sysvalue = *sysadr   ; 
ramchr   = *sysvalue ; 

if (print) {
           printf("sysvalue :%6d     \n",sysvalue) ;
           printf("ramchr   :%6d %c  \n",ramchr,ramchr ) ;
           }

while (ramchr != 206)
      {
       ramchr = *--sysvalue ;
           if (print) printf("r%4d %c s%6d\n",ramchr,ramchr,sysvalue) ;
       }

if (print) {
           printf("\n");
           printf("sysvalue :%6d     \n",sysvalue) ;
           printf("ramchr   :%6d %c  \n",ramchr,ramchr ) ;
           }

x=0;
while (ramchr != '(')
      {
      ramchr = *++sysvalue ;
      defname[x++]=ramchr ;
           if (print) printf("r%4d %c s%6d\n",ramchr,ramchr,sysvalue) ;
     }
printf("x=%5d \n",x);
defname[x]='\0' ;


if (print) {
           printf("\n");
           printf("sysvalue :%6d     \n",sysvalue) ;
           printf("ramchr   :%6d %c  \n",ramchr,ramchr ) ;
           }

      printf("defname  :%s\n",defname ) ;

      ramchr = *++sysvalue ;

if (print) {
           printf("sysvalue :%6d     \n",sysvalue) ;
           printf("ramchr   :%6d %c  \n",ramchr,ramchr ) ;
           }


return *defname ;
}

void main() {

// char *defname;

DEFFN() ;

printf("hallo %3d  ",defname);
printf("hallo %c\n",defname);
printf("hallo %s\n",defname);

return 0;

}
You do not have the required permissions to view the files attached to this post.
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 »

a working version ??
it does count correct! , but still 3,5 kb and how to connect it as asrc and argv

void main( DEFFN()) {}
does not work yet, but getting closer :p

Code: Select all

// DEFFN070f
// zcc +zx -vn -lm DEFFN070f.c -o DEFFN070f -lndos -create-app // -Cz --noloader --list --c-code-in-asm

//   1 DEF FN z()=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 
//  15 CLS : RANDOMIZE VAL FN a$(1,STR$ 128,65535)
//  16 LET x$="ZX"
//  20 PAUSE 0: BORDER 1: CLS : RANDOMIZE FN b(1,x$,3,4,"5")
//  25 PAUSE 0: BORDER 2: CLS : RANDOMIZE FN z()


#include <stdio.h>
#include <stdlib.h>


// DEFFN         equ 206
__at(23563) unsigned int DEF_ADR ;    // sysvar


extern unsigned char *defname[]="\0\0\0" ;
extern unsigned char *ramchr='\0' ;
extern unsigned char *amount='\0' ;

unsigned char *DEFFN() {

unsigned int *sysadr ;
         int x=-1 ;
unsigned char *sysvalue ;

amount='\0' ;
ramchr='\0' ;
amount='\0' ;

sysadr   = &DEF_ADR  ;
sysvalue = *sysadr   ; 
ramchr   = *sysvalue ; 

while (ramchr != 206)
      {
       ramchr = *--sysvalue ;
       }

while (ramchr != '(')
      {
      ramchr = *++sysvalue ;
      defname[++x]=ramchr ;
     }
defname[x]='\0' ;
++amount ;

ramchr = *++sysvalue ;

while (ramchr !=')' ) {

if ((ramchr >='A' && ramchr <='Z') || (ramchr >='a' && ramchr <='z'))
   {
    ramchr = *++sysvalue ;
    if (ramchr !='$' && ramchr !=14) return -1 ;
    if (ramchr =='$') ramchr = *++sysvalue ;
    if (ramchr !=14) return -1 ;
    // fetch internal value (1+4 mantise) here, in future
    sysvalue= sysvalue + 6 ;
    ++amount ;
   } 
   else { return -1; }  //end if 'A'

   ramchr = *++sysvalue ;
 }  //end while  ')'

return 0 ;
}


void main() {

DEFFN() ;

printf("defname %s\n",defname);
printf("amount %3d\n",amount);

return 0;
}
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 »

Code: Select all


// DEFFN070g
// zcc +zx -vn -lm DEFFN070g.c -o DEFFN070g -lndos -create-app // -Cz --noloader --list --c-code-in-asm

//   1 DEF FN z()=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 
//  15 CLS : RANDOMIZE VAL FN a$(1,STR$ 128,65535)
//  16 LET x$="ZX"
//  20 PAUSE 0: BORDER 1: CLS : RANDOMIZE FN b(1,x$,3,4,"5")
//  25 PAUSE 0: BORDER 2: CLS : RANDOMIZE FN z()


#include <stdio.h>
#include <stdlib.h>


// #define DEF_FN 206  ;
__at(23563) unsigned int DEF_ADR ;    // sysvar


extern unsigned char *defname[]="\0\0\0" ;
extern unsigned char *ramchr='\0' ;
extern unsigned char *amount='\0' ;

unsigned char *DEFFN() {

unsigned int *sysadr ;
         int x=-1 ;
unsigned char *sysvalue ;

amount='\0' ;
ramchr='\0' ;
amount='\0' ;

sysadr   = &DEF_ADR  ;
sysvalue = *sysadr   ;
ramchr   = *sysvalue ;

while (ramchr != 206 )
      {
       ramchr = *--sysvalue ;
      }

while (ramchr != '(')
      {
       ramchr = *++sysvalue ;
       defname[++x]=ramchr ;
      }
defname[x]='\0' ;
++amount ;

ramchr = *++sysvalue ;

while (ramchr !=')' ) {

if ((ramchr >='A' && ramchr <='Z') || (ramchr >='a' && ramchr <='z'))
   {
    ramchr = *++sysvalue ;
    if (ramchr !='$' && ramchr !=14) return -1 ;
    if (ramchr =='$') ramchr = *++sysvalue ;
    if (ramchr !=14) return -1 ;
    // fetch internal value (1+4 mantise) here, in future
    sysvalue= sysvalue + 6 ;
    ++amount ;
   } 
   else { return -1; }  //end if 'A'

   ramchr = *++sysvalue ;
 }  //end while  ')'

return 0 ;
}


void main() {

DEFFN() ;

printf("defname %s\n",defname);
printf("amount %3d\n",amount);

return 0;
}


this does Not work (yet?)

Code: Select all

void main(unsigned char *DEFFN[] ) {

//DEFFN() ;

printf("defname %s\n",defname);
printf("amount %3d\n",amount);

return 0;
}
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, reading about "pragma" in https://z88dk.org/forum/viewtopic.php?t=11957
I now wonder if there is a way to make a pragma that makes zcc use my d_argc instead of the official integreted argc and argv
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 »

first attempt fails and give maybe 2 answers?

Code: Select all

int main(unsigned char *d_argc ) {

//d_argc() ;

printf("defname %s\n",defname);
printf("amount %3d\n",amount);

return 0;
}

Code: Select all

//   CAN a pragma set the use off 'd_argc' instead off 'argc'
   #pragma redirect argc = d_argc()
   /tmp/tmpzccXXmMXesr/zcc_opt.def:4: error: syntax error
    ^---- EXTERN d_argc()
   /tmp/tmpzccXXmMXesr/zcc_opt.def:6: error: syntax error
    ^---- defc argc = d_argc()
   /tmp/tmpzccXXmMXesr/zcc_opt.def:3: error: undefined symbol: argc
does it need to be an EXTERN routine ? probably
what and where is 'defc' and do i need to reference to it ?
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 last understanding is that no replacement for argc exsist which means any 'pragma redirect' has no counterpart.
that means i will just try that deffn =usr cfile and that all. i think i have it working 50%?
hopefully i get the #asm version with a magere 512-1024bytes ?? in c thats very small.
no more arguments, =D
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 last attempt in "pure c" is 4kb and still is only the first setup

meanwhile i would like to use the native system values for printing on screen to not wipe the result off the last USR execution
how do i force zcc to use (and upgrade) "native sysvar" ??

Code: Select all

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

//   1 DEF FN z()=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 
//  15 CLS : RANDOMIZE VAL FN a$(1,STR$ 128,65535)
//  16 LET x$="ZX"
//  20 PAUSE 0: BORDER 1: CLS : RANDOMIZE FN b(1,x$,3,4,"5")
//  25 PAUSE 0: BORDER 2: CLS : RANDOMIZE FN z()


#include <stdio.h>
#include <stdlib.h>

__at(23563) unsigned int DEFADR ;    // sysvar
#define DEFFN 206

extern unsigned char *defname[]="\0\0\0" ;
extern unsigned char *amount='\0' ;



int dargc() {

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

amount='\0' ;

sysadr   = &DEFADR  ;
sysvalue = *sysadr   ;
ramchr   = *sysvalue ;

while (ramchr != DEFFN )
      {
       ramchr = *--sysvalue ;
      }

while (ramchr != '(')
      {
       ramchr = *++sysvalue ;
       defname[++x]=ramchr ;
      }

defname[x]='\0' ;
++amount ;
bytecount= x ;  // x=2 or 3

ramchr = *++sysvalue ;  // step over '('


while (ramchr !=')' ) {

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

    if (ramchr !='$' && ramchr !=14 && ramchr !=')' ) return bytecount ;

    if (ramchr =='$') {
        bytecount++ ;  // varname is 2 bytes
        ramchr = *++sysvalue ;
        }
    if (ramchr !=14 && ramchr !=')' ) return bytecount ;
    // fetch internal value (1+4 mantise) here, in future
    sysvalue += 6 ;  // jump OVER ',' but
    bytecount+= 5 ;  // dont count '14' or ','
    ++amount ;
   } 
   else { return bytecount; }  //end if 'A'

   ramchr = *++sysvalue ;
 }  //end while  ')'


return bytecount ;
}


int main() {

char *defstr[] ;
unsigned int bytecount ;
bytecount = dargc() ;

printf("defname %s\n",defname);
printf("amount %3d\n",amount);
printf("bytecount %6d\n",bytecount);

/*extern*/ char* deffnstr = (char*)malloc(bytecount+1);

return 0;
}
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'm reading your posts but honestly I still haven't got clear answers to your questions.
The ZX Spectrum had some nice trick to bind assembly code to a DEF FN defined function. Sadly I lost track of those articles explaining how to do it.
What you are trying to do is way more sophisticated, you want to make DEF FN react to a variable argument list.

I wonder if the macro based approach I used to catch parameters from Sinclair BASIC in C functions could be of any interest. It can be probably extended with DEF FN style arguments.

https://www.sinclairzxworld.com/viewtopic.php?t=4709
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, thanks for the link, its simular to the _naked() fetching for asm, last on the stack is last in the command and then work back.
Def fn works upward in steps of 8 or 9 bytes including the 2 separators.
i made some def usr s in asm and those work.
https://spectrumcomputing.co.uk/forums/ ... 14#p143114

i noticed that most argc commands are "hand made" aka special build in the main. even the arg.c from watcom actaly is just a c routine that is dedicated to watcom and not a common structure. that is difficult since the many different routines will have many different needs. how simple.
so there is no common structure to replace with a pragma-redirect. in my attempt to make such 'dargc' for using zx0.c inside a zx spectrum i probably just cut out some parts that with out arg are overhead and blindly copy/past. a bit like https://commons.wikimedia.org/wiki/Cate ... categories.
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 »

btw:
sysvar.def consists of 2 128k system variable only
where can i find the other syslists?
i can make some if needed ??

Code: Select all

defc SV_BANKM = 23388           ;Copy of last byte to 32765

defc SV_CHADD = 23645           ;Next character to be interpreted
Post Reply