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

📄 up2dsptest1.asm

📁 This program allows reading or writing values to and from the DSP through hyperterminal serial por
💻 ASM
📖 第 1 页 / 共 2 页
字号:

;FILE: microp2dsp.ASM
;
; This program allows reading or writing values to and from the DSP
; through hyperterminal serial port interface.
;
; command -- function description
; dr.... -- data memory read, eg dr22aa, reading data mem 0x22aa
; dw.... xxxx -- data memory write, eg dw22aa 12bb, writing data mem addr=0x22aa value = 0x12bb
; pr.... -- prog memory read, eg pr22aa, reading prog mem 0x22aa
; pw.... xxxx -- prog memory write, eg pw22aa 12bbcc, writing prog mem addr=0x22aa value =0x12bbcc
;
; register used:
; R0,1,2,3,4,5,6,7 in bank 0
; R0,1,2,3,4,5	in bank 1, 0xe,f,a,b,c
; A, B
;
; B -- used in interrupt routine
;
; by Francis Tiong
; 11th July 2005
;
;*********************************************************
CODE_SEG	segment	code
reg_seg		segment data
data_seg	segment data
bit_seg		segment bit
stack_seg	segment idata

#define UALE P3.2
#define	UWR P3.6
#define URD P3.7

#define NOT_USE_MOVX 1
#define AUTO_BAUD_RATE	0
#define testmode	0
#define testmode_further	0
;	PCON EQU 87H


;********************************************************************
; Interrupt vector table
;********************************************************************
                org 0               ; System reset      RST
                ljmp MAIN

                org 3               ; External 0        IE0
                reti

                org 0bh             ; Timer 0           TF0
                reti

                org 13h             ; External 1        IE1
                reti

                ;org 1bh             ; Timer 1           TF1
                ;reti

				org 23h
                ljmp ser_isr         ; Serial port       TI or RI

                org 2bh             ; Timer 2           TF2 or EXF2
                reti

	rseg reg_seg
	ds	18h

; define variables
	rseg	stack_seg
	org 	40h
stack:	ds	20

	rseg	data_seg
tmp_space:	ds	20	; bit addressable space should not be used for data

	rseg	data_seg
		; needed in case of extra copy in rxbuf 
rxbuf:	ds	40									   
rxbuf_ptr:	ds	1			; num values not processed in rxbuf,
							; if pointer exceeds half size of rxb then send xoff
txbuf:	ds	1
tmp_sav:ds	1

	rseg	bit_seg
sign_tst: dbit	8
txflag:	dbit	1			; 1=there is data in txbuf need to be sent
rxflag: dbit	1
rxdone:	dbit	1			; set to 1 when no more data need to be processed in rxbuf 

sav_C:	dbit	1			; saving the carry bit in interrupt

flow_control: dbit 1		; 1= transmitted xoff
download: dbit 	1			; 1= downloading code
last_byte : dbit 	0			;flag to indicate the last byte of program
byte0high			EQU		35h;
byte0middle			EQU		34h;
byte0low			EQU		37h;
;********************************************************************

	rseg	code_seg
	ORG 40H

MAIN:   
	MOV	SP, #stack	; init stack pointer

; setting timer and serial port
;S_INIT:
#if AUTO_BAUD_RATE
	CLR	TR1
	MOV	SCON,#01011010B	;TI set indicates transmitter ready.
				; mode 1,REN,
	MOV	TMOD,#00100001B	;Timer 1 is set to auto-reload timer mode.
	ORL	PCON,#80H     ; SMOD	; Set SMOD to double baud rate

			; wait for <space> from console, measure its
			; speed, and set baud rate in Timer 1 accordingly.
BAUDDET:
	MOV	TH1,#0	;Assume fastest rate.
	MOV	R0,#72	;144, 72 wait 1.5 bit times.
	JB	RXD,$	; wait for start bit								   
BAUDID:	DJNZ	R0,$
	DEC	TH1
	MOV	R0,#46	;94, 46, wait 1 bit time.
	JNB	RXD,BAUDID
	JB	RXD,$	;Hang-up here until space char. over.
	JNB	RXD,$

	SETB	TR1		; start timer
#else

