MCODE: Where these last posts are heading: A function called "NSG"


Here is what I want to do - to do is to create a function in the ICEBOX 1H that does this:

NSG (NoV Save/Get) is a prompting function allowing only 100-103 and 200-203 as input.

1. It first saves the input.
2. It then calls SAVEN (ICEBOX function to save Main Memory to file "N" in
HEPAX RAM of the current RAM block).
3. It then switches ram block to the one specified by the users input (from
the prompt)
4. It then restores Main Memory from another file named "N" in the new block.

It is simply a function that does a whole swich of bank and memory.

Problem is that when I calls the HSAVEA (from SAVEN), it kills the whole
return stack and never gets back to do tasks 3 and 4.

Any idea on how to solve this?


I am not sure I follow fully, but if it does not get back to you, maybe it does not end with a RTN?

Before running an instruction, 00F0 is pushed on the stack. This is the return address for main loop NFRPU. If the instruction uses up all the stack, it will blow the return address and cannot end with a RTN, instead it may jump to 00F0 directly.

Is this what is happening?

Maybe it is doing something else at exit as changing the whole memory is a quite dramatic behavior and it may feel some further cautious actions are needed before giving back control.

If it does not return using the stack, then it is not easy. Maybe you can plant something to indicate that you need to do step 3-4 in some safe RAM (IO buffer, Extended Memory, SS0 or even the HEPAX ram), then pick it up using code in a poll vector.


Obvious tricks are placing code in the same QUAD so the port-independent calls can use reduced stack levels. Or better yet, use GOTO ADR's instead.

Beyond that (which of course it's not always possible) you may have to modify SAVEN to store the stack addresses upon initialization and to restore it when it ends - so that they are preserved - and force a return instead of ending via NFRU.

Hope this prompts some ideas...

Edited: 5 Jan 2010, 3:11 a.m.


Excellent response. I feel fortunate to have access to people like you for my hobby.

It seems that HSAVEA eats up the whole return stack and leaves the calc in 00F0 "manually".

I have therefore opted to cut down on the functionality here and have the function do:

1. Prompt for input (100-103, 200-203)
2. Write the inputted number to address 4100 (switch the NoV block)
3. Restore Main Memory for that block by calling HGETA with the file name "N"

Thanks for the knowledge. ICEBOX v. 1H due out within 24 hours.


Now there is another little tricky thingy;

The function writes the input NoV bank config (100-103, 200-203) to address 4100 and then goes straight on to do a HGETA to restore Main Memory from a file named "N" - supposedly then from the new block... But here's the catch, it reads the "N"-file from the block previous to writing the new config into 4100. It seems the NoV-64 didn't get around to actually do the block switch before the HGETA asked for the "N"-file to read it and restore the memory, hence it takes the wrong "N"-file.

I should perhaps interject a pause before the function goes ahead and does the HGETA? But - I tried to interject a call to the mainframe function PSE, but that did not change anything...

Any ideas?

Edited: 7 Jan 2010, 12:50 p.m.


Hi Geir, and very happy new year!

Seem like this one is on my side of the fence... :-)

Originally, the control word at H'4100 was designed to behave in two different ways, depending on whether it swaps RAM or ROM blocks.

RAM Blocks are switched "on the fly" during Phi1 pluse #32 of the cycle inmediately *following* the WROM (H'040) instruction.

ROM Blocks are switched after power cyclig the HP-41. This is intentional, as a way to avoid situations in which the iddle ROM block can be loaded with image(s) in address(es) that may conflict with phisical ROM(s)

E.g. you have your card reader in place and have a configuration into ROM block 1 that (consequently) leaves page #E free. However, you may have page #E loaded with any other ROM image into ROM block 2. If you're allowed to swap ROM blocks on the fly your calc will crash...

I may take a more detailed look if needed but, a first glance, it looks like if you need to swap ROM's if won't work within a program. On the other hand if the requirements for HGETA are only RAM swapping then I think that a simple NOP (H'000) after the WRT (H'040) should be enough.

Hope this helps.

Best wishes from the Canary Islands.



... On the other hand if the requirements for HGETA are only RAM swapping then I think that a simple NOP (H'000) after the WRT (H'040) should be enough.

It didn't help. Here is a clarification of what happens:

0. Address 4100 contains 100
2. I enter "102" at the prompt
3. The NSG function then writes 102 to address 4100,
does the NOP and jumps to the program GETN
which simply writes "N" to the Alpha register and
calls HGETA to restore memory from the file named "N".
4. One would suspect that HGETA gets the file "N"
from Block #2 (h102), but it instead reads the file
from Block #0 (h100).

But, if I do this manually, i.e. I do XEQ"N102" and then XEQ"GETN" (which would be the same as the function "NSG"), id oes behave correctly (reading the file "N" from the new, switched-to block.


Edited: 9 Jan 2010, 9:27 a.m.


Hi again,

Yep, I have to correct myself:

It is the RAM power control register (internal to the NoV-64) which is updated "on the fly". The RAM block swapping takes effect after the next "STAND BY"... This is why it works as expected when the operation is performed manually.

I'll check for a suitable solution to allow RAM swapping while keeping ROM conflict protection.

Will mail you back in a few days with a modified code to test.

Best wishes.


To any MCODE dude:

Any way to do a very short STANDBY inside an Mcode program?

PS: Diego; looking forward to updated code.


Hi Geir,

Well, it looks like if it wasn't that hard...

You've got mail. ;-)

Please let me (us) know if it works OK with ICEBOX 1H and NoV-64.

If it does I'll include it also in the NoV-32 code and place an upgrade notice in my page with the new code.



Alright; It WORKS.

And the ICEBOX 1H is just around the corner.

Thanks Diego!


Hi Geir,

Good to know I can contribute a bit to this new release of your ICEBOX project ;-))



PS: will mail you again with the updated file for the NoV-32.


In the ICEBOX v. 1H, the function mentioned here as "NSG" is named "NBS" (NoV Block Switch).

Possibly Related Threads...
Thread Author Replies Views Last Post
  HP50g: Writing a function that returns a function Chris de Castro 2 1,596 12-10-2013, 06:49 PM
Last Post: Han
  HP-41 MCODE: The Last Function - at last! Ángel Martin 0 792 11-08-2013, 05:11 AM
Last Post: Ángel Martin
  setting up subroutines that are called many times... Geoff Quickfall 4 1,448 10-18-2013, 03:41 AM
Last Post: Geoff Quickfall
  Little curiosity: why the fourth stack register is called "T"? Antlab 34 6,187 07-03-2013, 04:49 PM
Last Post: Walter B
  41-MCODE: Auto XEQ+ALPHA possible? Ángel Martin 5 1,512 05-29-2013, 06:15 AM
Last Post: Ángel Martin
  HP 41 Mcode related Questions Michael Fehlhammer 4 1,447 05-10-2013, 07:09 PM
Last Post: Michael Fehlhammer
  41-MCODE: Breaking the FAT barrier. Ángel Martin 0 742 09-03-2012, 06:31 AM
Last Post: Ángel Martin
  41-MCODE: Dr. Jekyll & Mr. Hyde Ángel Martin 9 2,475 07-09-2012, 09:41 AM
Last Post: Monte Dalrymple
  HP41C: Factorial (kind of) in MCODE Frido Bohn 7 1,947 05-26-2012, 09:18 AM
Last Post: Frido Bohn
  41-MCODE: SOLVE & INTEG - 4k ROM Ángel Martin 9 2,175 04-19-2012, 05:29 AM
Last Post: fhub

Forum Jump: