i2c bit-banging on Z80 with 8255A.

This article is mainly aimed at my Polish readers, owners of the educational computer CA80, but the i2c bit-banging for Z80+8255A may come useful on other Z80 platforms. As always source code can be found on my GitHub page.

8255 port control challenge.

There are many websites that cover i2c in detail, so I’m not going to spend any time doing that here, but in the context of this article, the key issue is the fact I’m trying to use a very basic “software-only” implementation of i2c – later used to pull date and time information from hardware real-time clock (HW RTC). I2c uses two lines to implement it’s the bus: SDA (for data) and SCL (for clock). Those two lines have to be independently controlled via software, additionally, SDA is bi-directional, sometimes used as output and sometimes as input. The 8255 offers 3 ports (A, B, C) of 8 lines of general-purpose I/O connectivity. Unfortunately, the way it operates, all lines of each port can only be configured as input or output all at the same time. So if we “plug” our SDA and SCL lines to the same port (for example port B lines 0 and 1), we would not be able to implement the i2c bus this way. The only solution is to use two independent ports (for example port A, and B, or A and C). One more “trick” you can use is the fact that port C, is actually split in half and can be controlled independently (port 0-3 in one group, and 4-7 in another). This is exactly what I’ve done. Let’s see the diagram:

Diagram_v1

 

As you can see, I’ve used PC.0 for SDA and PC.4 for SCL signals. R1 and R2 are pull-up resistors (I used 10k, but 4.7k would be ok as well) required for all implementation of i2c, R3 and R4 are used for current limiting, for situations where software might be misbehaving sending data at the same time other transmissions are in progress. In my example I’m communicating with a popular RTC from Dallas – DS1308Z (you can use a cheap module from eBay – be aware of issues with those modules where the “trickle charge” circuit may cause the re-chargeable 2032 battery to explode. This has happened to my module, so I removed all the extra components, and I used a non-rechargeable 2032 battery).

The GitHub repository contains the required code RTC_0x2000_0x2300_v1.4.asm The file contains a read and write procedures for the RTC. The code is a bit of a mess of stuff I found on other projects and my own code – but since I haven’t done Z80 assembly language for the last 20 years there is much scope for improvement. Feel free to contribute, but in its current form, the program works and serves its purpose ­čÖé

The next section is more useful to my Polish audience, so I’ll attempt to write it in Polish.

Dla polskich u┼╝ytkownik├│w Mikrokomputera CA80 firmy MIK.

Niedawno uda┼éo mi si─Ö ÔÇ×reanimowa─çÔÇŁ m├│j emulator pami─Öci EPROM ERMAX100, wiec w ko┼äcu mog─Ö zabra─ç si─Ö ze par─Ö projekt├│w na CA80 kt├│re odwleka┼éem przez prawie ÔÇŽ. 20lat.

CA80 to by┼é prawdziwie m├│j pierwszy…hmm “komputer?”. Posk┼éada┼éem go jeszcze w podstaw├│wce! I dzia┼éa┼é. Powsta┼éo kilka projekt├│w, pami─Ötam dobre czasy pisania program├│w na kartce papieru i ÔÇ×kompilacjiÔÇŁ z ksi─ů┼╝k─ů w r─Öku, oraz ┼╝mudne wklepywanie kodu przez klawiatur─Ö CA80.

Dzi┼Ť, m├│j CA80 rzadko jest u┼╝ywany (chocia┼╝ teraz gdy mam mo┼╝liwo┼Ť─ç ┼éatwej emulacji EPROM, mam nadziej─Ö ze to si─Ö zmieni). Wi─Ökszo┼Ť─ç czasu sp─Ödza na moim biurku, wy┼Ťwietlaj─ůc ÔÇ×CA80ÔÇŁ. Dobrze by by┼éo chocia┼╝ na co dzie┼ä u┼╝ywa─ç go jako taki ÔÇ×retroÔÇŁ zegar. Ja mam now─ů wersje komputera z wy┼Ťwietlaczem VFD. Niestety brak podtrzymania pami─Öci czy sprz─Ötowego zegara czasu rzeczywistego (HW RTC) bardzo ogranicza CA80 w funkcji zegara. W tym projekcie chcia┼éem uzyska─ç nast─Öpuj─ůc─ů funkcjonalno┼Ť─ç:

  1. Zegar ÔÇ×tykaÔÇŁ gdy brak zasilania ÔÇô aka HW RTC na magistrali i2c z potrzymaniem bateryjnym.
  2. CA80 automatycznie wy┼Ťwietla czas gdy zasilanie powr├│ci (komenda *E[0] startuje automatycznie).

