The Museum of HP Calculators

HP Forum Archive 19

[ Return to Index | Top of Index ]

HP41 Virtual Memory - Terabytes?
Message #1 Posted by Raymund Heuvel on 13 Mar 2009, 9:56 p.m.

Virtual memory architectures are based on swapping "external memory" into actual address  space.
(I am not an expert on this so don't kill the amateur - a building engineer ...)

Owning just a HP41 and a HP71B, both with IL it seems not so easy but ...

Considering synthetic programming: Bringing the instruction pointer in the alpha registers (M,N,O,P) and executing an INA on the HP41 and OUTPUT :LOOP;X$ on the HP71 where X$ holds the program for the HP41 would modify the HP41 program on the fly.

I wrote a few small programs (not optimized, just to see if it is possible) and yes it works, but only in SST mode on the HP41. In RUN mode it simply won't work.. any hint from the synthetic specialists?

Here some experimental listings, goal of the miniproject: "Hello World" AVIEW. Big leap target ... a WALL function ??

HP41 Listing:

01LBL "V" Just the label 02 STOPIO seems to clear all IO (IFC HP-IL msg) 03 1 Assumung the HP-71 is #1 (Could also be anything else sending bytes 04 SELECT 05 SF 25 See HP71B listing ... 06 XEQ 01 To bring the program from Alpha regs back via return 07 RTN or STOP, GOTO 'END' or anything else 08 GTO 02 09LBL 01 10 RCL b 11 "` " 96 7 0 0 0 0 0 Instruction pointer => Byte 6 of reg 7 (M) 12 X<> [ X<>M 13 "AAAAA" append just 5 'A' (or anything else) 14 STO [ STO M 15 "AA" append just 2 'A' (or anything else) 16 RCL \ RCL N 17 " |" 167 29 145 124 The instruction code for REG M ... see below 167 29 => XROM 28,29 -> HP41-IL INA function 145 124 => STO b 19 STOP For convenience SST usage (see below) 18 STO b and jump into M (see line 12, falls through '0' bytes' 19 END

The HP71B program:

10 CONTROL OFF 20 M$=CHR$(167)&CHR$(29)&CHR$(173)&CHR$(25)&CHR$(133)&CHR$(178)&CHR$(130) 40 O$=CHR$(240+11)&"HELLO " 50 N$=CHR$(206)&CHR$(119)&CHR$(113)&CHR$(0)&CHR$(0)&CHR$(0)&CHR$(0) 60 C$=O$&N$&M$ 70 OUTPUT :LOOP ;C$ 140 O$="WORLD"&CHR$(126)&CHR$(133) 150 N$=CHR$(206)&CHR$(119)&CHR$(206)&CHR$(113)&CHR$(0)&CHR$(178)&CHR$(4) 160 C$=O$&N$&M$ 170 OUTPUT :LOOP ;C$

Comments per line: 10 Just to cooperate with the HP41 20 M$ (REG M) holds code equivalent to HP41: INA 167 29 FC? 25 173 25 RTN 133 GTO 01 178 130 => a COMPILED GTO thus a jump to start of register N (needs no label, restriction: do not PACK or anything else that destroys the jump bytes 40 O$ (REG O) holds code equivalent to HP41: "Hello " 251 + "HELLO" xFB (length 11) as first part of the string 50 N$ (REG N) holds code equivalent to HP41: X<>O 206 119 And bring O (The "Hello ") to X<>Y the Y Register + 4 NOPS ('0' Bytes) => The Instruction pointer falls to M ... 60 Add the whole bunch for sending 65 Just to follow the 71 70 Send to the 41 140 O$ : "WORLD" The rest of the "Hello " String (NO APPEND !) AVIEW 126 Display it RTN 133 and a normal return (To HP41 V Program line 8) 150 N$ : X<>O 206 119 X<>Z 206 113 Put 'WORLD' in 'Z' NOP 0 => to make the compiled goto (next line) easier ... GTO 01 178 4 => a COMPILED Jump to REG Y, Byte 6 (Left Byte) 165 170 And send it to the HP41

What happens ... In abstract In 'V' the bootstrap instructions are loaded for the initial INA function in Line 18 This could be improved with M$ code as in HP71 but I was to lazy ..

In Detail: <IP> means instruction pointer, located at the byte to start with Void fields means a '0'(Zero) Byte (<IP> falls through these as NOP)

<IP> falls through ... <IP> |Byte| 6 | 5 | 4 | 3 | 2 | 1 | 0 | --------------------------------------------------------------------- | M | | | | INA | STO b | ---------------------------------------------------------------------

The first INA results in:

|Byte| 6 | 5 | 4 | 3 | 2 | 1 | 0 | --------------------------------------------------------------------- | O |251 (FB)| 'H" | 'E' | 'L' | 'L' | 'O' | ' ' | ---------------------------------------------------------------------

--------------------------------------------------------------------- | N | X<>O | X<>Y | | | | | --------------------------------------------------------------------- <IP> --------------------------------------------------------------------- | M | INA | FC? 25 | RTN | GTO 01 (R:N,B6)| ---------------------------------------------------------------------

So a jump to N follows to the cuntional code, putting FB+Hello in Y and falls in M with the next INA resulting in ...

|Byte| 6 | 5 | 4 | 3 | 2 | 1 | 0 | --------------------------------------------------------------------- | O | 'W" | 'O' | 'R' | 'L' | 'D' | AVIEW | RTN | ---------------------------------------------------------------------

--------------------------------------------------------------------- | N | X<>O | X<>Z | |GTO 01 (R:Y,B:6) | --------------------------------------------------------------------- <IP> --------------------------------------------------------------------- | M | INA | FC? 25 | RTN | GTO 01 (R:N,B6)| ---------------------------------------------------------------------

So assuming INA works fine, code jumps to N and then to Y:Byte 6 where it finds

<IP> |Byte| 6 | 5 | 4 | 3 | 2 | 1 | 0 | --------------------------------------------------------------------- | Y |251 (FB)| 'H" | 'E' | 'L' | 'L' | 'O' | ' ' | --------------------------------------------------------------------- | Z | 'W" | 'O' | 'R' | 'L' | 'D' | AVIEW | RTN | ---------------------------------------------------------------------

Loading "Hello World" in the ALPHA regs (therefore this code is in Y,Z), doing an AVIEW and return to "V" line 08 (subsequent the XEQ 01 => We preserved the return value in REG b).

Start as follows: Run the HP71 Program (Output statements are buffered) Run the HP41 Program, perform the extra R/S to continue after the STOP in 18 => Rubbish in Display

AND NOW ... This works when in SST mode on the HP41 (SST from line 18 onwards or from line 1 ...) => A nice "HELLO WORLD" is Aviewed ... Step until you encounter RTN to return to the "V" program!! Otherwise your program pointer remains in the status register.

Its a pain in the brain but I can't find the bug... Somebody has an idea?? It could open therabytes of virtual memory for the HP41 of this works

Something like this as boot-trap loading some bigger program doing bigger things doing ....

When it workes, Yes Yes I will, I'll make it an article ....

Best regards

Raymund

      
Re: HP41 Virtual Memory - Terabytes?
Message #2 Posted by Howard Owen on 13 Mar 2009, 10:37 p.m.,
in response to message #1 by Raymund Heuvel

This is wicked cool...

But the HP71 can't handle terabytes, so it would have to be talking to a PC using a HP 82973A. But a PC with an ISA slot probably can't handle terabytes either, so it in turn would have to be using a decent 64-bit server (running Linux, for speed) in order to manage the multi-gigabyte chess program someone will undoubtedly write once this capability is available.

Don't you love this hobby? :)

Regards,
Howard

            
Re: HP41 Virtual Memory - Terabytes?
Message #3 Posted by Raymund Heuvel on 13 Mar 2009, 11:00 p.m.,
in response to message #2 by Howard Owen

I got the same results with a HP82164A (RS232) with my humble PC 
with 3TB disk. 
The disk cost are about 50% of the price I paid for my HP41CV in 
1980 so I'am looking forward to a "best value" upgrade for my 
beloved buddy.

Concerning application future: A standard HP41 in the Shuttle program => I assume NASA grabs the opportunity for Ares ...

BR

Raymund

      
Re: HP41 Virtual Memory - Terabytes?
Message #4 Posted by David Hayden on 13 Mar 2009, 11:37 p.m.,
in response to message #1 by Raymund Heuvel

Quote:
I wrote a few small programs (not optimized, just to see if it is possible) and yes it works, but only in SST mode on the HP41. In RUN mode it simply won't work.. any hint from the synthetic specialists?
Raymund,

I don't know anything about synthetic programming or details of the HP 41, but I know something about computer architectures. Modifying code is often tricky because the computer assumes just the opposite - that it won't be modified. This lets it do things like keep recently used instructions in cache, or soon-to-be-executed instructions in an internal pipeline.

The upshot is that if you modify the instruction stream, you have to flush the cache and the pipeline. I don't know if the HP41 has either of these things, but your symptom is pretty classic for the problem.

Good luck, and do keep up posted.

            
Re: HP41 Virtual Memory - Terabytes?
Message #5 Posted by Raymund Heuvel on 14 Mar 2009, 4:49 p.m.,
in response to message #4 by David Hayden

Maybe the MCode programmers can give a statement to this?

      
Re: HP41 Virtual Memory - Terabytes?
Message #6 Posted by PeterP on 15 Mar 2009, 5:09 p.m.,
in response to message #1 by Raymund Heuvel

Raymond,

Fabulous idea! No specialist here, but just a couple thoughts (don't have any HP with me currently but will try your set-up at home and share any further thoughts if I have any)

  1. I think register M is number 5 and not number 7 (T=0,Z=1,Y=2,X=3, L=4, M=5, N=6, O=7). As your line 17 clears all alpha it does not create a problem. Maybe one can use 48/5/00000 in your line 11 for byte 3 of reg 5
  2. very neat and clever separation of the first return address and program pointer and replacement with the wanted program pointer
  3. INA behaves differently depending on Flag 17 on the HP41. If that Flag is cleared, it expects/wait a CR/LF to end the transmission. If it is set, it just accepts the whole string until either alpha is full (24 chars) or the full string has been submitted. Maybe in SST mode the INA gets completed even without the CR sent, but not in Run mode. Have you tried running your experiment with Flag 17 set?
  4. Sorry for being slow, but can you explain the purpose of the Sto B after the INA that you place in Reg M? Doesn't INA wipe out Alpha and hence the StoB as well? As I said, I don't have any HP with me right now so I can't try it out myself, my apologies.
  5. In run-mode, I believe AVIEW has some extra features (e.g. print-out, halt of program depending on some printer flags etc). The other thing I am not sure currently is the treatment of the Alpha-register itself with AVIEW. In Run-Mode the calc normally shows the goose which it does not in SST mode, so I'm not sure if there is something here as well. Have you tried instead of Hello World to e.g. fill some registers with say Pi?
  6. I think there do exist WALL like functions that read/write the complete content of the calc (or subsections like EM, Status regs, user regs etc ) to an HP-IL mass-storage device. To read(write) the whole memory of an HP41 to(from) the HP71 one could simply use on the many available Non-normalized sto(recalls) for each register, rcl M(sto M) and INA(OUTA) but I guess it might take a while.
  7. If you want to use the 71 as a source of a loooong program for the 41, it might be tricky to write a meaningful program that can have no loops >20 bytes (the length of alpha)

Again, fascinating idea, do let us know how it goes!

Cheers

Peter

            
Re: HP41 Virtual Memory - Terabytes?
Message #7 Posted by Raymund Heuvel on 15 Mar 2009, 9:49 p.m.,
in response to message #6 by PeterP

Hi Peter
1)    Yes, you are correct. Legacy from previous experiments
3)    Yes, I did, no effect (same "rubbish")
4)    Legacy but it would bring IP back to main program where it does 
      the stop (if inserted) in case INA fails. Better would be to 
      use the M$ code of the HP71 in M (then 96/5/00000 in line 11 !)
