Canola  0.8.D001
lib/calculator/on_opcode_ope.cc
Go to the documentation of this file.
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 }