Sunday 30 April 2023

6502 : BEN2 : Terminal and keyboard

 Intro

In the last post on 6502 a week ago I described how I was able to blink an LED and display LCD messages.  LCD displays become very boring very quickly and input has to be facilititated with buttons which dont give much capability.  Clearly the ideal solution is to use a screen and keyboard.  In the past Ben has developed a keyboard interface and a video card interface but neither of these is particularly easy or suitable for my computer.

Back in 2021 when I first got to this stage I followed Dirk Grappendorf's tutorial to attach an ACIA serial UART to my original 6502 system.  This allowed me to connect the 6502 to my PC and I could use a Putty serial terminal session to display output from the 6502 and input information/commands at the keyboard.  This is the perfect solution for me as I don't want a separate screen and keyboard kicking around so it forms the next objective for my project.

 Hardware

Very recently, in the last month, Ben has released a tutorial on connecting an ACIA UART to the 6502 system.  His hardware schematic is very similar to the one Dirk provided and I was able to use it as my guide 



There isn't any more space on my BEN2 board so I need to use the CPU headers to extend 6502 busses and control signals to a breadboard add on.  It was always my intention that BEN2 should focus on CPU, memory and VIA like Ben's original project.  My aim is build a new board JON2 which will have an ACIA on the main board and VIA, LCD plus other peripherals on a separate board.  The current project helps me to finalise wiring required for the ACIA and develop useful software for it.

The breadboard layout is quite straightforward and easy to connect up:


Test Connectivity

Using Ben's schematic the ACIA can be addressed at $5002 (COMMAND) $5003 (CONTROL) and $5000 data.  Our first 6502 assembly program (serial-1-transmit) simply sends three values to these registers.  The command and control instructions setup the serial communications parameters and the third sends a character from the 6502 to the screen.


We set up an FTDI cable attached to the ACIA/UART RX/TX wires and attach the other end to a PC USB port.  We can check which port the FTDI cable is using with the Device Manager and start Putty using the appropriate serial parameters on that port.  Now we can single step through the program and a few seconds later we see, beautiful in its simplicity:

We can also use the Arduino monitor to see what happens each clock cycle.  In the picture below you can see that commands are written in cycles 17 and 23.  The character "j" (0x6A) is written in cycle 29.

The next program (serial-2-send-message) outputs a text string to the screen, waits for input and repeats a prompt each time a character is received.  The program logic includes waiting for transmit buffer to empty before sending the next character.  The program worked fine on slow clock speeds but became unreliable at 1000Hz and above - not much use to me.

These programs were implemented by copying previous programs from my board "JON" and modifying the memory addresses.  The third serial program (serial-3-title-input-subs) started to organise the code into subroutines:
init_acia  initialise communications parameter
putc        display a character
putstr      display a string
getc        input a character
It also incorporated a subroutine "short_delay" into putc to provide an extra gap between characters of about 500 cycles (0.5 milliseconds).  Once this was incorporated the clock worked fine upto full speed 1MHz which is great news.

Basic monitor commands and subroutines

I now needed a set of subroutines to control output to the hardware.  We start off with basic subroutines to display characters and strings on terminal and LCD.  We also need the ability to output hex addresses.  These were very simple to convert from versions working on  previous hardware.  They mainly just needed the hardware memory addresses used for the terminal updated.

With these building blocks I could set up a simple monitor.   It reads a character from the terminal and carries out the associated command:

l               echo a capital L
m            show register values
n             show some LCD values
o             memory dump
p             print a newline character



The follow on shell program (monitor-3-shell-2) is more useful and contains the tools we will need going further.  It allows hexadecimal address input and allows us to jump to a specified address, jump into a subroutine at a specified address or display a range of memory.  All these are great for debugging.


End note

I am very pleased with progress over the last week.  We have been able to take programs that worked previously  (18 months ago) and port them across to our new environment without major problems.

The one main area I have put to one side is the use of ROM for library subroutines.  The current monitor program takes about 30 seconds to load; it is about 1400 bytes in size.  I could reduce this considerably by storing subroutines in ROM.  However that will introduce another set of reliability problems so I am leaving it for the moment.  It may be good to keep the monitor in a separate area of memory and just load a stub program and anything that needs testing at $8000.

The hardware and software have been working reliably and provide me with a platform to move forward to the objectives I previously had issues with.  In particular I aim to get xmodem working.  This will allow me to run programs in RAM and dispense with the Arduino Mega load process. 


Thursday 27 April 2023

XV6

What is XV6

XV6 is an Operating System.  It is a reimplementation of Unix version 6 developed by MIT for educational purposes in 2006.  Originally Unix V6 ran on PDP-11 and was written in an old version of C.  XV6 was written for x66 PCs in ANSI C with a little assembly code. 

The source code of Unix V6 and XV6 is openly available.  XV6 is only about 6000 lines of code and is well-written; individual parts of the OS are easily recognisable.  Although it would be challenging to understand it all, this is the ultimate way of familiarising yourself with Operating System functions and code in general and Unix / Linux in particular.  

Build XV6

Michael Engel has adapted xv6 to run on an Allwinner Nezha RISC-V system and provided the source plus instructions on github.  The instructions look straightforward but it has taken me a while to get them to work.



The first step is to find the riscv-unknown-elf toolchain for building xv6.  I hoped I could use the Nezha itself but it runs riskv64-linux-gnu so that was a non-starter.  I found a Ubuntu package for riscv64-gcc-linux and was able to install it on WSL using apt install gcc-riscv64-linux-gnu.  This enabled me to cross compile programs on WSL and run them under linux on Nezha.  However I need a toolchain with "unknown" in the title as I won't have an existing OS on the target architecture.

I then found riscv-unknown-elf on github together with instructions to build it.  Not as easy as installing a package with apt, but worth a shot.


The instructions were good, I followed them carefully and a few hours and 6.65GB later the build said it was successful.

Next step is to build XV6 using riscv-unknown-elf, so I cloned Micahel Engel's xv6 and built it.  There was a compilation error when building fs.img but google provided a resolution.  I now have a file kernel.bin containing my very own Unix v6 OS which I need to load into Nezha RAM.

FEL mode

There isn't a way to put xv6 on an SD card, as it doesn't contain a disk driver so we have to load it into RAM. Allwinner provide low level routine to do this:


The Allwinner user community Sunxi,  provides wonderful resources for using Allwinner SoCs.  They explain how to install / use the xfel tool in conjunction with a Nezha in FEL mode.

After much difficulty I worked out that I could install the allwinner XFEL tool on a Raspberry Pi (PI41) and connect it to Nezha in FEL mode.  It was comparatively easy to build the XFEL tool and download my kernel to PI41.  I then pressed the Nezha FEL button and connected a PI41 USB port to the Nezha OTG USB-C port.  I could now see a new USB device from PI41.  I connected a USB FTDI serial cable to Nezha GPIO header pins so that I could see a Nezha console.  I loaded and ran a same file oreboot-licheerv.bin first and saw Nezha burst into life.


Finally I was in a position to try my new kernel.  I repeated the procedure with kernel.bin and it worked๐Ÿ˜€๐Ÿ˜€๐Ÿ˜€.  A message, followed by a command prompt flashed up on the screen.  Typing ls showed me a directory listing, including available commands:


I have built a real (but rather primitive) RISC-V Unix OS which I can tinker with or add to as much as I like.

Alternative XV6


As yet I cant think of much to test on my new Unix system and will need to find a suitable tutorial to teach me.  The XV6 is an educational system, used by many universities and there many resources out there to help me.
Whilst looking for something suitable I came across a youtube video which shows a ridiculously easy method of setting up XV6 on Windows WSL. 

 I spent a few minutes doing this and now have a second version available to me.  In all honesty it will be much easier to use WSL rather than a Nezha in FEL mode to tinker, but I have both available, they both "look" the same and are likely to be interchangeable.  I could easily develop on WSL before finalising on Nezha.




Thursday 20 April 2023

6502 : BEN2 : LCD

Intro

A blinking LED is a big step forward in terms of my soldering and making a more permanent, more reliable board.  However we have only progressed as far as part 2 in the Ben Eater 6502 video tutorials.

Assembly

Whereas Ben uses VASM assembler I use CA65 which has better capabilities for me.  BEN2 has the capability to download machine code from a sketch running on the attached Arduino Mega without the need to remove the ROM for programming.  This is the main difference / enhancement from the original Ben circuit.

This was a procedure I developed for previous boards, there are a number of steps to achieve this:

  1. Write a program using Notepad++ on Windows
  2. Compile and link the program using CA65/LD65 into machine code
  3. Convert machine code to a C source file containing the data in an array.
    I wrote a little C utility program to do this
  4. Build the sketch containing the data and download to the mega.
  5. Run the mega sketch which transfers data to the AT28C256 ROM
  6. Reset the 6502 and run the program
