Handling string variables (left-MID$ in Wimbasic)

Basic and Machine Language

Moderator: Moderators

Post Reply
wimoos
Vic 20 Afficionado
Posts: 350
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Handling string variables (left-MID$ in Wimbasic)

Post by wimoos »

Hello all,

While implementing the left-MID$ function in Wimbasic, I ran into CBM Basic's behaviour when dealing with string constants.
When a READ A$ or a A$="SOMESTRING" is performed, the A$ variable actually points to the program text. Only when a new string is built using GET A$, A$=STR$(X) or A$="SOME"+"STRING" memory is allocated from the top of Basic RAM and A$ points there.

My current implementation of the left-MID$ function performs the character substitution in-place and it convienently does nothing when A$ is in the program text. To come around this, A$ needs to be built at runtime.

Yet, I want the left-MID$ to work without this workaround, but I have only 15 bytes to spare for the code. How to fix this without inducing unnecessary garbage collections ?

Regards,

Wim.

LMIDSTR JSR $0073 ; READ TOKEN
JSR $CEFA ; CHECK OPEN PARENTHESIS
JSR $D08B ; READ VARNAME, RETURN POINTER
JSR $CD8F ; CHECK DATATYPE FOR STRING
STA $83 ; SAVE VARPTR
STY $84 ; SAVE VARPTR
JSR $CEFD ; CHECK COMMA
JSR $D79E ; READ BYTE
TXA
BEQ LA803
DEX
LDY #0
TXA
CMP ($83),Y
BCS LA803 ; START >= LENGTH OF TRGT$
STX $86 ; SAVE START
LDX #$FF
LDA ($7A),Y
CMP #$2C
BNE LNOLENGTH
JSR $D79B ; READ BYTE
LNOLENGTH STX $85 ; SAVE LENGTH
JSR $CEF7 ; CHECK CLOSED PARENTHESIS
LDA #$B2 ; TOKENIZED '='
JSR $CEFF ; CHECK EQUAL SIGN
JSR LGETSTR
STX $C1
STY $C2
CMP $85 ; LENGTH OF STRING < SPECIFICIED LENGTH
BCS LSHRTR1
STA $85
LSHRTR1 LDY #0
SEC
LDA ($83),Y
SBC $86
CMP $85 ; REMAINING LENGTH < DETERMINED LENGTH
BCS LSHRTR2
STA $85
LSHRTR2 LDA $85 ; DO NOTHING WHEN NOTHING TO DO
BEQ LMIDRET
INY
CLC
LDA ($83),Y ; ADD START TO TARGETBASE
ADC $86
TAX
INY
LDA ($83),Y
ADC #0
STA $B6
CPX $2D ; AND CHECK AGAINST END-OF-PROGRAM
SBC $2E
BCC LMIDRET ; DO NOTHING IF IT IS READONLY
STX $B5
LDY $85
LNXTCHR DEY
LDA ($C1),Y
STA ($B5),Y
TYA
BNE LNXTCHR
LMIDRET RTS


VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
User avatar
Mike
Herr VC
Posts: 4845
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

After getting the string descriptor, and the check for a string literal in the BASIC program confirms positive, you'd call the tail of the STR$() routine at $D47D, with A being the string length. This can induce a garbage-collection, but only if it's necessary. This routine exits with $62 pointing to the newly allocated string space, and $61 containing the string length again.

You'd then first copy the string literal to the bottom of the string heap:

Code: Select all

 JSR $D47D
 LDY #0
.loop
 LDA (zz),Y
 STA ($62),Y
 INY
 CPY $61
 BNE loop
(where zz contains a pointer of your original string), and then you'd made the pointer in the string descriptor point to the newly allocated string.

And then proceed with the rest of the routine.

You might be able to shave some bytes, when you then continue to use ($62) as pointer to the target string, and simply make a copy of the string descriptor pointer to ($62) in case the string didn't need to be copied to high RAM.
wimoos
Vic 20 Afficionado
Posts: 350
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Post by wimoos »

Thanks Mike,

I squeezed it in. Had to do some more space saving tricks, but
nonetheless: it's in there!

Download Wimbasic from http://home.kpn.nl/oost4231/wimbasic.zip

Regards,

Wim.
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
Post Reply