PDA

View Full Version : S-Basic



Dr_Acula
January 13th, 2009, 11:42 PM
I was wondering if a kind soul might have a copy or link to the manuals that came with s-basic?

I've got the program and some demo files and the help file which is very handy to get started. Programs certainly compile quickly on the N8VEM (and faster than MBASIC). No BRUN is needed. S-Basic seems more like modern languages including .net. It has no line numbers and variables are local and are declared at the beginning of each procedure. A big source of errors in MBASIC is using a variable name twice. There are no GOTOs!

Maybe someone has a suggestion for other versions of basic that didn't use line numbers and had local variables etc?

comment
mem.bas -- display CP/M memory map
written for SBASIC compiler
Addresses for BDOS and CCP are calculated from BIOS base
and will reflect actual rather than apparent locations.
TPA calculation will therefore correctly reflect reduction
in available memory that occurs when a resident system
extension (RSX) is installed.
end

var msize, tpa = real
var rsx_installed = string : 5

print "Start of BIOS : "; hex$(peek(2) * 100H)
print "Start of BDOS : "; hex$((peek(2) - 0EH) * 100H + peek(6))
print "Start of CCP : "; hex$((peek(2) - 16H) * 100H)
print

msize = 256 * peek(2) rem BIOS base
msize = msize - 18944 rem BIOS address in 20K system
msize = (msize / 1024) + 20 rem adjust and convert to K

rem Calculate available TPA in K based on apparent BDOS address
tpa = 256 * (peek(7) - 1) / 1024

print "CP/M size :"; msize; "K"
print "Available TPA :"; tpa; "K"

rem check whether actual and apparent BDOS entries differ
if peek(2) - 0EH = peek(7) then
rsx_installed = "No"
else
rsx_installed = "Yes"

print "RSX installed : "; rsx_installed

end

Terry Yager
January 14th, 2009, 12:17 AM
Gots the manual, but no copier/scanner. I can send it, but NZ is a long way away. Lemme know if nothing else comes up. If you have any immediate questions, mebbe I can look 'em up? Wait, lemme guess...command line parameters? It's in there.

S-BASIC is a pretty slick compiler, but I never did grok the language (any more than any other).

--T

Dr_Acula
January 14th, 2009, 01:55 AM
Many thanks for the quick response. Will see over the next few days if any links/posts come through. If not, one way round the problem of scanning etc taking time would be to try things and I'm sure 99% of things will work fine but if I get stuck maybe (if it is ok with you) just ask a specific question here?

Re postage to NZ, I'm in Australia and I'm sure all the New Zealanders will be having a quiet chuckle. NZ has two islands - the North and South islands, and another they refer to as the West island, which is Australia. A bit like Hawaii referring to North America as the East island.

tezza
January 14th, 2009, 09:13 AM
Re postage to NZ, I'm in Australia and I'm sure all the New Zealanders will be having a quiet chuckle.

And in fact I did, but then...Terry is Terry. Musta been into that home brew again :)

Tez

Terry Yager
January 14th, 2009, 09:32 PM
Tez told me that Oz is The Big Island...

--T

Dr_Acula
January 16th, 2009, 04:46 AM
Sbasic is an amazing language. You can add functions and procedures and these become new keywords in the language. So it is infinitely expandable.

But I need to make it *easy* to develop code. Attached is a screenshot of a vb.net terminal program with an early sbasic Integrated Development Environment. The top panel is the terminal running a N8VEM via a serial port (but it could be any CP/M computer). The lower panel is the sbasic source code. Just for fun I added code to add the colors so it looks like more modern programs with comments in green etc. Also, one would want a library of useful procedures, so I've added them on a drop down menu on the right. Just a bunch of little text files, but you can drop them into the program as needed. Much easier to follow than mysterious #include statements where you can't see what the code actually does.

The panel is a richtextbox so you can copy/paste/edit easily as well (^V and ^C from wordstar still work in vb.net!)

Then click on Compile and it runs xmodem on the N8VEM and then sends the .bas file, and then runs sbasic to compile it. The end of a compile is seen in the top panel. This takes about 20 seconds on a 4Mhz machine.

So - one click compile. Easy adding of code. No need to flip back and forth between text editor and compiler. Ability to easily add those little useful functions from the Basic Stamp and Picaxe - eg Serin and LCD display routines.

One could extend this to work for C or assembler too.

I gather you got sbasic when you bought a kaypro - is that right? If so, I can see why kaypro owners are so attached to their machines. So far it all has worked as expected and this is the most enjoyable language I have ever programmed in. Well structured like .net, but easier to learn.

Down the track if the compile times get too long I might see if I can automatically telnet to the Altair SIMH program which simulates a 200Mhz machine. Compiles are under a second on the simulator.

Just a general question - do people use their vintage machines for games, or for coding, or for other uses?

Terry Yager
January 16th, 2009, 07:47 AM
Just a quick note, another member, local to me, has kindly offered to scan the S-Basic manual, so as soon as I send it out it should be available shortly.

--T

tezza
January 16th, 2009, 09:51 AM
Just a quick note, another member, local to me, has kindly offered to scan the S-Basic manual, so as soon as I send it out it should be available shortly.

--T

Cool, I'll be interested in this. I notice my Kaypro II CP/M disk has S-BASIC on it. I'd like to explore it a little.

Tez

Dr_Acula
January 19th, 2009, 03:42 PM
Adding little library functions at the moment. eg output a string to a serial port:

procedure serout(outport=byte; baud=real; outstring=string)
var b=real
rem set port 0 to 3 for mini N8VEM default=0
out 96,outport
rem set baud rate
b=115200/baud
out 107,128 rem set dlab flag
out 104,b rem set baud rate
out 105,0
out 107,3 rem 8 data bits 1 stop bit
print outstring;
end
rem *** main routine ***
serout 0,38400,"Test serout"
end


And sbasic can interface with machine code. One little thing I haven't worked out is how to do a logical AND and OR. eg you can sure say if xx = a and yy=b then... but there is another type of AND where you say a=b AND c and there is a binary AND done on each bit. Even though this can be replicated with some sbasic code, this happens to be only one machine code instruction, so it is simpler to pass the values to a machine code routine, 'write' that routine with pokes and then call it.

function Logical_AND(a,b=byte)=byte
var l=byte
var hl,de,bc,af=integer
rem space at F880 to F8FB for small programs
bc=a rem transfer to bc and de registers
de=b
poke 0F880H,079H rem LD A,C
poke 0F881H,0A3H rem AND E
poke 0F882H,06FH rem LD L,A
poke 0F883H,0C9H rem RET
call (0F880H,hl,de,bc,af)
print af;" ";bc;" ";de;" ";hl
l=hl rem convert back to byte
end = l


rem *** main ***

var a=byte
var b=byte
var c=byte
a=15
b=3
c=Logical_AND(a,b)
print str$(c)

end

Dr_Acula
January 21st, 2009, 03:09 AM
Experiments with sbasic are going very well. I've got it reading and writing files to the disk. I've hit upon one minor snag though and any help from those with the manuals would be most appreciated. Dimensioning strings defaults to 80 characters per string and
DIM STRING LASTNAMES(100)

works fine. However

DIM STRING:20 LASTNAMES(100)

ought to save some space and is an example copied directly from the examples on the altair simh site. However it gives an error "undefined operand" and puts a $ in front of the 100. Maybe short strings can't be added and there is still plenty of memory so it isn't a major issue. Help would be most appreciated.

Terry Yager
January 21st, 2009, 12:56 PM
A quick glance reveals that strings are discussed in about 8 different sections of the manual. I'll have to get back to ya, if I can find what you're looking for.

--T

Terry Yager
January 22nd, 2009, 12:15 PM
Experiments with sbasic are going very well. I've got it reading and writing files to the disk. I've hit upon one minor snag though and any help from those with the manuals would be most appreciated. Dimensioning strings defaults to 80 characters per string and
DIM STRING LASTNAMES(100)

works fine. However

DIM STRING:20 LASTNAMES(100)

ought to save some space and is an example copied directly from the examples on the altair simh site. However it gives an error "undefined operand" and puts a $ in front of the 100. Maybe short strings can't be added and there is still plenty of memory so it isn't a major issue. Help would be most appreciated.

OK, hopefully this is what you are looking for:



Arrays (pg 56)

Arrays must be declared using the following statement:

