UMD
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
Font1
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};