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 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.
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.
https://www.cpcwiki.eu/index.php?title=Technical_information_about_Locomotive_BASIC
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__)
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.
Thanks will switch to using IX.