Stephen Smith's Blog

Musings on Machine Learning…

Posts Tagged ‘basic

Playing with FreeDOS and GW-Basic

with one comment

Introduction

Continuing with my series on ancient versions of the BASIC programming language, this week we’ll look at GW-Basic which was Microsoft’s BASIC for the original MS-DOS based computers. This predates QuickBasic, Visual Basic and VB.Net. The program is similar to last week’s Applesoft BASIC implementation since both were created by Microsoft. Applesoft was written in 6502 Assembly Language, and then ported to 8088 Assembly Language with minor tweaks. GW-Basic was replaced with QBasic in MS-DOS 5.0. On May 21, 2020, Microsoft open sourced GWBasic and you can browse the source code here.

Getting GWBasic

GWBasic isn’t included with Windows anymore, but since it’s been open sourced, you could build GWBasic from the source code, and several people have done this and made the executable available. I downloaded it from the Internet Archive. It is a single executable, so it only needs to be saved somewhere in your PATH to run. If you run it on Windows 11, you get:

Since Windows doesn’t support running 16-bit programs anymore. You could run it from an MS-DOS emulator, in a manner similar to what we did for the Apple II last time, but instead let’s take a different approach.

Enter FreeDOS

FreeDOS was started in 1994 after Microsoft announced they were no longer supporting MS-DOS and forcing everyone to Windows. It was created as a free open source alternative to allow everyone who loved MS-DOS to keep running free of Microsoft’s control. FreeDOS is a complete operating system and it runs GW-Basic perfectly. If you want to continue running MS-DOS programs like WordPerfect, Lotus 123 or any number of MS-DOS games, then FreeDOS is a great alternative.

Rather than install FreeDOS directly, I installed it in a VMWare image, where it runs great on my Windows 11 laptop. The installation is relatively pain free, using the LiveCD image from FreeDOS’s website. Once running, I needed to copy GWBASIC.EXE to that image. I did this by using AnyBurn to create an ISO image containing GWBASIC.EXE, which I could then mount as a CD-ROM drive from the VMWare player, and then copy GWBASIC.EXE over into a folder in the PATH on the FreeDOS harddrive. Then I typed in the AppleSoft program from last time, made a couple of minor tweaks to the graphics commands, initial screen location, and size and had a working program to again draw a Koch Snowflake.

The full program listing is at the end of this article. To extract the source code you need to save the GWBasic program with the A option so save will save the file in ASCII rather than a tokenized binary format. Then I used WinImage to create a floppy disk image which I could mount in the VMWare player and copy the file to. Note that VMWare loads CDRoms as read-only, so you can’t copy files to them, and I happen to be away from home and didn’t have a USB key which would also work.

Summary

Playing with GW-Basic is fun, and running under FreeDOS is just like running an old pre-Windows PC under MS-DOS. GWBasic has newer features I could have taken advantage of, but it is still of the line number required, fairly simple versions that people tend to be nostalgic for.

If you have any old MS-DOS 16-bit programs you want to run, this is a great way to do it. Kudos to Intel/AMD that you can still run these 16-bit programs, even if Microsoft doesn’t allow it anymore. FreeDOS itself is a 16-bit operating system. 

10 REM Program to Draw a Koch Snowflake
20 DIM DIST(10)
30 DIM LEVEL(10)
40 ST = 1
50 SCREEN 9
55 CLS
60 PRINT "Koch Snowflake (hit enter to continue)"
70 SX = 40
80 SY = 100
90 SA = 0
100 ST = 1
110 DIST(1) = 270
120 LEVEL(1) = 4
130 PI = 3.14159
140 X = SX
150 Y = SY
160 A = SA
170 A = A + 60
180 ST = 1
190 GOSUB 300
200 A = A - 120
210 ST = 1
220 GOSUB 300
230 A = A - 120
240 ST = 1
250 GOSUB 300
255 INPUT T$
260 END
300 REM Snowflake Side Subroutine
310 BR = 0
320 ST = ST + 1
330 IF LEVEL(ST - 1) = 1 THEN BR = 1
340 IF BR = 1 THEN ST = ST - 1
350 IF BR = 1 THEN GOSUB 1000
360 IF BR = 1 THEN RETURN
370 LEVEL(ST) = LEVEL(ST - 1) - 1
380 DIST(ST) = DIST(ST-1) / 3
390 GOSUB 300
400 A = A + 60
410 GOSUB 300
420 A = A - 120
430 GOSUB 300
440 A = A + 60
450 GOSUB 300
460 ST = ST - 1
470 RETURN
1000 REM Tutle Move Routine
1010 OX = X
1020 OY = Y
1030 X = X + DIST(ST) * COS(A*PI/180)
1040 Y = Y + DIST(ST) * SIN(A*PI/180)
1050 LINE (OX,OY)-(X,Y)
1060 RETURN

