% Elite12-P % 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MicroCode for UR-CPU project % John W. Peterson % CS-428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Definitions for basic control pins % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ALU control % (DefPin AluMode (Rom4 . 2#10000000)) % Special 'mode' for logical Ops (DefPin AluBit3 (Rom4 . 2#1000000)) (DefPin AluBit2 (Rom4 . 2#100000)) (DefPin AluBit1 (Rom4 . 2#10000)) (DefPin AluBit0 (Rom4 . 2#1000)) % % Macros for ALU output % AluBit (DefMacro ALU_Aout % output A leg w/ no effect (AluMode AluBit0 AluBit1 AluBit2 AluBit3 AluMode)) (DefMacro ALU_Bout (AluBit3 AluBit1 AluMode)) % output B leg w/no effectA (DefMacro ALU_comp (AluMode)) % ouput A' (DefMacro ALU_and (AluMode AluBit3 AluBit1 AluBit0)) % logical AND (DefMacro ALU_Add (AluBit3 AluBit0)) % Straight addition. (DefMacro ALU_ShiftL (AluBit3 AluBit2)) % Add A to itself (shft L) (DefMacro ALU_zero (AluMode AluBit1 AluBit0)) % Ouput a ZERO (DefMacro ALU_or (AluMode AluBit3 AluBit2 AluBit1)) % logical OR (DefMacro ALU_AddCarry ()) % Add the carry (DefMacro ALU_SubCarry (AluBit3 AluBit2 AluBit1 AluBit0)) % subtract the carry. %..add others as need arises. % % Carry IN control % (DefPin Cin1 (Rom4 . 2#100)) (DefPin Cin0 (Rom4 . 2#10)) % (DefMacro CinZero ()) % Carry in is constant zero (DefMacro CinOne (Cin0)) % Carry in is constant one (DefMacro CinPC (Cin1)) % Carry in is PC (DefMacro CinNotPC (Cin1 Cin0)) % Carry in is compliment of PC % % A leg ALU source selection % (DefPin Asrc2 (Rom4 . 2#1)) (DefPin Asrc1 (Rom3 . 2#10000000)) (DefPin Asrc0 (Rom3 . 2#1000000)) % (DefMacro Bus_Ena ()) % Enable the data bus onto the u_bus % Yuckko...since Bus_Ena also switchs the u-Bus Mux in the wrong direction, % we need a dummy enable to avoid this side effect, to be used when we want % data to go to the u-Bus from the B-leg (or just from the ALU itself, e.g. % ALU_Zero... % (DefMacro uBus_Ena (Asrc1)) (DefMacro PS_Ena (Asrc0)) % Enable the PS register onto the u_bus (DefMacro T_Ena (Asrc1)) % Enable the T register onto the u_bus (DefMacro PCL_Ena (Asrc1 Asrc0)) % the low order PC (DefMacro PCH_Ena (Asrc2)) % High order PC (DefMacro IRL_Ena (Asrc2 Asrc0)) % Low order IR (DefMacro IRH_Ena (Asrc2 Asrc1)) % High order IR (instruction reg) % % B leg ALU (accumulator) control % (DefPin ShiftCont (Rom3 . 2#100000)) % Shift the Acc (DefPin LoadAcc (Rom3 . 2#10000)) % Load (activate, actually) the Acc (DefMacro ShiftAcc (LoadAcc ShiftCont)) % % PS (processor status) control % (DefPin PSLoad (Rom3 . 2#1000)) (DefPin PSSel (Rom3 . 2#100)) (DefMacro LoadPSfromBus (PSLoad)) (DefMacro LoadPSfromALU (PSLoad PSsel)) % % Destination (which reg gets loaded from MUX output) % (DefPin Dest2 (Rom3 . 2#10)) (DefPin Dest1 (Rom3 . 2#1)) (DefPin Dest0 (Rom2 . 2#10000000)) % (DefMacro LoadAdrH (Dest2 Dest1 Dest0)) (DefMacro LoadAdrL (Dest2 Dest1)) (DefMacro LoadIR_H (Dest2 Dest0)) (DefMacro LoadIR_L (Dest2)) (DefMacro LoadPC_H (Dest1 Dest0)) (DefMacro LoadPC_L (Dest1)) (DefMacro LoadT (Dest0)) % % Bus Control bits % (DefPin BusReq (Rom2 . 2#1000000)) (DefPin BusRW (Rom2 . 2#100000)) % (DefMacro BusRead (BusReq BusRW)) (DefMacro BusWrite (BusReq)) % % u_Branch control % (DefPin LitOnly (Rom2 . 2#10000)) (DefPin LITpin (Rom2 . 2#1000)) (DefPin HRpin (Rom2 . 2#100)) % (DefMacro IncPC ()) (DefMacro Call (LitOnly LITpin HRpin)) (DefMacro JmpLit (LitOnly LitPin)) (DefMacro JmpCond (LitPin)) (DefMacro JmpHR (LitOnly HRpin)) % % Definitions for masking off u_code conditionals. % (DefPin LitMask0 (Rom1 . 2#1)) (DefPin LitMask1 (Rom1 . 2#10)) (DefPin LitMask2 (Rom1 . 2#100)) (DefPin LitMask3 (Rom1 . 2#1000)) (DefPin LitMask4 (Rom1 . 2#10000)) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Initialzation routine % (Location INIT 000 (ALU_Zero LoadPC_H)) % clear the high-order AR (Next (ALU_Zero LoadPC_L)) % and the low % % Perform an instruction fetch % (Label Ifetch LOC) (Next (ALU_Aout PCL_Ena LoadAdrL)) % Put the PC in the AR (Next (ALU_Aout PCH_Ena LoadAdrH)) (Next (BusRead Bus_Ena LoadIR_H)) % load the IR from the bus (Next (ALU_AddCarry CinOne PCL_Ena LoadPC_L LoadPSfromALU)) % Inc the PC % Don't worry about carry) % since it's going to be even (Next (ALU_Aout PCL_Ena LoadAdrL)) % Put the new PC in the AR (Next (ALU_Aout PCH_Ena LoadAdrH)) (Next (BusRead Bus_Ena LoadIR_L)) % Load the low order byte.. (Next (ALU_Aout PS_Ena LoadT)) % Save the CCs in T (Next (ALU_AddCarry CinOne PCL_Ena LoadPC_L LoadPSfromALU)) % Inc the PC (Next (ALU_AddCarry CinPC PCH_Ena LoadPC_H)) (Next (ALU_Aout T_Ena LoadPSfromBus)) % Restore PS bits (Next (ALU_Aout IRH_Ena LoadAdrH)) % put IR (address) in AR, (Next (ALU_Aout IRL_Ena LoadAdrL)) % Helpful to most inst's. (SetLit InstructionTable (JmpCond IRH_Ena)) % Jmp to inst. % %%%% % NOTE- a hell of a lot of these could be optimized by one cycle by jmping % to Ifetch while performing the last operation in the Inst. % % % STore Indirect (STI) % (Label STIinst LOC) (Next (ALU_Aout BusRead Bus_Ena LoadT)) % Put the data at pointed to into T (Next (ALU_AddCarry CinOne IRL_Ena LoadIR_L)) % Increment the IR to % point to next byte (Next (ALU_Mov IRL_Ena LoadAdrL)) % Put new pointer in address. (Next (BusRead Bus_Ena LoadIR_H)) % Grab the hi part of the address, % freely stomping on the IR (done w/it) (Next (ALU_Aout LoadAdrL T_Ena)) % Move low byte into adr L (Next (ALU_Aout LoadAdrH IRH_Ena)) % Grab the other half stashed in the IR (Next (ALU_Bout uBus_Ena BusWrite)) % Write the data (SetLit Ifetch (JmpLit)) % Done. % % ADD (add accumulator) instruction % (Label ADDinst LOC) (Next (ALU_Aout BusRead Bus_Ena LoadT)) % Stash adr'd data into T (Next (ALU_Add CinZero T_Ena LoadPSfromALU LoadAcc)) % Peform the addition (Label DontBranch LOC) % For benefit of conditional branches (SetLit Ifetch (JmpLit)) % % AND Logical and acc. % (Label ANDinst LOC) (Next (ALU_Aout BusRead Bus_Ena LoadT)) % Stash adr'd data into T (Next (ALU_And T_Ena LoadPSfromALU LoadAcc)) % Peform the AND (SetLit Ifetch (JmpLit)) % % NOT Logical and acc. % (Label NOTinst LOC) (Next (ALU_Bout _Ena LoadT)) % Put ACC into Treg (Next (ALU_comp T_Ena LoadPSfromALU LoadAcc)) % Peform the comp (SetLit Ifetch (JmpLit)) % % Shift left, ASL instruction % (Label ASLinst LOC) (Next (ALU_Bout LoadT)) % Put ACC into Treg (Next (ALU_ShiftL CinZero LoadAcc LoadPSfromALU uBus_Ena)) % Use AplusA ALU funct to get left shift (SetLit Ifetch (JmpLit)) % Done. % % Shift right, ASR instruction. The implementation of this takes advantage % of the fact the good Doctor is allowing is to stomp on the N bit in the % status word. Hence, the sequence is:: % (Label ASRinst LOC) (Next (ALU_Bout uBus_Ena LoadT))% Stuff the ALU into the T, to save ALU's % low order bit (Next (ShiftAcc)) % Shift, sucking in the C bit on the right (Next (ALU_Aout T_Ena LoadPSfromBus)) % Put the saved Acc bits back in CCs (SetLit Ifetch (JmpLit)) % done. % % BRAinst, complete the branch instruction % (Label BRAinst LOC) (Label Branch LOC) (Next (ALU_Mov LoadPC_L IRL_Ena)) (Next (ALU_Mov LoadPC_H IRH_Ena)) (SetLit Ifetch (JmpLit)) % % BRIinst, Branch Indirect thru the value addr field % (Label BRIinst LOC) (Next (ALU_Aout BusRead Bus_Ena LoadT)) % Put the data at pointed to into T (Next (ALU_AddCarry CinOne IRL_Ena LoadIR_L)) % Increment the IR to % point to next byte (Next (ALU_Mov IRL_Ena LoadAdrL)) % Put new pointer in address (Next (BusRead Bus_Ena LoadIR_H)) % Grab the hi part of the address, % freely stomping on the IR (done w/it) (Next (ALU_Aout LoadPC_L T_Ena)) % Move low byte into PC_L (Next (ALU_Aout LoadPC_H LoadIR_H)) % Grab the other half stashed in the IR (SetLit Ifetch (JmpLit)) % % JMSinst, jmp to a subroutine. % (Label JMSinst LOC) (Next (ALU_Aout PCL_Ena BusWrite)) % Write the PC into the location. (Next (ALU_AddCarry CinOne IRL_Ena LoadIR_L)) % Increment the IR to % point to next byte (Next (ALU_Mov IRL_ENA LoadAdrL)) (Next (ALU_Aout PCH_Ena BusWrite)) % Write the PC into the location. (Next (ALU_AddCarry CinOne PCL_Ena LoadPC_L LoadPSfromALU)) % Inc the PC % Don't worry about carry) % since it's going to be even (Next (ALU_Aout PS_Ena LoadT)) % Save the CCs in T (Next (ALU_AddCarry CinOne PCL_Ena LoadPC_L LoadPSfromALU)) % Inc the PC (Next (ALU_AddCarry CinPC PCH_Ena LoadPC_H)) (Next (ALU_Aout T_Ena LoadPSfromBus)) % Restore PS bits (Next (ALU_AddCarry CinZero IRL_Ena LoadIR_L)) % Decrement the IR to it's % original value (SetLit Branch (JmpLit)) % and branch off to it. % % bunch that had to be moved due to jumplit crock % (Label LDAinst LOC) (Next (BusRead Bus_Ena LoadAcc)) % LDA works in line. (SetLit Ifetch (JmpLit)) (Label STAinst LOC) (Next (uBus_Ena ALU_Bout BusWrite)) % STA works in line. (SetLit Ifetch (JmpLit)) (Label LDIinst LOC) (Next (ALU_Mov LoadAcc IRL_Ena)) % LDI works in line. (SetLit Ifetch (JmpLit)) (Label CLCinst LOC) (Next (ALU_SubCarry PS_Ena CinPC LoadPSfromBus)) (SetLit Ifetch (JmpLit)) % Now ain't this magic? It works on the basis % of the carrybit interacting with the alu. % look at the truth tables for exact info (Label STCinst LOC) (Next (ALU_AddCarry PS_Ena CinNotPC LoadPSfromBus)) (SetLit Ifetch (JmpLit)) % Same principle %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (Location InstructionTable 2#1100000000 ()) (Location MakeCodeKludge 2#10001111 ()) (Label InstructionTable LOC) (SetLit LDAinst (JmpLit)) (SetLit STAinst (JmpLit)) (SetLit LDIinst (JmpLit)) (SetLit STIinst (JmpLit)) % STI instruction (SetLit ADDinst (JmpLit)) % ADD instruction (SetLit ANDinst (JmpLit)) % Logical AND. (SetLit NOTinst (JmpLit)) (SetLit ASLinst (JmpLit)) (SetLit ASRinst (JmpLit)) (SetLit CLCinst (JmpLit)) (SetLit STCinst (JmpLit)) (SetLit BRAinst (JmpLit)) % Branch; load first half, then jmp to load 2nd (SetLit BRCtst (JmpCond PS_Ena)) %cond jmp on carry flag... (SetLit BRNtst (JmpCond PS_Ena)) %cond jmp on sign flag... (SetLit BRIinst (JmpLit)) % BRI, Branch Indirect (SetLit JMSinst (JmpLit)) % Jump Subroutine % Land here on conditional Branches %(Location CondBranchTable 2#1100100000 ()) % Carry branch should fall naturally into place... % (Location KludgeCarryBranchTable 2#10011111 ()) (Location BRkludge 16#DC ()) (Label BranchTable LOC) (Label BRNtst LOC) (SetLit DontBranch (JmpLit)) % just fetch next if cc's=00 (Label BRCtst LOC) (SetLit DontBranch (JmpLit)) % ignore if cc's=01 (SetLit Branch (JmpLit)) % Branch if cc's=10 (SetLit Branch (JmpLit)) % but go if cc's=11