DIM/DIMENSION [COM/BASE]<type>[:<SIZE>}<name>(<size>{,<size>})...

Note: This line is copied verbatim from the manual, but I'm guessing that the first (square) bracket is a typo. Looks like it should be a curly bracket instead, in keeping with the syntax of the rest of the line.


If COM is given, then the array resides in the common storage area.

If BASE is used, then the array is assigned no location or storage.

If both are ommited, then the location is in the standard data area.

<type> specifies the type for each <name> in the statement.

<name> is the name given to the array, and the same rules apply for it as for <name> in a variable statement.

<size> gives the number of elements in each dimension (vector) of the array.

As before, <SIZE> refers only to strings. Some examples:

DIM BASE CHAR VIDEO.DISPLAY(80,24)
DIM REAL X(5,5,7) Y(20) ALPHA.VECTOR(3)
DIM COM STRING:30 NAME(3)
DIM STRING:X+Y; FIELD (A+J,C)

(pg 57)

The DIM statement (for the data field only) may be used to change the <size> argument(s). The same array may be used more than once in several DIM statements. This does not create two arrays,but rather changes the size of the array. The number of size arguments (dimensions) must remain the same.

DIM <type><name>(<size exp>{,<size exp>})...

When an array is redimensioned, it's data contents are destroyed. If the <type>=STRING, then the syntax for the expression giving the maximum string length is:

STRING: <integer expression>
DIM STRING:MAX.LEN+Q; NAME(X-1)
DIM COM STRING:32 COMMON:NAME(20)

{The semicolon (;) is not allowed for arrays that are BASE or COMMON}

A base-located array may be positioned in memory, using the following statement:

LOCATE <name> AT <expression>

where:

<name> is the name of an array declared, using a DIM BASE... statement.

<expression> is an integer expression which specifies where in memory the array is to be positioned.


Hope this is helpful, lemme know if you have any more specific questions. Otherwise, wait for the scan of the manual to be posted (RSN).

--T

Dr_Acula
January 22nd, 2009, 02:08 PM
You have saved the day again Terry. Many thanks.

The key is putting in the COM which puts the string in a common area. So

DIM COM STRING:30 NAME(3) works
but
DIM STRING:30 NAME(3) does not. Yet
DIM STRING NAME(3) does work.

I'm just going to use that first one as it saves space. Most strings are short. It sure helps to have working examples. Back to coding...

Terry Yager
January 22nd, 2009, 04:20 PM
No sweat, doc. Looks like you've figgered out more without the manual than I ever did with it. Guess that's why I'm not a programmer.

--T

Dr_Acula
January 25th, 2009, 05:18 AM
Let's take sbasic a bit further. vb.net and c#.net etc all are converging into one language and have some syntax structures that can be replicated in sbasic. Eg to open a text file in vb.net and print a line

FileOpen(1, "MYFILE.TXT", OpenMode.Output) ' open a file
PrintLine(1, "hello")
FileClose(1)

We can get very close to replicating this in sbasic, and thus bring a 1970s program into 2009 and run .net like programs on old computers. Just a few minor changes - no brackets, and OpenMode.Output has to be in quotes. But the above can be replicated with this little program that opens a text file, prints two lines, closes it, opens it again and reads those lines back. It almost looks like vb.net. And I think this shows great credit to Kaypro as you couldn't get mbasic for instance to work like this.

rem *** Main ***
FileOpen 2,"MYFILE.TXT","OpenMode.Output"
PrintLine 2,"Hello"
PrintLine 2,"line 2"
FileClose 2
FileOpen 2,"MYFILE.TXT","OpenMode.Input"
Print LineInput(2)
Print Lineinput(2)
FileClose 2

And just for interest, these are the procedures behind the scenes.


files D, D, SA(4)

rem Converts character to upper case
function uppercase(ch = char) = char
if ch >= 'a' and ch <= 'z' then
ch = ch - 32
end = ch

function allcaps(source = string : 80) = string
var p = integer
for p = 1 to len(source) do
mid(source,p,1) = uppercase(mid(source,p,1))
next p
end = source

