Lab 03: Breadboard Computer Part 2#

In this lab, we will modify our computer to add output. Then we will write and run a program to display a message on the output device.

LCD showing "Hello, World!"

Preliminaries#

Wires#

You are provided with a variety of wires to connect components together. There should be enough to complete this lab, but you may need to request additional wires. There are four different lengths of wires used in this computer:

  • Extra Small (XS), which can connect holes at most three apart

  • Small (S), which can connect holes at most twelve apart

  • Medium (M), which can connect holes at most 45 apart

  • Long (L), which can connect holes at most 70 apart

There are six different colors of wires, which we use to indicate the kind of signal being carried:

  • Red: Power +5V (VCC) and Interrupts

  • Black: Ground (GND)

  • Blue: Control Signals

  • White: Address Signals

  • Green: Data Signals

  • Yellow: Clock Signals

Prepare for the lab#

Make sure that you have all the items needed for this lab:

  • Computer from Lab 02

  • Electrostatic foam with chips and passive components

  • 22 AWG hookup wire of lengths XS, S, and M

  • Bench Power Supply

  • 2 Banana Wires

  • Tweezers

  • Chip Puller

  • USB Flash Drive

You may wish to organize the wires by length and color to make them easier to find. Keeping things organized and tidy will help you work more efficiently.

The components on the electrostatic foam are organized so that you can easily find each item. You can reference the part number on the foam to the schematic diagrams in this lab to find the correct component. The component ID (unique for each element) is shown on the diagram of the foam below:

Layout of Chips on Foam

There will be a significant amount of reading to follow along with this lab. Details matter, so take your time and make sure you understand each step before moving on. If you have any questions, don’t hesitate to ask!

Within your group, make sure that everyone is participating. If one person is wiring up the computer, another could be reading off the steps and marking them as complete. A third person can then verify that wires have been connected correctly. Mistakes are bound to happen, and this will help you track everything.

Step 1: Fix Bugs from Lab 02#

There are a few things we need to fix from Lab 02 before we can move on. Some of these changes are to give more space for wires, while others fix the computer’s operation (which would arbitrarily halt).

  • Connect the following wires:

    • XS red: T-10-A — VCC

    • XS red: T-12-A — VCC

  • Move the green address wires connected in U-38-A through U-45-A into the B column (one hole to the right)

  • Move the green address wires connected in U-39-J through U-46-J into the I column (one hole to the left)

  • Move the following blue control signal wires:

    • U-52-A to U-53-A

    • U-53-J to U-54-J

  • Move the following address wire:

    • V-7-J to V-7-I

Warning

Someone who did not wire the breadboard should now verify the above steps were completed correctly.

Your updated computer should look like the following:

Breadboard Computer with revisions

Lab Report

Take a picture of your breadboard.

Test Your Computer#

Let’s verify that everything is working correctly before moving on. We will repeat the oscilloscope test from the end of Lab 02.

  • Take your breadboard to the oscilloscope station

  • Plug in the VCC and GND supply wires

  • Connect the probes as follows

    • Yellow: T-14-A

    • Light Blue: U-10-G

    • Magenta: T-15-H

    • Dark Blue: U-52-G

  • Connect the grounds from the probes to ground

  • Make sure the RUN/STOP button is green on the scope. Press it until it lights up green

  • Press ON/OFF on the power supply

  • You should now see four signals recorded, similar to the following:

    Memory Signals

    Lab Report

    Take a picture of the oscilloscope screen showing the memory signals. Label them with their meaning and describe what each signal does.

  • Press the ON/OFF button on the power supply to turn off the computer

  • Disconnect the oscilloscope probes

Next, we will test that all the address wires are connected correctly to the ROM. We will use a logic analyzer to measure the digital signals on each address pin of the ROM chip to verify that the computer is counting correctly.

  • Carefully bend the address wires away from the ZIF socket on the ROM chip. Be sure no wires get unplugged!

  • Remove your ROM chip from the ZIF socket

  • Insert the ROM chip connected to the logic analyzer. It will have many wires connected to it.

  • Plug the white jumper wires in to GND

  • Plug the black jumper wire into U-10-G

  • Plug the purple jumper wire into T-14-A

  • In the DSView software, click Run. It will indicate that the software is waiting for a trigger.

  • Press the ON/OFF button on the power supply. The software should now show a graph of the address lines counting up and down.

    It should look similar to the following:

    Logic Analyzer Output

    Lab Report

    Save a copy of the logic analyzer output to your flash drive. Include it in your lab report.

  • Export the data to a CSV file. Compare it with the expected values in the table below. If they don’t match, verify all of your wires from the latches to the memory chips and try again.

    Address

    32752

    32753

    32754

    32755

    32756

    32757

    0

    1

    2

    32752

    32752

    You can write a simple python program to generate this list of numbers and then use a compare tool (e.g., Visual Studio Code or DiffChecker) to compare the two files. Note that the last number is repeated twice. This is because the computer latches the address one final time as it is halting.