; setting timer and serial port
	MOV SCON,#50H             ;SET SERIAL PORT FOR MODE 1 OPERATION
	MOV PCON,#80H		  ;80h SET DOUBLE BAUD RATE BIT to 38.4k
        MOV TMOD,#20H             ;SET TIMER 1 TO AUTO RELOAD
        MOV TH1,#0FDH             ;LOAD RELOAD VALUE FOR 19.2k BAUD AT 16MHZ
        MOV TCON,#40H             ;START TIMER 1
        CLR TI
		MOV SBUF,#62H            ;TRANSMIT b=62 HEX OUT THE TXD LINE

		MOV A, #20H		 ;transmit space
		CALL TRANS_BYTE
#endif

	SETB 	ES		; enable srial interrupts
	SETB	EA		; enable all


	CLR	TXFLAG		; no data left in txbuf
	clr	rxflag
;	SETB TXDONE		; no data need to be sent
	SETB rxdone		; no data need to be processed
	clr flow_control	; xoff not yet sent 
	clr A;
	MOV rxbuf_ptr, #0


#if 1
	CLR C			;zero ALU carry flag	
				;8E=address of AUXR
	MOV 8EH, #03H		;set EXTRAM and AO to one
				; AO one will disable ALE	
	MOV P1, #02		; p1.0 = cs = LOW, p1.1=rst = HIGH

	MOV A, #62H		 ;transmit b=62 hex
	CALL TRANS_BYTE
#endif


; begin 

	call intro		;print out welcome message
	MOV rxbuf_ptr, #0
label:		
	MOV P0, #0H

	CALL RECEI_BYTE


#if 1
; check for commands, mem flag

#if 1
	CJNE	A,#1BH,NOT_FILE
	SETB	download		; downloading file

	JMP		FILE_XFR
#endif

NOT_FILE:
	CLR		download		;not downloading file

	MOV     R2, #0		; R2 = flag for dm=0x40 or pm dm=0
	CJNE	A,#64H,check_p		; d = 0x64

	; command 'd' received
	MOV 	R2, #40H
	SJMP	GOT_MEM_FLAG		
		
check_p: CJNE	A,#70H,label		; p = 0x70
	
GOT_MEM_FLAG:	CALL TRANS_BYTE


; check for commands, read/write flag	
	CALL RECEI_BYTE

	MOV     R4, #0		; R4 = flag for read=0 or write =1
	CJNE	A,#77H,check_r		; w = 0x77

	; command 'd' received
	MOV 	R4, #1H
	SJMP	GOT_RW_FLAG
		
check_r:	CJNE	A,#72H,label		; R = 0x72
	
GOT_RW_FLAG:	CALL TRANS_BYTE


; get high byte of address , send in addr 04
	CALL GET_BCD			; getting a BCD valued byte in A

	ORL	A, R2			; mem flag set in
					; high byte ready
#if NOT_USE_MOVX
; this section not using movx

;	MOV	R0, #04H	; R0= external address
	MOV	P0, #04H
	CLR	UALE

	MOV	P0, A
	CLR	UWR
	SETB	UWR
	SETB	UALE
#else
; this section for use of movx
	MOV	R0, #04H	; R0= external address
	MOVX	@R0, A
#endif

; get low byte of address , send in addr 05
	CALL GET_BCD			; getting a BCD valued byte in A

#if NOT_USE_MOVX

	MOV	P0, #05H
	CLR	UALE

	MOV	P0, A
	CLR	UWR
	SETB	UWR
	SETB	UALE
#else

; this section use Movx
	MOV	R0, #05H	; R0= external address
	MOVX	@R0, A
#endif
; send RW request in addr 02

	MOV	A, R4

#if NOT_USE_MOVX

	MOV	P0, #02H
	CLR	UALE

	MOV	P0, A
	CLR	UWR
	SETB	UWR
	SETB	UALE

#else
; this section use movx
	MOV	R0, #02H	; R0= external address
	MOVX	@R0, A
#endif
; check R or W , if W then fetch 16-bit data word

	DJNZ	R4, DO_READ

;write command process
PROCESS_WRITE_CMD:	CALL RECEI_BYTE				; expect one space between address and data
	CJNE	A,#20H,PROCESS_WRITE_CMD	; space = 0x20

	CALL TRANS_BYTE

	; get high byte of data
	CALL GET_BCD			; getting a BCD valued byte in A
	MOV	0CH, A			; high byte

	; get low byte of data
	CALL GET_BCD			; getting a BCD valued byte in A
	MOV	0BH, A			; 

	;if PM write then there is one more
	CJNE	R2,#0H,WRITE_CMD_DM	; if R2!=0 then DM

	CALL GET_BCD			; getting a BCD valued byte in A
	MOV	0AH, A			; lowest byte

	
; sending data out, high order byte first
WRITE_CMD_DM:	

#if NOT_USE_MOVX

; this section does not use movx
	MOV	P0, #06H	
	CLR	UALE

	MOV	P0, 0CH		; 0c
	CLR	UWR
	SETB	UWR
	SETB	UALE

	MOV	P0, #06H	
	CLR	UALE

	MOV	P0, 0BH		; 0b
	CLR	UWR
	SETB	UWR
	SETB	UALE

	
	CJNE	R2,#0H,end_wr_done	; if R2!=0 then DM

	MOV	P0, #06H	
	CLR	UALE

	MOV	P0, 0AH		; 0a
	CLR	UWR
	SETB	UWR
	SETB	UALE

end_wr_done:	nop
        JMP label                  ;DO IT ALL OVER AGAIN	
#else

	MOV	R0, #06H	; R0= external address, send to addr 6

; this section use movx
	MOV	A, 0CH
	MOVX	@R0, A

	MOV	A, 0BH
	MOVX	@R0, A
	
	CJNE	R2,#0H,label	; if R2!=0 then DM

	MOV	A, 0AH
	MOVX	@R0, A

        JMP label                  ;DO IT ALL OVER AGAIN	
#endif

;READ command process		
DO_READ: NOP  
;	CALL FUNC_DO_READ
;	CALL FUNC_DO_READ
;        JMP label                  ;DO IT ALL OVER AGAIN

FUNC_DO_READ:	
	MOV	A, #20H		;sending a space
	CALL 	TRANS_BYTE

	; get two nibbles
#if NOT_USE_MOVX

	MOV	P0, #06H	
	CLR	UALE

	MOV	P0, #0FFH	;prepare read input

	CLR	URD
	MOV	A, P0		;get one byte from DSP
	SETB	URD
	SETB	UALE
#else
; this section use movx
	MOV	R0, #06H	;get one byte from DSP
	MOVX	A, @R0
#endif

	MOV	R5,A		;R5= raw 2x 4 bits received

	; do nibble 0
	CALL	BCD_ASCII	;input in A, return in A


	MOV	0EH, A		;using location 13,12,11,10,9,8 to store result

	MOV	A, R5
	SWAP 	A

	; do nibble 1
	CALL	BCD_ASCII	;input in A, return in A

	MOV	0FH, A		;using location 13,12,11,10,9,8 to store result

	; get two nibbles
#if NOT_USE_MOVX

	MOV	P0, #06H	
	CLR	UALE

	MOV	P0, #0FFH	;prepare read input

	CLR	URD
	MOV	A, P0		;get one byte from DSP
	SETB	URD
	SETB	UALE
#else
; this section use movx
	MOV	R0, #06H	;get one byte from DSP
	MOVX	A, @R0
#endif

	MOV	R5,A		;R5= raw 2x 4 bits received

	; do nibble 2
	CALL	BCD_ASCII	;input in A, return in A
	
	MOV	0AH, A		;using location 13,12,11,10,9,8 to store result

	MOV	A, R5
	SWAP 	A

	; do nibble 3
	CALL	BCD_ASCII	;input in A, return in A
	
	MOV	0BH, A		;using location 13,12,11,10,9,8 to store result


	;check to see if PM word, if so then read two more nibbles
	CJNE	R2, #0, READ_DONE

	; get two nibbles
#if NOT_USE_MOVX

	MOV	P0, #06H	
	CLR	UALE

	MOV	P0, #0FFH	;prepare read input

	CLR	URD
	MOV	A, P0		;get one byte from DSP
	SETB	URD
	SETB	UALE