5)    I did not try but soon I will -> Keep you informed
6/7)  My fantasy goes more in the direction of a small loader that 
      loads (or writes) a number of registers, moves the curtain 
      (or vice-versa) and then finalizes the whole thing by 
      a "GTO ..". Then a WALL or READP, WRITEP look-a-likes could 
      be possible. 
      Yes the mass storage functions have these functions and I 
      have a tape, but also a RS232. The latter would open my 
      Terabytes disks for my HP41 environment in a total different 
      way.
      e.g.: run a default bootloader on the HP41 (An extended 
      version of the actual "V") and then the PC can step by step 
      put the HP41 into a desired state.
      Why should we do this: because we can (I hope ..)

Some actual observations: It looks as if the ALPHA register does not receive (all) data from the second INA / Output sequence. I have the feeling that maybe the INA uses some scratch in P. I'll create a programm that moves the INA into e.g. L (or ...) but not one of the ALPHA regs and do a CLA before the INA.

But this next week. Some busy times ...

Thanks for your remarks and help, to be continued

Raymund

                  
Re: HP41 Virtual Memory - Terabytes?
Message #8 Posted by PeterP on 16 Mar 2009, 10:16 p.m.,
in response to message #7 by Raymund Heuvel

Raymond,

Thanks for the feedback. Seems that F17 did not help but based on your suspicion that the second INA does not receive all I feel more certain that one of two things are happening.

  1. Either the 41 keeps on waiting for the string to finish but does not so in SST mode
  2. Or the two INA's write consecutively into the Alpha reg. It then gets too full and hence the calc does not receive the full amount.

However, if a WALL with a loader-program is your desire, I'm not sure that this way is the easiest possible to achieve this (aside from the pure intellectual pleasure to have programs run in Alpha. In the heydays(?) of the 41, Valentin Albillo developped a whole series of articles which where based on obfuscating programs by running it in Alpha only. The program basically was a series of synthetic alpha strings with a STO b to start the whole program...)

What about the following pseudo HP-41 program to receive the data from the 71:

Lbl 'GetPGM'
'move curtain so that desired program location starts at STO 00
'place number of registers to read from 71 into L
CLA
CLST
LBL 01
  INA 'read in three registers worth to minimize HP-IL overhead
  CLX
  RCL M
  NNSTO IND Y (there are a number of non-normalized STO available   
               they have slightly different syntax)
  ISG Y 
  NOP
  CLX
  RCL N 
  NNSTO IND Y (there are a number of non-normalized STO available   
               they have slightly different syntax)
  ISG Y 
  NOP
  CLX
  RCL O
  NNSTO IND Y (there are a number of non-normalized STO available   
               they have slightly different syntax)
  ISG Y 
  NOP
  CLX
DSE L
GTO 01
'move curtain to previous position and hence making the stored bytes available. 

This is a basic principle that was used for various tricks IIRC.

One thought though: I'm not sure how INA works with non-display characters and if it can be always trusted. Also, I'm not sure if it does not add a '01' in front of each register M/N/O for each set of 6 strings. This would have to be tested. However, even if that fails, one could do a series of

INA (read in 14 characters representing 7 bytes in hex)
CODE (and one of the many available versions can work) 
NNSTO IND Y

It would be twice as slow but would definitely work.

Still hope you can figure out what is going on with INA etc, its simply a very cool idea even though I think there might be better ways to achieve what you are aiming for.

HTH

Cheers

Peter

Edited: 16 Mar 2009, 10:19 p.m.

                        
Re: HP41 Virtual Memory - Terabytes?
Message #9 Posted by Raymund Heuvel on 17 Mar 2009, 10:54 p.m.,
in response to message #8 by PeterP

Hi Peter & all

Moving the INA part of the code to L and performing CLA before INA helps.

I learned that compiled 2 byte GTO's do not work in Status Regs. Compiled 3 Byte GTO's do!

My first "Hello World" is there, keep you posted after cleaning up the code and having time for proper documentation.

BR

Ray


[ Return to Index | Top of Index ]

Go back to the main exhibit hall