Congratulations, you have a computer with a CPU and memory that is tested to be working correctly!

Step 2: Add an LCD Output#

Next, we will add an LCD display to your computer to display output. This will be our fist IO device. IO devices in x86 use a separate IO address space. That is, there are separate addresses to communicate with the IO devices, which are called ports. Port 0x3F8 is different from memory address 0x3F8. In x86, ports are accessed using special in and out instructions.

Lab Report

Look up how big the IO address space is for the 8088 CPU. Report on how this compares with the memory address space.

We will need separate IO Read and Write control lines (currently your computer only decodes Memory Read and Write). Further, we need to choose which IO device is being accessed base on the address or port used by the CPU. We will use a demultiplexer or decoder to generate enable signals for a variety of IO devices based on the address provided. This device takes a number of address lines and generates a signal for one of \(N\) output lines based on the address. We will use a 74HCT138, which has 3 address lines and 8 output lines.

The schematic of our computer after this step is shown below:

Breadboard Computer with LCD

Connect ICs and Power#

  • Insert the 74HCT138 demultiplexer (U14) with pin 1 at W-4-E

  • Insert the 82C55A PIO (U16) with pin 1 at W-15-C

    • PIO stands for programmable input/output. Some documentation may refer to this as a PPI, or programmable peripheral interface.

    • This is an interface chip that the CPU can write and read from. It can control 24 pins to set them high or low (or read if another chip is driving the pin high or low).

    • We will use this chip to control the LCD display, which expects specific bit patterns and control signals to display characters. By programmatically generating these signals, we are bit-banging the LCD.

  • Move the ceramic capacitor in the power rails between X and Y down to about rows 40-41

  • Insert the LCD module with pin 1 in X-35-C and pin 16 in X-20-C

  • Insert the variable resistor R5 with pin 1 in X-2-D, pin 2 in X-3-C, and pin 3 in X-4-D (pins 1 and 3 are labelled on the top of the resistor)

  • Insert the variable resistor R6 with pin 1 in X-2-G, pin 2 in X-3-F, and pin 3 in X-4-G (pins 1 and 3 are labelled on the top of the resistor)

  • Turn both resistor knobs until they point down at the LCD module

  • Connect the following wires:

    • XS black: W-7-A — GND

    • XS black: W-11-A — GND

    • XS black: W-21-A — GND

    • XS black: X-35-A — GND

    • XS black: X-4-A — GND

    • S back: X-4-J — GND

    • M back: X-20-A — X-3-J

    • XS red: W-29-J — VCC

    • XS red: W-4-J — VCC

    • S red: W-9-A — VCC

    • S red: X-34-A — VCC

    • S red: X-21-A — VCC

    • S red: X-2-A — VCC

    • S red: X-2-J — VCC

    • M red: X-33-A — X-3-A

Warning

Someone who did not wire the breadboard should now verify the above steps were completed correctly.

Lab Report

Take a picture of your breadboard.

Connect Control, Address, and Data#

  • Connect the following signal wires (blue):

    • S: V-46-D — V-50-G

    • S: V-49-D — V-51-G

    • S: V-52-D — V-53-G

    • S: V-45-A — V-50-C

    • S: V-50-H — V-54-H

    • M: U-55-A — V-51-G

    • M: U-57-A — V-55-G

    • M: V-50-J — W-8-A

    • M: U-56-J — W-48-H

    • M: U-58-J — W-47-H

    • M: W-48-I — W-19-B

    • M: W-47-I — W-19-H

    • M: T-40-J — V-46-G

    • M: V-46-J — W-20-H

    • M: W-20-B — W-7-G

    Warning

    Someone who did not wire the breadboard should now verify the above steps were completed correctly.

  • Connect the following address wires (white):

    • S: V-7-J — W-4-A

    • M: V-5-B — W-5-A

    • M: V-24-J — W-6-A

    • M: U-33-I — W-22-A

    • M: U-34-I — W-23-A

  • Connect the following data wires (green):

    • M: U-39-J — W-37-A

    • M: U-40-J — W-38-A

    • M: U-41-J — W-39-A

    • M: U-42-J — W-40-A

    • M: U-43-J — W-41-A

    • M: U-44-J — W-42-A

    • M: U-45-J — W-43-A

    • M: U-46-J — W-44-A

    • M: U-37-E — W-28-H

    • M: U-38-E — W-27-H

    • M: U-39-E — W-26-H

    • M: U-40-E — W-25-H

    • M: U-41-E — W-24-H

    • M: U-42-E — W-23-H

    • M: U-43-E — W-22-H

    • M: U-44-E — W-21-H

    Warning

    Someone who did not wire the breadboard should now verify the above steps were completed correctly.

  • Wire the following signal wires (blue):

    • S: W-30-H — X-22-A

      • HINT: pre-bend the ends of these short wires to fit

    • S: W-31-H — X-23-A

    • S: W-32-H — X-24-A

    • S: W-33-H — X-25-A

    • S: W-34-H — X-26-A

    • M: W-34-A — X-27-A

    • M: W-33-A — X-28-A

    • M: W-32-A — X-29-A

    • M: W-30-A — X-32-A

    • M: W-29-A — X-31-A

    • M: W-28-A — X-30-A

    Warning

    Someone who did not wire the breadboard should now verify the above steps were completed correctly.

Your completed computer should look similar to:

Breadboard Computer with LCD

Lab Report

Take a picture of your breadboard.

Step 3: Program the ROM#

Test the LCD#

Now, we have to write a program to display a message on the LCD. Before doing this, let’s test that the LCD is working correctly.

  • Download a copy of hello.bin to your flash drive

    Note

    Copies of the infinite loop and address test ROMs are also available.

  • Remove the ROM chip from your computer by lifting the bar on the ZIF socket and removing the chip

  • Take your flash drive and ROM chip to the computer with the ROM programmer.

  • Insert the ROM chip into the programmer and the flash drive into the computer

  • From a terminal, run the following command:

    minipro -p AT28C256 -uP -w /path/to/hello.bin
    

    Replace /path/to/hello.bin with the path to the file on your flash drive, which you can do by dragging the file into the terminal window.

  • Once the command completes, remove the ROM chip from the programmer

  • Eject your flash drive from the computer by dragging its icon to the trash

  • Insert the ROM chip back into the ZIF socket on your computer and lower the bar

  • Hook up power to your computer and turn it on with the ON/OFF button

  • You should see the LCD display “Hello, World!”.

    • The left adjustable resistor (or potentiometerpot) controls the contrast of the display. If you can’t see the text, adjust this knob.

    • The right pot controls the backlight brightness. If you can’t see the display, adjust this knob.

  • If you press the reset button, the message should reappear

If this program does not work, double-check all of your wiring from Step 2. You may wish to compare with the reference computer. Congratulations! You have successfully added an output device to your computer!

Lab Report

Take a picture of the LCD displaying “Hello, World!”.

Write Your Own Hello World#

Now that you have a working LCD, let’s write our own program to display a message on the screen. Use the same development environment we set up in Lab 1 to write and assemble your x86 program.

Download a copy of lcd_helper.asm to your computer VSCode project. This file contains the assembly instructions needed to set up the LCD display.

A few things to note:

  • The LCD data pins are connected to PORTB of the PIO chip

  • The LCD control pins are connected to PORTC of the PIO chip

  • The PIO chip has four control registers. Each is accessed from a unique IO port on the x86.

    • Three of the ports are used to read/write the pins on the chip, which are grouped into three 8-bit ports: PORTA, PORTB, and PORTC:

      • PORTA is located at 0x4000

      • PORTB is located at 0x4001

      • PORTC is located at 0x4002

    • The fourth port is used to control the chip itself (e.g., whether a PORT is in read or write mode):

      • CTRL is located at 0x4003

Set up a new assembly file (e.g., lab3.asm) to write out Hello World program. You can use the following template to get started:

; simple hello world kernel for the ASM86-512 computer
; by YOUR NAME
BITS 16

; the ROM is 32KiB, so the chip will start of 0xF8000...the highest 32KiB of the 
; address space
ORG 0xF8000

; include the helper functions
%include "lcd_helper.asm"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Print Hello World Message                                                    ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  ; set the DS to the ROM address space
  ; this is useful if you want to use the lodsb instruction
  xor ax, ax
  or ax, 0xF000
  mov ds, ax

; TODO insert your code here

; at the end of your program, add a halt instruction to stop the CPU
; we'll follow this by a jump back to halt just to be safe
halt:
  hlt
  jmp halt

; TODO put any data here

; pad up to 0xFFFF0 (the location of the reset vector)
  times (0xFFFF0 - 0xF8000) - ($ - $$) db 0

  ; this is the code that will be run on power-up
  ; we will do a long jump (a jump with a segment) to the start of our ROM
  jmp 0xF000:0x8000

  ; pad to 0xFFFFF (the end of the address space)
  ; $ represents the current address, and $$ represents the starting address
  times (0x100000 - 0xF8000) - ($ - $$) db 0

