⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 21060_prom.asm

📁 ADSP21060处理器PROM加载ASM代码
💻 ASM
字号:
/***************************************************************************

	060_prom.asm

	Copyright (c) 1994 Analog Devices Inc.  All rights reserved.

***************************************************************************/
 	
/*

	This file is the PROM based boot loader of the ADSP21060 processor.

	Gordon A. Sterling		(617) 461 - 3076
	Systems Software Engineering
	Analog Devices, Inc.	

	Created on 1/4/94
	
*/

/* Define the addresses of various IOP registers			*/

#define SYSCON 0x00	
#define SYSTAT 0x03	
#define II6    0x40	
#define IM6    0x41	
#define C6     0x42	
#define EI6    0x45	
#define EM6    0x46	
#define EC6    0x47	

#define DMAC6  0x1c	

.SEGMENT/PM	seg_ldr;

/* The loader begins with the interrupts up to and including the low 	*/
/*  priority timer interrupt.						*/

		NOP;NOP;NOP;NOP;	/* Reserved interrupt		*/

___lib_RSTI: 	IDLE;			/* Implicit IDLE instruction	*/
		JUMP Start_Loader (DB);	/* Begin loader			*/
		NOP;			/* Pad to next interrupt	*/
		NOP;			/* Pad to next interrupt	*/

		NOP;NOP;NOP;NOP;	/* Reserved interrupt		*/

/* Vector for status stack/loop stack overflow or PC stack full: 	*/
___lib_SOVFI:	RTI;
		RTI;
		RTI;
		RTI;

/* Vector for high priority timer interrupt: 				*/
___lib_TMZHI:	RTI;
		RTI;
		RTI;
		RTI;

/* Vectors for external interrupts:					*/
___lib_VIRPTI:	RTI;
		RTI;
		RTI;
		RTI;

___lib_IRQ2I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_IRQ1I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_IRQ0I:	RTI;
		RTI;
		RTI;
		RTI;

		NOP;NOP;NOP;NOP;		/* Reserved interrupt	*/

/* Vectors for Serial port DMA channels: 				*/
___lib_SPR0I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_SPR1I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_SPT0I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_SPT1I:	RTI;
		RTI;
		RTI;
		RTI;

/* Vectors for link port DMA channels: 					*/
___lib_LP2I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_LP3I:	RTI;
		RTI;
		RTI;
		RTI;

/* Vectors for External port DMA channels: 				*/
___lib_EP0I:	R2=DM(DMAC6);		/* Get DMAC Control setting	*/
		RTI (DB);
		R6=0;
		DM(DMAC6)=R6;		/*  zeroed between uses.	*/

___lib_EP1I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_EP2I:	RTI;
		RTI;
		RTI;
		RTI;

___lib_EP3I:	RTI;
		RTI;
		RTI;
		RTI;

/* Vector for Link service request					*/
___lib_LSRQ:	RTI;
                RTI;
		RTI;
		RTI;

/* Vector for DAG1 buffer 7 circular buffer overflow			*/
___lib_CB7I:	RTI;
		RTI;
		RTI;
		RTI;

/* Vector for DAG2 buffer 15 circular buffer overflow			*/
___lib_CB15I:	RTI;
		RTI;
		RTI;
		RTI;

/* Vector for lower priority timer interrupt				*/
___lib_TMZLI:	RTI;
		RTI;
		RTI;
		RTI;

Start_Loader:	L0=0;			/* Zero out L-registers so they	*/
		L4=0;			/*  can be used without wrap	*/
		L7=0;
		L8=0;
		L12=0;
		L15=0;

		M5=0;			/* Setup M-registers to use for	*/			
		M6=1;			/*  for various memory transfers*/
		M13=0;
		M14=1;
				
		R10=DM(SYSCON);		/* Read current SYSCON setting	*/
		R12=PASS R10;		/* Hold Initial SYSCON setting	*/
		R11=BSET R10 BY 1;	/* Set BSO bit for reading ROM	*/
		R10=BCLR R10 BY 1;	/* Clear BSO bit for ext write	*/

		DM(SYSCON)=R10;		/* Clear BSO bit for writing RAM*/

		BIT SET IMASK 0x10000;	/* Enable EP0 interrupt		*/
		BIT SET MODE1 0x1800;	/* Enable interrupts and nesting*/

		R14=0x0221;		/* Remove for universal loader	*/
