Canola
0.8.D001
|
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/config.h> 00019 #include <libexplain/output.h> 00020 #include <libexplain/printf.h> 00021 #include <libexplain/putchar.h> 00022 00023 #include <lib/std_string_printf.h> 00024 00025 #include <test_calculator/calculator/test.h> 00026 00027 00028 calculator_test::~calculator_test() 00029 { 00030 } 00031 00032 00033 calculator_test::calculator_test() 00034 { 00035 } 00036 00037 00038 calculator::pointer 00039 calculator_test::create(void) 00040 { 00041 return pointer(new calculator_test()); 00042 } 00043 00044 00045 void 00046 calculator_test::derived_print(const display &value) 00047 { 00048 class cursor_t 00049 { 00050 public: 00051 cursor_t() : icol(1), ocol(1) { }; 00052 00053 void 00054 putch(char c) 00055 { 00056 if (c == ' ') 00057 ++icol; 00058 else 00059 { 00060 while (ocol < icol) 00061 { 00062 putchar(' '); 00063 ++ocol; 00064 } 00065 putchar(c); 00066 ++icol; 00067 ocol = icol; 00068 } 00069 } 00070 00071 void 00072 putstr(const char *s) 00073 { 00074 for (;;) 00075 { 00076 char c = *s++; 00077 if (!c) 00078 return; 00079 putch(c); 00080 } 00081 } 00082 00083 void 00084 set_column(int n) 00085 { 00086 assert(n > 17); 00087 if (n > icol) 00088 icol = n; 00089 } 00090 00091 void 00092 putch(int col, char c) 00093 { 00094 set_column(col); 00095 putch(c); 00096 } 00097 00098 void 00099 putstr(int col, const char *s) 00100 { 00101 set_column(col); 00102 putstr(s); 00103 } 00104 private: 00105 int icol; 00106 int ocol; 00107 }; 00108 cursor_t cursor; 00109 00110 for (int dignum = 15; dignum >= 0; --dignum) 00111 { 00112 const display::tube_t &tube = value.tubes[dignum]; 00113 if (tube.digit >= 10) 00114 cursor.putch(' '); 00115 else 00116 cursor.putch('0' + tube.digit); 00117 if (tube.dot) 00118 cursor.putch('.'); 00119 } 00120 if (value.negative) 00121 { 00122 cursor.set_column(18); 00123 cursor.putch('-'); 00124 } 00125 switch (value.column18) 00126 { 00127 case display::column18_blank: 00128 break; 00129 00130 case display::column18_minus: 00131 if (!value.negative) 00132 cursor.putch(18, '-'); 00133 break; 00134 00135 case display::column18_ce: 00136 cursor.putstr(18, "CE"); 00137 break; 00138 00139 case display::column18_cm: 00140 cursor.putstr(18, "CM"); 00141 break; 00142 00143 case display::column18_e: 00144 cursor.putch(18, 'E'); 00145 break; 00146 00147 case display::column18_fj: 00148 cursor.putstr(18, "FJ"); 00149 break; 00150 00151 case display::column18_ej: 00152 cursor.putstr(18, "EJ"); 00153 break; 00154 00155 case display::column18_uj: 00156 cursor.putstr(18, "UJ"); 00157 break; 00158 00159 case display::column18_mj: 00160 cursor.putstr(18, "MJ"); 00161 break; 00162 00163 case display::column18_sj: 00164 cursor.putstr(18, "SJ"); 00165 break; 00166 00167 case display::column18_rv: 00168 cursor.putstr(18, "RV"); 00169 break; 00170 00171 case display::column18_sfj: 00172 cursor.putstr(18, "SFJ"); 00173 break; 00174 00175 case display::column18_suj: 00176 cursor.putstr(18, "SUJ"); 00177 break; 00178 00179 case display::column18_srj: 00180 cursor.putstr(18, "SRJ"); 00181 break; 00182 00183 case display::column18_right: 00184 cursor.putstr(18, "\u2192"); 00185 break; 00186 00187 case display::column18_cs: 00188 cursor.putstr(18, "CS"); 00189 break; 00190 00191 default: 00192 break; 00193 } 00194 switch (value.column19) 00195 { 00196 case display::column19_blank: 00197 break; 00198 00199 case display::column19_plus_equals: 00200 cursor.putstr(19, "+="); 00201 break; 00202 00203 case display::column19_minus_equals: 00204 cursor.putstr(19, "-="); 00205 break; 00206 00207 case display::column19_times: 00208 cursor.putstr(19, "\u00D7"); 00209 break; 00210 00211 case display::column19_divide: 00212 cursor.putstr(19, "\u00F7"); 00213 break; 00214 00215 case display::column19_sqrt: 00216 cursor.putstr(19, "\u221A"); 00217 break; 00218 00219 case display::column19_m_plus: 00220 cursor.putstr(19, "M+"); 00221 break; 00222 00223 case display::column19_m_minus: 00224 cursor.putstr(19, "M-"); 00225 break; 00226 00227 case display::column19_rm: 00228 cursor.putstr(19, "RM"); 00229 break; 00230 00231 case display::column19_sm: 00232 cursor.putstr(19, "SM"); 00233 break; 00234 00235 case display::column19_print: 00236 cursor.putstr(19, "\u25CA"); 00237 break; 00238 00239 default: 00240 break; 00241 } 00242 switch (value.column20) 00243 { 00244 case display::column20_blank: 00245 break; 00246 00247 case display::column20_n1: 00248 cursor.putch(20, '1'); 00249 break; 00250 00251 case display::column20_fd: 00252 cursor.putstr(20, "FD"); 00253 break; 00254 00255 case display::column20_round_up: 00256 cursor.putstr(20, "\u2191"); 00257 break; 00258 00259 case display::column20_round_off: 00260 cursor.putstr(20, "5/4"); 00261 break; 00262 00263 case display::column20_round_down: 00264 cursor.putstr(20, "\u2193"); 00265 break; 00266 00267 case display::column20_dot: 00268 cursor.putstr(20, "."); 00269 break; 00270 00271 default: 00272 break; 00273 } 00274 switch (value.column21) 00275 { 00276 case display::column21_blank: 00277 break; 00278 00279 case display::column21_n0: 00280 case display::column21_n1: 00281 case display::column21_n2: 00282 case display::column21_n3: 00283 case display::column21_n4: 00284 case display::column21_n5: 00285 case display::column21_n6: 00286 case display::column21_n7: 00287 case display::column21_n8: 00288 case display::column21_n9: 00289 cursor.putch(21, '0' + value.column21 - display::column21_n0); 00290 break; 00291 00292 default: 00293 break; 00294 } 00295 explain_putchar_or_die('\n'); 00296 } 00297 00298 00299 void 00300 calculator_test::derived_feed(void) 00301 { 00302 explain_putchar_or_die('\n'); 00303 } 00304 00305 00306 void 00307 calculator_test::on_error_v(const char *fmt, va_list ap) 00308 { 00309 std::string text = std_string_printf_v(fmt, ap); 00310 explain_output_error_and_die("%s", text.c_str()); 00311 } 00312 00313 00314 void 00315 calculator_test::run(void) 00316 { 00317 // finish running any program 00318 for (;;) 00319 { 00320 if (printer_finished_event_expected()) 00321 printer_finished_event(); 00322 else if (clock_tick_expected()) 00323 clock_tick_event(); 00324 else 00325 break; 00326 } 00327 } 00328 00329 00330 void 00331 calculator_test::derived_off(void) 00332 { 00333 exit(0); 00334 } 00335 00336 00337 void 00338 calculator_test::derived_update_display(const display &) 00339 { 00340 } 00341 00342 00343 void 00344 calculator_test::clock_tick_start_running(void) 00345 { 00346 } 00347 00348 00349 void 00350 calculator_test::printer_timer_start_running(void) 00351 { 00352 } 00353 00354 00355 void 00356 calculator_test::on_opcode(opcode_t op, const location::pointer &where) 00357 { 00358 calculator::on_opcode(op, where); 00359 00360 // they could have "pressed" START 00361 // let it run for a few thousand instructions 00362 for (int j = 0; j < 5000; ++j) 00363 { 00364 if (printer_finished_event_expected()) 00365 printer_finished_event(); 00366 else if (clock_tick_expected()) 00367 clock_tick_event(); 00368 else 00369 break; 00370 } 00371 }