CNFLIB.DIR contains the source of a library which is made using parts of the startup and the config suppressor libraries. You will find the documentations for both below. Just d/l CNFLIB.DIR and excute SETUP... BEGIN_DOC startup_dm.doc Hi all. My HP48 often warmstarts (installed a new/changed lib, crash or ON-C). Every time I have to restart the permanent 5-level stack display, switch to the VAR menu and (after a memory lost) restore the flag settings. My first attemp creating an autostart to avoid this was a simple execution of the cfg program (see below) during a library configuration. Fine, my general settings (flags, last cmds) are restored every warmstart, but switching to the VAR menu during config-time makes no sense; the user interface (alias system outer loop - SOL) which handles menus isn't initialized ... It's neccessary for the cfg and especialy for stk5 (again, see below) that the SOL is allready initialized upon start. Maybe it's possible to set up an control-alarm from a library config routine, but the time needed to execute all library configs is very variable, and I don't know what happens if the alarm comes up during a library config without an installed SOL. While examining the warmstart code, I recognize that the initialization of the SOL is the last step in the procedure (starting at addr. #469Ah) and ... it's called via RAM -- means: the RAM cell FIRSTPROC (a supported entry !) contains the address of the SOL init routine which is jumped to (StartupProc - another supported entry !). With this information in mind I create the library below; a short CODE ob at the end of $CONFIG writes the address of StartUp into FIRSTPROC. StartUp sets up the control alarm (which will call cfg and dispatches to stk5 1s later), then dispatches to StartupProc (from the CODE ob at the end). To build this library you need to have RPL:2.1 (or higher), a reference table and <-LIB->:1.2 (or higher) installed. USRLIB WON'T WORK. More documentation can be found in the source listing below. Enjoy, 8-Detlef END_DOC BEGIN_RPL strup_dm.rpl %%HP: T(3); DIR @ SETUP ( --> ) @ Assumes, that RPL:2.1/2.2 and <-LIB->:1.2 are installed before d/l. @ Generates an untiteled library with the id 1112. You can switch @ to its menu with 1112 MENU. @ DON'T USE USRLIB TO BUILD THE LIB !!! SETUP \<< VARS 'TMP' DUP CRDIR EVAL "\010" 1 DISP \-> v \<< v SIZE 2 FOR x v x GET DUP 1 DISP DUP RCL \->RPL $\-> SWAP STO -1 STEP \>> { cfg stk5 } $visible STO 1112 $romid STO "Building Library" 1 DISP D\->LIB "Cleanup\010\010\010\010\010" 1 DISP UPDIR 'TMP' PGDIR \>> @ $CONFIG @ Of special interest is the CODE object at the end. It writes @ the address of StartUp into FIRSTPROC, so StartUp is called @ instead of StartupProc when all config codes are passed. @ You may change the whole code expect the CODE ob and its position. @ This $CONFIG does no autoattach ... it's not neccessary. @ DON'T EXECUTE THIS PROGRAM DIRECTLY !!! $CONFIG "($CONFIG) :: (Start your code here) FIFTYSIX TestSysFlag DUP IT (BEEP off) :: (Switch on) FIFTYSIX ClrSysFlag ; FIFTEEN # 190 TWENTYFOUR # 12C setbeep setbeep IT (BEEP was off) :: (Switch off) FIFTYSIX SetSysFlag ; FORTYONE TestSysFlag (24 hr) ?SKIP (Set def. contrast) (The following CODE ob in HP terms: CODE AD0EX D0=[5] #101 contr.reg. LC[2] #08 contr.val. DAT0=C B D0=A GOVLNG =Loop ENDCODE) CODE 1B 1321B10100318014C1308D465D2 (Insert your value ^^ here [reversed!], #03 <= x <= #13, HP def. #0B) (Finish your code here) (The following CODE ob in HP terms: CODE LC[5] #2F Offset DOCODE/StartUp A=A+C A rem.: A = Ob ptr LC[5] =FIRSTPROC CD0EX DAT0=A A D0=C GOVLNG =Loop ENDCODE) CODE 20 34F2000CA34E76071361401348D465D2 ;" @ cfg @ My personally configuration. Change it to your own. Note: the @ HXS flags are in reversed order. cfg "(cfg, \-> ) :: CK0 HOMEDIR (Go HOME) { %9600 %0 %1 %1 %1 %3 } ' ID IOPAR ?STO_HERE (Std IOPAR) %2 InitMenu% (Set VAR menu) PTR 5386E (Last cmd on) PTR 538CE (Last stack on) { HXS 10 0FF1481800308803 HXS 10 0000000000000000 } xSTOF (Std flags) ;" @ stk5 @ The famous permanent 5-level stack. I remove the CODE ob's, the @ lambda usage and add the exit feature via clearing flag -14. @ If you want to purge the lib, execute -14 CF first. stk5 "(stk5) :: CK0 FOURTEEN SetSysFlag BEGIN AtUserStack SysMenuCheck DA2aOK?NOTIT :: KEYINBUFFER? NOT PTR 38FB9 ORcase :: TOADISP PTR 38FB9 PTR 53A90 case PTR 39BF3 PTR 3958B PTR 39FD2 ERRSET :: PTR 39F6F #1+ DUP#0=csDROP ONESWAP ZERO_DO ISTOP-INDEX OVERDUP #3+ PTR 44197 :: :: DUP NOT?SEMI 3PICK #1<> ?SEMI PTR 39F56 NOT?SEMI OVER PTR 39E0F NOT?SEMI PTR 39FB0 ?SEMI DROPSWAPDROP OVERSWAP NULL{} SWAP3PICK ZERO_DO SWAPOVER PTR 39E78 INDEX@ #0=ITE PTR 39EB9 PTR 39F23 5UNROLL DUPNULLCOMP? IT PTR 39EE1 SWAPLOOP 2DROP DUPDUP #3+ UNROLL ZERO_DO ISTOP-INDEX #1+ROLL OVER ISTOP@ #- INDEX@ #+ #3+ DISPN LOOP RDROP DROPDUP FOUR #<> ?SEMI PTR 3957A ; ITE PTR 39DE2 #:>$ SWAP #2+ DISPN ONE ; SWAP#1+SWAP +LOOP DROP ; ERRTRAP PTR 39C61 SetDA2aValid ; PTR 394A5 ; DA1OK?NOTIT PTR 3959C DA2bOK?NOTIT DispEditLine DA3OK?NOTIT ?DispMenu ClrDAsOK PTR 4203C ERRSET DoKeyOb ERRTRAP PTR 38728 FOURTEEN TestSysFlag NOT_UNTIL ;" @ StartUp @ THIS COMMAND MUST BE HIDDEN AND IT MUST BE THE LAST VARIABLE IN @ THE DIRECTORY. Because of the method D->LIB buils a library this @ will guarantee that StartUp follows directly the config code. @ The offset needed for calculating the address which is stored @ into FIRSTPROC by the CODE ob in $CONFIG is hard coded. @ StartUp is called via FIRSTPROC from the warmstart routine. @ Again you may change the whole code (e.g. to a password gateway) @ except the CODE ob at the end and its position. But remember, @ the SOL isn't initialized yet. @ DON'T EXECUTE THIS PROGRAM DIRECTLY !!! StartUp "(StartUp) :: :: (Start own code here) DATE (Today) TOD % .0001 %HMS+ (Now + 1s) ' :: PTR E724 (Purge Alarm,%\->) ID cfg (call cfg) COLA ID stk5 (dispatch to stk5) ; THREE{}N PTR E54D (Install Alarm,{}\->%) DROP (Returned alm idx) (Finish own code here) ; ERRTRAP (In case of error..) :: ONE SetUserFlag (Signal error) ; DEPTH DUP#0=ITE DROP (Stack empty) :: (Junk on stk) NDROP (remove junk) TWO SetUserFlag (signal junk) ; (The following CODE ob in HP terms: CODE D0=[5] [=StartupProc]+5 GOVLNG =Loop ENDCODE) CODE E 1B395838D465D2 ;" END END_RPL BEGIN_DOC cfgsupr_dm.doc Hi all. A few days ago I got a library which conifg code crashes if no HP EQLIB is installed. If a config code errors during a warmstart, you have to hard reset the HP48 with the paperclip followed by 'NO'... I don't own a EQLIB, but I wanted to split the damned thing using <-LIB-> (a library must be installed for doing this). Unfortunately I never saw a copy of the config aborter listed in J.K.Horns library list (ID 14, IMHO the lib I needed), so I sat down and played a while with <-LIB->, <-RPL-> and libraries containing only the following config code: %%HP: T(3); ":: (The following CODE ob in HP terms: CODE GOSBVL =SAVPTR C=B A C[A] = R D0=C D0 = R D0=D0- 5 D0 = ->->caller A=DAT0 A A[A] = ->caller GOVLNG =PUSH#ALOOP ENDCODE) CODE 19 8FB9760D91341841428DC7530 DEPTH {}N DUP ' ID CfgStk PTR 2E9E6 (SysSTO) INCOMPDROP DROP ;" This lead to two interesting things: 1. During execution of a config code the stack contains a meta object made from library IDs (BINTS) of libraries pending for its config code execution. The meta ob looks like: #lowest_id ... #highest_id #no_of_ids 2. Each config code is called by the sys-RPL routine starting at address # 2216h: :: DUP ZERO_DO pullrev ( obn .. ob1 #n --> obn-1 .. ob1 #n-1 obn ) PTR 8143 ( #LibId --> conf_code TRUE | FALSE ) IT EVAL LOOP DROP ; Somewhere in the warmstart code the meta object of all existing library IDs is generated and #2216 is called; it pulls each ID and checks the associated library for a config code; if it's present, it's called. With this information in mind I made the library below, a config code suppressor. Its config code searches the home directory for the variable 'NoCfg', if it's nonexistent or don't contain a list (usally of real numbers) or a real number (which is internally converted to a list), no further action take place. If a library ID found in 'NoCfg' also appears in the meta object during config, it's removed from the meta object and the library is attached to the home directory. Finaly the code resets the LOOP parameters of the #2216 routine. I gave this library the lowest unused ID possible (4), so no config code of any moveable library have been executed when the lib 4 config code takes over control. Below you'll find the source directory of lib 4 (along with the binaries); to build it you need to have the <-RPL-> and <-LIB-> libraries beeing installed. Install/deinstall it like any other library. Where lib 4 is usefull for ? - if you get a new library, add its ID to the NoCfg variable to be shure it never gets control until you know what it do to your HP48. - if you have installed some noisy libraries (loud, long and ugly config codes), add the IDs to NoCfg. - if you want to take a look at a library containing a unfriendly config code (copy/shareware protection or buggy) add its ID to NoCfg. Eg. If you copy the W&W Dis-Assembler (ID 1432 (reserved !) into a R/W port, you loose all memory upon the next warmstart ! Just add 1432 to NoCfg. On the other side there're libraries that *MUST* run their config codes to work properly, e.g.: - the <-RPL-> library since version 3.0 - HP41 emulator. It messes with the low-level port configuration. If its libraries are simply attached, it may crash the HP48 when trying to use the emulator. - most config autostarts (eg. ID 1112) are useless if their config code is suppressed. - et c. (maybe somebody make a complete list ?) Enjoy, 8-Detlef END_DOC BEGIN_RPL cfgsupr_dm.rpl %%HP: T(3); DIR $ROMID # 4h @ As low as possible... $CONFIG ":: ' ID NoCfg Sys@ NOT?SEMI (NoCfg not in HOME dir) DUPTYPEREAL? IT ONE{}N (If %, embedd it in {}) DUPTYPELIST? NOTcaseDROP (If not {}, leave) SWAPDUP ( meta[LIDs] \-> #n1 .. #nn {} #n ) ZERO_DO ISTOP-INDEX ( \-> .. {} #n #x' ) #2+ DUP#1+ ROLL ( \-> .. {} #n #x #lid ) 4PICKOVER UNCOERCE ( \-> .. {} #n #x #lid {} %lid ) EQUALPOSCOMP ( \-> .. {} #n #x #lid #pos ) #0=ITE :: (LID not in {},) SWAP UNROLL (push it back) ; :: (LID in {},) TOSRRP DROP#1- (just attach it) ; LOOP SWAPDROP ZERO INDEXSTO (Reset config LOOP) DUP#1+ ISTOPSTO ;" END END_RPL