summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/sysinfo/benchmarkinfo.cpp94
-rw-r--r--noncore/settings/sysinfo/benchmarkinfo.h7
-rw-r--r--share/sysinfo/results30
3 files changed, 109 insertions, 22 deletions
diff --git a/noncore/settings/sysinfo/benchmarkinfo.cpp b/noncore/settings/sysinfo/benchmarkinfo.cpp
index 69d8229..0aeb251 100644
--- a/noncore/settings/sysinfo/benchmarkinfo.cpp
+++ b/noncore/settings/sysinfo/benchmarkinfo.cpp
@@ -1,221 +1,273 @@
1/********************************************************************** 1/**********************************************************************
2** BenchmarkInfo 2** BenchmarkInfo
3** 3**
4** A benchmark for Qt/Embedded 4** A benchmark for Qt/Embedded
5** 5**
6** Copyright (C) 2004 Michael Lauer <mickey@vanille.de> 6** Copyright (C) 2004 Michael Lauer <mickey@vanille.de>
7** Inspired by ZBench (C) 2002 Satoshi <af230533@im07.alpha-net.ne.jp> 7** Inspired by ZBench (C) 2002 Satoshi <af230533@im07.alpha-net.ne.jp>
8** 8**
9** This file may be distributed and/or modified under the terms of the 9** This file may be distributed and/or modified under the terms of the
10** GNU General Public License version 2 as published by the Free Software 10** GNU General Public License version 2 as published by the Free Software
11** Foundation and appearing in the file LICENSE.GPL included in the 11** Foundation and appearing in the file LICENSE.GPL included in the
12** packaging of this file. 12** packaging of this file.
13** 13**
14** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 14** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
15** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 15** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16** 16**
17**********************************************************************/ 17**********************************************************************/
18 18
19/* OPIE */ 19/* OPIE */
20#include <opie2/ostorageinfo.h> 20#include <opie2/ostorageinfo.h>
21#include <qpe/qpeapplication.h> 21#include <qpe/qpeapplication.h>
22#include <qpe/qcopenvelope_qws.h> 22#include <qpe/qcopenvelope_qws.h>
23#include <qpe/qpedecoration_qws.h> 23#include <qpe/qpedecoration_qws.h>
24#include <qpe/resource.h> 24#include <qpe/resource.h>
25#include <qpe/config.h> 25#include <qpe/config.h>
26 26
27/* QT */ 27/* QT */
28#include <qlayout.h> 28#include <qclipboard.h>
29#include <qcolor.h>
30#include <qcombobox.h>
31#include <qdirectpainter_qws.h>
32#include <qfile.h>
33#include <qtextstream.h>
29#include <qfiledialog.h> 34#include <qfiledialog.h>
30#include <qlabel.h> 35#include <qlabel.h>
36#include <qlayout.h>
31#include <qpainter.h> 37#include <qpainter.h>
32#include <qdirectpainter_qws.h>
33#include <qapplication.h>
34#include <qpushbutton.h> 38#include <qpushbutton.h>
35#include <qclipboard.h>
36#include <qtimer.h> 39#include <qtimer.h>
37#include <qcolor.h>
38#include <qpushbutton.h>
39 40
40/* STD */ 41/* STD */
41#include <time.h> 42#include <time.h>
42#include <stdio.h> 43#include <stdio.h>
43#include <stdlib.h> 44#include <stdlib.h>
44#include <math.h> 45#include <math.h>
45 46
46#include "benchmarkinfo.h" 47#include "benchmarkinfo.h"
47 48
48extern "C" 49extern "C"
49{ 50{
50 void BenchFFT( void ); 51 void BenchFFT( void );
51 double dhry_main( int ); 52 double dhry_main( int );
52} 53}
53 54
54#define DHRYSTONE_RUNS 20000000 55#define DHRYSTONE_RUNS 20000000
55#define TEST_DURATION 3 56#define TEST_DURATION 3
56 57
57#define BUFF_SIZE 8192 58#define BUFF_SIZE 8192
58#define FILE_SIZE 1024 * 1024 // 1Mb 59#define FILE_SIZE 1024 * 1024 // 1Mb
59 60
60//=========================================================================== 61//===========================================================================
61 62
62class BenchmarkPaintWidget : public QWidget 63class BenchmarkPaintWidget : public QWidget
63{ 64{
64 public: 65 public:
65 BenchmarkPaintWidget() : QWidget( 0, "Benchmark Paint Widget", WStyle_Customize|WStyle_StaysOnTop|WPaintUnclipped|WPaintClever ) 66 BenchmarkPaintWidget() : QWidget( 0, "Benchmark Paint Widget", WStyle_Customize|WStyle_StaysOnTop|WPaintUnclipped|WPaintClever )
66 { 67 {
67 resize( QApplication::desktop()->size() ); 68 resize( QApplication::desktop()->size() );
68 show(); 69 show();
69 p.begin( this ); 70 p.begin( this );
70 }; 71 };
71 72
72 ~BenchmarkPaintWidget() 73 ~BenchmarkPaintWidget()
73 { 74 {
74 p.end(); 75 p.end();
75 hide(); 76 hide();
76 }; 77 };
77 78
78 QPainter p; 79 QPainter p;
79}; 80};
80 81
81//=========================================================================== 82//===========================================================================
82 83
83BenchmarkInfo::BenchmarkInfo( QWidget *parent, const char *name, int wFlags ) 84BenchmarkInfo::BenchmarkInfo( QWidget *parent, const char *name, int wFlags )
84 : QWidget( parent, name, wFlags ) 85 : QWidget( parent, name, wFlags )
85{ 86{
86 87
87 setMinimumSize( 200, 150 ); 88 setMinimumSize( 200, 150 );
88 89
89 QVBoxLayout* vb = new QVBoxLayout( this ); 90 QVBoxLayout* vb = new QVBoxLayout( this );
90 vb->setSpacing( 4 ); 91 vb->setSpacing( 4 );
91 vb->setMargin( 4 ); 92 vb->setMargin( 4 );
92 93
93 tests = new QListView( this ); 94 tests = new QListView( this );
94 tests->setMargin( 1 ); 95 tests->setMargin( 0 );
95 tests->addColumn( "Tests" ); 96 tests->addColumn( tr( "Tests" ) );
96 tests->addColumn( "Results" ); 97 tests->addColumn( tr( "Results" ) );
98 tests->addColumn( tr( "Comparison" ) );
97 tests->setShowSortIndicator( true ); 99 tests->setShowSortIndicator( true );
98 100
99 test_alu = new QCheckListItem( tests, "1: Integer Arithmetic ", QCheckListItem::CheckBox ); 101 test_alu = new QCheckListItem( tests, tr( "1. Integer Arithmetic " ), QCheckListItem::CheckBox );
102 test_fpu = new QCheckListItem( tests, tr( "2. Floating Point Unit " ), QCheckListItem::CheckBox );
103 test_txt = new QCheckListItem( tests, tr( "3. Text Rendering " ), QCheckListItem::CheckBox );
104 test_gfx = new QCheckListItem( tests, tr( "4. Gfx Rendering " ), QCheckListItem::CheckBox );
105 test_ram = new QCheckListItem( tests, tr( "5. RAM Performance " ), QCheckListItem::CheckBox );
106 test_sd = new QCheckListItem( tests, tr( "6. SD Card Performance " ), QCheckListItem::CheckBox );
107 test_cf = new QCheckListItem( tests, tr( "7. CF Card Performance " ), QCheckListItem::CheckBox );
108
100 test_alu->setText( 1, "n/a" ); 109 test_alu->setText( 1, "n/a" );
101 test_fpu = new QCheckListItem( tests, "2: Floating Point Unit ", QCheckListItem::CheckBox ); 110 test_fpu->setText( 1, "n/a" );
102 test_fpu->setText( 1, "n/a" );
103 test_txt = new QCheckListItem( tests, "3: Text Rendering ", QCheckListItem::CheckBox );
104 test_txt->setText( 1, "n/a" ); 111 test_txt->setText( 1, "n/a" );
105 test_gfx = new QCheckListItem( tests, "4: Gfx Rendering ", QCheckListItem::CheckBox );
106 test_gfx->setText( 1, "n/a" ); 112 test_gfx->setText( 1, "n/a" );
107 test_ram = new QCheckListItem( tests, "5: RAM Performance ", QCheckListItem::CheckBox );
108 test_ram->setText( 1, "n/a" ); 113 test_ram->setText( 1, "n/a" );
109 test_sd = new QCheckListItem( tests, "6: SD Card Performance ", QCheckListItem::CheckBox );
110 test_sd->setText( 1, "n/a" ); 114 test_sd->setText( 1, "n/a" );
111 test_cf = new QCheckListItem( tests, "7: CF Card Performance ", QCheckListItem::CheckBox ); 115 test_cf->setText( 1, "n/a" );
112 test_cf->setText( 1, "n/a" ); 116
113 117 test_alu->setText( 2, "n/a" );
118 test_fpu->setText( 2, "n/a" );
119 test_txt->setText( 2, "n/a" );
120 test_gfx->setText( 2, "n/a" );
121 test_ram->setText( 2, "n/a" );
122 test_sd->setText( 2, "n/a" );
123 test_cf->setText( 2, "n/a" );
124
114 startButton = new QPushButton( tr( "&Start Tests!" ), this ); 125 startButton = new QPushButton( tr( "&Start Tests!" ), this );
115 connect( startButton, SIGNAL( clicked() ), this, SLOT( run() ) ); 126 connect( startButton, SIGNAL( clicked() ), this, SLOT( run() ) );
116 127
117 vb->addWidget( tests, 2 ); 128 vb->addWidget( tests, 2 );
118 vb->addWidget( startButton ); 129
130 QFile f( QPEApplication::qpeDir() + "/share/sysinfo/results" );
131 if ( f.open( IO_ReadOnly ) )
132 {
133 machineCombo = new QComboBox( this );
134
135 QTextStream ts( &f );
136 while( !ts.eof() )
137 {
138 QString machline = ts.readLine();
139 qDebug( "sysinfo: parsing benchmark results for '%s'", (const char*) machline );
140 QString resline = ts.readLine();
141 machines.insert( machline, new QStringList( QStringList::split( ",", resline ) ) );
142 machineCombo->insertItem( machline );
143 }
144
145 QHBoxLayout* hb = new QHBoxLayout( vb );
146 hb->addWidget( new QLabel( tr( "Compare To:" ), this ) );
147 hb->addWidget( machineCombo, 2 );
148 connect( machineCombo, SIGNAL( activated( int ) ), this, SLOT( machineActivated( int ) ) );
149 }
150
151 vb->addWidget( startButton, 2 );
119} 152}
120 153
121 154
122BenchmarkInfo::~BenchmarkInfo() 155BenchmarkInfo::~BenchmarkInfo()
123{} 156{}
124 157
125 158
159void BenchmarkInfo::machineActivated( int index )
160{
161 QStringList* results = machines[ machineCombo->text( index ) ];
162 if ( !results )
163 {
164 qDebug( "sysinfo: no results available." );
165 return;
166 }
167 QStringList::Iterator it = results->begin();
168 test_alu->setText( 2, *(it++) );
169 test_fpu->setText( 2, *(it++) );
170 test_txt->setText( 2, *(it++) );
171 test_gfx->setText( 2, *(it++) );
172 test_ram->setText( 2, *(it++) );
173 test_sd->setText( 2, *(it++) );
174 test_cf->setText( 2, *(it++) );
175}
176
177
126void BenchmarkInfo::run() 178void BenchmarkInfo::run()
127{ 179{
128 startButton->setText( "> Don't touch! Running Tests! Don't touch! <" ); 180 startButton->setText( "> Don't touch! Running Tests! Don't touch! <" );
129 qApp->processEvents(); 181 qApp->processEvents();
130 QTime t; 182 QTime t;
131 183
132 if ( test_alu->isOn() ) 184 if ( test_alu->isOn() )
133 { 185 {
134 int d = round( dhry_main( DHRYSTONE_RUNS ) ); 186 int d = round( dhry_main( DHRYSTONE_RUNS ) );
135 test_alu->setText( 1, QString( "%1 dhrys" ).arg( QString::number( d ) ) ); 187 test_alu->setText( 1, QString( "%1 dhrys" ).arg( QString::number( d ) ) );
136 test_alu->setOn( false ); 188 test_alu->setOn( false );
137 } 189 }
138 190
139 if ( test_fpu->isOn() ) 191 if ( test_fpu->isOn() )
140 { 192 {
141 t.start(); 193 t.start();
142 BenchFFT(); 194 BenchFFT();
143 test_fpu->setText( 1, QString( "%1 secs" ).arg( QString::number( t.elapsed() / 1000.0 ) ) ); 195 test_fpu->setText( 1, QString( "%1 secs" ).arg( QString::number( t.elapsed() / 1000.0 ) ) );
144 test_fpu->setOn( false ); 196 test_fpu->setOn( false );
145 } 197 }
146 198
147 if ( test_txt->isOn() ) 199 if ( test_txt->isOn() )
148 { 200 {
149 int value = textRendering( TEST_DURATION ); 201 int value = textRendering( TEST_DURATION );
150 test_txt->setText( 1, QString( "%1 chars/sec" ).arg( QString::number( value / TEST_DURATION ) ) ); 202 test_txt->setText( 1, QString( "%1 chars/sec" ).arg( QString::number( value / TEST_DURATION ) ) );
151 test_txt->setOn( false ); 203 test_txt->setOn( false );
152 } 204 }
153 205
154 if ( test_gfx->isOn() ) 206 if ( test_gfx->isOn() )
155 { 207 {
156 int value = gfxRendering( TEST_DURATION ); 208 int value = gfxRendering( TEST_DURATION );
157 test_gfx->setText( 1, QString( "%1 gops/sec" ).arg( QString::number( value / 4 / TEST_DURATION ) ) ); // 4 tests 209 test_gfx->setText( 1, QString( "%1 gops/sec" ).arg( QString::number( value / 4 / TEST_DURATION ) ) ); // 4 tests
158 test_gfx->setOn( false ); 210 test_gfx->setOn( false );
159 } 211 }
160 212
161 if ( test_ram->isOn() ) // /tmp is supposed to be in RAM on a PDA 213 if ( test_ram->isOn() ) // /tmp is supposed to be in RAM on a PDA
162 { 214 {
163 performFileTest( "/tmp/benchmarkFile.dat", test_ram ); 215 performFileTest( "/tmp/benchmarkFile.dat", test_ram );
164 } 216 }
165 217
166 if ( test_cf->isOn() ) 218 if ( test_cf->isOn() )
167 { 219 {
168 OStorageInfo storage; 220 OStorageInfo storage;
169 performFileTest( storage.cfPath() + "/benchmarkFile.dat", test_cf ); 221 performFileTest( storage.cfPath() + "/benchmarkFile.dat", test_cf );
170 } 222 }
171 223
172 if ( test_sd->isOn() ) 224 if ( test_sd->isOn() )
173 { 225 {
174 OStorageInfo storage; 226 OStorageInfo storage;
175 performFileTest( storage.sdPath() + "/benchmarkFile.dat", test_sd ); 227 performFileTest( storage.sdPath() + "/benchmarkFile.dat", test_sd );
176 } 228 }
177 229
178 startButton->setText( tr( "&Start Tests!" ) ); 230 startButton->setText( tr( "&Start Tests!" ) );
179} 231}
180 232
181 233
182int BenchmarkInfo::textRendering( int seconds ) 234int BenchmarkInfo::textRendering( int seconds )
183{ 235{
184 QTime t; 236 QTime t;
185 t.start(); 237 t.start();
186 int stop = t.elapsed() + seconds * 1000; 238 int stop = t.elapsed() + seconds * 1000;
187 239
188 int rr[] = { 255, 255, 255, 0, 0, 0, 0, 128, 128 }; 240 int rr[] = { 255, 255, 255, 0, 0, 0, 0, 128, 128 };
189 int gg[] = { 0, 255, 0, 0, 255, 255, 0, 128, 128 }; 241 int gg[] = { 0, 255, 0, 0, 255, 255, 0, 128, 128 };
190 int bb[] = { 0, 0, 255, 0, 0, 255, 255, 128, 0 }; 242 int bb[] = { 0, 0, 255, 0, 0, 255, 255, 128, 0 };
191 const QString text( "Opie Benchmark Test" ); 243 const QString text( "Opie Benchmark Test" );
192 244
193 int w = QApplication::desktop()->width(); 245 int w = QApplication::desktop()->width();
194 int h = QApplication::desktop()->height(); 246 int h = QApplication::desktop()->height();
195 247
196 srand( time( NULL ) ); 248 srand( time( NULL ) );
197 249
198 BenchmarkPaintWidget bpw; 250 BenchmarkPaintWidget bpw;
199 251
200 int loops = 0; 252 int loops = 0;
201 253
202 while ( t.elapsed() < stop ) 254 while ( t.elapsed() < stop )
203 { 255 {
204 int k = rand() % 9; 256 int k = rand() % 9;
205 int s = rand() % 100; 257 int s = rand() % 100;
206 bpw.p.setPen( QColor( rr[ k ], gg[ k ], bb[ k ] ) ); 258 bpw.p.setPen( QColor( rr[ k ], gg[ k ], bb[ k ] ) );
207 bpw.p.setFont( QFont( "Vera", s ) ); 259 bpw.p.setFont( QFont( "Vera", s ) );
208 bpw.p.drawText( rand() % w, rand() % h, text, text.length() ); 260 bpw.p.drawText( rand() % w, rand() % h, text, text.length() );
209 ++loops; 261 ++loops;
210 } 262 }
211 263
212 return loops * text.length(); 264 return loops * text.length();
213} 265}
214 266
215int BenchmarkInfo::gfxRendering( int seconds ) 267int BenchmarkInfo::gfxRendering( int seconds )
216{ 268{
217 int rr[] = { 255, 255, 255, 0, 0, 0, 0, 128, 128 }; 269 int rr[] = { 255, 255, 255, 0, 0, 0, 0, 128, 128 };
218 int gg[] = { 0, 255, 0, 0, 255, 255, 0, 128, 128 }; 270 int gg[] = { 0, 255, 0, 0, 255, 255, 0, 128, 128 };
219 int bb[] = { 0, 0, 255, 0, 0, 255, 255, 128, 0 }; 271 int bb[] = { 0, 0, 255, 0, 0, 255, 255, 128, 0 };
220 272
221 int w = QApplication::desktop()->width(); 273 int w = QApplication::desktop()->width();
diff --git a/noncore/settings/sysinfo/benchmarkinfo.h b/noncore/settings/sysinfo/benchmarkinfo.h
index 3c5ca37..d143602 100644
--- a/noncore/settings/sysinfo/benchmarkinfo.h
+++ b/noncore/settings/sysinfo/benchmarkinfo.h
@@ -1,64 +1,69 @@
1/********************************************************************** 1/**********************************************************************
2** BenchmarkInfo 2** BenchmarkInfo
3** 3**
4** A benchmark for Qt/Embedded 4** A benchmark for Qt/Embedded
5** 5**
6** Copyright (C) 2004 Michael Lauer <mickey@vanille.de> 6** Copyright (C) 2004 Michael Lauer <mickey@vanille.de>
7** Inspired by ZBench (C) 2002 Satoshi <af230533@im07.alpha-net.ne.jp> 7** Inspired by ZBench (C) 2002 Satoshi <af230533@im07.alpha-net.ne.jp>
8** 8**
9** This file may be distributed and/or modified under the terms of the 9** This file may be distributed and/or modified under the terms of the
10** GNU General Public License version 2 as published by the Free Software 10** GNU General Public License version 2 as published by the Free Software
11** Foundation and appearing in the file LICENSE.GPL included in the 11** Foundation and appearing in the file LICENSE.GPL included in the
12** packaging of this file. 12** packaging of this file.
13** 13**
14** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 14** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
15** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 15** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16** 16**
17**********************************************************************/ 17**********************************************************************/
18 18
19#include <qwidget.h> 19#include <qwidget.h>
20#include <qdialog.h> 20#include <qdialog.h>
21#include <qdict.h>
22#include <qstringlist.h>
21 23
22class QClipboard; 24class QClipboard;
25class QComboBox;
23class QCheckListItem; 26class QCheckListItem;
24class QPushButton; 27class QPushButton;
25class QListView; 28class QListView;
26 29
27class BenchmarkInfo : public QWidget 30class BenchmarkInfo : public QWidget
28{ 31{
29 Q_OBJECT 32 Q_OBJECT
30 33
31public: 34public:
32 BenchmarkInfo( QWidget *parent = 0, const char *name = 0, int wFlags = 0 ); 35 BenchmarkInfo( QWidget *parent = 0, const char *name = 0, int wFlags = 0 );
33 ~BenchmarkInfo(); 36 ~BenchmarkInfo();
34 37
35 QCheckListItem* test_alu; 38 QCheckListItem* test_alu;
36 QCheckListItem* test_fpu; 39 QCheckListItem* test_fpu;
37 QCheckListItem* test_txt; 40 QCheckListItem* test_txt;
38 QCheckListItem* test_gfx; 41 QCheckListItem* test_gfx;
39 QCheckListItem* test_ram; 42 QCheckListItem* test_ram;
40 QCheckListItem* test_sd; 43 QCheckListItem* test_sd;
41 QCheckListItem* test_cf; 44 QCheckListItem* test_cf;
42 45
43 bool main_rd; 46 bool main_rd;
44 bool main_wt; 47 bool main_wt;
45 bool sd_rd; 48 bool sd_rd;
46 bool sd_wt; 49 bool sd_wt;
47 bool cf_rd; 50 bool cf_rd;
48 bool cf_wt; 51 bool cf_wt;
49 52
50 QClipboard* clb; 53 QClipboard* clb;
51 54 QComboBox* machineCombo;
52 QListView* tests; 55 QListView* tests;
53 QPushButton* startButton; 56 QPushButton* startButton;
57 QDict <QStringList> machines;
54 58
55 int textRendering( int ); 59 int textRendering( int );
56 int gfxRendering( int ); 60 int gfxRendering( int );
57 void performFileTest( const QString& fname, QCheckListItem* item ); 61 void performFileTest( const QString& fname, QCheckListItem* item );
58 62
59private slots: 63private slots:
60 bool writeFile( const QString& ); 64 bool writeFile( const QString& );
61 bool readFile( const QString& ); 65 bool readFile( const QString& );
62 void run(); 66 void run();
67 void machineActivated( int );
63}; 68};
64 69
diff --git a/share/sysinfo/results b/share/sysinfo/results
new file mode 100644
index 0000000..1866da3
--- a/dev/null
+++ b/share/sysinfo/results
@@ -0,0 +1,30 @@
1<Choose a model>
2n/a,n/a,n/a,n/a,n/a,n/a,n/a,n/a,n/a
3Sharp SL-5500
4240010 dhrys,41.498 sec,88 char/sec,1786 gops/sec,50.123 kb/sec,41.7329 kb/sec,105.873 kb/sec
5Sharp SL-5600
6not,yet,contributed,please,mail,to,opie@handhelds.org
7Sharp C-700
8not,yet,contributed,please,mail,to,opie@handhelds.org
9Sharp C-750
10not,yet,contributed,please,mail,to,opie@handhelds.org
11Sharp C-760
12not,yet,contributed,please,mail,to,opie@handhelds.org
13Sharp C-860
14not,yet,contributed,please,mail,to,opie@handhelds.org
15HP iPAQ 36xx
16not,yet,contributed,please,mail,to,opie@handhelds.org
17HP iPAQ 37xx
18not,yet,contributed,please,mail,to,opie@handhelds.org
19HP iPAQ 38xx
20not,yet,contributed,please,mail,to,opie@handhelds.org
21HP iPAQ 54xx
22not,yet,contributed,please,mail,to,opie@handhelds.org
23HP iPAQ 55xx
24not,yet,contributed,please,mail,to,opie@handhelds.org
25HP Jornada 5x0
26not,yet,contributed,please,mail,to,opie@handhelds.org
27M&N Ramses
28not,yet,contributed,please,mail,to,opie@handhelds.org
29SIEMENS SIMpad
30not,yet,contributed,please,mail,to,opie@handhelds.org