#else
; this section use movx
	MOV	R0, #06H	;get one byte from DSP
	MOVX	A, @R0
#endif

	MOV	R5,A		;R5= raw 2x 4 bits received

	; do nibble 4
	CALL	BCD_ASCII	;input in A, return in A
	
	MOV	0CH, A		;using location 13,12,11,10,9,8 to store result

	MOV	A, R5
	SWAP 	A

	; do nibble 5
	CALL	BCD_ASCII	;input in A, return in A
	
	MOV	0DH, A		;using location 13,12,11,10,9,8 to store result

	;done getting ASCII values, now send to screen
READ_DONE:	MOV	A, 0FH
	CALL 	TRANS_BYTE

	MOV	A, 0EH
	CALL 	TRANS_BYTE

	MOV	A, 0BH
	CALL 	TRANS_BYTE

	MOV	A, 0AH
	CALL 	TRANS_BYTE

	;check to see if PM word, if so then read two more nibbles
	CJNE	R2, #0, end_rd_done

	MOV	A, 0DH
	CALL 	TRANS_BYTE

	MOV	A, 0CH
	CALL 	TRANS_BYTE

end_rd_done:	nop
;	RET
        JMP label                  ;DO IT ALL OVER AGAIN

#endif		
;*********************************************									  
; receive byte
; return value in A
;   first check to see if data in if not then wait
;	then read in data from rxbuf
;	next copy all unread data up by one... ie. rxbuf[0]=rxbuf[1] 
;*********************************************
RECEI_BYTE:

	JB     rxdone,$            ;Wait until character received.
	MOV     R6,rxbuf          ;Read input character.

	CLR	rxflag		;Clear reception flag.

	; check if needed to copy buffer content
	MOV A, rxbuf_ptr
	DEC A
	MOV rxbuf_ptr, A


	JZ SET_RXDONE


	; update receive buffer by shifting content by one
	MOV R7, rxbuf_ptr		; counter for use in decimation loop

	MOV A, #rxbuf
	ADD A, rxbuf_ptr
	MOV R1, A

UPDATE_RXBUF:	MOV R0, 01H		; MOV R0, R1
	MOV A, R0
	DEC A
	MOV R1, A

	MOV A, @R0
	MOV @R1, A
	DJNZ	R7, UPDATE_RXBUF


SET_RXDONE_RTN:
	MOV A, R6

	RET

SET_RXDONE:
	SETB rxdone		; no more data inside

	JBC flow_control, SET_XON	; if xoff has been sent now should send xon
	SJMP SET_RXDONE_RTN

SET_XON:
	MOV	A, #17	;xon
	CALL TRANS_BYTE
	MOV A, #'X'
	call TRANS_BYTE
	MOV A, #'N'
	call TRANS_BYTE

	SJMP SET_RXDONE_RTN

;transmit byte
; transmit value in A
TRANS_BYTE:
#if 0
	JB	TXFLAG,$	; not too hot, because it's blocking.

	MOV	TXBUF,A		;Write out character.
	SETB	TXFLAG

	JNB	TXDONE,TRANSB_RET
	SETB	TI
TRANSB_RET:	RET
#endif

#if 1 
;this is non-interrupt version, not used       
	JNB TI,$                  ;WAIT UNTIL TRANSMISSION COMPLETED
        CLR TI                    ;READY TO TRANSMIT ANOTHER
	MOV SBUF,A
#endif
	RET

#if 1
;Converting ASCII value to BCD value
; input can be upper or lower case letters
;Input A, Output A
ASCII_BCD:	
	MOV	R1,A		;R1= raw received byte
	SUBB 	A, #61H		;subtract to check whether it is numbers or letters
				;subtract to get back lower case value from ASCII format
	MOV	R6, #57H
	JNB	ACC.7,RECEIVE_LTR

;	MOV	20H,A		;20= temp testing location
;	JNB	20H.7,RECEIVE_LTR	; check sign bit of R2
	MOV	A, R1		

	SUBB 	A, #40H		;subtract to get back upper case value from ASCII format
	MOV	R6, #37H
	JNB	ACC.7,RECEIVE_LTR

	MOV 	R6, #2FH		;subtract to get back num value from ASCII format


