Showing posts with label BASIC. Show all posts
Showing posts with label BASIC. Show all posts

Wednesday, November 24, 2021

Retrocomputing Basic Implementations

Here is a summary of a number of Basic implementations that I have come across and worked with as part of my retrocomputing hobby. Many of these were ported by me or others to different platforms from the ones they were originally written for (for example, single board computers based on the 6502, 6809, Z80, and 68000 microprocessors). These are all found on my github  account.

Name Developer Platform Code size Comments
Enhanced Basic (68000) Lee Davison 68000 14K Full-featured Basic for 68K platform
Tiny Basic for the 68000 Gordon Brandly 68000 4K Derived from and similar to Palo Alto Tiny Basic.
Enhanced Basic (6502) Lee Davison 6502 11K Full-featured Basic for 6502 platform.
Microsoft Basic for 6502 Microsoft Apple 2, Commodore, KIM-1, OSI, and others 8K Basic used on several early 6502-based microcomputers.
Tiny Basic for 6502 Tom Pitman 6502 3K Originally published in Dr. Dobbs Journal.
Apple 1 Basic Steve Wozniak 6502 (Apple 1) 4K Basic for the Apple 1, later expanded into Apple 2 Integer Basic.
BBC Basic 2 for Acorn Atom/BBC Computer Roger Wilson (Acorn Computer) 6502-based Acorn Atom and BBC Computers 16K Basic for the Acorn Atom and BBC Computers.
Tiny Basic for 6800 Tom Pitman 6800 2K My version runs on the Heathkit ETA-3400.
Tiny Basic for 6809 Tom Pitman 6809 2K 6809 port of 6800 version.
TSC Micro BASIC PLUS Technical Systems Consultants 6809 4K Similar to Tiny Basic.
Sinclair ZX81 Basic John Grant and Steve Vickers, Nine Tiles Networks and Sinclair Research Sinclair ZX80/ZX81, Timex 1000 8K Basic for the Sinclair ZX81 computer.

Tuesday, February 12, 2019

6809 Single Board Computer: TSC Micro Basic Plus

On the hunt for interesting software that could run on my 6809 Single Board Computer, I came across a small BASIC interpreter.

Originally written for the 6800 processor to run on systems like the Southwest Technical Products SWTPC, Micro Basic Plus was developed by Technical Systems Consultants in 1976 and cost $15.95 for the manual and listing. A cassette tape was $6.95 and paper tape was $6.00. The original version can be found here  and had this marketing blurb about it:


TSC Micro Basic Plus

This is the most complete small Basic available to micro users. Statements include: PRINT, INPUT, READ, DATA, RESTORE, IF ... THEN, GOTO, GOSUB, LET, ON ...GOTO, ON ...GOSUB, RETURN, FOR (with + and - step), NEXT, DIM (single and double dimensioned arrays up to 98 by 98), REM and END. There are also several functions available which include TAB and SPC (for output formatting), RND, ABS, SGN and exponentiation. The commands available to the user are LIST, SCRATCH, RUN, and MONITOR. But the list does not stop here. MICRO BASIC PLUS also includes a complete line editor ability to have multiple statements per line, direct execution of most statements, large arithmetic range (integer only -99999 to +99999), and a very simple load and dump procedure for saving the user's BASIC program on paper tape or cassette and then reloading it at a later time. Also included is an EXTERNAL statement which allows the user to write 6800 machine language subroutines to be called during BASIC program execution.

You are probably thinking all this sounds great, but if the less extensive versions of small BASIC require 23K of memory then this version must require 5 or 6K because the capability is doubled. Well here is the icing on the cake. MICRO BASIC PLUS resides in a fraction over 3K which means that in a 4K system you still have room for a 30 to 60 line BASIC program. For more complex programs, we recommend a system with 8K or more of memory.

One more plus... you not only receive a complete manual and hex dump of the program, but also the fully commented source listing! This is a great aid for learning programming techniques as well as enabling you to alter the program should you so desire.


I found a 6809 port here,  developed by Drexel University to run on their 6809 Single Board Computer. It looks to have been a straight port from 6800 to 6809 mnemonics with the input/output routines adapted to their hardware and monitor.

I ported it to my board, using ASSIST09 monitor routines for i/o. I had it up and running in an evening, and made a few improvements after that. It supports most common BASIC keywords including ON/GOTO and ON/GOSUB and one and two dimensional arrays.

Overall, though, the language is pretty limited as compared to other BASICs with support for integer math only and no string variables at all. This is not surprising given that it is only a little of 3 Kilobytes in size! It is not too different in capabilities from Apple 1 BASIC originally written by Steve Wozniak and later expanded into Integer BASIC for the Apple ][.

I tried a few sample programs and they ran quite well. I made an enhancement it to show full error messages rather than just numbers (which increases the size by another 1/2 K or so). The code is here.

For running real BASIC programs I think I will stick to the port of Microsoft BASIC for the Color Computer, but this is an interesting little program.

Friday, January 13, 2017

Building a 68000 Single Board Computer - Enhanced Basic




The TUTOR monitor is quite powerful, but a high-level language makes programming much easier. In the 1980s the standard programming language for home computers was BASIC.

One of the options for BASIC on the 68000 is Enhanced Basic. Written by Lee Davison, Enhanced BASIC is a BASIC interpreter that he wrote from scratch, for both the 6502 and 68000 processors. It is designed to be easy to port to different systems and is free for non-commercial use.

I earlier looked at Enhanced Basic on my 6502-based Briel Replica 1 computer. The 68000 version looked interesting and feasible to port to the TS2.

Unfortunately, Lee Davison passed away in 2013 and his web site is no longer on-line. I was able to find the source for version 3.5.2, one version older than the latest 3.5.3 release.

It was originally written to compile using the Windows-based Easy68K assembler. While I was able to run this on Linux using the Wine software, it found that it would assemble with only a couple of trivial changes using the VASM assembler, which runs natively on Linux.

To port it to the TS2 I only needed to write routines for character input and output. I wrote them to talk directly to the 6850 console UART. I also needed to adjust the program addresses to work within the memory map of the TS2.

Enhanced Basic is almost 16K in size and and needs at least 16K of RAM for programs. The TS2 has 32K, so it was just enough for it to run out of RAM. It takes about 30 seconds to download the S record file over the serial port at 9600 bps.

Another machine dependent feature is loading and saving. As there is no easy way to implement the LOAD and SAVE commands, I modified it to display an unimplemented error if these commands are used. One could save programs by running LIST and capturing the output to a file from the terminal emulator program, and load using the reverse method.

Once I got it working from RAM, I then assembled it to run out of ROM. I first had to wire up the additional 16K ROM sockets on the TS2. Enhanced Basic conveniently fits in the second pair of 16K ROM, with TUTOR in the first 16K.

Running from ROM, it can now use all of the RAM. About 23K is available to BASIC programs when it starts up. Here is as sample session, starting from reset into the TUTOR monitor:

TUTOR  1.3 > GO C000
PHYSICAL ADDRESS=0000C000

23056 Bytes free
Enhanced 68k BASIC Version 3.52

Ready
10 FOR I = 1 TO 100
20 PRINT I;
30 NEXT I

RUN
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3
0 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Ready

20 PRINT HEX$(PEEK(I),2);" ";
LIST
10 FOR I = 1 TO 100
20 PRINT HEX$(PEEK(I),2);" ";
30 NEXT I

Ready
RUN
00 04 44 00 00 81 46 00 00 80 30 00 00 80 3A 00 00 8D E4 00 00 83 AC 00 00 83 B6
 00 00 83 C0 00 00 83 CA 00 00 8C BA 00 00 83 DE 00 00 83 E8 00 00 99 62 00 00 9
9 62 00 00 99 62 00 00 99 62 00 00 99 62 00 00 99 62 00 00 99 62 00 00 99 62 00 
00 99 62 00 00 99 62 00 00 99 62 00 00 99 62 00 00 83 F2 00 
Ready

The source code for the port can be found here on github.

Enhanced Basic has floating point and integer variables and over 100 keywords. It includes advanced functions like conversion to hexadecimal and binary. Keywords must be in uppercase.

It is not totally compatible with other BASICs so you will typically need to port programs to it. I tried the classic Hamurabi program that was in a book published by Creative Computing and found that it worked without changes, although there were some formatting issues in the output due to differences in the way the PRINT command functions. Here is a sample run of the game:

                                HAMURABI
               CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY

TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA
FOR A TEN-YEAR TERM OF OFFICE.

HAMURABI:  I BEG TO REPORT TO YOU,
IN YEAR 1, 0PEOPLE STARVED, 5CAME TO THE CITY,
POPULATION IS NOW 100
THE CITY NOW OWNS  1000ACRES.
YOU HARVESTED 3BUSHELS PER ACRE.
THE RATS ATE 200BUSHELS.
YOU NOW HAVE  2800BUSHELS IN STORE.

LAND IS TRADING AT 17BUSHELS PER ACRE.
HOW MANY ACRES DO YOU WISH TO BUY? 0
HOW MANY ACRES DO YOU WISH TO SELL? 0

HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? 2000
HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? 20

HAMURABI:  I BEG TO REPORT TO YOU,
IN YEAR 2, 0PEOPLE STARVED, 3CAME TO THE CITY,
A HORRIBLE PLAGUE STRUCK!  HALF THE PEOPLE DIED.
POPULATION IS NOW 51
THE CITY NOW OWNS  1000ACRES.
YOU HARVESTED 1BUSHELS PER ACRE.
THE RATS ATE 0BUSHELS.
YOU NOW HAVE  810BUSHELS IN STORE.

LAND IS TRADING AT 17BUSHELS PER ACRE.
HOW MANY ACRES DO YOU WISH TO BUY? 10
HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? 600
HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? 10

HAMURABI:  I BEG TO REPORT TO YOU,
IN YEAR 3, 21PEOPLE STARVED, 4CAME TO THE CITY,
A HORRIBLE PLAGUE STRUCK!  HALF THE PEOPLE DIED.
POPULATION IS NOW 17
THE CITY NOW OWNS  1010ACRES.
YOU HARVESTED 1BUSHELS PER ACRE.
THE RATS ATE 0BUSHELS.
YOU NOW HAVE  45BUSHELS IN STORE.

LAND IS TRADING AT 17BUSHELS PER ACRE.
HOW MANY ACRES DO YOU WISH TO BUY? 0
HOW MANY ACRES DO YOU WISH TO SELL? 0

HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? 45
HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? 0

YOU STARVED 15PEOPLE IN ONE YEAR!!!
DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY
BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE
ALSO BEEN DECLARED NATIONAL FINK!!!!

SO LONG FOR NOW.

Maybe in the future I will try porting the classic Star Trek game, one of my favourite BASIC programs of that era.

Saturday, January 31, 2015

The Superboard ///

My latest retrocomputing project is building the Superboard /// computer kit by Briel Computers.

It is a replica of the Ohio Scientific Superboard II. The original SuperBoard II was one of the first affordable computers that featured a full keyboard, video output, BASIC in ROM.


At a price of $279 in 1979, it was an amazing bargain at the time when compared to systems like the Apple II that retailed for about $1300. For that you got an assembled board but needed to add a 5 volt power supply, monitor or TV set and RF modulator, and cassette tape for storage.

I owned one that I purchased in 1979 and it was my first computer. With it, I learned BASIC and 6502 machine language programming.

The SuperBoard /// is Vince Briel's replica of the original SuperBoard. It features a 6502 processor, but simplifies the design by replacing a lot of logic chips with a Propeller CPU. It is software compatible with the original system.

It is sold assembled or as a kit. I opted for the kit.



To date I've made three YoutYube videos on the kit, covering unboxing, assembly, and basic operation. They can be found on my YouTube channel.

I also have some files on my github account including a handy Quick reference, the OSI firmware including BASIC, and a port of my JMON monitor program. The Visual Monitor program that I entered a few months ago also works.

Below are some useful web links.

My Stuff:



Ohio Scientific:

http://en.wikipedia.org/wiki/Ohio_Scientific
http://classiccmp.org/dunfield/osi/index.htm
http://home.cmaaccess.com/~jerrytravis/
http://oldcomputers.net/osi-600.html
http://osi.marks-lab.com/
http://osiweb.org/osiweb/software.html
http://superboard.com.sapo.pt/
http://uk101.sourceforge.net/
http://www.6502.org/
http://www.6502.org/users/sjgray/computer/osi-c4p/
http://www.binarydinosaurs.co.uk/Museum/ohio/index.php
http://www.classic-computers.org.nz/collection/challenger1.htm
http://www.compukit.org/Compukit.org
http://www.cse.dmu.ac.uk/~mward/martin/software/index.html#UK101
http://www.gifford.co.uk/~coredump/uk101.htm
http://www.historyofpersonalcomputing.com/osi-superboard-i-and-ii/
http://www.lysator.liu.se/adventure/machines/OSI.html
http://www.neoncluster.com/projects-osi/osi-cassettes.html
http://www.old-computers.com/museum/computer.asp?c=572&st=1
http://www.old-computers.com/museum/computer.asp?c=860&st=1
http://www.oldcomputermuseum.com/superboard_2.html
http://www.osiweb.org/
http://www.pagetable.com/?p=43
http://www.pagetable.com/?p=46
http://www.pc-history.org/ohio.htm
http://www.technology.niagarac.on.ca/people/mcsele/OhioScientific.html
http://dabeaz.blogspot.co.uk/2010/08/using-python-to-encode-cassette.html
http://searle.hostei.com/grant/uk101/uk101.html
http://www.slideshare.net/dabeaz/using-python3-to-build-a-cloud-computing-service-for-my-superboard-ii
https://www.youtube.com/watch?v=pB2t6xG2RzE

Superboard ///:

http://forum.6502.org/viewtopic.php?f=8&t=2487
http://www.brielcomputers.com/phpBB3/viewtopic.php?f=39&t=1627
http://www.brielcomputers.com/wordpress/?cat=39
http://www.brielcomputers.com/wordpress/?cat=41
http://www.retrothing.com/2014/06/superboard-iii-briel-recreates-another-1970s-microcomputer.html

Monday, March 17, 2014

Running Microsoft Basic 5 on CP/M

I recently posted a series of YouTube videos on the Briel Altair 800 kit, the most recent instalment being The Briel Altair 8800 Kit, Part 5: Advanced Topics  which I posted yesterday.

To supplement what I demonstrated there, I'm going to post more details and the files I used, to make it easier for others who want to try out the relevant software.

First, Microsoft BASIC.

Version 5.21 of Microsoft BASIC-80 dated 28-Jul-81 is included on the Briel Altair CD in the CP/M 3 disk image (CPM302GN.DSK) as the file MBASIC.COM. It will also run on CP/M version 2.2.

The Microsoft BASIC-80 ver 5.0 Reference Manual can be found on the Internet here.

Many of the programs from the David Ahl Creative Computing books on computer games can be found on the Briel Altair CD in the directory BASIC Software/creative computing.

Here is the source listing for the memory dump program I demonstrated. I wrote it quickly to demonstrate some of the BASIC-80 features like displaying numbers in hexadecimal.

100 REM Dump memory in hex and ASCII.
110 A = &H100 : REM Start address
120 A$ = "000" + HEX$(A)
130 A$ = RIGHT$(A$,4) 
140 PRINT A$;": ";
150 FOR I = 0 TO 15
160 S$ = "0" +HEX$(PEEK(A+I))
170 S$ = RIGHT$(S$,2)
180 PRINT S$;" ";
190 NEXT I
200 FOR I = 0 TO 15
210 IF PEEK(A+I) >= 32 AND PEEK(A+I) <= 126 THEN PRINT CHR$(PEEK(A+I)); ELSE PRINT".";
220 NEXT I
230 PRINT
240 A = A +16
250 GOTO 120

Wednesday, June 6, 2012

CFFA1 and BASIC Integration


I've been working on integrating the CFFA1 flash card with my ports of Enhanced BASIC and MS BASIC for the Replica 1 so that SAVE and LOAD commands will support BASIC programs.

Using the CFFA1 APIs to save and load memory to and from files is quite straightforward. To simplify the process of getting the filename from the user, I simply prompt for it.

I had problems getting loading of programs to work reliably on either version of BASIC. It was not clear what range of memory needed to be saved and restored. It's further complicated by the fact that the CFFA1 firmware uses a lot of locations in page zero that are also used by EhBASIC so they need to be correctly saved and restored.

After a few evenings without success it was becoming frustrating and I was ready to set it aside for a while. However, I made a posting to the EhBASIC section of the forums at 6502.org and a couple of helpful forum users gave me some more details I needed to get it working. It now seems to be working well with Enhanced BASIC. I haven't yet resolved all the issues with MS BASIC.





I've been watching an original Apple 1 that is up for sale on ebay. The auction will end tonight and is currently bidding at $35,100.

Another Apple 1 is going up for auction at Sotheby's in a week. They estimate it may sell for $120,00 to $180,000. One last year sold for over $200,000.





I also added a new command to JMON to allow writing data to memory, similar to Woz Mon's ":" command. This was the only feature that it was really lacking. I also have a few more features and enhancements planned.

Wednesday, May 30, 2012

Tips and Tricks for the CFFA1


As I've been using the CFFA1 Compact Flash Interface with my Replica 1, I came across a few tips and tricks that others may find useful. So here they are, in no particular order.





There are two menu commands that are undocumented and commented out in the source code for the help command, but they are enabled and available in the firmware. Control-S is a STATUS command which displays the status of a drive. Typical output looks like this:

DRIVE # (0-3): $3
BLOCK COUNT FOR DRIVE 3 = $D800

Control-D is a DEBUG command which toggles the display of additional debug information about data blocks being read.





While Linux does not directly support the ProDOS file system, you can copy the CF card under Linux using the "dd" command. This can be useful to back up a memory card or write an image, such as a po file like the Ultimate Apple 1 Archive. A Google search indicates there are some ProDOS utilities for Linux similar to Cider Press for Windows but I haven't looked at any of them yet.





If you want to make changes to the CFFA1 firmware and test it out, you can assemble it to RAM and run it from there, avoiding the need to program it into the EEPROM. I had to change a little more than just the definition of "Origin" in the source code. If you want a patch to do this, let me know and I'll send it to you.





If you want to reprogram the EEPROM on the CFFA1 with new software, it is quite easy. There is a procedure described in the manual which works. Another option is to use my JMON machine language monitor program. The basic approach is:


  1. Build the firmware for EEPROM at address $A000.
  2. Generate a Woz Mon file located in RAM, say, starting at address $6000.
  3. Load the JMON program.
  4. Load the Woz Mon file into memory.
  5. Enable EEPROM write access using DIP switch 4 in the CFFA1.
  6. Use JMON to copy the firmware from RAM at $6000 to EEPROM at $A000. Use a write delay (a value of 20 worked for me).
  7. Use JMON to verify the data after copying.
  8. Set DIP switch 4 back to disable EEPROM write access






If you run a buggy program when the CFFA1 is installed you may see a message "BREAK..." and then get placed in the Woz Monitor. This is a BRK handler that the CFFA1 installs. It also installs an IRQ handler. This can potentially interfere with other programs such as JMON that also set BRK handlers but is useful if a program encounters a bug and hits a BRK instruction (hex value $00).





This is documented in the manual but easy to overlook: From Apple BASIC you can invoke the CFFA1 menu with "CALL -24000". When invoked in this way to BASIC using the warm start address, so any BASIC program loaded from the CFFA1 will still be in memory and ready to run.





The CFFA1 card has data at two defined memory locations that can be used to identify when the card is present. The ID bytes listed in the manual are not correct the addresses. The CFFA1_API.s API file and documentation says to read addresses $AFFC and $AFFD but the hardware and firmware actually uses addresses $AFDC and $AFDD. Further, my CFFA1 board did not have these locations programmed even though firmware on CD-ROM did. I rewrite the EEPROM on my board using the firmware on the CD.

Here is the guts of the code I used to determine of a CFFA1 is present when I hooked up JMON and BASIC to the CFFA1 menu:

LOAD:
SAVE:
        LDA     $AFDC    ; First CFFA1 ID byte
        CMP     #$CF     ; Should contain $CF
        BNE     NoCFFA1
        LDA     $AFDD    ; First CFFA1 ID byte
        CMP     #$FA     ; Should contain $FA
        BNE     NoCFFA1
        JSR     $9006    ; Jump to CFFA1 menu, will return when done.
NoCFFA1:
        RTS





It is easy to load and save Applesoft Lite programs. The LOAD and SAVE commands support a CFFA1 card, if present. The commands accept a filename as a parameter (e.g. "SAVE MYPROGRAM"). The MENU command will launch the CFFA1's built-in menu.





I made a port of Enhanced BASIC for the Replica 1. If you want to save and load Enhanced BASIC programs, here is a procedure that will work. Save the programs as a binary file from Ram_base ($0400) to Ram_top ($5000). The length should be $4C00.

Once you have loaded and run EHBASIC, type LOAD or SAVE to invoke the CFFA1 menu. Then WRITE or LOAD as desired. QUIT after loading or saving to return to EHBASIC.

I may do a more sophisticated integration in the future (like what was done for Applesoft Lite).





I made a port of OSI BASIC for the Replica 1. The latest version will will invoke the CFFA1 menu when LOAD or SAVED is executed and a CFFA1 card is found. QUIT returns to BASIC.

You need to write memory from RAMSTART2 ($0300) to whatever address you specified in response to the "MEMORY SIZE?" prompt on cold start of BASIC. This address is also stored in addresses $85 and $86.

So for example, if you responded to "MEMORY SIZE?" with 24000, location $85 and $86 contain address $5DC0 which corresponds to 24000 in decimal.

To run a program after loading, either quit to get back to MS BASIC or invoke BASIC through warmstart, e.g. address $6274 if loaded into RAM at $6000.

I may do better integration in the future (like was done for Applesoft Lite).

Thursday, May 17, 2012

Corrections to Apple Basic User Manual

As I work with Apple BASIC I noticed a few errors and omissions on the manual. I wrote them down in the hope that they may be useful to someone else. Maybe Apple will issue a revised version :-)

The latest version can be found here but for convenience (and so it is searchable by Google) I'll paste my current version here.






This document lists some corrections to errors in the document "Preliminary Apple Basic Users Manual' October 1976. It also lists some notes on features that are non-obvious or of interest.

Title Page:

Note: The woodcut image of Sir Issac Newton sitting under an Apple Tree was the original Apple Computer Company Logo drawn by Ronald Wayne, the third employee of Apple.

Note: The address listed is no longer the headquarters of Apple Computer :-)

Second page:

Error: The word "likley" is misspelled (It is ironic that this is the page that says the manual may contain errors and asks users to send in corrections).

Page 1:

Note: An alternative way to get to the monitor from BASIC is to execute the command "CALL -256".

Page 2:

Note: The instructions for saving BASIC programs on tape assume LOMEM and HIMEM have their default values. If not, you need to adjust the command listed in step 3 accordingly.

Page 4:

Note: A quirk of Apple BASIC is that the number -32768, which is a valid 32 bit signed value, is not accepted. I don't think this was an oversight As Woz was an excellent programmer and had designed calculators in his career. I suspect it was to allow the the "*** >32767 ERR" message to be used for all overflow errors. We'll come across this issue later.

Page 6:

Error: Under point 3, if a string is not dimensioned it's length is taken to be one, not zero.

