/*************************************************************************** 020_jtag.asm Copyright (c) 1994 Analog Devices Inc. All rights reserved. ***************************************************************************/ /* This file is the PROM based JTAG boot loader of the ADSP21020 processor. Gordon A. Sterling (617) 461 - 3076 Systems Software Engineering Analog Devices, Inc. Created on 5/4/94 */ .SEGMENT/DM boot_rom; .ENDSEG; .SEGMENT/PM seg_ldr; Start_Loader: L3=0; L4=0; L8=0; L9=0; L13=0; L14=0; L15=0; M6=1; M13=0; M14=1; I3=boot_rom; JUMP (PC, read_info_word) (DB); I8=skip_loader; I9=skip_loader; skip_loader: R1=6; /* 6 words per location */ R2=R1*R2 (SSI); /* Compute first address*/ M4=R2; /* Point after loader */ MODIFY(I3,M4); zero_dm_space: JUMP (PC, read_info_word) (DB); I8=init_dm_space; I9=zero_some_dm; zero_some_dm: I4=R1; /* Load start address */ LCNTR=R2, DO (PC, zdb) UNTIL LCE;/* Loop N times */ NOP; /* Avoid small loop */ zdb: DM(I4,M6)=0; /* Zero out memory */ JUMP (PC, read_info_word) (DB); /* Read address/count */ I8=init_dm_space; /* If zero, do init */ I9=zero_some_dm; /* If non-zero, loop */ init_dm_space: JUMP (PC, read_info_word) (DB); /* Read address/count */ I8=zero_pm_space; /* If zero, zero pm */ I9=init_some_dm; /* If non-zero, do init */ init_some_dm: I4=R1; /* Point to block start */ LCNTR=R2, DO (PC, copy_PROM_to_dm) UNTIL LCE; MODIFY(I3,2); /* Skip over lower bits */ R15=DM(I3,M6); R1=FDEP R15 BY 0:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 8:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 16:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 24:8; copy_PROM_to_dm: DM(I4,M6)=R1; JUMP (PC, read_info_word) (DB); /* Read address/count */ I8=zero_pm_space; /* If zero, zero pm */ I9=init_some_dm; /* If non-zero, loop */ zero_pm_space: JUMP (PC, read_info_word) (DB); /* Read address/count */ I8=init_pm_space; /* If zero, init pm */ I9=zero_some_pm; /* If non-zero, zero pm */ zero_some_pm: I12=R1; /* Load start address */ LCNTR=R2, DO (PC, zpb) UNTIL LCE;/* Loop N times */ NOP; /* Avoid small loops */ zpb: PM(I12,M14)=PX; /* Zero out memory */ JUMP (PC, read_info_word) (DB); /* Read address/count */ I8=init_pm_space; /* If zero, init pm */ I9=zero_some_pm; /* If non-zero, loop */ init_pm_space: JUMP (PC, read_info_word) (DB); /* Read address/count */ I8=start_app; /* If zero, start app */ I9=init_some_pm; /* If non-zero, init pm */ init_some_pm: I12=R1; /* Point to block start */ LCNTR=R2, DO (PC, copy_PROM_to_pm) UNTIL LCE; R15=DM(I3,M6); R2=FDEP R15 BY 0:8, R15=DM(I3,M6); R2=R2 OR FDEP R15 BY 8:8, R15=DM(I3,M6); PX1=R2; R1=FDEP R15 BY 0:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 8:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 16:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 24:8; PX2=R1; copy_PROM_to_pm: PM(I12,M14)=PX; JUMP read_info_word (DB); /* Read address/count */ I8=start_app; /* If zero, start app */ I9=init_some_pm; /* If non-zero, loop */ start_app: JUMP 0x8; /* Begin app, as if reset */ /* This function reads a single word from the PROM. Usually this word */ /* is and address/count pair which indicates the location and length */ /* of the next initialization. */ read_info_word: R15=DM(I3,M6); R2=FDEP R15 BY 0:8, R15=DM(I3,M6); R2=R2 OR FDEP R15 BY 8:8, R15=DM(I3,M6); R1=FDEP R15 BY 0:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 8:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 16:8, R15=DM(I3,M6); R1=R1 OR FDEP R15 BY 24:8; R2=PASS R2; IF EQ JUMP (M13, I8) (DB); /* If zero, goto I8 */ IF NE JUMP (M13, I9) (DB); /* If non-zer, goto I9 */ PX1=0; /* Zero out PX register because */ PX2=0; /* it is used to zero memory */ .ENDSEG;