RECEIVE_LTR:	MOV A, R1
		SUBB A, R6
	RET

;**************************************************
; Returning one byte address or data in BCD form in A
GET_BCD:	CALL RECEI_BYTE		;getting first nibble of BCD value
	JB	download, NO_ECHO
	CALL TRANS_BYTE
NO_ECHO: nop
	CALL ASCII_BCD		; input A return A

	SWAP	A		;high nibble now in place
	MOV	R3,A		;R3= holding output byte	

	CALL RECEI_BYTE		;getting second nibble of BCD value
	JB	download, NO_ECHO1
	CALL TRANS_BYTE
NO_ECHO1: nop
	CALL ASCII_BCD		; input A return A

	ORL	A, R3		;put low nibble together with high nibble

;	MOV	P0, A		; output to port 0

	RET

;****************************************************
; Convert BCD nibble in A to ASCII value
;  output values in lower case
; Input value in A, return values in A
BCD_ASCII:	ANL	A, #0FH		;do low nibble 

	MOV	R1, A		;R1= current processing nibble
	SUBB 	A, #0AH		;subtract to check whether it is numbers or letters
				
	MOV	20H,A		;20= sign_tst, temp testing location
	MOV	A, R1		
	ADD 	A, #30H		;ADD to get ASCII format

	JB	20H.7,GOT_NUMBERS_DONE	; check sign bit, if neg then is number

	;got letters
	ADD 	A, #27H		;57H-30H=27H, ADD to get ASCII format	

GOT_NUMBERS_DONE:	NOP		

	RET

#endif



;********************************************************************
; Print welcome message
;********************************************************************
prompt1:        db ' Debugger and bootloader: ',0
prompt2:        db 'dr,dw,pr,pw or Download *.exe file',0

intro:          mov dptr,#prompt1
                lcall outstr
                mov dptr,#prompt2
                lcall outstr
                ret

;********************************************************************
; Send a null terminated string out serial port
;********************************************************************
outstr:         clr a
                movc a,@a+dptr      ; get character
                jz exit_outstr      ; stop if char == null
                call TRANS_BYTE       ; else send it
                inc dptr            ; point to next char
                sjmp outstr
exit_outstr:           ret


;**********************************************
; Serial Interrupt service routine
; interrupt routine uses  B
;*********************************************
ser_isr:
	jbc	ri,RXisr	; incoming character?
TXisr:                          ; else a TX interrupt
#if 0
	jbc	txflag,sendit	; if no character waiting
	clr	ti		;   then we just finished 
	setb	txdone
	sjmp	ser_ret

sendit:	mov	sbuf,txbuf
	clr	ti
	clr	txdone				  
#endif
	sjmp	ser_ret
;
RXisr:	
;	setb	rxflag   ;debug
;	MOV rxbuf_ptr, #1
;	reti ;debug
	MOV sav_C, C
	MOV B, A

	MOV A, #rxbuf
	ADD A, rxbuf_ptr

	MOV tmp_sav, R0		; save R0 value
	MOV R0, A

	mov	@R0,sbuf	; read incoming character
	MOV	R0, tmp_sav	; restore
	setb	rxflag    	;  set received flag
	CLR 	rxdone		; data in rx buf

	CLR C
	MOV A, rxbuf_ptr
	INC A
	MOV rxbuf_ptr, A	; increment to indicate value inside rxbuf

;	MOV tmp_sav, A

	;check if over half size then issue XOFF	
	SUBB A, #10H	; half size = 5
	JNC	send_xoff

back_seri:
	MOV A, B			; put original value back
	MOV C, sav_C
ser_ret:
	reti
send_xoff:
	setb flow_control	; indicate xoff sent

	MOV A, #19
	call TRANS_BYTE
	MOV A, #'X'
	call TRANS_BYTE
	MOV A, #'F'
	call TRANS_BYTE

	JMP back_seri

;***************
FILE_ERR1:	JMP FILE_ERR

;************************************
; check whether it is the end of file transfer
FILE_chk_end:
		CJNE	A,#1BH, FILE_ERR1					

⌨️ 快捷键说明

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