Page 7:

Error: The word "destingation" should be "destination" (in two places).

Page 8:

Note: Unlike expressions, string comparison using "<>" is not supported, only "#".

Page 10:

Error: The statement that changing LOMEM or HIMEM destroys the current user program is not correct. The program will still exist but may not run reliably. You should execute a SCR command before setting LOMEM or HIMEM. There is also no check that the values for LOMEM and HIMEM are valid.

Note: There is no way to suppress the question mark prompt in INPUT statements.

Page 12:

Note: The target of a GOTO or GOSUB can be an expression. This feature is not supported in most other versions of BASIC.

Note: In a remark statement like

10 REM A COMMENT : GOTO 100

Apple BASIC considers the whole line to be a comment.

Page 13:

Note: An error is reported if the last line executed in a program was not an END statement.

Note: Due to the quirk of not supporting the number -32768, you cannot use this address ($8000 in hex) with PEEK, POKE, or CALL.

Monday, May 14, 2012

Another BASIC Game


On Sunday I wrote a little Apple 1 BASIC program to generate horoscopes. Given your name and the date and location of your birth it generates a reading.

Is it scientific? No, in fact it hopefully demonstrates the Forer Effect .

Horoscope Program
I hope you find it amusing. You can download it from here.

Tuesday, May 1, 2012

Odds and Ends


I noticed a bug in the disassembler function of my JMON machine language monitor program. The destination address of branch instructions was wrong. I tracked it down to a conflict of page zero locations that was introduced in the last version when I added the memory test command. I fixed it and updated the code on github.com.





The remaining parts for my 16K memory board arrived so I can finally start assembling it. I confirmed that the EEPROM chips work when installed in the Multi I/O board. I also confirmed that the pin-compatible RAM chips work in the Multi I/O board. Watch for updates here as I build the board.





I recently blogged here about my port of the 2KSA assembler. I should mention that there are some other resident assemblers for the Apple 1 that are superior. Krusader comes in ROM with the Replica 1 and is excellent. Another option is the A1-Assembler which comes in ROM if you are using the Achatz A-ONE Apple 1 clone, or you can load it into RAM. I spent some time playing with it tonight and it is quite good.





When writing the ZOOP program I wanted a more flexible input routine than the Apple 1 BASIC INPUT statement. It always displays a "?" prompt, for one thing. In the end I ended up using it, but it got me thinking about my earlier machine language input routine. It only supports reading characters at a time and returning them as numbers via a PEEK command. I'd like to extend it to return strings.

Unfortunately, I can't think of an easy way to do it. There is no way Ican find in Apple 1 BASIC to convert a number to a string (e.g. an equivalent to the CHR$() function in most BASICs). A possible approach is to find where the BASIC string is stored in memory and write to it. I spent a little time on this tonight but didn't get any where.



Speaking of Apple 1 BASIC, some people have disassembled it. An upcoming task I plan to do is to get a disassembly of it to assemble and run again, and then see if I can make a few changes.



While one person reported to be playing it, no one has reported successfully completing my adventure game. Come on guys, is it really that hard? I hereby offer a prize (details to be determined) to the first person to successfully complete the game.

Wednesday, April 4, 2012

Lemonade Stand Ported to the Replica 1


I was thinking of some old BASIC games and my wife mentioned one she always liked: Lemonade Stand.  I looked for a port to the Apple 1 / Replica 1 but couldn't find one. There are lots of versions of it around, including some that run in a web browser.

