Labels

Wednesday, 23 June 2021

Nezha : RISC-V Linux SBC

The title of this post contains ample details to excite (me).  The "open source" architecture RISC-V is well on its way into the mainstream.  To be of general interest it needs to run Linux and a price point of $99 is well below previous development boards.

I ordered one as soon as I saw the indiegogo crowd funding page on 21st May.  Crowd funding was complete by 26th May, boards were shipped about 8th June and mine arrived yesterday.

Nehza has a similar form factor to a Raspberry PI and similar connectivity for HDMI, power, Ethernet, Wifi, Bluetooth, USB and Audio.  In a direct comparison RPI4 is faster, with more capabilities but that isn't the point.  Here we are running RISC-V not ARM.  Personally I feel this is an important moment in the evolution of systems.


I connected up the board, inserted the SD card provided and booted it up.  It started a Debian desktop and allowed me to signon.  Once ethernet was connected, I could happily SSH into the system.  This is perfectly what I hoped for.  I have a new (but familiar) world to explore.

Friday, 18 June 2021

6502 : CC65 and C Programming

Until now I have used VASM to assemble my 6502 programs and it has done the job well.  I have noticed that there are a few 6502 C compilers and I recall from my bare metal programming that you (only!) need a stack, a library and some initialisation code for a C environment.  There appears to be a WDC compiler which isn't well used and CC65 which is popular and practical.  As a first step I will move from using VASM assembly to CA65, which is a part of the CC65 program suite.

CA65

As CC65 is available as a debian package and I use Windows 10 for my 6502 development environment I installed it under WSL (Windows Subsystem for Linux).  I can now take assembler source programs, which are written in Notepad++ and copy the to directories I use for WSL.  Assembly with CA65 starts with running ca65 at the command line with a few options specified.  In particular we have to specify --type as "none"; CA65 is happy to assemble for various microcomputers (C64, Apple ][, etc) but my home brew system has no extra requirements.  The output listing shows that it creates the same output byte for byte as VASM.  The output file is formatted for linking modules and libraries so although I have nothing to link in I also need to run the linker LD65.  So I replace my vasm command with:
    ca65 -l map -t none testbed.s    and
    ld65 -o testbed.exe -t none testbed.o
Now I can process and load the program via the Arduino Mega as previously.

CC65

Creating a C environment is somewhat more challenging.  Luckily Dirk Grappendorf has set this up for his 6502 which is very similar to mine and has been kind enough to create a github repo containing the code.  I downloaded the repo and set about making my own minimal code base.  My target is a "hello, world" program which outputs a screen message.


There are very few files in the solution:

cc65.lib is the most significant, it is the library of C functions needed for stdio and stdlib.

firmware.cfg defines the different areas of memory in the computer, ROM, RAM layout is specified so the compiler can do the hard work in placing files.

startup.s is the initialisation code which sets up the stack, initialises memory and calls main().

zeropage.s provides the layout for variables in the zero page.

acia.s contains the serial programs init, getc, gets, putc, puts which we will use for screen output.

interrupt.s contains skeleton interrupt processing code (which I am not yet using)

io.inc65 defines a long list of constants for ACIA, VIA and other devices.

Once I edited firmware.cfg for my memory configuration, io.inc65 for my acia addresses and acia.s for my serial port config (19200 baud) I could compile and link the program with a single command:
   cl65 -C firmware.cfg -m firmware.map -o main.exe main.c acia.s zeropage.s startup.s  interrupt.s cc65.lib

This created a 32KB file which can be burned into my ROM.  In fact I use my Arduino Mega to write ROM so I don't want the entire 32KB file.  My program is less than 1KB in size.  I amended firmware.cfg to "pretend" I only had 2KB ROM, which created a much more manageable file.  Amazingly, thanks mainly to Dirk, my C environment works and without too much trouble I can read and write the screen, here is the first test program. 😊😊😊😊😊


C lib

So far we haven't used any C library functions, our example uses Dirks acia_init,acia_getc, and acia_putc for IO.  In fact I can remove include statments for <stdio.h> and <stdlib.h> without issue.  Of course C programs without library functions are not particularly useful, we really want to have them available to us.  I tried adding the abs() function from stdlib.h and it worked fine.  I also successfully tested strcpy() from <string.h>.  

<stdio.h> is more difficult to test; I haven't "linked" my I/O routines into C streams yet and my hardware/software doesn't have interrupts setup so I wouldn't expect I/O to work.  I did hope that I could use the sprintf() function to format output for me and wrote a test program but it didn't work.  I will look into the problem in more detail when I consider cc65.lib.  In fact cc65.lib was provided by Dirk I need to look at how he created it or derived it from cc65 provided libraries.

My mechanism for loading programs into ROM  using an Arduino Mega sketch is wonderful, it is automated and requires no removal/insertion of chips.  Using C and library functions necessarily means that our programs are increasing in size - programs may be 4KB or even more!  The Arduino environment only has 8KB for variables so I had to use the PROGMEM mechanism which directs the compiler to store nominated constants in ROM only.  A 4KB program takes over a minute to load which is not bad really but I will need to look at speeding up the sketch.

SIM65

CC65 also contains a simulator SIM65, which you can use to test your C programs. It is easiest to use with programs containing standard C library functions (printf etc).  You can add in assembly language subroutines from C.

Of course, without the real hardware, low level "driver" functions don't have much meaning but you can "simulate" them.  For example my "term_puts" assembly routine could be replace by one which calls printf.
In fact most or all emulators have this problem, they can't exactly replicate my hardware.  If I aim to design my hardware / software to be similar to Apple ][, BBC Micro, C64 etc I could use their full emulators to test programs but even then my hardware will be quite different from the original product.

I am not sure if I will use this but it is another great tool to have available.



Tuesday, 8 June 2021

6502 : Screen and Keyboard

 

I am thinking that the 6502 should have its own screen.  Traditionally an RS232 serial monitor would be appropriate for the time.  Back in the day I used a VT100 (text) and Tektronix 4025 (graphics) terminal attached to a PDP11 minicomputer.  I did consider buying a small terminal but, unsurprisingly, they aren’t made anymore.


