BASIC: New Commands

If you have feature requests, this is the place to post them. Please note your idea may already be something we have already discussed and decided against, or something we are working on privately, and we cannot be held responsible for any similarities in such instance. Whilst we cannot respond to every suggestion, your idea will be read and responded to where possible. Thank you for your input!
BruceMcF
Posts: 1336
Joined: Fri Jul 03, 2020 4:27 am

BASIC: New Commands

Post by BruceMcF »



On 8/28/2020 at 7:58 PM, SerErris said:




I agree, I do not see any reason for else.



You do not need to do anything it works out of the box like that:



So we even have a ELSE with multiple lines already in it. Yes it is a little bit different to write but it is not an issue and easy to understand after you  worked with it. 



Really, all Control Structures except counted loops are semantic sugar for GOTO and IF <condition> THEN GOTO. Where ELSE is needed is not in the ROM Basic, but as a reserved and reusable structured label in the EditorBasic, which allows working with labels and the editor basic sorts out line number behind the scenes.

TASK5: IF X5>0

THEN: DOTHIS

  DOMORE

  DOMORE

ELSE: DOTHAT

  DOMORE

  DOMORE

ENDIF

Becomes:

450 IF X5>0 THEN GOTO 460

455 GOTO 490

460 DOTHIS :

470 DOMORE

480 DOMORE:GOTO 520

490 DOTHAT

500 DOMORE

510 DOMORE

520 ...

Commodore 128 Basic V7 ELSE is just a modest space saver:

450 IF X>0 THEN GOTO 460:ELSE GOTO 490

460 DOTHIS

470 DOMORE

480 DOMORE:GOTO 520

490 DOTHAT

500 DOMORE

510 DOMORE

520 ...



But I am confident that all of the classic structured program structures can be done with IF/THEN and GOTO, because I am in the middle of implementing a Forth ... and while Forth has all of the classic structured programming structures, the underlying primitives are just BRANCH and ?BRANCH. IF/THEN/ELSE/ENDIF, REPEAT/UNTIL and BEGIN/WHILE/AGAIN are all straightforward to implement with GOTO and IF/THEN alone.

However, unless ELSE is implemented for speed, with the content after the ELSE token linked into the line number list, then the second is slower than the first, but I presume that the actual V7 implementation does it the slow way.

Starsickle
Posts: 81
Joined: Mon Aug 31, 2020 12:00 am

BASIC: New Commands

Post by Starsickle »


Having recently gotten into SmileBASIC4, I've found they've added quite a few things that I'm trying to recreate myself using the commands currently available. I did not know that there were Kernal level functions that are otherwise hidden (PLOT, for example.)

Kernal functions can be found in this reference: https://www.c64-wiki.com/wiki/Kernal

