📄 up2dsptest1.asm
字号:
;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 + -