HP98x0 CPU Microcode --------------------- Resident Diagnositc This is executed at power-up. 1717 : c677f80 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 1717 : c677f80 : IQN=0;XTR=1;clk=f;sec=1;pri=0; 1717 : c677f80 : A/B = (0) ZTT (0); 1717 : c677f80 : clocks=16; goto (1716) Microcode PC is reset to this state by the Init/ signal from the PSU. Clear selected accumulator (A or B), possibly 1716 : c677f45 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 1716 : c677f45 : IQN=0;XTR=1;clk=f;sec=8;pri=5; 1716 : c677f45 : A/B = (0) ZTT (0); 1716 : c677f45 : clocks=16; goto (1206) First real microinstruction. Clear selected accumulator. 1206 : 0445ff2 : TTM=0;TTT=0;SC=0(ZTS);X=4(CAB);R=1(PTR);ALU=1(AND);BRC=0 1206 : 0445ff2 : IQN=0;XTR=1;clk=f;sec=f;pri=2; 1206 : 0445ff2 : M,T = (0) AND (P); CAB; 1206 : 0445ff2 : clocks=16; goto (1011) Clear M and T registers (if ALU AND works correctly). Select other accumulator 1011 : e673f42 : TTM=1;TTT=1;SC=1(MTS);X=6(TTX);R=7(ZTR);ALU=2(IOR);BRC=0 1011 : e673f42 : IQN=0;XTR=1;clk=f;sec=8;pri=2; 1011 : e673f42 : A/B = (M) IOR (0); 1011 : e673f42 : clocks=16; goto (1201) Load this accumulator with 0 (from M) 1201 : ec70fee : TTM=1;TTT=1;SC=1(MTS);X=5(TTP);R=7(ZTR);ALU=0(XOR);BRC=0 1201 : ec70fee : IQN=0;XTR=0;clk=f;sec=d;pri=e; 1201 : ec70fee : P = (M) XOR (A/B,0); 1201 : ec70fee : clocks=16; goto (0414) Now XOR this with M (should be all 0s), result into P 0414 : d145f38 : TTM=1;TTT=1;SC=2(TTS);X=0(TTQ);R=1(PTR);ALU=5(IORCBC);BRC=0 0414 : d145f38 : IQN=0;XTR=1;clk=f;sec=6;pri=8; 0414 : d145f38 : Q = (T) IORCBC (P); 0414 : d145f38 : clocks=16; goto (1412) Or P (0) with T (0), result into Q, clear carry 1412 : af56fe9 : TTM=1;TTT=0;SC=1(MTS);X=7(NOP);R=5(QTR);ALU=7(ADD);BRC=0 1412 : af56fe9 : IQN=0;XTR=0;clk=f;sec=d;pri=9; 1412 : af56fe9 : T = (M) ADD (A/B,Q); 1412 : af56fe9 : clocks=16; goto (0507) Add M to accumulator OR Q, result to T. Everything is 0, so result should be too. 0507 : d507f10 : TTM=1;TTT=1;SC=2(TTS);X=4(CAB);R=0(UTR);ALU=7(ADD);BRC=0 0507 : d507f10 : IQN=0;XTR=1;clk=f;sec=2;pri=0; 0507 : d507f10 : = (T) ADD (1); CAB; 0507 : d507f10 : clocks=16; goto (0505) Add 1s to all bits of T, select other accumulator. Carry should remain clear 0505 : ff46fdc : TTM=1;TTT=1;SC=3(UTS);X=7(NOP);R=1(PTR);ALU=7(ADD);BRC=0 0505 : ff46fdc : IQN=0;XTR=0;clk=f;sec=b;pri=c; 0505 : ff46fdc : = (1) ADD (A/B,P); IOS; 0505 : ff46fdc : clocks=16; goto (1116) Add 1s to all bits of that accumulator. Carry should be clear if everything OK 1116 : caf73a7 : TTM=1;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=3(ZTT);BRC=1 1116 : caf73a7 : IQN=0;XTR=1;clk=3;sec=5;pri=7; 1116 : caf73a7 : E = (0) ZTT (0,E); 1116 : caf73a7 : clocks=4; if (QBC) goto (1613,1612) Clear E. If carry clear (Self-test OK), goto instruction fetch (with M,P =0). Otherwise report error. 1613 : 3003f59 : TTM=0;TTT=0;SC=3(UTS);X=0(TTQ);R=0(UTR);ALU=2(IOR);BRC=0 1613 : 3003f59 : IQN=0;XTR=1;clk=f;sec=a;pri=9; 1613 : 3003f59 : M,T,Q = (1) IOR (1); 1613 : 3003f59 : clocks=16; goto (0701) Set all bits of M,T,Q and go to DMA instruction to report error. --------------------- Incremnt PC -- Note on entry to this section, BC is normally clear if BC is set, then P is incremnted by 2 -- thus skiping the next machine instruction 0202 : 7d4708c : TTM=0;TTT=1;SC=3(UTS);X=5(TTP);R=1(PTR);ALU=7(ADD);BRC=0 0202 : 7d4708c : IQN=0;XTR=1;clk=0;sec=1;pri=c; 0202 : 7d4708c : M,P = (1) ADD (P); 0202 : 7d4708c : clocks=1; goto (1603) Add 1 to LSB of P (result also in M) 1603 : 4d47ec0 : TTM=0;TTT=1;SC=0(ZTS);X=5(TTP);R=1(PTR);ALU=7(ADD);BRC=0 1603 : 4d47ec0 : IQN=0;XTR=1;clk=e;sec=9;pri=0; 1603 : 4d47ec0 : M,P = (0) ADD (P); 1603 : 4d47ec0 : clocks=15; goto (1612) Add 0 to rest of P (thus adding 0001h to P) 1612 : cf31b28 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=4(ZTTCBC);BRC=0 1612 : cf31b28 : IQN=0;XTR=1;clk=b;sec=4;pri=8; 1612 : cf31b28 : = (0) ZTTCBC (); RDM ; 1612 : cf31b28 : clocks=12; goto (0616) Fetch -- Read next machine instruction from memory into T 0616 : d085fac : TTM=1;TTT=1;SC=2(TTS);X=0(TTQ);R=0(UTR);ALU=1(AND);BRC=1 0616 : d085fac : IQN=0;XTR=1;clk=f;sec=5;pri=c; 0616 : d085fac : Q = (T) AND (1); 0616 : d085fac : clocks=16; if (QNR) goto (1213,1212) And transfer it into Q. Handle I/O service request, or go to instruction decode routine --------------------- I/O service request handler. This does an I/O operation with Q=0, clearing the service reuqest F/F. It then executes the instruction at location 0002, but doesn't load P. In fact P is decremented so that at the end of the instruction (or subroutine if the instruction at location 2 is JSM, which it normally is), the current instruction is re-fetched and executed. 1212 : fd47f44 : TTM=1;TTT=1;SC=3(UTS);X=5(TTP);R=1(PTR);ALU=7(ADD);BRC=0 1212 : fd47f44 : IQN=0;XTR=1;clk=f;sec=8;pri=4; 1212 : fd47f44 : P = (1) ADD (P); 1212 : fd47f44 : clocks=16; goto (1602) Add FFFFh to P, thus decrementing it (BC is always clear on entry to this routine, having been cleared in the fetch routine at 1612). 1602 : 4077060 : TTM=0;TTT=1;SC=0(ZTS);X=0(TTQ);R=7(ZTR);ALU=3(ZTT);BRC=0 1602 : 4077060 : IQN=0;XTR=1;clk=0;sec=c;pri=0; 1602 : 4077060 : M,Q = (0) ZTT (0); 1602 : 4077060 : clocks=1; goto (1616) Shift a 0 into M and Q 1616 : c173e80 : TTM=1;TTT=1;SC=0(ZTS);X=0(TTQ);R=7(ZTR);ALU=6(IORSBC);BRC=0 1616 : c173e80 : IQN=0;XTR=1;clk=e;sec=1;pri=0; 1616 : c173e80 : Q = (0) IORSBC (0); 1616 : c173e80 : clocks=15; goto (1617) Shift 15 more 0s into Q, set carry. Q is now clear 1617 : 4f77e37 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 1617 : 4f77e37 : IQN=0;XTR=1;clk=e;sec=6;pri=7; 1617 : 4f77e37 : M = (0) ADD (0); 1617 : 4f77e37 : clocks=15; goto (1111) Add 15 0's to M. BC is set, so M ends up containing 0002 (address of I/O service machine instruction) 1111 : ce4e097 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=0 1111 : ce4e097 : IQN=1;XTR=0;clk=0;sec=3;pri=7; 1111 : ce4e097 : = (0) ZTT (A/B,P); IOS; 1111 : ce4e097 : clocks=1; IQN(QBC); goto (1612) Start an I/O operation. Q, and in particular Q(10) is clear, so the service reqeust FF is reset. Then go to the Fetch routine to execute the instruction at location 0002h ------------------- Instruction Decode 1213 : c8f708a : TTM=1;TTT=1;SC=0(ZTS);X=1(QAB);R=7(ZTR);ALU=3(ZTT);BRC=1 1213 : c8f708a : IQN=0;XTR=1;clk=0;sec=1;pri=a; 1213 : c8f708a : = (0) ZTT (0); QAB; 1213 : c8f708a : clocks=1; if (QMR) goto (0012,0013) Set A/B select flip-flop from bit 11 of the instruction and branch depending on whether it's a Memory Reference Instruction (bits 12-14 not all 1s) or not -- Memory Reference -- calculate address 0012 : 5ef398b : TTM=0;TTT=1;SC=2(TTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=1 0012 : 5ef398b : IQN=0;XTR=1;clk=9;sec=1;pri=b; 0012 : 5ef398b : M = (T) IOR (0); 0012 : 5ef398b : clocks=10; if (Q10/) goto (1313,1312) Copy lower 10 bits of instruction (in T) -- address part of the instuction -- to the M register. The high bits of M, giving the current page, end up in the LSBs of M. Test bit 10 of the instruction to determine if it's base page or current page. 1312 : 4e77542 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1312 : 4e77542 : IQN=0;XTR=1;clk=5;sec=8;pri=2; 1312 : 4e77542 : M = (0) ZTT (0); 1312 : 4e77542 : clocks=6; goto (1102) Base page : Shift 6 0's into M, thus forming a base page address 1313 : ee775c2 : TTM=1;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1313 : ee775c2 : IQN=0;XTR=1;clk=5;sec=9;pri=2; 1313 : ee775c2 : = (M) ZTT (0); 1313 : ee775c2 : clocks=6; goto (1102) Current page : Rotate M by 6 bits, so original 6 MSBs end up in the MSBs of M (thus keeping the current page) 1102 : cfb1b89 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=4(ZTTCBC);BRC=1 1102 : cfb1b89 : IQN=0;XTR=1;clk=b;sec=1;pri=9; 1102 : cfb1b89 : = (0) ZTTCBC (); RDM ; 1102 : cfb1b89 : clocks=12; if (Q15/) goto (0003,0002) Read in the addressed memory word. Check bit 15 of the instruction (in Q) to determine if it's indirect or not. Clear BC (needed by PC increment routine, amongst others) 0003 : 5e13f86 : TTM=0;TTT=1;SC=2(TTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=0 0003 : 5e13f86 : IQN=0;XTR=1;clk=f;sec=1;pri=6; 0003 : 5e13f86 : M,Q6 = (T) IOR (); 0003 : 5e13f86 : clocks=16; goto (0602) It is indirect. Copy read-in memory word (indirect address) into M. Shift bits into Q(6) also, so that Q(6) ends up set to the state of the MSB of this address. This is set if this address is also indirect 0602 : ceb7b86 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=3(ZTT);BRC=1 0602 : ceb7b86 : IQN=0;XTR=1;clk=b;sec=1;pri=6; 0602 : ceb7b86 : = (0) ZTT (); RDM ; 0602 : ceb7b86 : clocks=12; if (Q6/) goto (0003,0002) Read in data word. Test to see if this needs to be indirected again. If so, go back and do so At this point, M contains the address specified in the instruction (indirected if necessary), T contains the contents of that address. 0002 : ce0e01f : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=0(UTR);ALU=3(ZTT);BRC=0 0002 : ce0e01f : IQN=1;XTR=0;clk=0;sec=2;pri=f; 0002 : ce0e01f : = (0) ZTT (A/B,1); QmuJMP; 0002 : ce0e01f : clocks=1; IQN(QRD); goto (1700) A fork to select the appropriate routine based on the opcode in Q14-11. Go to 0000 : AD* ) 0200 : CP* ) Hardware causes the same location to be jumped to whether 0400 : LD* ) the A/B select bit is 0 or 1. The accumulator selection is 0600 : ST* ) done in hardware 1000 : IOR ) 1100 : ISZ ) Here, the 2 instructions that use an accumulator (AND, OR) 1200 : AND ) have bit 11 clear, therefore selecting A (in hardware) 1300 : DSZ ) 1400 : JSM 1500 : JMP --- Not memory reference 0013 : cff5089 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=5(IORCBC);BRC=1 0013 : cff5089 : IQN=0;XTR=1;clk=0;sec=1;pri=9; 0013 : cff5089 : = (0) IORCBC (0); 0013 : cff5089 : clocks=1; if (Q15/) goto (1112,1113) Clear carry. Branch on Q15 (0 for shift/rotate, complement/execute/DMA, alter/skip ; 1 for I/O and Mac groups) 1112 : cef70ab : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 1112 : cef70ab : IQN=0;XTR=1;clk=0;sec=5;pri=b; 1112 : cef70ab : = (0) ZTT (0); 1112 : cef70ab : clocks=1; if (Q10/) goto (0217,0216) I/O and Mac. Branch on Q10 (0 for Mac group, 1 for I/O) 1113 : ce574f9 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=5(QTR);ALU=3(ZTT);BRC=0 1113 : ce574f9 : IQN=0;XTR=1;clk=4;sec=f;pri=9; 1113 : ce574f9 : = (0) ZTT (Q); 1113 : ce574f9 : clocks=5; goto (0004) Rotate Q right 5 bits. This puts the 'secodnary opcode' -- bits 0-3 -- into the opcode field (bits 11-14) so that a QmuJMP can be done on it. 0004 : ce0e06f : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=0(UTR);ALU=3(ZTT);BRC=0 0004 : ce0e06f : IQN=1;XTR=0;clk=0;sec=c;pri=f; 0004 : ce0e06f : = (0) ZTT (A/B,1); QmuJMP; 0004 : ce0e06f : clocks=1; IQN(QRD); goto (1710) The QmuJMP fork on the secondary opcode. Go to 0010 : A*R ) 0210 : S*R ) Shift/Rotate group. 0410 : S*L ) 0610 : R*R ) 1010 : SZ*, RZ*, SI*, RI* ) 1110 : SL* ) 1210 : S*M ) Alter/Skip group 1310 : S*P ) 1410 : SES ) 1510 : SEC ) 1610 : Complement/Execute/DMA group 1710 : Register Reference group --------------------- Mmeory Reference Instruction Routines. On entry to all these routines, M contains the specified address, T is loaded with the contents of that address, BC is clear. AD* (Add) 0000 : d776fa0 : TTM=1;TTT=1;SC=2(TTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0000 : d776fa0 : IQN=0;XTR=0;clk=f;sec=5;pri=0; 0000 : d776fa0 : A/B = (T) ADD (A/B,0); 0000 : d776fa0 : clocks=16; goto (0005) Add T (contents of specified address) to the accumulator. 0005 : fafb087 : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=7(ZTR);ALU=2(IOR);BRC=1 0005 : fafb087 : IQN=1;XTR=1;clk=0;sec=1;pri=7; 0005 : fafb087 : E = (1) IOR (0,E); 0005 : fafb087 : clocks=1; IQN(QBC); if (QBC) goto (0704,0705) If carry set, shift a 1 into the E register. Then branch depending on carry. 0704 : cb71235 : TTM=1;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 0704 : cb71235 : IQN=0;XTR=1;clk=2;sec=6;pri=5; 0704 : cb71235 : E = (0) ZTTCBC (0,E); 0704 : cb71235 : clocks=3; goto (0202) Carry set, shift 3 0's into E (so E ends up as 0001). Clear carry (needed by PC increment routine) and go to increment PC and fetch nect instruction. 0705 : ce770b5 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0705 : ce770b5 : IQN=0;XTR=1;clk=0;sec=7;pri=5; 0705 : ce770b5 : = (0) ZTT (0); 0705 : ce770b5 : clocks=1; goto (0202) NOP, go to increment PC and fetch next instruction CP* (Compare) 0200 : 9e70f54 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=7(ZTR);ALU=0(XOR);BRC=0 0200 : 9e70f54 : IQN=0;XTR=0;clk=f;sec=a;pri=4; 0200 : 9e70f54 : T = (T) XOR (A/B,0); 0200 : 9e70f54 : clocks=16; goto (0612) XOR T with selected accumulator. T is zero if they're equal, non-zero otherwise. 0612 : df07f44 : TTM=1;TTT=1;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 0612 : df07f44 : IQN=0;XTR=1;clk=f;sec=8;pri=4; 0612 : df07f44 : = (T) ADD (1); 0612 : df07f44 : clocks=16; goto (0202) Add 1's to all bits of T. This sets BC if T non-zero. Then go to the PC increment routine. P is incremented by 2 if BC set (i.e. the original words were not equal). LD* (Load) 0400 : d673f16 : TTM=1;TTT=1;SC=2(TTS);X=6(TTX);R=7(ZTR);ALU=2(IOR);BRC=0 0400 : d673f16 : IQN=0;XTR=1;clk=f;sec=2;pri=6; 0400 : d673f16 : A/B = (T) IOR (0); 0400 : d673f16 : clocks=16; goto (0202) Copy T (addressed memory word) into the selected accumulator and go to incrememnt PC and fetch next instruction. ST* (Store) 0600 : 8e72fee : TTM=1;TTT=0;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 0600 : 8e72fee : IQN=0;XTR=0;clk=f;sec=d;pri=e; 0600 : 8e72fee : T = (0) IOR (A/B,0); 0600 : 8e72fee : clocks=16; goto (1015) Copy selected accumulator into T 1015 : ce67bfa : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=3(ZTT);BRC=0 1015 : ce67bfa : IQN=0;XTR=1;clk=b;sec=f;pri=a; 1015 : ce67bfa : = (0) ZTT (); WTM; 1015 : ce67bfa : clocks=12; goto (0202) Write it back to memory, and go to the PC increment routine IOR (Inclusive OR) 1000 : d672f1a : TTM=1;TTT=1;SC=2(TTS);X=6(TTX);R=7(ZTR);ALU=2(IOR);BRC=0 1000 : d672f1a : IQN=0;XTR=0;clk=f;sec=2;pri=a; 1000 : d672f1a : A/B = (T) IOR (A/B,0); 1000 : d672f1a : clocks=16; goto (0202) Inclusive Or T (addressed memory word) into the selected accumulator, go and increment PC. ISZ (Increment and Skip on Zero) 1100 : 9f070a0 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 1100 : 9f070a0 : IQN=0;XTR=1;clk=0;sec=5;pri=0; 1100 : 9f070a0 : T = (T) ADD (1); 1100 : 9f070a0 : clocks=1; goto (1105) Add 1 to LSB of T 1105 : 9f77e41 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 1105 : 9f77e41 : IQN=0;XTR=1;clk=e;sec=8;pri=1; 1105 : 9f77e41 : T = (T) ADD (0); 1105 : 9f77e41 : clocks=15; goto (1015) Add 15 0's to T (thus adding 0001h to T). Carry is set if T is incremented to 0000h. Go to 1015 to store the word back in memory and increment PC. AND (Bitwise AND) 1200 : d674f18 : TTM=1;TTT=1;SC=2(TTS);X=6(TTX);R=7(ZTR);ALU=1(AND);BRC=0 1200 : d674f18 : IQN=0;XTR=0;clk=f;sec=2;pri=8; 1200 : d674f18 : A/B = (T) AND (A/B,0); 1200 : d674f18 : clocks=16; goto (0202) And T into the selected accumulator, go and increment PC DSZ (Decrement and Skip on Zero) 1300 : 9f07fc0 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 1300 : 9f07fc0 : IQN=0;XTR=1;clk=f;sec=9;pri=0; 1300 : 9f07fc0 : T = (T) ADD (1); 1300 : 9f07fc0 : clocks=16; goto (1311) Add 1's to every bit of T (thus adding FFFFh), effectively decrementing it 1311 : cf63b38 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=6(IORSBC);BRC=0 1311 : cf63b38 : IQN=0;XTR=1;clk=b;sec=6;pri=8; 1311 : cf63b38 : = (0) IORSBC (); WTM; 1311 : cf63b38 : clocks=12; goto (0317) Write the word back to memory and set BC 0317 : 9e01f04 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=0(XOR);BRC=0 0317 : 9e01f04 : IQN=0;XTR=1;clk=f;sec=0;pri=4; 0317 : 9e01f04 : T = (T) XOR (1); 0317 : 9e01f04 : clocks=16; goto (0717) Invert all bits of T (thus T ends up as all 1's if it was decremented to 0) 0717 : 9f77fe5 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 0717 : 9f77fe5 : IQN=0;XTR=1;clk=f;sec=d;pri=5; 0717 : 9f77fe5 : T = (T) ADD (0); 0717 : 9f77fe5 : clocks=16; goto (0202) Add 0's to all bits of T. Since BC is set, this increments T. BC set after this instruction implies T was all 1's before, that is to say that T was all 0's after the decrement. Go and increment PC (by 2 if BC is set, thus skipping next machine instruction). JSM (Jump Subroutine) 1400 : e005f61 : TTM=1;TTT=1;SC=1(MTS);X=0(TTQ);R=0(UTR);ALU=1(AND);BRC=0 1400 : e005f61 : IQN=0;XTR=1;clk=f;sec=c;pri=1; 1400 : e005f61 : Q = (M) AND (1); 1400 : e005f61 : clocks=16; goto (1514) Save original M (address to call) in Q 1514 : 7e03980 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=2(IOR);BRC=0 1514 : 7e03980 : IQN=0;XTR=1;clk=9;sec=1;pri=0; 1514 : 7e03980 : M = (1) IOR (1); 1514 : 7e03980 : clocks=10; goto (1515) Load M with 10 1's 1515 : 4e77504 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1515 : 4e77504 : IQN=0;XTR=1;clk=5;sec=0;pri=4; 1515 : 4e77504 : M = (0) ZTT (0); 1515 : 4e77504 : clocks=6; goto (1115) and 6 0's. M now contains 1777 octal (stack pointer address) 1115 : cf33b80 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=6(IORSBC);BRC=0 1115 : cf33b80 : IQN=0;XTR=1;clk=b;sec=1;pri=0; 1115 : cf33b80 : = (0) IORSBC (); RDM ; 1115 : cf33b80 : clocks=12; goto (1114) Read stack pointer and set BC 1114 : 9f77f01 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 1114 : 9f77f01 : IQN=0;XTR=1;clk=f;sec=0;pri=1; 1114 : 9f77f01 : T = (T) ADD (0); 1114 : 9f77f01 : clocks=16; goto (1014) Add 0's to stack pointer. Since BC is set, this increments it 1014 : cf65b02 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=5(IORCBC);BRC=0 1014 : cf65b02 : IQN=0;XTR=1;clk=b;sec=0;pri=2; 1014 : cf65b02 : = (0) IORCBC (); WTM; 1014 : cf65b02 : clocks=12; goto (1214) Write incremented stack pointer back to location 1777 octal. Clear BC 1214 : 5f07f80 : TTM=0;TTT=1;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 1214 : 5f07f80 : IQN=0;XTR=1;clk=f;sec=1;pri=0; 1214 : 5f07f80 : M = (T) ADD (1); 1214 : 5f07f80 : clocks=16; goto (1215) Add 1's to each bit of the stack pointer (decrementing it), result into M. M therefore ends up containing the address of the Top Of Stack 1215 : 8f45f01 : TTM=1;TTT=0;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=5(IORCBC);BRC=0 1215 : 8f45f01 : IQN=0;XTR=1;clk=f;sec=0;pri=1; 1215 : 8f45f01 : T = (0) IORCBC (P); 1215 : 8f45f01 : clocks=16; goto (1315) Copy currnet PC into T, clear carry 1315 : ce67b80 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=3(ZTT);BRC=0 1315 : ce67b80 : IQN=0;XTR=1;clk=b;sec=1;pri=0; 1315 : ce67b80 : = (0) ZTT (); WTM; 1315 : ce67b80 : clocks=12; goto (1314) Save curent PC on stack. 1314 : 7c55f35 : TTM=0;TTT=1;SC=3(UTS);X=5(TTP);R=5(QTR);ALU=1(AND);BRC=0 1314 : 7c55f35 : IQN=0;XTR=1;clk=f;sec=6;pri=5; 1314 : 7c55f35 : M,P = (1) AND (Q); 1314 : 7c55f35 : clocks=16; goto (1612) Copy Q (address to call) into PC and M. Go and fetch the next instruction from there. JMP (Jump) 1500 : ed75f7b : TTM=1;TTT=1;SC=1(MTS);X=5(TTP);R=7(ZTR);ALU=5(IORCBC);BRC=0 1500 : ed75f7b : IQN=0;XTR=1;clk=f;sec=e;pri=b; 1500 : ed75f7b : P = (M) IORCBC (0); 1500 : ed75f7b : clocks=16; goto (0616) Clear carry, copy current address into PC. Go and execute the instruction in T (which was fetched from that address). ----------------------- Shift Group. On entry to these routine, Q3-Q0 contains the 'shift code' -- the number of bits to shift by -1 (in gneral). The corrent number of shifts are perfomed by shifting by 8 bits if Q3 is set, then by 4 bits if Q2 is set, 2 bits if Q1 is set and 1 more bit if Q0 is set. Finally, one extra bit shift is perfomed (since the shift code is the number of bits to shift -1). Also, the correct accumulator has been selected in hardware. A*R (Arithmetic Shift Right) 0010 : ce12f74 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=0 0010 : ce12f74 : IQN=0;XTR=0;clk=f;sec=e;pri=4; 0010 : ce12f74 : Q6 = (0) IOR (A/B); 0010 : ce12f74 : clocks=16; goto (0406) Rotate accumulator round 16 bits, shifting each bit into Q6. Q6 ends up set to the MSB of the accumulator. 0406 : f68b0f6 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=0(UTR);ALU=2(IOR);BRC=1 0406 : f68b0f6 : IQN=1;XTR=1;clk=0;sec=f;pri=6; 0406 : f68b0f6 : A/B = (1) IOR (1); 0406 : f68b0f6 : clocks=1; IQN(Q6/); if (Q6/) goto (0211,0210) If Q6 clear, then this is equivalent to a right shift (S*R), so go there. Otherwise, it's a shift right, filling up the MSBs with 1's. This is the 'extra' shift to correct for the definition of the shift code. 0211 : f60b703 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=0(UTR);ALU=2(IOR);BRC=0 0211 : f60b703 : IQN=1;XTR=1;clk=7;sec=0;pri=3; 0211 : f60b703 : A/B = (1) IOR (1); 0211 : f60b703 : clocks=8; IQN(Q3/); goto (0111) If Q3 set, shift 8 times, filling with 1's 0111 : f60b302 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=0(UTR);ALU=2(IOR);BRC=0 0111 : f60b302 : IQN=1;XTR=1;clk=3;sec=0;pri=2; 0111 : f60b302 : A/B = (1) IOR (1); 0111 : f60b302 : clocks=4; IQN(Q2/); goto (0311) If Q2 set, shift 4 times, filling with 1's 0311 : f60b111 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=0(UTR);ALU=2(IOR);BRC=0 0311 : f60b111 : IQN=1;XTR=1;clk=1;sec=2;pri=1; 0311 : f60b111 : A/B = (1) IOR (1); 0311 : f60b111 : clocks=2; IQN(Q1/); goto (0213) If Q1 set, shift twice, filling with 1's 0213 : f60b0c0 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=0(UTR);ALU=2(IOR);BRC=0 0213 : f60b0c0 : IQN=1;XTR=1;clk=0;sec=9;pri=0; 0213 : f60b0c0 : A/B = (1) IOR (1); 0213 : f60b0c0 : clocks=1; IQN(Q0/); goto (0202) If Q0 set, shift once, filling with 1, then go to increment PC and fetch next instruction S*R (Shift right). This is also used as part of the A*R routine when the MSB of the selected word is 0. 0210 : c67f703 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 0210 : c67f703 : IQN=1;XTR=1;clk=7;sec=0;pri=3; 0210 : c67f703 : A/B = (0) ZTT (0); 0210 : c67f703 : clocks=8; IQN(Q3/); goto (0110) If Q3 set, shift 8 times, filling with 0's 0110 : c67f302 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 0110 : c67f302 : IQN=1;XTR=1;clk=3;sec=0;pri=2; 0110 : c67f302 : A/B = (0) ZTT (0); 0110 : c67f302 : clocks=4; IQN(Q2/); goto (0310) If Q2 set, shift 4 times, filling with 0's 0310 : c67f111 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 0310 : c67f111 : IQN=1;XTR=1;clk=1;sec=2;pri=1; 0310 : c67f111 : A/B = (0) ZTT (0); 0310 : c67f111 : clocks=2; IQN(Q1/); goto (0212) If Q1 set, shift twice, filling with 0's 0212 : c67f0d0 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 0212 : c67f0d0 : IQN=1;XTR=1;clk=0;sec=b;pri=0; 0212 : c67f0d0 : A/B = (0) ZTT (0); 0212 : c67f0d0 : clocks=1; IQN(Q0/); goto (0201) If Q0 set, shift once, filling with 0. 0201 : c677090 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 0201 : c677090 : IQN=0;XTR=1;clk=0;sec=3;pri=0; 0201 : c677090 : A/B = (0) ZTT (0); 0201 : c677090 : clocks=1; goto (0202) Shift once, filling with 0 (to correct for the definition of the shift code), then go to increment PC and fetch next instruction. S*L (Shift Left), R*R (Rotate Right) This instructions share much microcode. The basic principle is to rotate the accumulator right the correct number of times, shifting the bits into the MSB end of T (initially cleared for a S*L). In the case of a R*R, that's in. For an S*L, And T and the selected accumulator. The appropriate number of MSBs are identical in the 2 registers, and are thus unchanged by the And. The rest of the accumulator is Anded with 0's, and is thus cleared. S*L 0410 : 8e17f01 : TTM=1;TTT=0;SC=0(ZTS);X=7(NOP);R=4(TQ6);ALU=3(ZTT);BRC=0 0410 : 8e17f01 : IQN=0;XTR=1;clk=f;sec=0;pri=1; 0410 : 8e17f01 : T,Q6 = (0) ZTT (); 0410 : 8e17f01 : clocks=16; goto (0510) Clear T and Q(6) (used as a flag to distinugish S*L from R*R), and go to the common S*L/R*R routine R*R 0610 : fe13003 : TTM=1;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=0 0610 : fe13003 : IQN=0;XTR=1;clk=0;sec=0;pri=3; 0610 : fe13003 : Q6 = (1) IOR (); 0610 : fe13003 : clocks=1; goto (0510) Set Q(6) and go to the common routine 0510 : be7a783 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 0510 : be7a783 : IQN=1;XTR=0;clk=7;sec=1;pri=3; 0510 : be7a783 : T = (1) IOR (A/B,0); 0510 : be7a783 : clocks=8; IQN(Q3/); goto (0611) If Q3 set, rotate by 8 bits 0611 : be7a302 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 0611 : be7a302 : IQN=1;XTR=0;clk=3;sec=0;pri=2; 0611 : be7a302 : T = (1) IOR (A/B,0); 0611 : be7a302 : clocks=4; IQN(Q2/); goto (0411) If Q2 set, rotate by 4 bits 0411 : be7a101 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 0411 : be7a101 : IQN=1;XTR=0;clk=1;sec=0;pri=1; 0411 : be7a101 : T = (1) IOR (A/B,0); 0411 : be7a101 : clocks=2; IQN(Q1/); goto (0511) If Q1 set, rotate by 2 bits 0511 : be7a050 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 0511 : be7a050 : IQN=1;XTR=0;clk=0;sec=a;pri=0; 0511 : be7a050 : T = (1) IOR (A/B,0); 0511 : be7a050 : clocks=1; IQN(Q0/); goto (0503) If Q0 set, rotate by 1 bit 0503 : cefe086 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 0503 : cefe086 : IQN=1;XTR=0;clk=0;sec=1;pri=6; 0503 : cefe086 : = (0) ZTT (A/B,0); 0503 : cefe086 : clocks=1; IQN(Q6/); if (Q6/) goto (0302,0303) If this is R*R rotate by one more bit (due to definition of shift code). 0302 : ce77001 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0302 : ce77001 : IQN=0;XTR=1;clk=0;sec=0;pri=1; 0302 : ce77001 : = (0) ZTT (0); 0302 : ce77001 : clocks=1; goto (0202) It's R*R, and it's finished, go to increment PC and fetch next instruction 0303 : d674f81 : TTM=1;TTT=1;SC=2(TTS);X=6(TTX);R=7(ZTR);ALU=1(AND);BRC=0 0303 : d674f81 : IQN=0;XTR=0;clk=f;sec=1;pri=1; 0303 : d674f81 : A/B = (T) AND (A/B,0); 0303 : d674f81 : clocks=16; goto (0202) It's S*L, And in mask value from T, then go to increment PC and fetch next instruction ---------------------- Alter/Skip Group On entry to these routines, Q has been rotated right by 5 bits. So the 'skip offset' is now in Q4-Q0. The 'S' bit is in Q5 and the 'C' bit in Q15 (these are also used to select between SZ*, RZ*, SI*, RI*). The correct accumulator has been selected in hardware. The routines end with Q(6) clear if a skip is to occur, and then go to a common routine which updates the P register. SZ*, RZ*, SI*, RI* 1010 : fff6f95 : TTM=1;TTT=1;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=1 1010 : fff6f95 : IQN=0;XTR=0;clk=f;sec=3;pri=5; 1010 : fff6f95 : = (1) ADD (A/B,0); 1010 : fff6f95 : clocks=16; if (Q5/) goto (1513,1512) Add 1's to all bits of the selected accumulator, discarding the result. This leaves BC set if that accumulator was non-zero. Jump depending on whether it's an S** or R** instruction 1512 : cf170a0 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=4(TQ6);ALU=7(ADD);BRC=0 1512 : cf170a0 : IQN=0;XTR=1;clk=0;sec=5;pri=0; 1512 : cf170a0 : Q6 = (0) ADD (); 1512 : cf170a0 : clocks=1; goto (1517) S** : Add BC to 0, result to Q(6). Q(6) is therefore loaded with the state of BC, and is set if original accumulator non-zero. 1513 : ff17020 : TTM=1;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=7(ADD);BRC=0 1513 : ff17020 : IQN=0;XTR=1;clk=0;sec=4;pri=0; 1513 : ff17020 : Q6 = (1) ADD (); 1513 : ff17020 : clocks=1; goto (1517) R** : Add BC to 1, result in Q(6). Q(6) is loaded with the inverse of BC, and is set if original accumulator zero 1517 : cff30a9 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=6(IORSBC);BRC=1 1517 : cff30a9 : IQN=0;XTR=1;clk=0;sec=5;pri=9; 1517 : cff30a9 : = (0) IORSBC (0); 1517 : cff30a9 : clocks=1; if (Q15/) goto (0412,0413) Set BC and branch depending on whether this is an 'increment' instruction (*I*) or not. 0412 : c776fa4 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0412 : c776fa4 : IQN=0;XTR=0;clk=f;sec=5;pri=4; 0412 : c776fa4 : A/B = (0) ADD (A/B,0); 0412 : c776fa4 : clocks=16; goto (0017) It is an increment instruction. Add 0's to all bits of the selected accumulator. Since BC is set, this increments it. Go to the common skip routine 0413 : ce77024 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0413 : ce77024 : IQN=0;XTR=1;clk=0;sec=4;pri=4; 0413 : ce77024 : = (0) ZTT (0); 0413 : ce77024 : clocks=1; goto (0017) It's not an increment instruction. Just go to the common skip routine. SL* (Skip on LSB of accumulator) 1110 : ce1a08e : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=0 1110 : ce1a08e : IQN=1;XTR=0;clk=0;sec=1;pri=e; 1110 : ce1a08e : Q6 = (0) IOR (A/B); 1110 : ce1a08e : clocks=1; IQN(QDC); goto (0711) Copy LSB of accumulator into Q(6). Since DC is clear (done in hardware when the accumulator is selected), the accumulator is not rotated. 0711 : f68b0f5 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=0(UTR);ALU=2(IOR);BRC=1 0711 : f68b0f5 : IQN=1;XTR=1;clk=0;sec=f;pri=5; 0711 : f68b0f5 : A/B = (1) IOR (1); 0711 : f68b0f5 : clocks=1; IQN(Q5/); if (Q5/) goto (0206,0207) If Q(5) (originally the S bit) is set, shift in a 1 0206 : ce76ec2 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0206 : ce76ec2 : IQN=0;XTR=0;clk=e;sec=9;pri=2; 0206 : ce76ec2 : = (0) ZTT (A/B,0); 0206 : ce76ec2 : clocks=15; goto (0017) And rotate the accumulator by 15 bits. This sets the LSB of the accumulator. 0207 : c6ff089 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=1 0207 : c6ff089 : IQN=1;XTR=1;clk=0;sec=1;pri=9; 0207 : c6ff089 : A/B = (0) ZTT (0); 0207 : c6ff089 : clocks=1; IQN(Q15/); if (Q15/) goto (1306,1307) If S is clear, consider Q(15) (originally C bit). If it's set, shift in a 0 1306 : ce76ecb : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1306 : ce76ecb : IQN=0;XTR=0;clk=e;sec=9;pri=b; 1306 : ce76ecb : = (0) ZTT (A/B,0); 1306 : ce76ecb : clocks=15; goto (0017) And rotate the accumulator by 15 bits. This clears the LSB of the accumulator. Go to the common skip routine 1307 : ce7704b : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1307 : ce7704b : IQN=0;XTR=1;clk=0;sec=8;pri=b; 1307 : ce7704b : = (0) ZTT (0); 1307 : ce7704b : clocks=1; goto (0017) Both S and C both clear. Just go to the common skip routine. S*M (Skip on -ve) 1210 : fe10f86 : TTM=1;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=0(XOR);BRC=0 1210 : fe10f86 : IQN=0;XTR=0;clk=f;sec=1;pri=6; 1210 : fe10f86 : Q6 = (1) XOR (A/B); 1210 : fe10f86 : clocks=16; goto (1411) Shift the inverses of the bits of the accumulator into Q(6). Q(6) ends up set if the accumulator was +ve. S*P (Skip on +ve) 1310 : ce12f87 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=0 1310 : ce12f87 : IQN=0;XTR=0;clk=f;sec=1;pri=7; 1310 : ce12f87 : Q6 = (0) IOR (A/B); 1310 : ce12f87 : clocks=16; goto (1411) Shif the bits of the accumulator into Q(6), which ends up set if the accumulator was -ve. For both S*P and S*M, then 1411 : cefeef5 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 1411 : cefeef5 : IQN=1;XTR=0;clk=e;sec=f;pri=5; 1411 : cefeef5 : = (0) ZTT (A/B,0); 1411 : cefeef5 : clocks=15; IQN(Q5/); if (Q5/) goto (1106,1107) If S was set, rotate accumulator by 15 bits 1106 : f6030c9 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=0(UTR);ALU=2(IOR);BRC=0 1106 : f6030c9 : IQN=0;XTR=1;clk=0;sec=9;pri=9; 1106 : f6030c9 : A/B = (1) IOR (1); 1106 : f6030c9 : clocks=1; goto (0017) and shift in a 1 (to the MSB). Then go to the common skip routine. 1107 : cefeec9 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 1107 : cefeec9 : IQN=1;XTR=0;clk=e;sec=9;pri=9; 1107 : cefeec9 : = (0) ZTT (A/B,0); 1107 : cefeec9 : clocks=15; IQN(Q15/); if (Q15/) goto (0016,0017) Otherwise, if C was set, rotate accumulator by 15 bits. If C clear, go to common skip routine. 0016 : c677080 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=3(ZTT);BRC=0 0016 : c677080 : IQN=0;XTR=1;clk=0;sec=1;pri=0; 0016 : c677080 : A/B = (0) ZTT (0); 0016 : c677080 : clocks=1; goto (0017) C set, shift in a 0 (to the MSB) and go to the common skip routine. SES (Skip on E set) 1410 : fa1902f : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=4(TQ6);ALU=0(XOR);BRC=0 1410 : fa1902f : IQN=1;XTR=1;clk=0;sec=4;pri=f; 1410 : fa1902f : Q6,E = (1) XOR (E); 1410 : fa1902f : clocks=1; IQN(QRD); goto (0314) Set Q(6) to the inverse of the LSB of E. E is not rotated 0314 : ce77001 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0314 : ce77001 : IQN=0;XTR=1;clk=0;sec=0;pri=1; 0314 : ce77001 : = (0) ZTT (0); 0314 : ce77001 : clocks=1; goto (0214) NOP, go to common SES/SEC routine SEC (Skip on E clear) 1510 : ca1b02f : TTM=1;TTT=1;SC=0(ZTS);X=3(TBE);R=4(TQ6);ALU=2(IOR);BRC=0 1510 : ca1b02f : IQN=1;XTR=1;clk=0;sec=4;pri=f; 1510 : ca1b02f : Q6,E = (0) IOR (E); 1510 : ca1b02f : clocks=1; IQN(QRD); goto (0214) Set Q(6) to LSB of E. E is not rotated. Go to the common SES/SEC routine SES and SEC continue : 0214 : fafb3d5 : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=7(ZTR);ALU=2(IOR);BRC=1 0214 : fafb3d5 : IQN=1;XTR=1;clk=3;sec=b;pri=5; 0214 : fafb3d5 : E = (1) IOR (0,E); 0214 : fafb3d5 : clocks=4; IQN(Q5/); if (Q5/) goto (0707,0706) If the S bit was set, fill E with 1's. 0707 : ce77047 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0707 : ce77047 : IQN=0;XTR=1;clk=0;sec=8;pri=7; 0707 : ce77047 : = (0) ZTT (0); 0707 : ce77047 : clocks=1; goto (0017) And go to the common skip routine 0706 : ca7d3f9 : TTM=1;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=1(AND);BRC=0 0706 : ca7d3f9 : IQN=1;XTR=1;clk=3;sec=f;pri=9; 0706 : ca7d3f9 : E = (0) AND (0,E); 0706 : ca7d3f9 : clocks=4; IQN(Q15/); goto (1611) S was clear, if the C bit was set, fill E with 0's 1611 : ce7703e : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1611 : ce7703e : IQN=0;XTR=1;clk=0;sec=6;pri=e; 1611 : ce7703e : = (0) ZTT (0); 1611 : ce7703e : clocks=1; goto (0017) Go to the common skip routine. Common Skip routine On entry, Q(4)-Q(0) contains the skip offset. Q(6) is clear if the skip it to take place. 0017 : 4f55370 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=5(QTR);ALU=5(IORCBC);BRC=0 0017 : 4f55370 : IQN=0;XTR=1;clk=3;sec=e;pri=0; 0017 : 4f55370 : M = (0) IORCBC (Q); 0017 : 4f55370 : clocks=4; goto (0001) Copy 4 LSBs of offset into M. Q(0) now contains the 'sign bit' of the offset, Q(2) the skip flag. 0001 : cef7092 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 0001 : cef7092 : IQN=0;XTR=1;clk=0;sec=3;pri=2; 0001 : cef7092 : = (0) ZTT (0); 0001 : cef7092 : clocks=1; if (Q2/) goto (0202,0203) If Q(2) set, go to incrment the PC and fetch the next instruction (no skip) 0203 : cef70b0 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 0203 : cef70b0 : IQN=0;XTR=1;clk=0;sec=7;pri=0; 0203 : cef70b0 : = (0) ZTT (0); 0203 : cef70b0 : clocks=1; if (Q0/) goto (0204,0205) If there is a skip, sign extend the offset by 0204 : 7f05b58 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=5(IORCBC);BRC=0 0204 : 7f05b58 : IQN=0;XTR=1;clk=b;sec=a;pri=8; 0204 : 7f05b58 : M = (1) IORCBC (1); 0204 : 7f05b58 : clocks=12; goto (1216) Filling the top 12 bits of M with 1's if the sign bit is set 0205 : 4e77bd8 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0205 : 4e77bd8 : IQN=0;XTR=1;clk=b;sec=b;pri=8; 0205 : 4e77bd8 : M = (0) ZTT (0); 0205 : 4e77bd8 : clocks=12; goto (1216) Or filling the top 12 bits of M with 0's if the sign bit is clear 1216 : 6d47f24 : TTM=0;TTT=1;SC=1(MTS);X=5(TTP);R=1(PTR);ALU=7(ADD);BRC=0 1216 : 6d47f24 : IQN=0;XTR=1;clk=f;sec=4;pri=4; 1216 : 6d47f24 : M,P = (M) ADD (P); 1216 : 6d47f24 : clocks=16; goto (1612) Add the offset to P, and store result in P and M. This modifies the current program address by the skip offset. Read the next instruction (no PC increment) and execute it. ---------------------------- Complement-Execute-DMA group 1610 : f6f8fc0 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=7(ZTR);ALU=0(XOR);BRC=1 1610 : f6f8fc0 : IQN=1;XTR=0;clk=f;sec=9;pri=0; 1610 : f6f8fc0 : A/B = (1) XOR (A/B,0); 1610 : f6f8fc0 : clocks=16; IQN(Q0/); if (Q0/) goto (1601,1600) If this is a complement (CM*, TC*) operation, invert all bits of the selected accumulator 1601 : f7fe099 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=1 1601 : f7fe099 : IQN=1;XTR=0;clk=0;sec=3;pri=9; 1601 : f7fe099 : A/B = (1) ADD (A/B,0); 1601 : f7fe099 : clocks=1; IQN(Q15/); if (Q15/) goto (0702,0703) And if it's a TC* (2's complement) operation, add 1 to the LSB of the accumulaotr 0702 : c776e80 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0702 : c776e80 : IQN=0;XTR=0;clk=e;sec=1;pri=0; 0702 : c776e80 : A/B = (0) ADD (A/B,0); 0702 : c776e80 : clocks=15; goto (0703) Add 0's to the remaining 15 bits. This increments the accumulator. 0703 : cf75085 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=5(IORCBC);BRC=0 0703 : cf75085 : IQN=0;XTR=1;clk=0;sec=1;pri=5; 0703 : cf75085 : = (0) IORCBC (0); 0703 : cf75085 : clocks=1; goto (0202) At the end of a complement operation, go and increment the PC and execute the next instruction 1600 : 7e8b089 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=2(IOR);BRC=1 1600 : 7e8b089 : IQN=1;XTR=1;clk=0;sec=1;pri=9; 1600 : 7e8b089 : M = (1) IOR (1); 1600 : 7e8b089 : clocks=1; IQN(Q15/); if (Q15/) goto (0701,0700) It's an EX* (execute) or DMA operation. If DMA, set the MSB of the M register (this is detected by the DMA hardware) 0701 : ce67b51 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=3(ZTT);BRC=0 0701 : ce67b51 : IQN=0;XTR=1;clk=b;sec=a;pri=1; 0701 : ce67b51 : = (0) ZTT (); WTM; 0701 : ce67b51 : clocks=12; goto (0613) Perform a Memory Write operation to trigger the DMA hardware. The power-on diagnostic ends up here on failure. 0613 : 4e72f20 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 0613 : 4e72f20 : IQN=0;XTR=0;clk=f;sec=4;pri=0; 0613 : 4e72f20 : M = (0) IOR (A/B,0); 0613 : 4e72f20 : clocks=16; goto (0617) Copy the A register to M (and thus output it) 0617 : c47703c : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=7(ZTR);ALU=3(ZTT);BRC=0 0617 : c47703c : IQN=0;XTR=1;clk=0;sec=6;pri=c; 0617 : c47703c : = (0) ZTT (0); CAB; 0617 : c47703c : clocks=1; goto (1211) Select the B accumulator 1211 : 4e72fd8 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 1211 : 4e72fd8 : IQN=0;XTR=0;clk=f;sec=b;pri=8; 1211 : 4e72fd8 : M = (0) IOR (A/B,0); 1211 : 4e72fd8 : clocks=16; goto (0202) Output the B register via M. The hardware will then halt the CPU here. When it's allowed to continue. go and increment PC, execute the next instruction. 0700 : 8f74f71 : TTM=1;TTT=0;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=5(IORCBC);BRC=0 0700 : 8f74f71 : IQN=0;XTR=0;clk=f;sec=e;pri=1; 0700 : 8f74f71 : T = (0) IORCBC (A/B,0); 0700 : 8f74f71 : clocks=16; goto (0616) EX* instruction. Copy selected accumulator into T. Then go to copy it into Q (as an instruction), and execute it. ----------------------------- Register Refeerence Group These instructions take data initially from the selected accumulator. They have an opcode (originally in bits 4-7) which is identical to the opcode in the bits 11-14 of the corresponding memory reference instruction. Q has been rotated, so this opcode is now in bits 15,0,1,2, with the indirect bit (originally bit 8) in Q(3). 1710 : 8e72f34 : TTM=1;TTT=0;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 1710 : 8e72f34 : IQN=0;XTR=0;clk=f;sec=6;pri=4; 1710 : 8e72f34 : T = (0) IOR (A/B,0); 1710 : 8e72f34 : clocks=16; goto (1316) Copy selected initially selected accumulator into T. 1316 : ce57352 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=5(QTR);ALU=3(ZTT);BRC=0 1316 : ce57352 : IQN=0;XTR=1;clk=3;sec=a;pri=2; 1316 : ce57352 : = (0) ZTT (Q); 1316 : ce57352 : clocks=4; goto (1104) Rotate Q by 4 bits. This puts the secondary opcode into Q(11)-Q(14) with the 'indirect' bit in Q(15) 1104 : c8f70b9 : TTM=1;TTT=1;SC=0(ZTS);X=1(QAB);R=7(ZTR);ALU=3(ZTT);BRC=1 1104 : c8f70b9 : IQN=0;XTR=1;clk=0;sec=7;pri=9; 1104 : c8f70b9 : = (0) ZTT (0); QAB; 1104 : c8f70b9 : clocks=1; if (Q15/) goto (0003,0002) If the 'indirect' bit is clear, go to the memory reference instruction decode QmuJmp to execute this instruction (with T as data). If it's set, go to the indirect address loop (which will treat T as an address). ------------------------ I/O instructions. Much of the I/O operation is handled by hardware on the clock and I/O interface PCBs. The routine here sets up the right conditions in the main CPU, and starts the I/O 'processor'. The I/O processor can set the BC flag, thus causing a skip when the PC is incremented at the end of the instruction 0217 : ce4e1a7 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=0 0217 : ce4e1a7 : IQN=1;XTR=0;clk=1;sec=5;pri=7; 0217 : ce4e1a7 : = (0) ZTT (A/B,P); IOS; 0217 : ce4e1a7 : clocks=2; IQN(QBC); goto (0512) Start the I/O operation (set the I/O flip-flop on the clock PCB) 0512 : ce731ef : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=0 0512 : ce731ef : IQN=0;XTR=1;clk=1;sec=d;pri=f; 0512 : ce731ef : = (0) IOR (0); 0512 : ce731ef : clocks=2; goto (1207) Set the ALU for IOR (used by the MI* instructions). 1207 : cef31ef : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=2(IOR);BRC=1 1207 : cef31ef : IQN=0;XTR=1;clk=1;sec=d;pri=f; 1207 : cef31ef : = (0) IOR (0); 1207 : cef31ef : clocks=2; if (QRD) goto (0512,0513) Keep the ALU doing IORs. Check to see if the I/O processor has finished. If not, round again. 0513 : ce770c7 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0513 : ce770c7 : IQN=0;XTR=1;clk=0;sec=9;pri=7; 0513 : ce770c7 : = (0) ZTT (0); 0513 : ce770c7 : clocks=1; goto (0202) I/O complete. Go to increment PC and execute next instruction (as mentioned above, the I/O hardware can set the BC flag, causing a skip). ----------------------- Macro Group. The opcode decoding logic for these instructions uses a sequence of conditional branches rather than a QmuJMP. 0216 : ced709d : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=5(QTR);ALU=3(ZTT);BRC=1 0216 : ced709d : IQN=0;XTR=1;clk=0;sec=3;pri=d; 0216 : ced709d : = (0) ZTT (Q); 0216 : ced709d : clocks=1; if (Q8/) goto (1715,1714) Rotate Q right one bit, and test Q(8). The hardware design causes the _old_ value of Q(8) to be tested. This therefore separates the MOV, CLR and XFR instructions from the rest. MOV,CLR,XFR continue : 1714 : 8ef5fc0 : TTM=1;TTT=0;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=1(AND);BRC=1 1714 : 8ef5fc0 : IQN=0;XTR=1;clk=f;sec=9;pri=0; 1714 : 8ef5fc0 : T = (0) AND (0); 1714 : 8ef5fc0 : clocks=16; if (Q0/) goto (1705,1704) Clear T. Test bit Q(0), which used to be Q(1) to detect the MOV instruction MOV : (Move Overflow) 1705 : fa25fbd : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=2(TRE);ALU=1(AND);BRC=0 1705 : fa25fbd : IQN=0;XTR=1;clk=f;sec=7;pri=d; 1705 : fa25fbd : A/B = (1) AND (E,E); E=0; 1705 : fa25fbd : clocks=16; goto (0202) Shfit E into A (selected in hardware), and fill E with 0's. Shift by 16 bits, so origianl E (overflow flag) ends up in the bottom 4 bits of A, rest of A and E is cleared. Go and increment PC, fetch next instruction CLR,XFR : 1704 : 7ef4f81 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=1(AND);BRC=1 1704 : 7ef4f81 : IQN=0;XTR=0;clk=f;sec=1;pri=1; 1704 : 7ef4f81 : M = (1) AND (A/B,0); 1704 : 7ef4f81 : clocks=16; if (Q1/) goto (1605,1604) Copy A (selected in hardware), which contains the address of the floating point pseudoregister into M. Test bit Q(1) (used to be Q(2)) to distinguish between the 2 instructions CLR : (Clear floating point pseudoregister) 1604 : cfe3b8d : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=6(IORSBC);BRC=1 1604 : cfe3b8d : IQN=0;XTR=1;clk=b;sec=1;pri=d; 1604 : cfe3b8d : = (0) IORSBC (); WTM; 1604 : cfe3b8d : clocks=12; if (Q8/) goto (0305,0304) Write T (cleared in state 1714) into current address in the pseudoregister. Set BC (needed to increment M later on). Test to see if the clear is complete, which occurs when bit Q(8) is set (having had the bit in Q(11) shifted into it). 0304 : ce57006 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=5(QTR);ALU=3(ZTT);BRC=0 0304 : ce57006 : IQN=0;XTR=1;clk=0;sec=0;pri=6; 0304 : ce57006 : = (0) ZTT (Q); 0304 : ce57006 : clocks=1; goto (0504) Rotate Q right one bit, thus 'incrementing' the word counter (A '1' moves towards Q(8)).. 0504 : 6f77f0b : TTM=0;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 0504 : 6f77f0b : IQN=0;XTR=1;clk=f;sec=0;pri=b; 0504 : 6f77f0b : M = (M) ADD (0); 0504 : 6f77f0b : clocks=16; goto (1604) Increment M to point to the next word of the pseudoregister, and go round again. 0305 : cf710b1 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 0305 : cf710b1 : IQN=0;XTR=1;clk=0;sec=7;pri=1; 0305 : cf710b1 : = (0) ZTTCBC (0); 0305 : cf710b1 : clocks=1; goto (0202) The CLR is complete. Clear BC and go to increment PC and fetch next instruction. XFR : (Transfer 1 floating point pseudoregister to another) 1605 : c535b48 : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=6(RDM);ALU=5(IORCBC);BRC=0 1605 : c535b48 : IQN=0;XTR=1;clk=b;sec=8;pri=8; 1605 : c535b48 : = (0) IORCBC (); RDM ;CAB; 1605 : c535b48 : clocks=12; goto (0615) Read first word of the 1st pseudoregister (pointed to by A, transfered into M in state 1704). Clear BC. Select B 0615 : 4776f05 : TTM=0;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0615 : 4776f05 : IQN=0;XTR=0;clk=f;sec=0;pri=5; 0615 : 4776f05 : M,A/B = (0) ADD (A/B,0); 0615 : 4776f05 : clocks=16; goto (0315) On all but first time through the loop, increment B (destination address). Copy it into M (always). 0315 : c5e3b8d : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=3(WTM);ALU=6(IORSBC);BRC=1 0315 : c5e3b8d : IQN=0;XTR=1;clk=b;sec=1;pri=d; 0315 : c5e3b8d : = (0) IORSBC (); WTM; CAB; 0315 : c5e3b8d : clocks=12; if (Q8/) goto (1614,1615) Write word to second pseudoregister, set BC, select A. Test to see if all words have been transfered (the 1 in Q(11) has got to Q(8)) 1615 : ce5700a : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=5(QTR);ALU=3(ZTT);BRC=0 1615 : ce5700a : IQN=0;XTR=1;clk=0;sec=0;pri=a; 1615 : ce5700a : = (0) ZTT (Q); 1615 : ce5700a : clocks=1; goto (0415) There are still words to tranfer : Rotate Q right 1 bit to 'increment' the word counter. 0415 : 4776f82 : TTM=0;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0415 : 4776f82 : IQN=0;XTR=0;clk=f;sec=1;pri=2; 0415 : 4776f82 : M,A/B = (0) ADD (A/B,0); 0415 : 4776f82 : clocks=16; goto (0614) Increment A (source address), and copy to M. 0614 : c533b80 : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=6(RDM);ALU=6(IORSBC);BRC=0 0614 : c533b80 : IQN=0;XTR=1;clk=b;sec=1;pri=0; 0614 : c533b80 : = (0) IORSBC (); RDM ;CAB; 0614 : c533b80 : clocks=12; goto (0615) Read next word from first pseudoregister, set BC (so that B is incremented this time round the loop), select B, go round again. 1614 : cf7107c : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 1614 : cf7107c : IQN=0;XTR=1;clk=0;sec=e;pri=c; 1614 : cf7107c : = (0) ZTTCBC (0); 1614 : cf7107c : clocks=1; goto (0202) All words transfered : Clear BC (needed by PC increment routine), go and increment PC, fetch next instruction. --- 1715 : ce950d0 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=4(TQ6);ALU=1(AND);BRC=1 1715 : ce950d0 : IQN=0;XTR=1;clk=0;sec=b;pri=0; 1715 : ce950d0 : Q6 = (0) AND (); 1715 : ce950d0 : clocks=1; if (Q0/) goto (1706,1707) Clear Q(6) (used as a flag for the end of instruction), test Q(0) (old Q(1)). Branch as follows : 1706 : RET 1707 : MRX, MRY, MLS, DLS, DRS, FXA, FMP, FDV, CMX, CMY, MDI, NRM RET continues : 1706 : 7e13942 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=0 1706 : 7e13942 : IQN=0;XTR=1;clk=9;sec=8;pri=2; 1706 : 7e13942 : M,Q6 = (1) IOR (); 1706 : 7e13942 : clocks=10; goto (1516) Set Q(6) (RET doesn't loop), load 10 1's into M 1516 : 4e75501 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=1(AND);BRC=0 1516 : 4e75501 : IQN=0;XTR=1;clk=5;sec=0;pri=1; 1516 : 4e75501 : M = (0) AND (0); 1516 : 4e75501 : clocks=6; goto (1416) And 6 0's into M. M now cotains 1777 octal, the stack pointer address. 1416 : cf35b80 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=5(IORCBC);BRC=0 1416 : cf35b80 : IQN=0;XTR=1;clk=b;sec=1;pri=0; 1416 : cf35b80 : = (0) IORCBC (); RDM ; 1416 : cf35b80 : clocks=12; goto (1417) Read in stack pointer, clear BC 1417 : 9f07f70 : TTM=1;TTT=0;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 1417 : 9f07f70 : IQN=0;XTR=1;clk=f;sec=e;pri=0; 1417 : 9f07f70 : T = (T) ADD (1); 1417 : 9f07f70 : clocks=16; goto (1401) Decrement stack pointer (by adding 1's to all bits). Continue at the common routine Other instructions continue : 1707 : 4f71544 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 1707 : 4f71544 : IQN=0;XTR=1;clk=5;sec=8;pri=4; 1707 : 4f71544 : M = (0) ZTTCBC (0); 1707 : 4f71544 : clocks=6; goto (1317) Clear BC, shift 6 0's into M 1317 : 7803370 : TTM=0;TTT=1;SC=3(UTS);X=1(QAB);R=0(UTR);ALU=2(IOR);BRC=0 1317 : 7803370 : IQN=0;XTR=1;clk=3;sec=e;pri=0; 1317 : 7803370 : M = (1) IOR (1); QAB; 1317 : 7803370 : clocks=4; goto (1301) Shift 4 1's into M 1301 : 44f7596 : TTM=0;TTT=1;SC=0(ZTS);X=4(CAB);R=7(ZTR);ALU=3(ZTT);BRC=1 1301 : 44f7596 : IQN=0;XTR=1;clk=5;sec=3;pri=6; 1301 : 44f7596 : M = (0) ZTT (0); CAB; 1301 : 44f7596 : clocks=6; if (Q6/) goto (1502,1503) And another 6 0's. M now contains 1700 octal -- the PC storage address. Select other accumulator. Test to see if instruction is starting or ending 1503 : be45f11 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=1(PTR);ALU=1(AND);BRC=0 1503 : be45f11 : IQN=0;XTR=1;clk=f;sec=2;pri=1; 1503 : be45f11 : T = (1) AND (P); 1503 : be45f11 : clocks=16; goto (1401) It's starting. Copy program counter into T, so it can be saved. 1401 : cfe3b90 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=6(IORSBC);BRC=1 1401 : cfe3b90 : IQN=0;XTR=1;clk=b;sec=3;pri=0; 1401 : cfe3b90 : = (0) IORSBC (); WTM; 1401 : cfe3b90 : clocks=12; if (Q0/) goto (1402,1403) RET continues here also. Save decremented stack pointer (for RET), or program counter (for everything else). Set BC. Test to see if the instruction is a RET or not. 1402 : 5e05f01 : TTM=0;TTT=1;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=1(AND);BRC=0 1402 : 5e05f01 : IQN=0;XTR=1;clk=f;sec=0;pri=1; 1402 : 5e05f01 : M = (T) AND (1); 1402 : 5e05f01 : clocks=16; goto (1502) RET instruction : Copy stack pointer value into M so that the top of stack can be read 1403 : 4f77f81 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 1403 : 4f77f81 : IQN=0;XTR=1;clk=f;sec=1;pri=1; 1403 : 4f77f81 : M = (0) ADD (0); 1403 : 4f77f81 : clocks=16; goto (1502) Everything else. Load M with 0+0+1 (from BC). This loads M with 1, the counter constant address 1502 : cfb5b86 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=5(IORCBC);BRC=1 1502 : cfb5b86 : IQN=0;XTR=1;clk=b;sec=1;pri=6; 1502 : cfb5b86 : = (0) IORCBC (); RDM ; 1502 : cfb5b86 : clocks=12; if (Q6/) goto (1303,1302) Read in the addressed location. This is either the top of stack (RET instruction), the counter constant (other instructions when starting) or the saved program counter (other instructions when ending). Test to see if the instruction is ending 1303 : dc05f89 : TTM=1;TTT=1;SC=2(TTS);X=5(TTP);R=0(UTR);ALU=1(AND);BRC=0 1303 : dc05f89 : IQN=0;XTR=1;clk=f;sec=1;pri=9; 1303 : dc05f89 : P = (T) AND (1); 1303 : dc05f89 : clocks=16; goto (0202) End of instruction. Copy T into program counter. This either restores the original PC, or loads it with the value popped from the subroutine stack as appropriate. Go and increment the program counter and fetch the next instruction --- 1302 : dc05f92 : TTM=1;TTT=1;SC=2(TTS);X=5(TTP);R=0(UTR);ALU=1(AND);BRC=0 1302 : dc05f92 : IQN=0;XTR=1;clk=f;sec=3;pri=2; 1302 : dc05f92 : P = (T) AND (1); 1302 : dc05f92 : clocks=16; goto (1101) Copy the counter constant into P. 1101 : fbf73a2 : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=7(ZTR);ALU=7(ADD);BRC=1 1101 : fbf73a2 : IQN=0;XTR=1;clk=3;sec=5;pri=2; 1101 : fbf73a2 : E = (1) ADD (0,E); 1101 : fbf73a2 : clocks=4; if (Q2/) goto (1304,1305) Decrement E, Branch on Q(2) (old Q(3)) as follows : 1304: MRX, MRY, DRS, NRM 1305: MLS, DLS, FXA, FMP, FDV, CMX, CMY, MDI 1305 : 7e93283 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=1 1305 : 7e93283 : IQN=0;XTR=1;clk=2;sec=1;pri=3; 1305 : 7e93283 : M,Q6 = (1) IOR (); 1305 : 7e93283 : clocks=3; if (Q3/) goto (1004,1005) Set Q(6). Shift 3 1's into M. Branch on Q(3) (old Q(4)) as follows : 1004: FXA, FDV, FMP 1005: MLS, DLS, CMX, CMY, MDI 1004 : 4ef51b7 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=1(AND);BRC=1 1004 : 4ef51b7 : IQN=0;XTR=1;clk=1;sec=7;pri=7; 1004 : 4ef51b7 : M = (0) AND (0); 1004 : 4ef51b7 : clocks=2; if (QBC) goto (1703,1702) Shift 2 0's into M. 1703 : c201180 : TTM=1;TTT=1;SC=0(ZTS);X=2(BCD);R=0(UTR);ALU=0(XOR);BRC=0 1703 : c201180 : IQN=0;XTR=1;clk=1;sec=1;pri=0; 1703 : c201180 : SDC; 1703 : c201180 : clocks=2; goto (1702) If BC was set (that is, if E was 1111(2)), set DC 1702 : 7505433 : TTM=0;TTT=1;SC=3(UTS);X=4(CAB);R=0(UTR);ALU=5(IORCBC);BRC=0 1702 : 7505433 : IQN=0;XTR=1;clk=4;sec=6;pri=3; 1702 : 7505433 : M = (1) IORCBC (1); CAB; 1702 : 7505433 : clocks=5; goto (1404) shift 5 1's into M. Clear BC. Select other accumulator 1404 : 4af55bd : TTM=0;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=1(AND);BRC=1 1404 : 4af55bd : IQN=0;XTR=1;clk=5;sec=7;pri=d; 1404 : 4af55bd : M,E = (0) AND (0,E); 1404 : 4af55bd : clocks=6; if (Q8/) goto (0103,0102) Clear E. Shift 6 0's into M. M now points to highest word in AR1. Branch on Q(8) (original Q(9) as follows : 0102: FXA, FDV 0103: FMP 0102 : ce77020 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0102 : ce77020 : IQN=0;XTR=1;clk=0;sec=4;pri=0; 0102 : ce77020 : = (0) ZTT (0); 0102 : ce77020 : clocks=1; goto (0106) NOP to get the branch to fit correctly --- 0103 : f776307 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0103 : f776307 : IQN=0;XTR=0;clk=3;sec=0;pri=7; 0103 : f776307 : A/B = (1) ADD (A/B,0); 0103 : f776307 : clocks=4; goto (0603) FMP continues by decrementing the lowest nybble of B (which is currently selected) and 0603 : cef6ba7 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 0603 : cef6ba7 : IQN=0;XTR=0;clk=b;sec=5;pri=7; 0603 : cef6ba7 : = (0) ZTT (A/B,0); 0603 : cef6ba7 : clocks=12; if (QBC) goto (0106,0107) Shifting it back into the right place. If B was decremented past 0, then this is the end of the instruction. BC is then clear. 0107 : c47701c : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=7(ZTR);ALU=3(ZTT);BRC=0 0107 : c47701c : IQN=0;XTR=1;clk=0;sec=2;pri=c; 0107 : c47701c : = (0) ZTT (0); CAB; 0107 : c47701c : clocks=1; goto (1505) End of FMP. Select A 1505 : fa25f12 : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=2(TRE);ALU=1(AND);BRC=0 1505 : fa25f12 : IQN=0;XTR=1;clk=f;sec=2;pri=2; 1505 : fa25f12 : A/B = (1) AND (E,E); E=0; 1505 : fa25f12 : clocks=16; goto (1707) Copy E into lowest nybble of A. Clear E and rest of A. Go to end of instructuction routine. This is the main loop for the FMP, FDV and FXA instructions. It basically has to add the mantissa of AR2 to that of AR1, and repeat it the right number of times (the difference between these instructions is the exit condition) 0106 : c437b04 : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=6(RDM);ALU=3(ZTT);BRC=0 0106 : c437b04 : IQN=0;XTR=1;clk=b;sec=0;pri=4; 0106 : c437b04 : = (0) ZTT (); RDM ;CAB; 0106 : c437b04 : clocks=12; goto (0506) Read in the next word of AR1. Select accumulator A 0506 : d605f40 : TTM=1;TTT=1;SC=2(TTS);X=6(TTX);R=0(UTR);ALU=1(AND);BRC=0 0506 : d605f40 : IQN=0;XTR=1;clk=f;sec=8;pri=0; 0506 : d605f40 : A/B = (T) AND (1); 0506 : d605f40 : clocks=16; goto (0516) Copy the next word of AR1 into A 0516 : ef73280 : TTM=1;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=6(IORSBC);BRC=0 0516 : ef73280 : IQN=0;XTR=1;clk=2;sec=1;pri=0; 0516 : ef73280 : = (M) IORSBC (0); 0516 : ef73280 : clocks=3; goto (0517) Rotate M right by 3 bits (this puts the bit that's different between AR1 and AR2 in the LSB), set carry 0517 : 6f77c04 : TTM=0;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 0517 : 6f77c04 : IQN=0;XTR=1;clk=c;sec=0;pri=4; 0517 : 6f77c04 : M = (M) ADD (0); 0517 : 6f77c04 : clocks=13; goto (0117) Increment the LSB of the rotated address, rotate it back to the right place. M now points to the corresponding word in AR2 0117 : ce37b70 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=3(ZTT);BRC=0 0117 : ce37b70 : IQN=0;XTR=1;clk=b;sec=e;pri=0; 0117 : ce37b70 : = (0) ZTT (); RDM ; 0117 : ce37b70 : clocks=12; goto (0101) Read in the next word of AR2 0101 : ce47037 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=0 0101 : ce47037 : IQN=0;XTR=1;clk=0;sec=6;pri=7; 0101 : ce47037 : = (0) ZTT (P); 0101 : ce47037 : clocks=1; goto (0607) This is the start of the digit addition loop for the 2 words. Shift PC right one bit to 'increment' the counter. The counter constant looks like 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 0 # * $ * $ * in binary. Bits marked with a '*' cause the current word to be ended when they get to bit 0. Bits marked with a '$' cause the next word to be fetched wben they get to bit 0. The bit marked with a '#' causes the complete loop to end. 0607 : d27e12f : TTM=1;TTT=1;SC=2(TTS);X=2(BCD);R=7(ZTR);ALU=3(ZTT);BRC=0 0607 : d27e12f : IQN=1;XTR=0;clk=1;sec=4;pri=f; 0607 : d27e12f : T = (T) BCDADD (A/B,0); 0607 : d27e12f : clocks=2; IQN(QRD); goto (1103) Add the next digits from the 2 words 1103 : bef4398 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=1(AND);BRC=1 1103 : bef4398 : IQN=0;XTR=0;clk=3;sec=3;pri=8; 1103 : bef4398 : T = (1) AND (A/B,0); 1103 : bef4398 : clocks=4; if (QPO) goto (0100,0101) Shift the sum nybble back into T (which accumulates the BCD sum of the 2 words). Tset to see if the current word is completed. If not, round again. 0100 : ce47087 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=0 0100 : ce47087 : IQN=0;XTR=1;clk=0;sec=1;pri=7; 0100 : ce47087 : = (0) ZTT (P); 0100 : ce47087 : clocks=1; goto (0601) Shift the counter (in P) right one bit. This moves the 'any more words' test bit into bit 0. 0601 : c4e7bb8 : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=3(WTM);ALU=3(ZTT);BRC=1 0601 : c4e7bb8 : IQN=0;XTR=1;clk=b;sec=7;pri=8; 0601 : c4e7bb8 : = (0) ZTT (); WTM; CAB; 0601 : c4e7bb8 : clocks=12; if (QPO) goto (1606,1607) Save the sum back into AR2. Select accumulator B. Test to see if there are any more words to add. 1606 : 6f07246 : TTM=0;TTT=1;SC=1(MTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 1606 : 6f07246 : IQN=0;XTR=1;clk=2;sec=8;pri=6; 1606 : 6f07246 : M = (M) ADD (1); 1606 : 6f07246 : clocks=3; goto (1016) Yes, there are more words. Decrement the least significat octal digit of the address, to point to the previous word in the arithmetic pseudoregister. 1016 : 6f77009 : TTM=0;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 1016 : 6f77009 : IQN=0;XTR=1;clk=0;sec=0;pri=9; 1016 : 6f77009 : M = (M) ADD (0); 1016 : 6f77009 : clocks=1; goto (0116) Flip the next bit to point to AR1 again. 0116 : ee77b40 : TTM=1;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0116 : ee77b40 : IQN=0;XTR=1;clk=b;sec=8;pri=0; 0116 : ee77b40 : = (M) ZTT (0); 0116 : ee77b40 : clocks=12; goto (0106) And rotate M to get the bits back in the right place. Go round the loop again. 1607 : cf7b07e : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=6(IORSBC);BRC=0 1607 : cf7b07e : IQN=1;XTR=1;clk=0;sec=e;pri=e; 1607 : cf7b07e : = (0) IORSBC (0); 1607 : cf7b07e : clocks=1; IQN(QDC); goto (0011) The loop is completed. If there's a DC, then set BC. 0011 : fe930d4 : TTM=1;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=2(IOR);BRC=1 0011 : fe930d4 : IQN=0;XTR=1;clk=0;sec=b;pri=4; 0011 : fe930d4 : Q6 = (1) IOR (); 0011 : fe930d4 : clocks=1; if (Q4/) goto (0402,0403) Set Q(6) (This might be the end of the complete instruction). Test if this is FDV (Q(4)=0) or not. 0403 : cef708e : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 0403 : cef708e : IQN=0;XTR=1;clk=0;sec=1;pri=e; 0403 : cef708e : = (0) ZTT (0); 0403 : cef708e : clocks=1; if (QDC) goto (1202,1203) FDV : Exit if DC set (overflow). 0402 : cb773db : TTM=1;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=7(ADD);BRC=0 0402 : cb773db : IQN=0;XTR=1;clk=3;sec=b;pri=b; 0402 : cb773db : E = (0) ADD (0,E); 0402 : cb773db : clocks=4; goto (1711) FXA or FDMP : Incrment E if there was an overflow (BC set in state 1607). 1711 : cef70d5 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 1711 : cef70d5 : IQN=0;XTR=1;clk=0;sec=b;pri=5; 1711 : cef70d5 : = (0) ZTT (0); 1711 : cef70d5 : clocks=1; if (Q5/) goto (1202,1203) Test if this is FXA (Q(5)=1) or not. 1202 : 4f715e1 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 1202 : 4f715e1 : IQN=0;XTR=1;clk=5;sec=d;pri=1; 1202 : 4f715e1 : M = (0) ZTTCBC (0); 1202 : 4f715e1 : clocks=6; goto (1317) FXA must be completed after one loop, FDV ends up here when it's completed. Clear BC, shift 6 zeros into M (start of PC save address), jump back to restore PC and exit. 1203 : 7f0323e : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=6(IORSBC);BRC=0 1203 : 7f0323e : IQN=0;XTR=1;clk=2;sec=6;pri=e; 1203 : 7f0323e : M = (1) IORSBC (1); 1203 : 7f0323e : clocks=3; goto (0405) FMP, FDV continues here. Set BC, shift 3 1s into M 0405 : 4e45008 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=1(AND);BRC=0 0405 : 4e45008 : IQN=0;XTR=1;clk=0;sec=0;pri=8; 0405 : 4e45008 : M = (0) AND (P); 0405 : 4e45008 : clocks=1; goto (1405) Shift a 0 into M. Rotate P right one bit, thus restoring the original counter constant value. 1405 : e8f7b8d : TTM=1;TTT=1;SC=1(MTS);X=1(QAB);R=7(ZTR);ALU=3(ZTT);BRC=1 1405 : e8f7b8d : IQN=0;XTR=1;clk=b;sec=1;pri=d; 1405 : e8f7b8d : = (M) ZTT (0); QAB; 1405 : e8f7b8d : clocks=12; if (Q8/) goto (0104,0105) Rotate M right 12 bits (Restoring pointer to last word of AR1). Select accumulator B. Test if this is FDV or FMP 0105 : c776f90 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0105 : c776f90 : IQN=0;XTR=0;clk=f;sec=3;pri=0; 0105 : c776f90 : A/B = (0) ADD (A/B,0); 0105 : c776f90 : clocks=16; goto (0106) FDV : Increment B (number of possible additions), go round again. 0104 : cf710b0 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 0104 : cf710b0 : IQN=0;XTR=1;clk=0;sec=7;pri=0; 0104 : cf710b0 : = (0) ZTTCBC (0); 0104 : cf710b0 : clocks=1; goto (0103) FMP : Clear BC and go to decrement B and see if the loop is finished --------------- MRX, MRY, DRS, NRM continue here 1304 : 7f150f7 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=5(IORCBC);BRC=0 1304 : 7f150f7 : IQN=0;XTR=1;clk=0;sec=f;pri=7; 1304 : 7f150f7 : M,Q6 = (1) IORCBC (); 1304 : 7f150f7 : clocks=1; goto (1413) Set Q(6). Shift a 1 into M 1413 : 7f871e4 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=1 1413 : 7f871e4 : IQN=0;XTR=1;clk=1;sec=d;pri=4; 1413 : 7f871e4 : M = (1) ADD (1); 1413 : 7f871e4 : clocks=2; if (Q4/) goto (1006,1007) Shift 1 0 into M (M now has 101 shifted into it -- the lowest digit of the addrress of the mantissa). Branch on Q(4) (old Q(5)) to split MRY and NRM from MRX and DRS 1006 : 7f050b0 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=5(IORCBC);BRC=0 1006 : 7f050b0 : IQN=0;XTR=1;clk=0;sec=7;pri=0; 1006 : 7f050b0 : M = (1) IORCBC (1); 1006 : 7f050b0 : clocks=1; goto (1001) NRM and MRY : Shift a 1 into M (next bit of AR2 address) 1007 : 4f75030 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=5(IORCBC);BRC=0 1007 : 4f75030 : IQN=0;XTR=1;clk=0;sec=6;pri=0; 1007 : 4f75030 : M = (0) IORCBC (0); 1007 : 4f75030 : clocks=1; goto (1001) DRS and MRX : Shift a 0 into M (next bit of AR1 address) 1001 : 7f875b4 : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=1 1001 : 7f875b4 : IQN=0;XTR=1;clk=5;sec=7;pri=4; 1001 : 7f875b4 : M = (1) ADD (1); 1001 : 7f875b4 : clocks=6; if (Q4/) goto (1406,1407) Shift 111110 into M. This forms the rest of both AR1 and AR2 address. Branch on Q(4) again. 1406 : 4bf15e3 : TTM=0;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=4(ZTTCBC);BRC=1 1406 : 4bf15e3 : IQN=0;XTR=1;clk=5;sec=d;pri=3; 1406 : 4bf15e3 : M,E = (0) ZTTCBC (0,E); 1406 : 4bf15e3 : clocks=6; if (Q3/) goto (1713,1712) MRY and NRM : Shift 6 0's into M (M now contains 0 000 001 111 10x 101 -- address of first word of manitssa of required arithmetic pseudoregister). Branch on Q(3) (original Q(4)) to split MRY and NRM. 1407 : 4bf15eb : TTM=0;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=4(ZTTCBC);BRC=1 1407 : 4bf15eb : IQN=0;XTR=1;clk=5;sec=d;pri=b; 1407 : 4bf15eb : M,E = (0) ZTTCBC (0,E); 1407 : 4bf15eb : clocks=6; if (Q10/) goto (0712,0713) MRX and DRS : Shift 6 0's into M (M now contains address of first mantissa word as above). Branch on Q(10) to split MRX and DRS --- 1713 : fa74307 : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=7(ZTR);ALU=1(AND);BRC=0 1713 : fa74307 : IQN=0;XTR=0;clk=3;sec=0;pri=7; 1713 : fa74307 : E = (1) AND (A/B,0,E); 1713 : fa74307 : clocks=4; goto (1013) MRY : Shift lowest nybble of A (to be shifted into the arithmetic pseudoregister) into E 0712 : fa7438f : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=7(ZTR);ALU=1(AND);BRC=0 0712 : fa7438f : IQN=0;XTR=0;clk=3;sec=1;pri=f; 0712 : fa7438f : E = (1) AND (A/B,0,E); 0712 : fa7438f : clocks=4; goto (1013) MRX : Shift lowset nybble of A into E. 1013 : c535b3d : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=6(RDM);ALU=5(IORCBC);BRC=0 1013 : c535b3d : IQN=0;XTR=1;clk=b;sec=6;pri=d; 1013 : c535b3d : = (0) IORCBC (); RDM ;CAB; 1013 : c535b3d : clocks=12; goto (0515) Start of shift loop for MRX and MRY. Read in first mantissa word of selected pseudoregister. Select accumulator B (which contains the shift count). 0515 : f776343 : TTM=1;TTT=1;SC=3(UTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 0515 : f776343 : IQN=0;XTR=0;clk=3;sec=8;pri=3; 0515 : f776343 : A/B = (1) ADD (A/B,0); 0515 : f776343 : clocks=4; goto (0605) Decement lowest nybble of B (shift count). BC is set if it decrements past 0. 0605 : cef6bc7 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 0605 : cef6bc7 : IQN=0;XTR=0;clk=b;sec=9;pri=7; 0605 : cef6bc7 : = (0) ZTT (A/B,0); 0605 : cef6bc7 : clocks=12; if (QBC) goto (0114,0115) And shift it back in to the right place. Test to see if it decemented past 0 (and thus the shift is finished). If not, go to the shift-right-one- nybble loop at 0114 0115 : 4f7151a : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 0115 : 4f7151a : IQN=0;XTR=1;clk=5;sec=2;pri=a; 0115 : 4f7151a : M = (0) ZTTCBC (0); 0115 : 4f7151a : clocks=6; goto (1317) Shift has finished. Shift 6 0's into M (start of program counter save address. and go to restore PC and continue. --- 0713 : c437bb6 : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=6(RDM);ALU=3(ZTT);BRC=0 0713 : c437bb6 : IQN=0;XTR=1;clk=b;sec=7;pri=6; 0713 : c437bb6 : = (0) ZTT (); RDM ;CAB; 0713 : c437bb6 : clocks=12; goto (0114) DRS : THis is also the start of the shift-right-one-nybble loop. Read in next word of AR2. 0114 : be25304 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=2(TRE);ALU=1(AND);BRC=0 0114 : be25304 : IQN=0;XTR=1;clk=3;sec=0;pri=4; 0114 : be25304 : T = (1) AND (E); E=T; 0114 : be25304 : clocks=4; goto (0514) Shift current word right one nybble, with E filling MS nybble. LS nybble ends up in E. 0514 : ce47470 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=0 0514 : ce47470 : IQN=0;XTR=1;clk=4;sec=e;pri=0; 0514 : ce47470 : = (0) ZTT (P); 0514 : ce47470 : clocks=5; goto (0502) Shift counter constant right 5 bits (equivalent to one complete word in the other routines). The counter constant will cause this loop to be executed 3 times, once for each mantissa word. 0502 : cfe3ba8 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=6(IORSBC);BRC=1 0502 : cfe3ba8 : IQN=0;XTR=1;clk=b;sec=5;pri=8; 0502 : cfe3ba8 : = (0) IORSBC (); WTM; 0502 : cfe3ba8 : clocks=12; if (QPO) goto (1507,1506) Write current word back to the pseudoregister. Set BC. Test to see if there's another word to shift 1507 : 6577f6a : TTM=0;TTT=1;SC=1(MTS);X=4(CAB);R=7(ZTR);ALU=7(ADD);BRC=0 1507 : 6577f6a : IQN=0;XTR=1;clk=f;sec=c;pri=a; 1507 : 6577f6a : M = (M) ADD (0); CAB; 1507 : 6577f6a : clocks=16; goto (0713) There is another word. Increment address (add 0 to all bits + BC, which is set). Select A accumulator. Go round again 1506 : e47704a : TTM=1;TTT=1;SC=1(MTS);X=4(CAB);R=7(ZTR);ALU=3(ZTT);BRC=0 1506 : e47704a : IQN=0;XTR=1;clk=0;sec=8;pri=a; 1506 : e47704a : = (M) ZTT (0); CAB; 1506 : e47704a : clocks=1; goto (0716) The complete pseudoregister has been shifted. Rotate M right one bit, select A accumulator. 0716 : 4e45090 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=1(AND);BRC=0 0716 : 4e45090 : IQN=0;XTR=1;clk=0;sec=3;pri=0; 0716 : 4e45090 : M = (0) AND (P); 0716 : 4e45090 : clocks=1; goto (0715) Shift a 0 into M. Rotate P right one bit, restoring original counter constant. 0715 : ee77d94 : TTM=1;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 0715 : ee77d94 : IQN=0;XTR=1;clk=d;sec=3;pri=4; 0715 : ee77d94 : = (M) ZTT (0); 0715 : ee77d94 : clocks=14; goto (0316) Rotate M by 14 bits. This causes M to point to the first mantissa word of the selected pseudoregister again. 0316 : faa5fab : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=2(TRE);ALU=1(AND);BRC=1 0316 : faa5fab : IQN=0;XTR=1;clk=f;sec=5;pri=b; 0316 : faa5fab : A/B = (1) AND (E,E); E=0; 0316 : faa5fab : clocks=16; if (Q10/) goto (1013,1012) Shift E (currently nybble shifted out from the last word) into lowest nybble of A. test to see if it's MRX / MRY (in which case go round again to check if the pseudoregister has been shifted enough times) or DRS (in whcih case, the instruction is complete). 1012 : 4f715a3 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 1012 : 4f715a3 : IQN=0;XTR=1;clk=5;sec=5;pri=3; 1012 : 4f715a3 : M = (0) ZTTCBC (0); 1012 : 4f715a3 : clocks=6; goto (1317) DRS : Shift 6 0's into M (start of PC save address) and go to restore program counter and continue. --- NRM continues : 1712 : c437b18 : TTM=1;TTT=1;SC=0(ZTS);X=4(CAB);R=6(RDM);ALU=3(ZTT);BRC=0 1712 : c437b18 : IQN=0;XTR=1;clk=b;sec=2;pri=8; 1712 : c437b18 : = (0) ZTT (); RDM ;CAB; 1712 : c437b18 : clocks=12; goto (0710) Read first mantissa word of AR2. Select accumulator B 0710 : d675b20 : TTM=1;TTT=1;SC=2(TTS);X=6(TTX);R=7(ZTR);ALU=1(AND);BRC=0 0710 : d675b20 : IQN=0;XTR=1;clk=b;sec=4;pri=0; 0710 : d675b20 : A/B = (T) AND (0); 0710 : d675b20 : clocks=12; goto (0714) Shift lowest 12 bits of mantissa word into B. 0714 : df07341 : TTM=1;TTT=1;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 0714 : df07341 : IQN=0;XTR=1;clk=3;sec=8;pri=1; 0714 : df07341 : = (T) ADD (1); 0714 : df07341 : clocks=4; goto (0604) Decrement MS nubble of first mantissa word of AR2 by adding 1111 to it (BC is clear). 0604 : c6f53f7 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=1(AND);BRC=1 0604 : c6f53f7 : IQN=0;XTR=1;clk=3;sec=f;pri=7; 0604 : c6f53f7 : A/B = (0) AND (0); 0604 : c6f53f7 : clocks=4; if (QBC) goto (0113,0112) Shift a nybble of 0's into B. Test to see if the MS nybble was originally zero or not. If it was, then the number needs normalising, continue at 0112 0113 : 4f7152a : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 0113 : 4f7152a : IQN=0;XTR=1;clk=5;sec=4;pri=a; 0113 : 4f7152a : M = (0) ZTTCBC (0); 0113 : 4f7152a : clocks=6; goto (1317) The number is already normallised (MS nybble of first word non-zero). Shift 6 0's into M (start of PC save address) and go to restore program counter and continue. --- MLS, DLS,CMX, CMY, MDI: 1005 : caf739b : TTM=1;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=3(ZTT);BRC=1 1005 : caf739b : IQN=0;XTR=1;clk=3;sec=3;pri=b; 1005 : caf739b : E = (0) ZTT (0,E); 1005 : caf739b : clocks=4; if (Q10/) goto (0306,0307) Clear E, Test bit Q(10) (originally Q(11)) to seprate instructions using AR1 fromt those useing AR2. Note at this point, M has had 3 1's shifted into it. 0306 : 4f730cb : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=6(IORSBC);BRC=0 0306 : 4f730cb : IQN=0;XTR=1;clk=0;sec=9;pri=b; 0306 : 4f730cb : M = (0) IORSBC (0); 0306 : 4f730cb : clocks=1; goto (1017) DLS, CHX : Shift a 0 into M (for AR1 address). Set BC 0307 : 7f0304b : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=6(IORSBC);BRC=0 0307 : 7f0304b : IQN=0;XTR=1;clk=0;sec=8;pri=b; 0307 : 7f0304b : M = (1) IORSBC (1); 0307 : 7f0304b : clocks=1; goto (1017) MLS, CMY, MDI : Shift a 1 into M (for AR2 address). Set BC 1017 : c281194 : TTM=1;TTT=1;SC=0(ZTS);X=2(BCD);R=0(UTR);ALU=0(XOR);BRC=1 1017 : c281194 : IQN=0;XTR=1;clk=1;sec=3;pri=4; 1017 : c281194 : SDC; 1017 : c281194 : clocks=2; if (Q4/) goto (1414,1415) Set decimal carry. Split off MDI instruction (which takes its address from A) 1415 : 4e77015 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1415 : 4e77015 : IQN=0;XTR=1;clk=0;sec=2;pri=5; 1415 : 4e77015 : M = (0) ZTT (0); 1415 : 4e77015 : clocks=1; goto (1117) DLS, MLS, CMX, CMY : Shift a 0 into M (next bit of AR1 or AR2 address) 1117 : 7e8344d : TTM=0;TTT=1;SC=3(UTS);X=7(NOP);R=0(UTR);ALU=2(IOR);BRC=1 1117 : 7e8344d : IQN=0;XTR=1;clk=4;sec=8;pri=d; 1117 : 7e8344d : M = (1) IOR (1); 1117 : 7e8344d : clocks=5; if (Q8/) goto (0407,0407) Shift 5 1's into M 0407 : 4ff15bb : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=1 0407 : 4ff15bb : IQN=0;XTR=1;clk=5;sec=7;pri=b; 0407 : 4ff15bb : M = (0) ZTTCBC (0); 0407 : 4ff15bb : clocks=6; if (Q10/) goto (1700,1701) And 6 0's. M now contains the address of the last word of the required pseudoregister. Branch on Q(10) (original Q(11)). 1700 : fa743c2 : TTM=1;TTT=1;SC=3(UTS);X=3(TBE);R=7(ZTR);ALU=1(AND);BRC=0 1700 : fa743c2 : IQN=0;XTR=0;clk=3;sec=9;pri=2; 1700 : fa743c2 : E = (1) AND (A/B,0,E); 1700 : fa743c2 : clocks=4; goto (1511) DLS, CHX : Rotate LS nybble of A into E (needed by DLS). 1701 : ce77042 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=0 1701 : ce77042 : IQN=0;XTR=1;clk=0;sec=8;pri=2; 1701 : ce77042 : = (0) ZTT (0); 1701 : ce77042 : clocks=1; goto (1511) MLS, CMT : NOP so the branch fits 1414 : 4f76f3d : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 1414 : 4f76f3d : IQN=0;XTR=0;clk=f;sec=6;pri=d; 1414 : 4f76f3d : M = (0) ADD (A/B,0); 1414 : 4f76f3d : clocks=16; goto (0112) MDI : transfer address from A into M. 0112 : ef730a5 : TTM=1;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=6(IORSBC);BRC=0 0112 : ef730a5 : IQN=0;XTR=1;clk=0;sec=5;pri=5; 0112 : ef730a5 : = (M) IORSBC (0); 0112 : ef730a5 : clocks=1; goto (0417) NRM enters here too. Rotate M right 1 bit, set BC. 0417 : 6f77e39 : TTM=0;TTT=1;SC=1(MTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 0417 : 6f77e39 : IQN=0;XTR=1;clk=e;sec=6;pri=9; 0417 : 6f77e39 : M = (M) ADD (0); 0417 : 6f77e39 : clocks=15; goto (1511) Incremement M starting at bit 1 (effectively adding 2 to M), to point to last word of mantissa. Rotate M back to the correct place. 1511 : ceb7bad : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=6(RDM);ALU=3(ZTT);BRC=1 1511 : ceb7bad : IQN=0;XTR=1;clk=b;sec=5;pri=d; 1511 : ceb7bad : = (0) ZTT (); RDM ; 1511 : ceb7bad : clocks=12; if (Q8/) goto (0014,0015) All the instruction routines come back together here. This is the start of the word loop. Read next word of the mntissa. Branch on Q(8) (originally Q(9)) to separate instructions requiring an arithmetic operation. 0015 : c674f65 : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=1(AND);BRC=0 0015 : c674f65 : IQN=0;XTR=0;clk=f;sec=c;pri=5; 0015 : c674f65 : A/B = (0) AND (A/B,0); 0015 : c674f65 : clocks=16; goto (0501) CMX, CMY, MDI : Clear A accumulator. 0501 : cec70b5 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=1 0501 : cec70b5 : IQN=0;XTR=1;clk=0;sec=7;pri=5; 0501 : cec70b5 : = (0) ZTT (P); 0501 : cec70b5 : clocks=1; if (Q5/) goto (0006,0007) Start of digit loop for arithmetic. Rotate counter constant right 1 bit (effectively 'incrementing the counter'). Separate complement from increment instrcutions. 0007 : d37e13d : TTM=1;TTT=1;SC=2(TTS);X=2(BCD);R=7(ZTR);ALU=7(ADD);BRC=0 0007 : d37e13d : IQN=1;XTR=0;clk=1;sec=6;pri=d; 0007 : d37e13d : T = (T) BCDSUB (A/B,0); 0007 : d37e13d : clocks=2; IQN(Q8/); goto (1501) CMX, CMY : Form 10's complement of selected digit (DC as set eariler). 0006 : d27e1bd : TTM=1;TTT=1;SC=2(TTS);X=2(BCD);R=7(ZTR);ALU=3(ZTT);BRC=0 0006 : d27e1bd : IQN=1;XTR=0;clk=1;sec=7;pri=d; 0006 : d27e1bd : T = (T) BCDADD (A/B,0); 0006 : d27e1bd : clocks=2; IQN(Q8/); goto (1501) MDI : Increment digit (if necessary, DC is initially set, then set by previous digit incrmeent if required) 1501 : bef4388 : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=7(ZTR);ALU=1(AND);BRC=1 1501 : bef4388 : IQN=0;XTR=0;clk=3;sec=1;pri=8; 1501 : bef4388 : T = (1) AND (A/B,0); 1501 : bef4388 : clocks=4; if (QPO) goto (0500,0501) Rotate updated nybble into the current word. Test to see if this is the end of the word. If not, go round again 0500 : ce470e7 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=0 0500 : ce470e7 : IQN=0;XTR=1;clk=0;sec=d;pri=7; 0500 : ce470e7 : = (0) ZTT (P); 0500 : ce470e7 : clocks=1; goto (0215) End of a word. Rotate the counter constant by one bit to test for the end of the complete mantissa. Then continue with the common routine. --- 0014 : be25f9a : TTM=1;TTT=0;SC=3(UTS);X=7(NOP);R=2(TRE);ALU=1(AND);BRC=0 0014 : be25f9a : IQN=0;XTR=1;clk=f;sec=3;pri=a; 0014 : be25f9a : T = (1) AND (E); E=T; 0014 : be25f9a : clocks=16; goto (1217) MLS, DLS, NRM : Rotate word right by 16 bits through E. This is effectively a left shift, bring E into the LS nybble and shifting the MS nybble into E. 1217 : ce47418 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=0 1217 : ce47418 : IQN=0;XTR=1;clk=4;sec=2;pri=8; 1217 : ce47418 : = (0) ZTT (P); 1217 : ce47418 : clocks=5; goto (0215) Rotate counter constant by 5 bits, effectively indicating a word is completed. Continue with the common routine. --- 0215 : cfe5bc8 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=5(IORCBC);BRC=1 0215 : cfe5bc8 : IQN=0;XTR=1;clk=b;sec=9;pri=8; 0215 : cfe5bc8 : = (0) IORCBC (); WTM; 0215 : cfe5bc8 : clocks=12; if (QPO) goto (1204,1205) Common routine. Write updated word back to memory. Clear BC. Test to see if the complete manissa is complete. 1204 : 6f07fe7 : TTM=0;TTT=1;SC=1(MTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 1204 : 6f07fe7 : IQN=0;XTR=1;clk=f;sec=d;pri=7; 1204 : 6f07fe7 : M = (M) ADD (1); 1204 : 6f07fe7 : clocks=16; goto (1511) It's not. Decrement M (to point to previous word of mantissa) and go round again. 1205 : ff930b2 : TTM=1;TTT=1;SC=3(UTS);X=7(NOP);R=4(TQ6);ALU=6(IORSBC);BRC=1 1205 : ff930b2 : IQN=0;XTR=1;clk=0;sec=7;pri=2; 1205 : ff930b2 : Q6 = (1) IORSBC (); 1205 : ff930b2 : clocks=1; if (Q2/) goto (1002,1003) The mantissa is complete. Set Q(6) (to indicate end of instruction). Set BC. Test Q(2) (origianl Q(3)) to see if this is an NRM instruction. 1003 : cef70b5 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 1003 : cef70b5 : IQN=0;XTR=1;clk=0;sec=7;pri=5; 1003 : cef70b5 : = (0) ZTT (0); 1003 : cef70b5 : clocks=1; if (Q5/) goto (1504,1505) MLS, DLS, CMX, CMY, MDI. Test Q(5) (originally Q(6)) to split off MDI instruciton. The rest continue at 1505 to restore the program counter and get the next instruction. 1504 : 8bff3ae : TTM=1;TTT=0;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=7(ADD);BRC=1 1504 : 8bff3ae : IQN=1;XTR=1;clk=3;sec=5;pri=e; 1504 : 8bff3ae : T,E = (0) ADD (0,E); 1504 : 8bff3ae : clocks=4; IQN(QDC); if (QDC) goto (0301,0300) MDI : If DC is set (indicating overflow) Shift 0001 into E and highest nybble of T (overflow flag and value). Branch on overflow 0301 : cf65b3c : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=3(WTM);ALU=5(IORCBC);BRC=0 0301 : cf65b3c : IQN=0;XTR=1;clk=b;sec=6;pri=c; 0301 : cf65b3c : = (0) IORCBC (); WTM; 0301 : cf65b3c : clocks=12; goto (1707) Overflow on MDI : Write overflow value to first word of mantissa, go to restore program counter and get next instruction 0300 : 4f715f8 : TTM=0;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=4(ZTTCBC);BRC=0 0300 : 4f715f8 : IQN=0;XTR=1;clk=5;sec=f;pri=8; 0300 : 4f715f8 : M = (0) ZTTCBC (0); 0300 : 4f715f8 : clocks=6; goto (1317) No overflow. Shift 6 0's into M (first part of program counter save address), then go to restore program counter and get next instruction --- NRM continues here 1002 : c776f6c : TTM=1;TTT=1;SC=0(ZTS);X=6(TTX);R=7(ZTR);ALU=7(ADD);BRC=0 1002 : c776f6c : IQN=0;XTR=0;clk=f;sec=c;pri=c; 1002 : c776f6c : A/B = (0) ADD (A/B,0); 1002 : c776f6c : clocks=16; goto (0416) Incrmeent B (BC set in state 1205) which holds a count of the number of times the mantissa was shifted. 0416 : cf72150 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=6(IORSBC);BRC=0 0416 : cf72150 : IQN=0;XTR=0;clk=1;sec=a;pri=0; 0416 : cf72150 : = (0) IORSBC (A/B,0); 0416 : cf72150 : clocks=2; goto (0404) Rotate B right 2 bits, set BC 0404 : cf761a0 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=7(ZTR);ALU=7(ADD);BRC=0 0404 : cf761a0 : IQN=0;XTR=0;clk=1;sec=5;pri=0; 0404 : cf761a0 : = (0) ADD (A/B,0); 0404 : cf761a0 : clocks=2; goto (0401) Increment next 2 bits of B (but don't save them). BC is set if B has got to 12, the maximum number of times that the mantissa can be shifted. 0401 : def6bd7 : TTM=1;TTT=1;SC=2(TTS);X=7(NOP);R=7(ZTR);ALU=3(ZTT);BRC=1 0401 : def6bd7 : IQN=0;XTR=0;clk=b;sec=b;pri=7; 0401 : def6bd7 : = (T) ZTT (A/B,0); 0401 : def6bd7 : clocks=12; if (QBC) goto (0312,0313) Rotate B by 12 bits to get the bits back in the right place. Rotate the current word right by 12 bits. Test to see if the shift count in B has overflowed 0312 : cb773ec : TTM=1;TTT=1;SC=0(ZTS);X=3(TBE);R=7(ZTR);ALU=7(ADD);BRC=0 0312 : cb773ec : IQN=0;XTR=1;clk=3;sec=d;pri=c; 0312 : cb773ec : E = (0) ADD (0,E); 0312 : cb773ec : clocks=4; goto (1707) It has. The mantissa must be zero. Increment E (to 0001) to indicate this, and go to restore the program counter and continue. 0313 : df073e5 : TTM=1;TTT=1;SC=2(TTS);X=7(NOP);R=0(UTR);ALU=7(ADD);BRC=0 0313 : df073e5 : IQN=0;XTR=1;clk=3;sec=d;pri=5; 0313 : df073e5 : = (T) ADD (1); 0313 : df073e5 : clocks=4; goto (0606) Decrement MS nybble of current word (but don't save the result), which is the first word of the mantissa. This is a test to see if that nybble is 0 0606 : cec70e7 : TTM=1;TTT=1;SC=0(ZTS);X=7(NOP);R=1(PTR);ALU=3(ZTT);BRC=1 0606 : cec70e7 : IQN=0;XTR=1;clk=0;sec=d;pri=7; 0606 : cec70e7 : = (0) ZTT (P); 0606 : cec70e7 : clocks=1; if (QBC) goto (0113,0112) Rotate counter constant right one bit to restore it. Test to see if the MS nybble of the current word is zero (not normalised), in which case go round again via state 0112, or if it's non-zero, in which case the mantissa is normalised, so exit via state 0113