After some digging around I found a version for the Mac that included the original Apple ][ version from 1979 as comments in it's source code. The comments in the BASIC code say that the original program was written by Bob Jamison of the Minnesota educational computing consortium and modified for the Apple ][ by Charlie Kellner in February 1979.

I extracted the original source code from the Mac version and removed anything to do with POKEs, graphics, etc. that was not supported on the Replica 1. After an hour or two I had it up and running.

It needs Applesoft Lite (not the Apple Integer BASIC built into the Replica 1) because it uses a lot of floating point calculations. I suppose it could be ported to the Integer BASIC with some effort. If you want to try it, the code is here.

Below is a transcript of a sample run of the game. It supports multiple players and let's you play until you quit or go bankrupt.

HI! WELCOME TO LEMONSVILLE, CALIFORNIA!


IN THIS SMALL TOWN, YOU ARE IN CHARGE OF
RUNNING YOUR OWN LEMONADE STAND. YOU CAN
COMPETE WITH AS MANY OTHER PEOPLE AS YOU
WISH, BUT HOW MUCH PROFIT YOU MAKE IS UP
TO YOU (THE OTHER STANDS' SALES WILL NOT
AFFECT YOUR BUSINESS IN ANY WAY). IF YOU
MAKE THE MOST MONEY, YOU'RE THE WINNER!!


ARE YOU STARTING A NEW GAME? (YES OR NO)
TYPE YOUR ANSWER AND HIT RETURN ==> Y Y
HOW MANY PEOPLE WILL BE PLAYING ==> 1


TO MANAGE YOUR LEMONADE STAND, YOU WILL 
NEED TO MAKE THESE DECISIONS EVERY DAY: 


1. HOW MANY GLASSES OF LEMONADE TO MAKE (ONLY ONE BATCH IS MADE EACH MORNING)
2. HOW MANY ADVERTISING SIGNS TO MAKE (THE SIGNS COST FIFTEEN CENTS EACH) 
3. WHAT PRICE TO CHARGE FOR EACH GLASS 


YOU WILL BEGIN WITH $2.00 CASH (ASSETS).
BECAUSE YOUR MOTHER GAVE YOU SOME SUGAR,
YOUR COST TO MAKE LEMONADE IS TWO CENTS 
A GLASS (THIS MAY CHANGE IN THE FUTURE).


PRESS SPACE TO CONTINUE, ESC TO END...


YOUR EXPENSES ARE THE SUM OF THE COST OF
THE LEMONADE AND THE COST OF THE SIGNS. 


YOUR PROFITS ARE THE DIFFERENCE BETWEEN 
THE INCOME FROM SALES AND YOUR EXPENSES.


THE NUMBER OF GLASSES YOU SELL EACH DAY 
DEPENDS ON THE PRICE YOU CHARGE, AND ON 
THE NUMBER OF ADVERTISING SIGNS YOU USE.


KEEP TRACK OF YOUR ASSETS, BECAUSE YOU 
CAN'T SPEND MORE MONEY THAN YOU HAVE! 


PRESS SPACE TO CONTINUE, ESC TO END...


LEMONSVILLE WEATHER REPORT:
  SUNNY


PRESS SPACE TO CONTINUE, ESC TO END...


ON DAY 1, THE COST OF LEMONADE IS $.02


LEMONADE STAND 1 ASSETS: $2.00


HOW MANY GLASSES OF LEMONADE DO YOU
WISH TO MAKE ?30


HOW MANY ADVERTISING SIGNS (15 CENTS
EACH) DO YOU WANT TO MAKE ?1


WHAT PRICE (IN CENTS) DO YOU WISH TO
CHARGE FOR LEMONADE ?25
WOULD YOU LIKE TO CHANGE ANYTHING?N


** LEMONSVILLE DAILY FINANCIAL REPORT **


DAY 1  STAND 1


6 GLASSES SOLD


$.25 PER GLASS, INCOME $1.50


30 GLASSES MADE


1 SIGNS MADE, EXPENSES $.75


PROFIT: $.75
ASSETS: $2.75


PRESS SPACE TO CONTINUE, ESC TO END...


LEMONSVILLE WEATHER REPORT:
  SUNNY


PRESS SPACE TO CONTINUE, ESC TO END...


ON DAY 2, THE COST OF LEMONADE IS $.02


LEMONADE STAND 1 ASSETS: $2.75


HOW MANY GLASSES OF LEMONADE DO YOU
WISH TO MAKE ?20


HOW MANY ADVERTISING SIGNS (15 CENTS
EACH) DO YOU WANT TO MAKE ?1


WHAT PRICE (IN CENTS) DO YOU WISH TO
CHARGE FOR LEMONADE ?14
WOULD YOU LIKE TO CHANGE ANYTHING?N


** LEMONSVILLE DAILY FINANCIAL REPORT **


DAY 2  STAND 1


20 GLASSES SOLD


$.14 PER GLASS, INCOME $2.80


20 GLASSES MADE


1 SIGNS MADE, EXPENSES $.55


PROFIT: $2.25
ASSETS: $5.00


PRESS SPACE TO CONTINUE, ESC TO END...


LEMONSVILLE WEATHER REPORT:
  SUNNY


PRESS SPACE TO CONTINUE, ESC TO END...


WOULD YOU LIKE TO PLAY AGAIN?N

Wednesday, March 7, 2012

Direct Keyboard Input From BASIC


The BASIC INPUT command reads a line of text from the keyboard and assigns it to one or more variables. Sometimes you want to get a single key without requiring the user to press <Enter>. You may also not want to echo the character to the screen. Many versions of BASIC provide a command called GET that reads a character from the keyboard immediately but Apple 1 BASIC does not. I describe here a way to do this using a small machine language routine that is called from BASIC.

Section III on page 8 of the Apple-1 Operation Manual describes how to read a key from the keyboard in assembly language. The keyboard interfaces through a 6821 PIA (Peripheral Interface Adaptor) chip. The high order bit of the control register at address $D011 will be set when a key has been pressed. The key code can then be read from the data register at address $D010. The high order bit of the key code is always 1 and the low order 7 bits are the ASCII code for the key that was pressed.

We can take the sample code from the Apple manual and turn it into a routine that we can call by adding an RTS (return from subroutine) at the end. We also need to store the character we read in a memory location for later use. Below is assembler code in a form that is accepted by the Krusader assembler if you want to try typing it in and assembling it.

CR .= $D011 ; CONTROL REGISTER
DATA .= $D010 ; DATA REGISTER
POLL LDA CR ; READ CONTROL REG
 BPL POLL ; BRANCH UNTIL BIT 7 SET
 LDA DATA ; GET CHARACTER
 STA KEY ; STORE IT
 RTS  ; RETURN
KEY .B $00 ; KEY CODE

The listing from Krusader is a little more readable:

000 CR     .=  $D011         ; CONTROL 
001 DATA   .=  $D010         ; DATA REG
002 POLL   LDA CR            ; READ CON
003        BPL POLL          ; BRANCH U
004        LDA DATA          ; GET CHAR
005        STA KEY           ; STORE IT
006        RTS               ; RETURN
007 KEY    .B  $00           ; KEY CODE

Below is the disassembly from Krusader:

0300   AD 11 D0    LDA   $D011
0303   10 FB       BPL   $0300
0305   AD 10 D0    LDA   $D010
0308   8D 0C 03    STA   $030C
030B   60          RTS   
030C   00          BRK  

The zero value we stored in location KEY gets disassembled as a BRK instruction but it's really just data. We can call this routine from BASIC using the CALL command and then reading location KEY.

First lets convert the start address of the routine and of KEY to decimal:

$0300 = 767
$030C = 780

Our BASIC code to call it looks like this. We call the routine, and then when it returns to BASIC we get the key from location 780. Since the high bit of the character is normally set, we can subtract 128 to get the more conventional ASCII code for the key.

10 CALL 767
20 K=PEEK(780)
30 IF K>=128 THEN K=K-128
40 PRINT "KEY=";K
50 END 

And running it, we see the output:

>RUN
KEY=65

In the example above I hit the key "A".

This works but we need to arrange to make sure that the machine language program resides in memory. We could save it as part of the binary dump of the program (as we discussed in a previous blog posting) but it would be ideal if the BASIC program set this all up itself so it was self-contained. Let's POKE the program into memory from our BASIC program.

We need to convert the hex bytes in the assembly listing to decimal needed by BASIC. Here is the conversion:

Hex:  AD 11  D0  10  FB  AD  10  D0  8D  0C  03  60
Dec: 173 17 208  16 251 173  16 208 141  12   3  96

We can POKE these values into memory starting at address $0300 or 768 decimal. It's a little verbose because we don't have a DATA statement in Apple 1 BASIC but for a short program like this it is fine.

The complete program is shown below. I made the code to initialize the machine language program a subroutine we can call at line 1000. We need to do this once. The routine to get a key is a subroutine at line 1100.  The main program displays the key code. We then loop back unless the the key was code 81 (the letter "Q") in which case we quit.

10 GOSUB 1000
20 GOSUB 1100
30 PRINT "GOT KEY: ";K
40 IF K <> 81 THEN 20
50 END
1000 REM INIT ML CODE
1010 POKE 768,173:POKE 769,17:POKE 770,208:POKE 771,16:POKE 772,251:POKE 773,173
1020 POKE 774,16:POKE 775,208:POKE 776, 141:POKE 777,12:POKE 778,3:POKE 779,96
1030 RETURN
1100 REM GET KEYBOARD KEY
1110 CALL 768
1120 K = PEEK(780)
1130 IF K > 128 THEN K = K - 128
1140 RETURN

If you've been paying close attention and followed all of this, you may be wondering why we can't avoid the machine language routine entirely and just read the keyboard registers directly from BASIC using PEEKs. The problem is that BASIC polls the keyboard after every statement and if a key is pressed, it stops execution. We need to read the PIA data register after a key is pressed to clear the control register bit that indicates that there was a keypress. By doing this in machine language we do it all outside of BASIC and avoid the problem of BASIC stopping.

If Apple 1 BASIC was like most other implementations, only stopping when a Control-C was pressed, we could get by with the approach of just PEEKing the hardware registers directly.

Some BASIC versions of GET wait for a key to be pressed and return it, like here. Some return an empty string if a key was not pressed. You could easily modify this program to return a suitable value (e.g. 0) if no key has been pressed, if this was the behaviour you needed.

I hope you can see from this example that it is quite easy to call machine language from BASIC and you could extend this to more complex machine language code that might return more values such as numbers or strings.

LOMEM, HIMEM, and saving BASIC Programs


I spent some time today making sense of how to save BASIC programs as memory dumps, and the use of the LOMEM and HIMEM commands. Much of this has been covered in forums, web sites, and in documentation but I wanted to combine all the information here in one place, hopefully in a form that makes sense.

Apple 1 BASIC, as on the Replica 1, doesn't use all available memory by default. Most later BASICs did this, possibly after prompting the user for a manual entry of memory size on startup if they desired. The lower and upper range of memory addresses can be set by using the commands LOMEM and HIMEM as documented in the Apple BASIC User's Manual. Here is an example:

LOMEM=2048
HIMEM=4096

This must be typed as a immediate mode command, not from within a BASIC program. It also destroys any program that might currently be loaded (It doesn't seem to actually clear any program from memory but it is likely to crash BASIC if you don't clear it). It doesn't do any checking that the addresses are valid.

The defaults are the values listed in the previous example, which make sense for the original Apple 1 with 4K of memory.

If you have more memory and you want to make use of it, you can use the commands to extend the range of memory used. Typically you would only set HIMEM. On a Replica 1 with 32K of RAM the highest address available is hex $7FFF or decimal 32767, so to make use of all the memory you could do:

HIMEM=32767

Before loading or entering a program.  How do you know if you need to do this? The symptom of running out of memory is getting the "*** MEM FULL ERR" error message.

Incidentally, you can't directly read the values of LOMEM and HIMEM from BASIC, although it may appear that you can. Try doing:

PRINT HIMEM
PRINT LOMEM

and you'll probably find what I did. HIMEM seems to give a random value and LOMEM crashes BASIC. But the information is stored in known memory locations. LOMEM is stored in zero page addresses $4A and $4B and HIMEM in $4C and $4D in the usual 6502 low byte/high byte format.

The following two lines of BASIC code will print the current values (note that hex address $4A is 74 in decimal):

PRINT "LOMEM=";PEEK(74)+256*PEEK(75)
PRINT "HIMEM=";PEEK(76)+256*PEEK(77)

By default we get when we run the above:

LOMEM=2048
HIMEM=4096

After setting HIMEM=32767 we see:

LOMEM=2048
HIMEM=32767

Why would you want to set LOMEM? It's dangerous to set it lower than the default as lower addresses contain page zero, the stack, and other low addresses used by BASIC or the Woz monitor. But you might want to move it higher to leave room for some machine language routines that you want to store there and call from BASIC using CALL.

Where this all becomes relevant is in saving a BASIC program as a memory dump that can be loaded back using the serial port on the Replica 1.

While you can save a program as the source code using LIST, a dump of memory is typically smaller and loads faster because BASIC does not have to parse every line as it comes in (f you have done the high speed serial mod, you can load files as fast as the computer can accept them and the difference between the speed of BASIC and the Woz monitor is significant).

You can save a program using the Woz monitor and later load it back the same way. The question is, what range of memory needs to be saved?

The answer is we need to save two regions of memory. The BASIC program itself will be stored in the range of memory from LOMEM to HIMEM so we need to save that. We also need to save some low memory that stores additional information, such as the values of LOMEM and HIMEM. It turns out saving zero pages addresses $4A through $FF will do the trick. There may be some addressess in there that don't need to be saved but it is less than 200 bytes so it's not worth trying to avoid a few bytes within that range by using multiple memory dump commands.

As an example, to save with the default values of LOMEM ($0800) and HIMEM ($1000) we could dump memory from the Woz monitor with these commands:

4A.FF
800.1000

For the case where HIMEM is $7FFF, we could use

4A.FF
800.7FFF

That's quite a bit of memory. Our BASIC program may not be using all that memory, but I don't know of any way to know what the highest and lowest addresses are that it actually uses, so we need to save the entire range to be sure. If you are working on a small program you should stick to the default value of HIMEM so you don't need to save as much memory.

To actually save to a file you'll want to use your terminal program to capture the output and save it to a file.  It's also good practice to start up BASIC from the file by adding a command to run from the BASIC warm start location, $E2B3 and then run the program, so the last two lines of the file would typically be:

E2B3R
RUN

If you want to save your program as a listing that can be loaded into BASIC rather than a Woz monitor memory dump, you should add any LOMEM or HIMEM commands to the top of the file so that they will be set automatically when loading the file. Do a SCR first to clear any existing program and add a RUN at the end to make it start. In case the user is in the Woz monitor, calling BASIC with an E000R command at the start of the file is good practice. Here is an example:

E000R
SCR
HIMEM=32768
100 REM MY BASIC PROGRAM
...
900 END
RUN

That's all I have to say about HIMEM and LOMEM and it's probably more than enough.

Thursday, March 1, 2012

Classic BASIC Games

The Apple 1 (and Replica 1) uses a 6502 microprocessor which run a native machine code. Programming in machine code is hard - it is low level, very tedious, and hard to debug. Steve Wozniak realized when he designed the Apple 1 that it needed to be easier to use, so he wrote an implementation of the BASIC language for it to make the computer more accessible to new computer users.

BASIC, which stands for Beginner's All-purpose Symbolic Instruction Code, is a much easier language to learn and program in for beginners. I'd say it is roughly 100 to 1000 times easier to program than machine language. What is the price you pay for the ease of use? Because it is interpreted, it runs 100 to 1000 times slower that machine language. In many cases the speed is not an issue.

Woz's implementation of BASIC was developed by hand assembling it on paper into machine code and then typed in using the monitor. It fit in 4K of memory and came on cassette tape. The Replica 1 includes it in ROM so it can be loaded immediately.

In this blog posting I'll describe some of the BASIC programs available for the Replica 1. Most of these are classic games from the early days of personal computers and were written for the Apple 1 or written for similar computers and ported to the Apple 1.

The dialect of BASIC in the Apple 1 has a number of quirks and limitations. In a future posting I'll talk about this in more detail as well as some other implementations of BASIC available for the Replica 1. Overall though, it is quite usable and compatible with most dialects of BASIC from that era of early personal computing.

The classic book "101 BASIC Computer Games" by David Ahl collected many of the popular early games written in BASIC. When it was first published in 1973, most computers were mainframes or minicomputers accessible only to university students and faculty and employees of computer companies. I was fortunate to find a used copy a few years back.


With this book and a computer running BASIC, even a non-programmer could type in and run computer programs (although you typically had to make changes to adjust for the dialect of BASIC on your computer).

I also have a copy of the version from 1978, now called the "Microcomputer Edition" and updated to reflect the early computers popular at that time such as the Apple II, Radio Shack TRS-80, Commodore PET, and Ohio Scientific. Around 1980 I owned an Ohio Scientific Superboard computer and spent many hours typing in, debugging, and playing games from this book.


The Replica 1 comes with a CD-ROM that includes a number of BASIC games (about 30 or so). Here is a brief review of what I think are some of the better ones.

ACEYDUCEY

A card game similar to blackjack where you bet on whether a card dealt will be in between two cards that are shown.

BLACKJACK

The classic card game Blackjack or 21 where the goal is to get as close as possible to 21 without going over.

BOWLING

An interestring implementation of 10 pin bowling with the only graphics being "ASCII art" indicating the pins. It supports multiple players. There is no skill involved, the computer simply reports the randomly generated results of each roll of the ball.

CRAPS

A computer version of the gambling game played by rolling dice.

DEAL

An implementation of the "Deal or No Deal" game show. This is a newly written game for the Replica 1 by Vince Briel and it is very well done.

ELIZA

This is a BASIC version of the classic artificial intelligence program that acts as a psychotherapist. You have a conversation with the computer and it may help you to discuss your problems. It can be entertaining but won't pass the Turing test.

HAMMURABI

Hammurabi (often mispelled Hamurabi) is a game where you are the ruler of ancient Sumeria and have to decide how to manage the city: how much land to buy or sell, how much grain to feed the people, plant for crops, or keep in storage. If you don't choose wisely, people will starve or revolt. Surviving your 10 year term of office is the challenge.
HANGMAN

A nice implementation of the classic hangman word guessing game. It is quite well done using ASCII art to draw the character.

SLOTS

This is a simulation of a one armed bandit slot machine.

STAR TREK 2003

Star Trek was the most popular BASIC game of all time and various incarnations of it ran on every microcomputer and mainframe since it was written in the late 1960s. In the game you travel through the galaxy attempting to rid each quadrant of Klingons using phasers and photon torpedoes.
This version was ported to the the Replica 1 by Vince Briel in 2003 and runs very well. It lacks a few features of some of the larger versions but does an amazing job within the memory and limitations of
Apple 1 BASIC.

This is my personal favourite classic BASIC game.

SUDOKO

A new program written by Larry Nelson for the Apple 1. It generates Sudoko puzzles in one of three difficulty levels and can also display the answer.

WORDSEARCH

This program generates word search puzzles using words that you enter. It's probably only useful if you save and print out the puzzles.

WUMPUS

In this game you are in a cave with twenty rooms in the form of a dodecahedron where every room leads to three other rooms. Your goal is to hunt down and shoot a creature called the Wumpus using your bow and arrows. Hazards you may encounter include bottomless pits and super bats.

This is a classic game but for some reason is not included in the 101 BASIC Computer Games book.

Entering these classic programs onto the Replica 1 is a lot of fun and a good way for non-programmers to get started.

Be warned though: One of the pioneers of computer programming, Edsger Dijkstra, said that programming in BASIC would ruin you as a programmer for life. It is too late for me, the first programming language I learned was BASIC.