Category Archives: Retro Computer Project

Retro Computer Build Part 5 – Revised Address Decoder

So, after a couple of weeks since writing the first post about this Micro, I’m rethinking the address decoding and mapping of the same. Currently, address line A15 is being used to select between the lower 32K of memory and the upper 32K of memory. In the lower 32K of memory, I will page 32K block of RAM in and out, as needed. While the upper 32K of memory will be used for ROM and video RAM. I had previously suggested using a 3-8 line decoder to break up the upper 32K of memory into 4K chunks and then join a few of them to give 8K chunks. After a few days of writing the post about address decoding, I realised there were a few options available.

If I use a 2 to 4 line decoder (74HC139), I can use address lines A14 and A13 to break the upper 32K of memory into 4 x 8K blocks (which makes it easier for memory management). The upper 3 x 8K blocks can be used for firmware. I can potentially look at paging out one or two of these 8K blocks.

The lower 8K page can be sub divided into 4 x 2K blocks using another 2 to 4 line decoder (74HC139) on address lines A12 and A11. One of these 2K blocks can be used for basic video memory.  If I add a second or third 2K block this would give 4K or 6K of video memory, which would suffice for a basic 40 column x 25 line or 80 column by 25 line display (with some basic colours and cursor functions).

The lower 2K block can be sub divided into 8 x 256 byte pages for I/O. This is still allot of wasted address space for I/O, so what can be done to be more efficient with the memory usage?

We can use a programmable logic device , a “PLD”, to manage the control logic for the I/O. This way we can re-program the PLD at a future date to incorporate any additional changes to the I/O that we may want.

Using an Atmel ATF22LV10C will give us up to 10 outputs each, which can be individually assigned to one or more addresses. With up to 12 address inputs, the PLD makes it easier to map the control lines required. The unused pins on this device will be brought out to a header in case we need to use these pins at a later date. This is a  simpler solution to the multiple address decoders and additional logic ICs that potentially we were looking at.

When looking at the above revised memory map, we can see the I/O region is spread over 256 bytes of memory.

ATF22LC10C Datasheet

Years ago I used us a Hi-Lo Programmer that connected to my PC via an ISA card. This device was supplied with its own DOS program for taking Boolean logic and producing a map file which could be programmed into a PLD or a GAL. As I can’t use this anymore on modern PCs or a laptop, I need to find a more modern solution.

So I purchased a G540 programmer on eBay for very little money. The G540 was supplied with some adaptors for PLCC devices. A chip extractor was also supplied with this package. This programmer has a USB port, so it can connect to my laptop or desktop PC.

eBay G540 programmer

Atmel has a utility call WinCupl which allows you to write Boolean logic and create a map file which can be programmed into the 22LC10 PLD. I’ve never used this program before, so a little bit of study will be needed.

 

Retro Computer Build Part 4 – Initial Firmware

At this stage we have the main control signals of the Micro setup. The address decoder is also setup and I have some thoughts already on changing this. The first ROM is now connected as is the console port via the MAX222.

Now we need some code to load into the ROM to see if the computer is actually running. For this, we are going to use assembly language, which is the closest we can get to the bare metal of the CPU. We could go down to machine code level programming but this project is meant to be fun not torture!

We can see from the above screen shot that Assembly Language is easier to read than Machine Code. Yes, in the early days of computers, programs were developed in machine code, then assembly, then more higher level languages such as C and C++.

Today there are many different high level programming languages for computers, such as Python, Ruby and C# to name just a few. These high level languages are used to make programming easier and quicker for us humans, but the computer still needs machine code to run. So when a programmer is finished writing their program, they will compile the program  to produce code that will eventually run as machine code. This is a simplified version of what happens on your PC or Mac, but the end result is the same.

So we’re going to program in Assembly and for this  we will need a Cross Assembler. A Cross Assembler is a program that operates on one type of computer and produces code that will run on a different type of computer. I’m going to use the ASxxxx Cross Assembler program by Alan R. Baldwin, which can be found in the links below. This tool supports a wide range of CPU including the Z80 and 6502.

Another program that will be needed is a Text Editor. We can’t use programs such as Word, Pages or other modern word processor programs, as these add formatting data to the files that the ASxxxx Cross Assembler does not understand. So the best choice is to use just a plain text edit or a program such as Atom (link provided below).

Atom is a great little text editor as it allows us to edit all the files in the project folder. We can look at the errors produced when compiling our program beside the Assembly code, which makes it much easier to debug. Atom has a great plugin that will highlight the assembly code in different colours, to make it easier to read. So we can quickly identify what are instructions and what is data?

To help make life easier, I have created a batch file called Make.BAT. The purpose of the file is to compile the assembly program and produce an output file than can be programmed into the ROM of the computer.

As you can see this Make file is very simple. In the first line we just call the as6801 assembler program and pass in a few switch parameters (-xlos), as well as the assembly source file name retro.asm.

The second line of the Make file calls the linker program, where we pass in the output of the assembler program to produce the file we can load into our ROM. We also pass in the name of the linker file which contains the commands for the linker program.

The retro.lnk file just contains the switch parameters for the linker, the name of the input file, the name of the output file and then the end command for the linker.

When we run the MAKE.BAT command, we get a file called retro.s19, which contains the code that the programer will use to program the ROM with this software.

There are a few steps in the process as you can see, but having this MAKE.BAT makes its very simple to produce the file that the programmer can use from the assembly source code.

Below you will find ZIP file which contains the first draft version of the source code (untested), if you want to have a look. This code was pulled from projects that I had developed back in the late 80’s and early 90’s for this Micro.

ASxxxx Cross Assembler

Atom Text Editor

Version_0_1

Retro Computer Build Part 3 – Console Port

So far we have discussed getting the Micro operational with the basic control lines, some ROM to hold the firmware, and RAM for the storage of data.

What about communicating directly to the Micro? How are we going to interact with it?

One of the reasons why this Micro was chosen, was because it has a built in UART. A UART is a port, that allows communications to and from another computer in a serial manner (one piece at a time). Serial communications are the most common form of communication methods used for computer to computer communications.

Initially, we will use the console port to interact with the Micro, as its primary interface. Over this interface, we will be able to mentor the internal registers of the Micro, write code, and perform some basic functions that will all help get the Micro operational.

There are different forms of serial communications. Some of these include USB, SATA, ADSL, Wi-Fi, and Ethernet. Each of these have their own advantages and disadvantages and specialised use cases. We will be using the RS232 serial communication on this console port.

In its day RS232 was a very common communication standard (it’s been around since 1962, it’s older than me). It’s not found in many new computers any more, as it has been replaced by USB. To enable RS232 for this Micro, we need to add a transceiver, which will convert the serial signals on the Micro to RS232 compliant levels.

As only some modern PC’s have an RS232 port, we may want to provide an alternative method, to allow communication over USB. If we bring out the serial connections from the Micro to a header, we could then connect this to a TTL to USB transceivers. This  now gives us the ability to plug this USB cable into a USB port on a PC or even an Apple Mac.

This is the approach that I’m thinking of taking, as if I don’t want to communicate over RS232. I could just pop-out the RS232 transceiver and plug in a TTL to USB transceiver into a header on the PCB. Then I could plug the transceiver into a USB port only computer and with a terminal program, I can start talking to the Micro.

We will be adding a full RS232 port to the Micro at a later date, as well as an RS485 port for industrial communications(more on that later in the build).

I plan to use a Maxim MAX222 transceiver, which gives us two transmitter & receiving lines that can be connected to the Micro. We are only going to use one of each of these. We might use the other two unused lines for control signals. The nice thing about this chip is that it has a sleep mode, where the chip will go to sleep when the sleep line is tied low. This device generates both the positive and negative supply rails for the RS232 port.

 

Retro Computer Build Testing – 01 Control Signals

In the above image, you can see where I have begun to test the control signals on the Micro. An old Thandar Logic Analyser TA100 was used to test these signals. Any modern logic analyser would also work, but I’m trying to keep this retro, or maybe I was just too lazy to plug in a USB logic analyser to my laptop and set it all up. I’ll let you decide.

You can see in the picture that the Micro’s clock E, the Read/Write line and the address strobe line, have been brought out of the Micro. The E and Read/Write line are inputs to the 74HC00 NAND gate logic, which is generating both a Read Enable and Write Enable signal, both of which are active low.

I’ll upload a quick video on these control signals when testing the address decoder logic.

All initial tests pass with no issues. So far so good.

Retro Computer Build Part 2 – Address & Memory Decoding

In this section we will look at the memory map, address decoding, memory devices and some other control signals that we need to get up and running for the computer.

The 6303 Micro has a 64K address range due to its 16 address lines. There are some key addresses that we need to know about and these are the interrupt  vectors. The table below shows these vectors –  these are memory locations that the Micro jumps to, when one of these interrupts are invoked. The purpose of these vectors is to tell the Micro what address it should look at to get the relevant instructions.

The most important of these is the Reset Vector, which is found at address locations FFFE and FFFF.

One simple method of managing the 64K memory map of the Micro is to break it up into smaller chunks. Back in the day, it was very common to break the memory map into 8 x 8K chunks and then to break these 8K chunks into small blocks.

As we plan to use a 32K RAM chip, we can use the address line A15 with a logic zero, to select this RAM chip. If we use a 74HC138 IC, which is a 3 to 8 line decoder, we can break up the upper 32K address space into 8 x 4K block. We can take the address line A15 with a logic high and the upper three address lines A14, A13 & A12 and use these to access each of these 8 x 4K  memory blocks.

As each of the ROMs are 8K in size, we will need to combine two 4K blocksin the address map to get an 8K address block for the ROM. There are 2 x 4K address blocks that we will use for expansion and video RAM.

The two most important items in this memory map are RAM1 and ROM1. ROM1 contains the code that will be executed when the Micro starts, while RAM1 is the location where program data can be stored.

It is worth saying that the addresses from 0x0000 to 0x00FF are used internally by the mMicro, some of which are internal RAM and internal registers. Addresses 0x0100 to 0x01FF will be used by external I/O, which we will define at a later time. The map below provides a simple overview of what can be used and what cannot be used.

0x0000 -> 0x001F – Internal registers of the Micro.
0x0020 -> 0x007F – External RAM, that can be used.
0x0080 -> 0x00FF – Internal RAM in the Micro.
0x0100 -> 0x01FF – External I/O for the Micro.
0x0200 -> 0x7FFF – External RAM.

A simple 40 Column by 25 Row display will use 1K just for text, with no formatting information such as colours, blinking text, etc. Once we start to add foreground and background colours as well as  other formatting, we find ourselves in the 4K region before we start.

Read & Write Enable

The Micro has a combined read & write line – the read control is active high and the write control is active low. When connected to some devices this is not a problem, but with other devices it can be very convenient to have separate read and write control lines.

This simple circuit provides the necessary signals from the combined  Read/Write line and the E clock signal.

Memory (ROM & RAM)

The memory side of this computer is very simple and we could just start with only 8K of RAM and 8K of ROM to get the system operating. Then later on we could think about adding more of both memory type, but this is not a good idea, as we might design ourselves into a corner with no way out. We have to think about this problem, so we can modify the design to allow the computer to be expandable.

When writing code for this computer, we will run into another problem – how to get the code into the ROM to begin with.  We can, of course use an EPROM programmer to program the base ROM. This is okay for the initial ROM, but if we want to make changes and test code, we won’t want to keep swapping out ROM’s all the time, with each change.

If the initial ROM (ROM1) is an EPROM and contains the basic code to get the system running and a system monitor (assembler), we can use this ROM to write programs in RAM, like a real computer. Then these programs can be tested in RAM and then copied to ROM2 or Ext ROM1, assuming these are EEPROM’s. This can help to speed up development on this computer.

As mentioned above, we can start with a basic 8K RAM – this will be perfect to get things up and running. We can add a second RAM and this will give another 8K RAM. Eventually we will run out of memory space to keep adding 8K RAM devices, so how can we add more RAM to the computer in the future, without having to re-design the computer?

One technique that was very common back in the day, was to page a RAM device. This was where the computer was able to access a certain amount of RAM at a specific moment in time. Then the computer would swap out that addressable range (page) on one device with the same addressable range (page) on a different device.

Think of it like a bookshelf – you start with just one book in your hands, as your eyes can only read one book at a time. When you’re finished reading or writing that book, you place it back on the shelf and take down the previous book or next book, to read or write. This is where the term “paging” came from – we are swapping one page of memory in and out. Only one page is active at a time.

To begin… if we had a 32K RAM, we could use address line A15 to select this RAM. But how could we page this RAM out? We would need to use some other control lines. If we had one pin of the Micro connected to control this RAM and another RAM, we could get a total of 64K RAM from one extra pin. If we had two control lines, then we could get up to 128K RAM in this computer. With a little bit of sideways thinking we could access more RAM memory, without giving up much of our memory map.

In the above circuit, you can see how you can use a 74HC139 and two control lines from the Micro and address line A15 to select one of four RAM IC’s.

The same logic can be applied to the ROMs.