Canola  0.8.D001
lib/interpose/memory.cc
Go to the documentation of this file.
00001 //
00002 // canola - canon canola 1614p emulator
00003 // Copyright (C) 2011 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/interpose/memory.h>
00019 
00020 
00021 interpose_memory::~interpose_memory()
00022 {
00023 }
00024 
00025 
00026 interpose_memory::interpose_memory(
00027     const pointer &a_deeper,
00028     int a_base,
00029     const location::pointer &a_start
00030 ) :
00031     deeper(a_deeper),
00032     base(a_base),
00033     start(a_start)
00034 {
00035     assert(deeper);
00036 }
00037 
00038 
00039 void
00040 interpose_memory::on_opcode(opcode_t op, const location::pointer &where)
00041 {
00042     if (!strict_memory_number_checking_required() && op < 128)
00043     {
00044         //
00045         // The 1614P Instruction Manual says that the [M3~], [SM3~],
00046         // [RM3~] and [CM3~] keys must be followed by a numeric key
00047         // from [0] to [9].
00048         //
00049         // This emulator, by default, will issue an error if you fail
00050         // to use a numeric key.  There is an option to disable the
00051         // error, and use original 1614P behavior instead.
00052         //
00053         // The real 1614P simply uses the lower 4 bits of whatever key you
00054         // press after one of the [M3~], [SM3~], [RM3~] and [CM3~] keys.
00055         // It doesn't complain if it isn't a numeric key.
00056         //
00057         op = opcode_t(0x70 | (op & 15));
00058     }
00059 
00060     int lo = 1;
00061     int hi = 9;
00062     switch (op)
00063     {
00064     case opcode_zero:
00065         goto yuck;
00066 
00067     case opcode_plus_equals:
00068     case opcode_minus_equals:
00069     case opcode_mul:
00070     case opcode_div:
00071     case opcode_sqrt:
00072     case opcode_ent:
00073     case opcode_sj:
00074     case opcode_ej:
00075     case opcode_mj:
00076     case opcode_uj:
00077     case opcode_fj:
00078     case opcode_suj:
00079     case opcode_sfj:
00080     case opcode_srj:
00081     case opcode_m1:
00082     case opcode_m2:
00083     case opcode_m3:
00084     case opcode_m4:
00085     case opcode_m5:
00086     case opcode_m6:
00087     case opcode_m7:
00088     case opcode_m8:
00089     case opcode_m9:
00090     case opcode_m10:
00091     case opcode_m11:
00092     case opcode_m12:
00093     case opcode_m13:
00094     case opcode_m14:
00095     case opcode_mm1:
00096     case opcode_mm2:
00097     case opcode_sm3:
00098     case opcode_sm4:
00099     case opcode_sm5:
00100     case opcode_sm6:
00101     case opcode_sm7:
00102     case opcode_sm8:
00103     case opcode_sm9:
00104     case opcode_sm10:
00105     case opcode_sm11:
00106     case opcode_sm12:
00107     case opcode_sm13:
00108     case opcode_sm14:
00109     case opcode_rm1:
00110     case opcode_rm2:
00111     case opcode_rm3:
00112     case opcode_rm4:
00113     case opcode_rm5:
00114     case opcode_rm6:
00115     case opcode_rm7:
00116     case opcode_rm8:
00117     case opcode_rm9:
00118     case opcode_rm10:
00119     case opcode_rm11:
00120     case opcode_rm12:
00121     case opcode_rm13:
00122     case opcode_rm14:
00123     case opcode_clear_indicator:
00124     case opcode_cm1:
00125     case opcode_cm2:
00126     case opcode_cm3:
00127     case opcode_cm4:
00128     case opcode_cm5:
00129     case opcode_cm6:
00130     case opcode_cm7:
00131     case opcode_cm8:
00132     case opcode_cm9:
00133     case opcode_cm10:
00134     case opcode_cm11:
00135     case opcode_cm12:
00136     case opcode_cm13:
00137     case opcode_cm14:
00138     case opcode_dot:
00139     case opcode_rv:
00140     case opcode_right:
00141     case opcode_chg_sign:
00142     case opcode_round_down:
00143     case opcode_round_off:
00144     case opcode_round_up:
00145     case opcode_print:
00146     case opcode_fd:
00147     case opcode_n0:
00148         goto yuck;
00149 
00150     case opcode_n1:
00151     case opcode_n2:
00152         if (base == (opcode_sm3 - 3))
00153         {
00154             lo = 3;
00155             goto yuck;
00156         }
00157         // Fall through...
00158 
00159     case opcode_n3:
00160     case opcode_n4:
00161     case opcode_n5:
00162     case opcode_n6:
00163     case opcode_n7:
00164     case opcode_n8:
00165     case opcode_n9:
00166     case opcode_n10:
00167     case opcode_n11:
00168     case opcode_n12:
00169     case opcode_n13:
00170     case opcode_n14:
00171         deeper->on_opcode
00172         (
00173             opcode_t(base + op - opcode_n0),
00174             location::span(start, where)
00175         );
00176         break;
00177 
00178     case opcode_extended_c:
00179     case opcode_extended_start:
00180     case opcode_extended_m3_tilde:
00181     case opcode_extended_sm3_tilde:
00182     case opcode_extended_rm3_tilde:
00183     case opcode_extended_cm3_tilde:
00184     case opcode_extended_off:
00185     case opcode_extended_program_print:
00186     case opcode_extended_display_print:
00187     case opcode_extended_paper_feed:
00188     case opcode_extended_rounding_switch_up:
00189     case opcode_extended_rounding_switch_off:
00190     case opcode_extended_rounding_switch_down:
00191     case opcode_extended_decimal_point_selector_0:
00192     case opcode_extended_decimal_point_selector_1:
00193     case opcode_extended_decimal_point_selector_2:
00194     case opcode_extended_decimal_point_selector_3:
00195     case opcode_extended_decimal_point_selector_4:
00196     case opcode_extended_decimal_point_selector_5:
00197     case opcode_extended_decimal_point_selector_6:
00198     case opcode_extended_decimal_point_selector_7:
00199     case opcode_extended_decimal_point_selector_8:
00200     case opcode_extended_decimal_point_selector_9:
00201     case opcode_extended_decimal_point_selector_10:
00202     case opcode_extended_decimal_point_selector_11:
00203     case opcode_extended_decimal_point_selector_12:
00204     case opcode_extended_decimal_point_selector_float:
00205     case opcode_extended_goto_000:
00206     case opcode_extended_goto_001:
00207     case opcode_extended_goto_002:
00208     case opcode_extended_goto_003:
00209     case opcode_extended_goto_004:
00210     case opcode_extended_goto_005:
00211     case opcode_extended_goto_006:
00212     case opcode_extended_goto_007:
00213     case opcode_extended_goto_008:
00214     case opcode_extended_goto_009:
00215     case opcode_extended_goto_010:
00216     case opcode_extended_goto_011:
00217     case opcode_extended_goto_012:
00218     case opcode_extended_goto_013:
00219     case opcode_extended_goto_014:
00220     case opcode_extended_goto_015:
00221     case opcode_extended_goto_100:
00222     case opcode_extended_goto_101:
00223     case opcode_extended_goto_102:
00224     case opcode_extended_goto_103:
00225     case opcode_extended_goto_104:
00226     case opcode_extended_goto_105:
00227     case opcode_extended_goto_106:
00228     case opcode_extended_goto_107:
00229     case opcode_extended_goto_108:
00230     case opcode_extended_goto_109:
00231     case opcode_extended_goto_110:
00232     case opcode_extended_goto_111:
00233     case opcode_extended_goto_112:
00234     case opcode_extended_goto_113:
00235     case opcode_extended_goto_114:
00236     case opcode_extended_goto_115:
00237     case opcode_extended_goto_200:
00238     case opcode_extended_goto_201:
00239     case opcode_extended_goto_202:
00240     case opcode_extended_goto_203:
00241     case opcode_extended_goto_204:
00242     case opcode_extended_goto_205:
00243     case opcode_extended_goto_206:
00244     case opcode_extended_goto_207:
00245     case opcode_extended_goto_208:
00246     case opcode_extended_goto_209:
00247     case opcode_extended_goto_210:
00248     case opcode_extended_goto_211:
00249     case opcode_extended_goto_212:
00250     case opcode_extended_goto_213:
00251     case opcode_extended_goto_214:
00252     case opcode_extended_goto_215:
00253     case opcode_extended_goto_300:
00254     case opcode_extended_goto_301:
00255     case opcode_extended_goto_302:
00256     case opcode_extended_goto_303:
00257     case opcode_extended_goto_304:
00258     case opcode_extended_goto_305:
00259     case opcode_extended_goto_306:
00260     case opcode_extended_goto_307:
00261     case opcode_extended_goto_308:
00262     case opcode_extended_goto_309:
00263     case opcode_extended_goto_310:
00264     case opcode_extended_goto_311:
00265     case opcode_extended_goto_312:
00266     case opcode_extended_goto_313:
00267     case opcode_extended_goto_314:
00268     case opcode_extended_goto_315:
00269     case opcode_extended_goto_400:
00270     case opcode_extended_goto_401:
00271     case opcode_extended_goto_402:
00272     case opcode_extended_goto_403:
00273     case opcode_extended_goto_404:
00274     case opcode_extended_goto_405:
00275     case opcode_extended_goto_406:
00276     case opcode_extended_goto_407:
00277     case opcode_extended_goto_408:
00278     case opcode_extended_goto_409:
00279     case opcode_extended_goto_410:
00280     case opcode_extended_goto_411:
00281     case opcode_extended_goto_412:
00282     case opcode_extended_goto_413:
00283     case opcode_extended_goto_414:
00284     case opcode_extended_goto_415:
00285     case opcode_extended_goto_500:
00286     case opcode_extended_goto_501:
00287     case opcode_extended_goto_502:
00288     case opcode_extended_goto_503:
00289     case opcode_extended_goto_504:
00290     case opcode_extended_goto_505:
00291     case opcode_extended_goto_506:
00292     case opcode_extended_goto_507:
00293     case opcode_extended_goto_508:
00294     case opcode_extended_goto_509:
00295     case opcode_extended_goto_510:
00296     case opcode_extended_goto_511:
00297     case opcode_extended_goto_512:
00298     case opcode_extended_goto_513:
00299     case opcode_extended_goto_514:
00300     case opcode_extended_goto_515:
00301     case opcode_extended_goto_600:
00302     case opcode_extended_goto_601:
00303     case opcode_extended_goto_602:
00304     case opcode_extended_goto_603:
00305     case opcode_extended_goto_604:
00306     case opcode_extended_goto_605:
00307     case opcode_extended_goto_606:
00308     case opcode_extended_goto_607:
00309     case opcode_extended_goto_608:
00310     case opcode_extended_goto_609:
00311     case opcode_extended_goto_610:
00312     case opcode_extended_goto_611:
00313     case opcode_extended_goto_612:
00314     case opcode_extended_goto_613:
00315     case opcode_extended_goto_614:
00316     case opcode_extended_goto_615:
00317     case opcode_extended_goto_700:
00318     case opcode_extended_goto_701:
00319     case opcode_extended_goto_702:
00320     case opcode_extended_goto_703:
00321     case opcode_extended_goto_704:
00322     case opcode_extended_goto_705:
00323     case opcode_extended_goto_706:
00324     case opcode_extended_goto_707:
00325     case opcode_extended_goto_708:
00326     case opcode_extended_goto_709:
00327     case opcode_extended_goto_710:
00328     case opcode_extended_goto_711:
00329     case opcode_extended_goto_712:
00330     case opcode_extended_goto_713:
00331     case opcode_extended_goto_714:
00332     case opcode_extended_goto_715:
00333         goto yuck;
00334 
00335     default:
00336         yuck:
00337         on_error
00338         (
00339             "'%s' not valid here, a number key %d..%d was expected",
00340             opcode_name(op).c_str(),
00341             lo,
00342             hi
00343         );
00344         break;
00345     }
00346 }
00347 
00348 
00349 void
00350 interpose_memory::on_error_v(const char *fmt, va_list ap)
00351 {
00352     deeper->on_error_v(fmt, ap);
00353 }
00354 
00355 
00356 bool
00357 interpose_memory::strict_memory_number_checking_required(void)
00358     const
00359 {
00360     return deeper->strict_memory_number_checking_required();
00361 }