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.OL2 < prev    next >
Text File  |  1991-02-06  |  33KB  |  1,032 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.  
  528. ifdef DEBUG
  529. PUSH    DX
  530. PUSH    AX
  531. ifdef Microsoft
  532. CALL    _PRINT_INT
  533. else
  534. CALL    PRINT_INT
  535. endif
  536. POP     AX
  537. POP     DX
  538. endif
  539.     MOV     CX,DX           ; MOVE THE COMM. PORT INTO THE CX REGISTER
  540.     MOV     BL,1            ; MOVE A FLAG INTO THE BL REGISTER
  541.     SHL     BL,CL           ; SHIFT THE FLAG TO LINE UP WITH THE CORRECT INITIALIZATION FLAG
  542.     CMP     AH,00           ; CHECK FOR PORT INITIALIZATION
  543.     JNE     NOT_INIT_COM_PORT   ; JUMP AROUND INITIALIZING THE COMM PORT
  544.  
  545. INIT_COM_PORT:              ; INITIALIZE THE COMM. PORT
  546. ifdef Microsoft
  547.     TEST    BL,_INITIALIZED_FLAGS; CHECK WHETHER THIS CONNECTION HAS BEEN INITIALIZED
  548.     JNE     PORT_ALREADY_INIT   ; JUMP TO THE CHECK FOR CLOSING THE PORT
  549.     OR      _INITIALIZED_FLAGS,BL; SET THE INITIALIZED FLAG FOR THIS PORT
  550. else
  551.     TEST    BL,INITIALIZED_FLAGS; CHECK WHETHER THIS CONNECTION HAS BEEN INITIALIZED
  552.     JNE     PORT_ALREADY_INIT   ; JUMP TO THE CHECK FOR CLOSING THE PORT
  553.     OR      INITIALIZED_FLAGS,BL; SET THE INITIALIZED FLAG FOR THIS PORT
  554. endif
  555.     JMP     SHORT RESET_INIT      ; JUMP TO RESETING THE COMM. PORT BUFFER
  556.  
  557. PORT_ALREADY_INIT:          ; THE PORT HAS ALREADY BEEN INITIALIZED
  558. ifdef Microsoft
  559.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER WE WERE CONNECTED
  560. else
  561.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER WE WERE CONNECTED
  562. endif
  563.     JE      RESET_INIT      ; IGNORE RE-INITIALIZATION IF NOT CONNECTED
  564.     NOT     BL              ; INVERT AL IN PREPERATION FOR TURNING OFF THE FLAGS
  565. ifdef Microsoft
  566.     AND     _INITIALIZED_FLAGS,BL; RESET THE INITIALIZATION FLAG FOR THIS PORT
  567.     AND     _CONNECTED_FLAGS,BL  ; RESET THE CONNECTED FLAG FOR THIS PORT
  568. else
  569.     AND     INITIALIZED_FLAGS,BL; RESET THE INITIALIZATION FLAG FOR THIS PORT
  570.     AND     CONNECTED_FLAGS,BL  ; RESET THE CONNECTED FLAG FOR THIS PORT
  571. endif
  572.  
  573. ifdef Microsoft
  574.     MOV     SI,OFFSET _PNUM ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  575. else
  576.     MOV     SI,OFFSET PNUM  ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  577. endif
  578.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  579.     ADD     SI,DX           ; TWICE BECAUSE THESE ARE INTEGERS, NOT BYTES
  580.     PUSH    DX
  581.     PUSH    [SI]            ; PUSH THE NETWORK PORT NUMBER
  582. ifdef Microsoft
  583.     CALL    _NETCLOSE       ; CLOSE THE CONNECTION
  584. else
  585.     CALL    NETCLOSE        ; CLOSE THE CONNECTION
  586. endif
  587.     ADD     SP,2            ; GET RID OF THE PARAMETER WE PASSED
  588.     POP     DX
  589.  
  590. RESET_INIT:
  591. ifdef Microsoft
  592.     MOV     SI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  593. else
  594.     MOV     SI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  595. endif
  596.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  597.     MOV     BYTE PTR [SI],0     ; ZERO OUT THE BUFFER OFFSET FOR THE COMM. PORT
  598.  
  599. INIT_FINISHED:
  600.     MOV     AX,61B0H        ; MOVE THE RS-232 CONNECTED FLAGS INTO THE RETURN VALUE
  601.     JMP     SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  602.  
  603. NOT_INIT_COM_PORT:
  604.     CMP     AH,01           ; CHECK FOR SEND CHARACTER
  605.     JE      SEND_CHARACTER  ; JUMP TO SENDING THE CHARACTER
  606.     JMP     NOT_SEND_CHARACTER; JUMP AROUND SENDING THE CHARACTER
  607.  
  608. SEND_CHARACTER:             ; SEND A CHARACTER
  609. ifdef Microsoft
  610.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  611.     JE      DONT_NET_SEND   ; CONNECTION NOT OPEN YET, DON'T SEND THE CHARACTER
  612.     JMP     NET_SEND        ; OK, THE CONNECTION IS INITIALIZED, SEND THE CHARACTER
  613. DONT_NET_SEND:
  614.     TEST    BL,_OPENING_FLAGS; IF THE OPENING FLAG IS SET FOR THE PORT, CACHE THE CHARACTER IN A BUFFER
  615. else
  616.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  617.     JE      DONT_NET_SEND   ; CONNECTION NOT OPEN YET, DON'T SEND THE CHARACTER
  618.     JMP     NET_SEND        ; OK, THE CONNECTION IS INITIALIZED, SEND THE CHARACTER
  619. DONT_NET_SEND:
  620.     TEST    BL,OPENING_FLAGS; IF THE OPENING FLAG IS SET FOR THE PORT, CACHE THE CHARACTER IN A BUFFER
  621. endif
  622.     JNE     CACHE_PORT_NAME ; GO CACHE THE CHARACTER
  623.     CMP     AL,02           ; CHECK WHETHER THIS IS THE BEGINNING OF A PORT NAME
  624.     JE      START_PORT_NAME ; START CACHING THE PORT NAME
  625. ifdef DEBUG
  626. .286
  627. PUSH    2048h
  628. ifdef Microsoft
  629. CALL    _PRINT_INT
  630. else
  631. CALL    PRINT_INT
  632. endif
  633. ADD     SP,2
  634. .8086
  635. endif
  636. ifdef DEBUG
  637. PUSH    BX
  638. ifdef Microsoft
  639. CALL    _PRINT_INT
  640. else
  641. CALL    PRINT_INT
  642. endif
  643. ADD     SP,2
  644. endif
  645. ifdef DEBUG
  646. MOV     AL,_OPENING_FLAGS
  647. XOR     AH,AH
  648. PUSH    AX
  649. ifdef Microsoft
  650. CALL    _PRINT_INT
  651. else
  652. CALL    PRINT_INT
  653. endif
  654. ADD     SP,2
  655. endif
  656.     MOV     AH,80H          ; REPORT ERROR CONDITION
  657.     JMP     SEND_FINISHED   ;
  658.  
  659. START_PORT_NAME:            ; INITIALIZE THE PORT NAME CACHING
  660. ifdef Microsoft
  661.     OR      _OPENING_FLAGS,BL; SET THE OPENING FLAG
  662. else
  663.     OR      OPENING_FLAGS,BL; SET THE OPENING FLAG
  664. endif
  665. ifdef DEBUG
  666. .286
  667. PUSH    2047h
  668. ifdef Microsoft
  669. CALL    _PRINT_INT
  670. else
  671. CALL    PRINT_INT
  672. endif
  673. ADD     SP,2
  674. .8086
  675. endif
  676. ifdef DEBUG
  677. PUSH    BX
  678. ifdef Microsoft
  679. CALL    _PRINT_INT
  680. else
  681. CALL    PRINT_INT
  682. endif
  683. ADD     SP,2
  684. endif
  685. ifdef DEBUG
  686. MOV     AL,_OPENING_FLAGS
  687. XOR     AH,AH
  688. PUSH    AX
  689. ifdef Microsoft
  690. CALL    _PRINT_INT
  691. else
  692. CALL    PRINT_INT
  693. endif
  694. ADD     SP,2
  695. endif
  696.     JMP     SEND_DONE       ; INDICATE A SUCCESSFUL CHARACTER SEND, BUT DON'T REALLY
  697.  
  698. CACHE_PORT_NAME:            ; STUFF THE CHARACTER INTO A BUFFER, OR OPEN A CONNECTION
  699.     CMP     AL,03H          ; CHECK WHETHER THIS IS THE TERMINATING CHARACTER IN A PORT NAME
  700.     JE      NET_OPEN        ; GO, OPEN THE CONNECTION
  701. ifdef Microsoft
  702.     MOV     DI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  703. else
  704.     MOV     DI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  705. endif
  706.     ADD     DI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  707.     MOV     CL,AL           ; SAVE THE CHARACTER TEMPORARILY
  708.     MOV     AL,64           ; MOVE THE SIZE OF THE PORT NAME BUFFER INTO AL
  709.     MUL     DL              ; GET THE OFFSET OF THE PORT BUFFER TO USE
  710.     ADD     AX,DS:[DI]      ; GET THE OFFSET TO STORE THE CHARACTER AT
  711.     INC     BYTE PTR DS:[DI]    ; INCREMENT THE BUFFER OFFSET FOR THE COMM. PORT
  712.     CMP     BYTE PTR DS:[DI],64 ; CHECK WHETHER WE HAVE TOO LONG OF A NAME
  713.     JE      NAME_TOO_LONG   ; JUMP FOR TOO LONG OF A NAME
  714. ifdef Microsoft
  715.     MOV     SI,OFFSET _PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  716. else
  717.     MOV     SI,OFFSET PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  718. endif
  719.     ADD     SI,AX           ; GET THE CORRECT OFFSET TO STORE THIS CHARACTER AT
  720.     MOV     AL,CL           ; RESTORE THE CHARACTER TO STORE
  721.     MOV     [SI],AL         ; APPEND THE CHARACTER TO THE PORT NAME
  722. ifdef DEBUG
  723. .286
  724. PUSH    2044h
  725. ifdef Microsoft
  726. CALL    _PRINT_INT
  727. else
  728. CALL    PRINT_INT
  729. endif
  730. ADD     SP,2
  731. .8086
  732. endif
  733.     JMP     SEND_DONE       ; INDICATE A GOOD TRANSFER
  734.  
  735. NAME_TOO_LONG:              ; THE PORT NAME WAS TOO LONG
  736.     MOV     BYTE PTR DS:[DI],0  ; RESET THE LENGTH OF THE PORT NAME
  737.     NOT     BL              ;
  738. ifdef Microsoft
  739.     AND     _OPENING_FLAGS,BL; RESET THE OPENING FLAG
  740. else
  741.     AND     OPENING_FLAGS,BL; RESET THE OPENING FLAG
  742. endif
  743.     MOV     AL,CL           ; RESTORE THE CHARACTER TO SEND
  744. ifdef DEBUG
  745. .286
  746. PUSH    2045h
  747. ifdef Microsoft
  748. CALL    _PRINT_INT
  749. else
  750. CALL    PRINT_INT
  751. endif
  752. ADD     SP,2
  753. .8086
  754. endif
  755.     MOV     AH,80H          ; INDICATE ERROR CONDITION
  756.     JMP     SHORT SEND_FINISHED   ; JUMP TO THE END OF THE ROUTINE
  757.  
  758. NET_OPEN:                   ; OPEN THE CONNECTION TO THE NETWORK
  759.     NOT     BL              ;
  760. ifdef Microsoft
  761.     AND     _OPENING_FLAGS,BL; RESET THE OPENING FLAG
  762.     MOV     DI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  763. else
  764.     AND     OPENING_FLAGS,BL; RESET THE OPENING FLAG
  765.     MOV     DI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  766. endif
  767.     ADD     DI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  768.     MOV     CL,AL           ; SAVE THE CHARACTER TEMPORARILY
  769.     MOV     AL,64           ; MOVE THE SIZE OF THE PORT NAME BUFFER INTO AL
  770.     MUL     DL              ; GET THE OFFSET OF THE PORT BUFFER TO USE
  771.     ADD     AX,DS:[DI]      ; GET THE OFFSET TO STORE THE CHARACTER AT
  772. ifdef Microsoft
  773.     MOV     SI,OFFSET _PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  774. else
  775.     MOV     SI,OFFSET PORT_BUFFER; GET THE OFFSET INTO THE COMM. PORT BUFFER
  776. endif
  777.     PUSH    BX              ; SAVE THE COMM. PORT FLAGS
  778.     ADD     SI,AX           ; GET THE CORRECT OFFSET TO STORE THIS CHARACTER AT
  779.     MOV     AL,CL           ; RESTORE THE CHARACTER TO STORE
  780.     MOV     BYTE PTR [SI],0 ; APPEND THE TERMINATING ZERO
  781.     PUSH    DX              ; PUSH THE COMM. PORT WE ARE OPENING
  782. ifdef Microsoft
  783.     CALL    _INT14OPEN      ; OPEN THE CONNECTION
  784. else
  785.     CALL    INT14OPEN       ; OPEN THE CONNECTION
  786. endif
  787.     POP     DX              ; RECOVER THE COMM. PORT WE USED
  788.     POP     BX              ; RECOVER THE COMM. PORT FLAGS
  789.     CMP     AX,1            ; CHECK FOR GOOD OPENING
  790.     JNE     BAD_NET_OPEN    ; CONNECTION DIDN'T OPEN
  791.  
  792.     NOT     BL              ;
  793. ifdef Microsoft
  794.     OR      _CONNECTED_FLAGS,BL; SET THE CONNECTED FLAG
  795.     MOV     SI,OFFSET _BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  796. else
  797.     OR      CONNECTED_FLAGS,BL; SET THE CONNECTED FLAG
  798.     MOV     SI,OFFSET BUFFER_OFFSET; GET THE OFFSET INTO THE COMM. PORT BUFFER
  799. endif
  800.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  801.     MOV     BYTE PTR [SI],0     ; ZERO OUT THE BUFFER OFFSET FOR THE COMM. PORT
  802.     JMP     SHORT SEND_DONE       ; INDICATE A SUCCESSFUL CONNECTION OPENING
  803.  
  804. BAD_NET_OPEN:
  805. ifdef DEBUG
  806. .286
  807. PUSH    2046h
  808. ifdef Microsoft
  809. CALL    _PRINT_INT
  810. else
  811. CALL    PRINT_INT
  812. endif
  813. ADD     SP,2
  814. .8086
  815. endif
  816.     MOV     AX,80           ; INDICATE A BAD NETWORK OPEN
  817.     JMP     SHORT SEND_FINISHED   ; RETURN FROM THE INTERRUPT
  818.  
  819. NET_SEND:                   ; SEND THE CHARACTER IN AL ONTO THE NET
  820. ifdef Microsoft
  821.     MOV     _CHAR_TO_SEND,AL ; STORE THE CHARACTER TO SEND ON THE NET
  822. else
  823.     MOV     CHAR_TO_SEND,AL ; STORE THE CHARACTER TO SEND ON THE NET
  824. endif
  825.     MOV     AX,1            ; THE NUMBER OF CHARACTERS TO DROP ONTO THE NET
  826.     PUSH    AX
  827.     PUSH    DS              ; PUSH THE SEGMENT ADDRESS OF THE CHARACTER TO SEND
  828.     MOV     AX,OFFSET _CHAR_TO_SEND ; PUSH THE ADDRESS OF THE CHARACTER TO SEND
  829.     PUSH    AX
  830. ifdef Microsoft
  831.     MOV     SI,OFFSET _PNUM ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  832. else
  833.     MOV     SI,OFFSET PNUM  ; GET THE OFFSET INTO THE COMM. PORT NETWORK PORT NUMBERS
  834. endif
  835.     ADD     SI,DX           ; INCREMENT TO THE CORRECT COMM. PORT OFFSET
  836.     ADD     SI,DX           ; TWICE BECAUSE THESE ARE INTEGERS, NOT BYTES
  837.     PUSH    [SI]            ; PUSH THE NETWORK PORT NUMBER
  838. ifdef Microsoft
  839.     CALL    _NETWRITE       ; CLOSE THE CONNECTION
  840. else
  841.     CALL    NETWRITE        ; CLOSE THE CONNECTION
  842. endif
  843.     ADD     SP,8            ; RESTORE THE STACK FRAME
  844. ;   JMP     SEND_DONE       ; INDICATE A SUCCESSFUL DATA SEND
  845.  
  846. SEND_DONE:                  ; INDICATE A SUCCESSFUL CHARACTER SEND
  847.     MOV     AH,21           ; INDICATE A HAPPY CHARACTER SEND
  848. SEND_FINISHED:
  849.     JMP     SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  850.  
  851. NOT_SEND_CHARACTER:
  852.     CMP     AH,02           ; CHECK FOR RECEIVING CHARACTER
  853.     JNE     NOT_RECEIVE_CHARACTER;  JUMP AROUND RECEIVING A CHARACTER
  854.  
  855. RECEIVE_CHARACTER:          ; GET A CHARACTER
  856. ifdef Microsoft
  857.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  858. else
  859.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  860. endif
  861.     JNE     GET_PORT_CHARACTER; GET A CHARACTER FROM THE PORT
  862.     MOV     AH,80H          ; REPORT ERROR CONDITION
  863.     JMP     SHORT RECEIVE_FINISHED   ;
  864.  
  865. GET_PORT_CHARACTER:
  866. ifdef QAK
  867.     PUSH    DX                      ; PUSH THE PORT NUMBER
  868. ifdef Microsoft
  869.     CALL    _GET_COMM_CHAR          ; CALL A C ROUTINE TO GET THE CHARACTER
  870. else
  871.     CALL    GET_COMM_CHAR           ; CALL A C ROUTINE TO GET THE CHARACTER
  872. endif
  873.     ADD     SP,2                    ; REMOVE PARAMETER
  874. else
  875. ifdef Microsoft
  876.     MOV     SI,OFFSET _DATA_BEGIN   ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  877.     MOV     DI,OFFSET _DATA_END     ; GET THE POINTER TO THE END OF THE DATA BUFFER
  878. else
  879.     MOV     SI,OFFSET DATA_BEGIN    ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  880.     MOV     DI,OFFSET DATA_END      ; GET THE POINTER TO THE END OF THE DATA BUFFER
  881. endif
  882.     SHL     DX,1                    ; MULTIPLY THE PORT NUMBER BY 4 TO GET THE
  883.     SHL     DX,1                    ;   OFFSET TO THE CORRECT ARRAY ELEMENT
  884.     ADD     SI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  885.     ADD     DI,DX
  886. WAIT_FOR_CHARACTER:
  887.     MOV     AX,DS:[SI]              ; GET THE OFFSET INTO THE DATA BUFFER OF THE BEGINNING
  888.     CMP     AX,DS:[DI]              ; CHECK WHETHER THERE ARE CHARACTERS IN THE BUFFER
  889.     JE      WAIT_FOR_CHARACTER      ; IF THE TWO POINTERS ARE THE SAME, THEN WAIT FOR DATA
  890.  
  891.     PUSH    DS
  892.     MOV     DI,AX                   ; SAVE THE OFFSET OF THE BEGINING POINTER
  893.     MOV     AX,DS:[SI+2]            ; GET THE SEGMENT OF THE BEGINNING POINTER
  894.     MOV     DS,AX
  895.     MOV     AL,BYTE PTR DS:[DI]     ; GET THE CHARACTER FROM THE BEGINNING OF THE QUEUE
  896.     POP     DS                      ; RECOVER THE DATA SEGMENT
  897. ifdef Microsoft
  898.     MOV     DI,OFFSET _DATA_MAX     ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  899. else
  900.     MOV     DI,OFFSET DATA_MAX      ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  901. endif
  902.     ADD     DI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  903.     INC     WORD PTR DS:[SI]        ; INCREMENT THE BEGINNING OF THE QUEUE
  904.     MOV     CX,DS:[SI]              ; GET THE BEGINNING OF THE QUEUE
  905.     CMP     CX,DS:[DI]              ; CHECK FOR WRAPPING AROUND
  906.     JL      NOT_WRAPPED             ; JUMP AROUND WRAP-AROUND FIX
  907. ifdef Microsoft
  908.     MOV     DI,OFFSET _DATA_START   ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  909. else
  910.     MOV     DI,OFFSET DATA_START    ; GET THE POINTER TO THE MAX OF THE DATA BUFFER
  911. endif
  912.     ADD     DI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  913.     MOV     CX,DS:[DI]              ; GET THE START OF THE QUEUE
  914.     MOV     DS:[SI],CX              ; MOVE THE BEGINNING OF THE QUEUE AROUND
  915. endif
  916.  
  917. NOT_WRAPPED:
  918.     MOV     AH,21           ; REPORT SUCCESS
  919.  
  920. RECEIVE_FINISHED:
  921.     JMP     SHORT SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  922.  
  923. NOT_RECEIVE_CHARACTER:
  924.     CMP     AH,03           ; CHECK FOR READ STATUS
  925.     JNE     SSKIP           ; A COMMUNICATION REQUEST WHICH WE DON'T HANDLE
  926.  
  927. READ_STATUS:                ; CHECK FOR A CHARACTER
  928. ifdef Microsoft
  929.     TEST    BL,_CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  930. else
  931.     TEST    BL,CONNECTED_FLAGS; CHECK WHETHER THIS PORT IN CONNECTED
  932. endif
  933.     JNE     GET_PORT_STATUS ; GET THE PORT STATUS
  934. ;    MOV     AX,7ABFH          ; REPORT ERROR CONDITION
  935.     MOV     AX,2000H           ; REPORT ERROR CONDITION
  936.     JMP     SHORT STATUS_FINISHED ;
  937.  
  938. GET_PORT_STATUS:
  939. ifdef Microsoft
  940.     MOV     SI,OFFSET _DATA_BEGIN   ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  941.     MOV     DI,OFFSET _DATA_END     ; GET THE POINTER TO THE END OF THE DATA BUFFER
  942. else
  943.     MOV     SI,OFFSET DATA_BEGIN    ; GET THE POINTER TO THE BEGINNING OF THE DATA BUFFER
  944.     MOV     DI,OFFSET DATA_END      ; GET THE POINTER TO THE END OF THE DATA BUFFER
  945. endif
  946.     SHL     DX,1                    ; MULTIPLY THE PORT NUMBER BY 4 TO GET THE
  947.     SHL     DX,1                    ;   OFFSET TO THE CORRECT ARRAY ELEMENT
  948.     ADD     SI,DX                   ; INCREMENT TO THE CORRECT ARRAY ELEMENT
  949.     ADD     DI,DX
  950.  
  951.     MOV     AX,DS:[SI]              ; GET THE OFFSET INTO THE DATA BUFFER OF THE BEGINNING
  952.     CMP     AX,DS:[DI]              ; CHECK WHETHER THERE ARE CHARACTERS IN THE BUFFER
  953.     JE      CHARACTER_NOT_READY     ; IF THE TWO POINTERS ARE THE SAME, THEN THERE IS NO DATA
  954.     MOV     AX,2100h                ; SET THE DATA READY FLAG
  955. ;    JMP     STATUS_FINISHED
  956.     JMP     SHORT SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  957. CHARACTER_NOT_READY:
  958.     MOV     AX,2000H                  ; RESET THE DATA READY FLAG
  959.  
  960. STATUS_FINISHED:
  961.     JMP     SHORT SSKIP2          ; JUMP TO THE END OF THE ROUTINE
  962.  
  963. SSKIP:
  964.  
  965. ifdef DEBUG
  966. PUSH    AX                  ; DEBUGGING
  967. ifdef Microsoft
  968. CALL    _PRINT_INT2
  969. else
  970. CALL    PRINT_INT2
  971. endif
  972. POP     AX
  973. endif
  974.  
  975.     XOR     BL,BL
  976.     MOV     CS:INTENTER,BL    ; REENTER FLAG, DONE NOW
  977.     CLI
  978.     MOV     BX,OLDSS        ; restore the old stack
  979.     MOV     SS,BX
  980.     MOV     SP,OLDSP
  981.     STI
  982. SERIAL2:
  983.     POP     SI
  984.     POP        DI
  985.     POP        DX
  986.     POP        CX
  987.     POP        BX
  988.     POP        AX
  989.     POP        ES
  990.     POP        DS
  991.     JMP     SHORT LEAVE_SERIAL    ; JUMP TO THE END OF THE SERIAL ROUTINES
  992.  
  993. SSKIP2:
  994.     XOR     BL,BL
  995.     MOV     CS:INTENTER,BL    ; REENTER FLAG, DONE NOW
  996.     CLI
  997.     MOV     BX,OLDSS        ; restore the old stack
  998.     MOV     SS,BX
  999.     MOV        SP,OLDSP
  1000.     STI
  1001. SERIAL3:
  1002.     POP     SI
  1003.     POP        DI
  1004.     POP        DX
  1005.     POP        CX
  1006.     POP        BX
  1007.     POP     ES              ; POP AX INTO ES TO PRESERVE THE RETURN VALUE IN AX
  1008.     POP        ES
  1009.     POP        DS
  1010. ;
  1011. ;
  1012. ;   forward to any other existing routines
  1013. ;
  1014. LEAVE_SERIAL:
  1015. ifdef QAK
  1016.     JMP     DWORD PTR CS:SIP
  1017. else
  1018.     IRET
  1019. endif
  1020. ifdef Microsoft
  1021. _INT14INST      ENDP
  1022. else
  1023. INT14INST       ENDP
  1024. endif
  1025. ifdef Microsoft
  1026. ;_TEXT ends
  1027.  
  1028. else
  1029.     ENDPS
  1030. endif
  1031.     END
  1032.