Monday, November 26, 2012

Hello World the Hard Way

Well it looks like my love of the original Commodore 64 has taken me somewhere unexpected.   Somewhere I thought I would never be.   The world of software emulation.  The picture you see here is from my current project.   I'm calling it SASM64.  It stands for Semi Abstract State machine, and is a functional Commodore 64 emulator.

I like to call this hello world the hard way, as I had to write an entire environment for the hello world program before I ran it.   Hello world isn't actual the first program this emulator ran.  Due to some bugs during development I could not get strings to work.   So the first program that ran correctly was 10 print 5+3.

Before depart to far here and start telling antic dotes that only interest me, I'll start by telling you why this project was started and what the design goals were.

The SASM64 project began as an extension of my desire to join the world of homebrew CPU.  The Magic-1 is a wonderful example, and one of the most complete homebrew CPU projects I've seen.  Just to be clear here were not talking about building a computer from scratch.   Were talking about building a computer without a microprocessor.    The goal is to build the processor, not just a computer.    I've made lots of plan and sketches but nothing really has come from my project yet.

A few weeks ago while thinking about the homebrew CPU concept I decided to undertake an intermediate step that would advance my understanding of how to build a CPU.  A CPU is is made up of many state machines, and I don't really have a clear picture in my head of how many and what type of state machines will need to be designed for a CPU to work.  So I set out to write a software CPU core just to see what was involved.  I also decided to go with a known processor so I would have a code base to work from.

