Useful Snippets

Porting Richard Russell's BBC BASIC (Z80) to the TI-83+ and TI-84+ series calculators.

Moderator: benryves

Post Reply
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Useful Snippets

Post by benryves »

This thread is (hopefully) going to contain useful snippets of BBC BASIC code. At the moment they'll appear cryptic as there's nothing to compare them to, but hopefully that will change when the BBC BASIC test version gets released.

I'll start the ball rolling with a pair of functions to change the case of strings as BBC BASIC does not have the UCASE$() or LCASE$() functions you may be familiar with from other dialects of BASIC.

String case conversion

Code: Select all

DIM CS 67:FOR Q%=0TO1:P%=CS
  [OPT Q%*2
  LD A,(IX+0):OR A:RET Z:LD C,A
  .CS_LP LD L,(IX+2):LD H,(IX+3):LD A,(IX+1):CP 128:JR NZ,CS_NFIX:LD B,0:LD E,L:LD D,H
  .CS_LEN LD A,(DE):CP 13:JR Z,CS_GO:INC B:INC DE:JR CS_LEN
  .CS_NFIX LD B,(HL):INC HL:INC HL:LD E,(HL):INC HL:LD D,(HL):EX DE,HL:CP 129:JR NZ,CS_SKIP
  .CS_GO LD A,(HL):.CS_MIN CP 97:JR C,CS_NX:.CS_MAX CP 123:JR NC,CS_NX:.CS_OFF SUB 32:LD (HL),A
  .CS_NX INC HL:DJNZ CS_GO
  .CS_SKIP INC IX:INC IX:INC IX:DEC C:RET Z:JR CS_LP:]
NEXT
DEFFN_UCASE$(s$)CS_MIN?1=97:CS_MAX?1=123:CS_OFF?1=32:CALLCS,s$:=s$
DEFFN_LCASE$(s$)CS_MIN?1=65:CS_MAX?1=91:CS_OFF?1=-32:CALLCS,s$:=s$
Usage
The easiest way to use the code is to call either the FN_UCASE$() or FN_LCASE$() function.

Code: Select all

PRINT FN_UCASE$("Hello, World!") : REM Prints "HELLO, WORLD!"
PRINT FN_LCASE$("BBC BASIC Z80") : REM Prints "bbc basic z80"
You can convert multiple strings at a time by calling the assembly routine CS directly. Both movable and fixed strings are supported. The strings passed to the routine are overwritten.

Code: Select all

A$="The"
B$="Quick"
DIM C 100:$C="Brown"
DIM D 100:$D="Fox"
CALL CS,A$,B$,$C,$D
The exact operation carried out (converting to uppercase or lowercase) depends on whether FN_UCASE$() or FN_LCASE$() was most recently called. To set the conversion call either of these BASIC functions first:

Code: Select all

A$=FN_LCASE$(A$):CALL CS,B$,$C,$D
Remarks
You must not modify the variables CS, CS_MIN, CS_MAX or CS_OFF. Doing so is likely to crash the calculator.
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Re: Useful Snippets

Post by benryves »

Enumerating Filenames
You can enumerate filenames using the OSGBPB call.

Code: Select all

10 osgbpb=&FFD1:DIM osgbpb_con 12:DIM osgbpb_fname 13
20 DEFPROC_ResetGetFile:osgbpb_con!9=0:ENDPROC
30 DEFFN_GetNextFile LOCAL L%,H%,A%:L%=osgbpb_con:H%=osgbpb_con DIV256:A%=8:osgbpb_con!1=osgbpb_fname:osgbpb_con!5=1:CALLosgbpb:osgbpb_fname?(1+?osgbpb_fname)=13:IF osgbpb_con!5:=""ELSE=$(osgbpb_fname+1)
Usage
Before enumerating filenames you must call PROC_ResetGetFile to start from the first file. You can then call FN_GetNextFile in a loop to retrieve filenames - it returns the next filename if available, otherwise it returns the empty string.

Code: Select all

40 PROC_ResetGetFile
50 REPEAT
60   name$=FN_GetNextFile
70   IF name$<>"" PRINT name$
80 UNTIL name$=""
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Re: Useful Snippets

Post by benryves »

Finding the upper bound of an array

Once you have dimensioned an array you may well wish to retrieve its upper bound - that is, the highest index you can access in that array. In some dialects of BASIC this action is performed by the UBOUND function. In BBC BASIC you need to add some assembly to your program:

Code: Select all

DIM UBOUND 50:P%=UBOUND
[OPT 0
LD A,(IX+0):CP 2:RET NZ
LD A,(IX+4):CP 4:RET C:CP 6:RET NC
LD L,(IX+2):LD H,(IX+3)
DEC HL:LD D,(HL):DEC HL:LD E,(HL):DEC DE
LD L,(IX+5):LD H,(IX+6)
LD (HL),E:INC HL:LD (HL),D:INC HL:LD (HL),0:INC HL:LD (HL),0
LD A,(IX+4):CP 4:RET Z:INC HL:LD (HL),0:RET:]
Usage

As you cannot pass arrays into BASIC functions you must CALL the routine, passing it the first element of the array you wish to dimension and a label to receive the upper bound.

Code: Select all

DIM some_array$(123)
CALL UBOUND,some_array$(0),array_size
PRINT "some_array$(";array_size;")"
The destination variable may be a real or an integer variable.
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Re: Useful Snippets

Post by benryves »

Getting or setting the LCD contrast

Here's a simple one for special effects. Results are returned using the TI-OS contrast level (0 is the minimum, 10 the maximum).
As the contrast setter is a multi-line procedure you will need to put these routines at the end of your program, preferably after an END statement.

Code: Select all

DEF FN_contrast=?&8447/4
DEF PROC_contrast(c)c=INT(c*4)
IF c<0 c=0
IF c>39 c=39
?&8447=c:CALL&B:PUT&10,c+&D8:ENDPROC
Usage
Use FN_contrast to get the contrast level and PROC_contrast() to set it, like this:

Code: Select all

PRINT "Contrast level is ";FN_contrast
PROC_contrast(6.25) : REM Set contrast to 6.25
Post Reply