^ma 1 80 ^pl 0 ^ju ^sk0STORING KEY ASSIGNMENTS IN EM USING ZENROM ^sk1^coRequirements: HP41 + XF/M (or 41CX) ^co ZENROM ^co Synthetics ^ju^sk1One if the attractions of Extended Memory is that using it requires no external paraphernalia. With a card reader or tape/disk you need some form of storage media such as cards, cassettes or disks. Not so with EM; everything is in those little plug-in modules. This does pose one problem - that of limited storage space - but another disadvantage is that you simply cannot do as much with EM as you can with the other methods of storage. The card reader and HP-IL both allow storage of key assignments of CAT 2&3 functions/programs (assignments of CAT 1 programs are saved with them, even into EM) via functions like WSTS and WRTK. With EM normally this is not possible, since the inbuilt functions only allow text, programs and registers to be saved. Various programs have been written to rectify this; my contribution is described below. ^sk1SAVEK and GETK - the two new functions provided by my program - both behave like inbuilt HP-41 functions. Any program that attempts to add functions to the 41 should try and do this - have a look at 'Simulating HP-41 Native Functions' by Wlodek Mier-Jedrzejowicz in DATAFILE V3N3 and V3N4. My program leaves the stack unaffected by saving it into a data file in EM and then recovering it later. This is done with the two general purpose routines SAVES and GETS. These save the complete stack (including L) and SAVES does not itself alter the stack - by putting XEQ "SAVES" at the start of a routine and XEQ "GETS" at the end you can have your routine leave the stack unaffected. This program manages to be shorter than most of its ilk by cheating and using the non-normalising store and recall functions of the ZENROM. For an explanation of non-normalised numbers and their importance (together with the importance of preventing much of the data inside the 41 from being normalised) see the ZENROM manual or 'Extend your HP-41' by Wlodek. ^sk1PROGRAM DESCRIPTION ^sk1(1) SAVEK - SAVE Key assignments ^sk0First, the program counts the number of Key Assignment Registers (KARs) in memory. It does this by recalling each register in memory, starting at number 192 (0C0h) where the first KAR is always located. It then compares the leftmost byte of this register with 240 (F0h), since this byte in a KAR always holds this value. It repeats this process until it finds a register that is not a KAR (either empty, or a buffer or alarm) and then uses the address of this register to work out how many KARs it has counted. It then prompts for a file name and creates a data file long enough to hold all the KARs, plus three more registers. The first thing the program saves in this file is the file size, followed by the KARs. SAVEX can safely be used since it is non-normalising. After this is done, the program saves the two key assignment map registers ( and e) before restoring the stack and returning. ^sk1(2) GETK - GET Key assignments ^sk0After prompting for the name of the data file holding the assignments GETK goes to its start and retrieves the file length, extracting from this the number of KARs to be recovered. While doing this it executes CBE to clear all the old assignments, together with any buffers below the .END. in memory. It then restores the KARs in sequence before restoring the assignment map registers. Finally it restores the stack. The keyfile is left in EM so that it can be used again, e.g. as one of a number of assignment files. ^sk1(3) CBE - Clear Below the .END. ^sk0This works by altering register c to move the .END. down to register 0C0h. It then extracts the original position of the .END. from the initial value of c and uses the 41CX function CLRGX to clear all of memory up to this value. If you do not have a CX then a substitute program to emulate CLRGX is given in Wlodek's book. The original value of c is then restored. ^sk1(4) SAVES - SAVE Stack and GETS - GET Stack ^sk0SAVES creates a five-register data file to hold the stack, using synthetics to save X in part of ALPHA while doing so. GETS restores the stack (SIGN is used instead of STO L to save a value in L) and deletes the data file (thus avoiding a DUP FL error the next time SAVES is used). ^sk1PROGRAM USE ^coa) To save assignments ^co XEQ "SAVEK" see "FL NAME?" ^co ASN3, R/S saves keys in file called ASN3 ^co name ( 8 letters ^sk1^cob) To recover assignments ^co XEQ "GETK" see "FL NAME?" ^co ASN3, R/S assignments restored ^sk1OPERATING LIMITS ^sk1^ju(1) GETK clears everything below the .END. - old assignments, alarms, buffers, the lot. If you want to get around this, then you could try rewriting the program to save all the buffers in memory (it is harder to cope with previous assignments) by changing the program to save all registers above 0C0h between the first one with a leftmost byte value different from F0h, and the last register below the .END. If you use the Advantage ROM, then if you have a matrix in memory, do not worry about clearing the matrix buffer - this is automatically set up again the next time you use a matrix function (this allows you to remove the ADV pac without losing matrices held in memory, and to save matrices on tape or cards). ^sk1(2) If you have any assignments to program labels made when SAVEK is used, the assigment flags for those labels will be saved. If the program in question is subsequently deleted and the assignments are read back, the 41 sees that there seems to be something assigned to the key in question, but cannot find anything that will admit to being assigned to it. This assignment will show up as XROM 06,27. ^sk1(3) Interrupting GETK can be VERY painful, especially if you stop in the middle of the call to CBE, in which case you can completely foul up your 41's memory. However, for those interested in examining the programs more thoroughly, it should be safe to SST all of them (but use caution). ^sk1Byte Values:- ^sk0Line 02 of "CBE" is F7,0C,00,01,69,0C,00,00 ^sk0Line 08 is not synthetic ^sk1Simon Bradshaw (HPCC#398)