📄 dcm44s.a51
字号:
;*
;* DESCRIPTION: If this station is a slave:
;* If in auto mode, jump to auto routine.
;* Else if no frame received, then
;* assume transmit ack. set to auto mode
;* and wait on event.
;* else jump to slave non-auto rcv routine.
;* If this station is a master:
;* If no frame received, then this was a xmit-complete
;* interrupt. So set the serial timeout flag
;* and wait on the next event.
;* else clear the serial timeout flag and counter
;* and jump to the master receive frame routine.
;*
;***************************************************************************
serial_interrupt_check:
clr si ;clear interrupt flag
jb s_station_mode,master_int ;if master, jump
; Process this interrupt as a non-master
;
jnb am, slave_non_auto ;if slave in flex mode, jump
ajmp auto_information_frame_check ;else jump to auto frame check routine
slave_non_auto:
jb rbe, slave_xmit_ack ;if no frame received, jump
ajmp non_auto_slave_rcv ;else process received frame
slave_xmit_ack:
; The interrupt was caused by the completed transmission of a frame by the
; slave. Set to auto mode.
;
setb am ;set to auto mode
ajmp event_detect ;go wait on event
master_int:
jb rbe, master_xmit_ack ;if no receive buffer, then deal with
;transmit-complete interrupt
master_rcv_int:
; A frame was received by the master. Go investigate the type of frame
; and process accordingly
;
clr si ;clear any extra interrupt
clr s_timeout_set ;reset the timeout flag
clr s_timeout_count ;zero the timeout count
ajmp non_auto_master_rcv ;go process received frame
master_xmit_ack:
; Since rbe=1, it is assumed here that the interrupt was caused by
; a transmit-complete condition.
;
setb s_timeout_set ;else set timeout for a response
ajmp event_detect ;go wait on next event
$EJECT
;***************************************************************************
;*
;* PROCEDURE: send_serial
;*
;* PURPOSE: initiate serial transmission of message
;*
;* CALLED FROM: None
;*
;* ENTERED FROM: local_gateway_switch
;* parallel_gateway_switch
;*
;* CALLS: enqueue_message
;*
;* ENTERS: serial_order_send (implicit) (msg_ptr in R0)
;* serial_reply_send (msg_ptr in R0)
;*
;* INPUTS: msg_ptr in R0
;*
;* RETURNS: None
;*
;* DESCRIPTION: Checks message type for order or reply, then
;* jumps to appropriate routine to send it.
;*
;***************************************************************************
send_serial:
; If the link is active (in init., poll, or info. mode), enqueue the message
; and return. Otherwise, enqueue the message and initiate transmission
;
%enqueue_message_def(s_queue_ptr) ;enqueue the message
mov a,#active_link_msk ;in init, poll, or info mode?
anl a,s_station_ops ;
jnz ret_vec ;if link active, return
acall check_receive_buffer ;check on receive buffer
jb s_station_mode,initiate_order_transmission ;if master, jump
; This station is not a master. See if the message is an order or a
; reply. If an order, change the station into a master.
;
%set_msg_ptr(message_route_ofs) ;check msg type
mov a, @r1 ;
jnb acc.msg_type_bpos, send_serial_slave_order ;if order, jump
send_serial_slave_reply:
; This public procedure sends a reply message serially from a slave.
; Inputs: r0 = the address of the message to be sent
;
setb s_info_mode ;
%set_msg_ptr(message_length_ofs) ;r1,a => message.length
mov tbs, a ;Set new message pointer
mov tbl, @r1 ;Set new message length
dec tbl ;
dec tbl ;
setb tbf ;Enable transmit
ret_vec:
ret ;Return to wherever this
; started
send_serial_slave_order:
; The slave is requested to send an order. Set up for being a master and
; transmit the order message.
; Inputs: r0 => order message
;
setb s_station_mode ;set to master mode
clr am ;clear auto mode
mov a, #ofl_msk ;a <= offline mask
mov nsnr, a ;set nsnr to offline
mov dptr, #s_station_state ;initialize station state table
loop1: ;to all entries offline
movx @dptr, a ;
djnz dpl, loop1 ;
mov dptr, #s_station_poll ;initialize station poll table
clr a ;to all zero entries
loop2: ;
movx @dptr, a ;
djnz dpl, loop2 ;
mov s_poll_queue_out, a ;set poll queue ptr to zero
mov stad,#0ffh ;set station addr. to ff
; sjmp initiate_order_transmission ;transmit order as master
$EJECT
;***************************************************************************
;*
;* PROCEDURE: initiate_order_transmission
;*
;* PURPOSE: initiate_order_transmission starts the serial
;* transmission of an order message.
;*
;* ENTERED BY: send_serial
;*
;* CALLED BY: station_swap_check
;*
;* CALLS: None
;*
;* INPUTS: Message Pointer: r0
;*
;* RETURNS: Nothing
;*
;* DESCRIPTION: Checks for destination address match to current
;* station address (STAD). If no match, then
;* the current NSNR is written to current station's
;* state (s_station_state), and the new station's
;* state is written to NSNR --- unless, the station
;* is currently unsynchronized. Then the message is
;* pushed back into the queue and a DISC is sent to
;* initiate the synchronization handshake.
;* Otherwise, the transmit pointer and length are
;* set up, and an I frame generated with Nr and Ns
;* from NSNR.
;*
;***************************************************************************
initiate_order_transmission:
%set_msg_ptr(message_station_ofs) ;check the msg's station
mov a,@r1 ;swap stations if needed
acall swap_station_states ;input: a = msg.stad
jb ses, ios_station_init ;if not yet intitialized, then start
%set_msg_ptr(message_length_ofs) ;else set up i-frame for xmit
mov tbs, r1 ;
mov tbl, @r1 ;
dec tbl ;
dec tbl ;
mov a, nsnr ;
mov s_last_nsnr, a ;save current nsnr count
swap a ;build control byte
orl a, #i_msk ;
mov tcb, a ;
setb s_info_mode ;set to info mode
; sjmp ios_frame_transmit ;
ios_frame_transmit: ;transmit frame
mov sts, #11100000B ;rts=1, tbf=1, rbe=1
ret ;and return
ios_station_init:
setb s_init_mode ;set to initialization mode
mov tcb, #disc_msk ;set to transmit DISC
sjmp ios_frame_transmit
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -