Path: utzoo!attcan!uunet!microsoft!alonzo From: alonzo@microsoft.UUCP (Alonzo Gariepy) Newsgroups: comp.sys.handhelds Subject: HP28S PROCESSOR NOTES (2 of 4) Keywords: hp28s, cpu, processor, assembler, architecture, memory Message-ID: <9083@microsoft.UUCP> Date: 19 Nov 89 18:56:02 GMT Organization: Microsoft Corp., Redmond WA Lines: 284 HP28S PROCESSOR ARCHITECTURE Version 1 Copyright (C) 1989, Alonzo Gariepy ================================================================ Overview ======== The HP28 (Saturn) CPU uses 64 bit data registers and 20 bit address registers. The unit of addressibility is a four bit nibble, hence the address space of the processor is 2^20 nibbles or half a megabyte. The HP28S address space contains 128 kilobytes of ROM at addresses #00000 to #3FFFF, and 32 kilobytes of RAM at addresses #C0000 to #CFFFF. The RAM is aliased at addresses #D0000 to #DFFFF. Other little chunks of the address space are used here and there for hardware control. Most operations on data registers can be restricted to particlar ranges of nibbles, called fields. These fields have been chosen to optimize the floating point arithmetic of the calculator. The format for floating point numbers is a 1 nibble sign, followed by a 12 nibble mantissa and 3 nibble exponent, making 16 nibbles or 64 bits in all. The four data registers are called A, B, C, and D. The instruction set does not allow these registers to be used interchangeably. For example, registers A and B never interact with register D. Memory operations are restricted to data registers A and C with the bulk of the responsibility on register C. There is a 4 bit pointer register, called P, that is used to specify the position of a one nibble field (.P) or the length of a multi-nibble field (.WP). The two 20 bit address registers are called D0 and D1 (go figure) and can be used interchangeably. There are five 64 bit temporary registers called R0, R1, R2, R3, and R4. The operations they support are restricted to moving and swapping with registers A and C. The HP28S system software uses some of the above registers for its own purposes. Register B points to the end of the object heap growing up toward the stack. Register D1 points to the end of the stack growing down toward the heap. Register D holds the size of the free area in between. When it reaches zero, the stack and heap have met and its time to garbage collect. Garbage collection creates free space by discarding unused objects from the heap and compacting what is left. Memory is allocated in units of 5 nibbles. The MEM function calculates the number of free bytes by performing garbage collection and then multiplying D by 2.5. Register P is assumed always to be zero. D0 is the RPL instruction pointer. If you change any of these registers (B, D1, D, P, D0) in your machine code programs, restore their previous values before exiting. It is said that R4 is used by the interrupt handler, but I have yet to confirm this. If you do a SETDEC, make sure you restore the calculation mode with SETHEX before returning. See CPU Bugs section. Fields ====== Each 64 bit register comprises 16 nibbles that can be grouped into fields for calculation and data movement. These nibbles are numbered from right to left starting at 0; nibble 0 is the low order or least signficant nibble and nibble 15 is the high order or most significant nibble: +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | 15| 14| 13| 12| 11| 10| 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ In the following diagrams, each nibble within a field is marked with its position, while those outside are blank. The vertical bar has been removed from between the nibbles of a field. Field: .P Name: Pointer Field Start: nibble P Size: 1 nibble Example: RETZ.P B +---+- - - -+---+---+---+- - - -+---+---+ | | | | P | | | | | +---+- - - -+---+---+---+- - - -+---+---+ Field: .WP Name: Word to Pointer Field Start: nibble 0 Size: P+1 nibbles Example: OR.WP C,D +---+- - - -+---+---+---+- - - -+---+---+ | | | | P P-1 1 0 | +---+- - - -+---+---+---+- - - -+---+---+ Field: .XS Name: Exponent Sign Field Start: nibble 2 Size: 1 nibble Example: NOT.XS C +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | | | | | 2 | | | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Field: .X Name: Exponent Field Start: nibble 0 Size: 3 nibbles Example: SUB.X A,C +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | | | | | 2 1 0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Field: .S Name: Sign Field Start: nibble 15 Size: 1 nibble Example: CLR.S B +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | 15| | | | | | | | | | | | | | | | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Field: .M Name: Mantissa Field Start: nibble 3 Size: 12 nibbles Example: MOVE.M B,C +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | 14 13 12 11 10 9 8 7 6 5 4 3 | | | | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Field: .B Name: Byte Field Start: nibble 0 Size: 2 nibbles Example: INC.B C +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | | | | | | 1 0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Field: .W Name: Word Field Start: nibble 0 Size: 16 nibbles Example: SWAP.W A,R2 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Field: .A Name: Address Field Start: nibble 0 Size: 5 nibbles Example: ADD.A 5,D1 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | | | 4 3 2 1 0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Field: .n Name: n Nibble Field Start: nibble 0 Size: n nibbles Example: MOVE.8 @D0,A +---+- - - -+---+---+---+- - - -+---+---+ | | | |n-1 n-2 1 0 | +---+- - - -+---+---+---+- - - -+---+---+ Field. .Pn Name: n from Pointer Field Start: nibble P Size: n nibbles Example: MOVE.P3 6,C +---+- - - -+---+---+- - - -+---+---+---+- - - -+---+ | | | |P+n-1 P+1 P | | | | +---+- - - -+---+---+- - - -+---+---+---+- - - -+---+ Control Registers ================= In addition to the data and address registers (A, B, C, D, R0, R1, R2, R3, R4, D0, D1, and P) the CPU also has some registers devoted to control, status, and I/O. The control registers are 20 bits long and include the program counter (PC) and the eight level return stack (RSTK). Instructions that directly reference the PC or the return stack use all five nibbles (the .A field). MOVE.A reg,PC ; reg A or C MOVE.A PC,reg ; reg A or C MOVE.A @reg,PC ; reg A or C SWAP.A reg,PC ; reg A or C PUSH.A C POP.A C The PC and RSTK are indirectly modified by JUMP, BRANCH, CALL, and RETURN instructions. One level of the return stack must be available for interrupt handling, leaving seven for program use. Status Registers ================ The status registers include: the carry bit (C), the 16 bit status register (ST), and the 4 bit hardware status register (HST). Each bit of these registers can be set or cleared individually and can be tested as part of a conditional branch or return. The lower 12 bits (.X field) of ST can be cleared, moved, or swapped together: CLR.X ST MOVE.X ST,C MOVE.X C,ST SWAP.X C,ST The carry bit is set or cleared indirectly by arithmetic operations. The RETSETC and RETCLRC instructions do this directly. The hardware status register is made up of the XM, SB, SR, and MP flags. These can be cleared together or in any combination. The XM bit (eXternal Module Missing) is set when the nibbles 00 are executed (the RETSETXM instruction) which happens when you jump to nonexistent memory. SB (the Sticky Bit) is set whenever a non-zero bit is shifted out the right end of a register. The SR bit (Service Request) is set by the SREQ instruction when there is an outstanding service requests (polling). I do not know how the MP (Module Pulled) bit is set (perhaps when power is lost). I/O Registers ============= Finally, there are a 16 bit input register (IN) and a 12 bit ouput register (OUT). The input register is used to read the keyboard, and the output register to control the beeper. Summary ======= Below is a table of all the registers in the CPU. Registers that are used by the system are marked with *. The system only uses the low 20 bits of these registers, which must be restored after use. Since R4 and RSTK are used by interrupts, you should never change the lower 20 bits of R4 nor PUSH/CALL more than seven addresses onto the return stack. 16 nibbles 5 nibbles Data Temp Addr Ctrl Stat I/O Pntr ------ ------ ------ ------ ------ ----- ------ A R0 D0* PC C IN P* B* R1 D1* RSTK* ST ? OUT C R2 HST D* R3 R4* CPU Bugs ======== The CPU has some bugs in it, instructions that do now work correctly. I have run into some, but they are difficult to accurately characterize. When NOTHING else explains your problem, suspect a bug in the processor. Two bugs that I have seen explicitly stated are: 1. SETHEX may not work unless preceded immediately by SETDEC. (Reference: W.Meir). 2. The 818 opcodes (ADD.f x,reg and SUB.f x,reg) don't always work as advertised. To be specific, when the field of such an instruction is XS, S, P, or WP, and a carry (or borrow) is generated out of the most significant nibble, it wraps around and affects the least significant nibble. (Reference: Dave Kaffine).