From 82a52d6a0cbf69ffdfd71d30c3cde4f72117af87 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 7 Jun 2020 23:05:26 +0200 Subject: [PATCH] beginning of dummy string memory management --- c64/aliases/,aliases_ram_lowmem.s | 6 +- c64/basic/basic_do_new.s | 6 +- c64/basic/engine/ad9e.frmevl.s | 22 ++---- c64/basic/engine/alloc_temp_string.s | 81 ++++++++++++++++++++++ c64/basic/engine/execute_line_statements.s | 8 +++ c64/basic/operators/oper_add.s | 42 +++++++++-- 6 files changed, 139 insertions(+), 26 deletions(-) create mode 100644 c64/basic/engine/alloc_temp_string.s diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index 2e316747..72bd6d0b 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -28,9 +28,9 @@ .label TANSGN = $12 // -- NOT IMPLEMENTED -- .label CHANNL = $13 // -- NOT IMPLEMENTED -- .label LINNUM = $14 // $14-$15 BASIC line number, [!] also used by DOS Wedge - .label TEMPPT = $16 // -- NOT IMPLEMENTED -- - .label LASTPT = $17 // $17-$18 -- NOT IMPLEMENTED -- - .label TEMPST = $19 // $19-$21 -- NOT IMPLEMENTED -- + .label TEMPPT = $16 // pointer to the first available slot in the temporary string descriptor stack + .label LASTPT = $17 // $17-$18 pointer to the last used slot in the temporary string descriptor + .label TEMPST = $19 // $19-$21 temporary string stack descriptors .label INDEX = $22 // $22-$25 temporary variables, [!] our usage might be different .label RESHO = $26 // $26-$2A -- NOT IMPLEMENTED -- .label TXTTAB = $2B // $2B-$2C start of BASIC code diff --git a/c64/basic/basic_do_new.s b/c64/basic/basic_do_new.s index c50d10b1..aae36217 100644 --- a/c64/basic/basic_do_new.s +++ b/c64/basic/basic_do_new.s @@ -73,11 +73,14 @@ basic_do_clr: sta MEMSIZ+0 sta FRETOP+0 - // FALL THROUGH + // FALLTHROUGH basic_do_clr: + // XXX shouldnt FRETOP go here? + // Clear variables, arrays and strings + lda VARTAB+0 sta ARYTAB+0 sta STREND+0 @@ -87,4 +90,5 @@ basic_do_clr: rts + #endif // ROM layout diff --git a/c64/basic/engine/ad9e.frmevl.s b/c64/basic/engine/ad9e.frmevl.s index 54bd7624..a2bd1fdf 100644 --- a/c64/basic/engine/ad9e.frmevl.s +++ b/c64/basic/engine/ad9e.frmevl.s @@ -11,7 +11,6 @@ // // Output: // - VALTYP - $00 = floating number, $FF = string -// - INTFLG (XXX float/integer, probably) // - for float: FAC1 // - for string: __FAC1 + 0 = length, __FAC1 + 1 = pointer to string // @@ -20,20 +19,11 @@ // in a correct order // -// XXX finish the implementation +// XXX finish the implementation: invoking functions, fetcching PI, fetching float, fetching variables FRMEVL: - // XXX we neeed FRETOP for string concatenation - - // lda VARTAB+0 - // sta FRETOP+0 - // lda VARTAB+1 - // sta FRETOP+1 - - // XXX we also need TEMMPPT, LASTPT and TEMPST - // Push the sentinel to the stack lda #$00 @@ -72,7 +62,7 @@ FRMEVL_loop: // Check for the PI cmp #$FF // check for PI - beq_16 FRMEVL_fetch_PI // XXX + beq_16 FRMEVL_fetch_PI // If not a PI and not an unary operator, than everything above // $7F has to be a function @@ -256,16 +246,16 @@ FRMEVL_push_value_operator: FRMEVL_push_string: - // Push string - address, length, type + // Push string - length, address, type + + lda __FAC1+0 + pha lda __FAC1+1 pha lda __FAC1+2 pha - lda __FAC1+0 - pha - txa pha diff --git a/c64/basic/engine/alloc_temp_string.s b/c64/basic/engine/alloc_temp_string.s new file mode 100644 index 00000000..935c5ccd --- /dev/null +++ b/c64/basic/engine/alloc_temp_string.s @@ -0,0 +1,81 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Allocates area for a temporary string +// +// Input: +// - .A - string length +// + + +// XXX - this is a dummy implementation, until proper string handling is implemented +// XXX - addresses are probably wrong, debug it + + +alloc_temp_string: + + // Check if temporary descriptor stack has a free slot + + ldx LASTPT + cpx #$1F + bcs_16 do_FORMULA_TOO_COMPLEX_error + + // Prepare data in index registers + + tay // store length, we will need .A in a moment + + // Increment temporary descriptor stack pointers by 3 + + lda LASTPT + adc #$03 // Carry is already clear here + sta LASTPT + adc #$03 + sta TEMPPT + + // Fill in the new entry + + cmp #$1C + bne !+ + + // Fill in the address - first entry + + ldx TEMPPT + lda STREND+0 + sta $01, x // address - lo byte + lda STREND+1 + sta $02, x // address - hi byte + + jmp alloc_temp_string_space_check +!: + // Fill in the adress - use previous entry + + ldx LASTPT + lda $01, x // address - lo byte + ldx TEMPPT + sta $01, x + + ldx LASTPT + lda $02, x // address - hi byte + ldx TEMPPT + sta $02, x + inc $02, x + + // FALLTROUGH + +alloc_temp_string_space_check: + + // Fill in the length of the new string + + ldx TEMPPT + tya + sta $00, x // length + + // Check if we have enough space + + lda $02, x + cmp FRETOP+1 + beq_16 do_OUT_OF_MEMORY_error + + rts diff --git a/c64/basic/engine/execute_line_statements.s b/c64/basic/engine/execute_line_statements.s index b8a47eb6..5b0e39a3 100644 --- a/c64/basic/engine/execute_line_statements.s +++ b/c64/basic/engine/execute_line_statements.s @@ -32,6 +32,14 @@ execute_statements: cmp #$7F bcc_16 do_SYNTAX_error // branch if not a token XXX here we should handle variable assignments + // Initialize temporary string stack - just about any statement might need it + // XXX original C64 ROM initializes this during the startup too - not sure where to put this + + ldx #$16 + stx LASTPT + ldx #$19 + stx TEMPPT + #if !HAS_OPCODES_65C02 // Get the jump table entry for it, push it on the stack, and then RTS to start it. diff --git a/c64/basic/operators/oper_add.s b/c64/basic/operators/oper_add.s index f4d03945..2670de2e 100644 --- a/c64/basic/operators/oper_add.s +++ b/c64/basic/operators/oper_add.s @@ -25,11 +25,6 @@ oper_add_floats: oper_add_strings: - // Pull string length - - pla - sta __FAC2+0 - // Retrieve string address pla @@ -37,6 +32,41 @@ oper_add_strings: pla sta __FAC2+1 - // XXX merge strings here + // Pull string length + + pla + sta __FAC2+0 + beq oper_add_strings_end // if string 2 is empty, we have nothing to do + + // If string 1 is empty, just copy the metadata + + lda __FAC1+0 + bne !+ + + lda __FAC2+0 + sta __FAC1+0 + lda __FAC2+1 + sta __FAC1+1 + lda __FAC2+2 + sta __FAC1+2 + + jmp FRMEVL_continue +!: + // Allocate memory for concatenated string + + clc + adc __FAC2+0 + bcs_16 do_STRING_TOO_LONG_error + + jsr alloc_temp_string + +.break + + + + // XXX finish the implementation + + +oper_add_strings_end: jmp FRMEVL_continue