Post Reply 
HP-41 MCode Question
03-24-2019, 01:01 PM
Post: #1
HP-41 MCode Question
Some basic questions for the HP-41 MCode gurus here.

After a pause of 30 years, I am starting to relearn HP-41 MCode again.

About the interaction between register C and RAM register 0 of a selected RAM chip ...

Available instructions
Code:
DEC   BIN         OCT   HEX  HP          J/DA        ZenROM      NEWT        Description
----  ----------  ----  ---  ----------  ----------  ----------  ----------  -----------------------------------------
                                                                             Copy RAM register 0 (T) to C
0040  0000101000  0050  028  REGN=C 0    WRIT 0(T)   REG=C 0/T   REGN=C      Copy C to RAM register 0 (T)
----  ----------  ----  ---  ----------  ----------  ----------  ----------  -----------------------------------------
0752  1011110000  1360  2F0  DATA=C      WRITE DATA  WDATA       DATA=C      Copy C to selected register
0056  0000111000  0070  038  C=DATA      READ DATA   RDATA       C=DATA      Copy selected register to C
----  ----------  ----  ---  ----------  ----------  ----------  ----------  -----------------------------------------
Note: interestingly opcode 0x038 take the same place in the Class 0 Subclass E group (0000-1110-00) as the would have been C=REG 0/T instruction.

Extract from MCODE for Beginners from Ken Emery page 53
Code:
Sometimes we don't know exactly where in a RAM chip we will be, and we can't have the RAMSLCT pointer being moved on us. 
How do we read or write to the selected RAM register without moving the RAMSLCT pointer? We use the READ DATA and WRITE DATA instructions. 
These instructions read and write data between the C register and RAM without modifying the RAMSLCT pointer.

The READ DATA instruction is sometimes listed as READ 0 by some disassemblers. THIS IS INCORRECT! There is no such thing as a READ 0 instruction. 
This was a mistake made by some of the early pioneers in the MCODE field, working without factory documentation that appeared later.

Live trace (extract) from Genesis-41 doing a RDN function who's implementation is actually doing 3 roll up !!!
Code:
,29DA 1 14ED  04E  N C=0       ALL     ; C[13:0] = 00000000000000, CARRY = 0
,29DC 1 14EE  270  p RAMSLCT           ; RAM reg = 000
,29DE 1 14EF  038  8 C=REG     0(T)    ; RAM read (C=08000000000000) from reg = 000 (subclass E)
,29E0 1 14F0  0AE    A<>C      ALL     ; A[13:0] = 08000000000000, C[13:0] = 000000000F0000, CARRY = 0
,29E2 1 14F1  078  x C=REG     1(Z)    ; RAM read (C=07000000000000) from reg = 001 (subclass E)
,29E4 1 14F2  028  ( REG=C     0(T)    ; RAM write (C=07000000000000) to reg 000 (subclass A)
,29E6 1 14F3  0B8    C=REG     2(Y)    ; RAM read (C=06000000000000) from reg = 002 (subclass E)
,29E8 1 14F4  068  h REG=C     1(Z)    ; RAM write (C=06000000000000) to reg 001 (subclass A)
,29EA 1 14F5  0F8    C=REG     3(X)    ; RAM read (C=05000000000000) from reg = 003 (subclass E)
,29EC 1 14F6  0A8    REG=C     2(Y)    ; RAM write (C=05000000000000) to reg 002 (subclass A)
,29EE 1 14F7  0AE    A<>C      ALL     ; A[13:0] = 05000000000000, C[13:0] = 08000000000000, CARRY = 0
,29F0 1 14F8  0E8    REG=C     3(X)    ; RAM write (C=08000000000000) to reg 003 (subclass A)
From the above trace, we clearly see at line 29DE, dissambled as C=REG 0(T) instead of RDATA, loading C register with register 0 of the selected RAM chip 0.

Question 1: could you explain why RDATA is not the equivalent of the inexistant C=REG 0(T)

Question 2: what are the differences between WDATA and REG=C 0/T

Thanks

Sylvain
Find all posts by this user
Quote this message in a reply
03-24-2019, 03:19 PM
Post: #2
RE: HP-41 MCode Question
(03-24-2019 01:01 PM)Sylvain Cote Wrote:  Question 1: could you explain why RDATA is not the equivalent of the inexistant C=REG 0(T)
Question 2: what are the differences between WDATA and REG=C 0/T

1) Not sure there's a *reason* why, to me it's simply the way it is: there's no READ 0(T) instruction because its place is taken by READ DATA. This means that to read the T register you need to select the data address zero first.

2) Well, they are two different instructions: WRITE 0(T) writes the C contents into the T register (when Chip_00 is selected of course); whilst WRITE DATA writes it into whatever register is selected by a previous execution of RAMSLCT.

Perhaps this is not what you were expecting, but to me this is just a pragmatic reality...

Cheers,
ÁM

"To live or die by your own sword one must first learn to wield it aptly."
Find all posts by this user
Quote this message in a reply
03-24-2019, 07:33 PM
Post: #3
RE: HP-41 MCode Question
Thank you Ángel.

Next time I will do a test before asking questions, if I had done that I would had my answer right away.

Question 1 test
Code:
F000  001    XROM 1
F001  002    2 FUNCTIONS
F002  000    FCT:SCOTETST 1A
F003  08F    ADR: F08F
F004  000    FCT:TST
F005  093    ADR: F093
F006  000    NOP               
F007  000    NOP

TST body
Code:
F093  130  0 LDI       S&X              /// 
F094  1F0                               /// loading top main memory RAM chip register address offset 0
F095  270  p RAMSLCT                    /// selecting first RAM register of the top main memory RAM chip (1F0..1FF)
F096  038  8 RDATA                      /// read selected register (1F0) who currently is REG 00
F097  3F8    C=REG     F(e)             /// read last register (1FF) of selected RAM chip who currently is REG 15
F098  130  0 LDI       S&X              /// 
F099  1FF                               /// loading top main memory RAM chip register address offset 15
F09A  270  p RAMSLCT                    /// selecting last RAM register (1FF) of the top main memory RAM chip (1F0..1FF)
F09B  038  8 RDATA                      /// read selected register (1FF) who currently is REG 15
F09C  3B8    C=REG     E(d)             /// read one before last register of selected RAM chip (1FE) who currently is REG 14
F09D  130  0 LDI       S&X              /// 
F09E  010                               /// loading invalid register address
F09F  270  p RAMSLCT                    /// deselect RAM register
F0A0  3E0    RTN                        /// return

Setup before TST execution
Code:
SIZE 016
315 STO 15   /// located at RAM register 1FF
914 STO 14   /// located at RAM register 1FE
701 STO 01   /// located at RAM register 1F1
800 STO 00   /// located at RAM register 1F0

TST execution trace
Code:
F093  130  0 LDI       S&X     
F094  1F0                      ; C[S&X] = 1F0
F095  270  p RAMSLCT           ; RAM reg = 1F0
F096  038  8 RDATA             ; RAM read (C=08000000000002) from reg = 1F0 (subclass E)
F097  3F8    C=REG     F(e)    ; RAM read (C=03150000000002) from reg = 1FF (subclass E)
F098  130  0 LDI       S&X     
F099  1FF                      ; C[S&X] = 1FF
F09A  270  p RAMSLCT           ; RAM reg = 1FF
F09B  038  8 RDATA             ; RAM read (C=03150000000002) from reg = 1FF (subclass E)
F09C  3B8    C=REG     E(d)    ; RAM read (C=09140000000002) from reg = 1FE (subclass E)
F09D  130  0 LDI       S&X     
F09E  010                      ; C[S&X] = 010
F09F  270  p RAMSLCT           ; RAM reg = 010
F0A0  3E0    RTN               ; next PC = 00F0

Lesson learned from the above example:
1) RDATA always read current selected register (as you said)
2) RDATA has the same behavior of the non existent C=REG 0 if first register of a RAM chip is selected
3) C=REG 1 to 15 always return offset data from the current RAM chip selected

I still find it special (asymmetrical?) to create a WDATA and 16 x REG=C instructions and not do the same for the RDATA and C=REG counterpart.
It's not like they did not had free instruction slots to do it ...

Thanks again for the information Ángel.

Best regards,

Sylvain
Find all posts by this user
Quote this message in a reply
03-25-2019, 06:01 AM
Post: #4
RE: HP-41 MCode Question
(03-24-2019 07:33 PM)Sylvain Cote Wrote:  I still find it special (asymmetrical?) to create a WDATA and 16 x REG=C instructions and not do the same for the RDATA and C=REG counterpart.
It's not like they did not had free instruction slots to do it ...

That's true, I suppose that's what tripped up the MCODE pioneers... until they realized the scheme. I have no idea why HP chose that arrangement, moot point or curiosity these days...

Good luck with your MCODE refreshing!

ÁM.

"To live or die by your own sword one must first learn to wield it aptly."
Find all posts by this user
Quote this message in a reply
03-25-2019, 08:29 PM
Post: #5
RE: HP-41 MCode Question
I have a far fetched theory. HP saved some transistors in their RAM chips and as this it the T register, it written to more often than it is read. Reading is done when dropping and rotating the stack. The cost in ROM for this is max 4 instructions.

ENTER or numeric input lifts the stack, which means it writes a lot more to T more than it is read, so the being able to write to it is more important than reading it. The C=0, RAMSLCT (DADD=C) selects T and chip 0, so it may also become selected for free, which may be taken advantage of, depending on the firmware.

Anyone who spots old HP engineers at the conferences can try to ask if anyone knows the real answer.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 3 Guest(s)