home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 11 / 11.iso / n / n002 / 4.ddi / ECLSRCA.ZIP / XCOMMS.ASM < prev   
Encoding:
Assembly Source File  |  1991-06-20  |  255.1 KB  |  7,214 lines

  1. ;       XCOMMS.ASM - The XCOMMS kernal
  2. ;
  3. ;       If assembled to be bundled in - MASM XCOMMS,,/DBUNDLD /Dmemory_model;
  4. ;       otherwise, - MASM XCOMMS /Dmemory_model;
  5. ;
  6. ;         Copyright (C) 1991, South Mountain Software Inc.
  7. ;           All Rights Reserved
  8. ;
  9. ;
  10. ;       ===============================================================
  11. ;       Definitions
  12. ;       ===============================================================
  13. ;
  14.  
  15. INTERCEPTED     EQU     01h                     ; Timer_State value
  16. NATIVE          EQU     00h                     ; Timer_State value
  17.  
  18. KEYBK           EQU     1Bh                     ; Keyboard break
  19. TIMER           EQU     1Ch                     ; Timer interrupt
  20. BDOS            EQU     21h                     ; BDOS interrupt 
  21. RS232           EQU     14h                     ; Int 14h service vector
  22.  
  23. LIST_END        EQU     0
  24. XCOMMS_ID       EQU     0A66AH
  25. REV_MAJOR       EQU     4
  26. REV_MINOR       EQU     0
  27.  
  28. IONOP           MACRO                           ; Chip overrun safety factor
  29.                 JMP     $+2
  30.                 JMP     $+2
  31.                 JMP     $+2
  32.                 ENDM
  33.  
  34. Enter_critical  MACRO                           ; Disable interrupts
  35.                 PUSHF
  36.                 CLI
  37.                 ENDM                            ; (The stack is changed!)
  38.  
  39. Exit_critical   MACRO                           ; Enable interrupts
  40.                 POPF
  41.                 ENDM                            ; (The stack is changed!)
  42. ;
  43. ;       ===============================================================
  44. ;       References
  45. ;       ===============================================================
  46. ;
  47.  
  48.         PUBLIC  XCOMMS
  49.  
  50.         INCLUDE         ECLMACRO.INC
  51.  
  52. ;
  53. ;       ===============================================================
  54. ;       Local data
  55. ;       ===============================================================
  56. ;
  57.         IFDEF   BUNDLD
  58. _data   segment  word public 'DATA'
  59. _data   ends
  60. DGROUP  GROUP _DATA
  61.  
  62.         modstart        XCOMMS
  63.         ELSE
  64. CSEG    SEGMENT BYTE PUBLIC 'CODE'
  65.         ASSUME CS:CSEG, DS:CSEG, SS:CSEG, ES:CSEG
  66.         ENDIF
  67.  
  68. Service LABEL   WORD
  69.         DW      1400h                           ; COMMS_Status
  70.         DW      1401h                           ; COMMS_Link
  71.         DW      1402h                           ; COMMS_UnLink
  72.         DW      1403h                           ; COMMS_DTRon
  73.         DW      1404h                           ; COMMS_DTRoff
  74.         DW      1405h                           ; COMMS_RTSon
  75.         DW      1406h                           ; COMMS_RTSoff
  76.         DW      1407h                           ; COMMS_BREAKon
  77.         DW      1408h                           ; COMMS_BREAKoff
  78.         DW      1409h                           ; COMMS_fc_on
  79.         DW      140Ah                           ; COMMS_fc_off
  80.         DW      140Bh                           ; COMMS_DTRget
  81.         DW      140Ch                           ; COMMS_RTSget
  82.         DW      140Dh                           ; COMMS_Gaddr
  83.         DW      140Eh                           ; COMMS_Flush
  84.         DW      140Fh                           ; COMMS_BREAKget REV 1.2
  85.         DW      1410h                           ; COMMS_19200 REV 1.2
  86.         DW      1411h                           ; COMMS_GPORT REV 2.0
  87.         DW      1412h                           ; COMMS_Uxmit REV 2.0
  88.         DW      1413h                           ; COMMS_UTEST REV 2.0
  89.         DW      1414h                           ; COMMS_UKILL REV 2.0
  90.         DW      1415h                           ; COMMS_FASTR REV 2.0
  91.         DW      1416h                           ; COMMS_XCTIMOU REV 2.0
  92.         DW      1417h                           ; COMMS_FCKILL REV 2.0
  93.         DW      1418h                           ; COMMS_38400 REV 2.0
  94.         DW      1419h                           ; COMMS_OUT2 REV 3.0a
  95.         DW      1420h                           ; COMMS_STATUS_PORT REV 3.0
  96.         DW      1421h                           ; COMMS_SHARED_VECTOR REV 3.0
  97.         DW      1422h                           ; COMMS_ICMASK REV 3.0
  98.         DW      1423h                           ; COMMS_BOARD_TYPE 3.0
  99.         DW      1424h                           ; COMMS_57K REV 3.0
  100.         DW      1425h                           ; COMMS_115K REV 3.0
  101.         DW      1426h                           ; COMMS_STARTPORT REV 3.0
  102.         DW      1427h                           ; COMMS_MAXPORT REV 3.0
  103.         DW      1428h                           ; COMMS_SET_FC_CHAR REV 3.0
  104.         DW      1429h                           ; COMMS_Test_16550 REV 4.0
  105.         DW      142Ah                           ; COMMS_Set_16550 REV 4.0
  106.         DW      142Bh                           ; COMMS_Get_Buffer_Memory REV 4.0
  107.         DW      142Ch                           ; COMMS_Free_Buffer_Memory REV 4.0
  108.         DW      142Dh                           ; COMMS_Put_Buffer_Memory REV 4.0
  109.         DW      142Eh                           ; COMMS_Set_Int_Exit REV 4.0
  110.  
  111.         DW      0000h                           ; XCOMMS_Status
  112.         DW      0001h                           ; XCOMMS_Exit
  113.         DW      0002h                           ; XCOMMS_Entry
  114.  
  115.         DW      0010h                           ; BUFFR_Init
  116.         DW      0011h                           ; BUFFR_Status
  117.         DW      0012h                           ; BUFFR_Gmem
  118.         DW      0013h                           ; BUFFR_Pmem
  119.  
  120.         DW      1C00h                           ; TIMER_Status
  121.         DW      1C01h                           ; TIMER_Link
  122.         DW      1C02h                           ; TIMER_UnLink
  123.         DW      1C03h                           ; TIMER_Set
  124.         DW      1C04h                           ; TIMER_Clear
  125.         DW      1C05h                           ; TIMER_Test
  126.         DW      1C06h                           ; TIMER_Wait
  127.         DW      1C10h                           ; TIMERP_Status
  128.         DW      1C11h                           ; TIMERP_Link
  129.         DW      1C12h                           ; TIMERP_UnLink
  130.         DW      1C13h                           ; TIMERP_Set
  131.         DW      1C14h                           ; TIMERP_Clear
  132.         DW      1C15h                           ; TIMERP_Test
  133.         DW      1C16h                           ; TIMERP_Wait
  134.  
  135.         DW      1B00h                           ; KEYBK_Status
  136.         DW      1B01h                           ; KEYBK_Link
  137.         DW      1B02h                           ; KEYBK_UnLink
  138.         DW      1B03h                           ; KEYBK_Test
  139.  
  140. EndServ LABEL   WORD
  141. No_Serv EQU     (EndServ - Service) / 2         ; Number of services
  142.  
  143.  
  144. Routine LABEL   WORD
  145.         DW      OFFSET  COMMS_Status
  146.         DW      OFFSET  COMMS_Link
  147.         DW      OFFSET  COMMS_UnLink
  148.         DW      OFFSET  COMMS_DTRon
  149.         DW      OFFSET  COMMS_DTRoff
  150.         DW      OFFSET  COMMS_RTSon
  151.         DW      OFFSET  COMMS_RTSoff
  152.         DW      OFFSET  COMMS_BREAKon
  153.         DW      OFFSET  COMMS_BREAKoff
  154.         DW      OFFSET  COMMS_fc_on
  155.         DW      OFFSET  COMMS_fc_off
  156.         DW      OFFSET  COMMS_DTRget
  157.         DW      OFFSET  COMMS_RTSget
  158.         DW      OFFSET  COMMS_Gaddr
  159.         DW      OFFSET  COMMS_Flush
  160.         DW      OFFSET  COMMS_BREAKget          ; Rev 1.2
  161.         DW      OFFSET  COMMS_19200             ; Rev 1.2
  162.         DW      OFFSET  COMMS_GPORT             ; REV 2.0
  163.         DW      OFFSET  COMMS_Uxmit             ; REV 2.0
  164.         DW      OFFSET  COMMS_UTEST             ; REV 2.0
  165.         DW      OFFSET  COMMS_UKILL             ; REV 2.0
  166.         DW      OFFSET  COMMS_FASTR             ; REV 2.0
  167.         DW      OFFSET  COMMS_XCTIMOU           ; REV 2.0
  168.         DW      OFFSET  COMMS_FCKILL            ; REV 2.0
  169.         DW      OFFSET  COMMS_38400             ; REV 2.0
  170.     DW    OFFSET  COMMS_OUT2        ; 2.0a
  171.     DW    OFFSET  COMMS_STATUS_PORT    ; 3.0
  172.     DW    OFFSET  COMMS_SHARED_VECTOR    ; 3.0
  173.     DW    OFFSET  COMMS_SHARED_ICMASK    ; 3.0
  174.     DW    OFFSET  COMMS_BOARD_TYPE    ; 3.0
  175.     DW    OFFSET  COMMS_57K        ; 3.0
  176.     DW    OFFSET  COMMS_115K        ; 3.0
  177.     DW    OFFSET  COMMS_STARTPORT        ; 3.0
  178.     DW    OFFSET  COMMS_MAXPORT        ; 3.0
  179.     DW    OFFSET  COMMS_SET_FC_CHAR    ; 3.0
  180.         DW      OFFSET  COMMS_Test_16550        ; REV 4.0
  181.         DW      OFFSET  COMMS_Set_16550         ; REV 4.0
  182.         DW      OFFSET  COMMS_Get_Buffer_Memory ; REV 4.0
  183.         DW      OFFSET  COMMS_Free_Buffer_Memory ; REV 4.0
  184.         DW      OFFSET  COMMS_Put_Buffer_Memory ; REV 4.0
  185.         DW      OFFSET  COMMS_Set_Int_Exit      ; REV 4.0
  186.  
  187.         DW      OFFSET  XCOMMS_Status
  188.         DW      OFFSET  XCOMMS_Exit
  189.         DW      OFFSET  XCOMMS_Entry
  190.  
  191.         DW      OFFSET  BUFFR_Init  
  192.         DW      OFFSET  BUFFR_Status
  193.         DW      OFFSET  BUFFR_Gmem   
  194.         DW      OFFSET  BUFFR_Pmem
  195.  
  196.         DW      OFFSET  TIMER_Status
  197.         DW      OFFSET  TIMER_Link
  198.         DW      OFFSET  TIMER_UnLink
  199.         DW      OFFSET  TIMER_Set
  200.         DW      OFFSET  TIMER_Clear
  201.         DW      OFFSET  TIMER_Test
  202.         DW      OFFSET  TIMER_Wait
  203.         DW      OFFSET  TIMERP_Status           ; REV 2.0
  204.         DW      OFFSET  TIMERP_Link             ; REV 2.0
  205.         DW      OFFSET  TIMERP_UnLink           ; REV 2.0
  206.         DW      OFFSET  TIMERP_Set              ; REV 2.0
  207.         DW      OFFSET  TIMERP_Clear            ; REV 2.0
  208.         DW      OFFSET  TIMERP_Test             ; REV 2.0
  209.         DW      OFFSET  TIMERP_Wait             ; REV 2.0
  210.  
  211.         DW      OFFSET  KEYBK_Status
  212.         DW      OFFSET  KEYBK_Link
  213.         DW      OFFSET  KEYBK_UnLink
  214.         DW      OFFSET  KEYBK_Test
  215.  
  216.  
  217.  
  218. XCOMMS_State     DW      NATIVE                  ; Not used
  219. XCOMMS_Buffer_Offset    DW      ?
  220. XCOMMS_Buffer_Segment   DW      ?
  221. XCOMMS_Buffer_Count     DW      ?
  222.  
  223. copyright_data label word
  224.         DB      "Copyright (C) 1991, South Mountain Software Inc", 13,10
  225.  
  226.  
  227. Entries LABEL   WORD
  228.         DW      OFFSET  BUFFR_Entry
  229.         DW      OFFSET  TIMER_Entry
  230.         DW      OFFSET  KEYBK_Entry
  231.         DW      OFFSET  COMMS_Entry
  232.         DW      LIST_END
  233.  
  234. Exeunts LABEL   WORD
  235.         DW      OFFSET  TIMER_Exit
  236.         DW      OFFSET  KEYBK_Exit
  237.         DW      OFFSET  COMMS_Exit
  238. ;;;;;   DW      OFFSET  BUFFR_Init
  239.         DW      LIST_END
  240.  
  241. ;
  242. ;       ===============================================================
  243. ;       Kernal drivers
  244. ;       ===============================================================
  245. ;
  246.  
  247. ;*******************************************************************
  248. ;*******************************************************************
  249. ;*******************************************************************
  250. ;*******************************************************************
  251. ;        INCLUDE COMMS.ASM ; Communications handler (COMM_INT.ASM)
  252. ;*******************************************************************
  253. ;
  254. ;       COMMS.ASM  XCOMMS kernal Communications handler
  255. ;
  256. ;       (C) Copyright 1986, 1987, 1988 Essential Software, Inc.
  257. ;       (C) Copyright 1989, South Mountain Software, Inc.
  258. ;           All Rights Reserved
  259. ;
  260. ;    *************************************************************
  261. ;    *********************** MODIFICATIONS ***********************
  262. ;    *************************************************************
  263. ;
  264. ;    10-25-89    - changes marked with "- **XMIT*XON*FIX**"
  265. ;       1) Added lockout of interrupts when doing the setup and transmission
  266. ;          of the first character in unpended transmits. (see COMMS_Uxmit).
  267. ;          Also added check for flow control and XONs. 
  268. ;
  269. ;       When XCOMMS is entered, the INT 14h vector is automatically
  270. ;       intercepted.  Each INT 14h request is checked for the appropriate
  271. ;       LINKed unit - since either COM1 and/or COM2 may be linked.
  272. ;
  273. ;       If intercepted, receiver interrupts are generated - none of the
  274. ;       modem and line control signals are forced or verified unless
  275. ;       explicitly desired by the caller at COMMS_Link request.
  276. ;
  277. ;       An overrun error will NOT occur if the received character runs out of
  278. ;       buffer space.  Simply, characters that cannot be stored are ignored.
  279. ;
  280. ;       DEPENDS ON SYSTEM ROM BAUD RATE TABLE AT F000:E729(HEX)
  281. ;
  282. ;       CPR         Rev fixed   Description
  283. ;       -------     ----------  ----------------------------------------
  284. ;       ECL0002     1.2         xc_link loops forever on a non-existent COMx
  285. ;                   1.2         New feature - COMMS_BREAKget returns status
  286. ;                   1.2         New feature - COMMS_19200 fast speed
  287. ;                   2.0         COMMS_FASTR
  288. ;                   2.0         New feature - COMMS_38400 fast speed
  289. ;            2.0a        Modified not to clear DTR in COMMS_Link
  290.  
  291. PUBLIC INT14SEND, INT14READ, INT14STATUS
  292.  
  293. TIMEOUT         EQU     0FFFFh                  ; INT14READ,SEND loop timeout
  294.  
  295. ; Flow control bit masks (.Comm_Xflags)
  296. FC_ENABLED      EQU     01h                     ; Flow control is enabled
  297. FC_XOFF_SENT    EQU     02h                     ; Xoff has been transmitted
  298. FC_XOFF_RCVD    EQU     04h                     ; Xoff has been received
  299. FC_SEND_XOFF    EQU     08h                     ; Xoff needs to be transmitted
  300. FC_SEND_XON     EQU     10h                     ; Xon needs to be transmitted
  301. FC_REC_ON       EQU     20h                     ; REC Flow control enabled
  302. FC_TX_ON        EQU     40h                     ; TX Flow control enabled
  303.  
  304. IONOP           MACRO                           ; Chip overrun safety factor
  305.                 JMP     $+2
  306.                 JMP     $+2
  307.                 JMP     $+2
  308.                 ENDM
  309. ;
  310. ; 8259A Interrupt Controller port assignments:
  311.  
  312. ICA                     EQU     021h            ; Interrupt controller addr
  313. EOI                     EQU     020h            ; End of interrupt addr
  314.  
  315. UART_DEF                STRUC
  316. TX_RD_BUFF_DLLO         DB      ?               ; TRANSMIT WO, READ RO
  317.                                                 ; DIVISOR LATCH LOW IF DLAB=1
  318. IER_DLHI                DB      ?               ; INTERRUPT ENABLE REGISTER
  319.                                                 ; DIVISOR LATCH HIGH IF DLAB=1
  320. IIR                     DB      ?               ; INTERRUPT ID REGISTER
  321. LCR                     DB      ?               ; LINE CONTROL REGISTER RW
  322. MCR                     DB      ?               ; MODEM CONTROL REGISTER RW
  323. LSR                     DB      ?               ; LINE STATUS REGISTER RW
  324. MSR                     DB      ?               ; MODEM STATUS REGISTER RW
  325.  
  326. UART_DEF                ENDS
  327.  
  328.  
  329. ;
  330. ;   ================================================================
  331. ;   *** Communications port data base structure ***
  332. ;
  333. ;   Each port is defined in terms of the following structure
  334. ;   including:
  335. ;       Port address and vector information
  336. ;       Status flags (intercepted, DTR enabled, and break detected)
  337. ;       Receive Buffer pointers, counters, and flags
  338. ;       Transmit (rev 2.0) buffers and counters
  339. ;   ================================================================
  340. ;
  341.  
  342. Comms_str               STRUC
  343. Comm_PortAddr           DW      ?               ; Base port address FIXED
  344. Comm_Vector             DB      ?               ; Interrupt vector FIXED
  345. Comm_IC_Mask            DB      ?               ; Int Controller mask FIXED
  346. Comm_New_offset         DW      ?
  347. Comm_New_segment        DW      ?
  348. Comm_State              DW      ?               ; = 01h if intercepted
  349. Comm_DTR_RTS            DB      ?               ; Intercepted INT14INIT flag
  350. Comm_Break              DB      ?               ; Break detected (recv int)
  351.  
  352. Comm_Old_IntOffset      DW      ?               ; IREQ3, 4 old offset
  353. Comm_Old_IntSegment     DW      ?               ; IREQ3, 4 old segment
  354.  
  355. Comm_Receive_Count      DD      ?               ; Bytes received (DD!)
  356. Comm_Buffer_Count       DW      ?               ; Number of blocks current
  357.  
  358. Comm_CR_BUFFR_Offset    DW      ?               ; Interrupt buffer pointer
  359. Comm_CR_BUFFR_Segment   DW      ?
  360. Comm_CR_BUFFR_Index     DW      ?               ; Next index in buffer
  361.  
  362. Comm_RD_BUFFR_Offset    DW      ?               ; Int 14h read buffer pointer
  363. Comm_RD_BUFFR_Segment   DW      ?
  364. Comm_RD_BUFFR_Index     DW      ?               ; Next index in buffer
  365. Comm_Error              DW      ?               ; Overrun error flag
  366.  
  367. Comm_Xflags             DW      ?               ; Bit 0 X-On, X-Off
  368.                                                 ; Bit 1 X-Off sent
  369.                                                 ; Bit 2 X-Off received
  370. Comm_high               DW      ?               ; High water mark
  371. Comm_low                DW      ?               ; Low water mark
  372. Comm_xcount             DW      ?               ; Rev 2.0 Transmit buffer counter
  373. Comm_xptr_Offset        DW      ?               ; Rev 2.0 Transmit buffer addr
  374. Comm_xptr_Segment       DW      ?               ; Rev 2.0 Transmit buffer addr
  375. Comm_unit               DW      ?               ; COM1 = 0, COM2 = 2, ...
  376. Comm_UART_Mode          DW      0               ; 16450: 0; 16550: (nonzero) contains trigger and mode information; 
  377. Comm_IXmit_Base        DW    ?        ;
  378. Comm_IXmit_Top        DW    ?        ;
  379. Comm_IRec_Base        DW    ?        ;
  380. Comm_IRec_Top        DW    ?        ;
  381. Comm_rxbusy        DW    ?        ;
  382. Comms_str               ENDS
  383.  
  384.  
  385.  
  386. TIMERS_X16              LABEL   WORD                    ; 16-bit baud divisors
  387.                         DW      1047, 768, 384, 192, 96,48,24,12
  388. INT14_Old_Offset        DW      ?
  389. INT14_Old_Segment       DW      ?
  390. timeout_variable        DW      ?
  391. out2_variable        DW    08h    ; default to force out2 high for
  392.                     ; COM1 & COM2
  393. port_hold        DW    ?    ; hold unit (port) number briefly
  394. board_type        DW    0    ; multiport board type
  395. starting_port        DW    99    ; starting port number for multiports
  396.                     ; multiplied by 2 for offset
  397. multi_init        DW    0    ; flag for multiport linking
  398. multi_unlinked        DW    0    ; flag for multiport unlinking
  399. maxshare        DW    0    ; max num ports on this irq
  400.  
  401. ; variables below are for second multiport
  402. board2_type        DW    0    ; multiport board type
  403. starting2_port        DW    99; starting port number for multiports
  404.                     ; multiplied by 2 for offset
  405. multi2_init        DW    0    ; flag for multiport linking
  406. multi2_unlinked        DW    0    ; flag for multiport unlinking
  407. maxshare2        DW    0    ; max num ports on this irq
  408. XON                DB         11h     ; Character XON
  409. XOFF                DB         13h     ; Character XOFF
  410.  
  411.  
  412. ; EQUATES FOR MASK TESTS
  413. MREC     EQU     1
  414. MSEND    EQU     2
  415. MMSR     EQU     4
  416. MERR     EQU     8
  417.  
  418. IFDEF INT_EXITS
  419. com1_mask               DW      0
  420. com1_func               DD      0
  421. com2_mask               DW      0
  422. com2_func               DD      0
  423. share1_mask             DW      0
  424. share1_func             DD      0
  425. share2_mask             DW      0
  426. share2_func             DD      0
  427. ENDIF
  428.  
  429.  
  430.  
  431.  
  432. TEST_EXIT_REC   MACRO   handler,  call_to, jmp_to, port
  433.         local   nothing_yet, change_char, no_jump, local_port, local_jump
  434.         jmp     local_jump
  435. local_port      dw      0
  436. local_jump:
  437.         test    word ptr cs:handler, MREC
  438.         jz      nothing_yet
  439.         mov     cs:local_port, port
  440.         push    ax
  441.         push    bx
  442.         push    cx
  443.         push    dx
  444.         push    ds
  445.         mov     bx, DGROUP
  446.         mov     ds, bx
  447.         xor     ah, ah
  448.         push    ax
  449.         mov     ax, MREC
  450.         push    ax
  451.         push    cs:local_port
  452.         call    dword ptr call_to
  453.         add     sp, 6
  454.         pop     ds
  455.         pop     dx
  456.         pop     cx
  457.         pop     bx
  458.  
  459.         cmp     ax, 0
  460.         jne     change_char
  461.         pop     ax
  462.         jmp     short nothing_yet
  463. change_char:
  464.         add     sp, 2           ; old ax still on stack
  465.         cmp     ax, 0ffffh      ; should we not save the char ( ax == -1)
  466. ;       je      jmp_to          rel jump out of range
  467.         jne     no_jump
  468.         jmp     jmp_to
  469. no_jump:
  470.                                 ; anything else means store a new character
  471.         xor     ah, ah          ; leave new char in AL
  472. nothing_yet:
  473.         ENDM
  474.  
  475. TEST_EXIT_SEND       MACRO   handler, call_to, port
  476.         local   nothing_yet, local_port, local_jump
  477.         jmp     local_jump
  478. local_port      dw      0
  479. local_jump:
  480.         test    word ptr cs:handler, MSEND
  481.         jz      nothing_yet
  482.         mov     cs:local_port, port
  483.         push    ax
  484.         push    bx
  485.         push    cx
  486.         push    dx
  487.         push    ds
  488.         mov     bx, DGROUP
  489.         mov     ds, bx
  490.         mov     ax, MSEND
  491.         push    ax
  492.         push    cs:local_port
  493.         call    dword ptr call_to
  494.         add     sp, 4
  495.         pop     ds
  496.         pop     dx
  497.         pop     cx
  498.         pop     bx
  499.         pop     ax
  500.  
  501. nothing_yet:
  502.         ENDM
  503.  
  504. TEST_EXIT_MSR       MACRO   handler, call_to, port
  505.         local   nothing_yet, local_port, local_jump
  506.         jmp     local_jump
  507. local_port      dw      0
  508. local_jump:
  509.         test    word ptr cs:handler, MMSR
  510.         jz      nothing_yet
  511.         mov     cs:local_port, port
  512.         push    ax
  513.         push    bx
  514.         push    cx
  515.         push    dx
  516.         push    ds
  517.         mov     bx, DGROUP
  518.         mov     ds, bx
  519.         xor     ah, ah
  520.         push    ax
  521.         mov     ax, MMSR
  522.         push    ax
  523.         push    cs:local_port
  524.         call    dword ptr call_to
  525.         add     sp, 6
  526.         pop     ds
  527.         pop     dx
  528.         pop     cx
  529.         pop     bx
  530.         pop     ax
  531.  
  532. nothing_yet:
  533.         ENDM
  534.  
  535. TEST_EXIT_ERR       MACRO   handler, call_to, port
  536.         local   nothing_yet, local_port, local_jump
  537.         jmp     local_jump
  538. local_port      dw      0
  539. local_jump:
  540.         test    word ptr cs:handler, MERR
  541.         jz      nothing_yet
  542.         mov     cs:local_port, port
  543.         push    ax
  544.         push    bx
  545.         push    cx
  546.         push    dx
  547.         push    ds
  548.         mov     bx, DGROUP
  549.         mov     ds, bx
  550.         xor     ah, ah
  551.         push    ax
  552.         mov     ax, MERR
  553.         push    ax
  554.         push    cs:local_port
  555.         call    dword ptr call_to
  556.         add     sp, 6
  557.         pop     ds
  558.         pop     dx
  559.         pop     cx
  560.         pop     bx
  561.         pop     ax
  562.  
  563. nothing_yet:
  564.         ENDM
  565.  
  566.  
  567. public board_type, starting_port, multi_init, maxshare
  568. public board2_type, starting2_port, multi2_init, maxshare2
  569.  
  570. ; variables below are for first and second PC/Xx intelligent multiport board
  571. PC_Xx_structure        STRUC
  572. pcxx_io_port         DB    ?    ;
  573. pcxx_irq        DB    ?    ;
  574. pcxx_window_base    DW    ?    ;
  575. pcxx_memory_seg        DW    ?    ;
  576. pcxx_memory_size    DD    ?    ;
  577. pcxx_nports        DB    ?    ;
  578. pcxx_board_type        DW    ?    ;
  579. PC_Xx_structure        ENDS
  580.  
  581.  
  582. ;*******************************************************************
  583. ;*******************************************************************
  584. ;*******************************************************************
  585. ;*******************************************************************
  586. ;        INCLUDE COMM_INT.ASM        ; Communications handler (COMM_INT.ASM)
  587. ;*******************************************************************
  588. ;
  589. ;       COMSALL.asm      IBM PC COM1 and COM2 & MULTI-PORT Communications
  590. ;       Comm_int.asm - Communications interrupt handlers
  591. ;                       (include file from COMMS.ASM)
  592. ;
  593. ;       (C) Copyright 19896 SOuth Mountain Software Inc.
  594. ;
  595. ;    *************************************************************
  596. ;    *********************** MODIFICATIONS ***********************
  597. ;    *************************************************************
  598. ;
  599. ;    10-23-89    - changes marked with "- WQ " 
  600. ;            - assemble with /DWQ for this one
  601. ;    1) Changed by WQ to add setting of flag bit when 1st XON received.
  602. ;       Used so that the transmitter can wait for the first XON to
  603. ;       be received before starting the transmission of data. This
  604. ;       flag bit is in the structure entry "COMx.Comm_Xflags" (bit value
  605. ;       "FC_FIRST_XON - 80H") which can be read via the "xc_gaddr()"
  606. ;       function. This flag setting is NOT used within the driver - if
  607. ;       needed by the application it must be read in the high level file
  608. ;       transfer portion of the C code. Note that this bit value is
  609. ;       currently unused but reserved by the ESI Comm. Library.
  610. ;
  611. ;    10-25-89    - changes marked with "- **XMIT*XON*FIX**"
  612. ;       1) Fixed bug in the 8250 "bug fix" code that caused a permanent loop
  613. ;          to be caused when flow control was enabled, the THRE was empty, and
  614. ;          the last character received was an XOFF. 
  615. ;    12-27-89    - added DIGIBOARD Multichannel support
  616. ;    10-11-90 JHL    - Corrected code to support Digiboard PC/X boards using
  617. ;    even IRQs. Corrected code to support Digiboard MC/X boards.
  618. ;       12-05-90 JHL    - Corrected code to support AST 4 PORT DOS and 
  619. ;    DFI MU440 boards in "Compatible" mode.
  620. ;
  621. ;       service routines        description
  622. ;
  623. ;       IREQ4                   COM1 standard interrupt operation
  624. ;       IREQ3                   COM2 standard interrupt operation
  625. ;       IREQSHARE               COM3+ multi-port interrupt operation
  626. ;       IREQSHARE2              COM3n multi-port interrupt operation
  627. ;
  628. ;       CPR     Rev fixed       Description
  629. ;       ------- ---------       ------------------------------------
  630. ;       ECL0006 1.2             Interrupts "lost" CX during buffer read
  631. ;               2.0             Redistributed support for COM1 and COM2
  632. ;        2.0a        Changed to IIR only checking.
  633. ;        2.0a        Also combined flow control code
  634. ;                and enabled XON/XOFF in both TX & RX.
  635. ;        2.0a        Enabled hardwire handshaking for unpended TX
  636. ;        3.0        ALL of the multiport stuff + hardware bugfix
  637.  
  638. IFDEF WQ
  639. FC_FIRST_XON    EQU    80h    ;1st XON received for WQ
  640. ENDIF
  641.  
  642. PUBLIC          C1
  643. PUBLIC          IREQ4,IREQ3,IREQSHARE,IREQSHARE2
  644.  
  645. C1    EQU 03F8h       ; 8250 UART port offset COM1
  646. C2 EQU 02F8h       ; 8250 UART port offset COM2
  647. C3 EQU 0           ; 3-n default to none available
  648. C4 EQU 0
  649. C5 EQU 0
  650. C6 EQU 0
  651. C7 EQU 0
  652. C8 EQU 0
  653. C9 EQU 0
  654. C10 EQU 0
  655. C11    EQU 0
  656. C12    EQU 0
  657. C13    EQU 0
  658. C14    EQU 0
  659. C15    EQU 0
  660. C16    EQU 0
  661. C17    EQU 0
  662. C18    EQU 0
  663. C19    EQU 0
  664. C20    EQU 0
  665. C21    EQU 0
  666. C22    EQU 0
  667. C23    EQU 0
  668. C24    EQU 0
  669. C25    EQU 0
  670. C26    EQU 0
  671. C27    EQU 0
  672. C28    EQU 0
  673. C29    EQU 0
  674. C30    EQU 0
  675. C31    EQU 0
  676. C32    EQU 0
  677. C33    EQU 0
  678. C34    EQU 0
  679.  
  680.  
  681. COM1            Comms_str <C1, 0Ch, 0EFh, OFFSET IREQ4, SEG IREQ4>
  682. COM2            Comms_str <C2, 0Bh, 0F7h, OFFSET IREQ3, SEG IREQ3>
  683. COM3            Comms_str <C3, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  684. COM4            Comms_str <C4, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  685. COM5            Comms_str <C5, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  686. COM6            Comms_str <C6, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  687. COM7            Comms_str <C7, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  688. COM8            Comms_str <C8, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  689. COM9            Comms_str <C9, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  690. COM10           Comms_str <C10, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  691. COM11           Comms_str <C11, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  692. COM12           Comms_str <C12, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  693. COM13           Comms_str <C13, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  694. COM14           Comms_str <C14, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  695. COM15           Comms_str <C15, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  696. COM16           Comms_str <C16, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  697. COM17           Comms_str <C17, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  698. COM18           Comms_str <C18, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  699. COM19           Comms_str <C19, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  700. COM20           Comms_str <C20, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  701. COM21           Comms_str <C21, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  702. COM22           Comms_str <C22, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  703. COM23           Comms_str <C23, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  704. COM24           Comms_str <C24, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  705. COM25           Comms_str <C25, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  706. COM26           Comms_str <C26, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  707. COM27           Comms_str <C27, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  708. COM28           Comms_str <C28, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  709. COM29           Comms_str <C29, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  710. COM30           Comms_str <C30, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  711. COM31           Comms_str <C31, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  712. COM32           Comms_str <C32, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  713. COM33           Comms_str <C33, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  714. COM34           Comms_str <C34, 0Dh, 0DFh, OFFSET IREQSHARE, SEG IREQSHARE>
  715.  
  716. Shared_vector           DB 0Dh
  717. Shared_IC_mask          DB 0DFh
  718. Shared_Old_IntOffset    DW  ?           ; Shared interrupt previous vector
  719. Shared_Old_IntSegment   DW  ?
  720. Shared_New_IntOffset    DW  OFFSET IREQSHARE
  721. Shared_New_IntSegment   DW  SEG IREQSHARE
  722. Status_port        DW  0h        ; no default
  723.  
  724. Shared2_vector           DB 0Dh
  725. Shared2_IC_mask          DB 0DFh
  726. Shared2_Old_IntOffset    DW  ?           ; Shared interrupt previous vector
  727. Shared2_Old_IntSegment   DW  ?
  728. Shared2_New_IntOffset    DW  OFFSET IREQSHARE2
  729. Shared2_New_IntSegment   DW  SEG IREQSHARE2
  730. Status2_port         DW  0h        ; no default
  731.  
  732. public Shared_vector, Shared_IC_mask, Status_port
  733. public Shared2_vector, Shared2_IC_mask, Status2_port
  734.  
  735.  
  736.  
  737. MAXPORTS        EQU     34       ; COM1 and COM2 & 32 others
  738.  
  739. Port_Table      DW      OFFSET  COM1    ; Pointer to Comms_str structures
  740.                 DW      OFFSET  COM2
  741.                 DW      OFFSET  COM3
  742.                 DW      OFFSET  COM4
  743.                 DW      OFFSET  COM5
  744.                 DW      OFFSET  COM6
  745.                 DW      OFFSET  COM7
  746.                 DW      OFFSET  COM8
  747.                 DW      OFFSET  COM9
  748.                 DW      OFFSET  COM10
  749.                 DW      OFFSET  COM11
  750.                 DW      OFFSET  COM12
  751.                 DW      OFFSET  COM13
  752.                 DW      OFFSET  COM14
  753.                 DW      OFFSET  COM15
  754.                 DW      OFFSET  COM16
  755.                 DW      OFFSET  COM17
  756.                 DW      OFFSET  COM18
  757.                 DW      OFFSET  COM19
  758.                 DW      OFFSET  COM20
  759.                 DW      OFFSET  COM21
  760.                 DW      OFFSET  COM22
  761.                 DW      OFFSET  COM23
  762.                 DW      OFFSET  COM24
  763.                 DW      OFFSET  COM25
  764.                 DW      OFFSET  COM26
  765.                 DW      OFFSET  COM27
  766.                 DW      OFFSET  COM28
  767.                 DW      OFFSET  COM29
  768.                 DW      OFFSET  COM30
  769.                 DW      OFFSET  COM31
  770.                 DW      OFFSET  COM32
  771.                 DW      OFFSET  COM33
  772.                 DW      OFFSET  COM34
  773.  
  774. STATUS_POLLED   EQU     0               ; Status default polled
  775. STATUS_INTERRUP EQU     1               ; Status interrupt driven
  776. STATUS_FLOWC    EQU     2               ; Status interrupt and flow control on
  777.  
  778. Port_Status     DW      MAXPORTS DUP (?);
  779.  
  780.  
  781.  
  782. ;   =======================================================================
  783.  
  784. ;****  first Load_SI is from original  COM1COM2
  785. ;Load_SI         MACRO                   ; Required MACRO to load SI with Comms_str addr
  786. ;                LOCAL   skip
  787. ;                LEA     SI, COM1        ; Assume COM1
  788. ;                CMP     DL, 00
  789. ;                JE      skip
  790. ;                LEA     SI, COM2
  791. ;skip:
  792. ;                ENDM
  793.  
  794. Load_SI         MACRO                   ; Required MACRO to load SI with Comms_str addr
  795.                 PUSH    BX
  796.                 MOV     BL, DL          ; (No checking performed)
  797.                 MOV     BH, 0
  798.                 ADD     BX, BX
  799.                 MOV     SI, Port_Table[BX]
  800.                 POP     BX
  801.                 ENDM
  802.  
  803.  
  804.  
  805. SI_continue     MACRO                   ; Given SI, continue xmission
  806.                 LOCAL   skip
  807.                 CMP     [SI].Comm_xcount, 0
  808.                 JZ      skip
  809.                 DEC     [SI].Comm_xcount
  810.                 CMP     [SI].Comm_xcount, 0
  811.                 JZ      skip
  812.  
  813.                 PUSH    ES
  814.                 MOV     BX, [SI].Comm_xptr_Offset
  815.                 MOV     ES, [SI].Comm_xptr_Segment
  816.                 MOV     AL, ES:[BX]
  817.                 INC     [SI].Comm_xptr_Offset
  818.                 SI_putAL
  819.                 POP     ES
  820. skip:
  821.                 ENDM
  822.  
  823. ;    This macro is used to xmit up to 16 bytes when FIFOs are enabled.
  824. ;     Upon entry into this macro, both software flow control and hardware
  825. ;    flow control has been checked so that we can xmit at least 1 charater
  826. ;     without additional checking.
  827. SI_FIFO_continue     MACRO            ; Given SI, continue xmission
  828.                 LOCAL   exit_1
  829.                 LOCAL   pop_exit_2
  830.         LOCAL    send_char_to_FIFO
  831.                 LOCAL   stuff_FIFO
  832.         LOCAL    no_fc
  833.  
  834.                 cmp    [si].Comm_xcount, 0
  835.                 jz      exit_1                ; No more characters to xmit - then exit
  836.         push    es
  837.         push    cx
  838.         mov    cx, 010h            ; set loop counter to 16 characters
  839.                 mov     es, [si].Comm_xptr_Segment    ; load segment of xmit buffer
  840. ;    Send first character to the FIFO
  841.         jmp    send_char_to_FIFO
  842.  
  843. ;    Send the next character to the FIFO
  844. stuff_FIFO:
  845.  
  846. ;    Check if software Flow Control is enabled (XON - XOFF)
  847.         test    [si].Comm_Xflags, FC_TX_ON    ;Is flow control enabled
  848.         je    no_fc
  849.         test    [si].Comm_Xflags, FC_XOFF_RCVD    ;Was XOFF received
  850.         jne    pop_exit_2              ;If so we cannot xmit
  851.  
  852. ;    Check if Hardware Flow Control is disabled (Hardware Handshaking)
  853. no_fc:
  854.         cmp    [si].Comm_DTR_RTS, 0        ; see if handshaking disabled
  855.         je    send_char_to_FIFO          ; Stuff next character in FIFO
  856.             mov     dx, [si].Comm_PortAddr        ; Yes- read in modem status register to clear interrupt
  857.         add    dx, MSR
  858.             in      al, dx                
  859. ;    look for Hardware Handshaking flag
  860.         and    al, [si].Comm_DTR_RTS        ; look for CTS and/or DSR
  861.         cmp    al, [si].Comm_DTR_RTS        ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  862.             jne    pop_exit_2            ; try again if no CTS/DSR
  863. ;        and    al, 00110000B            ; look for CTS and DSR
  864. ;        cmp    al, 00110000B            ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  865. ;            jne    pop_exit_2            ; try again if no CTS/DSR
  866.  
  867. send_char_to_FIFO:
  868.                 dec     [si].Comm_xcount
  869.                 cmp     [si].Comm_xcount, 0
  870.                 jz      pop_exit_2
  871.  
  872.                 mov     bx, [si].Comm_xptr_Offset
  873.                 mov     al, es:[bx]
  874.                 inc     [si].Comm_xptr_Offset
  875.                 SI_putAL                ; Send character to FIFO
  876.  
  877.         loop     stuff_FIFO
  878.  
  879. pop_exit_2:
  880.         pop    cx
  881.         pop    es
  882. exit_1:
  883.                 ENDM
  884.  
  885.  
  886.  
  887. SI_putAL        MACRO                   ; Given SI, send the character in AL
  888.                                         ; !!! .Comm_xcount not modified !!!
  889.                 MOV     DX, [SI].Comm_PortAddr
  890. ;***            ADD     DX, TX_RD_BUFF_DLLO   ;2.0a not necessary
  891.                 OUT     DX, AL
  892.                 IONOP
  893.                 ENDM
  894.  
  895.  
  896. SI_FCon         MACRO
  897.                 MOV     BX, [SI].Comm_unit
  898.                 MOV     WORD PTR Port_Status[BX], STATUS_FLOWC
  899.                 ENDM
  900.  
  901. ;   =======================================================================
  902.  
  903. SI_FCoff        MACRO
  904.                 MOV     BX, [SI].Comm_unit
  905.                 MOV     WORD PTR Port_Status[BX], STATUS_INTERRUP
  906.                 ENDM
  907.  
  908. ;   =======================================================================
  909. ;
  910. ;    This macro gets the value of an 8250 register into AL.  It assumes
  911. ;    SI points to the port offset address already.
  912. ;
  913. SI_REG        MACRO    xxx
  914.             MOV     DX, [SI].Comm_PortAddr
  915.                ADD    DX, xxx
  916.             IN      AL, DX        ; Get cause of interrupt
  917.         ENDM
  918.  
  919.  
  920. IREQ4   PROC    FAR             ; COM1 standard interrupt operation
  921.         PUSH    DS              ; Save segments
  922.         PUSH    ES              ; Removed the LINE BREAK code!
  923.         PUSH    CS
  924.         POP     DS
  925.         PUSH    DI
  926.         PUSH    SI
  927.         PUSH    DX
  928.     PUSH    CX
  929.     PUSH    BX
  930.         PUSH    AX
  931.  
  932. _ireq4_tryall:            ;***** REV 2.0a changes here
  933.         MOV     SI, OFFSET COM1
  934.         MOV    DX, C1+IIR    ; Find out what caused interrupt
  935.         IN      AL, DX        ; Get cause of interrupt
  936.     and    al, 0Fh     ; Isolate bits 0-3 of IIR
  937.         CMP    AL, 01H        ; Any more interrupts pending?
  938.  
  939.            JNE    _ireq4_ckrec    ; jump if IIR says we have interrupt       **XMIT*XON*FIX**
  940. ;                                                                          **XMIT*XON*FIX**
  941. ; This area handles the "known" 8250-18450 UART bug that occurs when a     **XMIT*XON*FIX**
  942. ; received data interrupt occurs at the same time that a THRE interrupt    **XMIT*XON*FIX**
  943. ; occurred. When this circumstance occurs, no further TX interrupts are    **XMIT*XON*FIX**
  944. ; generated, halting data xmission.                                        **XMIT*XON*FIX**
  945. ;                                                                          **XMIT*XON*FIX**
  946.            MOV    DX, C1+LSR    ; look at THRE to get around 8250 bug
  947.            IN    AL, DX
  948.            test    AL, 20H
  949.            jnz    _ireq4_txbug    ; have to check TX
  950.            jmp    _ireq4_exit
  951. ;          AND    AL, 20H        ; isolate THRE
  952. ;          CMP    AL, 20H
  953. ;          JE    _ireq4_txbug    ; have to check TX
  954. ;          JMP    _ireq4_exit
  955.  
  956. _ireq4_txbug:
  957.         CMP     [SI].Comm_xcount, 0      ; anything to be xmitted?         **XMIT*XON*FIX**
  958.         JNE    _ireq4_txbug_xmt_enter   ; yes- see if conditions are ok   **XMIT*XON*FIX**
  959.         JMP    _ireq4_exit              ; no - nothing to do, get out     **XMIT*XON*FIX**
  960.  
  961. ;                                                                          **XMIT*XON*FIX**
  962. ; THRE is empty - if flow control is enabled check for proper XON state.   **XMIT*XON*FIX**
  963. ; (Note: 8250 bug will be overcome on the next receive interrupt by an     **XMIT*XON*FIX**
  964. ;        XON).                                                             **XMIT*XON*FIX**
  965. ;                                                                          **XMIT*XON*FIX**
  966. _ireq4_txbug_xmt_enter:                                                   ;**XMIT*XON*FIX**
  967.  
  968.  
  969.     TEST    COM1.Comm_Xflags,FC_TX_ON    ; Is flow control enabled? **XMIT*XON*FIX**
  970.     JE    txbug_no_fc4            ; no - check handshaking   **XMIT*XON*FIX**
  971.     TEST    COM1.Comm_Xflags,FC_XOFF_RCVD    ; Was XOFF received?       **XMIT*XON*FIX**
  972.     JE    txbug_no_fc4            ; no - check handshaking   **XMIT*XON*FIX**
  973.     JMP     _ireq4_exit                 ; wait for XON to xmit     **XMIT*XON*FIX**
  974.  
  975. ;                                                                          **XMIT*XON*FIX**
  976. ; THRE is empty - if h/w handshake is enabled check modem signals.         **XMIT*XON*FIX**
  977. ; (Note: 8250 bug will be overcome when the modem signals change and cause **XMIT*XON*FIX**
  978. ;        an interrupt).                                                    **XMIT*XON*FIX**
  979. ;                                                                          **XMIT*XON*FIX**
  980. txbug_no_fc4:                                                             ;**XMIT*XON*FIX**
  981.     CMP    [SI].Comm_DTR_RTS, 0  ; see if handshaking disabled        **XMIT*XON*FIX**
  982. ;    JE    _ireq4_ckxmt3         ; handshaking is off, go xmit data!  **XMIT*XON*FIX**
  983.         jne     tempab                ; rel jump out of range
  984.         jmp     _ireq4_ckxmt3
  985. tempab:
  986.         MOV     DX, C1+MSR            ; read in modem status register to   **XMIT*XON*FIX**
  987.         IN      AL, DX              ;    clear interrupt                 **XMIT*XON*FIX**
  988. ;    look for Hardware Handshaking flag
  989.     and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  990.     cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  991. ;    AND    AL, 00110000B          ; look for CTS and DSR               **XMIT*XON*FIX**
  992. ;    CMP    AL, 00110000B          ;                                    **XMIT*XON*FIX**
  993.         JE    _ireq4_ckxmt3          ; CTS/DSR ok, go xmit data           **XMIT*XON*FIX**
  994.            JMP    _ireq4_exit           ; can't xmit now so exit             **XMIT*XON*FIX**
  995.  
  996. ; AL contains bits 0-3 of IIR. Check if IIR bit 2 (04h)is set (Receive 
  997. ; Data Available) or if both IIR bits 2 and 3 (0Ch) are set 
  998. ; (Character Timeout Indication - Receive Data Available).
  999. _ireq4_ckrec:
  1000. ;    test    al, 0CH        ; Got a character to read?
  1001.     cmp    al, 04H        ; Got a character to read?
  1002.     jnz    _ireq4_charto    ; No
  1003.     jmp     _ireq4_dataready          ; Yes - go process it
  1004. _ireq4_charto:
  1005.     cmp    al, 0CH        ; Got a character to read?
  1006.     jnz    _ireq4_ckxmt    ; No
  1007.     jmp     _ireq4_dataready          ; Yes - go process it
  1008.  
  1009. _ireq4_ckxmt:                     ; AL contains bits 0-3 of IIR.
  1010.     CMP    AL, 02H        ; Ready to xmit a character? (Check Xmit Holding Reg Empty)
  1011. ;    JNE    _ireq4_ckmsr    ; No ; Rel Jump Out of range
  1012.     je    _ireq4_xmt_enter
  1013.     jmp    _ireq4_ckmsr    ; No
  1014.  
  1015. ;    Transmit interrupt generated!!!!!!!!
  1016. _ireq4_xmt_enter:               ; Xmit chars if there are any to Xmit
  1017.  
  1018. IFDEF   INT_EXITS
  1019.         TEST_EXIT_SEND       cs:com1_mask, cs:com1_func, 0
  1020. ENDIF
  1021.  
  1022.     TEST    COM1.Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  1023.     JE    no_fc4
  1024.     TEST    COM1.Comm_Xflags,FC_XOFF_RCVD    ;Was XOFF received
  1025. ;rel jmp out of range       JNE    _ireq4_tryall    ; if so we cannot xmit
  1026.         je      x2
  1027.         jmp     _ireq4_tryall
  1028. x2:
  1029. no_fc4:
  1030.     CMP    [SI].Comm_DTR_RTS, 0    ;2.0a see if handshaking disabled
  1031.     JE    _ireq4_ckxmt3
  1032.         MOV     DX, C1+MSR      ; Yes- read in modem status register to
  1033.         IN      AL, DX        ;    clear interrupt
  1034.  
  1035. ;    look for Hardware Handshaking flag
  1036.     and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  1037.     cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  1038. ;    AND    AL, 00110000B    ; look for CTS and DSR
  1039. ;    CMP    AL, 00110000B    ;
  1040. ;rel jmp out of range       JNE    _ireq4_tryall    ; try again if no CTS/DSR
  1041.         je      x1
  1042.         jmp     _ireq4_tryall
  1043. x1:
  1044.  
  1045. ;    Xmit Interrupt Received, all clear to stuff Xmit buffer.
  1046. ;    When the Xmit FIFO is enabled (FCR0=1), Xmit interrupts will occur
  1047. ;    as follows: The transmitter holding register interrupt (02) occurs
  1048. ;    when the Xmit FIFO is empty. It is cleared as soon as the transmitter 
  1049. ;    holding register is written to (1 to 16 characters may be written to
  1050. ;    the Xmit FIFO while servicing this interrupt) or the IIR is read.
  1051. _ireq4_ckxmt3:
  1052. ;    Check if our UART mode indicates FIFOs are enabled
  1053. ;    Allowable values for "COMM_UART_Mode" are:
  1054. ;    0 = 16440 (16550 Character) mode
  1055. ;    1 = 16550 FIFOs enabled, DMA mode 0
  1056. ;    9 = 16550 FIFOs enabled, DMA mode 1 (This mode is not used)
  1057.  
  1058.     test    [si].COMM_UART_Mode, 09h 
  1059.     jz    _ireq4_x1char    ; FIFOs not present or not enabled
  1060.  
  1061.     SI_FIFO_continue        ; Stuff up to 16 chars in Xmit FIFO
  1062.         jmp    _ireq4_tryall    ; Now go see if anything else is pending
  1063.  
  1064. _ireq4_x1char:            ; Xmit 1 character
  1065.     SI_continue             ; Xmit next char in Xmit buffer
  1066.         jmp    _ireq4_tryall    ; Now go see if anything else is pending
  1067.  
  1068. ;     No chars received, no chars to Xmit
  1069. _ireq4_ckmsr:                     ;
  1070.     CMP    AL, 00H        ; Change in modem status? (AL contains bits 0-3 of IIR)
  1071.     JNE    _ireq4_ckerr    ; No - check  for error or break
  1072. _ireq4_ckmsr2:                     ;
  1073.         MOV     DX, C1+MSR      ; Yes- read in modem status register to
  1074.         IN      AL, DX        ;    clear interrupt
  1075.  
  1076. IFDEF INT_EXITS
  1077.         TEST_EXIT_MSR   cs:com1_mask, cs:com1_func, 0
  1078. ENDIF
  1079.  
  1080.         CMP     [SI].Comm_DTR_RTS, 0    ; See if handshaking enabled
  1081. ;        JE    _ireq4_tryall    ; Now go see if anything else is pending
  1082.     JNE    _ireq4_ckmsr3    ; JE above relative JMP out of range
  1083.     JMP    _ireq4_tryall
  1084. _ireq4_ckmsr3:
  1085.     MOV    DX, C1+LSR
  1086.     IN    AL, DX
  1087. ; Check Xmit Holding Reg (LSR bit 6) and Xmit Empty (LSR bit 7) bits
  1088.     AND    AL, 60h        ; See if ready to transmit
  1089.     CMP    AL, 60h
  1090. ;    JE    _ireq4_ckxmt2    ; Relative Jump Out Of Range
  1091.     jne    _ireq4_1rjor
  1092.     jmp    _ireq4_xmt_enter ; go to start of Xmit char processing
  1093. _ireq4_1rjor:
  1094.         jmp    _ireq4_tryall    ; Now go see if anything else is pending
  1095.  
  1096.  
  1097. _ireq4_ckerr:            ; 
  1098.         CMP    AL, 06H        ; Got a rec'd char w/error or break?
  1099. ;**        JNE    _ireq4_tryall    ; No
  1100.     JE    _ireq4_ckerr2    ; Relative jmp out of range
  1101.     JMP    _ireq4_tryall
  1102. _ireq4_ckerr2:
  1103.         MOV     DX, C1+LSR      ; Yes- read in line status register to
  1104.         IN      AL, DX        ;    clear interrupt
  1105.  
  1106. IFDEF INT_EXITS
  1107.         TEST_EXIT_ERR   cs:com1_mask, cs:com1_func, 0
  1108. ENDIF
  1109.  
  1110.         mov     BYTE PTR [si].Comm_Break, al
  1111.         JMP    _ireq4_tryall    ; Now go see if anything else is pending
  1112.  
  1113.  
  1114. _ireq4_exit:
  1115.         MOV     AL, 20h         ; Acknowledge interrupt
  1116.         OUT     EOI, AL
  1117.         POP     AX              ; Restore registers
  1118.         POP     BX
  1119.     POP    CX
  1120.         POP     DX
  1121.         POP     SI
  1122.         POP     DI
  1123.         POP     ES
  1124.         POP     DS
  1125.         IRET
  1126.  
  1127. ;       Read and Store  character
  1128. ; Data has been received (IIR is 04h or 0Ch); AL contains bits 0-3 of IIR
  1129. _ireq4_dataready:
  1130. ;    Check if 16550 is present and if FIFOs are enabled
  1131.  
  1132.     test    [si].COMM_UART_Mode, 09h 
  1133.     jz    _ireq4_noFIFO_dataready    ; FIFOs not present or not enabled
  1134.     jmp    _ireq4_FIFO_dataready    ; FIFOs are present and enabled
  1135.     
  1136. _ireq4_noFIFO_dataready:
  1137. ;    Read received character
  1138.         MOV     DX, C1+TX_RD_BUFF_DLLO
  1139.         IN      AL, DX
  1140.  
  1141. IFDEF   INT_EXITS
  1142.         TEST_EXIT_REC   cs:com1_mask, cs:com1_func, _ireq4_tryall, 0
  1143. ENDIF
  1144.  
  1145.  
  1146. ;    Check if Xmit Flow Control has been enabled
  1147.     TEST    COM1.Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  1148.     JE    no_fc4r
  1149.         CMP     AL, XOFF            ; Compare incomming char to XOFF
  1150.         JNE     _ireq4fc_rskip1
  1151.         OR      COM1.Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  1152.         JMP     _ireq4_tryall
  1153. _ireq4fc_rskip1:
  1154.         CMP     AL, XON
  1155.         JNE     _ireq4fc_rskip2
  1156.         AND     COM1.Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  1157. IFDEF WQ
  1158.         OR    COM1.Comm_Xflags, FC_FIRST_XON      ; Got 1st XON for WQ
  1159. ENDIF
  1160.         SI_continue           ; Xmit next char in Xmit buffer if there is a char to Xmit
  1161.         JMP     _ireq4_tryall
  1162. _ireq4fc_rskip2:
  1163.  
  1164. no_fc4r:                                      ; No Flow Control Enabled
  1165.         MOV     DX, COM1.Comm_CR_BUFFR_Segment
  1166.         MOV     ES, DX
  1167.         MOV     DI, COM1.Comm_CR_BUFFR_Offset
  1168.         MOV     DX, COM1.Comm_CR_BUFFR_Index
  1169.         ADD     DI, DX
  1170.         STOSB                                 ; Store Char in receive buffer
  1171. ; Increment Index into receive buffer
  1172.         ADD     WORD PTR COM1.Comm_Receive_Count, 1
  1173.         ADC     WORD PTR COM1.Comm_Receive_Count + 2, 0
  1174.         INC     DX
  1175.         CMP     DX, BUFFER_SIZE
  1176.         JNZ     _ireq4_cont
  1177.  
  1178. ;       Optionally, add another buffer
  1179.  
  1180.         PUSH    CX              ; REV 1.2 ECL0006
  1181.         CALL    BUFFR_Gmem      ; Get next available buffer
  1182.         POP     CX              ; REV 1.2 ECL0006
  1183.         JC      _ireq4_nobuff   ; None available
  1184.                                 ; Increment next buffer information
  1185.         INC     COM1.Comm_Buffer_Count
  1186.         MOV     DI, COM1.Comm_CR_BUFFR_Offset
  1187.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  1188.         MOV     ES:[DI+2], DX
  1189.         MOV     COM1.Comm_CR_BUFFR_Offset, BX
  1190.         MOV     COM1.Comm_CR_BUFFR_Segment, DX
  1191.         MOV     DX, 4           ; New index
  1192.  
  1193. _ireq4_cont:
  1194. ;    Store Updated Receive Buffer Index in COMMS structure
  1195.         MOV     COM1.Comm_CR_BUFFR_Index, DX
  1196.  
  1197.     TEST    COM1.Comm_Xflags,FC_REC_ON    ;Is flow control enabled
  1198.     JNE    ck4_hi
  1199.         JMP     _ireq4_tryall
  1200. ck4_hi:                    ; check high flow control mark
  1201.         TEST    COM1.Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  1202.     JE    ck4_hi_2
  1203.         JMP     _ireq4_tryall
  1204. ck4_hi_2:
  1205. ;****    don't check high word, XON/XOFF only supported < 64K
  1206. ;****    CMP    WORD PTR COM1.Comm_Receive_Count+2, 0
  1207. ;****    JNE    over4_high
  1208.     MOV    AX, COM1.Comm_high
  1209.     CMP    WORD PTR COM1.Comm_Receive_Count, AX
  1210.     JGE    over4_high
  1211.         JMP     _ireq4_tryall
  1212. over4_high:
  1213.                 ; have to send XOFF
  1214.     MOV    DX, C1+LSR    ; get line status
  1215.      IN    AL, DX
  1216. ; Any error is revealed via LSR bits 1-4 when it's associated 
  1217. ; character is at the top of the FIFO
  1218.     TEST    AL, 01h        ; has a char come in
  1219.     JE    over4_cont
  1220.     jmp    _ireq4_noFIFO_dataready    ; if so, go get it
  1221. over4_cont:
  1222.     TEST    AL, 40h        ; look at TX ready bits
  1223.     JE    over4_high    ; wait for TX OK
  1224.     SUB    DX, LSR
  1225.     MOV    AL, XOFF
  1226.     OUT    DX, AL        ; Xmit XOFF
  1227.     OR    COM1.Comm_Xflags, FC_XOFF_SENT
  1228.  
  1229.         JMP     _ireq4_tryall
  1230.  
  1231.  
  1232. ; No more Receive Buffer space available; Next Character received will
  1233. ; overwrite the last character received.
  1234. _ireq4_nobuff:                  ; None available
  1235.         SUB     WORD PTR COM1.Comm_Receive_Count, 1
  1236.         SBB     WORD PTR COM1.Comm_Receive_Count + 2, 0
  1237.     JMP     _ireq4_tryall
  1238.  
  1239. ;*************************************************************************
  1240. ;    The following code is executed if the Uart has it's FIFOS enabled.
  1241. ;*************************************************************************
  1242. ;    If the Receive FIFOs are enabled, then the code will loop until
  1243. ;    the Receive FIFO is empty. Bit 0 of the Line Status Register is
  1244. ;    set to one whenever at least 1 character is in the Recieve Buffer
  1245. ;    Register. This bit (LSR bit0) is set to zero by reading all data 
  1246. ;    in the receive buffer or FIFO.
  1247.  
  1248. _ireq4_FIFO_dataready:
  1249. ;    Read received character
  1250.         MOV     DX, C1+TX_RD_BUFF_DLLO
  1251.         IN      AL, DX                      ; Read character received
  1252.  
  1253. IFDEF   INT_EXITS
  1254.         TEST_EXIT_REC   cs:com1_mask, cs:com1_func, _ireq4_tryall, 0
  1255. ENDIF
  1256.  
  1257. ;    Check if Xmit Flow Control has been enabled
  1258.     TEST    COM1.Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  1259.     JE    no_fc4rFIFO
  1260.         CMP     AL, XOFF            ; Compare incomming char to XOFF
  1261.         JNE     _ireq4fc_FIFOrskip1
  1262.         OR      COM1.Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  1263.  
  1264. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1265.     jmp    _ireq4_check_data_ready
  1266.  
  1267. _ireq4fc_FIFOrskip1:
  1268.         CMP     AL, XON
  1269.         JNE     _ireq4fc_FIFOrskip2
  1270.         AND     COM1.Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  1271. IFDEF WQ
  1272.     OR    COM1.Comm_Xflags, FC_FIRST_XON      ; Got 1st XON - WQ
  1273. ENDIF
  1274.         SI_continue           ; Xmit next char in Xmit buffer if there is a char to Xmit
  1275.  
  1276. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1277.     jmp    _ireq4_check_data_ready
  1278.  
  1279. _ireq4fc_FIFOrskip2:
  1280.  
  1281. no_fc4rFIFO:                                      ; No Flow Control Enabled
  1282. ;    Get ECL Receive buffer location
  1283.         MOV     DX, COM1.Comm_CR_BUFFR_Segment
  1284.         MOV     ES, DX
  1285.         MOV     DI, COM1.Comm_CR_BUFFR_Offset
  1286.         MOV     DX, COM1.Comm_CR_BUFFR_Index
  1287.         ADD     DI, DX
  1288.         STOSB                                 ; Store Char in receive buffer
  1289. ; Increment Index into receive buffer
  1290.         ADD     WORD PTR COM1.Comm_Receive_Count, 1
  1291.         ADC     WORD PTR COM1.Comm_Receive_Count + 2, 0 
  1292.         INC     DX
  1293.         CMP     DX, BUFFER_SIZE
  1294.         JNZ     _ireq4_contFIFO
  1295.  
  1296. ;       Optionally, add another buffer
  1297.  
  1298.         PUSH    CX              ; REV 1.2 ECL0006
  1299.         CALL    BUFFR_Gmem      ; Get next available buffer
  1300.         POP     CX              ; REV 1.2 ECL0006
  1301.         JC      _ireq4_FIFOrjor6 ; No Buffers available
  1302.     jmp    _ireq4_FIFOrjor7 ; Buffers available
  1303. _ireq4_FIFOrjor6:
  1304.     jmp    _ireq4_FIFOnobuff   ; No Buffers available
  1305. _ireq4_FIFOrjor7:
  1306.                                 ; Increment next buffer information
  1307.         INC     COM1.Comm_Buffer_Count
  1308.         MOV     DI, COM1.Comm_CR_BUFFR_Offset
  1309.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  1310.         MOV     ES:[DI+2], DX
  1311.         MOV     COM1.Comm_CR_BUFFR_Offset, BX
  1312.         MOV     COM1.Comm_CR_BUFFR_Segment, DX
  1313.         MOV     DX, 4           ; New index
  1314.  
  1315. _ireq4_contFIFO:
  1316. ;    Store Updated Receive Buffer Index in COMMS structure
  1317.         MOV     COM1.Comm_CR_BUFFR_Index, DX 
  1318.  
  1319.     TEST    COM1.Comm_Xflags,FC_REC_ON    ;Is Receive flow control enabled
  1320.     JNE    ck4_hi_FIFO
  1321.  
  1322. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1323.     jmp    _ireq4_check_data_ready
  1324.  
  1325. ck4_hi_FIFO:                    ; check high flow control mark
  1326.         TEST    COM1.Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  1327.     JE    ck4_hi_2_FIFO
  1328.  
  1329. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1330.     jmp    _ireq4_check_data_ready
  1331.  
  1332. ck4_hi_2_FIFO:
  1333. ;****    don't check high word, XON/XOFF only supported < 64K
  1334. ;****    CMP    WORD PTR COM1.Comm_Receive_Count+2, 0
  1335. ;****    JNE    over4_high
  1336.     MOV    AX, COM1.Comm_high
  1337.     CMP    WORD PTR COM1.Comm_Receive_Count, AX
  1338.     JGE    over4_high_FIFO
  1339.  
  1340. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1341.     jmp    _ireq4_check_data_ready
  1342.  
  1343. over4_high_FIFO:
  1344.                 ; have to send XOFF
  1345.     MOV    DX, C1+LSR    ; get line status
  1346.      IN    AL, DX
  1347. ;    Any error is revealed via LSR bits 1-4 when it's associated 
  1348. ;    character is at the top of the FIFO
  1349.     TEST    AL, 01h        ; has a char come in
  1350.     JE    over4_cont_FIFO
  1351.     JMP    _ireq4_FIFO_dataready    ; if so, go get it
  1352.  
  1353. over4_cont_FIFO:
  1354.     TEST    AL, 40h        ; look at TX ready bits
  1355.     JE    over4_high_FIFO    ; wait for TX OK
  1356.     SUB    DX, LSR
  1357.     MOV    AL, XOFF
  1358.     OUT    DX, AL        ; Xmit XOFF
  1359.     OR    COM1.Comm_Xflags, FC_XOFF_SENT
  1360.  
  1361. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1362.     jmp    _ireq4_check_data_ready
  1363.  
  1364. ; No more Receive Buffer space available; Next Character received will
  1365. ; overwrite the last character received.
  1366. _ireq4_FIFOnobuff:                  ; None available
  1367.         SUB     WORD PTR COM1.Comm_Receive_Count, 1
  1368.         SBB     WORD PTR COM1.Comm_Receive_Count + 2, 0
  1369.  
  1370. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1371. _ireq4_check_data_ready:
  1372.     mov    dx, C1+LSR            ; Load Line Status reg address
  1373.     in    al, dx                ; Get LSR
  1374.     test    al, 01h                ; Test for Receive FIFO empty
  1375.     jnz    _ireq4_FIFO_rjor1        ; Get next character in Receive FIFO
  1376.     JMP     _ireq4_tryall
  1377. _ireq4_FIFO_rjor1:                ; Relative Jump Out Of Range
  1378.     jmp    _ireq4_FIFO_dataready        ; Get next character in Receive FIFO
  1379.  
  1380. IREQ4   ENDP
  1381.  
  1382. ;*********************************************************************
  1383.  
  1384. IREQ3   PROC    FAR             ; COM1 standard interrupt operation
  1385.         PUSH    DS              ; Save segments
  1386.         PUSH    ES              ; Removed the LINE BREAK code!
  1387.         PUSH    CS
  1388.         POP     DS
  1389.         PUSH    DI
  1390.         PUSH    SI
  1391.         PUSH    DX
  1392.     PUSH    CX
  1393.         PUSH    BX
  1394.         PUSH    AX
  1395.  
  1396. _ireq3_tryall:            ;***** REV 2.0a changes here
  1397.         MOV     SI, OFFSET COM2
  1398.         MOV    DX, C2+IIR    ; Find out what caused interrupt
  1399.         IN      AL, DX        ; Get cause of interrupt
  1400.     and    al, 0Fh     ; Isolate bits 0-3 of IIR
  1401.         CMP    AL, 01H        ; Any more interrupts pending?
  1402.  
  1403.            JNE    _ireq3_ckrec    ; jump if IIR says we have interrupt       **XMIT*XON*FIX**
  1404. ;                                                                          **XMIT*XON*FIX**
  1405. ; This area handles the "known" 8250-18450 UART bug that occurs when a     **XMIT*XON*FIX**
  1406. ; received data interrupt occurs at the same time that a THRE interrupt    **XMIT*XON*FIX**
  1407. ; occurred. When this circumstance occurs, no further TX interrupts are    **XMIT*XON*FIX**
  1408. ; generated, halting data xmission.                                        **XMIT*XON*FIX**
  1409. ;                                                                          **XMIT*XON*FIX**
  1410.            MOV    DX, C2+LSR    ; look at THRE to get around 8250 bug
  1411.            IN    AL, DX
  1412. ;          AND    AL, 20H        ; isolate THRE
  1413. ;          CMP    AL, 20H
  1414. ;          JE    _ireq3_txbug    ; have to check TX
  1415. ;          JMP    _ireq3_exit
  1416.     test    al, 020H
  1417.           jnz    _ireq3_txbug    ; have to check TX
  1418.           jmp    _ireq3_exit
  1419.  
  1420. _ireq3_txbug:
  1421.         CMP     [SI].Comm_xcount, 0      ; anything to be xmitted?         **XMIT*XON*FIX**
  1422.         JNE    _ireq3_txbug_xmt_enter   ; yes- see if conditions are ok   **XMIT*XON*FIX**
  1423.         JMP    _ireq3_exit              ; no - nothing to do, get out     **XMIT*XON*FIX**
  1424.  
  1425. ;                                                                          **XMIT*XON*FIX**
  1426. ; THRE is empty - if flow control is enabled check for proper XON state.   **XMIT*XON*FIX**
  1427. ; (Note: 8250 bug will be overcome on the next receive interrupt by an     **XMIT*XON*FIX**
  1428. ;        XON).                                                             **XMIT*XON*FIX**
  1429. ;                                                                          **XMIT*XON*FIX**
  1430. _ireq3_txbug_xmt_enter:                                                   ;**XMIT*XON*FIX**
  1431.     TEST    COM2.Comm_Xflags,FC_TX_ON    ; Is flow control enabled? **XMIT*XON*FIX**
  1432.     JE    txbug_no_fc3            ; no - check handshaking   **XMIT*XON*FIX**
  1433.     TEST    COM2.Comm_Xflags,FC_XOFF_RCVD    ; Was XOFF received?       **XMIT*XON*FIX**
  1434.     JE    txbug_no_fc3            ; no - check handshaking   **XMIT*XON*FIX**
  1435.     JMP     _ireq3_exit                 ; wait for XON to xmit     **XMIT*XON*FIX**
  1436.  
  1437. ;                                                                          **XMIT*XON*FIX**
  1438. ; THRE is empty - if h/w handshake is enabled check modem signals.         **XMIT*XON*FIX**
  1439. ; (Note: 8250 bug will be overcome when the modem signals change and cause **XMIT*XON*FIX**
  1440. ;        an interrupt).                                                    **XMIT*XON*FIX**
  1441. ;                                                                          **XMIT*XON*FIX**
  1442. txbug_no_fc3:                                                             ;**XMIT*XON*FIX**
  1443.     CMP    [SI].Comm_DTR_RTS, 0  ; see if handshaking disabled        **XMIT*XON*FIX**
  1444. ;    JE    _ireq3_ckxmt3         ; handshaking is off, go xmit data!  **XMIT*XON*FIX**
  1445.         jne     tempaa                ; rel jump out of range
  1446.         jmp     _ireq3_ckxmt3
  1447. tempaa:
  1448.         MOV     DX, C2+MSR            ; read in modem status register to   **XMIT*XON*FIX**
  1449.         IN      AL, DX              ;    clear interrupt                 **XMIT*XON*FIX**
  1450. ;    look for Hardware Handshaking flag
  1451.     and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  1452.     cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  1453. ;    AND    AL, 00110000B          ; look for CTS and DSR               **XMIT*XON*FIX**
  1454. ;    CMP    AL, 00110000B          ;                                    **XMIT*XON*FIX**
  1455.         JE    _ireq3_ckxmt3          ; CTS/DSR ok, go xmit data           **XMIT*XON*FIX**
  1456.            JMP    _ireq3_exit           ; can't xmit now so exit             **XMIT*XON*FIX**
  1457.  
  1458. ; AL contains bits 0-3 of IIR. Check if IIR bit 2 (04h)is set (Receive 
  1459. ; Data Available) or if both IIR bits 2 and 3 (0Ch) are set 
  1460. ; (Character Timeout Indication - Receive Data Available).
  1461. _ireq3_ckrec:
  1462. ;    test    al, 0CH        ; Got a character to read?
  1463.     cmp    al, 04H        ; Got a character to read?
  1464.     jnz    _ireq3_charto    ; No
  1465.     jmp     _ireq3_dataready          ; Yes - go process it
  1466. _ireq3_charto:
  1467.     cmp    al, 0CH        ; Got a character to read?
  1468.     jnz    _ireq3_ckxmt    ; No
  1469.     jmp     _ireq3_dataready          ; Yes - go process it
  1470.  
  1471. _ireq3_ckxmt:                     ; AL contains bits 0-3 of IIR.
  1472.     CMP    AL, 02H        ; Ready to xmit a character? (Check Xmit Holding Reg Empty)
  1473. ;    JNE    _ireq3_ckmsr    ; No ; Rel Jump Out of range
  1474.     je    _ireq3_xmt_enter
  1475.     jmp    _ireq3_ckmsr    ; No
  1476.  
  1477. ;     Transmit interrupt generated!!!!!!!!
  1478. _ireq3_xmt_enter:               ; Xmit chars if there are any to Xmit
  1479.  
  1480. IFDEF   INT_EXITS
  1481.         TEST_EXIT_SEND       cs:com2_mask, cs:com2_func, 1
  1482. ENDIF
  1483.  
  1484.     TEST    COM2.Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  1485.     JE    no_fc3
  1486.     TEST    COM2.Comm_Xflags,FC_XOFF_RCVD    ;Was XOFF received
  1487. ;rel jmp OOR    JNE    _ireq3_tryall            ;If so we cannot xmit
  1488.         JE      no_fc3
  1489.         JMP     _ireq3_tryall
  1490. no_fc3:
  1491.     CMP    [SI].Comm_DTR_RTS, 0    ;2.0a see if handshaking disabled
  1492.     JE    _ireq3_ckxmt3
  1493.         MOV     DX, C2+MSR      ; Yes- read in modem status register to
  1494.         IN      AL, DX        ;    clear interrupt
  1495.  
  1496. ;    look for Hardware Handshaking flag
  1497.     and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  1498.     cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  1499. ;    AND    AL, 00110000B    ; look for CTS and DSR
  1500. ;    CMP    AL, 00110000B    ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  1501. ; rel jmp OOR   JNE    _ireq3_tryall    ; try again if no CTS/DSR
  1502.         JE      xx1
  1503.         JMP     _ireq3_tryall
  1504. xx1:
  1505.  
  1506. ;    Xmit Interrupt Received, all clear to stuff Xmit buffer.
  1507. ;    When the Xmit FIFO is enabled (FCR0=1), Xmit interrupts will occur
  1508. ;    as follows: The transmitter holding register interrupt (02) occurs
  1509. ;    when the Xmit FIFO is empty. It is cleared as soon as the transmitter 
  1510. ;    holding register is written to (1 to 16 characters may be written to
  1511. ;    the Xmit FIFO while servicing this interrupt) or the IIR is read.
  1512. _ireq3_ckxmt3:
  1513. ;    Check if our UART mode indicates FIFOs are enabled
  1514. ;    Allowable values for "COMM_UART_Mode" are:
  1515. ;    0 = 16440 (16550 Character) mode
  1516. ;    1 = 16550 FIFOs enabled, DMA mode 0
  1517. ;    9 = 16550 FIFOs enabled, DMA mode 1 (This mode is not used)
  1518.  
  1519.     test    [si].COMM_UART_Mode, 09h 
  1520.     jz    _ireq3_x1char    ; FIFOs not present or not enabled
  1521.  
  1522.     SI_FIFO_continue        ; Stuff up to 16 chars in Xmit FIFO
  1523.         jmp    _ireq3_tryall    ; Now go see if anything else is pending
  1524.  
  1525. _ireq3_x1char:            ; Xmit 1 character
  1526.         SI_continue             ; Xmit next char in Xmit buffer
  1527.         jmp    _ireq3_tryall    ; Now go see if anything else is pending
  1528.  
  1529. ;     No chars received, no chars to Xmit
  1530. _ireq3_ckmsr:                     
  1531.     CMP    AL, 00H        ; Change in modem status? (AL contains bits 0-3 of IIR)
  1532.     JNE    _ireq3_ckerr    ; No - check  for error or break
  1533. _ireq3_ckmsr2:                     ;
  1534.         MOV     DX, C2+MSR      ; Yes- read in modem status register to
  1535.         IN      AL, DX        ;    clear interrupt
  1536.  
  1537. IFDEF INT_EXITS
  1538.         TEST_EXIT_MSR   cs:com2_mask, cs:com2_func, 1
  1539. ENDIF
  1540.  
  1541.         CMP     [SI].Comm_DTR_RTS, 0    ; See if handshaking enabled
  1542. ;        JE    _ireq3_tryall    ; Now go see if anything else is pending
  1543.     JNE    _ireq3_ckmsr3    ; JE above relative JMP out of range
  1544.     JMP    _ireq3_tryall
  1545. _ireq3_ckmsr3:
  1546.     MOV    DX, C2+LSR
  1547.     IN    AL, DX
  1548. ; Check Xmit Holding Reg (LSR bit 6) and Xmit Empty (LSR bit 7) bits
  1549.     AND    AL, 60h        ; See if ready to transmit
  1550.     CMP    AL, 60h
  1551. ;    JE    _ireq3_ckxmt2    ; Relative Jump Out Of Range
  1552.     jne    _ireq3_1rjor
  1553.     jmp    _ireq3_xmt_enter ; go to start of Xmit char processing
  1554. _ireq3_1rjor:
  1555.         jmp    _ireq3_tryall    ; Now go see if anything else is pending
  1556.  
  1557.  
  1558. _ireq3_ckerr:            ;
  1559.         CMP    AL, 06H        ; Got a rec'd char w/error or break?
  1560. ;**        JNE    _ireq3_tryall    ; No
  1561.     JE    _ireq3_ckerr2    ; Relative jmp out of range
  1562.     JMP    _ireq3_tryall
  1563. _ireq3_ckerr2:
  1564.         MOV     DX, C2+LSR      ; Yes- read in line status register to
  1565.         IN      AL, DX        ;    clear interrupt             
  1566.  
  1567. IFDEF INT_EXITS
  1568.         TEST_EXIT_ERR   cs:com2_mask, cs:com2_func, 1
  1569. ENDIF
  1570.  
  1571.         mov     BYTE PTR [si].Comm_Break, al
  1572.         JMP    _ireq3_tryall    ; Now go see if anything else is pending
  1573.  
  1574.  
  1575. _ireq3_exit:
  1576.         MOV     AL, 20h         ; Acknowledge interrupt
  1577.         OUT     EOI, AL
  1578.         POP     AX              ; Restore registers
  1579.         POP     BX
  1580.     POP    CX
  1581.         POP     DX
  1582.         POP     SI
  1583.         POP     DI
  1584.         POP     ES
  1585.         POP     DS
  1586.         IRET
  1587.  
  1588. ;       Read and Store  character
  1589. ; Data has been received (IIR is 04h or 0Ch); AL contains bits 0-3 of IIR
  1590. _ireq3_dataready:
  1591. ;    Check if 16550 is present and if FIFOs are enabled
  1592.  
  1593.     test    [si].COMM_UART_Mode, 09h 
  1594.     jz    _ireq3_noFIFO_dataready    ; FIFOs not present or not enabled
  1595.     jmp    _ireq3_FIFO_dataready    ; FIFOs are present and enabled
  1596.     
  1597. _ireq3_noFIFO_dataready:
  1598. ;    Read received character
  1599.         MOV     DX, C2+TX_RD_BUFF_DLLO
  1600.         IN      AL, DX                      ; Read character received
  1601.  
  1602. IFDEF   INT_EXITS
  1603.         TEST_EXIT_REC   cs:com2_mask, cs:com2_func, _ireq3_tryall, 1
  1604. ENDIF
  1605.  
  1606. ;    Check if Xmit Flow Control has been enabled
  1607.     TEST    COM2.Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  1608.     JE    no_fc3r
  1609.         CMP     AL, XOFF            ; Compare incomming char to XOFF
  1610.         JNE     _ireq3fc_rskip1
  1611.         OR      COM2.Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  1612.         JMP     _ireq3_tryall
  1613. _ireq3fc_rskip1:
  1614.         CMP     AL, XON
  1615.         JNE     _ireq3fc_rskip2
  1616.         AND     COM2.Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  1617. IFDEF WQ
  1618.     OR    COM2.Comm_Xflags, FC_FIRST_XON      ; Got 1st XON - WQ
  1619. ENDIF
  1620.         SI_continue           ; Xmit next char in Xmit buffer if there is a char to Xmit
  1621.         JMP     _ireq3_tryall
  1622. _ireq3fc_rskip2:
  1623.  
  1624. no_fc3r:                                      ; No Flow Control Enabled
  1625.         MOV     DX, COM2.Comm_CR_BUFFR_Segment
  1626.         MOV     ES, DX
  1627.         MOV     DI, COM2.Comm_CR_BUFFR_Offset
  1628.         MOV     DX, COM2.Comm_CR_BUFFR_Index
  1629.         ADD     DI, DX
  1630.         STOSB                                 ; Store Char in receive buffer
  1631. ; Increment Index into receive buffer
  1632.         ADD     WORD PTR COM2.Comm_Receive_Count, 1
  1633.         ADC     WORD PTR COM2.Comm_Receive_Count + 2, 0 
  1634.         INC     DX
  1635.         CMP     DX, BUFFER_SIZE
  1636.         JNZ     _ireq3_cont
  1637.  
  1638. ;       Optionally, add another buffer
  1639.  
  1640.         PUSH    CX              ; REV 1.2 ECL0006
  1641.         CALL    BUFFR_Gmem      ; Get next available buffer
  1642.         POP     CX              ; REV 1.2 ECL0006
  1643.         JC      _ireq3_nobuff   ; None available
  1644.                                 ; Increment next buffer information
  1645.         INC     COM2.Comm_Buffer_Count
  1646.         MOV     DI, COM2.Comm_CR_BUFFR_Offset
  1647.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  1648.         MOV     ES:[DI+2], DX
  1649.         MOV     COM2.Comm_CR_BUFFR_Offset, BX
  1650.         MOV     COM2.Comm_CR_BUFFR_Segment, DX
  1651.         MOV     DX, 4           ; New index
  1652.  
  1653. _ireq3_cont:
  1654. ;    Store Updated Receive Buffer Index in COMMS structure
  1655.         MOV     COM2.Comm_CR_BUFFR_Index, DX 
  1656.  
  1657.     TEST    COM2.Comm_Xflags,FC_REC_ON    ;Is flow control enabled
  1658.     JNE    ck3_hi
  1659.         JMP     _ireq3_tryall
  1660. ck3_hi:                    ; check high flow control mark
  1661.         TEST    COM2.Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  1662.     JE    ck3_hi_2
  1663.         JMP     _ireq3_tryall
  1664. ck3_hi_2:
  1665. ;****    don't check high word, XON/XOFF only supported < 64K
  1666. ;****    CMP    WORD PTR COM2.Comm_Receive_Count+2, 0
  1667. ;****    JNE    over3_high
  1668.     MOV    AX, COM2.Comm_high
  1669.     CMP    WORD PTR COM2.Comm_Receive_Count, AX
  1670.     JGE    over3_high
  1671.         JMP     _ireq3_tryall
  1672. over3_high:
  1673.                 ; have to send XOFF
  1674.     MOV    DX, C2+LSR    ; get line status
  1675.      IN    AL, DX
  1676. ; Any error is revealed via LSR bits 1-4 when it's 
  1677. ; associated character is at the top of the FIFO
  1678.     TEST    AL, 01h        ; has a char come in
  1679.     JE    over3_cont
  1680.     JMP    _ireq3_noFIFO_dataready    ; if so, go get it
  1681. over3_cont:
  1682.     TEST    AL, 40h        ; look at TX ready bits
  1683.     JE    over3_high    ; wait for TX OK
  1684.     SUB    DX, LSR
  1685.     MOV    AL, XOFF
  1686.     OUT    DX, AL        ; Xmit XOFF
  1687.     OR    COM2.Comm_Xflags, FC_XOFF_SENT
  1688.  
  1689.         JMP     _ireq3_tryall
  1690.  
  1691.  
  1692. ; No more Receive Buffer space available; Next Character received will
  1693. ; overwrite the last character received.
  1694. _ireq3_nobuff:                  ; None available
  1695.         SUB     WORD PTR COM2.Comm_Receive_Count, 1
  1696.         SBB     WORD PTR COM2.Comm_Receive_Count + 2, 0
  1697.     JMP     _ireq3_tryall
  1698.  
  1699. ;*************************************************************************
  1700. ;    The following code is executed if the Uart has it's FIFOS enabled.
  1701. ;*************************************************************************
  1702. ;    If the Receive FIFOs are enabled, then the code will loop until
  1703. ;    the Receive FIFO is empty. Bit 0 of the Line Status Register is
  1704. ;    set to one whenever at least 1 character is in the Recieve Buffer
  1705. ;    Register. This bit (LSR bit0) is set to zero by reading all data 
  1706. ;    in the receive buffer or FIFO.
  1707.  
  1708. _ireq3_FIFO_dataready:
  1709. ;    Read received character
  1710.         MOV     DX, C2+TX_RD_BUFF_DLLO
  1711.         IN      AL, DX                      ; Read character received
  1712.  
  1713. IFDEF   INT_EXITS
  1714.         TEST_EXIT_REC   cs:com2_mask, cs:com2_func, _ireq3_tryall, 1
  1715. ENDIF
  1716.  
  1717. ;    Check if Xmit Flow Control has been enabled
  1718.     TEST    COM2.Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  1719.     JE    no_fc3rFIFO
  1720.         CMP     AL, XOFF            ; Compare incomming char to XOFF
  1721.         JNE     _ireq3fc_FIFOrskip1
  1722.         OR      COM2.Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  1723.  
  1724. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1725.     jmp    _ireq3_check_data_ready
  1726.  
  1727. _ireq3fc_FIFOrskip1:
  1728.         CMP     AL, XON
  1729.         JNE     _ireq3fc_FIFOrskip2
  1730.         AND     COM2.Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  1731. IFDEF WQ
  1732.     OR    COM2.Comm_Xflags, FC_FIRST_XON      ; Got 1st XON - WQ
  1733. ENDIF
  1734.         SI_continue           ; Xmit next char in Xmit buffer if there is a char to Xmit
  1735.  
  1736. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1737.     jmp    _ireq3_check_data_ready
  1738.  
  1739. _ireq3fc_FIFOrskip2:
  1740.  
  1741. no_fc3rFIFO:                                      ; No Flow Control Enabled
  1742. ;    Get ECL Receive buffer location
  1743.         MOV     DX, COM2.Comm_CR_BUFFR_Segment
  1744.         MOV     ES, DX
  1745.         MOV     DI, COM2.Comm_CR_BUFFR_Offset
  1746.         MOV     DX, COM2.Comm_CR_BUFFR_Index
  1747.         ADD     DI, DX
  1748.         STOSB                                 ; Store Char in receive buffer
  1749. ; Increment Index into receive buffer
  1750.         ADD     WORD PTR COM2.Comm_Receive_Count, 1
  1751.         ADC     WORD PTR COM2.Comm_Receive_Count + 2, 0 
  1752.         INC     DX
  1753.         CMP     DX, BUFFER_SIZE
  1754.         JNZ     _ireq3_contFIFO
  1755.  
  1756. ;       Optionally, add another buffer
  1757.  
  1758.         PUSH    CX              ; REV 1.2 ECL0006
  1759.         CALL    BUFFR_Gmem      ; Get next available buffer
  1760.         POP     CX              ; REV 1.2 ECL0006
  1761.         JC      _ireq3_FIFOrjor6 ; No Buffers available
  1762.     jmp    _ireq3_FIFOrjor7 ; Buffers available
  1763. _ireq3_FIFOrjor6:
  1764.     jmp    _ireq3_FIFOnobuff   ; No Buffers available
  1765. _ireq3_FIFOrjor7:
  1766.                                 ; Increment next buffer information
  1767.         INC     COM2.Comm_Buffer_Count
  1768.         MOV     DI, COM2.Comm_CR_BUFFR_Offset
  1769.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  1770.         MOV     ES:[DI+2], DX
  1771.         MOV     COM2.Comm_CR_BUFFR_Offset, BX
  1772.         MOV     COM2.Comm_CR_BUFFR_Segment, DX
  1773.         MOV     DX, 4           ; New index
  1774.  
  1775. _ireq3_contFIFO:
  1776. ;    Store Updated Receive Buffer Index in COMMS structure
  1777.         MOV     COM2.Comm_CR_BUFFR_Index, DX 
  1778.  
  1779.     TEST    COM2.Comm_Xflags,FC_REC_ON    ;Is Receive flow control enabled
  1780.     JNE    ck3_hi_FIFO
  1781.  
  1782. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1783.     jmp    _ireq3_check_data_ready
  1784.  
  1785. ck3_hi_FIFO:                    ; check high flow control mark
  1786.         TEST    COM2.Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  1787.     JE    ck3_hi_2_FIFO
  1788.  
  1789. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1790.     jmp    _ireq3_check_data_ready
  1791.  
  1792. ck3_hi_2_FIFO:
  1793. ;****    don't check high word, XON/XOFF only supported < 64K
  1794. ;****    CMP    WORD PTR COM2.Comm_Receive_Count+2, 0
  1795. ;****    JNE    over3_high
  1796.     MOV    AX, COM2.Comm_high
  1797.     CMP    WORD PTR COM2.Comm_Receive_Count, AX
  1798.     JGE    over3_high_FIFO
  1799.  
  1800. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1801.     jmp    _ireq3_check_data_ready
  1802.  
  1803. over3_high_FIFO:
  1804.                 ; have to send XOFF
  1805.     MOV    DX, C2+LSR    ; get line status
  1806.      IN    AL, DX
  1807. ;    Any error is revealed via LSR bits 1-4 when it's associated 
  1808. ;    character is at the top of the FIFO
  1809.     TEST    AL, 01h        ; has a char come in
  1810.     JE    over3_cont_FIFO
  1811.     JMP    _ireq3_FIFO_dataready    ; if so, go get it
  1812.  
  1813. over3_cont_FIFO:
  1814.     TEST    AL, 40h        ; look at TX ready bits
  1815.     JE    over3_high_FIFO    ; wait for TX OK
  1816.     SUB    DX, LSR
  1817.     MOV    AL, XOFF
  1818.     OUT    DX, AL        ; Xmit XOFF
  1819.     OR    COM2.Comm_Xflags, FC_XOFF_SENT
  1820.  
  1821. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1822.     jmp    _ireq3_check_data_ready
  1823.  
  1824. ; No more Receive Buffer space available; Next Character received will
  1825. ; overwrite the last character received.
  1826. _ireq3_FIFOnobuff:                  ; None available
  1827.         SUB     WORD PTR COM2.Comm_Receive_Count, 1
  1828.         SBB     WORD PTR COM2.Comm_Receive_Count + 2, 0
  1829.  
  1830. ;    Check if receive FIFO is empty by checking bit0 of LSR
  1831. _ireq3_check_data_ready:
  1832.     mov    dx, C2+LSR            ; Load Line Status reg address
  1833.     in    al, dx                ; Get LSR
  1834.     test    al, 01h                ; Test for Receive FIFO empty
  1835.     jnz    _ireq3_FIFO_rjor1        ; Get next character in Receive FIFO
  1836.     JMP     _ireq3_tryall
  1837. _ireq3_FIFO_rjor1:                ; Relative Jump Out Of Range
  1838.     jmp    _ireq3_FIFO_dataready        ; Get next character in Receive FIFO
  1839. ;*********************************************************************
  1840.  
  1841. IREQ3   ENDP
  1842.  
  1843. ;*********************************************************************
  1844. ;
  1845. ;                Shared Interrupt Service Routine
  1846. ;
  1847. ;   IREQSHARE   1  First determine which UART interrupted:
  1848. ;                   COM1, COM2, COM3, ... COM8
  1849. ;               2  Then branch off if FLOW CONTROL enabled for that interrupt
  1850. ;
  1851.  
  1852. IREQSHARE   PROC    FAR             ; Shared code IREQ for COM2, COM3, and COM4
  1853.         PUSH    DS              ; Save segments
  1854.         PUSH    ES              ; Removed the LINE BREAK code!
  1855.         PUSH    CS
  1856.         POP     DS
  1857.         PUSH    DI
  1858.         PUSH    SI
  1859.         PUSH    DX
  1860.         PUSH    CX
  1861.         PUSH    BX
  1862.         PUSH    AX
  1863. ;       ---------------------------------------------------------------
  1864. ;       ---------------------------------------------------------------
  1865. ;       Determine what port interrupted
  1866.  
  1867. share_startover:
  1868.     CMP    board_type, DIGI8
  1869.     JE    digicom8_ports        ; jmp to DigiBoard PC/4 and PC/8 code
  1870.     CMP    board_type, DIGIPC16
  1871.     JE    digipc16_ports        ; jmp to DigiBoard PC/16 code
  1872.     CMP    board_type, DIGIMC
  1873.     JE    digicomMC_ports
  1874.     CMP    board_type, STAR8
  1875. ;    JE    star8_ports        ; rel jmp out of range
  1876.     JNE    s1
  1877.     JMP    star8_ports
  1878. s1:
  1879.     CMP    board_type, PS2
  1880. ;    JE    ps2_ports        ; rel jmp out of range
  1881.     JNE    comm_int3
  1882.     JMP    ps2_ports
  1883. comm_int3:
  1884.     CMP    board_type, AST
  1885. ;    JE    ast_ports        ; rel jmp out of range
  1886.     JNE    s2
  1887.     JMP    ast_ports
  1888. s2:
  1889.     CMP    board_type, ASTCMP
  1890. ;    JE    astcmp_ports        ; rel jmp out of range
  1891.     JNE    comm_int1
  1892.     JMP    astcmp_ports
  1893. comm_int1:                  ; should never reach here
  1894.  
  1895.  
  1896. digicomMC_ports:
  1897. ;*** following code works for DIGIBORD Microchannel MC/X Boards ***
  1898.         MOV     DX, Status_port
  1899.         IN      AX, DX        ; Read 16 bit status port
  1900.         CMP     AX, 0         ; Check if any ports are active
  1901.     JNZ    digimc_cont
  1902.     JMP      _share_exit   ; Nope - false alarm  (rel jump out of range)
  1903. digimc_cont:
  1904.     MOV    BX, starting_port
  1905.     MOV    DX, 1       
  1906.  
  1907. share_which_portmc:      ; loop until we find an active port
  1908.     test    AX, DX
  1909. ;        JNZ    share_int_here   ; rel jmp out of range
  1910.     JZ    s3    
  1911.        JMP    share_int_here  ; found active port w/ BX point to comm unit
  1912. s3:
  1913.     SHL    DX, 1
  1914.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  1915.     JMP    share_which_portmc
  1916.  
  1917. digipc16_ports:      
  1918. ;*** following code works for DIGIBORD PC/16
  1919.     MOV     DX, Status_port ;
  1920.     IN      AL, DX        ; Read status port first set of 8 ports
  1921.         CMP     AL, -1        ; FFh in status port = no interrupt pending
  1922.     JNZ    digi_cont     ; board # indicates either ports 1-8 or 9-16
  1923.     INC     DX            ; status port address for next set of 8 ports
  1924.     IN      AL, DX        ; Read status port for next set of 8 ports
  1925.         CMP     AL, -1        ; FFh in status port = no interrupt pending
  1926.     JNZ    digi_cont     ; board # indicates either ports 1-8 or 9-16
  1927.     JMP      _share_exit   ; Nope - false alarm  (rel jump out of range)
  1928.  
  1929. digicom8_ports:
  1930. ;*** following code works for DIGIBORD PC/4 & PC/8
  1931.     MOV     DX, Status_port       ; get status port address
  1932. ; Determine if the digiboard is generating an even or odd IRQ
  1933.     MOV    AL, SHARED_VECTOR
  1934.     AND     AX,1      ; check if bit zero is set (for odd IRQ)
  1935. ; if even IRQ, add 1 to status port address
  1936.     JNZ    digi_odd_irq   ; odd IRQ, don't increment status port adress
  1937.     INC     DX        ; even IRQ, increment status port adress
  1938. digi_odd_irq:
  1939.     IN      AL, DX        ; Read status port
  1940.         CMP     AL, -1        ; FFh in status port = no interrupt pending
  1941.     JNZ    digi_cont
  1942.     JMP      _share_exit   ; Nope - false alarm  (rel jump out of range)
  1943. digi_cont:
  1944.     PUSH    AX        ; save which board bits
  1945.     AND     AX, 07h        ; ***  will only work for 8 ports so far ***
  1946.         SHL     AX, 01
  1947.         MOV     BX, AX                  ; Make BX point to comm unit * 2
  1948.     ADD    BX, starting_port    ; have to consider starting at COM3
  1949.     POP    AX
  1950.     AND    AX, 18H            ; mask board number bits
  1951. ;    JZ    share_int_here        ; board zero - rel jmp out of range
  1952.     JNZ    comm_int7
  1953.     JMP    share_int_here
  1954. comm_int7:
  1955.     SHR    AX, 1             ; isolate board bits
  1956.     SHR    AX, 1
  1957.     SHR    AX, 1
  1958.     CMP    AX, 1
  1959.     JE    board2            ; if second board
  1960.     CMP    AX, 2
  1961.     JE    board3            ; if third board
  1962.     ADD    BX, 48            ; must be fourth board
  1963.     JMP    share_int_here
  1964. board3:    
  1965.     ADD    BX, 32
  1966.     JMP    share_int_here
  1967. board2:    
  1968.     ADD    BX, 16
  1969.     JMP    share_int_here
  1970.  
  1971.  
  1972. ps2_ports:
  1973. ;       Determine what port interrupted
  1974.         MOV     CX, maxshare
  1975.         MOV     BX, starting_port               ; Start at COM2
  1976. id_loop1:
  1977.         MOV     SI, Port_Table[BX]      ; Point to Comms_Str entry
  1978.  
  1979.     SI_REG    IIR
  1980.     and    al, 0Fh     ; Isolate bits 0-3 of IIR
  1981.         CMP    AL, 01H        ; Any more interrupts pending?
  1982.         JE    _share_advance
  1983.     JMP    _share_ckrec    ; Jump if we have int here
  1984.  
  1985. ;       Advance to next communications port
  1986.  
  1987. _share_advance:
  1988.         ADD     BX, 2                   ; Point to next entry
  1989.         LOOP    id_loop1                 ; Go back for to try the next COMx
  1990.         JMP     _share_exit
  1991. ;       ---------------------------------------------------------------
  1992.  
  1993.  
  1994. star8_ports:
  1995. ;****  following code works for STARGATE PLUS8
  1996.     MOV     DX, Status_port
  1997.         IN      AL, DX                  ; Read status port
  1998. ;***    AND    AL, 0FFh
  1999.     CMP     AL, 0h        ; Zero if no ints pending
  2000.     JNE    _share_cont8    ; Relative jump out of range
  2001.     JMP    _share_exit     ; Nope - false alarm
  2002. _share_cont8:
  2003.     MOV    BX, starting_port
  2004.     MOV    AH, 1
  2005. share_which_port8:
  2006.     test    AL, AH
  2007.         JNZ    share_int_here
  2008.     SHL    AH, 1
  2009.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  2010.     JMP    share_which_port8
  2011.  
  2012. ast_ports:
  2013. ;****  following code works for AST 4port DOS and DFI MU440 in "Expanded Mode"
  2014.     MOV     DX, Status_port
  2015.         IN      AL, DX                  ; Read status port
  2016.     AND    AL, 0Fh
  2017.     CMP     AL, 0Fh
  2018.     JNE    _share_cont4    ; Relative jump out of range
  2019.     JMP    _share_exit     ; Nope - false alarm
  2020. _share_cont4:
  2021.         AND     AX, 0Fh
  2022.     MOV    BX, starting_port
  2023.     MOV    AH, 1
  2024. share_which_port:
  2025.     test    AL, AH
  2026.         JZ    share_int_here
  2027.     SHL    AH, 1
  2028.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  2029.     JMP    share_which_port
  2030.  
  2031. astcmp_ports:
  2032. ;****  following code works for AST 4port DOS and DFI MU440 in "Compatible Mode"
  2033.     MOV     DX, Status_port
  2034.         IN      AL, DX                  ; Read status port
  2035. ; look at bits 2 (1st shared port) and 3 (2ond shared port) of status register.
  2036. ; If one of these bit is zero, then that is the port generating the interrupt.
  2037.     AND    AL, 0Ch       
  2038.     CMP     AL, 0Ch       ; when bits set to 1 - no interrupt.
  2039.     JNE    _share_astcmp4    ; Relative jump out of range
  2040.     JMP    _share_exit     ; Nope - false alarm
  2041. _share_astcmp4:
  2042.         AND     AX, 0Ch
  2043.     MOV    BX, starting_port
  2044.     MOV    AH, 4   ; start with bit 3 of status register
  2045. share_astcmp_port:
  2046.     test    AL, AH
  2047.         JZ    share_int_here
  2048.     SHL    AH, 1
  2049.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  2050.     JMP    share_astcmp_port
  2051.  
  2052.  
  2053. share_int_here:
  2054. ;       ---------------------------------------------------------------
  2055. ;       Check for receive interrupt
  2056.  
  2057.         MOV     SI, Port_Table[BX]      ; Point to Comms_Str entry
  2058.  
  2059.     SI_REG    IIR
  2060.     and    al, 0Fh     ; Isolate bits 0-3 of IIR
  2061.         CMP    AL, 01H        ; Any more interrupts pending?
  2062.     JNE    _share_ckrec    ; JE out of range
  2063.         JMP    share_startover       ; No - false alarm somehow
  2064.  
  2065. ; AL contains bits 0-3 of IIR. Check if IIR bit 2 (04h)is set (Receive 
  2066. ; Data Available) or if both IIR bits 2 and 3 (0Ch) are set 
  2067. ; (Character Timeout Indication - Receive Data Available).
  2068. _share_ckrec:
  2069. ;    test    al, 0CH        ; Got a character to read?
  2070.     cmp    al, 04H        ; Got a character to read?
  2071.     jnz    _share_charto    ; No
  2072.     jmp     _share_dataready          ; Yes - go process it
  2073. _share_charto:
  2074.     cmp    al, 0CH        ; Got a character to read?
  2075.     jnz    _share_ckxmt    ; No
  2076.     jmp     _share_dataready          ; Yes - go process it
  2077.  
  2078. _share_ckxmt:                     ; AL contains bits 0-3 of IIR.
  2079.     CMP    AL, 02H        ; Ready to xmit a character?
  2080. ;    JNE    _share_ckmsr    ; No ; Rel Jump Out of range
  2081.     je    _share_xmt_enter
  2082.     jmp    _share_ckmsr    ; No
  2083.  
  2084.  
  2085. ;     Transmit interrupt generated!!!!!!!!
  2086. _share_xmt_enter:        ; Xmit chars if there are any to Xmit
  2087.  
  2088. IFDEF INT_EXITS
  2089.         push    bx
  2090.         shr     bx, 1
  2091.         TEST_EXIT_SEND   cs:share1_mask, cs:share1_func, bx
  2092.         pop     bx
  2093. ENDIF
  2094.  
  2095.     TEST    [SI].Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  2096.     JE    share_no_fc3
  2097.     TEST    [SI].Comm_Xflags,FC_XOFF_RCVD    ;Was XOFF received
  2098.     JE    share_no_fc3    ; Relative jump out of range
  2099.     JMP    share_startover            ;If so we cannot xmit
  2100. share_no_fc3:
  2101.     CMP    [SI].Comm_DTR_RTS, 0    ;2.0a see if handshaking disabled
  2102.     JE    _share_ckxmt3
  2103.     SI_REG    MSR        ; Yes - read MSR to clear interrupt.
  2104.  
  2105. ;    look for Hardware Handshaking flag
  2106.     and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  2107.     cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  2108. ;    AND    AL, 00110000B    ; look for CTS and DSR
  2109. ;    CMP    AL, 00110000B    ;
  2110.     JE    _share_ckxmt3    ; rel jump out of range
  2111.         JMP    share_startover    ; try again if no CTS/DSR
  2112.  
  2113. ;    Xmit Interrupt Received, all clear to stuff Xmit buffer.
  2114. ;    When the Xmit FIFO is enabled (FCR0=1), Xmit interrupts will occur
  2115. ;    as follows: The transmitter holding register interrupt (02) occurs
  2116. ;    when the Xmit FIFO is empty. It is cleared as soon as the transmitter 
  2117. ;    holding register is written to (1 to 16 characters may be written to
  2118. ;    the Xmit FIFO while servicing this interrupt) or the IIR is read.
  2119. _share_ckxmt3:
  2120. ;    Check if our UART mode indicates FIFOs are enabled
  2121. ;    Allowable values for "COMM_UART_Mode" are:
  2122. ;    0 = 16440 (16550 Character) mode
  2123. ;    1 = 16550 FIFOs enabled, DMA mode 0
  2124. ;    9 = 16550 FIFOs enabled, DMA mode 1 (This mode is not used)
  2125.  
  2126.     test    [si].COMM_UART_Mode, 09h 
  2127.     jz    _share_x1char    ; FIFOs not present or not enabled
  2128.  
  2129.     SI_FIFO_continue        ; Stuff up to 16 chars in Xmit FIFO
  2130.         jmp    share_startover    ; Now go see if anything else is pending
  2131.  
  2132. _share_x1char:            ; Xmit 1 character
  2133.         SI_continue             ; Xmit next char in Xmit buffer
  2134.         jmp    share_startover    ; Now go see if anything else is pending
  2135.  
  2136. ;     No chars received, no chars to Xmit
  2137. _share_ckmsr:
  2138.     CMP    AL, 00H        ; Change in modem status?
  2139.     JNE    _share_ckerr    ; No - check  for error or break
  2140. _share_ckmsr2:                     ;
  2141.     SI_REG    MSR        ; Yes- read in MSR to clear interrupt
  2142.  
  2143. IFDEF INT_EXITS
  2144.         push    bx
  2145.         shr     bx, 1
  2146.         TEST_EXIT_MSR   cs:share1_mask, cs:share1_func, bx
  2147.         pop     bx
  2148. ENDIF
  2149.         CMP     [SI].Comm_DTR_RTS, 0    ; See if handshaking enabled
  2150.     JNE    _share_cont1    ; relative jump was out of range
  2151.     JMP    share_startover    ; Now go see if anything else is pending
  2152. _share_cont1:
  2153.     SI_REG    LSR
  2154. ; Check Xmit Holding Reg (LSR bit 6) and Xmit Empty (LSR bit 7) bits
  2155.     AND    AL, 60h        ; See if ready to transmit
  2156.     CMP    AL, 60h
  2157. ;    JE    _share_xmt_enter; go to start of Xmit char processing
  2158. ;       JMP    share_startover    ; Now go see if anything else is pending
  2159.     jne    _share_1rjor
  2160.     jmp    _share_xmt_enter ; go to start of Xmit char processing
  2161. _share_1rjor:
  2162.         jmp    share_startover    ; Now go see if anything else is pending
  2163.  
  2164. _share_ckerr:            ; 
  2165.         CMP    AL, 06H        ; Got a rec'd char w/error or break?
  2166.     JE    _share_cont2    ; Relative jump out of range
  2167.         JMP    share_startover    ; No
  2168. _share_cont2:
  2169.     SI_REG    LSR        ; Yes- read in LSR to clear interrupt
  2170.  
  2171. IFDEF INT_EXITS
  2172.         push    bx
  2173.         shr     bx, 1
  2174.         TEST_EXIT_ERR   cs:share1_mask, cs:share1_func, bx
  2175.         pop     bx
  2176. ENDIF
  2177.         mov     BYTE PTR [si].Comm_Break, al
  2178.         JMP    share_startover    ; Now go see if anything else is pending
  2179.  
  2180.  
  2181. _share_exit:
  2182.         MOV     AL, 20h         ; Acknowledge interrupt
  2183.         OUT     EOI, AL
  2184.         POP     AX              ; Restore registers
  2185.         POP     BX
  2186.     POP    CX
  2187.     POP     DX
  2188.         POP     SI
  2189.         POP     DI
  2190.         POP     ES
  2191.         POP     DS
  2192.         IRET
  2193.  
  2194. ;       Read and Store  character
  2195. ; Data has been received (IIR is 04h or 0Ch); AL contains bits 0-3 of IIR
  2196. _share_dataready:
  2197. ;    Check if 16550 is present and if FIFOs are enabled
  2198.     test    [si].COMM_UART_Mode, 09h 
  2199.     jz    _share_noFIFO_dataready    ; FIFOs not present or not enabled
  2200.     jmp    _share_FIFO_dataready    ; FIFOs are present and enabled
  2201.     
  2202. _share_noFIFO_dataready:
  2203. ;    Read received character
  2204.     SI_REG    TX_RD_BUFF_DLLO             ; Read character received
  2205.  
  2206. IFDEF INT_EXITS
  2207.         push    bx
  2208.         shr     bx, 1
  2209.         TEST_EXIT_REC   cs:share1_mask, cs:share1_func,clrbx1 ,bx
  2210.         pop     bx
  2211.         jmp     short   ok10
  2212. clrbx1:
  2213.         pop     bx
  2214.         jmp     share_startover
  2215. ok10:
  2216. ENDIF
  2217.  
  2218.  
  2219. ;    Check if Xmit Flow Control has been enabled
  2220.     TEST    [SI].Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  2221.     JE    share_no_fc3r
  2222.         CMP     AL, XOFF
  2223.         JNE     _sharefc_rskip1
  2224.         OR      [SI].Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  2225.         JMP     share_txbug
  2226. _sharefc_rskip1:
  2227.         CMP     AL, XON
  2228.         JNE     _sharefc_rskip2
  2229.         AND     [SI].Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  2230.         SI_continue          ; Xmit next char in Xmit buffer if there is a char to Xmit
  2231.         JMP     share_txbug
  2232. _sharefc_rskip2:
  2233.  
  2234. share_no_fc3r:                                ; No Flow Control Enabled
  2235. ;    Get ECL Receive buffer location
  2236.         MOV     DX, [SI].Comm_CR_BUFFR_Segment
  2237.         MOV     ES, DX
  2238.         MOV     DI, [SI].Comm_CR_BUFFR_Offset
  2239.         MOV     DX, [SI].Comm_CR_BUFFR_Index
  2240.         ADD     DI, DX
  2241.         STOSB                                 ; Store Char in receive buffer
  2242. ; Increment Index into receive buffer
  2243.         ADD     WORD PTR [SI].Comm_Receive_Count, 1
  2244.         ADC     WORD PTR [SI].Comm_Receive_Count + 2, 0
  2245.         INC     DX
  2246.         CMP     DX, BUFFER_SIZE
  2247.         JNZ     _share_cont
  2248.  
  2249. ;       Optionally, add another buffer
  2250.  
  2251.         PUSH    CX              ; REV 1.2 ECL0006
  2252.         CALL    BUFFR_Gmem      ; Get next available buffer
  2253.         POP     CX              ; REV 1.2 ECL0006
  2254.         JC      _share_nobuff   ; None available
  2255.                                 ; Increment next buffer information
  2256.         INC     [SI].Comm_Buffer_Count
  2257.         MOV     DI, [SI].Comm_CR_BUFFR_Offset
  2258.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  2259.         MOV     ES:[DI+2], DX
  2260.         MOV     [SI].Comm_CR_BUFFR_Offset, BX
  2261.         MOV     [SI].Comm_CR_BUFFR_Segment, DX
  2262.         MOV     DX, 4           ; New index
  2263.  
  2264. _share_cont:
  2265. ;    Store Updated Receive Buffer Index in COMMS structure
  2266.         MOV     [SI].Comm_CR_BUFFR_Index, DX
  2267.  
  2268.     TEST    [SI].Comm_Xflags,FC_REC_ON    ;Is flow control enabled
  2269.     JNE    share_ck3_hi
  2270.         JMP     share_txbug
  2271. share_ck3_hi:                    ; check high flow control mark
  2272.         TEST    [SI].Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  2273.     JE    share_ck3_hi_2
  2274.         JMP     share_txbug
  2275. share_ck3_hi_2:
  2276. ;****    don't check high word, XON/XOFF only supported < 64K
  2277. ;****    CMP    WORD PTR [SI].Comm_Receive_Count+2, 0
  2278. ;****    JNE    over3_high
  2279.     MOV    AX, [SI].Comm_high
  2280.     CMP    WORD PTR [SI].Comm_Receive_Count, AX
  2281.     JGE    share_over3_high
  2282.         JMP     share_txbug
  2283. share_over3_high:
  2284.                 ; have to send XOFF
  2285.     SI_REG    LSR        ; get line status
  2286. ; Any error is revealed via LSR bits 1-4 when it's associated 
  2287. ; character is at the top of the FIFO
  2288.     TEST    AL, 01h        ; has a char come in
  2289.     JE    share_over3_cont
  2290.     jmp    _share_noFIFO_dataready    ; if so, go get it
  2291. share_over3_cont:
  2292.     TEST    AL, 40h        ; look at TX ready bits
  2293.     JE    share_over3_high    ; wait for TX OK
  2294.     SUB    DX, LSR
  2295.     MOV    AL, XOFF
  2296.     OUT    DX, AL        ; Xmit XOFF
  2297.     OR    [SI].Comm_Xflags, FC_XOFF_SENT
  2298.  
  2299.         JMP     share_txbug
  2300.  
  2301.  
  2302. ; No more Receive Buffer space available; Next Character received will
  2303. ; overwrite the last character received.
  2304. _share_nobuff:                  ; None available
  2305.         SUB     WORD PTR [SI].Comm_Receive_Count, 1
  2306.         SBB     WORD PTR [SI].Comm_Receive_Count + 2, 0
  2307.     JMP     share_txbug
  2308.  
  2309.  
  2310.  
  2311. ;*************************************************************************
  2312. ;    The following code is executed if the Uart has it's FIFOS enabled.
  2313. ;*************************************************************************
  2314. ;    If the Receive FIFOs are enabled, then the code will loop until
  2315. ;    the Receive FIFO is empty. Bit 0 of the Line Status Register is
  2316. ;    set to one whenever at least 1 character is in the Recieve Buffer
  2317. ;    Register. This bit (LSR bit0) is set to zero by reading all data 
  2318. ;    in the receive buffer or FIFO.
  2319.  
  2320. _share_FIFO_dataready:
  2321. ;    Read received character
  2322.     SI_REG    TX_RD_BUFF_DLLO             ; Read character received
  2323.  
  2324. IFDEF INT_EXITS
  2325.         push    bx
  2326.         shr     bx, 1
  2327.         TEST_EXIT_REC   cs:share1_mask, cs:share1_func,clrbx2,bx
  2328.         pop     bx
  2329.         jmp     short   ok11
  2330. clrbx2:
  2331.         pop     bx
  2332.         jmp     _share_check_data_ready
  2333. ok11:
  2334. ENDIF
  2335.  
  2336.  
  2337. ;    Check if Xmit Flow Control has been enabled
  2338.     TEST    [si].Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  2339.     JE    share_no_fc3rFIFO
  2340.         CMP     AL, XOFF            ; Compare incomming char to XOFF
  2341.         JNE     _sharefc_FIFOrskip1
  2342.         OR      [si].Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  2343.  
  2344. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2345.     jmp    _share_check_data_ready
  2346.  
  2347. _sharefc_FIFOrskip1:
  2348.         CMP     AL, XON
  2349.         JNE     _sharefc_FIFOrskip2
  2350.         AND     [si].Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  2351. IFDEF WQ
  2352.     OR    [si].Comm_Xflags, FC_FIRST_XON      ; Got 1st XON - WQ
  2353. ENDIF
  2354.         SI_continue           ; Xmit next char in Xmit buffer if there is a char to Xmit
  2355.  
  2356. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2357.     jmp    _share_check_data_ready
  2358.  
  2359. _sharefc_FIFOrskip2:
  2360.  
  2361. share_no_fc3rFIFO:                                ; No Flow Control Enabled
  2362. ;    Get ECL Receive buffer location
  2363.         MOV     DX, [si].Comm_CR_BUFFR_Segment
  2364.         MOV     ES, DX
  2365.         MOV     DI, [si].Comm_CR_BUFFR_Offset
  2366.         MOV     DX, [si].Comm_CR_BUFFR_Index
  2367.         ADD     DI, DX
  2368.         STOSB                                 ; Store Char in receive buffer
  2369. ; Increment Index into receive buffer
  2370.         ADD     WORD PTR [si].Comm_Receive_Count, 1
  2371.         ADC     WORD PTR [si].Comm_Receive_Count + 2, 0 
  2372.         INC     DX
  2373.         CMP     DX, BUFFER_SIZE
  2374.         JNZ     _share_contFIFO
  2375.  
  2376. ;       Optionally, add another buffer
  2377.  
  2378.         PUSH    CX              ; REV 1.2 ECL0006
  2379.         CALL    BUFFR_Gmem      ; Get next available buffer
  2380.         POP     CX              ; REV 1.2 ECL0006
  2381.         JC      _share_FIFOrjor6 ; No Buffers available
  2382.     jmp    _share_FIFOrjor7 ; Buffers available
  2383. _share_FIFOrjor6:
  2384.     jmp    _share_FIFOnobuff   ; No Buffers available
  2385. _share_FIFOrjor7:
  2386.                                 ; Increment next buffer information
  2387.         INC     [si].Comm_Buffer_Count
  2388.         MOV     DI, [si].Comm_CR_BUFFR_Offset
  2389.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  2390.         MOV     ES:[DI+2], DX
  2391.         MOV     [si].Comm_CR_BUFFR_Offset, BX
  2392.         MOV     [si].Comm_CR_BUFFR_Segment, DX
  2393.         MOV     DX, 4           ; New index
  2394.  
  2395. _share_contFIFO:
  2396. ;    Store Updated Receive Buffer Index in COMMS structure
  2397.         MOV     [si].Comm_CR_BUFFR_Index, DX 
  2398.  
  2399.     TEST    [si].Comm_Xflags,FC_REC_ON    ;Is Receive flow control enabled
  2400.     JNE    share_ck3_hi_FIFO
  2401.  
  2402. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2403.     jmp    _share_check_data_ready
  2404.  
  2405. share_ck3_hi_FIFO:                    ; check high flow control mark
  2406.         TEST    [si].Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  2407.     JE    share_ck3_hi_2_FIFO
  2408.  
  2409. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2410.     jmp    _share_check_data_ready
  2411.  
  2412. share_ck3_hi_2_FIFO:
  2413. ;****    don't check high word, XON/XOFF only supported < 64K
  2414. ;****    CMP    WORD PTR COM2.Comm_Receive_Count+2, 0
  2415. ;****    JNE    over3_high
  2416.     MOV    AX, [si].Comm_high
  2417.     CMP    WORD PTR [si].Comm_Receive_Count, AX
  2418.     JGE    share_over3_high_FIFO
  2419.  
  2420. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2421.     jmp    _share_check_data_ready
  2422.  
  2423. share_over3_high_FIFO:
  2424.                 ; have to send XOFF
  2425.     SI_REG    LSR        ; get line status
  2426. ;    Any error is revealed via LSR bits 1-4 when it's associated 
  2427. ;    character is at the top of the FIFO
  2428.     TEST    AL, 01h        ; has a char come in
  2429.     JE    share_over3_cont_FIFO
  2430.     JMP    _share_FIFO_dataready    ; if so, go get it
  2431.  
  2432. share_over3_cont_FIFO:
  2433.     TEST    AL, 40h        ; look at TX ready bits
  2434.     JE    share_over3_high_FIFO    ; wait for TX OK
  2435.     SUB    DX, LSR
  2436.     MOV    AL, XOFF
  2437.     OUT    DX, AL        ; Xmit XOFF
  2438.     OR    [si].Comm_Xflags, FC_XOFF_SENT
  2439.  
  2440. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2441.     jmp    _share_check_data_ready
  2442.  
  2443. ; No more Receive Buffer space available; Next Character received will
  2444. ; overwrite the last character received.
  2445. _share_FIFOnobuff:                  ; None available
  2446.         SUB     WORD PTR [si].Comm_Receive_Count, 1
  2447.         SBB     WORD PTR [si].Comm_Receive_Count + 2, 0
  2448.  
  2449. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2450. _share_check_data_ready:
  2451.     SI_REG    LSR                ; get line status register
  2452.     test    al, 01h                ; Test for Receive FIFO empty
  2453.     jnz    _share_FIFO_rjor1        ; Get next character in Receive FIFO
  2454.     JMP     share_txbug
  2455. _share_FIFO_rjor1:                ; Relative Jump Out Of Range
  2456.     jmp    _share_FIFO_dataready        ; Get next character in Receive FIFO
  2457.  
  2458. ;*********************************************************************
  2459.  
  2460.  
  2461. share_txbug:               ; code for 8250 TX bug goes here for multiports
  2462.            SI_REG LSR    ; look for THRE to get around 8250 bug
  2463.     test    al, 020H
  2464.           jnz    _share_txbug    ; have to check TX
  2465.           jmp    share_startover
  2466. ;          AND    AL, 20H        ; isolate THRE
  2467. ;          CMP    AL, 20H
  2468. ;          JE    _share_txbug    ; have to check TX
  2469. ;          JMP    share_startover
  2470. _share_txbug:
  2471.         CMP     [SI].Comm_xcount, 0
  2472.         JE      _share_txbug_exit
  2473.         JMP     _share_xmt_enter
  2474. _share_txbug_exit:
  2475.         JMP     share_startover
  2476.  
  2477. IREQSHARE   ENDP
  2478.  
  2479. ;
  2480. ;                Shared Interrupt Service Routine
  2481. ;
  2482. ;   IREQSHARE2   1  First determine which UART interrupted:
  2483. ;                   COM1, COM2, COM3, ... COM8
  2484. ;               2  Then branch off if FLOW CONTROL enabled for that interrupt
  2485. ;
  2486.  
  2487. IREQSHARE2   PROC    FAR        ; Shared code IREQ for COM2, COM3, and COM4
  2488.         PUSH    DS              ; Save segments
  2489.         PUSH    ES              ; Removed the LINE BREAK code!
  2490.         PUSH    CS
  2491.         POP     DS
  2492.         PUSH    DI
  2493.         PUSH    SI
  2494.         PUSH    DX
  2495.         PUSH    CX
  2496.         PUSH    BX
  2497.         PUSH    AX
  2498. ;       ---------------------------------------------------------------
  2499. ;       ---------------------------------------------------------------
  2500. ;       Determine what port interrupted
  2501.  
  2502. share2_startover:
  2503.     CMP    board2_type, DIGI8
  2504.     JE    digicom82_ports  
  2505.     CMP    board2_type, DIGIPC16
  2506.     JE    digipc162_ports
  2507.     CMP    board2_type, DIGIMC
  2508.     JE    digicomMC2_ports
  2509.     CMP    board2_type, STAR8
  2510. ;    JE    star82_ports            ; rel jmp out of range
  2511.     JNE    s4
  2512.     JMP    star82_ports
  2513. s4:
  2514.     CMP    board2_type, PS2
  2515. ;    JE    ps22_ports                ; rel jmp out of range
  2516.     JNE    comm_int6
  2517.     JMP    ps22_ports
  2518. comm_int6:
  2519.     JMP    ast2_ports
  2520.     CMP    board2_type, AST
  2521. ;    JE    ast2_ports            ; rel jmp out of range
  2522.     JNE    s5
  2523.     JMP    ast2_ports
  2524. s5:
  2525.     CMP    board2_type, ASTCMP
  2526. ;    JE    ast2cmp_ports            ; rel jmp out of range
  2527.     JNE    comm_int2
  2528.     JMP    ast2cmp_ports
  2529. comm_int2:                           ; should never get here
  2530.  
  2531.  
  2532.  
  2533. digicomMC2_ports:
  2534. ;*** following code works for DIGIBORD Microchannel COM/4 & COM/8
  2535.         MOV     DX, Status2_port
  2536.         IN      AX, DX                  ; Read status port
  2537.         CMP     AX, 0
  2538.     JNZ    digimc2_cont
  2539.     JMP      _share2_exit   ; Nope - false alarm  (rel jump out of range)
  2540. digimc2_cont:
  2541.     MOV    BX, starting2_port
  2542.     MOV    DX, 1
  2543.  
  2544. share_which_portmc2:
  2545.     test    AX, DX
  2546. ;        JNZ    share2_int_here            ; rel jmp out of range
  2547.      JZ    s6
  2548.     JMP    share2_int_here
  2549. s6:
  2550.     SHL    DX, 1
  2551.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  2552.     JMP    share_which_portmc2
  2553.  
  2554.  
  2555. digipc162_ports:      ; Second PC/16 , board number 1
  2556. ;*** following code works for DIGIBORD PC/16
  2557.     MOV     DX,Status2_port ;
  2558.     IN      AL, DX        ; Read status port first set of 8 ports
  2559.         CMP     AL, -1        ; FFh in status port = no interrupt pending
  2560.     JNZ    digi2_cont    ; board # indicates either ports 1-8 or 9-16
  2561.     INC     DX            ; status port address for next set of 8 ports
  2562.     IN      AL, DX        ; Read status port for next set of 8 ports
  2563.         CMP     AL, -1        ; FFh in status port = no interrupt pending
  2564.     JNZ    digi2_cont    ; board # indicates either ports 1-8 or 9-16
  2565.     JMP      _share2_exit ; Nope - false alarm  (rel jump out of range)
  2566.  
  2567. digicom82_ports:      ; Second PC/4 or PC/8 , board number 1
  2568. ;*** following code works for DIGIBORD PC/4 & PC/8
  2569.     MOV     DX, Status2_port       ; get status port address
  2570. ; Determine if the digiboard is generating an even or odd IRQ
  2571.     MOV    AL, SHARED2_VECTOR
  2572.     AND     AX,1      ; check if bit zero is set (for odd IRQ)
  2573. ; if even IRQ, add 1 to status port address
  2574.     JNZ    digi2_odd_irq   ; odd IRQ, don't increment status port adress
  2575.     INC     DX        ; even IRQ, increment status port adress
  2576. digi2_odd_irq:
  2577.     IN      AL, DX        ; Read status port
  2578.         CMP     AL, -1        ; FFh in status port = no interrupt pending
  2579.     JNZ    digi2_cont
  2580.     JMP      _share2_exit   ; Nope - false alarm  (rel jump out of range)
  2581. digi2_cont:
  2582.     PUSH    AX        ; save which board bits
  2583.         AND     AX, 07h        ; ***  will only work for 8 ports so far ***
  2584.         SHL     AX, 01
  2585.         MOV     BX, AX                  ; Make BX point to comm unit * 2
  2586.     ADD    BX, starting2_port    ; have to consider starting at COM3
  2587.     POP    AX
  2588.     AND    AX, 18H            ; mask board number bits
  2589. ;    JZ    share2_int_here        ; board zero rel jump out of range
  2590.     JNZ    comm_int4
  2591.     JMP    share2_int_here        ; board zero
  2592. comm_int4:
  2593.     SHR    AX, 1             ; isolate board bits
  2594.     SHR    AX, 1
  2595.     SHR    AX, 1
  2596.     CMP    AX, 1
  2597.     JE    board2_2        ; if second board
  2598.     CMP    AX, 2
  2599.     JE    board2_3        ; if third board
  2600.     ADD    BX, 48            ; must be fourth board
  2601.     JMP    share2_int_here
  2602. board2_3:
  2603.     ADD    BX, 32
  2604.     JMP    share2_int_here
  2605. board2_2:
  2606.     ADD    BX, 16
  2607.     JMP    share2_int_here
  2608.  
  2609.  
  2610. ps22_ports:
  2611. ;       Determine what port interrupted
  2612.         MOV     CX, maxshare2
  2613.         MOV     BX, starting2_port               ; Start at COM2
  2614. id2_loop1:
  2615.         MOV     SI, Port_Table[BX]      ; Point to Comms_Str entry
  2616.  
  2617.     SI_REG    IIR
  2618.     and    al, 0Fh     ; Isolate bits 0-3 of IIR
  2619.         CMP    AL, 01H        ; Any more interrupts pending?
  2620.         JE    _share2_advance
  2621.     JMP    _share2_ckrec    ; Jump if we have int here
  2622.  
  2623. ;       Advance to next communications port
  2624.  
  2625. _share2_advance:
  2626.         ADD     BX, 2                   ; Point to next entry
  2627.         LOOP    id2_loop1                 ; Go back for to try the next COMx
  2628.         JMP     _share2_exit
  2629. ;       ---------------------------------------------------------------
  2630.  
  2631.  
  2632.  
  2633. star82_ports:
  2634. ;****  following code works for STARGATE PLUS8
  2635.     MOV     DX, Status2_port
  2636.         IN      AL, DX                  ; Read status port
  2637. ;***    AND    AL, 0FFh
  2638.     CMP     AL, 0h        ; Zero if no ints pending
  2639.     JNE    _share2_cont8    ; Relative jump out of range
  2640.     JMP    _share2_exit     ; Nope - false alarm
  2641. _share2_cont8:
  2642.     MOV    BX, starting2_port
  2643.     MOV    AH, 1
  2644. share2_which_port8:
  2645.     test    AL, AH
  2646.         JNZ    share2_int_here
  2647.     SHL    AH, 1
  2648.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  2649.     JMP    share2_which_port8
  2650.  
  2651. ast2_ports:
  2652. ;****  following code works for AST 4port DOS and DFI MU440 in "Expanded Mode"
  2653.     MOV     DX, Status2_port
  2654.         IN      AL, DX                  ; Read status port
  2655.     AND    AL, 0Fh
  2656.     CMP     AL, 0Fh
  2657.     JNE    _share2_cont4    ; Relative jump out of range
  2658.     JMP    _share2_exit     ; Nope - false alarm
  2659. _share2_cont4:
  2660.         AND     AX, 0Fh
  2661.     MOV    BX, starting2_port
  2662.     MOV    AH, 1
  2663. share2_which_port:
  2664.     test    AL, AH
  2665.         JZ    share2_int_here
  2666.     SHL    AH, 1
  2667.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  2668.     JMP    share2_which_port
  2669.  
  2670. ast2cmp_ports:
  2671. ;****  following code works for AST 4port DOS and DFI MU440 in "Compatible Mode"
  2672.     MOV     DX, Status2_port
  2673.         IN      AL, DX                  ; Read status port
  2674. ; look at bits 2 (1st shared port) and 3 (2ond shared port) of status register.
  2675. ; If one of these bit is zero, then that is the port generating the interrupt.
  2676.     AND    AL, 0Ch    
  2677.     CMP     AL, 0Ch       ; when bits set to 1 - no interrupt.
  2678.     JNE    _share2_astcmp4    ; Relative jump out of range
  2679.     JMP    _share2_exit     ; Nope - false alarm
  2680. _share2_astcmp4:
  2681.         AND     AX, 0Ch
  2682.     MOV    BX, starting2_port
  2683.     MOV    AH, 4     ; start looking at bit 3 of status register
  2684. share2_astcmp_port:
  2685.     test    AL, AH
  2686.         JZ    share2_int_here
  2687.     SHL    AH, 1
  2688.     ADD    BX, 2                  ; Make BX point to comm unit * 2
  2689.     JMP    share2_astcmp_port
  2690.  
  2691.  
  2692.  
  2693. share2_int_here:
  2694. ;       ---------------------------------------------------------------
  2695. ;       Check for receive interrupt
  2696.  
  2697.         MOV     SI, Port_Table[BX]      ; Point to Comms_Str entry
  2698.  
  2699.     SI_REG    IIR
  2700.     and    al, 0Fh     ; Isolate bits 0-3 of IIR
  2701.         CMP    AL, 01H        ; Any more interrupts pending?
  2702.     JNE    _share2_ckrec    ; JE out of range
  2703.         JMP    share2_startover       ; No - false alarm somehow
  2704.  
  2705. ; AL contains bits 0-3 of IIR. Check if IIR bit 2 (04h)is set (Receive 
  2706. ; Data Available) or if both IIR bits 2 and 3 (0Ch) are set 
  2707. ; (Character Timeout Indication - Receive Data Available).
  2708. _share2_ckrec:
  2709. ;    test    al, 0CH        ; Got a character to read?
  2710.     cmp    al, 04H        ; Got a character to read?
  2711.     jnz    _share2_charto    ; No
  2712.     jmp     _share2_dataready          ; Yes - go process it
  2713. _share2_charto:
  2714.     cmp    al, 0CH        ; Got a character to read?
  2715.     jnz    _share2_ckxmt    ; No
  2716.     jmp     _share2_dataready          ; Yes - go process it
  2717.  
  2718. _share2_ckxmt:                     ;
  2719.     CMP    AL, 02H        ; Ready to xmit a character?
  2720. ;    JNE    _share2_ckmsr    ; No ; Rel Jump Out of range
  2721.     je    _share2_xmt_enter
  2722.     jmp    _share2_ckmsr    ; No
  2723.  
  2724.  
  2725. ;     Transmit interrupt generated!!!!!!!!
  2726. _share2_xmt_enter:        ; Xmit chars if there are any to Xmit
  2727.                                 ; Transmit interrupt generated!!!!!!!!
  2728.  
  2729. IFDEF INT_EXITS
  2730.         push    bx
  2731.         shr     bx, 1
  2732.         TEST_EXIT_SEND   cs:share2_mask, cs:share2_func, bx
  2733.         pop     bx
  2734. ENDIF
  2735.  
  2736.         TEST    [SI].Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  2737.     JE    share2_no_fc3
  2738.     TEST    [SI].Comm_Xflags,FC_XOFF_RCVD    ;Was XOFF received
  2739.     JE    share2_no_fc3    ; Relative jump out of range
  2740.     JMP    share2_startover            ;If so we cannot xmit
  2741. share2_no_fc3:
  2742.     CMP    [SI].Comm_DTR_RTS, 0    ;2.0a see if handshaking disabled
  2743.     JE    _share2_ckxmt3
  2744.     SI_REG    MSR        ; Yes - read MSR to clear interrupt.
  2745.  
  2746. ;    look for Hardware Handshaking flag
  2747.     and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  2748.     cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  2749. ;    AND    AL, 00110000B    ; look for CTS and DSR
  2750. ;    CMP    AL, 00110000B    ;
  2751.     JE    _share2_ckxmt3    ; rel jump out of range
  2752.         JMP    share2_startover    ; try again if no CTS/DSR
  2753.  
  2754. ;    Xmit Interrupt Received, all clear to stuff Xmit buffer.
  2755. ;    When the Xmit FIFO is enabled (FCR0=1), Xmit interrupts will occur
  2756. ;    as follows: The transmitter holding register interrupt (02) occurs
  2757. ;    when the Xmit FIFO is empty. It is cleared as soon as the transmitter 
  2758. ;    holding register is written to (1 to 16 characters may be written to
  2759. ;    the Xmit FIFO while servicing this interrupt) or the IIR is read.
  2760. _share2_ckxmt3:
  2761. ;    Check if our UART mode indicates FIFOs are enabled
  2762. ;    Allowable values for "COMM_UART_Mode" are:
  2763. ;    0 = 16440 (16550 Character) mode
  2764. ;    1 = 16550 FIFOs enabled, DMA mode 0
  2765. ;    9 = 16550 FIFOs enabled, DMA mode 1 (This mode is not used)
  2766.  
  2767.     test    [si].COMM_UART_Mode, 09h 
  2768.     jz    _share2_x1char    ; FIFOs not present or not enabled
  2769.  
  2770.     SI_FIFO_continue        ; Stuff up to 16 chars in Xmit FIFO
  2771.         jmp    share2_startover; Now go see if anything else is pending
  2772.  
  2773. _share2_x1char:            ; Xmit 1 character
  2774.         SI_continue             ; Xmit next char in Xmit buffer
  2775.         jmp    share2_startover; Now go see if anything else is pending
  2776.  
  2777. ;     No chars received, no chars to Xmit
  2778. _share2_ckmsr:
  2779.     CMP    AL, 00H        ; Change in modem status?
  2780.     JNE    _share2_ckerr    ; No - check  for error or break
  2781. _share2_ckmsr2:                    ;
  2782.     SI_REG    MSR        ; Yes- read in MSR to clear interrupt
  2783.  
  2784. IFDEF INT_EXITS
  2785.         push    bx
  2786.         shr     bx, 1
  2787.         TEST_EXIT_MSR   cs:share2_mask, cs:share2_func, bx
  2788.         pop     bx
  2789. ENDIF
  2790.         CMP     [SI].Comm_DTR_RTS, 0    ; See if handshaking enabled
  2791.     JNE    _share2_cont1    ; relative jump was out of range
  2792.     JMP    share2_startover; Now go see if anything else is pending
  2793. _share2_cont1:
  2794.     SI_REG    LSR
  2795. ; Check Xmit Holding Reg (LSR bit 6) and Xmit Empty (LSR bit 7) bits
  2796.     AND    AL, 60h        ; See if ready to transmit
  2797.     CMP    AL, 60h
  2798. ;    JE    _share2_xmt_enter; go to start of Xmit char processing
  2799. ;       JMP    share2_startover; Now go see if anything else is pending
  2800.     jne    _share2_1rjor
  2801.     jmp    _share2_xmt_enter ; go to start of Xmit char processing
  2802. _share2_1rjor:
  2803.         jmp    share2_startover  ; Now go see if anything else is pending
  2804.  
  2805. _share2_ckerr:            ; 
  2806.         CMP    AL, 06H        ; Got a rec'd char w/error or break?
  2807.     JE    _share2_cont2    ; Relative jump out of range
  2808.         JMP    share2_startover; No
  2809. _share2_cont2:
  2810.     SI_REG    LSR        ; Yes- read in LSR to clear interrupt
  2811.  
  2812. IFDEF INT_EXITS
  2813.         push    bx
  2814.         shr     bx, 1
  2815.         TEST_EXIT_ERR   cs:share2_mask, cs:share2_func, bx
  2816.         pop     bx
  2817. ENDIF
  2818.         mov     BYTE PTR [si].Comm_Break, al
  2819.         JMP    share2_startover; Now go see if anything else is pending
  2820.  
  2821.  
  2822. _share2_exit:
  2823.         MOV     AL, 20h         ; Acknowledge interrupt
  2824.         OUT     EOI, AL
  2825.         POP     AX              ; Restore registers
  2826.         POP     BX
  2827.     POP    CX
  2828.     POP     DX
  2829.         POP     SI
  2830.         POP     DI
  2831.         POP     ES
  2832.         POP     DS
  2833.         IRET
  2834.  
  2835. ;       Read and Store  character
  2836. ; Data has been received (IIR is 04h or 0Ch); AL contains bits 0-3 of IIR
  2837. _share2_dataready:
  2838. ;    Check if 16550 is present and if FIFOs are enabled
  2839.     test    [si].COMM_UART_Mode, 09h 
  2840.     jz    _share2_noFIFO_dataready; FIFOs not present or not enabled
  2841.     jmp    _share2_FIFO_dataready    ; FIFOs are present and enabled
  2842.     
  2843. _share2_noFIFO_dataready:
  2844. ;    Read received character
  2845.     SI_REG    TX_RD_BUFF_DLLO             ; Read character received
  2846.  
  2847. IFDEF INT_EXITS
  2848.         push    bx
  2849.         shr     bx, 1
  2850.         TEST_EXIT_REC   cs:share2_mask, cs:share2_func, clrbx3,bx
  2851.         pop     bx
  2852.         jmp     short   ok12
  2853. clrbx3:
  2854.         pop     bx
  2855.         jmp     share2_startover
  2856. ok12:
  2857. ENDIF
  2858.  
  2859. ;    Check if Xmit Flow Control has been enabled
  2860.     TEST    [SI].Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  2861.     JE    share2_no_fc3r
  2862.         CMP     AL, XOFF
  2863.         JNE     _share2fc_rskip1
  2864.         OR      [SI].Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  2865.         JMP     share2_txbug
  2866. _share2fc_rskip1:
  2867.         CMP     AL, XON
  2868.         JNE     _share2fc_rskip2
  2869.         AND     [SI].Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  2870.         SI_continue
  2871.         JMP     share2_txbug
  2872. _share2fc_rskip2:
  2873.  
  2874. share2_no_fc3r:                                ; No Flow Control Enabled
  2875. ;    Get ECL Receive buffer location
  2876.         MOV     DX, [SI].Comm_CR_BUFFR_Segment
  2877.         MOV     ES, DX
  2878.         MOV     DI, [SI].Comm_CR_BUFFR_Offset
  2879.         MOV     DX, [SI].Comm_CR_BUFFR_Index
  2880.         ADD     DI, DX
  2881.         STOSB                                 ; Store Char in receive buffer
  2882. ; Increment Index into receive buffer
  2883.         ADD     WORD PTR [SI].Comm_Receive_Count, 1
  2884.         ADC     WORD PTR [SI].Comm_Receive_Count + 2, 0
  2885.         INC     DX
  2886.         CMP     DX, BUFFER_SIZE
  2887.         JNZ     _share2_cont
  2888.  
  2889. ;       Optionally, add another buffer
  2890.  
  2891.         PUSH    CX              ; REV 1.2 ECL0006
  2892.         CALL    BUFFR_Gmem      ; Get next available buffer
  2893.         POP     CX              ; REV 1.2 ECL0006
  2894.         JC      _share2_nobuff   ; None available
  2895.                                 ; Increment next buffer information
  2896.         INC     [SI].Comm_Buffer_Count
  2897.         MOV     DI, [SI].Comm_CR_BUFFR_Offset
  2898.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  2899.         MOV     ES:[DI+2], DX
  2900.         MOV     [SI].Comm_CR_BUFFR_Offset, BX
  2901.         MOV     [SI].Comm_CR_BUFFR_Segment, DX
  2902.         MOV     DX, 4           ; New index
  2903.  
  2904. _share2_cont:
  2905. ;    Store Updated Receive Buffer Index in COMMS structure
  2906.         MOV     [SI].Comm_CR_BUFFR_Index, DX
  2907.  
  2908.     TEST    [SI].Comm_Xflags,FC_REC_ON    ;Is flow control enabled
  2909.     JNE    share2_ck3_hi
  2910.         JMP     share2_txbug
  2911. share2_ck3_hi:                    ; check high flow control mark
  2912.         TEST    [SI].Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  2913.     JE    share2_ck3_hi_2
  2914.         JMP     share2_txbug
  2915. share2_ck3_hi_2:
  2916. ;****    don't check high word, XON/XOFF only supported < 64K
  2917. ;****    CMP    WORD PTR [SI].Comm_Receive_Count+2, 0
  2918. ;****    JNE    over3_high
  2919.     MOV    AX, [SI].Comm_high
  2920.     CMP    WORD PTR [SI].Comm_Receive_Count, AX
  2921.     JGE    share2_over3_high
  2922.         JMP     share2_txbug
  2923. share2_over3_high:
  2924.                 ; have to send XOFF
  2925.     SI_REG    LSR        ; get line status
  2926. ; Any error is revealed via LSR bits 1-4 when it's associated 
  2927. ; character is at the top of the FIFO
  2928.     TEST    AL, 01h        ; has a char come in
  2929.     JE    share2_over3_cont
  2930.     jmp     _share2_noFIFO_dataready    ; if so, go get it
  2931. share2_over3_cont:
  2932.     TEST    AL, 40h        ; look at TX ready bits
  2933.     JE    share2_over3_high    ; wait for TX OK
  2934.     SUB    DX, LSR
  2935.     MOV    AL, XOFF
  2936.     OUT    DX, AL        ; Xmit XOFF
  2937.     OR    [SI].Comm_Xflags, FC_XOFF_SENT
  2938.  
  2939.         JMP     share2_txbug
  2940.  
  2941.  
  2942. ; No more Receive Buffer space available; Next Character received will
  2943. ; overwrite the last character received.
  2944. _share2_nobuff:                  ; None available
  2945.         SUB     WORD PTR [SI].Comm_Receive_Count, 1
  2946.         SBB     WORD PTR [SI].Comm_Receive_Count + 2, 0
  2947.     JMP     share2_txbug
  2948.  
  2949.  
  2950.  
  2951. ;*************************************************************************
  2952. ;    The following code is executed if the Uart has it's FIFOS enabled.
  2953. ;*************************************************************************
  2954. ;    If the Receive FIFOs are enabled, then the code will loop until
  2955. ;    the Receive FIFO is empty. Bit 0 of the Line Status Register is
  2956. ;    set to one whenever at least 1 character is in the Recieve Buffer
  2957. ;    Register. This bit (LSR bit0) is set to zero by reading all data 
  2958. ;    in the receive buffer or FIFO.
  2959.  
  2960. _share2_FIFO_dataready:
  2961. ;    Read received character
  2962.     SI_REG    TX_RD_BUFF_DLLO             ; Read character received
  2963.  
  2964.  
  2965. IFDEF INT_EXITS
  2966.         push    bx
  2967.         shr     bx, 1
  2968.         TEST_EXIT_REC   cs:share2_mask, cs:share2_func,clrbx4 ,bx
  2969.         pop     bx
  2970.         jmp     short   ok14
  2971. clrbx4:
  2972.         pop     bx
  2973.         jmp     _share2_check_data_ready
  2974. ok14:
  2975. ENDIF
  2976.  
  2977. ;    Check if Xmit Flow Control has been enabled
  2978.     TEST    [si].Comm_Xflags,FC_TX_ON    ;Is flow control enabled
  2979.     JE    share2_no_fc3rFIFO
  2980.         CMP     AL, XOFF            ; Compare incomming char to XOFF
  2981.         JNE     _share2fc_FIFOrskip1
  2982.         OR      [si].Comm_Xflags, FC_XOFF_RCVD  ; Incoming XOFF, pause xmission
  2983.  
  2984. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2985.     jmp    _share2_check_data_ready
  2986.  
  2987. _share2fc_FIFOrskip1:
  2988.         CMP     AL, XON
  2989.         JNE     _share2fc_FIFOrskip2
  2990.         AND     [si].Comm_Xflags, NOT FC_XOFF_RCVD  ; Incoming XON, continue xmission
  2991. IFDEF WQ
  2992.     OR    [si].Comm_Xflags, FC_FIRST_XON      ; Got 1st XON - WQ
  2993. ENDIF
  2994.         SI_continue           ; Xmit next char in Xmit buffer if there is a char to Xmit
  2995.  
  2996. ;    Check if receive FIFO is empty by checking bit0 of LSR
  2997.     jmp    _share2_check_data_ready
  2998.  
  2999. _share2fc_FIFOrskip2:
  3000.  
  3001. share2_no_fc3rFIFO:                                ; No Flow Control Enabled
  3002. ;    Get ECL Receive buffer location
  3003.         MOV     DX, [si].Comm_CR_BUFFR_Segment
  3004.         MOV     ES, DX
  3005.         MOV     DI, [si].Comm_CR_BUFFR_Offset
  3006.         MOV     DX, [si].Comm_CR_BUFFR_Index
  3007.         ADD     DI, DX
  3008.         STOSB                                 ; Store Char in receive buffer
  3009. ; Increment Index into receive buffer
  3010.         ADD     WORD PTR [si].Comm_Receive_Count, 1
  3011.         ADC     WORD PTR [si].Comm_Receive_Count + 2, 0 
  3012.         INC     DX
  3013.         CMP     DX, BUFFER_SIZE
  3014.         JNZ     _share2_contFIFO
  3015.  
  3016. ;       Optionally, add another buffer
  3017.  
  3018.         PUSH    CX              ; REV 1.2 ECL0006
  3019.         CALL    BUFFR_Gmem      ; Get next available buffer
  3020.         POP     CX              ; REV 1.2 ECL0006
  3021.         JC      _share2_FIFOrjor6 ; No Buffers available
  3022.     jmp    _share2_FIFOrjor7 ; Buffers available
  3023. _share2_FIFOrjor6:
  3024.     jmp    _share2_FIFOnobuff   ; No Buffers available
  3025. _share2_FIFOrjor7:
  3026.                                 ; Increment next buffer information
  3027.         INC     [si].Comm_Buffer_Count
  3028.         MOV     DI, [si].Comm_CR_BUFFR_Offset
  3029.         MOV     ES:[DI], BX     ; Save pointer in previous last block
  3030.         MOV     ES:[DI+2], DX
  3031.         MOV     [si].Comm_CR_BUFFR_Offset, BX
  3032.         MOV     [si].Comm_CR_BUFFR_Segment, DX
  3033.         MOV     DX, 4           ; New index
  3034.  
  3035. _share2_contFIFO:
  3036. ;    Store Updated Receive Buffer Index in COMMS structure
  3037.         MOV     [si].Comm_CR_BUFFR_Index, DX 
  3038.  
  3039.     TEST    [si].Comm_Xflags,FC_REC_ON    ;Is Receive flow control enabled
  3040.     JNE    share2_ck3_hi_FIFO
  3041.  
  3042. ;    Check if receive FIFO is empty by checking bit0 of LSR
  3043.     jmp    _share2_check_data_ready
  3044.  
  3045. share2_ck3_hi_FIFO:                    ; check high flow control mark
  3046.         TEST    [si].Comm_Xflags, FC_XOFF_SENT  ; Outgoing XOFF already sent
  3047.     JE    share2_ck3_hi_2_FIFO
  3048.  
  3049. ;    Check if receive FIFO is empty by checking bit0 of LSR
  3050.     jmp    _share2_check_data_ready
  3051.  
  3052. share2_ck3_hi_2_FIFO:
  3053. ;****    don't check high word, XON/XOFF only supported < 64K
  3054. ;****    CMP    WORD PTR COM2.Comm_Receive_Count+2, 0
  3055. ;****    JNE    over3_high
  3056.     MOV    AX, [si].Comm_high
  3057.     CMP    WORD PTR [si].Comm_Receive_Count, AX
  3058.     JGE    share2_over3_high_FIFO
  3059.  
  3060. ;    Check if receive FIFO is empty by checking bit0 of LSR
  3061.     jmp    _share2_check_data_ready
  3062.  
  3063. share2_over3_high_FIFO:
  3064.                 ; have to send XOFF
  3065.     SI_REG    LSR        ; get line status
  3066. ;    Any error is revealed via LSR bits 1-4 when it's associated 
  3067. ;    character is at the top of the FIFO
  3068.     TEST    AL, 01h        ; has a char come in
  3069.     JE    share2_over3_cont_FIFO
  3070.     JMP    _share2_FIFO_dataready    ; if so, go get it
  3071.  
  3072. share2_over3_cont_FIFO:
  3073.     TEST    AL, 40h        ; look at TX ready bits
  3074.     JE    share2_over3_high_FIFO    ; wait for TX OK
  3075.     SUB    DX, LSR
  3076.     MOV    AL, XOFF
  3077.     OUT    DX, AL        ; Xmit XOFF
  3078.     OR    [si].Comm_Xflags, FC_XOFF_SENT
  3079.  
  3080. ;    Check if receive FIFO is empty by checking bit0 of LSR
  3081.     jmp    _share2_check_data_ready
  3082.  
  3083. ; No more Receive Buffer space available; Next Character received will
  3084. ; overwrite the last character received.
  3085. _share2_FIFOnobuff:                  ; None available
  3086.         SUB     WORD PTR [si].Comm_Receive_Count, 1
  3087.         SBB     WORD PTR [si].Comm_Receive_Count + 2, 0
  3088.  
  3089. ;    Check if receive FIFO is empty by checking bit0 of LSR
  3090. _share2_check_data_ready:
  3091.     SI_REG    LSR                ; get line status register
  3092.     test    al, 01h                ; Test for Receive FIFO empty
  3093.     jnz    _share2_FIFO_rjor1        ; Get next character in Receive FIFO
  3094.     JMP     share2_txbug
  3095. _share2_FIFO_rjor1:                ; Relative Jump Out Of Range
  3096.     jmp    _share2_FIFO_dataready        ; Get next character in Receive FIFO
  3097.  
  3098. ;*********************************************************************
  3099.  
  3100.  
  3101. share2_txbug:               ; code for 8250 TX bug goes here for multiports
  3102.            SI_REG LSR    ; look for THRE to get around 8250 bug
  3103.     test    al, 020H
  3104.           jnz    _share2_txbug    ; have to check TX
  3105.           jmp    share2_startover
  3106. ;          AND    AL, 20H        ; isolate THRE
  3107. ;          CMP    AL, 20H
  3108. ;          JE    _share2_txbug    ; have to check TX
  3109. ;          JMP    share2_startover
  3110. _share2_txbug:
  3111.         CMP     [SI].Comm_xcount, 0
  3112.         JE      _share2_txbug_exit
  3113.         JMP    _share2_xmt_enter
  3114. _share2_txbug_exit:
  3115.         JMP     share2_startover
  3116.  
  3117. IREQSHARE2   ENDP
  3118.  
  3119. ;*******************************************************************
  3120. ;*******************************************************************
  3121. ;*******************************************************************
  3122. ;*******************************************************************
  3123.  
  3124.  
  3125. ;
  3126. ;       ===============================================================
  3127. ;       Local procedures
  3128. ;       ===============================================================
  3129. ;
  3130.  
  3131. Old_INT14       PROC    NEAR                    ; Go to original Int 14h
  3132.                 PUSHF
  3133.                 CALL    DWORD PTR CS:[INT14_Old_Offset]
  3134.                 RET
  3135. Old_INT14       ENDP
  3136.  
  3137.  
  3138. ;
  3139. ;       ===============================================================
  3140. ;       INT 14h entry (regardless of intercept - they all come here)
  3141. ;       ===============================================================
  3142. ;
  3143.  
  3144.  
  3145. RS232_Int       PROC    FAR                     ; Interrupt 14 BIOS service
  3146.                 STI                             ; Allow interrupts
  3147.                 PUSH    DS                      ; Data segment too!
  3148.                 PUSH    CS
  3149.                 POP     DS
  3150.                 PUSH    SI                      ; Used point to COMM data base
  3151.                                                 ; *** SI, DS preset ***
  3152.                 Load_SI                         ; Load SI with Comms_Str
  3153.  
  3154.                 CMP     CS:[SI].Comm_State, INTERCEPTED
  3155.                 JE      _RS232go                ; Intercepted?
  3156.                 CALL    Old_INT14               ; Native - go back
  3157.                 JMP     SHORT _RS232exit
  3158.  
  3159. _RS232go:    ;  SI is preset to COM1 or COM2 database
  3160.  
  3161.                 CMP     AH, 02h
  3162.                 JNE     $+7
  3163.                 CALL    INT14READ
  3164.                 JMP     SHORT   _RS232exit
  3165.                 CMP     AH, 03h
  3166.                 JNE     $+7
  3167.                 CALL    INT14STATUS
  3168.                 JMP     SHORT   _RS232exit
  3169.                 CMP     AH, 00h
  3170.                 JNE     $+7
  3171.                 CALL    INT14INIT
  3172.                 JMP     SHORT   _RS232exit
  3173.                 CMP     AH, 01h
  3174.                 JNE     $+7
  3175.                 CALL    INT14SEND
  3176.                 JMP     SHORT   _RS232exit
  3177. _RS232exit:
  3178.                 POP     SI
  3179.                 POP     DS
  3180.                 IRET
  3181. RS232_Int       ENDP
  3182.  
  3183.  
  3184. ;
  3185. ;       ===============================================================
  3186. ;       INT14INIT       Initialize communications interface (intercepted)
  3187. ;       ===============================================================
  3188. ;       same as BIOS
  3189. ;
  3190. ;       Revision 1.2                    Special 19,200 entry
  3191. ;                                       ; CX is the configuration
  3192. ;                                       ; DX is the unit number
  3193. COMMS_19200     PROC    NEAR            ; requires baud bits to be 0!
  3194.                 PUSH    SI
  3195.                 Load_SI                         ; Load SI with Comms_Str
  3196.                 MOV     AX, CX          ; Baud rate is preset to a 0 (110 baud)
  3197.                 MOV     WORD PTR TIMERS_X16, 6  ; 19,200 divisor
  3198.                 CALL    INT14INIT
  3199.                 MOV     WORD PTR TIMERS_X16, 1047   ; original 110 divisor
  3200.                 POP     SI
  3201.                 RET
  3202. COMMS_19200     ENDP
  3203.  
  3204. COMMS_38400     PROC    NEAR            ; requires baud bits to be 0!
  3205.                 PUSH    SI
  3206.                 Load_SI                         ; Load SI with Comms_Str
  3207.                 MOV     AX, CX          ; Baud rate is preset to a 0 (110 baud)
  3208.                 MOV     WORD PTR TIMERS_X16, 3  ; 38,400 divisor
  3209.                 CALL    INT14INIT
  3210.                 MOV     WORD PTR TIMERS_X16, 1047   ; original 110 divisor
  3211.                 POP     SI
  3212.                 RET
  3213. COMMS_38400     ENDP
  3214.  
  3215.  
  3216.  
  3217. INT14INIT       PROC    NEAR                    ; AH = 0
  3218.                 PUSH    BX
  3219.                 PUSH    CX
  3220.                 PUSH    DX
  3221.  
  3222.                 MOV     AH, AL                  ; Save original parameter
  3223.  
  3224. ;       ===============================================================
  3225. ;               Set Baud rate
  3226. ;       ===============================================================
  3227.  
  3228.                 MOV     DX, [SI].Comm_PortAddr  ; Set DLAB
  3229.                 ADD     DX, LCR
  3230.                 IN      AL, DX
  3231.                 IONOP
  3232.                 OR      AL, 80h
  3233.                 OUT     DX, AL
  3234.                 IONOP
  3235.  
  3236.                 MOV     BX, AX                  ; Access baud table
  3237.                 AND     BX, 0E000h              ; Isolate baud rate triplet
  3238.                 MOV     CL, 12
  3239.                 SHR     BX, CL
  3240.                 MOV     CX, TIMERS_X16[BX]
  3241.                                                 ; Low byte divisor first
  3242.                 MOV     AL, CL
  3243.                 MOV     DX, [SI].Comm_PortAddr
  3244.                 ADD     DX, TX_RD_BUFF_DLLO
  3245.                 OUT     DX, AL
  3246.                 IONOP
  3247.                                                 ; High byte divisor last
  3248.                 MOV     AL, CH
  3249.                 MOV     DX, [SI].Comm_PortAddr
  3250.                 ADD     DX, IER_DLHI
  3251.                 OUT     DX, AL
  3252.                 IONOP
  3253.  
  3254. ;       ===============================================================
  3255. ;               Set parity stop data bit configuration
  3256. ;       ===============================================================
  3257.  
  3258.                 MOV     DX, [SI].Comm_PortAddr  ; RESet DLAB, parity etc...
  3259.                 ADD     DX, LCR
  3260.                 MOV     AL, AH                  ; Restore original parameter
  3261.                 AND     AL, 01Fh
  3262.                 OUT     DX, AL
  3263.                 IONOP
  3264.                 CALL    INT14STATUS
  3265.  
  3266.                 POP     DX
  3267.                 POP     CX
  3268.                 POP     BX
  3269.                 RET
  3270.  
  3271. INT14INIT       ENDP
  3272.  
  3273. ;
  3274. ;       ===============================================================
  3275. ;       INT14SEND       Send character (intercept mode only)
  3276. ;                       Rev 2.0 - all with interrupts!
  3277. ;       ===============================================================
  3278. ;       same as BIOS
  3279. INT14SEND       PROC    NEAR                    ; AH = 1
  3280.                 PUSH    DX
  3281.                 PUSH    CX
  3282.                 PUSH    BX
  3283.  
  3284.                 MOV     BL, AL                  ; Save character
  3285.                 MOV     DX, [SI].Comm_PortAddr
  3286.                 ADD     DX, MCR
  3287.                 IN      AL, DX
  3288.                 IONOP
  3289.                 MOV     AH, AL
  3290.                 CMP     [SI].Comm_DTR_RTS, 0
  3291.                 JE      _SEND_goahead           ; Ignore DSR, CTS
  3292.  
  3293. ;       ===============================================================
  3294. ;               Optionally, set DTR, RTS and wait for CTS and/or DSR
  3295. ;               MCR still in register AL, character in BL
  3296. ;       ===============================================================
  3297.  
  3298.                 OR      AL, 03h
  3299.                 OUT     DX, AL
  3300.                 IONOP
  3301.  
  3302.                 MOV     DX, [SI].Comm_PortAddr  ; Wait for DSR and CTS
  3303.                 ADD     DX, MSR
  3304.                 MOV     CX, timeout_variable    ; Timed loop for modem
  3305. _Sd_loop:
  3306.                 IN      AL, DX
  3307.                 IONOP
  3308.                 MOV     AH, AL                  ; Set AH register to status
  3309. ;    look for Hardware Handshaking flag
  3310.         and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  3311.         cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  3312. ;               AND     AL, 30h
  3313. ;               CMP     AL, 30h
  3314.                 JE      _SEND_goahead
  3315.                 LOOP    _Sd_loop                ; Go back for more punishment
  3316.  
  3317.                 OR      AH, 080h                ; OOOOOOOOPPPPPPSSSSSSS!
  3318.                 JMP     _SEND_exit              ; Can't wait for modem signals
  3319.  
  3320. ;       ===============================================================
  3321. ;               Optionally, if been XOFF'ed wait around
  3322. ;       ===============================================================
  3323.  
  3324. _SEND_goahead:
  3325.                 MOV     CX, timeout_variable    ; Timed loop for modem
  3326. _St_loop:
  3327.                 TEST    [SI].Comm_Xflags, FC_XOFF_RCVD  ; Have we been X-OFFed?
  3328.                 JZ      _SEND_really_goahead
  3329.                 IONOP
  3330.                 IONOP
  3331.                 IONOP
  3332.                 JMP     _St_loop                ; Go back for more punishment
  3333.  
  3334.                 OR      AH, 080h                ; OOOOOOOOPPPPPPSSSSSSS!
  3335.                 JMP     _SEND_exit              ; Timeout - can't wait!
  3336. ;       ===============================================================
  3337. ;               If output pending, then wait till complete
  3338. ;       ===============================================================
  3339.  
  3340. _SEND_really_goahead:
  3341. _SEND_notready:
  3342.                 CMP     [SI].Comm_xcount, 0     ; Wait till ISR completes
  3343.                 JNE     _SEND_notready
  3344.  
  3345. ;       ===============================================================
  3346. ;               Transmit character and wait till completed
  3347. ;       ===============================================================
  3348.  
  3349.                 MOV     [SI].Comm_xcount, 1     ; Rev 2.0 set counter
  3350.                 MOV     AL, BL                  ; Retrieve the character
  3351.                 SI_PutAL                        ; Send the character
  3352.  
  3353. _SEND_waitloop:
  3354.                 CMP     [SI].Comm_xcount, 0     ; wait till ISR completes
  3355.                 JNE     _SEND_waitloop
  3356.  
  3357. ;       ===============================================================
  3358. ;               To be compatible with ROM BIOS, return the LSR in AH
  3359. ;       ===============================================================
  3360.  
  3361.                 MOV     DX, [SI].Comm_PortAddr
  3362.                 ADD     DX, LSR
  3363.                 IN      AL, DX
  3364.                 MOV     AH, AL                  ; Move LSR to AH status
  3365.                 IONOP
  3366. _SEND_exit:
  3367.                 POP     BX
  3368.                 POP     CX
  3369.                 POP     DX
  3370.                 RET
  3371. INT14SEND       ENDP
  3372.  
  3373. ;
  3374. ;       ===============================================================
  3375. ;       INT14READ       Read next data byte (intercept mode only)
  3376. ;       ===============================================================
  3377. ;       same as BIOS
  3378.  
  3379. INT14READ       PROC    NEAR                    ; AH = 2
  3380.                 PUSH    ES
  3381.                 PUSH    BX
  3382.                 PUSH    CX
  3383.                 PUSH    DX
  3384.  
  3385. ;       ===============================================================
  3386. ;               If IBM BIOS compatible (wait for DSR), drop RTS
  3387. ;       ===============================================================
  3388.  
  3389. ;;              CMP     [SI].Comm_DTR_RTS, 0
  3390. ;;              JE      _READ_WAIT
  3391. ;;
  3392. ;;              MOV     DX, [SI].Comm_PortAddr  ; Set DSR, drop RTS
  3393. ;;              ADD     DX, MCR
  3394. ;;              IN      AL, DX
  3395. ;;              IONOP
  3396. ;;              OR      AL, 1                   ; Keep bit 0 (DTR) high
  3397. ;;              AND     AL, 0FDh                ; Force bit 1 (RTS) low
  3398. ;;              OUT     DX, AL
  3399. ;;              IONOP
  3400.  
  3401. ;       ===============================================================
  3402. ;               Wait for character
  3403. ;       ===============================================================
  3404.  
  3405. _READ_WAIT:
  3406.                 MOV     CX, timeout_variable    ; Timeout
  3407.  
  3408. _Rd_loop:
  3409.                 CALL    INT14STATUS             ; Get the status
  3410. ; JHL 3-5-91 Commented out code so that we do not need CTS or DSR to be 
  3411. ; enabled (when Hardware Handshaking is enabled) when we read data from 
  3412. ; xcomms receive buffer
  3413. ;                CMP     [SI].Comm_DTR_RTS, 0
  3414. ;                JE      _READ_SKIP_Chek         ; Ignore IBM BIOS DSR check
  3415.  
  3416. ;                TEST    AL, 20h                 ; Is DSR (modem) asserted?
  3417. ;                JZ      _READ_TRY_AGAIN         ; Not yet!
  3418. _READ_SKIP_Chek:
  3419.                 TEST    AH, 01h                 ; Data ready?
  3420.                 JNE     _Rd_gotchar             ; Yes!
  3421.                 CMP     [SI].Comm_Error, 0      ; Overflow?
  3422.                 MOV     [SI].Comm_Error, 0      ; Reset errors-no matter what
  3423.                 JNE     _Read_Error
  3424. _READ_TRY_AGAIN:
  3425.                 LOOP    _Rd_loop                ; Continue
  3426. _Read_Error:
  3427.                 OR      AH, 80h                 ; No character yet????
  3428.                 JMP     _READ_Exit              ; TIMEOUT - NO DSR  or
  3429.                                                 ; TIMEOUT - No character  or
  3430.                                                 ; BUFFR Overflow error
  3431. _Rd_gotchar:
  3432.                 CALL    _Rd_getchar
  3433. _READ_Exit:
  3434.                 POP     DX
  3435.                 POP     CX
  3436.                 POP     BX
  3437.                 POP     ES
  3438.                 RET
  3439. INT14READ       ENDP
  3440.  
  3441. ;       ===============================================================
  3442. ;       _Rd_gotchar
  3443. ;               Character found - get character then update buffer pointer
  3444. ;       ===============================================================
  3445. ;       Given:
  3446. ;               AH      Status of the line (is preserved and not modified)
  3447. ;               DS, CS  XCOMMS segment
  3448. ;               SI      COMx data base
  3449. ;       Return:
  3450. ;               AH      Same
  3451. ;               AL      Character
  3452. ;               SI      COMx data base
  3453. ;               ES, BX, CX  modified
  3454. ;       ===============================================================
  3455.  
  3456. _Rd_getchar     PROC
  3457.                 CLI                             ;;; Disable interrupts
  3458.  
  3459.                 SUB     WORD PTR [SI].Comm_Receive_Count, 1
  3460.                 SBB     WORD PTR [SI].Comm_Receive_Count+2, 0
  3461.  
  3462.                 MOV     BX, [SI].Comm_RD_BUFFR_Segment
  3463.                 MOV     ES, BX
  3464.                 MOV     BX, [SI].Comm_RD_BUFFR_Offset
  3465.                 ADD     BX, [SI].Comm_RD_BUFFR_Index
  3466.                 MOV     AL, ES:[BX]             ;;; Read the character byte
  3467.  
  3468.                 INC     [SI].Comm_RD_BUFFR_Index
  3469.                 CMP     [SI].Comm_RD_BUFFR_Index, BUFFER_SIZE
  3470.                 JNE     _READ_pointer
  3471.  
  3472. ;       ===============================================================
  3473. ;               Go to next block
  3474. ;       ===============================================================
  3475.  
  3476.                 MOV     [SI].Comm_RD_BUFFR_Index, 4
  3477.                 MOV     BX, [SI].Comm_RD_BUFFR_Offset
  3478.                 MOV     CX, ES:[BX]
  3479.                 MOV     [SI].Comm_RD_BUFFR_Offset, CX
  3480.                 MOV     CX, ES:[BX+2]
  3481.                 MOV     [SI].Comm_RD_BUFFR_Segment, CX
  3482.                 MOV     DX, ES
  3483.  
  3484.                 PUSH    AX
  3485.                 CALL    BUFFR_Pmem
  3486.                 DEC     [SI].Comm_Buffer_Count
  3487.                 POP     AX
  3488.  
  3489. ;       ===============================================================
  3490. ;               If the buffer is empty, then reset all pointers
  3491. ;       ===============================================================
  3492.  
  3493. _READ_pointer:
  3494.                 MOV     BX, WORD PTR [SI].Comm_Receive_Count
  3495.                 OR      BX, WORD PTR [SI].Comm_Receive_Count+2
  3496.                 JNE     _Rd_gcexit
  3497.                 MOV     [SI].Comm_RD_BUFFR_Index, 4
  3498.                 MOV     [SI].Comm_CR_BUFFR_Index, 4
  3499. _Rd_gcexit:
  3500.         STI                             ; Enable interrupts
  3501.         TEST    [SI].Comm_Xflags, FC_ENABLED ; test for flow control
  3502.         JE    no_fc_here
  3503.         TEST    [SI].Comm_Xflags, FC_XOFF_SENT ; if we sent XOFF
  3504.         JE    no_fc_here
  3505.                     ; look for <= low water mark
  3506. ;*****    XON/XOFF only supported for high/lows < 64K
  3507. ;*****        CMP    WORD PTR [SI].Comm_Receive_Count+2, 0    ;count > 64K?
  3508. ;*****        JNE    no_fc_here    ; if > 64K, can't be low water mark
  3509.         MOV    DX, [SI].Comm_low
  3510.         CMP    WORD PTR [SI].Comm_Receive_Count, DX    ; <= low
  3511.         JG    no_fc_here
  3512.                     ; have to send XON
  3513.         MOV    DX, [SI].Comm_PortAddr
  3514.         ADD    DX, LSR        ; get line status
  3515.         MOV    AH, AL        ; save character read
  3516.  
  3517.         XOR    BX, BX        ; must clear transmit count, temporarily
  3518.                     ; not to interfere with xon logic here
  3519.         XCHG    [SI].Comm_xcount, BX    ; save count and clear it
  3520. loop_xon:
  3521.          IN    AL, DX
  3522.         AND    AL, 60h        ; look at TX ready bits
  3523.         CMP    AL, 60h
  3524.         JNE    loop_xon    ; wait for TX OK
  3525.  
  3526.         SUB    DX, LSR        ; point to TX Port
  3527.         MOV    AL, XON
  3528.         CLI            ; turn ints off around here to
  3529.                     ; guarantee we don't hang tx in the
  3530.                     ; middle of a uput
  3531.         MOV    [SI].Comm_xcount, BX    ; restore tx count
  3532.         OUT    DX, AL        ; send xon
  3533.  
  3534.         STI
  3535.  
  3536.         AND    [SI].Comm_Xflags, NOT FC_XOFF_SENT
  3537.         MOV    AL, AH        ; restore char read
  3538.  
  3539. no_fc_here:
  3540. ;****      the STI instruction was moved above not to leave ints off too long
  3541. ;****        STI                             ; Enable interrupts
  3542.                 RET
  3543. _Rd_getchar     ENDP
  3544.  
  3545. ;       ===============================================================
  3546. ;       ===============================================================
  3547.  
  3548.  
  3549. ;
  3550. ;       ===============================================================
  3551. ;       INT14STATUS     Read status (intercept mode only)
  3552. ;       ===============================================================
  3553. ;       same as BIOS call
  3554. INT14STATUS     PROC    NEAR                    ; AH = 3
  3555.                 PUSH    BX
  3556.                 PUSH    DX
  3557.  
  3558.                 MOV     DX, [SI].Comm_PortAddr
  3559.                 ADD     DX, LSR
  3560.                 IN      AL, DX
  3561.                 IONOP
  3562.                 or      al, BYTE PTR [SI].Comm_Break
  3563.                 AND     AL, 0FEh                ; Get rid of Data Ready
  3564.                 MOV     BX, WORD PTR [SI].Comm_Receive_Count
  3565.                 OR      BX, WORD PTR [SI].Comm_Receive_Count+2
  3566.                 CMP     BX, 0
  3567.                 JE      _Status_skip1
  3568.                 OR      AL, 1h                  ; Set Data Ready bit
  3569. _Status_skip1:
  3570.                 MOV     AH, AL
  3571.                 MOV     DX, [SI].Comm_PortAddr
  3572.                 ADD     DX, MSR
  3573.                 IN      AL, DX
  3574.                 IONOP
  3575.  
  3576.                 POP     DX
  3577.                 POP     BX
  3578.                 RET
  3579. INT14STATUS     ENDP
  3580.  
  3581.  
  3582.  
  3583.  
  3584. ;
  3585. ;       ===============================================================
  3586. ;       COMMS_Entry     Enter the COMMS library
  3587. ;       COMMS_Exit      Exit the COMMS library
  3588. ;       ===============================================================
  3589. ;
  3590. ;       Since either COM1 or COM2 can be linked at anytime, the default
  3591. ;       condition at COMMS_Entry is to take all INT14 BIOS calls - all
  3592. ;       requests for native (UnLinked) COM unit will go to the previous
  3593. ;       BIOS service routine.
  3594. ;
  3595. ;       Input           Description
  3596. ;       --------------  ---------------------------
  3597. ;       DS, CS          XBIOS CSEG[ment]
  3598. ;
  3599. ;       Output          Description
  3600. ;       --------------  ---------------------------
  3601. ;       Not applicable
  3602. ;
  3603. ;       Registers used  Description
  3604. ;       --------------  ---------------------------
  3605. ;       None affected
  3606. ;       ===============================================================
  3607. ;
  3608.  
  3609. COMMS_Entry     PROC NEAR
  3610.                 PUSH    SI                          ; Rev 2.0 (new)
  3611.                 PUSH    DI                          ; Rev 2.0 (new)
  3612.  
  3613.  
  3614.         JMP PASTSHARE
  3615.  
  3616. ;formerly macro    Ports_Entr                          ; Rev 2.0 (new)
  3617.  
  3618. ;Ports_Entr      MACRO
  3619.  
  3620.                 PUSH    BX
  3621.                 PUSH    CX
  3622.  
  3623. ;               -------- SHARED INTERRUPT --------------------------
  3624. ;               1. Take over the shared interrupt IREQ completely
  3625. ;               2. Enable the interrupt controller 8259
  3626. ;               3. Initialize status for each port assuming polling
  3627. ;               4. Setup COM3, COM4 in ROM BIOS data base region
  3628. ;               ----------------------------------------------------
  3629.  
  3630.  
  3631.                     ; 1 Point to shared interrupt
  3632.                 MOV     AL, Shared_vector
  3633.                 MOV     BX, OFFSET IREQSHARE
  3634.                 MOV     DX, SEG IREQSHARE
  3635.                 swapvec
  3636.                 MOV     Shared_Old_IntOffset, BX
  3637.                 MOV     Shared_Old_IntSegment, DX
  3638.                 IN      AL, ICA                 ; 2 Enable 8259 channel
  3639.                 AND     AL, Shared_IC_mask
  3640.                 IONOP
  3641.                 OUT     ICA, AL
  3642.                 IONOP
  3643.  
  3644.  
  3645.  
  3646.  
  3647.                 MOV     CX, MAXPORTS            ; 3 Polled mode
  3648.                 MOV     BX, 0
  3649. Port_Status_Loop:
  3650.                 MOV     WORD PTR Port_Status[BX], STATUS_POLLED
  3651.                 MOV     SI, Port_Table[BX]
  3652.                 MOV     [SI].Comm_unit, BX
  3653.                 ADD     BX, 2
  3654.                 LOOP    Port_Status_Loop
  3655.  
  3656.                 PUSH    ES                      ; 4 Setup ROM BIOS data base
  3657.                 MOV     AX, 40h
  3658.                 MOV     ES, AX
  3659.                 MOV     WORD PTR ES:00h, C1
  3660.                 MOV     WORD PTR ES:02h, C2
  3661.                 MOV     WORD PTR ES:04h, C3
  3662.                 MOV     WORD PTR ES:06h, C4
  3663.                 POP     ES
  3664.                 POP     CX
  3665.                 POP     BX
  3666. ;                ENDM
  3667.  
  3668. PASTSHARE:
  3669.  
  3670.                 MOV     CX, MAXPORTS                ; Rev 2.0 (upgraded)
  3671.                 MOV     DL, 0                       ; Rev 2.0
  3672. _Entry_loop:                                        ; Rev 2.0 init all ports
  3673.                 PUSH    DX                          ; Rev 2.0
  3674.                 CALL    COMMS_Gaddr                 ; Rev 2.0 (assume same segment)
  3675.                 MOV     [BX].Comm_State, NATIVE     ; Rev 2.0
  3676.                 MOV     [BX].Comm_Xflags, 0         ; Rev 2.0
  3677.                 POP     DX                          ; Rev 2.0
  3678.                 INC     DL                          ; Rev 2.0
  3679.                 LOOP    _Entry_loop                 ; Rev 2.0
  3680.  
  3681.                 MOV     timeout_variable, TIMEOUT   ; Default
  3682.  
  3683. ;       ===============================================================
  3684. ;               Set interrupt vector int 14h
  3685. ;       ===============================================================
  3686.  
  3687.                 MOV     AL, RS232
  3688.                 MOV     DX, SEG RS232_Int
  3689.                 MOV     BX, OFFSET RS232_Int
  3690.                 swapvec
  3691.                 MOV     WORD PTR INT14_Old_Offset, BX
  3692.                 MOV     WORD PTR INT14_Old_Segment, DX
  3693.  
  3694. ;       ===============================================================
  3695. ;               Copy the baud rate table from system ROM
  3696. ;       ===============================================================
  3697.  
  3698.                 PUSH    DS
  3699.                 MOV     SI, 0E729h              ; Source ROM table
  3700.                 MOV     AX, 0F000h
  3701.                 MOV     DS, AX
  3702.  
  3703.                 MOV     DI, OFFSET TIMERS_X16   ; Destination XBIOS table
  3704.                 PUSH    DS
  3705.                 POP     ES
  3706.  
  3707.                 MOV     CX, 8                   ; Move 8 baud rate divisors
  3708.                 REP     MOVSW
  3709.                 POP     DS
  3710.  
  3711.                 POP DI                          ; Rev 2.0 (new)
  3712.                 POP SI                          ; Rev 2.0 (new)
  3713.                 RET
  3714. COMMS_Entry     ENDP
  3715.  
  3716.  
  3717. COMMS_Exit      PROC NEAR
  3718.                 PUSH    SI                          ; Rev 2.0 (new)
  3719.                 PUSH    DI                          ; Rev 2.0 (new)
  3720.  
  3721. ;formerly macro       Ports_Exit                          ; Rev 2.0 (new)
  3722.  
  3723. ;Ports_Exit      MACRO
  3724.  
  3725. ;               -------- SHARED INTERRUPT --------------------------
  3726. ;               1. Restore interrupt vector to previous contents
  3727. ;               2. Disable the interrupt controller 8259 channel
  3728. ;               3. Clear COM3 and COM4 entries in ROM BIOS data base
  3729. ;               ----------------------------------------------------
  3730.  
  3731. ;*****                MOV     AL, Shared_vector       ;***** 1 Restore shared vector
  3732. ;*****                MOV     BX, Shared_Old_IntOffset
  3733. ;*****                MOV     DX, Shared_Old_IntSegment
  3734. ;*****                setvec
  3735.                                                 ;***** 2 Disable shared 8259 channel
  3736. ;*****                AND     CL, Shared_IC_mask
  3737. ;*****                NOT     CL
  3738. ;*****                IN      AL, ICA
  3739. ;*****                IONOP
  3740. ;*****                OUT     ICA, AL
  3741. ;*****                IONOP
  3742.  
  3743. ;                PUSH    ES                      ; 3 Reset ROM BIOS data base
  3744. ;                MOV     AX, 40h
  3745. ;                MOV     ES, AX
  3746. ;                MOV     WORD PTR ES:00h, 03F8h
  3747. ;                MOV     WORD PTR ES:02h, 02F8h
  3748. ;                MOV     WORD PTR ES:04h, 0
  3749. ;                MOV     WORD PTR ES:06h, 0
  3750. ;                POP     ES
  3751. ;                ENDM
  3752.  
  3753.  
  3754.  
  3755.                 MOV     CX, MAXPORTS                ; Rev 2.0 (upgraded)
  3756.                 MOV     DX, 0                       ; Rev 2.0
  3757. _exit_loop:
  3758.                 CALL    COMMS_UnLink
  3759.                 INC     DL
  3760.                 LOOP    _exit_loop
  3761.  
  3762.                 MOV     AL, RS232
  3763.                 MOV     BX, WORD PTR INT14_Old_Offset
  3764.                 MOV     DX, WORD PTR INT14_Old_Segment
  3765.                 setvec
  3766.                 POP     DI                          ; Rev 2.0 (new)
  3767.                 POP     SI                          ; Rev 2.0 (new)
  3768.                 RET
  3769. COMMS_Exit      ENDP
  3770.  
  3771.  
  3772.  
  3773. ;
  3774. ;       ===============================================================
  3775. ;       COMMS_Link      Connect the communications circuit
  3776. ;       COMMS_UnLink    Disconnect the communications circuit
  3777. ;       ===============================================================
  3778. ;
  3779. ;       In the case of Link, connect into interrupt
  3780. ;       service routine structure.  In the case of UnLink,
  3781. ;       restore the old interrupt service routine`s address and
  3782. ;       return all buffers to the buffer manager!
  3783. ;
  3784. ;       XOFF/XON mode automatically disabled
  3785. ;
  3786. ;       Input           Description
  3787. ;       --------------  ---------------------------
  3788. ;       DS, CS          XBIOS CSEG[ment]
  3789. ;       DX              Unit number (COM1 = 00h, COM2 = 01h)
  3790. ;       CL              = 0 leave DTR, RTS alone
  3791. ;                       = 1 assert DTR, RTS and watch for modem signals
  3792. ;                           (like on IBM PC)
  3793. ;
  3794. ;       Output          Description
  3795. ;       --------------  ---------------------------
  3796. ;       AL = 00h,       Successful operation
  3797. ;       CY = NC
  3798. ;
  3799. ;       CY = C
  3800. ;       AL = FFh        Unsuccessful operation - already linked
  3801. ;       AL = FEh        No buffers available
  3802. ;
  3803. ;       Registers used  Description
  3804. ;       --------------  ---------------------------
  3805. ;       None affected
  3806. ;       ===============================================================
  3807. ;
  3808.  
  3809. public COMMS_Link
  3810. COMMS_Link      PROC NEAR
  3811.                 PUSH    SI
  3812.                 PUSH    BX
  3813.                 PUSH    CX
  3814.                 PUSH    DX
  3815.  
  3816.         MOV    port_hold, DX        ; save unit number
  3817.                 Load_SI                         ; Load SI with Comms_Str
  3818.                 CMP     [SI].Comm_State, INTERCEPTED
  3819.                 JNE     _Lk_1
  3820.                 JMP     _Lk_error
  3821. _Lk_1:
  3822.                 MOV     [SI].Comm_xcount, 0     ; Rev 2.0
  3823.  
  3824. ;       ===============================================================
  3825. ;               Clear the UART of any extraneous characters
  3826. ;       ===============================================================
  3827.  
  3828.                 MOV     [SI].Comm_DTR_RTS, CL
  3829. _Lk_notready:
  3830.                 MOV     DX, [SI].Comm_PortAddr
  3831.                 ADD     DX, LSR
  3832.                 IN      AL, DX
  3833.                 IONOP
  3834.                 TEST    AL, 01
  3835.                 JZ      check_iir
  3836.                 MOV     DX, [SI].Comm_PortAddr
  3837.                 ADD     DX, TX_RD_BUFF_DLLO
  3838.                 IN      AL, DX
  3839.         IONOP
  3840.         JMP    _Lk_notready
  3841. check_iir:
  3842.                 MOV     DX, [SI].Comm_PortAddr
  3843.         ADD    DX, IIR
  3844.         IN    AL, DX
  3845.         IONOP
  3846.         AND     AL,0Fh          ; recover bits 0-3 of IIR
  3847.         CMP    AL, 1        ; no ints pending
  3848.         JE    _Lk_ready
  3849.                 IONOP
  3850.                 MOV     DX, [SI].Comm_PortAddr
  3851.                 ADD     DX, MSR
  3852.                 IN      AL, DX
  3853.                 IONOP
  3854.                 IONOP
  3855.                 JMP     _Lk_notready
  3856.                 NOP                     ; REV 1.2 ECL0002
  3857.                 NOP                     ; REV 1.2 ECL0002
  3858. _Lk_ready:
  3859.  
  3860.  
  3861. ;       ===============================================================
  3862. ;               Setup the first initial buffer and point to first byte
  3863. ;       ===============================================================
  3864.  
  3865.                 MOV     [SI].Comm_Buffer_Count, 0
  3866.                 CALL    BUFFR_Gmem
  3867.                 JNC     _Lk_ok2
  3868.                 JMP     _Lk_error2
  3869. _Lk_ok2:
  3870.                 CALL    COMMS_Bufclr    ; Given DX:BX and SI
  3871.  
  3872. ;               Disable X-On and X-Off flow control processing
  3873.  
  3874.                 MOV     [SI].Comm_Xflags, 0
  3875.  
  3876.  
  3877. ;       ===============================================================
  3878. ;               Enable interrupts
  3879. ;       ===============================================================
  3880.  
  3881. ;       ===============================================================
  3882. ;               Install the new IREQ interrupt handler
  3883. ;       ===============================================================
  3884.  
  3885.  
  3886. ;*** formerly macro     SI_Link                         ; Rev 2.0
  3887.  
  3888. ;SI_Link         MACRO        ; Given SI, store Interrupt link addr in vector
  3889.                                 ; and return in DX:BX the previous contents
  3890.  
  3891.  
  3892.                 ; I/O is repeated twice to make up for
  3893.                 ; some wierdness with 8259's.
  3894.                 ; We needed it on 12Mhz, 0 wait 286.
  3895.                 ; In any event, it does no harm.
  3896.  
  3897.                 IN      AL, ICA                 ; Enable 8259 channel
  3898.                 IONOP
  3899.                 IONOP
  3900.                 IN      AL, ICA                 ; Enable 8259 channel
  3901.                 IONOP
  3902.         IONOP
  3903.         PUSH    AX
  3904.         MOV    AX, port_hold
  3905.         SHL    AX, 1        ; mul port by 2 for cmp
  3906.  
  3907.         CMP    AX, starting_port  ; if multiport, use shared logic
  3908.         POP    AX
  3909.         JGE    shared_logic
  3910.         JMP    no_shared
  3911. shared_logic:
  3912.         PUSH    AX
  3913.         MOV    AX, port_hold
  3914.         SHL    AX, 1        ; mul port by 2 for cmp
  3915.  
  3916.         CMP    AX, starting2_port  ; if multiport number 2
  3917.         POP    AX
  3918.         JL    j1    ;jump out of range
  3919.         JMP    shared2_logic
  3920. j1:
  3921.  
  3922.         CMP    multi_init, 0
  3923.         JE    shared_10
  3924.  
  3925.                 MOV     BX, [SI].Comm_unit
  3926.                 MOV     WORD PTR Port_Status[BX], STATUS_INTERRUP
  3927.  
  3928.         JMP    Link_10
  3929. shared_10:
  3930.         MOV    multi_init, 1        ; set flag
  3931.         MOV    multi_unlinked, 0    ; force reset of unlink flag
  3932.         AND    AL, Shared_IC_mask
  3933.                 OUT     ICA, AL
  3934.                 IONOP
  3935.                 IONOP
  3936.                 OUT     ICA, AL
  3937.                 IONOP
  3938.                 IONOP
  3939.  
  3940.  
  3941.                 MOV     AL, Shared_vector    ; Move over vector
  3942. ;*******                MOV     BX, [SI].Comm_New_offset
  3943. ;*******                MOV     DX, [SI].Comm_New_segment
  3944.         MOV    BX, Shared_New_IntOffset
  3945.         MOV    DX, Shared_New_IntSegment
  3946.                 swapvec
  3947. ;******  silink below was from original AST.AST where status port
  3948. ;******  had to be initialized to turn on interrupts
  3949. silink:
  3950.  
  3951. ;********                MOV     [SI].Comm_Old_IntOffset, BX
  3952. ;********                MOV     [SI].Comm_Old_IntSegment, DX
  3953.                 MOV     Shared_Old_IntOffset, BX
  3954.                 MOV     Shared_Old_IntSegment, DX
  3955.  
  3956.                 MOV     BX, [SI].Comm_unit
  3957.                 MOV     WORD PTR Port_Status[BX], STATUS_INTERRUP
  3958.  
  3959.         CMP    board_type, AST    ; is this AST in "expanded mode"
  3960.         JE    j2            ; jump out of range
  3961.         CMP    board_type, ASTCMP ; is this AST in "compatible mode"
  3962.         JE    j2            ; jump out of range
  3963.         JMP    Link_10            ; skip if not
  3964. j2:        PUSH    DX            ; otherwise init status port
  3965.         PUSH    AX
  3966.         MOV    DX, Status_port
  3967.         MOV    AL, 8fh
  3968.         OUT    DX, AL
  3969.         POP    AX
  3970.         POP    DX
  3971.  
  3972. ;
  3973. ;        ENDM
  3974. ;
  3975.         JMP    Link_10
  3976.  
  3977. shared2_logic:
  3978.         CMP    multi2_init, 0
  3979.         JE    shared2_10
  3980.                 MOV     BX, [SI].Comm_unit
  3981.                 MOV     WORD PTR Port_Status[BX], STATUS_INTERRUP
  3982.  
  3983.         JMP    Link_10
  3984. shared2_10:
  3985.         MOV    multi2_init, 1        ; set flag
  3986.         MOV    multi2_unlinked, 0    ; force reset of unlink flag
  3987.         AND    AL, Shared2_IC_mask
  3988.                 OUT     ICA, AL
  3989.                 IONOP
  3990.                 IONOP
  3991.                 OUT     ICA, AL
  3992.                 IONOP
  3993.                 IONOP
  3994.  
  3995.  
  3996.                 MOV     AL, Shared2_vector    ; Move over vector
  3997. ;*******                MOV     BX, [SI].Comm_New_offset
  3998. ;*******                MOV     DX, [SI].Comm_New_segment
  3999.         MOV    BX, Shared2_New_IntOffset
  4000.         MOV    DX, Shared2_New_IntSegment
  4001.                 swapvec
  4002. ;******  silink below was from original AST.AST where status port
  4003. ;******  had to be initialized to turn on interrupts
  4004. silink2:
  4005.                 MOV     BX, [SI].Comm_unit
  4006.                 MOV     WORD PTR Port_Status[BX], STATUS_INTERRUP
  4007.  
  4008. ;********                MOV     [SI].Comm_Old_IntOffset, BX
  4009. ;********                MOV     [SI].Comm_Old_IntSegment, DX
  4010.                 MOV     Shared2_Old_IntOffset, BX
  4011.                 MOV     Shared2_Old_IntSegment, DX
  4012.  
  4013.         CMP    board2_type, AST        ; is this AST 4 port DOS
  4014.         JE    comms_j1            ; jump out of range
  4015.         CMP    board2_type, ASTCMP     ; is this AST 4 port DOS
  4016.         JE    comms_j1            ; jump out of range
  4017.         JNE    Link_10            ; skip if not
  4018. comms_j1:
  4019.         PUSH    DX            ; otherwise init status port
  4020.         PUSH    AX
  4021.         MOV    DX, Status2_port
  4022.         MOV    AL, 8fh
  4023.         OUT    DX, AL
  4024.         POP    AX
  4025.         POP    DX
  4026.  
  4027. ;
  4028. ;        ENDM
  4029. ;
  4030.         JMP    SHORT    Link_10
  4031. no_shared:
  4032.         AND     AL, [SI].Comm_IC_Mask
  4033.                 OUT     ICA, AL
  4034.                 IONOP
  4035.                 IONOP
  4036.                 OUT     ICA, AL
  4037.                 IONOP
  4038.                 IONOP
  4039.  
  4040.  
  4041.                 MOV     AL, [SI].Comm_vector    ; Move over vector
  4042.                 MOV     BX, [SI].Comm_New_offset
  4043.                 MOV     DX, [SI].Comm_New_segment
  4044.                 swapvec
  4045. ;                ENDM
  4046.  
  4047.  
  4048.                 MOV     [SI].Comm_Old_IntOffset, BX
  4049.                 MOV     [SI].Comm_Old_IntSegment, DX
  4050.  
  4051. Link_10:
  4052.  
  4053.  
  4054.                 MOV     DX, [SI].Comm_PortAddr
  4055.         CMP    DX, 0
  4056.         JE    _Lk_exit    ; get out if no uart here
  4057.                 ADD     DX, MCR
  4058.         PUSH    AX
  4059.         MOV    AX, port_hold
  4060.         SHL    AX, 1        ; mul port by 2 for cmp
  4061.  
  4062.         CMP    AX, starting_port  ; if multiport, use shared logic
  4063.         POP    AX
  4064.         MOV    CX, 08        ;default to turn on out2 of MCR
  4065.                     ;for standard com ports
  4066.         JL    Link_25
  4067.                 MOV     CX, out2_variable   ; out2 on/off code for multiports
  4068. Link_25:
  4069. ;        MOV    CH, 0bh        ;2.0a  Enable TX/RX/MODEM ints
  4070.         mov    ch, 0Fh        ;4.0   Enable TX/RX/MODEM/linestatus ints
  4071.  
  4072.                 CMP     [SI].Comm_DTR_RTS, 0
  4073.                 JE      _Lk_skip1
  4074.                 OR      CL, 03h                 ; Raise DTR, and RTS
  4075. _Lk_skip1:
  4076.                 IN      AL, DX
  4077.                 IONOP
  4078.                 OR      AL, CL  ;****** 2.0a  (Maybe Raise OUT2  DTR,RTS)
  4079.                 OUT     DX, AL
  4080.  
  4081.                 MOV     DX, [SI].Comm_PortAddr
  4082.                 ADD     DX, IER_DLHI
  4083.                 MOV     AL, CH                 ; Rev 2.0a Enable interrupts
  4084.  
  4085.                 OUT     DX, AL
  4086.  
  4087.                 MOV     [SI].Comm_State, INTERCEPTED
  4088.                 MOV     AL, 00h
  4089.                 CLC
  4090.                 JMP     SHORT _Lk_exit
  4091. _Lk_error:
  4092.                 MOV     AL, 0FFh
  4093.                 JMP     _Lk_errrr
  4094. _Lk_error2:
  4095.                 MOV     AL, 0FEh
  4096. _Lk_errrr:
  4097.                 STC
  4098. _Lk_exit:
  4099.                 POP     DX
  4100.                 POP     CX
  4101.                 POP     BX
  4102.                 POP     SI
  4103.  
  4104.                 RET
  4105. COMMS_Link      ENDP
  4106.  
  4107. COMMS_UnLink    PROC NEAR
  4108.                 PUSH    SI
  4109.                 PUSH    BX
  4110.                 PUSH    CX
  4111.                 PUSH    DX
  4112.         MOV    port_hold, DX
  4113.  
  4114.                 Load_SI                         ; Load SI with Comms_Str
  4115.                 CMP     [SI].Comm_State, INTERCEPTED
  4116.                 JE      _Ul_ok
  4117.                 JMP     _Ul_error
  4118. _Ul_ok:
  4119.                 MOV     [SI].Comm_State, NATIVE
  4120.  
  4121. ;       ===============================================================
  4122. ;               Disable communications interface
  4123. ;       ===============================================================
  4124.  
  4125.                 MOV     DX, [SI].Comm_PortAddr  ; Disable ALL interrupts
  4126.         CMP    DX, 0
  4127. ;***        JE    _no_uart    ; out of range
  4128.         JNE    _Ul_10
  4129.         JMP    _no_uart
  4130. _Ul_10:
  4131.                 ADD     DX, IER_DLHI
  4132.                 XOR     AL, AL
  4133.                 OUT     DX, AL
  4134.                 IONOP
  4135.  
  4136.                 MOV     DX, [SI].Comm_PortAddr  ; Deassert DSR, DTR
  4137.                 ADD     DX, MCR
  4138.                 IN      AL, DX
  4139.                 IONOP
  4140.                 AND     AL, 03h                 ; Clear out OUT1, OUT2
  4141.                 OUT     DX, AL
  4142.                 IONOP
  4143.  
  4144. ;       ===============================================================
  4145. ;               Reset IREQx Interrupt vector
  4146. ;       ===============================================================
  4147.  
  4148.  
  4149. ; formerly macro  SI_UnLink           ; Rev 2.0 disable 8259, vector
  4150.  
  4151.  
  4152. ;SI_UnLink       MACRO                   ; Given SI, store previous interrupt vector
  4153.                                         ; DX:BX are returned unmodified
  4154.  
  4155.                                         ; Disable 8259 first (COM1 and COM2 are unique)
  4156.         MOV    AX, port_hold
  4157.         SHL    AX, 1        ; mul. by 2 for cmp
  4158.         CMP    AX, starting_port
  4159.         JGE    shared_logic2
  4160.                 MOV     CL, [SI].Comm_IC_Mask
  4161.                 NOT     CL
  4162.                 IN      AL, ICA
  4163.                 IONOP
  4164.                 OR      AL, CL
  4165.                 OUT     ICA, AL
  4166.                 IONOP
  4167.  
  4168.  
  4169.                 MOV     AL, [SI].Comm_vector
  4170.                 MOV     BX, [SI].Comm_Old_IntOffset
  4171.                 MOV     DX, [SI].Comm_Old_IntSegment
  4172.                 setvec
  4173.         JMP    _no_uart
  4174.  
  4175. ;                ENDM
  4176.  
  4177. shared_logic2:
  4178.         CMP    multi_unlinked, 0
  4179.         JE    shared_logic2_10
  4180.         MOV    AX, port_hold
  4181.         SHL    AX, 1        ; mul. by 2 for cmp
  4182.         CMP    AX, starting2_port
  4183.         JGE    shared2_logic2
  4184.  
  4185.             JMP    _no_uart
  4186.  
  4187. shared_logic2_10:
  4188.         MOV    multi_unlinked, 1
  4189.         MOV    multi_init, 0        ; clear for linking again
  4190.                 MOV     CL, Shared_IC_mask
  4191.                 NOT     CL
  4192.                 IN      AL, ICA
  4193.                 IONOP
  4194.                 OR      AL, CL
  4195.                 OUT     ICA, AL
  4196.                 IONOP
  4197.  
  4198.  
  4199.                 MOV     AL, Shared_vector
  4200. ;******                MOV     BX, [SI].Comm_Old_IntOffset
  4201. ;******                MOV     DX, [SI].Comm_Old_IntSegment
  4202.                 MOV     BX, Shared_Old_IntOffset
  4203.                 MOV     DX, Shared_Old_IntSegment
  4204.                 setvec
  4205. ;******        JMP    SHORT _no_uart
  4206.  
  4207.  
  4208. ;*******  si_unlink below from original multiport asm files
  4209. ;*******
  4210. siunlink:
  4211. ;SI_UnLink       MACRO                   ; Given SI, store previous interrupt vector
  4212.                                         ; DX:BX are returned unmodified
  4213.         PUSH    AX
  4214.         PUSH    BX
  4215.         PUSH    DX
  4216.                 MOV     BX, [SI].Comm_unit
  4217.                 MOV     WORD PTR Port_Status[BX], STATUS_POLLED
  4218.         MOV    DX, Status_port
  4219.         CMP    board_type, AST        ; is this AST 4 port DOS
  4220.         JNE    Unlink_10            ; skip if not
  4221. ;*****        MOV    AL,0Fh
  4222. ;*****        OUT    DX,AL
  4223. Unlink_10:
  4224.         POP    DX
  4225.         POP    BX
  4226.         POP    AX
  4227.             JMP    _no_uart
  4228. ;                ENDM
  4229.  
  4230. shared2_logic2:
  4231.         CMP    multi2_unlinked, 0
  4232.         JE    shared2_logic2_10
  4233.             JMP    _no_uart
  4234.  
  4235. shared2_logic2_10:
  4236.         MOV    multi2_unlinked, 1
  4237.         MOV    multi2_init, 0        ; clear for linking again
  4238.                 MOV     CL, Shared2_IC_mask
  4239.                 NOT     CL
  4240.                 IN      AL, ICA
  4241.                 IONOP
  4242.                 OR      AL, CL
  4243.                 OUT     ICA, AL
  4244.                 IONOP
  4245.  
  4246.  
  4247.                 MOV     AL, Shared2_vector
  4248. ;******                MOV     BX, [SI].Comm_Old_IntOffset
  4249. ;******                MOV     DX, [SI].Comm_Old_IntSegment
  4250.                 MOV     BX, Shared2_Old_IntOffset
  4251.                 MOV     DX, Shared2_Old_IntSegment
  4252.                 setvec
  4253. ;******        JMP    SHORT _no_uart
  4254.  
  4255.  
  4256. ;*******  si_unlink below from original multiport asm files
  4257. ;*******
  4258. ;SI_UnLink       MACRO                   ; Given SI, store previous interrupt vector
  4259.                                         ; DX:BX are returned unmodified
  4260.         PUSH    AX
  4261.         PUSH    BX
  4262.         PUSH    DX
  4263.                 MOV     BX, [SI].Comm_unit
  4264.                 MOV     WORD PTR Port_Status[BX], STATUS_POLLED
  4265.         MOV    DX, Status_port
  4266.         CMP    board2_type, AST        ; is this AST 4 port DOS
  4267.         JNE    Unlink2_10            ; skip if not
  4268. ;*****        MOV    AL,0Fh
  4269. ;*****        OUT    DX,AL
  4270. Unlink2_10:
  4271.         POP    DX
  4272.         POP    BX
  4273.         POP    AX
  4274. ;                ENDM
  4275.  
  4276.  
  4277. _no_uart:
  4278.  
  4279.                 STI                             ; Enable the interrupts
  4280.  
  4281. ;       ===============================================================
  4282. ;               Disable X-On and X-Off flow control processing
  4283. ;               Return all used buffers back into the pool
  4284. ;               [Data receive interrupts are disabled, so links will remain]
  4285. ;       ===============================================================
  4286.  
  4287.  
  4288.                 MOV     [SI].Comm_Xflags, 0     ; CLEAR ALL XON/XOFF STATUS
  4289.                 CALL    COMMS_Buffree
  4290.                 MOV     AX, 00
  4291.                 CLC
  4292.                 JMP     SHORT _Ul_exit
  4293. _Ul_error:
  4294.                 MOV     AL, 0FFh
  4295.                 STC
  4296. _Ul_exit:
  4297.                 POP     DX
  4298.                 POP     CX
  4299.                 POP     BX
  4300.                 POP     SI
  4301.                 RET
  4302. COMMS_UnLink    ENDP
  4303.  
  4304. ;
  4305. ;       ===============================================================
  4306. ;       COMMS_Bufclr    Clear the receive buffer data base (used by COMMS_Flush)
  4307. ;       ===============================================================
  4308. ;
  4309. ;       Given the buffer address in DX:BX, initialize the data base
  4310. ;       so that it appears that there is no data received.
  4311. ;       The XON/XOFF and other status is not changed!
  4312. ;
  4313. ;       Input           Description
  4314. ;       --------------  ---------------------------
  4315. ;       DS, CS          XBIOS CSEG[ment]
  4316. ;       SI              Pointer to communications database
  4317. ;       DX:BX           Pointer to the first buffer block
  4318. ;
  4319. ;       Output          Description
  4320. ;       --------------  ---------------------------
  4321. ;       Not applicable
  4322. ;
  4323. ;       Registers used  Description
  4324. ;       --------------  ---------------------------
  4325. ;       Not applicable
  4326. ;       ===============================================================
  4327. ;
  4328.  
  4329. COMMS_Bufclr    PROC    NEAR
  4330.                 MOV     [SI].Comm_Buffer_Count, 1
  4331.                 MOV     [SI].Comm_CR_BUFFR_Offset, BX
  4332.                 MOV     [SI].Comm_RD_BUFFR_Offset, BX
  4333.                 MOV     [SI].Comm_CR_BUFFR_Segment, DX
  4334.                 MOV     [SI].Comm_RD_BUFFR_Segment, DX
  4335.                 MOV     [SI].Comm_CR_BUFFR_Index, 4
  4336.                 MOV     [SI].Comm_RD_BUFFR_Index, 4
  4337.  
  4338.                 MOV     WORD PTR [SI].Comm_Receive_Count, 0
  4339.                 MOV     WORD PTR [SI].Comm_Receive_Count+2, 0
  4340.                 MOV     WORD PTR [SI].Comm_Error, 0
  4341.                 MOV     BYTE PTR [SI].Comm_Break, 0
  4342.                 RET
  4343. COMMS_Bufclr    ENDP
  4344.  
  4345. ;
  4346. ;       ===============================================================
  4347. ;       COMMS_Buffree   Return the buffer pool (used by COMMS_Flush)
  4348. ;       ===============================================================
  4349. ;
  4350. ;       Given the buffer address in DX:BX, initialize the data base
  4351. ;       so that it appears that there is no data received.
  4352. ;       The XON/XOFF and other status is not changed!
  4353. ;
  4354. ;       Input           Description
  4355. ;       --------------  ---------------------------
  4356. ;       DS, CS          XBIOS CSEG[ment]
  4357. ;       SI              Pointer to communications database
  4358. ;
  4359. ;       Output          Description
  4360. ;       --------------  ---------------------------
  4361. ;       Not applicable
  4362. ;
  4363. ;       Registers used  Description
  4364. ;       --------------  ---------------------------
  4365. ;       Not applicable
  4366. ;       ===============================================================
  4367. ;
  4368.  
  4369. COMMS_Buffree   PROC NEAR
  4370.                 MOV     CX, [SI].Comm_Buffer_Count
  4371.                 MOV     BX, [SI].Comm_RD_BUFFR_Offset
  4372.                 MOV     DX, [SI].Comm_RD_BUFFR_Segment
  4373.                 PUSH    ES
  4374. _put_em_back:                                   ; DX:BX buffer, scratch ES,AX
  4375.                 MOV     ES, DX
  4376.                 MOV     AX, ES:[BX]             ; Get next buffer link offset
  4377.                 PUSH    AX
  4378.                 MOV     AX, ES:[BX+2]           ; Get next buffer link segment
  4379.                 PUSH    AX
  4380.                 CALL    BUFFR_Pmem
  4381.                 POP     DX
  4382.                 POP     BX
  4383.                 DEC     [SI].Comm_Buffer_Count
  4384.                 LOOP    _put_em_back            ; Return the next buffer
  4385.                 POP     ES
  4386.                 XOR     AX, AX
  4387.                 MOV     WORD PTR [SI].Comm_Receive_Count, AX
  4388.                 MOV     WORD PTR [SI].Comm_Receive_Count + 2, AX
  4389.                 CLC
  4390.                 RET
  4391. COMMS_Buffree   ENDP
  4392.  
  4393. ;
  4394. ;       ===============================================================
  4395. ;       COMMS_Flush     Clear the receive buffers (leave modes intact!)
  4396. ;       ===============================================================
  4397. ;
  4398. ;
  4399. ;       Input           Description
  4400. ;       --------------  ---------------------------
  4401. ;       DS, CS          XBIOS CSEG[ment]
  4402. ;       SI              Pointer to communications database
  4403. ;
  4404. ;       Output          Description
  4405. ;       --------------  ---------------------------
  4406. ;       Not applicable
  4407. ;
  4408. ;       Registers used  Description
  4409. ;       --------------  ---------------------------
  4410. ;       Not applicable
  4411. ;       ===============================================================
  4412. ;
  4413. COMMS_Flush     PROC    NEAR
  4414.                 PUSH    SI
  4415.                 Load_SI                         ; Load SI with Comms_Str
  4416.                 CMP     [SI].Comm_State, INTERCEPTED
  4417.                 JE      _init_buffers          ; NATIVE POLLED MODE
  4418.                 MOV     DX, [SI].Comm_PortAddr
  4419.                 IN      AL, DX
  4420.                 IONOP
  4421.                 MOV     DX, [SI].Comm_PortAddr
  4422.                 IN      AL, DX
  4423.                 IONOP
  4424.                 JMP     SHORT   _flush_exit
  4425.  
  4426. _init_buffers:                                  ; INTERRUPT MODE
  4427.                 CLI                             ; Clear interrupts
  4428.  
  4429. ;    Check if our UART mode indicates FIFOs are enabled
  4430. ;    Allowable values for bits 0 to 3 of "COMM_UART_Mode" are:
  4431. ;    0 = 16440 (16550 Character) mode
  4432. ;    1 = 16550 FIFOs enabled, DMA mode 0
  4433. ;    9 = 16550 FIFOs enabled, DMA mode 1 (This mode is not used)
  4434.  
  4435.         test    [si].COMM_UART_Mode, 09h 
  4436.         jz    _flush_continue    ; FIFOs not present or not enabled
  4437.  
  4438. ;    Clear Receive FIFO by writing a 1 to bit 1 of the UART's FCR
  4439.                 mov     dx, [si].Comm_PortAddr
  4440.         add    dx, 2                   ; DX points to FCR or IIR
  4441.                 mov     ax, [si].COMM_UART_Mode
  4442.         or      ax, 02h         ; Enable bit 1 of UART's FCR
  4443.         out    dx, al            ; clear Receive FIFO
  4444.                 IONOP
  4445.  
  4446. _flush_continue:
  4447.                 CALL    COMMS_Buffree           ; Return all buffers
  4448.                 CALL    BUFFR_Gmem              ; Return the first buffer
  4449.                 CALL    COMMS_Bufclr            ; And initialize the database
  4450. _flush_exit:
  4451.                 MOV     AX, 0                   ; Assume all works!
  4452.                 CLC
  4453.                 STI                             ; Enable interrupts
  4454.                 POP     SI
  4455.                 RET
  4456. COMMS_Flush     ENDP
  4457.  
  4458.  
  4459. ;
  4460. ;       ===============================================================
  4461. ;       COMMS_Status    Return the link status
  4462. ;       ===============================================================
  4463. ;
  4464. ;       Input           Description
  4465. ;       --------------  ---------------------------
  4466. ;       DS, CS          XBIOS CSEG[ment]
  4467. ;       DX              Unit number (COM1 = 00h, COM2 = 01h)
  4468. ;
  4469. ;       Output          Description
  4470. ;       --------------  ---------------------------
  4471. ;       AX = 00h,       Native
  4472. ;       AX = 01h,       Intercepted
  4473. ;         CX            Number of bytes received (low part)
  4474. ;         DX            " (high part)
  4475. ;
  4476. ;       Registers used  Description
  4477. ;       --------------  ---------------------------
  4478. ;       AX, CX, DX
  4479. ;       ===============================================================
  4480. ;
  4481. COMMS_Status    PROC NEAR
  4482.                 PUSH    SI
  4483.                 Load_SI                         ; Load SI with Comms_Str
  4484.                 MOV     AX, [SI].Comm_State
  4485.                 CMP     AL, INTERCEPTED
  4486.                 JNE     _ST_intercept
  4487.                 MOV     CX, WORD PTR [SI].Comm_Receive_Count
  4488.                 MOV     DX, WORD PTR [SI].Comm_Receive_Count+2
  4489.                 JMP     SHORT   _ST_exit
  4490. _ST_intercept:
  4491.                 PUSH    AX
  4492.                 MOV     DX, [SI].Comm_PortAddr
  4493.                 ADD     DX, LSR
  4494.                 IN      AL, DX
  4495.                 MOV     CX, 0
  4496.                 MOV     DX, CX
  4497.                 TEST    AL, 01h
  4498.                 JZ      _ST_intercept1
  4499.                 INC     CX
  4500. _ST_intercept1:
  4501.                 POP     AX
  4502. _ST_exit:
  4503.                 POP     SI
  4504.                 RET
  4505. COMMS_Status    ENDP
  4506.  
  4507. ;
  4508. ;       ===============================================================
  4509. ;       COMMS_DTRon     Enable Data Terminal Ready
  4510. ;       COMMS_DTRoff    Disable Data Terminal Ready
  4511. ;       COMMS_DTRget    Return status of Data Terminal Ready
  4512. ;       ===============================================================
  4513. ;
  4514. ;       Input           Description
  4515. ;       --------------  ---------------------------
  4516. ;       DS, CS          XBIOS CSEG[ment]
  4517. ;       DX              Unit number (COM1 = 00h, COM2 = 01h)
  4518. ;
  4519. ;       Output          Description
  4520. ;       --------------  ---------------------------
  4521. ;       AX              modified
  4522. ;
  4523. ;       Registers used  Description
  4524. ;       --------------  ---------------------------
  4525. ;       AL              Port value
  4526. ;       DX              Port address
  4527. ;       SI              COMMS structure base address
  4528. ;       ===============================================================
  4529. ;
  4530.  
  4531.  
  4532. COMMS_DTRon     PROC    NEAR
  4533.                 PUSH    SI
  4534.                 Load_SI                         ; Load SI with Comms_Str
  4535.                                                 ; Read in current setting
  4536.                 PUSH    DX
  4537.                 MOV     DX, [SI].Comm_PortAddr
  4538.                 ADD     DX, MCR
  4539.                 IN      AL, DX
  4540.                 IONOP
  4541.                 OR      AL, 001h                ; Set the DTR bit
  4542.                 OUT     DX, AL
  4543.                 IONOP
  4544.                 POP     DX
  4545.                 POP     SI
  4546.                 RET
  4547. COMMS_DTRon     ENDP
  4548.  
  4549. COMMS_DTRoff    PROC    NEAR
  4550.                 PUSH    SI
  4551.                 Load_SI                         ; Load SI with Comms_Str
  4552.                 PUSH    DX
  4553.                 MOV     DX, [SI].Comm_PortAddr
  4554.                 ADD     DX, MCR
  4555.                 IN      AL, DX
  4556.                 IONOP
  4557.                 AND     AL, 0FEh                ; Clear the DTR bit
  4558.                 OUT     DX, AL
  4559.                 IONOP
  4560.                 POP     DX
  4561.                 POP     SI
  4562.                 RET
  4563. COMMS_DTRoff    ENDP
  4564.  
  4565. COMMS_DTRget    PROC    NEAR
  4566.                 PUSH    SI
  4567.                 Load_SI                         ; Load SI with Comms_Str
  4568.                                                 ; Read in current setting
  4569.                 PUSH    DX
  4570.                 MOV     DX, [SI].Comm_PortAddr
  4571.                 ADD     DX, MCR
  4572.                 IN      AL, DX
  4573.                 IONOP
  4574.                 AND     AL, 001h                ; Set the DTR bit
  4575.                 MOV     AH, 00h
  4576.                 POP     DX
  4577.                 POP     SI
  4578.                 RET
  4579. COMMS_DTRget    ENDP
  4580.  
  4581.  
  4582. ;
  4583. ;       ===============================================================
  4584. ;       COMMS_RTSon     Enable Request to Send
  4585. ;       COMMS_RTSoff    Disable Request to Send
  4586. ;       COMMS_RTSget    Return status of RTS
  4587. ;       ===============================================================
  4588. ;
  4589. ;       Input           Description
  4590. ;       --------------  ---------------------------
  4591. ;       DS, CS          XBIOS CSEG[ment]
  4592. ;       DX              Unit number (COM1 = 00h, COM2 = 01h)
  4593. ;
  4594. ;       Output          Description
  4595. ;       --------------  ---------------------------
  4596. ;       AX              modified
  4597. ;
  4598. ;       Registers used  Description
  4599. ;       --------------  ---------------------------
  4600. ;       AL              Port value
  4601. ;       DX              Port address
  4602. ;       SI              COMMS structure base address
  4603. ;       ===============================================================
  4604. ;
  4605.  
  4606. COMMS_RTSon     PROC    NEAR
  4607.                 PUSH    SI
  4608.                 Load_SI                         ; Load SI with Comms_Str
  4609.                 PUSH    DX
  4610.                 MOV     DX, [SI].Comm_PortAddr
  4611.                 ADD     DX, MCR
  4612.                 IN      AL, DX
  4613.                 IONOP
  4614.                 OR      AL, 002h                ; Set the RTS bit
  4615.                 OUT     DX, AL
  4616.                 IONOP
  4617.                 POP     DX
  4618.                 POP     SI
  4619.                 RET
  4620. COMMS_RTSon     ENDP
  4621.  
  4622. COMMS_RTSoff    PROC    NEAR
  4623.                 PUSH    SI
  4624.                 Load_SI                         ; Load SI with Comms_Str
  4625.                 PUSH    DX
  4626.                 MOV     DX, [SI].Comm_PortAddr
  4627.                 ADD     DX, MCR
  4628.                 IN      AL, DX
  4629.                 IONOP
  4630.                 AND     AL, 0FDh                ; Clear the RTS bit
  4631.                 OUT     DX, AL
  4632.                 IONOP
  4633.                 POP     DX
  4634.                 POP     SI
  4635.                 RET
  4636. COMMS_RTSoff    ENDP
  4637.  
  4638.  
  4639. COMMS_RTSget    PROC    NEAR
  4640.                 PUSH    SI
  4641.                 Load_SI                         ; Load SI with Comms_Str
  4642.                 PUSH    DX
  4643.                 MOV     DX, [SI].Comm_PortAddr
  4644.                 ADD     DX, MCR
  4645.                 IN      AL, DX
  4646.                 IONOP
  4647.                 AND     AL, 002h                ; Set the RTS bit
  4648.                 SHR     AL, 1
  4649.                 MOV     AH, 0
  4650.                 POP     DX
  4651.                 POP     SI
  4652.                 RET
  4653. COMMS_RTSget    ENDP
  4654.  
  4655. ;       ===============================================================
  4656. ;       COMMS_BREAKon   Enable Line Break
  4657. ;       COMMS_BREAKoff  Disable Line Break
  4658. ;       ===============================================================
  4659. ;
  4660. ;       Input           Description
  4661. ;       --------------  ---------------------------
  4662. ;       DS, CS          XBIOS CSEG[ment]
  4663. ;       DX              Unit number (COM1 = 00h, COM2 = 01h)
  4664. ;
  4665. ;       Output          Description
  4666. ;       --------------  ---------------------------
  4667. ;       AX              modified
  4668. ;
  4669. ;       Registers used  Description
  4670. ;       --------------  ---------------------------
  4671. ;       AL              Port value
  4672. ;       DX              Port address
  4673. ;       SI              COMMS structure base address
  4674. ;       ===============================================================
  4675. ;
  4676. COMMS_BREAKon   PROC    NEAR
  4677.                 PUSH    SI
  4678.                 Load_SI                         ; Load SI with Comms_Str
  4679.                 PUSH    DX
  4680.                 MOV     DX, [SI].Comm_PortAddr
  4681.                 ADD     DX, LCR
  4682.                 IN      AL, DX
  4683.                 IONOP
  4684.                 OR      AL, 040h                ; Set the Break bit
  4685.                 OUT     DX, AL
  4686.                 IONOP
  4687.                 POP     DX
  4688.                 POP     SI
  4689.                 RET
  4690. COMMS_BREAKon   ENDP
  4691.  
  4692. COMMS_BREAKoff  PROC    NEAR
  4693.                 PUSH    SI
  4694.                 Load_SI                         ; Load SI with Comms_Str
  4695.                 PUSH    DX
  4696.                 MOV     DX, [SI].Comm_PortAddr
  4697.                 ADD     DX, LCR
  4698.                 IN      AL, DX
  4699.                 IONOP
  4700.                 AND     AL, 0BFh                ; Clear the break bit
  4701.                 OUT     DX, AL
  4702.                 IONOP
  4703.                 POP     DX
  4704.                 POP     SI
  4705.                 RET
  4706. COMMS_BREAKoff  ENDP
  4707.  
  4708. COMMS_BREAKget  PROC    NEAR
  4709.                 PUSH    SI
  4710.                 Load_SI                         ; Load SI with Comms_Str
  4711.                 PUSH    DX
  4712.                 MOV     DX, [SI].Comm_PortAddr
  4713.                 ADD     DX, LCR
  4714.                 IN      AL, DX
  4715.                 IONOP
  4716.                 AND     AL, 040h                ; Clear the break bit
  4717.                 MOV     AH, 00h
  4718.                 MOV     CL, 6
  4719.                 SHR     AL, CL
  4720.                 POP     DX
  4721.                 POP     SI
  4722.                 RET
  4723. COMMS_BREAKget  ENDP
  4724.  
  4725.  
  4726. ;
  4727. ;       ===============================================================
  4728. ;       COMMS_fc_on   Enable XON flow control (only in interrupt mode)
  4729. ;       COMMS_fc_off  Disable XON flow control (only in interrupt mode)
  4730. ;       ===============================================================
  4731. ;
  4732. ;       Input           Description
  4733. ;       --------------  ---------------------------
  4734. ;       DS, CS          XBIOS CSEG[ment]
  4735. ;       DL              Unit number (COM1 = 00h, COM2 = 01h)
  4736. ;    DH        3 for rec & tx, 1 for rec only, 2 for tx only
  4737. ;
  4738. ;       Output          Description
  4739. ;       --------------  ---------------------------
  4740. ;       AL              modified
  4741. ;         == 00h, CY=NC Successful disabling of flow control
  4742. ;       AL== FFh, CY=C  Interrupts not enabled
  4743. ;       AL== FEh, CY=C  Flow control was already enabled
  4744. ;       AL== FDh, CY=C  Low is >= high water mark
  4745. ;
  4746. ;       Registers used  Description
  4747. ;       --------------  ---------------------------
  4748. ;       DX              Port address
  4749. ;       SI              COMMS structure base address
  4750. ;       ===============================================================
  4751. ;
  4752. public COMMS_fc_on
  4753. COMMS_fc_on     PROC    NEAR
  4754.                 PUSH    SI
  4755.                 PUSH    DX
  4756.         XOR    DH, DH            ; DL has port number
  4757.         Load_SI                         ; Load SI with Comms_Str
  4758.                 MOV     AL, 0FFh                ; Assume interrupt error
  4759.                 CMP     [SI].Comm_State, INTERCEPTED
  4760.                 JNE     _fcon_error
  4761. ;***                MOV     AL, 0FEh                ; Assume flow control
  4762. ;***                CMP     [SI].Comm_Xflags, 0
  4763. ;***                JNE     _fcon_error
  4764.                 MOV     AL, 0FDh                ; Assume water marks error
  4765.                 CMP     CX, BX
  4766.                 JB      _fcon_error             ; (unsigned compare)
  4767.                                                 ; All is OK
  4768.                 MOV     [SI].Comm_Xflags, 01h
  4769.                 MOV     [SI].Comm_low, BX
  4770.                 MOV     [SI].Comm_high, CX
  4771.  
  4772.         POP    BX                ; bh has rec/tx indicator
  4773.         XOR     BL, BL
  4774.         MOV    BL, BH
  4775.         MOV    AX, BX
  4776.         AND    AX, 1            ; rec on ?
  4777.         JZ    test_tx
  4778.         OR    [SI].COMM_Xflags, FC_REC_ON
  4779. test_tx:
  4780.         MOV    AX, BX
  4781.         AND    AX, 2            ; rec on ?
  4782.         JZ    test_tx2
  4783.         OR    [SI].COMM_Xflags, FC_TX_ON
  4784. test_tx2:
  4785.  
  4786.  
  4787. ;
  4788. ;               Enable XON/XOFF routines
  4789. ;
  4790.                 SI_FCon
  4791.  
  4792.                 MOV     AL, 00h
  4793.                 CLC
  4794.                 JMP     SHORT   _fcon_exit
  4795. _fcon_error:
  4796.                 STC
  4797.         POP    BX
  4798. _fcon_exit:
  4799.                 POP     SI
  4800.                 RET
  4801. COMMS_fc_on     ENDP
  4802.  
  4803.  
  4804. ;
  4805. ;       ===============================================================
  4806. ;       COMMS_fc_off  Disable XON flow control (only in interrupt mode)
  4807. ;       ===============================================================
  4808. ;
  4809. ;       Input           Description
  4810. ;       --------------  ---------------------------
  4811. ;       DS, CS          XBIOS CSEG[ment]
  4812. ;       DL              Unit number (COM1 = 00h, COM2 = 01h)
  4813. ;    DH        3 for rec & tx, 1 for rec only, 2 for tx only
  4814. ;
  4815. ;       Output          Description
  4816. ;       --------------  ---------------------------
  4817. ;       AL              modified
  4818. ;         == 00h, CY=NC Successful disabling of flow control
  4819. ;       AL== FFh, CY=C  Interrupts not enabled
  4820. ;       AL== FEh, CY=C  Flow control wasn't even enabled
  4821. ;
  4822. ;       Registers used  Description
  4823. ;       --------------  ---------------------------
  4824. ;       DX              Port address
  4825. ;       SI              COMMS structure base address
  4826. ;       ===============================================================
  4827. ;
  4828.  
  4829. COMMS_fc_off    PROC    NEAR
  4830.                 PUSH    SI
  4831.                PUSH    DX
  4832.         XOR    DH, DH            ; dl has port number
  4833.         Load_SI                         ; Load SI with Comms_Str
  4834.                 MOV     AL, 0FFh                ; Assume interrupt error
  4835.                 CMP     [SI].Comm_State, INTERCEPTED
  4836.                 JNE     _fcoff_error
  4837. ;***                MOV     AL, 0FEh                ; Assume no flow control
  4838. ;***                TEST    [SI].Comm_Xflags, 1
  4839. ;***                JZ      _fcoff_error
  4840.                                                 ; All is OK
  4841.                 MOV     [SI].Comm_low, 0
  4842.                 MOV     [SI].Comm_high, 0
  4843. ;******         MOV     [SI].Comm_Xflags, 00h
  4844.  
  4845.         POP    BX                ; bh has rec/tx indicator
  4846.         XOR     BL, BL
  4847.         MOV    BL, BH
  4848.         MOV    AX, BX
  4849.         AND    AX, 1            ; rec off ?
  4850.         JZ    test_txoff
  4851.         AND    [SI].COMM_Xflags, NOT FC_REC_ON
  4852. test_txoff:
  4853.         MOV    AX, BX
  4854.         AND    AX, 2            ; rec on ?
  4855.         JZ    test_txoff2
  4856.         AND    [SI].COMM_Xflags, NOT FC_TX_ON
  4857. test_txoff2:
  4858.         MOV    AX, [SI].COMM_Xflags
  4859.         TEST    AX, FC_TX_ON or FC_REC_ON
  4860.         JNZ    fc_not_off
  4861.         MOV    [SI].COMM_Xflags, 0
  4862.  
  4863.                 SI_FCoff
  4864.  
  4865. fc_not_off:
  4866.                 CLC
  4867.                 MOV     AL, 00h
  4868.                 JMP     SHORT   _fcoff_exit
  4869. _fcoff_error:
  4870.                 STC
  4871.         POP    BX
  4872. _fcoff_exit:
  4873.                 POP     SI
  4874.                 RET
  4875. COMMS_fc_off    ENDP
  4876.  
  4877.  
  4878. ;
  4879. ;       ===============================================================
  4880. ;       COMMS_Gaddr     Return the address to the COMMS structure
  4881. ;       ===============================================================
  4882. ;
  4883. ;       Input           Description
  4884. ;       --------------  ---------------------------
  4885. ;       DL              Comm unit number
  4886. ;
  4887. ;       Output          Description
  4888. ;       --------------  ---------------------------
  4889. ;       DX:BX           Address of Comm's structure
  4890. ;
  4891.  
  4892. COMMS_Gaddr     PROC NEAR
  4893.                 PUSH    SI
  4894.  
  4895.                 Load_SI                         ; Load SI with Comms_Str
  4896.                 MOV     BX, SI
  4897.                 PUSH    CS
  4898.                 POP     DX
  4899.  
  4900.                 POP     SI
  4901.                 RET
  4902. COMMS_Gaddr     ENDP
  4903.  
  4904. ;
  4905. ;       ===============================================================
  4906. ;       COMMS_GPORT     Return the status of the communications port
  4907. ;       ===============================================================
  4908. ;       Available for external use (XC_TSR.ASM)
  4909. ;
  4910. ;       Input           Description
  4911. ;       --------------  ---------------------------
  4912. ;       DX              Desired port number
  4913. ;
  4914. ;       Output          Description
  4915. ;       --------------  ---------------------------
  4916. ;       AX = 0          OK, port exists
  4917. ;            1          OK, however, actual I/O port doesn't seem to exist
  4918. ;           -1          Port is not supported
  4919.  
  4920.                 PUBLIC  COMMS_GPORT
  4921. COMMS_GPORT     PROC NEAR
  4922.                 PUSH    SI
  4923.                 Load_SI
  4924.                 MOV     AX, -1                  ; Assume illegal port
  4925.  
  4926.                 CMP     DX, MAXPORTS            ; Return max ports
  4927.                 JGE     _gport_skip
  4928.  
  4929.                 MOV     DX, [SI].Comm_PortAddr  ; Test the port presence
  4930.                 ADD     DX, LCR                 ; Read the LCR
  4931.                 IN      AL, DX
  4932.                 IONOP
  4933.                 MOV     BH, AL                  ; Save the contents
  4934.  
  4935.                 INC     AL                      ; Modify the LCR
  4936.                 MOV     BL, AL
  4937.                 OUT     DX, AL
  4938.                 IONOP
  4939.                 MOV     AL, 0AAh                ; In case data doesn't latch
  4940.                 IN      AL, DX                  ; Read in the LCR again
  4941.  
  4942.                 CMP     AL, BL
  4943.                 JE      _gport_reset
  4944.                 MOV     AX, 1                   ; Not the same, exit
  4945.                 JMP     SHORT   _gport_skip
  4946. _gport_reset:
  4947.                 MOV     AL, BH                  ; Restore original LCR
  4948.                 OUT     DX, AL
  4949.                 MOV     AX, 0
  4950.                 IONOP
  4951. _gport_skip:
  4952.                 POP     SI
  4953.                 RET
  4954. COMMS_GPORT     ENDP
  4955.  
  4956. ;
  4957. ;       ===============================================================
  4958. ;       COMMS_Uxmit     Unpended block transmit
  4959. ;       ===============================================================
  4960. ;
  4961. ;       Input           Description
  4962. ;       --------------  ---------------------------
  4963. ;       CX              Count
  4964. ;       SI:BX           Address of transmit buffer
  4965. ;       DL              Communications unit
  4966. ;
  4967. ;       Output          Description
  4968. ;       --------------  ---------------------------
  4969. ;       AX              0 (successful)
  4970.  
  4971. public COMMS_Uxmit
  4972. COMMS_Uxmit     PROC NEAR
  4973.                 PUSH    ES
  4974.                 PUSH    SI
  4975.                 PUSH    SI
  4976.                 POP     ES
  4977.                 Load_SI                         ; Load SI with Comms_Str
  4978. _uxmit_loop:
  4979.                 CMP     [SI].Comm_xcount, 0     ; Transmission in progress?
  4980.                 JNE     _uxmit_loop             ; Yes - wait ...
  4981.  
  4982.     MOV     DX, [SI].Comm_PortAddr          ; read in THRE register    **XMIT*XON*FIX**
  4983.     ADD    DX,LSR                          ;                          **XMIT*XON*FIX**
  4984. _uxmit_loop2:                                   ;                          **XMIT*XON*FIX**
  4985.     IN    AL, DX                          ;                          **XMIT*XON*FIX**
  4986.            AND    AL, 20H                        ; isolate THRE             **XMIT*XON*FIX**
  4987.            CMP    AL, 20H                         ; last char xmitted?       **XMIT*XON*FIX**
  4988.     JNE     _uxmit_loop2                    ; no - wait ...            **XMIT*XON*FIX**
  4989.  
  4990.            CLI                                 ; disable interrupts       **XMIT*XON*FIX**
  4991.  
  4992. ; The following 4 lines were moved after "no_handshake:"
  4993. ;               INC     CX                      ; Always starts one greater
  4994. ;               MOV     [SI].Comm_xcount, CX
  4995. ;               MOV     [SI].Comm_xptr_Segment, ES
  4996. ;               MOV     [SI].Comm_xptr_Offset, BX
  4997.  
  4998.     TEST    [SI].Comm_Xflags,FC_TX_ON    ; Is flow control enabled? **XMIT*XON*FIX**
  4999.     JE    uxmit_no_fc             ; no - check handshaking   **XMIT*XON*FIX**
  5000.     TEST    [SI].Comm_Xflags,FC_XOFF_RCVD    ; Was XOFF received?       **XMIT*XON*FIX**
  5001.     JE    uxmit_no_fc             ; no - check handshaking   **XMIT*XON*FIX**
  5002.     MOV    AX, -1                          ;                          **XMIT*XON*FIX**
  5003.     JMP    err_return                      ;                          **XMIT*XON*FIX**
  5004.  
  5005.             ;********** 2.0a  added handshaking logic
  5006. uxmit_no_fc:                                                              ;**XMIT*XON*FIX**
  5007.         CMP    [SI].Comm_DTR_RTS, 0  ; Are we using handshaking
  5008.         JE    no_handshake
  5009.             MOV     DX, [SI].Comm_PortAddr ; Yes- read in modem status register to
  5010.         ADD    DX,MSR
  5011.             IN      AL, DX        ;    clear interrupt
  5012. ;    look for Hardware Handshaking flag
  5013.         and    al, [si].Comm_DTR_RTS ; look for CTS and/or DSR
  5014.         cmp    al, [si].Comm_DTR_RTS ; Unable to Xmit if Hardware Handshaking and CTS/DST not set
  5015. ;        AND    AL, 00110000B    ; look for CTS and DSR
  5016. ;        CMP    AL, 00110000B    ;
  5017.             JE    no_handshake    ; OK to proceed
  5018.            MOV    AX, -1
  5019.         JMP    err_return
  5020.  
  5021. no_handshake:
  5022.                 INC     CX                      ; Always starts one greater
  5023.                 MOV     [SI].Comm_xcount, CX
  5024.                 MOV     [SI].Comm_xptr_Segment, ES
  5025.                 MOV     [SI].Comm_xptr_Offset, BX
  5026.  
  5027.         SI_continue
  5028.                 MOV     AX, 0
  5029. err_return:
  5030.         STI                             ;re-enable interrupts      **XMIT*XON*FIX**
  5031.                 POP     SI
  5032.                 POP     ES
  5033.                 RET
  5034. COMMS_Uxmit     ENDP
  5035.  
  5036.  
  5037. ;
  5038. ;       ===============================================================
  5039. ;       COMMS_FASTR     Fast read of the input buffer
  5040. ;       ===============================================================
  5041. ;
  5042. ;       Input           Description
  5043. ;       --------------  ---------------------------
  5044. ;       CX              Count
  5045. ;       SI:BX           Address of user's buffer
  5046. ;       DL              Communications unit
  5047. ;
  5048. ;       Output          Description
  5049. ;       --------------  ---------------------------
  5050. ;       DX              0 (successful)
  5051.  
  5052. COMMS_FASTR     PROC NEAR
  5053.                 PUSH    ES
  5054.                 PUSH    DI
  5055.                 PUSH    SI
  5056.                 PUSH    SI
  5057.                 POP     ES                      ; ES:BX points to user's buffer
  5058.                 Load_SI                         ; Load SI with Comms_Str
  5059.                 MOV     DI, BX
  5060.                 XOR     DX, DX                  ; DX actual, CX expected count
  5061. _Fastr_loop:
  5062.                 MOV     AX, WORD PTR [SI].Comm_Receive_Count
  5063.                 OR      AX, WORD PTR [SI].Comm_Receive_Count+2
  5064.                 JZ      _Fastr_exit
  5065.  
  5066.                 PUSH    CX
  5067.                 PUSH    DX
  5068.                 PUSH    ES
  5069.                 CALL    _Rd_getchar
  5070.                 POP     ES
  5071.                 POP     DX
  5072.                 POP     CX
  5073.                 STOSB                   ; Save the character
  5074.                 INC     DX              ; Increment actual count read
  5075.                 LOOP    _Fastr_loop
  5076. _Fastr_exit:
  5077.                 MOV     AX, DX          ; Return the count
  5078.                 POP     SI
  5079.                 POP     DI
  5080.                 POP     ES
  5081.                 RET
  5082. COMMS_FASTR     ENDP
  5083.  
  5084.  
  5085. ;       ===============================================================
  5086. ;       COMMS_UTEST     Unpended block transmit
  5087. ;       ===============================================================
  5088. ;
  5089. ;       Input           Description
  5090. ;       --------------  ---------------------------
  5091. ;       DL              Communications unit
  5092. ;
  5093. ;       Output          Description
  5094. ;       --------------  ---------------------------
  5095. ;       AX              0 (all done)
  5096. ;                       != 0 (output still in progress)
  5097.  
  5098. COMMS_UTEST     PROC NEAR
  5099.                 PUSH    SI
  5100.                 Load_SI                         ; Load SI with Comms_Str
  5101.  
  5102.                 MOV     AX, [SI].Comm_xcount
  5103.  
  5104.                 POP     SI
  5105.                 RET
  5106. COMMS_UTEST     ENDP
  5107.  
  5108. ;       ===============================================================
  5109. ;       COMMS_UKILL    Unpended block transmit terminator
  5110. ;       ===============================================================
  5111. ;
  5112. ;       Input           Description
  5113. ;       --------------  ---------------------------
  5114. ;       DL              Communications unit
  5115. ;
  5116. ;       Output          Description
  5117. ;       --------------  ---------------------------
  5118. ;       Not applicable
  5119.  
  5120. COMMS_UKILL     PROC NEAR
  5121.                 PUSH    SI
  5122.                 Load_SI                         ; Load SI with Comms_Str
  5123.  
  5124. ;    Check if our UART mode indicates FIFOs are enabled
  5125. ;    Allowable values for bits 0 to 3 of "COMM_UART_Mode" are:
  5126. ;    0 = 16440 (16550 Character) mode
  5127. ;    1 = 16550 FIFOs enabled, DMA mode 0
  5128. ;    9 = 16550 FIFOs enabled, DMA mode 1 (This mode is not used)
  5129.         test    [si].COMM_UART_Mode, 09h 
  5130.         jz    _ukill_continue    ; FIFOs not present or not enabled
  5131.  
  5132. ;    Clear TX FIFO by writing a 1 to bit 2 of the UART's FCR
  5133.                 mov     dx, [si].Comm_PortAddr
  5134.         add    dx, 2                   ; DX points to FCR or IIR
  5135.                 mov     ax, [si].COMM_UART_Mode
  5136.         or      ax, 04h         ; Enable bit 2 of UART's FCR
  5137.                 mov     [si].Comm_xcount, 00    ; Clear XCOMMS TX buffer
  5138.         out    dx, al            ; clear TX FIFO
  5139.                 IONOP
  5140.  
  5141. _ukill_continue:
  5142.                 mov     [si].Comm_xcount, 00    ; Clear XCOMMS TX buffer
  5143.  
  5144.                 POP     SI
  5145.                 RET
  5146. COMMS_UKILL     ENDP
  5147.  
  5148.  
  5149. ;       ===============================================================
  5150. ;       COMMS_FCKILL   KILL ALL OF THE FLOW CONTROL DATA BASE
  5151. ;       ===============================================================
  5152. ;
  5153. ;       Clear the state bits except for the FC_ENABLED bit.
  5154. ;       If there was any transmission pended (waiting on XON)
  5155. ;       then "kick start" it and continue sending where it left
  5156. ;       off.
  5157. ;
  5158. ;       Input           Description
  5159. ;       --------------  ---------------------------
  5160. ;       DL              Communications unit
  5161. ;
  5162. ;       Output          Description
  5163. ;       --------------  ---------------------------
  5164. ;       Not applicable
  5165.  
  5166. COMMS_FCKILL    PROC NEAR
  5167.                 PUSH    SI
  5168.                 Load_SI                     ; Load SI with Comms_Str
  5169.  
  5170.                 AND     [SI].Comm_Xflags, FC_ENABLED
  5171.                 SI_continue                 ; Continue transmission
  5172.                 POP     SI
  5173.                 RET
  5174. COMMS_FCKILL    ENDP
  5175.  
  5176.  
  5177. ;       ===============================================================
  5178. ;       COMMS_XCTIMOU  Set the send/transmit timeout value
  5179. ;       ===============================================================
  5180. ;
  5181. ;       Input           Description
  5182. ;       --------------  ---------------------------
  5183. ;       DL              Communications unit
  5184. ;       CX              New timeout value (unsigned)
  5185. ;
  5186. ;       Output          Description
  5187. ;       --------------  ---------------------------
  5188. ;       Not applicable
  5189.  
  5190. COMMS_XCTIMOU   PROC NEAR
  5191.                 MOV     timeout_variable, CX
  5192.                 RET
  5193. COMMS_XCTIMOU   ENDP
  5194.  
  5195.  
  5196. ;       ===============================================================
  5197. ;       COMMS_OUT2  Set the out2 initialization value
  5198. ;       ===============================================================
  5199. ;
  5200. ;       Input           Description
  5201. ;       --------------  ---------------------------
  5202. ;       DL              Communications unit
  5203. ;       CX              New value (unsigned)
  5204. ;
  5205. ;       Output          Description
  5206. ;       --------------  ---------------------------
  5207. ;       Not applicable
  5208.  
  5209. COMMS_OUT2   PROC NEAR
  5210.                 MOV     out2_variable, CX
  5211.                 RET
  5212. COMMS_OUT2   ENDP
  5213.  
  5214. ;       ===============================================================
  5215. ;       COMMS_STATUS_PORT  Set the status port value
  5216. ;       ===============================================================
  5217. ;
  5218. ;       Input           Description
  5219. ;       --------------  ---------------------------
  5220. ;       DL              Communications unit
  5221. ;       CX              New value (unsigned)
  5222. ;
  5223. ;       Output          Description
  5224. ;       --------------  ---------------------------
  5225. ;       Not applicable
  5226.  
  5227. COMMS_STATUS_PORT   PROC NEAR
  5228.         CMP    DL, 0
  5229.         JE    firstboard4
  5230.         MOV    Status2_port, CX
  5231.         RET
  5232. firstboard4:
  5233.                 MOV     Status_port, CX
  5234.                 RET
  5235. COMMS_STATUS_PORT   ENDP
  5236.  
  5237. ;       ===============================================================
  5238. ;       COMMS_SHARED_VECTOR  Set the shared VECTOR value
  5239. ;       ===============================================================
  5240. ;
  5241. ;       Input           Description
  5242. ;       --------------  ---------------------------
  5243. ;       DL              Communications unit
  5244. ;       CX              New value (unsigned)
  5245. ;
  5246. ;       Output          Description
  5247. ;       --------------  ---------------------------
  5248. ;       Not applicable
  5249.  
  5250. COMMS_SHARED_VECTOR   PROC NEAR
  5251.         CMP    DL, 0
  5252.         JE    firstboard5
  5253.         MOV    Shared2_vector, CL
  5254.         RET
  5255. firstboard5:
  5256.                 MOV     Shared_vector, CL
  5257.                 RET
  5258. COMMS_SHARED_VECTOR   ENDP
  5259.  
  5260. ;       ===============================================================
  5261. ;       COMMS_SHARED_ICMASK  Set the shared ICMASK value
  5262. ;       ===============================================================
  5263. ;
  5264. ;       Input           Description
  5265. ;       --------------  ---------------------------
  5266. ;       DL              Communications unit
  5267. ;       CX              New value (unsigned)
  5268. ;
  5269. ;       Output          Description
  5270. ;       --------------  ---------------------------
  5271. ;       Not applicable
  5272.  
  5273. COMMS_SHARED_ICMASK   PROC NEAR
  5274.         CMP    DL, 0
  5275.         JE    firstboard6
  5276.         MOV    Shared2_IC_mask, CL
  5277.         RET
  5278. firstboard6:
  5279.                 MOV     Shared_IC_mask, CL
  5280.                 RET
  5281. COMMS_SHARED_ICMASK   ENDP
  5282.  
  5283. ;       ===============================================================
  5284. ;       COMMS_BOARD_TYPE  Set the multiport board type
  5285. ;       ===============================================================
  5286. ;
  5287. ;       Input           Description
  5288. ;       --------------  ---------------------------
  5289. ;       DL              Communications unit
  5290. ;       CX              New value (unsigned)
  5291. ;
  5292. ;       Output          Description
  5293. ;       --------------  ---------------------------
  5294. ;       Not applicable
  5295.  
  5296. COMMS_BOARD_TYPE   PROC NEAR
  5297.         CMP    DL, 0
  5298.         JE    firstboard7
  5299.         MOV    board2_type, CX
  5300.         RET
  5301. firstboard7:
  5302.                 MOV     board_type, CX
  5303.                 RET
  5304. COMMS_BOARD_TYPE   ENDP
  5305.  
  5306.  
  5307. ;       ===============================================================
  5308. ;       COMMS_STARTPORT  Set the multiport starting port number
  5309. ;       ===============================================================
  5310. ;
  5311. ;       Input           Description
  5312. ;       --------------  ---------------------------
  5313. ;       DL              Communications unit
  5314. ;       CX              New value (unsigned)
  5315. ;
  5316. ;       Output          Description
  5317. ;       --------------  ---------------------------
  5318. ;       Not applicable
  5319.  
  5320. COMMS_STARTPORT   PROC NEAR
  5321.         CMP    DL, 0
  5322.         JE    firstboard8
  5323.         MOV    starting2_port, CX
  5324.         RET
  5325. firstboard8:
  5326.                 MOV     starting_port, CX
  5327.                 RET
  5328. COMMS_STARTPORT   ENDP
  5329.  
  5330. ;       ===============================================================
  5331. ;       COMMS_MAXPORT  Set the multiport maximum port number
  5332. ;       ===============================================================
  5333. ;
  5334. ;       Input           Description
  5335. ;       --------------  ---------------------------
  5336. ;    DL        Multiport board number
  5337. ;       CX              New value (unsigned)
  5338. ;
  5339. ;       Output          Description
  5340. ;       --------------  ---------------------------
  5341. ;       Not applicable
  5342.  
  5343. COMMS_MAXPORT   PROC NEAR
  5344.         CMP    DL, 0
  5345.         JE    firstboard9
  5346.         MOV    maxshare2, CX
  5347.         RET
  5348. firstboard9:
  5349.                 MOV     maxshare, CX
  5350.                 RET
  5351. COMMS_MAXPORT   ENDP
  5352.  
  5353.  
  5354. COMMS_57K       PROC    NEAR            ; requires baud bits to be 0!
  5355.                 PUSH    SI
  5356.                 Load_SI                         ; Load SI with Comms_Str
  5357.                 MOV     AX, CX          ; Baud rate is preset to a 0 (110 baud)
  5358.                 MOV     WORD PTR TIMERS_X16, 2  ; 57K divisor
  5359.                 CALL    INT14INIT
  5360.                 MOV     WORD PTR TIMERS_X16, 1047   ; original 110 divisor
  5361.                 POP     SI
  5362.                 RET
  5363. COMMS_57K       ENDP
  5364.  
  5365. COMMS_115K      PROC    NEAR            ; requires baud bits to be 0!
  5366.                 PUSH    SI
  5367.                 Load_SI                         ; Load SI with Comms_Str
  5368.                 MOV     AX, CX          ; Baud rate is preset to a 0 (110 baud)
  5369.                 MOV     WORD PTR TIMERS_X16, 1  ; 115K divisor
  5370.                 CALL    INT14INIT
  5371.                 MOV     WORD PTR TIMERS_X16, 1047   ; original 110 divisor
  5372.                 POP     SI
  5373.                 RET
  5374. COMMS_115K      ENDP
  5375.  
  5376.  
  5377. public COMMS_SET_FC_CHAR
  5378. ;       ===============================================================
  5379. ;       COMMS_SET_FC_CHAR  Set the XON/XOFF characters
  5380. ;       ===============================================================
  5381. ;
  5382. ;       Input           Description
  5383. ;       --------------  ---------------------------
  5384. ;    DL        0 = XON, 1 = XOFF
  5385. ;       CL              New value (unsigned char)
  5386. ;
  5387. ;       Output          Description
  5388. ;       --------------  ---------------------------
  5389. ;       Not applicable
  5390.  
  5391. COMMS_SET_FC_CHAR   PROC NEAR
  5392.         CMP    DL, 0
  5393.         JNE    set_xoff
  5394.         MOV    XON, CL
  5395.         RET
  5396. set_xoff:
  5397.                 MOV     XOFF, CL
  5398.                 RET
  5399. COMMS_SET_FC_CHAR   ENDP
  5400.  
  5401. ;
  5402. ;       ===============================================================
  5403. ;       COMMS_Test_16550 : Test for existence of NS16550A UART
  5404. ;       ===============================================================
  5405. ;
  5406. ;
  5407. ;       Input           Description
  5408. ;       --------------  ---------------------------
  5409. ;       SI              Pointer to communications database
  5410. ;
  5411. ;       Output          Description
  5412. ;       --------------  ---------------------------
  5413. ;    AX              0 = NS 16550A UART is not present
  5414. ;                       1 = NS 16550A UART is present
  5415. ;
  5416. ;       Registers used  Description
  5417. ;       --------------  ---------------------------
  5418. ;       Not applicable
  5419. ;       ===============================================================
  5420. ;
  5421. COMMS_Test_16550   PROC    NEAR
  5422.                 push    si
  5423.                 Load_SI                         ; Load SI with Comms_Str
  5424.                 mov     dx, [SI].Comm_PortAddr  ; load port base adress
  5425.         add    dx, 2                   ; DX points to FCR or IIR
  5426.         mov    al, 01h                 ; FIFO enable bit0 of FCR
  5427.         out    dx, al                  ; Try to enable FIFOs
  5428.         IONOP
  5429.                 in      al, dx                  ; Read IIR or FCR
  5430.         IONOP
  5431.         test    al, 0C0h                ; See if IIR FIFO Enable Bits are set
  5432.         mov    al, 00h                 ; FIFO disable bit0 of FCR
  5433.         out    dx, al                  ; Disable FIFOs
  5434.         IONOP
  5435.         mov    [SI].COMM_UART_Mode, 00h;Initialize UART Mode field
  5436.         jz    _TST16550_not_present   ; NS 16550A not present
  5437. ; NS 16550A IS Present
  5438.         mov    ax, 01h                 ; Return 1 : 16550A present
  5439.         jmp    _exit_Test_16550
  5440.  
  5441. _TST16550_not_present:        
  5442.         mov    ax, 00h                 ; Return 0 : 16550A not present
  5443.  
  5444. _exit_Test_16550:
  5445.                 pop     si
  5446.                 ret
  5447. COMMS_Test_16550     ENDP
  5448.  
  5449. ;
  5450. ;       ===============================================================
  5451. ;       COMMS_Set_16550 : Enable / Disable FIFOs on NS16550A UART
  5452. ;       ===============================================================
  5453. ;
  5454. ;
  5455. ;       Input           Description
  5456. ;       --------------  ---------------------------
  5457. ;       SI              Pointer to communications database
  5458. ;       CH              Always 0x00
  5459. ;
  5460. ;       CL              NS16550A Trigger value: (bits 6 and 7)
  5461. ;                       0x0* = 1 byte    
  5462. ;                       0x1* = 4 bytes   
  5463. ;                       0x2* = 8 bytes   
  5464. ;                       0x3* = 14 bytes  
  5465. ;
  5466. ;                       NS16550A Mode Value:  (bits 0 to 3)
  5467. ;                       0x*0 = disable FIFOs (16450 mode)
  5468. ;                       0x*1 = Enable FIFOs, DMA mode 0
  5469. ;                       0x*9 = Enable FIFOs, DMA mode 1 (not used)
  5470. ;
  5471. ;       Output          Description
  5472. ;       --------------  ---------------------------
  5473. ;    AX              0 = NS 16550A UART is not present
  5474. ;                       1 = NS 16550A UART is present and initialzed
  5475. ;
  5476. ;       Registers used  Description
  5477. ;       --------------  ---------------------------
  5478. ;       Not applicable
  5479. ;       ===============================================================
  5480. ;
  5481.  
  5482. COMMS_Set_16550   PROC    NEAR
  5483.                 push    si
  5484.  
  5485.                 Load_SI                         ; Load SI with Comms_Str
  5486.                 mov     dx, [si].Comm_PortAddr  ; load port base adress
  5487.         add    dx, 2                   ; DX points to FCR or IIR
  5488.                 test    cl, 09h                 ; Mode: 0=disable, 1=FIFO enable:DMA mode0, 9=FIFO enable:DMA mode1 (not used)
  5489.                 jnz     _SET16550_enabled       ; enable FIFO operation
  5490.                 jmp     _SET16550_not_enabled   ; Disable FIFO operation
  5491.  
  5492. ; ATTEMPT TO ENABLE NS16550A
  5493. _SET16550_enabled:
  5494.                 mov     al, cl                  ; recover trigger value and mode
  5495.         out    dx, al                  ; Try to enable FIFOs w/ trigger
  5496.         IONOP
  5497.                 in      al, dx                  ; Read IIR or FCR: Check for FIFOs enabled
  5498.         IONOP
  5499.         test    al, 0C0h                ; IIR, FIFO Enable mask
  5500.         jz    _SET16550_not_enabled   ; NS 16550A not present
  5501.  
  5502. ; UART now intialized with FIFOs enabled with DMA mode 0 or mode 1
  5503.         mov    [si].COMM_UART_Mode, cx ; Store UART's FCR containing Mode and Trigger info. 
  5504.                 mov     ax, 01h                 ; Return 1 : 16550A present and initialized
  5505.         jmp    _exit_Set_16550
  5506.  
  5507. _SET16550_not_enabled:   ; Disable FIFO operation
  5508.         mov    ax, 00h                 ; FIFO disable bit0 of FCR
  5509.                                                 ; Return 0 : 16550A not present
  5510.         out    dx, al                  ; Disable FIFOs
  5511.         IONOP
  5512.         mov    [si].COMM_UART_Mode, 00h;Initialize UART Mode field
  5513.  
  5514. _exit_Set_16550:
  5515.                 pop     si
  5516.                 ret
  5517. COMMS_Set_16550     ENDP
  5518.  
  5519.  
  5520.  
  5521. ;
  5522. ;       ===============================================================
  5523. ;       COMMS_Get_Buffer_Memory
  5524. ;       ===============================================================
  5525. ;
  5526. ;
  5527. ;       Input           Description
  5528. ;       --------------  ---------------------------
  5529. ;       DH              1=get first buffer; 0=get subsequent buffers
  5530. ;    DL        Comm Port number (starting from 0)
  5531. ;
  5532. ;       Output          Description
  5533. ;       --------------  ---------------------------
  5534. ;    AX              1 = Buffer Allocated
  5535. ;                       0 = Buffer not allocated
  5536. ;
  5537. ;       Registers used  Description
  5538. ;       --------------  ---------------------------
  5539. ;       SI              Pointer to communications database
  5540. ;       ===============================================================
  5541. ;
  5542.  
  5543. COMMS_Get_Buffer_Memory  PROC    NEAR
  5544.         push    si
  5545.         push     di
  5546.         push     es
  5547.  
  5548. ;        cli                ; Disable Interrupts
  5549.  
  5550.                 Load_SI                         ; Load SI with Comms_Str
  5551.  
  5552.         test    dh, 01h
  5553.         jnz    xcgmem_first_buffer
  5554.  
  5555. ;    Get ECL Receive buffer location (segment)
  5556.             mov     dx, [si].Comm_CR_BUFFR_Segment
  5557.             mov     es, dx
  5558.  
  5559. ;       add another buffer
  5560.             call    BUFFR_Gmem      ; Get next available buffer
  5561.             jc      xcgmem_nobuff  ; None available
  5562.                                 ; Increment next buffer information
  5563.             inc     [si].Comm_Buffer_Count
  5564.             mov     di, [si].Comm_CR_BUFFR_Offset
  5565.             mov     es:[di], bx     ; Save pointer in previous last block
  5566.             mov     es:[di+2], dx
  5567.             mov     [si].Comm_CR_BUFFR_Offset, bx
  5568.             mov     [si].Comm_CR_BUFFR_Segment, dx
  5569.             mov     [si].Comm_CR_BUFFR_Index, 4   ; New index
  5570.         mov     ax, 01h
  5571.         jmp    xcgmem_exit
  5572.  
  5573. xcgmem_first_buffer:
  5574.         mov    WORD PTR [si].Comm_Receive_Count, 0
  5575.         mov    WORD PTR [si].Comm_Receive_Count + 2, 0
  5576.         mov    [si].Comm_Buffer_Count, 0
  5577.             call    BUFFR_Gmem      ; Get next available buffer
  5578.             jc      xcgmem_nobuff  ; None available
  5579.         call    COMMS_Bufclr
  5580.         mov     ax, 01h
  5581.         jmp    xcgmem_exit
  5582.  
  5583.  
  5584. xcgmem_nobuff:
  5585.         mov     ax, 00h
  5586.  
  5587. xcgmem_exit:
  5588. ;        sti                ; Enable Interrupts
  5589.         pop     es
  5590.         pop     di
  5591.                 pop     si
  5592.                 ret
  5593. COMMS_Get_Buffer_Memory     ENDP
  5594.  
  5595.  
  5596. ;
  5597. ;       ===============================================================
  5598. ;       COMMS_Free_Buffer_Memory
  5599. ;       ===============================================================
  5600. ;
  5601. ;
  5602. ;       Input           Description
  5603. ;       --------------  ---------------------------
  5604. ;       DH              Always 0x00
  5605. ;    DL        Comm Port number (starting from 0)
  5606. ;
  5607. ;       Output          Description
  5608. ;       --------------  ---------------------------
  5609. ;    Not Applicable
  5610. ;
  5611. ;       Registers used  Description
  5612. ;       --------------  ---------------------------
  5613. ;       SI              Pointer to communications database
  5614. ;       ===============================================================
  5615. ;
  5616.  
  5617. COMMS_Free_Buffer_Memory  PROC    NEAR
  5618.         push    si
  5619.  
  5620.         cli                ; Disable Interrupts
  5621.  
  5622.                 Load_SI                         ; Load SI with Comms_Str
  5623.  
  5624. ;       Free all buffers for this port
  5625.             call    COMMS_Buffree      ; Free all buffers for this port
  5626.  
  5627.         sti                ; Enable Interrupts
  5628.  
  5629.                 pop     si
  5630.                 ret
  5631. COMMS_Free_Buffer_Memory     ENDP
  5632.  
  5633. ;
  5634. ;       ===============================================================
  5635. ;       COMMS_Put_Buffer_Memory
  5636. ;       ===============================================================
  5637. ;
  5638. ;
  5639. ;       Input           Description
  5640. ;       --------------  ---------------------------
  5641. ;    BX        Offset of the buffer base
  5642. ;    DX        Segment of the buffer base
  5643. ;
  5644. ;       Output          Description
  5645. ;       --------------  ---------------------------
  5646. ;    Not Applicable
  5647. ;
  5648. ;       Registers used  Description
  5649. ;       --------------  ---------------------------
  5650. ;       SI              Pointer to communications database
  5651. ;       ===============================================================
  5652. ;
  5653. COMMS_Put_Buffer_Memory  PROC    NEAR
  5654.         cli        ; disable ints
  5655. ;       Place one of the released memory buffers back in the pool
  5656.             call    BUFFR_Pmem
  5657.         sti        ; enable ints
  5658.                 ret
  5659. COMMS_Put_Buffer_Memory     ENDP
  5660.  
  5661.  
  5662. ;
  5663. ;       ===============================================================
  5664. ;       COMMS_Set_Int_Exit
  5665. ;       ===============================================================
  5666. ;
  5667. ;
  5668. ;       Input           Description
  5669. ;       --------------  ---------------------------
  5670. ;       CH              Interrupt Handler Number COM1, COM2, SHARE1, SHARE2
  5671. ;    CL        MASK for Interrupt Events to trap
  5672. ;       BX              Offset of exit Function to call
  5673. ;    DX        Segment of the function
  5674. ;
  5675. ;       Output          Description
  5676. ;       --------------  ---------------------------
  5677. ;    Not Applicable
  5678. ;
  5679. ;       Registers used  Description
  5680. ;       --------------  ---------------------------
  5681. ;       SI              Pointer to variable data area
  5682. ;       ===============================================================
  5683. ;
  5684. PUBLIC COMMS_Set_Int_Exit
  5685. COMMS_Set_Int_Exit  PROC    NEAR
  5686. IFDEF INT_EXITS
  5687.                 push    ds
  5688.                 push    cs
  5689.                 pop     ds
  5690.                 mov     si, offset cs:com1_mask ; use ds:si to reference data
  5691.                 xor     ah, ah                  ; 6 bytes per handler
  5692.                 mov     al, ch
  5693.                 xor     ch, ch
  5694.                 mov     ah, 6
  5695.                 mul     ah
  5696.                 add     si, ax                  ; si now points to mask area
  5697.                 mov     word ptr [si], cx              ; mask
  5698.                 mov     word ptr [si+2], bx          ; offset address
  5699.                 mov     word ptr [si+4], dx          ; segment address
  5700.  
  5701.         cli                        ; disable ints
  5702.                 mov     word ptr si, cx             ; mask value
  5703.         sti                        ; enable ints
  5704.                 pop     ds
  5705. ENDIF
  5706.                 ret
  5707. COMMS_Set_Int_Exit      ENDP
  5708.  
  5709.  
  5710.  
  5711. ;*******************************************************************
  5712. ;*******************************************************************
  5713. ;*******************************************************************
  5714. ;*******************************************************************
  5715. ;        INCLUDE BUFFR.ASM ; Include buffer management services
  5716. ;*******************************************************************
  5717. ;
  5718. ;       BUFFR.ASM - XCOMMS kernal memory allocation services
  5719. ;
  5720. ;       (C) Copyright 1989, South Mountain Software Inc.
  5721. ;           All Rights Reserved
  5722. ;
  5723. ;
  5724. ;       Note that all of the procedures do not expect the segment
  5725. ;       registers to be preset to anything (except the CS, of course).
  5726. ;       Each buffer is suitable filled with the buffer number byte
  5727. ;       (first buffer filled with 0, second with 1, etc.).
  5728. ;
  5729. ;       The first 2 words of each buffer contains the pointer to the
  5730. ;       next buffer in the chain.
  5731. ;
  5732. ;       Note - the BUFFR module has no concept where the contiguous
  5733. ;               memory buffer came from!
  5734. ;
  5735. ;       Revision 2.0        No changes required
  5736.  
  5737. ;
  5738. ;       ===============================================================
  5739. ;       Definitions
  5740. ;       ===============================================================
  5741. ;
  5742.  
  5743. BUFFER_SIZE     EQU     1024
  5744. PARA            EQU     16
  5745. SEG_1K          EQU     1024 / PARA
  5746.  
  5747.  
  5748. ;
  5749. ;       ===============================================================
  5750. ;       Local data
  5751. ;       ===============================================================
  5752. ;
  5753.  
  5754. BUFFR_DATA      LABEL   BYTE                    ; BUFFR module data base
  5755. Available       DW      ?                       ; Number of buffers left
  5756. No_of_Buffers   DW      ?                       ; Number of buffers total
  5757. BUFFR_Pool      DD      ?
  5758. Base_Buffer     DD      ?                       ; Base of the buffer
  5759. BUFFR_Total     DW      8
  5760. BUFFR_Used      DW      0
  5761.  
  5762. ;
  5763. ;       ===============================================================
  5764. ;       Local procedures
  5765. ;       ===============================================================
  5766. ;
  5767. ;       BUFFR_Entry     Enter in the buffer module and allocate
  5768. ;       BUFFR_Status    Return the number of buffer used
  5769. ;       BUFFR_Init      Initialize the buffer pool    
  5770. ;       BUFFR_Gmem      Get the next buffer from the buffer pool
  5771. ;       BUFFR_Pmem      Put the memory block back into the pool
  5772. ;
  5773.  
  5774.  
  5775.  
  5776. ;
  5777. ;       ===============================================================
  5778. ;       BUFFR_Entry     Enter in the buffer module and allocate
  5779. ;       ===============================================================
  5780. ;
  5781. ;
  5782. ;       Input           Description
  5783. ;       --------------  ---------------------------
  5784. ;       BX              Offset of the buffer base
  5785. ;       DX              Segment of the buffer base
  5786. ;       CX              Number of 1K buffers to allocate
  5787. ;
  5788. ;       Output          Description
  5789. ;       --------------  ---------------------------
  5790. ;       Not applicable
  5791. ;
  5792. ;       Registers used  Description
  5793. ;       --------------  ---------------------------
  5794. ;       AX, BX, CX, DX  Modified (not important to maintain)
  5795. ;       ===============================================================
  5796. ;
  5797.  
  5798.  
  5799. BUFFR_Entry     PROC NEAR
  5800.  
  5801. ;               Setup the buffer parameters
  5802.  
  5803.                 PUSH    DS
  5804.                 PUSH    CS
  5805.                 POP     DS
  5806.  
  5807.                 MOV     Available, 0
  5808.                 MOV     No_of_Buffers, CX
  5809.  
  5810. ;               Adjust the base address so that the entire buffer fits in
  5811. ;               a segment
  5812.  
  5813.                 TEST    BX, 0000Fh              ; First, get to paragraph
  5814.                 JZ      _entry_ok
  5815.                 AND     BX, 0FFF0h
  5816.                 INC     DX
  5817. _entry_ok:
  5818.                 MOV     AX, BX                  ; Next, give it plenty of room
  5819.                 AND     BX, 0F000h
  5820.                 MOV     CL, 4
  5821.                 SHR     AX, CL
  5822.                 AND     AX, 00FFh
  5823.                 ADD     DX, AX
  5824.                 MOV     WORD PTR [Base_Buffer], BX
  5825.                 MOV     WORD PTR [Base_Buffer+2], DX
  5826.  
  5827. ;               Initialize the buffer pool list
  5828.  
  5829.                 CALL    BUFFR_Init
  5830.                 POP     DS
  5831.                 RET
  5832. BUFFR_Entry     ENDP
  5833.  
  5834.  
  5835. ;
  5836. ;       ===============================================================
  5837. ;       BUFFR_Status    Return the number of buffer used
  5838. ;       ===============================================================
  5839. ;
  5840. ;       Return the number of buffers reserved and the number
  5841. ;       of buffers available (in the buffer pool).  The number
  5842. ;       actually in current use is equal to the difference.
  5843. ;
  5844. ;       Input           Description
  5845. ;       --------------  ---------------------------
  5846. ;       Not applicable
  5847. ;
  5848. ;       Output          Description
  5849. ;       --------------  ---------------------------
  5850. ;       BX              Number of buffers reserved
  5851. ;       CX              Number of buffers available for use
  5852. ;
  5853. ;       Registers used  Description
  5854. ;       --------------  ---------------------------
  5855. ;       BX, CX          Modified
  5856. ;       ===============================================================
  5857. ;
  5858.  
  5859. BUFFR_Status    PROC    NEAR
  5860.                 PUSH    DS
  5861.                 PUSH    CS
  5862.                 POP     DS
  5863.                 MOV     BX, No_of_Buffers
  5864.                 MOV     CX, Available
  5865.                 POP     DS
  5866.                 RET
  5867. BUFFR_Status    ENDP
  5868.  
  5869.  
  5870. ;
  5871. ;       ===============================================================
  5872. ;       BUFFR_Init      Initialize the buffer pool    
  5873. ;       ===============================================================
  5874. ;
  5875. ;       Make all buffer entries available for use.
  5876. ;       This assumes that the No_of_Buffers and the Base_Buffer
  5877. ;       variables are preset.
  5878. ;
  5879. ;       Input           Description
  5880. ;       --------------  ---------------------------
  5881. ;       Not applicable
  5882. ;
  5883. ;       Output          Description
  5884. ;       --------------  ---------------------------
  5885. ;       Not applicable
  5886. ;
  5887. ;       Registers used  Description
  5888. ;       --------------  ---------------------------
  5889. ;       None modified 
  5890. ;       ===============================================================
  5891. ;
  5892.  
  5893. BUFFR_Init      PROC NEAR
  5894.                 PUSH    ES
  5895.                 PUSH    DS
  5896.                 PUSH    CS
  5897.                 POP     DS
  5898.                 PUSH    AX
  5899.                 PUSH    BX
  5900.                 PUSH    CX
  5901.                 PUSH    DX                
  5902.  
  5903.                 MOV     Available, 0            ; All buffers are available
  5904.                 MOV     BX, WORD PTR Base_Buffer; Assume base is adjusted
  5905.                 MOV     DX, WORD PTR Base_Buffer+2
  5906.                 MOV     CX, No_of_Buffers
  5907.                 MOV     AL, 0
  5908. _BI_loop:
  5909.                 MOV     ES, DX
  5910.                 MOV     DI, BX
  5911.                 PUSH    CX
  5912.                 MOV     CX, BUFFER_SIZE
  5913.                 REP     STOSB
  5914.                 POP     CX
  5915.                 INC     AL
  5916.                 PUSH    AX
  5917.                 CALL    BUFFR_Pmem              ; Add all buffers to pool
  5918.                 ADD     DX, SEG_1K
  5919.                 POP     AX
  5920.                 LOOP    _BI_loop
  5921.  
  5922.                 POP     DX
  5923.                 POP     CX
  5924.                 POP     BX
  5925.                 POP     AX
  5926.                 POP     DS
  5927.                 POP     ES
  5928.                 RET
  5929. BUFFR_Init      ENDP
  5930.  
  5931. ;
  5932. ;       ===============================================================
  5933. ;       BUFFR_Gmem      Get the next buffer from the buffer pool
  5934. ;       ===============================================================
  5935. ;
  5936. ;       The user asks for the next memory buffer and if one is 
  5937. ;       available, becomes the owner.  The number of buffers available
  5938. ;       will be decreased by one - in fact, the number of buffers left
  5939. ;       available is returned in this call.
  5940. ;
  5941. ;         Before:
  5942. ;                          +----------+
  5943. ;               BUFFR_Pool |     o----|----------+
  5944. ;                          +----------+          |
  5945. ;                                          b     v
  5946. ;                                         +--------------+
  5947. ;                                         |      o-------|---> c
  5948. ;                                         +--------------+
  5949. ;
  5950. ;         After:
  5951. ;                          +----------+
  5952. ;               BUFFR_Pool |     o----|----------+
  5953. ;                          +----------+          |
  5954. ;                                          c     v
  5955. ;                                         +--------------+
  5956. ;                                         |      o-------|---> d
  5957. ;                                         +--------------+
  5958. ;
  5959. ;       If a buffer is not available (all are being owned), the appropriate
  5960. ;       status is returned and the pool is unchanged.
  5961. ;
  5962. ;       Input           Description
  5963. ;       --------------  ---------------------------
  5964. ;       Not applicable
  5965. ;
  5966. ;       Output          Description
  5967. ;       --------------  ---------------------------
  5968. ;       if buffer is returned (released to the user):
  5969. ;         CY = NC       Signal (flag)
  5970. ;         AL = 00h      Signal byte
  5971. ;         BX            Offset of the buffer
  5972. ;         DX            Segment of the buffer
  5973. ;         CX            Number of 1K buffers still available (after release)
  5974. ;       if buffer is not available:
  5975. ;         CY = C        Signal (flag)
  5976. ;         AL = FFh      Signal byte
  5977. ;
  5978. ;       Registers used  Description
  5979. ;       --------------  ---------------------------
  5980. ;       AX, BX, CX, DX  Modified
  5981. ;       ===============================================================
  5982. ;
  5983.  
  5984. BUFFR_Gmem      PROC NEAR
  5985.                 PUSH    DS
  5986.                 PUSH    CS
  5987.                 POP     DS
  5988.                 CMP     Available, 0            ; Any buffers available?
  5989.                 JE      _BG_error               ; No
  5990.  
  5991.                 PUSHF                           ; FORCE Disable interrupts
  5992.                 CLI
  5993.                 PUSH    AX
  5994.                 PUSH    ES
  5995.                                                 ; Unlink the first entry
  5996.                 MOV     AX, WORD PTR BUFFR_Pool+2
  5997.                 MOV     ES, AX
  5998.                 MOV     BX, WORD PTR BUFFR_Pool
  5999.                 MOV     AX, ES:[BX]
  6000.                 MOV     WORD PTR BUFFR_Pool, AX
  6001.                 MOV     AX, ES:[BX+2]
  6002.                 MOV     WORD PTR BUFFR_Pool+2, AX
  6003.                 MOV     DX, ES
  6004.  
  6005.                 POP     ES
  6006.                 POP     AX
  6007.  
  6008.                 DEC     Available
  6009.                 POPF
  6010.                 MOV     CX, Available           ; Return buffers still left
  6011.                 CLC     
  6012.                 MOV     AL, 00h
  6013.                 JMP     SHORT   _BG_exit
  6014. _BG_error:
  6015.                 STC
  6016.                 MOV     AL, 0FFh
  6017. _BG_exit:
  6018.                 POP     DS
  6019.                 RET
  6020. BUFFR_Gmem      ENDP
  6021.  
  6022. ;
  6023. ;       ===============================================================
  6024. ;       BUFFR_Pmem      Put the memory block back into the pool
  6025. ;       ===============================================================
  6026. ;
  6027. ;       Place one of the released memory buffers back into the pool -
  6028. ;       note that the offset must be at least 1K bytes from the
  6029. ;       segmentation limit (it is not checked).
  6030. ;
  6031. ;       Using the address (segment:offset) received by the BUFFR_Pmem
  6032. ;       call will guarantee that.  All registers are returned unmodified.
  6033. ;
  6034. ;       MEMORY BUFFERS MUST HAVE BEEN INITIALIZED WITH BUFFR_ENTRY BEFORE
  6035. ;       THEY CAN BE PUT BACK INTO THE POOL.
  6036. ;
  6037. ;         Before:
  6038. ;                          +----------+
  6039. ;               BUFFR_Pool |     o----|----------+
  6040. ;                          +----------+          |
  6041. ;                                          b     v
  6042. ;                                         +--------------+
  6043. ;                                         |      o-------|---> c
  6044. ;                                         +--------------+
  6045. ;
  6046. ;         After (insert 'x'):
  6047. ;
  6048. ;                          +----------+
  6049. ;               BUFFR_Pool |     o----|----------+
  6050. ;                          +----------+          |
  6051. ;                                          x     v
  6052. ;                                         +--------------+
  6053. ;                                         |      o-------|---> b
  6054. ;                                         +--------------+
  6055. ;
  6056. ;       Input           Description
  6057. ;       --------------  ---------------------------
  6058. ;       BX              Offset of the buffer base
  6059. ;       DX              Segment of the buffer base
  6060. ;
  6061. ;       Output          Description
  6062. ;       --------------  ---------------------------
  6063. ;       BX              Offset of the buffer base
  6064. ;       DX              Segment of the buffer base
  6065. ;
  6066. ;       Registers used  Description
  6067. ;       --------------  ---------------------------
  6068. ;       Not applicable  (None modified)
  6069. ;       ===============================================================
  6070. ;
  6071.  
  6072. BUFFR_Pmem      PROC NEAR
  6073.                 PUSH    DS
  6074.                 PUSH    CS
  6075.                 POP     DS
  6076.                 PUSH    ES
  6077.                 PUSH    AX
  6078.  
  6079. ;               Add the front of the queue address to this buffer
  6080.  
  6081.                 PUSHF
  6082.                 CLI
  6083.                 MOV     ES, DX                  ; Add the link
  6084.                 MOV     AX, WORD PTR BUFFR_Pool
  6085.                 MOV     ES:[BX], AX
  6086.                 MOV     AX, WORD PTR BUFFR_Pool+2
  6087.                 MOV     ES:[BX+2], AX
  6088.  
  6089. ;               Put the buffer into the front of the queue
  6090.  
  6091.                 MOV     WORD PTR BUFFR_Pool, BX
  6092.                 MOV     WORD PTR BUFFR_Pool+2, DX
  6093.  
  6094. ;               Decrement the number used
  6095.  
  6096.                 INC     Available
  6097.                 POPF
  6098.  
  6099.                 POP     AX
  6100.                 POP     ES
  6101.                 POP     DS
  6102.                 RET
  6103. BUFFR_Pmem      ENDP
  6104.  
  6105.  
  6106.  
  6107. ;*******************************************************************
  6108. ;*******************************************************************
  6109. ;*******************************************************************
  6110. ;*******************************************************************
  6111. ;        INCLUDE TIMER.ASM ; The timer services
  6112. ;*******************************************************************
  6113. ;
  6114. ;       TIMER.ASM - XCOMMS kernal timer services
  6115. ;
  6116. ;       (C) Copyright 19896 SOuth Mountain Software Inc.
  6117. ;           All Rights Reserved
  6118. ;
  6119. ;       The TIMER component allows the 1Ch interrupt to be taken over
  6120. ;       for machine-independent timer requests.  Note that the 1Ch
  6121. ;       interrupt handlers must be chained (previous handlers expect to
  6122. ;       still be called every 55 milliseconds).
  6123. ;
  6124. ;       Revision 2.0        Changes required for timer "ports"
  6125. ;                           NOTE - no verification of timer channel number!
  6126. ;
  6127. ;       ===============================================================
  6128. ;       Definitions
  6129. ;       ===============================================================
  6130. ;
  6131.  
  6132. ;
  6133. ;       ===============================================================
  6134. ;       Local data
  6135. ;       ===============================================================
  6136. ;
  6137.  
  6138. Timer_State             DW      ?               ; = 01h if intercepted
  6139. Timer_Old_Offset        DD      ?               ; Old 1Ch interrupt address
  6140. Timer_Counter           DW      ?               ; Timer decrementing counter
  6141. Timer_Ports_Counter     DW      MAXPORTS DUP (?)    ; Multiple timer channels
  6142. Timer_Ports_State       DW      MAXPORTS DUP (?)    ; Multiple timer channels
  6143.  
  6144. ;
  6145. ;       ===============================================================
  6146. ;       Local procedures
  6147. ;       ===============================================================
  6148. ;
  6149. ;       TIMER_Int       The 1Ch interrupt handler (chained)
  6150. ;       TIMER_Entry     Enter the timer module
  6151. ;       TIMER_Exit      Exit the timer module
  6152. ;       TIMER_Status    Return timer status
  6153. ;       TIMER_Link      Link into Interrupt 1Ch chain (if not already)
  6154. ;       TIMER_UnLink    Remove Link into the 1Ch timer interrupt chain
  6155. ;       TIMER_Set       Set the Time counter increment (and go!)
  6156. ;       TIMER_Clear     Abort the current timer count request
  6157. ;       TIMER_Test      Test - return the current counter value
  6158. ;       TIMER_Wait      Wait for the counter request to complete
  6159. ;
  6160.  
  6161.  
  6162. ;
  6163. ;       ===============================================================
  6164. ;       TIMER_Int       Chain the 1Ch interrupt handler
  6165. ;       ===============================================================
  6166. ;
  6167. ;       Take the 1Ch interrupt (once every 55 milliseconds) and
  6168. ;       if a timer counter is current, decrement.  In any event,
  6169. ;       perform an indirect FAR jump to the previous 1Ch handler
  6170. ;       in the chain.
  6171. ;
  6172. ;       Performance - routine should not take longer than 20 microseconds.
  6173. ;
  6174. ;       Input           Description
  6175. ;       --------------  ---------------------------
  6176. ;       Not applicable
  6177. ;
  6178. ;       Output          Description
  6179. ;       --------------  ---------------------------
  6180. ;       Not applicable
  6181. ;
  6182. ;       Registers used  Description
  6183. ;       --------------  ---------------------------
  6184. ;       None affected
  6185. ;       ===============================================================
  6186. ;
  6187.  
  6188. Timer_Int       PROC    FAR                     ; New interrupt handler
  6189.                 PUSH    BX
  6190.                 PUSH    CX
  6191.  
  6192. ;   =======================
  6193. ;   Decrement generic timer
  6194. ;   =======================
  6195.  
  6196.                 CMP     CS:Timer_Counter, 0
  6197.                 JE      _TI_exit
  6198.                 DEC     CS:Timer_Counter        ; Decrement the counter
  6199. _TI_exit:
  6200.  
  6201. ;   =======================
  6202. ;   Decrement timer channels
  6203. ;   =======================
  6204.  
  6205.                 MOV     BX, 0                   ; Timer channel index
  6206.                 MOV     CX, MAXPORTS
  6207. _TI_loop:
  6208.                 CMP     CS:Timer_Ports_Counter[BX], 0
  6209.                 JE      _TI_skip
  6210.                 DEC     CS:Timer_Ports_Counter[BX]
  6211. _TI_skip:
  6212.                 ADD     BX, 2
  6213.                 LOOP    _TI_loop
  6214.  
  6215.                 POP     CX
  6216.                 POP     BX
  6217.  
  6218. ;   =======================
  6219. ;   Chain to previous timer
  6220. ;   =======================
  6221.  
  6222.                 JMP     DWORD PTR CS:[Timer_Old_Offset]
  6223. Timer_Int       ENDP
  6224.  
  6225.  
  6226.  
  6227. ;
  6228. ;       ===============================================================
  6229. ;       TIMER_Entry     Enter the timer module
  6230. ;       ===============================================================
  6231. ;
  6232. ;       Input           Description
  6233. ;       --------------  ---------------------------
  6234. ;       Not applicable
  6235. ;
  6236. ;       Output          Description
  6237. ;       --------------  ---------------------------
  6238. ;       Not applicable
  6239. ;
  6240. ;       Registers used  Description
  6241. ;       --------------  ---------------------------
  6242. ;       None affected
  6243. ;       ===============================================================
  6244.  
  6245. TIMER_Entry     PROC NEAR
  6246.                 PUSH    BX
  6247.                 PUSH    CX
  6248.  
  6249.                 MOV     Timer_Counter, 0        ; Init generic timer
  6250.                 MOV     Timer_State, NATIVE     ; Assume not intercepted
  6251.  
  6252.                 MOV     BX, 0                   ; Init timer channels
  6253.                 MOV     CX, MAXPORTS
  6254. TIMER_Entry_loop:
  6255.                 MOV     Timer_Ports_State[BX], NATIVE
  6256.                 MOV     Timer_Ports_Counter[BX], 0
  6257.                 ADD     BX, 2
  6258.                 LOOP    TIMER_Entry_loop
  6259.  
  6260.                 POP     CX
  6261.                 POP     BX
  6262.                 RET
  6263. TIMER_Entry     ENDP
  6264.  
  6265. ;
  6266. ;       ===============================================================
  6267. ;       TIMER_Exit      Exit the timer module
  6268. ;       ===============================================================
  6269. ;
  6270. ;       Input           Description
  6271. ;       --------------  ---------------------------
  6272. ;       Not applicable
  6273. ;
  6274. ;       Output          Description
  6275. ;       --------------  ---------------------------
  6276. ;       Not applicable
  6277. ;
  6278. ;       Registers used  Description
  6279. ;       --------------  ---------------------------
  6280. ;       None affected
  6281. ;       ===============================================================
  6282.  
  6283. TIMER_Exit      PROC NEAR
  6284.                 PUSH    DX
  6285.                 PUSH    CX
  6286.  
  6287.                 MOV     DX, 0                   ; Restore timer channels
  6288.                 MOV     CX, MAXPORTS
  6289. _TIMER_Exit_loop:
  6290.                 CALL    TIMERP_UnLink
  6291.                 INC     DX
  6292.                 LOOP    _TIMER_Exit_loop
  6293.                 POP     CX
  6294.                 POP     DX
  6295.  
  6296.                 CALL    TIMER_UnLink            ; Restore generic timer 1C interrupt
  6297.                 CLC
  6298.                 RET
  6299. TIMER_Exit      ENDP
  6300.  
  6301. ;
  6302. ;       ===============================================================
  6303. ;       TIMER_Status    Return timer status
  6304. ;       [TIMERP_Status  Return timer channel status]
  6305. ;       ===============================================================
  6306. ;
  6307. ;       Input           Description
  6308. ;       --------------  ---------------------------
  6309. ;       AH = 1Ch        TIMER interrupt number
  6310. ;       AL = 00h        Status request
  6311. ;       [DX             Communications channel number]
  6312. ;
  6313. ;       Output          Description
  6314. ;       --------------  ---------------------------
  6315. ;       AX = 00h        Not intercepted
  6316. ;       AX = 01h        Intercepted
  6317. ;
  6318. ;       Registers used  Description
  6319. ;       --------------  ---------------------------
  6320. ;       AX              Return value only
  6321. ;       ===============================================================
  6322. ;
  6323.  
  6324. TIMER_Status    PROC NEAR
  6325.                 MOV     AX, Timer_State         ; Return the status
  6326.                 RET                
  6327. TIMER_Status    ENDP
  6328.  
  6329. ;       ===============================================================
  6330.  
  6331. TIMERP_Status   PROC NEAR
  6332.                 PUSH    BX
  6333.  
  6334.                 MOV     BX, DX
  6335.                 ADD     BX, BX
  6336.                 MOV     AX, Timer_Ports_State[BX]
  6337.  
  6338.                 POP     BX
  6339.                 RET                
  6340. TIMERP_Status   ENDP
  6341.  
  6342.  
  6343. ;
  6344. ;       ===============================================================
  6345. ;       TIMER_Link      Link into Interrupt 1Ch chain (if not already)
  6346. ;       [TIMERP_Link      Link into Interrupt 1Ch chain (if not already)]
  6347. ;       ===============================================================
  6348. ;
  6349. ;       Input           Description
  6350. ;       --------------  ---------------------------
  6351. ;       AH = 1Ch        TIMER interrupt number
  6352. ;       AL = 01h        Link request
  6353. ;       [DX             Communications channel number]
  6354. ;
  6355. ;       Output          Description
  6356. ;       --------------  ---------------------------
  6357. ;       AL = 00h        Successful - chained in
  6358. ;       CY = NC         Successful - chained in
  6359. ;               - or -
  6360. ;       AL = FFh        Error
  6361. ;       CY = C          Error - already chained, request ignored
  6362. ;
  6363. ;       Registers used  Description
  6364. ;       --------------  ---------------------------
  6365. ;       AX              Return value only
  6366. ;       DS              Vector handler new segment address
  6367. ;       DX              Vector handler new offset address
  6368. ;       ES              Vector handler old segment address
  6369. ;       BX              Vector handler old offset address
  6370. ;       ===============================================================
  6371. ;
  6372.  
  6373. TIMER_Link      PROC NEAR
  6374.                 CMP     Timer_State, INTERCEPTED
  6375.                 JE      _TL_Error
  6376.  
  6377. ;               Save the current timer 1Ch vector handler address
  6378.  
  6379.                 MOV     Timer_Counter, 0        ; Timer counter is dead
  6380.  
  6381.                 MOV     AL, TIMER
  6382.                 MOV     DX, SEG Timer_Int
  6383.                 MOV     BX, OFFSET Timer_Int
  6384.                 swapvec
  6385.                 MOV     WORD PTR Timer_Old_Offset, BX
  6386.                 MOV     WORD PTR Timer_Old_Offset+2, DX
  6387.                 MOV     Timer_State, INTERCEPTED
  6388.                 MOV     AL, 00h
  6389.                 CLC
  6390.                 JMP     SHORT _TL_Exit
  6391. _TL_Error:
  6392.                 MOV     AL, 0FFh
  6393.                 STC
  6394. _TL_Exit:
  6395.                 RET
  6396. TIMER_Link      ENDP
  6397.  
  6398. ;       ===============================================================
  6399.  
  6400. TIMERP_Link     PROC NEAR       ; Assumes TIMER_Link already called!!!!!!!!!
  6401.                 PUSH    BX
  6402.  
  6403.                 MOV     BX, DX
  6404.                 ADD     BX, BX
  6405.                 CMP     Timer_Ports_State[BX], INTERCEPTED
  6406.                 JE      _TLP_Error
  6407.                 MOV     Timer_Ports_State[BX], INTERCEPTED
  6408.                 MOV     AL, 00h
  6409.                 CLC
  6410.                 JMP     SHORT   _TLP_Exit
  6411. _TLP_Error:
  6412.                 MOV     AL, 0FFh
  6413.                 STC
  6414. _TLP_Exit:
  6415.                 POP     BX
  6416.                 RET
  6417. TIMERP_Link     ENDP
  6418.  
  6419. ;
  6420. ;       ===============================================================
  6421. ;       TIMER_UnLink    Remove Link into the 1Ch timer interrupt chain
  6422. ;       [TIMERP_UnLink    Remove Link into the 1Ch timer interrupt chain]
  6423. ;       ===============================================================
  6424. ;
  6425. ;       Link into the 1Ch timer interrupt chain ONLY IF the Timer_Int
  6426. ;       routine isn't already linked in.  Return the appropriate status.
  6427. ;
  6428. ;       TIMERP_UnLink does not modify interrupt 1C - assumes TIMER_UnLink controls
  6429. ;
  6430. ;       Input           Description
  6431. ;       --------------  ---------------------------
  6432. ;       AH = 1Ch        TIMER interrupt number
  6433. ;       AL = 02h        UnLink request
  6434. ;       [DX             Communications channel number]
  6435. ;
  6436. ;       Output          Description
  6437. ;       --------------  ---------------------------
  6438. ;       CY = NC         Successful - unchained out of 1Ch
  6439. ;       CY = C          Error - not chained, request ignored
  6440. ;
  6441. ;       Registers used  Description
  6442. ;       --------------  ---------------------------
  6443. ;       AX              Set vector interface, scratch
  6444. ;       DS              Vector handler new segment address
  6445. ;       DX              Vector handler new offset address
  6446. ;       ===============================================================
  6447. ;
  6448.  
  6449. TIMER_UnLink    PROC NEAR
  6450.                 CMP     Timer_State, INTERCEPTED
  6451.                 JNE     _TU_Error
  6452.  
  6453.                 MOV     BX, WORD PTR Timer_Old_Offset
  6454.                 MOV     DX, WORD PTR Timer_Old_Offset+2
  6455.                 MOV     AL, TIMER
  6456.                 setvec
  6457.                 MOV     Timer_State, NATIVE
  6458.                 MOV     Timer_Counter, 0        ; Timer counter is dead
  6459.                 MOV     AL, 00h
  6460.                 CLC
  6461.  
  6462.                 JMP     SHORT _TU_Exit
  6463. _TU_Error:
  6464.                 MOV     AL, 0FFh
  6465.                 STC
  6466. _TU_Exit:
  6467.  
  6468.                 RET
  6469. TIMER_UnLink    ENDP
  6470.  
  6471. ;       ===============================================================
  6472.  
  6473. TIMERP_UnLink   PROC NEAR
  6474.                 PUSH    BX
  6475.  
  6476.                 MOV     BX, DX
  6477.                 ADD     BX, BX
  6478.                 CMP     Timer_Ports_State[BX], INTERCEPTED
  6479.                 JNE     _TUP_Error
  6480.                 MOV     Timer_Ports_State[BX], NATIVE
  6481.                 MOV     Timer_Ports_Counter[BX], 0
  6482.                 MOV     AL, 00h
  6483.                 CLC
  6484.                 JMP     SHORT   _TUP_Exit
  6485. _TUP_Error:
  6486.                 MOV     AL, 0FFh
  6487.                 STC
  6488. _TUP_Exit:
  6489.                 POP     BX
  6490.                 RET
  6491. TIMERP_UnLink   ENDP
  6492.  
  6493. ;       ===============================================================
  6494. ;
  6495. ;       Remaining timer services will NOT work if timer is not
  6496. ;       enabled - this routine is used by those routines
  6497. ;
  6498. ;       ===============================================================
  6499.  
  6500. _timer_status   PROC    NEAR
  6501.                 MOV     AX, Timer_State
  6502.                 CMP     AX, NATIVE
  6503.                 JNE     _intercept
  6504.                 MOV     AL, 0FFh
  6505.                 STC
  6506.                 JMP     SHORT _exit
  6507. _intercept:
  6508.                 MOV     AL, 00h
  6509.                 CLC
  6510. _exit:
  6511.                 RET
  6512. _timer_status   ENDP
  6513.  
  6514. ;       ===============================================================
  6515.  
  6516. _timerp_status  PROC    NEAR        ; Expected DX for communications port number
  6517.  
  6518.                 MOV     BX, DX
  6519.                 ADD     BX, BX
  6520.                 MOV     AX, Timer_Ports_State[BX]
  6521.                 CMP     AX, NATIVE
  6522.                 JNE     p_intercept
  6523.                 MOV     AL, 0FFh
  6524.                 STC
  6525.                 JMP     SHORT p_exit
  6526. p_intercept:
  6527.                 MOV     AL, 00h
  6528.                 CLC
  6529. p_exit:                             ; Return BX as an index (word offset)
  6530.                 RET
  6531. _timerp_status  ENDP
  6532.  
  6533. ;
  6534. ;       ===============================================================
  6535. ;       TIMER_Set       Set the Time counter increment (and go!)
  6536. ;       [TIMERP_Set     Set the time channel counter and start]
  6537. ;       ===============================================================
  6538. ;
  6539. ;       Input           Description
  6540. ;       --------------  ---------------------------
  6541. ;       CX              Number of timer ticks (one occurs every 55 millis)
  6542. ;       [DX             Timer channel number]
  6543. ;
  6544. ;       Output          Description
  6545. ;       --------------  ---------------------------
  6546. ;       AL = FFh,CY=C   Not intercepted
  6547. ;       AX = 00h,CY=NC  Intercepted
  6548. ;       CX              same as above
  6549. ;
  6550. ;       Registers used  Description
  6551. ;       --------------  ---------------------------
  6552. ;       Not applicable
  6553. ;       ===============================================================
  6554. ;
  6555.  
  6556. TIMER_Set       PROC
  6557.                 CALL    _timer_status           ; Set AL status return
  6558.                 MOV     Timer_Counter, CX
  6559.                 RET
  6560. TIMER_Set       ENDP
  6561.  
  6562. ;       ===============================================================
  6563.  
  6564. TIMERP_Set      PROC
  6565.                 PUSH    BX
  6566.                 CALL    _timerp_status          ; Set AL status return
  6567.                 MOV     Timer_Ports_Counter[BX],CX
  6568.                 POP     BX
  6569.                 RET
  6570. TIMERP_Set      ENDP
  6571.  
  6572. ;
  6573. ;       ===============================================================
  6574. ;       TIMER_Clear     Abort the current timer count request
  6575. ;       [TIMERP_Clear   Abort the current timer channel count request]
  6576. ;       ===============================================================
  6577. ;
  6578. ;       Input           Description
  6579. ;       --------------  ---------------------------
  6580. ;       DS              Pointer to CS segment
  6581. ;       [DX             Timer channel number]
  6582. ;
  6583. ;       Output          Description
  6584. ;       --------------  ---------------------------
  6585. ;       AL = FFh,CY=C   Not intercepted
  6586. ;       AX = 00h,CY=NC  Intercepted
  6587. ;
  6588. ;       Registers used  Description
  6589. ;       --------------  ---------------------------
  6590. ;       AX              Return value only
  6591. ;       ===============================================================
  6592. ;
  6593.  
  6594. TIMER_Clear     PROC
  6595.                 CALL    _timer_status           ; Set AL status return
  6596.                 MOV     Timer_Counter, 0        ; Timer counter is dead
  6597.                 RET
  6598. TIMER_Clear     ENDP
  6599.  
  6600. ;       ===============================================================
  6601.  
  6602. TIMERP_Clear    PROC
  6603.                 PUSH    BX
  6604.                 CALL    _timerp_status          ; Set AL status return
  6605.                 MOV     Timer_Ports_Counter[BX],0; Timer counter is dead
  6606.                 POP     BX
  6607.                 RET
  6608. TIMERP_Clear    ENDP
  6609.  
  6610. ;
  6611. ;       ===============================================================
  6612. ;       TIMER_Test      Test - return the current counter value
  6613. ;       [TIMERP_Test      Test - return the current counter value]
  6614. ;       ===============================================================
  6615. ;
  6616. ;       Input           Description
  6617. ;       --------------  ---------------------------
  6618. ;       DS              Pointer to CS segment
  6619. ;       [DX             Timer channel number]
  6620. ;
  6621. ;       Output          Description
  6622. ;       --------------  ---------------------------
  6623. ;       AL = FFh,CY=C   Not intercepted
  6624. ;               or 
  6625. ;       AX = 00h,CY=NC  Intercepted
  6626. ;         CX = 00h      Counter complete (or not even counted down)
  6627. ;         CX > 00h      Counter timer still in progress
  6628. ;
  6629. ;       Registers used  Description
  6630. ;       --------------  ---------------------------
  6631. ;       AX              Return value only
  6632. ;       ===============================================================
  6633. ;
  6634.  
  6635. TIMER_Test      PROC
  6636.                 CALL    _timer_status           ; Set AL status return
  6637.                 MOV     CX, Timer_Counter       ; Timer counter is dead
  6638.                 RET
  6639. TIMER_Test      ENDP
  6640.  
  6641. ;       ===============================================================
  6642.  
  6643. TIMERP_Test     PROC
  6644.                 PUSH    BX
  6645.                 CALL    _timerp_status          ; Set AL status return
  6646.                 MOV     CX, Timer_Ports_Counter[BX]
  6647.                 POP     BX
  6648.                 RET
  6649. TIMERP_Test     ENDP
  6650. ;       ===============================================================
  6651.  
  6652. ;
  6653. ;       ===============================================================
  6654. ;       TIMER_Wait      Wait for the counter request to complete
  6655. ;       [TIMERP_Wait      Wait for the counter request to complete]
  6656. ;       ===============================================================
  6657. ;
  6658. ;       If no request is given (or the timer not even linked in),
  6659. ;       the request returns immediately.
  6660. ;
  6661. ;       Input           Description
  6662. ;       --------------  ---------------------------
  6663. ;       DS              Pointer to CS segment
  6664. ;       [DX             Timer channel number]
  6665. ;
  6666. ;       Output          Description
  6667. ;       --------------  ---------------------------
  6668. ;       AL = FFh,CY=C   Not intercepted
  6669. ;       AX = 00h,CY=NC  Intercepted
  6670. ;       AX = 00h        Not intercepted
  6671. ;       AX = 01h        Intercepted
  6672. ;
  6673. ;       Registers used  Description
  6674. ;       --------------  ---------------------------
  6675. ;       AX              Return value only
  6676. ;       ===============================================================
  6677. ;
  6678.  
  6679. TIMER_Wait      PROC
  6680.                 STI                             ; ENABLE interrupts
  6681.                 CALL    _timer_status           ; Set AL status return
  6682.                 JC      _wait_exit              ; Not intercepted
  6683. _Wait:
  6684.                 CMP     Timer_Counter, 0
  6685.                 NOP
  6686.                 JNE     _Wait
  6687.                 CLC                             ; Restored flag 
  6688. _wait_exit:
  6689.                 RET
  6690. TIMER_Wait      ENDP
  6691.  
  6692. ;       ===============================================================
  6693.  
  6694. TIMERP_Wait     PROC
  6695.                 STI                             ; ENABLE interrupts
  6696.                 CALL    _timerp_status          ; Set AL status return
  6697.                 JC      _waitp_exit             ; Not intercepted
  6698. _Waitp:
  6699.                 CMP     Timer_Ports_Counter[BX], 0
  6700.                 NOP
  6701.                 JNE     _Waitp
  6702.                 CLC                             ; Restored flag 
  6703. _waitp_exit:
  6704.                 RET
  6705. TIMERP_Wait     ENDP
  6706. ;       ===============================================================
  6707.  
  6708. ;*******************************************************************
  6709. ;*******************************************************************
  6710. ;*******************************************************************
  6711. ;*******************************************************************
  6712. ;        INCLUDE KEYBK.ASM ; The Ctrl-Break services
  6713. ;*******************************************************************
  6714. ;
  6715. ;       KEYBK.ASM  XCOMMS kernal Ctrl-Break handler
  6716. ;
  6717. ;       (C) Copyright 19896 SOuth Mountain Software Inc.
  6718. ;           All Rights Reserved
  6719. ;
  6720. ;       All of the procedures are extended, miscellaneous services that
  6721. ;       have no equivalent defined in PC BIOS.
  6722. ;
  6723. ;       KEYBK
  6724. ;
  6725. ;       The KEYBK component chains into the 1Bh Ctrl-Break request.
  6726. ;       If a check for Ctrl-Break occurs, any keystrokes queued or
  6727. ;       automatically thrown away.
  6728. ;
  6729. ;       Revision 2.0    No changes required
  6730.  
  6731. ;
  6732. ;       ===============================================================
  6733. ;       Local data
  6734. ;       ===============================================================
  6735. ;
  6736.  
  6737. Keyboard_State          DW      ?               ; = 01h if intercepted
  6738. Keybk_Old_Offset        DD      ?               ; Old 1Ch interrupt address
  6739. Keyboard_Break          DW      ?               ; Ctrl-Break Flag
  6740.  
  6741. ;
  6742. ;       ===============================================================
  6743. ;       Local procedures
  6744. ;       ===============================================================
  6745. ;
  6746. ;       Keybk_Int       Chain the 1Bh interrupt handler
  6747. ;
  6748. ;       KEYBK_Entry     Enter the keyboard break module
  6749. ;       KEYBK_Exit      Exit the keyboard break module
  6750. ;       KEYBK_Status    Return keyboard Break intercept status
  6751. ;       KEYBK_Link      Link into Interrupt 1Bh chain (if not already)
  6752. ;       KEYBK_UnLink    Remove Link into the 1Bh Ctrl-Break chain
  6753. ;       KEYBK_Test      Test - return the current Ctrl-Break status
  6754. ;
  6755.  
  6756. ;
  6757. ;       ===============================================================
  6758. ;       Keybk_Int       Chain the 1Bh interrupt handler
  6759. ;       ===============================================================
  6760. ;
  6761. ;       Take the Ctrl-Break Interrupt (1Bh) and set a flag.  Note that
  6762. ;       we must NOT chain to the previous handler - this would cause
  6763. ;       MS-DOS to abort.
  6764. ;
  6765. ;       Input           Description
  6766. ;       --------------  ---------------------------
  6767. ;       Not applicable
  6768. ;
  6769. ;       Output          Description
  6770. ;       --------------  ---------------------------
  6771. ;       Not applicable
  6772. ;
  6773. ;       Registers used  Description
  6774. ;       --------------  ---------------------------
  6775. ;       None affected
  6776. ;       ===============================================================
  6777. ;
  6778.  
  6779. Keybk_Int       PROC    FAR                     ; New interrupt handler
  6780.                 MOV     CS:Keyboard_Break, 1
  6781.                 IRET
  6782. ; *****         JMP     DWORD PTR CS:[Keybk_Old_Offset]
  6783. Keybk_Int       ENDP
  6784.  
  6785. ;
  6786. ;       ===============================================================
  6787. ;       KEYBK_Entry     Enter the keyboard break module
  6788. ;       ===============================================================
  6789. ;
  6790. ;       Input           Description
  6791. ;       --------------  ---------------------------
  6792. ;       Not applicable
  6793. ;
  6794. ;       Output          Description
  6795. ;       --------------  ---------------------------
  6796. ;       Not applicable
  6797. ;
  6798. ;       Registers used  Description
  6799. ;       --------------  ---------------------------
  6800. ;       None affected
  6801. ;       ===============================================================
  6802.  
  6803. KEYBK_Entry     PROC NEAR
  6804.                 MOV     Keyboard_Break, 0       ; No break pressed
  6805.                 MOV     Keyboard_State, NATIVE  ; Assume not intercepted
  6806.                 RET
  6807. KEYBK_Entry     ENDP
  6808.  
  6809.  
  6810. ;
  6811. ;       ===============================================================
  6812. ;       KEYBK_Exit      Exit the keyboard break module
  6813. ;       ===============================================================
  6814. ;
  6815. ;       Input           Description
  6816. ;       --------------  ---------------------------
  6817. ;       Not applicable
  6818. ;
  6819. ;       Output          Description
  6820. ;       --------------  ---------------------------
  6821. ;       Not applicable
  6822. ;
  6823. ;       Registers used  Description
  6824. ;       --------------  ---------------------------
  6825. ;       None affected
  6826. ;       ===============================================================
  6827.  
  6828. KEYBK_Exit      PROC NEAR
  6829.                 CALL    KEYBK_UnLink            ; Restore if intercepted
  6830.                 CLC
  6831.                 RET
  6832. KEYBK_Exit      ENDP
  6833.  
  6834. ;
  6835. ;       ===============================================================
  6836. ;       KEYBK_Status    Return keyboard Break intercept status
  6837. ;       ===============================================================
  6838. ;
  6839. ;       Input           Description
  6840. ;       --------------  ---------------------------
  6841. ;       AH = 1Bh        Break interrupt number
  6842. ;       AL = 00h        Status request
  6843. ;
  6844. ;       Output          Description
  6845. ;       --------------  ---------------------------
  6846. ;       AX = 00h        Not intercepted
  6847. ;       AX = 01h        Intercepted
  6848. ;
  6849. ;       Registers used  Description
  6850. ;       --------------  ---------------------------
  6851. ;       AX              Return value only
  6852. ;       ===============================================================
  6853.  
  6854. KEYBK_Status    PROC
  6855.                 MOV     AX, Keyboard_State
  6856.                 RET
  6857. KEYBK_Status    ENDP
  6858.  
  6859. ;
  6860. ;       ===============================================================
  6861. ;       KEYBK_Link      Link into Interrupt 1Bh chain (if not already)
  6862. ;       ===============================================================
  6863. ;
  6864. ;       Input           Description
  6865. ;       --------------  ---------------------------
  6866. ;       AH = 1Bh        KEYBK interrupt number
  6867. ;       AL = 01h        Link request
  6868. ;
  6869. ;       Output          Description
  6870. ;       --------------  ---------------------------
  6871. ;       AL = 00h        Successful - chained in
  6872. ;       CY = NC         Successful - chained in
  6873. ;               - or -
  6874. ;       AL = FFh        Error
  6875. ;       CY = C          Error - already chained, request ignored
  6876. ;
  6877. ;       Registers used  Description
  6878. ;       --------------  ---------------------------
  6879. ;       AX              Return value only
  6880. ;       DX              Vector handler offset address
  6881. ;       BX              Vector handler offset address
  6882. ;       ===============================================================
  6883. ;
  6884.  
  6885. KEYBK_Link      PROC NEAR
  6886.                 CMP     Keyboard_State, INTERCEPTED
  6887.                 JE      _KL_Error
  6888.  
  6889. ;               Save the current timer 1Ch vector handler address
  6890.  
  6891.                 MOV     Keyboard_Break, 0       ; NO Ctrl-Break pressed yet
  6892.                 MOV     AL, KEYBK
  6893.                 MOV     DX, SEG Keybk_Int
  6894.                 MOV     BX, OFFSET Keybk_Int
  6895.                 swapvec
  6896.                 MOV     WORD PTR Keybk_Old_Offset, BX
  6897.                 MOV     WORD PTR Keybk_Old_Offset+2, DX
  6898.                 MOV     Keyboard_State, INTERCEPTED
  6899.                 MOV     AL, 00h
  6900.                 CLC
  6901.                 JMP     SHORT _KL_Exit
  6902. _KL_Error:
  6903.                 MOV     AL, 0FFh
  6904.                 STC
  6905. _KL_Exit:
  6906.                 RET
  6907. KEYBK_Link      ENDP
  6908.  
  6909.  
  6910. ;
  6911. ;       ===============================================================
  6912. ;       KEYBK_UnLink    Remove Link into the 1Bh Ctrl-Break chain
  6913. ;       ===============================================================
  6914. ;
  6915. ;       Link into the 1Bh keyboard interrupt chain ONLY IF the Keybk_Int
  6916. ;       routine isn't already linked in.  Return the appropriate status.
  6917. ;
  6918. ;       Input           Description
  6919. ;       --------------  ---------------------------
  6920. ;       AH = 1Bh        Keyboard Break interrupt number
  6921. ;       AL = 02h        UnLink request
  6922. ;
  6923. ;       Output          Description
  6924. ;       --------------  ---------------------------
  6925. ;       CY = NC         Successful - unchained out of 1Ch
  6926. ;       CY = C          Error - not chained, request ignored
  6927. ;
  6928. ;       Registers used  Description
  6929. ;       --------------  ---------------------------
  6930. ;       AX              Set vector interface, scratch
  6931. ;       DS              Vector handler new segment address
  6932. ;       DX              Vector handler new offset address
  6933. ;       ===============================================================
  6934. ;
  6935.  
  6936. KEYBK_UnLink    PROC NEAR
  6937.                 CMP     Keyboard_State, INTERCEPTED
  6938.                 JNE     _KU_Error
  6939.                 MOV     BX, WORD PTR Keybk_Old_Offset
  6940.                 MOV     DX, WORD PTR Keybk_Old_Offset+2
  6941.                 MOV     AL, KEYBK
  6942.                 setvec
  6943.                 MOV     Keyboard_State, NATIVE
  6944.                 MOV     Keyboard_Break, 0
  6945.                 MOV     AL, 00h
  6946.                 CLC
  6947.                 JMP     SHORT _KU_Exit
  6948. _KU_Error:
  6949.                 MOV     AL, 0FFh
  6950.                 STC
  6951. _KU_Exit:
  6952.  
  6953.                 RET
  6954. KEYBK_UnLink    ENDP
  6955.  
  6956.  
  6957. ;
  6958. ;       ===============================================================
  6959. ;       KEYBK_Test      Test - return the current Ctrl-Break status
  6960. ;       ===============================================================
  6961. ;
  6962. ;       If keyboard interrupt is NOT taken over, then a 0 is always
  6963. ;       returned.
  6964. ;
  6965. ;       Input           Description
  6966. ;       --------------  ---------------------------
  6967. ;       DS              Pointer to CS segment
  6968. ;
  6969. ;       Output          Description
  6970. ;       --------------  ---------------------------
  6971. ;       AX = 00h        No 
  6972. ;       AX = 01h        Ctrl-Break pressed
  6973. ;
  6974. ;       Registers used  Description
  6975. ;       --------------  ---------------------------
  6976. ;       AX              Return value only
  6977. ;       ===============================================================
  6978. ;
  6979.  
  6980. KEYBK_Test      PROC
  6981.                 CLI
  6982.                 MOV     AX, Keyboard_Break
  6983.                 MOV     Keyboard_Break, 0
  6984.                 STI
  6985.                 CMP     AX, 0
  6986.                 RET
  6987. KEYBK_Test      ENDP
  6988.  
  6989.  
  6990.  
  6991. ;*******************************************************************
  6992. ;*******************************************************************
  6993. ;*******************************************************************
  6994. ;*******************************************************************
  6995.  
  6996.  
  6997.  
  6998. ;
  6999. ;       ===============================================================
  7000. ;       XCOMMS local kernal drivers
  7001. ;       ===============================================================
  7002. ;
  7003. ;       XCOMMS_Entry     Enter and initialize all XCOMMS Services
  7004. ;       XCOMMS_Exit      Enter and initialize all XCOMMS Services
  7005. ;       XCOMMS_Status    Return revision level of XCOMMS
  7006.  
  7007. ;
  7008. ;       ===============================================================
  7009. ;       XCOMMS_Entry     Enter and initialize all XCOMMS Services
  7010. ;       ===============================================================
  7011. ;
  7012. ;       Using the <Entries> table of intra-segment offsets, call
  7013. ;       each of these procedures.  The first routine called must be
  7014. ;       the BUFFR entry to reserve the buffer pool.
  7015. ;
  7016. ;       Input           Description
  7017. ;       --------------  ---------------------------
  7018. ;       DX:BX           Address of buffer pool
  7019. ;       CX              Number of 1K buffers
  7020. ;
  7021. ;       Output          Description
  7022. ;       --------------  ---------------------------
  7023. ;       Not applicable
  7024. ;
  7025. ;       Registers used  Description
  7026. ;       --------------  ---------------------------
  7027. ;       SI              Word index into <Entries> table
  7028. ;       ===============================================================
  7029. ;
  7030.  
  7031. XCOMMS_Entry    PROC    NEAR
  7032.                 MOV     XCOMMS_Buffer_Offset, BX
  7033.                 MOV     XCOMMS_Buffer_Segment, DX
  7034.                 MOV     XCOMMS_Buffer_Count, CX
  7035.                 MOV     SI, 0                   ; Call everyone
  7036. _XENTR_loop:
  7037.                 CMP     Entries[SI], LIST_END
  7038.                 JE      _XENTR_exit
  7039.                 PUSH    SI
  7040.                 CALL    Entries[SI]             ; Call indirect
  7041.                 POP     SI
  7042.                 ADD     SI, 2
  7043.                 JMP     _XENTR_loop
  7044. _XENTR_exit:
  7045.                 MOV     AX, 0
  7046.                 CLC
  7047.                 RET
  7048.  
  7049. XCOMMS_Entry    ENDP
  7050.  
  7051. ;
  7052. ;       ===============================================================
  7053. ;       XCOMMS_Exit      Enter and initialize all XCOMMS Services
  7054. ;       ===============================================================
  7055. ;
  7056. ;       Using the <Exeunts> table of intra-segment offsets, call
  7057. ;       each of these procedures.  This is assumed to be invoked only
  7058. ;       when XCOMMS is to end.  It is possible for XCOMMS to continue
  7059. ;       - so the XCOMMS_Entry will be called automatically.
  7060. ;
  7061. ;       Input           Description
  7062. ;       --------------  ---------------------------
  7063. ;       AX = 0001h      Entered via the XCOMMS vector
  7064. ;
  7065. ;       Output          Description
  7066. ;       --------------  ---------------------------
  7067. ;       Not applicable
  7068. ;
  7069. ;       Registers used  Description
  7070. ;       --------------  ---------------------------
  7071. ;       BX              Word index into <Exeunt> table
  7072. ;       ===============================================================
  7073. ;
  7074.  
  7075. XCOMMS_Exit     PROC    NEAR
  7076.                 MOV     BX, 0                   ; Call everyone
  7077. _XEXIT_loop:
  7078.                 CMP     Exeunts[BX], LIST_END
  7079.                 JE      _XEXIT_exit
  7080.                 PUSH    BX
  7081.                 CALL    Exeunts[BX]             ; Call indirect
  7082.                 POP     BX
  7083.                 ADD     BX, 2
  7084.                 JMP     _XEXIT_loop
  7085. _XEXIT_exit:
  7086. ;;              MOV     BX, XCOMMS_Buffer_Offset
  7087. ;;              MOV     DX, XCOMMS_Buffer_Segment
  7088. ;;              MOV     CX, XCOMMS_Buffer_Count
  7089. ;;              CALL    XCOMMS_Entry
  7090.                 MOV     AX, 0
  7091.                 CLC
  7092.                 RET
  7093.  
  7094. XCOMMS_Exit     ENDP
  7095.  
  7096.  
  7097. ;
  7098. ;       ===============================================================
  7099. ;       XCOMMS_Status    Return revision level of XCOMMS
  7100. ;       ===============================================================
  7101. ;
  7102. ;
  7103. ;       Input           Description
  7104. ;       --------------  ---------------------------
  7105. ;       AX = 0000h
  7106. ;
  7107. ;       Output          Description
  7108. ;       --------------  ---------------------------
  7109. ;       AH              Revision major level (binary)
  7110. ;       AL              Revision minor level (binary)
  7111. ;       BX              Number of buffers allocated
  7112. ;       CX              Number of buffers available for use (in pool)
  7113. ;
  7114. ;       ===============================================================
  7115. ;
  7116. XCOMMS_Status   PROC    NEAR
  7117.                 MOV     AH, REV_MAJOR
  7118.                 MOV     AL, REV_MINOR
  7119.                 CALL    BUFFR_Status
  7120.                 RET
  7121. XCOMMS_Status   ENDP
  7122.  
  7123. ;
  7124. ;       ===============================================================
  7125. ;       XCOMMS kernal dispatch interrupt handler
  7126. ;       ===============================================================
  7127. ;
  7128.  
  7129. ;
  7130. ;       ===============================================================
  7131. ;       XCOMMS       Take the XCOMMS kernal interrupt 
  7132. ;       ===============================================================
  7133. ;
  7134. ;       Using the AH,AL 16-bit XCOMMS request code, dispatch to the 
  7135. ;       requested service routine.  Since all general purpose registers
  7136. ;       (AX, BX, CX, DX, SI, DI, BP) must be maintained in the 
  7137. ;       interface, an indirect call is performed by placing the addres
  7138. ;       of the XCOMMS service routine on the stack.  An XCOMMS routine
  7139. ;       will simply perform a NEAR RET to return back to XCOMMS_Int.
  7140. ;
  7141. ;       Note -  "XCOMMS Service" refers to the routine defined
  7142. ;               in XCOMMS for a given intercepted action.
  7143. ;
  7144. ;       XCOMMS Service  Description
  7145. ;       --------------  ---------------------------
  7146. ;       AX,BX,CX,DX     User defined
  7147. ;       SI,DI,BP        User defined
  7148. ;       CS,DS,ES        XCOMMS resident code segment
  7149. ;       SP,SS           User defined
  7150. ;
  7151.  
  7152. XCOMMS          PROC    NEAR                    ; *** Should be FAR ***
  7153.                 JMP     SHORT   _XI_skip
  7154.                 DW      XCOMMS_ID
  7155. _XI_skip:
  7156.                 STI                             ; ENABLE INTERRUPTS
  7157.                 PUSH    DS                      ; Save often used seg regs
  7158.                 PUSH    ES
  7159.                 PUSH    CS
  7160.                 PUSH    CS
  7161.                 POP     ES
  7162.                 POP     DS
  7163.                 PUSH    BP
  7164.                 MOV     BP, SP
  7165.  
  7166.                 PUSH    CX                      ; Look for the AH,AL code
  7167.                 PUSH    DI
  7168.                 MOV     DI, OFFSET Service
  7169.                 MOV     CX, No_Serv
  7170.                 PUSH    CX
  7171.                 REPNZ   SCASW
  7172.                 POP     DI
  7173.                 JNZ     _XI_error
  7174.                 SUB     DI, CX
  7175.                 DEC     DI
  7176.                 SHL     DI, 1
  7177.                 MOV     DI, Routine[DI]
  7178.  
  7179. ;               |----------|
  7180. ;               | user DS  |
  7181. ;               |----------|
  7182. ;               | user ES  |
  7183. ;               |----------|
  7184. ;               | user BP  |<-- BP
  7185. ;               |----------|----------|
  7186. ;               | user CX  |_XI_return| [BP-2]
  7187. ;               |----------|----------|
  7188. ;               | user DI  |  service | [BP-4] <-- SP
  7189. ;               |----------|----------|
  7190.  
  7191.                 MOV     CX, OFFSET _XI_return
  7192.                 XCHG    CX, [BP-2]
  7193.                 XCHG    DI, [BP-4]
  7194.                 RET                             ; *** NEAR *** Call
  7195. _XI_return:
  7196.                 JMP     SHORT _XI_exit
  7197. _XI_error:
  7198.                 POP     DI
  7199.                 POP     CX
  7200. _XI_exit:
  7201.                 POP     BP
  7202.                 POP     ES
  7203.                 POP     DS
  7204.                 IRET                            ; Not chained!
  7205. XCOMMS          ENDP
  7206.  
  7207.         IFDEF   BUNDLD
  7208.                 modend  XCOMMS
  7209.         ELSE
  7210. CSEG            ENDS
  7211.         ENDIF
  7212.                 END
  7213.  
  7214.