procedure FileOpen(number =byte;filename=string:20;mode=string:20)
var a=byte
mode=allcaps(mode)
filename=allcaps(filename)
if number<>2 then print "Only file number 2 supported"
if mode="OPENMODE.OUTPUT" then
create filename
open #number;filename
if mode="OPENMODE.INPUT" then
open #number;filename
if mode<>"OPENMODE.OUTPUT" and mode<>"OPENMODE.INPUT" then
print "Error in FileOpen with mode"
end

function LineInput(number=byte)=string
var lineoftext=string
var a=byte
lineoftext=""
a=0
while a<>13 do
begin
read #number;a
lineoftext=lineoftext+chr$(a)
end
read #number;a
print "";
rem if you don't have a print, the end below gives an error?!!
end = lineoftext

procedure PrintLine(number=byte;lineoftext=string:80)
var length=byte
var i=byte
var a=byte
length=len(lineoftext)
for i=1 to length
a=mid$(lineoftext,i,1)
write #number;a
next i
a=13
write #number;a
a=10
write #number;a
end

procedure FileClose(number=byte)
close #number
end

Dr_Acula
January 28th, 2009, 12:21 AM
Sbasic compile is getting slow for the big programs - up to 90 seconds. So - time to do the compiling on the Altair SIMH and then transfer the compiled .COM over to a real CP/M board via a serial link. Now the whole process takes one click on a button and only 8 seconds.

The secret is to shell the Altair SIMH from vb.net, link to it via telnet, send commands to move the file from the PC to the altair, run the compile program (sbasic compiler in this case but it could be any compiler), copy the resulting .COM back onto the PC, close down the altair SIMH program then download the .COM via xmodem at 38400 baud. Much quicker than writing a program on Wordstar or Vedit and compiling on a real CP/M computer (though this can be done too).

The attached screenshot shows 4 panels. Top left is the VT100 terminal of a real N8VEM board. The bottom left is an sbasic program. The top right is a scrolling version of the VT100 terminal so you can go back over long program traces to find errors, and the bottom right is the Altair SIMH.

This process will work with any vintage computer that can talk to a seperate terminal.

Terry Yager
January 28th, 2009, 10:12 AM
The secret is to shell the Altair SIMH from vb.net, link to it via telnet, send commands to move the file from the PC to the altair, run the compile program (sbasic compiler in this case but it could be any compiler), copy the resulting .COM back onto the PC, close down the altair SIMH program then download the .COM via xmodem at 38400 baud. Much quicker than writing a program on Wordstar or Vedit and compiling on a real CP/M computer (though this can be done too).

Holt on thar, BabaLouie! All this shuffling back and forth takes less time and effort than just waiting the minute & a half to compile on a real CP/M box?

--T

Dr_Acula
January 28th, 2009, 01:18 PM
Sure does. Shelling to the SIMH, copying the file over, compiling and copying back takes about 4 seconds. 2 seconds waiting for xmodem to respond and 2 secs to download. It is all one keypress too. To be fair, the dowload time goes up with long files, but so does the time to send a raw file. Still, regardless of the file size it is about 10 times quicker.

Terry Yager
January 28th, 2009, 01:27 PM
How fast is that SIMH anyway? Does it run at the full speed of your PC? And how fast do you have the N8VEM clocked?

--T

Dr_Acula
January 28th, 2009, 02:59 PM
This particular N8VEM is 4.9Mhz, though I have used 3.68 to 8Mhz oscillators. I ran a speed test on the SIMH and it told me it was a 200Mhz machine. This was on a 2.4Ghz PC of about 2004 vintage - I guess 12 instructions per simulated instruction is pretty good optimising. Newer PCs would be faster - even if the CPU speed isn't much faster the ram is running faster. My laptop is a similar age and SPEED.COM says it is 163Mhz on the SIMH.

Dr_Acula
January 29th, 2009, 03:02 PM
Peter Schorn has kindly given two code examples for running the SIMH simulator. The first (above) talks to the SIMH from within vb.net via Telnet. The second method opens the SIMH in a dos window and runs a batch file which can include instructions such as change a drive or run a file. This is even faster and is particularly useful for debugging code.

Speed tests on compiling a 228 line program with one keypress from within vb.net:

Copy to a real CP/M board at 4Mhz and compile = 4 seconds for xmodem transfer and 60 seconds to compile.
On the SIMH via Telnet then sending to a real board and running = 8 seconds.
On the SIMH using the code below as a batch file = 3 seconds.