I have an ESP32 and Waveshare 3.5” LCD screen which could be used.  Commands sent to the ESP32 could then be interpreted and the results displayed on the LCD screen.  Graphics would be done by commands as they were on Tektronix graphics terminals.  This is not similar to home computers which used memory map graphics.   ESP32 may be able to do cycle stealing graphics where it interleaves display and 6502 operations.  This would be aligned to the home computer ethos but quite a complex project.

I then considered how an RPI could be used.  Instead of connecting 6502 serial to the PC running putty we could connect it to my RPI 2B (called PI2)  which has a 3.5” screen attached.  I wasn’t sure how to connect my FTDI cable to the RPI.  I connected up with a loopback wire between RX and TX and then set about working out how to use it. 

Using a normal ssh session on PI2 I tried a utility miniterm (which seems to be python but works for me at the RPI command line) and it gave me a choice of ttyASM0 (console) and ttyUSB0  (serial port).  dmesg also shows ttyUSB0 being attached when I plug in the FTDI.  With miniterm using the serial port characters typed at the keyboard were echoed via the loopback wire.  I then setup miniterm to access the 6502 (miniterm /dev/ttyUSB0 -s 19200.  Rebooting the 6502 shows me output in the miniterm session.

PI2 has a Waveshare 3.5” screen directly connected to GPIO pins.  At installation the screen is configured so it is a console.  When PI2, which runs headless, is turned on boot messages are displayed.  On completion there is an autologin to user pi.  Connecting a USB keyboard to PI2 allows keyboard input at the console.  If I start miniterm at the console I see 6502 output on the LCD screen and can enter commands as 6502 input on the keyboard.  JOB DONE!

This is a brilliant solution, for a few minutes work we have a small self-contained text screen and keyboard for our 6502 system.  Purists will rightly argue that it is a modern powerful SoC acting as a dumb screen for a primitive system.  However a modern dumb terminal would be more expensive and have many components.  An old terminal would be real retro hardware, but we aren’t in that business.

miniterm doesn’t have many features and doesn’t support ANSI escape codes well.  I  tried minicom and putty but they didn’t work well for me but I settled on the linux utility screen which is simple but effective.

I can visit the screen topic later to see whether I can find a bit-map graphics terminal solution but for now I am happy with the system.

Monday, 7 June 2021

6502 : Program Library

ROMLIB4

Our subroutine library ROMLIB3 is saved in memory at $E000.  There is nothing special about the code, we could store programs, program snippets or data in the library.  In fact I decided to store programs in ROMLIB4 starting at $E400.

As a first example I stored echo.s, my previous simple command line in ROMLIB4.  Following Dirk Grappendorfs monitor I added a command "jhhhh" to allow the user to jump in to a program.  For the first example "je400" causes the echo program to be invoked with its simple command line.  I added an "e" option to echo which exits back to cmdline with a "jmp $8000" causing it to reinitialise.

Previously I have written two diagnostic programs to show messages on terminal and LCD without using RAM.  I added these to the program library so they can be started from the monitor.  Alternatively they can be started by changing the contents of the reset vector at FFFC, FFFD or writing a short program, loaded at $8000 with a statment "jmp $E4xx".

As with the subroutine library I need to be very careful that labels are unique.  For programs there is more likely to be a clash as one program is often used as the basis for the next.  To make life simple I add a suffix, 1,2,3,4,... to the labels in successive programs to make them unique.

Instead of jumping to a program address from the monitor we would like to do a jump subroutine to an address in the subroutine libary with a call "shhhh", for example "sE1E2" to display registers and return to the monitor.  The "j" jump option used the "jmp (indirect)" opcode but the 6502 / 65C02 doesnt have a "jsr (indirect)" opcode.  I simulate this by putting a return address on the stack and jumping to the subroutine as shown below.

TESTBED

I can now add my cmdline.s to the program library (its start address is $E5D7).  I start a new program testbed.s which starts with the instruction "jmp $E5D7" which is a 3 byte opcode at $8000.  The program itself continues at $8003 and in fact I display "#" as a terminal prompt followed by options which I want to test.  One of the options is "e" which takes us back to the monitor.

Now when I compile and load the program I see my cmdline monitor.  I can then issue the command "j8003" which takes me to the "#" prompt and allows me to run functions I am testing.  Typing "e" takes me back to the monitor.

The testbed program is only about 100 bytes so it assembles really quickly.  The program logic is in ROMLIB4/cmdline.s and subroutines are in romlib3.  This gives me an excellent testing environment.







6502 : Reliability and diagnostic information

Reliability

Our environment for developing and running 6502 programs is still not reliable.  Since I put the hardware on a stand, physical connectivity has not been a problem.  I am past the stage where single stepping through 6502 programs looking at bus signals using the Arduino Mega is regularly required.  However when I turn the 6502 on, or reboot, the system doesn't always come up properly.

When you start the system  the Mega runs its program which typically stop the 6502 whilst it loads a program into ROM.  It is possible to use an external 5V power supply instead and disconnect both 5v and GND from Mega to breadboard.  This avoids any complications due to the Mega doing unexpected things.  It may be necessary to do a reset for the 6502 to boot normally.

I start a new terminal-based "monitor program called cmdline which has options for checking various system information.  Initially I set up power up self test (POST) subroutines for terminal and LCD but there isn't much testing the 6502 can do at start up without using terminal or LCD for output.  On the basis it is obvious if LCD and terminal are working I dispensed with POST.

cmdline has an "r" option which jumps to $8000 to reboot and initialise the system.  Interestingly this is very dependable, implying that startup problems are power or hardware related and the software is working just fine.

Diagnostic subroutines

Option "d" calls a subroutine to display register values: Accumulator, X, Y, P (status flags), S (stack pointer) and PC (Program Counter).  Program status flags are made available by pushing them on the stacvk (php) and popping them (pla) to the accumulator.  The TSX command provides access to the stack pointer.  The program counter is actually available st compile time and is retrieved by loading a label value.

The term-register subroutine is not very useful at the command line as it just shows values when the 6502 is at the monitor prompt; it is more helpful as a subroutine call when testing a program to print out register values.

Dirk Grappendorf has a monitor program which allows the user to display a range of memory addresses.  It is very useful for looking at page zero ($0000), stack ($0100) and working storage ($0200).  We implement "mhhhh" where "hhhh" is the start address to list.  It is pleasing that we can copy Dirks assembly code to convert hex numbers into our program - I don't want to have to write all the code myself.

I was also able to copy another subroutine PRIMM, courtesy of Lee Davidson at 6502.org.  This allows you to put display text in your program immediately after a subroutine call, which avoids situations where the text and code become separated when copying program snippets around.

One issue we face when using the 6502 system is that we dont know what program is running.  To improve the situation we display the program name and assembly time on the LCD and provide an option to display it on the terminal.
We capture the information  to be added within the formatHexProgram and forward variables which are copied into the writeROM sketch.  The sketch loads the information at $FFE0-$FFF7 in ROM so that subroutines can show details on screen or LCD.



Sunday, 6 June 2021

6502 : Library and Shell User Interface

Library

We now have a number of subroutines for simple tasks which will be useful in a variety of programs.  It doesn't make sense to process them every time a program is assembled.  It is much better to save them permanently in an area of ROM, that is to say a library.

We start with a modified assembly procedure which saves object code starting at address $E000.  The library source is a set of subroutines (in alphabetic order) which I call ROMLIB3 (because it was my third attempt!).  Once these have been assembled and saved in ROM we look at the assembly listing to find the start address of each subroutine and add the address as a symbol in our program.  By convention I make the symbols upper case.  I can then delete the source subroutine from the program and replace the jump subroutine name with a symbol.


In this way we can use any or all subroutines in the library simply by adding a symbol table containing start addresses to a program. 

The upload sketch to store hex in ROM can only process about 30-50 bytes per second.  Our programs were increasing in size towards 1KB and we are now down to about 400 bytes so load time is halved to about 10s.

Initial library contents include:
Terminal i/o: getc, init, putc, putstr, hex_digit, hex_digits, registers (to show current contents)
LCD output: init_VIA, init_LCD,  clear, instruction (control command), putc, wait (until ready), hex_digit, hex_digits, putstr

We do have to be careful with our organisation when using libraries.  It is not permissable to change the contents of a library member as this will mean that the start addresses of all subsquent subroutines change and in turn the symbol table in each program needs to be amended and the program re-assembed.  Instead, if a subroutine must be altered, its labels are all prefixed with "OLD" and the new version of the subroutine added to the bottom of the list.  The latest program can then use the new version whilst previous projects remain unchanged.  

Shell

Rather than load a program which executes a single function it is useful to have a "monitor" program.  In fact this is a simple "shell" program such as bash, which is loaded when the user signs on and allows them to carry out various function.

Our shell starts of simple as shown in the picture below.  It shows a title on the terminal, in this case "Ava go" and a ">" prompt.  User input is a single letter, valid choices are l,n,o,p and Return.  The "l" option simply prints an upper case "L".  I find this very useful to check if input is working. "n" displays a hex string on the LCD screen, "o" is a memory dump progrm (wip), "p" tests the newline and "Return" shows a prompt.

We have now moved on from building hardware and writing programs which utilise it to a computer with a user interface and subroutines available to make the programmers life easier.

In the next episode we will expand our shell program to help us check on the current status of the computer.




Wednesday, 21 April 2021

6502: Progress on many fronts

 In the three weeks since my last 6502 blog I have been busy both with hardware improvements and software development.  On the hardware front, a more useful clock has been added, an LED and four buttons have been added to reflect Ben Eaters finished 6502 system and the LCD has been put on the board.  I have also developed a rudimentary hardware error diagnosis procedure.
I have enhanced the vasm/sketch/batch file so a single click can compile and download a new 6502 program and provided some subroutines to write to the screen and use the LED.
These are described in a little detail below.

Subroutines

So far we only have a couple of 6502 assembly programs: one that writes to the screen then accepts input and the other which writes an LCD message.  Assembler is a pain to write so we put everything into subroutines which we can easily re-use in other programs.  In due course we will put the most commonly used into ROM as library routines.  We can immediately add some subroutines based on code we already have:

  init_acia  setup the terminal for i/o   
  putc        write a character to the the terminal
  getc        read a chacter from the terminal
  putstr      write a string to the terminal

Simplified compilation

Previously (see 6502:serial console:software) I simplified my code development cycle to two steps: (1) compile a program and format the executable as input to a sketch; (2) upload the sketch.  Although this beats the pants off removing and replacing an EEPROM all the time it is still tedious.

I found that you can actually use many Arduino IDE functions from the command line using arduino-cli.  I installed it in a folder next to my assembler and tinkered with its configuration file (arduino-cli.yaml) to locate files in line with with my IDE (which uses the portable scheme).  My hardware wasn't recognised automatically in the Windows environment and I had to search a bit to work out that the required platform is arduino:avr:mega.

Once files are in the right place and a batch file links the commands together it is very easy to compile an assembly program and upload the executable in a sketch as a single operation.  This makes software development a lot easier as I forget about the environment and click on a compile icon to build and load a new program version.

I also arranged to save compiled sketches, including executables, as HEX files in the program folder so that I can easily load and run one using a batch file.  I have a batch file for each commonly used program so I can switch between programs easily.

TikTokClk

Ben's 555 clock is a very good learning project but I find it cumbersome in practice.  I set up an Arduino nano to provide a clock pulse on a GPIO output.  Initially I used the serial monitor and delayMicrosecond() function to control the output speed or single step mode.

Once this was working I made it much more useable by adding two buttons to the nano.  One button is used for single stepping.  The other switches between a selection of clock speeds (10Hz, 100Hz, 1kHz, 10kHz).  delay and microSecondDelay aren't very good so I used the micros() function to tell me how many microseconds since the last tick and transition the clock output at the end of an interval.

Button debounce is a nuisance so I used a simple Arduino ButtonDebounce library to control them.  I found this very effective.  You need to make sure your main loop executes quickly and include a button status update method for each button.  A callback then takes control when a valid press or release is identified leaving you to specify what happens next.

As I didn't want to connect the nano during operation I set up 3 LEDs to indicate the speed.  I used D13, which has the builtin LED attached, as my clock output so I can always see if the clock is running.  It is possible to see individual clock pulses at 10Hz, but after that the LED is continually lit.

Hardware Revision 5

Now that we have a more compact clock I can remove the Ben clock and add the LCD screen to the same breadboard segment.  I also added 4 buttons and an LED connected up to the remaining 5 VIA pins.  These are shown on Ben's 6502 photo but I haven't seen them discussed on his videos yet.

By the way I subscribed to Ben's patreon.  His tutorials have been massively informative and fun so I thought it only right to give something back.  He arranges it so you don't pay per week/month/quarter, you only contribute each time he releases a video, so I will continue to benefit as I contribute to his costs.

As I now have a good hardware build, I tidied up the wiring, to remove those long wires which always seem to get added as a design moves on.  I also purchased an FTDI cable so that I don't have my FTDI board sticking out.  With the buttons I use and the LCD and LEDs all at the bottom of the board I think Hardware rev 5 looks good.



What other hardware could I need?  Well an SD card would be good and some sort of integral graphics screen would help, but at the moment I feel they are luxuries.  I am happy I have a good environment with rev5 to write assembly programs with ample input / output facilities.

Diagnosis

When making changes to the hardware or even in normal use, it is possible that a bad connection will prevent the hardware from working.  There are proably 100 wires and 200 pin connections currently in the design.  A trial and error approach to fixing problems is often doomed to be a long and frustrating series of failures.

We keep the Arduino Mega attached to our 6502 system (primarily for downloading programs) and it is also vital for low level debugging.  Whith the 6502 clock stopped (i.e. in single step mode) we can use the eeprom-write sketch to test writing and reading the ROM, that is to say that we can check that ROM connections are working.
We also need to check the program in ROM is the one we expect.  If a different program is loaded, the 6502 may not be doing what we expect.  We can check the assembly listing output file against the executable loaded into ROM.

Next we check that 6502 boot sequence, stepping the processor and using the eeprom-monitor sketch.  This shows values loaded and after a reset it should be possible to see the reset vector FFFC and FFFD loading start address 8000.  Stepping a bit further will show us whether the stack is being used properly (i.e. RAM is working) as the first subroutine is executed. 

If the ROM, RAM and 6502 are ok the problem may lie with I/O.  Either a screen output program (using ACIA) or an LCD output (using VIA) should work so they can be checked independently.

This scheme should allow a failing component to be identified and individual pin signals can then be checked with an LED as necessary.

LED Flash

With a working 65C22 VIA, adding an LED output should be simple, it is only necessary to raise a VIA output pin high/low to turn on/off the LED.
In practice it is a little more difficult.  We have to write a byte to portA each time we change a bit, so if we are controlling the LCD with portA bits 5-7 we need to keep bit 0 as previously set so the LED is in the same state.  I thought that setting the pin as an input might preserve its state but the signal is turned off.  Consequently the LED bit has to be ORed with LCD bits before writing them.

Having worked this out it was an easy matter to set portA bit 0 to 1 or 0 for 255 clock cycles by decrementing an X register counter to zero in a loop and changing the LED pin state each time the value reached zero.  Unfortunately this ties up the processor so is very inefficient.  I will investigate a solution using interrupts, or perhaps a state machine.

TinyCAD

Having finished hardware rev 5 I should update the hardware schematic for Arduino Nano, LCD, LED and buttons.  I am learning the TinyCAD package so I can provide a better representation.  As the diagram becomes more complex the chances of errors increase.  As yet my skills have not advanced far enough for a complete schematic.

Sunday, 28 March 2021

6502 : Add RAM and VIA

 My 6502 system now has a working screen but as yet no RAM.  I find the idea of a working computer with no RAM strangely intruiging, but it is time to move on.  On the face of it, adding RAM is easy as I have done it before following the Ben Eater tutorial and its setup is very similar to the ROM.

RAM

Indeed 62256 memory connection is mostly straightforward.  The chip is located adjacent to the ROM and address/data pin connections are the same.  I rewired two existing NAND gates so they were in the same configuration as Ben's tutorial and used an extra NAND for RAM address wire setup as Ben did.

All worked well, with the proviso that it took a long time.  I found it vital to update the wiring schematic (now Hardware revison 3) before starting and to list out all the changes to existing wiring before I started.  As the circuit becomes more complex, any faults introduced can be very hard to identify.  Loose wires coming out are quite difficult to diagnose but an incorrect wiring change is even harder.

Initially I just added the RAM and wrote a small program to test reading/writing addresses and using the stack in a subroutine call.  I then moved theACIA serial chip from address $0000 where it conflicted with RAM to $6000, which Bens tutorial had previously made accessible for the VIA chip.

It feels very good indeed to have a computer with RAM, ROM, screen input / output which I can program easily in assembler language.  

VIA

To complete my basic computer I need to connect the Versatile Interface Adapter (VIA) so that I can access other peripherals.  I am hoping that this will be my last device attached to the 6502 directly as I have concerns I could mess it up or break it if I do too much tweaking.

Although Ben's initial LCD connection to VIA is not required, it does provide a useful test and confirm whether VIA is working so I connect / test the LCD as previously.

VIA connections are not complex, 8 data pins, 6 address related and 4 control pins.  I need an extra logic gate, and I connected a HCF4069 hex invertor for this.  I moved the A13 address pin from ACIA to VIA so that it uses address $6000.  I then inverted A13 as input to ACIA which is now at $4000.

I found that updating my schematic was vital before making connections as it is VERY easy to confuse yourself.  It is also sensible to write down each connection you need to make beforehand.  Thirdly, testing regularly that the original functions still work provides confidence that important existing pins have not been dislodged by the work.

On completion of the connections I could check that ACIA worked at its new address and then connect an LCD to the VIA as per Ben's instructions and check it work.  All is good, our computer now has RAM and I/O capabilities :) :) :)



Monday, 22 March 2021

6502 : Serial Terminal

 In my previous Ben Eater: 6502 post I set up a 6502 + EEPROM board with a Mega attached which enabled me to download programs with the ROM in situ.  As a second major enhancement, I need it have keyboard input and display output.  Ben does a diy video controller board but that looks painful.  Much more practical for me is to use a serial port with an emulated terminal.  I guess this isn't a pure solution, however I could make it one if I went on ebay to buy an old terminal.  In fact I did consider buying a real DEC VT100 as I used one for much of my (short) programming career but that would be overkill.

My objective is to provide a serial terminal input and output on my 6502 board using hardware compatible with the 6502 and EEPROM.  The best solution used by 6502 afficionados is an  ACIA (Asynchronous Communication Interface Adapter) W65C51 which interfaces to an FTDI chip and provides serial transmit / receive upto 19200bps.  An excellent example circuit and associated program is provided by Dirk Grappendorf.  I particularly liked that the program doesn't use RAM so I could proceed with the program before adding RAM to my computer (I never thought I would be able to say that).

Hardware

W65C51 chips are available on ebay for about £5, and they also require a 1.8432MHz oscillator (HC49) for another £1.




To check my understanding of the hardware I added the W65C51 to my board and connected up power, address, data and control pins (output-enable, chip-enable, write-enable).  I was then able to set pins in a sketch to control ACIA.  ACIA was setup with RS0=A0, RS1=A1 and /CS1=/A15 so that ACIA registers can be accessed at addresses 0000, 0001, 0002, 0003. 

I could then send a character to the serial port at 19200baud with 3 commands:
  Write 0B to address 0002             (for no parity, no echo, no interrupt)
  Write 1F to address 0003              (1 stop bit, 8 data bits, 19200 baud)
  Write characters to address 0000
 

6502 Connection

Once I knew the hardware was connected properly and working I could write a program.  For the previous test 6502 and EEPROM were turned off, so I turned them on and tried saving the simplest possible program to EEPROM and running it from the 6502.

loop:
  8000 LDA #0B             A9 0B    
  8002 STA $0002          85 02   store COMMAND byte
  8004 LDA #1F              A9 1F   store CONTROL byte
  8006 STA $0003          85 03
  8008 LDA #6A             A9 6A   write letter "j" on terminal
  800a STA $0000          85 00
  800c JMP loop           4C 00 80 start from the beginning

I used the monitor sketch to debug the program.  It was easy to have a bad or incorrect connection so I spent some time producing and checking the schematic above to ensure my hardware was set up as expected.  I used a couple of NAND gates to get the ROM and ACIA addressing signals as I wanted them.  In the listing below you can see the three write commands at lines 59,64 and 69.


Software

With a simple program working I could concentrate on providing a working programming environment. Initially I used VASM to compile a simple program and then manually transcribed the bytes into an array in a sketch for download to the EEPROM.  However this quickly became painful and I wrote a small utility program in C to read the VASM hex output file and format it into a text file which was included in my sketch as progdata.h.

Initially I had lots of manual intervention to stop the clock, download data, start clock and reset the 6502/ACIA.  It was easy to get the mega to sketch control the reset and clock pins during EEPROM download. 


I now have an easy programming environment which only requires two steps (1) compile program and format output into a sketch (2) download the sketch with clock paused, then reset the processor.

In the test program I used screen codes to erase and colour text to give a nicer result.











Sunday, 21 March 2021

C graphics programs

 For some reason I had a sudden urge to work out how to write graphics programs.  The natural place to start is on Windows.  I have Mingw installed so I can run X11 programs, in particular X11 programs written under WSL can be run in a window.  The Xeyes sample is shown in the screen shot below.

I also have code::blocks installed so I had a quick look at whether it could do anything for me.  C::B includes a number of openGL related templates.  I tried the openGL template first, it compiled cleanly and gave me a lovely rotating triangle.  I then tried to use GLUT which is mentioned in a number of Google articles on the subject.  GLUT is obsolete and replaced by freeglut which needs some tweaking to get working under C::B (directions provided by GeekforGeeks). Again it provides a lovely demo, in this case some pretty wire frame demos.

In summary I have some great tools at my finger tips when I get an urge to actually write graphics programs.


Shortly after finishing this little investigation on how to write C graphics programs, I stumbled across HTML5 Canvas which provides you with space in your web page where you can put graphics.  The graphics commands themselves are written in javascript.  This is definitely an easier way of doing simple graphics.  A bit of cutting and pasting and I could do a sample on my website.




Tuesday, 16 March 2021

Uprooting a Galaxy S7 Edge

 Two years ago Annette had paid for her lovely Saumsung Galaxy S7 Edge and wanted to unlock it so she could move to another provider.  At the Sutton high street phone provider they suggested the quickest solution would be to pop in to a local phone shop to unlock it.  The (dodgy?) shop failed to unlock it and needed to keep it for someone to look at it, which in the end took two weeks.  When it came back all was not well, it wouldn't accept software updates or allow phone payments to work.  Annette took it to Samsung who said it had been rooted, would have to be rebuilt and might cost a lot of money with no guarantee of repair.  Eventually Annette purchased a new phone and the old one languished in a drawer.

I opened the drawer recently, saw the phone and thought that we should either sell, use or give it to a worthy cause.  There is also a possibility I could do something "techical" with it - use it as a display, an IOT box or may be run Android / linux natively.  The phone is still worth about £130.   It doesn't have a SIM card but I could run apps, browse the net etc.

I saw that it still has some of Annettes information stored so I decided a factory reset would be a good start.  The phone whinged loudly about doing this wanting repeated confirmation of Google and Samsung account passwords which didn't seem to exist.  Eventually Annette managed to delete her Samsung account from the phone and we were able to complete factory reset.  Unfortunately the phone was now effectively dead, it said "custom binary blocked by FRP lock" and wouldn't boot up.  Oh dear!

I googled solutions and it became clear that we needed to replace the firmware.  It appears that a tool called Odin is used to replace firmware and various firmware versions are available on line.  I tried various sites and in the end found an excellent one, sammobile with up-to-date software and firmware.The firmware download is about 2.3GB and they have a very slow throttled free download available (24 hours).  You have to make sure the firmware is for your specific phone model and country.  I thought it totally fair to pay a small amount (€6.5) for a faster download (10 minutes).  You need to install Samsung drivers and Odin software on your PC and unzip the download files.  You then put the phone into download mode, connect it to the PC which then installs it on the phone in a couple of minutes.


After that it is simply a matter of  restarting and signing on with your Google account (which must have been used to sync with the device previously).  The phone now appears totally fine and useable, altogether a wonderfully uplifting experience.  It is a shame that Samsung were unable to do this.  I believe Odin originated within Samsung and they use it themselves so they should have been able to do what I did in a few minutes.




Maixduino : AI meets Arduino

 I read an article in Elektor about an amazing Maixduino hardware board which provides an AI system in an Arduino compatible package.

The board is packed full of juicy hardware, including an ESP32 for ancilliary processing, a camera, SD card, audio and an LCD screen.  At its heart is a Sipeed Maix 64 bit RISC-V module which processes AI.  It can be programmed through the Arduino IDE which avoids a steep learning curve.

I purchased one from Mouser and started to follow Elektor article to set it up.  If you follow detailed instructions and an installation works first time you have an immensely satisfying experience but you tend to learn a little.  When events dont go as planned and issues need to be investigated by looking around different sites and articles, it can be frustrating but you learn a lot more.  Needless to say my installation experience was a struggle.

After some unsuccessful attempts at installing the Arduino software I tried the PC based micropython environment which is described well at icircuit.net and I was soon able to flash Maixduino using the kflash command line tool.  The documentation provided by sipeed also provides good detailed explanations.  Maixduino uses two COM ports one for the Maix processor and the other for the ESP32.  It was exciting to see them both communicating properly, giving me more confidence with the hardware setup and PC connection.  The test program I ran was great, it showed a camera image on the LCD screen.
Returning to the Arduino environment, with my hardware setup validated, I looked a bit more closely at the software environment.  The Elektor article had described a simple Arduino installation which obviously worked for the author.  I was pleased when I found out how to setup multiple Arduino environments on the same PC. Some of the software included in Maixduino libraries has been used by me on other projects, in particular Adafruit graphics libraries.  I set up a "portable" Arduino IDE environment which uses a separate copy of libraries and configuration files.  I then repeated the installation process.  The portable environment is nice as you can see everything relating to libraries you have installed, sketches you have written etc in sub folders of the portable folder.

Using the new environment I could compile a sketch (with a number of warning messages)  but still not "upload" to the board.  I saw two flags in preferences.txt for compile.debug and upload.debug, both set to False.  I turned them on and could see the detailed commands the IDE uses to create and upload a program to a board.   I could see kflash running and failing so I lowered the upload speed from 1,500,000  to 1,000,000bps.  Rebooting and resetting the board now allowed the upload to proceed. 

I tried a few demo programs to verify the environment. Using the Kendryte K210 AI module you declare the ST7789 screen and use the Adafruit GFX library to draw shapes, lines, text etc.  Using th ESP32 I started with a "Hello World" serial monitor display.

I was now able to return to the Elektor article and try the "selfie" program which shows a camera image on the LCD display.  I still had some minor problems, there were duplicate Adafruit GFX libraries (I deleted the one not provided by Maixduino) and a typo in a Maixduino library(googling provided me with a correction to apply).  Finally I was able to complete the first experiment and take a picture, as shown below it is a picture of a rock.
The second example described by Elektor is to run a demo which is a  real image recognition program.  It isn't practical to "train" the AI system oneself without a lot of effort and thousands of images but the sipeed demo provides you with a pre-prepared "neural net" which is copied to the SD card.  A simple sketch reads in the net then analyses a video image before guessing what it shows.

Bella was the first subject.  The program is incredibly fast, it analyses the picture in about a second then guesses.  Bella isn't a very good subject as she moves around and takes whatever position she wants in front of the camera.  The best guess is shown below, the AI top answer is "Fur coat" - very funny, but actually accurate, after that it suggests she is a German Shepherd or police dog! Wow.


I found this a stunning result.  AI hardware, costing £20 can actually identify a dog and have a good guess at the breed within a second.  It shows how real AI technology is and indicates that practical systems are within our reach.  Another stunning Elektor article which is the start of a short series, so there should be more to blog about soon.

Thursday, 4 March 2021

Ben Eater : Arduino EEPROM Programmer

 Having substantially completed Ben's 6502 Hello World project I can start to think what to progress myself.  My priority is to see if I can avoid the need to remove the EEPROM, burn new code in a programmer, and replace it each time I write, amend or correct a 6502 assembly program.

I have a Mega 2560 attached to the 6502 board connected to the address and data buses and therefore connected to most pins on the AT28C256 EEPROM.  The TLS EEPROM programmer I have been using doesn't require special hardware capabilities so providing I connect the Mega to the three EEPROM control pins (Output Enable, Write Enable, Chip Enable) I should be able to write programs to it.

Prototype EEPROM write sketch

I started with a separate breadboard EEPROM with digital I/O pins on an Arduino Mega 2560 connected to each I/O pin.  I firstly wrote a sketch to read data from the EEPROM and display on the Arduino serial monitor.  Functionally this program was very similar to the 6502 video program to read from memory, so it was easy to implement in a sketch.

Ben has an Arduino EEPROM programmer as a separate video tutorial.  It uses a nano and shift registers instead of a Mega to read/write the EEPROM but it provided useful hints for me to write to the EEPROM.  In fact the write process is very simple: disable the output pins, set address and data values on the bus then pulse Write Enable low for 1 microsecond to write data.  To test the program I took the EEPROM which previously displayed "Goodbye, Cruel W" and changed the letter "l" (0x68" to "t" (0x74).  I replaced the EEPROM in the 6502 board and checked that the message displayed was updated. 


John65-02

Originally it was my intention to retrofit this change to the BenEater circuit but instead I have started a new circuit which I will call John65-02.  Leaving the mega connected to ROM I also connected up a 6502 CPU on the board.  CPU and ROM share the same address and data bus so I simply added chip enable, output enable, write enable logic from 6502 as previously.  I connected Bens clock circuit for a testing clock signal.  With the mega connected to 6502 read-write bus, clock and reset I was able to run the Mega monitor program to watch what was happening on the processor.  Importantly, without changing any connections I can also run a sketch to re-program the ROM.  I thought I might have to turn off the 6502 using its ready or bus enable pins but it turned out that , as long as I stopped the clock I could run the ROM update.

This is great progress, I can avoid removing chips to change a program.  It was becoming a liability inserting/removing the chip on a crowded board.  Eventually wires would be dislodged causing a difficult debugging exercise.

In addition to being able to write to the ROM, I have more work to do.  I need to be able to move the raw data from a PC file into a sketch so that I can download it to the ROM.  I am considering using X/Y/ZMODEM to do this, as I did for the RPI bare metal programs.  Alternatively I have ordered a wide 28 pin ZIF socket, which I could put into the circuit to make ROM extraction / replacement easier.

Ben Eater : 6502 : Clock and Loop

 We now have our hello world program using Ben's home made clock and all looks good.  The clock has been really helpful in allowing us to step through programs and run them slowly but we should really run more quickly using an oscillator.  In previous tutorials we looked at a number of timing considerations relating to our chipset.  Now (video #8) Ben guides us through clock considerations for our breadboard circuit. 

All circuits have inductance and capacitance from wires and physical geometry of the system, breadboard circuits suffer more than PCBs.  The unwanted effects include spikes and sluggish changes and they increase with frequency. Looking at the 6502 data sheet we need our rising or falling pulse to transition within 5ns.  Ben checks the diy clock and 5ns response is fine.

The 1mhz clock chip is then connected to the circuit.  Again 5ns response is fine so the 6502 should be fine. However the circuit doesn’t work.  The LCD is reacting more slowly than it should. In fact if you add 750 NOP instructions to commands the circuit works!

Our problem (video #9) is that we don’t check the LCD busy flag before sending the next command to it.  Ben guides through branching, looping and reading LCD values so that we can check LCD status and send commands in an orderly fashion. Our LCD happily displays text with the 6502 working at 1MHz.

Now we have the ability to loop we can tidy up our assembly program to send a message, we store the message characters as data in a block of memory and loop to read through upto a null byte.

Our Hello World is now fully working and we have learnt a huge amount about building basic 6502 systems along the way.





  


Tuesday, 16 February 2021

Ben Eater : 6502 : Using RAM and providing LCD output

 By the end of the previous tutorials Ben had arranged for us to write assembler programs which can be stored in an EEPROM so that the 6502 can run the program.  We also have a "Virtual Interface Adapter" which gives us the ability to latch output from the data bus and initially we arranged to set LED patterns.

LCD

Displaying output on LEDs becomes very dull very quickly so our next mission is to display a message on an LCD panel (video #4).  I am quite familiar with the HD44780 LCD controller from other projects so I found this quite easy.
The LCD has three control signals RS RW EN which we attach to VIA PORTA and 8 data pins which we attach to PORTB.  Register select switches between the instruction register and data register in the controller and RW determines whether data is being written to or read from the controller.  The Enable signal is pulsed to actually execute the command.  We program the LCD by putting a character or instruction in port B, setting RS and RW in Port A then briefly enabling the EN pin.  It takes about four command instructions to setup the LCD and we can then send characters in subsequent commands.  Each display command takes 8 assembler instructions so our program is about 160 lines long.
Finally we can display our message

Stack

It is a real pain duplicating 8 assembler instructions each time we want to send a character so we use a subroutine mechanism.  Define the character to be displayed then call a subroutine to control the LCD. At the end of the subroutine return to define / process the next character.  This removes the repeated code and our program is reduced to 75 lines.

 Unfortunately this program doesn't work!  The 6502 needs to save a return address when it jumps into a subroutine (JSR) so that it can return to execute the next instruction when it is finished (RTS) (video#5).  The 6502 uses an area of memory called the stack 0100-01ff  where it pushes 2-byte addresses and pops or pulls them back on return.  256 bytes allows for upto 128 nested subroutines.

RAM

Previously we attached an EEPROM to the 6502 bus and read data from it.  We attach a 62256 32k x 8 bit RAM chip, which uses the same pin positions as the EEPROM.  We set it up so that we can address it at 0x0000 to 0x3FFF (16k). Our life then becomes rather complicated as we delve into the timing diagram (video #6).  A lot of patience and study of the 6502 and 62256 datasheets is required to get this right.  It turns out that we need to ensure that A15, the first address line is set before the others and we have to add a little bit of circuitry to achieve this.

Finally we can run our subroutine (video #7) and stepping through we see data written to the stack as part of each JSR and retrieved/moved to the PC (program counter) when executing RTS.  It works a treat and our subroutines do their job.

Tuesday, 9 February 2021

Ben Eater : 6502 : Writing in Machine Code

 In my  previous 6502 post Ben showed (video #1) how to connect up the microprocessor with a few inputs so that it would run through its boot sequence.  We used an Arduino Mega to monitor address and data lines so that we can see what is happening.

We now need to write a program (video #2).  We know that the 6502 reads the program start address from the reset vector at 0xfffc and 0xfffd so we have to provide some hardware (memory) which is addressable.  By that I mean we attach the address/data lines on the 6502 to address/data lines on a memory chip and when requested the memory chip will look at the address lines and respond with the bits at that address on the data lines.  

For the program memory we use an AT28C256 32KB EEPROM.  This has to be configured with a special programmer, we use a TL866II Plus programmer to write our information on to the EEPROM.  The first step is to define a machine code program which the 6502 will understand.  We then need to create a file containing the program and, using the programmer copy it across to the EEPROM.  Ben uses Python to write a file called rom.bin which is exactly 0x8000=32KB long.  The programmer copies this to the EEPROM which can then be attached to the 6502.

In order to see some results we need the 6502 to produce some output.  Using a cunning scheme Ben arranges for the EEPROM input to use memory addresses 0x8000-FFFF leaving addresses 0x0000-0x7FFF for output.  A multipurpose output chip called a W65C22 Versatile Interface Adapter is attached to address/data lines (lets call them busses from now on).  We will use it to latch information from the data bus to an output port.   We attach LEDs to the output port so that we can see the results.  Another cunning scheme is required so that the W65C22 reacts when the 6502 sends to addresses 0x6000..... 

Now we have hardware attached where we can store our program and we can control an output device.  A short machine code program is written to configure the W65C22 for output, write output patterns to the LEDs and loop around.  Awesome.

This is a packed hour long lesson, at the end of which we should understand programming an EEPROM, ROM addressing, latching output, using an output chip and writing machine code.  Wow.

After the steep learning curve of video #2 we consolidate our position in video #3.  Writing machine code quickly gives you a headache and it is much easier just to write the assembler code and ask an assembly program to convert it.  Video #3 shows you how to install and use vasm to create rom images which can be loaded into the eeprom.  This results in another LED program which is demoed below.


 

  




Monday, 8 February 2021

MacBook Air M1

 I wanted to buy a laptop, mainly because I am not happy sitting at my desk all the time whilst typing.  An iPad is fine for armchair computer use but not for typing.

A Windows laptop is the obvious choice but I am not enthusiastic about Windows software at the moment.  In particular a practical alternative to MS-Word for word processing would be welcome.  Previously I borrowed Harry's ancient MacBook Pro and found it quite usable despite being unfamiliar and 10 years old.  In addition macOs is linux-based and I see lots of Macs used in linux-related tutorials these days.  Although miscellaneous software is more likely to run on Windows, I don't expect the laptop to be used for everything and it doesn't need to replace Windows.

The new Apple MacBook Air M1 is based on an ARM chip which is faster than and uses less power than previous Intel-based processors which gives it a very long battery life and means it requires no fan so makes no noise.  It became available in the UK in November 2020 at John Lewis Partnership which is my preferred supplier as they combine competitive prices with excellent service.  The entry level model costs £999 has 8GB RAM, 256GB SSD and 13.1" display.  It looks excellent value compared with older MacBooks or the M1 with larger SSD.  It is also apparently possible to use App Store iPhone/iPad apps, which haven't previously been available for MacBook users.

As you would hope and expect Apple set up is straightforward and it only takes a few minutes to be working on the Internet.  I was particularly impressed with the user guide and newbie guides which are specific to this model.  I shall perhaps blog later on getting used to MacOs. 


Sunday, 31 January 2021

Ben Eater : 6502

 Ben Eater is a remarkable electronics teacher and the 6502 video series continues to demonstrate the high quality he has brought to previous projects.  I am excited to get started with my new 6502 microprocessor kit.

The 6502 microprocessor comes from a simpler age, its data sheet has only 32 pages and it needs no ancilliary components; it conveniently uses 5V power.  We put the processor on a breadboard and connect a few pins to get started:

  • four inputs used for control purposes are set to high and a reset button which can be set low to reset the processor
  • for a clock input use the Ben Eater clock module; it allows us to run the processor slowly or single step it in the course of setting up and testing our hardware
  • connect a few LEDs to the first 5 address pins
When we apply power and start the clock ticking we see LEDs flashing showing that the processor is doing something, although we dont know what.

An effective way of finding out what is happening is to use an Arduino Mega to monitor the 16 address and 8 data pins.  We also want to check the status of the read/write pin.  A simple sketch, using interrupts reads each pin with the clock ticks and displays address/data values on the serial monitor.
As the data pins will be read at some stage we hardware values 11101010 (0xEA)  using resistors to the data pins.

In conjunction with the manual we see that on reset there is a 7 cycle initiation sequence which reads the reset vector from memory address FFFD and FFFE. Our read operations always return 0xEA so the reset vector read in is an address EAEA and we can see that the processor starts executing a program from that address.   Each instruction read in will also be 0xEA, which was conveniently chosen as it is the NOP instruction.  We can see from the Arduino serial monitor that the processor continuously reads and executes NOP instructions (which each take two cycles) and increments the program counter.


Amazingly without knowing very much at all we have an understanding of where we need to load our programs and we can see the simple NOP program running.  Good progress for our first hour.



Thursday, 28 January 2021

DIY Oscilloscope

Occasionally I need to use an oscilloscope to look at a wave form.  They cost about £200 which is quite expensive for something I would only use a couple of times a year.  They are also quite complicated and it is potentially difficult to find the view that you want.

A few years ago I used PC based software which worked in conjunction with a PC sound card to work as an oscilloscope.  The input is taken from signal and ground into the PC jack plug which is + or - 0.7V.  The sound card then provides 16 bit samples at 44,100Hz.  A quick look reveals that these programs are still available, for example Christian Zeitnitz or TorVergata.  A problem with using the PC sound card is that you have to make sure your input does not exceed 0.7V, otherwise you could damage the sound card or PC.

More recently I have seen Arduino based solutions and as soon as you start looking there are loads of them.  The first one I chose to look at is at electronicsforu. A simple sketch runs on an Arduino nano to capture a signal on an ADC (Analog to Digital Converter) pin and send it through the serial interface to the PC.  A simple program pcscope.exe runs on the PC to discover the arduino and display the serial data as a wave form.  This is about as simple as you can get and it works without other components on a 5V circuit and only requires a signal/ground connection to the circuit under test.  I may look at other more sophisticated solutions in due course. The pictures below show a bit of debuggin on my Ben Eater clock module flashing at about 1Hz.  The arduino nano takes its signal from the 555 timer output via the white wire and the PC displays the output wave form.


Of course once you start looking at these free solutions other ideas come up.  Oscilloscope for ipad costs £10 and looks good for audio signals but it is probably not suitable for electronics.  More fun would is a build your own JYE Tech oscilloscope, available from Amazon for £30.  It wouldn't be very accurate but it should do the basics.

A real oscilloscope would be worthwhile if I want to spend any time learning how to use it.  Probes and electronics need to be good quality to get results so spending £200 on something like a Hantek DSO5102P (reviewed by my heros Rui and Sara Santos at RandomNerdsTutorials) would be reasonable. 

 


Monday, 25 January 2021

Ben Eater : Clock

 Ben Eater is a wonderful teacher of digital electronics.  As I watch his youtube videos I am always amazed at how clearly and concisely he can explain and demonstrate circuits.  His big project was a set of videos explaining how to build an 8 bit microprocessor up from TTL components which I greatly enjoyed.  More recently he has shown how to make up a system based on the 6502 microprocessor.  Both sets of videos make me itch to follow his instructions to make my own system.  He has been kind enough to make available kits of parts containing everything needed to build his projects so I will do just that.  

Complete 8-bit CPU

It would be amazing to construct the 8-bit uproc but I don't know that I would have many uses for it once finished.  I have very fond memories of the 6502 from my youth, I used it at work around 1980 at British Aerospace and found its assembler language sensible and simple compared to other hardware languages I had to use at the time.  The 6502 was hugely successful and formed the basis of the Apple IIe, the BBC micro, Ataris and many others so I am looking forward to being reacquainted.  One of the many blessings of a daugher-in-law from California is that it makes it easier to purchase Ben Eater kits and get them back to England so I am now the proud possessor of 6502 kit and clock module.



The clock module is the first step of the 8-bit uproc project but is also useful for 6502 testing.  For a processor the actual clock speed will be 1MHz or greater, but when testing the system it is useful to be able to run the clock very slowly (c1Hz) or even single step it.  The 555 timer provides many different functions, it has been sold since 1972 in huge quantities. The Ben Eater clock circuit utilises three 555 chips to build our testing clock and demonstrate how it is configured.

There is a set of 4 videos, the first three going through configuring 555 as an astable, monostable and bistable device and the fourth one adds some simple logic gates so that we can produce a single tick or a regular tick-tock.  Ben describes how to choose ancillary resisters and capacitors to achieve the desired effect, how to connect the circuits and some additions to make the circuit more reliable by "debouncing".