home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / X25.ZIP / X25 / X25_M / X25MRCV.ASM < prev    next >
Assembly Source File  |  1991-09-29  |  39KB  |  793 lines

  1.         PAGE    ,132  ; (CTRL-OH) sets printer to condensed mode
  2.         TITLE   X25MRCV.ASM - Receiver Sample Program for MASM 5.1
  3. ;*************************************************************************
  4. ; Module      : X25MRCV.ASM
  5. ;
  6. ; Copyright   : (C) Copyright IBM Corp. 1989,1991
  7. ;               Licensed Material - Program Property of IBM
  8. ;               All Rights Reserved
  9. ;
  10. ; Compiler    : Microsoft Macro Assembler 5.1
  11. ;               Microsoft is a registered trademark of Microsoft Corporation.
  12. ;
  13. ; Description : This is the receiver part of the sample program to
  14. ;               demonstrate use of the X.25 API supplied in the OS/2
  15. ;               Extended Services Communications Manager.
  16. ;
  17. ;               After initialising the X.25 API, the program starts
  18. ;               listening for an incoming call corresponding to a name
  19. ;               in the routing table. This name is given as a parameter
  20. ;               to the program.
  21. ;
  22. ;               When the incoming call is received, it is accepted and
  23. ;               the program then starts to receive data transmitted from
  24. ;               from the remote application. Acknowledgments are sent
  25. ;               when required.
  26. ;
  27. ;               The program loops until a an end of data marker is
  28. ;               received. It then sends a clear packet to acknowledge
  29. ;               that all data has been received before tidying up and
  30. ;               exiting.
  31. ;
  32. ;               The program loops until a Clear Indication packet is
  33. ;               received. It then tidies up, and exits.
  34. ;
  35. ;               In the event of an error, a message is printed,
  36. ;               and the program tries to tidy up before exiting.
  37. ;
  38. ;               The program uses the following X.25 API verbs:
  39. ;
  40. ;                   X25APPINIT
  41. ;                   X25LISTEN
  42. ;                   X25CALLRECEIVE
  43. ;                   X25CALLACCEPT
  44. ;                   X25CALLCLEAR
  45. ;                   X25DATARECEIVE
  46. ;                   X25ACK
  47. ;                   X25DEAFEN
  48. ;                   X25APPTERM
  49. ;
  50. ; Note        : The name supplied as a parameter must already exist in
  51. ;               the routing table. It must allow reception of any
  52. ;               incoming calls. An entry created from model profile M7
  53. ;               is suitable for this purpose.
  54. ;
  55. ;               This program should be started before the transmitter
  56. ;               program.
  57. ;*************************************************************************
  58. .286p                           ; Allows use of 286 protected mode instructions
  59. .xlist                                ; turns off the listing of included files
  60.             INCLUDE sysmac.inc              ; Include macros for OS/2 functions
  61.             INCLUDE x25_aset.inc                                 ; X25 includes
  62.             INCLUDE x25_a.inc
  63. .list                                                ; restores the list option
  64.  
  65. @mova      macro    full_address, ofs, sel      ; move selector and offset
  66.             mov   ax, sel                       ; move address of data selector
  67.             mov   word ptr full_address+2,ax    ; and
  68.             mov   ax, ofs                       ; offset into the data buffer
  69.             mov   word ptr full_address,ax      ; double word
  70.            endm
  71.  
  72. @X25       macro                                        ; define x25 call macro
  73.             push shrdseg
  74.             push ofs_xvrb
  75.             call far ptr x25
  76.            endm
  77.  
  78.  
  79.  
  80. stack       SEGMENT word stack 'STACK'
  81.             DB     3500d DUP (?)                         ; define our stacksize
  82. stack       ENDS
  83.  
  84. dgroup      GROUP  data                               ; DGROUP required by OS/2
  85.  
  86. data            SEGMENT word public 'DATA'
  87.  
  88.  
  89. ofs_xvrb        DW  0                                          ; offset of xvrb
  90. ofs_call_data   DW  0                              ; offset of call data buffer
  91. ofs_data_data   DW  0                 ; offset of data buffer for received data
  92. ofs_listen_data DW  0                            ; offset of listen data buffer
  93. SemAddress      DD  0                                ; address of ram semaphore
  94.  
  95. buffer_size     EQU 4096d                             ;data receive buffer size
  96. message_size    EQU 36d                            ;length of message in buffer
  97. Rt_Pointer      DD  0                     ; pointer to routing table entry name
  98. InputString     DB  9 DUP (?)                           ; buffer for char input
  99. InputStringLen  EQU $-InputString                             ;length of buffer
  100. ValidChars      DW  ?                            ; actual number of chars input
  101. TableName       DB  8 DUP (' ')                   ; name in table to listen for
  102. TableNameLen    EQU $-TableName                            ;length of TableName
  103. data_type       DB  ?                               ; used by data receive verb
  104. connid          DD  0                                   ; connection identifier
  105. data_complete   DB  ?                               ;set when all data received
  106. complete        EQU 1                                ;all data received setting
  107. more_to_come    EQU 0                               ;more data to come setting
  108. ErrNum          DW  ?                   ; return code from x25 and system calls
  109. ErrorType       DW  ?                        ; to check if error was Dos or X25
  110. Immediate       EQU 1                                      ;X25 immediate error
  111. Completion      EQU 2                                     ;X25 completion error
  112. DosError        EQU 3                                      ;Error from OS2 call
  113.  
  114. shrdseg         DW  0                  ; segment selector for our shared memory
  115. initalise       EQU 1               ; flag for dossubset to initalise a segment
  116. shareable       EQU 0011b                                ; flag for DosAllocSeg
  117. segsize         EQU 32768                ; size for DosAllocSeg and DosSubAlloc
  118.  
  119. NoTimeOut       DD  -1                             ; no time out for DosSemWait
  120. hundreds        DB  ?                      ; used for hex to decimal conversion
  121. tens            DB  ?
  122. units           DB  ?
  123. hundred         DW  100d
  124. ten             DW  10d
  125.  
  126.                                                  ; Messages used by the program
  127. BadEnvMsg       DB  'Bad Enviroment - cannot find routing table entry name'
  128. BadEnvLen       EQU $-BadEnvMsg
  129. InitGoodMsg     DB  'X.25 API Initialised'
  130. InitGoodLen     EQU $-InitGoodMsg
  131. InitBadMsg      DB  'Couldn''t initialise X.25 API'
  132. InitBadLen      EQU $-InitBadMsg
  133. ListenGoodMsg   DB  'Now ready to receive an incoming call'
  134. ListenGoodLen   EQU $-ListenGoodMsg
  135. ListenBadMsg    DB  'Listen failed'
  136. ListenBadLen    EQU $-ListenBadMsg
  137. CallRcvGoodMsg  DB  'Incoming call has arrived'
  138. CallRcvGoodLen  EQU $-CallRcvGoodMsg
  139. CallRcvBadMsg   DB  'Call receive failed'
  140. CallRcvBadLen   EQU $-CallRcvBadMsg
  141. CallAccGoodMsg  DB  'Call accepted OK'
  142. CallAccGoodLen  EQU $-CallAccGoodMsg
  143. CallAccBadMsg   DB  'Call accept failed'
  144. CallAccBadLen   EQU $-CallAccBadMsg
  145. DataRcvGoodMsg  DB  'Data Receive completed successfully'
  146. DataRcvGoodLen  EQU $-DataRcvGoodMsg
  147. DataRcvBadMsg   DB  'Data receive failed'
  148. DataRcvBadLen   EQU $-DataRcvBadMsg
  149. AckGoodMsg      DB  'Data acknowledged'
  150. AckGoodLen      EQU $-AckGoodMsg
  151. AckBadMsg       DB  'Ack failed'
  152. AckBadLen       EQU $-AckBadMsg
  153. EOMRcvMsg       DB  'End of data marker received'
  154. EOMRcvLen       EQU $-EOMRcvMsg
  155. ClrCallGoodMsg  DB  'Call cleared OK'
  156. ClrCallGoodLen  EQU $-ClrCallGoodMsg
  157. ClrCallBadMsg   DB  'Call Clear failed'
  158. ClrCallBadLen   EQU $-ClrCallBadMsg
  159. ClrErrMsg       DB  'Call was cleared - Cause :'
  160. ClrErrLen       EQU $-ClrErrMsg
  161. DeafenGoodMsg   DB  'Deafen successful'
  162. DeafenGoodLen   EQU $-DeafenGoodMsg
  163. DeafenBadMsg    DB  'Deafen failed'
  164. DeafenBadLen    EQU $-DeafenBadMsg
  165. ClearMsg        DB  'Clear indication packet has been received'
  166. ClearLen        EQU $-ClearMsg
  167. UknDataMsg      DB  'Unexpected type of data has been received'
  168. UknDataLen      EQU $-UknDataMsg
  169. TermGoodMsg     DB  'X.25 API Terminated'
  170. TermGoodLen     EQU $-TermGoodMsg
  171. TermBadMsg      DB  'Couldn''t Terminate X.25 API'
  172. TermBadLen      EQU $-TermBadMsg
  173. X25ImmErrMsg    DB  'X25 Error Occured Immediate Return Code of :'
  174. X25ImmErrLen    EQU $-X25ImmErrMsg
  175. X25DelErrMsg    DB  'X25 Error Occured Completion Return Code of :'
  176. X25DelErrLen    EQU $-X25DelErrMsg
  177. DosErrMsg       DB  'Dos Error Occured Return Code of :'
  178. DosErrLen       EQU $-DosErrMsg
  179. DosTermMsg      DB  ' Terminating Program'
  180. DosTermLen      EQU $-DosTermMsg
  181. crlf            DB  0Dh, 0Ah                     ;carriage return and line feed
  182.  
  183. data            ENDS                             ; end of the main data segment
  184.  
  185. shared_buffer   SEGMENT word public 'shared'
  186.  
  187. xvrb            X25VERB         <>
  188.                 org     xvrb                     ; define over the same storage
  189. call_data       X25CALL_DATA    <>              ; we will override the selector
  190.                 org     xvrb                                ; and offset anyway
  191. data_data       X25DATA_DATA    <>
  192.                 org     xvrb
  193. listen_data     X25LISTEN_DATA  <>
  194.  
  195. shared_buffer   ENDS
  196.  
  197. code        SEGMENT byte public 'CODE'
  198.             ASSUME cs:code,ds:dgroup,ss:stack
  199.  
  200. ;=============================================================================
  201. ; Main program starts here
  202. ;=============================================================================
  203. x25mrcv     PROC   FAR                                  ; Entry point from OS/2
  204.             mov    word ptr Rt_Pointer+2,AX          ;Save command line pointer
  205.             mov    word ptr Rt_Pointer,BX
  206.             mov    ax,dgroup                         ; Set up addressability to
  207.             mov    ds,ax                           ; the automatic data segment
  208.             call   allocmem               ; allocate the shared memory segments
  209.  
  210.             call   parse_rtname        ; get parameter passed from env string
  211.             assume es:shared_buffer    ; saves us preceding everything with ES:
  212.             mov    es, shrdseg         ; set ES to our allocated segment
  213.             call   init_app                                     ; start the API
  214.             call   listen                                ; listen to the sender
  215.             call   callrcv                                ; and wait for a call
  216.             call   callacc                                    ; accept the call
  217.             mov    data_complete,more_to_come           ;indicate start of data
  218. looprcv:
  219.             call   rcv_data                             ; receive data
  220.             cmp    data_complete,complete             ;see if all data received
  221.             je     finish
  222.             cmp    data_type, X25DATARCV_DATA     ; see if data packet received
  223.             je     looprcv                                   ;receive more data
  224.             cmp    data_type, X25DATARCV_CLEAR       ;see if data type is clear
  225.             jne    Unexpected                     ;if it is not goto unexpected
  226.             @VioWrtTTY ClearMsg, ClearLen,0           ; say we received a clear
  227.             @VioWrtTTY crlf,2,0
  228.             jmp    finish
  229. Unexpected:
  230.             @VioWrtTTY UknDataMsg, UknDataLen,0           ; not data or a clear
  231.             @VioWrtTTY crlf,2,0                                 ; finish anyway
  232. finish:
  233.             call   clear_call                  ; finished so clear the call and
  234.             call   deafen                                      ; stop listening
  235.             call   term_app                               ; finish with the API
  236.  
  237.             @dosexit       1,0                     ; Exit with return code of 0
  238.  
  239. ;=============================================================================
  240. ; Get Routing Table entry name
  241. ;=============================================================================
  242. parse_rtname proc
  243.  
  244. ; Gets the routing table entry name from the command line and places it into
  245. ; a variable for later use
  246.  
  247.          les     di,Rt_Pointer              ;points to command line in env str
  248.          xor     ax,ax                      ;set AL = 00
  249.          mov     cx,100                     ;max size to scan = 100 bytes
  250.          cld                                ;set DF to increment
  251. Pf_Skip_Command:
  252.          scas    es:byte ptr [di]           ;look for 00 (end of command)
  253.          je      Pf_Next                    ;we are now past the command
  254.          dec     cx                         ;else try again
  255.          jcxz    Pf_Bad_Env                 ;if we count out,something's wrong
  256.          jmp     Pf_Skip_Command            ;keep looking for end of command
  257. Pf_Next:
  258.          cmp     byte ptr es:0 [di],20h     ;Usually we have a leading blank
  259.          jne     Pf_Noadj                   ;If not, the name addr is ok
  260.          inc     di                         ;Else, increment to skip leading
  261.                                             ;blank
  262.          jmp     Pf_Next                    ;Keep looking for first nonblank
  263. Pf_Noadj:
  264.          mov     word ptr Rt_Pointer,di     ;reset ptr to indicate ASCIIZ
  265.                                             ;filename
  266.          xor     cx,cx                      ;string size = 0
  267.          mov     si,0                       ;offset into TableName
  268.                                             ;to put data
  269. Pf_Loop:
  270.          mov     al,byte ptr es:[di]        ;get a byte of name
  271.          cmp     al,00                      ;end of name flag ?
  272.          je      Pf_Done                    ;if so we are done moving it
  273.          cmp     al,20h                     ;is it a blank ?
  274.          Je      Pf_Skipit                  ;if blank, skip it
  275.          mov     byte ptr [TableName + si],al        ;move the data
  276.          inc     si                         ;SI = index in TableName
  277.          inc     cx                         ;increment count
  278. Pf_Skipit:
  279.          inc     di                         ;DI = source index in env string
  280.          cmp     cx,TableNameLen            ;check for max size
  281.          je      Pf_8_Bytes                 ;only take first 8 bytes
  282.          Jmp     Pf_Loop                    ;go move another
  283. Pf_Done:
  284.          mov     byte ptr [TableName + si],al        ;move the data
  285. Pf_8_Bytes:
  286.          ret
  287.  
  288. Pf_Bad_env:                                 ;error in env string
  289.         @VioWrtTTY BadEnvMsg, BadEnvLen,0   ;issue message
  290.         @VioWrtTTY crlf,2,0
  291.         @DosExit 0,0                        ;and quit
  292. parse_rtname endp
  293. ;=============================================================================
  294. ; Make and Call X25APPINIT
  295. ;=============================================================================
  296. init_app    PROC                                 ;make verb and call X25APPINIT
  297.             mov    di, ofs_xvrb                      ; address our given offset
  298.             mov    [di+xvrb.verb_code], X25APPINIT
  299.             mov    [di+xvrb.version_id], X25_API_VERSION
  300.             mov    [di+xvrb.data_buffer_size], 0  ; The data buffer is not used
  301.  
  302.             @X25                                            ; Call the X.25 API
  303.  
  304.             cmp    ax, X25_OK                              ; check immediate RC
  305.             je     NoImmErr1
  306.             mov    ErrorType, Immediate              ; Indicate immediate error
  307.             jmp    InitErr
  308. NoImmErr1:
  309.             call   SemWait                          ; wait for verb to complete
  310.             mov    di, ofs_xvrb
  311.             mov    ax, [di+xvrb.return_code]
  312.             cmp    ax, X25_OK                             ; check Completion RC
  313.             je     InitGood
  314.             mov    ErrorType, Completion            ; Indicate completion error
  315.             jmp    InitErr
  316. InitErr:
  317.             mov    ErrNum, ax
  318.             @VioWrtTTY InitBadMsg,InitBadlen,0       ; report failure then call
  319.             @VioWrtTTY crlf,2,0
  320.             call   Error                                    ; the error routine
  321. Initgood:
  322.             @VioWrtTTY InitGoodMsg,InitGoodlen,0
  323.             @VioWrtTTY crlf,2,0
  324.             ret
  325.  
  326. init_app    ENDP
  327.  
  328. ;=============================================================================
  329. ; Make and Call X25LISTEN
  330. ;=============================================================================
  331. listen      PROC                                  ;make verb and call X25LISTEN
  332.             mov    di, ofs_xvrb
  333.             mov    [di+xvrb.verb_code], X25LISTEN
  334.             mov    [di+xvrb.version_id], X25_API_VERSION
  335.             mov    [di+xvrb.queue_number], 0         ; queues are not used here
  336.             @mova  [di+xvrb.data_buffer_ptr], ofs_listen_data, shrdseg
  337.             mov    [di+xvrb.data_buffer_size], X25LISTENDATA_SIZE
  338.  
  339.             mov    di, ofs_listen_data                          ; buffer offset
  340.             mov    [di+listen_data.num_of_rtes], 1          ; set for one entry
  341.  
  342.             mov    bx, 0                                     ; initialise index
  343. copyloop:
  344.             mov    al , byte ptr[TableName + bx]
  345.             mov    byte ptr [di+listen_data.rte_entry_list + bx], al
  346.             inc    bx                     ; copy the contents of tablename into
  347.             cmp    bx, TableNameLen          ; first position of the entry_list
  348.             jne    copyloop                ; copy all 8 chars, unused ones will
  349.                                                                     ; be spaces
  350.             @X25                                            ; Call the X.25 API
  351.             cmp    ax, X25_OK                              ; check immediate RC
  352.             je     NoImmErr2
  353.             mov    ErrorType, Immediate              ; Indicate immediate error
  354.             jmp    ListenErr
  355. NoImmErr2:
  356.             call   SemWait                          ; wait for verb to complete
  357.             mov    di, ofs_xvrb
  358.             mov    ax, [di+xvrb.return_code]
  359.             cmp    ax, X25_OK                             ; check Completion RC
  360.             je     ListenGood
  361.             mov    ErrorType, Completion            ; Indicate completion error
  362.             jmp    ListenErr                         ; To be safe if code added
  363. ListenErr:
  364.             mov    ErrNum, ax                               ; store error value
  365.             @VioWrtTTY ListenBadMsg,ListenBadlen,0
  366.             @VioWrtTTY crlf,2,0
  367.             call   Error                                 ; call error procedure
  368. Listengood:
  369.             @VioWrtTTY ListenGoodMsg,ListenGoodlen,0
  370.             @VioWrtTTY crlf,2,0
  371.             ret
  372.  
  373. listen      ENDP
  374.  
  375. ;=============================================================================
  376. ; Make and Call X25CALLRECEIVE
  377. ;=============================================================================
  378. callrcv     PROC                             ;make verb and call X25CALLRECEIVE
  379.             mov    di, ofs_xvrb
  380.             mov    [di+xvrb.verb_code], X25CALLRECEIVE  ; function to be called
  381.             mov    [di+xvrb.version_id], X25_API_VERSION
  382.             mov    [di+xvrb.verb_option], X25CALLRCV_ADDRESS
  383.             mov    [di+xvrb.queue_number], 0
  384.             @mova  [di+xvrb.data_buffer_ptr], ofs_call_data, shrdseg
  385.             mov    [di+xvrb.data_buffer_size], X25CALLDATA_SIZE
  386.  
  387.             @X25                                            ; Call the X.25 API
  388.             cmp    ax, X25_OK                              ; check immediate RC
  389.             je     NoImmErr3
  390.             mov    ErrorType, Immediate              ; Indicate immediate error
  391.             jmp    CallRcvErr
  392.  
  393. NoImmErr3:  call   SemWait                          ; wait for verb to complete
  394.             mov    di, ofs_xvrb
  395.             mov    ax, [di+xvrb.return_code]
  396.             cmp    ax, X25_OK                             ; check Completion RC
  397.             je     CallRcvGood
  398.             mov    ErrorType, Completion            ; Indicate completion error
  399.             jmp    CallRcvErr
  400. CallRcvErr:
  401.             mov    ErrNum, ax
  402.             @VioWrtTTY CallRcvBadMsg,CallRcvBadlen,0
  403.             @VioWrtTTY crlf,2,0
  404.             call   Error
  405.  
  406. CallRcvGood:
  407.             mov   ax, word ptr [di+xvrb.connection_id]
  408.             mov   word ptr connid, ax                    ; fill in the returned
  409.             mov   ax, word ptr [di+xvrb.connection_id+2]        ; connection id
  410.             mov   word ptr connid+2, ax
  411.             @VioWrtTTY CallRcvGoodMsg,CallRcvGoodlen,0
  412.             @VioWrtTTY crlf,2,0
  413.             ret
  414.  
  415. callrcv     ENDP
  416.  
  417. ;=============================================================================
  418. ; Make and Call X25CALLACCEPT
  419. ;=============================================================================
  420. callacc     PROC                              ;make verb and call X25CALLACCEPT
  421.             mov    di, ofs_xvrb
  422.             mov    [di+xvrb.verb_code], X25CALLACCEPT   ; function to be called
  423.             mov    [di+xvrb.version_id], X25_API_VERSION
  424.             mov    [di+xvrb.queue_number], 0
  425.             mov    [di+xvrb.data_buffer_size], 0
  426.             mov    ax, word ptr connid+2
  427.             mov    word ptr [di+xvrb.connection_id+2], ax         ; fill in the
  428.             mov    ax, word ptr connid                          ; connection id
  429.             mov    word ptr [di+xvrb.connection_id], ax
  430.             mov    [di+xvrb.control],d_bit_management
  431.                                                        ; acks to be done by app
  432.  
  433.             @X25                                            ; Call the X.25 API
  434.             cmp    ax, X25_OK                              ; check immediate RC
  435.             je     NoImmErr4
  436.             mov    ErrorType, Immediate              ; Indicate immediate error
  437.             jmp    CallAccErr
  438. NoImmErr4:
  439.             call   SemWait                          ; wait for verb to complete
  440.             mov    di, ofs_xvrb
  441.             mov    ax, [di+xvrb.return_code]
  442.             cmp    ax, X25_OK                             ; check Completion RC
  443.             je     CallAccGood
  444.             mov    ErrorType, Completion            ; Indicate completion error
  445.             jmp    CallAccErr
  446. CallAccErr:
  447.             mov    ErrNum, ax
  448.             @VioWrtTTY CallAccBadMsg,CallAccBadlen,0
  449.             @VioWrtTTY crlf,2,0
  450.             call   Error
  451. CallAccGood:
  452.             @VioWrtTTY CallAccGoodMsg,CallAccGoodlen,0
  453.             @VioWrtTTY crlf,2,0
  454.             ret
  455.  
  456. CallAcc     ENDP
  457.  
  458. ;=============================================================================
  459. ; Make and Call X25DATARECEIVE
  460. ;=============================================================================
  461. rcv_data    PROC                             ;make verb and call X25DATARECEIVE
  462.             mov    di, ofs_xvrb
  463.             mov    [di+xvrb.verb_code], X25DATARECEIVE  ; function to be called
  464.             mov    [di+xvrb.version_id], X25_API_VERSION
  465.             mov    [di+xvrb.queue_number], 0
  466.             @mova  [di+xvrb.data_buffer_ptr], ofs_data_data, shrdseg
  467.             mov    ax, buffer_size                    ; size of the data packet
  468.             mov    [di+xvrb.data_buffer_size], ax
  469.             mov    ax, word ptr connid+2
  470.             mov    word ptr [di+xvrb.connection_id+2], ax         ; fill in the
  471.             mov    ax, word ptr connid                          ; connection id
  472.             mov    word ptr [di+xvrb.connection_id], ax
  473.  
  474.             @X25                                            ; Call the X.25 API
  475.             cmp    ax, X25_OK                              ; check immediate RC
  476.             je     NoImmErr5
  477.             mov    ErrorType, Immediate              ; Indicate immediate error
  478.             jmp    DataRcvErr
  479. NoImmErr5:
  480.             call   SemWait                          ; wait for verb to complete
  481.             mov    di, ofs_xvrb
  482.             mov    ax, [di+xvrb.return_code]
  483.             cmp    ax, X25_OK                             ; check Completion RC
  484.             je     DataRcvGood
  485.             mov    ErrorType, Completion            ; Indicate completion error
  486.             jmp    DataRcvErr
  487. DataRcvErr:
  488.             mov    ErrNum, ax
  489.             @VioWrtTTY DataRcvBadMsg,DataRcvBadlen,0
  490.             @VioWrtTTY crlf,2,0
  491.             call   Error
  492. DataRcvGood:
  493.             @VioWrtTTY DataRcvGoodMsg,DataRcvGoodlen,0
  494.             @VioWrtTTY crlf,2,0
  495.  
  496.             mov    di, ofs_xvrb
  497.             mov    al, [di+xvrb.data_event_type]
  498.             mov    data_type, al                           ; save received type
  499.             cmp    al, X25DATARCV_DATA                            ; see if data
  500.             jne    Rcv_end                           ; if not data goto rcv_end
  501.             push   di
  502.             mov    di, ofs_data_data                 ; load buffer offset
  503.             cmp    byte ptr es:[di], '*'             ; test buffer first byte
  504.             pop    di
  505.             jne    Displaydata
  506.             mov    data_complete,complete
  507.             @VioWrtTTY EOMRcvMsg,EOMRcvlen,0
  508.             @VioWrtTTY crlf,2,0
  509.             jmp    Nodisplay
  510. Displaydata:
  511.             push   shrdseg                                      ; push selector
  512.             push   ofs_data_data                                  ; push offset
  513.             push   MESSAGE_SIZE                             ; push message size
  514.             push   0
  515.             call    far ptr VIOWRTTTY                             ;display data
  516.             @VioWrtTTY crlf,2,0
  517. Nodisplay:
  518.                                                    ; check if the D bit is set,
  519.                                                          ; if so acknowledge it
  520.             test   [di+xvrb.control], d_bit
  521.             jz     rcv_end                                   ; d bit is not set
  522.  
  523.             mov    al,[di+xvrb.data_event_type]
  524.             cmp    al, X25DATARCV_DATA               ; did we receive data ?
  525.             jne    rcv_end                           ; no, so don't acknowledge
  526.             call   ack_data                     ; else we must send an ack back
  527. rcv_end :   ret
  528.  
  529. rcv_data    ENDP
  530.  
  531. ;=============================================================================
  532. ; Make and Call X25ACK
  533. ;=============================================================================
  534. ack_data    PROC                                     ;make verb and call X25ACK
  535.  
  536.             mov    di, ofs_xvrb
  537.             mov    [di+xvrb.verb_code], X25ACK
  538.             mov    [di+xvrb.version_id], X25_API_VERSION
  539.             mov    [di+xvrb.queue_number], 0         ; queues are not used here
  540.             mov    ax, word ptr connid+2
  541.             mov    word ptr [di+xvrb.connection_id+2], ax         ; fill in the
  542.             mov    ax, word ptr connid                          ; connection id
  543.             mov    word ptr [di+xvrb.connection_id], ax
  544.  
  545.             @X25                                            ; Call the X.25 API
  546.             cmp    ax, X25_OK                              ; check immediate RC
  547.             je     NoImmErr6
  548.             mov    ErrorType, Immediate              ; Indicate immediate error
  549.             jmp    AckErr
  550. NoImmErr6:
  551.             call   SemWait                          ; wait for verb to complete
  552.             mov    di, ofs_xvrb
  553.             mov    ax, [di+xvrb.return_code]
  554.             cmp    ax, X25_OK                             ; check Completion RC
  555.             je     AckGood
  556.             mov    ErrorType, Completion            ; Indicate completion error
  557.             jmp    AckErr
  558. AckErr:
  559.             mov    ErrNum, ax
  560.             @VioWrtTTY AckBadMsg,AckBadlen,0
  561.             @VioWrtTTY crlf,2,0
  562.             call   Error
  563. AckGood:
  564.             @VioWrtTTY AckGoodMsg,AckGoodlen,0
  565.             @VioWrtTTY crlf,2,0
  566.             ret
  567.  
  568. ack_data    ENDP
  569.  
  570. ;=============================================================================
  571. ; Make and Call X25CALLCLEAR
  572. ;=============================================================================
  573. clear_call  PROC                               ;make verb and call X25CALLCLEAR
  574.             mov   di, ofs_xvrb
  575.             mov   [di+xvrb.verb_code], X25CALLCLEAR
  576.             mov   [di+xvrb.version_id], X25_API_VERSION
  577.             mov   [di+xvrb.queue_number], 0          ; queues are not used here
  578.             mov   ax, word ptr connid+2
  579.             mov   word ptr [di+xvrb.connection_id+2], ax          ; fill in the
  580.             mov   ax, word ptr connid                           ; connection id
  581.             mov   word ptr [di+xvrb.connection_id], ax
  582.             mov   [di+xvrb.data_buffer_size], 0
  583.             mov   [di+xvrb.cause_code], 0
  584.             mov   [di+xvrb.diagnostic_code], 0
  585.  
  586.             ; We want the verb to complete before the clear confirm packet
  587.             ; has been received so we set the option to no wait
  588.             mov [di+xvrb.verb_option], X25CALLCLEAR_NOWAIT
  589.  
  590.             @X25                                            ; Call the X.25 API
  591.             cmp   ax, X25_OK                               ; check immediate RC
  592.             je    NoImmErr7
  593.             mov   ErrorType, Immediate               ; Indicate immediate error
  594.             jmp   ClrCallErr
  595. NoImmErr7:
  596.             call  SemWait                           ; wait for verb to complete
  597.             mov   di, ofs_xvrb
  598.             mov   ax, [di+xvrb.return_code]
  599.             cmp   ax, X25_OK                              ; check Completion RC
  600.             je    ClrCallGood
  601.             mov   ErrorType, Completion             ; Indicate completion error
  602.             jmp   ClrCallErr
  603. ClrCallErr:
  604.             mov   ErrNum, ax
  605.             @VioWrtTTY ClrCallBadMsg,ClrCallBadlen,0
  606.             @VioWrtTTY crlf,2,0
  607.             call  Error
  608. ClrCallGood:
  609.             @VioWrtTTY ClrCallGoodMsg,ClrCallGoodlen,0
  610.             @VioWrtTTY crlf,2,0
  611.             ret
  612.  
  613. clear_call  ENDP
  614.  
  615.  
  616. ;=============================================================================
  617. ; Make and Call X25DEAFEN
  618. ;=============================================================================
  619. deafen      PROC                                 ; make verb and call X25DEAFEN
  620.             mov    di, ofs_xvrb
  621.             mov    [di+xvrb.verb_code], X25DEAFEN
  622.             mov    [di+xvrb.version_id], X25_API_VERSION
  623.             mov    [di+xvrb.queue_number], 0         ; queues are not used here
  624.                                                      ; uses same data as listen
  625.             @mova  [di+xvrb.data_buffer_ptr], ofs_listen_data, shrdseg
  626.             mov    [di+xvrb.data_buffer_size], X25LISTENDATA_SIZE
  627.  
  628.             mov    di, ofs_listen_data
  629.             mov    [di+listen_data.num_of_rtes], 1          ; set for one entry
  630.  
  631.             mov    bx, 0                                     ; initialise index
  632. copyloop2:
  633.             mov    al , byte ptr [TableName + bx]
  634.             mov    byte ptr [di+listen_data.rte_entry_list + bx], al
  635.             inc    bx                     ; copy the contents of tablename into
  636.             cmp    bx, TableNameLen          ; first position of the entry_list
  637.             jne    copyloop2               ; copy all 8 chars, unused ones will
  638.                                                                     ; be spaces
  639.  
  640.             @X25                                            ; Call the X.25 API
  641.             cmp    ax, X25_OK                              ; check immediate RC
  642.             je     NoImmErr8
  643.             mov    ErrorType, Immediate              ; Indicate immediate error
  644.             jmp    DeafenErr
  645. NoImmErr8:
  646.             call   SemWait                          ; wait for verb to complete
  647.             mov    di, ofs_xvrb
  648.             mov    ax, [di+xvrb.return_code]
  649.             cmp    ax, X25_OK                             ; check Completion RC
  650.             je     DeafenGood
  651.             mov    ErrorType, Completion            ; Indicate completion error
  652.             jmp    DeafenErr
  653. DeafenErr:
  654.             mov    ErrNum, ax
  655.             @VioWrtTTY DeafenBadMsg,DeafenBadlen,0
  656.             @VioWrtTTY crlf,2,0
  657.             call   Error
  658. DeafenGood:
  659.             @VioWrtTTY DeafenGoodMsg,DeafenGoodlen,0
  660.             @VioWrtTTY crlf,2,0
  661.             ret
  662.  
  663. deafen      ENDP
  664.  
  665. ;=============================================================================
  666. ; Make and Call X25APPTERM
  667. ;=============================================================================
  668. term_app    PROC
  669.             mov    di, ofs_xvrb
  670.             mov    [di+xvrb.verb_code], X25APPTERM
  671.             mov    [di+xvrb.version_id], X25_API_VERSION
  672.  
  673.             @X25                                            ; Call the X.25 API
  674.             cmp    ax, X25_OK                              ; check immediate RC
  675.             je     NoImmErr9
  676.             mov    ErrorType, Immediate              ; Indicate immediate error
  677.             jmp    TermErr
  678. NoImmErr9:
  679.             call   SemWait                          ; wait for verb to complete
  680.             mov    di, ofs_xvrb
  681.             mov    ax, [di+xvrb.return_code]
  682.             cmp    ax, X25_OK                             ; check Completion RC
  683.             je     TermGood
  684.             mov    ErrorType, Completion            ; Indicate completion error
  685.             jmp    TermErr
  686. TermErr:
  687.             mov    ErrNum, ax
  688.             @VioWrtTTY TermBadMsg,TermBadlen,0
  689.             @VioWrtTTY crlf,2,0
  690.             call   Error
  691. TermGood:
  692.             @VioWrtTTY TermGoodMsg,TermGoodlen,0
  693.             @VioWrtTTY crlf,2,0
  694.             ret
  695.  
  696. term_app    ENDP
  697.  
  698. ;=============================================================================
  699. ; Allocate Memory for shared data segment
  700. ;=============================================================================
  701. allocmem    PROC
  702.             @DosAllocSeg segsize, shrdseg, shareable    ; size of 32k, sharable
  703.                                                       ; and allocated to shrseg
  704.             cmp    ax,0                                      ; check rc is zero
  705.             je     SubSet                           ; then jump to next command
  706.             mov    ErrNum, ax                            ; else store the error
  707.             mov    ErrorType, DosError                    ; note the error type
  708.             Call   Error                   ; and show that an error has occured
  709. SubSet:
  710.             @DosSubSet shrdseg, initalise, segsize             ; initialise for
  711.                                                                 ; suballocation
  712.             @DosSubAlloc shrdseg,ofs_xvrb, X25VERB_SIZE
  713.             @DosSubAlloc shrdseg,ofs_call_data, X25CALLDATA_SIZE
  714.             @DosSubAlloc shrdseg,ofs_data_data, buffer_size
  715.             @DosSubAlloc shrdseg,ofs_listen_data, X25LISTENDATA_SIZE
  716.             ret
  717.  
  718. allocmem    ENDP
  719.  
  720. ;=============================================================================
  721. ; wait for the verb to complete
  722. ;=============================================================================
  723. SemWait    PROC                       ; for a RAM semaphore we give the address
  724.                                          ; where the semaphore handle is stored
  725.            mov   di, ofs_xvrb
  726.            lea   ax, [di+xvrb.ram_semaphore]                           ; offset
  727.            mov   word ptr SemAddress,ax
  728.            mov   ax, shrdseg                                         ; selector
  729.            mov   word ptr SemAddress+2,ax
  730.            @DosSemWait SemAddress , NoTimeOut
  731.            ret
  732.  
  733. SemWait    ENDP
  734.  
  735. ;=============================================================================
  736. ; Register an Error
  737. ;=============================================================================
  738. Error       PROC
  739.             mov    ax, ErrorType                        ;place error type in AX
  740.             cmp    ax, Immediate                  ;compare with immediate error
  741.             je     ImmErr                       ;If immediate error goto ImmErr
  742.             cmp    ax, DosError                        ;commpare with Dos error
  743.             je     DosErr                             ;If Dos error goto DosErr
  744. CompErr:
  745.             @VioWrtTTY x25DelErrMsg,x25DelErrLen,0 ;indicate error has occurred
  746.             mov    ax, ErrNum                        ;Move error number into AX
  747.             call   WrtDec                             ;Display out error number
  748.             jmp    terminate                                 ;terminate program
  749. ImmErr:
  750.             @VioWrtTTY x25ImmErrMsg,x25ImmErrLen,0 ;indicate error has occurred
  751.             mov    ax, ErrNum                        ;Move error number into AX
  752.             call   WrtDec                             ;Display out error number
  753.             jmp    terminate                                 ;terminate program
  754. DosErr:
  755.             @VioWrtTTY DosErrMsg,DosErrLen,0       ;indicate error has occurred
  756.             mov    ax, ErrNum                        ;Move error number into AX
  757.             call   WrtDec                             ;Display out error number
  758.                                                              ;terminate program
  759. terminate:  @VioWrtTTY crlf,2,0                 ; carriage return and line feed
  760.             @VioWrtTTY DosTermMsg,DosTermLen,0     ;Display terminating message
  761.             @dosexit       1,1                     ; Exit with return code of 1
  762.             ret
  763.  
  764. Error       ENDP
  765.  
  766. ;=============================================================================
  767. ; convert a hex word to a decimal number
  768. ;=============================================================================
  769. WrtDec      PROC                        ; write the decimal value of a hex word
  770.                                                  ; less than 1000d stored in ax
  771.                                                ; at the current cursor position
  772.             cwd                               ; extends ax into the dx register
  773.             div    hundred                  ; divide the word by word value 100
  774.             mov    hundreds, al               ; quotient in ax, remainder in dx
  775.             add    hundreds, 30h    ;  add 30h to make it a printable character
  776.             mov    ax, dx                              ; move remainder into ax
  777.             cwd                               ; extends ax into the dx register
  778.             div    ten                       ; divide the word by word value 10
  779.             mov    tens, al                   ; quotient in ax, remainder in dx
  780.             add    tens, 30h        ;  add 30h to make it a printable character
  781.             mov    units, dl                               ; remainder is units
  782.             add    units, 30h       ;  add 30h to make it a printable character
  783.             @VioWrtTTY hundreds,1,0                        ; print out hundreds
  784.             @VioWrtTTY tens,1,0                                ; print out tens
  785.             @VioWrtTTY units,1,0                              ; print out units
  786.             ret
  787.  
  788. WrtDec      ENDP
  789.  
  790. x25mrcv     ENDP
  791. code        ENDS
  792.             END    x25mrcv
  793.