more work on string support
This commit is contained in:
1 parent
127b71f67f
commit
159acfba2f
7 files changed
+133
-73
No files matched your search
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user