Written by smist08

October 6, 2022 at 12:35 pm

Koch Snowflake in Applesoft Basic

with one comment

Introduction

After learning to program in high school in BASIC on a PDP-11, I went to University where first year computer science was taught using WATFIV (Waterloo Fortran IV), where we had to write our programs by hand, type them into an IBM card punch machine and then submit our stack of punch cards to the data center to run. Later we would receive back our punch cards along with any printout from the program.

Definitely a step backwards from the interactive programming on the PDP-11. I joined the co-op program and after my first work term, used much of the money I made to buy an Apple II+ computer. This returned me to BASIC programming with Applesoft BASIC, which was created by Microsoft for Apple to replace their original Integer Basic.

Last time I produced a Koch Snowflake in QB64, a version of BASIC more advanced than the early BASICs like on the PDP-11 or Apple II. QB64 had functions, subroutines, structured programming and line numbers were optional. I wondered about producing the same program on a more original version of BASIC.  Applesoft is a good candidate as it uses line numbers, has no structured programming, but it does have a handful of builtin graphics commands that allow us to write our Koch Snowflake program. The main challenge is what to do about the recursive function calls.

Apple II Emulators

Although I sold my Apple II+ many years ago, to buy an IBM AT clone, it turns out many people have put a lot of effort into writing Apple II emulators and that you can find an Apple II emulator on most systems, In this case I used the AppleWin emulator, which was easy to install and up and running in no time. Below is the Koch Snowflake on the Apple screen. This is in the Apple II’s high resolution graphics mode of 280×192 in 6 colors. Rather low res by today’s standards.

Applesoft BASIC programs aren’t stored on the disk as regular text files, they are stored in a tokenized format which helps the interpreter run them faster. This is a problem as you can’t easily transfer the files back and forth to a PC. Since the program is small, I just typed it into the Apple, but it means to show the listing you get the following screen shots rather than text in the article.

The big innovation of Applesoft BASIC is that variables are floating point by default rather than integer, so this works well for the couple of calculations we need to do. The other thing is that variable names can be longer, but only the first two characters are used for uniqueness, hence AB = ABC = ABCD. The program roughly follows the same logic as the program in the last article, except no functions and recursion is handled by a simple stack stored in a couple of arrays.

The Program

The first part of the program initializes the variables, defines the arrays that will be used to stack level and line length and sets the graphics mode and color (white = 3).

The next part corresponds to the KochSnowflake subroutine in the last article that draws the main three sides of the snowflake.

Lines 200 to 330 correspond to the SnowflakeSide subroutine, note the lack of structured programming forces us to have four IF statements.

Lines 1000 to 1060 are the turtle graphics routine. We don’t have a turn routine, as the angle is a global variable. Move is similar to the Move Subroutine in the last article.

All in all, still quite a simple program. Editing programs in Applesoft is quite old school, but the memory of how to do things returns fairly quickly. Still people who’ve only used graphics editors might find it baffling.

Summary

It’s great that people have put so much effort into creating such high quality emulators of historical computer systems. This was a nice journey back down memory lane of how I did most of my programming in University from second year onwards. The Apple emulators support Apple’s Pascal system and even the add-on Z80 CPM cards. Perhaps I wouldn’t want to produce modern commercial software this way, but I think there are lessons to be learned from learning some of the old ways.

Written by smist08

September 17, 2022 at 9:48 am

Back to Basics

with 4 comments

Introduction

I originally learned to program in grade 10, where my highschool had a DEC LA36 DECwriter terminal connected through a 300 baud modem to a local college’s DEC PDP-11 running the RSTS-11 operating system. We wrote programs in the built-in BASIC programming language. This was 1976 back before structured programming took off where programs had line numbers and you used GOTO statements all over the place. The advantage of BASIC is that it is simple to learn and the students at our high school picked it up pretty quickly. We wrote programs to perform scientific calculations and wrote all sorts of games. Programming back then was a lot of fun. I’ve blogged about quite a few programming languages, including Python, Fortran, Assembly Language, Erlang, Julia, Scratch, Processing, and C. I was just remembering BASIC and wondered about playing around with that. In my career I worked quite a bit with Microsoft’s Visual Basic, but wanted something more old school and open source. Similarly VB.Net is just C# without the semi-colons. After a bit of research, I found there are dozens of implementations of BASIC floating around. Some require line numbers, some contain structured programming, some are interpreters, some are compilers. I may survey some of these in a later blog, but as an example I thought I’d play with QB64 abit which is a compiler implementation of QBasic/QuickBasic. This implementation runs on Windows, Linux and MacOS, but as a compiler I think it only emits Intel/AMD assembly code. I ran this on Ubuntu Linux 22.04 on my laptop.

