more work on string support

This commit is contained in:
FeralChild64 committed 2020-07-15 22:04:46 +02:00
1 parent 127b71f67f
commit 159acfba2f
7 files changed
+133 -73

No files matched your search

+78 -22
View File
@@ -9,9 +9,19 @@ cmd_let:
// Fetch variable name, should be followed by assign operator // Fetch variable name, should be followed by assign operator
jsr fetch_variable jsr fetch_variable
#if HAS_OPCODES_65CE02
bcs_16 do_SYNTAX_error bcs_16 do_SYNTAX_error
jsr injest_assign jsr injest_assign
bcs_16 do_SYNTAX_error bcs_16 do_SYNTAX_error
#else
bcs !+
jsr injest_assign
bcc !++
!:
jmp do_SYNTAX_error
!:
#endif
// Determine variable type and push it to the stack // Determine variable type and push it to the stack
@@ -149,12 +159,67 @@ cmd_let_assign_string:
// First special case - check if the new string has size 0 // First special case - check if the new string has size 0
lda DSCPNT+0 lda __FAC1+0
bne cmd_let_assign_string_not_empty bne cmd_let_assign_string_not_empty
// XXX free old string data // Yes, it is empty - check if the old one is, free it if necessary
// Set the new variable as size 0 lda DSCPNT+0
bne !+
jsr varstr_free_DSCPNT_set
!:
// Set the new variable as empty string
ldy #$00
lda #$00
#if CONFIG_MEMORY_MODEL_60K
ldx #<VARPNT
#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
sta (VARPNT), y
#endif
rts
cmd_let_assign_string_not_empty:
// Check if the source and destination strings are the same
lda DSCPNT+1
cmp __FAC1+1
bne cmd_let_assign_string_not_same
iny
lda DSCPNT+2
cmp __FAC1+2
bne cmd_let_assign_string_not_same
// If we are here, than both source and destination strings are the same - nothing more to be done
rts
cmd_let_assign_string_not_same:
.break
// XXX something is wrong with checks below
// Strings are not the same - check if the new one is located within the text area, between TXTTAB and VARTAB
lda TXTTAB+1
cmp __FAC1+2
bcc cmd_let_assign_string_not_text_area
bne !+
lda TXTTAB+0
cmp __FAC1+1
bcc cmd_let_assign_string_not_text_area
!:
lda __FAC1+2
cmp VARTAB+1
bcc cmd_let_assign_string_not_text_area
bne !+
lda __FAC1+1
cmp VARTAB+0
bcc cmd_let_assign_string_not_text_area
!:
// String is located within text area - great, just copy the descriptor
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
@@ -164,30 +229,21 @@ cmd_let_assign_string:
#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
ldy #$00
lda __FAC1+0
sta (VARPNT), y
iny
lda __FAC1+1
sta (VARPNT), y
iny
lda __FAC1+2
sta (VARPNT), y
#endif #endif
rts rts
cmd_let_assign_string_not_empty: cmd_let_assign_string_not_text_area:
// Check if the source and destination strings are the same (VARPNT should now point just after variable name)
lda VARPNT+0
cmp __FAC1+1
bne !+
iny
lda VARPNT+1
cmp __FAC1+2
bne !+
// If we are here, than both source and destination strings are the same - nothing more to be done
rts
!:
// Strings are not the same - check if the new one is located within a text area, between TXTTAB and VARTAB
// XXX
// Check if size of both equals and the old on is above FRETOP // Check if size of both equals and the old on is above FRETOP
+9 -9
View File
@@ -15,11 +15,10 @@
// - https://sites.google.com/site/h2obsession/CBM/basic/variable-format // - https://sites.google.com/site/h2obsession/CBM/basic/variable-format
// //
// Input: // Input:
// - DSCPNT+0, DSCPNT+1 - pointer to string descriptor, first pointed byte should contain desired length // - DSCPNT+1, DSCPNT+2 - pointer to string descriptor, first pointed byte should contain desired length
// //
// XXX test this routine // XXX test this routine
// XXX change DSCPNT to use standard descriptor format
varstr_alloc: varstr_alloc:
@@ -61,7 +60,7 @@ varstr_alloc_retry:
// Create the back-pointer to the string descriptor // Create the back-pointer to the string descriptor
ldy #$00 ldy #$00
lda DSCPNT+0 lda DSCPNT+1
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
ldx #<FRETOP ldx #<FRETOP
@@ -71,7 +70,7 @@ varstr_alloc_retry:
#endif #endif
iny iny
lda DSCPNT+1 lda DSCPNT+2
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
jsr poke_under_roms jsr poke_under_roms
@@ -84,12 +83,12 @@ varstr_alloc_retry:
dey // $01 -> $00 dey // $01 -> $00
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
ldx #<DSCPNT ldx #<DSCPNT+1
jsr peek_under_roms jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_DSCPNT jsr peek_under_roms_via_DSCPNT_PLUS_1
#else // CONFIG_MEMORY_MODEL_38K #else // CONFIG_MEMORY_MODEL_38K
lda (DSCPNT),y lda (DSCPNT+1),y
#endif #endif
jsr varstr_FRETOP_down_A jsr varstr_FRETOP_down_A
@@ -101,7 +100,7 @@ varstr_alloc_retry:
lda FRETOP+0 lda FRETOP+0
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
ldx #<DSCPNT ldx #<FRETOP
jsr poke_under_roms jsr poke_under_roms
#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
sta (FRETOP), y sta (FRETOP), y
@@ -111,9 +110,10 @@ varstr_alloc_retry:
lda FRETOP+1 lda FRETOP+1
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
ldx #<DSCPNT+1
jsr poke_under_roms jsr poke_under_roms
#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
sta (DSCPNT), y sta (DSCPNT+1), y
#endif #endif
// The end // The end
+3 -5
View File
@@ -6,15 +6,13 @@
// Helper routines for 'varstr_alloc' // Helper routines for 'varstr_alloc'
// //
// XXX change DSCPNT to use standard descriptor format varstr_FRETOP_down_A: // .A - bytes to lower FRETOP, uses DSCPNT+0
varstr_FRETOP_down_A: // .A - bytes to lower FRETOP, uses DSCPNT+2 sta DSCPNT+0
sta DSCPNT+2
sec sec
lda FRETOP+0 lda FRETOP+0
sbc DSCPNT+2 sbc DSCPNT+0
sta FRETOP+0 sta FRETOP+0
bcs !+ bcs !+
dec FRETOP+1 dec FRETOP+1
+33 -26
View File
@@ -6,14 +6,11 @@
// Releases back memory used by string // Releases back memory used by string
// //
// Input: // Input:
// - DSCPNT+0, DSCPNT+1 - pointer to string descriptor // - DSCPNT+1, DSCPNT+2 - pointer to string descriptor
// //
// XXX test this routine // XXX test this routine
// XXX check if this entry point is needed
// XXX handle strings located in program area
// XXX change DSCPNT to use standard descriptor format
varstr_free: varstr_free:
@@ -23,23 +20,23 @@ varstr_free:
ldy #$00 ldy #$00
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
ldx #<DSCPNT ldx #<DSCPNT+1
jsr peek_under_roms jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_DSCPNT jsr peek_under_roms_via_DSCPNT_PLUS_1
#else // CONFIG_MEMORY_MODEL_38K #else // CONFIG_MEMORY_MODEL_38K
lda (DSCPNT),y lda (DSCPNT+1),y
#endif #endif
sta DSCPNT+2 // length of the string sta DSCPNT+0 // length of the string
iny iny
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
jsr peek_under_roms jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_DSCPNT jsr peek_under_roms_via_DSCPNT_PLUS_1
#else // CONFIG_MEMORY_MODEL_38K #else // CONFIG_MEMORY_MODEL_38K
lda (DSCPNT),y lda (DSCPNT+1),y
#endif #endif
pha pha
@@ -48,20 +45,30 @@ varstr_free:
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
jsr peek_under_roms jsr peek_under_roms
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
jsr peek_under_roms_via_DSCPNT jsr peek_under_roms_via_DSCPNT_PLUS_1
#else // CONFIG_MEMORY_MODEL_38K #else // CONFIG_MEMORY_MODEL_38K
lda (DSCPNT),y lda (DSCPNT+1),y
#endif #endif
sta DSCPNT+1 sta DSCPNT+2
pla pla
sta DSCPNT+0 sta DSCPNT+1
// FALLTROUGH
varstr_free_DSCPNT_set:
// consider moving size check (DSCPNT+0) here
// XXX
// XXX check if string is located above FRETOP, handle case if it is not
// XXX
// Quick check - is the string the lowest one? // Quick check - is the string the lowest one?
cmp FRETOP+0 cmp FRETOP+0
bne varstr_free_inside bne varstr_free_inside
lda DSCPNT+1 lda DSCPNT+2
cmp FRETOP+1 cmp FRETOP+1
bne varstr_free_inside bne varstr_free_inside
@@ -73,7 +80,7 @@ varstr_free:
#if !HAS_OPCODES_65CE02 #if !HAS_OPCODES_65CE02
lda #$02 // free the back-pointer lda #$02 // free the back-pointer
sta DSCPNT+2 sta DSCPNT+0
jmp varstr_FRETOP_up jmp varstr_FRETOP_up
#else // HAS_OPCODES_65CE02 #else // HAS_OPCODES_65CE02
@@ -90,7 +97,7 @@ varstr_free_inside:
// This is not the lowest string; mark it as free // This is not the lowest string; mark it as free
// First preserve the string size, it will make it easier for the garbage collector // First preserve the string size, it will make it easier for the garbage collector
lda DSCPNT+2 lda DSCPNT+0
tay tay
dey dey
@@ -101,14 +108,14 @@ varstr_free_inside:
sta (FRETOP), y sta (FRETOP), y
#endif #endif
// Now increase DSCPNT+0/+1 to point to the back-pointer // Now increase DSCPNT+1/+2 to point to the back-pointer
clc clc
lda DSCPNT+0 lda DSCPNT+1
adc DSCPNT+2 adc DSCPNT+0
sta DSCPNT+0 sta DSCPNT+1
bcc !+ bcc !+
inc DSCPNT+1 inc DSCPNT+2
!: !:
// Fill the back-pointer with 0 // Fill the back-pointer with 0
@@ -116,10 +123,10 @@ varstr_free_inside:
ldy #$00 ldy #$00
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
ldx #<DSCPNT ldx #<DSCPNT+1
jsr poke_under_roms jsr poke_under_roms
#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
sta (DSCPNT), y sta (DSCPNT+1), y
#endif #endif
iny // $00 -> $01 iny // $00 -> $01
@@ -127,6 +134,6 @@ varstr_free_inside:
#if CONFIG_MEMORY_MODEL_60K #if CONFIG_MEMORY_MODEL_60K
jmp poke_under_roms jmp poke_under_roms
#else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K #else // CONFIG_MEMORY_MODEL_38K || CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
sta (DSCPNT), y sta (DSCPNT+1), y
rts rts
#endif #endif
+2 -2
View File
@@ -8,11 +8,11 @@
// XXX change DSCPNT to use standard descriptor format // XXX change DSCPNT to use standard descriptor format
varstr_FRETOP_up: // DSCPNT+2 - bytes to increment FRETO, uses DSCPNT+2 varstr_FRETOP_up: // DSCPNT+0 - bytes to increment FRETO
clc clc
lda FRETOP+0 lda FRETOP+0
adc DSCPNT+2 adc DSCPNT+0
sta FRETOP+0 sta FRETOP+0
bcc !+ bcc !+
inc FRETOP+1 inc FRETOP+1
+6 -7
View File
@@ -4,7 +4,6 @@
// XXX test this routine // XXX test this routine
// XXX change DSCPNT to use standard descriptor format
varstr_garbage_collect: varstr_garbage_collect:
@@ -323,13 +322,13 @@ varstr_garbage_collect_unused:
// XXX move these routines to separate files // XXX move these routines to separate files
varstr_TXTPTR_down_A: // .A - bytes to decrease TXTPTR, uses DSCPNT+2 varstr_TXTPTR_down_A: // .A - bytes to decrease TXTPTR, uses DSCPNT+0
sta DSCPNT+2 sta DSCPNT+0
sec sec
lda TXTPTR+0 lda TXTPTR+0
sbc DSCPNT+2 sbc DSCPNT+0
sta TXTPTR+0 sta TXTPTR+0
bcs !+ bcs !+
dec TXTPTR+1 dec TXTPTR+1
@@ -337,13 +336,13 @@ varstr_TXTPTR_down_A: // .A - bytes to decrease TXTPTR, uses DS
rts rts
varstr_INDEX_up_A: // .A - bytes to increase TXTPTR, uses DSCPNT+2 varstr_INDEX_up_A: // .A - bytes to increase TXTPTR, uses DSCPNT+0
sta DSCPNT+2 sta DSCPNT+0
clc clc
lda INDEX+0 lda INDEX+0
adc DSCPNT+2 adc DSCPNT+0
sta INDEX+0 sta INDEX+0
bcc !+ bcc !+
dec INDEX+1 dec INDEX+1
@@ -68,7 +68,7 @@ peek_under_roms_via_VARPNT:
jmp peek_under_roms_finalize jmp peek_under_roms_finalize
#endif #endif
peek_under_roms_via_DSCPNT: peek_under_roms_via_DSCPNT_PLUS_1:
// Unmap BASIC lower ROM // Unmap BASIC lower ROM
@@ -77,7 +77,7 @@ peek_under_roms_via_DSCPNT:
// Retrieve value from under ROMs // Retrieve value from under ROMs
lda (DSCPNT), y lda (DSCPNT+1), y
#if HAS_OPCODES_65C02 #if HAS_OPCODES_65C02
bra peek_under_roms_finalize bra peek_under_roms_finalize