Canola  0.8.D001
lib/calculator/update_display.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/calculator.h>
00019 
00020 
00021 void
00022 calculator::update_display(void)
00023 {
00024     switch (program_mode)
00025     {
00026     case program_mode_learn:
00027     case program_mode_program_check:
00028         update_display_lrn();
00029         break;
00030 
00031     case program_mode_operation:
00032     case program_mode_operation_check:
00033         update_display_ope();
00034         break;
00035 
00036     default:
00037         assert(!"this mode doesn't exist");
00038         break;
00039     }
00040 }
00041 
00042 
00043 void
00044 calculator::calculate_display_lrn(display &value, int addr, int opc)
00045 {
00046     value.tubes[9].digit = addr / 100;
00047     value.tubes[8].digit = (addr / 10) % 10;
00048     value.tubes[7].digit = addr % 10;
00049 
00050     value.tubes[4].digit = opc >> 4;
00051     value.tubes[3].digit = (opc & 15) / 10;
00052     value.tubes[2].digit = (opc & 15) % 10;
00053 
00054     if (!opcode_valid(opc))
00055         value.negative = true;
00056     value.set_opcode(opcode_t(opc));
00057 
00058     //
00059     // At least one tube MUST have a the dot turned on
00060     // (probably a hardware limitation).
00061     //
00062     // <question>
00063     // What does the dot in digit 16 mean in LRN mode?
00064     // Does PRO CHE mode have the dot in a different column?
00065     // </question>
00066     //
00067     value.tubes[15].dot = true;
00068 }
00069 
00070 
00071 void
00072 calculator::update_display_lamps(display &value)
00073 {
00074     value.m1 = (memory[1] != 0);
00075     value.m2 = (memory[2] != 0);
00076     switch (clock_tick_mode)
00077     {
00078     case clock_tick_mode_disabled:
00079     case clock_tick_mode_running:
00080         break;
00081 
00082     case clock_tick_mode_entry:
00083     case clock_tick_mode_ej:
00084     case clock_tick_mode_sj:
00085        value.entry = true;
00086        break;
00087 
00088     default:
00089         break;
00090     }
00091 }
00092 
00093 
00094 void
00095 calculator::update_display_lrn(void)
00096 {
00097     unsigned addr = wrap_address(address);
00098     assert(addr >= 1 && addr <= 240);
00099 
00100     display value;
00101     calculate_display_lrn(value, addr, programme[addr]);
00102     update_display_lamps(value);
00103     derived_update_display(value);
00104 }
00105 
00106 
00107 void
00108 calculator::update_display_ope(void)
00109 {
00110     display value = x_register.get_display();
00111     update_display_lamps(value);
00112     derived_update_display(value);
00113 }