Canola
0.8.D001
|
00001 // 00002 // canola - canon canola 1614p emulator 00003 // Copyright (C) 2011, 2012 Peter Miller 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License, version 3, as 00007 // published by the Free Software Foundation. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License along 00015 // with this program. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 #include <lib/ac/stdio.h> 00019 #include <lib/calculator.h> 00020 00021 00022 void 00023 calculator::maybe_accumulate(void) 00024 { 00025 if (accumulate_mode) 00026 { 00027 memory[1] += x_register; 00028 precro_current.apply(memory[1]); 00029 if (memory[1].has_overflowed()) 00030 { 00031 // Question: Does program execution stop if M1 overflows? 00032 clock_tick_mode = clock_tick_mode_disabled; 00033 // x_register = number::infinity(); 00034 on_error("Memory 1 has overflowed"); 00035 } 00036 } 00037 } 00038 00039 00040 void 00041 calculator::constant_mode_eval(bool neg) 00042 { 00043 // Instruction Manual, p. 10 00044 switch (constant_mode_action) 00045 { 00046 default: 00047 assert(!"unknown deferred action"); 00048 case deferred_action_none: 00049 x_register = 0; 00050 clock_tick_mode = clock_tick_mode_disabled; 00051 on_error 00052 ( 00053 "No constant operation has been supplied. You need to " 00054 "perform at least one multiplication or division first." 00055 ); 00056 break; 00057 00058 case deferred_action_multiplication: 00059 x_register *= constant_mode_rhs; 00060 break; 00061 00062 case deferred_action_division: 00063 if (constant_mode_rhs == 0) 00064 { 00065 x_register = number::infinity(); 00066 clock_tick_mode = clock_tick_mode_disabled; 00067 on_error("Division by zero"); 00068 } 00069 else 00070 { 00071 x_register /= constant_mode_rhs; 00072 } 00073 break; 00074 } 00075 if (neg) 00076 x_register = -x_register; 00077 } 00078 00079 00080 void 00081 calculator::non_constant_mode_eval(bool neg) 00082 { 00083 if (neg) 00084 x_register = y_register - x_register; 00085 else 00086 x_register += y_register; 00087 } 00088 00089 00090 void 00091 calculator::eval(bool neg) 00092 { 00093 if (constant_mode) 00094 constant_mode_eval(neg); 00095 else 00096 non_constant_mode_eval(neg); 00097 } 00098 00099 00100 void 00101 calculator::eval_mul(bool neg) 00102 { 00103 switch (deferred_action) 00104 { 00105 default: 00106 assert(!"unkown deferred action"); 00107 break; 00108 00109 case deferred_action_none: 00110 assert(!"this isn't supposed to happen"); 00111 break; 00112 00113 case deferred_action_multiplication: 00114 if (constant_mode) 00115 { 00116 // Instruction Manual, p. 10 00117 // 00118 // Yes, we are supposed to use the Y register, I checked. Making 00119 // this asymmetric with division seems harder to implement, and 00120 // harder for the user to remember. 00121 // I wonder why they did it that way? 00122 constant_mode_rhs = y_register; 00123 constant_mode_action = deferred_action; 00124 // Question: Is the K constant negative when you use [-=] ? 00125 // ...probably not, considering the example on p. 32. 00126 } 00127 if (y_register == 0) 00128 { 00129 // Instruction Manual, p. 29. 00130 // 00131 // "Note: the operation a x b += RV recalls b instead of a, 00132 // only when a is zero." 00133 y_register = x_register; 00134 x_register = 0; 00135 } 00136 else 00137 { 00138 x_register *= y_register; 00139 } 00140 if (x_register.has_overflowed()) 00141 clock_tick_mode = clock_tick_mode_disabled; 00142 else if (neg) 00143 x_register = -x_register; 00144 break; 00145 00146 case deferred_action_division: 00147 if (constant_mode) 00148 { 00149 // Instruction Manual, p. 10 00150 constant_mode_rhs = x_register; 00151 constant_mode_action = deferred_action; 00152 // Question: What does "[K] 2 [X] 3 [-=] 5 [+=]" display? 00153 } 00154 if (x_register == 0) 00155 { 00156 x_register = number::infinity(); 00157 clock_tick_mode = clock_tick_mode_disabled; 00158 on_error("Division by zero"); 00159 } 00160 else 00161 { 00162 x_register = y_register / x_register; 00163 if (x_register.has_overflowed()) 00164 clock_tick_mode = clock_tick_mode_disabled; 00165 else if (neg) 00166 x_register = -x_register; 00167 } 00168 break; 00169 } 00170 } 00171 00172 00173 void 00174 calculator::on_opcode_ope(opcode_t op, const location::pointer &) 00175 { 00176 bool neg = false; 00177 if (op < 128) 00178 ++number_of_keys_since_ej; 00179 switch (op) 00180 { 00181 case opcode_zero: 00182 assert(!"this isn't supposed to be possible"); 00183 break; 00184 00185 case opcode_plus_equals: 00186 plus_equals: 00187 switch (mstate) 00188 { 00189 default: 00190 assert(!"not supposed to happen"); 00191 00192 case mstate_reset: 00193 // Example: [C] [+=] 00194 // Example: [RM1] [2] [+=] [+=] 00195 eval(neg); 00196 // The example on p.30 of the Instruction Manual is 00197 // accurate. The [AM1] key only applies to multiply and 00198 // divide, but not addition nor subtraction. 00199 maybe_accumulate(); 00200 // <question> 00201 // When in AM1 mode, is the x-register rounded before or 00202 // after adding it to M1? 00203 // </question> 00204 break; 00205 00206 case mstate_lhs_digits_before_dot: 00207 // Example: [C] [5] [+=] 00208 // Example: [RM1] [2] [+=] 00209 eval(neg); 00210 maybe_accumulate(); 00211 break; 00212 00213 case mstate_lhs_digits_after_dot: 00214 // Example: [C] [.] [5] [+=] 00215 // Example: [RM1] [.] [2] [+=] 00216 eval(neg); 00217 maybe_accumulate(); 00218 break; 00219 00220 case mstate_lhs_complete: 00221 // Example: [C] [RM9] [+=] 00222 // Example: [C] [2] [sqrt] [+=] 00223 // Example: [RM1] [RM2] [+=] 00224 eval(neg); 00225 maybe_accumulate(); 00226 break; 00227 00228 case mstate_mul: 00229 // Example: [C] [4] [mul] [+=] 00230 // Example: "[C] [5] [+=] [7] [X] [+=]" displays 49 00231 // Example: "[C] [5] [+=] [7] [X] [+=] [RV]" displays 7 00232 // 00233 // Example: "[RM1] [X] [RM2] [RM9] [+=]" displays 21 00234 // when m1=2 m2=3 m9=7 00235 case mstate_mul_digits_before_dot: 00236 // Example: [4] [mul] [5] [+=] 00237 case mstate_mul_digits_after_dot: 00238 // Example: [4] [mul] [.] [5] [+=] 00239 case mstate_mul_complete: 00240 // Example: [4] [mul] [RM1] [+=] 00241 eval_mul(neg); 00242 #if 1 00243 // The examples on p.25 says this *does* happen. 00244 // Question: Do the examples on Instruction Mananual p.25 work? 00245 maybe_accumulate(); 00246 #else 00247 // The example on p.30 says this does *not* happen. 00248 // The p.30 example is confirmed as accurate. 00249 // 00250 // Is there something subtlely different in those examples 00251 // that I'm missing? 00252 #endif 00253 break; 00254 } 00255 00256 // Do any rounding required. 00257 precro_current.apply(x_register); 00258 precro_current = precro_front_panel; 00259 00260 deferred_action = deferred_action_none; 00261 mstate = mstate_reset; 00262 break; 00263 00264 case opcode_minus_equals: 00265 neg = true; 00266 // Example: "[K] [2] [x] [3] [-=] [4] [+=]" displays 8 00267 // If it is negative, then [-=] is sugar for [CS] [+=] 00268 // and the neg local vaiable is not required. 00269 goto plus_equals; 00270 00271 case opcode_mul: 00272 // See Instruction Manual, p. 21, for example. 00273 switch (mstate) 00274 { 00275 default: 00276 assert(!"unknown mstate"); 00277 00278 case mstate_reset: 00279 // Example: [C] [1] [+=] [2] [+=] [X] 00280 y_register = x_register; 00281 mstate = mstate_mul; 00282 break; 00283 00284 case mstate_lhs_digits_before_dot: 00285 // Example: [C] [7] [X] 00286 // Example: [C] [RM1] [2] [X] 00287 y_register = x_register; 00288 mstate = mstate_mul; 00289 break; 00290 00291 case mstate_lhs_digits_after_dot: 00292 // Example: [C] [.] [7] [X] 00293 // Example: [C] [RM1] [.] [2] [X] 00294 y_register = x_register; 00295 mstate = mstate_mul; 00296 break; 00297 00298 case mstate_lhs_complete: 00299 // Example: [RM1] [X] 00300 // Example: [C] [RM1] [RM2] [X] 00301 y_register = x_register; 00302 mstate = mstate_mul; 00303 break; 00304 00305 case mstate_mul: 00306 // Example: [C] [3] [div] [X] 00307 // Calculator Instruction Manual, p. 22 00308 // sort-of changing our mind 00309 deferred_action = deferred_action_multiplication; 00310 break; 00311 00312 case mstate_mul_digits_before_dot: 00313 // Example: [C] [2] [X] [3] [X] 00314 case mstate_mul_digits_after_dot: 00315 // Example: [C] [2] [X] [.] [3] [X] 00316 case mstate_mul_complete: 00317 // Example: [C] [2] [X] [RM9] [X] 00318 switch (deferred_action) 00319 { 00320 default: 00321 assert(!"unknown deferred action"); 00322 break; 00323 00324 case deferred_action_none: 00325 assert(!"not supposed to happen"); 00326 break; 00327 00328 case deferred_action_multiplication: 00329 x_register *= y_register; 00330 00331 if (x_register.has_overflowed()) 00332 clock_tick_mode = clock_tick_mode_disabled; 00333 break; 00334 00335 case deferred_action_division: 00336 if (x_register == 0) 00337 { 00338 x_register = number::infinity(); 00339 clock_tick_mode = clock_tick_mode_disabled; 00340 on_error("Division by zero"); 00341 } 00342 else 00343 { 00344 // Note: we do not adjust decimal places yet 00345 // Instruction Manual, p. 22 00346 x_register = y_register / x_register; 00347 00348 if (x_register.has_overflowed()) 00349 clock_tick_mode = clock_tick_mode_disabled; 00350 } 00351 } 00352 // no rounding here 00353 y_register = x_register; 00354 mstate = mstate_mul; 00355 break; 00356 } 00357 deferred_action = deferred_action_multiplication; 00358 break; 00359 00360 case opcode_div: 00361 switch (mstate) 00362 { 00363 default: 00364 assert(!"unknown mstate"); 00365 00366 case mstate_reset: 00367 // Example: [C] [1] [+=] [2] [+=] [div] 00368 y_register = x_register; 00369 mstate = mstate_mul; 00370 break; 00371 00372 case mstate_lhs_digits_before_dot: 00373 // Example: [C] [7] [div] 00374 // Example: [C] [RM1] [2] [div] 00375 y_register = x_register; 00376 mstate = mstate_mul; 00377 break; 00378 00379 case mstate_lhs_digits_after_dot: 00380 // Example: [C] [.] [7] [div] 00381 // Example: [C] [RM1] [.] [2] [div] 00382 y_register = x_register; 00383 mstate = mstate_mul; 00384 break; 00385 00386 case mstate_lhs_complete: 00387 // Example: [RM1] [div] 00388 // Example: [C] [RM1] [RM2] [div] 00389 y_register = x_register; 00390 mstate = mstate_mul; 00391 break; 00392 00393 case mstate_mul: 00394 // Example: [C] [3] [X] [div] 00395 // Calculator Instruction Manual, p. 22 00396 // sort-of changing our mind 00397 deferred_action = deferred_action_division; 00398 break; 00399 00400 case mstate_mul_digits_before_dot: 00401 // Example: [C] [2] [X] [3] [div] 00402 case mstate_mul_digits_after_dot: 00403 // Example: [C] [2] [X] [.] [3] [div] 00404 case mstate_mul_complete: 00405 // Example: [C] [2] [X] [RM9] [div] 00406 switch (deferred_action) 00407 { 00408 default: 00409 assert(!"unknown deferred action"); 00410 break; 00411 00412 case deferred_action_none: 00413 assert(!"not supposed to happen"); 00414 break; 00415 00416 case deferred_action_multiplication: 00417 x_register *= y_register; 00418 if (x_register.has_overflowed()) 00419 clock_tick_mode = clock_tick_mode_disabled; 00420 break; 00421 00422 case deferred_action_division: 00423 if (x_register == 0) 00424 { 00425 x_register = number::infinity(); 00426 clock_tick_mode = clock_tick_mode_disabled; 00427 on_error("Division by zero"); 00428 } 00429 else 00430 { 00431 // Note: we do not adjust decimal places yet 00432 // Instruction Manual, p. 22 00433 x_register = y_register / x_register; 00434 00435 if (x_register.has_overflowed()) 00436 clock_tick_mode = clock_tick_mode_disabled; 00437 } 00438 break; 00439 } 00440 // no rounding here 00441 y_register = x_register; 00442 mstate = mstate_mul; 00443 break; 00444 } 00445 deferred_action = deferred_action_division; 00446 break; 00447 00448 case opcode_sqrt: 00449 // This is tricky. Does sqrt also set y_register to zero? one? 00450 switch (mstate) 00451 { 00452 case mstate_reset: 00453 // Example: [1] [+=] [2] [+=] [sqrt] 00454 mstate = mstate_lhs_complete; 00455 break; 00456 00457 case mstate_lhs_digits_before_dot: 00458 // Example: [C] [2] [sqrt] 00459 // Example: [RM2] [3] [sqrt] 00460 mstate = mstate_lhs_complete; 00461 break; 00462 00463 case mstate_lhs_digits_after_dot: 00464 // Example: [C] [.] [2] [sqrt] 00465 // Example: [RM2] [.] [3] [sqrt] 00466 mstate = mstate_lhs_complete; 00467 break; 00468 00469 case mstate_lhs_complete: 00470 // Example: [C] [RM2] [sqrt] 00471 // Example: [RM2] [RM9] [sqrt] 00472 mstate = mstate_lhs_complete; 00473 break; 00474 00475 case mstate_mul: 00476 // Example: [7] [X] [sqrt] 00477 // 00478 // Example: 00479 // Canola in the Classroom, p.10 00480 // [CI] 2.7 [X] [sqrt] [+=] displays 1.643167672515492 00481 // ...it is as if the [X] never happened 00482 // how can this be right? 00483 // 00484 // Example: "[C] 1 [+=] 9 [x] [sqrt] [+=]" displays 3 00485 // Wow, that's weird. Either 00486 // (a) the deferred [X] was discarded, and y_register set to zero, 00487 // (b) the deferred [X] was retained, and y_register set to 1. 00488 // Either way, it sure looks like [sqrt] messes with y_register. 00489 // 00490 // Question: What does "[C] 2 [sqrt] [RV]" display? 00491 // Question: What does "[C] 3 [+M1] [C] [RM1] 2 [sqrt] [RV]" dispay? 00492 // 00493 mstate = mstate_lhs_complete; 00494 break; 00495 00496 case mstate_mul_digits_before_dot: 00497 // Example: [2] [X] [3] [sqrt] 00498 mstate = mstate_lhs_complete; 00499 break; 00500 00501 case mstate_mul_digits_after_dot: 00502 // Example: [2] [X] [.] [3] [sqrt] 00503 mstate = mstate_lhs_complete; 00504 break; 00505 00506 case mstate_mul_complete: 00507 // Example: [2] [X] [RM9] [sqrt] 00508 mstate = mstate_lhs_complete; 00509 break; 00510 00511 default: 00512 assert(!"unknown mstate"); 00513 } 00514 00515 // Instruction Manual, p. 24 00516 x_register = x_register.sqrt(); 00517 #if 1 00518 // Example: "7 +M1 +M1 C 2 X 3 sqrt RM1 +=" displays 15.73205... 00519 // Thus, we see that the deferred multiply is reset by [sqrt]. 00520 y_register = 0; 00521 deferred_action = deferred_action_none; 00522 #else 00523 y_register = 1; 00524 #endif 00525 // Question: Does the [sqrt] key clear the K constant? 00526 // This seems likely, as it will need all 3 registers for the 00527 // calculation... which is why it nukes y_register. 00528 00529 // The sqrt operation ignores the rounding switch. 00530 // Where did I see that in the Manual? 00531 // 00532 // It also has some error in more than one of the least significant 00533 // digits, which may explain why it ignores the rounding switch. 00534 // 00535 precro_current.apply(x_register); 00536 precro_current = precro_front_panel; 00537 break; 00538 00539 case opcode_ent: 00540 not_valid_here: 00541 on_error 00542 ( 00543 "'%s' is not valid in Program Mode %s", 00544 opcode_name(op).c_str(), 00545 program_mode_name(program_mode) 00546 ); 00547 // stop the clock 00548 clock_tick_mode = clock_tick_mode_disabled; 00549 break; 00550 00551 case opcode_sj: 00552 switch (clock_tick_mode) 00553 { 00554 case clock_tick_mode_sj: 00555 address = find_flag_jump(next_opcode()); 00556 clock_tick_mode = clock_tick_mode_running; 00557 clock_tick_start_running(); 00558 break; 00559 00560 case clock_tick_mode_entry: 00561 // See instruction manual, p. 49. 00562 // Weird. 00563 address = 0; 00564 clock_tick_mode = clock_tick_mode_running; 00565 clock_tick_start_running(); 00566 break; 00567 00568 case clock_tick_mode_disabled: 00569 case clock_tick_mode_running: 00570 case clock_tick_mode_ej: 00571 default: 00572 // Example: [SJ] is ignored in OPE mode. 00573 goto not_valid_here; 00574 } 00575 break; 00576 00577 case opcode_ej: 00578 case opcode_mj: 00579 // These are taken care of in calculator::execute_one_instruction(). 00580 goto not_valid_here; 00581 00582 case opcode_uj: 00583 // This is taken care of in interpose_stateful 00584 // 00585 // <question> 00586 // In OPE mode, with a program running, what happens when the UJ 00587 // key is pressed? I've seen suggestions that this will halt 00588 // execution. Does execution stop immediately, or does it wait 00589 // for the second key? 00590 // </question> 00591 goto not_valid_here; 00592 00593 case opcode_fj: 00594 case opcode_suj: 00595 case opcode_sfj: 00596 case opcode_srj: 00597 // These are taken care of in calculator::execute_one_instruction(). 00598 goto not_valid_here; 00599 00600 case opcode_m1: 00601 case opcode_m2: 00602 case opcode_m3: 00603 case opcode_m4: 00604 case opcode_m5: 00605 case opcode_m6: 00606 case opcode_m7: 00607 case opcode_m8: 00608 case opcode_m9: 00609 case opcode_m10: 00610 case opcode_m11: 00611 case opcode_m12: 00612 case opcode_m13: 00613 case opcode_m14: 00614 // Example: "[1] [2] [+M1] [3]" displays 3 00615 // Example: "[1] [2] [+M1] [3] [RV]" displays 12 00616 { 00617 unsigned n = op - (opcode_m1 - 1); 00618 memory[n] += x_register; 00619 if (memory[n].has_overflowed()) 00620 { 00621 // Question: Does program executuion stop if [+M9] overflows? 00622 // Question: Does program executuion stop if [-M2] overflows? 00623 clock_tick_mode = clock_tick_mode_disabled; 00624 // x_register = number::infinity(); 00625 on_error("Memory %d has overflowed", n); 00626 } 00627 switch (mstate) 00628 { 00629 case mstate_reset: 00630 // Example: [C] [RM1] [RM2] [+=] [+M1] 00631 mstate = mstate_lhs_complete; 00632 break; 00633 00634 case mstate_lhs_digits_before_dot: 00635 // Example: [C] 1 [+M1] 00636 // Example: [RM2] 2 [+M1] 00637 mstate = mstate_lhs_complete; 00638 break; 00639 00640 case mstate_lhs_digits_after_dot: 00641 // Example: [C] 1.2 [+M1] 00642 // 00643 // Example: [RM2] .3 [+M1] 00644 // Question: What does "1 m2 m2 c rm2 .3 m1 2 +=" display? 00645 // if 2.3, we are OK 00646 // if 0.32, we shouldn't have changed state 00647 mstate = mstate_lhs_complete; 00648 break; 00649 00650 case mstate_lhs_complete: 00651 // Example: [C] 2 [sqrt] [+M1] 00652 // Example: [RM2] [RM9] [+M1] 00653 break; 00654 00655 case mstate_mul: 00656 // Example: 5 [x] [+M1] 00657 // Example: "[5] [x] [m1] [2] [+=]" displays 10 00658 break; 00659 00660 case mstate_mul_digits_before_dot: 00661 // Example: 5 [x] 6 [+M1] 00662 // Example: "[5] [x] [6] [m1] [2] [+=]" displays 12 00663 mstate = mstate_mul_complete; 00664 break; 00665 00666 case mstate_mul_digits_after_dot: 00667 // Example: 5 [x] 0.6 [+M1] 00668 // Example: "5 [x] 0.6 [+M1] 2 [+=]" displays 1.2 00669 mstate = mstate_mul_complete; 00670 break; 00671 00672 case mstate_mul_complete: 00673 // Example: 5 [x] 2 [sqrt] [+M1] 00674 break; 00675 00676 default: 00677 assert(!"unknown mstate"); 00678 break; 00679 } 00680 } 00681 break; 00682 00683 case opcode_mm1: 00684 case opcode_mm2: 00685 // Example: "[1] [2] [-M1] [3]" displays 3 00686 { 00687 unsigned n = op - (opcode_mm1 - 1); 00688 memory[n] -= x_register; 00689 if (memory[n].has_overflowed()) 00690 { 00691 clock_tick_mode = clock_tick_mode_disabled; 00692 // x_register = number::infinity(); 00693 on_error("Memory %d has overflowed", n); 00694 } 00695 switch (mstate) 00696 { 00697 case mstate_reset: 00698 // Example: [C] 3 [+=] 2 [+=] [-M1] 00699 mstate = mstate_lhs_complete; 00700 // The alternative is to leave it in mstate_reset, 00701 // the two are indistinguishable, afaict. 00702 break; 00703 00704 case mstate_lhs_digits_before_dot: 00705 // Example: [C] 2 [-M1] 00706 // Example: [RM2] 2 [-M1] 00707 // Example: "[CM2] [RM2] 2 [-M2] 3 [+=]" displays 5 00708 mstate = mstate_lhs_complete; 00709 break; 00710 00711 case mstate_lhs_digits_after_dot: 00712 // Example: [C] .2 [-M1] 00713 // Example: "[c] [.] [2] [-M1] [3] [+=]" displays 3.2 00714 // Example: [RM2] .3 [-M1] 00715 // Example: "[CM2] [RM2] .3 [-M2] 4 [+=]" displays 4.3 00716 mstate = mstate_lhs_complete; 00717 break; 00718 00719 case mstate_lhs_complete: 00720 // Example: [C] 2 [sqrt] [-M1] 00721 // Example: [RM2] [RM9] [-M1] 00722 break; 00723 00724 case mstate_mul: 00725 // Example: 5 [x] [-M1] 00726 // Question: What does [5] [x] [-m1] [3] [+=] display? 00727 // If 15, we are ok. 00728 break; 00729 00730 case mstate_mul_digits_before_dot: 00731 // Example: 5 [x] 6 [-M1] 00732 // Example: "[5] [x] [6] [mm2] [2] [+=]" displays 12 00733 mstate = mstate_mul_complete; 00734 break; 00735 00736 case mstate_mul_digits_after_dot: 00737 // Example: 5 [x] 0.6 [-M1] 00738 // Example: "[5] [x] [.] [6] [mm2] [2] [+=]" displays 1.2 00739 mstate = mstate_mul_complete; 00740 break; 00741 00742 case mstate_mul_complete: 00743 // Example: 5 [x] 2 [sqrt] [-M1] 00744 break; 00745 00746 default: 00747 assert(!"unknown mstate"); 00748 break; 00749 } 00750 } 00751 break; 00752 00753 case opcode_sm3: 00754 case opcode_sm4: 00755 case opcode_sm5: 00756 case opcode_sm6: 00757 case opcode_sm7: 00758 case opcode_sm8: 00759 case opcode_sm9: 00760 case opcode_sm10: 00761 case opcode_sm11: 00762 case opcode_sm12: 00763 case opcode_sm13: 00764 case opcode_sm14: 00765 // Question: What does [1] [2] [SM9] [3] display? 00766 { 00767 unsigned n = op - (opcode_sm3 - 3); 00768 memory[n] = x_register; 00769 if (memory[n].has_overflowed()) 00770 { 00771 clock_tick_mode = clock_tick_mode_disabled; 00772 // x_register = number::infinity(); 00773 on_error("Memory %d has overflowed", n); 00774 } 00775 switch (mstate) 00776 { 00777 case mstate_reset: 00778 // Example: [C] 3 [+=] 2 [+=] [SM9] 00779 mstate = mstate_lhs_complete; 00780 break; 00781 00782 case mstate_lhs_digits_before_dot: 00783 // Example: [C] 2 [SM9] 00784 // Question: What does "[C] [2] [SM5] [4]" display? 00785 // Example: [RM2] 2 [SM9] 00786 mstate = mstate_lhs_complete; 00787 break; 00788 00789 case mstate_lhs_digits_after_dot: 00790 // Example: [C] .2 [SM9] 00791 // Example: [RM2] .3 [SM9] 00792 // Question: What does "[RM2] .3 [SM9] 4" display? 00793 mstate = mstate_lhs_complete; 00794 break; 00795 00796 case mstate_lhs_complete: 00797 // Example: [C] [2] [sqrt] [SM9] 00798 // Question: What does "[C] [2] [sqrt] [SM9] [3]" display? 00799 // Example: [RM2] [RM9] [SM4] 00800 break; 00801 00802 case mstate_mul: 00803 // Example: 5 [x] [SM9] 00804 mstate = mstate_mul_complete; 00805 break; 00806 00807 case mstate_mul_digits_before_dot: 00808 // Example: 5 [x] 6 [SM9] 00809 // Question: What does "5 [x] 6 [SM9] [7] [+=]" display? 00810 mstate = mstate_mul_complete; 00811 break; 00812 00813 case mstate_mul_digits_after_dot: 00814 // Example: 5 [x] 0.6 [SM9] 00815 // Question: What does "5 [x] 0.6 [SM9] 7 [+=]" display? 00816 mstate = mstate_mul_complete; 00817 break; 00818 00819 case mstate_mul_complete: 00820 // Example: 5 [x] 2 [sqrt] [SM9] 00821 // Question: What does "5 [x] 2 [sqrt] [SM9] 7 [+=]" display? 00822 break; 00823 00824 default: 00825 assert(!"unknown mstate"); 00826 break; 00827 } 00828 } 00829 break; 00830 00831 case opcode_rm1: 00832 case opcode_rm2: 00833 case opcode_rm3: 00834 case opcode_rm4: 00835 case opcode_rm5: 00836 case opcode_rm6: 00837 case opcode_rm7: 00838 case opcode_rm8: 00839 case opcode_rm9: 00840 case opcode_rm10: 00841 case opcode_rm11: 00842 case opcode_rm12: 00843 case opcode_rm13: 00844 case opcode_rm14: 00845 switch (mstate) 00846 { 00847 case mstate_reset: 00848 // Example: [C] [2] [+=] [3] [+=] [RM1] 00849 mstate = mstate_lhs_complete; 00850 break; 00851 00852 case mstate_lhs_digits_before_dot: 00853 // Example: [C] [1] [+=] [2] [RM1] 00854 // Example: "7 [+M1] [c] 1 [+=] 2 [RM1] [+=]" displays 9 00855 // Example: [RM1] [2] [RM9] 00856 // Question: What does "3 +M1 C 5 SM9 c RM1 2 RM9 +=" display? 00857 mstate = mstate_lhs_complete; 00858 break; 00859 00860 case mstate_lhs_digits_after_dot: 00861 // Example: [C] [.] [2] [RM1] 00862 // Example: "7 [+M1] [C] 1 [+=] .2 [RM1] [+=]" displays 7.2 00863 // Example: [RM1] [.] [2] [RM9] 00864 // Question: What does "3 +M1 C 5 SM9 C RM1 .2 RM9 +=" display? 00865 mstate = mstate_lhs_complete; 00866 break; 00867 00868 case mstate_lhs_complete: 00869 // Example: [C] [RM1] [RM2] 00870 // 00871 // FIXME: Instruction Manual reference? While this is 00872 // implied by the Instruction Manual, I don't expect it to 00873 // be explicitly stated anywhere. 00874 // 00875 // Example: "[7] [+M1] [C] 13 [RM1] [RV]" displays 13 00876 // Example: [RM1] [RM2] [RM9] 00877 break; 00878 00879 case mstate_mul: 00880 // Example: [2] [X] [RM1] 00881 mstate = mstate_mul_complete; 00882 break; 00883 00884 case mstate_mul_digits_before_dot: 00885 // Example: [2] [X] [3] [RM1] 00886 // Example: "7 [+M1] [+M1] [C] 2 [X] 3 [RM1] [+=]" displays 42 00887 mstate = mstate_mul_complete; 00888 break; 00889 00890 case mstate_mul_digits_after_dot: 00891 // Example: [2] [X] [.] [3] [RM1] 00892 // Example: "7 [+M1] [+M1] [C] 2 [X] .3 [RM1] [+=]" displays 4.2 00893 mstate = mstate_mul_complete; 00894 break; 00895 00896 case mstate_mul_complete: 00897 // Example: [2] [X] [3] [sqrt] [RM1] 00898 // Example: "7 +M1 +M1 C 2 X 3 sqrt RM1 +=" displays 15.73205... 00899 // Thus, we see that the deferred multiply is reset by [sqrt]. 00900 mstate = mstate_mul_complete; 00901 break; 00902 00903 default: 00904 assert(!"unknown mstate"); 00905 break; 00906 } 00907 y_register = x_register; 00908 x_register = memory[op - (opcode_rm1 - 1)]; 00909 break; 00910 00911 case opcode_clear_indicator: 00912 switch (mstate) 00913 { 00914 case mstate_reset: 00915 // Example: [C] [3] [+=] [CI] 00916 // Example: "c 3 += ci 4 +=" displays 4 00917 // Example: "c 3 += ci 4 rv" displays 0 00918 // 00919 // This is a tough case. There are several possibilities: 00920 #if 0 00921 // 1. Do nothing. We are already at a place that will 00922 // start a new number. This probably doesn't match 00923 // expectations. 00924 break; 00925 #endif 00926 #if 0 00927 // 2. Pretend a zero has been pressed. This means copying 00928 // x_register to y_register, as pressing zero would. 00929 // This makes the best sense arithmetically, a best 00930 // preserves the "I entered the wrong number" concept. 00931 y_register = x_register; 00932 x_register = 0; 00933 mstate = mstate_lhs_digits_before_dot; 00934 break; 00935 #endif 00936 // 3. Zero the x_register, but don't copy x_register to 00937 // y_register. This is truly stupid (a) which is likely 00938 // for silicon of this era, and (b) actually matches some 00939 // implied uses cases in the documentation where using 00940 // [CI] in the right place *effectively* clears both 00941 // x_register and y_register, in this case by having the 00942 // next digit pressed tranfer zero into the y_register. 00943 x_register = 0; 00944 break; 00945 00946 case mstate_lhs_digits_before_dot: 00947 // Example: [C] [3] [+=] [4] [CI] 00948 // 00949 // The difficulty here (and the next 2 cases) is that if we go back 00950 // to mstate_reset it will cause the x_register to be copied to the 00951 // y_register *again* which will give the wrong answer when [+=] is 00952 // subsequently pressed. 00953 // 00954 // Example: [RM1] [2] [CI] 00955 // Example: "[RM1] [2] [CI]" displays 0 00956 x_register = 0; 00957 00958 // Example: "[RM1] [2] [CI] [3] [+=]" displays 3 00959 // 00960 // Well, I *think* this is what this example means. 00961 mstate = mstate_lhs_complete; 00962 // Question: What does "7 [M1] [C] [RM1] [2] [CI] [3] [RV]" display? 00963 // 00964 // <question> 00965 // What does "7 [M1] [C] [RM1] [2] [CI] [3] [RV] [RV]" display? 00966 // </question> 00967 break; 00968 00969 case mstate_lhs_digits_after_dot: 00970 // Example: [C] [3] [+=] [.] [4] [CI] 00971 // Example: [RM1] [.] [2] [CI] 00972 x_register = 0; 00973 mstate = mstate_lhs_complete; 00974 break; 00975 00976 case mstate_lhs_complete: 00977 // Example: [C] [3] [+=] [2] [sqrt] [CI] 00978 // Example: [RM1] [2] [sqrt] [CI] 00979 // Example: "[RM1] [2] [sqrt] [CI]" displays 0 00980 // Example: "[RM1] [2] [sqrt] [CI] [3] [+=]" displays 3 00981 x_register = 0; 00982 break; 00983 00984 case mstate_mul: 00985 // Example: [C] [2] [X] [CI] 00986 x_register = 0; 00987 break; 00988 00989 case mstate_mul_digits_before_dot: 00990 // Example: [C] [2] [X] [3] [CI] 00991 // Example: "12 [x] 34 [ci]" displays 0 00992 // Question: What does "12 [x] 34 [ci] 56 [+=]" display? 00993 x_register = 0; 00994 mstate = mstate_mul; 00995 break; 00996 00997 case mstate_mul_digits_after_dot: 00998 // Example: [C] [2] [X] [.] [3] [CI] 00999 // Example: "[C] [2] [X] [.] [3] [CI] 4" displays 4 01000 // Question: What does "[C] [2] [X] [.] [3] [CI] 4 [RV]" display? 01001 x_register = 0; 01002 mstate = mstate_mul; 01003 break; 01004 01005 case mstate_mul_complete: 01006 // Example: [C] [2] [X] [RM9] [CI] 01007 x_register = 0; 01008 mstate = mstate_mul; 01009 break; 01010 01011 default: 01012 assert(!"unknown mstate"); 01013 break; 01014 } 01015 break; 01016 01017 case opcode_cm1: 01018 case opcode_cm2: 01019 case opcode_cm3: 01020 case opcode_cm4: 01021 case opcode_cm5: 01022 case opcode_cm6: 01023 case opcode_cm7: 01024 case opcode_cm8: 01025 case opcode_cm9: 01026 case opcode_cm10: 01027 case opcode_cm11: 01028 case opcode_cm12: 01029 case opcode_cm13: 01030 case opcode_cm14: 01031 // Example: "[1] [2] [CM1] [3]" displays 123 01032 memory[op - (opcode_cm1 - 1)] = 0; 01033 break; 01034 01035 case opcode_dot: 01036 switch (mstate) 01037 { 01038 case mstate_reset: 01039 // Example: [C] [.] entering a fraction 01040 y_register = x_register; 01041 x_register = 0; 01042 mstate = mstate_lhs_digits_after_dot; 01043 break; 01044 01045 case mstate_lhs_digits_before_dot: 01046 // Example: [C] [2] [.] 01047 // Example: [RM1] [RM2] [2] [.] 01048 mstate = mstate_lhs_digits_after_dot; 01049 break; 01050 01051 case mstate_lhs_digits_after_dot: 01052 // Example: [C] [2] [.] [3] [.] 01053 // Example: [RM1] [RM2] [2] [.] [3] [.] 01054 // This *has* been confirmed by a real 1614P. 01055 // Just move the decimal point to the rigth hand side. 01056 x_register.insert_dot(); 01057 break; 01058 01059 case mstate_lhs_complete: 01060 // Example: [RM1] [.] entering a fraction 01061 // Example: [RM1] [RM2] [.] entering a fraction 01062 y_register = x_register; 01063 x_register = 0; 01064 mstate = mstate_lhs_digits_after_dot; 01065 break; 01066 01067 case mstate_mul: 01068 // Example: [RM1] [X] [.] entering a fraction 01069 x_register = 0; 01070 mstate = mstate_mul_digits_after_dot; 01071 break; 01072 01073 case mstate_mul_digits_before_dot: 01074 // Example: [RM1] [2] [.] 01075 mstate = mstate_mul_digits_after_dot; 01076 break; 01077 01078 case mstate_mul_digits_after_dot: 01079 // Example: 7 [x] [.] [2] [.] 01080 // This *has* been confirmed by a real 1614P. 01081 // Just move the decimal point to the rigth hand side. 01082 x_register.insert_dot(); 01083 break; 01084 01085 case mstate_mul_complete: 01086 // Example: [2] [X] [3] [sqrt] [.] 01087 // Example: "[2] [X] [3] [sqrt] [.] [2] [RV]" displays 1.732... 01088 y_register = x_register; 01089 x_register = 0; 01090 mstate = mstate_mul_digits_after_dot; 01091 break; 01092 01093 default: 01094 assert(!"unknown mstate"); 01095 break; 01096 } 01097 break; 01098 01099 case opcode_rv: 01100 { 01101 number temp = x_register; 01102 x_register = y_register; 01103 y_register = temp; 01104 01105 switch (mstate) 01106 { 01107 case mstate_reset: 01108 // Example: [C] 1 [+=] 2 [+=] [RV] 01109 mstate = mstate_lhs_complete; 01110 break; 01111 01112 case mstate_lhs_digits_before_dot: 01113 // Example: [C] [1] [+=] [2] [RV] 01114 // Example: [RM1] 2 [RV] 01115 mstate = mstate_lhs_complete; 01116 break; 01117 01118 case mstate_lhs_digits_after_dot: 01119 // Example: [C] [1] [+=] [2] [.] [1] [RV] 01120 // Example: [RM1] .3 [RV] 01121 mstate = mstate_lhs_complete; 01122 break; 01123 01124 case mstate_lhs_complete: 01125 // Example:[C] 1 [+=] [RM1] [RV] 01126 // Example: [RM1] [RM2] [RV] 01127 break; 01128 01129 case mstate_mul: 01130 // Example: [c] [2] [div] [RV] 01131 mstate = mstate_mul_complete; 01132 break; 01133 01134 case mstate_mul_digits_before_dot: 01135 // Example: [RM1] 2 [div] 3 [RV] 01136 mstate = mstate_mul_complete; 01137 break; 01138 01139 case mstate_mul_digits_after_dot: 01140 // Example: [RM1] 2 [div] .3 [RV] 01141 mstate = mstate_mul_complete; 01142 break; 01143 01144 case mstate_mul_complete: 01145 // Example: [2] [X] [3] [sqrt] [RV] 01146 break; 01147 01148 default: 01149 assert(!"unknown mstate"); 01150 break; 01151 } 01152 } 01153 break; 01154 01155 case opcode_right: 01156 // Confirmed by an actial 1614P: 01157 // 01158 // 123.45 "->" 123.4 "->" 123. "->" 12. "3" 12.3 01159 // 01160 // This example shows the state machine does NOT change any 01161 // "after dot" states into "before dot" states. 01162 x_register.right_shift(); 01163 break; 01164 01165 case opcode_chg_sign: 01166 // This has no effect on the mstate. 01167 // This was confirmed by using an actual 1614P. 01168 x_register = -x_register; 01169 break; 01170 01171 case opcode_round_down: 01172 case opcode_round_off: 01173 case opcode_round_up: 01174 case opcode_print: 01175 case opcode_fd: 01176 // These are taken care of in calculator::execute_one_instruction(). 01177 goto not_valid_here; 01178 01179 case opcode_n0: 01180 case opcode_n1: 01181 case opcode_n2: 01182 case opcode_n3: 01183 case opcode_n4: 01184 case opcode_n5: 01185 case opcode_n6: 01186 case opcode_n7: 01187 case opcode_n8: 01188 case opcode_n9: 01189 switch (mstate) 01190 { 01191 default: 01192 assert(!"unknown mstate"); 01193 case mstate_reset: 01194 // Example: [C] [1] 01195 y_register = x_register; 01196 x_register = 0; 01197 mstate = mstate_lhs_digits_before_dot; 01198 // fall through... 01199 01200 case mstate_lhs_digits_before_dot: 01201 // Example: [C] [1] [2] 01202 // Example: [RM1] [2] [3] 01203 x_register.insert_digit_before_dot(op - opcode_n0); 01204 break; 01205 01206 case mstate_lhs_digits_after_dot: 01207 // Example: [C] [1] [.] 01208 // Example: [RM1] [2] [.] [3] 01209 x_register.insert_digit_after_dot(op - opcode_n0); 01210 break; 01211 01212 case mstate_lhs_complete: 01213 // Example: [9] [sqrt] [8] 01214 // Example: "[C] [9] [sqrt] [8] [+=]" displays 11 01215 // Example: [RM1] [RM2] [3] 01216 y_register = x_register; 01217 x_register = 0; 01218 x_register.insert_digit_before_dot(op - opcode_n0); 01219 mstate = mstate_lhs_digits_before_dot; 01220 break; 01221 01222 case mstate_mul: 01223 // Example: [3] [X] [2] 01224 x_register = 0; 01225 mstate = mstate_mul_digits_before_dot; 01226 x_register.insert_digit_before_dot(op - opcode_n0); 01227 break; 01228 01229 case mstate_mul_digits_before_dot: 01230 // Example: [3] [X] [2] [1] 01231 x_register.insert_digit_before_dot(op - opcode_n0); 01232 break; 01233 01234 case mstate_mul_digits_after_dot: 01235 // Example: [3] [X] [.] [1] 01236 x_register.insert_digit_after_dot(op - opcode_n0); 01237 break; 01238 01239 case mstate_mul_complete: 01240 // Example: "[3] [X] [2] [m1] [7] +=" displays 14 01241 y_register = x_register; 01242 x_register = 0; 01243 x_register.insert_digit_before_dot(op - opcode_n0); 01244 mstate = mstate_mul_digits_before_dot; 01245 // i.e. don't forget the [X], but the left hand side shifts down 01246 break; 01247 } 01248 if (x_register.has_overflowed()) 01249 { 01250 clock_tick_mode = clock_tick_mode_disabled; 01251 on_error("Too many digits in number"); 01252 } 01253 break; 01254 01255 case opcode_n10: 01256 case opcode_n11: 01257 case opcode_n12: 01258 case opcode_n13: 01259 case opcode_n14: 01260 // These opcodes cause an immediate overflow. 01261 // This has been confirmed by a real 1614P. 01262 x_register = number::infinity(); 01263 clock_tick_mode = clock_tick_mode_disabled; 01264 on_error("'%s' is not a valid numeric digit", opcode_name(op).c_str()); 01265 break; 01266 01267 case opcode_extended_c: 01268 x_register = 0; 01269 y_register = 0; 01270 mstate = mstate_reset; 01271 deferred_action = deferred_action_none; 01272 address = 0; 01273 clock_tick_mode = clock_tick_mode_disabled; 01274 call_stack.clear(); 01275 01276 // Note: The [C] key clears the [K] constant value. 01277 constant_mode_action = deferred_action_none; 01278 constant_mode_rhs = 0; 01279 01280 // Note: the [C] key does NOT clear overflowed memory locations. 01281 break; 01282 01283 case opcode_extended_start: 01284 start: 01285 switch (clock_tick_mode) 01286 { 01287 case clock_tick_mode_disabled: 01288 clock_tick_mode = clock_tick_mode_running; 01289 clock_tick_start_running(); 01290 break; 01291 01292 case clock_tick_mode_running: 01293 default: 01294 // ignore 01295 break; 01296 01297 case clock_tick_mode_entry: 01298 clock_tick_mode = clock_tick_mode_running; 01299 switch (mstate) 01300 { 01301 default: 01302 assert(!"unknown mstate"); 01303 01304 case mstate_reset: 01305 break; 01306 01307 case mstate_lhs_digits_before_dot: 01308 mstate = mstate_lhs_complete; 01309 goto start_key_implies_print; 01310 01311 case mstate_lhs_digits_after_dot: 01312 mstate = mstate_lhs_complete; 01313 goto start_key_implies_print; 01314 01315 case mstate_lhs_complete: 01316 mstate = mstate_lhs_complete; 01317 // See the Printer Unit Instruction Manual, p. 11 01318 // 01319 // FIXME: It isn't that simple, see the Instruction manual, 01320 // p. 45. It would appear that any calculation performed also 01321 // counts as entry for the purposes of "entry". 01322 start_key_implies_print: 01323 derived_print(x_register.get_display()); 01324 break; 01325 01326 case mstate_mul: 01327 break; 01328 01329 case mstate_mul_digits_before_dot: 01330 mstate = mstate_mul_complete; 01331 goto start_key_implies_print; 01332 01333 case mstate_mul_digits_after_dot: 01334 mstate = mstate_mul_complete; 01335 goto start_key_implies_print; 01336 01337 case mstate_mul_complete: 01338 mstate = mstate_mul_complete; 01339 goto start_key_implies_print; 01340 } 01341 clock_tick_start_running(); 01342 break; 01343 01344 case clock_tick_mode_sj: 01345 next_opcode(); 01346 clock_tick_mode = clock_tick_mode_running; 01347 clock_tick_start_running(); 01348 break; 01349 01350 case clock_tick_mode_ej: 01351 { 01352 unsigned char label = next_opcode(); 01353 if (number_of_keys_since_ej > 0) 01354 { 01355 // Make sure on_opcode_ope_che() matches this code. 01356 derived_print(x_register.get_display()); 01357 address = find_flag_jump(label); 01358 // <question> 01359 // Does the ENT opcode terminate numeric entry, or 01360 // can add digits? 01361 // </question> 01362 // 01363 // <question> 01364 // Does the EJ opcode terminate numeric entry, or 01365 // can add digits? 01366 // </question> 01367 } 01368 clock_tick_mode = clock_tick_mode_running; 01369 clock_tick_start_running(); 01370 } 01371 break; 01372 } 01373 break; 01374 01375 case opcode_extended_m3_tilde: 01376 case opcode_extended_sm3_tilde: 01377 case opcode_extended_rm3_tilde: 01378 case opcode_extended_cm3_tilde: 01379 goto not_valid_here; 01380 01381 case opcode_extended_off: 01382 derived_off(); 01383 break; 01384 01385 case opcode_extended_program_print: 01386 program_print(); 01387 break; 01388 01389 case opcode_extended_display_print: 01390 // Question: What does "[1] [.] [2] [DrintDisp] [3]" do? 01391 derived_print(x_register.get_display()); 01392 break; 01393 01394 case opcode_extended_paper_feed: 01395 derived_feed(); 01396 break; 01397 01398 case opcode_extended_rounding_switch_up: 01399 precision_and_rounding_set 01400 ( 01401 precision_and_rounding 01402 ( 01403 precision_and_rounding_get().get_precision(), 01404 precision_and_rounding::round_up 01405 ) 01406 ); 01407 break; 01408 01409 case opcode_extended_rounding_switch_off: 01410 precision_and_rounding_set 01411 ( 01412 precision_and_rounding 01413 ( 01414 precision_and_rounding_get().get_precision(), 01415 precision_and_rounding::round_off 01416 ) 01417 ); 01418 break; 01419 01420 case opcode_extended_rounding_switch_down: 01421 precision_and_rounding_set 01422 ( 01423 precision_and_rounding 01424 ( 01425 precision_and_rounding_get().get_precision(), 01426 precision_and_rounding::round_down 01427 ) 01428 ); 01429 break; 01430 01431 case opcode_extended_decimal_point_selector_0: 01432 case opcode_extended_decimal_point_selector_1: 01433 case opcode_extended_decimal_point_selector_2: 01434 case opcode_extended_decimal_point_selector_3: 01435 case opcode_extended_decimal_point_selector_4: 01436 case opcode_extended_decimal_point_selector_5: 01437 case opcode_extended_decimal_point_selector_6: 01438 case opcode_extended_decimal_point_selector_7: 01439 case opcode_extended_decimal_point_selector_8: 01440 case opcode_extended_decimal_point_selector_9: 01441 case opcode_extended_decimal_point_selector_10: 01442 case opcode_extended_decimal_point_selector_11: 01443 case opcode_extended_decimal_point_selector_12: 01444 precision_and_rounding_set 01445 ( 01446 precision_and_rounding 01447 ( 01448 op - opcode_extended_decimal_point_selector_0, 01449 precision_and_rounding_get().get_rounding() 01450 ) 01451 ); 01452 break; 01453 01454 case opcode_extended_decimal_point_selector_float: 01455 precision_and_rounding_set 01456 ( 01457 precision_and_rounding 01458 ( 01459 -1, 01460 precision_and_rounding_get().get_rounding() 01461 ) 01462 ); 01463 break; 01464 01465 case opcode_extended_goto_000: 01466 case opcode_extended_goto_001: 01467 case opcode_extended_goto_002: 01468 case opcode_extended_goto_003: 01469 case opcode_extended_goto_004: 01470 case opcode_extended_goto_005: 01471 case opcode_extended_goto_006: 01472 case opcode_extended_goto_007: 01473 case opcode_extended_goto_008: 01474 case opcode_extended_goto_009: 01475 case opcode_extended_goto_010: 01476 case opcode_extended_goto_011: 01477 case opcode_extended_goto_012: 01478 case opcode_extended_goto_013: 01479 case opcode_extended_goto_014: 01480 case opcode_extended_goto_015: 01481 case opcode_extended_goto_100: 01482 case opcode_extended_goto_101: 01483 case opcode_extended_goto_102: 01484 case opcode_extended_goto_103: 01485 case opcode_extended_goto_104: 01486 case opcode_extended_goto_105: 01487 case opcode_extended_goto_106: 01488 case opcode_extended_goto_107: 01489 case opcode_extended_goto_108: 01490 case opcode_extended_goto_109: 01491 case opcode_extended_goto_110: 01492 case opcode_extended_goto_111: 01493 case opcode_extended_goto_112: 01494 case opcode_extended_goto_113: 01495 case opcode_extended_goto_114: 01496 case opcode_extended_goto_115: 01497 case opcode_extended_goto_200: 01498 case opcode_extended_goto_201: 01499 case opcode_extended_goto_202: 01500 case opcode_extended_goto_203: 01501 case opcode_extended_goto_204: 01502 case opcode_extended_goto_205: 01503 case opcode_extended_goto_206: 01504 case opcode_extended_goto_207: 01505 case opcode_extended_goto_208: 01506 case opcode_extended_goto_209: 01507 case opcode_extended_goto_210: 01508 case opcode_extended_goto_211: 01509 case opcode_extended_goto_212: 01510 case opcode_extended_goto_213: 01511 case opcode_extended_goto_214: 01512 case opcode_extended_goto_215: 01513 case opcode_extended_goto_300: 01514 case opcode_extended_goto_301: 01515 case opcode_extended_goto_302: 01516 case opcode_extended_goto_303: 01517 case opcode_extended_goto_304: 01518 case opcode_extended_goto_305: 01519 case opcode_extended_goto_306: 01520 case opcode_extended_goto_307: 01521 case opcode_extended_goto_308: 01522 case opcode_extended_goto_309: 01523 case opcode_extended_goto_310: 01524 case opcode_extended_goto_311: 01525 case opcode_extended_goto_312: 01526 case opcode_extended_goto_313: 01527 case opcode_extended_goto_314: 01528 case opcode_extended_goto_315: 01529 case opcode_extended_goto_400: 01530 case opcode_extended_goto_401: 01531 case opcode_extended_goto_402: 01532 case opcode_extended_goto_403: 01533 case opcode_extended_goto_404: 01534 case opcode_extended_goto_405: 01535 case opcode_extended_goto_406: 01536 case opcode_extended_goto_407: 01537 case opcode_extended_goto_408: 01538 case opcode_extended_goto_409: 01539 case opcode_extended_goto_410: 01540 case opcode_extended_goto_411: 01541 case opcode_extended_goto_412: 01542 case opcode_extended_goto_413: 01543 case opcode_extended_goto_414: 01544 case opcode_extended_goto_415: 01545 case opcode_extended_goto_500: 01546 case opcode_extended_goto_501: 01547 case opcode_extended_goto_502: 01548 case opcode_extended_goto_503: 01549 case opcode_extended_goto_504: 01550 case opcode_extended_goto_505: 01551 case opcode_extended_goto_506: 01552 case opcode_extended_goto_507: 01553 case opcode_extended_goto_508: 01554 case opcode_extended_goto_509: 01555 case opcode_extended_goto_510: 01556 case opcode_extended_goto_511: 01557 case opcode_extended_goto_512: 01558 case opcode_extended_goto_513: 01559 case opcode_extended_goto_514: 01560 case opcode_extended_goto_515: 01561 case opcode_extended_goto_600: 01562 case opcode_extended_goto_601: 01563 case opcode_extended_goto_602: 01564 case opcode_extended_goto_603: 01565 case opcode_extended_goto_604: 01566 case opcode_extended_goto_605: 01567 case opcode_extended_goto_606: 01568 case opcode_extended_goto_607: 01569 case opcode_extended_goto_608: 01570 case opcode_extended_goto_609: 01571 case opcode_extended_goto_610: 01572 case opcode_extended_goto_611: 01573 case opcode_extended_goto_612: 01574 case opcode_extended_goto_613: 01575 case opcode_extended_goto_614: 01576 case opcode_extended_goto_615: 01577 case opcode_extended_goto_700: 01578 case opcode_extended_goto_701: 01579 case opcode_extended_goto_702: 01580 case opcode_extended_goto_703: 01581 case opcode_extended_goto_704: 01582 case opcode_extended_goto_705: 01583 case opcode_extended_goto_706: 01584 case opcode_extended_goto_707: 01585 case opcode_extended_goto_708: 01586 case opcode_extended_goto_709: 01587 case opcode_extended_goto_710: 01588 case opcode_extended_goto_711: 01589 case opcode_extended_goto_712: 01590 case opcode_extended_goto_713: 01591 case opcode_extended_goto_714: 01592 case opcode_extended_goto_715: 01593 { 01594 int flag = op - opcode_extended_goto_000; 01595 address = find_flag_jump(flag); 01596 goto start; 01597 } 01598 01599 default: 01600 on_error("%s: %d: undefined 0x%02X opcode", __FILE__, __LINE__, op); 01601 // stop the clock 01602 clock_tick_mode = clock_tick_mode_disabled; 01603 break; 01604 } 01605 if (x_register.has_overflowed()) 01606 { 01607 // stop the clock 01608 clock_tick_mode = clock_tick_mode_disabled; 01609 } 01610 }