"Sherman, set the Wayback machine for ... 1978", quoting Kevin Flynn from TRON. He actually says "set the Wayback machine for three years ago", but the movie was filmed in 1981 so it's kind of the same thing.
But I digress...
Say, if you don't want to read my nostalgic drivel but need some Sym-1 resources, click the link to go right there. Or you can go straight to the sections on BASIC programming or on the cc65 C Compiler for the Sym-1. But if you're feeling nostalgic yourself, read on.
In 1978, we were paying about 75¢ a gallon for gas. We had just celebrated the bicentennial, and were still wowing over Peter Frampton's talk-box guitar on "Do You Feel Like We Do." Intel Corporation had invented the microprocessor just seven short years ago. Their 8080 was an excellent chip, but the failure rate was high, so rejects drove up costs to around $250 per chip. In volume, a manufacturer could negotiate the price down to under a hundred bucks, but that was still fairly expensive.
Enter the 6502 from MOS Technologies. It was a low-cost microprocessor, mainly because the fabrication technology increased yield. They had a much lower rejection rate, and cost per chip was much lower. It also required only a single voltage power supply. So manufacturers embraced the chip and put it in computers like the Apple, the Pet, the KIM-1 and the VIM-1, later renamed Sym-1.
VIM-1 |
external keypad and display |
keypad and display wiring |
The Apple and the Pet were more like what was to become personal computers. The KIM-1 and the Sym-1 were more microcontrollers, much like what the Raspberry Pi is today. The KIM-1 and Sym-1 were actually designed to showcase chips from their respective manufacturers, MOS Technologies and Synertek.
What I liked about the Sym-1 was that it had a lot of I/O lines, so it could sense and control a lot of devices. And its monitor ROM had several useful functions that were well-documented, so programming was made simpler by taking advantage of the built-in software. Further, it had Microsoft BASIC on ROM as well as a nice assembler/editor.
I got my first Sym-1 in 1978, and it was before they changed the name so the silkscreen on the PCB and the packaging labeled it as VIM. They later changed the name to what it is commonly known as, the Sym-1. Mine had the Microsoft 8K BASIC ROM and 4kB of RAM. When Synertek introduced the v.1.1 monitor ROM, I purchased it so I have both v.1.0 and v.1.1 ROMs. The only real difference was in the tape routines, and mine worked well with v.1.0, so it didn't change much for me.
In the 1970s and early 1980s, minicomputers ran business and microprocessors were used just for specialized controllers and what-not. There were, as I mentioned earlier, several really cool general-purpose microcomputer systems but the public still perceived computers as room-filling beasts that spanned several 6-foot-tall, 19-inch-wide cabinets and using disk drives as big as washing machines.
But through the 1980s and 1990s, that all changed. The minicomputers were slowly replaced by more and more capable microcomputers. The first step in the evolution was microcomputer workstations that acted both as terminals to minicomputers and as stand-alone systems that could do word processing and general applications. Then several microcomputers were networked, and businesses started becoming less reliant on minicomputers. Eventually, even powerful servers were made using microprocessors of ever-increasing computing power, memory and speed.
As those years passed, eventually I used my Sym-1 less and less. It was like Puff the Magic Dragon for me.
~~~~~~~~~~~~~~~~ Days pass, years... decades... ~~~~~~~~~~~~~~~~
I found myself longing for those days in the summer of 2020, so I dusted off my old Sym-1, hooked it up to 5v and a terminal emulator and fired it up. As if the last 40 years were just a single night, the system gave a Beep. I pressed "Q" and it returned the "." prompt. I started BASIC by typing "j 0" and got the old familiar message:
.j 0 MEMORY SIZE? WIDTH? 3583 BYTES FREE BASIC V1.1 COPYRIGHT 1978 SYNERTEK SYSTEMS CORP.
Super groovy cool!
I started thinkin' I should add some memory. These days, large memory is cheap so I set about looking. What I found was two things:
1. You can still get 2114 chips - both new and old stock - but the new chips have about 50% failure rate. I expect they're not testing them after they are made, and defects are slipping (pouring) through. So if you buy new 2114 RAM chips, buy twice as many as you need.
2. Corsham Technologies' Bob Applegate sells an excellent memory card for the Sym-1. So forget about the 2114 chips and buy a memory card from CorshamTech.com. He also sells edge connectors, both for power and expansion. Bob is a great guy, so be sure to shop there!
CorshamTech RAM card |
Sym-1, after the silkscreen change to SYM |
You can click on any picture on this page to get a closer look.
Check out Bob's memory boards. You'll notice they have small DIP switches, which are really convenient. They let you enable or disable RAM in 4K blocks. This is great because you can select or deselect the first 4K, depending on whether or not you populated your Sym-1 with 2114 chips. You can also select the whole B000-FFFF range if you don't have BASIC and RAE ROMs installed, which will allow you to load them from tape. I've provided ROM images for both BASIC and RAE as WAV files, loadable through the tape input, at the resources section below.
After installing the CorshamTech memory board, my system was huge! Enough memory to run the old Star Trek game that was so popular in the 1970s! It's in the resources section below, by the way. Just click the links for the "BASIC programs."
.j 0 MEMORY SIZE? WIDTH? 32255 BYTES FREE BASIC V1.1 COPYRIGHT 1978 SYNERTEK SYSTEMS CORP.Nice!
When I was searching for stuff for my Sym-1, I found one on eBay and I bid on it. Ended up getting the one pictured right beside the CorshamTech memory board, shown above. It looked to me like it had never been used. Even the box was pristine. Compared to the box mine came in - which has "been around" - this one looks brand new. It also shows the name change from VIM to SYM:
VIM-1 and SYM-1 packaging, side view |
VIM-1 and SYM-1 packaging, top view |
If you look closely at the Sym-1 photo above, you'll see a modern part in the U20 ROM socket where the Monitor ROM should be. This is a 2332 replacement part with a Monitor 1.1 image in it. The Sym-1 from eBay came with Monitor v.1.0 - which is fine with me - but still, I wanted to use the binary images to make a new ROM for it. However, 2332 chips and programmers have become scarce and expensive. So I found another alternative.
I found a guy named Tony that runs a website called Vintage-Computers.it, which is a computer repair site in Rome. What's really neat is he makes a product called
So I contacted Tony and provided ROM images for Monitor 1.1, BASIC and RAE as five 4kB blocks. I ordered five of these chips setup to emulate 2332 ROMs, so that each can be jumpered for its intended use - Monitor at 8000, BASIC at C000, BASIC at D000, RAE at B000 and RAE at E000. I also ordered a MultiROM jumpered to emulate a 2364 with BASIC as a single 8K block from C000-DFFF. The Sym-1 can be jumpered for either kind of ROM chip, but I found that early boards were sent out jumpered for 4K ROMs and later boards were jumpered for 8K ROMs. It's easy enough to change the jumpers, but it's also nice to have a variety of ROMs, suitable for either application.
I also ordered another memory board from CorshamTech for the new Sym-1. If you look closely at the Corsham memory board photo above, you'll notice that two of the boards have switches to select B000-FFFF but two of the boards have the C000-DFFF range disabled. That's because I run two of those boards on the new Sym-1, and I haven't populated the ROM sockets with BASIC. Instead, I load BASIC from tape (actually, a digital audio recorder/player) when I want to use it.
Funny aside - using a digital audio device to record and playback data files - so the Sym-1 digitizes the sound to make analog and the digital recorder samples the analog to make it digital again. Goofy. But it works, and it's easy. Makes me think of a microprocessor controlled vacuum tube, but that's another inside joke from a long, long time ago...
The CorshamTech boards come with the edge connector soldered on, and it's made to mount in the same plane as the Sym-1 "motherboard." But I decided to get a Metcase enclosure for my Syms, and it doesn't have quite enough depth for that. So I ordered another pair of memory boards from CorshamTech sans edge connectors. I soldered 'em on 90° so I could stand the memory board upright. Fits in the case that way. That's also why I have the detached keypad and the display on my original Sym, so it can mount to the front panel. I socketed the 7-segment displays and installed a SIP keyboard connector to connect them.
Sym-1 System with Front Panel Keypad and Display |
Sym-1 Cabinet Internal Layout |
I used the Metcase M5503110, which is light gray and just large enough to mount the Sym-1, memory board and power supply. I also installed a board that has a couple of little audio amplifiers, mostly so I could adjust the levels for a variety of tape and digital audio recorders. The blue LEDs aren't "period correct" but they nicely complement the blue in the Synertek logo. I think if blue LEDs were available back when Synertek was around they would have used 'em. I had panels made at Ideal Specialty, in Tulsa. The job number was K-22971, and that can be used to identify the drawings, if you want to have a similar case made for your Sym-1.
Sym-1 System without Front Panel Keypad and Display |
Sym-1 Cabinet Rear Panel |
As you can see, I had two cabinets made. One system has a keypad and display mounted on the front panel, and one does not. Both systems used the same rear-panel. You might also notice the vertically mounted Corsham memory board. There is plenty of space between it and the rear panel of the cabinet, but I still glued on a piece of 40mil PVC plastic sheet material, sitting just behind the memory board. Never hurts to be safe.
To make it really fun, connect using a VT-100 clone based on the boards made by Geoff Graham and Peter Hizalev.
Microsoft 8K BASIC
Most people think Microsoft got its start with Windows. Some know about MS-DOS and the story of its inception. Gates' deal with IBM to put MS-DOS - and later Windows - on the IBM-PC is definitely the defining moment for Microsoft. It's what launched them into the juggernaut of success they are today.
But the first Microsoft product was actually 8K BASIC. It was in all the popular microcomputers in the 1970s. They started off making it for the MITS Altair 8800 computer, which had an 8080 microprocessor. And when the 6502 became popular, Microsoft created a version for it. The Apple II, the Commodore Pet and the Sym-1 all had very similar versions of this 8K BASIC.
You can run simple BASIC programs with 4Kb of RAM, but a lot of the "really good programs" need more than that. One in particular that I always loved, was Star Trek. Any time I was at a computer club meeting where someone had a computer with more than 24Kb RAM, they'd be running that game. Just like you could expect to hear Led Zeppelin's "Stairway to Heaven" or Lynyrd Skynyrd's "Freebird" in every college dorm and at every party, if you went to a computer club meeting you would see Star Trek running on the head geek's computer.
So now, with the CorshamTech memory board, my Sym-1 could be propelled to the pinnacle of geekdom and run Star Trek.
The problem is there are a lot of versions of the game and most don't adhere to the 72 characters per line length limit. Some come close though. That's a problem with many of the popular BASIC programs - there wasn't a standard back then. Even the language was slightly different between platforms. You had Dartmouth BASIC, the original. Then you had Digital Equipment Corporation's PDP-11 BASIC and BASIC-PLUS. You had Data General's Business BASIC. Wang had their own BASIC. Basically, every platform had their own version of BASIC.
Microsoft's entry of 8K BASIC sort of standardized the microcomputer industry, simply because it was so common. But that was still just another version of BASIC, and the popular "BASIC Computer Games" was actually written for DEC BASIC, so some stuff worked on 8K BASIC and some stuff didn't.
So I set about finding all the BASIC programs I could find and seeing which would run on the Sym-1. Where I found line length past 72, I modified the program so it would fit. I usually just split the line into two lines. Sometimes, I needed to do a little more. But in most cases, the program is completely original. I've noted changes in a README.TXT file in the archive.
Some programs use trigonometric functions, which aren't included in the 6502 version of Microsoft BASIC. They're in the other versions of Microsoft BASIC but wouldn't quite fit into 8K ROM for the 6502. So since these functions are rarely used, they were left out.
Synertek provided code for the TRIG function, which was to be installed in RAM, when needed. I've included a version of this code that resides at 9EC7-9FFF in the memory region just above the Monitor ROM. So if you have the CorshamTech memory board, be sure to enable this memory bank. You can then load the TRIG function before loading any BASIC programs that need it.
Alternatively, you can modify BASIC to include the TRIG function and recompile it. The BASIC Interpreter Source for cc65 is available. It's assembly code - not C - but the ca65 assembler included in the cc65 distribution will build it. More information on cc65 is shown below.
Resident Assembler / Editor
Synertek provided a Resident Assembler / Editor, commonly abbreviated the RAE. It was a bit of an oddball, because Synertek didn't appear to use it, themselves. It was a ghost of a product, and I can't recall ever seeing any RAE listings other than those from members of the Sym-1 users group. Even Synertek's documentation mentions their use of the Teledyn cross-assembler, TASM. The RAE was somewhat popular with members of the Sym-1 users group though.
Still, it was a nice little assembler and an interesting product, so I modified a couple of the programs from Synertek's Technical Notes (which can be found in the documentation archive) so they would build in the RAE.
I probably should address the issue of transferring the files to the Sym-1. There's no really easy way to do it, at least not "right out of the box." You would think you could just copy-and-paste the contents of a program from some text editor like vi or notepad into a terminal emulator program and it would transfer essentially the same as typing it manually. The problem is the Sym-1 has to interpret every keystroke and determine what to do with it, so every character that comes across takes some processing time on the Sym. And since the serial interface has no handshaking signals, the flow must be throttled.
What I found is the transfer of HEX files (for object code) and the transfer of BASIC programs each have their own issues. For HEX files, one must simply throttle the speed of the nibbles, so that there is a slight delay after the two HEX digits that make up a byte are sent. This gives the monitor code time to parse the input and put it in memory. For BASIC, the speed of each character sent is one parameter and the speed of each line is another separate parameter. In other words, each character of a line is throttled by one amount, and then after the carriage return is sent, we have an additional delay. This lets BASIC parse the line and put its tokens into memory.
So I wrote a couple of little Python scripts to do this for me. One is 'upload', and the other is 'upload_hex'. Use 'upload' to transfer BASIC files and use 'upload_hex' for HEX files. They each take one argument, which is the source file name. The communications port is defined in the code, itself. My system has a USB-to-RS-232 adapter defined as COM3, so that's what is in the Python script. You can change yours to whatever you need it to be, or modify the script to pass it as a command line argument.
To transfer BASIC files, I first start up BASIC on the Sym-1 then I type 'upload <program>' on the connected PC. To transfer object code, I first type 'm 200' and press enter on the Sym-1, and then I type 'upload_hex <hexfile>' on the connected PC. It's a gomer-approach, but it's pretty reliable. Only occasionally do I get an error - if I see 'ER xx' when sending HEX files, I know right away I must do it over - but it works about 80% of the time.
Compilers always write object code as BIN files, sometimes without an extension. If you don't name 'em, a compiler will even call the file 'a.out' so but the point is it is raw binary. To transfer to the Sym-1, it needs to be a hexadecimal representation of the binary, so you will need to run 'bin2hex' on the compiled/linked program before transferring it. You can easily find 'bin2hex' on the internet.
Another option is this interesting new tool that may make connection with the Sym easier:
So you can use whichever upload tool is easiest for you.
cc65 C Compiler
When the Sym-1 was introduced, the C language wasn't very popular. But it became hugely popular, both for systems programming and for things like embedded systems. It has some constructs that are very "close to the machine" that make it perfect for embedded systems. But it has some abstractions that make it easy to write higher-level systems too. So it's a great language to use.
Still, it was not available for the Sym-1 in the 1970s or 1980s, or for that matter, even in the 1990s. By that time, I had long moved away from the Sym-1, putting it on the shelf for more capable systems. I often used C for embedded controllers in the 1980s, and I still do. I still use C++ for systems programming too. So when I brushed the dust off my Sym-1 and started looking around for stuff to do with it, I was really excited to find the cc65 compiler for the 6502.
I stumbled across the cc65 compiler by finding the BASIC sources mentioned above. The BASIC sources are assembly language, and they are built using the assembler (ca65) and linker (ld65) included with cc65.
I was super-excited to find this compiler, but my excitement paused a bit when I realized that it didn't have all the files to support a Sym-1. There was memory configuration in the BASIC source distribution that could be used as a basis for the C language configuration though, and the documentation is really good for creating the code needed for a new target system. So I set about doing that.
The cc65 compiler will actually work on the Sym-1 - "right out of the box" - but it can't support any I/O so it's not particularly useful. A person can, however, compile a full-featured C program that operates in memory and leaves its results in memory. So all the heavy lifting has already been done by all the contributors of the cc65 project that have made it such an excellent compiler for the 6502.
All I needed to do to complete a port to the Sym-1 was to create a memory map and to provide functions for system I/O. I made functions to access all the Sym-1 I/O lines, the built-in "front panel" display and to direct read and write to the async port so console I/O will work. So I created the (asminc) map of all the important memory locations for monitor access and memory-mapped I/O, wrote little assembly functions for all the I/O and voilĂ ! I had a Sym-1 port for cc65.
One of the first things I noticed - which was actually a no-brainer after seeing it - was that the compiled binary was much smaller when using primitive console functions like getchar(), putchar() and even puts() than it was when using functions that had formatting functionality. The reason is pretty obvious - Code that has to parse and interpret a format specifier is more complex than code that just operates on a single char, or that iterates through a char array. So for example, see the following two "Hello World" code snippets and notice the difference in the compiled executable binary size:
"Hello World" using puts() builds a 526 byte binary:
#include <stdio.h>; void main (void) { puts( "Hello World!" ); return; }"Hello World" using printf() builds a 2368 byte binary:
#include <stdio.h>; void main (void) { printf( "Hello World!\n" ); return; }These two programs provide the exact same output.
The second thing I noticed was equally obvious, after actually doing it. I made two memory configurations - one for the "stock" 4kb Sym-1 and a second for a Sym-1 fully populated with RAM. That second memory configuration only uses the bottom 32kb because it is contiguous. So but the stock 4kb configuration provides only 283 bytes of heap storage, whereas the 32kb configuration provides up to 28,187 bytes of heap. I found this by compiling the following program and linking it once using the sym1-4k.cfg file and a second time with the sym1-32k.cfg file. I've included both in the Sym-1 distribution of cc65. Of course, since the heap-test program uses printf(), the small memory configuration would have more heap available if it hadn't.
Understand that the 283 byte limitation on the 4kb configuration is for heap storage. It's not the total memory available. The compiler allocates memory for the stack, and you'll probably do everything on the stack when writing a 4kb Sym-1 program. You can do a lot with a 4kb Sym-1 if you are careful with your programming style. I've included a few sample programs in the Sym-1 cc65 distribution archive that run just fine in 4kb.
Heap test program:
#include <stdio.h>; #include <stdlib.h>; #include <string.h>; void main (void) { char* buffer; int heap_size; heap_size = _heapmaxavail(); printf( "Heap available is %d bytes.\n", heap_size ); buffer = malloc( heap_size ); memset( buffer, 0x00, sizeof(buffer) ); if( buffer ) { puts( "Memory allocated." ); } else { puts( "Couldn't allocate memory." ); } return; }You'll notice that the simple programs above all include <stdio.h>, which is fine for console I/O but has no access to the Sym-specific I/O. For that, one would include <sym1.h>.
After I had the port completed, I thought I'd better compile some other stuff to make sure it worked. I found a cool little "Adventure" program written by Jeff Tranter. He makes Apple clones and runs cc65 on them. So I compiled his Adventure program and it built and ran first try. I was excited both to know the cc65 compiler was working fine on the Sym-1 and also because I had a cool Adventure program now too! I also compiled Payton Byrd's port of Wumpus. It requires the time function to randomize - and the Sym-1 doesn't have a real-time clock - so I removed the time call and instead used an uninitialized int within a function. So just a very small change was needed to get that to compile too.
Now knowing the C compiler was working well, I decided to write a few more programs with it. I always liked John Conway's life simulator, and it was popular on systems of the Sym-1 era. Even though there was a BASIC version of it, the speed of a compiled executable made a C version of the program more attractive. So I wrote a version of Life in C. Similarly, the Mandelbrot set images were sort of a 1980s thing, but the first ones were primitive ASCII renditions made on minicomputers in the 1970s, so I couldn't resist but to write a fixed-point integer version of the Mandelbrot program in C. And finally - my pièce de résistance for cc65 on the Sym-1 - was to write a really nice big text adventure game. It doesn't have the space for the full version of Zork, but it does have enough room for any of the three-part "slices." Then it occurred to me that even better would be to write something totally new. So I set about making a map and a storyline and Jinx was born.
One more thing - an aside, really - for those of you interested in writing C programs for the Sym-1 or any platform using cc65, for that matter. This is especially true for those of you coding in C++. Most developers today are working with technologies like objects and dependency injection. These approaches are several generations away from the original C, and coding style is much different. What is considered "best practice" today is not really what works best in cc65. For example, most would frown upon using global variables and would prefer to pass variables between functions. But that requires stack operations - pushes and pops - which are expensive operations, especially for a register-limited eight-bit processor like the 6502.
I hope you find this stuff to be fun and useful. If you have a Sym-1 or a Sym-1 clone, I'm sure you'll get more out of it.
Please let me know if you find any errors or omissions, or if you find any bugs. You can reach me at wayne@parhamdata.com.
Resources
Other Interesting Sym-1 Sites