SPECIAL CM stack HP3000 instructions for MPE XL machines. (Added to emulator, and Object Code Translator) [Edited/corrected by Stan Sieler 2020-08-13] [started with INCINSTR - M2, added more] Quick summary: MFVA Move From Virtual Address S-5 target DB-relative byte address S-4 source hi virtual space S-3 source lo virtual space S-2 source hi virtual space offset S-1 source lo virtual space offset S-0 positive byte count MQFV Move to Q-relative from Virtual Address S-5 target Q-relative byte address S-4 source hi virtual space S-3 source lo virtual space S-2 source hi virtual space offset S-1 source lo virtual space offset S-0 positive byte count MTVA Move To Virtual Address S-5 target hi virtual space S-4 target lo virtual space S-3 target hi virtual space offset S-2 target lo virtual space offset S-1 source DB-relative byte address S-0 positive byte count MQTV Move from Q-relative to Virtual Address S-5 target hi virtual space S-4 target lo virtual space S-3 target hi virtual space offset S-2 target lo virtual space offset S-1 source Q-relative byte address S-0 positive byte count OSLDA Operating System Load instruction (PM) S-1 Table ID S-0 Table Offset (16-bit alignment) (byte offset) Table IDs and offsets are found in DOSLDA.CMOS.CM31900 include file. Known/supported/implemented table IDs are: 1 = CM Globals 2 = PIB (current process' PIB) result: S-0 16-bit value from table.offset. DPID Disable PID protection (PM) EPID Enable PID protection (PM) SWT Switch to NM (The last two bits are interpreted as an immediate field) BRKP Breakpoint (The last eight bits are interpreted as an immediate field) PM = you must be in Privileged Mode (PM) to use this opcode. (For some instructions, the need for 'PM' is not known.) ------ Useful DEFINEs (for SPL): DEFINE MFVA'inst = CON %020440 #, MQVA'inst = CON %020441 #, MTVA'inst = CON %020442 #, MQTV'inst = CON %020443 #, OSLDA'inst = CON %020457 #, DPID'inst = CON %020444 #, EPID'inst = CON %020445 #, SWT'inst = CON %030064 #, // not used? // SWT1'inst= CON %030065 #, // not used? SWT2'inst = CON %030066 #, SWT3'inst = CON %030067 #, // not used? //SWT4'inst = CON %030070 #, // not used? // ... //SWT11'inst= CON %030077 #, // not used? BRKP'inst = CON %036000 #, BRKP1'inst = CON %036001 #, // = DEBUG intrinsic // bottom 8 bits > 1 treated as "Hardcoded breakpoint" BRKP2'inst = CON %036002 #, // DO NOT USE: can cause buzz loop // ... // BRKP7'inst = CON %036007 #, // not used? // 'assemble' version (unused ones omitted) MFVA = assemble (MFVA' nst ) #, MQFV = assemble (MQVA'inst ) #, MTVA = assemble (MTVA'inst ) #, MQTV = assemble (MQTV'inst ) #, OSLDA = assemble (OSLDA'inst) #, DPID = assemble (DPID'inst ) #, EPID = assemble (EPID'inst ) #, SWT2 = assemble (SWT2'inst ) #, BRKP = assemble (BRKP'inst ) #, BRKP1 = assemble (BRKP1'inst) #; ! aka "DEBUG" ------ MFVA Move From Virtual Address This instruction moves a byte string from a Precision Architecture Virtual Address to an HP3000 DB area. It expects to find a positive byte count in A which represents the size of the block of bytes to be transferred, an offset into a source virtual space in C and B to be used with the source Virtual space ID in E and D to determine the address of the first source data byte, and a DB-relative address in F to be used in calculating the target address for the first byte transfer. The stack before execution is as follows; +----------------------------------+ TOS-5 (F) | Target DB-rel byte address | +----------------------------------+ TOS-4 (E) | Source Hi virtual space ID | +----------------------------------+ TOS-3 (D) | Source Lo virtual space ID | +----------------------------------+ TOS-2 (C) | Source Hi virtual space offset | +----------------------------------+ TOS-1 (B) | Source Lo virtual space offset | +----------------------------------+ TOS (A) | Byte count | +----------------------------------+ The source address is used directly as given, and the DB-relative target byte address is formed by adding the address of DB and the DB-relative address in F. Byte wrap-around is implemented, i.e. if not in split stack mode and the target address is above S, then 2**16 is subtracted from the target address. This is the normal byte mechanism to do DB negative addressing. The target byte address thus pointed to receives a byte from the source byte address, and the byte count is decremented. Bytes from the source area continue to be moved to the target area until the byte count reaches zero. The stack then is popped of all parameters. Data is protected by whatever means Native Mode has employed on the virtual address. Opcode: %020440 Indicators: unaffected Traps: MODE, STUN, BNDV Pseudo-code implementation: begin SBA := (S-4, S-3, S-2, S-1); ! Source Byte Address, 64-bit TBA := (S-5) + DB; ! Target Byte Address, 16-bit if TBA > S and not Split_Stack then TBA := TBA - 2**16; ! DB negative while (S) > 0 do begin (TBA) := (SBA); ! transfer one byte SBA := SBA + 1; TBA := TBA + 1; (S) := (S) - 1; ! decrement # bytes left to transfer end; S := S - 6; ! pop all the parameters off the stack end;  ------ MTVA Move To Virtual Address This instruction moves a string of bytes from an HP3000 DB area to a Precision Architecture virtual address. It expects to find a positive byte count in A which represents the size of the block of bytes to be transferred, a DB-relative address in B to be used in calculating the source address of the first byte to be transferred, and an offset into a target virtual space in D and C to be used with the target virtual space ID in F and E to determine the address of the first target byte location. The stack before execution is as follows: . +----------------------------------+ TOS-5 (F) | Target Hi virtual space ID | +----------------------------------+ TOS-4 (E) | Target Lo virtual space ID | +----------------------------------+ TOS-3 (D) | Target Hi virtual space offset | +----------------------------------+ TOS-2 (C) | Target Lo virtual space offset | +----------------------------------+ TOS-1 (B) | Source DB-rel byte address | +----------------------------------+ TOS (A) | Byte count | +----------------------------------+ The DB-relative source byte address is formed by adding the address of DB and the DB-relative address in B. Byte wrap-around is implemented, i.e., if not in split stack mode and the source address is above S, the 2**16 is subtracted from the source address. This is the normal byte mechanism for achieving DB negative addressing. The target address is used directly as given in F, E, D and C. The source byte pointed to is is moved to the target location, and the byte count is decremented. Bytes from the source area continue to be moved to the target area until the byte count reaches zero. The stack then is popped of all parameters. Data is protected by whatever means Native Mode has employed on the virtual address. Opcode: %020442 Indicators: unaffected Traps: MODE, STUN, BNDV Pseudo-code implementation: begin TBA := (S-5,S-4,S-3,S-2); ! Target Byte Addr. in virtual space SBA := (S-1) + DB; ! Source Byte Address if SBA > S and not Split_Stack then SBA := SBA - 2**16; ! DB negative while (S) > 0 do begin (TBA) := (SBA); ! transfer one byte TBA := TBA + 1; SBA := SBA + 1; (S) := (S) - 1; End; S := S - 6; end; ------ MQFV Move to Q-relative From Virtual address This instruction moves a byte string from a Precision Architecture Virtual Address to an HP3000 stack. It expects to find a positive byte count in A (which represents the size of the block of bytes to be transferred), a 32-bit offset into a source virtual space in C and B, and a 32-bit source virtual space ID in E and D to determine the address of the first source data byte, and a Q-relative address in F to be used in calculating the target address for the first byte transfer. The stack before execution is as follows: +----------------------------------+ TOS-5 (F) | Target Q-rel byte address | +----------------------------------+ TOS-4 (E) | Source Hi virtual space ID | +----------------------------------+ TOS-3 (D) | Source Lo virtual space ID | +----------------------------------+ TOS-2 (C) | Source Hi virtual space offset | +----------------------------------+ TOS-1 (B) | Source Lo virtual space offset | +----------------------------------+ TOS (A) | Byte count | +----------------------------------+ The source address is used directly as given, and the Q-relative target byte address is formed by adding the byte address of Q and the Q-relative address in F. Byte wrap-around is implemented, i.e. if the target address is above S, then 2**16 is subtracted from the target address. This is the mechanism to do Q negative byte addressing. The target byte address thus pointed to receives a byte from the source byte address, and the byte count is decremented. Bytes from the source area continue to be moved to the target area until the byte count reaches zero. The stack then is popped of all parameters. Data is protected by whatever means Native Mode has employed on the virtual address. Opcode: %020441 Indicators: unaffected Traps: MODE, STUN, BNDV Pseudo-code implementation: begin SBA := (S-4,S-3,S-2,S-1); ! Source Byte Addr. in virtual 8pace TBA := (S-5) + Q; ! Target Byte Address if TBA > S then TBA := TBA - 2**16; ! Q negative While (S) > 0 do begin (TBA) := (SBA); ! transfer one byte SBA := SBA + 1; ' " TBA := TBA + 1; (S) := (S) - 1; end; S : = S - 6; end;  ------ MQTV Move Q-relative To Virtual address This instruction moves a string of bytes from an HP3000 stack to a Precision Architecture virtual address. It expects to find a positive byte count in A which represents the size of the block of bytes to be transferred, a Q-relative address in B to be used in calculating the source address of the first byte to be transferred, a 32-bit offset into a target virtual space in D and C to be used with the 32-bit target virtual space ID in F and E to determine the address of the first target byte location. The stack before execution is as follows: +----------------------------------+ TOS-5 (F) | Target Hi virtual space ID | +----------------------------------+ TOS-4 (E) | Target Lo virtual space ID | +----------------------------------+ TOS-3 (D) | Target Hi virtual space offset | +----------------------------------+ TOS-2 (C) | Target Lo virtual space offset | +----------------------------------+ TOS-1 (B) | Source Q-rel byte address | +----------------------------------+ TOS (A) | Byte count | +----------------------------------+ The Q-relative source byte address is formed by adding the byte address of Q and the Q-relative address in B. Byte wrap-around is implemented, i.e., if the source address is above S, the 2**16 is subtracted from the source address. This is the mechanism for achieving Q negative byte addressing. The target address is used directly as given in F, E, D and C. The source byte pointed to is is moved to the target location, and the byte count is decremented. Bytes from the source area continue to be moved to the target area until the byte count reaches zero. The stack then is popped of all parameters. Data is protected by whatever means Native Mode has employed on the virtual address. Opcode: %020443 Indicators: unaffected Traps: MODE, STUN, BNDV Pseudo-code implementation: begin TBA := (S-5,S-4,S-3,S-2); ! Target 64-bit virtual Byte Address SBA := (S-1) + Q; ! Source Byte Address IF SBA > S then SBA := SBA - 2**16; ! Q negative while (S) > 0 do begin (TBA) := (SBA); ! transfer 1 byte TBA := TBA + 1; SBA := SBA + 1; (S) := (S) - 1; end; S := S - 6; end; ------ OSLDA Operating System Load instruction (PM) This instruction loads a 16-bit halfword from the specified byte-offset of a system table. The byte-offset must be even (i.e., 16-bit aligned). The system table is a magic number defined in DOSLDA.CMOS.CM31900. The documented table offsets are also in DOSLDA.CMOS.CM31900. Opcode: %020457 Indicators: unaffected ? Traps: ? The stack before execution is as follows: +----------------------------------+ TOS-1 (B) | Table ID (currently: 1 or 2) | +----------------------------------+ TOS (A) | Byte offset (must be even) | +----------------------------------+ The only Table IDs supported are: 1 = CM Globals 2 = PIB (current process' PIB) The two parameters are popped from the stack, and the 16-bit result is pushed onto the stack. result: S-0 16-bit value from table.offset. NOTE: I suspect that some table offsets will vary from release to release of MPE/iX. NOTE: (assuming SYMOS is open) you can find PIB offsets by doing: :debug /* open the correct SYMOS (not shown here) ft "pib_type" m /* offsets usually in hex c ------ DPID Disable PID protection Opcode: %020444 Indicators: unaffected ? Traps: ? This instruction turns off PID checking for accessing data. (This means, for example, that you could access portions of another process' stack, assuming the current ring level and the ring level of the page being accessed 'match'.) The instruction has no parameters on the stack. The stack *after* execution is as follows: +----------------------------------+ TOS (A) | zero | +----------------------------------+ ------ EPID Enable PID protection Opcode: %020445 Indicators: unaffected ? Traps: ? This instruction turns on PID checking for accessing data. (This means, for example, that you could access portions of another process' stack, assuming the current ring level and the ring level of the page being accessed 'match'.) The stack before execution is as follows: +----------------------------------+ TOS (A) | unknown integer value (unused?) | +----------------------------------+ The unknown integer value is popped from the stack when EPID returns. Sadly, the implementers missed a chance to return the old state of the "data protection" flag. ------ SWT Switch to NM Opcode: %030064 Indicators: unaffected ? Traps: ? unused? ------ SWT2'inst = CON %030066 #, Opcode: %030066 Indicators: unaffected ? Traps: ? Stack before call: ... S-3 nth-1 halfword S-2 nth halfword S-1 # halfwords of parameters E.g.: 5 for writelog'nm'stub'nm S-0 procedure number. E.g.: writelog'nm'stub'nm example: >> (call to nm) freaddir ( file_num : shortint; 1 halfword anyvar $extnaddr$ target : IO_buf_t; 1 halfword (DB 'word' addr) tcount : shortint; 1 halfword rec_count : integer); 2 halfwords tos := 5; // # of halfwords tos := FREADDIR'NM'STUB'NM; SWT2; ------ BRKP BreaKPoint 0 Opcode: %036000 Indicators: unaffected ? Traps: ? ------ BRKP1 Breakpoint 1 This instruction is interpreted as a call to the DEBUG intrinsic. Opcode: %036001 Indicators: unaffected ? Traps: ? ------ BRKP2'inst = CON %036002 #, ------ //