Canola  0.8.D001
lib/calculator.h
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 #ifndef LIB_CALCULATOR_H
00019 #define LIB_CALCULATOR_H
00020 
00021 #include <lib/ac/stdarg.h>
00022 #include <boost/shared_ptr.hpp>
00023 #include <list>
00024 #include <map>
00025 #include <string>
00026 
00027 #include <lib/display.h>
00028 #include <lib/format_printf.h>
00029 #include <lib/interpose.h>
00030 #include <lib/location.h>
00031 #include <lib/number.h>
00032 #include <lib/opcode.h>
00033 #include <lib/precision_and_rounding.h>
00034 #include <lib/sizeof.h>
00035 
00036 class debugger; // forward
00037 class program_card_functor; // forward
00038 
00043 class calculator
00044 {
00045 public:
00046     typedef boost::shared_ptr<calculator> pointer;
00047 
00051     virtual ~calculator();
00052 
00068     virtual void on_opcode(opcode_t op, const location::pointer &where);
00069 
00079     void on_opcode_lrn(opcode_t op, const location::pointer &where);
00080 
00090     void on_opcode_ope(opcode_t op, const location::pointer &where);
00091 
00101     void on_opcode_pro_che(opcode_t op, const location::pointer &where);
00102 
00112     void on_opcode_ope_che(opcode_t op, const location::pointer &where);
00113 
00127     void on_error(const char *fmt, ...)
00128                                                             FORMAT_PRINTF(2, 3);
00129 
00130     virtual void on_error_v(const char *fmt, va_list ap)
00131                                                         FORMAT_PRINTF(2, 0) = 0;
00132 
00137     virtual void run(void) = 0;
00138 
00146     enum program_mode_t
00147     {
00154         program_mode_learn,
00155 
00163         program_mode_operation,
00164 
00172         program_mode_program_check,
00173 
00180         program_mode_operation_check,
00181     };
00182 
00187     program_mode_t program_mode_get(void);
00188 
00196     void program_mode_set(program_mode_t pm);
00197 
00208     enum program_selector_t
00209     {
00210         program_selector_i_ii,
00211         program_selector_i,
00212         program_selector_ii
00213     };
00214 
00219     program_selector_t program_selector_get(void) const;
00220 
00228     void program_selector_set(program_selector_t ps);
00229 
00237     void precision_and_rounding_set(const precision_and_rounding &value);
00238 
00244     const precision_and_rounding &precision_and_rounding_get(void) const;
00245 
00250     void clear_program(void);
00251 
00264     bool load_program(const std::string &filename, bool binary);
00265 
00276     void save_program_as(const std::string &filename, bool binary);
00277 
00285     void accumulate_mode_set(bool value);
00286 
00307     void constant_mode_set(bool value);
00308 
00316     void program_card_walk(program_card_functor &f) const;
00317 
00327     virtual void property(const std::string &name, const std::string &value);
00328 
00338     static const char *program_mode_name(program_mode_t pm);
00339 
00346     bool strict_memory_number_checking_required(void) const;
00347 
00352     void strict_memory_number_checking_set(bool);
00353 
00365     bool save_memories_as_program(const std::string &filename);
00366 
00367 protected:
00372     calculator();
00373 
00379     void update_display(void);
00380 
00391     void clock_tick_event(void);
00392 
00397     bool clock_tick_expected(void) const;
00398 
00407     virtual void clock_tick_start_running(void) = 0;
00408 
00414     void printer_finished_event(void);
00415 
00420     bool printer_finished_event_expected(void) const;
00421 
00422     typedef boost::shared_ptr<debugger> debugger_pointer;
00423 
00432     void update_debugger(debugger &where);
00433 
00441     void set_address(int n);
00442 
00453     bool get_step(int addr, unsigned char &op, location::pointer &where) const;
00454 
00455 private:
00467     virtual void derived_print(const display &value) = 0;
00468 
00473     virtual void derived_feed(void) = 0;
00474 
00478     virtual void derived_off(void) = 0;
00479 
00488     virtual void derived_update_display(const display &value) = 0;
00489 
00498     virtual void printer_timer_start_running(void) = 0;
00499 
00504     bool accumulate_mode_get(void) const;
00505 
00511     enum mstate_t
00512     {
00519         mstate_reset,
00520         mstate_lhs_digits_before_dot,
00521         mstate_lhs_digits_after_dot,
00522         mstate_lhs_complete,
00523         mstate_mul,
00524         mstate_mul_digits_before_dot,
00525         mstate_mul_digits_after_dot,
00526         mstate_mul_complete,
00527     };
00528 
00529     static const char *mstate_name(mstate_t s);
00530 
00531     mstate_t mstate;
00532 
00537     precision_and_rounding precro_front_panel;
00538 
00545     precision_and_rounding precro_current;
00546 
00547     number x_register;
00548 
00549     number y_register;
00550 
00551     number memory[16];
00552 
00618     program_selector_t program_selector;
00619 
00630     unsigned char address;
00631 
00638     unsigned char programme[256];
00639 
00645     location::pointer programme_location[SIZEOF(programme)];
00646 
00651     program_mode_t program_mode;
00652 
00653     interpose::pointer interpose_by_program_mode[4];
00654 
00655     enum deferred_action_t
00656     {
00657         deferred_action_none,
00658         deferred_action_multiplication,
00659         deferred_action_division,
00660     };
00661 
00666     deferred_action_t deferred_action;
00667 
00672     void update_display_lrn(void);
00673 
00685     void calculate_display_lrn(display &disp, int addr, int op);
00686 
00691     void update_display_ope(void);
00692 
00693     enum clock_tick_mode_t
00694     {
00695         clock_tick_mode_disabled,
00696         clock_tick_mode_running,
00697         clock_tick_mode_entry,
00698         clock_tick_mode_sj,
00699         clock_tick_mode_ej,
00700     };
00701 
00708     clock_tick_mode_t clock_tick_mode;
00709 
00716     bool printer_delay_active;
00717 
00723     unsigned char next_opcode(void);
00724 
00736     unsigned find_flag_jump(unsigned char label);
00737 
00746     unsigned wrap_address(unsigned addr) const;
00747 
00752     void update_display_lamps(display &value);
00753 
00758     void execute_one_instruction(void);
00759 
00764     void program_print(void);
00765 
00779     bool accumulate_mode;
00780 
00788     std::list<unsigned> call_stack;
00789 
00802     unsigned find_subroutine_flag_jump(unsigned char label);
00803 
00810     location::pointer next_location(void) const;
00811 
00833     bool constant_mode;
00834 
00841     deferred_action_t constant_mode_action;
00842 
00849     number constant_mode_rhs;
00850 
00858     void constant_mode_eval(bool neg);
00859 
00867     void non_constant_mode_eval(bool neg);
00868 
00875     void eval(bool neg);
00876 
00884     void eval_mul(bool neg);
00885 
00886     typedef std::map<std::string, std::string> properties_t;
00887 
00892     properties_t properties;
00893 
00903     std::string get_property(const std::string &name,
00904         const std::string &dflt = "") const;
00905 
00915     bool get_bool_property(const std::string &name, bool dflt = false) const;
00916 
00924     bool have_property(const std::string &name) const;
00925 
00932     void maybe_accumulate(void);
00933 
00940     bool strict_memory_number_checking;
00941 
00948     int number_of_keys_since_ej;
00949 
00954     calculator(const calculator &);
00955 
00960     calculator &operator=(const calculator &);
00961 };
00962 
00963 // vim: set ts=8 sw=4 et :
00964 #endif // LIB_CALCULATOR_H