📄 dcm44p.a51
字号:
$TITLE (iDCM 44 COMMUNICATIONS FIRMWARE: PARALLEL MODULE)
$DATE (8 AUGUST 86)
$NOMO
$PAGING
$REGISTERBANK (0)
;***************************************************************************
;*
;* TITLE: iDCM 44 COMMUNICATIONS FIRMWARE: PARALLEL MODULE
;*
;* RELEASE: 2.0
;*
;* DESCRIPTION: THIS MODULE CONTAINS THE PARALLEL PROCEDURES
;*
;* UPDATES:
;*
;***************************************************************************
;*
;* COPYRIGHT 1983, 1986 INTEL CORPORATION
;*
;* INTEL CORPORATION PROPRIETARY INFORMATION. THIS LISTING
;* IS SUPPLIED UNDER THE TERMS OF A LICENSE AGREEMENT WITH
;* INTEL CORPORATION AND MAY NOT BE COPIED NOR DISCLOSED
;* EXCEPT IN ACCORDANCE WITH THE TERMS OF THAT AGREEMENT.
;*
;***************************************************************************
NAME DCM44P
USING 0
$include(reg44.pdf)
$include(dcm44c.ext)
$include(dcm44c.lit)
$include(dcm44m.a51)
$include(r2sys.mac)
public init_parallel_sw, input_interrupt_check, output_interrupt_check
public send_parallel
extrn code (event_detect, te_set_wait, parallel_gateway_switch)
extrn code (rqsystemstart, serial_interrupt_check)
extrn data (req_next_buffer)
extrn bit (x_parallel_enabled, i_blocked_flag)
DCMFW_CODE_SEG SEGMENT CODE
DCMFW_INT_SEG SEGMENT DATA
DCMFW_EXT_SEG SEGMENT XDATA
RSEG DCMFW_INT_SEG
O_Count: DS 1
O_Queue_Ptr: DS 1
I_Bfr_Ptr_Reg EQU R2
I_Data_Ptr_Reg EQU R3
; O_Msg_Ptr_Reg EQU R4
O_Data_Ptr_Reg EQU R5
I_Bfr_Ptr EQU AR2
I_Data_Ptr EQU AR3
; O_Msg_Ptr EQU AR4
O_Data_Ptr EQU AR5
poll_reps EQU 20
RSEG DCMFW_CODE_SEG
$EJECT
;***************************************************************************
;*
;* PROCEDURE: init_parallel_sw
;*
;* PURPOSE: Initialize paralllel variables
;*
;* CALLED FROM: comm_task
;*
;* CALLS: None
;*
;* ENTERS: None
;*
;* INPUTS: None
;*
;* RETURNS: Nothing
;*
;* DESCRIPTION: Init_parallel_SW initializes global variables
;*
;***************************************************************************
init_parallel_sw:
;
;The following data items are cleared by power-up test
;
;
; mov o_queue_ptr,#0
; mov i_bfr_ptr_reg,#0
; mov i_data_ptr_reg,#0
; mov o_data_ptr_reg,#0
; mov o_count,#0
;
; clr i_blocked_flag ;clear by serial init routine
orl tcon,#bytebus_edge_intr_msk ;set Input/Output Ints for edge
mov dptr,#g_station_mode_cfg ;set parallel enabled flag
movx a,@dptr ;
mov c,acc.parallel_ifc_bpos ;
mov x_parallel_enabled,c ;
ret ;and return
$EJECT
;***************************************************************************
;*
;* PROCEDURE: input_interrupt_check
;*
;* PURPOSE: Input Interrupt Check processes data in from the
;* parallel interface.
;*
;* CALLED FROM: event_detect
;*
;* ENTERED FROM: event_detect
;*
;* CALLS: parallel_gateway_switch
;* allocate (macro) buffer pointer returned in A
;*
;* ENTERS: event_detect
;* rqsystemstart
;*
;* INPUTS: None
;*
;* RETURNS: Nothing
;*
;* DESCRIPTION: Input Interrupt Check determines if data is ready for
;* reception from the input FIFO queue. If so, and if
;* a buffer has been allocated for it, the data is read
;* and placed in the buffer. If no buffer is ready, one
;* is allocated (if possible). When a command is waiting,
;* it is read, and the buffer is routed to its
;* destination. The module repeats until no more data can
;* be read. Then it jumps to event_detect.
;*
;* There one special case on command. If the command is
;* not a zero value, then the system is reset by jumping
;* to rqstartsystem: location 0.
;*
;***************************************************************************
input_interrupt_check:
mov a,i_data_ptr ;get next buffer byte address
jnz i_set_input_address ;if no buffer is ready,
acall get_parallel_receive_buffer ; then get one, if possible
jnz i_set_input_address ;Got a buffer
setb i_blocked_flag ;If still no buffer,
jb i_fifo_empty_bit,ed_vec ;if fifo empty, jump
jnb i_data_rdy_bit,i_get_command ;if command, go test for reset
ed_vec:
ajmp te_set_wait ; Then flag block and return
i_set_input_address:
mov r0,a ;r0 => message.length
mov dptr,#g_data_in ;Set up input data address
i_check_data_in_bit:
mov r6,#poll_reps ;Else poll for input byte
i_check_data_poll:
jnb i_fifo_empty_bit,i_read_ready ;if input byte ready, jump
djnz r6,i_check_data_poll ;else try again
i_read_not_ready:
mov i_data_ptr,r0 ;if still no input data, save context
ajmp event_detect ;and wait on event
i_read_ready:
jnb i_data_rdy_bit,i_get_command ;If command ready then go process it
movx a,@dptr ;else store data byte in buffer
mov @r0,a ;
inc r0 ;and set ptr for next byte
sjmp i_check_data_in_bit ;go get next byte/command
i_get_command:
mov dptr,#g_command_in ;read command
movx a,@dptr ;
jz i_end_of_msg_cmd ;if command = 0, then jump
ljmp rqsystemstart ;else reset system
i_end_of_msg_cmd: ;a = 0
mov r0,i_bfr_ptr ;r0 => message to be routed
mov i_bfr_ptr_reg,a ;clear input registers
mov i_data_ptr_reg,a ;
mov a,r0 ;if no msg. to xmit,
jz serial_check ; then jump
acall parallel_gateway_switch ;and route message
serial_check:
jnb si,input_interrupt_check
ajmp serial_interrupt_check ;and repeat
check_parallel_receive_buffer:
;
; This procedure checks to see if there is presently a buffer posted for
; the parallel input. If there is not, it trys to allocate one.
; Inputs: none
; Returns: a = 0, if there is still no buffer for the parallel input
; else, a = i_data_ptr_reg
;
mov a,i_bfr_ptr ;is a receive buffer posted?
jnz cpr_ret ;if so, return
get_parallel_receive_buffer: ;secondary entry
%req_allocate ;else allocate one
jz cpr_ret ;if unsuccessful, return w/ acc=0
mov i_bfr_ptr,a ;else set up registers
add a,#message_length_ofs ;
mov i_data_ptr_reg,a ;
cpr_ret:
ret ;and return
$EJECT
;***************************************************************************
;*
;* PROCEDURE: output_interrupt_check
;*
;* PURPOSE: Output Interrupt Check processes data out to the
;* parallel interface.
;*
;* CALLED FROM: event_detect
;*
;* CALLS: dequeue_message
;* req_deallocate (in_line macro)
;*
;* ENTERS: None
;*
;* INPUTS: None
;*
;* RETURNS: Nothing
;*
;* DESCRIPTION: Output Interrupt Check determines if data is ready for
;* transmission to the output FIFO queue. If so,
;* the data is read from the message and output to the
;* FIFO. If the message is finished, a command is output
;* and the message is deallocated or used for a receive
;* buffer. Then another message is dequeued, if any.
;* Then it jumps back to event_detect.
;*
;***************************************************************************
output_interrupt_check:
mov a,o_queue_ptr ;anything to transmit?
jnz o_transmit ;if so, jump
ret ;else return
o_transmit:
mov a,o_count ;
mov r0,o_data_ptr ;Get next message byte address
cjne r0,#0,o_check_message_complete ;if partial message, jump
mov a,o_queue_ptr ;else, set up regs for new message
add a,#message_length_ofs ;
mov o_data_ptr_reg,a ;
mov r0,a ; r0 => message.length
mov a,@r0 ;
dec a ;
dec a ; a = count
o_check_message_complete:
jz o_send_command ;if message complete go send cmd.
mov r1,a ;else, r1 = remaining byte count
mov dptr,#g_data_out ;set up output data address
o_send_data:
mov a,@r0 ;send next data byte
mov r6,#poll_reps ;
o_send_data_poll:
jnb o_fifo_full_bit,o_write_data_ready ;if output fifo ready, jump
djnz r6,o_send_data_poll ;else try again
o_write_not_ready:
mov o_data_ptr,r0 ;save transmit msg. context
mov o_count,r1 ;
ret ;and return
o_write_data_ready:
movx @dptr,a ;output data byte
inc r0 ;point to next byte to output
djnz r1,o_send_data ;if msg. not xmitted, go send next byte
; sjmp o_send_command ;else go send command byte
o_send_command:
mov r6,#poll_reps ;poll status for fifo-not_full
o_send_command_poll:
jnb o_fifo_full_bit,o_write_cmd_ready ;If so, go write command
djnz r6,o_send_command_poll ;try again
sjmp o_write_not_ready ;if still not ready, jump
o_write_cmd_ready:
clr a ;write 0 to command port
mov dptr,#g_command_out ;
movx @dptr,a ;
%dequeue_message_def(o_queue_ptr) ;dequeue the xmitted message
%req_deallocate ;and return it to the sbp
mov o_data_ptr,#0 ;indicate xmit is complete
acall check_parallel_receive_buffer ;see if input needs a buffer
sjmp output_interrupt_check ; and repeat
$EJECT
;***************************************************************************
;*
;* PROCEDURE: send_parallel
;*
;* PURPOSE: Send Parallel initiates the transfer of a message
;* across the parallel interface.
;*
;* CALLED FROM: serial_gateway_switch, local_gateway_switch
;*
;* ENTERED FROM: serial_gateway_switch, local_gateway_switch
;*
;* CALLS: enqueue_message (in-line macro) (msg_ptr in R0)
;* Output_interrupt_check
;* req_deallocate (in-line macro)
;*
;* ENTERS: Parallel_Gateway_Switch (Msg_ptr in A)
;*
;* INPUTS: Msg_Ptr: R0
;*
;* RETURNS: Nothing
;*
;* DESCRIPTION: Send Parallel check to see if a message is currently
;* being transmitted. If so, the current message is
;* enqueued for later transmission. Otherwise, the
;* current message is set up for transmission and
;* input_interrupt_check is initiated.
;*
;***************************************************************************
send_parallel:
jnb x_parallel_enabled,psp_no_parallel ;if parallel disabled, jump
%enqueue_message_def(o_queue_ptr) ;else enqueue message and
ajmp output_interrupt_check ;jump to output the message
psp_no_parallel:
%set_msg_ptr(message_route_ofs) ;r1 => message.flags
mov a,@r1 ;
jb acc.msg_type_bpos,psp_reply_return ;if reply, then jump
setb acc.msg_type_bpos ;if order, then change to reply
mov @r1,a ;
%set_msg_ptr(message_command_ofs) ;set error status
mov @r1, #e_no_destination_device ;
ajmp parallel_gateway_switch ;and return msg. to sender
psp_reply_return:
mov a,r0 ;else if reply, then
%req_deallocate ;deallocate buffer
ret ;and return
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -