(**********************************************************************) (* *) (* Function: PSP *) (* Position Synchronised Pulse *) (* *) (* Creation Date: Pre 89 From: NEW *) (* *) (* Author: Motorola *) (* *) (* Description: *) (* ------------ *) (* Generate pulses referenced to an angle clock that is fed into tcr2 *) (* and whose period has been measured by another function - PMA_PMM. *) (* Two modes for pulse generation:- angle-angle and angle-time. *) (* *) (* *) (* Updates: By: Modification: *) (* -------- --- ------------- *) (* 02/Mar/92 JW Cleaned up for inclusion in Library *) (* 11/Apr/93 JL Converted to new syntax & changed unused link *) (* state to End_of_link. *) (* *) (*--------------------------------------------------------------------*) (* Standard Exits Used:- End_Of_Phase: Y End_Of_Link: N *) (* *) (* External Files %included: NONE. *) (* *) (* CODE SIZE excluding standard exits = 96 LONG WORDS *) (*--------------------------------------------------------------------*) (* *) (* *) (********** This Revision: 2.0 *********) (* *) (* Functionally identical to 68332 TPU ROM of masks D33F, D87M, 2D87M *) (* *) (********** LAST MODIFIED: 11/Apr/93 BY: Jeff Loeliger ********) (* *) (**********************************************************************) (***************************************************************************) (*Motorola reserves the right to make changes without further notice to any*) (*product herein. Motorola makes no warranty, representation or guarantee *) (*regarding the suitability of its products for any particular purpose, nor*) (*does Motorola assume any liability arising out of the application or use *) (*of any product or circuit, and specifically disclaims any and all *) (*liability, including without limitation consequential or incidental *) (*damages. "Typical" parameters can and do vary in different applications. *) (*All operating parameters, including "Typical",must be validated for each *) (*customer application by customer's technical experts. Motorola does not *) (*convey any license under its patent rights nor the rights of others. *) (*Motorola products are not designed, intended, or authorized for use as *) (*components in systems intended for surgical implant into the body, or *) (*other applications intended to support or sustain life, or for any other *) (*application in which the failure of the Motorola product could create a *) (*situation where injury or death may occur. Should Buyer purchase or use *) (*Motorola products for any such unintended or unauthorized application, *) (*Buyer, shall indemnify and hold Motorola and its officers, employees, *) (*subsidiaries, affiliates, and distributors harmless against all claims, *) (*costs, damages, and expenses, and reasonable attorney fees arising out *) (*of, directly or indirectly, any claim of personal injury or death *) (*associated with such unintended or unauthorized use, even if such claim *) (*alleges that Motorola was negligent regarding the design or manufacture *) (*of the part. *) (*Motorola and the Motorola logo are registered trademarks of Motorola Inc.*) (*Motorola is an Equal Opportunity/Affirmative Action Employer. *) (*Copyright Motorola Inc. 1993 *) (***************************************************************************) (* Parameters *) %macro CHANNEL_CONTROL_DR 'prm0'. %macro PERIOD_ADDRESS 'prm0'. %macro R2_A2_TEMP 'prm1'. %macro ANGLE_TIME 'prm2'. %macro RATIO_TEMP 'prm3'. %macro RATIO1_ANGLE1 'prm4'. %macro RATIO2_ANGLE2 'prm5'. %macro HIGH_TIME 'prm5'. %macro ANGLE_ANGLE_MODE 'hsq0 = 0'. %macro HIGH_TIME_MODE 'hsq0 = 1'. %macro EXECUTE_IMM_LOW 'hsq1 = 0'. %macro EXECUTE_IMM_HIGH 'hsq1 = 1'. Init_dr_pir : chan cir. %entry start_address Init_dr; name = init_dr; disable_match; cond hsr1=1,hsr0=0,. Init_dr : (* load R1, A1, R2, A2 coherently *) (* p : RATIO1, ANGLE1 *) (* diob : RATIO2, ANLGE2 *) ram diob <- @RATIO2_ANGLE2. ram p <- @RATIO1_ANGLE1. (********************************************************************) (* PROCEDURE : Check_gt_tcr2 *) (* CALLED BY : Trans_h_l, init_dr *) (* ACTION : *) (* PARAMETERS & REGISTERS : *) (* p : RATIO1, ANGLE1 *) (* diob : RATIO2, ANLGE2 *) (********************************************************************) Check_gt_tcr2 : chan set flag1; au a := tcr2; chan neg_mrl, neg_tdl, neg_lsl. (* store RATIO2_ANGLE2 into R2_A2_TEMP *) ram diob -> @R2_A2_TEMP; au nil := p_low - a, ccl. chan pin := low, TBS := out_m2_c1,pac := no_change,enable_mtsr; chan clear flag0; if N = FALSE then goto Gen_match_t1, flush. if @HIGH_TIME_MODE then goto gen_match_t1_max, flush. (********************************************************************) (* PROCEDURE : gen_match_t2_max *) (* CALLED BY : init, check_t1_lt_t2 *) (* ACTION : generate match on angle2 + 8000 *) (* PARAMETERS & REGISTERS : *) (* diob : ratio2, angle2 *) (********************************************************************) gen_match_t2_max : au p := diob. (********************************************************************) (* PROCEDURE : gen_match_t1_max *) (* CALLED BY : init, check_t1_lt_t2 *) (* ACTION : generate match on angle1 + 8000 *) (* PARAMETERS & REGISTERS : *) (* p : ratio1, angle1 *) (********************************************************************) gen_match_t1_max : chan set flag0; au ert := p_low + max; chan write_MER, neg_mrl; end. %entry ram p <- @RATIO_TEMP; start_address trns_h_l_a1_a2; name = trns_h_l_a1_a2; cond hsr1=0,hsr0=0,m/tsr = 1,lsr = 0,pin = 0,flag0 = 1. trns_h_l_a1_a2 : chan TBS := out_m2_c1,pac := no_change; chan clear flag0; if @ANGLE_ANGLE_MODE then goto h_l_a1_a2_aa, flush. if flag1 = 0 then goto Init_dr_pir, flush. h_l_a1_a2_aa : (* sample tcr2 + 1 into a *) au a := tcr2 + 1; (* store previous matched angle into sr *) (* load R1, A1, R2, A2 coherently *) (* p : RATIO1, ANGLE1 *) (* diob : RATIO2, ANLGE2 *) ram diob <- @RATIO2_ANGLE2. au sr := p_low; ram p <- @RATIO1_ANGLE1. (* store RATIO2_ANGLE2 into R2_A2_TEMP *) (* store RATIO1_ANGLE1 into RATIO_TEMP *) ram diob -> @R2_A2_TEMP. ram p -> @RATIO_TEMP; au diob := sr. (* diob - OLD_ANGLE2 *) (* p - RATIO1, ANGLE1 *) if flag1 = 1 then goto Gen_match_t1, flush. chan cir. (**********************************************************************) (* PROCEDURE : Check_t1_lt_t2 *) (* CALLED BY : Trans_h_l, trans_l_h *) (* ACTION : *) (* PARAMETERS & REGISTERS : *) (* p - r1 t1 *) (* diob - t2 (previous matched angle) *) (* a - tcr2 + 1 *) (**********************************************************************) Check_t1_lt_t2 : (* compare angle1 with old angle2 *) au nil := p_low - diob, ccl. chan set flag1; if LOW_SAME = TRUE then goto Gen_match_t2_max, flush. (* compare tcr2 + 1 to old angle2 *) au nil := a - diob, ccl. (* gen match on TCR2 (immediate match) if C = 1 & N = 1 *) chan clear flag0; if C = FALSE then goto gen_match_t1, flush. if N = TRUE then goto gen_match_t1_tbs. ram p -> @RATIO_TEMP; au ert := tcr2. (********************************************************************) (* PROCEDURE : gen_match_t1 *) (* CALLED BY : Init_dr, trans_h_l_a1_a2, check_gt_tcr2 *) (* ACTION : store ratio1, angle1 into RATIO_TEMP *) (* generate a match on angle 1 *) (* clear flag1 *) (* PARAMETERS & REGISTERS : *) (* p - RATIO1, ANGLE1 *) (********************************************************************) gen_match_t1: au ert := p_low; ram p -> @RATIO_TEMP. gen_match_t1_tbs: chan write_MER, neg_mrl; chan clear flag1; end. %entry ram p <- @RATIO_TEMP; start_address tcr2_eq_a2_r2_gt_8000; name = tcr2_eq_a2_r2_gt_8000; cond hsr1=0,hsr0=0,m/tsr = 1,lsr = 0,pin = 1,flag0 = 0. tcr2_eq_a2_r2_gt_8000: chan PAC := high_low; chan set flag0; if flag1 = 0 then goto call_compute, flush. goto match_ert_max, flush. %entry ram p <- @RATIO_TEMP; start_address tcr2_eq_a1_r1_gt_8000; name = tcr2_eq_a1_r1_gt_8000; cond hsr1=0,hsr0=0,m/tsr = 1,lsr = 0,pin = 0,flag0 = 0. tcr2_eq_a1_r1_gt_8000: chan PAC := low_high. check_rat_gt_8000 : chan set flag0; if flag1 = 0 then goto tcr2_eq_t1, flush. match_ert_max : (* ratio1 gt 8000 : generate match on MER + 8000 *) read_mer. au ert := ert + MAX; chan write_MER, neg_mrl; chan clear flag1; end. tcr2_eq_t1 : (********************************************************************) (* PARAMETERS & REGISTERS : *) (* p - RATIO_TEMP *) (********************************************************************) if @HIGH_TIME_MODE then goto call_compute, flush. (* A_A_MODE : store ert into ANGLE_TIME *) au diob := ert; ram diob -> @ANGLE_TIME. call_compute : call compute_next_edge, flush. (********************************************************************) (* PROCEDURE : check_edge_time *) (* CALLED BY : compute_next_edge *) (* ACTION : *) (* PARAMETERS & REGISTERS : *) (* p - offset time *) (********************************************************************) check_edge_time : au nil :=<< p + max, ccl. chan clear flag1; chan tbs := out_m1_c1; if LOW_SAME = TRUE then goto match_on_edge_time, flush. (* C = Şbit15 Z = (bits14..0 = 0) *) (* P <= 8000 if C=1 ³ Z=1 *) (* P <= 8000 if LOW_SAME=1 *) match_ert_8000 : (* match on ert + offset - 8000 *) chan clear flag0; au diob := ert + p. au ert := diob + max; chan write_mer, neg_mrl,pac := no_change; chan set flag1; end. match_on_edge_time : (* match on ert + offset *) au ert := ert + p; chan write_mer, neg_mrl; chan set flag0; end. %entry ram p <- @RATIO_TEMP; start_address trns_l_h_a1_gt_a2; name = trns_l_h_a1_gt_a2; cond hsr1=0,hsr0=0,m/tsr = 1,lsr = 0,pin = 1,flag0 = 1. trns_l_h_a1_gt_a2 : chan PAC := high_low, TBS := out_m2_c1; chan clear flag0; if @ANGLE_ANGLE_MODE then goto check_if_trns_l_h, flush. (* high_time mode *) store_angle_time : (* l_h mode 1 (high_time mode) - store angle time *) read_mer; chan cir. au diob := ert; ram diob -> @ANGLE_TIME. get_high_time : goto check_edge_time, flush; ram p <- @R2_A2_TEMP. (* angle_angle mode *) check_if_trns_l_h : (* p - r1_a1 *) chan pac := no_change; if flag1 = 1 then goto Gen_match_t1. au diob := p_low; ram p <- @R2_A2_TEMP. (* p - r2_a2 *) (* diob - a1 (ratio_temp)*) au a := tcr2 + 1; chan cir. au nil := p_low - diob, ccl; ram p -> @RATIO_TEMP. (* a1 =? a2 *) if Z = FALSE then goto Check_t1_lt_t2, flush. (* a1 = a2 *) a1_eq_a2 : call compute_next_edge, flush. goto trns_l_h_mode1, flush. %entry ram p <- @RATIO1_ANGLE1; start_address Immed_l_dr; name = immed_l_dr; disable_match; cond hsr1=0,hsr0=1,pin = 0. Immed_l_dr : (* load R1, A1, R2, A2 coherently *) (* p : RATIO1, ANGLE1 *) (* diob : RATIO2, ANLGE2 *) au a := tcr2; ram p <- @RATIO1_ANGLE1. au nil := p_low - a - 1, ccl; ram diob <- @RATIO2_ANGLE2. (* If Host_seq_1 = 0 then update *) (* R2_A2_TEMP and finish *) if @EXECUTE_IMM_LOW then goto check_tcr2_a1, flush. ram diob -> @R2_A2_TEMP; end. (* If TCR2 >= angle1 then *) (* do nothing *) check_tcr2_a1 : if N = TRUE then goto End_of_phase, flush. chan clear flag0; chan TBS := out_m2_c1,PAC := no_change; if TRUE then goto Gen_match_t1. (* store RATIO2_ANGLE2 into R2_A2_TEMP *) ram diob -> @R2_A2_TEMP. %entry ram p <- @RATIO2_ANGLE2; start_address Immed_h_dr; name = immed_h_dr; disable_match; cond hsr1=0,hsr0=1,pin = 1. Immed_h_dr : if @EXECUTE_IMM_LOW then goto End_of_phase, flush. if @ANGLE_ANGLE_MODE then goto Check_A1_eq_A2, flush. (* HIGH_TIME mode *) (* store new high time into R2_A2_TEMP *) ram p -> @R2_A2_TEMP. (* IF MRL=1 & flag0=1 goto l_h transition phase *) if MRL = 0 then goto trns_l_h_mode1, flush. if flag0 = 1 then goto trns_l_h_a1_gt_a2, flush. trns_l_h_mode1 : (* p - high_time *) (* diob - angle_time *) (* a - tcr1 *) (* sr - elapsed_time (tcr1 - angle_time) *) au a := tcr1; ram diob <- @ANGLE_TIME. au sr := a - diob. (* IF ELAPSED_TIME <= HIGH_TIME then gen immediate match *) au nil := sr - p, ccl. chan clear flag1; chan tbs := out_m1_c1; if C = TRUE then goto check_abs , flush. au ert := tcr1; chan write_mer, pac := high_low, neg_mrl; chan set flag0; end. check_abs : (* sr - MATCH_ABS (angle_time + high_time) *) au sr := diob + p. (* IF TCR_TEMP - MATCH_ABS < 8000 then generate match *) (* on MATCH_ABS *) au nil := a - sr, ccl. chan clear flag0; if N = FALSE then goto gen_match_abs_8000, flush. au ert := sr; chan write_mer, PAC := high_low, neg_mrl; chan set flag0; end. gen_match_abs_8000 : (* IF TCR_TEMP - MATCH_ABS >= 8000 then generate match *) (* on MATCH_ABS - 8000 *) au ert := sr + max; chan write_mer, PAC := no_change, neg_mrl; chan set flag1; end. (* ANGLE_ANGLE mode *) Check_A1_eq_A2 : (* load R1, A1, R2, A2 coherently *) (* p : RATIO2, ANGLE2 *) (* diob : ANLGE1 *) au a := tcr2; ram p <- @RATIO1_ANGLE1. au diob := p_low; ram p <- @RATIO2_ANGLE2. ram p -> @R2_A2_TEMP; (* If TCR2 <= NEW_ANGLE2 then *) (* match on NEW_ANGLE2 *) au nil := p_low - a, ccl. chan clear flag0; chan TBS := out_m2_c1,PAC := no_change; if N = FALSE then goto Gen_match_t1, flush. ram p -> @RATIO_TEMP; au nil := p_low - diob, ccl. (* If OLD_ANGLE1 = NEW_ANGLE2 *) (* treat like A1 = A2 *) chan clear flag1; if Z = TRUE then goto a1_eq_a2, flush. (* If OLD_ANGLE1 > NEW_ANGLE2 *) (* match OLD_ANGLE1 + 8000 *) chan set flag1; if N = TRUE then goto gen_match_t2_max, flush. (* If OLD_ANGLE1 < NEW_ANGLE2 *) (* Generate immediate match on *) (* TCR2 *) au ert := tcr2; chan write_MER, neg_mrl; chan clear flag1; end. %entry ram p <- @CHANNEL_CONTROL_DR; start_address force_mode; name = force_mode; cond hsr1=1,hsr0=1. force_mode : if TRUE then goto End_of_phase, flush; chan config := p, disable_mtsr. (********************************************************************) (* PROCEDURE : compute_next_edge *) (* CALLED BY : tcr2_eq_t1, check_if_trns_l_h *) (* ACTION : *) (* RES := PERIOD * RATIO / #128 *) (* PARAMETERS & REGISTERS : *) (* ON ENTRY : *) (* ---------- *) (* p - RATIO_TEMP *) (* ON EXIT : *) (* ---------- *) (* p - RESULT (PERIOD*RATIO / #128) *) (* a - RESULT / #2 (PERIOD*RATIO / #256) *) (* diob - period *) (********************************************************************) compute_next_edge : (* RES := PERIOD * RATIO *) (* a := diob * sr / #256 *) au sr := p_high; ram p <- @PERIOD_ADDRESS. au diob := p_high. au a := 0; ram diob <- by_diob. au dec := #7. repeat; au a :=>> a + diob, shift. (* a contains PERIOD*RATIO / 256 *) (* so shift left to get PERIOD*RATIO / 128 *) return. au p :=<< a. (********************************************************************) (* UNUSED ENTRIES *) (********************************************************************) %entry start_address End_of_Link; name = dr_undef; cond hsr1=0,hsr0=0,lsr = 1.