On 9 May 1995, James Unterburger wrote: > The HP doc on MAKEROM shows a CON(1) 8 instruction preceding > the definition of a user word (i.e., visible in the Library > soft menu) and mentions that it's for non-algebraics. > > Does anyone know what the possible values and meanings are for > this nibble? How do I make an algebraic? What other types > of interpretations are available? Here is a clipping from the entries.srt file dated September 15, 1993 by Mika Heiskanen. I consider it essential reading for the serious HP48 hacker. ******************************************************************************* Library Property Fields ----------------------- The visible romptrs in ROM are arranged in memory as follows: CON(1) #prop or CON(3) #prop CON(3) #libnum CON(3) #cmdnum ... The prop field contains bit data which is used to indicate different properties of the romptr and may imply an associated element after the romptr body. In the following explanations 'flag nn has data' means that the flag set implies an element. The element implied can be one of the following: - A 5 nibble pointer to either of following - A binary number, the body of which is the address of a valid object This is used to reference objects in hidden ROM. - A normal object ROMPTRS for which libnum >= #700 (%1792) ---------------------------------------- SST 0x8 has SST data PROMPT 0x4 has prompt message 0x3 is end macro 0x2 is middle macro PARSE 0x1 has begin macro 0x0 has stand-alone macro Order of implied elements: PARSE SST PROMPT Entries related to macro properties: 2699F ?OKMACRO ( ob --> flag ) Is ob romp with libnum >= #700? 26886 ?PARSE# ( romp --> # ) ( GX: 268D6 ) 0=stand-alone, 1=begin, 2=middle, 3=end 26906 ?PARSE ( romp --> ob TRUE / FALSE ) ( GX: 26917 ) Recalls parser property 270AF ?PROMPT ( ob --> ob' TRUE / ob FALSE ) ( GX: 2708E ) Recalls prompt string 271B9 ?SST ( ob --> ob' TRUE / ob FALSE ) ( GX: 281C5 ) Recalls single-step property PARSE: Parser object. A begin macro parser must do the parsing until the end macro token. Required syntax: ( ob1 .. obn #n HXS $string #offset $token --> ob1'.. obn' #n' HXS' $string #offset' $token' flag TRUE --> ob1 .. obn #n HXS $string #offset $token FALSE ) ob1..obn are previously parsed objects, #n their count HXS is a token-type table $string = the string being parsed $token = the token to parse #offset = offset to next char after $token (in $string) If FALSE is returned error was found If TRUE TRUE is returned parsing was succesful If FALSE TRUE is returned parsing was succesful but not completed (usually an error condition) Example: PARSEHALT = :: 'Rapndit xHALT TrueTrue ; SST: Single step program. Syntax: ( ROMPTR --> ? ) Debugged stream is in return stack. The usual exit is entry GsstFIN. Example: SSTDO = :: sstDISP @ Displays "DO" RDUP @ Duplicates 'current' stream GsstFIN @ Exit SST ; PROMPT: Prompt string Example: PROMPTIF = $ "IF-prompt" ROMPTRS for which libnum < #700 (%1792) --------------------------------------- Commands -------- 0x8 command flag - always set for commands EQWR 0x4 has eqwr entry AKA 0x2 has algebraic alias DISP 0x1 has display data - always clear? Functions --------- 0x800 command flag - always clear for functions EQWR 0x400 has eqwr entry AKA 0x200 has algebraic alias - always clear for functions DISP 0x100 has display data DER 0x080 has derivative data RINV 0x040 has inversion data COLCT 0x020 has colct data EXPND 0x010 has expand data RULES 0x008 has rules data INTG 0x004 has integral data WHERE 0x002 has where data VUNS 0x001 has very-unsyminner data Order of implied elements is EQWR ... VUNS Entries related to command/function properties: ?OKINALG (ob --> ob flag ) Is object allowed in algebraics? 26B40 ?FUNCTION (romptr --> romptr flag ) ( GX: 26B04 ) Is romptr command prop cleared? 26B73 ?AKA (romptr --> ob T / romptr F ) ( GX: 26B2E ) Recall AKA property. 26BBD ?DISP (ob --> ob ob_disp #args T / ob F ) (GX: 26BED) Recall DISP property. (Other than romp gives FALSE) 26F0D ?DER (ob --> ob_der T / ob F ) ( GX: 26F18 ) 26F1B ?RINV (ob --> ob_rinv T / ob F ) ( GX: 26F26 ) 26F29 ?COLCT (ob --> ob_colct T / ob F ) ( GX: 26F34 ) 26F37 ?EXPAN (ob --> ob_expan T / ob F ) ( GX: 26F42 ) 26F45 ?RULES (ob --> ob_rules T / ob F ) ( GX: 26F50 ) 26F53 ?INTG (ob --> ob_intg T / ob F ) ( GX: 26F5E ) 26F61 ?WHERE (ob --> ob_where T / ob F ) ( GX: 26F6C ) 26F6F ?VUNS (ob --> ob_vuns T / ob F ) ( GX: 26F7A ) 270AF ?EQWR (ob --> ob_eqwr T / ob F ) ( GX: 2708E ) EQWR: Equation Writer routine to handle special features. Structure / Arguments not interesting. AKA: Algebraic aka word for commands. Used when function uses a special way to input arguments. ?AKA does ROMPTR@ so to use AKA property use this trick: Put A ROMPTR as the aka property, the contents of which should be the wanted aka property. Thus the ROMPTR will 'pass' the correct property for DoKeyOb. DISP: Display format as a hex number or returned by a hex number. Syntax: ( --> hxs ) First/Last nibbles act as priorities/terminators 0 = Any Argument 1 = Command Name 2 = Symbolic Argument 3 = Quoted Name (Symbolic containing only ID) 4 = ( 5 = ) 6 = , 7 = = 8 = ??? 9 = Repeat 60 = ANY A = ??? B = Repeat 370 = QN=ANY C = ??? D = ??? E = ??? F = ??? 26C65 ?DISPARGS (GX: 26C8B) (ob --> ob #args ob_disp ) Recall argument count & display number for program. If no ?DISP gives false then UNDEFXLIBERR 26E56 DISPEXAM (GX: 26E61) (hxs --> NameNot1st? #P1 #P2 Parens? ) Examine DISP property, returns TRUE if function name is not first, priorities and TRUE if parentheses are second. 5E9E1 ?DISPINF ( ob --> flag ) Execute ?DISP, if property exists and arg count is infinate (#FFFFF) returns TRUE, else FALSE. Internal DISP values for SX: 26DD2 DISPARGSINF HXS 7 0140950 F(A,B,C,D...) 26DE3 DISPARGS1 HXS 6 014050 F(A) 26DF3 DISPARGS2 HXS 8 01406050 F(A,B) 26E05 DISPARGS3 HXS A 0140606050 F(A,B,C) 26E19 DISPARGS4 HXS C 014060606050 F(A,B,C,D) 26E2F DISPARGS5 HXS E 01406060606050 F(A,B,C,D,E) 1B0E6 DISP^ HXS 5 90109 (HXS 7 9014050) 1AFF5 DISP/ HXS 5 80108 (HXS 7 8014050) 1AEDE DISP* HXS 5 80108 1BE84 DISPMOD HXS 5 80108 1AC75 DISP+ HXS 5 70107 1EA21 DISP== HXS 5 60106 1E7CE DISPAND HXS 5 50105 1E854 DISPOR HXS 5 40104 26E47 DISP= HXS 5 00700 1BB2A DISP! HXS 4 A010 1B3C9 DISPSQRT HXS 4 010C (DISPARGS1) 1A9F9 DISPNEG HXS 4 0108 1E8CB DISPNOT HXS 4 0105 1FB1D DISPUNIT HXS 5 90127 1F00E DISPDER HXS 7 0134250 DER QN(SYMB) 1F241 DISPINTG HXS C 014060626350 I(ANY,ANY,SYMB,QN) 1F319 DISPSUM HXS C 014370606250 SUM(QN=ANY,ANY,SYMB) 1A471 DISPIFTE HXS A 0140626250 IFTE(ANY,SYMB,SYMB) 1F523 DISPQUOTE HXS 6 014250 QUOTE(SYMB) 1F5D9 DISPAPPLY HXS 9 014360950 APPLY(QN,ANY,...) 1F40C DISPWHERE HXS A 2214370B50 SYMB|(QN=ANY,...) DER: Derivation program. Syntax: ( Meta ALG_id/lam --> Ob ) Meta contains the stack arguments to the function. ALG_id/lam is the variable of derivation embedded into a single-object symbolic. Ob returned should be the single-step derivative of the function, as a type suitable in algebraics. NOTE!! DERFCN is bugged. If you use it to take a derivative of your own ROMPTR which has normal arguments (not infinate) and der property the internal program drops the size of Meta instead of the argument count for xFCNAPPLY. (ROLLDROP instead of 4ROLLDROP). Only way to get around it is: :: Bind ( get rid of ALG_id/lam ) TWO OVER splitup ( find last args size ) SWADROP #2- ( Correct to Meta size ) 1GETABND ( recover ALG_id/lam ) Now you have Meta ALG_id/lam on the stack as you should have. You can now use larg, parg etc to split Meta if it actually contains multiple args. RINV: Inversion program. Used by ISOL. Syntax: ( Meta1 Meta2 id --> Meta1' Meta2' & continue ISOL) ( --> FALSE ) id = variable to isolate Meta2 = Isolated so far Meta1 = Argument of the function Example: RINVLN = :: ISOLSWAP: xEXP ; ISOLSWAP = :: addtpsh 'RRDROP SWAP#1+ ISOLCONT ; COLCT: Colct execution of the function. Used for preventing evaluation of some of the arguments. Syntax is the same as for the function itself, including all error checking. ( ob1...obn ob --> ob1...obn ob FALSE / ob1'..obN' TRUE) FALSE should be returned for default operations, TRUE is property does the evaluation. EXPND: Expand program for the function. RULES: Rules menu for the function. Internal RULES menus: (# references to hidden ROM) INTG: Integration program for the function. ( Meta #pos --> Meta FALSE / Meta' TRUE ) pos is the position of the interesting function (Not necessarily topmost function!) in Meta. 2 means topmost function in Meta, 3 next object etc. WHERE: How to do WHERE (|) for the function. ( [QN1 ob1 ... QNN obN] [arg1...argM] --> expr) VUNS: Imploding symbolics and finding command alias for functions. NEEDQN? (Meta #n --> UNSYM element builds symbolic from Meta: (Builds arguments to symbolics if necessary) ([expr...expr' arg1..argN] --> [expr..expr' arg1'..argN']) Expressions must not be touched. QN element tests if a given argument should be quoted: Fixed args: (#n --> flag) Inf args: (#n #total --> flag) UNAKA element splits algebraic for user level OBJ-> when rpn version of function takes different arguments than alg version. ( [arg1...argN] alg_ob --> [ob1..obN] rpl_ob) Internal VUNS values for SX: 5A211 VUNSDER { UNSYMDER QN1= UNAKADER } 5A22A VUNSINTG { UNSYMINTG QN4= UNAKAINTG } 5A243 VUNSSUM { UNSYMSUM QN1= } 5A257 VUNSWHERE { UNSYMWHERE QNEVEN UNAKAWHERE } 5A270 VUNSIFTE { UNSYMIFTE QNDRPFALSE } 5A284 VUNSQUOTE { UNSYMQUOTE QNDRPFALSE } 5A298 VUNSAPPLY { UNSYMAPPLY QNDRP1= UNAKAAPPLY } 5A2B1 VUNSUNIT { UNSYMUNIT QNDRPFALSE } 5A2C5 VUNSXROOT { NOP DROPFALSE UNAKAXROOT }