So I began my software core project with somewhat different goals than what I imagine to be the typical software Emulator Author.   Instead of tyring to optimize the code (though there is some that entered out of necessity) the code is written to simulate multiple state machines.    Thus the name SM in the title.    Ultimately I don't have the detail of a physical state machine, my software state machines are somewhat abstracted from the real state machines.    So I set out with the following Goals
  • Design A functional Software 6502 Core
  • Design it using multiple state machines
  • Design it in a human friendly language (I chose C# as I am familiar with it)
  • Design enough functionality that it can run Basic using an existing ROM.
I reached those goals within about two or three weeks of starting the project.   Its first existence was in a very ugly Windows forms Application.  I was able to get it running the Commodore 64 Kernel, and Basic ROMS and execute basic program.    It has turned into such a rewarding project that I was unable to stop there.    I started a new XNA project and dropped the code in, added a limited Text mode video driver, some tolls to drop PRG files into memory (no floppy emulation yet), and most recently add a from scratch Software SID emulator.  With a bit of hacking at it It now is capable of playing SID files.

This project not been without pitfalls, many of them around incorrect, and incomplete documentation.  Some of them directly related to the fact I am not, nor have ever claimed to be a programmer.    There was a lot of making it up as I go along.   My plan is to tear myself away from this project for a while and document the process, and share the problems and solutions I've passed along the way.


Stay Tuned....

Wednesday, April 11, 2012

Custom Case Build Part 2

The second part of the build I have not yet finished.   Well I finished it once then decided it was unfinished so there is still more to do.

As there is no mother board in my C64x case I needed to come up with a way to still use the keyboard.   I went with the simplest solution I could think of.   I bought a cheap USB hub at my local computer store, ripped it apart, soldered pin headers to it, and mounted it in my case.   I didn't want to modify the C64x case as it was rather spendy and I thought some day I may put a motherboard in it.   So to mount the USB hub I cut a piece of metal about the size of a mother board and mounted it in the case using the existing motherboard mounting points.    After that anything I added to the case was just mounted to the metal plate.
Once the keyboard was working I was pretty happy, but still planed to use the power light and button on the keyboard.  I built a board using an FTDI breakout board from Sparkfun, and a Parallax propeller.  The board has two headers for the power LED and power switch connectors.   I latter added two 9 pin connectors for commodore style joysticks.  I've been working on an application to control the LED on the keyboard and accept input from the power button and joysticks.
I'm still working on the app but it is coming along.   Most of the major features are in place and right now I am mostly working on getting it to look nice.   I tried to roughly follow the look of the commodore breadboard.
The sliders and radio buttons control the behavior of the LED.   It has 4 different modes: On, Off, Dimmed, Flashing, and Glowing.   The sliders adjust the absolute dim and rate of dimming, as well as amount of time the LED spends fully on and fully off. The board is capable of storing two profiles.   One for when the computer is sleeping and one for when it is awake.   Once you have saved these profiles to the board it will automatically change to those profiles when the USB buss is  asked to go to low power mode (this happens when the computer is sleeping) and when it comes out (when the computer wakes up).
The power button can preform several operations.   When the computer is sleeping it will wake it from sleep. When the computer is awake a quick tap will eject the CD/DVD/Blu-Ray from the drive.   This is handy since there is no physical eject button I have access in the 1541.   Holding it slightly longer will cause the computer to got to sleep.   And if you hold it for a few seconds it will shut the computer down.
The board also displays several pieces of information.   What Com port the board was detected on.   What firmware version the board is reporting, link indicators that include sending and reviving data, as well as indicators for joystick activity.
The two joysticks are mapped to keyboard presses.   They are configured to the default keyboard shortcut for the VICE keyboard joystick mapping.   The keys can all be changed by clicking the remap joystick button.
I will be releasing all the source code and schematics for this board and application soon.   I had packaged the boards firmware but am not releasing it as I added joystick support and that is not in the schematic. I do not believe I will be making any changes to the software on the board so as soon as I get the schematics done I will release the code.  The windows application still needs a few tweaks before I release it but it is essentially done.   I'm not much of a windows application developer so please don't laugh to much at my code.   Once I mount the the 9 pin joystick connectors in the case I'll make a video of the final product.   
This video shows an earlier version of the board (no joystick support) and an earlier version of the application.


Custom Case Build

I've been working on a new project for about a month.  Things are really coming along nicely but I haven't taken the opportunity to document much of it yet.    I'm trying to rectify that now.
The project is about 95% complete so I better get on with it before I forget how it all works.

This project originated from the news that the rights to the Commodore name had been purchased and there was a product being released (the Commodore 64x) that looked just like the original Commodore 64 with a modern keyboard layout and hardware.    After investigating these (http://www.commodoreusa.net/) I was amazed but found them too expensive.

I eventually did purchase the bare bones case planing on building my own system.    However I ran into a snag.  The slope of the case to accommodate the keyboard really limits the space for your motherboard.   Depending were components were located on the board they may not fit in the case.   I bought a board that will not fit.    Here is were my project began.

With several options in front of me I finally settled on building my own case out of a 1541 drive I had laying around for parts, and converting the case into a keyboard.  The final product is pretty nice.  
  • Slot Load Blu-Ray player that slides out of the original floppy drive slot
  • Full use of Commodore keyboard case via internal hub (only USB cable to run it all)
  • Custom board (ruining on a Parallax Propeller) to control the power light and button
  • Custom software to interface with the board
  • Commodore style joystick ports.
My plan is to document the steps I've taken so far and to release all the code for the firmware and software.  Be warned my embedded programming is much better than my application programming.

Before I begin I must mention that I collect vintage computers, primaraly Commodore so I would ask that if you do make one your self, be kind to the collectors and try to find a broken drive and not sacrifice a working drive.

To build this I used parts from an old computer case, and a mostly striped Commodore 1541 drive.   To begin I stripped the floppy drive down to the plastic components, trimmed the tabs of the floppy drive face plate so it could sit flush against the Blu-Ray drive, and hot glued it in place.
The next step was to cut down the internal metal chassis to allow a motherboard to fit in the back of the case, and the front to mount the drives to.

At this point I built a mount for the laptop Blu-Ray drive using a the 3.5 mounting hardware from a sacrificial computer case. After cleaning up all the edges and surfaces so that
 the bracket could sit flat I mounted it temporarily in the case to measure for the Optical drive.
Once this is in place you can mark the proper height to cut for the optical drive to mount.  When you cut the bracket you'll leave the other side long to mount the hard drive.   The mounting points for the optical drives are disturbingly small.   I believe they are 3mm screws so you have to measure very carefully to drill the holes to mount the drive.

I mounted the hard drive using a 3.5 to 2.5 mounting bracket.   This was simply attached to the 3.5 bracket on the side that was left long.
This can now be loaded into the 1541 case.
This first part of the build was the most difficult portion.  The optical drive must be very carefully mounted to allow the disc to slide through the slot.  Mounting the motherboard was accomplished by cutting the two rear posts down to allow the board to fit, cutting a whole in the back for the parts, and dry fitting the board in the case.   I used an auto punch to mark where to mount the standoffs.  There were a few alignment issues with the feet on the bottom of the drive, but a small notch fixed this.
I drilled two holes in the top of the case for the power connector and power switch.
The last step was to solder on the power led, and hard drive led connectors from the other case to the LEDs on the floppy drive. 
To fix the posts I had to cut for the motherboard to fit I used some plastic spacers to mount the rear screws.
This is  a video I shot when I first got it up an running.   I'm working a better on for the complete project.
That covers the 1541 portion of the build.  I'll cover the keyboard next.


Friday, May 20, 2011

Preparing for ALU construction

Most of the parts have arrived.   I am close to being able to begin construction on my ALU.  I've received my XOR, OR, AND, and 4 to 1 ICs.    I've got some boards I will do my prototyping on, I've had them for a while aready.  These Boards from sure electronics are my preferred prototyping boards.   They are vectored with support for more than one power buss, and you can solder on ether side of the board (Very convenient if you want to stack boards).   I decided later on in the project that I wanted to socket the ICs (the fact that I went CMOS had something to do with this), so I'm currently waiting on a shipment of sockets.

As I draw closer to my first prototype of the ALU I'm again revisiting the scale of these.  Originally I wanted to do a 32bit data bus.   The math on this just doesn't work on the prototyping boards I want to use.  This would mean 64 Inputs, 32 ANDd, 32, ORed, 32 XORed, and a few combinations that will have to pass between boards, along with the control signals.   I've only got about 128 lines I can pass between these boards, so 16 bit is looking more likely.   I've even considered dropping back to 8. 

Another limiting factor I hadn't planed on was the board size limitation on eagalecad.  Its A bit more spendy that I would like to license, as I am just starting to learn how to use it.    The size limitation has lead to some rather densely populated boards, that become difficult or impossible to route.   I had fantasised about having boards made as this would save lots of labor, and would be reproducible.

I'm planning on finalizing my a few design pieces of the ALU this weekend.   I'm in the process of determining the fewest number of control signals necessary to control it.   That shouldn't take to long, then I'll try look at how many ICs I can comfortably fit on a board and decide 16bit or 8 bit.   I'll probably do 16bit if at all possible.   

The ALU is the only part that really will be affected adversely by the larger bus size.   The sequencer/controller will ultimately end up simpler if the data bus is wide enough I won't need to decode any instructions, rather the instructions can decode themselves.   Thus the state machine can run off an instruction register directly without having to do combinational decoding.  I'm envisioning a single bit in the instructions that repents what the function is being preformed.  So imagine a bit that indicates a task will be sent to the ALU.   That's all the state machine needs to do.   Other bits will tell witch register should jump on the bust to the ALU inputs.   The ALU can look at the bits on the instruction register to figure out what function it is preforming.   And another couple of bits will tell a witch register should store the result.  Instructions that require 2 or 3 cycles can have bits that affect program flow right from the instruction register. 

So that's the plan now.   Make the data bus as big as possible, Optimises the instructions to simplify the sequencer/controller, build it, program it, and enjoy.

Wednesday, May 18, 2011

I'm Back

Okay I'm back.   Its been a while since I've had a chance to even look at this.    I haven't worked on a project in quite some time.   It was rather depressing when I look at what I've worked on recently and I don't really haven't had anything really exciting to brewing.    I've been working on more flight simulator items, but the sudden death of my soldering iron slowed that down.

I do have a new project I've just begun.  Its a project I've been dreaming about forever (or at least since the 80s).  I don't think I was even 10 when I first had the desire to build my own computer.   I've played with a few projects over the years, but the ultimate dream has changed with time.

Recently, inspired by a certain google emplyees' MAGIC-1 project www.homebrewcpu.com I've decided to go all in and build my own computer, CPU and all.  Ultimately I wanted to build 3 different machines.  A relay computer, TI 7400 based system, and a FPGA solution.   My goal is to document these well enough that they could be recreated. 

I put off the relay computer, because I don't envision it to be the most rewarding of the three.  At the size and scale I am envisioning this project I can only see this useful for recursive calculations.   That's not something I really do a lot of.

The FPGA I put off because I've never used one before.   I've recently started playing with CPLDs, but not yet FPGAs.  So I'll save this one for later.   I happen to live in the town where digilent is based.   I've even met its founder, and eventually I think I'll be using one of their boards for my project.

So that leaves me with the 7400 based system.  I've decided not to emulate any CPU but to go my own way.   This leaves me with a few obstacles to overcome, lack of a tool chain, or operating system being the primary.   But I hope they will in themselves be interesting projects.

I've sent in my first parts order to mouser this week, so the project may begin.  I'm still  finalizing the specifications, but several sketches have steered me away from a 512bit data bus (maby version 2).  The first piece I plan on building is the ALU.  It supports not, and, or, xor, add, and subtract. 

I've spent a lot of time deciding what kind of adder I will be using.  I found I'm not a fan of look-ahead carry units, I really don't want to complicate the design any more than I have to.  However I did have one idea I have been playing with (I'll have to do the math to ensure it really speeds things up).   I am calling it a parallel ripple adder (I don't know if anyone uses this method but I haven't found anything yet).  The idea is to break the adder into smaller pieces, say 8 bits.    The first 8 bits are a standard ripple carry adder.  The following bytes are calculated twice, one assumes the previous byte carried and the other assumes it did not.  The idea I have the normal delay for a carry adder bit it is only 8 bits.    Each additional 8 bits would only have 3 gate delay for the true carries to propagate the correct selection (I'm thinking result_with_carry AND carry OR result_without_carry AND noncarry).

The actual ripple carry adder I've decided to go with is Result = ((A XOR Subtract) XOR B) XOR CarryIn, where CarryIn for the first bit is CarryIn OR Subtract.   CarryOut = (((A XOR Subtract) XOR B) AND CarryIn) OR (A AND B)

Well that is a rough outline of where I am now.  I'll post drawings here as I finish them.   But be warned my eaglecadd skills are not the greatest yet.

Thursday, June 10, 2010

Okay how about a video

Okay well talk is cheep. So I slapped together a real really quick video of my current project, you know the touch screen remote control system, just to show it works.. Well sort of.

Right now the features working are, a debug menu accessed via the USB port. You can communicate directly with the 4D Systems touch screen with this interface, as well as decode several different types of Remote Control IR signals.

The actual touch screen is running on its own cog in the propeller. It just continually runs scripts stored on an uSD card. There are three different types of files it uses. A script File, a button File, and an image file. Scripts run a very limited script language I have written for it. It just does things like load an image, pause, load a different script, pause some more, load a button file.... The button files contain coordinates for the touch screen and a script name to go along with that.

So at boot up it runs a boot script witch loads a button file. When the script finishes running it waits for you to press the touch screen. When you press the touch screen it looks to see if there is button defined in that spot and if so run the script. That script may or may not load a new button file so commands that don't require a new menu will not need to update what the buttons do.

What that all boils down to is the entire thing is fully configurable via simple test editor, and a tool 4D systems provides to convert images into a format it can play.

Okay not a lot of detail... But here is the first video of it in action...

Saturday, June 5, 2010

Wisdom for the day.

Okay so I still haven't posted what I wanted to about my current project. I've been busy, please forgive me. I've got a little bit of a time constraint on this project and I haven't been taking as much time to document as I would like. I did however just fix a problem that was driving me nuts for a long time, so I'm going to take a brake and tell my tail.

My project is using a Propeller microcontroler from Parallax. I'm communicating with a piece of hardware using serial. I've been pulling my hair out for days, searching for a bug that didn't exist. Let me explain...

I'm using the full duplex 4 port serial driver from the propeller object exchange. I've used it many times and had lots of success with it. On my current project I am using it because I need to serial ports, I'm using one for a debug port and the other to communicate with a display. The problem was I was the commands I was sending to the display were not always working correctly. I blamed myself (quite correctly as it turned out). My initial tests indicated that I was successfully communicating at 115200 bps. I was wrong! I kept checking my code trying to figure out why some times the same function would work and other times it would not.

The thing finally made me realize what I was going wrong happened today. I'm working on a text interpreter for running scripts on the propeller. No mater what I did it kept reporting the wrong file size back to me over serial. For some reason the last bit of every byte was 1. A of 20 bytes was reporting the file size of $0080808A. (okay so the two highest nibbles were right). I then wrote test code to display the contents of the file. It worked perfectly.

This was were it got frustrating. I finally decided to trudge on with the code event though the file size was missing I could just wait till I got errors and assume I was at the end of the file. So I wrote more code, implementing handshaking as a form of flow control. That's when it became clear. Data after the ACK was corrupt. It turned out all this time that if I was transmitting while receiving the received (well it could even be the transmitted I don't know) was corrupt. I turned the communication speed down and everything is working the way it is supposed to.

So my new found wisdom is don't assume bidirectional communication is functional until you test them at the same time! I made a mistake weeks ago and didn't even look at it but it was the problem.