/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 27-Dec-85 | [1.241] Created * 27-Jan-86 | [1.350] declare single_cycle_decode * 25-Feb-86 | [1.379] include <> => include "" * 10-Nov-91 | [1.428] converted to Microsoft C 6.0 libraries * 18-Nov-91 | [1.428] memory.h => mem1401.h, avoid ANSI name *****************************************************************************/ #include "stdio.h" #include "btypes.h" #include "mem1401.h" #include "boolean.h" #include "mach.h" #include "diag.h" #include "instr.h" #include "ifetch.h" /* Machine State: */ #define MCS_A_complete single_cycle(i_MCS,A_complete) #define MCS_B_complete single_cycle(i_MCS,B_complete) #define MCS_B_f_complete single_cycle(i_MCS,B_f_complete) #define MCS_B_s_complete single_cycle(i_MCS,B_s_complete) #define MCS_move single_cycle(i_MCS,local_microstate+1) #define MCS_suppress_f_complete single_cycle(i_MCS,local_microstate+2) #define MCS_suppress_s_complete single_cycle(i_MCS,local_microstate+3) #define MCS_suppress_init single_cycle(i_MCS,local_microstate+4) #define MCS_skip_f_complete single_cycle(i_MCS,local_microstate+5) #define MCS_skip_s_complete single_cycle(i_MCS,local_microstate+6) extern char * single_cycle_decode(); /***************************************************************************** 1401 Simulator Move Characters and Suppress Zeroes Move and Suppress Zeroes (Two Addresses) ---------------------------------------- Instruction format Mnemonic Op Code A-address B-address -------- ------- --------- --------- MCS Z AAA BBB Function: The data in the A-field is moved to the B-field. AFter the move, high-order zeros and commas are replaced by blanks in the B-field. Any character that is not a comma, hyphen, blank, significant digit, or zero causes zero suppression to begin again. The sign is removed from the units position of the data field. Word Marks: The A-field word mark stops transmission of data. B-field word marks, encountered during the move operation, are erased. Note: This description of the instruction assumes a 1401 without the expanded print-edit special feature. If the feature is installed, a decimal point does not start zero suppression. Simulator note: We implement expanded print-edit. Address Registers After Operation: I-Add A-Add B-Add ----- ----- ----- NSI A-La B+1 Chaining: This instruction can be chained to the preceding operation (if that instruction left usable address-register contents) by supplying only the operation code. *****************************************************************************/ static int init_B_addr; /**************************************************************************** * inst_MCS * result: boolean * true if instruction succeeded * false if instruction failed * Effect: * Executes move and suppress zeroes instruction ****************************************************************************/ boolean inst_MCS() { boolean quit; boolean result; boolean cycling; boolean run; switch(I_cycle) { /* length dispatch */ case 1: /* chained */ break; case 7: /* normal */ break; default: /* illegal length */ illegal_length(); return false; } /* length dispatch */ tell_op(op_A|op_B); result = true; cycling = true; quit = false; while(cycling) { /* move chars */ if(bad_address(A_addr)) { /* bogus */ cycle = cycle_A; result = false; quit = true; cycling = false; break; } /* bogus */ if(bad_address(B_addr)) { /* bogus */ cycle = cycle_B; result = false; quit = true; cycling = false; break; } /* bogus */ switch(single_cycle_state) { /* state decode */ case single_cycle_run: init_B_addr = B_addr; run = true; single_cycle_state = MCS_move; break; case MCS_move: B = memory[A_addr]; memory[B_addr] = BA8421(B); if(WM(B)) single_cycle_state = MCS_suppress_init; A_addr--; B_addr--; break; case single_cycle_start: run = false; init_B_addr = B_addr; /* FALLS THRU TO MCS_B_COMPLETE! */ case MCS_B_complete: B = memory[A_addr]; A_addr--; cycle = cycle_A; single_cycle_state = MCS_A_complete; cycling = run; break; case MCS_A_complete: A = B; memory[B_addr] = BA8421(A); B_addr--; cycle = cycle_B; if(WM(B)) single_cycle_state = MCS_suppress_init; else single_cycle_state = MCS_B_complete; cycling = run; break; case MCS_suppress_init: /* FALLS THRU TO MCS_suppress */ case MCS_suppress_s_complete: B_addr++; if(B_addr > init_B_addr) { /* done */ quit = true; cycling = false; break; } /* done */ B = memory[B_addr]; cycle = cycle_B; single_cycle_state = MCS_suppress_f_complete; cycling = run; break; case MCS_suppress_f_complete: /* We are in suppress mode. if the character is '0' or ',', make it a space and set the state to MCS_suppress_s_complete */ switch(BA8421(B)) { /* decode */ case 10: /* BCD '0' */ case 27: /* BCD ',' */ B = 0; /* BCD space */ memory[B_addr] = B; single_cycle_state = MCS_suppress_s_complete; break; case 1: /* BCD '1' */ case 2: /* BCD '2' */ case 3: /* BCD '3' */ case 4: /* BCD '4' */ case 5: /* BCD '5' */ case 6: /* BCD '6' */ case 7: /* BCD '7' */ case 8: /* BCD '8' */ case 9: /* BCD '9' */ single_cycle_state = MCS_skip_f_complete; break; default: /* skip it but don't change suppress */ single_cycle_state = MCS_suppress_s_complete; break; } /* decode */ cycle = cycle_B; cycling = run; break; case MCS_skip_s_complete: B_addr++; if(B_addr > init_B_addr) { /* done */ quit = true; cycling = false; break; } /* done */ B = memory[B_addr]; single_cycle_state = MCS_skip_f_complete; cycle = cycle_B; cycling = run; break; case MCS_skip_f_complete: switch(BA8421(B)) { /* check char */ case 1: /* BCD '1' */ case 2: /* BCD '2' */ case 3: /* BCD '3' */ case 4: /* BCD '4' */ case 5: /* BCD '5' */ case 6: /* BCD '6' */ case 7: /* BCD '7' */ case 8: /* BCD '8' */ case 9: /* BCD '9' */ case 10: /* BCD '0' */ case 32: /* BCD '-' */ case 27: /* BCD ',' */ case 59: /* BCD '.' (EXPANDED PRINT EDIT) */ case 0: /* BCD space */ /* retain skip mode */ single_cycle_state = MCS_skip_s_complete; break; default: /* It isn't any of the above, restart suppress mode */ single_cycle_state = MCS_suppress_s_complete; break; } /* check char */ cycle = cycle_B; cycling = run; break; default: sprintf(diag_buffer,"Illegal microstate %s",single_cycle_decode()); tell(diag_buffer); result = false; cycling = run; break; } /* state decode */ if(quit) { single_cycle_state = single_cycle_complete; break; } if(diagnostics_on && run) tell_new_state("MCS"); } /* move chars */ tell_new_state("MCS"); return result; }