HP Articles Forum
[Return to the Index ]
[ Previous | Next ]
Effective Computer-aided Calculator Programming - Part 1 - Voyager
Posted by Egan Ford on 2 Apr 2008, 12:47 a.m.
The purpose for this series of articles is to describe the options available to aid in the rapid development and testing of RPN code by leveraging the use of text editors, compilers, and accelerated simulators and emulators.
Part 1 of this series supports the follow models: 11C, 12C, 15C, and the 16C.
The Voyager compiler used in this article requires a Perl interpreter. For Linux and OS/X nothing is required, however for Windows, Perl must be installed. There are a number of freely available Perl implementations for Windows; one of the most popular is the freely available ActivePerl (http://www.activestate.com/store/activeperl/download/).
To verify that Perl is working open up a command prompt and type:
perl -e "print \"hello world\n\""
Nonpareil 15C Windows Snap Shot
NOTE: The Voyager compiler in this article only supports Nonpareil.
To install Nonpareil for Windows visit http://nonpareil.brouhaha.com/download and download and install GTK first, then download and extract the Nonpareil Windows zip file into any directory. To launch Nonpareil, change to the nonpareil-0.77-win32 directory and type:
nonpareil calculatore.g.
nonpareil 15cAlternatively you can give no argument and then be greeted by a GUI calculator selector.
To install Nonpareil for Linux/Unix first verify that GTK is installed, and then download the source from http://nonpareil.brouhaha.com/download, extract, and type as root:
cd nonpareil-0.78/scons-local tar -xzf scons-local-0.96.90.tar.gz cd .. scons-local/scons.py installThis will place nonpareil in /usr/local/bin. If you wish to install in a different directory read the INSTALL file for more details.
OS/X users can get Nonpareil from http://homepage.mac.com/mba/nonpareil/. This version unfortunately does not save or read Nonpareil state files making the compiler only good for syntax checking, macros, virtual labels (12C), numeric expansion, and publication of code (pretty print). OS/X users may opt for VMware Fusion, Parallels, or Wine with the Windows or Linux version of Nonpareil.
vcomp.pl has a number of advanced features to make Voyager development and testing more efficient:
The Windows version can be obtained from here: http://www.hpmuseum.org/guest/eganford/vcomp.zip, to install just copy into any directory in your path.
Linux, OS/X, Cygwin, Unix, etc… Install
The non-Windows version can be obtain from here: http://www.hpmuseum.org/guest/eganford/vcomp.gz, to install just copy into any directory in your path and type:
gunzip <vcomp.gz >vcomp.pl chmod 755 vcomp.pl
vcomp.pl without any options will produce the following helpful output:
vcomp.pl dict [-help] [-c|-cc n] <model> list [-help] [-c|-cc n] [-code|-linecode] <file> comp [-help] [-strip n] [-phase 1|2] [-c|-cc n] [-new <model>] -nst <file> <code>
<model> Must be 11C, 12C, 15C, or 16C. <file> Is an existing or new Nonpareil State file. <code> Is your text source code.vcomp.pl has three modes of operation: dictionary, list, and compile. Although all the examples use the first four letters, the lazy (or efficient) can opt to use just the first letter when specifying the mode of operation. Each mode has options specific to that mode. However there are few universal options.
The universal option –help can be used with any vcomp.pl command/mode to display usage and examples. E.g.:
vcomp.pl dict –helpwill output:
vcomp.pl dict [-c|-cc n] <model>
-c n Print output in n columns. -cc n Print output using x columns that can fit in n characters.
<model> Must be 11C, 12C, 15C, or 16C.
E.g. 11C dictionary in 2 columns:
vcomp.pl dict -c 2 11C
E.g. 15C dictionary in x columns that can fix in 80 characters:
vcomp.pl dict -cc 80 15C-c and –cc are two other universal options that can be used to columnize any output. –c n will display the output in n columns whereas –cc n will determine based on the length of the longest line how many columns can fit within an n character line, e.g. –cc 80 will columnize the output into m columns such that the maximum character count for any output line will <= 80.
Dictionary
The dictionary is used to convert statements to byte code (compiling) and byte code to statements (listing). The vomp.pl dict command can be used to list the contents of the dictionary, e.g.:
vcomp.pl dict -c 2 15COutput:
% 43 14 RCL/ (i) - 45,10,24 + 40 RCL/ .0 - 45,10,.0 - 30 RCL/ .1 - 45,10,.1 ->DEG 43 3 RCL/ .2 - 45,10,.2 ->H 43 2 RCL/ .3 - 45,10,.3 . . . RCL- B - 45,30,12 x^2 43 11 RCL- C - 45,30,13 y^,r 42 48 RCL- D - 45,30,14 y hat,r RCL- E - 45,30,15 LIN EST RCL- I - 45,30,25 y^x 14The listing is sorted alphabetically. Nested statements (e.g. y hat,r, LIN EST above) are aliases. That is LIN EST could be used in your source instead of or in addition to y^,r when compiling, however when listing only the primary statement (e.g. y^,r) will be used. The dictionary and its contents are user definable.
Editing the Dictionary
To edit the dictionary for any model use your favorite text editor and search for "model Opcode Start", e.g. "11C Opcode Start", then scroll down until you find the statements you wish to edit or rearrange. E.g.:
ee | L.R. | 42 49 | ef | y^,r | 42 48 | ef | y hat, r | 42 48 | ef | LIN EST | 42 48 | f0 | 0 | 0 |Notice how y^,r, y hat, r and LIN EST all have the same byte code. The first one listed will be the primary and the others will be aliases. Feel free to edit this to suit your taste, but make a backup first, just in case.
List
vcomp.pl listwill list the contents of any existing or newly created Nonpareil state file, e.g.:
vcomp.pl list -c 2 "c:\Documents and Settings\Egan\nonpareil\12C.nst"Output:
01 - 0 0 24 - 1 1 02 - 44 2 STO 2 25 - 40 + 03 - 1 1 26 - 1 1 04 - 44 1 STO 1 27 - 4 4 05 - 44 0 STO 0 28 - 8 8 06 - 1 1 29 - 6 6 07 - 16 CHS 30 - 3 3 08 - 44 20 1 STOx 1 31 - 5 5 09 - 2 2 32 - 6 6 10 - 44 40 0 STO+ 0 33 - 4 4 11 - 45 0 RCL 0 34 - 8 8 12 - 1 1 35 - 20 x 13 - 1 1 36 - 5 5 14 - 21 y^x 37 - 0 0 15 - 22 1/x 38 - 5 5 16 - 45 1 RCL 1 39 - 48 . 17 - 20 x 40 - 2 2 18 - 44 40 2 STO+ 2 41 - 1 1 19 - 42 14 RND 42 - 10 / 20 - 43 35 x=0 43 - 1 1 21 - 43,33 23 GTO 23 44 - 1 1 22 - 43,33 06 GTO 06 45 - 22 1/x 23 - 45 2 RCL 2 46 - 21 y^xThe –code and –linecode options can be used to limit the amount of information, e.g.:
vcomp.pl list -c 5 -code 12C.nst
0 RCL 0 GTO 23 5 1 STO 2 1 GTO 06 6 / 1 1 RCL 2 4 1 STO 1 y^x 1 8 1 STO 0 1/x + x 1/x 1 RCL 1 1 5 y^x CHS x 4 0 STOx 1 STO+ 2 8 5 2 RND 6 . STO+ 0 x=0 3 2
vcomp.pl list -c 3 -linecode 12C.nst
01 0 17 x 33 4 02 STO 2 18 STO+ 2 34 8 03 1 19 RND 35 x 04 STO 1 20 x=0 36 5 05 STO 0 21 GTO 23 37 0 06 1 22 GTO 06 38 5 07 CHS 23 RCL 2 39 . 08 STOx 1 24 1 40 2 09 2 25 + 41 1 10 STO+ 0 26 1 42 / 11 RCL 0 27 4 43 1 12 1 28 8 44 1 13 1 29 6 45 1/x 14 y^x 30 3 46 y^x 15 1/x 31 5 16 RCL 1 32 6
vcomp.pl compwill compile plain text statements into Voyager byte code in the form of a Nonpareil state file.
When compiling you have the option of creating a new out-of-the-box state file or inserting your code into an existing state file preserving the contents of the stack and storage registers.
NOTE: Inserting into an existing state file is experimental. Backup your data first.
NOTE: New state files are not exactly "out-of-the-box", the 11C, 12C, and 15C are out-of-the-box + FIX 9.
Source Code Anatomy
;Area of a circle ENTER ENTER * 3.141592654 *
;my blah program LBL A ;LBL A 2 * ;X * 2 -> X ;Fix this bug later
123 -123 -123.45 -123.45E-5
lbl a LBL A LblA LBL Aare all the same statement.
&MOD
LBL A LBL FOO LBL B2 GRO A GTO FOO GTO B2
To compile the source file area.12c and insert into an existing 12C.nst state file:
vcomp.pl comp -nst 12C.nst area.12cTo compile the source file area.12c and create a new 12C.nst state file:
vcomp.pl comp -new 12C -nst 12C.nst area.12cThe output for any successful compile should look like this:
Phase 1: Preprocessor Phase 2: Check GTOs Phase 3: Compile Done!The only difference between the two is the use of the –new option. This is required to instruct the compiler as to what model you are compiling for. Without –new the compiler can autodetect the model from the provided state file.
Because of the advanced preprocessing features of this compiler the post compiled listing may not match your source code, e.g.
Input file area.12:
ENTER ENTER * 3.141592654 *Listing:
vcomp.pl list -linecode 12c.nst
01 ENTER 02 ENTER 03 x 04 3 05 . 06 1 07 4 08 1 09 5 10 9 11 2 12 6 13 5 14 4 15 x
ERROR: illegal instruction: 01 ENTER, line: 1However if you strip off the first 4 characters all is well:
vcomp.pl comp -strip 4 -new 12c -nst 12c.nst area.txt
Phase 1: Preprocessor Phase 2: Check GTOs Phase 3: Compile Done!
Macros are defined in vcomp.pl. To add or edit use your favorite text editor and search for "model Macro Start", e.g. "12C Macro Start". This is an example of two 12C macros:
12C Macro Start &SMOD LBL START - LSTx x<=y GTO START Rv &MOD x<>y ENTER Rv x<>y / LSTx x<>y INTG * x<>y - CHS 12C Macro EndMacro definitions start with &NAME and end when the next macro starts and may contain any number of legitimate statements and virtual labels (12C only). E.g. the &SMOD (slow or subtract mod) leverages the use of 12C virtual labels to setup a loop.
In this example two 15C macros are defined. One for calling the other as a subroutine:
&CALL_MOD GSB .8 &MOD LBL .8 x<>y ENTER Rv x<>y / LSTx x<>y INT * R^ - CHS RTNAn example of how to use this macro:
LBL A ... &CALL_MOD ... &CALL_MOD ... RTN ;End of program &MODNOTE: Macros cannot call macros.
Compiler Preprocessor
Phase 1 of the compiler checks for syntax, expands macros, checks for duplicate labels, processes virtual labels, and expands multiple digit numbers. If there is an error the compiler will halt and display a useful message. E.g. the following 12C program has an invalid statement on line 3:
11 &SMOD SINThe compiler will report:
ERROR: illegal instruction: SIN, line: 3Errors in macros will be reported as:
ERROR: illegal instruction: SIN, in macro: &TAN, line: 2.1The 2.1 indicates the 2nd line of your code and the 1st line of the macro.
Phase 2 of the compiler checks for valid GTO statements and completes the processing of the virtual label GTOs. If a GTO has nowhere to go an error message will be produced and the compiler will halt. E.g., the following 12C program has an invalid GTO:
11 &SMOD GTO AThe compiler will report:
ERROR: Virtual GTO A goes nowhere, post processed line: 8Line 8? The source only has 3 lines. Finding the source of this error may be difficult with larger programs. This can be addressed with the –phase option. –phase 1 will halt the compile and dump out intermediate results, e.g.
vcomp.pl comp -phase 1 -new 12c -nst 12c.nst foo.txt
Phase 1: Preprocessor
001 1f 1 002 1f 1 003 b2 - 004 d5 LSTx 005 c5 x<=y 006 ---- gtostart 007 dc Rv 008 ---- gtoaThe first column is the line number. Column 2 is the byte code. The gtoa on line 8 is the offending statement. The ---- statements require the next compiler phase, to see the byte code and the final GTO statements use –phase 2 after replacing GTO A with RTN, e.g.:
vcomp.pl comp -phase 2 -new 12c -nst 12c.nst foo.txt
Phase 1: Preprocessor Phase 2: Check GTOs
001 1f 1 002 1f 1 003 b2 - 004 d5 LSTx 005 c5 x<=y 006 03 GTO 03 007 dc Rv 008 00 GTO 00For long programs the –c and –cc options can be used with –phase to columnize the output.
Authors
vcomp.pl was written by Thomas Klemm and Egan Ford.
To test your program with Nonpareil:
vcomp.pl comp –nst "c:\Documents and Settings\Egan\nonpareil\15C.nst" code.extLinux/UNIX users:
vcomp.pl comp –nst ~/.nonpareil/15C.nst code.txtI prefer this method because all my register and stack variables are still intact.
Accelerate your Nonpareil
Nonpareil will execute your programs at authentic Voyager speeds. It can be very frustrating to have a competition or challenge code take 9 hours just to return the wrong answer. If you have the ability to build your own version of Nonpareil you can speed up program execution by about 200 times.
First edit src/model.c and change the following lines from:
{ "11C", PLATFORM_VOYAGER, ARCH_NUT, 40, 215000 }, { "12C", PLATFORM_VOYAGER, ARCH_NUT, 40, 215000 }, { "15C", PLATFORM_VOYAGER, ARCH_NUT, 80, 215000 }, { "16C", PLATFORM_VOYAGER, ARCH_NUT, 40, 215000 },to:
{ "11C", PLATFORM_VOYAGER, ARCH_NUT, 40, 2147483647 }, { "12C", PLATFORM_VOYAGER, ARCH_NUT, 40, 2147483647 }, { "15C", PLATFORM_VOYAGER, ARCH_NUT, 80, 2147483647 }, { "16C", PLATFORM_VOYAGER, ARCH_NUT, 40, 2147483647 },This will increase the emulated frequency to as fast as possible. Don’t get too excited, you are still limited by the speed of your computer.
Next edit src/voyager_lcd.c, and change:
#define VOYAGER_DISPLAY_BLINK_DIVISOR 150to:
#define VOYAGER_DISPLAY_BLINK_DIVISOR 0This will disable the blinking "running". This will not increase the speed of the emulation, but will reduce the OS overhead measurably when running accelerated. This is important for the next step to get the most out of your pimped-out Voyager.
Lastly edit src/proc.c and fiddle with:
#define MAX_INST_BURST 5000If you make this number too big you will be unable to use the virtual keyboard. This number will vary from system to system. Increase this value by increments of 5000 until Nonpareil becomes unstable (keyboard does not work) or CPU utilization reaches 100% when running your program. For my 2.4 GHz P4 system I have MAX_INST_BURST set to 30000. My CPU utilization is 98%. A program that took 9:37 hours with Nonpareil and a real 15C now runs in 3:05 minutes.
It is probably not a good idea to replace your normal Nonpareil. To avoid overwriting when compiling with scons.py do not specify the install option.
Linux example:
To build/test:
cd nonpareil-0.78 scons-local/scons.py build/posix/nonpareil 15cWhen you have a satisfactory supercharged Nonpareil binary, just copy it to /usr/local/bin as nonpareil.fast, e.g.:
cp ./build/posix/nonpareil /usr/local/bin/nonpareil.fast
Unfortunately there is no way to electronically transfer your programs from the virtual to the physical world. But you can use the listing features of the compiler to provide the necessary keystrokes to save time and increase accuracy.
Reported bug in vcomp 15C listings has been fixed.
Edited: 30 Oct 2012, 9:19 a.m.