Postanowi┼éem i2c zrobi─ç w programie, poprzez tak zwane ÔÇ×bit bangingÔÇŁ. Elektronika to tylko podstawowe elementy standardowej implantacji DS1307Z (gotowy modu┼é mo┼╝na kupi─ç na eBay za par─Ö dolar├│w).

Kod ┼║r├│d┼éowy programu jest na GitHub. Plik RTC_0x2000_0x2300_v1.4.asm nale┼╝y skompilowa─ç darmowym ÔÇ×z80-asmÔÇŁ asemblerem. Jest zaprojektowany by zosta┼é zaprogramowany do EPROM w podstawce U9 CA80, zaraz ponad podstawowym kodem pod adresem 0x2000h. Ja mia┼éem w U9 pami─Ö─ç 2764, kt├│r─ů wymieni┼éem na 27128.

Aby uzyska─ç automatyczna synchronizacj─Ö po starcie oraz automatyczne wy┼Ťwietlenie czasu, nale┼╝y te┼╝ zast─ůpi─ç komend─Ö skoku do g┼é├│wnego menu w monitorze CA80, skokiem do mojego programu:

2764_after

Pod addresem 0x0269h zamieni─ç komend─Ö:

JR START ( 18 05 )

na:

JP 2000h ( C3 00 20)

Na GitHub zamie┼Ťci┼éem obraz binarny dla pami─Öci EPROM 27128 oraz 27256 kt├│ry zawiera ju┼╝ dodatkowy kod i zmiany w monitorze, nale┼╝y tylko go zaprogramowa─ç i zainstalowa─ç w CA80 w podstawce U9 (zak┼éadam ze wszystkie po┼é─ůczenia konfiguracyjne s─ů w fabrycznej pozycji). Elektronik─Ö mo┼╝na zlutowa─ç na wewn─ůtrz CA80 lub pod┼é─ůczy─ç do z┼é─ůcza u┼╝ytkownika, wymaga tylko 4 po┼é─ůcze┼ä (VCC,GND, SDA-PC.0 i SCL-PC.4).

Program automatycznie odczyta czas i dat─Ö po starcie CA80 z HW RTC and nastepnie automatycznie przejedzie do wy┼Ťwietlania czasu. Wszytkie inne zlecenia powinny dzia┼éa─ç bez zmian. Do monitora mo┼╝na wr├│ci─ç naciskaj─ůc klawisz “M”.

┼╗eby zaprogramowa─ç aktualy czas do nowego uk┼éadu RTC, nale┼╝y najpierw ustawi─ç czas w CA80 zleceniem *E[1][sek].[min].[godz]= a nast─Öpnie wywo┼éa─ç program u┼╝ytkownika pod adresem 0x2100h komend─ů *E[G][2100]=, kt├│ra zapisze aktualny czas do HW RTC.

Kod jest napisany tak “na szybko”, cz─Ö┼Ť─ç jest skopiowana z innych projekt├│w online, wyszed┼éem z wprawy nie pisz─ůc w assembly prze 20lat ­čÖé Zapraszam do ulepszenia.

Tymczasem zostawiam was ze zdj─Öciem mojego CA80, dumnie wy┼Ťwietlaj─ůcego czas.

CA_80

ERMAX100 EPROM Emulator Revival

Intro.

I’ve been trying to get back into some of my “retro computer programming”. By the way, “computer” is a bit of an overstatement. As my first “computer” was a very special device, that looked like a calculator and only had an 8 digit 7 segment VFD display – it was called CA80 and was an educational “kit” computer from Poland. I’ll write more about it in the future, for now, I’m just liking to hackaday.io article describing it. One of the challenges of “programming” was that there was no editor on the “computer” and you had to program and compile on paper and once done you had to “punch it in” into the computer by hand. This is not very effective in 2020, so I started looking around for ways to “send” the code directly to the memory of my little computer. And here comes another device from the “days past” – and EPROM Emulator ERMAX100. It was released by a Polish company ASTAR ABR around 1995. By that time I was 15 and in the middle of working on my final year project based on 8051, I was desperate to get my hands on the ERMAX100 so that I can compile the code on my PC (yep at that time I was finally using a proper computer) and send over a serial connection to the emulator that would “pretend” the EPROM memory of my target system. I managed to somehow convince my parents and ended up buying it. I successfully used it for a few years, until devices with builtin flash memory, like the Atmel 89C2051, showed up on the market. Worth noting ERMAX100 can emulate all the common sizes of EPROMs from a 2kB 2716 all the way to a 64kB 27512.

My ERMAX100.

This is my example of the device. At one end the device has just a serial port (RS232) and optional 5V power connector, on the other end the plug for a cable that ends with 28 pin emulator “probe”. There are also two “RESET” hooks, that allows you to reset the target system after the code upload. I’ve added an extra “Reset” button, to be able to reset the emulator itself, as it sometimes “got stuck”.

Ermax100_FB

Here is the emulator “in action”, plugged into my CA80 “microcomputer”.

ERMAX100_CA

The “90s” hardware in the 2020 problem.

Once I got my emulator plugged into the “target” there was a very important issue I was facing. Who still has a serial RS232 compatible port on a computer? I didn’t have one, and I since I wanted the flexibility of being able to plug the emulator to any of my modern machines I came up with a solution: “convert” the device to use USB, to be more precise: replace the RS232 connector on the device with chap USB TTL serial cable.

So I’ve opened the emulator and discovered that it only uses the receive line of the serial port, and the hardware implementation is based on a single transistor. I quickly tested the theory, bypassing the RS232 connector and plugging the TTL-to-USB cable directly to the device:

ERMAX100_TTL_Details

Since that idea worked well, I made it a bit more permanent, first I removed the RS232 connector and the redundant power socket (we can now provide power via USB):

ERMAX100_no_rs232

To re-use the old panel, I filled the holes with epoxy glue and used some black tape to give it a fresh surface. I think the result is acceptable.

ERMAX100_Panel

I’ve attached the 5V, TX and GND lines from the USB-to-TTL cable after removing the transistor that acted as RS232 to TTL converter in the original solution, and secured the cable with a cable tie using two of the holes left after removing the power and RS232 connectors.

ERMAX100_attached

The end result is my ERMAX100 converted into USB ­čÖé

ERMAX100_USB

The “90s” software in the 2020 problem.

The software that came with it was from the 90s and “it showed”. It was DOS “only” and didn’t run on my Windows 10 machine. Besides that, I do most of my coding those days from a Linux machine (Raspberry pi 4 to be exact).

So I decided to try and “figure out” the protocol and re-implement it in something more platform-agnostic like Python script.

I had to “dig out” one of my older Windows 7 based computers and used it to send a few examples of data using the original software. I then “sniffed” the data on another computer.

ERMAX100_W7

The results were a bit strange:

550301
91ffffffffffffffffffffffff...fff06050403
a2
Total: 4100

550301
90ffffffffffffffffffffffff...fff06050403
a2
Total: 4100

Looks like the format is as follows:

The first byte is a “synchronization” byte of 0x55H, followed by a “type of EPROM” byte of 0x01H for 2716, 0x02H for 2732 etc. The 3rd byte seems to always be 0x01H. Following those 3 bytes is the actual binary file that is the “emulated” data. The last one or two bytes were some kind of CRC check or similar. It was strange as the last┬á “CRC Byte” was not changing even if I was sending different data (see the example above where my first byte is 0x90H or 0x91H but the CRC stays the same at 0xA2H). Also, the CRC byte and something else was overwitting the last 2-3 bytes of my binary file (again in the example above you can see binary data finishes with 0403, but the original data that I’m sending ends with 04030201). Using different data file I was getting different “CRC” bytes, sometimes even for the same type of file sent multiple times, I was seeing different CRC byte. I the end I assumed that last byte “doesn’t” matter or is not even implemented on the ERMAX100. To test my theory I wrote a simple python script:

import serial,os

ser = serial.Serial('/dev/ttyUSB0',57600, timeout=5)

binary_data = open("C930.rom", 'rb').read()

sync_byte = b'\x55'
mem_type = b'\x04'
is_one = b'\x01' # doesn't matter, code ignores this anyway.

out_data = sync_byte + mem_type + is_one + binary_data

print("Sent: {} Bytes".format(str(len(binary_data))))

ser.write(out_data)
ser.close()

exit()

You will need Python 3.8 and “pyserial” library (“pip install pyserial”). To my surprise, it worked! Even better than the original program, as it wasn’t overwriting the last bytes of my payload with CRC.

Now that I confirmed the “protocol” is correct, I wrote a full script that replaces the original DOS software with a simple Python-based script. I tested it so far on a raspberry pi and a Windows 10 machine both work well. The source is on my GitHub page.

I don’t think there are many people using the ERMAX100 but if you found this article and ended up using the script let me know.

I’m leaving you with some pictures of my ERMAX100 “in action”, emulating the 2764 EPROM of my CA80 microcomputer, programmed from Raspberry Pi 4.

IMG_4343

IMG_4341