Fill in the TODO sections with your code. Note that we are running with ROM only. That means you can use the stack or any call, push, or pop instructions.

Interfacing with the LCD#

To communicate with the LCD, you will need to:

  • Load the byte of data you wish to send to the LCD into al

  • Load the control register into dx

  • Issue the out dx, ax instruction to send the data in al to the port stored in dx

Full documentation on the LCD commands can be found in the HD44780 datasheet; however, we will describe the basics here.

To write a character to the LCD, you will need to:

  • Output the ASCII character to the PORTB register

  • Set the RS bit to 1 (indicating that you are writing data)

  • Send a pulse to the E bit (indicating that you are sending data)

  • Set the RS bit back to 0

  • Wait for the LCD to process the data

        gantt
  title LCD Data Write Timing
  dateFormat  HH:mm:ss
  axisFormat  %H:%M:%S
  section LCD Write
  E Bit Pulsed               :done, 00:00:04, 00:00:06
  RS Bit Set to 1            :done, 00:00:02, 00:00:08
  ASCII Data Valid on PORT B :done, 00:00:00, 00:00:10
    

Checking to see if the LCD has processed the instruction to write the character is a bit more complicated. The LCD has a busy flag that is set when it is processing an instruction. To check if the LCD is busy, you will need to:

  • Switch PORTB to input mode

  • Set the RW bit to 1 (indicating that you are reading data)

  • Send a pulse to the E bit (indicating that you are sending data)

  • Read the data from the PORTB register

  • Check if bit position 7 is set to 1

    • If the bit is 1, the device is busy and we need to wait

    • If the bit is 0, the device is ready to accept more data

  • Set the RW bit back to 0

  • Set PORTB back to output mode

To write A to the LCD, the basic process looks like:

  ; write the character `A` to the LCD
  mov al, 'A'
  mov dx, PORTB
  out dx, al
  ; set RS bit to send data
  mov al, RS
  mov dx, PORTC
  out dx, al
  ; set E bit to send data
  mov al, RS | E
  out dx, al
  ; clear E bit
  mov al, RS
  out dx, al
  ; clear RS/RW/E bits
  mov al, 0
  out dx, al

  ; wait for the LCD to process the instruction
  ; set PORT B to input
  mov al, 0b10000010
  mov dx, CTRL
  out dx, al
p1:
  ; toggle the RW pin
  mov al, RW
  mov dx, PORTC
  out dx, al
  ; set E bit to send instruction
  mov al, E | RW
  out dx, al
  ; read the busy flag
  mov dx, PORTB
  in al, dx
  and al, 0x80
  ; if the busy flag is set, try again
  jne p1
  ; clear the E and RW pins
  mov al, 0
  mov dx, PORTC
  out dx, al
  ; set PORT B back to output
  mov al, 0b10000000
  mov dx, CTRL
  out dx, al

  ; output 0s to PORT B
  mov al, 0
  mov dx, PORTB
  out dx, al

  ; output 0s to PORT C
  mov al, 0
  mov dx, PORTC
  out dx, al

Adapt this code into your program to display your message on the LCD. You should only need to change the first line. This code will like be the body of a loop.

Testing Your Program#

Danger

Ensure that your computer is powered off (the green power light on the supply is off) before inserting or removing the ROM chip!

  • Assemble your program using nasm:

    nasm -f bin lab3.asm -o lab3.bin
    
  • Copy the lab3.bin file to your flash drive. Remove the ROM chip from your computer and program it with your ROM binary:

    minipro -p AT28C256 -uP -w /path/to/lab3.bin
    
  • Insert the ROM chip back into your computer and power it on

  • You should see your message displayed on the LCD

Lab Report

Film a video of your computer displaying your message on the LCD. Include the video in your lab report upload.

Step 4: Lab Cleanup#

Before you leave, make sure to clean up your station. This includes:

  • Placing all leftover components back in the foam or in the bags

  • Coiling up the power wires and placing them by the power supply

  • Turning off the power supply

  • Leaving your station neat and tidy

Step 5: Lab Report#

Collect your notes into a well formatted report that details your progress through this lab assignment. Begin the report with a brief abstract that describes the purpose of this lab (in your own words) and what you were able to achieve.

In the remainder of the report, be sure to address the callouts throughout this lab description. When screenshots or images are requested, provide a brief caption describing what is being shown.

Make sure to also submit a copy of your final program that displays your message on the LCD as well as a video of your computer running.