Page 2 of 2
BASIC: New Commands
Posted: Sat Aug 29, 2020 3:21 pm
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.
BASIC: New Commands
Posted: Wed Sep 02, 2020 12:18 am
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).
BASIC: New Commands
Posted: Wed Sep 02, 2020 4:24 pm
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 ...
BASIC: New Commands
Posted: Thu Sep 03, 2020 5:20 pm
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.
BASIC: New Commands
Posted: Thu Sep 24, 2020 6:30 pm
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.
BASIC: New Commands
Posted: Thu Sep 24, 2020 6:52 pm
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
BASIC: New Commands
Posted: Fri Sep 25, 2020 1:00 pm
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!
BASIC: New Commands
Posted: Mon Jan 04, 2021 11:14 am
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.