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

📄 test_dram.asm

📁 一款MP3 Player Firmware 的原代码,非常有参考价值
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; MP3 Player, Test DRAM, http://www.pjrc.com/tech/mp3; Copyright (c) 2000, PJRC.COM, LLC; This program is free software; you can redistribute it and/or; modify it under the terms of the GNU General Public License; as published by the Free Software Foundation; either version 2; of the License, or (at your option) any later version.; This program is distributed in the hope that it will be useful,; but WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the; GNU General Public License for more details.; You should have received a copy of the GNU General Public License; along with this program; if not, write to the Free Software; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.; As a specific exception to the GPL, the executable object code built; from this source code may be combined with hardware configuration data; files.  A hardware configuration data file is a set of data that is; transmitted to an intergrated circuit that is not a general purpose; microprocessor or microcontroller, in order to establish its normal; operation.  The process of combining the executable ojbect code built; from the GPL licensed source code with the hardware configuration data; shall be considered an aggregation of another work not based on the; Program.  While the GPL does not restrict use of the program, any; use restriction associated with the hardware configuration data (for; example, that it only be used with particular hardware) shall apply; to the combined file which includes a copy of the hardware configuration; data.; Contact: paul@pjrc.com.equ    location, 0xE000        ;where this program will exist.equ    cout, 0x0030            ;Send Acc to serial port.equ    cin, 0x0032             ;Get Acc from serial port.equ    phex, 0x0034            ;Print Hex value of Acc.equ	phex1, 0x002E.equ    phex16, 0x0036          ;Print Hex value of DPTR.equ    pstr, 0x0038            ;Print string pointed to by DPTR,.equ    upper, 0x0040           ;Convert Acc to uppercase.equ    pint8u, 0x004D          ;print Acc at an integer, 0 to 255.equ    pint8, 0x0050           ;print Acc at an integer, -128 to 127.equ    pint16u, 0x0053         ;print DPTR as an integer, 0 to 65535.equ    newline, 0x0048         ;print CR/LF (13 and 10).equ    cin_filter, 0x0062      ;get a character, but look for esc sequences.equ	call_bank1, 0x0FE0.equ	alt_xdownload, 0x3000 + 73.equ    sta013_init, 0x3000 + 67.equ	test_sta013_driver, 0x3000 + 148.equ	test_count, 0x28.equ	good_mem_mask, 0x29	;4 bytes (1 bit for each 32 megs).org    location.db     0xA5,0xE5,0xE0,0xA5     ;signiture bytes.db     254,'T',0,0             ;id.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;user defined.db     255,255,255,255         ;length and checksum (255=unused).db     "DRAM and STA013 DMA Test",0.org    location+64             ;executable code begins here;memory map:;;4 megs, pages 0 to 1023;8 megs, pages 0 to 2047;16 mges, pages 0 to 1023, 2048 to 3071, 4096 to 5119, and 6144 to 7167;32 megs, pages 0 to 8191	mov	test_count, #0		;count # of testsdram_test:	lcall	cfg_fpga	clr	a	mov	good_mem_mask+0, a	mov	good_mem_mask+1, a	mov	good_mem_mask+2, a	mov	good_mem_mask+3, a	; loop1 traverses all 32 sections and checks if each is ok	mov	r2, #0	mov	r4, #0		;r4 to count # of megabytes foundsimmsz_loop1:	; loop2 writes known data into every good section we've	; found so far.  This is necessary because we will check	; it all to make sure it didn't change unexpectedly	mov	r3, #0simmsz_loop2:	mov	a, r3	clr	c	subb	a, r2	jnc	simmsz_loop2_end	mov	b, r3	lcall	is_section_ok	jnz	simmsz_loop2_next	mov	dpl, #0	mov	dph, r3	acall	set_page	acall	wr_dramsimmsz_loop2_next:	inc	r3	sjmp	simmsz_loop2simmsz_loop2_end:	; now check if this 1-meg section works by writing & reading	mov	dpl, #0	mov	dph, r2	acall	simm_test_page	jc	simmsz_skip_setting_ok	; loop3 checks all other previously known good sections to	; see if the write into this one also corrupted data in	; any other good memory.	mov	r3, #0simmsz_loop3:	mov	a, r3	clr	c	subb	a, r2	jnc	simmsz_loop3_end	;check all other pages	mov	b, r3	lcall	is_section_ok		;that were previously found good	jz	simmsz_loop3_next	mov	dpl, #0	mov	dph, r3	acall	simm_test_page_rdonly	;and if they got corrupted, then	jc	simmsz_skip_setting_ok	;this current page (r2) is bad!simmsz_loop3_next:	inc	r3	sjmp	simmsz_loop3simmsz_loop3_end:	; since this page had good memory and using it didn't corrupt	; and other pages, we'll consider it usable memory	mov	b, r2	acall	mark_section_as_ok	inc	r4simmsz_skip_setting_ok:simmsz_loop1_next:	inc	r2	cjne	r2, #32, simmsz_loop1	mov	dptr, #msg_found	lcall	pstr	mov	a, r4	lcall	pint8u	mov	dptr, #msg_usable_mem	lcall	pstr	mov	a, good_mem_mask+3	lcall	phex	mov	a, good_mem_mask+2	lcall	phex	mov	a, good_mem_mask+1	lcall	phex	mov	a, good_mem_mask+0	lcall	phex	lcall	newlinesimm_4k_check:	mov	dptr, #msg_ck_simm_block	lcall	pstr	mov	dptr, #0	acall	set_page	acall	wr_dram_4k	mov	dptr, #0	acall	set_page	acall	ck_dram_4k	jc	simm_4k_check_err	mov	dptr, #mesg_ok	lcall	pstr	sjmp	simm_4k_check_donesimm_4k_check_err:	mov	dptr, #msg_simm_block_err	lcall	pstrsimm_4k_check_done:	;let's do some more tests, which aren't really needed for	;figuring out the simm size, but it'd be nice to do.  All	;pages under 1024 should work in all simm sizesdtest3:	mov	dptr, #0	acall	v_simm_test_page	mov	dptr, #1023	acall	v_simm_test_page	mov	dptr, #341	acall	v_simm_test_page	mov	dptr, #682	acall	v_simm_test_page	mov	dptr, #981	acall	v_simm_test_page	mov	dptr, #154	acall	v_simm_test_page	mov	dptr, #256	acall	v_simm_test_page	mov	dptr, #512	acall	v_simm_test_page	mov	dptr, #2	acall	v_simm_test_page	mov	dptr, #73	acall	v_simm_test_page	mov	dptr, #1	acall	v_simm_test_page	mov	dptr, #4	acall	v_simm_test_page	mov	dptr, #555	acall	v_simm_test_page	mov	dptr, #16	acall	v_simm_test_page	mov	dptr, #1014	acall	v_simm_test_page	mov	dptr, #8	acall	v_simm_test_page	mov	dptr, #136	acall	v_simm_test_page	mov	dptr, #32	acall	v_simm_test_page	mov	dptr, #777	acall	v_simm_test_page	mov	dptr, #128	acall	v_simm_test_page	mov	dptr, #31	acall	v_simm_test_page	mov	dptr, #64	acall	v_simm_test_page	mov	dptr, #89	acall	v_simm_test_page	mov	dptr, #224	acall	v_simm_test_page	mov	dptr, #123	acall	v_simm_test_page	mov	dptr, #765	acall	v_simm_test_page	mov	dptr, #777	acall	v_simm_test_page_rdonly	mov	dptr, #154	acall	v_simm_test_page_rdonly	mov	dptr, #256	acall	v_simm_test_page_rdonly	mov	dptr, #1	acall	v_simm_test_page_rdonly	mov	dptr, #8	acall	v_simm_test_page_rdonly	mov	dptr, #2	acall	v_simm_test_page_rdonly	mov	dptr, #682	acall	v_simm_test_page_rdonly	mov	dptr, #4	acall	v_simm_test_page_rdonly	mov	dptr, #341	acall	v_simm_test_page_rdonly	mov	dptr, #16	acall	v_simm_test_page_rdonly	mov	dptr, #0	acall	v_simm_test_page_rdonly	mov	dptr, #1023	acall	v_simm_test_page_rdonlytest_sta013:	mov	dptr, #msg_dma_test        lcall   pstr        mov     dptr, #sta013_init        lcall   call_bank1        jc      test_sta013_fail	mov	dptr, #mesg_ok	lcall	pstr        mov     dptr, #test_sta013_driver        lcall   call_bank1	mov	a, dpl	jnz	test_sta013_fail	mov	dptr, #mesg_ok	lcall	pstr	rettest_sta013_fail:	mov	dptr, #mesg_error	lcall	pstr	ret	;value in b between 0-31, returns zero if that bit in	;good_mem_mask is clear, or non-zero if it is setis_section_ok:	acall	mem_mask_setup	anl	a, @r0	ret	;value in b between 0-31, mark that megabyte of memory as okmark_section_as_ok:	acall	mem_mask_setup	orl	a, @r0	mov	@r0, a	ret	;given a number in b from 0 to 31, set up r0 to point	;to the byte within "good_mem_mask", and return Acc	;with the bitmask for the bit within that bytemem_mask_setup:	mov	a, b	swap	a	rl	a	anl	a, #3	add	a, #good_mem_mask	mov	r0, a	mov	a, b	anl	a, #7	inc	a	movc	a, @a+pc	ret	.db	1, 2, 4, 8, 16, 32, 64, 128;test a page of DRAM memory (specified by dptr).  Return C=1 if;an error, or C=0 if ok.  Normally bytes are written to the;page and then read back, but "simm_test_page_rdonly" may be;called to read the page and see if previously written data;is ok.simm_test_page:	push	dpl	push	dph	acall	set_page	acall	wr_dram	pop	dph	pop	dplsimm_test_page_rdonly:	acall	set_page	ajmp	ck_dramv_simm_test_page:	push	dpl	push	dph	acall	simm_test_page	jnc	no_news_is_good_newssimm_test_error:	mov	dptr, #msg_warn_simm	lcall	pstr	pop	dph	pop	dpl	mov	a, dph	lcall	phex	mov	a, dpl	lcall	phex	lcall	newline	acall	print_test_buffer	acall	set_page	acall	print_test_buffer	lcall	newline	retv_simm_test_page_rdonly:	push	dpl	push	dph	acall	simm_test_page_rdonly	jc	simm_test_errorno_news_is_good_news:	pop	dph	pop	dpl	retprint_test_buffer:	mov	r1, #test_data_bufferprint_test_buffer_loop:	mov	a, @r1	lcall	phex	inc	r1	cjne	r1, #test_data_buffer+num_test_bytes, print_test_buffer_loop	lcall	newline	ret	;maps a block at 0000, and also sets up r5 as a seed	;for that block number, so that we can write some	;data into that block that's different from any	;other block (we hope).set_page:	mov	a, dpl	xrl	a, #01001101b	xrl	a, dph	xrl	a, #10110010b	mov	r5, a			;set rand seed based on block #	mov	r1, #test_data_buffer	mov	a, dpl	xrl	a, #01110101b	mov	@r1, a			;store block # into buffer	inc	r1	mov	a, dph	xrl	a, #01110101b	mov	@r1, a	inc	r1set_page_loop:	acall	rand8	mov	@r1, a			;fill rest of buffer with "rand" data	inc	r1	cjne	r1, #test_data_buffer+num_test_bytes, set_page_loop	mov	a, dpl	mov	b, dph	mov	dptr, #dram_page_cfg	movx	@dptr, a		;and map this block at 0000-0FFF	inc	dptr	mov	a, b	movx	@dptr, a	ret.equ	num_test_bytes, 16.equ	test_data_buffer, 0xC0	;write data in test_data_buffer to DRAMwr_dram:	mov	dptr, #0	mov	r1, #test_data_bufferwr_dram_loop:	mov	a, @r1	inc	r1	movx	@dptr, a	inc	dptr	cjne	r1, #test_data_buffer+num_test_bytes, wr_dram_loop	ret	;compare data in DRAM to test_data_buffer	;return C=0 if good, C=1 if any error	;test_data_buffer is filled with data from DRAMck_dram:	mov	dptr, #0	mov	r1, #test_data_buffer	clr	psw.5ck_dram_loop:	movx	a, @dptr	mov	b, a	clr	c	subb	a, @r1	jz	ck_dram_next	mov	@r1, b	setb	psw.5ck_dram_next:	inc	dptr	inc	r1	cjne	r1, #test_data_buffer+num_test_bytes, ck_dram_loop	mov	c, psw.5	ret	;fill a block with short clips of data at 256 byte intervalswr_dram_4k:	mov	r0, #0wr_4k_1:mov	dph, r0	mov	dpl, #0wr_4k_2:acall	rand8	movx	@dptr, a	inc	dptr	mov	a, dpl	cjne	a, #9, wr_4k_2	inc	r0	cjne	r0, #16, wr_4k_1	ret	;check a block with short clips of data at 256 byte intervals	;C=0 if the data is all good, C=1 if there's a problemck_dram_4k:	mov	r0, #0ck_4k_1:mov	dph, r0	mov	dpl, #0ck_4k_2:acall	rand8	mov	b, a	movx	a, @dptr	cjne	a, b, ck_4k_err	inc	dptr	mov	a, dpl	cjne	a, #9, ck_4k_2	inc	r0	cjne	r0, #16, ck_4k_1	clr	c	retck_4k_err:	setb	c	ret; generate an 8 bit random number, r5 holds the "seed"rand8:  mov     a, r5        jnz     rand8b        cpl     a        mov     r5, arand8b: anl     a, #10111000b        mov     c, p        mov     a, r5        rlc     a        mov     r5, a        retcfg_fpga:	mov	dptr, #mesg_xilinx_cfg	lcall	pstr	mov	dptr, #alt_xdownload	lcall	call_bank1	jc	error	mov	dptr, #mesg_ok	lcall	pstr	reterror:	mov	dptr, #mesg_error	lcall	pstr	ljmp	0; Simple communication with an IDE disk drive.equ	buffer, 0x0000		;a 512 byte buffer;registers implemented in the FPGA.equ	dram_page_cfg,	0xFF00.equ	ide_data,	0xFF60.equ	ide_err,	0xFF62.equ	ide_sec_cnt,	0xFF64.equ	ide_sector,	0xFF66.equ	ide_cyl_lsb,	0xFF68.equ	ide_cyl_msb,	0xFF6A.equ	ide_head,	0xFF6C.equ	ide_command,	0xFF6E.equ	ide_status,	0xFF6E.equ	ide_control,	0xFF7C.equ	ide_astatus,	0xFF7E.equ	ide_rst_bit,	0xFF40.equ	ide_data_buf_msb, 0xFF43.equ	dma_ide_dest,	0xFF22.equ	dma_ide_count,	0xFF24.equ	irq_dma_ide_ack,0xFF5C.equ	dma_ide_go,	0xFF58.equ	irq_ident,	0xFF50.equ	dma_mp3_src,	0xFF28.equ	dma_mp3_count,	0xFF2A.equ	dma_mp3_go,	0xFF59.equ	irq_dma_mp3_ack,0xFF5D;IDE Command Constants.  These should never change..equ	ide_cmd_recal, 0x10.equ	ide_cmd_read, 0x20.equ	ide_cmd_write, 0x30.equ	ide_cmd_init, 0x91.equ	ide_cmd_id, 0xEC.equ	ide_cmd_spindown, 0xE6.equ	ide_cmd_spinup, 0xE1.equ    ide_cmd_sleep, 0xE6.equ	ide_cmd_initparms, 0x91;------------------------------------------------------------------;internal ram usage.equ	lba, 0x70		;4 bytes, 28 bit Logical Block Address.equ	sec_count, 0x74;------------------------------------------------------------------; Main Program, a simple menu driven interface..org	location+0x400.db     0xA5,0xE5,0xE0,0xA5     ;signiture bytes.db     35,255,0,0              ;id, 35=program.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;reserved.db     0,0,0,0                 ;user defined.db     255,255,255,255         ;length and checksum (255=unused).db     "IDE Disk Drive Test",0.org    location+0x400+64             ;executable code begins here	lcall	cfg_fpga	mov	dptr, #msg_1	;print a welcome message	lcall	pstr	;initialize the drive.  If there is no drive, this may hang	acall	ide_init	;get the drive id info.  If there is no drive, this may hang	acall	drive_id	; print the drive's model number	mov	dptr, #msg_mdl	lcall	pstr	mov	dptr, #buffer + 60	mov	r0, #40	acall	print_name	lcall	newline	; print the drive's serial number	mov	dptr, #msg_sn	lcall	pstr	mov	dptr, #buffer + 20	mov	r0, #20	acall	print_name	lcall	newline	; print the drive's cylinder, head, and sector specs	mov	dptr, #msg_cy	lcall	pstr	mov	dptr, #buffer + 2	acall	print_parm	mov	dptr, #msg_hd	lcall	pstr

⌨️ 快捷键说明

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