/***************************************************************************** hp41c.c HP41C calculator emulator v1.4 Harold Z. Bencowitz Beaumont, Texas 24-sep-86 ****************************************************************************** description: hp41c is a program to emulate the Hewlett-Packard 41C series of hand-held programmable calculators. it requires a vt100 or vt200 series terminal. it has been tested on rt11 v5.3 and tsx+ v6.01. the major design goal was to make an exactly identical user interface for those features included. to operate the "calculator" follow directions in the HP41C owners handbook. the keyboard mapping is given on screen when the program is run. many features of the hp41c are not supported, primarily programming and functions which are only useful from programs. features supported: display control functions ie <-, CLX, EEX, FIX, ENTER, and CHS; all mathematical functions available from the keyboard (without XEQ) namely: add, subtract, multiply, divide, 1/x, x**2, SQRT, y**x, ln, e**x, log, and 10**x; OCT and DEC (decimal/octal conversions (both from keypad and XEQ); rotate stack down (RDN); trig functions (SIN, COS, TAN, ASIN, ACOS, ATAN); nonvolatile memory (if program is named sy:hp41c.sav); degree/radian/grad mode switching for trig functions; STO and RCL (store and recall from memory); storage register arithmetic, direct storage in stack registers; XEQ commands D-R, DEC, DEG, RAD, FRC, GRAD, INT, CLRG, OCT, PI, MOD, CLST, R-D. features not supported: alpha mode (including AON, AOFF, ASHF, ASTO, AVIEW, CLA), user defined keys (user mode), indirect memory access, last x, LN1+X, accumulations (CLsum, sum+, sum-, sumREG, mean, sum, SD), BEEP, TONE, VIEW, ADV, SIZE, COPY, ON, OFF, rotate up, programming (including numerous functions such as R/S, pack, catalog, sst, bst, CLP, DEL, DSE, END, all flag instructions, GTO, GTO., GTO.., ISG, LBL, PROMPT, PSE, RTN, STOP, and all comparisons), and some xeq commands including: ABS, ENG, SCI, FACT, HMS, HMS+, HMS-, HR, LASTX, %, %CH, P-R, R-P, RND, SIGN (some of these are only useful from programs). operating instructions: remember that the HP41C uses reverse polish notation. to operate the "calculator" follow directions in the HP41C owners handbook. almost all operations are the same when supported although many HP41C features are not supported. the mapping of the terminal keyboard to the "calculator" is explained on screen. the set of functions on the right are those activated by pressing the gold key prior to the specific key. almost all "calculator" functions are operated from the keypad. in addition four keys are used which are F17-F20 on a vt200 and UP-RIGHT (arrows) on a vt100. in addition the delete key on each terminal turns the program off (control C is not disabled but it should be avoided, otherwise the vt200 will be left with the cursor off and the current data will not be written to disk). only these keys are active and others are ignored. the functions available through the XEQ command are listed on the far left of the screen. XEQ does not require turning alpha mode on as the HP41C does. pressing XEQ automatically enables alpha mode. to terminate an alpha string press "." on the keypad. during alpha mode only A-Z (lowercase converted to upper), "-", keypad comma (<- function), and keypad period (terminate alpha mode) are active. possible additions: accumulator functions (+ACC, -ACC, mean, SDEV, and clear acc), and some of the following functions using XEQ: ABS, CLD, ENG, SCI, FACT, HMS, HMS+, HMS-, HR, LASTX, %, %CH, P-R, R^, R-P, RND. differences/limitations: uses standard PDP11 double floats in which the permissible size of a number is ~1.7e-38 to ~1.7e38 whereas the HP41C allows 9.9...e-99 to 9.9...e99. the program will not allow any value outside the range 1.0e-37 to 1.0e37. the program deals with out of range entries (NOT out of range results) differently than the HP41C. it displays an error message and remains in active mode allowing revision of the entered number, whereas the HP41C merely truncates the number to 0. or 9.9...e99 and tries to use it. PDP11 double floats have more decimal places accuracy than the HP41C. this is corrected for in the software. however occasionally this difference will result in a slightly different result than the HP41C (eg 1.123 - 1, then the result - .123 = a very small number rather than zero). DEC and OCT functions are available through keyboard commands as well as XEQ. XEQ does not require turning alpha mode off and on as the HP41C does. pressing XEQ automatically enables alpha mode. to terminate an alpha string press "." on the keypad. the trig functions may give slightly different results (7-10th decimal place). some trig functions may occasionally give very small answers instead of 0. (eg. tan of 720 degrees) or vice versa (sine of -1.236e-20). no other differences are known. revision history: v1.0 completed 24-jun-86 includes all display control keys includes + - / * and 1/x v1.1 completed 14-jul-86 keys added to displayed map, error in vt100 active, "shift" display, cutoff, x**2, sqrt, y**x, ln, e**x, log, 10**x, oct, dec v1.2 completed 18-jul-86 RDN, DEG/RAD/GRAD mode switching, STO, RCL, delete from anywhere to stop v1.3 completed 21-jul-86 XEQ (RAD, DEC, DEG, GRAD, CLST, CLRG, OCT, PI), storage in stack nonvolatile memory (write to disk) v1.4 completed 24-sep-86 fix bugs in k_oct and k_dec; set_inactive() created, improved general purpose isint(); SIN, COS, TAN, ASIN, ACOS, ATAN; XEQ: INT, FRC, MOD. vtttid() modified to allow vt132 and vt100 with printer port. installation/building: included: hp41c.sav, hp41c.h, hp41c.c, vt.obj, hclib.obj, hp41c.end, and hp41c.doc (included in hp41c.c also). to install: copy hp41c.sav to sy:. it will run from other locations but error messages will appear whenever the program is run or stopped if it cannot read/write from sy:hp41c.sav. the source module hp41c.c must be compiled and linked with library modules from hclib (my own c function library), clib (whitesmith's c function library), vt (my video terminal library), and syslib. after compilation and linking, the size of hp41c.sav must equal the number of blocks defined by BLOCK below. if not, change BLOCK and recompile. otherwise, append hp41c.end to hp41.sav to make the final hp41c.sav. definition: active mode means that entry is one key at a time prompted by '_' (if not in the far right character position) where entries can be edited with <-. inactive mode numbers cannot be edited. implementation notes: there is one source file hp41c.c and a header file hp41c.h. the video terminal library vt.obj, my library hclib.obj, and Whitesmith's clib.obj are also required. the program queries the terminal for type. it will not run unless the identification indicates a vt100 series or vt200 (in 7 bit mode only) series terminal. the following are differences between vt100 and vt200 implementations: 1) downloadable character sets on the vt200 allow the display to place the decimal point "between" two numbers rather than as a separate character and 2) the cursor is turned off on a vt200. the program uses special terminal mode and thus requires running in singlechar mode with TSX+ (done automatically) and changes the keypad and cursor control (arrow) keys to application mode. all keyboard input is captured and undefined keys are ignored. control-C is not disabled. the active display is defined by adc[], expdc[3], adc_sign, adc_dec, adc_dec, adc_dot, exp_flag, exp_sign, and exp_end. this is explained in comments in active(). the calculator stack is in extern double stack[3] (T, Z, and Y are in [2], [1], and [0] respectively) and x_value (X). dis_fix is the number of decimal places to display as entered by FIX. note that this is different from automatic variable fix. act_flag is YES if the display is in active mode. err_flag is YES if an error message is displayed (set NO by display(), set YES by derror(), only used by k_clc). lift_stack if YES means that the next time the display changes from inactive to active, the x value will be pushed onto the stack. this is explained in appendix C of the HP41C manual. stack lift is disabled by ENTER and CLX. it is not changed by <-. CHS and EEX do not change it during active mode; at other times they enable stack lift. all other operations enable stack lift. to use non-volatile memory, ie read/write data to disk, append 2 blocks to the compiled and linked *.sav image. the first word of the two blocks must be CALCODE. BLOCK, the starting block number to read must be equal to the length of the original *.sav file in blocks. the easiest way to do this is to append hp41c.end. this feature is turned off at compilation if NVMEM is undefined.