home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / NET14 / INT14ASM.OLD < prev    next >
Text File  |  1991-02-05  |  34KB  |  1,069 lines

  1. ;
  2. ;  Int 14h support routines
  3. ;****************************************************************************
  4. ;*                                                                          *
  5. ;*                                                                          *
  6. ;*      part of NCSA Telnet                                                 *
  7. ;*      by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer     *
  8. ;*          Kurt Mahan, Heeren Pathak, Quincey Koziol, & Chris Wilson       *
  9. ;*                                                                          *
  10. ;*      National Center for Supercomputing Applications                     *
  11. ;*      152 Computing Applications Building                                 *
  12. ;*      605 E. Springfield Ave.                                             *
  13. ;*      Champaign, IL  61820                                                *
  14. ;*                                                                          *
  15. ;****************************************************************************
  16. ;
  17.     NAME    INT14
  18. ;Microsoft EQU 1
  19. ;Lattice EQU 1
  20.     ifndef Microsoft
  21.         ifndef Lattice
  22.             if2
  23.                 %out
  24.                 %out ERROR: You have to specify "/DMicrosoft" or "/DLattice" on the
  25.                 %out         MASM command line to determine the type of assembly.
  26.                 %out
  27.             endif
  28.             end
  29.         endif
  30.     endif
  31. ;
  32. ;******************************************************************
  33. ;*
  34. ;*    We need to set up a stack for netsleep when we exit to DOS.
  35.  
  36. NEWSTACK SEGMENT PARA STACK 'STACK'
  37.     dw 4096 dup(?)
  38. STACKEND label far 
  39. NEWSTACK    ends
  40.  
  41. X   EQU     6
  42. PORT    EQU 1
  43. ifdef Microsoft
  44. ;DGROUP  group _DATA
  45. ;_DATA segment public 'DATA'
  46. ;    assume DS:DGROUP
  47. .8086
  48. .MODEL    LARGE
  49. .DATA
  50.     else
  51.     INCLUDE    DOS.MAC
  52.     SETX
  53.     DSEG
  54. endif
  55.  
  56. OLDSS           dw ?
  57. OLDSP           dw ?
  58.  
  59. NUM_COMM_PORTS EQU  4
  60.  
  61. ifdef Microsoft
  62. PUBLIC  _INITIALIZED_FLAGS,_CONNECTED_FLAGS,_OPENING_FLAGS       ; FOR DEBUGGING
  63. PUBLIC  _PORT_BUFFER,_BUFFER_OFFSET       ; FOR DEBUGGING
  64. PUBLIC  _PNUM,_DATA_BEGIN,_DATA_MAX,_DATA_END,_DATA_START
  65. EXTRN   _PRINT_INT:PROC         ; FOR DEBUGGING
  66. EXTRN   _PRINT_INT2:PROC        ; FOR DEBUGGING
  67. EXTRN   _GET_COMM_CHAR:PROC     ; GET A CHARACTER FROM A COMM BUFFER
  68. EXTRN   _NETCLOSE:PROC          ; EXTERNAL PROCEDURE TO CLOSE A CONNECTION
  69. EXTRN   _NETWRITE:PROC          ; EXTERNAL PROCEDURE TO WRITE TO A CONNECTION
  70. EXTRN   _INT14OPEN:PROC         ; EXTERNAL PROCEDURE TO OPEN A CONNECTION
  71. _PNUM   DW NUM_COMM_PORTS DUP(0)    ; PORT WE ARE CONNECTED TO
  72.  
  73. _INITIALIZED_FLAGS DB 0         ; A FLAG IN EACH BIT POSITION TO INDICATE THAT
  74.                                 ; COMM. PORT IS INITIALIZED (BIT 0 IS COMM PORT
  75.                                 ; 0, BIT 1 IF COMM. PORT 1, ETC..)
  76. _CONNECTED_FLAGS DB 0           ; A FLAG IN EACH BIT POSITION TO INDICATE THAT
  77.                                 ; COMM. PORT IS CONNECTED (BIT 0 IS COMM PORT
  78.                                 ; 0, BIT 1 IS COMM. PORT 1, ETC..)
  79. _OPENING_FLAGS DB 0             ; A FLAG IN EACH BIT POSITION TO INDICATE THAT
  80.                                 ; COMM. PORT IS OPENING (BIT 0 IS COMM PORT
  81.                                 ; 0, BIT 1 IS COMM. PORT 1, ETC..)
  82. _PORT_BUFFER    DB  NUM_COMM_PORTS DUP (64 DUP (0)) ; SPECIFY THE FOUR BUFFERS FOR THE CONNECTION NAMES
  83. _BUFFER_OFFSET  DB  NUM_COMM_PORTS DUP (0)   ; THE OFFSETS INTO THE FOUR PORT BUFFERS
  84. _CHAR_TO_SEND   DB 0            ; SPACE TO STORE THE CHARACTER TO SEND ON THE NET
  85. _DATA_BEGIN     DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE BEGINNING OF
  86.                                 ;   THE DATA BUFFER FOR EACH COMM. PORT
  87. _DATA_END       DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE END OF
  88.                                 ;   THE DATA BUFFER FOR EACH COMM. PORT
  89. _DATA_MAX       DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE MAX OF
  90.                                 ;   THE DATA BUFFERS FOR EACH COMM. PORT
  91. _DATA_START     DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE START OF
  92.                                 ;   THE DATA BUFFERS FOR EACH COMM. PORT
  93. else
  94. PUBLIC  INITIALIZED_FLAGS,CONNECTED_FLAGS,OPENING_FLAGS       ; FOR DEBUGGING
  95. PUBLIC  PORT_BUFFER,BUFFER_OFFSET       ; FOR DEBUGGING
  96. PUBLIC  PNUM,DATA_BEGIN,DATA_MAX,DATA_END,DATA_START
  97. EXTRN   PRINT_INT:PROC          ; FOR DEBUGGING
  98. EXTRN   PRINT_INT2:PROC         ; FOR DEBUGGING
  99. EXTRN   GET_COMM_CHAR:PROC      ; GET A CHARACTER FROM A COMM BUFFER
  100. EXTRN   NETCLOSE:PROC           ; EXTERNAL PROCEDURE TO CLOSE A CONNECTION
  101. EXTRN   NETWRITE:PROC           ; EXTERNAL PROCEDURE TO WRITE TO A CONNECTION
  102. EXTRN   INT14OPEN:PROC          ; EXTERNAL PROCEDURE TO OPEN A CONNECTION
  103. PNUM   DW NUM_COMM_PORTS DUP(0)             ; PORT WE ARE CONNECTED TO
  104.  
  105. INITIALIZED_FLAGS DB 0          ; A FLAG IN EACH BIT POSITION TO INDICATE THAT
  106.                                 ; COMM. PORT IS INITIALIZED (BIT 0 IS COMM PORT
  107.                                 ; 0, BIT 1 IF COMM. PORT 1, ETC..)
  108. CONNECTED_FLAGS DB 0            ; A FLAG IN EACH BIT POSITION TO INDICATE THAT
  109.                                 ; COMM. PORT IS CONNECTED (BIT 0 IS COMM PORT
  110.                                 ; 0, BIT 1 IS COMM. PORT 1, ETC..)
  111. OPENING_FLAGS DB 0              ; A FLAG IN EACH BIT POSITION TO INDICATE THAT
  112.                                 ; COMM. PORT IS OPENING (BIT 0 IS COMM PORT
  113.                                 ; 0, BIT 1 IS COMM. PORT 1, ETC..)
  114. PORT_BUFFER     DB  NUM_COMM_PORTS DUP (64 DUP (0)) ; SPECIFY THE FOUR BUFFERS FOR THE CONNECTION NAMES
  115. BUFFER_OFFSET   DB  NUM_COMM_PORTS DUP (0)   ; THE OFFSETS INTO THE FOUR PORT BUFFERS
  116. CHAR_TO_SEND    DB 0             ; SPACE TO STORE THE CHARACTER TO SEND ON THE NET
  117. DATA_BEGIN      DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE BEGINNING OF
  118.                                 ;   THE DATA BUFFERS FOR EACH COMM. PORT
  119. DATA_END        DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE END OF
  120.                                 ;   THE DATA BUFFERS FOR EACH COMM. PORT
  121. DATA_MAX        DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE MAX OF
  122.                                 ;   THE DATA BUFFERS FOR EACH COMM. PORT
  123. DATA_START      DD NUM_COMM_PORTS DUP(0); ARRAY OF POINTERS TO THE START OF
  124.                                 ;   THE DATA BUFFERS FOR EACH COMM. PORT
  125. endif
  126.  
  127. ifdef Microsoft
  128. ;_DATA ends
  129. ;
  130. ;_TEXT    segment public 'CODE'
  131. ;    assume CS:_TEXT
  132. .CODE
  133. else
  134.     ENDDS
  135.     PSEG
  136. endif    
  137. ;
  138. ;**************************************************************************
  139. ;
  140. ;  Routines to install and deinstall a routine which manages the
  141. ;       serial port
  142. ;
  143. ;
  144. SERIALINT     EQU 4*14H       ; User hook to timer int
  145.  
  146. ifdef Microsoft
  147.     PUBLIC  _INT14INST,_INT14DEINST
  148.     PUBLIC  _INT14CHECK,_INT14RECEIVE
  149.     PUBLIC  _GO_TSR
  150.     EXTRN   _int14netsleep:FAR   ; C routine which gets called from handler
  151.     PUBLIC  _TIMEINST,_TIMEDEINST
  152. else    
  153.     PUBLIC  INT14INST,INT14DEINST
  154.     PUBLIC  INT14CHECK,INT14RECEIVE
  155.     PUBLIC  GO_TSR
  156.     EXTRN   int14netsleep:FAR   ; C routine which gets called from handler
  157.     PUBLIC  TIMEINST,TIMEDEINST
  158. endif   
  159. ;
  160. ;**************************************************************************
  161. ;
  162. ;  Routines to install and deinstall a timer routine which calls
  163. ;  netsleep(0);
  164. ;  The timer is set to go off every 1/2 second to check for packets 
  165. ;  in the incoming packet buffer.  We use the user-hook into the system 
  166. ;  timer which occurs every 1/18th of a second.
  167. ;
  168. ;
  169. TIMEINT        EQU    4*1CH        ; User hook to timer int
  170.  
  171. ;*************************************************************************
  172. ;
  173. ;  Take out the timer interrupt handler, restore previous value
  174. ;
  175. ifdef Microsoft
  176. _TIMEDEINST    PROC    FAR
  177. else
  178. TIMEDEINST PROC    FAR
  179. endif
  180.     MOV        CX,CS:TIP        ; GET OLD IP FROM SAVE SPOT
  181.     MOV        DX,CS:TCS        ; GET OLD CS FROM SAVE SPOT
  182.     MOV        BX,TIMEINT        ; INTERRUPT IN TABLE FOR TIMER
  183.     PUSH    DS
  184.     XOR        AX,AX            ; SYSTEM INTERRUPT TABLE
  185.     MOV        DS,AX        
  186.     CLI
  187.     MOV        [BX],CX            ; STORE OLD IP INTO THE TABLE
  188.     INC        BX
  189.     INC        BX                ; MOVE POINTER IN INTERRUPT TABLE
  190.     MOV        [BX],DX            ; STORE OLD CS INTO THE TABLE
  191.     STI
  192.     POP        DS
  193.     RET
  194. ifdef Microsoft
  195. _TIMEDEINST    ENDP
  196. else
  197. TIMEDEINST ENDP
  198. endif
  199.  
  200. ;
  201. ;
  202. ;  install the timer interrupt handler, the handler is technically
  203. ;  part of this procedure.
  204. ;
  205. ifdef Microsoft
  206. _TIMEINST  PROC    FAR
  207. else
  208. TIMEINST   PROC    FAR
  209. endif
  210.     XOR        AX,AX
  211.     MOV     CS:INTENTER,AL    ; CLEAR THIS FLAG
  212.     MOV        CS:TMYDS,DS        ; STORE FOR USE BY HANDLER
  213.     MOV        BX,TIMEINT        ; INTERRUPT IN TABLE FOR TIMER (1c)
  214.     PUSH    DS
  215.     XOR        AX,AX            ; SYSTEM INTERRUPT TABLE
  216.     MOV        DS,AX        
  217.     MOV        AX,OFFSET THAND    ; WHERE THE HANDLER IS
  218.     CLI
  219.     MOV        DX,[BX]            ; KEEP COPY OF THE IP
  220.     MOV        [BX],AX            ; STORE IP INTO THE TABLE
  221.     INC        BX
  222.     INC        BX                ; MOVE POINTER IN INTERRUPT TABLE
  223.     MOV        CX,[BX]            ; KEEP COPY OF THE CS, TOO
  224.     MOV        AX,CS
  225.     MOV        [BX],AX            ; STORE NEW CS INTO THE TABLE
  226.     STI
  227.     POP    DS
  228.     MOV    CS:TIP,DX            ; STORE THEM AWAY
  229.     MOV    CS:TCS,CX
  230.     RET
  231. ;
  232. ;  Code segment addressable data for keeping track of the interrupt handler
  233. ;  stuff
  234. ;
  235. TMYDS        DW    00H            ; THE DATA SEGMENT FOR THIS ASSEMBLY CODE
  236. TICNT        DB    0            ; COUNTER OF 1/18THS SEC
  237. INTENTER      DB  00
  238. TIP          DW  00
  239. TCS          DW  00
  240. ;
  241. ;   The handler itself.
  242. ;
  243. THAND:                           ; not a public name, only handles ints
  244.     STI
  245.     PUSH    DS
  246.     PUSH     ES
  247.     PUSH    AX
  248.     PUSH    BX
  249.     PUSH    CX
  250.     PUSH    DX
  251.     PUSH    DI
  252.     PUSH    SI
  253.  
  254.     CLD                        ; ALL MOVES WILL BE FORWARD
  255.     MOV     AL,CS:INTENTER
  256.     OR        AL,AL
  257.     JNZ        TIME2
  258.     MOV        AL,1
  259.     MOV     CS:INTENTER,AL    ; SET FLAG TO INDICATE BUSY
  260. ifdef FAST
  261.     INC     CS:TICNT
  262.     MOV     AL,CS:TICNT     ; COUNTER FOR US
  263. ifdef QAK
  264.     AND        AL,7            ; SEE IF # MOD 8 = 0
  265. else
  266.     AND     AL,3            ; SEE IF # MOD 4 = 0
  267. endif
  268.     JNZ        TSKIP            ; SKIP 7 OUT OF 8 TIMES
  269. endif
  270. ;
  271.     MOV        AL,60H            ; EOI FOR TIMER INT
  272.     OUT        20H,AL            ; LET LOWER INTERRUPTS IN
  273. ;
  274. ;  SET UP CORRECT DS
  275. ;
  276.     MOV        DS,CS:TMYDS        ; GET CORRECT DS
  277. ;
  278. ;  do we have to set up our own stack here?
  279. ;
  280.     MOV        AX,SS
  281.     MOV        OLDSS,AX
  282.     MOV        OLDSP,SP
  283.     CLI
  284.     MOV        AX,seg NEWSTACK
  285.     MOV        SS,AX
  286.     MOV        SP,OFFSET STACKEND
  287.     STI
  288. ;    XOR     AX,AX
  289. ;    PUSH    AX
  290. ifdef Microsoft
  291.     CALL _int14netsleep
  292. else    
  293.     CALL int14netsleep
  294. endif
  295. ;    POP     AX
  296.     CLI    
  297.     MOV        AX,OLDSS
  298.     MOV        SS,AX
  299.     MOV        SP,OLDSP
  300.     STI
  301. TSKIP:
  302.     XOR        AL,AL
  303.     MOV     CS:INTENTER,AL    ; REENTER FLAG, DONE NOW
  304. ifdef QAK
  305. MOV     AX,65               ; DEBUGGING
  306. PUSH    AX
  307. ifdef Microsoft
  308. CALL    _PRINT_INT
  309. else
  310. CALL    PRINT_INT
  311. endif
  312. POP     AX
  313. endif
  314. TIME2:
  315.     POP     SI
  316.     POP        DI
  317.     POP        DX
  318.     POP        CX
  319.     POP        BX
  320.     POP        AX
  321.     POP        ES
  322.     POP        DS
  323. ;
  324. ;   forward to any other existing routines
  325. ;
  326. ifndef QAK
  327.     JMP     DWORD PTR CS:TIP
  328. else
  329.     IRET
  330. endif
  331. ifdef Microsoft
  332. _TIMEINST      ENDP
  333. else
  334. TIMEINST       ENDP
  335. endif
  336.  
  337. ;*************************************************************************
  338. ;
  339. ;  Go into TSR mode
  340. ;
  341. ifdef Microsoft
  342. _GO_TSR    PROC    FAR
  343. else
  344. GO_TSR  PROC    FAR
  345. endif
  346.     MOV     AX,3100H            ; DOS TSR FUNCTION
  347.     MOV     DX,3360H            ; THIS IS REALLY, REALLY BAD, NEEDS TO NOT
  348.                                 ; BE A HARDWIRED NUMBER
  349.     INT     21H                 ; GO TSR
  350. ifdef Microsoft
  351. _GO_TSR    ENDP
  352. else
  353. GO_TSR  ENDP
  354. endif
  355. ;*************************************************************************
  356. ;
  357. ;  Check the int14 receive status
  358. ;
  359. ifdef Microsoft
  360. _INT14CHECK    PROC    FAR
  361. else
  362. INT14CHECK PROC    FAR
  363. endif
  364.     MOV     AH,3
  365.     MOV     DX,PORT
  366.     INT     14H
  367.     XOR     AL,AL
  368.     RET
  369. ifdef Microsoft
  370. _INT14CHECK    ENDP
  371. else
  372. INT14CHECK ENDP
  373. endif
  374.  
  375. ;*************************************************************************
  376. ;
  377. ;  Get a character from int14
  378. ;
  379. ifdef Microsoft
  380. _INT14RECEIVE    PROC    FAR
  381. else
  382. INT14RECEIVE PROC    FAR
  383. endif
  384.     MOV     AH,2
  385.     MOV     DX,PORT
  386.     INT     14H
  387.     RET
  388. ifdef Microsoft
  389. _INT14RECEIVE   ENDP
  390. else
  391. INT14RECEIVE ENDP
  392. endif
  393.  
  394. ;*************************************************************************
  395. ;
  396. ;  Take out the serial interrupt handler, restore previous value
  397. ;
  398. ifdef Microsoft
  399. _INT14DEINST    PROC    FAR
  400. else
  401. INT14DEINST PROC    FAR
  402. endif
  403. ifdef DEBUG
  404. MOV     AX,43               ; DEBUGGING
  405. PUSH    AX
  406. ifdef Microsoft
  407. CALL    _PRINT_INT
  408. else
  409. CALL    PRINT_INT
  410. endif
  411. POP     AX
  412. endif
  413.     MOV     CX,CS:SIP       ; GET OLD IP FROM SAVE SPOT
  414.     MOV     DX,CS:SCS       ; GET OLD CS FROM SAVE SPOT
  415.     MOV     BX,SERIALINT    ; INTERRUPT IN TABLE FOR TIMER
  416.     PUSH    DS
  417.     XOR        AX,AX            ; SYSTEM INTERRUPT TABLE
  418.     MOV        DS,AX        
  419.     CLI
  420.     MOV        [BX],CX            ; STORE OLD IP INTO THE TABLE
  421.     INC        BX
  422.     INC        BX                ; MOVE POINTER IN INTERRUPT TABLE
  423.     MOV        [BX],DX            ; STORE OLD CS INTO THE TABLE
  424.     STI
  425.     POP        DS
  426.     RET
  427. ifdef Microsoft
  428. _INT14DEINST    ENDP
  429. else
  430. INT14DEINST ENDP
  431. endif
  432. ;
  433. ;
  434. ;  install the serial interrupt handler, the handler is technically
  435. ;  part of this procedure.
  436. ;
  437. ifdef Microsoft
  438. _INT14INST  PROC    FAR
  439. else
  440. INT14INST   PROC    FAR
  441. endif
  442.  
  443. ifdef DEBUG
  444. MOV     AX,42               ; DEBUGGING
  445. PUSH    AX
  446. ifdef Microsoft
  447. CALL    _PRINT_INT
  448. else
  449. CALL    PRINT_INT
  450. endif
  451. POP     AX
  452. endif
  453.  
  454.     XOR        AX,AX
  455.     MOV     CS:INTENTER,AL    ; CLEAR THIS FLAG
  456.     MOV     CS:SMYDS,DS     ; STORE FOR USE BY HANDLER
  457.     MOV     BX,SERIALINT    ; INTERRUPT IN TABLE FOR TIMER (1c)
  458.     PUSH    DS
  459.     XOR        AX,AX            ; SYSTEM INTERRUPT TABLE
  460.     MOV        DS,AX        
  461.     MOV     AX,OFFSET SHAND ; WHERE THE HANDLER IS
  462.     CLI
  463.     MOV        DX,[BX]            ; KEEP COPY OF THE IP
  464.     MOV        [BX],AX            ; STORE IP INTO THE TABLE
  465.     INC        BX
  466.     INC        BX                ; MOVE POINTER IN INTERRUPT TABLE
  467.     MOV        CX,[BX]            ; KEEP COPY OF THE CS, TOO
  468.     MOV        AX,CS
  469.     MOV        [BX],AX            ; STORE NEW CS INTO THE TABLE
  470.     STI
  471.     POP    DS
  472.     MOV CS:SIP,DX           ; STORE THEM AWAY
  473.     MOV CS:SCS,CX
  474.     RET
  475. ;
  476. ;  Code segment addressable data for keeping track of the interrupt handler
  477. ;  stuff
  478. ;
  479. SMYDS       DW  00H         ; THE DATA SEGMENT FOR THIS ASSEMBLY CODE
  480. SICNT       DB  0           ; COUNTER OF 1/18THS SEC
  481. ;SENTER      DB  00
  482. SIP         DW  00
  483. SCS         DW  00
  484. ;
  485. ;   The handler itself.
  486. ;
  487. SHAND:                      ; not a public name, only handles ints
  488.     STI
  489.     PUSH    DS
  490.     PUSH     ES
  491.     PUSH    AX
  492.     PUSH    BX
  493.     PUSH    CX
  494.     PUSH    DX
  495.     PUSH    DI
  496.     PUSH    SI
  497.  
  498.     CLD                        ; ALL MOVES WILL BE FORWARD
  499.     MOV     BL,CS:INTENTER    ; CHECK FOR RE-ENTRY
  500.     OR      BL,BL
  501.     JZ      NO_RE_ENTRY     ;
  502.     JMP     SERIAL2         ; DON'T RE-ENTER, WE ARE BUSY NOW
  503. NO_RE_ENTRY:
  504.     MOV     BL,1
  505.     MOV     CS:INTENTER,BL    ; SET FLAG TO INDICATE BUSY
  506.  
  507. ;
  508. ifdef QAK
  509.     MOV        AL,60H            ; EOI FOR TIMER INT
  510.     OUT        20H,AL            ; LET LOWER INTERRUPTS IN
  511. endif
  512. ;
  513. ;  SET UP CORRECT DS
  514. ;
  515.     MOV     DS,CS:SMYDS     ; GET CORRECT DS
  516. ;
  517. ;  do we have to set up our own stack here?
  518. ;
  519.     MOV     BX,SS
  520.     MOV     OLDSS,BX
  521.     MOV        OLDSP,SP
  522.     CLI
  523.     MOV     BX,seg NEWSTACK
  524.     MOV     SS,BX
  525.     MOV        SP,OFFSET STACKEND
  526.     STI
  527. ifdef REAL_CODE
  528.     XOR     AX,AX
  529.     PUSH     AX
  530. ifdef Microsoft
  531.     CALL _netsleep
  532. else    
  533.     CALL netsleep
  534. endif
  535.     POP        AX
  536. else
  537.  
  538. ifdef DEBUG
  539. PUSH    DX
  540. PUSH    AX
  541. ifdef Microsoft
  542. CALL    _PRINT_INT
  543. else
  544. CALL    PRINT_INT
  545. endif
  546. POP     AX
  547. POP     DX
  548. endif
  549.     MOV     CX,DX           ; MOVE THE COMM. PORT INTO THE CX REGISTER
  550.     MOV     BL,1            ; MOVE A FLAG INTO THE BL REGISTER
  551.     SHL     BL,CL           ; SHIFT THE FLAG TO LINE UP WITH THE CORRECT INITIALIZATION FLAG
  552.     CMP     AH,00           ; CHECK FOR PORT INITIALIZATION
  553.     JNE     NOT_INIT_COM_PORT   ; JUMP AROUND INITIALIZING THE COMM PORT
  554.  
  555. INIT_COM_PORT:              ; INITIALIZE THE COMM. PORT
  556. ifdef Microsoft
  557.     TEST    BL,_INITIALIZED_FLAGS; CHECK WHETHER THIS CONNECTION HAS BEEN INITIALIZED
  558.     JNE     PORT_ALREADY_INIT   ; JUMP TO THE CHECK FOR CLOSING THE PORT
  559.     OR      _INITIALIZED_FLAGS,BL; SET THE INITIALIZED FLAG FOR THIS PORT
  560. else
  561.     TEST    BL,INITIALIZED_FLAGS; CHECK WHETHER THIS CONNECTION HAS BEEN INITIALIZED
  562.     JNE     PORT_ALREADY_INIT   ; JUMP TO THE CHECK FOR CLOSING THE PORT
  563.     OR      INITIALIZED_FLAGS,BL; SET THE INITIALIZED FLAG FOR THIS PORT
  564. endif
  565.     JMP     SHORT RESET_INIT      ; JUMP TO RESETING THE COMM. PORT BUFFER
  566.  
  567. PORT_ALREADY_INIT:          ; THE PORT HAS ALREADY BEEN INITIALIZED
  568. ifdef Microsoft
  569.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER WE WERE CONNECTED
  570. else
  571.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER WE WERE CONNECTED
  572. endif
  573.     JE      RESET_INIT      ; IGNORE RE-INITIALIZATION IF NOT CONNECTED
  574.     NOT     BL              ; INVERT AL IN PREPERATION FOR TURNING OFF THE FLAGS
  575. ifdef Microsoft
  576.     AND     _INITIALIZED_FLAGS,BL; RESET THE INITIALIZATION FLAG FOR THIS PORT
  577.     AND     _CONNECTED_FLAGS,BL  ; RESET THE CONNECTED FLAG FOR THIS PORT
  578. else
  579.     AND     INITIALIZED_FLAGS,BL; RESET THE INITIALIZATION FLAG FOR THIS PORT
  580.     AND     CONNECTED_FLAGS,BL  ; RESET THE CONNECTED FLAG FOR THIS PORT
  581. endif
  582.  
  583. ifdef Microsoft
  584.     MOV     SI,OFFSET _PNUM ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  585. else
  586.     MOV     SI,OFFSET PNUM  ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  587. endif
  588.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  589.     ADD     SI,DX           ; TWICE BECAUSE THESE ARE INTEGERS, NOT BYTES
  590.     PUSH    DX
  591.     PUSH    [SI]            ; PUSH THE NETWORK PORT NUMBER
  592. ifdef Microsoft
  593.     CALL    _NETCLOSE       ; CLOSE THE CONNECTION
  594. else
  595.     CALL    NETCLOSE        ; CLOSE THE CONNECTION
  596. endif
  597.     ADD     SP,2            ; GET RID OF THE PARAMETER WE PASSED
  598.     POP     DX
  599.  
  600. RESET_INIT:
  601. ifdef Microsoft
  602.     MOV     SI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  603. else
  604.     MOV     SI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  605. endif
  606.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  607.     MOV     BYTE PTR [SI],0     ; ZERO OUT THE BUFFER OFFSET FOR THE COMM. PORT
  608.  
  609. INIT_FINISHED:
  610.     MOV     AX,61B0H        ; MOVE THE RS-232 CONNECTED FLAGS INTO THE RETURN VALUE
  611.     JMP     SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  612.  
  613. NOT_INIT_COM_PORT:
  614.     CMP     AH,01           ; CHECK FOR SEND CHARACTER
  615.     JE      SEND_CHARACTER  ; JUMP TO SENDING THE CHARACTER
  616.     JMP     NOT_SEND_CHARACTER; JUMP AROUND SENDING THE CHARACTER
  617.  
  618. SEND_CHARACTER:             ; SEND A CHARACTER
  619. ifdef Microsoft
  620.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  621.     JE      DONT_NET_SEND   ; CONNECTION NOT OPEN YET, DON'T SEND THE CHARACTER
  622.     JMP     NET_SEND        ; OK, THE CONNECTION IS INITIALIZED, SEND THE CHARACTER
  623. DONT_NET_SEND:
  624.     TEST    BL,_OPENING_FLAGS; IF THE OPENING FLAG IS SET FOR THE PORT, CACHE THE CHARACTER IN A BUFFER
  625. else
  626.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  627.     JE      DONT_NET_SEND   ; CONNECTION NOT OPEN YET, DON'T SEND THE CHARACTER
  628.     JMP     NET_SEND        ; OK, THE CONNECTION IS INITIALIZED, SEND THE CHARACTER
  629. DONT_NET_SEND:
  630.     TEST    BL,OPENING_FLAGS; IF THE OPENING FLAG IS SET FOR THE PORT, CACHE THE CHARACTER IN A BUFFER
  631. endif
  632.     JNE     CACHE_PORT_NAME ; GO CACHE THE CHARACTER
  633.     CMP     AL,02           ; CHECK WHETHER THIS IS THE BEGINNING OF A PORT NAME
  634.     JE      START_PORT_NAME ; START CACHING THE PORT NAME
  635. ifdef DEBUG
  636. .286
  637. PUSH    2048h
  638. ifdef Microsoft
  639. CALL    _PRINT_INT
  640. else
  641. CALL    PRINT_INT
  642. endif
  643. ADD     SP,2
  644. .8086
  645. endif
  646. ifdef DEBUG
  647. PUSH    BX
  648. ifdef Microsoft
  649. CALL    _PRINT_INT
  650. else
  651. CALL    PRINT_INT
  652. endif
  653. ADD     SP,2
  654. endif
  655. ifdef DEBUG
  656. MOV     AL,_OPENING_FLAGS
  657. XOR     AH,AH
  658. PUSH    AX
  659. ifdef Microsoft
  660. CALL    _PRINT_INT
  661. else
  662. CALL    PRINT_INT
  663. endif
  664. ADD     SP,2
  665. endif
  666.     MOV     AH,80H          ; REPORT ERROR CONDITION
  667.     JMP     SEND_FINISHED   ;
  668.  
  669. START_PORT_NAME:            ; INITIALIZE THE PORT NAME CACHING
  670. ifdef Microsoft
  671.     OR      _OPENING_FLAGS,BL; SET THE OPENING FLAG
  672. else
  673.     OR      OPENING_FLAGS,BL; SET THE OPENING FLAG
  674. endif
  675. ifdef DEBUG
  676. .286
  677. PUSH    2047h
  678. ifdef Microsoft
  679. CALL    _PRINT_INT
  680. else
  681. CALL    PRINT_INT
  682. endif
  683. ADD     SP,2
  684. .8086
  685. endif
  686. ifdef DEBUG
  687. PUSH    BX
  688. ifdef Microsoft
  689. CALL    _PRINT_INT
  690. else
  691. CALL    PRINT_INT
  692. endif
  693. ADD     SP,2
  694. endif
  695. ifdef DEBUG
  696. MOV     AL,_OPENING_FLAGS
  697. XOR     AH,AH
  698. PUSH    AX
  699. ifdef Microsoft
  700. CALL    _PRINT_INT
  701. else
  702. CALL    PRINT_INT
  703. endif
  704. ADD     SP,2
  705. endif
  706.     JMP     SEND_DONE       ; INDICATE A SUCCESSFUL CHARACTER SEND, BUT DON'T REALLY
  707.  
  708. CACHE_PORT_NAME:            ; STUFF THE CHARACTER INTO A BUFFER, OR OPEN A CONNECTION
  709.     CMP     AL,03H          ; CHECK WHETHER THIS IS THE TERMINATING CHARACTER IN A PORT NAME
  710.     JE      NET_OPEN        ; GO, OPEN THE CONNECTION
  711. ifdef Microsoft
  712.     MOV     DI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  713. else
  714.     MOV     DI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  715. endif
  716.     ADD     DI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  717.     MOV     CL,AL           ; SAVE THE CHARACTER TEMPORARILY
  718.     MOV     AL,64           ; MOVE THE SIZE OF THE PORT NAME BUFFER INTO AL
  719.     MUL     DL              ; GET THE OFFSET OF THE PORT BUFFER TO USE
  720.     ADD     AX,DS:[DI]      ; GET THE OFFSET TO STORE THE CHARACTER AT
  721.     INC     BYTE PTR DS:[DI]    ; INCREMENT THE BUFFER OFFSET FOR THE COMM. PORT
  722.     CMP     BYTE PTR DS:[DI],64 ; CHECK WHETHER WE HAVE TOO LONG OF A NAME
  723.     JE      NAME_TOO_LONG   ; JUMP FOR TOO LONG OF A NAME
  724. ifdef Microsoft
  725.     MOV     SI,OFFSET _PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  726. else
  727.     MOV     SI,OFFSET PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  728. endif
  729.     ADD     SI,AX           ; GET THE CORRECT OFFSET TO STORE THIS CHARACTER AT
  730.     MOV     AL,CL           ; RESTORE THE CHARACTER TO STORE
  731.     MOV     [SI],AL         ; APPEND THE CHARACTER TO THE PORT NAME
  732. ifdef DEBUG
  733. .286
  734. PUSH    2044h
  735. ifdef Microsoft
  736. CALL    _PRINT_INT
  737. else
  738. CALL    PRINT_INT
  739. endif
  740. ADD     SP,2
  741. .8086
  742. endif
  743.     JMP     SEND_DONE       ; INDICATE A GOOD TRANSFER
  744.  
  745. NAME_TOO_LONG:              ; THE PORT NAME WAS TOO LONG
  746.     MOV     BYTE PTR DS:[DI],0  ; RESET THE LENGTH OF THE PORT NAME
  747.     NOT     BL              ;
  748. ifdef Microsoft
  749.     AND     _OPENING_FLAGS,BL; RESET THE OPENING FLAG
  750. else
  751.     AND     OPENING_FLAGS,BL; RESET THE OPENING FLAG
  752. endif
  753.     MOV     AL,CL           ; RESTORE THE CHARACTER TO SEND
  754. ifdef DEBUG
  755. .286
  756. PUSH    2045h
  757. ifdef Microsoft
  758. CALL    _PRINT_INT
  759. else
  760. CALL    PRINT_INT
  761. endif
  762. ADD     SP,2
  763. .8086
  764. endif
  765.     MOV     AH,80H          ; INDICATE ERROR CONDITION
  766.     JMP     SHORT SEND_FINISHED   ; JUMP TO THE END OF THE ROUTINE
  767.  
  768. NET_OPEN:                   ; OPEN THE CONNECTION TO THE NETWORK
  769.     NOT     BL              ;
  770. ifdef Microsoft
  771.     AND     _OPENING_FLAGS,BL; RESET THE OPENING FLAG
  772.     MOV     DI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  773. else
  774.     AND     OPENING_FLAGS,BL; RESET THE OPENING FLAG
  775.     MOV     DI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  776. endif
  777.     ADD     DI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  778.     MOV     CL,AL           ; SAVE THE CHARACTER TEMPORARILY
  779.     MOV     AL,64           ; MOVE THE SIZE OF THE PORT NAME BUFFER INTO AL
  780.     MUL     DL              ; GET THE OFFSET OF THE PORT BUFFER TO USE
  781.     ADD     AX,DS:[DI]      ; GET THE OFFSET TO STORE THE CHARACTER AT
  782. ifdef Microsoft
  783.     MOV     SI,OFFSET _PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  784. else
  785.     MOV     SI,OFFSET PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  786. endif
  787.     PUSH    BX              ; SAVE THE COMM. PORT FLAGS
  788.     ADD     SI,AX           ; GET THE CORRECT OFFSET TO STORE THIS CHARACTER AT
  789.     MOV     AL,CL           ; RESTORE THE CHARACTER TO STORE
  790.     MOV     BYTE PTR [SI],0 ; APPEND THE TERMINATING ZERO
  791.     PUSH    DX              ; PUSH THE COMM. PORT WE ARE OPENING
  792. ifdef Microsoft
  793.     CALL    _INT14OPEN      ; OPEN THE CONNECTION
  794. else
  795.     CALL    INT14OPEN       ; OPEN THE CONNECTION
  796. endif
  797.     POP     DX              ; RECOVER THE COMM. PORT WE USED
  798.     POP     BX              ; RECOVER THE COMM. PORT FLAGS
  799.     CMP     AX,1            ; CHECK FOR GOOD OPENING
  800.     JNE     BAD_NET_OPEN    ; CONNECTION DIDN'T OPEN
  801.  
  802.     NOT     BL              ;
  803. ifdef Microsoft
  804.     OR      _CONNECTED_FLAGS,BL; SET THE CONNECTED FLAG
  805.     MOV     SI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  806. else
  807.     OR      CONNECTED_FLAGS,BL; SET THE CONNECTED FLAG
  808.     MOV     SI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  809. endif
  810.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  811.     MOV     BYTE PTR [SI],0     ; ZERO OUT THE BUFFER OFFSET FOR THE COMM. PORT
  812.     JMP     SHORT SEND_DONE       ; INDICATE A SUCCESSFUL CONNECTION OPENING
  813.  
  814. BAD_NET_OPEN:
  815. ifdef DEBUG
  816. .286
  817. PUSH    2046h
  818. ifdef Microsoft
  819. CALL    _PRINT_INT
  820. else
  821. CALL    PRINT_INT
  822. endif
  823. ADD     SP,2
  824. .8086
  825. endif
  826.     MOV     AX,80           ; INDICATE A BAD NETWORK OPEN
  827.     JMP     SHORT SEND_FINISHED   ; RETURN FROM THE INTERRUPT
  828.  
  829. NET_SEND:                   ; SEND THE CHARACTER IN AL ONTO THE NET
  830. ifdef Microsoft
  831.     MOV     _CHAR_TO_SEND,AL ; STORE THE CHARACTER TO SEND ON THE NET
  832. else
  833.     MOV     CHAR_TO_SEND,AL ; STORE THE CHARACTER TO SEND ON THE NET
  834. endif
  835.     MOV     AX,1            ; THE NUMBER OF CHARACTERS TO DROP ONTO THE NET
  836.     PUSH    AX
  837.     PUSH    DS              ; PUSH THE SEGMENT ADDRESS OF THE CHARACTER TO SEND
  838.     MOV     AX,OFFSET _CHAR_TO_SEND ; PUSH THE ADDRESS OF THE CHARACTER TO SEND
  839.     PUSH    AX
  840. ifdef Microsoft
  841.     MOV     SI,OFFSET _PNUM ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  842. else
  843.     MOV     SI,OFFSET PNUM  ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  844. endif
  845.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  846.     ADD     SI,DX           ; TWICE BECAUSE THESE ARE INTEGERS, NOT BYTES
  847.     PUSH    [SI]            ; PUSH THE NETWORK PORT NUMBER
  848. ifdef Microsoft
  849.     CALL    _NETWRITE       ; CLOSE THE CONNECTION
  850. else
  851.     CALL    NETWRITE        ; CLOSE THE CONNECTION
  852. endif
  853.     ADD     SP,8            ; RESTORE THE STACK FRAME
  854. ;   JMP     SEND_DONE       ; INDICATE A SUCCESSFUL DATA SEND
  855.  
  856. SEND_DONE:                  ; INDICATE A SUCCESSFUL CHARACTER SEND
  857.     MOV     AH,21           ; INDICATE A HAPPY CHARACTER SEND
  858. SEND_FINISHED:
  859.     JMP     SHORT SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  860.  
  861. NOT_SEND_CHARACTER:
  862.     CMP     AH,02           ; CHECK FOR RECEIVING CHARACTER
  863.     JNE     NOT_RECEIVE_CHARACTER;  JUMP AROUND RECEIVING A CHARACTER
  864.  
  865. RECEIVE_CHARACTER:          ; GET A CHARACTER
  866. ifdef Microsoft
  867.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  868. else
  869.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  870. endif
  871.     JNE     GET_PORT_CHARACTER; GET A CHARACTER FROM THE PORT
  872.     MOV     AH,80H          ; REPORT ERROR CONDITION
  873.     JMP     SHORT RECEIVE_FINISHED   ;
  874.  
  875. GET_PORT_CHARACTER:
  876. ifndef QAK
  877.     PUSH    DX                      ; PUSH THE PORT NUMBER
  878. ifdef Microsoft
  879.     CALL    _GET_COMM_CHAR          ; CALL A C ROUTINE TO GET THE CHARACTER
  880. else
  881.     CALL    GET_COMM_CHAR           ; CALL A C ROUTINE TO GET THE CHARACTER
  882. endif
  883.     ADD     SP,2                    ; REMOVE PARAMETER
  884. else
  885. ifdef Microsoft
  886.     MOV     SI,OFFSET _DATA_BEGIN   ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  887.     MOV     DI,OFFSET _DATA_END     ; GET THE POINTER TO THE END OF THE DATA BUFFER
  888. else
  889.     MOV     SI,OFFSET DATA_BEGIN    ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  890.     MOV     DI,OFFSET DATA_END      ; GET THE POINTER TO THE END OF THE DATA BUFFER
  891. endif
  892.     SHL     DX,1                    ; MULTIPLY THE PORT NUMBER BY 4 TO GET THE
  893.     SHL     DX,1                    ;   OFFSET TO THE CORRECT ARRAY ELEMENT
  894.     ADD     SI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  895.     ADD     DI,DX
  896. WAIT_FOR_CHARACTER:
  897. ifdef QAK
  898.     MOV     AX,DS:[SI+2]            ; GET THE OFFSET INTO THE DATA BUFFER OF THE BEGINNING
  899.     CMP     AX,DS:[DI+2]            ; CHECK WHETHER THERE ARE CHARACTERS IN THE BUFFER
  900. else
  901.     MOV     AX,DS:[SI]              ; GET THE OFFSET INTO THE DATA BUFFER OF THE BEGINNING
  902.     CMP     AX,DS:[DI]              ; CHECK WHETHER THERE ARE CHARACTERS IN THE BUFFER
  903. endif
  904.     JE      WAIT_FOR_CHARACTER      ; IF THE TWO POINTERS ARE THE SAME, THEN WAIT FOR DATA
  905.  
  906.     PUSH    DS
  907.     MOV     DI,AX                   ; SAVE THE OFFSET OF THE BEGINING POINTER
  908. ifdef QAK
  909.     MOV     AX,DS:[SI]              ; GET THE SEGMENT OF THE BEGINNING POINTER
  910. else
  911.     MOV     AX,DS:[SI+2]            ; GET THE SEGMENT OF THE BEGINNING POINTER
  912. endif
  913.     MOV     DS,AX
  914.     MOV     AL,BYTE PTR DS:[DI]     ; GET THE CHARACTER FROM THE BEGINNING OF THE QUEUE
  915.     POP     DS                      ; RECOVER THE DATA SEGMENT
  916. ifdef Microsoft
  917.     MOV     DI,OFFSET _DATA_MAX     ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  918. else
  919.     MOV     DI,OFFSET DATA_MAX      ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  920. endif
  921.     ADD     DI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  922. ifdef QAK
  923.     INC     WORD PTR DS:[SI+2]      ; INCREMENT THE BEGINNING OF THE QUEUE
  924.     MOV     CX,DS:[SI+2]            ; GET THE BEGINNING OF THE QUEUE
  925.     CMP     CX,DS:[DI+2]            ; CHECK FOR WRAPPING AROUND
  926. else
  927.     INC     WORD PTR DS:[SI]        ; INCREMENT THE BEGINNING OF THE QUEUE
  928.     MOV     CX,DS:[SI]              ; GET THE BEGINNING OF THE QUEUE
  929.     CMP     CX,DS:[DI]              ; CHECK FOR WRAPPING AROUND
  930. endif
  931.     JL      NOT_WRAPPED             ; JUMP AROUND WRAP-AROUND FIX
  932. ifdef Microsoft
  933.     MOV     DI,OFFSET _DATA_START   ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  934. else
  935.     MOV     DI,OFFSET DATA_START    ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  936. endif
  937.     ADD     DI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  938. ifdef QAK
  939.     MOV     CX,DS:[DI+2]            ; GET THE START OF THE QUEUE
  940.     MOV     DS:[SI+2],CX            ; MOVE THE BEGINNING OF THE QUEUE AROUND
  941. else
  942.     MOV     CX,DS:[DI]              ; GET THE START OF THE QUEUE
  943.     MOV     DS:[SI],CX              ; MOVE THE BEGINNING OF THE QUEUE AROUND
  944. endif
  945. endif
  946.  
  947. NOT_WRAPPED:
  948.     MOV     AH,21           ; REPORT SUCCESS
  949.  
  950. RECEIVE_FINISHED:
  951.     JMP     SHORT SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  952.  
  953. NOT_RECEIVE_CHARACTER:
  954.     CMP     AH,03           ; CHECK FOR READ STATUS
  955.     JNE     SSKIP           ; A COMMUNICATION REQUEST WHICH WE DON'T HANDLE
  956.  
  957. READ_STATUS:                ; CHECK FOR A CHARACTER
  958. ifdef Microsoft
  959.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  960. else
  961.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  962. endif
  963.     JNE     GET_PORT_STATUS ; GET THE PORT STATUS
  964. ;    MOV     AX,7ABFH          ; REPORT ERROR CONDITION
  965.     MOV     AX,2000H           ; REPORT ERROR CONDITION
  966.     JMP     SHORT STATUS_FINISHED ;
  967.  
  968. GET_PORT_STATUS:
  969. ifdef Microsoft
  970.     MOV     SI,OFFSET _DATA_BEGIN   ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  971.     MOV     DI,OFFSET _DATA_END     ; GET THE POINTER TO THE END OF THE DATA BUFFER
  972. else
  973.     MOV     SI,OFFSET DATA_BEGIN    ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  974.     MOV     DI,OFFSET DATA_END      ; GET THE POINTER TO THE END OF THE DATA BUFFER
  975. endif
  976.     SHL     DX,1                    ; MULTIPLY THE PORT NUMBER BY 4 TO GET THE
  977.     SHL     DX,1                    ;   OFFSET TO THE CORRECT ARRAY ELEMENT
  978.     ADD     SI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  979.     ADD     DI,DX
  980.  
  981. ifdef QAK
  982.     MOV     AX,DS:[SI+2]            ; GET THE OFFSET INTO THE DATA BUFFER OF THE BEGINNING
  983.     CMP     AX,DS:[DI+2]            ; CHECK WHETHER THERE ARE CHARACTERS IN THE BUFFER
  984. else
  985.     MOV     AX,DS:[SI]              ; GET THE OFFSET INTO THE DATA BUFFER OF THE BEGINNING
  986.     CMP     AX,DS:[DI]              ; CHECK WHETHER THERE ARE CHARACTERS IN THE BUFFER
  987. endif
  988.     JE      CHARACTER_NOT_READY     ; IF THE TWO POINTERS ARE THE SAME, THEN THERE IS NO DATA
  989.     MOV     AX,2100h                ; SET THE DATA READY FLAG
  990. ;    JMP     STATUS_FINISHED
  991.     JMP     SHORT SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  992. CHARACTER_NOT_READY:
  993.     MOV     AX,2000H                  ; RESET THE DATA READY FLAG
  994.  
  995. STATUS_FINISHED:
  996.     JMP     SHORT SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  997.  
  998. endif
  999.  
  1000. SSKIP:
  1001.  
  1002. ifdef DEBUG
  1003. PUSH    AX                  ; DEBUGGING
  1004. ifdef Microsoft
  1005. CALL    _PRINT_INT2
  1006. else
  1007. CALL    PRINT_INT2
  1008. endif
  1009. POP     AX
  1010. endif
  1011.  
  1012.     XOR     BL,BL
  1013.     MOV     CS:INTENTER,BL    ; REENTER FLAG, DONE NOW
  1014.     CLI
  1015.     MOV     BX,OLDSS        ; restore the old stack
  1016.     MOV     SS,BX
  1017.     MOV     SP,OLDSP
  1018.     STI
  1019. SERIAL2:
  1020.     POP     SI
  1021.     POP        DI
  1022.     POP        DX
  1023.     POP        CX
  1024.     POP        BX
  1025.     POP        AX
  1026.     POP        ES
  1027.     POP        DS
  1028.     JMP     SHORT LEAVE_SERIAL    ; JUMP TO THE END OF THE SERIAL ROUTINES
  1029.  
  1030. SSKIP2:
  1031.     XOR     BL,BL
  1032.     MOV     CS:INTENTER,BL    ; REENTER FLAG, DONE NOW
  1033.     CLI
  1034.     MOV     BX,OLDSS        ; restore the old stack
  1035.     MOV     SS,BX
  1036.     MOV        SP,OLDSP
  1037.     STI
  1038. SERIAL3:
  1039.     POP     SI
  1040.     POP        DI
  1041.     POP        DX
  1042.     POP        CX
  1043.     POP        BX
  1044.     POP     ES              ; POP AX INTO ES TO PRESERVE THE RETURN VALUE IN AX
  1045.     POP        ES
  1046.     POP        DS
  1047. ;
  1048. ;
  1049. ;   forward to any other existing routines
  1050. ;
  1051. LEAVE_SERIAL:
  1052. ifdef QAK
  1053.     JMP     DWORD PTR CS:SIP
  1054. else
  1055.     IRET
  1056. endif
  1057. ifdef Microsoft
  1058. _INT14INST      ENDP
  1059. else
  1060. INT14INST       ENDP
  1061. endif
  1062. ifdef Microsoft
  1063. ;_TEXT ends
  1064.  
  1065. else
  1066.     ENDPS
  1067. endif
  1068.     END
  1069.