For sure - anything on that list is desirable in a more useful command (I've noticed the issues list. Keep it growing!) I'm still new and finding my way around (as well as catching up with status of ongoing development), but I'm definitely trying to move as much BASIC as I can from SB4 to equivalent bits using the VERA-based X16 and C64 BASIC.

For inspiration and comparison, here's a link to the SmileBASIC reference. http://smilebasic.com/en/reference/

Example: I've noticed SB4's LOCATE is similar to C64's PLOT, but PLOT is accessed via SYS $FFF0, and with some preparation.

While I can understand obvious technological and design differences between the platforms that run these two - I'm of the mind that anything that could make anything easier and more direct is worth doing at some point (priorities upheld, ofc).

SerErris
Posts: 172
Joined: Sat Aug 08, 2020 9:18 am

BASIC: New Commands

Post by SerErris »


Maybe you want to have a look at this: https://github.com/commanderx16/x16-docs/blob/master/Commander X16 Programmer's Reference Guide.md

X16 has already a much broader BASIC dialect than C64. Some borrowed from new Commodores ..

For you .. PSET and LINE are interesting in the context above, but there are others like COLOR or SCREEN ... 

BruceMcF
Posts: 1336
Joined: Fri Jul 03, 2020 4:27 am

BASIC: New Commands

Post by BruceMcF »



On 9/3/2020 at 12:24 AM, SerErris said:




Maybe you want to have a look at this: https://github.com/commanderx16/x16-docs/blob/master/Commander X16 Programmer's Reference Guide.md



X16 has already a much broader BASIC dialect than C64. Some borrowed from new Commodores ..



For you .. PSET and LINE are interesting in the context above, but there are others like COLOR or SCREEN ... 



This feature request is about the text display mode, not about the graphics screen. The graphics commands export GEOS BIOS functions to Basic, LOCATE would export the ALREADY EXISTING Kernel PLOT call to Basic.

I don't mean to rain on your RTFM parade, but RTFR is also a thing.

pastblast
Posts: 20
Joined: Tue Sep 01, 2020 8:00 pm

BASIC: New Commands

Post by pastblast »


Back when I used to program an 8-bit home machine, I would use the following for MOD: a mod b === a - int(a/b) * b

Example:

10 A = 111

20 B = 4

30 M = A - INT(A/B) * B

40 PRINT M

This will print a value of 3.

SlithyMatt
Posts: 913
Joined: Tue Apr 28, 2020 2:45 am

BASIC: New Commands

Post by SlithyMatt »



18 minutes ago, pastblast said:




Back when I used to program an 8-bit home machine, I would use the following for MOD: a mod b === a - int(a/b) * b



Example:



10 A = 111



20 B = 4



30 M = A - INT(A/B) * B



40 PRINT M



This will print a value of 3.



If you're modulo-ing by a power of 2, it can be done much faster with an AND:

10 A = 111

20 REM MODULO 4 IS JUST THE LOWEST TWO BITS

30 M = A AND 3

40 PRINT M

pastblast
Posts: 20
Joined: Tue Sep 01, 2020 8:00 pm

BASIC: New Commands

Post by pastblast »



18 hours ago, SlithyMatt said:




If you're modulo-ing by a power of 2, it can be done much faster with an AND:



10 A = 111



20 REM MODULO 4 IS JUST THE LOWEST TWO BITS



30 M = A AND 3



40 PRINT M



Absolutely. I was just showing the generic way to do MOD when not having the operator available. I totally agree to using AND whenever possible. Thanks for highlighting that.

I have always enjoyed doing bit-fiddling stuff, so I truly get into the AND, OR, NOT, XOR, etc. side of things. I once wrote the entire windowing system for a touch-screen based printer. After writing all of the window operations and window message handling in C++, including per-pixel transparency of overlapping windows, I decided that it was just too slow. So I rewrote the "blitter" operations in ARM assembly language, and (WOW) what a difference in speed!

kelli217
Posts: 535
Joined: Sun Jul 05, 2020 11:27 pm

BASIC: New Commands

Post by kelli217 »


This is not 'advanced' coding I'm going to be showing here. I am only just getting back into things, so I'm working at a 'mediocre amateur' level. Consider this less as a tutorial and more as just sort of thinking out loud.

I appreciate the arithmetic workaround for MOD; I've used it in the past. I like the logic-based workaround for MOD of a power of 2; that one hadn't occurred to me.

I guess the LOCATE could be worked around too. You could do it in BASIC using the screen editor cursor movement characters — which I'll show with {curly brackets} (a.k.a. braces) in the old Gazette style of notating special characters — and the TAB() function.

100 R=15:C=20:GOSUB 1000

110 PRINT"HELLO WORLD!"

999 END

1000 REM SCREEN POSITION (R)OW AND (C)OL

1010 ?"{HOME}": REM START FROM TOP LEFT OF SCREEN

1020 FOR I=0TOR:IF I THEN PRINT"{DOWN}";

1030 NEXT I

1040 PRINT TAB(C);

1050 RETURN

But as BruceMcF points out, you can call PLOT from the KERNAL routines to either set or get the current cursor position on the screen. However, while documentation says to put your cursor column in the X register and row in the Y register, actual experimentation with r38 shows that it's the opposite. So when using SYS to call it, location 781 ($30D) for X is row and 782 ($30E) for Y is column. You also have to clear the carry bit (bit 0) of the status register (SR), in location 783 ($30F). Using SYS pushes the registers onto the stack, including SR, before loading a new one from those memory locations, and pulls it back off after storing the routine's output in that same memory, so the system state isn't trashed by being relatively clumsy with SR.



100 R=15:C=20:GOSUB 1000

110 PRINT"HELLO WORLD!"

999 END

1000 REM SCREEN POSITION - REQUIRES (R)OW AND (C)OL

1010 POKE 781,R:POKE 782,C:POKE 783,0;:REM 783 = SR

1020 SYS $FFF0

1030 RETURN

Besides being faster, and using less BASIC code, you can also find out where the cursor is, by setting the carry bit of SR when you call the PLOT routine. The return values will be in the memory locations.

100 PRINT"AFTER PRINTING THIS, THE CURSOR POSITION IS:":GOSUB 1000

110 PRINT"ROW:";R,"COL";C

999 END

1000 REM GET POSITION - RETURNS (R)OW AND (C)OL

1010 POKE 783,1:SYS $FFF0

1020 R=PEEK(781):C=PEEK(782)

1030 RETURN

To me, not having an explicit ELSE keyword just means that there's a little bit of spaghetti coding and reversing the order of the code blocks:

100 IF T=1 THEN 150

110 REM TEST IS FALSE (ELSE)

120 ...

130 ...

140 ... : GOTO 200

150 REM TEST IS TRUE (THEN)

160 ...

170 ...

180 ...

190 ...

200 REM CODE EXECUTION PATHS REJOIN HERE (ENDIF)

There's also the inline example for simple code, with no spaghetti, but there are potentially two assignment operations, so it's not particularly efficient:

100 A=16:IF T=1 THEN A=32

Again, the 'test is false' code comes first, and it's only overridden if the test is true. This is of limited utility; it only works if the true and false cases affect the same variables. Otherwise, use the code blocks as in the first example.

Post Reply