/*		R14=PASS R2;		Use this for universal loader	*/

		R15=3;			/* EC to load one 48-bit word	*/
		R0=DM(SYSTAT);		/* Load the Host ID for use with*/
		R0=FEXT R0 BY 8:3;	/*  the PROM loader. 		*/

		BTST R14 BY 9;		/* Is this a PROM load?		*/
		IF SZ R11=PASS R10, R0=M5;/* No, don't change BSO bit	*/
		IF NOT SZ R15=R15+R15;	/* Yes, set to 6 bytes/48-bit	*/

		BTST R14 BY 0;		/* Is this a LINK load?		*/
		IF SZ R11=PASS R10, R0=M5;/* Yes, don't change BSO bit	*/
		IF SZ R15=ASHIFT R15 BY 2;/* Yes, set to 12 nibs/48-bit	*/

		DM(IM6)=M13;		/* Setup the DMA registers for	*/
		DM(EM6)=M14;

		I4  = 0x400600;		/* Address of boot rom		*/
		I7  = SYSCON;		/* Address of SYSCON		*/
		I12 = SYSCON;		/* Address of SYSCON		*/
		I15 = 0x20004;

		R0=PASS R0;		/* Test for HostID == 0		*/
		IF EQ JUMP read_boot_info;	/* Skip over multi-boot	*/

get_addr:	CALL read_PROM_word (DB);
		NOP;
		NOP;

		COMP(R0, R2);
		IF NE JUMP get_addr (DB);
		NOP;
		NOP;

		DM(EI6)=R3;			/* Point to address in PROM	*/

read_boot_info:	CALL read_PROM_word (DB);
		NOP;	
		NOP;

		R0=PASS R2;

		CALL read_PROM_word (DB);
		NOP;
		NOP;

load_memory:	R0=PASS R0;
		IF NE JUMP (PC, test_dm16_zero);

/* After the IDLE completes, the following sequence of instructions will*/
/* be executed: (Remember these are in a loop)				*/
/*	R0=R0-R0, DM(I4,M5)=R9, PM(I12,M13)=R11				*/
/* This instructions sets the EQ flag to terminate the loop, writes 	*/
/* the original value to SYSCON, and writes a *new* instruction over	*/
/* itself.  The new instruction is:					*/
/*	PM(0, I8)=PX;							*/
/* This instruction resets the DMA6 vector to whatever it should be.	*/
/* The loop will terminate, because of the previous set EQ.  Instruction*/
/* flow will continue with 0x20005, just like nothing happened!		*/

final_init:	R9=0xb1db0000;		/* Load instruction PM(0,I8)=PX;*/
		R11=BSET R11 BY 8;	/* Set IDW to 1 for inst write	*/
		DM(SYSCON)=R11;		/* Setup to read PROM, inst wrt	*/

		R1=0x020000;		/* Point to destination		*/
		R2=0x100;		/* Load length of last init	*/
		R4=R2*R15 (SSI);	/* Compute external length	*/

		DM(IM6)=M14;		/* Set to increment internal ptr*/

		I4=0x020004;		/* Point to 0x020004 for patch	*/
		I8=0x020040;		/* Point to DMA6 vector to patch*/

		R4=PASS R4, R11=R12;	/* Clear AZ, hold initial SYSCON*/

		DO ___lib_RSTI UNTIL EQ;/* Setup dummy loop		*/

		R0=PCSTK;		/* Clean off old top-of-loop	*/
		R0=0x20004;		/*  and replace with new	*/
		PCSTK=R0;		/*  top-of-loop value		*/

		DM(II6)=R1;		/* Setup DMA to load over ldr	*/
		DM(C6)=R2;		/* Load internal count		*/
		DM(EC6)=R4;		/* Load external count		*/
		JUMP 0x20004 (DB);	/* Jump to start		*/
		DM(DMAC6)=R14;		/* Start DMA transfer		*/
		IDLE;			/* After IDLE, patch then start	*/

