/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 15-Dec-85 | [1.199] Created * 27-Jan-86 | [1.350] declare single_cycle_decode * 25-Feb-86 | [1.379] include <> => include "" * 31-Jul-86 | [1.405] Made char vars unsigned * 6-Aug-86 | [1.410] Added NOTREACHED comment * 10-Nov-91 | [1.428] converted to Microsoft C 6.0 * 18-Nov-91 | [1.428] memory.h => mem1401.h, avoid ANSI name *****************************************************************************/ #include "stdio.h" #include "boolean.h" #include "mem1401.h" #include "btypes.h" #include "mach.h" #include "diag.h" #include "instr.h" #include "alerts.h" #include "poll.h" #include "ifetch.h" #include "alert.h" #define BWZ_B_f_complete single_cycle(i_BWZ,B_f_complete) extern char * single_cycle_decode(); /***************************************************************************** 1401 Simulator Branch on Word Mark or Zone Instruction Branch on Word Mark or Zone --------------------------- Instruction format Mnemonic Op Code I-address B-address d-char -------- ------- --------- --------- ------ BWZ V III BBB d Function: This instruction examines the single character at the B-address for zone or word mark combinations specified by the d-character. A correct comparison branches to the specified I-address. If the program does not branch to the I-address, it continues sequentially. The d-character can be one of: 1 word mark 2 No zone 3 A word mark, or no zone B 12-zone (AB) C A word mark, or 12 zone K 11-zone (B) L A word mark, or 11-zone S 0-zone (A) T A word mark, or 0-zone Word Marks: Word marks in the location tested have no effect on the operation. Address Registers After Operation: No Branch: I-Add A-Add B-Add NSI BI B-1 Branch I-Add A-Add B-Add NSI BI NSI Chaining: The instruction can be chained to the preceding operation by supplying only the operation code. *****************************************************************************/ /**************************************************************************** * bwz * Inputs: * unsigned char data: data to test * unsigned char d: Condition to test it against * Result: boolean * true if branch should be taken * false if not * Effect: * may set a process alert if the d-char is illegal ****************************************************************************/ boolean bwz(unsigned char data, unsigned char d) { switch(d) { /* d decode */ case 1: /* "1" - word mark */ return (boolean) WM(data); case 2: /* "2" - no zone */ return (boolean) ZONEBITS(data) == 0; case 3: /* "3" - wm or no zone */ return WM(data) || (ZONEBITS(data) == 0); case 50: /* "B" - AB bits */ return ZONEBITS(data) == BA_bits; case 51: /* "C" - AB bits or wm */ return WM(data) || (ZONEBITS(data) == BA_bits); case 34: /* "K" - B bit */ return ZONEBITS(data) == B_bits; case 35: /* "L" - B bit or wm */ return WM(data) || (ZONEBITS(data) == B_bits); case 18: /* "S" - A bit */ return ZONEBITS(data) == A_bits; case 19: /* "T" - A bit or wm */ return WM(data) || (ZONEBITS(data) == A_bits); default: /* Illegal code */ alert(alert_process); return false; } /* d decode */ /*NOTREACHED */ return false; /* should never get here */ } /**************************************************************************** * inst_BWZ * Result: boolean * true if processing should continue * false if processing should halt * Effect: * Executes the branch-on-word-or-zone instruction ****************************************************************************/ boolean inst_BWZ() { tell_op(op_A|op_B|op_d); switch(I_cycle) { /* BWZ */ case 1: /* chained */ if(bad_address(B_addr)) return false; switch(single_cycle_state) { /* state decode */ case single_cycle_run: B = memory[B_addr]; if(bwz(B,d_char)) { /* take branch */ NI_addr = A_addr; B_addr = I_addr; poll(); } /* take branch */ else { /* don't branch */ B_addr--; } /* don't branch */ single_cycle_state = single_cycle_complete; break; case single_cycle_start: B = memory[B_addr]; B_addr--; cycle = cycle_B; single_cycle_state = BWZ_B_f_complete; break; case BWZ_B_f_complete: if(bwz(B,d_char)) { /* take branch */ NI_addr = A_addr; B_addr = I_addr; poll(); } /* take branch */ single_cycle_state = single_cycle_complete; default: sprintf(diag_buffer,"Illegal microstate %s",single_cycle_decode()); tell(diag_buffer); single_cycle_state = single_cycle_complete; } /* state decode */ tell_new_state("BWZ"); break; /* Biiibbbd */ case 8: /* two-address + d */ if(bad_address(B_addr)) return false; switch(single_cycle_state) { /* state decode */ case single_cycle_run: B = memory[B_addr]; if(bwz(B,d_char)) { /* take branch */ NI_addr = A_addr; B_addr = I_addr; poll(); } /* take branch */ else { /* don't branch */ B_addr--; } /* don't branch */ single_cycle_state = single_cycle_complete; break; case single_cycle_start: B = memory[B_addr]; A = d_char; /* this may not be right... */ B_addr--; cycle = cycle_B; single_cycle_state = BWZ_B_f_complete; break; case BWZ_B_f_complete: if(bwz(B,d_char)) { /* take branch */ NI_addr = A_addr; B_addr = I_addr; poll(); } /* take branch */ single_cycle_state = single_cycle_complete; } /* state decode */ /* be sure to reset any indicators as described in 'notes' */ single_cycle_state = single_cycle_complete; tell_new_state("BWZ"); break; default: /* Illegal */ illegal_length(); return false; } return true; }