Steps 4 and 5 can be run from a Windows command line using a utility arduino-cli.  This enables us to incorporate all the compilation and download steps into a single batch file with suitable checks to highlight any errors.  It make for an easy development cycle, which is very helpful because my programming isn't very good.

Another helpful tool to assist with program debugging is an enhancement to the monitor sketch which outputs address and data bus information.  As each instruction is read in I check the instruction code and show the mnemonic on the Arduino serial monitor.  As we know how many cycles each instruction takes we can highlight each mnemonic as it is executed.

Clock Speed

Previous Ben boards I have built have failed when a full 1MHz clock is used.  Initially, using the Ben Eater clock we can single step through a program and then adjust the clock speed when the clock is running automatically.  However the maximum speed for the Ben clock is about 500Hz so running the clock 2000 times faster at 1MHz is quite different.
To help resolve the problem I built a small breadboard with the 1MHz oscillator on.  It has two binary decoders.  The first provides outputs 500KHz, 250kHz,...., 4KHz and the second one which was set up to provide outputs from 16KHz to 4Hz.
Once a program is working with the Ben clock at 500Hz I can scale it up in increments to 1MHz to check that it still works.

I followed this approach with the LED blink program.  Each flash of the LED takes about 20 cycles so the LED flashes at about 25Hz when the Ben Eater clock is running quickly and this is about the fastest speed that you can clearly see the LED flashing.
In order to test the 1MHz oscillator I needed to slow down the blinking process.  I did this by putting a delay in the blink program using X register to loop counting down to 0 which introduces a delay of 5 cycles per iteration and about 1000 cycles in toal.  It causes the LED to blink very slowly.  I could then increase the oscillator clock speed.  The completed blink-slow program slows blinking further using an outer loop with the Y register and I successfully ran the program at 1MHz.



This represents another major step forward for me as I haven't been able to run programs reliably at full-speed or have the capability to change the clock speed over its entire range.

LCD

LEDs become very boring very quickly.  Following the same route as Ben's original video 4 I connected the HD44780 LCD to the VIA I/O interface and used the test program to check it was working.  This wasn't difficult as I have run the program on the previous hardware.  We now have a working output device.  On the photo you can see a separate breadboard for the LCD just about see Hello, World! on the display.

Initially I used the Ben Eater clock running slowly to test the LCD and saw the characters displayed one by one.  Once I was happy it was working I used the oscillator at increasing speeds until it was running at full speed.  I also tidied up the oscillator to make it easy to run it at speeds from 0.1Hz to 1 MHz easily. I just attach the white clock wire to a colour coded breadboard wire.



Sunday 2 April 2023

Omega Onion : A forgotten gem

I was looking through my electronics drawers a few days ago to find stuff which is no longer useful and can be discarded to make room for new toys.  I came across an envelope containing some Onion Omega kit, a kickstarter purchase I received in November 2015.  I couldn't remember what an Onion Omega does, but it seemed unlikely to do anything impressive, being towards 8 years old.  I was very wrong.


The board is tiny, only 4cm x 3cm.  The easiest way to use it is to plug it in to the mini-dock which gives you a micro-USB connector for power and a serial port.  There is also a USB socket so that you can insert memory sticks etc.  All this is achieved without making without making the system any bigger.  The full dock is a little bigger and provides GPIO pin headers which you can use.

Once the board is connected you can connect the board to a PC USB and connect with Putty.  Switching the processor on shows you a full linux boot sequence giving you console access after about 20s.

There is no SD card so the root filesystem is very small, only 7.4M however you can use a USB stick to add as much as you want

The Onion includes two wifi ports.  The first is configured as an Access Point which you can link to from a PC, iPad or phone to use a browser application.

Once you have set the second port to access home wifi you can access the application from LAN PCs and you also have internet access for software updates or whatever you need.

The Operating System is OpenWRT which accounts for its tiny size.  However the running processes include an extensive list of software and more can be added using the OpenWRT package manager.


Since the Onion is nearly eight years old, unsurprisingly the documentation has been archived but it is readily available and contains some great ideas for projects.  For example you can use python, install a LAMP stack, PHP, NodeJS and cross-compile programs.  GPIO pins are available and controllable for attaching sensors etc.



Overall this is a brilliant little device with a wide range of functions.  It is a shame I forgot about it for so long and I must investigate further.

Initial ideas are:
look at OpenWRT software in more detail to see how so much function is packed into a a small space
Setting up a simple website either using uHTTPd or installing lighttpd
It could provide a local website when we are away in the van.