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 #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