v1.2 NOTE: If you have any questions, comments, error reports or any additional info on the subject, drop me an e-mail at Ludvik.Krulik@snet.fer.un-lj.si 1. Overview Library 179 (103 XLIBs) contains most of the code and data for internal browser. Browser is used by Memory Application, Alarms Browser, Flag Browser, UserRPL CHOOSE command and others. Contents: 1. Overview 2. Using browser 2.1 Executing browser 2.2 Stack structure 2.3 Stack structure elements 3. Example 1 4. Some Library 179 XLIBs 5. Some useful ROMPTRs 6. NULLLAMs used by browser 7. Implementation of some other functions 8. Browser POL 8.1 Example 2 2. Using browser 2.1 Executing browser You start browser by executing ROMPTR 0B3 000. 2.2 Stack structure Stack structure for ROMPTR 0B3 000 is: ( ::Appl $InitTitle ::Converter {}Items InitOffset --> --> {}Checked TRUE ) or ( ::Appl $InitTitle ::Converter {}Items InitOffset --> FALSE ) if check marks are enabled and ( ::Appl $InitTitle ::Converter {}Items InitOffset --> ob TRUE ) or ( ::Appl $InitTitle ::Converter {}Items InitOffset --> FALSE ) if check marks are disabled. 2.3 Stack structure elements * ::Appl represents secondary that is responsible for most of the work. It is evaluated by browser in order to define data needed by the browser. The stack structure is: - ( #ReqNum --> ...data... TRUE ) if required date is supplied or - ( #ReqNum --> FALSE ) if required data is not supplied. (browser will use default instead) Most #ReqNum (in decimal): - 57 == #PageSize Number of lines browser will display on screen. Should be 5 for full screen and 4 for windowed browser. But you are free to use any number. ( --> # ) - 58 == #Height Height of browser line. ( --> # ) - 59 == #Width Width of browser line. Leave space for display of arrows if number of elements is greater then page size. ( --> # ) - 60 == FullScreen? Full screen or windowed? ( --> flag ) - 61 == CheckMarks? Use check marks? ( --> flag ) - 62 == #NumOfElems Number of elements in a list. ( --> # ) - 63 == ::CoordinatesProv Returns coordinates of upper left corner of browser in HARDBUFF. ( --> #x #y ) - 64 == #OffsetInPage Initial difference between marked selection and top of page. ! Note: Difference must be less then current selection and less than page size. Otherwise, HP48 will crash. ( --> # ) - 65 == ::BackGrnd Background drawing secondary. Example of use: let browser use only 4 lines in full screen mode and use the last line as a status line. ( --> ) - 66 == ::TitleDiplayer Should display title in HARDBUFF. ( --> ) - 67 Returns title as GROB. ( --> GROB ) - 68 If 67 not defined, returns title as GROB for full screen only. ( --> GROB ) - 69 If 67 not defined, returns title as GROB for windowed only. ( --> GROB ) - 70 == Title ( --> $ ) ! Note: If $InitTitle is NULL$, this data will be ignored and no title will be displayed. Otherwise it will override $InitTitle. - 74 Displays all visible lines of browser. ( --> ) - 79 Displays one line in HARDBUFF, also inverse it if it's current selection. ( # --> ) - 80 == ::ElemProv Element provider. Object ob is later converted to string by evaluating ::Converter. ( # --> ob ) - 81 == ::ConvIntoLineGrob Converts element into GROB with dimensions 7NULLLAM x 8NULLLAM that fits into browser line. ( # --> 7NULLLAMx8NULLLAM_GROB) ! Note: This function enables Alarm and Flag browsers to use two different fonts in the same line. ! Note: If implemented and check marks are enabled, it must incorporate check mark into GROB if item is checked. - 82 == ::ElemProvStr Provides elements as strings. (no need to use ::Converter) ( # --> $ ) - 83 == {}Menus Declaration of menus. (standard) - 84 Called upon entry to initialize 4NULLLAM and 5NULLLAM. Upon exit, browser restores original display using this two NULLLAMs. ( --> ) - 85 == ::EntryProc Called upon entry, after all NULLLAMs etc. have been set. ( --> ) - 86 == ::CheckItemProc Should refresh 15NULLLAM. ( # --> ) - 87 == ::ExitProc Called upon exit. ( --> ) - 91 == ::CancelAction Called after pressing ON key or CANCL menu key. Returns TRUE to exit browser, FALSE to continue. ( --> flag ) - 96 == ::ENTERAction Called after pressing ENTER or OK menu key. Returns TRUE to exit browser, FALSE to continue. ( --> flag ) ! Note: Instead of complex ::Appl you can use 'DROPFALSE. Default values will be used. You can supply items through {}Items plus ::Converter. This is the way UserRPL command CHOOSE does it. Here's simplified UserRPL CHOOSE example: :: 'DROPFALSE ( no ::Appl ) "TEST" ( $InitTitle ) ' ROMPTR 0B3 64 ( standard ::Converter, can handle a lot ) { { "ONE" %1 } { "TWO" %2 } { "THREE" %3 } } ( {}Items ) TWO ( InitOffset ) ROMPTR 0B3 000 ( runs browser ) NOTcase ( exited through: ) FALSE ( - Cancel, signal false ) DUPTYPELIST? ( - OK/ENTER, is selected element a list?... ) IT ROMPTR 0B0 099 ( ...Yes, extract second element ) TRUE ( signal true ) ; * $InitTitle represents initial title. It can be overridden through #ReqNum 70 if $InitTitle isn't equal to NULL$. * ::Converter represents secondary for converting elements of whatever type you use into strings that browser can display. Stack structure for ::Converter is ( ob --> $ ). * {}Items = Items list. Memory, Flag, Alarm browsers put an empty list here. CHOOSE puts list of choose items here. {}Items can be overridden by ::ElemProv or ::ElemProvStr. * InitOffset represents initial offset into list. Type of InitOffset can be: - Binary integer: * if it equals zero, no selection is displayed, (browser works as a viewer) * otherwise it's initial offset. - List: If check marks are enabled, format is: { #InitOffset #checkedIndex1 ... #checkedIndexN } ! Note: In the above text I was referring to a 'list' of elements that you browse through. In reality, it can be anything that has finite number of elements and can be handled by ::ElemProv (Element Provider) and ::Converter (Element Converter) or ::ElemProvStr (Element Provider as Strings) alone. ! Note: Browser doesn't check index, so it must be less then or equal to the number of elements if you modify it yourself. ! Note: If you enter alpha shifted key, browser searches through element strings (runs ::ElemProv and ::Converter) to find a match between key (character) and first character in string. If you choose not to implement ::Converter and enter alpha-shifted key, HP will crash. ! Note: By default, you can exit browser through Cancel and ENTER keys. Exiting through cancel returns FALSE. Exiting through ENTER returns: - list of checked elements and TRUE flag, if check marks were enabled and some elements were checked, - list containing current element and TRUE flag, if check marks were enabled but none of the elements were checked, - current element and TRUE flag, if check marks were not enabled. This can be changed by defining exit procedures. ! Note: You can also exit browser through ROMPTR call. See below. ! Note: You do not have to worry about refreshing the screen - browser does that automatically after every valid menu key. However, you can control the refresh of every area of browser display: - Background area == DA1 - Title area == DA2a - Lines + arrows == DA2b - Menu line == DA3 3. Example 1 Here's the source of EXAMPLE1.BIN ============================================================================ * * ! Note: Some of the supported constants (SIXTYFIVE, SIXTYSEVEN, * EIGHTYFIVE, EIGHTYSEVEN, NINETYSIX) have different names in * ENTRIES.A from HP Tools. Please change the source * accordingly. ASSEMBLE NIBASC /HPHP48-R/ RPL INCLUDE ROMPTRS.H :: { "1: SQUARE" "2: TRIANGLE" "3: CIRCLE" "4: LINE" "5: CURVE" "6: ARC" "7: ELLIPSIS" } "SHAPES" { LAM List LAM Title } BIND ' :: ( *** ::Appl *** ) { EIGHTY :: LAM List SWAP NTHCOMPDROP ; ( ::ElemProv ) SIXTYSEVEN :: LAM Title $>grob INVGROB ; ( Returns title as GROB ) SIXTYTWO :: LAM List LENCOMP ; ( #NumOfElems ) EIGHTYFIVE :: "Hi" ROMPTR 0B0 091 ; ( ::EntryProc ) EIGHTYSEVEN :: "Bye" ROMPTR 0B0 091 ; ( ::ExitProc ) SIXTY TRUE ( FullScreen? ) SIXTYONE FALSE ( CheckMarks? ) FIFTYSEVEN FIVE ( #PageSize ) FIFTYEIGHT SEVEN ( #Height ) FIFTYNINE SIXTY ( #Width ) NINETYSIX ( ::ENTERAction ) :: 18GETLAM BBGetN ROMPTR 0B0 091 SetDA123NoCh ( don't re-draw ) FALSE ( don't exit ) ; SIXTYTHREE :: TWENTY TEN ; ( ::CoordinatesProv ) SIXTYFIVE ( ::BackGrnd ) :: BlankDA12 90 10 "Static" $>GROB XYGROBDISP 90 20 "ENTER" $>GROB XYGROBDISP 90 30 "TO VIEW" $>grob XYGROBDISP ; EIGHTYONE ( ::ConvIntoLineGrob ) :: BBGetN ( get N-th element ) 7GETLAM 8GETLAM MAKEGROB ( make empty line grob ) SWAP $>grob SWAPDUP 3UNROLL ONEONE GROB! ; FIVETHREE ( {}Menus ) { { "OK" BBDone } ( Simulate Ok ) { "CANCEL" BBCancel } ( Simulate Cancel ) NullMenuKey { "NEW" :: { "1: YELLOW" "2: GREEN" "3: BLUE" "4: CYAN" "5: MAGENTA" "6: BLACK" "7: RED" "8: SILVER" "9: BROWN" } ' LAM List STO "COLORS" ' LAM Title STO ( *** RecalculateNewSize *** begin ) BBReReadNumOfElems BBReReadWidth 18GETLAM ( #index ) 12GETLAM ( #NumOfElems ) DUP#0=IT DROPONE #MIN ( shrink #index if #NumOfElems was reduced ) 18PUTLAM FALSE BBRecalcOff&Disp? ( *** RecalculateNewSize *** end ) ; } } } EQLookup case :: EVAL TRUE ; DROPFALSE ; * Note: EQLookup checks if two elements have the SAME ADDRESS. Therefore, * you cannot use non built-in integers. SPACE$ ( *** $InitTitle *** ) ( overridden by $InitTitle2 ) MINUSONE ( *** ::Converter ***, not used ) NULL{} ( *** {}Items *** ) FOUR ( *** InitOffset *** ) BBBrowse ( Start Browser ) ABND ; ============================================================================ 4. Some Library 179 XLIBs ( others are mostly used internally by browser) #00 == Browse start browser #05 - {}menus with "OK" ( --> {} ) #06 - {}menus with "CANCEL", "OK" ( --> {} ) #07 - {}menus with "CHK", "CANCEL", "OK" ( --> {} ) #15 - move selection to line & display ( # --> ) #19 == RecalcOff&Disp? recalculate offset in page and re-draw lines if flag TRUE ( flag --> ) #1A - simulate UpArrow ( --> ) #1C - simulate DownArrow ( --> ) #1E - simulate [LS]+[UpArrow] ( --> ) #1F - simulate [LS]+[DownArrow] ( --> ) #20 - simulate [RS]+[UpArrow] ( --> ) #21 - simulate [RS]+[DownArrow] ( --> ) #22 - run ::EntryProc ( --> ) #23 == ReReadPageSize re-read #PageSize ( 57 ) ( --> ) #24 == ReReadHeight re-read #Height of browser line ( 58 ) ( --> ) #25 == ReReadCoord re-read coordinates ( 63 ) ( --> ) #26 == ReReadWidth re-read #Width of browser line ( 59 ) ( --> ) #28 == RunENTERAction #29 == RunCancelAction #2A == ChkCurr (un)check current element ( --> ) #2B == ChkAll check all elements ( --> ) #2C == UnChkAll uncheck all elements ( --> ) #2D == Cancel simulate Cancel ( --> ) #2E == Done simulate OK ( --> ) #2F == ReDrawBackgr re-draw background ( --> ) #30 == ReDrawTitle re-draw title ( --> ) #31 - returns full title GROB ( --> GROB ) #33 - returns $InitTitle as GROB ( --> GROB ) #34 == GetTitle returns title ( --> $ ) #35 == ReDrawLines re-draw browser lines ( --> ) #36 == ReDrawLine re-draw one line ( # --> ) #37 - returns n-th element as GROB ( # --> GROB ) #38 - returns n-th element as string ( # --> $ ) #3A == RestEntryLCD - calls ::ExitProc and if not defined, restores entry screen ( --> ) ! Note: Do not call this from ::ExitProc or your HP will enter endless loop. See RestoreEntryLCD from ::ExitProc below. #3B - re-read CheckMarks? ( 61 ) ( --> ) #3C - re-read FullScreen? ( 60 ) ( --> ) #3D == ReReadMenus re-read {}Menus ( 83 ) ( --> ) #3E == ReReadNumOfElems re-read #NumOfElems ( 62 ) ( --> ) #3F == GetN get N-th element ( # --> ob ) #48 - NumOfElems > PageSize? ( --> flag ) #4B == IsChecked? ( # --> flag ) #50 - display up arrow? ( --> flag ) #51 - display down arrow? ( --> flag ) #52 - get up arrow as GROB ( --> GROB ) #53 - get down arrow as GROB ( --> GROB ) #54 - get SPACE as GROB ( --> GROB ) #56 - $InitTitle = NULL$? ( --> flag ) #59 == PgDown go down 1 page ( --> ) #5A == PgUp go up 1 page ( --> ) #5B == Empty? is browser empty? ( --> flag ) #5C ... #62 = various GROBs #63 - xCHOOSE w/o CK ( see UserRPL CHOOSE ) #64 - standard converter, used by xCHOOSE #65 - identical to #64 #66 - simplified CHOOSE, used by TIME, I/O, SOLVE and other choose boxes: ( $InitTitle {}Items --> ob TRUE ) or ( $InitTitle {}Items --> FALSE ) {}Items: { { $Item1 Ob1 } ... { $ItemN ObN } } 5. Some useful ROMPTRs ROMPTR 0B0 07E returns GROB 6x9, check mark. ROMPTR 0B0 080 returns GROB 6x9, inverse check mark. ROMPTR 0B0 084 returns GROB 6x9, black. ROMPTR 0B0 085 returns GROB 9x9, a warning sign. ROMPTR 0B0 086 returns GROB 21x8, CHK and checkmark. ROMPTR 0B0 087 returns GROB 131x7, background for title. 6. NULLLAMs used by browser * 1 = not used (used by CACHE) * 2 = POL Exit condition ( flag ) * 3 = initial display status { DA1IsStatFlag DA2bEditFlag DA1BadFlag DA2aBadFlag DA2bBadFlag DA3BadFlag } * 4 = entry menu ( GROB 131x8 ) * 5 = entry stack ( GROB 131x56 ) * 6 = offset in page ( # ) * 7 = height of browser line ( # ) * 8 = width of browser line ( # ) * 9 = x coordinate of left upper corner of browser in HARDBUFF ( # ) * 10 = y coordinate of left upper corner of browser in HARDBUFF ( # ) * 11 = page size ( # ) * 12 = number of elements ( # ) * 13 = menus ( {} ) * 14 = full screen? ( flag ) * 15 = list of indexes of checked items ( {} ) * 16 = check marks enabled? ( flag ) * 17 = do browser? (or viewer ) ( flag ) * 18 = current selection index ( # ) * 19 = {}Items ( {} ) * 20 = ::Converter ( :: ) * 21 = $InitTitle ( $ ) * 22 = ::Appl ( :: ) 7. Implementation of some other functions * GoToEnd: :: 12GETLAM 18PUTLAM FALSE ROMPTR 0B3 019 ( recalculate offset in page, no display ) ; * GoToBeginning: :: ONEONE 18PUTLAM 6PUTLAM ; * RecalculateNewSize (number of elements has changed): :: ROMPTR 0B3 03E ( ReReadNumOfElems ) ROMPTR 0B3 026 ( ReReadWidth ) 18GETLAM ( #index ) 12GETLAM ( #NumOfElems ) DUP#0=IT DROPONE #MIN ( shrink #index if #NumOfElems was reduced ) 18PUTLAM FALSE ROMPTR 0B3 019 ( RecalcOff&Disp?, no display ) ; * RestoreEntryLCD from ::ExitProc: :: 5GETLAM HARDBUFF 14GETLAM ITE ZEROZERO :: 10GETLAM #3- 9GETLAM ROMPTR 0B3 045 #3- ; GROB! 4GETLAM HARDBUFF2 ZEROZERO GROB! ; 8. Browser POL Browser runs as POL, but doesn't allow user to provide the hard key assignments. If you want you're own keys, you have to run modified browser. Here is disassembly of ROMPTR 0B3 000: :: POLSaveUI ERRSET :: DUP#0= ( InitOffset == #0?... ) ITE :: DROPONE TRUE ; ( ...yes, do viewer - no selection ) FALSE ( ...no, do browser - with selection ) MINUSONE THIRTEEN NDUPN DROP ROMPTR 0B3 057 ( GetDisplayStatus, 3NULLLAM format ) FALSE TWENTYONE ROMPTR 0B0 0DB ( CACHE 21 NULLLAMs ) ROMPTR 0B3 03B ( Get #ReqNum 61 into 16NULLLAM ) ROMPTR 0B3 03C ( Get #ReqNum 60 into 14NULLLAM ) ROMPTR 0B3 03D ( Get #ReqNum 83 into 13NULLLAM ) ROMPTR 0B3 03E ( Get #ReqNum 62 into 12NULLLAM ) ROMPTR 0B3 024 ( Get #ReqNum 58 into 7NULLLAM ) ROMPTR 0B3 023 ( Get #ReqNum 57 into 11NULLLAM ) ROMPTR 0B3 026 ( Get #ReqNum 59 into 8NULLLAM ) ROMPTR 0B3 025 ( Get #ReqNum 63 into 9NULLLAM/10NULLLAM ) ROMPTR 0B3 04A ( Initialize 15NULLLAM ) ROMPTR 0B3 027 ( Run #ReqNum 64 ) ROMPTR 0B3 039 ( Run #ReqNum 84 ) ROMPTR 0B3 022 ( Run ::EntryProc ) ' ROMPTR 0B3 001 ( AppDisplay ) ' ROMPTR 0B3 008 ( AppKeys, replace this ) TrueTrue ( NonAppKeyOK? + DoStdKeys? ) 13GETLAM ( AppMenu ) ONEFALSE ( #AppMenuRow + SuspendOK? ) ' 2GETLAM ( ExitCond ) ' ROMPTR 0B0 000 ( AppError ) POLSetUI ( Setup POL ) ClrDAsOK POLKeyUI ( Run POL ) ROMPTR 0B3 03A ( Restore entry screen ) ClrDAsOK 3GETLAM ( {}displayStatus ) ROMPTR 0B3 058 ( SetDisplayStatus ) ABND ; ERRTRAP POLResUI&Err POLRestoreUI ; 8.1 Example 2 Here's the source of EXAMPLE2.BIN, that utilizes modified ROMPTR #0B3 #000 ============================================================================ * * ! Note: Some of the supported constants (SIXTYFIVE, EIGHTYTWO) * have different names in ENTRIES.A from HP Tools. Please * change the source accordingly. * ASSEMBLE NIBASC /HPHP48-R/ RPL INCLUDE KEYDEFS.H INCLUDE ROMPTRS.H :: { "1: SQUARE" "2: TRIANGLE" "3: CIRCLE" "4: LINE" "5: CURVE" "6: ARC" "7: ELLIPSIS" } "SHAPES" { LAM List LAM Title } BIND ' :: ( *** ::Appl *** ) { EIGHTYTWO :: LAM List SWAP NTHCOMPDROP ; ( ::ElemProvStr ) SIXTYTWO :: LAM List LENCOMP ; ( #NumOfElems ) SEVENTY :: LAM Title ; ( Title ) SIXTY TRUE ( FullScreen? ) SIXTYONE TRUE ( CheckMarks? ) FIFTYSEVEN FIVE ( #PageSize ) FIFTYNINE SIXTY ( #Width ) SIXTYFIVE ( ::BackGrnd ) :: CLEARVDISP 100 10 "PRESS" $>GROB XYGROBDISP 100 20 "SIN" $>GROB XYGROBDISP ; FIVETHREE ( {}Menus ) { { "OK" BBDone } ( Simulate Ok ) { "CANCEL" BBCancel } ( Simulate Cancel ) { :: TakeOver ROMPTR 0B0 086 ; ( CHK menu key ) { BBChkCurr BBChkAll BBUnChkAll } } NullMenuKey { "NEW" :: { "1: YELLOW" "2: GREEN" "3: BLUE" "4: CYAN" "5: MAGENTA" "6: BLACK" "7: RED" "8: SILVER" "9: BROWN" } ' LAM List STO "COLORS" ' LAM Title STO ( *** RecalculateNewSize *** begin ) BBReReadNumOfElems BBReReadWidth 18GETLAM ( #index ) 12GETLAM ( #NumOfElems ) DUP#0=IT DROPONE #MIN ( shrink #index if #NumOfElems was reduced ) 18PUTLAM FALSE BBRecalcOff&Disp? ( *** RecalculateNewSize *** end ) ; } } } EQLookup case :: EVAL TRUE ; DROPFALSE ; * Note: EQLookup checks if two elements have the SAME ADDRESS. Therefore, * you cannot use non built-in integers. SPACE$ ( *** $InitTitle *** ) ( overridden by $InitTitle2 ) MINUSONE ( *** ::Converter ***, not used ) NULL{} ( *** {}Items *** ) FOUR ( *** InitOffset *** ) POLSaveUI ( -------------- ROMPTR 0B3 000 - begin ------ ) ERRSET :: DUP#0= ( InitOffset == 0?... ) ITE :: DROPONE TRUE ; ( ...yes, do viewer - no selection ) FALSE ( ...no, do browser - with selection ) MINUSONE THIRTEEN NDUPN DROP ROMPTR 0B3 057 ( GetDisplayStatus, 3NULLLAM format ) FALSE TWENTYONE ROMPTR 0B0 0DB ( CACHE 21 NULLLAMs ) ROMPTR 0B3 03B ( Get #ReqNum 61 into 16NULLLAM ) ROMPTR 0B3 03C ( Get #ReqNum 60 into 14NULLLAM ) ROMPTR 0B3 03D ( Get #ReqNum 83 into 13NULLLAM ) ROMPTR 0B3 03E ( Get #ReqNum 62 into 12NULLLAM ) ROMPTR 0B3 024 ( Get #ReqNum 58 into 7NULLLAM ) ROMPTR 0B3 023 ( Get #ReqNum 57 into 11NULLLAM ) ROMPTR 0B3 026 ( Get #ReqNum 59 into 8NULLLAM ) ROMPTR 0B3 025 ( Get #ReqNum 63 into 9NULLLAM/10NULLLAM ) ROMPTR 0B3 04A ( Initialize 15NULLLAM ) ROMPTR 0B3 027 ( Run #ReqNum 64 ) ROMPTR 0B3 039 ( Run #ReqNum 84 ) ROMPTR 0B3 022 ( Run ::EntryProc ) ' ROMPTR 0B3 001 ( AppDisplay ) ' :: ( AppKeys ) 2DUP :: ( -------------- user's AppKeys - begin -------- ) kpNoShift #=casedrop ( no-shift plane ) :: kcSin ?CaseKeyDef :: TakeOver "Hi from SIN" ROMPTR 0B0 091 ; DROPFALSE ; 2DROPFALSE ; ( -------------- user's AppKeys - end -------- ) case :: ROTROT2DROP TRUE ; ROMPTR 0B3 008 ( runs browser's original AppKeys ) ; TrueTrue ( NonAppKeyOK? + DoStdKeys? ) 13GETLAM ( AppMenu ) ONEFALSE ( #AppMenuRow + SuspendOK? ) ' 2GETLAM ( ExitCond ) ' ROMPTR 0B0 000 ( AppError ) POLSetUI ( Setup POL ) ClrDAsOK POLKeyUI ( Run POL ) ROMPTR 0B3 03A ( Restore entry screen ) ClrDAsOK 3GETLAM ( {}DisplayStatus ) ROMPTR 0B3 058 ( SetDisplayStatus ) ABND ; ERRTRAP POLResUI&Err POLRestoreUI ( -------------- ROMPTR 0B3 000 - end -------- ) ABND ; ============================================================================ Enjoy LK, II/1996