CPCWiki forum

General Category => Technical Support - Software related => Topic started by: Rabs on 16:06, 14 August 22

Title: How to pass an array from BASIC to machine code
Post by: Rabs on 16:06, 14 August 22
How do you pass an array defined in BASIC to machine code using the CALL command and how do you then access the array?

I can see how to pass a string and how to access the string, using the string descriptor via IX,  but what do you do for an array? Must be missing something obvious but can't work it out.

I guess something like;

DIM array[10] 

CALL someroutine, @array[0]

Then look, at IX somehow?

Any help much appreciated.

Title: Re: How to pass an array from BASIC to machine code
Post by: Bread80 on 10:50, 15 August 22
My article at http://bread80.com/2021/11/20/variables-def-fn-definitions-and-arrays-storage-in-amstrad-cpc-locomotive-basic/ should tell you everything you need to know about variable storage on the CPC.

There's no way to get the address of an entire array, whatever that would mean. But all the elements are stored contiguously, so if you get the address of @a[0] then the rest of the array will follow straight after.

The final table in the article gives details of when information is stored about the array structure. The downside is you'll have to walk it backwards but the size is variable depending on the number of dimensions.
Title: Re: How to pass an array from BASIC to machine code
Post by: Rabs on 18:10, 15 August 22
Thanks for the info, very interesting.

If I specify @a%[0] in a CALL command (for a variable defined as "DIM a%[2]"), that after the CALL command, DE contains the address for the first data element and as you indicated the integer elements are stored contiguously but also IY contains the address of the variable name.

If, however, I specify @a[0] (for a variable defined as "DIM a[2]"), this appears to not work. DE contains the same address as above but the data is not there!

Title: Re: How to pass an array from BASIC to machine code
Post by: pelrun on 08:16, 16 August 22
Is it not there or is it in a form you're not expecting? Remember that the default variable type is real - i.e. floating point.

https://www.cpcwiki.eu/index.php?title=Technical_information_about_Locomotive_BASIC
Title: Re: How to pass an array from BASIC to machine code
Post by: Rabs on 12:35, 16 August 22
And the penny drops...

Excellent thanks.

Yes, the data is there and is in floating pointing format.  :)

I knew I was missing something obvious.
Title: Re: How to pass an array from BASIC to machine code
Post by: Bread80 on 12:02, 18 August 22
The source code for a call command. Also used when dispatching an RSX.

;; command CALL
command_CALL:                    ;{{Addr=$f25c Code Calls/jump count: 0 Data use count: 1}}
        call    eval_expr_as_uint ; get address
        ld      c,$ff           
;; store address of function
_command_call_2:                  ;{{Addr=$f261 Code Calls/jump count: 1 Data use count: 0}}
        ld      (Machine_code_address_to_CALL_),de       
;; store rom select
        ld      a,c             
        ld      (ROM_select_number_for_the_above_CALLRSX),a       
        ld      (saved_address_for_SP_during_a_CALL_or_an),sp       
        ld      b,$20            ; max 32 parameters
_command_call_7:                  ;{{Addr=$f26f Code Calls/jump count: 1 Data use count: 0}}
        call    next_token_if_prev_is_comma           
        jr      nc,_command_call_14; (+$08)
        push    bc               
        call    eval_expr_as_string           
        pop    bc               
        push    de                ; push parameter onto stack
        djnz    _command_call_7  ; (-$0d)
_command_call_14:                ;{{Addr=$f27c Code Calls/jump count: 1 Data use count: 0}}
        call    error_if_not_end_of_statement_or_eoln           
        ld      (BASIC_Parser_position_moved_on_to__),hl       
        ld      a,$20            ; max 32 parameters
;; B = $20-number of parameters specified
        sub    b               
;; A = number of parameters
        ld      ix,$0000          ;##LIT##
        add    ix,sp            ; IX points to parameters on stack

;; IX = points to parameters
;; A = number of parameters
;; execute function
        rst    $18             
        defw Machine_code_address_to_CALL_               
        ld      sp,(saved_address_for_SP_during_a_CALL_or_an)       
        call    clear_string_stack           
        ld      hl,(BASIC_Parser_position_moved_on_to__)       
        ret 
Officially the address of the parameters is in IX, the number of parameters in A. Parameters are in reverse order.

DE and IY /may/ contain something useful but it's not remotely guaranteed.
Title: Re: How to pass an array from BASIC to machine code
Post by: Rabs on 17:32, 18 August 22
Thanks will switch to using IX.
Powered by SMFPacks Menu Editor Mod