The trick is to create some small text files first and then shell the SIMH to run those files. This is the code in vb.net


' compile using SIMH but leave the SIMH window open, and don't send to N8VEM
Dim Location As New Process
Dim Filename1 As String 'eg MYFILE.BAS
FileOpen(1, "C:\N8VEM\AltairSIMH\SIM.BAT", OpenMode.Output) ' open a file
PrintLine(1, "altairZ80 sim_cmd")
FileClose(1)
' create the large simulation file
FileOpen(1, "C:\N8VEM\AltairSIMH\sim_cmd", OpenMode.Output) ' open a file
PrintLine(1, "d tracks[0-7] 254")
PrintLine(1, "attach dsk cpm2.dsk")
PrintLine(1, "attach dsk1 basic.dsk")
PrintLine(1, "attach dsk2 games.dsk")
PrintLine(1, "attach dsk3 sbasic.dsk")
PrintLine(1, "attach dsk4 supercalc.dsk")
PrintLine(1, "attach dsk5 tools.dsk")
PrintLine(1, "attach dsk6 wordstar.dsk")
PrintLine(1, "attach hdsk i.dsk")
PrintLine(1, "set cpu 64k")
PrintLine(1, "set cpu noitrap")
PrintLine(1, "set cpu z80")
PrintLine(1, "set cpu altairrom")
PrintLine(1, "set cpu nonbanked")
PrintLine(1, "Reset cpu ")
PrintLine(1, "set sio ansi")
PrintLine(1, "set sio nosleep")
PrintLine(1, "attach sio cpm_cmd") ' attach the little file below to run a batch
PrintLine(1, "boot dsk") ' will run till type HALT which runs HALT.COM
PrintLine(1, "bye")
FileClose(1)
' now create the file to compile
Filename1 = Strings.Left(SbasicFile, Len(SbasicFile) - 4) 'trim the .bas
FileCopy("C:\N8VEM\" + Filename1 + ".BAS", "C:\N8VEM\AltairSIMH\" + Filename1 + ".BAS")
FileOpen(1, "C:\N8VEM\AltairSIMH\cpm_cmd", OpenMode.Output) ' open a file
PrintLine(1, "D:") ' sbasic is on the D drive
PrintLine(1, "R " + Filename1 + ".BAS") ' read the file into the SIMH
PrintLine(1, "SBASIC " + Filename1) 'compile it
FileClose(1)
' shell the altair SIMH
Location.StartInfo.FileName = "SIM.BAT"
Location.StartInfo.WorkingDirectory = "C:\n8vem\AltairSIMH"
Location.Start() ' shell the batch file
Sleep(2000)
Kill("C:\N8VEM\AltairSIMH\" + Filename1 + ".BAS") ' clean up

Terry Yager
January 29th, 2009, 06:30 PM
Pretty impressive speed-wise, but somehow it's just not the same thing as working with the real hardware...

--T

Dr_Acula
January 29th, 2009, 09:14 PM
I think both systems complement each other. I always seem to need the real hardware running at the same time. I find I make two sorts of errors when writing code. The first are syntax errors, like writing "end procedure" instead of "end", or "dim a as integer" instead of "dim a = integer". These are usually the product of switching from other languages like vb.net. So for these errors, it is helpful to run them through the SIMH. But the second sort of error is the code not doing what it is supposed to. The only way to test these is on real hardware, and for my current projects, this is very much true because a lot of code is talking to real serial ports and other hardware specific code that isn't implemented on the SIMH. The CP/M board and the PC are permanently connected at the moment.

Another feature of sbasic is the ability to write procedures that replicate functions that have become indispensible in modern languages, eg trim and ucase. One thing that is easier now is to put these functions in a library on the internet and have others contribute.

And one day, down the track, I'd like to get this running on a good old fashioned original CP/M machine just to prove it can be done. I keep scouring ebay and other places and sooner or later something will turn up that is local and doesn't involve large shipping costs. Meanwhile, I can admire with admiration the wonderful photos people post on this forum!

Terry Yager
January 29th, 2009, 09:54 PM
Oh, I get it (I think). So the PC is being used as an emulator for preliminary testing/debugging your code? That makes sense, I guess. I wish you luck in getting a vintage CP/M box soon. Then you'll understand where I'm coming from. There's nothing like running the old hardware (I didn't realize you don't have anything like that).

--T

Dr_Acula
February 27th, 2009, 09:44 PM
A quick update on where this sbasic is going. I've been coding for several hours a day every day for the last month but haven't had a chance to write it up yet. I've got a program that has grown to 30k in size now. Compiling that on a real cp/m board is taking a *long* time so the SIMH is proving invaluable (though it is still 20 seconds and another 20 to download the .COM).

The program is designed to be a repeater for wireless modules and is going to end up in cp/m machines out in the field, so one feature is an auto upgrade via the network. Trials are running with three cp/m boards. This is now working - the sbasic program can create a batch file and then shell out to that batch file, and the last entry reruns the program. It can shell out to xmodem, and tell another board, via wireless, to also shell xmodem and then the xmodem does the file transfer. 30k at 1200 baud takes a little while, but it only does this when the network is quiet. There are rf modules up to 19200 baud but 1200 has a longer range. So an upgrade consists of programs periodically comparing their version numbers, and if a new version is ready it is copied across, and then another batch file is created that renames the old version as the new version, and then reruns the program but it is now the new version. The new version of the program propagates through the network.

The point of all this is to have a program that can route messages through a wireless network. It is all the backend stuff in the internet that we take for granted and it is quite challenging to simplify it to fit in a cp/m environment. Wireless nodes need to send out 'ping' messages from time to time to see who is near them, and then test those links for reliability. That ends up being a simple text file that sbasic can create, and which can be read with any text editor. It can also be copied to other boards via wireless by shelling xmodem as above. So every board can build up links to nearby boards, and then get the list of links from every board. With that information, any board can work out the optimum path for a message through the network with the minimum number of hops.

The thing that is becoming increasingly clear is how well structured sbasic is. Programs in, say, mbasic, become very difficult to understand once they grow to 30k in size, with gosubs to line numbers that have no meaning. sbasic, on the other hand, can take subroutines and call them names that make sense. I've added some vb.net commands such as ucase and trim, and then the code ends up looking like .net code.

sbasic does have a few disadvantages. Loading and Saving text files takes a little time. And one has to remember it is a single pass compiler, so subroutines can only reference subroutines above them so there is sometimes some cutting and pasting to change the order of subroutines in the code. And the Chain command only can chain sbasic programs so there is a bit of custom programming to make a $$$.sub file in the exact format required in order to chain programs like xmodem.

Overall though, it is proving a pleasure to work with. I've got about 30 useful functions and procedures now and when I get a moment I might publish those somewhere in case anyone else wants to use this program.

JDT
April 5th, 2009, 09:05 PM
Everything Dr. Acula Said

Share =)

Happy now, T? =)