test_dm16_zero:	R0=R0-1;
		IF EQ JUMP (PC, dm16_zero);
		R0=R0-1;
		IF NE JUMP (PC, test_dm40_zero);

dm32_zero:
dm16_zero:	R0=R0-R0, I0=R3;
		LCNTR=R2, DO dm16_zero_loop UNTIL LCE;	
			NOP;
dm16_zero_loop:		DM(I0,M6)=R0;

		JUMP read_boot_info;

test_dm40_zero:	R0=R0-1;
		IF NE JUMP (PC, test_dm16_init);

dm40_zero:	PX1=0;	
		PX2=0;
		R0=R0-R0, I0=R3;
		LCNTR=R2, DO dm40_zero_loop UNTIL LCE;
			NOP;
dm40_zero_loop:		DM(I0,M6)=PX;

		JUMP read_boot_info;

test_dm16_init:	R0=R0-1;
		IF NE JUMP (PC, test_dm32_init);

dm16_init:	I0=R3;
		LCNTR=R2, DO dm16_init_loop UNTIL LCE;
			CALL read_PROM_word (DB);
			NOP;
			NOP;

dm16_init_loop:		DM(I0,M6)=R3;

		JUMP read_boot_info;

test_dm32_init:	R0=R0-1;
		IF NE JUMP (PC, test_dm40_init);

dm32_init:	I0=R3;
		LCNTR=R2, DO dm32_init_loop UNTIL LCE;
			CALL read_PROM_word (DB);
			NOP;	
			NOP;
			
dm32_init_loop:		DM(I0,M6)=R3;

		JUMP read_boot_info;

test_dm40_init:	R0=R0-1;
		IF NE JUMP (PC, test_pm16_zero);

dm40_init:	I0=R3;
		LCNTR=R2, DO dm40_init_loop UNTIL LCE;
			CALL read_PROM_word (DB);
			NOP;
			NOP;

dm40_init_loop:		DM(I0,M6)=PX;
		JUMP read_boot_info;

test_pm16_zero:	R0=R0-1;
		IF EQ JUMP (PC, dm16_zero);
		R0=R0-1;
		IF EQ JUMP (PC, dm32_zero);

test_pm40_zero:	R0=R0-1;
		IF EQ JUMP (PC, dm40_zero);
		R0=R0-1;
		IF NE JUMP (PC, test_pm16_init);

pm48_zero:	PX1=0;
		PX2=0;
		R0=R0-R0, I8=R3;
		LCNTR=R2, DO pm40_zero_loop UNTIL LCE;	
			NOP;
pm40_zero_loop:		PM(I8,M14)=PX;

		JUMP read_boot_info;

test_pm16_init:	R0=R0-1;
		IF EQ JUMP (PC, dm16_init);

test_pm32_init:	R0=R0-1;
		IF EQ JUMP (PC, dm32_init);

test_pm40_init:	R0=R0-1;
		IF EQ JUMP (PC, dm40_init);

test_pm48_init:	R0=R0-1;
		IF NE JUMP read_boot_info;

pm48_init:	I8=R3;
		LCNTR=R2, DO pm48_init_loop UNTIL LCE;
			CALL read_PROM_word (DB);
			NOP;
			NOP;

pm48_init_loop:		PM(I8,M14)=PX;
		JUMP read_boot_info;

read_PROM_word:	R13=DM(SYSCON);		/* Save old value of SYSCON	*/
		DM(SYSCON)=R11;		/* Set BSO bit for ROM read	*/
		DM(II6)=I15;		/* Setup DMA destination address*/
		DM(C6)=M14;		/* Setup DMA internal length	*/
		DM(EC6)=R15;		/* Setup DMA external count	*/
		DM(DMAC6)=R14;		/* Start DMA 			*/
		IDLE;			/* Wait for DMA to complete	*/
		PX=PM(0x020004);	/* Read word from scratch	*/
		DM(SYSCON)=R13;		/* Reset SYSCON to previous	*/
		RTS (DB);
		R2=PX1;			/* Copy PX values into DREGS	*/
		R2=PASS R2, R3=PX2;	/* Test the length		*/

.ENDSEG;







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -