diff --git a/src/basic/engine_variables/array_create.s b/src/basic/engine_variables/array_create.s index 14558871..6994ed3b 100644 --- a/src/basic/engine_variables/array_create.s +++ b/src/basic/engine_variables/array_create.s @@ -22,36 +22,48 @@ array_create: lda FOUR6 pha - // Push 0 to mark end of the dimensions - - lda #$00 - pha - - // Now check if the array dimension is given - if not, assume '10' was specified + // Check if the array dimension is given - if not, assume '10' was specified bit DIMFLG bmi array_create_fetch_dims lda #$0A pha + lda #$00 + pha + ldx #$01 bne array_create_store_dims // branch always array_create_fetch_dims: + ldx #$00 // counts number of dimensions + + // FALLTROUGH + +array_create_fetch_dims_loop: + + inx + // XXX check if stack has reasonable space free // Fetch the dimension, put it on the stack - confirmed with orioginal ROM, // that it also stores dimensions in the reverse order - jsr fetch_uint8 + jsr fetch_uint16 bcs_16 do_SYNTAX_error + + // XXX we probably need to increment LINNUM first + + lda LINNUM+0 + pha + lda LINNUM+1 pha // Check if more dimensions are given jsr fetch_character_skip_spaces cmp #$2C // ',' - beq array_create_fetch_dims + beq array_create_fetch_dims_loop cmp #$29 // ')' bne_16 do_SYNTAX_error @@ -62,40 +74,93 @@ array_create_store_dims: // We got the dimensions, time to alocate memory. Arrays are not declared too often, // it will be easier if we perform the garbage collection now + phx_trash_a jsr varstr_garbage_collect - // Create the initial array structure - - // Bytes 0/1 - array name, but we can not fetch it easily now, so skip it - // Bytes 2/3 - offset to the next array - our will be the last one, so 0 - but we will set it later - // Byte 4 - number of dimensions, determine it - // Bytes 5+ - size in each dimension - - // INDEX+2/+3 will be used to calculate number of 'records' + // __FAC1+0/+1 will be used to calculate number of elements ldy #$01 - sty INDEX+3 + sty __FAC1+0 dey - sty INDEX+4 + sty __FAC1+1 - ldy #$05 -!: + // Create the initial array structure (format checked by creating arrays with original ROM) + + // Bytes 0/1 - array name, but we can not fetch it easily now, so skip it for now + // Bytes 2/3 - offset to the next array, skip it for now too + // Byte 4 - number of dimensions + // Bytes 5+ - max index in each dimension (big endian!), this will be set in a loop + + ldy #$04 pla - beq array_create_store_num_dims - // XXX implement this +#if CONFIG_MEMORY_MODEL_60K + + // XXX + // XXX: implement this + // XXX +#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K -array_create_store_num_dims: + sta (STREND), y - // .Y contains number of dimensions + 5 +#endif - // XXX rework code below + iny // .Y - index to store dimension sizes + tax // .X - dimensions not sotred yet + // FALLTROUGH +array_create_store_loop: +#if CONFIG_MEMORY_MODEL_60K + + // XXX + // XXX: implement this + // XXX +#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K + pla + sta (STREND), y + sta __FAC1+3 + iny + pla + sta (STREND), y + sta __FAC1+2 + iny +#endif + + jsr helper_array_create_mul + + dex + bne array_create_store_loop + + // FALLTROUGH + +array_create_store_dims_done: + + // Restore FOUR6, calculate number of bytes needed for storage + + pha + sta FOUR6 // XXX do we need to store this value in FOUR6? + sta __FAC1+2 + stx __FAC1+3 // .X is 0 at this point + + jsr helper_array_create_mul + + // XXX check if we have enough memory + + // XXX retrieve and store array name + + // XXX calculate and store offset to the next array + + // XXX clear area + + // XXX adjust STREND + + // XXX adjust offset of the previous array + + jmp do_NOT_IMPLEMENTED_error - jsr do_NOT_IMPLEMENTED_error diff --git a/src/basic/engine_variables/helper_array_create_mul.s b/src/basic/engine_variables/helper_array_create_mul.s new file mode 100644 index 00000000..3be777ec --- /dev/null +++ b/src/basic/engine_variables/helper_array_create_mul.s @@ -0,0 +1,76 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// 16-bit multiplication, INDEX+0/+1 = __FAC1+0/+1 * __FAC1+2/+3; __FAC1+0/+1 = INDEX+0/+1 +// uses INDEX+2/+3 (for helper routine) as work area + + +helper_array_create_mul: // preserves .X and .Y + + phx_trash_a + + // We will reuse 8x8 multiplication routine used by floating point operations + + // __FAC1+0 (lo byte) * __FAC1+2 (lo byte) + + lda __FAC1+0 + sta INDEX+2 + lda __FAC1+2 + jsr mul_FAC2_FAC1_8x8 // this preserves .Y + + sta INDEX+0 // result - lo byte + stx INDEX+1 // result - hi byte + + // __FAC1+0 (lo byte) * __FAC1+3 (hi byte) + + lda __FAC1+0 + sta INDEX+2 + lda __FAC1+3 + jsr helper_array_create_mul_8x8_add // multiply and add to high byte of the result + + // __FAC1+1 (hi byte) * __FAC1+2 (lo byte) + + lda __FAC1+1 + sta INDEX+2 + lda __FAC1+2 + jsr helper_array_create_mul_8x8_add // multiply and add to high byte of the result + + // __FAC1+1 (hi byte) * __FAC1+3 (hi byte) has to be 0, + // otherwise the result would be out of range + // do not calculate + + lda __FAC1+0 + beq helper_array_create_mul_success + lda __FAC1+3 + beq helper_array_create_mul_success + + // FALLTROUGH + +helper_array_create_mul_error: + + jmp do_OUT_OF_MEMORY_error + +helper_array_create_mul_success: + + lda INDEX+0 + sta __FAC+0 + lda INDEX+1 + sta __FAC+1 + + plx_trash_a + rts + +helper_array_create_mul_add: + + jsr mul_FAC2_FAC1_8x8 + + cpx #$00 + bne helper_array_create_mul_error + + clc + adc INDEX+1 + bcs helper_array_create_mul_error + sta INDEX+1 + + rts