[Coco] Wierd bug---is it my code, or BASIC?

Sean Conner sean at conman.org
Fri Nov 14 18:14:18 EST 2025


  I've been playing around with extending BASIC, this time by adding new
commands and functions to the user command interpretation table at $013E.  I
was able to add several new commands and functions, but one of my functions
isn't quite working as intended, and I don't know if it's my code, or BASIC.

  Here's the function in question:

FP0		equ	$0050
CHKSTR		equ	$B146
RSVPSTR		equ	$B50F
GIVSTR		equ	$B54C

id              jsr     CHKSTR          ; check we have a string
                ldy     FP0+2           ; get string descriptor
                ldb     ,y              ; get length
                jsr     RSVPSTR         ; reserve some new space
                ldy     2,y             ; point to actual string
                tstb                    ; do we have any characters?
                beq     iddone          ; if not, skip
idcopy          lda     ,y+             ; copy the string
                sta     ,x+
                decb
                bne     idcopy
iddone          jmp     GIVSTR          ; return new string to BASIC

  When the code is loaded, and I do:

	FOR I=1 TO 100:PRINT I,ID$("ID"):NEXT

I get:

	1	ID
	2	ID
	3	ID
	4	ID
	5	ID
	6	ID
	7	ID
	8
	?ST ERROR

But yet, if I do:

	I$="ID":FOR I=1 TO 100:PRINT I,ID$(I$):NEXT

it runs fine (I'll spare you the 100 lines of output).  As far as I can
tell, this should work for both cases, so I'm not sure if it's my code, or
BASIC.

  Attached is the minimum version that exhibits the error (and the code
should assemble fine using any assembler---I hope).  Also is the BASIC
program to poke it into memory.  It assumes a 32K DECB system.  When the
BASIC code is loaded:

	RUN
	EXEC&H7000

  To test if the code is properly loaded, you can type:

	XYZZY

which should print out "NOTHING HAPPENS".  I hope someone can help.

  -spc

-------------- next part --------------
; LGPL3+ Copyright 2025 by Sean Conner
; MVP of buggy behavior for DECB 32K
; To install, load program, then
; 	RUN
; 	EXEC&H7000
; To test install:
;	XYZZY
; should print "NOTHING HAPPENS"
; To test code:
;	FOR I=1 TO 100:?I,ID$("ID"):NEXT:' THIS FAILS
;	I$="ID":FOR I=1 TO 100:?I,ID$(I$):NEXT:' THIS WORKS

FP0		equ	$0050
CHKSTR		equ	$B146	; check FP0 is string
RSVPSTR		equ	$B50F	; reserve string space
GIVSTR		equ	$B54C	; return string to BASIC
SYNTAX		equ	$B277	; signal SN error
RUNTOKEN	equ	$ADD4	; run code for token
PUTSTR		equ	$B99F	; display string descriptor
PEVALP		equ	$B262	; '(' expr '}'

		org	$7000

initialize	ldx	#initdata	; data for user BASIC table
		ldy	#$013E		; pointer to user BASIC table
initcopy	ldd	,x++		; copy data
		std	,y++
		cmpx	#initdend
		bne	initcopy
		rts			; return to BASIC

initdata	fcb	1
		fdb	cmdtext
		fdb	cmdhandler
		fcb	1
		fdb	fntext
		fdb	fnhandler
		fcb	0
		fdb	0
		fdb	SYNTAX
		fcb	0
		fdb	0
		fdb	SYNTAX
initdend	equ	*

cmdtext		fcc	'XYZZ'
		fcb	'Y'+$80
cmddisp		fdb	xyzzy

cmdhandler	cmpa	#$E2		; xyzzy token
		lbhi	SYNTAX		; if higher, error
		ldx	#cmddisp	; get jmp table
		suba	#$E2		; adjust token to offset
		jmp	RUNTOKEN	; jump through dispatch table

xyzzy		ldd	#xmsg		; point to string descriptor
		std	FP0+2		; store it
		jmp	PUTSTR		; print it

xmsg		fcb	15		; length of string
		fcb	0
		fdb	xmsgtext	; ptr to string contents
		fcb	0
xmsgtext	fcc	'NOTHING HAPPENS'

fntext		fcc	'ID'
		fcb	'$'+$80
fndisp		fdb	id

fnhandler	cmpb	#($A8-$80)*2	; ID$ token
		lbhi	SYNTAX		; if higher, error
		subb	#($A8-$80)*2	; adjust token to offset
		pshs	b		; save
		jsr	PEVALP		; parse '(' expr ')'
		puls	b		; restore offset
		ldx	#fndisp		; get jmp table
		jmp	[b,x]		; jump to routine

id		jsr	CHKSTR		; check we have a string
		ldy	FP0+2		; get string descriptor
		ldb	,y		; get length
		jsr	RSVPSTR		; reserve some new space
		ldy	2,y		; point to actual string
		tstb			; do we have any characters?
		beq	iddone		; if not, skip
idcopy		lda	,y+		; copy the string
		sta	,x+
		decb
		bne	idcopy
iddone		jmp	GIVSTR		; return new string to BASIC

		end	initialize
-------------- next part --------------
10 DATA142,112,17,16,142,1,62,236,129,237,161,140,112,37,38,247,57,1,112,37,112,44,1,112,86,112,91,0,0,0,178,119,0,0,0,178,119,88,89,90,90,217,112,58,129,226,16,34,66,69,142,112,42,128,226,126,173,212,204,112,66,221,82,126,185,159,15,0,112,71,0,78
20 DATA79,84,72,73,78,71,32,72,65,80,80,69,78,83,73,68,164,112,111,193,80,16,34,66,22,192,80,52,4,189,178,98,53,4,142,112,89,110,149,189,177,70,16,158,82,230,164,189,181,15,16,174,34,93,39,7,166,160,167,128,90,38,249,126,181,76
30 CLEAR200,28671:FORA=28672TO28809:READB:POKEA,B:NEXT:


More information about the Coco mailing list