Terry Yager
April 6th, 2009, 05:20 AM
OMG, did you have to quote the whole thing? (Sorry, dear readers, it's a pet peeve of mine).

--T (Your heavy-handed moderator)

Dr_Acula
April 6th, 2009, 04:15 PM
I've got a complete standalone CP/M computer now http://hackaday.com/2009/03/04/n8vem-computer-with-a-3km-wireless-link/

Technically, it isn't vintage, but I do note that most of the chips on the N8VEM board were made in the mid to late 1980s.

Sbasic is going well. Recently on the N8VEM forum someone wanted to move the cursor around on the screen and they wanted to use LOCATE. We couldn't quite do that as locate is already a keyword, but we got close with CURLOCARE. Or we could have used LOCATE_CURSOR or anything really. sbasic enables you to add your own keywords, eg CLS, and hence build up your own language.

And of course, for the purists, it would be written in Wordstar or another text editor on the actual computer. Sbasic takes about 1 minute minimum to compile on a CP/M computer which is a bit longer than doing it on a PC and sending it over. On the other hand, a PC takes over a minute to boot up, but a CP/M computer is about 3 seconds. So for one simple change to a program and then a recompile, it is now faster on a real CP/M computer.

There are standard vt100 codes to change text color. So sbasic can work in color too :)

JDT
April 6th, 2009, 05:25 PM
Sbasic is going well. Recently on the N8VEM forum someone wanted to move the cursor around on the screen and they wanted to use LOCATE.


yea... that was me =P