Koch Snowflake Yet Again

I use drawing the Koch Snowflake as a good example, as it’s a simple program, does something nice, but is long enough to demonstrate a few things of the language. QB64 has lots of built in graphics commands, so why not. The full listing is at the end of the article.

QB64 comes with a character based IDE which is good enough for basic development. Of course the source files are text files, so you can edit them in any editor you prefer. I was worried about the implementation, as I usually use recursion and wasn’t sure if this would be supported, but it turned out this wasn’t a problem. QB64 could easily handle the task and the program is actually fairly compact.

Notes on QB64

  • Installation: I installed QB64 on Ubuntu Linux, the Linux version of QB64 has a shell script setup_lnx.sh which installs all the dependent packages along with the QB64 program. The script seems to know about quite a few flavors of Linux, but I can only attest to it running well on Debian based distributions.
  • Global Variables: I was expecting any variables to be defined or used outside a sub or function to be global, however this isn’t the case you have to “DIM SHARED” any variables you want to be global.
  • Variable Types: By default variables are single precision floating point. If you need them to be something else then you can use a “DIM” statement or there are a number of special characters that when placed on the end of a variable specify the type. Hence the & at the end of WHITE& tells QB64 this is a long integer. If you leave this off the program won’t work as the value produced by _RGB32(255, 255, 255) doesn’t fit in a floating point variable.
  • Line Numbers: This is a newer flavor of Basic with structured programming and hence no line numbers. You can always add labels and GOTO statements if you want to.
  • There is a JavaScript version of the compiler that emits JavaScript code, but it didn’t work on this program, generating JavaScript with a syntax error which I think was to do with the recursion. However, playing with QB in the JavaScript sandbox is fun.

Summary

QB64 is fun to play with. It’s not as old as the RSTS-11 Basic I learned in school and is a bit newer than the AppleSoft Basic I played with on my old Apple II+. If you worked with either QuickBasic or GWBasic on MS-DOS then this will be familiar, including the character based IDE.

In education, kids seem to start programming in Scratch and then progress to programming in Python. I wonder if there is room for Basic in-between as something more substantial than Scratch but without the complexity of the modern Python language. You can do a lot with Basic without the steep learning curve associated with more modern systems.

‘ Program to draw a Koch snowflake
_Title “Koch Snowflake”

STARTX = 50
STARTY = 130
STARTANGLE = 0
LEVEL% = 3

DECLARE SUB KochSnowflake(level%)
DECLARE SUB SnowflakeSide(level%, size%)
DECLARE SUB move(dist%)

Dim Shared X, Y, angle, PI, WHITE&

WHITE& = _RGB32(255, 255, 255)
PI = 3.14159
X = STARTX
Y = STARTY
angle = STARTANGLE

Screen _NewImage(520, 520, 32)
Cls
KochSnowFlake (LEVEL%)

Sub SnowflakeSide (level%, size%)
    If level% = 0 Then
        move (size%)
    Else
        Call SnowflakeSide(level% – 1, size% / 3)
        turn (60)
        Call SnowflakeSide(level% – 1, size% / 3)
        turn (-120)
        Call SnowflakeSide(level% – 1, size% / 3)
        turn (60)
        Call SnowflakeSide(level% – 1, size% / 3)
    End If
End Sub

Sub KochSnowFlake (level%)
    turn (60)
    Call SnowflakeSide(level%, 400)
    turn (-120)
    Call SnowflakeSide(level%, 400)
    turn (-120)
    Call SnowflakeSide(level%, 400)
End Sub

Sub move (dist%)
    oldx = X
    oldy = Y
    X = X + dist% * Cos(angle * PI / 180)
    Y = Y + dist% * Sin(angle * PI / 180)
    Line (oldx, oldy)-(X, Y), WHITE&
End Sub

Sub turn (angle_increment)
    angle = angle + angle_increment
End Sub

Written by smist08

September 4, 2022 at 3:42 pm

Posted in programming

Tagged with , ,