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

📄 dcm44p.a51

📁 8051实时操作系统
💻 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 + -