How to pass an array from BASIC to machine code

Started by Rabs, 18:06, 14 August 22

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


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.


My article at 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.


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!


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.


And the penny drops...

Excellent thanks.

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

I knew I was missing something obvious.


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__)       
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.


Powered by SMFPacks Menu Editor Mod