Monday 30 August 2021

6502 : Xmodem

 My 6502 system is working well but I still find the program upload process irritating.  I am probably being a diva about this as the old school method to remove, program, replace the EEPROM chip was very painful.   My programs are quite small but it takes time to compile them, transfer them to an Arduino sketch then run the sketch to copy the program to EEPROM.  For a 1KB program, which is quite large for my assembler programs but reasonable for C it can take a minute to process.

I have been thinking of trying to implement XMODEM for a while, it seems sensible to use the serial port session which will allow a transfer at 19200 baud, taking a few seconds for program download into RAM (not EEPROM).  6502.org provides a copy of Daryl Rictor's xmodem code so a couple of weeks ago I tried it out.  The code is intended for a 65C02 + ACIA 6551, the same as mine, and it is only a couple of hundred lines long so I thought I have a good chance of success.  I was a little nieve but that is the best way to start a long journey.

It was easy to download the program and tweak it to compile/load successfully.  However, on starting Xmodem nothing happened.  Not knowing the code or the protocol or having a tool to look at serial port traffic meant that debugging and experimentation were unsuccessful.

I found the modem protocol is quite simple so I wrote a C program under Windows WSL to download a test packet meaning that at least I had reasonable input.  I still couldn't get the example code working so I wrote my own version called xm.  After a while this worked fine, I could compile a program, start xm running and run my serial program to send the machine code. I excluded most of the modem error checking, particularly block number and CRC checks as we are transmitting at quite slow speeds down a 15cm cable.  The only downside is that I have to exit Putty to start the serial program downloading as they share the COM port; on completion I have to restart Putty.  This can be accomplished by means of a batch file loop but still it doesn't seem right.

In an effort to streamline this process I considered writing my own terminal emulator, from which I could easily start the transfer program.  Again I chose C under WSL as my development environment.  Configuring and using serial ports with C isn't terribly easy, some low level commands are required to setup the UART; as usual a good tutorial made this easy.  After that READ and WRITE statements can be used to fill/send buffers through the port.  Under Linux and WSL there isn't a function kbhit() to tell you if the user has pressed a key so I had to implement that myself based on Morgan Mcguire.  Although I could easily capture and display information from the 6502 and deal with keyboard input properly I couldn't get the two to work together seamlessly and I didn't complete this attempt.

On a whim I googled to see whether there are any software only (free) packages which can monitor the serial port.  It turns out there are a few, and Serial Port Monitor seemed a good choice.  The free version is old and not Windows 10 friendly so I used a demo of the paid version.  It is a shame it costs $100 so it is't something I would buy for a one-off problem.  The software is clever enough (using admin privilege) to share the serial port with Putty and after a few minutes learning I could see the serial port traffic.

Using Serial Port Monitor I could see that xmodem was sending a good packet to the 6502 but it was being NAKed by the 6502 and repeatedly resent.  My debugging focussed again on the sample code but I still couldn't get it working.  In particular, not all bytes were read in the ACIA port properly.  I tried all sorts of things to make it work, including slowing the transmission to 9600 or 4800, swapping my Arduino Nano controllable clock for the 1Mhz chip,  using RTS / CTS flow control with extra wires on the USBTTL connection, putting delays on the 6502 send characters which were being garbled.

Eventually I decided to write my own 6502 program, jmodem.  With my new understanding of modem and the structure of the sample code it was a simple job to write my own using subroutines I have previously written.  The only new feature is to read characters until no more come.  Xmodem sends a 128 byte buffer with 3 header characters, terminated by two CRC bytes.      It then stops and waits for ACK or NAK.  If any characters are lost there will be less than 133 characters in total.  Once I had this subroutine working with Putty terminal input remaining coding was easy.  The program initially accepted just one block, checked the number of bytes and transferred it to a fixed memory address.  It was then easy to loop round until an EOT byte was received.


Success is sweet.  I can now load programs into RAM quickly when I want to without exiting Putty using a standard technique.  Completed programs or subroutines can still be saved in ROM using the Arduino Mega but we no longer need it for normal development or system usage.





Thursday 19 August 2021

Printing reports from Google in Landscape

I have a simple but very useful mariadb/mysql database for my art slideshow app and I use the excellent utility HeidiSQL to maintain it.  Mariadb doesn't have reporting capabilities which is a problem for me as I occasionally need to print lists of pictures.  It is, of course, possible to create and display queries and I can save these to a linux file.  However they need some formatting and importing them to Word, setting up the layout, checking it looks ok is a pain.  Exporting csv data and reading into Excel is a comon way of processing records, but I am not keen on writing Excel macros to do this.  I am sure there are lots of reporting packages I could use but that would be overkill.

I do have the capability to output a selection of records to a browser thanks to Tania Rascia's excellent tutorial.  I use the web query to update descriptions in the database associated with pictures so I thought it would be worthwhile to see whether I am able to print reports.  Usually printing from a web browser provides what you want but is messy due to screen formats being inappropriate but I thought some tailoring would be possible.

In fact it turns out to be a simple and effective solution.  Clearly we want to use CSS to reformat our web page for printing.  Using the @media CSS rule you can specify separate definitions for screen and print.  My first experiment was to display screen text as blue and printed text as green.
To test output just choose print in the browser and you see the print version of the report in print preview


After that we can write print specific CSS to ensure the report is in landscape mode and that instructions and unnecessary screen text are hidden.  I can also set up a print button on my screen.


A very satisfying solution to my problem.






Wednesday 11 August 2021

Windows 10 Pro

Why

One of the good things about using RPis is that we can SSH into them remotely so it is easy to use multiple systems for different purposes with a single screen (or two) and keyboard.

I am planning to purchase a new PC but I am not looking forward to it  because of all the tasks involved in switching over from the old one.  It would be much simpler and satisfying to run old and new in parallel.  I could set up the new PC and transfer over important and frequently used applications and data.  There are lots of apps, data, configurations on the old one which I probably don't need and I could leave them in place initially.

Unfortunately running two Windows PCs with separate screens and keyboards is a pain.  They take up a lot of space and aren't convenient to use.  I could use KVM style screen / keyboard switch but good ones are expensive and I find them messy.

I could use TeamViewer, splash top  or VNC to access the old PC from the new one.  In the past I have found them a bit clunky but that is probably my lack of familiarity.  However I decided to try Microsoft Windows Remote Desktop which I would hope is well integrated.

How

To use RDP I need my existing Win10 PC to be running Win10 Pro.  Win10 Pro doesn't have many useful features but RDP and bit locker disk encryption are good.  

Buying direct from Microsoft is quite expensive but a quick Google showed me that there are plenty of third-party suppliers who can provide a product key for about £20.  These sites can be dodgy so I picked one called unitysoft, which has an office address and support available.  On purchase I received a product key and some straightforward instructions.

All you really have to do is change the product key in Settings > System >  About.
The computer then spends a couple of minutes reconfiguring existing software so you have Windows 10 Pro.  You can check this in Settings > System > About 😀😊😊

To access the PC remotely just download the Microsoft Remote Desktop app onto Macbook, iPad etc and connect to the system with your current userid and password.  If you are logged on locally you will be logged off.

So

This is wonderful, just what I always wanted.  I can install my new PC, transfer over what I want to it and leave the old box in the corner connected to network but without screen / keyboard.  If there is something I need over the next few months (and there will be) I can turn on the old PC and sort it out.

In the example below you see my lovely Macbook M1 with a Windows Remote Desktop.  Normally I would run it as a full screen, but this shows the Apple background and apps as well as the Windows desktop.  At the moment I am debugging a 6502 program with my board attached to the PC using a COM port.  I can sit in comfort with no cables or hardware attached attached to my Macbook and happily use Windows functions. Bliss.



Monday 9 August 2021

6502: Download programs to RAM

 My current mechanism for loading programs onto 6502 is to use the Arduino Mega to download machine code to ROM.  Although this is a vast improvement on using an Eeprom programmer it is quite slow, particularly for C programs which tend to be larger.

It would be preferable to use the 6502 serial interface to download a compiled program to RAM where it cn be executed.  This is analagous to loading a program from disk into memory and running it.  I still expect to save completed programs and subroutines in ROM, but this scheme should make the development cycle easier.

Both Extraputty and TeraTerm provide xmodem transfers.  Daryl Rictor has provided a sample xmodem implementation for 6502 so I have the basic ingredients available to me.

My objective is to take a machine code / hex program from the PC, transmit via USB serial port to the ACIA 6551 then read it in to RAM where it can be executed.

Initial tests did not go well. I dont have the ability to log the character string that Extraputty / xmodem is sending or an understanding of the protocol or much idea of how the receive program works.  The trial and error method is somewhat doomed.

The xmodem protocol is intended to be simple to implement, a major factor in its long term popularity. 

 
Data is downloaded in 128-byte packets.
Each packet has a 3 byte header: <soh=0x01> <block number> <inverted block number>
There is also a 2 byte trailer containing a CRC code.
This makes a total of 133 bytes

The receiver sends a character 'C' to the sender to start transmission.
Sender responds with a packet (133 bytes) which the receiver acknowledges with <ACK>.
The receiver carries out block number and CRC checks, if they fail the receiver sends <NAK> instead of <ACK> and the sender retransmits.
This is repeated until all packets are sent, at which point the sender sends <EOT=0x04>

To simplify testing I wrote a C program on my PC which sens a single xmodem format packet to the 6502.  I was pleased to find that Windows/WSL allows me to use a PC COMnn port as /dev/ttySnn providing the program has sudo privileges.  It is a bit fiddly to configure the settings but straightforward if you have a good tutorial .  The completed program looks more complicated than it is. 

Unfortunately, even with a known test program I couldn't make xmodem work. My 6551 works fine but my system or ExtraPutty may be incompatible in some way with Daryl's xmodem example.

I then decided to write my own xmodem receiver.  I simply have to read in some data packets, in a known format, into RAM using my existing subroutine library and I have Daryl's example for hints and guidance.  As we are using a short local connection I can skip the error checking - if an error occurs I would just reload the program.

This approach is much more successful.  I can take an executable program, created using cc65 on the PC and transfer it to 6502 RAM.  After checking using the monitor that my first program was transferred successfully to RAM address $1000 I tried to run it but (of course!) it failed.  The program had originally been compiled to run at $8000.  Once I changed the .org statement to rectify this it ran fine.  I would include an  image but the test program just displays a '#' character and allows character input.

This is an excellent result.  Although there are currently a number of rough edges to smooth over we have a working solution.  It allows us to reduce reliance on the Arduino Mega and the expectation is that it will accelerate downloads and speed up my development cycle (which involves frequent program changes).