/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 13-Dec-85 | [1.183] Created * 27-Jan-86 | [1.350] declare single_cycle_decode * 25-Feb-86 | [1.379] include <> => include "" * 6-Aug-86 | [1.410] 'bytes' array is now unsigned * 10-Nov-91 | [1.428] converted for Microsoft C 6.0 * 18-Nov-91 | [1.428] memory.h => mem1401.h, avoid ANSI name *****************************************************************************/ #include "stdio.h" #include "btypes.h" #include "boolean.h" #include "mem1401.h" #include "mach.h" #include "diag.h" #include "instr.h" #include "ifetch.h" #include "cvbytes.h" #define debug_SAR false /* Machine State: */ #define SAR_B_1_complete single_cycle(i_SAR,local_microstate+1) #define SAR_B_2_complete single_cycle(i_SAR,local_microstate+2) #define SAR_B_3_complete single_cycle(i_SAR,local_microstate+3) static unsigned char bytes[3]; /* The converted address */ extern char * single_cycle_decode(); /***************************************************************************** 1401 Simulator Store A-Register Store A-Register (One Address) ------------------------------ Instruction format Mnemonic Op Code A-address -------- ------- --------- SAR Q AAA Function: This instruction stores the contents of the A-address register from the previous operation in the 3-position field that has its units position defined by the A-address of the Store A-Address-Register instruction. Word Marks: Word marks are not affected. Address Registers After Operation: I-Add A-Add B-Add ----- ----- ----- NSI A-3 Ap Chaining: If this instruction is chained (operation code only) to the preceding operation, the following will result (assume xxx is 1-char field) Registers after / \ Instruction A-addr B-addr zzz zzz-3 ----------- ------ ------ --- ----- M xxx yyy xxx-1 yyy-1 ??? ??? Q zzz zzz-3 xxx-1 xxx-1 ??? Q zzz-6 zzz-3 xxx-1 zzz-3 *****************************************************************************/ /**************************************************************************** * inst_SAR * result: boolean * true if instruction succeeded * false if instruction failed * Effect: * Stores the previous A-address in the field designated by the * A-address of this instruction. ****************************************************************************/ boolean inst_SAR() { int i; tell_op(op_A); switch(I_cycle) { /* length decode */ case 1: /* chained */ case 4: /* one-address */ break; default: illegal_length(); return false; } /* length decode */ switch(single_cycle_state) { /* state decode */ case single_cycle_run: /* Note that we cannot convert it directly into memory because wordmarks at destination site must be preserved We store the contents of the B_addr register because the instruction fetch logic set B = Ap. */ cvbytes(bytes,B_addr); for(i=2;i>=0;i--) { /* store it */ if(bad_address(A_addr-2+i)) { /* can't store */ cycle = cycle_A; return false; } /* can't store */ #if debug_SAR if(diagnostics_on) { /* tell */ sprintf(diag_buffer,"%d:memory[%d] = %c", i,A_addr-2+i,bcd_to_ascii(bytes[i])); tell(diag_buffer); } /* tell */ #endif B = memory[A_addr-2+i] = bytes[i] | WM(memory[A_addr-2+i]); } /* store it */ A_addr -= 3; single_cycle_state = single_cycle_complete; break; case single_cycle_start: cvbytes(bytes,B_addr); /* see note above */ if(bad_address(A_addr)) { /* can't store */ cycle = cycle_A; return false; } /* can't store */ B = memory[A_addr] = bytes[2]; single_cycle_state = SAR_B_1_complete; A_addr--; cycle = cycle_A; break; case SAR_B_1_complete: if(bad_address(A_addr)) { /* can't store */ cycle = cycle_A; return false; } /* can't store */ B = memory[A_addr] = bytes[1]; single_cycle_state = SAR_B_2_complete; A_addr--; cycle = cycle_A; break; case SAR_B_2_complete: if(bad_address(A_addr)) { /* can't store */ cycle = cycle_A; return false; } /* can't store */ B = memory[A_addr] = bytes[0]; single_cycle_state = single_cycle_complete; cycle = cycle_A; A_addr--; break; default: sprintf(diag_buffer,"Illegal microstate %s",single_cycle_decode()); tell(diag_buffer); return false; break; } /* state decode */ tell_new_state("SAR"); return true; }