-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathTI_calculator_simulator.html
472 lines (440 loc) · 24.9 KB
/
TI_calculator_simulator.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
<html>
<!--
TI calculator simulator
Ken Shirriff, http://righto.com/ti
Based on patent US3934233
-->
<head>
<title>Simulating a TI calculator with crazy 11-bit opcodes</title>
<meta name="description" content="Register-level simulator of a TI calculator with 11-bit opcodes">
<meta name="keywords" content="calculator,simulator,TI,Datamath,0800,Texas Instruments, reverse engineering">
<meta name="author" content="Ken Shirriff">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Chivo:400' rel='stylesheet' type='text/css'/>
<script src="calcImage.js"></script>
<script src="controller.js"></script>
<script src="cpu.js"></script>
<script src="display.js"></script>
<script src="instruction.js"></script>
<script src="keygrid.js"></script>
<script src="masks_0800.js"></script>
<script src="model.js"></script>
<script src="registers.js"></script>
<script src="sourceCode.js"></script>
<script src="sourceWindow.js"></script>
<!-- header styles -->
<style type="text/css">
body {
font-family: arial;
margin: 0;
}
#header {
padding: 0;
margin: 0;
border-top: dotted 1px #444444;
border-bottom: dotted 1px #444444;
background: #f6fbf7;
}
h1 {
margin: 8px 0 0 0;
padding-top:20px;
padding-right:0px;
padding-bottom:2px;
padding-left:5%;
color:#444444;
background:#f6fbf7;
font:normal 300% Chivo,Verdana,Sans-Serif;
letter-spacing:-2px;
}
.description {
padding:0px;
margin-top:7px;
margin-right:12%;
margin-bottom:7px;
margin-left:5%;
color:#444444;
background:transparent;
font:bold 100% Verdana,Sans-Serif;
}
div.cite {font-size: .8em;.; font-style: italic; color: #888; margin-bottom: 9px;}
.cite a {color: #888 !important;}
a.ref { color: gray;vertical-align: super; text-decoration: none; font-size:60%;margin-left: 2px;}
a img.hilite {
border: 1px solid;
color: #888;
}
a:link img.hilite, a:visited img.hilite {
color: #888;
}
a:hover img.hilite {
color: #f66;
}
a:active img.hilite {
color: #33c;
}
</style>
<!-- content styles -->
<style type="text/css">
.content {
margin: 20px;
}
h3 {
color: #444444;
font: normal 160% Verdana,Sans-Serif;
letter-spacing: -1px;
}
#calcImageDiv {
float: left;
height:400px;
position: relative;
}
#calcImage {
position: absolute;
top: 0;
left: 0;
}
button {
border: 1px solid #ccc;
width: 33px;
height: 33px;
cursor: pointer;
}
.cond, .cond th, .cond tr, .cond td {
border: none !important;
text-align: left !important;
}
td {
font-family: courier, fixed;
}
#registers {
border-collapse: collapse;
border-right: 1px solid #ddd;
}
#registers th {
font-weight: bold;
text-align: right;
padding-right: 10px;
border-right: 1px solid #ddd;
max-width: 70px;
width: 70px;
}
#registers td {
text-align: center;
min-width: 43px;
width: 43px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.mask {
background-color: #fcc;
}
#sourceWindow {
font-size: 14px;
line-height: 1em;
width: 500px;
height: 336px;
border: 1px solid #ddd;
font-family: courier, fixed;
font-size: 12px;
overflow-x: hidden;
overflow-y: scroll;
}
div#instruction {
margin-top: 10px;
}
div#sourceWindow div {
font-family: courier, fixed;
white-space: pre;
color: #ccc;
}
.addr {
color: #844;
}
.instr {
color: #000;
}
.comment {
color: #090;
}
.highlight {
background-color: #fcc;
}
</style>
<script>
$(document).ready(function() {
var model = new Model(objectCode);
var keys = [
['1', '2', '3', '4', '5', '6', '7', '8', '9', ''],
['C', '=', '+', '-', '*', '/', 'CE', '.', '0', 'D'],
['', '', '', '', '', '', '', '', '', '']];
// Initialize the positions of the keys in the image
var xvals = [[45, 92], [108, 154], [171, 217], [233, 280]];
var xbotvals = [[45, 125], [139, 187], [202, 280]];
var yvals = [[254, 303], [316, 365], [379, 427], [441, 490], [503, 552]];
var keypos = {
'CE': [xvals[0], yvals[0]],
'/': [xvals[1], yvals[0]],
'*': [xvals[2], yvals[0]],
'7': [xvals[0], yvals[1]],
'8': [xvals[1], yvals[1]],
'9': [xvals[2], yvals[1]],
'C': [xvals[3], yvals[1]],
'4': [xvals[0], yvals[2]],
'5': [xvals[1], yvals[2]],
'6': [xvals[2], yvals[2]],
'-': [xvals[3], yvals[2]],
'1': [xvals[0], yvals[3]],
'2': [xvals[1], yvals[3]],
'3': [xvals[2], yvals[3]],
'+': [xvals[3], yvals[3]],
'0': [xbotvals[0], yvals[4]],
'.': [xbotvals[1], yvals[4]],
'=': [xbotvals[2], yvals[4]],
'POWER': [[242, 260], [261, 288]]};
var keygrid = new Keygrid($("#keygrid")[0], model, keys);
var calcImage = new CalcImage($("#calcImage"), model, keypos, 329, 600 /* image original dimensions */);
var registers = new Registers($("#registers")[0], model);
var display = new Display($("#display"), model);
var display2 = new Display($("#calcDisplay"), model);
var sourceWindow = new SourceWindow($("#sourceWindow"), model, sourceCode);
var cpu = new Cpu(model, masks);
var instruction = new Instruction($("#instruction"), model);
var controller = new Controller(calcImage, model, keygrid, display, display2, sourceWindow, cpu,
registers, instruction, $("#playButton"), $("#stopButton"), $("#stepButton"));
});
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-3782444-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
</body>
<div id="header-wrapper" style="font-size:small">
<div class="header section" id="header"><div class="widget Header" id="Header1">
<div id="header-inner" style="background-image: url(https://lh5.googleusercontent.com/-OyFd36t2Doo/T7nMSchO46I/AAAAAAAAKjM/ynuhCCEf_bs/s800/background.jpg); background-position: right ; min-height: 105px; height: 105px; background-repeat: no-repeat; ">
<div class="titlewrapper" style="background: transparent" onclick="window.location='http://righto.com'">
<h1 class="title" style="background: transparent; border-width: 0px">
Ken Shirriff's blog
</h1>
</div>
<div class="descriptionwrapper">
<!--
<p class="description"><span>Chargers, microprocessors, Arduino, and whatever</span></p>
</div>
-->
</div>
</div></div>
</div>
<div class="content">
<h3>Simulating a TI calculator with crazy 11-bit opcodes</h3>
<div style="border: 1px solid gray; background-color: #e8d6ab; padding: 5px; margin-bottom: 15px;">
I've also built a <a href="http://files.righto.com/calculator/sinclair_scientific_simulator.html">simulator for the Sinclair Scientific calculator</a> that shows how trig and log were implemented in 320 instructions. Check it out!
</div>
This realistic simulator of a 4-function Texas Instruments calculator from 1974 runs the calculator's source code instruction by instruction by simulating the processor. The unusual processor has 11-bit opcodes, 44-bit BCD registers, and a 9-bit address bus.
<p>
To use the simulator, <i>slowly</i> click keys on the calculator image and
you can watch how the calculator performs operations step by step. Since the processor doesn't do multiplication or division, it does these operations by repeated addition or subtraction.
Try 2 ÷ 3 = for example.
<p>
<div id="calcImageDiv">
<img id="calcImage" src="http://files.righto.com/calculator/TI_DataMath_2500.jpg" width=220 height=400></img>
<canvas id="calcDisplay" width="150" height="30" style="position: absolute; top: 88px; left: 32px;"></canvas>
</div>
<div style="margin-left: 240px; ">
<button id="playButton" title="run" style="background:url(http://files.righto.com/calculator/play.png) no-repeat 2px 2px;"></button>
<button id="stopButton" title="stop" style="background:url(http://files.righto.com/calculator/stop.png) no-repeat 2px 2px;"></button>
<button id="stepButton" title="step" style="background:url(http://files.righto.com/calculator/step.png) no-repeat 2px 2px;"></button>
<br/>
<div id="sourceWindow"></div>
<div id="instruction"></div>
</div>
<div style="clear: both;"></div>
<p>
<p>
<canvas id="display" width="405" height="70" style="padding-left: 80px;"></canvas>
<br/>
<canvas id="keygrid" width="405" height="95" style="margin-left: 80px"></canvas>
<table id="registers">
<tr><th>D</th>
<td id="registers-d10"></td>
<td id="registers-d9"></td>
<td id="registers-d8"></td>
<td id="registers-d7"></td>
<td id="registers-d6"></td>
<td id="registers-d5"></td>
<td id="registers-d4"></td>
<td id="registers-d3"></td>
<td id="registers-d2"></td>
<td id="registers-d1"></td>
<td id="registers-d0"></td>
</tr>
<tr><th>A</th>
<td id="registers-a10"></td>
<td id="registers-a9"></td>
<td id="registers-a8"></td>
<td id="registers-a7"></td>
<td id="registers-a6"></td>
<td id="registers-a5"></td>
<td id="registers-a4"></td>
<td id="registers-a3"></td>
<td id="registers-a2"></td>
<td id="registers-a1"></td>
<td id="registers-a0"></td>
</tr>
<tr><th>B</th>
<td id="registers-b10"></td>
<td id="registers-b9"></td>
<td id="registers-b8"></td>
<td id="registers-b7"></td>
<td id="registers-b6"></td>
<td id="registers-b5"></td>
<td id="registers-b4"></td>
<td id="registers-b3"></td>
<td id="registers-b2"></td>
<td id="registers-b1"></td>
<td id="registers-b0"></td>
</tr>
<tr><th>C</th>
<td id="registers-c10"></td>
<td id="registers-c9"></td>
<td id="registers-c8"></td>
<td id="registers-c7"></td>
<td id="registers-c6"></td>
<td id="registers-c5"></td>
<td id="registers-c4"></td>
<td id="registers-c3"></td>
<td id="registers-c2"></td>
<td id="registers-c1"></td>
<td id="registers-c0"></td>
</tr>
<tr><th>AF</th>
<td id="registers-af10" title="dpt"></td>
<td id="registers-af9"></td>
<td id="registers-af8"></td>
<td id="registers-af7" title="st"></td>
<td id="registers-af6" title="sign"></td>
<td id="registers-af5" title="post/temp"></td>
<td id="registers-af4" title="equal"></td>
<td id="registers-af3" title="clear display"></td>
<td id="registers-af2" title="op3: operation"></td>
<td id="registers-af1" title="op2: sub/div"></td>
<td id="registers-af0" title="op1: mul/div"></td>
</tr>
<tr><th>BF</th>
<td id="registers-bf10" title="fd"></td>
<td id="registers-bf9"></td>
<td id="registers-bf8"></td>
<td id="registers-bf7"></td>
<td id="registers-bf6" title="sign"></td>
<td id="registers-bf5" title="ovf"></td>
<td id="registers-bf4" title="post/temp"></td>
<td id="registers-bf3" title="const"></td>
<td id="registers-bf2" title="op3: operation"></td>
<td id="registers-bf1" title="op2: sub/div"></td>
<td id="registers-bf0" title="op1: mul/div"></td>
</tr>
<tr><th>MASK/K</th>
<td id="registers-m10"></td>
<td id="registers-m9"></td>
<td id="registers-m8"></td>
<td id="registers-m7"></td>
<td id="registers-m6"></td>
<td id="registers-m5"></td>
<td id="registers-m4"></td>
<td id="registers-m3"></td>
<td id="registers-m2"></td>
<td id="registers-m1"></td>
<td id="registers-m0"></td>
</tr>
<tr class="cond"><th>Instr</th>
<td colspan=4 id="registers-i" style="font-family: courier, fixed"></td>
</tr>
<tr class="cond"><th>Cond</th>
<td colspan=4 id="registers-cc"></td>
</tr>
</table>
<h4>The simulator</h4>
The simulator simulates the calculator at the register and instruction level, showing what the hardware really does.
The register table at the bottom shows the digit scan register D, the 11-digit A, B, and C registers, the 11-bit flag registers AF and BF, the current mask and constant (K) value, the 11-bit instruction being executed, and the condition code.
Above that, the display and keyboard matrix show how the hardware is organized and how one column of the display and keyboard gets scanned each operation.
The source code window shows the code that is being executed. The A register hold the value that is displayed, and the B register controls the decimal point position.
<p>
The simulator is implemented in JavaScript. I haven't optimized it for performance, since it's interesting to see the instructions as they execute.
You can use the single-step button above the source window to see what's happening in more detail.
For comparison, the real processor runs at about 4000 instructions per second.
<p>
<h4>Architecture</h4>
The <a href="http://datamath.org/Chips/TMS0803.htm">TMS0800</a> series calculator chip was used in the <a href="http://datamath.org/BASIC/TI-1000/TI-1500.htm">TI-1500</a> calculator, Sinclair Scientific, and other calculators of the mid 1970s.
This processor has many unusual architectural features. It's interesting to examine this chip and discover how many CPU features that we take for granted can actually be done very differently.
<p>
The three registers (A, B, and C) hold eleven decimal digits as BCD, and the arithmetic takes place in decimal, digit by digit. The chip supports multi-digit decimal addition and subtraction, but not multiplication or division.
<p>
Each instruction is an 11 bit opcode, which comes from a ROM that has 320 11-bit words. The entire calculator software had to fit in this tiny ROM. An eleven bit instruction set seems very unusual, but it allows all instructions to fit into a single 11-bit word, avoiding multi-byte instructions. The first two bits of an instruction are the "class", selecting the type of instruction (arithmetic, flag, or branch). The next 5 bits select the specific instruction opcode. The final four bits select the mask and constant. The following drawing from <a href="https://www.google.com/patents/US3934233">the patent</a> shows the structure:
<p>
<a href="https://www.google.com/patents/US3934233">
<img class="hilite" src="https://lh4.googleusercontent.com/-lUdHoHanHTE/UcZxYHi1BAI/AAAAAAAAT1E/KXurwlCpPjc/s400/opcodes.png" width="400" alt="Opcode structure for a TI calculator. From https://www.google.com/patents/US3934233" title="Opcode structure for a TI calculator. From https://www.google.com/patents/US3934233">
</a>
<p>
The instructions are fairly basic, such as <code>AABA</code>, which adds A and B storing to A, or <code>SRLA</code>, which shifts register A left by one digit. If you single-step using the control above the source window, each instruction is explained in more detail.
<p>
One of the most unusual features of this processor is that operations have a mask that selects which digits are affected. For instance, when adding the A and B registers, a single digit can be added, all 11 digits can be added, or the two highest digits can be added depending on the mask specified in the instruction. Likewise, an operation can act on a single flag, the three lowest flags, or other combinations. In total, there are 16 different masks. This gives the processor a lot of flexibility, and allows a single operation to process multiple digits without coding a loop - the hardware does the loop internally.
<p>
The mask bits also select a constant value associated with a mask. For instance, the lowest digit can be incremented by 7 or the second digit can be incremented by 4, or 0 can be stored into all the digits, depending on the mask in the instruction. Most processors use a second instruction word to specify constant values, but the TI processor folds the constants into the single instruction. The full list of masks and constants is <a href="https://patentimages.storage.googleapis.com/pages/US3934233-33.png">here</a>.
<p>
The two 11-bit flag registers AF and BF are a very important part of the processor, as they are used to keep track of the calculator's state. For instance, the calculator remembers which operation key was pressed by using a few flag bits. The set, clear, test, compare, and exchange operations are also controlled by the mask, so they can operate on a single bit or multiple bits at a time. Boolean operations are notably missing.
<p>
One feature of the chip specially designed for calculators is the digit scan register, which cycles through 10 scan lines. These lines illuminate one digit at a time. They also scan the key matrix to detect key presses. Several of the instructions are tied closely to the digit scan. For instance, <code>AKCN</code> increments A each scan until a key is found. Since keys 1 through 9 and tied to scan lines 1 through 9, the result is the desired digit value. Similarly <code>SYNC</code> synchronizes execution to the scan.
<p>
The chip has a single condition bit. Depending on the instruction, this holds the status for key down, carry, borrow, equality, or zero. Most processors use separate condition flags for each type of condition. In contrast, t 0800 has a single flag and the programmer needs to keep track of what it holds. The condition flag is used to control conditional branches. There is no unconditional branch - the BET (branch every time) instruction is just a condition branch when the programmer knows the condition flag is clear. The top two class bits indicate a conditional branch, leaving 9 bits for the address. Thus, branch instructions fit in a single word, unlike most processors.
<p>
A few instructions don't have room for an opcode and branch address, so they use the same bits for both, which is very strange. The <code>WAITNO</code> and <code>WAITDK</code> instructions branch when a key is pressed. The bizarre thing about these instructions is that the opcode takes up most of the address bits, so there is little choice about where the branch ends up. The destination instruction is forced to go in a small area, even if that's in the middle of an unrelated block of code.
<p>
If you want to know more about the chip, the architecture diagram from the patent and the chip schematic links below are extremely detailed. I tediously assembled the schematic from many pieces in the patent.
<p>
<a href="https://www.google.com/patents/US3934233"><img class="hilite" src="https://lh5.googleusercontent.com/-9arWpZn1KEA/UcZ3tMdSf8I/AAAAAAAAT2E/BaTi5N1rAqg/h300/fig2-small.png" height="w300"
alt="Architecture of a TI calcuator. From https://www.google.com/patents/US3934233"
title="Architecture of a TI calcuator. From https://www.google.com/patents/US3934233"></a>
<a href="https://photos.google.com/share/AF1QipPQDRu0QGA7v_N_CJCOEbu9JHqGOAMcQYnDq_xEi4HRpzmI-vpp0XkC2xzCdmDLxA/photo/AF1QipN1sNIO5CUkKPJ3ABMv3hWiM04Z5QjD1H_YsqpV?key=U0otN2xNd3c0YXh0SmtfM1N1aS1lOVhZOFJjM1hB"><img class="hilite" src="https://lh3.googleusercontent.com/-G3zKz6CtWEE/UcZ2t-zN4YI/AAAAAAAAT1w/ewzzNvRGR4A/h300-w300-c/US3934233-schematic.png" height="300"
alt="Very large schematic of a TI calculator chip, assembled by Ken Shirriff from https://www.google.com/patents/US3934233"
title="Very large schematic of a TI calculator chip, assembled by Ken Shirriff from https://www.google.com/patents/US3934233">
</a>
<h4>Algorithms</h4>
The chip patent includes the full source code for the calculator, implementing addition, subtraction, multiplication, and division. The chip doesn't support multiplication or division directly so multiplication is performed by repeated addition, and division is performed by repeated subtraction, very similar to grade-school multiplication and long division.
<p>
During computation, numbers are represented as a sign flag, a 9-digit mantissa, and a 2 digit exponent. The exponent indicates how many digits are after the decimal point. e.g. 1.23 has a mantissa of 123 and an exponent of 2. Numbers are shifted left and aligned during computation so 1.23 can also be represented mantissa 12300000 and exponent 7. You can see the numbers getting shifted left and right during computation.
<p>
For display, the A register holds the sign (represented by the number 14) and the displayed digits. The B register indicates the position of the decimal point by having the digit 2 at the decimal point position. A minus sign is indicated by the digit value 14 in A at the proper position. Leading zeros are suppressed by the hardware, so for instance it displays 12, not 000000012.
<p>
I've added extensive comments to the source code.
As an outline of the code, it starts with <code>CLEAR</code>, which resets everything. The <code>LOCK</code> loop waits for keys to get released, and then <code>IDLE</code> waits for a key press. <code>KEY</code> waits a bit to debounce the key and then scans for a non-digit key. Then it counts the scans to get the value of any digit key. A digit is appended to A and then <code>DPTPOS</code> sets B to display the decimal point correctly.
<p>
To perform addition or subtraction, the two arguments are aligned along their decimal points, added or subtracted, and the sign set appropriately. Multiplication is done by repeatedly adding, multiplying by 10, and continuing through all the digits. Division is done by repeatedly subtracting, multiplying by 10, and continuing through all the digits. After the operation, the <code>POST</code> code normalizes the result and handles any overflow.
<p>
Additional code handles constant operations, a more advanced feature than you'd expect to find in a simple calculator. E.g. if you enter "3 * 6 = ", followed by "9 =", the calculator remembers the previous "* 6" operation and computes "9 * 6". (Sort of <a href="http://en.wikipedia.org/wiki/Currying">currying</a>.) The constant mantissa is stored in C, the exponent is stored in B, and the operation is stored in the AF flags. Likewise, "5 * = = " computes 5 cubed.
<p>
It's interesting to watch the digits bounce back and forth, even for simple computations. There's a lot more happening in a calculator and more programming involved than you might think.
<p>
After a divide by zero or overflow, the calculator will lock up until you hit Clear. I thought earlier that there was a bug in the original source code that kept Clear from working, but it turns out that the Clear button is actually wired in the calculator to the hardware reset, rather than being implemented in the code. I added this reset feature to the simulator and Clear now works.
<h4>Making a scientific calculator from this chip</h4>
The most amazing thing about this chip is that the Sinclair company took this chip with barely enough ROM to do four-function math, and reprogrammed it into a scientific calculator with trig, inverse trig, exponentials, and logs. The resulting <a href="http://en.wikipedia.org/wiki/Sinclair_Scientific">Sinclair Scientific</a> calculator became popular due to its low cost.
<p>
How did Sinclair fit all this into 320 words of ROM? The short answer is they used RPN which simplified the code, and they made extreme tradeoffs in the scientific algorithms that reduced accuracy and performance. The algorithms are a bit like decimal <a href="http://en.wikipedia.org/wiki/CORDIC">CORDIC</a>, but much simplified. I plan to provide full details later.
<h4>Notes and credits</h4>
For sharing, <a href="http://righto.com/ti">righto.com/ti</a> is a short link to this page.
<p>
This simulator is based on the extremely detailed 50 page patent (<a href="https://www.google.com/patents/US3934233">3934233</a>), which is one of the most informative patents I've seen. I wish all patents were like this one: the text seems to have been written by engineers who wanted to explain everything, and the patent includes the full schematic and source code. Ironically, the patent itself is very narrow, claiming an obscure detail of the ROM decoding that could have been written up in about 2 pages.
<p>
Source code entered by Phil Mainwaring. Calculator <a href="http://commons.wikimedia.org/wiki/File:TI_DataMath_2500.jpg">image</a> from <a href="//de.wikipedia.org/wiki/Ralf_Pfeifer" title="de:Ralf Pfeifer">Ralf Pfeifer</a> at <a href="http://de.wikipedia.org">de.wikipedia</a>. Built using <a href="http://jquery.com/">jQuery</a> and tested with <a href="http://qunitjs.com/">QUnit</a>. Inspired by <a href="http://visual6502.org/">Visual 6502</a>.
<p>
Random cultural reference: This TI calculator also appears on the cover of <i>Zero Day</i> by nerdcore artist <a href="http://frontalot.com/index.php/">MC Frontalot</a>.
<p>
<a href="https://www.youtube.com/watch?v=rjigODNy3jk&feature=youtube_gdata_player"><img class="hilite" src="https://lh6.googleusercontent.com/-m0O6vFdGBoI/UiFjnEaI4FI/AAAAAAAAVOM/UDQ9YeL41KY/s288/Zero-Day-Album-Cover-400.jpg"></a>
<p>
<div style="background: #cef; border: 2px solid #bbb; font-weight: bold; padding: 4px;">There's lots of discussion of this simulator at <a href="http://www.reddit.com/r/programming/comments/1k630o/simulating_a_ti_calculator_with_crazy_11bit/">Reddit programming</a> and <a href="http://www.metafilter.com/130871/Simulating-a-TI-calculator-with-crazy-11-bit-opcodes">MetaFilter</a>. Thanks for visiting!</div>
</html>