UMD

From RevSpace
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Project UMD
Under Monitor Display hacks
Status Abandoned
Contact Eightdot, Sebastius
Last Update 2019-01-13

Introduction

todo

on Host

stty -F /dev/ttyUSB0 115200

C code:

./test CD 01 05 ff `echo Hoi RevSpace | perl -nle'print join " ", unpack("H*", $_) =~ /(..)/g'`  > /dev/ttyUSB0

Perl code:

perl test.pl "Hoi RevSpace" > /dev/ttyUSB0

C code

#include <stdio.h>
#include <stdlib.h>

unsigned short crctbl[]={
	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};

unsigned short docrc(unsigned short crci,unsigned char data)
{
	unsigned short idx,crc;
	crc=crci;
	idx = (crc ^ data) & 0xff;
	crc >>=8;
	crc ^= crctbl[idx];
	return crc;	
}



int main(int argc, char ** argv)
{
	int i,len=1;
	unsigned char buffer[512];
	unsigned char tmp;
	unsigned short crc=0xffff;
	buffer[0]=0xfe;
	for (i=1;i<argc;i++)
	{
		tmp=strtol(argv[i],NULL,16);
		crc=docrc(crc,tmp);
		if((tmp==0xff) || (tmp==0xfe) || (tmp==0xfd))
		{
			buffer[len++]=0xfd;
			tmp ^= 0x20;
		}
		buffer[len++]=tmp;
		//printf("%04x\n",crc);
	}
	tmp=crc ^ 0xff;
	if((tmp==0xff) || (tmp==0xfe) || (tmp==0xfd))
	{
		buffer[len++]=0xfd;
		tmp ^= 0x20;
	}
	buffer[len++]=tmp;
	tmp=(crc>>8) ^ 0xff;
	if((tmp==0xff) || (tmp==0xfe) || (tmp==0xfd))
	{
		buffer[len++]=0xfd;
		tmp ^= 0x20;
	}
	buffer[len++]=tmp;
	buffer[len++]=0xff;
	for(i=0;i<len;i++)
	{
		//printf("%02x ",buffer[i]);
		printf("%c",buffer[i]);
	}
	//printf("\n");
	crc=docrc(crc,crc ^ 0xff);
	//printf("%04x\n",crc);
	crc=docrc(crc,tmp);
	//printf("%04x\n",crc);
	return 0;
}

Equivalente Perlcode

#!/usr/bin/perl -w
use strict;
use Digest::CRC;

my $crc = Digest::CRC->new(
    width => 16, init => 0xffff,
    xorout => 0, refout => 1, poly => 0x1021, refin => 1, cont => 1
);

my $text = shift;

my $command = "\xcd\x01\x05\xff$text";
$crc->add($command);

my $checksum = "\xff\xff" ^ pack "v", $crc->digest;

$command .= $checksum;
$command =~ s/([\xfd-\xff])/"\xfd" . ($1 ^ "\x20")/ge;

my $packet = "\xfe$command\xff";
print $packet;

Protocol

bootloader (in EPROM)

starts program download if:
address == 0xFE  ||
flash[5] !=0x23  ||    //programmed after rest of flash
flash[6] !=0xff        //programmed to 0 by appication before
                       //reboot to request download



max 0x200 bytes/?message?
0xFD   escape, next byte ^= 0x20
0xFE   message start
0xFF   message end

crc16_<<ccitt?>> over unescaped data,
including crc bytes should give 0xf0B8

message:
+0      ?
+1      0x05
+2      0x02 erase
"       0x05 program
"       0x0a done
+3      program: address low
+5      program: address high
+7      program: data (len = messagelen-7)

application (in FLASH)

0xFD   escape, next byte ^= 0x20
0xFE   message start
0xFF   message end

crc16_<<ccitt?>> over unescaped data,
including crc bytes should give 0xf0B8
 
message:
+0      0xFF    bootload, writes 0x00 to flash[0x6], then reboots
+1      0x05    ? must be 0x05
+2      0x01    ? must be 0x01
+3      swver   must be 0xffff or >= flash[0xE]
                        (=0x0504 = v4.5)
+5      hwver   must be flash[0x14] (=0x03)     
              
message:
+0      0x02    update bit_buf
+1              data (len=msg_size-1; max 0x400)

message:
+0      0xDB    broadcast ?
+1       0x01   set telly? (note: no reset)
+2       idx    bit to set ?

message:
+0      0xCD    unicast ?
+1      0xFF    to all ?
+2      0x02    bitbus set bytes        +3 offs         +5 data
"       0x05    set str by id           +3 id           +5 str
"       0x07    see 0x0c
"       0x0c    cpy? 3E80 by id         +3 id           +5 data (words)
"       0x0d    update str by id        +3 id           +5 str

+0      0xCD    unicast ?
+1      addr    must be my_addr (canot be 0xff)
+2      0x01    ? len==0x4 ? clr ?      +3 idx          strobj.len=0
"       0x01    ? len!=0x4 ? clr ?      +3 idx          +4 pos      +8 len 
"       0x02    set stridx id           +3 str_idx      +4 id
"       0x04    set strobj flags        +3 idx          +4 val      &03 font (0,1 valid 2,3 invalid)
                                           &08 dimm &10 inverse video &20 left al. &40 right al. &84 ??
"       0x05    set strobj string       +3 idx          +4..14 string
"       0x07    see 0x0c
"       0x09    cpy ?                   idx=myaddr?     +3 data (words)
"       0x0a    set displ_map_bright?   +3 val
"       0x0b    set telly bits?         +3 idx          +4 data (dwords)
"       0x0c    ?cpy?                   +3 idx          +4 data (words)
"       0x0d    set stings              +3 idx          +4 strings (0 sep)
"       0x0e    set substr bitidxmap    +3 str_idx      +4 data (words)
"       0x0f    set substr idxs         +3 str_idx      +4 data

fonts

Font0

UMD font0.svg

Font1

UMD font1.svg

dumper

#!/usr/bin/perl

use strict;

use Fcntl qw(:seek);

my($fh, $filename, $byte_position, $fontbytes);

$filename      = "umd_flash.bin";
$byte_position = 0x16e0+0x800*1;

open($fh, "<", $filename)
  || die "can't open $filename: $!";

binmode($fh)
  || die "can't binmode $filename";

sysseek($fh, $byte_position, SEEK_CUR)  # NB: 0-based
  || die "couldn't see to byte $byte_position in $filename: $!";

sysread($fh, $fontbytes, 0x800,0) == 0x800
  || die "couldn't read byte from $filename: $!";


my $ledsz = 10;
my $cellsz = $ledsz*8+6;
my $tblsz = 16*$cellsz;

print qq(<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n);
print qq{<svg width="@{[ $tblsz+4 ]}" height="@{[ $tblsz+4 ]}" xmlns="http://www.w3.org/2000/svg">\n};
print qq(<rect width="@{[ $tblsz+2 ]}" height="@{[ $tblsz+2 ]}" style="fill:rgb(255,255,255);stroke-width:1;stroke:rgb(0,0,0)" />);
foreach my $row (0 .. 15)
{ 
	print qq(<line x1="0" x2="@{[ $tblsz+2 ]}" y1="@{[ $row*$cellsz+1 ]}" y2="@{[ $row*$cellsz+1 ]}" style="stroke:rgb(0,0,0);stroke-width:1"/>\n);
	print qq(<line y1="0" y2="@{[ $tblsz+2 ]}" x1="@{[ $row*$cellsz+1 ]}" x2="@{[ $row*$cellsz+1 ]}" style="stroke:rgb(0,0,0);stroke-width:1"/>\n);
	foreach my $col (0..15)
	{
		my $charlen=ord(substr($fontbytes,$row*128+$col*8,1));
		my $charbytes=substr($fontbytes,$row*128+$col*8+1,7);
		if ($charlen ne 0)
		{
			print qq(<rect x="@{[ $col*$cellsz+4 ]}" y="@{[ $row*$cellsz+4 ]}" width="@{[ $ledsz*$charlen+1 ]}" height="@{[ $ledsz*7 ]}");
		        print 	qq( style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" />\n);
			foreach my $byt (0..7)
			{
				foreach my $bit (0..7)
				{
					if(ord(substr($charbytes,$byt,1)) & (1<<$bit))
					{
						print qq(<circle cx="@{[ $col*$cellsz+4+$ledsz*$byt+$ledsz/2 ]}");
					        print qq( cy="@{[ $row*$cellsz+4+$ledsz*$bit+$ledsz/2 ]}" r="@{[ $ledsz/2 ]}");
						print qq( stroke="black" stroke-width="1" fill="#00ff00" />\n);
					}
				}
			}
		}
	}

}
print qq{</svg>\n};