[comp.sys.handhelds] Machine code on the 28S

alonzo@microsoft.UUCP (Alonzo GARIEPY) (06/04/90)

In email, <Rick Grevelle> writes
| Hello Alonzo:
| 
| There are still many details about which I am confused. Can you tell me
| how to determine where to peek to view the code which is called by the 
| routine below? Even after studying your processor notes I'm unable to
| understand the instruction: 8Exxxx  CALL.4  PC+6+xxxx.
| 
| #44A4h:	#9A440
| 	#8E87A0         ????
| 	#147            move.a  @d1,c
| 	#137            swap.a   c,d1
| 	#141            move.a  a,@d1
| 	#135            move.a   c,d1
| 	#142            move.a  @d0,a
| 	#164            add.a    5,d0
| 	#808C           jump    @a
| 
| What did you mean when you said relative CALLS contain an offset from
| the next instruction?
| 
| And also, what did you mean when you said that these are expressed relative
| to the address of the call instruction itself (PC).
| 
| Would you explain what it means when you stated that offsets are
| in 2's complement form?
| 
| Lastly, how does the program counter enter in to: PC+6+xxxx? 
| 
| Thanks for any help you can give!
| 
| Rick

First, I have translated the listing to canonical form.  The answer to 
your primary question is evident from the listing: the called routine is
at #04f27.

	#044A4: #9A440		
	#044a9: #8E87A0 	call.4	#04f27 
	#044af: #00147  	move.a	@d1,c
	#044b2: #00137  	swap.a	c,d1
	#044b5: #00141  	move.a  a,@d1
	#044b8: #00135  	move.a	c,d1
	#044bb: #00142  	move.a	@d0,a
	#044be: #00164  	add.a	#5,d0
	#044c1: #00808C 	jump	@a

Now your other questions:

| What did you mean when you said relative CALLS contain an offset from
| the next instruction?

The jump instruction is described in the notes as
	6xxx	JUMP.3	PC+1+xxx

Take an example such as
	#00086:	#6634		jump.3	#004bd

In this case the PC is #00086, xxx is #436 (remember to reverse it) so the
destination is #86+1+#436 = #004bd.  The offset is relative to the second
nibble of the current instruction (i.e., PC + 1).

The call.4 instruction is described in the notes as
	8Exxxx	CALL.4	PC+6+xxxx

Take an example such as
	#03acd:	#8eea51		call.4 #05081

In this case the PC is #03acd, xxxx is #15ae (remember to reverse it) so the
destination is #03acd+6+#15ae = #05081.  The offset is relative to the first
nibble of the next instruction (for call.4 that means PC + 6).  In the Saturn 
CPU, all call offsets are relative to the first nibble of the next instruction.

| And also, what did you mean when you said that these are expressed relative
| to the address of the call instruction itself (PC).

For uniformity, I have written all address equations in terms of the current
PC.  Because the Saturn uses different base addresses to offset for jumps and
calls, I have specify correction factors such as +1, +2, and +6.  You can
see how these work from the above examples.

| Would you explain what it means when you stated that offsets are
| in 2's complement form?

That means that if the high bit is a 1, the offset is actually negative.
But there are at least three ways to write a negative number in binary.
The Saturn uses 2's complement form because the final address can be
calculated simply by sign extending the offset and adding it.  Sign extension
means taking the highest bit (1 or 0) and copying it all the way to the
left.

Take an example such as
	#00405: #6edf	jump.3	#003e4

Note that xxx is #fde.  In binary, that is 1111 1101 1110.  We can calculate
the final address (PC+1+xxx) by sign extending xxx and adding it to PC+1

	PC  0000 0000 0100 0000 0101 +	
	1   0000 0000 0000 0000 0001 +
	xxx 1111 1111 1111 1101 1110 =
	    ========================
   PC+1+xxx 0000 0000 0011 1110 0100  (extra carry is discarded)	

Note that both postive and negative numbers are said to be in 2's complement
form in this system and both are sign extended before the addition, but the
sign bit for postive numbers is 0 and it has no real effect.  For simpler,
manual subtraction, a 2's complement number can be negated by sign extending,
inverting all its bits and adding 1.

(1)	#fde
(2)	#fffde		(sign extend)
(3)	#00021		(invert)
(4)	#00022		(add 1)

So the offset is really #-22.  The destination, expressed relative to the
PC is PC+1-#22 or PC-#21
	#00405: #6edf	jump.3	PC-#21 (#003e4)

| Lastly, how does the program counter enter in to: PC+6+xxxx? 

I use PC to mean the address of the current instruction.  That is not the
way some processor manuals do it, but I find it simpler.

It is a pleasure to respond to such clearly stated questions.

alonzo

hobbes@portia.Stanford.EDU (Andrew Zimmerman) (06/05/90)

A couple of questions of the hp48sx assembly language.  My sources for these
questions are notes by Alonzo Gariepy for the hp-28s and the recent note
about the 48sx.

#1 The new document gives XLIB numbers for all of the command.  ie for
RR, it gives a number of 003002.  When I look at the table in 74600, where
it appears that there is a table of commands, the table looks more like

	DB	02	; number of characters in string
	DB	"RR"	; the string
	D3	003	; XLIB# ?
	DB	02	; number of characters in next string
	DB	"SL"	; the next string
	D3	005	; XLIB# ?

(Note: XLIB 4 is skipped, because the table is sorted by the number of
characters, and 004 is RRB)

So, where do the extra 3 nybbles come from in the document.

#2 What is register D1 used for?  The documents say that Register D1 points 
to the end of the stack growing down toward the heap.  I interpret this to
mean that D1 is the stack pointer.  But, in disassembling the code for
peek, we have a sequence of instructions that have
MOVE.A	@D1,A
MOVE.A	A,D0
ADD.a	10,D0
MOVE.A	@D0,C
SWAP.A	C,D0
MOVE.W	@D0,C

from this code, I get the impression that D1 is either a pointer to the 
stack pointer, or the instruction should be MOVE.A D1,A.

#3 If I look at the code for ASR at 1957B, I see D9D2.. which appears to be
D9   MOVE.A	B,C
D2   CLR.A	C
Is this correct?  Seems it is clearing reg C after putting something in it.

#4 Does anyone know where the processor starts execution?  I am guessing that
it starts at 00000.  (Sorry all you motorola people out there :-)) 
If I do an EVAL at 00000, it seems that the hp48 comes up in normal mode.
But, if you look at the code, there is a jump as the second instruction.
This is supposed to be a JUMP.3.  Assuming that was the case, I went to the
address and did an eval.  Didn't seem to work.  But, if I assume that it is
a 4 nybble address, this address is valid, and the machine come up.  Also,
If I do an eval right after the JUMP, assuming 4, the machine does come
up after doing a memory clear.

#5 How was the instruction set determined?  Boy, I can't find any fields in
it, and those it appears to have move around.

Thanks for any help,
Andrew
zimmer@calvin.Stanford.edu

hobbes@portia.Stanford.EDU (Andrew Zimmerman) (06/05/90)

In my previous posting, ignore the question about the JUMP.3 command.
I was constructing the jump address backwards. Sorry about that.

Andrew
zimmer@calvin.stanford.edu

alonzo@microsoft.UUCP (Alonzo GARIEPY) (06/06/90)

In <1990Jun4.222439.21761@portia.Stanford.EDU> (Andrew Zimmerman) writes:
> A couple of questions of the hp48sx assembly language.  My sources for these
> questions are notes by Alonzo Gariepy for the hp-28s and the recent note
> about the 48sx.

Question #1
-----------
> 	DB	02	; number of characters in string
> 	DB	"RR"	; the string
> 	D3	003	; XLIB# ?
> So, where do the extra 3 nybbles come from in the document?

The entry in my HP-48 XLIB listing is:

195DB  003002 RR

These are: the RPL (SYSEVAL) address of the command, the XLIB#, and the 
command name.  Commands and functions can be stored in two forms within 
a program: as the RPL address or as an XLIB object.  The program editor
knows how to look up the address form to find the name of the command or 
function.  When it finds an address it doesn't recognize it displays 
	<external>  

An XLIB object comprises the prolog (02E92), the library number (002 for 
commands and functions, 700 for control structures), and the index (the RR
command's index is 003, RAND's is 07F).  That is 11 nibbles total.  Commands
and functions are treated as different types at the user level (types 18 and
19, respectively); any other XLIB is displayed as XLIB xxx xxx which is
called an XLIB Name (type 14).

The reason the library number doesn't appear in the table is that there is
a separate table for each library.  But the library number does appear in
every XLIB object.

Question #2
-----------
> What is register D1 used for?  The documents say that Register D1 points 
> to the end of the stack growing down toward the heap.  I interpret this to
> mean that D1 is the stack pointer.  But, in disassembling the code for
> peek, we have a sequence of instructions that have
>
> MOVE.A	@D1,A		; Get pointer to first object off stack
> MOVE.A	A,D0		; and put it in D0
> ADD.a		10,D0		; point to 10th nib (after prolog and length)
> MOVE.A	@D0,C		; move first 5 nibbles of object data into C
> SWAP.A	C,D0		; put object data into D0 (swap is irrelevant)
> MOVE.W	@D0,C		; use data as address of 16 nibs to put in C

The comments above are mine, and explain what is going on.  Each element of
the stack is a 5 nibble address that points to an object.  If you type
	"Hello" DUP
the stack consists of two identical pointers to the same "Hello" string.
The D1 register points to the top of the stack, which is an address.  In
the code above, at the top of the stack is the address of a binary integer
which hold the PEEK address.  MOVE D1,A would just move the address of the
top of stack into register A.  MOVE @D1,A moves the address of the binary
object into A.  We then increment 10 so that A points to the PEEK address
just after the prolog and length (5 nibbles each) of the binary integer.

Question #3 
-----------
> If I look at the code for ASR at 1957B, I see D9D2.. which appears to be
> D9   MOVE.A	B,C
> D2   CLR.A	C
> Is this correct?  Seems it is clearing reg C after putting something in it.

Commands, Functions, SYSEVALs, etc. point to RPL objects, not machine code.
What you are really seeing is the prolog (02D9D) of a RPL program object.
Every RPL routine begins with these five nibbles.  A machine code object
begins with 02DCC and a five nibble length.  Note that all addresses appear
in reverse order in memory.

Question #4
-----------
> Does anyone know where the processor starts execution?  I am guessing that
> it starts at 00000.  (Sorry all you motorola people out there :-)) 

The processor begins at the beginning, 00000.  The instructions there are:

#00000: #23	 MOVE.1	3,P
#00002: #69B1    JUMP.3 #001BC
...
#001BC: #8D6CF10 JUMP.A	#01FC6
...
#01FC6: #846	 CLRB	6,ST
#01FC9: #842	 CLRB	2,ST
#01FCC: #857	 SETB	7,ST
#01FCF: #6310	 JUMP.3	#01FE3

I assume that the setting of the status register is used to configure
the operation of the initialization routines.  Have fun at #01FE3

Question #5
-----------
> How was the instruction set determined?  Boy, I can't find any fields 
> in it, and those it appears to have move around.

I agree.  Sometimes availability, not suitability, is the deciding factor.
It can be shown that the Saturn instruction set is not very well suited to
its work, but now there is an enormous body of excellent code that it would 
be impractical to replace.  

I once designed a macro language, which I named QUAD for QUick And Dirty
so I wouldn't feel defensive if it was every foisted on someone outside
my project.  We can only imagine how the designers of the Saturn feel :-).

Thanks for providing so much information with your questions.  It is too
time consuming for me if I have to research and invent examples.

Alonzo Gariepy			// The content of this message does not
alonzo@microsoft		// represent the policies of Microsoft Corp.

umapd51@sunb.cc.ic.ac.uk (W.A.C. Mier-Jedrzejowicz) (06/07/90)

Question 5 of the original posting was "How was the instruction set
determined..." Alonzo Gariepy's reply concerns the nature of the
instructions and the fields thsy use. Did the question ask about this,
or about the way that users have found out what codes are used? If the
question was the latter, then the answer is that HP released internal
documentation on the HP-71B, the first HP handheld which used the Saturn
processor. The price of the documentation was high enough to discourage
most individual users from buying it, but a few did. When the HP-28C was
released, HP told the user clubs that the 28C also used a Saturn
processor, but with a few extra instructions. Some detailed analysis of
the HP-28C, with a list of HP-71B Saturn instructions, and with the
information from HP that a new instruction called PC=(A) was used, 
allowed me to sort out what was happening and publish a PEEK program in
August 1987 for the HP-28C. That led to a lot of interesting work by
other users, and HP eventually relented and released the full
list of the new instructions to a user club. When the HP-28S came along,
HP again released a full set of instructions to a few user club people,
and this is the set described by Alonzo. The original set was called the
"level 0" instruction set, the expanded instruction set used by the
HP-28C is the "level 1" set, and the HP-28S and HP 48SX use the "level
2" set.
Back to the origins of the instruction set - Alonzo points out that it
could be better designed - well, this is like evolving an arm from a fin
- the Saturn level 2 set evolved from the original Saturn set, and that
evolved from the HP-41 CPU, which in turn evolved largely from the CPU
used by the HP-25 and... Sure, HP might like something better suited to
what is happening now, but they've got what evolved from back then. The
same applies to the names/mnemonics used - they could be designed
differently, but when Alonzo made a reasonable suggestion he found a lot
of people objecting on the (also reasonable) grounds that a great deal
of code had been written and documented using the HP mnemonics.
So, a long answer to a short question, sorry...
Wlodek Mier-Jedrzejowicz,
Space and Atmospheric Physics, Imperial College, London.
BITNET: UMAPD51@VAXA.CC.IC.AC.UK
Unix: see header
Disclaimer - the above are my opinions, not those of Imperial College
or HP. If Alonzo has opinions on my opinions, I look forward to them!