Since I became the owner of the Verbarius clock, I wanted to extend it's functionality.
Speaking shortly, these clocks show current time using different words in different languages.
First, I wanted to add an ability to display time using numbers and hands.
Second, the pixel screen evoked in me memories of the 8 bit aesthetics.
UPDATE: Just published some source code on GitHub and added new, babylonian numbers clock generator. Have fun!
Connection to the clock
While connected to a PC via USB clock is detected as the removable disk and the SD-cardreader disk. The latter contains several files of at least two types:
size filename 1 920 boot1.sys 1 920 boot2.sys 1 920 boot3.sys 29 491 200 rd00.sys 29 491 200 rd01.sys 29 491 200 rd02.sys 29 491 200 rd03.sys ...
Almost all of them have the same size, so it's reasonable to suggest that all data is stored in a non-compressed bitmap format.
Analyzing the structure of a language pack
The language pack analysis itself was preceded by the following reasoning:
- Different files have the same size (29 491 200 bytes) -> the data is stored as uncompressed images.
- The most frequent byte values are 0x00 and 0xff -> the data is stored in a plain unencrypted way.
- There are 60*24 = 1440 minutes a day, for every minute there could be presumably from 6 to 10 alternative spellings -> the language pack should contain from 8640 to 14400 different frames (approximately 2k-3.5k bytes per frame).
- Visual approximation of the screen size — 300 x 60 pixels, and the screen is black&white -> the most likely storage format is bit-per-pixel.
- Each frame could be preceded by the header of a fixed length.
- The whole file could be preceded by the header of a fixed length.
Next, the simple python script was written for the more detailed analysis of the language pack format. It supported the manual choice of the byte ordering, the frame size and gave controls to tune some other parameters. Below are some examples:
Thus, I managed to determine the following format settings:
- The header of the frame has a length of 128 bytes.
- There is no special header in the beginning of the file.
- Each frame has size of 240х64 pixels, stored in the bit-per-pixel format -> the full length of frame is 1920+128 bytes.
- For each minute there are exactly 10 frames stored, even if some of them are not used.
The structure of the header was analyzed by the visual comparison of headers from several different frames:
hour 1 min 5 frame 3 offset 6144
01 05 03 ff ff ff ff ff ff ff ff ff ff
hour 1 min 5 frame 4 offset 8192
01 05 04 ff ff ff ff ff ff ff ff ff ff
hour 1 min 5 frame 5 offset 10240
01 05 05 ff ff ff ff ff ff ff ff ff ff
hour 1 min 5 frame 6 offset 12288
ff ff ff ff ff ff ff ff ff ff ff ff ff
- the first byte of the header contains the hour,
- the second byte contains the minutes,
- the third — the number of the frame,
- in case the frame is unused, the first three bytes contain the value 0xff,
- the remaining bytes of the header are never used.
Building custom language-packs
Based on the collected information another simple python script was written. It allows you to build a custom valid language pack from the set of arbitrary images of a suitable size. Further opportunities were limited only by imagination.
The first thing I decided to do was to return the clock an ability to display the digits (and binary digits just for fun):
Then came the turn of clock's hands and the BCD-format time presentation:
As the end of the project I prepared several dozens of old school 8-bit pictures (mainly from the ZX speccy) and uploaded them into the clock to form the slideshow: